Version 2.14.0-358.0.dev
Merge commit '45ae00676adcd36eda411dd6fcec550784128b9a' into 'dev'
diff --git a/pkg/analyzer/test/src/dart/resolution/local_variable_test.dart b/pkg/analyzer/test/src/dart/resolution/local_variable_test.dart
index 213fbbb..ddad876 100644
--- a/pkg/analyzer/test/src/dart/resolution/local_variable_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/local_variable_test.dart
@@ -11,7 +11,6 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(LocalVariableResolutionTest);
- defineReflectiveTests(LocalVariableResolutionWithNullSafetyTest);
});
}
@@ -95,11 +94,7 @@
expect(x.isLate, isFalse);
expect(x.isStatic, isFalse);
}
-}
-@reflectiveTest
-class LocalVariableResolutionWithNullSafetyTest
- extends LocalVariableResolutionTest with WithNullSafetyMixin {
test_element_late() async {
await assertErrorsInCode(r'''
void f() {
diff --git a/pkg/analyzer/test/src/dart/resolution/postfix_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/postfix_expression_test.dart
index 094323e..2c5f443 100644
--- a/pkg/analyzer/test/src/dart/resolution/postfix_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/postfix_expression_test.dart
@@ -12,13 +12,298 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(PostfixExpressionResolutionTest);
- defineReflectiveTests(PostfixExpressionResolutionWithNullSafetyTest);
+ defineReflectiveTests(PostfixExpressionResolutionWithoutNullSafetyTest);
});
}
@reflectiveTest
class PostfixExpressionResolutionTest extends PubPackageResolutionTest
- with WithoutNullSafetyMixin {
+ with PostfixExpressionResolutionTestCases {
+ test_inc_propertyAccess_nullShorting() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ int foo = 0;
+}
+
+void f(A? a) {
+ a?.foo++;
+}
+''');
+
+ assertPostfixExpression(
+ findNode.postfix('foo++'),
+ readElement: findElement.getter('foo'),
+ readType: 'int',
+ writeElement: findElement.setter('foo'),
+ writeType: 'int',
+ element: numElement.getMethod('+'),
+ type: 'int?',
+ );
+ }
+
+ test_inc_simpleIdentifier_parameter_depromote() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ Object operator +(int _) => this;
+}
+
+void f(Object x) {
+ if (x is A) {
+ x++;
+ x; // ref
+ }
+}
+''');
+
+ if (hasAssignmentLeftResolution) {
+ assertType(findNode.simple('x++;'), 'A');
+ }
+
+ assertPostfixExpression(
+ findNode.postfix('x++'),
+ readElement: findElement.parameter('x'),
+ readType: 'A',
+ writeElement: findElement.parameter('x'),
+ writeType: 'Object',
+ element: findElement.method('+'),
+ type: 'A',
+ );
+
+ assertType(findNode.simple('x; // ref'), 'Object');
+ }
+
+ test_nullCheck() async {
+ await assertNoErrorsInCode(r'''
+void f(int? x) {
+ x!;
+}
+''');
+
+ assertPostfixExpression(
+ findNode.postfix('x!'),
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: null,
+ element: null,
+ type: 'int',
+ );
+ }
+
+ test_nullCheck_functionExpressionInvocation_rewrite() async {
+ await assertNoErrorsInCode(r'''
+void f(Function f2) {
+ f2(42)!;
+}
+''');
+ }
+
+ test_nullCheck_indexExpression() async {
+ await assertNoErrorsInCode(r'''
+void f(Map<String, int> a) {
+ int v = a['foo']!;
+ v;
+}
+''');
+
+ assertIndexExpression(
+ findNode.index('a['),
+ readElement: elementMatcher(
+ mapElement.getMethod('[]'),
+ substitution: {'K': 'String', 'V': 'int'},
+ ),
+ writeElement: null,
+ type: 'int?',
+ );
+
+ assertPostfixExpression(
+ findNode.postfix(']!'),
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: null,
+ element: null,
+ type: 'int',
+ );
+ }
+
+ test_nullCheck_null() async {
+ await assertErrorsInCode('''
+void f(Null x) {
+ x!;
+}
+''', [
+ error(HintCode.NULL_CHECK_ALWAYS_FAILS, 19, 2),
+ ]);
+
+ assertType(findNode.postfix('x!'), 'Never');
+ }
+
+ test_nullCheck_nullableContext() async {
+ await assertNoErrorsInCode(r'''
+T f<T>(T t) => t;
+
+int g() => f(null)!;
+''');
+
+ assertMethodInvocation2(
+ findNode.methodInvocation('f(null)'),
+ element: findElement.topFunction('f'),
+ typeArgumentTypes: ['int?'],
+ invokeType: 'int? Function(int?)',
+ type: 'int?',
+ );
+
+ assertPostfixExpression(
+ findNode.postfix('f(null)!'),
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: null,
+ element: null,
+ type: 'int',
+ );
+ }
+
+ /// See https://github.com/dart-lang/language/issues/1163
+ test_nullCheck_participatesNullShorting() async {
+ await assertErrorsInCode('''
+class A {
+ int zero;
+ int? zeroOrNull;
+
+ A(this.zero, [this.zeroOrNull]);
+}
+
+void test1(A? a) => a?.zero!;
+void test2(A? a) => a?.zeroOrNull!;
+void test3(A? a) => a?.zero!.isEven;
+void test4(A? a) => a?.zeroOrNull!.isEven;
+
+class Foo {
+ Bar? bar;
+
+ Foo(this.bar);
+
+ Bar? operator [](int? index) => null;
+}
+
+class Bar {
+ int baz;
+
+ Bar(this.baz);
+
+ int operator [](int index) => index;
+}
+
+void test5(Foo? foo) => foo?.bar!;
+void test6(Foo? foo) => foo?.bar!.baz;
+void test7(Foo? foo, int a) => foo?.bar![a];
+void test8(Foo? foo, int? a) => foo?[a]!;
+void test9(Foo? foo, int? a) => foo?[a]!.baz;
+void test10(Foo? foo, int? a, int b) => foo?[a]![b];
+''', [
+ error(StaticWarningCode.UNNECESSARY_NON_NULL_ASSERTION, 107, 1),
+ error(StaticWarningCode.UNNECESSARY_NON_NULL_ASSERTION, 173, 1),
+ ]);
+
+ void assertTestType(int index, String expected) {
+ var function = findNode.functionDeclaration('test$index(');
+ var body = function.functionExpression.body as ExpressionFunctionBody;
+ assertType(body.expression, expected);
+ }
+
+ assertTestType(1, 'int?');
+ assertTestType(2, 'int?');
+ assertTestType(3, 'bool?');
+ assertTestType(4, 'bool?');
+
+ assertTestType(5, 'Bar?');
+ assertTestType(6, 'int?');
+ assertTestType(7, 'int?');
+ assertTestType(8, 'Bar?');
+ assertTestType(9, 'int?');
+ assertTestType(10, 'int?');
+ }
+
+ test_nullCheck_superExpression() async {
+ await assertErrorsInCode(r'''
+class A {
+ int foo() => 0;
+}
+
+class B extends A {
+ void bar() {
+ super!.foo();
+ }
+}
+''', [
+ error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 70, 6),
+ ]);
+
+ assertTypeDynamic(findNode.super_('super!'));
+
+ assertPostfixExpression(
+ findNode.postfix('super!'),
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: null,
+ element: null,
+ type: 'dynamic',
+ );
+
+ assertMethodInvocation2(
+ findNode.methodInvocation('foo();'),
+ element: null,
+ typeArgumentTypes: [],
+ invokeType: 'dynamic',
+ type: 'dynamic',
+ );
+ }
+
+ test_nullCheck_typeParameter() async {
+ await assertNoErrorsInCode(r'''
+void f<T>(T? x) {
+ x!;
+}
+''');
+
+ var postfixExpression = findNode.postfix('x!');
+ assertPostfixExpression(
+ postfixExpression,
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: null,
+ element: null,
+ type: 'T & Object',
+ );
+ }
+
+ test_nullCheck_typeParameter_already_promoted() async {
+ await assertNoErrorsInCode('''
+void f<T>(T? x) {
+ if (x is num?) {
+ x!;
+ }
+}
+''');
+
+ var postfixExpression = findNode.postfix('x!');
+ assertPostfixExpression(
+ postfixExpression,
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: null,
+ element: null,
+ type: 'T & num',
+ );
+ }
+}
+
+mixin PostfixExpressionResolutionTestCases on PubPackageResolutionTest {
test_dec_simpleIdentifier_parameter_int() async {
await assertNoErrorsInCode(r'''
void f(int x) {
@@ -484,288 +769,6 @@
}
@reflectiveTest
-class PostfixExpressionResolutionWithNullSafetyTest
- extends PostfixExpressionResolutionTest with WithNullSafetyMixin {
- test_inc_propertyAccess_nullShorting() async {
- await assertNoErrorsInCode(r'''
-class A {
- int foo = 0;
-}
-
-void f(A? a) {
- a?.foo++;
-}
-''');
-
- assertPostfixExpression(
- findNode.postfix('foo++'),
- readElement: findElement.getter('foo'),
- readType: 'int',
- writeElement: findElement.setter('foo'),
- writeType: 'int',
- element: numElement.getMethod('+'),
- type: 'int?',
- );
- }
-
- test_inc_simpleIdentifier_parameter_depromote() async {
- await assertNoErrorsInCode(r'''
-class A {
- Object operator +(int _) => this;
-}
-
-void f(Object x) {
- if (x is A) {
- x++;
- x; // ref
- }
-}
-''');
-
- if (hasAssignmentLeftResolution) {
- assertType(findNode.simple('x++;'), 'A');
- }
-
- assertPostfixExpression(
- findNode.postfix('x++'),
- readElement: findElement.parameter('x'),
- readType: 'A',
- writeElement: findElement.parameter('x'),
- writeType: 'Object',
- element: findElement.method('+'),
- type: 'A',
- );
-
- assertType(findNode.simple('x; // ref'), 'Object');
- }
-
- test_nullCheck() async {
- await assertNoErrorsInCode(r'''
-void f(int? x) {
- x!;
-}
-''');
-
- assertPostfixExpression(
- findNode.postfix('x!'),
- readElement: null,
- readType: null,
- writeElement: null,
- writeType: null,
- element: null,
- type: 'int',
- );
- }
-
- test_nullCheck_functionExpressionInvocation_rewrite() async {
- await assertNoErrorsInCode(r'''
-void f(Function f2) {
- f2(42)!;
-}
-''');
- }
-
- test_nullCheck_indexExpression() async {
- await assertNoErrorsInCode(r'''
-void f(Map<String, int> a) {
- int v = a['foo']!;
- v;
-}
-''');
-
- assertIndexExpression(
- findNode.index('a['),
- readElement: elementMatcher(
- mapElement.getMethod('[]'),
- substitution: {'K': 'String', 'V': 'int'},
- ),
- writeElement: null,
- type: 'int?',
- );
-
- assertPostfixExpression(
- findNode.postfix(']!'),
- readElement: null,
- readType: null,
- writeElement: null,
- writeType: null,
- element: null,
- type: 'int',
- );
- }
-
- test_nullCheck_null() async {
- await assertErrorsInCode('''
-void f(Null x) {
- x!;
-}
-''', [
- error(HintCode.NULL_CHECK_ALWAYS_FAILS, 19, 2),
- ]);
-
- assertType(findNode.postfix('x!'), 'Never');
- }
-
- test_nullCheck_nullableContext() async {
- await assertNoErrorsInCode(r'''
-T f<T>(T t) => t;
-
-int g() => f(null)!;
-''');
-
- assertMethodInvocation2(
- findNode.methodInvocation('f(null)'),
- element: findElement.topFunction('f'),
- typeArgumentTypes: ['int?'],
- invokeType: 'int? Function(int?)',
- type: 'int?',
- );
-
- assertPostfixExpression(
- findNode.postfix('f(null)!'),
- readElement: null,
- readType: null,
- writeElement: null,
- writeType: null,
- element: null,
- type: 'int',
- );
- }
-
- /// See https://github.com/dart-lang/language/issues/1163
- test_nullCheck_participatesNullShorting() async {
- await assertErrorsInCode('''
-class A {
- int zero;
- int? zeroOrNull;
-
- A(this.zero, [this.zeroOrNull]);
-}
-
-void test1(A? a) => a?.zero!;
-void test2(A? a) => a?.zeroOrNull!;
-void test3(A? a) => a?.zero!.isEven;
-void test4(A? a) => a?.zeroOrNull!.isEven;
-
-class Foo {
- Bar? bar;
-
- Foo(this.bar);
-
- Bar? operator [](int? index) => null;
-}
-
-class Bar {
- int baz;
-
- Bar(this.baz);
-
- int operator [](int index) => index;
-}
-
-void test5(Foo? foo) => foo?.bar!;
-void test6(Foo? foo) => foo?.bar!.baz;
-void test7(Foo? foo, int a) => foo?.bar![a];
-void test8(Foo? foo, int? a) => foo?[a]!;
-void test9(Foo? foo, int? a) => foo?[a]!.baz;
-void test10(Foo? foo, int? a, int b) => foo?[a]![b];
-''', [
- error(StaticWarningCode.UNNECESSARY_NON_NULL_ASSERTION, 107, 1),
- error(StaticWarningCode.UNNECESSARY_NON_NULL_ASSERTION, 173, 1),
- ]);
-
- void assertTestType(int index, String expected) {
- var function = findNode.functionDeclaration('test$index(');
- var body = function.functionExpression.body as ExpressionFunctionBody;
- assertType(body.expression, expected);
- }
-
- assertTestType(1, 'int?');
- assertTestType(2, 'int?');
- assertTestType(3, 'bool?');
- assertTestType(4, 'bool?');
-
- assertTestType(5, 'Bar?');
- assertTestType(6, 'int?');
- assertTestType(7, 'int?');
- assertTestType(8, 'Bar?');
- assertTestType(9, 'int?');
- assertTestType(10, 'int?');
- }
-
- test_nullCheck_superExpression() async {
- await assertErrorsInCode(r'''
-class A {
- int foo() => 0;
-}
-
-class B extends A {
- void bar() {
- super!.foo();
- }
-}
-''', [
- error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 70, 6),
- ]);
-
- assertTypeDynamic(findNode.super_('super!'));
-
- assertPostfixExpression(
- findNode.postfix('super!'),
- readElement: null,
- readType: null,
- writeElement: null,
- writeType: null,
- element: null,
- type: 'dynamic',
- );
-
- assertMethodInvocation2(
- findNode.methodInvocation('foo();'),
- element: null,
- typeArgumentTypes: [],
- invokeType: 'dynamic',
- type: 'dynamic',
- );
- }
-
- test_nullCheck_typeParameter() async {
- await assertNoErrorsInCode(r'''
-void f<T>(T? x) {
- x!;
-}
-''');
-
- var postfixExpression = findNode.postfix('x!');
- assertPostfixExpression(
- postfixExpression,
- readElement: null,
- readType: null,
- writeElement: null,
- writeType: null,
- element: null,
- type: 'T & Object',
- );
- }
-
- test_nullCheck_typeParameter_already_promoted() async {
- await assertNoErrorsInCode('''
-void f<T>(T? x) {
- if (x is num?) {
- x!;
- }
-}
-''');
-
- var postfixExpression = findNode.postfix('x!');
- assertPostfixExpression(
- postfixExpression,
- readElement: null,
- readType: null,
- writeElement: null,
- writeType: null,
- element: null,
- type: 'T & num',
- );
- }
-}
+class PostfixExpressionResolutionWithoutNullSafetyTest
+ extends PubPackageResolutionTest
+ with PostfixExpressionResolutionTestCases, WithoutNullSafetyMixin {}
diff --git a/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart
index 06fd33d..1fa6d56 100644
--- a/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart
@@ -12,13 +12,140 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(PrefixExpressionResolutionTest);
- defineReflectiveTests(PrefixExpressionResolutionWithNullSafetyTest);
+ defineReflectiveTests(PrefixExpressionResolutionWithoutNullSafetyTest);
});
}
@reflectiveTest
class PrefixExpressionResolutionTest extends PubPackageResolutionTest
- with WithoutNullSafetyMixin {
+ with PrefixExpressionResolutionTestCases {
+ test_bang_no_nullShorting() async {
+ await assertErrorsInCode(r'''
+class A {
+ bool get foo => true;
+}
+
+void f(A? a) {
+ !a?.foo;
+}
+''', [
+ error(CompileTimeErrorCode.UNCHECKED_USE_OF_NULLABLE_VALUE_AS_CONDITION,
+ 55, 6),
+ ]);
+
+ assertPrefixExpression(
+ findNode.prefix('!a'),
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: null,
+ element: boolElement.getMethod('!'),
+ type: 'bool',
+ );
+ }
+
+ test_minus_no_nullShorting() async {
+ await assertErrorsInCode(r'''
+class A {
+ int get foo => 0;
+}
+
+void f(A? a) {
+ -a?.foo;
+}
+''', [
+ error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
+ 50, 1),
+ ]);
+
+ assertPrefixExpression(
+ findNode.prefix('-a'),
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: null,
+ element: intElement.getMethod('unary-'),
+ type: 'int',
+ );
+ }
+
+ test_plusPlus_depromote() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ Object operator +(int _) => this;
+}
+
+void f(Object x) {
+ if (x is A) {
+ ++x;
+ }
+}
+''');
+
+ assertPrefixExpression(
+ findNode.prefix('++x'),
+ readElement: findElement.parameter('x'),
+ readType: 'A',
+ writeElement: findElement.parameter('x'),
+ writeType: 'Object',
+ element: findElement.method('+'),
+ type: 'Object',
+ );
+
+ if (hasAssignmentLeftResolution) {
+ assertType(findNode.simple('x;'), 'A');
+ }
+ }
+
+ test_plusPlus_nullShorting() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ int foo = 0;
+}
+
+void f(A? a) {
+ ++a?.foo;
+}
+''');
+
+ assertPrefixExpression(
+ findNode.prefix('++a'),
+ readElement: findElement.getter('foo'),
+ readType: 'int',
+ writeElement: findElement.setter('foo'),
+ writeType: 'int',
+ element: numElement.getMethod('+'),
+ type: 'int?',
+ );
+ }
+
+ test_tilde_no_nullShorting() async {
+ await assertErrorsInCode(r'''
+class A {
+ int get foo => 0;
+}
+
+void f(A? a) {
+ ~a?.foo;
+}
+''', [
+ error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
+ 50, 1),
+ ]);
+
+ assertPrefixExpression(
+ findNode.prefix('~a'),
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: null,
+ element: intElement.getMethod('~'),
+ type: 'int',
+ );
+ }
+}
+
+mixin PrefixExpressionResolutionTestCases on PubPackageResolutionTest {
test_bang_bool_context() async {
await assertNoErrorsInCode(r'''
T f<T>() {
@@ -637,130 +764,6 @@
}
@reflectiveTest
-class PrefixExpressionResolutionWithNullSafetyTest
- extends PrefixExpressionResolutionTest with WithNullSafetyMixin {
- test_bang_no_nullShorting() async {
- await assertErrorsInCode(r'''
-class A {
- bool get foo => true;
-}
-
-void f(A? a) {
- !a?.foo;
-}
-''', [
- error(CompileTimeErrorCode.UNCHECKED_USE_OF_NULLABLE_VALUE_AS_CONDITION,
- 55, 6),
- ]);
-
- assertPrefixExpression(
- findNode.prefix('!a'),
- readElement: null,
- readType: null,
- writeElement: null,
- writeType: null,
- element: boolElement.getMethod('!'),
- type: 'bool',
- );
- }
-
- test_minus_no_nullShorting() async {
- await assertErrorsInCode(r'''
-class A {
- int get foo => 0;
-}
-
-void f(A? a) {
- -a?.foo;
-}
-''', [
- error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
- 50, 1),
- ]);
-
- assertPrefixExpression(
- findNode.prefix('-a'),
- readElement: null,
- readType: null,
- writeElement: null,
- writeType: null,
- element: intElement.getMethod('unary-'),
- type: 'int',
- );
- }
-
- test_plusPlus_depromote() async {
- await assertNoErrorsInCode(r'''
-class A {
- Object operator +(int _) => this;
-}
-
-void f(Object x) {
- if (x is A) {
- ++x;
- }
-}
-''');
-
- assertPrefixExpression(
- findNode.prefix('++x'),
- readElement: findElement.parameter('x'),
- readType: 'A',
- writeElement: findElement.parameter('x'),
- writeType: 'Object',
- element: findElement.method('+'),
- type: 'Object',
- );
-
- if (hasAssignmentLeftResolution) {
- assertType(findNode.simple('x;'), 'A');
- }
- }
-
- test_plusPlus_nullShorting() async {
- await assertNoErrorsInCode(r'''
-class A {
- int foo = 0;
-}
-
-void f(A? a) {
- ++a?.foo;
-}
-''');
-
- assertPrefixExpression(
- findNode.prefix('++a'),
- readElement: findElement.getter('foo'),
- readType: 'int',
- writeElement: findElement.setter('foo'),
- writeType: 'int',
- element: numElement.getMethod('+'),
- type: 'int?',
- );
- }
-
- test_tilde_no_nullShorting() async {
- await assertErrorsInCode(r'''
-class A {
- int get foo => 0;
-}
-
-void f(A? a) {
- ~a?.foo;
-}
-''', [
- error(CompileTimeErrorCode.UNCHECKED_METHOD_INVOCATION_OF_NULLABLE_VALUE,
- 50, 1),
- ]);
-
- assertPrefixExpression(
- findNode.prefix('~a'),
- readElement: null,
- readType: null,
- writeElement: null,
- writeType: null,
- element: intElement.getMethod('~'),
- type: 'int',
- );
- }
-}
+class PrefixExpressionResolutionWithoutNullSafetyTest
+ extends PubPackageResolutionTest
+ with PrefixExpressionResolutionTestCases, WithoutNullSafetyMixin {}
diff --git a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
index b95d627..e3ef89b 100644
--- a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
@@ -11,13 +11,168 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(PropertyAccessResolutionTest);
- defineReflectiveTests(PropertyAccessResolutionWithNullSafetyTest);
+ defineReflectiveTests(PropertyAccessResolutionWithoutNullSafetyTest);
});
}
@reflectiveTest
class PropertyAccessResolutionTest extends PubPackageResolutionTest
- with WithoutNullSafetyMixin {
+ with PropertyAccessResolutionTestCases {
+ test_implicitCall_tearOff_nullable() async {
+ await assertErrorsInCode('''
+class A {
+ int call() => 0;
+}
+
+class B {
+ A? a;
+}
+
+int Function() foo() {
+ return B().a; // ref
+}
+''', [
+ error(CompileTimeErrorCode.RETURN_OF_INVALID_TYPE_FROM_FUNCTION, 85, 5),
+ ]);
+
+ var identifier = findNode.simple('a; // ref');
+ assertElement(identifier, findElement.getter('a'));
+ assertType(identifier, 'A?');
+ }
+
+ test_nullShorting_cascade() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ int get foo => 0;
+ int get bar => 0;
+}
+
+void f(A? a) {
+ a?..foo..bar;
+}
+''');
+
+ assertPropertyAccess2(
+ findNode.propertyAccess('..foo'),
+ element: findElement.getter('foo'),
+ type: 'int',
+ );
+
+ assertPropertyAccess2(
+ findNode.propertyAccess('..bar'),
+ element: findElement.getter('bar'),
+ type: 'int',
+ );
+
+ assertType(findNode.cascade('a?'), 'A?');
+ }
+
+ test_nullShorting_cascade2() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ int? get foo => 0;
+}
+
+main() {
+ A a = A()..foo?.isEven;
+ a;
+}
+''');
+
+ assertPropertyAccess2(
+ findNode.propertyAccess('..foo?'),
+ element: findElement.getter('foo'),
+ type: 'int?',
+ );
+
+ assertPropertyAccess2(
+ findNode.propertyAccess('.isEven'),
+ element: intElement.getGetter('isEven'),
+ type: 'bool',
+ );
+
+ assertType(findNode.cascade('A()'), 'A');
+ }
+
+ test_nullShorting_cascade3() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ A? get foo => this;
+ A? get bar => this;
+ A? get baz => this;
+}
+
+main() {
+ A a = A()..foo?.bar?.baz;
+ a;
+}
+''');
+
+ assertPropertyAccess2(
+ findNode.propertyAccess('.foo'),
+ element: findElement.getter('foo'),
+ type: 'A?',
+ );
+
+ assertPropertyAccess2(
+ findNode.propertyAccess('.bar'),
+ element: findElement.getter('bar'),
+ type: 'A?',
+ );
+
+ assertPropertyAccess2(
+ findNode.propertyAccess('.baz'),
+ element: findElement.getter('baz'),
+ type: 'A?',
+ );
+
+ assertType(findNode.cascade('A()'), 'A');
+ }
+
+ test_nullShorting_cascade4() async {
+ await assertNoErrorsInCode(r'''
+A? get foo => A();
+
+class A {
+ A get bar => this;
+ A? get baz => this;
+ A get baq => this;
+}
+
+main() {
+ foo?.bar?..baz?.baq;
+}
+''');
+
+ assertSimpleIdentifier(
+ findNode.simple('foo?'),
+ element: findElement.topGet('foo'),
+ type: 'A?',
+ );
+
+ assertPropertyAccess2(
+ findNode.propertyAccess('.bar'),
+ element: findElement.getter('bar'),
+ type: 'A?',
+ );
+
+ assertPropertyAccess2(
+ findNode.propertyAccess('.baz'),
+ element: findElement.getter('baz'),
+ type: 'A?',
+ );
+
+ assertPropertyAccess2(
+ findNode.propertyAccess('.baq'),
+ element: findElement.getter('baq'),
+ type: 'A',
+ );
+
+ assertType(findNode.cascade('foo?'), 'A?');
+ }
+}
+
+mixin PropertyAccessResolutionTestCases on PubPackageResolutionTest {
test_extensionOverride_read() async {
await assertNoErrorsInCode('''
class A {}
@@ -561,158 +716,6 @@
}
@reflectiveTest
-class PropertyAccessResolutionWithNullSafetyTest
- extends PropertyAccessResolutionTest with WithNullSafetyMixin {
- test_implicitCall_tearOff_nullable() async {
- await assertErrorsInCode('''
-class A {
- int call() => 0;
-}
-
-class B {
- A? a;
-}
-
-int Function() foo() {
- return B().a; // ref
-}
-''', [
- error(CompileTimeErrorCode.RETURN_OF_INVALID_TYPE_FROM_FUNCTION, 85, 5),
- ]);
-
- var identifier = findNode.simple('a; // ref');
- assertElement(identifier, findElement.getter('a'));
- assertType(identifier, 'A?');
- }
-
- test_nullShorting_cascade() async {
- await assertNoErrorsInCode(r'''
-class A {
- int get foo => 0;
- int get bar => 0;
-}
-
-void f(A? a) {
- a?..foo..bar;
-}
-''');
-
- assertPropertyAccess2(
- findNode.propertyAccess('..foo'),
- element: findElement.getter('foo'),
- type: 'int',
- );
-
- assertPropertyAccess2(
- findNode.propertyAccess('..bar'),
- element: findElement.getter('bar'),
- type: 'int',
- );
-
- assertType(findNode.cascade('a?'), 'A?');
- }
-
- test_nullShorting_cascade2() async {
- await assertNoErrorsInCode(r'''
-class A {
- int? get foo => 0;
-}
-
-main() {
- A a = A()..foo?.isEven;
- a;
-}
-''');
-
- assertPropertyAccess2(
- findNode.propertyAccess('..foo?'),
- element: findElement.getter('foo'),
- type: 'int?',
- );
-
- assertPropertyAccess2(
- findNode.propertyAccess('.isEven'),
- element: intElement.getGetter('isEven'),
- type: 'bool',
- );
-
- assertType(findNode.cascade('A()'), 'A');
- }
-
- test_nullShorting_cascade3() async {
- await assertNoErrorsInCode(r'''
-class A {
- A? get foo => this;
- A? get bar => this;
- A? get baz => this;
-}
-
-main() {
- A a = A()..foo?.bar?.baz;
- a;
-}
-''');
-
- assertPropertyAccess2(
- findNode.propertyAccess('.foo'),
- element: findElement.getter('foo'),
- type: 'A?',
- );
-
- assertPropertyAccess2(
- findNode.propertyAccess('.bar'),
- element: findElement.getter('bar'),
- type: 'A?',
- );
-
- assertPropertyAccess2(
- findNode.propertyAccess('.baz'),
- element: findElement.getter('baz'),
- type: 'A?',
- );
-
- assertType(findNode.cascade('A()'), 'A');
- }
-
- test_nullShorting_cascade4() async {
- await assertNoErrorsInCode(r'''
-A? get foo => A();
-
-class A {
- A get bar => this;
- A? get baz => this;
- A get baq => this;
-}
-
-main() {
- foo?.bar?..baz?.baq;
-}
-''');
-
- assertSimpleIdentifier(
- findNode.simple('foo?'),
- element: findElement.topGet('foo'),
- type: 'A?',
- );
-
- assertPropertyAccess2(
- findNode.propertyAccess('.bar'),
- element: findElement.getter('bar'),
- type: 'A?',
- );
-
- assertPropertyAccess2(
- findNode.propertyAccess('.baz'),
- element: findElement.getter('baz'),
- type: 'A?',
- );
-
- assertPropertyAccess2(
- findNode.propertyAccess('.baq'),
- element: findElement.getter('baq'),
- type: 'A',
- );
-
- assertType(findNode.cascade('foo?'), 'A?');
- }
-}
+class PropertyAccessResolutionWithoutNullSafetyTest
+ extends PubPackageResolutionTest
+ with PropertyAccessResolutionTestCases, WithoutNullSafetyMixin {}
diff --git a/pkg/analyzer/test/src/dart/resolution/top_level_variable_test.dart b/pkg/analyzer/test/src/dart/resolution/top_level_variable_test.dart
index 1349f39..444c894 100644
--- a/pkg/analyzer/test/src/dart/resolution/top_level_variable_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/top_level_variable_test.dart
@@ -11,13 +11,32 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(TopLevelVariableTest);
- defineReflectiveTests(TopLevelVariableWithNullSafetyTest);
+ defineReflectiveTests(TopLevelVariableWithoutNullSafetyTest);
});
}
@reflectiveTest
class TopLevelVariableTest extends PubPackageResolutionTest
- with WithoutNullSafetyMixin {
+ with TopLevelVariableTestCases {
+ test_type_inferred_nonNullify() async {
+ newFile('$testPackageLibPath/a.dart', content: r'''
+// @dart = 2.7
+var a = 0;
+''');
+
+ await assertErrorsInCode('''
+import 'a.dart';
+
+var v = a;
+''', [
+ error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 7, 8),
+ ]);
+
+ assertType(findElement.topVar('v').type, 'int');
+ }
+}
+
+mixin TopLevelVariableTestCases on PubPackageResolutionTest {
test_session_getterSetter() async {
await resolveTestCode('''
var v = 0;
@@ -65,22 +84,5 @@
}
@reflectiveTest
-class TopLevelVariableWithNullSafetyTest extends TopLevelVariableTest
- with WithNullSafetyMixin {
- test_type_inferred_nonNullify() async {
- newFile('$testPackageLibPath/a.dart', content: r'''
-// @dart = 2.7
-var a = 0;
-''');
-
- await assertErrorsInCode('''
-import 'a.dart';
-
-var v = a;
-''', [
- error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 7, 8),
- ]);
-
- assertType(findElement.topVar('v').type, 'int');
- }
-}
+class TopLevelVariableWithoutNullSafetyTest extends PubPackageResolutionTest
+ with TopLevelVariableTestCases, WithoutNullSafetyMixin {}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/conditional_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/conditional_expression_test.dart
index 71d74e19..a1531fb 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/conditional_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/conditional_expression_test.dart
@@ -9,27 +9,13 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(ConditionalExpressionTest);
- defineReflectiveTests(ConditionalExpressionWithNullSafetyTest);
+ defineReflectiveTests(ConditionalExpressionWithoutNullSafetyTest);
});
}
@reflectiveTest
class ConditionalExpressionTest extends PubPackageResolutionTest
- with WithoutNullSafetyMixin {
- test_upward() async {
- await resolveTestCode('''
-void f(bool a, int b, int c) {
- var d = a ? b : c;
- print(d);
-}
-''');
- assertType(findNode.simple('d)'), 'int');
- }
-}
-
-@reflectiveTest
-class ConditionalExpressionWithNullSafetyTest extends ConditionalExpressionTest
- with WithNullSafetyMixin {
+ with ConditionalExpressionTestCases {
@failingTest
test_downward() async {
await resolveTestCode('''
@@ -51,3 +37,20 @@
assertType(findNode.conditionalExpression('b ?'), 'int?');
}
}
+
+mixin ConditionalExpressionTestCases on PubPackageResolutionTest {
+ test_upward() async {
+ await resolveTestCode('''
+void f(bool a, int b, int c) {
+ var d = a ? b : c;
+ print(d);
+}
+''');
+ assertType(findNode.simple('d)'), 'int');
+ }
+}
+
+@reflectiveTest
+class ConditionalExpressionWithoutNullSafetyTest
+ extends PubPackageResolutionTest
+ with ConditionalExpressionTestCases, WithoutNullSafetyMixin {}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/function_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/function_expression_test.dart
index bcde92b..11676d2 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/function_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/function_expression_test.dart
@@ -10,13 +10,129 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(FunctionExpressionTest);
- defineReflectiveTests(FunctionExpressionWithNullSafetyTest);
+ defineReflectiveTests(FunctionExpressionWithoutNullSafetyTest);
});
}
@reflectiveTest
class FunctionExpressionTest extends PubPackageResolutionTest
- with WithoutNullSafetyMixin {
+ with FunctionExpressionTestCases {
+ test_contextFunctionType_nonNullify() async {
+ newFile('$testPackageLibPath/a.dart', content: r'''
+// @dart = 2.7
+
+int Function(int a) v;
+''');
+
+ await assertErrorsInCode('''
+import 'a.dart';
+
+T foo<T>() => throw 0;
+
+void f() {
+ v = (a) {
+ return foo();
+ };
+}
+''', [
+ error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 7, 8),
+ ]);
+ assertType(findElement.parameter('a').type, 'int');
+ _assertReturnType('(a) {', 'int');
+ }
+
+ test_contextFunctionType_nonNullify_returnType_takeActual() async {
+ newFile('$testPackageLibPath/a.dart', content: r'''
+// @dart = 2.7
+
+void foo(int Function() x) {}
+''');
+ await assertErrorsInCode('''
+import 'a.dart';
+
+void test(int? a) {
+ foo(() => a);
+}
+''', [
+ error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 7, 8),
+ ]);
+ _assertReturnType('() => a', 'int?');
+ }
+
+ test_contextFunctionType_nonNullify_returnType_takeContext() async {
+ newFile('$testPackageLibPath/a.dart', content: r'''
+// @dart = 2.7
+
+void foo(int Function() x) {}
+''');
+ await assertErrorsInCode('''
+import 'a.dart';
+
+void test(dynamic a) {
+ foo(() => a);
+}
+''', [
+ error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 7, 8),
+ ]);
+ _assertReturnType('() => a', 'int');
+ }
+
+ test_contextFunctionType_returnType_async_blockBody_objectQ() async {
+ await assertNoErrorsInCode('''
+T foo<T>() => throw 0;
+
+Object? Function() v = () async {
+ return foo();
+};
+''');
+ assertTypeArgumentTypes(
+ findNode.methodInvocation('foo();'),
+ ['FutureOr<Object?>'],
+ );
+ _assertReturnType('() async', 'Future<Object?>');
+ }
+
+ test_contextFunctionType_returnType_async_blockBody_objectQ2() async {
+ await assertNoErrorsInCode('''
+T foo<T>() => throw 0;
+
+Object? Function() v = () async {
+ return;
+};
+''');
+ _assertReturnType('() async', 'Future<Null>');
+ }
+
+ test_contextFunctionType_returnType_async_expressionBody_objectQ() async {
+ await assertNoErrorsInCode('''
+T foo<T>() => throw 0;
+
+Object? Function() v = () async => foo();
+''');
+ assertTypeArgumentTypes(
+ findNode.methodInvocation('foo();'),
+ ['FutureOr<Object?>'],
+ );
+ _assertReturnType('() async => foo', 'Future<Object?>');
+ }
+
+ test_optOut_downward_returnType_expressionBody_Null() async {
+ newFile('$testPackageLibPath/a.dart', content: r'''
+void foo(Map<String, String> Function() f) {}
+''');
+ await resolveTestCode('''
+// @dart = 2.5
+import 'a.dart';
+
+void main() {
+ foo(() => null);
+}
+''');
+ _assertReturnType('() =>', 'Null*');
+ }
+}
+
+mixin FunctionExpressionTestCases on PubPackageResolutionTest {
test_contextFunctionType_returnType_async_blockBody_futureOrVoid() async {
var expectedErrors = expectedErrorsByNullability(
nullable: [
@@ -460,119 +576,5 @@
}
@reflectiveTest
-class FunctionExpressionWithNullSafetyTest extends FunctionExpressionTest
- with WithNullSafetyMixin {
- test_contextFunctionType_nonNullify() async {
- newFile('$testPackageLibPath/a.dart', content: r'''
-// @dart = 2.7
-
-int Function(int a) v;
-''');
-
- await assertErrorsInCode('''
-import 'a.dart';
-
-T foo<T>() => throw 0;
-
-void f() {
- v = (a) {
- return foo();
- };
-}
-''', [
- error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 7, 8),
- ]);
- assertType(findElement.parameter('a').type, 'int');
- _assertReturnType('(a) {', 'int');
- }
-
- test_contextFunctionType_nonNullify_returnType_takeActual() async {
- newFile('$testPackageLibPath/a.dart', content: r'''
-// @dart = 2.7
-
-void foo(int Function() x) {}
-''');
- await assertErrorsInCode('''
-import 'a.dart';
-
-void test(int? a) {
- foo(() => a);
-}
-''', [
- error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 7, 8),
- ]);
- _assertReturnType('() => a', 'int?');
- }
-
- test_contextFunctionType_nonNullify_returnType_takeContext() async {
- newFile('$testPackageLibPath/a.dart', content: r'''
-// @dart = 2.7
-
-void foo(int Function() x) {}
-''');
- await assertErrorsInCode('''
-import 'a.dart';
-
-void test(dynamic a) {
- foo(() => a);
-}
-''', [
- error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 7, 8),
- ]);
- _assertReturnType('() => a', 'int');
- }
-
- test_contextFunctionType_returnType_async_blockBody_objectQ() async {
- await assertNoErrorsInCode('''
-T foo<T>() => throw 0;
-
-Object? Function() v = () async {
- return foo();
-};
-''');
- assertTypeArgumentTypes(
- findNode.methodInvocation('foo();'),
- ['FutureOr<Object?>'],
- );
- _assertReturnType('() async', 'Future<Object?>');
- }
-
- test_contextFunctionType_returnType_async_blockBody_objectQ2() async {
- await assertNoErrorsInCode('''
-T foo<T>() => throw 0;
-
-Object? Function() v = () async {
- return;
-};
-''');
- _assertReturnType('() async', 'Future<Null>');
- }
-
- test_contextFunctionType_returnType_async_expressionBody_objectQ() async {
- await assertNoErrorsInCode('''
-T foo<T>() => throw 0;
-
-Object? Function() v = () async => foo();
-''');
- assertTypeArgumentTypes(
- findNode.methodInvocation('foo();'),
- ['FutureOr<Object?>'],
- );
- _assertReturnType('() async => foo', 'Future<Object?>');
- }
-
- test_optOut_downward_returnType_expressionBody_Null() async {
- newFile('$testPackageLibPath/a.dart', content: r'''
-void foo(Map<String, String> Function() f) {}
-''');
- await resolveTestCode('''
-// @dart = 2.5
-import 'a.dart';
-
-void main() {
- foo(() => null);
-}
-''');
- _assertReturnType('() =>', 'Null*');
- }
-}
+class FunctionExpressionWithoutNullSafetyTest extends PubPackageResolutionTest
+ with FunctionExpressionTestCases, WithoutNullSafetyMixin {}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart
index 80aeb15..39f7df5 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart
@@ -10,13 +10,98 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(ListLiteralTest);
- defineReflectiveTests(ListLiteralWithNullSafetyTest);
+ defineReflectiveTests(ListLiteralWithoutNullSafetyTest);
});
}
@reflectiveTest
class ListLiteralTest extends PubPackageResolutionTest
- with WithoutNullSafetyMixin {
+ with ListLiteralTestCases {
+ test_context_spread_nullAware() async {
+ await assertNoErrorsInCode('''
+T f<T>(T t) => t;
+
+main() {
+ <int>[...?f(null)];
+}
+''');
+
+ assertMethodInvocation2(
+ findNode.methodInvocation('f(null)'),
+ element: findElement.topFunction('f'),
+ typeArgumentTypes: ['Iterable<int>?'],
+ invokeType: 'Iterable<int>? Function(Iterable<int>?)',
+ type: 'Iterable<int>?',
+ );
+ }
+
+ test_nested_hasNull_1() async {
+ await assertNoErrorsInCode('''
+main() {
+ [[0], null];
+}
+''');
+ assertType(findNode.listLiteral('[0'), 'List<int>');
+ assertType(findNode.listLiteral('[[0'), 'List<List<int>?>');
+ }
+
+ test_nested_hasNull_2() async {
+ await assertNoErrorsInCode('''
+main() {
+ [[0], [1, null]];
+}
+''');
+ assertType(findNode.listLiteral('[0'), 'List<int>');
+ assertType(findNode.listLiteral('[1,'), 'List<int?>');
+ assertType(findNode.listLiteral('[[0'), 'List<List<int?>>');
+ }
+
+ test_noContext_noTypeArgs_spread_never() async {
+ await assertNoErrorsInCode('''
+void f(Never a) async {
+ // ignore:unused_local_variable
+ var v = [...a];
+}
+''');
+ assertType(findNode.listLiteral('['), 'List<Never>');
+ }
+
+ test_noContext_noTypeArgs_spread_nullAware_never() async {
+ await assertErrorsInCode('''
+void f(Never a) async {
+ // ignore:unused_local_variable
+ var v = [...?a];
+}
+''', [
+ error(StaticWarningCode.INVALID_NULL_AWARE_OPERATOR, 69, 4),
+ ]);
+ assertType(findNode.listLiteral('['), 'List<Never>');
+ }
+
+ test_noContext_noTypeArgs_spread_nullAware_typeParameter_implementsNever() async {
+ await assertErrorsInCode('''
+void f<T extends Never>(T a) async {
+ // ignore:unused_local_variable
+ var v = [...?a];
+}
+''', [
+ error(StaticWarningCode.INVALID_NULL_AWARE_OPERATOR, 82, 4),
+ ]);
+ assertType(findNode.listLiteral('['), 'List<Never>');
+ }
+
+ test_noContext_noTypeArgs_spread_typeParameter_implementsNever() async {
+ await assertNoErrorsInCode('''
+void f<T extends Never>(T a) async {
+ // ignore:unused_local_variable
+ var v = [...a];
+}
+''');
+ assertType(findNode.listLiteral('['), 'List<Never>');
+ }
+}
+
+mixin ListLiteralTestCases on PubPackageResolutionTest {
test_context_noTypeArgs_expression_conflict() async {
await assertErrorsInCode('''
List<int> a = ['a'];
@@ -415,88 +500,5 @@
}
@reflectiveTest
-class ListLiteralWithNullSafetyTest extends ListLiteralTest
- with WithNullSafetyMixin {
- test_context_spread_nullAware() async {
- await assertNoErrorsInCode('''
-T f<T>(T t) => t;
-
-main() {
- <int>[...?f(null)];
-}
-''');
-
- assertMethodInvocation2(
- findNode.methodInvocation('f(null)'),
- element: findElement.topFunction('f'),
- typeArgumentTypes: ['Iterable<int>?'],
- invokeType: 'Iterable<int>? Function(Iterable<int>?)',
- type: 'Iterable<int>?',
- );
- }
-
- test_nested_hasNull_1() async {
- await assertNoErrorsInCode('''
-main() {
- [[0], null];
-}
-''');
- assertType(findNode.listLiteral('[0'), 'List<int>');
- assertType(findNode.listLiteral('[[0'), 'List<List<int>?>');
- }
-
- test_nested_hasNull_2() async {
- await assertNoErrorsInCode('''
-main() {
- [[0], [1, null]];
-}
-''');
- assertType(findNode.listLiteral('[0'), 'List<int>');
- assertType(findNode.listLiteral('[1,'), 'List<int?>');
- assertType(findNode.listLiteral('[[0'), 'List<List<int?>>');
- }
-
- test_noContext_noTypeArgs_spread_never() async {
- await assertNoErrorsInCode('''
-void f(Never a) async {
- // ignore:unused_local_variable
- var v = [...a];
-}
-''');
- assertType(findNode.listLiteral('['), 'List<Never>');
- }
-
- test_noContext_noTypeArgs_spread_nullAware_never() async {
- await assertErrorsInCode('''
-void f(Never a) async {
- // ignore:unused_local_variable
- var v = [...?a];
-}
-''', [
- error(StaticWarningCode.INVALID_NULL_AWARE_OPERATOR, 69, 4),
- ]);
- assertType(findNode.listLiteral('['), 'List<Never>');
- }
-
- test_noContext_noTypeArgs_spread_nullAware_typeParameter_implementsNever() async {
- await assertErrorsInCode('''
-void f<T extends Never>(T a) async {
- // ignore:unused_local_variable
- var v = [...?a];
-}
-''', [
- error(StaticWarningCode.INVALID_NULL_AWARE_OPERATOR, 82, 4),
- ]);
- assertType(findNode.listLiteral('['), 'List<Never>');
- }
-
- test_noContext_noTypeArgs_spread_typeParameter_implementsNever() async {
- await assertNoErrorsInCode('''
-void f<T extends Never>(T a) async {
- // ignore:unused_local_variable
- var v = [...a];
-}
-''');
- assertType(findNode.listLiteral('['), 'List<Never>');
- }
-}
+class ListLiteralWithoutNullSafetyTest extends PubPackageResolutionTest
+ with ListLiteralTestCases, WithoutNullSafetyMixin {}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/map_literal_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/map_literal_test.dart
index e4af4f6..894f8a9 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/map_literal_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/map_literal_test.dart
@@ -11,13 +11,121 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(MapLiteralTest);
- defineReflectiveTests(MapLiteralWithNullSafetyTest);
+ defineReflectiveTests(MapLiteralWithoutNullSafetyTest);
});
}
@reflectiveTest
-class MapLiteralTest extends PubPackageResolutionTest
- with WithoutNullSafetyMixin {
+class MapLiteralTest extends PubPackageResolutionTest with MapLiteralTestCases {
+ test_context_noTypeArgs_noEntries_typeParameterNullable() async {
+ await assertNoErrorsInCode('''
+class C<T extends Object?> {
+ Map<String, T> a = {}; // 1
+ Map<String, T>? b = {}; // 2
+ Map<String, T?> c = {}; // 3
+ Map<String, T?>? d = {}; // 4
+}
+''');
+ assertType(setOrMapLiteral('{}; // 1'), 'Map<String, T>');
+ assertType(setOrMapLiteral('{}; // 2'), 'Map<String, T>');
+ assertType(setOrMapLiteral('{}; // 3'), 'Map<String, T?>');
+ assertType(setOrMapLiteral('{}; // 4'), 'Map<String, T?>');
+ }
+
+ test_context_spread_nullAware() async {
+ await assertNoErrorsInCode('''
+T f<T>(T t) => t;
+
+main() {
+ <int, double>{...?f(null)};
+}
+''');
+
+ assertMethodInvocation2(
+ findNode.methodInvocation('f(null)'),
+ element: findElement.topFunction('f'),
+ typeArgumentTypes: ['Map<int, double>?'],
+ invokeType: 'Map<int, double>? Function(Map<int, double>?)',
+ type: 'Map<int, double>?',
+ );
+ }
+
+ test_noContext_noTypeArgs_spread_never() async {
+ await assertErrorsInCode('''
+void f(Never a, bool b) async {
+ // ignore:unused_local_variable
+ var v = {...a, if (b) throw 0: throw 0};
+}
+''', [
+ error(HintCode.DEAD_CODE, 87, 21),
+ ]);
+ assertType(setOrMapLiteral('{...'), 'Map<Never, Never>');
+ }
+
+ test_noContext_noTypeArgs_spread_nullAware_never() async {
+ await assertErrorsInCode('''
+void f(Never a, bool b) async {
+ // ignore:unused_local_variable
+ var v = {...?a, if (b) throw 0: throw 0};
+}
+''', [
+ error(StaticWarningCode.INVALID_NULL_AWARE_OPERATOR, 77, 4),
+ error(HintCode.DEAD_CODE, 88, 21),
+ ]);
+ assertType(setOrMapLiteral('{...'), 'Map<Never, Never>');
+ }
+
+ test_noContext_noTypeArgs_spread_nullAware_null() async {
+ await assertErrorsInCode('''
+void f(Null a, bool b) async {
+ // ignore:unused_local_variable
+ var v = {...?a, if (b) throw 0: throw 0};
+}
+''', [
+ error(HintCode.DEAD_CODE, 99, 9),
+ ]);
+ assertType(setOrMapLiteral('{...'), 'Map<Never, Never>');
+ }
+
+ test_noContext_noTypeArgs_spread_nullAware_typeParameter_never() async {
+ await assertErrorsInCode('''
+void f<T extends Never>(T a, bool b) async {
+ // ignore:unused_local_variable
+ var v = {...?a, if (b) throw 0: throw 0};
+}
+''', [
+ error(StaticWarningCode.INVALID_NULL_AWARE_OPERATOR, 90, 4),
+ error(HintCode.DEAD_CODE, 101, 21),
+ ]);
+ assertType(setOrMapLiteral('{...'), 'Map<Never, Never>');
+ }
+
+ test_noContext_noTypeArgs_spread_nullAware_typeParameter_null() async {
+ await assertErrorsInCode('''
+void f<T extends Null>(T a, bool b) async {
+ // ignore:unused_local_variable
+ var v = {...?a, if (b) throw 0: throw 0};
+}
+''', [
+ error(HintCode.DEAD_CODE, 112, 9),
+ ]);
+ assertType(setOrMapLiteral('{...'), 'Map<Never, Never>');
+ }
+
+ test_noContext_noTypeArgs_spread_typeParameter_never() async {
+ await assertErrorsInCode('''
+void f<T extends Never>(T a, bool b) async {
+ // ignore:unused_local_variable
+ var v = {...a, if (b) throw 0: throw 0};
+}
+''', [
+ error(HintCode.DEAD_CODE, 100, 21),
+ ]);
+ assertType(setOrMapLiteral('{...'), 'Map<Never, Never>');
+ }
+}
+
+mixin MapLiteralTestCases on PubPackageResolutionTest {
AstNode setOrMapLiteral(String search) => findNode.setOrMapLiteral(search);
test_context_noTypeArgs_entry_conflictingKey() async {
@@ -439,112 +547,5 @@
}
@reflectiveTest
-class MapLiteralWithNullSafetyTest extends MapLiteralTest
- with WithNullSafetyMixin {
- test_context_noTypeArgs_noEntries_typeParameterNullable() async {
- await assertNoErrorsInCode('''
-class C<T extends Object?> {
- Map<String, T> a = {}; // 1
- Map<String, T>? b = {}; // 2
- Map<String, T?> c = {}; // 3
- Map<String, T?>? d = {}; // 4
-}
-''');
- assertType(setOrMapLiteral('{}; // 1'), 'Map<String, T>');
- assertType(setOrMapLiteral('{}; // 2'), 'Map<String, T>');
- assertType(setOrMapLiteral('{}; // 3'), 'Map<String, T?>');
- assertType(setOrMapLiteral('{}; // 4'), 'Map<String, T?>');
- }
-
- test_context_spread_nullAware() async {
- await assertNoErrorsInCode('''
-T f<T>(T t) => t;
-
-main() {
- <int, double>{...?f(null)};
-}
-''');
-
- assertMethodInvocation2(
- findNode.methodInvocation('f(null)'),
- element: findElement.topFunction('f'),
- typeArgumentTypes: ['Map<int, double>?'],
- invokeType: 'Map<int, double>? Function(Map<int, double>?)',
- type: 'Map<int, double>?',
- );
- }
-
- test_noContext_noTypeArgs_spread_never() async {
- await assertErrorsInCode('''
-void f(Never a, bool b) async {
- // ignore:unused_local_variable
- var v = {...a, if (b) throw 0: throw 0};
-}
-''', [
- error(HintCode.DEAD_CODE, 87, 21),
- ]);
- assertType(setOrMapLiteral('{...'), 'Map<Never, Never>');
- }
-
- test_noContext_noTypeArgs_spread_nullAware_never() async {
- await assertErrorsInCode('''
-void f(Never a, bool b) async {
- // ignore:unused_local_variable
- var v = {...?a, if (b) throw 0: throw 0};
-}
-''', [
- error(StaticWarningCode.INVALID_NULL_AWARE_OPERATOR, 77, 4),
- error(HintCode.DEAD_CODE, 88, 21),
- ]);
- assertType(setOrMapLiteral('{...'), 'Map<Never, Never>');
- }
-
- test_noContext_noTypeArgs_spread_nullAware_null() async {
- await assertErrorsInCode('''
-void f(Null a, bool b) async {
- // ignore:unused_local_variable
- var v = {...?a, if (b) throw 0: throw 0};
-}
-''', [
- error(HintCode.DEAD_CODE, 99, 9),
- ]);
- assertType(setOrMapLiteral('{...'), 'Map<Never, Never>');
- }
-
- test_noContext_noTypeArgs_spread_nullAware_typeParameter_never() async {
- await assertErrorsInCode('''
-void f<T extends Never>(T a, bool b) async {
- // ignore:unused_local_variable
- var v = {...?a, if (b) throw 0: throw 0};
-}
-''', [
- error(StaticWarningCode.INVALID_NULL_AWARE_OPERATOR, 90, 4),
- error(HintCode.DEAD_CODE, 101, 21),
- ]);
- assertType(setOrMapLiteral('{...'), 'Map<Never, Never>');
- }
-
- test_noContext_noTypeArgs_spread_nullAware_typeParameter_null() async {
- await assertErrorsInCode('''
-void f<T extends Null>(T a, bool b) async {
- // ignore:unused_local_variable
- var v = {...?a, if (b) throw 0: throw 0};
-}
-''', [
- error(HintCode.DEAD_CODE, 112, 9),
- ]);
- assertType(setOrMapLiteral('{...'), 'Map<Never, Never>');
- }
-
- test_noContext_noTypeArgs_spread_typeParameter_never() async {
- await assertErrorsInCode('''
-void f<T extends Never>(T a, bool b) async {
- // ignore:unused_local_variable
- var v = {...a, if (b) throw 0: throw 0};
-}
-''', [
- error(HintCode.DEAD_CODE, 100, 21),
- ]);
- assertType(setOrMapLiteral('{...'), 'Map<Never, Never>');
- }
-}
+class MapLiteralWithoutNullSafetyTest extends PubPackageResolutionTest
+ with MapLiteralTestCases, WithoutNullSafetyMixin {}
diff --git a/pkg/analyzer/test/src/diagnostics/abstract_class_member_test.dart b/pkg/analyzer/test/src/diagnostics/abstract_class_member_test.dart
index cba3c60..7879c8c 100644
--- a/pkg/analyzer/test/src/diagnostics/abstract_class_member_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/abstract_class_member_test.dart
@@ -10,13 +10,15 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(AbstractClassMemberTest);
- defineReflectiveTests(AbstractClassMemberWithNullSafetyTest);
+ defineReflectiveTests(AbstractClassMemberWithoutNullSafetyTest);
});
}
@reflectiveTest
class AbstractClassMemberTest extends PubPackageResolutionTest
- with WithoutNullSafetyMixin {
+ with AbstractClassMemberTestCases {}
+
+mixin AbstractClassMemberTestCases on PubPackageResolutionTest {
test_abstract_field_dynamic() async {
await assertErrorsInCode(
'''
@@ -55,5 +57,5 @@
}
@reflectiveTest
-class AbstractClassMemberWithNullSafetyTest extends AbstractClassMemberTest
- with WithNullSafetyMixin {}
+class AbstractClassMemberWithoutNullSafetyTest extends PubPackageResolutionTest
+ with AbstractClassMemberTestCases, WithoutNullSafetyMixin {}
diff --git a/pkg/analyzer/test/src/diagnostics/assignment_to_final_test.dart b/pkg/analyzer/test/src/diagnostics/assignment_to_final_test.dart
index d45f72d..1ef0c33 100644
--- a/pkg/analyzer/test/src/diagnostics/assignment_to_final_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/assignment_to_final_test.dart
@@ -10,119 +10,13 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(AssignmentToFinalTest);
- defineReflectiveTests(AssignmentToFinalWithNullSafetyTest);
+ defineReflectiveTests(AssignmentToFinalWithoutNullSafetyTest);
});
}
@reflectiveTest
class AssignmentToFinalTest extends PubPackageResolutionTest
- with WithoutNullSafetyMixin {
- test_prefixedIdentifier_instanceField() async {
- await assertNoErrorsInCode('''
-class A {
- var x = 0;
-}
-
-void f(A a) {
- a.x = 0;
- a.x += 0;
- ++a.x;
- a.x++;
-}
-''');
- }
-
- test_prefixedIdentifier_instanceField_final() async {
- await assertErrorsInCode('''
-class A {
- final x = 0;
-}
-
-void f(A a) {
- a.x = 0;
- a.x += 0;
- ++a.x;
- a.x++;
-}
-''', [
- error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 46, 1),
- error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 57, 1),
- error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 71, 1),
- error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 78, 1),
- ]);
- }
-
- test_simpleIdentifier_inheritedSetter_shadowedBy_topLevelGetter() async {
- await assertErrorsInCode('''
-class A {
- void set foo(int _) {}
-}
-
-int get foo => 0;
-
-class B extends A {
- void bar() {
- foo = 0;
- }
-}
-''', [
- error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 96, 3),
- ]);
- }
-
- test_simpleIdentifier_topLevelGetter() async {
- await assertErrorsInCode('''
-int get x => 0;
-
-void f() {
- x = 0;
- x += 0;
- ++x;
- x++;
-}
-''', [
- error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 30, 1),
- error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 39, 1),
- error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 51, 1),
- error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 56, 1),
- ]);
- }
-
- test_simpleIdentifier_topLevelVariable() async {
- await assertNoErrorsInCode('''
-var x = 0;
-
-void f() {
- x = 0;
- x += 0;
- ++x;
- x++;
-}
-''');
- }
-
- test_simpleIdentifier_topLevelVariable_final() async {
- await assertErrorsInCode('''
-final x = 0;
-
-void f() {
- x = 0;
- x += 0;
- ++x;
- x++;
-}
-''', [
- error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 27, 1),
- error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 36, 1),
- error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 48, 1),
- error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 53, 1),
- ]);
- }
-}
-
-@reflectiveTest
-class AssignmentToFinalWithNullSafetyTest extends AssignmentToFinalTest
- with WithNullSafetyMixin {
+ with AssignmentToFinalTestCases {
test_prefixedIdentifier_instanceField_abstract() async {
await assertNoErrorsInCode('''
abstract class A {
@@ -450,3 +344,111 @@
]);
}
}
+
+mixin AssignmentToFinalTestCases on PubPackageResolutionTest {
+ test_prefixedIdentifier_instanceField() async {
+ await assertNoErrorsInCode('''
+class A {
+ var x = 0;
+}
+
+void f(A a) {
+ a.x = 0;
+ a.x += 0;
+ ++a.x;
+ a.x++;
+}
+''');
+ }
+
+ test_prefixedIdentifier_instanceField_final() async {
+ await assertErrorsInCode('''
+class A {
+ final x = 0;
+}
+
+void f(A a) {
+ a.x = 0;
+ a.x += 0;
+ ++a.x;
+ a.x++;
+}
+''', [
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 46, 1),
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 57, 1),
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 71, 1),
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 78, 1),
+ ]);
+ }
+
+ test_simpleIdentifier_inheritedSetter_shadowedBy_topLevelGetter() async {
+ await assertErrorsInCode('''
+class A {
+ void set foo(int _) {}
+}
+
+int get foo => 0;
+
+class B extends A {
+ void bar() {
+ foo = 0;
+ }
+}
+''', [
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 96, 3),
+ ]);
+ }
+
+ test_simpleIdentifier_topLevelGetter() async {
+ await assertErrorsInCode('''
+int get x => 0;
+
+void f() {
+ x = 0;
+ x += 0;
+ ++x;
+ x++;
+}
+''', [
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 30, 1),
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 39, 1),
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 51, 1),
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 56, 1),
+ ]);
+ }
+
+ test_simpleIdentifier_topLevelVariable() async {
+ await assertNoErrorsInCode('''
+var x = 0;
+
+void f() {
+ x = 0;
+ x += 0;
+ ++x;
+ x++;
+}
+''');
+ }
+
+ test_simpleIdentifier_topLevelVariable_final() async {
+ await assertErrorsInCode('''
+final x = 0;
+
+void f() {
+ x = 0;
+ x += 0;
+ ++x;
+ x++;
+}
+''', [
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 27, 1),
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 36, 1),
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 48, 1),
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 53, 1),
+ ]);
+ }
+}
+
+@reflectiveTest
+class AssignmentToFinalWithoutNullSafetyTest extends PubPackageResolutionTest
+ with AssignmentToFinalTestCases, WithoutNullSafetyMixin {}
diff --git a/pkg/analyzer/test/src/diagnostics/dead_code_test.dart b/pkg/analyzer/test/src/diagnostics/dead_code_test.dart
index 1fc2927..92f1995 100644
--- a/pkg/analyzer/test/src/diagnostics/dead_code_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/dead_code_test.dart
@@ -10,13 +10,139 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(DeadCodeTest);
- defineReflectiveTests(DeadCodeWithNullSafetyTest);
+ defineReflectiveTests(DeadCodeWithoutNullSafetyTest);
});
}
@reflectiveTest
-class DeadCodeTest extends PubPackageResolutionTest
- with WithoutNullSafetyMixin {
+class DeadCodeTest extends PubPackageResolutionTest with DeadCodeTestCases {
+ test_assert_dead_message() async {
+ // We don't warn if an assert statement is live but its message is dead,
+ // because this results in nuisance warnings for desirable assertions (e.g.
+ // a `!= null` assertion that is redundant with strong checking but still
+ // useful with weak checking).
+ await assertErrorsInCode('''
+void f(Object waldo) {
+ assert(waldo != null, "Where's Waldo?");
+}
+''', [
+ error(HintCode.UNNECESSARY_NULL_COMPARISON_TRUE, 38, 7),
+ ]);
+ }
+
+ test_flowEnd_tryStatement_body() async {
+ await assertErrorsInCode(r'''
+Never foo() => throw 0;
+
+main() {
+ try {
+ foo();
+ 1;
+ } catch (_) {
+ 2;
+ }
+ 3;
+}
+''', [
+ error(HintCode.DEAD_CODE, 57, 2),
+ ]);
+ }
+
+ test_invokeNever_functionExpressionInvocation_getter_propertyAccess() async {
+ await assertErrorsInCode(r'''
+class A {
+ Never get f => throw 0;
+}
+void g(A a) {
+ a.f(0);
+ print(1);
+}
+''', [
+ error(HintCode.RECEIVER_OF_TYPE_NEVER, 54, 3),
+ error(HintCode.DEAD_CODE, 57, 16),
+ ]);
+ }
+
+ test_invokeNever_functionExpressionInvocation_parenthesizedExpression() async {
+ await assertErrorsInCode(r'''
+void g(Never f) {
+ (f)(0);
+ print(1);
+}
+''', [
+ error(HintCode.RECEIVER_OF_TYPE_NEVER, 20, 3),
+ error(HintCode.DEAD_CODE, 23, 16),
+ ]);
+ }
+
+ test_invokeNever_functionExpressionInvocation_simpleIdentifier() async {
+ await assertErrorsInCode(r'''
+void g(Never f) {
+ f(0);
+ print(1);
+}
+''', [
+ error(HintCode.RECEIVER_OF_TYPE_NEVER, 20, 1),
+ error(HintCode.DEAD_CODE, 21, 16),
+ ]);
+ }
+
+ test_returnTypeNever_function() async {
+ await assertErrorsInCode(r'''
+Never foo() => throw 0;
+
+main() {
+ foo();
+ 1;
+}
+''', [
+ error(HintCode.DEAD_CODE, 45, 2),
+ ]);
+ }
+
+ test_returnTypeNever_getter() async {
+ await assertErrorsInCode(r'''
+Never get foo => throw 0;
+
+main() {
+ foo;
+ 2;
+}
+''', [
+ error(HintCode.DEAD_CODE, 45, 2),
+ ]);
+ }
+
+ @FailingTest(reason: '@alwaysThrows is not supported in flow analysis')
+ @override
+ test_statementAfterAlwaysThrowsFunction() async {
+ return super.test_statementAfterAlwaysThrowsFunction();
+ }
+
+ @FailingTest(reason: '@alwaysThrows is not supported in flow analysis')
+ @override
+ test_statementAfterAlwaysThrowsMethod() async {
+ return super.test_statementAfterAlwaysThrowsMethod();
+ }
+
+ test_switchStatement_exhaustive() async {
+ await assertErrorsInCode(r'''
+enum Foo { a, b }
+
+int f(Foo foo) {
+ switch (foo) {
+ case Foo.a: return 0;
+ case Foo.b: return 1;
+ }
+ return -1;
+}
+''', [
+ error(HintCode.DEAD_CODE, 111, 10),
+ ]);
+ }
+}
+
+mixin DeadCodeTestCases on PubPackageResolutionTest {
@override
void setUp() {
super.setUp();
@@ -846,129 +972,5 @@
}
@reflectiveTest
-class DeadCodeWithNullSafetyTest extends DeadCodeTest with WithNullSafetyMixin {
- test_assert_dead_message() async {
- // We don't warn if an assert statement is live but its message is dead,
- // because this results in nuisance warnings for desirable assertions (e.g.
- // a `!= null` assertion that is redundant with strong checking but still
- // useful with weak checking).
- await assertErrorsInCode('''
-void f(Object waldo) {
- assert(waldo != null, "Where's Waldo?");
-}
-''', [
- error(HintCode.UNNECESSARY_NULL_COMPARISON_TRUE, 38, 7),
- ]);
- }
-
- test_flowEnd_tryStatement_body() async {
- await assertErrorsInCode(r'''
-Never foo() => throw 0;
-
-main() {
- try {
- foo();
- 1;
- } catch (_) {
- 2;
- }
- 3;
-}
-''', [
- error(HintCode.DEAD_CODE, 57, 2),
- ]);
- }
-
- test_invokeNever_functionExpressionInvocation_getter_propertyAccess() async {
- await assertErrorsInCode(r'''
-class A {
- Never get f => throw 0;
-}
-void g(A a) {
- a.f(0);
- print(1);
-}
-''', [
- error(HintCode.RECEIVER_OF_TYPE_NEVER, 54, 3),
- error(HintCode.DEAD_CODE, 57, 16),
- ]);
- }
-
- test_invokeNever_functionExpressionInvocation_parenthesizedExpression() async {
- await assertErrorsInCode(r'''
-void g(Never f) {
- (f)(0);
- print(1);
-}
-''', [
- error(HintCode.RECEIVER_OF_TYPE_NEVER, 20, 3),
- error(HintCode.DEAD_CODE, 23, 16),
- ]);
- }
-
- test_invokeNever_functionExpressionInvocation_simpleIdentifier() async {
- await assertErrorsInCode(r'''
-void g(Never f) {
- f(0);
- print(1);
-}
-''', [
- error(HintCode.RECEIVER_OF_TYPE_NEVER, 20, 1),
- error(HintCode.DEAD_CODE, 21, 16),
- ]);
- }
-
- test_returnTypeNever_function() async {
- await assertErrorsInCode(r'''
-Never foo() => throw 0;
-
-main() {
- foo();
- 1;
-}
-''', [
- error(HintCode.DEAD_CODE, 45, 2),
- ]);
- }
-
- test_returnTypeNever_getter() async {
- await assertErrorsInCode(r'''
-Never get foo => throw 0;
-
-main() {
- foo;
- 2;
-}
-''', [
- error(HintCode.DEAD_CODE, 45, 2),
- ]);
- }
-
- @FailingTest(reason: '@alwaysThrows is not supported in flow analysis')
- @override
- test_statementAfterAlwaysThrowsFunction() async {
- return super.test_statementAfterAlwaysThrowsFunction();
- }
-
- @FailingTest(reason: '@alwaysThrows is not supported in flow analysis')
- @override
- test_statementAfterAlwaysThrowsMethod() async {
- return super.test_statementAfterAlwaysThrowsMethod();
- }
-
- test_switchStatement_exhaustive() async {
- await assertErrorsInCode(r'''
-enum Foo { a, b }
-
-int f(Foo foo) {
- switch (foo) {
- case Foo.a: return 0;
- case Foo.b: return 1;
- }
- return -1;
-}
-''', [
- error(HintCode.DEAD_CODE, 111, 10),
- ]);
- }
-}
+class DeadCodeWithoutNullSafetyTest extends PubPackageResolutionTest
+ with DeadCodeTestCases, WithoutNullSafetyMixin {}
diff --git a/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart b/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
index 12614bb..a6d071f 100644
--- a/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
+++ b/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
@@ -42,7 +42,7 @@
/// Notice that the component has to include the platform, and that no other
/// platform will be loaded.
factory IncrementalKernelGenerator.fromComponent(
- CompilerOptions options, Uri entryPoint, Component component,
+ CompilerOptions options, Uri entryPoint, Component? component,
[bool? outlineOnly, IncrementalSerializer? incrementalSerializer]) {
return new IncrementalCompiler.fromComponent(
new CompilerContext(
@@ -72,7 +72,7 @@
/// Returns a component whose libraries are the recompiled libraries,
/// or - in the case of [fullComponent] - a full Component.
- Future<Component> computeDelta({List<Uri> entryPoints, bool fullComponent});
+ Future<Component> computeDelta({List<Uri>? entryPoints, bool fullComponent});
/// Returns [CoreTypes] used during compilation.
/// Valid after [computeDelta] is called.
@@ -136,7 +136,7 @@
List<TypeParameter> typeDefinitions,
String syntheticProcedureName,
Uri libraryUri,
- [String className,
+ [String? className,
bool isStatic = false]);
/// Sets experimental features.
diff --git a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
index 46566f1..8cf810b 100644
--- a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
+++ b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
@@ -58,7 +58,7 @@
/// Re-uses cached components from [oldState.workerInputCache], and reloads them
/// as necessary based on [workerInputDigests].
Future<InitializedCompilerState> initializeIncrementalCompiler(
- InitializedCompilerState oldState,
+ InitializedCompilerState? oldState,
Set<String> tags,
Uri sdkSummary,
Uri packagesFile,
@@ -99,7 +99,7 @@
}
Future<InitializedCompilerState> initializeCompiler(
- InitializedCompilerState oldState,
+ InitializedCompilerState? oldState,
Uri sdkSummary,
Uri librariesSpecificationUri,
Uri packagesFile,
diff --git a/pkg/vm/lib/incremental_compiler.dart b/pkg/vm/lib/incremental_compiler.dart
index 5179a44..a8d3271 100644
--- a/pkg/vm/lib/incremental_compiler.dart
+++ b/pkg/vm/lib/incremental_compiler.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
/// Defines wrapper class around incremental compiler to support
/// the flow, where incremental deltas can be rejected by VM.
import 'dart:async';
@@ -20,23 +18,23 @@
/// deltas and combines them together into resultant program until it is
/// accepted.
class IncrementalCompiler {
- IncrementalKernelGenerator _generator;
- IncrementalSerializer incrementalSerializer;
+ late IncrementalKernelGenerator _generator;
+ IncrementalSerializer? incrementalSerializer;
// Component that reflect the state that was most recently accepted by the
// client. Is [null], if no compilation results were accepted by the client.
- Component _lastKnownGood;
- List<Component> _pendingDeltas;
+ Component? _lastKnownGood;
+ late List<Component> _pendingDeltas;
CompilerOptions _compilerOptions;
bool initialized = false;
bool fullComponent = false;
- Uri initializeFromDillUri;
+ Uri? initializeFromDillUri;
Uri _entryPoint;
final bool forExpressionCompilationOnly;
Uri get entryPoint => _entryPoint;
IncrementalKernelGenerator get generator => _generator;
- Component get lastKnownGoodComponent => _lastKnownGood;
+ Component? get lastKnownGoodComponent => _lastKnownGood;
IncrementalCompiler(this._compilerOptions, this._entryPoint,
{this.initializeFromDillUri, bool incrementalSerialization: true})
@@ -61,12 +59,12 @@
///
/// If [entryPoint] is specified, that points to new entry point for the
/// compilation. Otherwise, previously set entryPoint is used.
- Future<Component> compile({Uri entryPoint}) async {
+ Future<Component> compile({Uri? entryPoint}) async {
final task = new TimelineTask();
try {
task.start("IncrementalCompiler.compile");
_entryPoint = entryPoint ?? _entryPoint;
- List<Uri> entryPoints;
+ List<Uri>? entryPoints;
if (entryPoint != null) entryPoints = [entryPoint];
Component component = await _generator.computeDelta(
entryPoints: entryPoints, fullComponent: fullComponent);
@@ -80,8 +78,9 @@
}
_combinePendingDeltas(bool includePlatform) {
- Procedure mainMethod;
- NonNullableByDefaultCompiledMode compilationMode;
+ Procedure? mainMethod;
+ NonNullableByDefaultCompiledMode compilationMode =
+ NonNullableByDefaultCompiledMode.Invalid;
Map<Uri, Library> combined = <Uri, Library>{};
Map<Uri, Source> uriToSource = new Map<Uri, Source>();
for (Component delta in _pendingDeltas) {
@@ -104,8 +103,8 @@
..setMainMethodAndMode(mainMethod?.reference, true, compilationMode);
}
- CoreTypes getCoreTypes() => _generator.getCoreTypes();
- ClassHierarchy getClassHierarchy() => _generator.getClassHierarchy();
+ CoreTypes? getCoreTypes() => _generator.getCoreTypes();
+ ClassHierarchy? getClassHierarchy() => _generator.getClassHierarchy();
/// This lets incremental compiler know that results of last [compile] call
/// were accepted, don't need to be included into subsequent [compile] calls
@@ -118,13 +117,14 @@
Map<Uri, Library> combined = <Uri, Library>{};
Map<Uri, Source> uriToSource = <Uri, Source>{};
- if (_lastKnownGood != null) {
+ Component? lastKnownGood = _lastKnownGood;
+ if (lastKnownGood != null) {
// TODO(aam): Figure out how to skip no-longer-used libraries from
// [_lastKnownGood] libraries.
- for (Library library in _lastKnownGood.libraries) {
+ for (Library library in lastKnownGood.libraries) {
combined[library.importUri] = library;
}
- uriToSource.addAll(_lastKnownGood.uriToSource);
+ uriToSource.addAll(lastKnownGood.uriToSource);
}
Component candidate = _combinePendingDeltas(true);
@@ -133,13 +133,13 @@
}
uriToSource.addAll(candidate.uriToSource);
- _lastKnownGood = new Component(
+ _lastKnownGood = lastKnownGood = new Component(
libraries: combined.values.toList(),
uriToSource: uriToSource,
)..setMainMethodAndMode(
candidate.mainMethod?.reference, true, candidate.mode);
for (final repo in candidate.metadata.values) {
- _lastKnownGood.addMetadataRepository(repo);
+ lastKnownGood.addMetadataRepository(repo);
}
_pendingDeltas.clear();
}
@@ -182,12 +182,12 @@
fullComponent = true;
}
- Future<Procedure> compileExpression(
+ Future<Procedure?> compileExpression(
String expression,
List<String> definitions,
List<String> typeDefinitions,
String libraryUri,
- String klass,
+ String? klass,
bool isStatic) {
Map<String, DartType> completeDefinitions = {};
for (String name in definitions) {
@@ -202,7 +202,6 @@
}
Uri library = Uri.parse(libraryUri);
- if (library == null) return null;
return _generator.compileExpression(expression, completeDefinitions,
typeParameters, kDebugProcedureName, library, klass, isStatic);
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 43d5a59..51ed004 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -2,10 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
/// Defines the VM-specific translation of Dart source code to kernel binaries.
-library vm.kernel_front_end;
import 'dart:async';
import 'dart:io' show File, IOSink;
@@ -162,7 +159,7 @@
/// Run kernel compiler tool with given [options] and [usage]
/// and return exit code.
Future<int> runCompiler(ArgResults options, String usage) async {
- final String platformKernel = options['platform'];
+ final String? platformKernel = options['platform'];
if (options['help']) {
print(usage);
@@ -176,26 +173,26 @@
final String input = options.rest.single;
final String outputFileName = options['output'] ?? "$input.dill";
- final String packages = options['packages'];
+ final String? packages = options['packages'];
final String targetName = options['target'];
- final String fileSystemScheme = options['filesystem-scheme'];
- final String depfile = options['depfile'];
- final String fromDillFile = options['from-dill'];
- final List<String> fileSystemRoots = options['filesystem-root'];
+ final String? fileSystemScheme = options['filesystem-scheme'];
+ final String? depfile = options['depfile'];
+ final String? fromDillFile = options['from-dill'];
+ final List<String>? fileSystemRoots = options['filesystem-root'];
final bool aot = options['aot'];
final bool tfa = options['tfa'];
final bool linkPlatform = options['link-platform'];
final bool embedSources = options['embed-sources'];
final bool enableAsserts = options['enable-asserts'];
- final bool nullSafety = options['sound-null-safety'];
+ final bool? nullSafety = options['sound-null-safety'];
final bool useProtobufTreeShakerV2 = options['protobuf-tree-shaker-v2'];
final bool splitOutputByPackages = options['split-output-by-packages'];
- final String manifestFilename = options['manifest'];
- final String dataDir = options['component-name'] ?? options['data-dir'];
+ final String? manifestFilename = options['manifest'];
+ final String? dataDir = options['component-name'] ?? options['data-dir'];
final bool minimalKernel = options['minimal-kernel'];
final bool treeShakeWriteOnlyFields = options['tree-shake-write-only-fields'];
- final List<String> experimentalFlags = options['enable-experiment'];
+ final List<String>? experimentalFlags = options['enable-experiment'];
final Map<String, String> environmentDefines = {};
if (!parseCommandLineDefines(options['define'], environmentDefines, usage)) {
@@ -217,7 +214,7 @@
final fileSystem =
createFrontEndFileSystem(fileSystemScheme, fileSystemRoots);
- final Uri packagesUri = packages != null ? resolveInputUri(packages) : null;
+ final Uri? packagesUri = packages != null ? resolveInputUri(packages) : null;
final platformKernelUri = Uri.base.resolveUri(new Uri.file(platformKernel));
final List<Uri> additionalDills = <Uri>[];
@@ -232,7 +229,8 @@
final verbosity = Verbosity.parseArgument(options['verbosity']);
final errorPrinter = new ErrorPrinter(verbosity);
- final errorDetector = new ErrorDetector(previousErrorHandler: errorPrinter);
+ final errorDetector =
+ new ErrorDetector(previousErrorHandler: errorPrinter.call);
final CompilerOptions compilerOptions = new CompilerOptions()
..sdkSummary = platformKernelUri
@@ -280,19 +278,20 @@
errorPrinter.printCompilationMessages();
- if (errorDetector.hasCompilationErrors || (results.component == null)) {
+ final Component? component = results.component;
+ if (errorDetector.hasCompilationErrors || (component == null)) {
return compileTimeErrorExitCode;
}
final IOSink sink = new File(outputFileName).openWrite();
final BinaryPrinter printer = new BinaryPrinter(sink,
libraryFilter: (lib) => !results.loadedLibraries.contains(lib));
- printer.writeComponentFile(results.component);
+ printer.writeComponentFile(component);
await sink.close();
if (depfile != null) {
await writeDepfile(
- fileSystem, results.compiledSources, outputFileName, depfile);
+ fileSystem, results.compiledSources!, outputFileName, depfile);
}
if (splitOutputByPackages) {
@@ -314,14 +313,14 @@
/// Results of [compileToKernel]: generated kernel [Component] and
/// collection of compiled sources.
class KernelCompilationResults {
- final Component component;
+ final Component? component;
/// Set of libraries loaded from .dill, with or without the SDK depending on
/// the compilation settings.
final Set<Library> loadedLibraries;
- final ClassHierarchy classHierarchy;
- final CoreTypes coreTypes;
- final Iterable<Uri> compiledSources;
+ final ClassHierarchy? classHierarchy;
+ final CoreTypes? coreTypes;
+ final Iterable<Uri>? compiledSources;
KernelCompilationResults(this.component, this.loadedLibraries,
this.classHierarchy, this.coreTypes, this.compiledSources);
@@ -338,29 +337,30 @@
List<String> deleteToStringPackageUris: const <String>[],
bool aot: false,
bool useGlobalTypeFlowAnalysis: false,
- Map<String, String> environmentDefines,
+ required Map<String, String> environmentDefines,
bool enableAsserts: true,
bool useProtobufTreeShakerV2: false,
bool minimalKernel: false,
bool treeShakeWriteOnlyFields: false,
- String fromDillFile: null}) async {
+ String? fromDillFile: null}) async {
// Replace error handler to detect if there are compilation errors.
final errorDetector =
new ErrorDetector(previousErrorHandler: options.onDiagnostic);
- options.onDiagnostic = errorDetector;
+ options.onDiagnostic = errorDetector.call;
+ final target = options.target!;
options.environmentDefines =
- options.target.updateEnvironmentDefines(environmentDefines);
+ target.updateEnvironmentDefines(environmentDefines);
- CompilerResult compilerResult;
+ CompilerResult? compilerResult;
if (fromDillFile != null) {
compilerResult =
await loadKernel(options.fileSystem, resolveInputUri(fromDillFile));
} else {
compilerResult = await kernelForProgram(source, options);
}
- Component component = compilerResult?.component;
- Iterable<Uri> compiledSources = component?.uriToSource?.keys;
+ final Component? component = compilerResult?.component;
+ Iterable<Uri>? compiledSources = component?.uriToSource.keys;
Set<Library> loadedLibraries = createLoadedLibrariesSet(
compilerResult?.loadedComponents, compilerResult?.sdkComponent,
@@ -373,13 +373,8 @@
// Run global transformations only if component is correct.
if ((aot || minimalKernel) && component != null) {
- await runGlobalTransformations(
- options.target,
- component,
- useGlobalTypeFlowAnalysis,
- enableAsserts,
- useProtobufTreeShakerV2,
- errorDetector,
+ await runGlobalTransformations(target, component, useGlobalTypeFlowAnalysis,
+ enableAsserts, useProtobufTreeShakerV2, errorDetector,
minimalKernel: minimalKernel,
treeShakeWriteOnlyFields: treeShakeWriteOnlyFields);
@@ -387,7 +382,7 @@
// compiledSources is component.uriToSource.keys.
// Make a copy of compiledSources to detach it from
// component.uriToSource which is cleared below.
- compiledSources = compiledSources.toList();
+ compiledSources = compiledSources!.toList();
component.metadata.clear();
component.uriToSource.clear();
@@ -406,7 +401,7 @@
}
Set<Library> createLoadedLibrariesSet(
- List<Component> loadedComponents, Component sdkComponent,
+ List<Component>? loadedComponents, Component? sdkComponent,
{bool includePlatform: false}) {
final Set<Library> loadedLibraries = {};
if (loadedComponents != null) {
@@ -481,8 +476,11 @@
/// Runs given [action] with [CompilerContext]. This is needed to
/// be able to report compile-time errors.
-Future<T> runWithFrontEndCompilerContext<T>(Uri source,
- CompilerOptions compilerOptions, Component component, T action()) async {
+Future<T> runWithFrontEndCompilerContext<T>(
+ Uri source,
+ CompilerOptions compilerOptions,
+ Component component,
+ Future<T> action()) async {
final processedOptions =
new ProcessedOptions(options: compilerOptions, inputs: [source]);
@@ -498,7 +496,7 @@
}
class ErrorDetector {
- final DiagnosticMessageHandler previousErrorHandler;
+ final DiagnosticMessageHandler? previousErrorHandler;
bool hasCompilationErrors = false;
ErrorDetector({this.previousErrorHandler});
@@ -514,8 +512,9 @@
class ErrorPrinter {
final Verbosity verbosity;
- final DiagnosticMessageHandler previousErrorHandler;
- final compilationMessages = <Uri, List<DiagnosticMessage>>{};
+ final DiagnosticMessageHandler? previousErrorHandler;
+ final Map<Uri?, List<DiagnosticMessage>> compilationMessages =
+ <Uri?, List<DiagnosticMessage>>{};
ErrorPrinter(this.verbosity, {this.previousErrorHandler});
@@ -539,8 +538,8 @@
}
return 0;
});
- for (final Uri sourceUri in sortedUris) {
- for (final DiagnosticMessage message in compilationMessages[sourceUri]) {
+ for (final Uri? sourceUri in sortedUris) {
+ for (final DiagnosticMessage message in compilationMessages[sourceUri]!) {
if (Verbosity.shouldPrint(verbosity, message)) {
printDiagnosticMessage(message, print);
}
@@ -576,7 +575,7 @@
}
/// Create front-end target with given name.
-Target createFrontEndTarget(String targetName,
+Target? createFrontEndTarget(String targetName,
{bool trackWidgetCreation = false, bool nullSafety = false}) {
// Make sure VM-specific targets are available.
installAdditionalTargets();
@@ -591,9 +590,8 @@
/// If requested, create a virtual mutli-root file system and/or an http aware
/// file system.
FileSystem createFrontEndFileSystem(
- String multiRootFileSystemScheme, List<String> multiRootFileSystemRoots,
- {bool allowHttp}) {
- allowHttp ??= false;
+ String? multiRootFileSystemScheme, List<String>? multiRootFileSystemRoots,
+ {bool allowHttp = false}) {
FileSystem fileSystem = StandardFileSystem.instance;
if (allowHttp) {
fileSystem = HttpAwareFileSystem(fileSystem);
@@ -615,7 +613,7 @@
Future<Uri> asFileUri(FileSystem fileSystem, Uri uri) async {
FileSystemEntity fse = fileSystem.entityForUri(uri);
if (fse is MultiRootFileSystemEntity) {
- fse = await (fse as MultiRootFileSystemEntity).delegate;
+ fse = await fse.delegate;
}
return fse.uri;
}
@@ -645,8 +643,9 @@
Future writeOutputSplitByPackages(Uri source, CompilerOptions compilerOptions,
KernelCompilationResults compilationResults, String outputFileName) async {
final packages = <String>[];
- await runWithFrontEndCompilerContext(
- source, compilerOptions, compilationResults.component, () async {
+ final Component component = compilationResults.component!;
+ await runWithFrontEndCompilerContext(source, compilerOptions, component,
+ () async {
// When loading a kernel file list, flutter_runner and dart_runner expect
// 'main' to be last.
await forEachPackage(compilationResults,
@@ -655,12 +654,10 @@
final String filename = '$outputFileName-$package.dilp';
final IOSink sink = new File(filename).openWrite();
- Component partComponent = compilationResults.component;
-
final BinaryPrinter printer = new BinaryPrinter(sink,
libraryFilter: (lib) =>
packageFor(lib, compilationResults.loadedLibraries) == package);
- printer.writeComponentFile(partComponent);
+ printer.writeComponentFile(component);
await sink.close();
}, mainFirst: false);
@@ -673,7 +670,7 @@
await packagesList.close();
}
-String packageFor(Library lib, Set<Library> loadedLibraries) {
+String? packageFor(Library lib, Set<Library> loadedLibraries) {
// Core libraries are not written into any package kernel binaries.
if (loadedLibraries.contains(lib)) return null;
@@ -701,23 +698,25 @@
}
}
-Future<Null> forEachPackage<T>(KernelCompilationResults results,
- T action(String package, List<Library> libraries),
- {bool mainFirst}) async {
- final Component component = results.component;
+Future<void> forEachPackage(KernelCompilationResults results,
+ Future<void> action(String package, List<Library> libraries),
+ {required bool mainFirst}) async {
+ final Component component = results.component!;
final Set<Library> loadedLibraries = results.loadedLibraries;
sortComponent(component);
- final packages = new Map<String, List<Library>>();
+ final Map<String, List<Library>> packages = <String, List<Library>>{};
packages['main'] = <Library>[]; // Always create 'main'.
for (Library lib in component.libraries) {
- packages
- .putIfAbsent(packageFor(lib, loadedLibraries), () => <Library>[])
- .add(lib);
+ final String? package = packageFor(lib, loadedLibraries);
+ // Ignore external libraries.
+ if (package == null) {
+ continue;
+ }
+ packages.putIfAbsent(package, () => <Library>[]).add(lib);
}
- packages.remove(null); // Ignore external libraries.
- final mainLibraries = packages.remove('main');
+ final mainLibraries = packages.remove('main')!;
if (mainFirst) {
await action('main', mainLibraries);
}
@@ -728,7 +727,7 @@
component.setMainMethodAndMode(null, true, compilationMode);
component.problemsAsJson = null;
for (String package in packages.keys) {
- await action(package, packages[package]);
+ await action(package, packages[package]!);
}
component.setMainMethodAndMode(mainMethod?.reference, true, compilationMode);
component.problemsAsJson = problemsAsJson;
@@ -750,8 +749,8 @@
file.write(_escapePath(output));
file.write(':');
for (Uri dep in compiledSources) {
- // Skip empty or corelib dependencies.
- if (dep == null || dep.scheme == 'org-dartlang-sdk') continue;
+ // Skip corelib dependencies.
+ if (dep.scheme == 'org-dartlang-sdk') continue;
Uri uri = await asFileUri(fileSystem, dep);
file.write(' ');
file.write(_escapePath(uri.toFilePath()));
@@ -761,7 +760,7 @@
}
Future<void> createFarManifest(
- String output, String dataDir, String packageManifestFilename) async {
+ String output, String? dataDir, String packageManifestFilename) async {
List<String> packages = await File('$output-packages').readAsLines();
// Make sure the 'main' package is the last (convention with package loader).
@@ -791,7 +790,7 @@
'typed_data',
'vector_math'
]) {
- Digest digest;
+ Digest? digest;
if (packages.contains(package)) {
final filenameInBuild = '$output-$package.dilp';
final bytes = await File(filenameInBuild).readAsBytes();
@@ -813,11 +812,20 @@
CompilerResultLoadedFromKernel(this.component);
- List<int> get summary => null;
+ @override
+ List<int>? get summary => null;
+
+ @override
List<Component> get loadedComponents => const <Component>[];
+
+ @override
List<Uri> get deps => const <Uri>[];
- CoreTypes get coreTypes => null;
- ClassHierarchy get classHierarchy => null;
+
+ @override
+ CoreTypes? get coreTypes => null;
+
+ @override
+ ClassHierarchy? get classHierarchy => null;
}
Future<CompilerResult> loadKernel(
diff --git a/pkg/vm/lib/target/dart_runner.dart b/pkg/vm/lib/target/dart_runner.dart
index c1df052..995d484 100644
--- a/pkg/vm/lib/target/dart_runner.dart
+++ b/pkg/vm/lib/target/dart_runner.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
import 'package:kernel/target/targets.dart';
import 'package:vm/target/vm.dart' show VmTarget;
diff --git a/pkg/vm/lib/target/flutter.dart b/pkg/vm/lib/target/flutter.dart
index 3ffdc12..1eadf20 100644
--- a/pkg/vm/lib/target/flutter.dart
+++ b/pkg/vm/lib/target/flutter.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
import 'package:kernel/ast.dart' show Component, Library;
import 'package:kernel/core_types.dart' show CoreTypes;
import 'package:kernel/target/changed_structure_notifier.dart';
@@ -14,7 +12,7 @@
class FlutterTarget extends VmTarget {
FlutterTarget(TargetFlags flags) : super(flags);
- WidgetCreatorTracker _widgetTracker;
+ late final WidgetCreatorTracker _widgetTracker = WidgetCreatorTracker();
@override
String get name => 'flutter';
@@ -57,15 +55,12 @@
CoreTypes coreTypes,
List<Library> libraries,
DiagnosticReporter diagnosticReporter,
- {void Function(String msg) logger,
- ChangedStructureNotifier changedStructureNotifier}) {
+ {void Function(String msg)? logger,
+ ChangedStructureNotifier? changedStructureNotifier}) {
super.performPreConstantEvaluationTransformations(
component, coreTypes, libraries, diagnosticReporter,
logger: logger, changedStructureNotifier: changedStructureNotifier);
if (flags.trackWidgetCreation) {
- if (_widgetTracker == null) {
- _widgetTracker = WidgetCreatorTracker();
- }
_widgetTracker.transform(component, libraries, changedStructureNotifier);
}
}
diff --git a/pkg/vm/lib/target/flutter_runner.dart b/pkg/vm/lib/target/flutter_runner.dart
index a9c41ac..addd766 100644
--- a/pkg/vm/lib/target/flutter_runner.dart
+++ b/pkg/vm/lib/target/flutter_runner.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
import 'package:kernel/target/targets.dart';
import 'package:vm/target/vm.dart' show VmTarget;
diff --git a/pkg/vm/lib/target/install.dart b/pkg/vm/lib/target/install.dart
index d691d28..b22d469 100644
--- a/pkg/vm/lib/target/install.dart
+++ b/pkg/vm/lib/target/install.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
import 'package:kernel/target/targets.dart' show targets, TargetFlags;
import 'package:vm/target/dart_runner.dart' show DartRunnerTarget;
import 'package:vm/target/flutter.dart' show FlutterTarget;
diff --git a/pkg/vm/lib/target/vm.dart b/pkg/vm/lib/target/vm.dart
index 20cd144..ec6e1b1 100644
--- a/pkg/vm/lib/target/vm.dart
+++ b/pkg/vm/lib/target/vm.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
import 'package:kernel/ast.dart';
import 'package:kernel/clone.dart';
import 'package:kernel/class_hierarchy.dart';
@@ -34,14 +32,14 @@
class VmTarget extends Target {
final TargetFlags flags;
- Class _growableList;
- Class _immutableList;
- Class _internalLinkedHashMap;
- Class _immutableMap;
- Class _oneByteString;
- Class _twoByteString;
- Class _smi;
- Class _double; // _Double, not double.
+ Class? _growableList;
+ Class? _immutableList;
+ Class? _internalLinkedHashMap;
+ Class? _immutableMap;
+ Class? _oneByteString;
+ Class? _twoByteString;
+ Class? _smi;
+ Class? _double; // _Double, not double.
VmTarget(this.flags);
@@ -116,7 +114,7 @@
final Field little =
coreTypes.index.getField('dart:typed_data', 'Endian', 'little');
host.isConst = true;
- host.initializer = new CloneVisitorNotMembers().clone(little.initializer)
+ host.initializer = new CloneVisitorNotMembers().clone(little.initializer!)
..parent = host;
}
@@ -126,8 +124,8 @@
CoreTypes coreTypes,
List<Library> libraries,
DiagnosticReporter diagnosticReporter,
- {void Function(String msg) logger,
- ChangedStructureNotifier changedStructureNotifier}) {
+ {void Function(String msg)? logger,
+ ChangedStructureNotifier? changedStructureNotifier}) {
super.performPreConstantEvaluationTransformations(
component, coreTypes, libraries, diagnosticReporter,
logger: logger, changedStructureNotifier: changedStructureNotifier);
@@ -152,11 +150,11 @@
CoreTypes coreTypes,
ClassHierarchy hierarchy,
List<Library> libraries,
- Map<String, String> environmentDefines,
+ Map<String, String>? environmentDefines,
DiagnosticReporter diagnosticReporter,
- ReferenceFromIndex referenceFromIndex,
- {void Function(String msg) logger,
- ChangedStructureNotifier changedStructureNotifier}) {
+ ReferenceFromIndex? referenceFromIndex,
+ {void Function(String msg)? logger,
+ ChangedStructureNotifier? changedStructureNotifier}) {
transformMixins.transformLibraries(
this, coreTypes, hierarchy, libraries, referenceFromIndex);
logger?.call("Transformed mixin applications");
@@ -184,7 +182,7 @@
}
// TODO(kmillikin): Make this run on a per-method basis.
- bool productMode = environmentDefines["dart.vm.product"] == "true";
+ bool productMode = environmentDefines!["dart.vm.product"] == "true";
transformAsync.transformLibraries(
new TypeEnvironment(coreTypes, hierarchy), libraries,
productMode: productMode);
@@ -204,9 +202,9 @@
CoreTypes coreTypes,
ClassHierarchy hierarchy,
Procedure procedure,
- Map<String, String> environmentDefines,
- {void Function(String msg) logger}) {
- bool productMode = environmentDefines["dart.vm.product"] == "true";
+ Map<String, String>? environmentDefines,
+ {void Function(String msg)? logger}) {
+ bool productMode = environmentDefines!["dart.vm.product"] == "true";
transformAsync.transformProcedure(
new TypeEnvironment(coreTypes, hierarchy), procedure,
productMode: productMode);
@@ -451,7 +449,7 @@
}
@override
- Class concreteIntLiteralClass(CoreTypes coreTypes, int value) {
+ Class? concreteIntLiteralClass(CoreTypes coreTypes, int value) {
const int bitsPerInt32 = 32;
const int smiBits32 = bitsPerInt32 - 2;
const int smiMin32 = -(1 << smiBits32);
@@ -490,7 +488,6 @@
Map<String, String> updateEnvironmentDefines(Map<String, String> map) {
// TODO(alexmarkov): Call this from the front-end in order to have
// the same defines when compiling platform.
- assert(map != null);
map['dart.isVM'] = 'true';
// TODO(dartbug.com/36460): Derive dart.library.* definitions from platform.
for (String library in extraRequiredLibraries) {
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index 83c9a50..75eff47 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -2,10 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
/// Global type flow analysis.
-library kernel.transformations.analysis;
import 'dart:collection';
import 'dart:core' hide Type;
@@ -51,24 +48,28 @@
/// Maintains set of dependent invocations.
class _DependencyTracker {
- Set<_Invocation> _dependentInvocations;
+ Set<_Invocation>? _dependentInvocations;
void addDependentInvocation(_Invocation invocation) {
if (!identical(invocation, this)) {
- _dependentInvocations ??= new Set<_Invocation>();
- _dependentInvocations.add(invocation);
+ var dependentInvocations = _dependentInvocations;
+ if (dependentInvocations == null) {
+ _dependentInvocations = dependentInvocations = Set<_Invocation>();
+ }
+ dependentInvocations.add(invocation);
}
}
void invalidateDependentInvocations(_WorkList workList) {
- if (_dependentInvocations != null) {
+ final dependentInvocations = _dependentInvocations;
+ if (dependentInvocations != null) {
if (kPrintTrace) {
tracePrint(' - CHANGED: $this');
- for (var di in _dependentInvocations) {
+ for (var di in dependentInvocations) {
tracePrint(' - invalidating $di');
}
}
- _dependentInvocations.forEach(workList.invalidateInvocation);
+ dependentInvocations.forEach(workList.invalidateInvocation);
}
}
}
@@ -83,12 +84,12 @@
final Selector selector;
final Args<Type> args;
- Type result;
+ Type? result;
/// Result of the invocation calculated before invocation was invalidated.
/// Used to check if the re-analysis of the invocation yields the same
/// result or not (to avoid invalidation of callers if result hasn't changed).
- Type invalidatedResult;
+ Type? invalidatedResult;
/// Number of times result of this invocation was invalidated.
int invalidationCounter = 0;
@@ -108,7 +109,7 @@
/// Returns result of this invocation if its available without
/// further analysis, or `null` if it's not available.
/// Used for recursive calls while this invocation is being processed.
- Type get resultForRecursiveInvocation => result;
+ Type? get resultForRecursiveInvocation => result;
/// Use [type] as a current computed result of this invocation.
/// If this invocation was invalidated, and the invalidated result is
@@ -116,7 +117,6 @@
/// Result type may be saturated if this invocation was invalidated
/// too many times.
void setResult(TypeFlowAnalysis typeFlowAnalysis, Type type) {
- assert(type != null);
result = type;
if (invalidatedResult != null) {
@@ -132,8 +132,8 @@
// the analysis, result is saturated after invocation is invalidated
// at least [_Invocation.invalidationLimit] times.
if (invalidationCounter > _Invocation.invalidationLimit) {
- result =
- result.union(invalidatedResult, typeFlowAnalysis.hierarchyCache);
+ result = result!
+ .union(invalidatedResult!, typeFlowAnalysis.hierarchyCache);
}
}
invalidatedResult = null;
@@ -192,11 +192,12 @@
// they could fail bounds checks.
//
// TODO(sjindel): Use [TypeCheck] to avoid bounds checks.
- if (selector.member.function != null) {
- typeChecksNeeded = selector.member.function.typeParameters
- .any((t) => t.isGenericCovariantImpl);
+ final function = selector.member.function;
+ if (function != null) {
+ typeChecksNeeded =
+ function.typeParameters.any((t) => t.isGenericCovariantImpl);
} else {
- Field field = selector.member;
+ Field field = selector.member as Field;
if (selector.callKind == CallKind.PropertySet) {
// TODO(dartbug.com/40615): Use TFA results to improve this criterion.
typeChecksNeeded = field.isGenericCovariantImpl;
@@ -277,13 +278,10 @@
fieldValue.isInitialized = true;
return const EmptyType();
}
-
- // Make dartanalyzer happy.
- throw 'Unexpected call kind ${selector.callKind}';
}
Type _processFunction(TypeFlowAnalysis typeFlowAnalysis) {
- final Member member = selector.member;
+ final Member member = selector.member!;
if (selector.memberAgreesToCallKind(member)) {
if (_argumentsValid()) {
final summary = typeFlowAnalysis.getSummary(member);
@@ -326,13 +324,12 @@
}
bool _argumentsValid() {
- final function = selector.member.function;
- assert(function != null);
-
+ final member = selector.member!;
+ final function = member.function!;
final int positionalArguments = args.positionalCount;
- final int firstParamIndex = numTypeParams(selector.member) +
- (hasReceiverArg(selector.member) ? 1 : 0);
+ final int firstParamIndex =
+ numTypeParams(member) + (hasReceiverArg(member) ? 1 : 0);
final int requiredParameters =
firstParamIndex + function.requiredParameterCount;
if (positionalArguments < requiredParameters) {
@@ -361,9 +358,9 @@
class _DispatchableInvocation extends _Invocation {
bool _isPolymorphic = false;
- Set<Call> _callSites; // Populated only if not polymorphic.
- Member _monomorphicTarget;
- _DirectInvocation _monomorphicDirectInvocation;
+ Set<Call>? _callSites; // Populated only if not polymorphic.
+ Member? _monomorphicTarget;
+ _DirectInvocation? _monomorphicDirectInvocation;
@override
set typeChecksNeeded(bool value) {
@@ -434,7 +431,8 @@
if (!_isPolymorphic) {
assert(target == _monomorphicTarget);
- _monomorphicDirectInvocation = directInvocation;
+ _monomorphicDirectInvocation =
+ directInvocation as _DirectInvocation;
}
type = typeFlowAnalysis.workList.processInvocation(directInvocation);
@@ -486,13 +484,13 @@
final bool isNullableReceiver = receiver is NullableType;
if (isNullableReceiver) {
- receiver = (receiver as NullableType).baseType;
+ receiver = receiver.baseType;
assert(receiver is! NullableType);
}
if (selector is InterfaceSelector) {
final staticReceiverType = new ConeType(typeFlowAnalysis.hierarchyCache
- .getTFClass(selector.member.enclosingClass));
+ .getTFClass(selector.member!.enclosingClass!));
receiver = receiver.intersection(
staticReceiverType, typeFlowAnalysis.hierarchyCache);
assert(receiver is! NullableType);
@@ -507,7 +505,7 @@
// invocation to the receiver class. A new allocated class discovered
// in the receiver cone will invalidate this invocation.
receiver = typeFlowAnalysis.hierarchyCache
- .specializeTypeCone((receiver as ConeType).cls, allowWideCone: false);
+ .specializeTypeCone(receiver.cls, allowWideCone: false);
}
assert(targets.isEmpty);
@@ -535,7 +533,7 @@
Class nullClass =
typeFlowAnalysis.environment.coreTypes.deprecatedNullClass;
- Member target = typeFlowAnalysis.hierarchyCache.hierarchy
+ Member? target = typeFlowAnalysis.hierarchyCache.hierarchy
.getDispatchTarget(nullClass, selector.name, setter: selector.isSetter);
if (target != null) {
@@ -552,7 +550,7 @@
TypeFlowAnalysis typeFlowAnalysis) {
final TFClass cls = receiver.cls;
- Member target =
+ Member? target =
(cls as _TFClassImpl).getDispatchTarget(selector, typeFlowAnalysis);
if (target != null) {
@@ -647,8 +645,9 @@
if (_isPolymorphic) {
callSite.setPolymorphic();
} else {
- if (_monomorphicTarget != null) {
- callSite.addTarget(_monomorphicTarget);
+ final monomorphicTarget = _monomorphicTarget;
+ if (monomorphicTarget != null) {
+ callSite.addTarget(monomorphicTarget);
}
}
@@ -660,18 +659,20 @@
/// Notify call sites monitoring this invocation about changes in
/// polymorphism of this invocation.
void _notifyCallSites() {
- if (_callSites != null) {
- _callSites.forEach(_notifyCallSite);
+ final callSites = _callSites;
+ if (callSites != null) {
+ callSites.forEach(_notifyCallSite);
}
}
@override
- Type get resultForRecursiveInvocation {
+ Type? get resultForRecursiveInvocation {
if (result != null) {
return result;
}
- if (_monomorphicDirectInvocation != null) {
- return _monomorphicDirectInvocation.resultForRecursiveInvocation;
+ final monomorphicDirectInvocation = _monomorphicDirectInvocation;
+ if (monomorphicDirectInvocation != null) {
+ return monomorphicDirectInvocation.resultForRecursiveInvocation;
}
return null;
}
@@ -683,30 +684,30 @@
/// 1) Add 1..N concrete types ordered by classId OR add 1 arbitrary type.
/// 2) Make type nullable.
class _ReceiverTypeBuilder {
- Type _type;
- List<ConcreteType> _list;
+ Type? _type;
+ List<ConcreteType>? _list;
bool _nullable = false;
/// Appends a ConcreteType. May be called multiple times.
/// Should not be used in conjunction with [addType].
void addConcreteType(ConcreteType type) {
- if (_list == null) {
- if (_type == null) {
+ final list = _list;
+ if (list == null) {
+ final Type? t = _type;
+ if (t == null) {
_type = type;
return;
}
+ final ct = t as ConcreteType;
- assert(_type is ConcreteType);
- assert(_type != type);
-
- _list = <ConcreteType>[];
- _list.add(_type);
-
+ assert(ct != type);
+ assert(ct.cls.id < type.cls.id);
+ _list = <ConcreteType>[ct, type];
_type = null;
+ } else {
+ assert(list.last.cls.id < type.cls.id);
+ list.add(type);
}
-
- assert(_list.last.cls.id < type.cls.id);
- _list.add(type);
}
/// Appends an arbitrary Type. May be called only once.
@@ -723,12 +724,13 @@
/// Returns union of added types.
Type toType() {
- Type t = _type;
+ Type? t = _type;
if (t == null) {
- if (_list == null) {
+ final list = _list;
+ if (list == null) {
t = const EmptyType();
} else {
- t = new SetType(_list);
+ t = SetType(list);
}
} else {
assert(_list == null);
@@ -753,7 +755,7 @@
static const int maxInvocationsPerSelector = 5000;
int count = 0;
- _Invocation approximation;
+ _Invocation? approximation;
}
/// Maintains ([Selector], [Args]) => [_Invocation] cache.
@@ -771,7 +773,7 @@
_Invocation invocation = (selector is DirectSelector)
? new _DirectInvocation(selector, args)
: new _DispatchableInvocation(selector, args);
- _Invocation result = _invocations.lookup(invocation);
+ _Invocation? result = _invocations.lookup(invocation);
if (result != null) {
return result;
}
@@ -784,14 +786,16 @@
final sa = (_approximations[selector] ??= new _SelectorApproximation());
if (sa.count >= _SelectorApproximation.maxInvocationsPerSelector) {
- if (sa.approximation == null) {
+ _Invocation? approximation = sa.approximation;
+ if (approximation == null) {
final rawArgs =
_typeFlowAnalysis.summaryCollector.rawArguments(selector);
- sa.approximation = new _DispatchableInvocation(selector, rawArgs);
+ sa.approximation =
+ approximation = _DispatchableInvocation(selector, rawArgs);
Statistics.approximateInvocationsCreated++;
}
Statistics.approximateInvocationsUsed++;
- return sa.approximation;
+ return approximation;
}
++sa.count;
@@ -809,8 +813,8 @@
class _FieldValue extends _DependencyTracker {
final Field field;
final Type staticType;
- final Summary typeGuardSummary;
- Type value;
+ final Summary? typeGuardSummary;
+ Type value = const EmptyType();
/// Flag indicating if field initializer was executed.
bool isInitialized = false;
@@ -825,8 +829,6 @@
: staticType = typesBuilder.fromStaticType(field.type, true) {
if (field.initializer == null && _isDefaultValueOfFieldObservable()) {
value = new Type.nullable(const EmptyType());
- } else {
- value = const EmptyType();
}
}
@@ -839,8 +841,7 @@
return true;
}
- final enclosingClass = field.enclosingClass;
- assert(enclosingClass != null);
+ final enclosingClass = field.enclosingClass!;
// Default value is not observable if every generative constructor
// is redirecting or initializes the field.
@@ -856,10 +857,11 @@
});
}
- void ensureInitialized(TypeFlowAnalysis typeFlowAnalysis, Type receiverType) {
+ void ensureInitialized(
+ TypeFlowAnalysis typeFlowAnalysis, Type? receiverType) {
if (field.initializer != null) {
assert(field.isStatic == (receiverType == null));
- final args = !field.isStatic ? <Type>[receiverType] : const <Type>[];
+ final args = !field.isStatic ? <Type>[receiverType!] : const <Type>[];
final initializerInvocation = typeFlowAnalysis._invocationsCache
.getInvocation(
new DirectSelector(field, callKind: CallKind.FieldInitializer),
@@ -870,17 +872,18 @@
}
}
- Type getValue(TypeFlowAnalysis typeFlowAnalysis, Type receiverType) {
+ Type getValue(TypeFlowAnalysis typeFlowAnalysis, Type? receiverType) {
ensureInitialized(typeFlowAnalysis, receiverType);
addDependentInvocation(typeFlowAnalysis.currentInvocation);
+ final typeGuardSummary = this.typeGuardSummary;
return (typeGuardSummary != null)
- ? typeGuardSummary.apply(Args([receiverType, value]),
+ ? typeGuardSummary.apply(Args([receiverType!, value]),
typeFlowAnalysis.hierarchyCache, typeFlowAnalysis)
: value;
}
void setValue(
- Type newValue, TypeFlowAnalysis typeFlowAnalysis, Type receiverType) {
+ Type newValue, TypeFlowAnalysis typeFlowAnalysis, Type? receiverType) {
// Make sure type cones are specialized before putting them into field
// value, in order to ensure that dependency is established between
// cone's base type and corresponding field setter.
@@ -907,10 +910,11 @@
//
final hierarchy = typeFlowAnalysis.hierarchyCache;
// TODO(sjindel/tfa): Perform narrowing inside 'TypeCheck'.
+ final typeGuardSummary = this.typeGuardSummary;
final narrowedNewValue = typeGuardSummary != null
? typeGuardSummary
- .apply(
- new Args([receiverType, newValue]), hierarchy, typeFlowAnalysis)
+ .apply(new Args([receiverType!, newValue]), hierarchy,
+ typeFlowAnalysis)
.intersection(staticType, hierarchy)
: newValue.specialize(hierarchy).intersection(staticType, hierarchy);
Type newType =
@@ -952,28 +956,26 @@
/// Flag indicating if this class has a noSuchMethod() method not inherited
/// from Object.
/// Lazy initialized by ClassHierarchyCache.hasNonTrivialNoSuchMethod().
- bool hasNonTrivialNoSuchMethod;
+ bool? hasNonTrivialNoSuchMethod;
_TFClassImpl(int id, Class classNode, this.supertypes)
: super(id, classNode) {
supertypes.add(this);
}
- ConcreteType _concreteType;
- ConcreteType get concreteType =>
- _concreteType ??= new ConcreteType(this, null);
+ late final ConcreteType concreteType = ConcreteType(this, null);
- Type _specializedConeType;
+ Type? _specializedConeType;
Type get specializedConeType =>
_specializedConeType ??= _calculateConeTypeSpecialization();
bool get hasWideCone =>
_allocatedSubtypes.length > maxAllocatedTypesInSetSpecializations;
- WideConeType _wideConeType;
+ late final WideConeType _wideConeType = WideConeType(this);
WideConeType get wideConeType {
assert(hasWideCone);
- return _wideConeType ??= new WideConeType(this);
+ return _wideConeType;
}
Type _calculateConeTypeSpecialization() {
@@ -999,14 +1001,16 @@
_specializedConeType = null; // Reset cached specialization.
}
- Member getDispatchTarget(
+ Member? getDispatchTarget(
Selector selector, TypeFlowAnalysis typeFlowAnalysis) {
- Member target = _dispatchTargets[selector];
+ Member? target = _dispatchTargets[selector];
if (target == null) {
target = typeFlowAnalysis.hierarchyCache.hierarchy.getDispatchTarget(
classNode, selector.name,
setter: selector.isSetter);
- _dispatchTargets[selector] = target;
+ if (target != null) {
+ _dispatchTargets[selector] = target;
+ }
}
return target;
}
@@ -1021,10 +1025,11 @@
final cachedFlattenedTypeArgs = <Class, List<DartType>>{};
final cachedFlattenedTypeArgsForNonGeneric = <Class, List<Type>>{};
- RuntimeTypeTranslatorImpl closedTypeTranslator;
+ late final RuntimeTypeTranslatorImpl closedTypeTranslator;
- GenericInterfacesInfoImpl(this.hierarchy) {
- closedTypeTranslator = RuntimeTypeTranslatorImpl.forClosedTypes(this);
+ GenericInterfacesInfoImpl(CoreTypes coreTypes, this.hierarchy) {
+ closedTypeTranslator =
+ RuntimeTypeTranslatorImpl.forClosedTypes(coreTypes, this);
}
List<DartType> flattenedTypeArgumentsFor(Class klass, {bool useCache: true}) {
@@ -1049,7 +1054,7 @@
if (klass == iface) return 0;
final pair = new SubtypePair(klass, iface);
- int offset = supertypeOffsetsCache[pair];
+ int? offset = supertypeOffsetsCache[pair];
if (offset != null) return offset;
@@ -1064,16 +1069,16 @@
}
List<Type> flattenedTypeArgumentsForNonGeneric(Class klass) {
- List<Type> result = cachedFlattenedTypeArgsForNonGeneric[klass];
+ List<Type>? result = cachedFlattenedTypeArgsForNonGeneric[klass];
if (result != null) return result;
List<DartType> flattenedTypeArgs =
flattenedTypeArgumentsFor(klass, useCache: false);
- result = new List<Type>.filled(flattenedTypeArgs.length, null);
- for (int i = 0; i < flattenedTypeArgs.length; ++i) {
- final translated = closedTypeTranslator.translate(flattenedTypeArgs[i]);
+ result = <Type>[];
+ for (DartType arg in flattenedTypeArgs) {
+ final translated = closedTypeTranslator.translate(arg);
assert(translated is RuntimeType || translated is UnknownType);
- result[i] = translated;
+ result.add(translated as Type);
}
cachedFlattenedTypeArgsForNonGeneric[klass] = result;
return result;
@@ -1108,10 +1113,8 @@
_ClassHierarchyCache(this._typeFlowAnalysis, this.hierarchy,
this.genericInterfacesInfo, this.environment, bool nullSafety)
: objectNoSuchMethod = hierarchy.getDispatchTarget(
- environment.coreTypes.objectClass, noSuchMethodName),
- super(environment.coreTypes, nullSafety) {
- assert(objectNoSuchMethod != null);
- }
+ environment.coreTypes.objectClass, noSuchMethodName)!,
+ super(environment.coreTypes, nullSafety);
@override
_TFClassImpl getTFClass(Class c) {
@@ -1198,10 +1201,13 @@
bool hasNonTrivialNoSuchMethod(TFClass c) {
final classImpl = c as _TFClassImpl;
- classImpl.hasNonTrivialNoSuchMethod ??=
- (hierarchy.getDispatchTarget(c.classNode, noSuchMethodName) !=
- objectNoSuchMethod);
- return classImpl.hasNonTrivialNoSuchMethod;
+ bool? value = classImpl.hasNonTrivialNoSuchMethod;
+ if (value == null) {
+ classImpl.hasNonTrivialNoSuchMethod = value =
+ (hierarchy.getDispatchTarget(c.classNode, noSuchMethodName) !=
+ objectNoSuchMethod);
+ }
+ return value;
}
_DynamicTargetSet getDynamicTargetSet(DynamicSelector selector) {
@@ -1294,10 +1300,11 @@
}
bool invalidateProtobufFields() {
- if (_typeFlowAnalysis.protobufHandler == null) {
+ final protobufHandler = _typeFlowAnalysis.protobufHandler;
+ if (protobufHandler == null) {
return false;
}
- final fields = _typeFlowAnalysis.protobufHandler.getInvalidatedFields();
+ final fields = protobufHandler.getInvalidatedFields();
if (fields.isEmpty) {
return false;
}
@@ -1305,7 +1312,7 @@
for (var field in fields) {
assert(field.isStatic);
// Reset summary in order to rebuild it.
- _typeFlowAnalysis._summaries[field] = null;
+ _typeFlowAnalysis._summaries.remove(field);
// Invalidate (and enqueue) field initializer invocation.
final initializerInvocation = _typeFlowAnalysis._invocationsCache
.getInvocation(
@@ -1328,10 +1335,11 @@
}
Type processInvocation(_Invocation invocation) {
- if (invocation.result != null) {
+ Type? result = invocation.result;
+ if (result != null) {
// Already processed.
Statistics.usedCachedResultsOfInvocations++;
- return invocation.result;
+ return result;
}
// Test if tracing is enabled to avoid expensive message formatting.
@@ -1374,18 +1382,18 @@
-1);
}
processing.remove(invocation);
- return invocation.invalidatedResult;
+ return invocation.invalidatedResult!;
}
callStack.add(invocation);
pending.remove(invocation);
- Type result = invocation.process(_typeFlowAnalysis);
+ result = invocation.process(_typeFlowAnalysis);
invocation.setResult(_typeFlowAnalysis, result);
// setResult may saturate result to ensure convergence.
- result = invocation.result;
+ result = invocation.result!;
// Invocation is still pending - it was invalidated while being processed.
// Move result to invalidatedResult.
@@ -1434,12 +1442,12 @@
final TypeEnvironment environment;
final LibraryIndex libraryIndex;
final PragmaAnnotationParser annotationMatcher;
- final ProtobufHandler protobufHandler;
- NativeCodeOracle nativeCodeOracle;
- _ClassHierarchyCache hierarchyCache;
- SummaryCollector summaryCollector;
- _InvocationsCache _invocationsCache;
- _WorkList workList;
+ final ProtobufHandler? protobufHandler;
+ late NativeCodeOracle nativeCodeOracle;
+ late _ClassHierarchyCache hierarchyCache;
+ late SummaryCollector summaryCollector;
+ late _InvocationsCache _invocationsCache;
+ late _WorkList workList;
GenericInterfacesInfo _genericInterfacesInfo;
final Map<Member, Summary> _summaries = <Member, Summary>{};
@@ -1459,7 +1467,7 @@
this.environment,
this.libraryIndex,
this.protobufHandler,
- PragmaAnnotationParser matcher)
+ PragmaAnnotationParser? matcher)
: annotationMatcher =
matcher ?? new ConstantPragmaAnnotationParser(coreTypes) {
nativeCodeOracle = new NativeCodeOracle(libraryIndex, annotationMatcher);
@@ -1488,9 +1496,9 @@
}
_FieldValue getFieldValue(Field field) {
- _FieldValue fieldValue = _fieldValues[field];
+ _FieldValue? fieldValue = _fieldValues[field];
if (fieldValue == null) {
- Summary typeGuardSummary = null;
+ Summary? typeGuardSummary = null;
if (field.isGenericCovariantImpl) {
typeGuardSummary = summaryCollector.createSummary(field,
fieldSummaryType: FieldSummaryType.kFieldGuard);
@@ -1548,24 +1556,24 @@
bool isClassAllocated(Class c) => hierarchyCache.allocatedClasses.contains(c);
- Call callSite(TreeNode node) => summaryCollector.callSites[node];
+ Call? callSite(TreeNode node) => summaryCollector.callSites[node];
- TypeCheck explicitCast(AsExpression cast) =>
+ TypeCheck? explicitCast(AsExpression cast) =>
summaryCollector.explicitCasts[cast];
- TypeCheck isTest(IsExpression node) => summaryCollector.isTests[node];
+ TypeCheck? isTest(IsExpression node) => summaryCollector.isTests[node];
- NarrowNotNull nullTest(TreeNode node) => summaryCollector.nullTests[node];
+ NarrowNotNull? nullTest(TreeNode node) => summaryCollector.nullTests[node];
- Type fieldType(Field field) => _fieldValues[field]?.value;
+ Type? fieldType(Field field) => _fieldValues[field]?.value;
- Args<Type> argumentTypes(Member member) => _summaries[member]?.argumentTypes;
+ Args<Type>? argumentTypes(Member member) => _summaries[member]?.argumentTypes;
- Type argumentType(Member member, VariableDeclaration memberParam) {
+ Type? argumentType(Member member, VariableDeclaration memberParam) {
return _summaries[member]?.argumentType(member, memberParam);
}
- List<VariableDeclaration> uncheckedParameters(Member member) =>
+ List<VariableDeclaration>? uncheckedParameters(Member member) =>
_summaries[member]?.uncheckedParameters;
bool isTearOffTaken(Member member) => _tearOffTaken.contains(member);
@@ -1599,7 +1607,7 @@
/// ---- Implementation of [CallHandler] interface. ----
@override
- Type applyCall(Call callSite, Selector selector, Args<Type> args,
+ Type applyCall(Call? callSite, Selector selector, Args<Type> args,
{bool isResultUsed: true, bool processImmediately: true}) {
_Invocation invocation = _invocationsCache.getInvocation(selector, args);
@@ -1629,7 +1637,7 @@
workList.enqueueInvocation(invocation);
}
- return null;
+ return const EmptyType();
}
}
@@ -1680,7 +1688,7 @@
}
@override
- void recordTearOff(Procedure target) {
+ void recordTearOff(Member target) {
_tearOffTaken.add(target);
}
}
diff --git a/pkg/vm/lib/transformations/type_flow/calls.dart b/pkg/vm/lib/transformations/type_flow/calls.dart
index 060500a..dd16279d 100644
--- a/pkg/vm/lib/transformations/type_flow/calls.dart
+++ b/pkg/vm/lib/transformations/type_flow/calls.dart
@@ -2,10 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
/// Declares classes which describe a call: selectors and arguments.
-library vm.transformations.type_flow.calls;
import 'dart:core' hide Type;
@@ -30,10 +27,10 @@
Selector(this.callKind);
/// Interface or concrete target, may be null.
- Member get member;
+ Member? get member;
/// Selector name.
- Name get name => member.name;
+ Name get name => member!.name;
bool get isSetter => (callKind == CallKind.PropertySet);
@@ -46,6 +43,7 @@
/// Static approximation of Dart return type.
DartType get staticReturnType {
+ final member = this.member;
if (member == null) {
return const DynamicType();
}
@@ -61,7 +59,6 @@
case CallKind.SetFieldInConstructor:
return const NeverType.nonNullable();
}
- return null;
}
bool memberAgreesToCallKind(Member member) {
@@ -79,7 +76,6 @@
case CallKind.SetFieldInConstructor:
return member is Field;
}
- return false;
}
String get _callKindPrefix {
@@ -94,7 +90,6 @@
case CallKind.FieldInitializer:
return 'init ';
}
- return '';
}
}
@@ -169,7 +164,7 @@
DynamicSelector(CallKind callKind, this.name) : super(callKind);
@override
- Member get member => null;
+ Member? get member => null;
@override
int get hashCode => (super.hashCode ^ name.hashCode + 37) & kHashMask;
@@ -189,7 +184,8 @@
final List<T> values;
final List<String> names;
- int _hashCode;
+ @override
+ late final int hashCode = _computeHashCode();
Args(this.values, {this.names = const <String>[]}) {
assert(isSorted(names));
@@ -206,9 +202,6 @@
T get receiver => values[0];
- @override
- int get hashCode => _hashCode ??= _computeHashCode();
-
int _computeHashCode() {
int hash = 1231;
for (var v in values) {
diff --git a/pkg/vm/lib/transformations/type_flow/native_code.dart b/pkg/vm/lib/transformations/type_flow/native_code.dart
index 7a5baf9..0611379 100644
--- a/pkg/vm/lib/transformations/type_flow/native_code.dart
+++ b/pkg/vm/lib/transformations/type_flow/native_code.dart
@@ -2,10 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
/// Handling of native code and entry points.
-library vm.transformations.type_flow.native_code;
import 'dart:core' hide Type;
@@ -35,24 +32,21 @@
/// Record the fact that given member is called from this.
void recordMemberCalledViaThis(Member target);
- /// Record the fact that given method is torn off.
- void recordTearOff(Procedure target) {}
+ /// Record the fact that given member is torn off.
+ void recordTearOff(Member target) {}
}
class PragmaEntryPointsVisitor extends RecursiveVisitor {
final EntryPointsListener entryPoints;
final NativeCodeOracle nativeCodeOracle;
final PragmaAnnotationParser matcher;
- Class currentClass = null;
PragmaEntryPointsVisitor(
- this.entryPoints, this.nativeCodeOracle, this.matcher) {
- assert(matcher != null);
- }
+ this.entryPoints, this.nativeCodeOracle, this.matcher);
- PragmaEntryPointType _annotationsDefineRoot(List<Expression> annotations) {
+ PragmaEntryPointType? _annotationsDefineRoot(List<Expression> annotations) {
for (var annotation in annotations) {
- ParsedPragma pragma = matcher.parsePragma(annotation);
+ ParsedPragma? pragma = matcher.parsePragma(annotation);
if (pragma == null) continue;
if (pragma is ParsedEntryPointPragma) return pragma.type;
}
@@ -72,7 +66,6 @@
}
nativeCodeOracle.addClassReferencedFromNativeCode(klass);
}
- currentClass = klass;
klass.visitChildren(this);
}
@@ -88,8 +81,7 @@
}
Member target = proc;
while (target is Procedure && target.isRedirectingFactory) {
- target = getRedirectingFactoryBody(target).target;
- assert(target != null);
+ target = getRedirectingFactoryBody(target)!.target!;
assert(
(target is Procedure && target.isFactory) || target is Constructor);
}
@@ -152,7 +144,7 @@
}
entryPoints
.addRawCall(new DirectSelector(ctor, callKind: CallKind.Method));
- entryPoints.addAllocatedClass(currentClass);
+ entryPoints.addAllocatedClass(ctor.enclosingClass);
nativeCodeOracle.setMemberReferencedFromNativeCode(ctor);
}
}
@@ -201,9 +193,7 @@
final Set<Class> _classesReferencedFromNativeCode = new Set<Class>();
final PragmaAnnotationParser _matcher;
- NativeCodeOracle(this._libraryIndex, this._matcher) {
- assert(_matcher != null);
- }
+ NativeCodeOracle(this._libraryIndex, this._matcher);
void addClassReferencedFromNativeCode(Class klass) {
_classesReferencedFromNativeCode.add(klass);
@@ -219,9 +209,9 @@
bool isMemberReferencedFromNativeCode(Member member) =>
_membersReferencedFromNativeCode.contains(member);
- PragmaRecognizedType recognizedType(Member member) {
+ PragmaRecognizedType? recognizedType(Member member) {
for (var annotation in member.annotations) {
- ParsedPragma pragma = _matcher.parsePragma(annotation);
+ ParsedPragma? pragma = _matcher.parsePragma(annotation);
if (pragma is ParsedRecognized) {
return pragma.type;
}
@@ -229,15 +219,16 @@
return null;
}
- bool isRecognized(Member member, [List<PragmaRecognizedType> expectedTypes]) {
- PragmaRecognizedType type = recognizedType(member);
+ bool isRecognized(Member member,
+ [List<PragmaRecognizedType>? expectedTypes]) {
+ PragmaRecognizedType? type = recognizedType(member);
return type != null &&
(expectedTypes == null || expectedTypes.contains(type));
}
bool hasDisableUnboxedParameters(Member member) {
for (var annotation in member.annotations) {
- ParsedPragma pragma = _matcher.parsePragma(annotation);
+ ParsedPragma? pragma = _matcher.parsePragma(annotation);
if (pragma is ParsedDisableUnboxedParameters) {
if (member.enclosingLibrary.importUri.scheme != "dart") {
throw "ERROR: Cannot use @pragma(vm:disable-unboxed-parameters) outside core libraries.";
@@ -255,11 +246,11 @@
EntryPointsListener entryPointsListener,
TypesBuilder typesBuilder,
RuntimeTypeTranslator translator) {
- TypeExpr returnType = null;
- bool nullable = null;
+ TypeExpr? returnType = null;
+ bool? nullable = null;
for (var annotation in member.annotations) {
- ParsedPragma pragma = _matcher.parsePragma(annotation);
+ ParsedPragma? pragma = _matcher.parsePragma(annotation);
if (pragma == null) continue;
if (pragma is ParsedResultTypeByTypePragma ||
pragma is ParsedResultTypeByPathPragma ||
@@ -278,8 +269,8 @@
returnType = entryPointsListener.addAllocatedClass(type.classNode);
if (pragma.resultTypeUsesPassedTypeArguments) {
returnType = translator.instantiateConcreteType(
- returnType,
- member.function.typeParameters
+ returnType as ConcreteType,
+ member.function!.typeParameters
.map((t) => TypeParameterType(
t, TypeParameterType.computeNullabilityFromBound(t)))
.toList());
@@ -314,7 +305,7 @@
return returnType;
} else {
return typesBuilder.fromStaticType(
- member.function.returnType, nullable ?? true);
+ member.function!.returnType, nullable ?? true);
}
}
}
diff --git a/pkg/vm/lib/transformations/type_flow/protobuf_handler.dart b/pkg/vm/lib/transformations/type_flow/protobuf_handler.dart
index a4b0bbc..c0175a4 100644
--- a/pkg/vm/lib/transformations/type_flow/protobuf_handler.dart
+++ b/pkg/vm/lib/transformations/type_flow/protobuf_handler.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
import 'package:kernel/ast.dart';
import 'package:kernel/clone.dart' show CloneVisitorNotMembers;
import 'package:kernel/core_types.dart' show CoreTypes;
@@ -47,14 +45,14 @@
final Procedure _builderInfoAddMethod;
// Type of BuilderInfo.add<Null>().
- FunctionType _typeOfBuilderInfoAddOfNull;
+ late FunctionType _typeOfBuilderInfoAddOfNull;
final _messageClasses = <Class, _MessageClass>{};
final _invalidatedClasses = <_MessageClass>{};
/// Creates [ProtobufHandler] instance for [component].
/// Returns null if protobuf library is not used.
- static ProtobufHandler forComponent(
+ static ProtobufHandler? forComponent(
Component component, CoreTypes coreTypes) {
final libraryIndex = LibraryIndex(component, [protobufLibraryUri]);
if (!libraryIndex.containsLibrary(protobufLibraryUri)) {
@@ -68,12 +66,12 @@
libraryIndex.getClass(protobufLibraryUri, 'GeneratedMessage'),
_tagNumberClass =
libraryIndex.getClass(protobufLibraryUri, 'TagNumber'),
- _tagNumberField = libraryIndex.getMember(
- protobufLibraryUri, 'TagNumber', 'tagNumber'),
+ _tagNumberField =
+ libraryIndex.getField(protobufLibraryUri, 'TagNumber', 'tagNumber'),
_builderInfoClass =
libraryIndex.getClass(protobufLibraryUri, 'BuilderInfo'),
- _builderInfoAddMethod =
- libraryIndex.getMember(protobufLibraryUri, 'BuilderInfo', 'add') {
+ _builderInfoAddMethod = libraryIndex.getProcedure(
+ protobufLibraryUri, 'BuilderInfo', 'add') {
final functionType = _builderInfoAddMethod.getterType as FunctionType;
_typeOfBuilderInfoAddOfNull = Substitution.fromPairs(
functionType.typeParameters, const <DartType>[NullType()])
@@ -130,8 +128,9 @@
List<Field> getInvalidatedFields() {
final fields = <Field>[];
for (var cls in _invalidatedClasses) {
- if (cls._metadataField != null) {
- fields.add(cls._metadataField);
+ final field = cls._metadataField;
+ if (field != null) {
+ fields.add(field);
}
}
_invalidatedClasses.clear();
@@ -143,14 +142,15 @@
++Statistics.protobufMetadataInitializersUpdated;
Statistics.protobufMetadataFieldsPruned -= cls.numberOfFieldsPruned;
- final field = cls._metadataField;
- if (cls._originalInitializer == null) {
- cls._originalInitializer = field.initializer;
+ final field = cls._metadataField!;
+ Expression? originalInitializer = cls._originalInitializer;
+ if (originalInitializer == null) {
+ cls._originalInitializer = originalInitializer = field.initializer!;
}
final cloner = CloneVisitorNotMembers();
- field.initializer = cloner.clone(cls._originalInitializer)..parent = field;
+ field.initializer = cloner.clone(originalInitializer)..parent = field;
final transformer = _MetadataTransformer(this, cls);
- field.initializer.accept(transformer);
+ field.initializer!.accept(transformer);
_invalidatedClasses.remove(cls);
cls.numberOfFieldsPruned = transformer.numberOfFieldsPruned;
@@ -168,8 +168,8 @@
}
class _MessageClass {
- Field _metadataField;
- Expression _originalInitializer;
+ Field? _metadataField;
+ Expression? _originalInitializer;
final _usedTags = <int>{};
int numberOfFieldsPruned = 0;
}
diff --git a/pkg/vm/lib/transformations/type_flow/signature_shaking.dart b/pkg/vm/lib/transformations/type_flow/signature_shaking.dart
index a61e222..5ae2e16 100644
--- a/pkg/vm/lib/transformations/type_flow/signature_shaking.dart
+++ b/pkg/vm/lib/transformations/type_flow/signature_shaking.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
import 'package:kernel/ast.dart';
import 'package:kernel/external_name.dart';
import 'package:kernel/type_environment.dart';
@@ -57,7 +55,7 @@
SignatureShaker(this.typeFlowAnalysis, this.tableSelectorAssigner);
- _ProcedureInfo _infoForMember(Member member) {
+ _ProcedureInfo? _infoForMember(Member member) {
if (!(member is Procedure &&
(member.kind == ProcedureKind.Method ||
member.kind == ProcedureKind.Factory) ||
@@ -89,7 +87,7 @@
}
while (worklist.isNotEmpty) {
_ParameterInfo param = worklist.removeLast();
- for (_ParameterInfo dependencyParam in param.useDependencies) {
+ for (_ParameterInfo dependencyParam in param.useDependencies!) {
if (!dependencyParam.isRead) {
dependencyParam.isRead = true;
if (dependencyParam.useDependencies != null) {
@@ -141,7 +139,7 @@
return positional.any((param) =>
param.canBeEliminated ||
(param.isAlwaysPassed &&
- param.index >= function.requiredParameterCount)) ||
+ param.index! >= function.requiredParameterCount)) ||
named.values
.any((param) => param.canBeEliminated || param.isAlwaysPassed);
}
@@ -149,7 +147,7 @@
class _ParameterInfo {
final _ProcedureInfo info;
- final int index;
+ final int? index;
int passCount = 0;
bool isRead = false;
@@ -160,7 +158,7 @@
/// List of parameter variables which were passed as arguments via this
/// parameter. When this parameter is considered used, all [useDependencies]
/// parameters should be transitively marked as read.
- List<_ParameterInfo> useDependencies = null;
+ List<_ParameterInfo>? useDependencies = null;
_ParameterInfo(this.info, this.index);
@@ -177,7 +175,7 @@
void observeParameter(
Member member, VariableDeclaration param, SignatureShaker shaker) {
- final Type type = shaker.typeFlowAnalysis.argumentType(member, param);
+ final Type? type = shaker.typeFlowAnalysis.argumentType(member, param);
// A parameter is considered constant if the TFA has inferred it to have a
// constant value in every implementation. The constant value inferred does
@@ -214,19 +212,19 @@
_Collect(this.shaker);
void enterFunction(Member member) {
- final _ProcedureInfo info = shaker._infoForMember(member);
+ final _ProcedureInfo? info = shaker._infoForMember(member);
if (info == null) return;
localParameters.clear();
useDependencies.clear();
- final FunctionNode fun = member.function;
+ final FunctionNode fun = member.function!;
for (int i = 0; i < fun.positionalParameters.length; i++) {
final VariableDeclaration param = fun.positionalParameters[i];
localParameters[param] = info.ensurePositional(i)
..observeParameter(member, param, shaker);
}
for (VariableDeclaration param in fun.namedParameters) {
- localParameters[param] = info.ensureNamed(param.name)
+ localParameters[param] = info.ensureNamed(param.name!)
..observeParameter(member, param, shaker);
}
@@ -270,19 +268,22 @@
void addUseDependency(Expression arg, _ParameterInfo param) {
if (arg is VariableGet) {
- _ParameterInfo localParam = localParameters[arg.variable];
+ _ParameterInfo? localParam = localParameters[arg.variable];
if (localParam != null && !localParam.isUsed) {
// This is a parameter passed as an argument. Mark it as a use
// dependency.
- param.useDependencies ??= [];
- param.useDependencies.add(localParam);
+ var paramUseDependencies = param.useDependencies;
+ if (paramUseDependencies == null) {
+ param.useDependencies = paramUseDependencies = [];
+ }
+ paramUseDependencies.add(localParam);
useDependencies.add(arg);
}
}
}
void collectCall(Member member, Arguments args) {
- final _ProcedureInfo info = shaker._infoForMember(member);
+ final _ProcedureInfo? info = shaker._infoForMember(member);
if (info == null) return;
for (int i = 0; i < args.positional.length; i++) {
@@ -306,7 +307,10 @@
@override
void visitSuperMethodInvocation(SuperMethodInvocation node) {
- collectCall(node.interfaceTarget, node.arguments);
+ final interfaceTarget = node.interfaceTarget;
+ if (interfaceTarget != null) {
+ collectCall(interfaceTarget, node.arguments);
+ }
super.visitSuperMethodInvocation(node);
}
@@ -338,7 +342,7 @@
class _Transform extends RecursiveVisitor {
final SignatureShaker shaker;
- StaticTypeContext typeContext;
+ late StaticTypeContext typeContext;
final Map<VariableDeclaration, Constant> eliminatedParams = {};
final Set<VariableDeclaration> unusedParams = {};
final List<LocalInitializer> addedInitializers = [];
@@ -349,16 +353,15 @@
Member member, _ParameterInfo param, VariableDeclaration variable) {
Constant value;
if (param.isConstant) {
- Type type = shaker.typeFlowAnalysis.argumentType(member, variable);
+ Type type = shaker.typeFlowAnalysis.argumentType(member, variable)!;
if (type is ConcreteType) {
- assert(type.constant != null);
- value = type.constant;
+ value = type.constant!;
} else {
assert(type is NullableType && type.baseType is EmptyType);
value = NullConstant();
}
} else {
- value = (variable.initializer as ConstantExpression)?.constant ??
+ value = (variable.initializer as ConstantExpression?)?.constant ??
NullConstant();
}
eliminatedParams[variable] = value;
@@ -370,10 +373,10 @@
eliminatedParams.clear();
unusedParams.clear();
- final _ProcedureInfo info = shaker._infoForMember(member);
+ final _ProcedureInfo? info = shaker._infoForMember(member);
if (info == null || !info.eligible || info.callCount == 0) return;
- final FunctionNode function = member.function;
+ final FunctionNode function = member.function!;
if (!info.transformNeeded(function)) return;
@@ -404,9 +407,9 @@
// as required positional parameters, alphabetically by name.
final List<VariableDeclaration> sortedNamed = function.namedParameters
.toList()
- ..sort((var1, var2) => var1.name.compareTo(var2.name));
+ ..sort((var1, var2) => var1.name!.compareTo(var2.name!));
for (VariableDeclaration variable in sortedNamed) {
- final _ParameterInfo param = info.named[variable.name];
+ final _ParameterInfo param = info.named[variable.name!]!;
if (param.isAlwaysPassed) {
if (param.isUsed) {
if (param.canBeEliminated) {
@@ -451,7 +454,7 @@
// 4. All named parameters that are not always passed and can't be
// eliminated, as named parameters in alphabetical order.
for (VariableDeclaration variable in sortedNamed) {
- final _ParameterInfo param = info.named[variable.name];
+ final _ParameterInfo param = info.named[variable.name!]!;
if (!param.isAlwaysPassed) {
if (param.isUsed) {
if (param.canBeEliminated) {
@@ -475,7 +478,7 @@
@override
void visitVariableGet(VariableGet node) {
- Constant constantValue = eliminatedParams[node.variable];
+ Constant? constantValue = eliminatedParams[node.variable];
if (constantValue != null) {
node.replaceWith(ConstantExpression(constantValue));
}
@@ -511,7 +514,7 @@
void Function(Expression, _ParameterInfo) fun) {
for (int i = args.named.length - 1; i >= 0; i--) {
final NamedExpression namedExp = args.named[i];
- fun(namedExp.value, info.named[namedExp.name]);
+ fun(namedExp.value, info.named[namedExp.name]!);
}
for (int i = args.positional.length - 1; i >= 0; i--) {
fun(args.positional[i], info.positional[i]);
@@ -519,8 +522,8 @@
}
void transformCall(
- Member target, TreeNode call, Expression receiver, Arguments args) {
- final _ProcedureInfo info = shaker._infoForMember(target);
+ Member target, TreeNode call, Expression? receiver, Arguments args) {
+ final _ProcedureInfo? info = shaker._infoForMember(target);
if (info == null || !info.eligible) return;
bool transformNeeded = false;
@@ -544,7 +547,7 @@
Map<Expression, VariableDeclaration> hoisted = {};
if (hoistingNeeded) {
if (call is Initializer) {
- final Constructor constructor = call.parent;
+ final Constructor constructor = call.parent as Constructor;
forEachArgumentRev(args, info, (Expression arg, _ParameterInfo param) {
if (mayHaveOrSeeSideEffects(arg) && !isUnusedParam(arg)) {
VariableDeclaration argVar = VariableDeclaration(null,
@@ -557,8 +560,8 @@
}
});
} else {
- final TreeNode parent = call.parent;
- Expression current = call;
+ final TreeNode parent = call.parent!;
+ Expression current = call as Expression;
forEachArgumentRev(args, info, (Expression arg, _ParameterInfo param) {
if (mayHaveOrSeeSideEffects(arg) && !isUnusedParam(arg)) {
VariableDeclaration argVar = VariableDeclaration(null,
@@ -606,7 +609,7 @@
final List<NamedExpression> sortedNamed = args.named.toList()
..sort((var1, var2) => var1.name.compareTo(var2.name));
for (NamedExpression arg in sortedNamed) {
- final _ParameterInfo param = info.named[arg.name];
+ final _ParameterInfo param = info.named[arg.name]!;
if (param.isAlwaysPassed && !param.canBeEliminated) {
positional.add(getMaybeHoistedArg(arg.value));
}
@@ -625,7 +628,7 @@
// eliminated, as named parameters in alphabetical order.
// (Arguments are kept in original order.)
for (NamedExpression arg in args.named) {
- final _ParameterInfo param = info.named[arg.name];
+ final _ParameterInfo param = info.named[arg.name]!;
if (!param.isAlwaysPassed && !param.canBeEliminated) {
arg.value = getMaybeHoistedArg(arg.value)..parent = arg;
named.add(arg);
@@ -644,7 +647,10 @@
@override
void visitSuperMethodInvocation(SuperMethodInvocation node) {
super.visitSuperMethodInvocation(node);
- transformCall(node.interfaceTarget, node, null, node.arguments);
+ final interfaceTarget = node.interfaceTarget;
+ if (interfaceTarget != null) {
+ transformCall(interfaceTarget, node, null, node.arguments);
+ }
}
@override
diff --git a/pkg/vm/lib/transformations/type_flow/summary.dart b/pkg/vm/lib/transformations/type_flow/summary.dart
index dcae2df..fb18cec 100644
--- a/pkg/vm/lib/transformations/type_flow/summary.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary.dart
@@ -2,10 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
/// Type flow summary of a member, function or initializer.
-library vm.transformations.type_flow.summary;
import 'dart:core' hide Type;
@@ -18,7 +15,7 @@
abstract class CallHandler {
Type applyCall(Call callSite, Selector selector, Args<Type> args,
- {bool isResultUsed});
+ {required bool isResultUsed});
void typeCheckTriggered();
void addAllocatedClass(Class c);
}
@@ -27,14 +24,10 @@
abstract class Statement extends TypeExpr {
/// Index of this statement in the [Summary].
int index = -1;
- Summary summary;
+ late Summary summary;
@override
- Type getComputedType(List<Type> types) {
- final type = types[index];
- assert(type != null);
- return type;
- }
+ Type getComputedType(List<Type?> types) => types[index]!;
String get label => "t$index";
@@ -48,7 +41,7 @@
void accept(StatementVisitor visitor);
/// Execute this statement and compute its resulting type.
- Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+ Type apply(List<Type?> computedTypes, TypeHierarchy typeHierarchy,
CallHandler callHandler);
}
@@ -74,9 +67,9 @@
// [staticType] is null if no narrowing should be performed. This happens for
// type parameters and for parameters whose type is narrowed by a [TypeCheck]
// statement.
- final Type staticTypeForNarrowing;
+ final Type? staticTypeForNarrowing;
- Type defaultValue;
+ Type? defaultValue;
Type _argumentType = const EmptyType();
Parameter(this.name, this.staticTypeForNarrowing);
@@ -97,7 +90,7 @@
}
@override
- Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+ Type apply(List<Type?> computedTypes, TypeHierarchy typeHierarchy,
CallHandler callHandler) =>
throw 'Unable to apply _Parameter';
@@ -110,7 +103,7 @@
}
Type _observeNotPassed(TypeHierarchy typeHierarchy) {
- final Type argType = defaultValue.specialize(typeHierarchy);
+ final Type argType = defaultValue!.specialize(typeHierarchy);
_observeArgumentType(argType, typeHierarchy);
return argType;
}
@@ -130,7 +123,7 @@
String dump() => "$label = _Narrow ($arg to $type)";
@override
- Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+ Type apply(List<Type?> computedTypes, TypeHierarchy typeHierarchy,
CallHandler callHandler) =>
arg.getComputedType(computedTypes).intersection(type, typeHierarchy);
}
@@ -147,11 +140,11 @@
// Shared NarrowNotNull instances which are used when the outcome is
// known at summary creation time.
- static final NarrowNotNull alwaysNotNull = NarrowNotNull(null)
+ static final NarrowNotNull alwaysNotNull = NarrowNotNull(const EmptyType())
.._flags = canBeNotNullFlag;
- static final NarrowNotNull alwaysNull = NarrowNotNull(null)
+ static final NarrowNotNull alwaysNull = NarrowNotNull(const EmptyType())
.._flags = canBeNullFlag;
- static final NarrowNotNull unknown = NarrowNotNull(null)
+ static final NarrowNotNull unknown = NarrowNotNull(const EmptyType())
.._flags = canBeNullFlag | canBeNotNullFlag;
bool get isAlwaysNull => (_flags & canBeNotNullFlag) == 0;
@@ -173,14 +166,14 @@
}
@override
- Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+ Type apply(List<Type?> computedTypes, TypeHierarchy typeHierarchy,
CallHandler callHandler) =>
handleArgument(arg.getComputedType(computedTypes));
}
/// Joins values from multiple sources. Its type is a union of [values].
class Join extends Statement {
- final String _name;
+ final String? _name;
final DartType staticType;
final List<TypeExpr> values = <TypeExpr>[]; // TODO(alexmarkov): Set
@@ -197,15 +190,14 @@
" (${values.join(", ")})";
@override
- Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+ Type apply(List<Type?> computedTypes, TypeHierarchy typeHierarchy,
CallHandler callHandler) {
- Type type = null;
- assert(values.isNotEmpty);
+ Type? type = null;
for (var value in values) {
final valueType = value.getComputedType(computedTypes);
type = type != null ? type.union(valueType, typeHierarchy) : valueType;
}
- return type;
+ return type!;
}
}
@@ -222,7 +214,7 @@
String dump() => "$label = _Use ($arg)";
@override
- Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+ Type apply(List<Type?> computedTypes, TypeHierarchy typeHierarchy,
CallHandler callHandler) =>
throw 'Use statements should be removed during summary normalization';
}
@@ -231,7 +223,7 @@
class Call extends Statement {
final Selector selector;
final Args<TypeExpr> args;
- final Type staticResultType;
+ final Type? staticResultType;
Call(this.selector, this.args, this.staticResultType,
bool isInstanceCreation) {
@@ -252,9 +244,10 @@
String dump() => "$label${isResultUsed ? '*' : ''} = _Call $selector $args";
@override
- Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+ Type apply(List<Type?> computedTypes, TypeHierarchy typeHierarchy,
CallHandler callHandler) {
- final List<Type> argTypes = new List<Type>.filled(args.values.length, null);
+ final List<Type> argTypes =
+ new List<Type>.filled(args.values.length, const EmptyType());
for (int i = 0; i < args.values.length; i++) {
final Type type = args.values[i].getComputedType(computedTypes);
if (type == const EmptyType()) {
@@ -271,14 +264,15 @@
callHandler
.addAllocatedClass((argTypes[0] as ConcreteType).cls.classNode);
}
- final Stopwatch timer = kPrintTimings ? (new Stopwatch()..start()) : null;
+ final Stopwatch? timer = kPrintTimings ? (new Stopwatch()..start()) : null;
Type result = callHandler.applyCall(
this, selector, new Args<Type>(argTypes, names: args.names),
isResultUsed: isResultUsed);
- summary.calleeTime += kPrintTimings ? timer.elapsedMicroseconds : 0;
+ summary.calleeTime += kPrintTimings ? timer!.elapsedMicroseconds : 0;
if (isInstanceCreation) {
result = argTypes[0];
} else if (isResultUsed) {
+ final staticResultType = this.staticResultType;
if (staticResultType != null) {
result = result.intersection(staticResultType, typeHierarchy);
}
@@ -302,9 +296,9 @@
static const int kReceiverMayBeInt = (1 << 6);
static const int kInstanceCreation = (1 << 7);
- Member _monomorphicTarget;
+ Member? _monomorphicTarget;
- Member get monomorphicTarget => _monomorphicTarget;
+ Member? get monomorphicTarget => _monomorphicTarget;
bool get isMonomorphic => (_flags & kMonomorphic) != 0;
@@ -396,18 +390,19 @@
"/$paramIndex]${nullability.suffix})";
@override
- Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+ Type apply(List<Type?> computedTypes, TypeHierarchy typeHierarchy,
CallHandler callHandler) {
Type argType = arg.getComputedType(computedTypes);
- Type extractedType;
+ Type? extractedType;
void extractType(ConcreteType c) {
- if (c.typeArgs == null) {
+ final typeArgs = c.typeArgs;
+ if (typeArgs == null) {
extractedType = const UnknownType();
} else {
final interfaceOffset = typeHierarchy.genericInterfaceOffsetFor(
c.cls.classNode, referenceClass);
- final typeArg = c.typeArgs[interfaceOffset + paramIndex];
+ final typeArg = typeArgs[interfaceOffset + paramIndex];
Type extracted = typeArg;
if (typeArg is RuntimeType) {
final argNullability = typeArg.nullability;
@@ -472,16 +467,15 @@
}
@override
- Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+ Type apply(List<Type?> computedTypes, TypeHierarchy typeHierarchy,
CallHandler callHandler) {
bool hasRuntimeType = false;
- final types = new List<Type>.filled(flattenedTypeArgs.length, null);
- for (int i = 0; i < types.length; ++i) {
+ final types = List<Type>.generate(flattenedTypeArgs.length, (int i) {
final computed = flattenedTypeArgs[i].getComputedType(computedTypes);
assert(computed is RuntimeType || computed is UnknownType);
if (computed is RuntimeType) hasRuntimeType = true;
- types[i] = computed;
- }
+ return computed;
+ });
return new ConcreteType(cls, hasRuntimeType ? types : null);
}
}
@@ -505,14 +499,13 @@
"${nullability.suffix})";
@override
- Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+ Type apply(List<Type?> computedTypes, TypeHierarchy typeHierarchy,
CallHandler callHandler) {
- final types = new List<RuntimeType>.filled(flattenedTypeArgs.length, null);
- for (int i = 0; i < types.length; ++i) {
- final computed = flattenedTypeArgs[i].getComputedType(computedTypes);
- assert(computed is RuntimeType || computed is UnknownType);
+ final types = <RuntimeType>[];
+ for (TypeExpr arg in flattenedTypeArgs) {
+ final computed = arg.getComputedType(computedTypes);
if (computed is UnknownType) return const UnknownType();
- types[i] = computed;
+ types.add(computed as RuntimeType);
}
DartType dartType;
if (klass == typeHierarchy.coreTypes.deprecatedFutureOrClass) {
@@ -545,17 +538,15 @@
// "unchecked" entrypoint.
bool isTestedOnlyOnCheckedEntryPoint;
- VariableDeclaration get parameter =>
- node is VariableDeclaration ? node : null;
+ bool get isParameterCheck => node is VariableDeclaration;
+ VariableDeclaration get parameterVariable => node as VariableDeclaration;
bool alwaysPass = true;
bool alwaysFail = true;
- TypeCheck(this.arg, this.type, this.node, this.staticType, this.kind) {
- assert(node != null);
- isTestedOnlyOnCheckedEntryPoint =
- parameter != null && !parameter.isCovariant;
- }
+ TypeCheck(this.arg, this.type, this.node, this.staticType, this.kind)
+ : isTestedOnlyOnCheckedEntryPoint =
+ node is VariableDeclaration && !node.isCovariant;
@override
void accept(StatementVisitor visitor) => visitor.visitTypeCheck(this);
@@ -568,7 +559,7 @@
}
@override
- Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+ Type apply(List<Type?> computedTypes, TypeHierarchy typeHierarchy,
CallHandler callHandler) {
Type argType = arg.getComputedType(computedTypes);
Type checkType = type.getComputedType(computedTypes);
@@ -624,11 +615,11 @@
int requiredParameterCount;
List<Statement> _statements = <Statement>[];
- TypeExpr result = null;
- Type resultType = EmptyType();
+ TypeExpr result = const EmptyType();
+ Type resultType = const EmptyType();
// Analysis time of callees. Populated only if kPrintTimings.
- int calleeTime;
+ int calleeTime = 0;
Summary(this.name,
{this.parameterCount: 0,
@@ -658,7 +649,7 @@
/// Apply this summary to the given arguments and return the resulting type.
Type apply(Args<Type> arguments, TypeHierarchy typeHierarchy,
CallHandler callHandler) {
- final Stopwatch timer = kPrintTimings ? (new Stopwatch()..start()) : null;
+ final Stopwatch? timer = kPrintTimings ? (new Stopwatch()..start()) : null;
final int oldCalleeTime = calleeTime;
calleeTime = 0;
final args = arguments.values;
@@ -677,7 +668,7 @@
//
// The first `parameterCount` statements are Parameters.
- List<Type> types = new List<Type>.filled(_statements.length, null);
+ List<Type?> types = new List<Type?>.filled(_statements.length, null);
for (int i = 0; i < positionalArgCount; i++) {
final Parameter param = _statements[i] as Parameter;
@@ -687,9 +678,9 @@
}
final argType = args[i].specialize(typeHierarchy);
param._observeArgumentType(argType, typeHierarchy);
- if (param.staticTypeForNarrowing != null) {
- types[i] =
- argType.intersection(param.staticTypeForNarrowing, typeHierarchy);
+ final staticTypeForNarrowing = param.staticTypeForNarrowing;
+ if (staticTypeForNarrowing != null) {
+ types[i] = argType.intersection(staticTypeForNarrowing, typeHierarchy);
} else {
// TODO(sjindel/tfa): Narrowing is performed inside a [TypeCheck] later.
types[i] = args[i];
@@ -710,9 +701,10 @@
args[positionalArgCount + argIndex].specialize(typeHierarchy);
argIndex++;
param._observeArgumentType(argType, typeHierarchy);
- if (param.staticTypeForNarrowing != null) {
+ final staticTypeForNarrowing = param.staticTypeForNarrowing;
+ if (staticTypeForNarrowing != null) {
types[i] =
- argType.intersection(param.staticTypeForNarrowing, typeHierarchy);
+ argType.intersection(staticTypeForNarrowing, typeHierarchy);
} else {
types[i] = argType;
}
@@ -741,7 +733,7 @@
resultType = resultType.union(computedType, typeHierarchy);
if (kPrintTimings) {
- final dirtyTime = timer.elapsedMicroseconds;
+ final dirtyTime = timer!.elapsedMicroseconds;
final pureTime = dirtyTime < calleeTime ? 0 : (dirtyTime - calleeTime);
Statistics.numSummaryApplications.add(name);
Statistics.dirtySummaryAnalysisTime.add(name, dirtyTime);
@@ -753,9 +745,9 @@
}
Args<Type> get argumentTypes {
- final argTypes = new List<Type>.filled(parameterCount, null);
- final argNames = new List<String>.filled(
- parameterCount - positionalParameterCount, null);
+ final argTypes = new List<Type>.filled(parameterCount, const EmptyType());
+ final argNames =
+ new List<String>.filled(parameterCount - positionalParameterCount, '');
for (int i = 0; i < parameterCount; i++) {
Parameter param = _statements[i] as Parameter;
argTypes[i] = param.argumentType;
@@ -769,7 +761,7 @@
Type argumentType(Member member, VariableDeclaration memberParam) {
final int firstParamIndex =
numTypeParams(member) + (hasReceiverArg(member) ? 1 : 0);
- final positional = member.function.positionalParameters;
+ final positional = member.function!.positionalParameters;
for (int i = 0; i < positional.length; i++) {
if (positional[i] == memberParam) {
final Parameter param = _statements[firstParamIndex + i] as Parameter;
@@ -791,8 +783,8 @@
for (Statement statement in _statements) {
if (statement is TypeCheck &&
statement.alwaysPass &&
- statement.parameter != null) {
- params.add(statement.parameter);
+ statement.isParameterCheck) {
+ params.add(statement.parameterVariable);
}
}
return params;
@@ -808,17 +800,17 @@
(hasReceiverArg(member) ? 1 : 0) + numTypeParams(member);
final Map<String, Parameter> paramsByName = {};
for (int i = implicit; i < parameterCount; i++) {
- final Parameter param = statements[i];
+ final Parameter param = statements[i] as Parameter;
paramsByName[param.name] = param;
}
- FunctionNode function = member.function;
+ FunctionNode function = member.function!;
statements.length = implicit;
for (VariableDeclaration param in function.positionalParameters) {
- statements.add(paramsByName[param.name]);
+ statements.add(paramsByName[param.name]!);
}
positionalParameterCount = statements.length;
for (VariableDeclaration param in function.namedParameters) {
- statements.add(paramsByName[param.name]);
+ statements.add(paramsByName[param.name]!);
}
parameterCount = statements.length;
requiredParameterCount = implicit + function.requiredParameterCount;
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index cd78792..d2157f7 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -2,10 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
/// Creation of type flow summaries out of kernel AST.
-library vm.transformations.type_flow.summary_collector;
import 'dart:core' hide Type;
@@ -14,6 +11,7 @@
import 'package:kernel/ast.dart' as ast show Statement, StatementVisitor;
import 'package:kernel/class_hierarchy.dart'
show ClassHierarchy, ClosedWorldClassHierarchy;
+import 'package:kernel/core_types.dart' show CoreTypes;
import 'package:kernel/type_environment.dart'
show StaticTypeContext, SubtypeCheckMode, TypeEnvironment;
import 'package:kernel/type_algebra.dart' show Substitution;
@@ -239,7 +237,7 @@
// function and checks if control can fall through them or not.
bool controlCanFallThrough(FunctionNode function) {
- return function.body.accept(this);
+ return function.body!.accept(this);
}
@override
@@ -285,11 +283,11 @@
bool visitContinueSwitchStatement(ContinueSwitchStatement node) => false;
@override
- bool visitIfStatement(IfStatement node) =>
- node.then == null ||
- node.otherwise == null ||
- node.then.accept(this) ||
- node.otherwise.accept(this);
+ bool visitIfStatement(IfStatement node) {
+ final otherwise = node.otherwise;
+ if (otherwise == null) return true;
+ return node.then.accept(this) || otherwise.accept(this);
+ }
@override
bool visitReturnStatement(ReturnStatement node) => false;
@@ -323,7 +321,7 @@
final List<VariableDeclaration> varDeclarations = <VariableDeclaration>[];
/// Set of captured variables.
- Set<VariableDeclaration> captured;
+ Set<VariableDeclaration>? captured;
/// Set of variables which were modified for each loop, switch statement
/// and try block statement. Doesn't include captured variables and
@@ -334,10 +332,10 @@
int numVariablesAtFunctionEntry = 0;
/// Active loops, switch statements and try blocks.
- List<ast.Statement> activeStatements;
+ List<ast.Statement>? activeStatements;
/// Number of variables at entry of active statements.
- List<int> numVariablesAtActiveStatements;
+ List<int>? numVariablesAtActiveStatements;
_VariablesInfoCollector(Member member) {
member.accept(this);
@@ -345,8 +343,10 @@
int get numVariables => varDeclarations.length;
- bool isCaptured(VariableDeclaration variable) =>
- captured != null && captured.contains(variable);
+ bool isCaptured(VariableDeclaration variable) {
+ final captured = this.captured;
+ return captured != null && captured.contains(variable);
+ }
Set<int> getModifiedVariables(ast.Statement st) {
return modifiedSets[st] ?? const <int>{};
@@ -387,14 +387,15 @@
}
void _useVariable(VariableDeclaration variable, bool isVarAssignment) {
- final index = varIndex[variable];
+ final index = varIndex[variable]!;
if (_isDeclaredBefore(index, numVariablesAtFunctionEntry)) {
_captureVariable(variable);
return;
}
+ final activeStatements = this.activeStatements;
if (isVarAssignment && activeStatements != null) {
for (int i = activeStatements.length - 1; i >= 0; --i) {
- if (_isDeclaredBefore(index, numVariablesAtActiveStatements[i])) {
+ if (_isDeclaredBefore(index, numVariablesAtActiveStatements![i])) {
final st = activeStatements[i];
(modifiedSets[st] ??= <int>{}).add(index);
} else {
@@ -410,8 +411,8 @@
}
void _endCollectingModifiedVariables() {
- activeStatements.removeLast();
- numVariablesAtActiveStatements.removeLast();
+ activeStatements!.removeLast();
+ numVariablesAtActiveStatements!.removeLast();
}
@override
@@ -457,7 +458,7 @@
@override
visitTryCatch(TryCatch node) {
_startCollectingModifiedVariables(node);
- node.body?.accept(this);
+ node.body.accept(this);
_endCollectingModifiedVariables();
visitList(node.catches, this);
}
@@ -465,9 +466,9 @@
@override
visitTryFinally(TryFinally node) {
_startCollectingModifiedVariables(node);
- node.body?.accept(this);
+ node.body.accept(this);
_endCollectingModifiedVariables();
- node.finalizer?.accept(this);
+ node.finalizer.accept(this);
}
@override
@@ -489,7 +490,7 @@
visitList(node.variables, this);
_startCollectingModifiedVariables(node);
node.condition?.accept(this);
- node.body?.accept(this);
+ node.body.accept(this);
visitList(node.updates, this);
_endCollectingModifiedVariables();
}
@@ -521,7 +522,7 @@
enum FieldSummaryType { kFieldGuard, kInitializer }
/// Create a type flow summary for a member from the kernel AST.
-class SummaryCollector extends RecursiveResultVisitor<TypeExpr> {
+class SummaryCollector extends RecursiveResultVisitor<TypeExpr?> {
final Target target;
final TypeEnvironment _environment;
final ClosedWorldClassHierarchy _hierarchy;
@@ -529,7 +530,7 @@
final TypesBuilder _typesBuilder;
final NativeCodeOracle _nativeCodeOracle;
final GenericInterfacesInfo _genericInterfacesInfo;
- final ProtobufHandler _protobufHandler;
+ final ProtobufHandler? _protobufHandler;
final Map<TreeNode, Call> callSites = <TreeNode, Call>{};
final Map<AsExpression, TypeCheck> explicitCasts =
@@ -540,13 +541,13 @@
final Set<Name> _nullMethodsAndGetters = <Name>{};
final Set<Name> _nullSetters = <Name>{};
- Summary _summary;
- _VariablesInfoCollector _variablesInfo;
+ Summary _summary = Summary('<unused>');
+ late _VariablesInfoCollector _variablesInfo;
// Current value of each variable. May contain null if variable is not
// declared yet, or EmptyType if current location is unreachable
// (e.g. after return or throw).
- List<TypeExpr> _variableValues;
+ List<TypeExpr?> _variableValues = const <TypeExpr?>[];
// Contains Joins which accumulate all values of certain variables.
// Used only when all variable values should be merged regardless of control
@@ -558,30 +559,30 @@
// If _variableCells[i] != null, then all values are accumulated in the
// _variableCells[i]. _variableValues[i] does not change and remains equal
// to _variableCells[i].
- List<Join> _variableCells;
+ List<Join?> _variableCells = const <Join?>[];
// Counts number of Joins inserted for each variable. Only used to set
// readable names for such joins (foo_0, foo_1 etc.)
- List<int> _variableVersions;
+ List<int> _variableVersions = const <int>[];
// State of variables after corresponding LabeledStatement.
// Used to collect states from BreakStatements.
- Map<LabeledStatement, List<TypeExpr>> _variableValuesAfterLabeledStatements;
+ Map<LabeledStatement, List<TypeExpr?>>? _variableValuesAfterLabeledStatements;
// Joins corresponding to variables on entry to switch cases.
// Used to propagate state from ContinueSwitchStatement to a target case.
- Map<SwitchCase, List<Join>> _joinsAtSwitchCases;
+ Map<SwitchCase, List<Join?>>? _joinsAtSwitchCases;
// Join which accumulates all return values.
- Join _returnValue;
+ Join? _returnValue;
- Parameter _receiver;
- ConstantAllocationCollector constantAllocationCollector;
- RuntimeTypeTranslatorImpl _translator;
- StaticTypeContext _staticTypeContext;
+ Parameter? _receiver;
+ late ConstantAllocationCollector constantAllocationCollector;
+ late RuntimeTypeTranslatorImpl _translator;
+ StaticTypeContext? _staticTypeContext;
// Currently only used for factory constructors.
- Map<TypeParameter, TypeExpr> _fnTypeVariables;
+ Map<TypeParameter, TypeExpr>? _fnTypeVariables;
SummaryCollector(
this.target,
@@ -592,7 +593,6 @@
this._nativeCodeOracle,
this._genericInterfacesInfo,
this._protobufHandler) {
- assert(_genericInterfacesInfo != null);
constantAllocationCollector = new ConstantAllocationCollector(this);
_nullMethodsAndGetters.addAll(getSelectors(
_hierarchy, _environment.coreTypes.deprecatedNullClass,
@@ -615,8 +615,8 @@
_staticTypeContext = new StaticTypeContext(member, _environment);
_variablesInfo = new _VariablesInfoCollector(member);
_variableValues =
- new List<TypeExpr>.filled(_variablesInfo.numVariables, null);
- _variableCells = new List<Join>.filled(_variablesInfo.numVariables, null);
+ new List<TypeExpr?>.filled(_variablesInfo.numVariables, null);
+ _variableCells = new List<Join?>.filled(_variablesInfo.numVariables, null);
_variableVersions = new List<int>.filled(_variablesInfo.numVariables, 0);
_variableValuesAfterLabeledStatements = null;
_joinsAtSwitchCases = null;
@@ -633,25 +633,24 @@
parameterCount: numArgs, positionalParameterCount: numArgs);
// TODO(alexmarkov): subclass cone
_receiver = _declareParameter("this",
- _environment.coreTypes.legacyRawType(member.enclosingClass), null,
+ _environment.coreTypes.legacyRawType(member.enclosingClass!), null,
isReceiver: true);
} else {
_summary = new Summary(summaryName);
}
- _translator = new RuntimeTypeTranslatorImpl(
- this, _summary, _receiver, null, _genericInterfacesInfo);
+ _translator = new RuntimeTypeTranslatorImpl(_environment.coreTypes,
+ _summary, _receiver, null, _genericInterfacesInfo);
if (fieldSummaryType == FieldSummaryType.kInitializer) {
- assert(member.initializer != null);
- _summary.result = _visit(member.initializer);
+ _summary.result = _visit(member.initializer!);
} else {
final Parameter valueParam =
_declareParameter("value", member.type, null);
_summary.result = _typeCheck(valueParam, member.type, member);
}
} else {
- FunctionNode function = member.function;
+ final FunctionNode function = member.function!;
final numTypeParameters = numTypeParams(member);
final firstParamIndex = (hasReceiver ? 1 : 0) + numTypeParameters;
@@ -666,43 +665,42 @@
firstParamIndex + function.requiredParameterCount);
if (numTypeParameters > 0) {
- _fnTypeVariables = <TypeParameter, TypeExpr>{};
- for (int i = 0; i < numTypeParameters; ++i) {
- _fnTypeVariables[function.typeParameters[i]] =
- _declareParameter(function.typeParameters[i].name, null, null);
- }
+ _fnTypeVariables = <TypeParameter, TypeExpr>{
+ for (TypeParameter tp in function.typeParameters)
+ tp: _declareParameter(tp.name!, null, null)
+ };
}
if (hasReceiver) {
// TODO(alexmarkov): subclass cone
_receiver = _declareParameter("this",
- _environment.coreTypes.legacyRawType(member.enclosingClass), null,
+ _environment.coreTypes.legacyRawType(member.enclosingClass!), null,
isReceiver: true);
}
- _translator = new RuntimeTypeTranslatorImpl(
- this, _summary, _receiver, _fnTypeVariables, _genericInterfacesInfo);
+ _translator = new RuntimeTypeTranslatorImpl(_environment.coreTypes,
+ _summary, _receiver, _fnTypeVariables, _genericInterfacesInfo);
// Handle forwarding stubs. We need to check types against the types of
// the forwarding stub's target, [member.concreteForwardingStubTarget].
- FunctionNode useTypesFrom = member.function;
- if (member is Procedure &&
- member.isForwardingStub &&
- member.concreteForwardingStubTarget != null) {
+ FunctionNode useTypesFrom = function;
+ if (member is Procedure && member.isForwardingStub) {
final target = member.concreteForwardingStubTarget;
- if (target is Field) {
- useTypesFrom = FunctionNode(null, positionalParameters: [
- VariableDeclaration("value", type: target.type)
- ]);
- } else {
- useTypesFrom = member.concreteForwardingStubTarget.function;
+ if (target != null) {
+ if (target is Field) {
+ useTypesFrom = FunctionNode(null, positionalParameters: [
+ VariableDeclaration("value", type: target.type)
+ ]);
+ } else {
+ useTypesFrom = target.function!;
+ }
}
}
for (int i = 0; i < function.positionalParameters.length; ++i) {
final decl = function.positionalParameters[i];
_declareParameter(
- decl.name,
+ decl.name!,
_useTypeCheckForParameter(decl)
? null
: useTypesFrom.positionalParameters[i].type,
@@ -711,7 +709,7 @@
for (int i = 0; i < function.namedParameters.length; ++i) {
final decl = function.namedParameters[i];
_declareParameter(
- decl.name,
+ decl.name!,
_useTypeCheckForParameter(decl)
? null
: useTypesFrom.namedParameters[i].type,
@@ -740,7 +738,7 @@
assert(count == _summary.parameterCount);
_returnValue = new Join("%result", function.returnType);
- _summary.add(_returnValue);
+ _summary.add(_returnValue!);
if (member is Constructor) {
// Make sure instance field initializers are visited.
@@ -750,7 +748,7 @@
new DirectSelector(f, callKind: CallKind.FieldInitializer));
}
}
- member.initializers.forEach(_visit);
+ member.initializers.forEach(_visitWithoutResult);
}
if (function.body == null) {
@@ -760,15 +758,15 @@
// Runtime type could be more precise than static type, so
// calculate intersection.
final typeCheck = _typeCheck(type, function.returnType, function);
- _returnValue.values.add(typeCheck);
+ _returnValue!.values.add(typeCheck);
} else {
- _returnValue.values.add(type);
+ _returnValue!.values.add(type);
}
} else {
- _visit(function.body);
+ _visitWithoutResult(function.body!);
if (_fallthroughDetector.controlCanFallThrough(function)) {
- _returnValue.values.add(_nullType);
+ _returnValue!.values.add(_nullType);
}
}
@@ -776,15 +774,15 @@
// In addition to what is returned from the function body,
// operator == performs implicit comparison with null
// and returns bool.
- _returnValue.values.add(_boolType);
+ _returnValue!.values.add(_boolType);
}
- _summary.result = _returnValue;
+ _summary.result = _returnValue!;
}
member.annotations.forEach(_visit);
- member.enclosingClass?.annotations?.forEach(_visit);
- member.enclosingLibrary?.annotations?.forEach(_visit);
+ member.enclosingClass?.annotations.forEach(_visit);
+ member.enclosingLibrary.annotations.forEach(_visit);
_staticTypeContext = null;
@@ -808,9 +806,7 @@
}
Args<Type> rawArguments(Selector selector) {
- final member = selector.member;
- assert(member != null);
-
+ final member = selector.member!;
final List<Type> args = <Type>[];
final List<String> names = <String>[];
@@ -822,15 +818,14 @@
if (hasReceiverArg(member)) {
assert(member.enclosingClass != null);
final receiver =
- new ConeType(_typesBuilder.getTFClass(member.enclosingClass));
+ new ConeType(_typesBuilder.getTFClass(member.enclosingClass!));
args.add(receiver);
}
switch (selector.callKind) {
case CallKind.Method:
if (member is! Field) {
- final function = member.function;
- assert(function != null);
+ final function = member.function!;
final int paramCount = function.positionalParameters.length +
function.namedParameters.length;
@@ -840,7 +835,7 @@
if (function.namedParameters.isNotEmpty) {
for (var param in function.namedParameters) {
- names.add(param.name);
+ names.add(param.name!);
}
// TODO(dartbug.com/32292): make sure parameters are sorted in
// kernel AST and remove this sorting.
@@ -864,11 +859,15 @@
return new Args<Type>(args, names: names);
}
- TypeExpr _visit(TreeNode node) => node.accept(this);
+ TypeExpr _visit(Expression node) => node.accept(this)!;
- Args<TypeExpr> _visitArguments(TypeExpr receiver, Arguments arguments,
+ void _visitWithoutResult(TreeNode node) {
+ node.accept(this);
+ }
+
+ Args<TypeExpr> _visitArguments(TypeExpr? receiver, Arguments arguments,
{bool passTypeArguments: false}) {
- final args = <TypeExpr>[];
+ final List<TypeExpr> args = <TypeExpr>[];
if (passTypeArguments) {
for (var type in arguments.types) {
args.add(_translator.translate(type));
@@ -890,7 +889,7 @@
}
names.sort();
for (var name in names) {
- args.add(map[name]);
+ args.add(map[name]!);
}
return new Args<TypeExpr>(args, names: names);
} else {
@@ -899,9 +898,9 @@
}
Parameter _declareParameter(
- String name, DartType type, Expression initializer,
+ String name, DartType? type, Expression? initializer,
{bool isReceiver: false}) {
- Type staticType;
+ Type? staticType;
if (type != null) {
staticType = _typesBuilder.fromStaticType(type, !isReceiver);
}
@@ -916,7 +915,7 @@
} else if (initializer is BasicLiteral ||
initializer is SymbolLiteral ||
initializer is TypeLiteral) {
- param.defaultValue = _visit(initializer);
+ param.defaultValue = _visit(initializer) as Type;
} else {
throw 'Unexpected parameter $name default value ${initializer.runtimeType} $initializer';
}
@@ -930,8 +929,7 @@
}
void _declareVariable(VariableDeclaration decl, TypeExpr initialValue) {
- final int varIndex = _variablesInfo.varIndex[decl];
- assert(varIndex != null);
+ final int varIndex = _variablesInfo.varIndex[decl]!;
assert(_variablesInfo.varDeclarations[varIndex] == decl);
assert(_variableValues[varIndex] == null);
if (_variablesInfo.isCaptured(decl)) {
@@ -944,8 +942,8 @@
}
void _writeVariable(VariableDeclaration variable, TypeExpr value) {
- final int varIndex = _variablesInfo.varIndex[variable];
- final Join join = _variableCells[varIndex];
+ final int varIndex = _variablesInfo.varIndex[variable]!;
+ final Join? join = _variableCells[varIndex];
if (join != null) {
join.values.add(value);
} else {
@@ -953,11 +951,12 @@
}
}
- List<TypeExpr> _cloneVariableValues(List<TypeExpr> values) =>
- new List<TypeExpr>.from(values);
+ List<TypeExpr?> _cloneVariableValues(List<TypeExpr?> values) =>
+ new List<TypeExpr?>.from(values);
- List<TypeExpr> _makeEmptyVariableValues() {
- final values = new List<TypeExpr>.filled(_variablesInfo.numVariables, null);
+ List<TypeExpr?> _makeEmptyVariableValues() {
+ final values =
+ new List<TypeExpr?>.filled(_variablesInfo.numVariables, null);
for (int i = 0; i < values.length; ++i) {
if (_variableCells[i] != null) {
values[i] = _variableValues[i];
@@ -978,11 +977,11 @@
return join;
}
- void _mergeVariableValues(List<TypeExpr> dst, List<TypeExpr> src) {
+ void _mergeVariableValues(List<TypeExpr?> dst, List<TypeExpr?> src) {
assert(dst.length == src.length);
for (int i = 0; i < dst.length; ++i) {
- final TypeExpr dstValue = dst[i];
- final TypeExpr srcValue = src[i];
+ final TypeExpr? dstValue = dst[i];
+ final TypeExpr? srcValue = src[i];
if (identical(dstValue, srcValue)) {
continue;
}
@@ -997,21 +996,21 @@
} else if (srcValue is Join && srcValue.values.contains(dstValue)) {
dst[i] = srcValue;
} else {
- final Join join = _makeJoin(i, dst[i]);
- join.values.add(src[i]);
+ final Join join = _makeJoin(i, dstValue);
+ join.values.add(srcValue);
dst[i] = join;
}
}
}
- void _copyVariableValues(List<TypeExpr> dst, List<TypeExpr> src) {
+ void _copyVariableValues(List<TypeExpr?> dst, List<TypeExpr?> src) {
assert(dst.length == src.length);
for (int i = 0; i < dst.length; ++i) {
dst[i] = src[i];
}
}
- bool _isIdenticalState(List<TypeExpr> state1, List<TypeExpr> state2) {
+ bool _isIdenticalState(List<TypeExpr?> state1, List<TypeExpr?> state2) {
assert(state1.length == state2.length);
for (int i = 0; i < state1.length; ++i) {
if (!identical(state1[i], state2[i])) {
@@ -1021,14 +1020,14 @@
return true;
}
- List<Join> _insertJoinsForModifiedVariables(TreeNode node, bool isTry) {
- final List<Join> joins =
- new List<Join>.filled(_variablesInfo.numVariables, null);
+ List<Join?> _insertJoinsForModifiedVariables(ast.Statement node, bool isTry) {
+ final List<Join?> joins =
+ new List<Join?>.filled(_variablesInfo.numVariables, null);
for (var i in _variablesInfo.getModifiedVariables(node)) {
if (_variableCells[i] != null) {
assert(_variableCells[i] == _variableValues[i]);
} else {
- final join = _makeJoin(i, _variableValues[i]);
+ final join = _makeJoin(i, _variableValues[i]!);
joins[i] = join;
_variableValues[i] = join;
if (isTry) {
@@ -1044,7 +1043,7 @@
/// Stops accumulating values in [joins] by removing them from
/// _variableCells.
- void _restoreVariableCellsAfterTry(List<Join> joins) {
+ void _restoreVariableCellsAfterTry(List<Join?> joins) {
for (int i = 0; i < joins.length; ++i) {
if (joins[i] != null) {
assert(_variableCells[i] == joins[i]);
@@ -1053,14 +1052,14 @@
}
}
- void _mergeVariableValuesToJoins(List<TypeExpr> values, List<Join> joins) {
+ void _mergeVariableValuesToJoins(List<TypeExpr?> values, List<Join?> joins) {
for (int i = 0; i < joins.length; ++i) {
final join = joins[i];
final value = values[i];
if (join != null &&
!identical(join, value) &&
!identical(join.values.first, value)) {
- join.values.add(value);
+ join.values.add(value!);
}
}
}
@@ -1079,16 +1078,17 @@
// TODO(alexmarkov): Avoid declaring variables with static types.
void _declareVariableWithStaticType(VariableDeclaration decl) {
- if (decl.initializer != null) {
- _visit(decl.initializer);
+ final initializer = decl.initializer;
+ if (initializer != null) {
+ _visit(initializer);
}
_declareVariable(decl, _typesBuilder.fromStaticType(decl.type, true));
}
Call _makeCall(TreeNode node, Selector selector, Args<TypeExpr> args,
{bool isInstanceCreation = false}) {
- Type staticResultType = null;
- Member target;
+ Type? staticResultType = null;
+ Member? target;
if (selector is DirectSelector) {
target = selector.member;
} else if (selector is InterfaceSelector) {
@@ -1101,9 +1101,7 @@
}
Call call = new Call(selector, args, staticResultType, isInstanceCreation);
_summary.add(call);
- if (node != null) {
- callSites[node] = call;
- }
+ callSites[node] = call;
return call;
}
@@ -1189,53 +1187,43 @@
}
DartType _staticDartType(Expression node) =>
- node.getStaticType(_staticTypeContext);
+ node.getStaticType(_staticTypeContext!);
Type _staticType(Expression node) =>
_typesBuilder.fromStaticType(_staticDartType(node), true);
- ConcreteType _cachedBoolType;
- ConcreteType get _boolType => _cachedBoolType ??=
+ late final ConcreteType _boolType =
_entryPointsListener.addAllocatedClass(_environment.coreTypes.boolClass);
- ConcreteType _cachedBoolTrue;
- ConcreteType get _boolTrue => _cachedBoolTrue ??=
- new ConcreteType(_boolType.cls, null, BoolConstant(true));
+ late final ConcreteType _boolTrue =
+ ConcreteType(_boolType.cls, null, BoolConstant(true));
- ConcreteType _cachedBoolFalse;
- ConcreteType get _boolFalse => _cachedBoolFalse ??=
- new ConcreteType(_boolType.cls, null, BoolConstant(false));
+ late final ConcreteType _boolFalse =
+ ConcreteType(_boolType.cls, null, BoolConstant(false));
- Type _cachedDoubleType;
- Type get _doubleType => _cachedDoubleType ??= new ConeType(
- _typesBuilder.getTFClass(_environment.coreTypes.doubleClass));
+ late final Type _doubleType =
+ ConeType(_typesBuilder.getTFClass(_environment.coreTypes.doubleClass));
- Type _cachedIntType;
- Type get _intType => _cachedIntType ??=
- new ConeType(_typesBuilder.getTFClass(_environment.coreTypes.intClass));
+ late final Type _intType =
+ ConeType(_typesBuilder.getTFClass(_environment.coreTypes.intClass));
- Type _cachedStringType;
- Type get _stringType => _cachedStringType ??= new ConeType(
- _typesBuilder.getTFClass(_environment.coreTypes.stringClass));
+ late final Type _stringType =
+ ConeType(_typesBuilder.getTFClass(_environment.coreTypes.stringClass));
- Type _cachedSymbolType;
- Type get _symbolType => _cachedSymbolType ??= new ConeType(
- _typesBuilder.getTFClass(_environment.coreTypes.symbolClass));
+ late final Type _symbolType =
+ ConeType(_typesBuilder.getTFClass(_environment.coreTypes.symbolClass));
- Type _cachedTypeType;
- Type get _typeType => _cachedTypeType ??=
- new ConeType(_typesBuilder.getTFClass(_environment.coreTypes.typeClass));
+ late final Type _typeType =
+ ConeType(_typesBuilder.getTFClass(_environment.coreTypes.typeClass));
- Type _cachedNullType;
- Type get _nullType =>
- _cachedNullType ??= new Type.nullable(const EmptyType());
+ late final Type _nullType = Type.nullable(const EmptyType());
- Class get _superclass => _staticTypeContext.thisType.classNode.superclass;
+ Class get _superclass => _staticTypeContext!.thisType!.classNode.superclass!;
Type _boolLiteralType(bool value) => value ? _boolTrue : _boolFalse;
- Type _intLiteralType(int value, Constant constant) {
- final Class concreteClass =
+ Type _intLiteralType(int value, Constant? constant) {
+ final Class? concreteClass =
target.concreteIntLiteralClass(_environment.coreTypes, value);
if (concreteClass != null) {
constant ??= IntConstant(value);
@@ -1247,8 +1235,8 @@
return _intType;
}
- Type _doubleLiteralType(double value, Constant constant) {
- final Class concreteClass =
+ Type _doubleLiteralType(double value, Constant? constant) {
+ final Class? concreteClass =
target.concreteDoubleLiteralClass(_environment.coreTypes, value);
if (concreteClass != null) {
constant ??= DoubleConstant(value);
@@ -1260,8 +1248,8 @@
return _doubleType;
}
- Type _stringLiteralType(String value, Constant constant) {
- final Class concreteClass =
+ Type _stringLiteralType(String value, Constant? constant) {
+ final Class? concreteClass =
target.concreteStringLiteralClass(_environment.coreTypes, value);
if (concreteClass != null) {
constant ??= StringConstant(value);
@@ -1284,7 +1272,7 @@
node.positionalParameters.forEach(_declareVariableWithStaticType);
node.namedParameters.forEach(_declareVariableWithStaticType);
- _visit(node.body);
+ _visitWithoutResult(node.body!);
_variableValues = savedVariableValues;
_returnValue = savedReturn;
@@ -1307,8 +1295,7 @@
for (Class c
in _hierarchy.computeSubtypesInformation().getSubtypesOf(cls)) {
if (!c.isAbstract) {
- final candidate = _hierarchy.getDispatchTarget(c, _equalsName);
- assert(candidate != null);
+ final candidate = _hierarchy.getDispatchTarget(c, _equalsName)!;
assert(!candidate.isAbstract);
if (candidate != _environment.coreTypes.objectEquals) {
_cachedHasOverriddenEquals[cls] = true;
@@ -1328,12 +1315,12 @@
// On exit _variableValues is null, so caller should explicitly pick
// either trueState or falseState.
void _visitCondition(
- Expression node, List<TypeExpr> trueState, List<TypeExpr> falseState) {
+ Expression node, List<TypeExpr?> trueState, List<TypeExpr?> falseState) {
assert(_isIdenticalState(_variableValues, trueState));
assert(_isIdenticalState(_variableValues, falseState));
if (node is Not) {
_visitCondition(node.operand, falseState, trueState);
- _variableValues = null;
+ _variableValues = const <TypeExpr?>[]; // Should not be used.
return;
} else if (node is LogicalExpression) {
final isOR = (node.operatorEnum == LogicalExpressionOperator.OR);
@@ -1351,7 +1338,7 @@
_visitCondition(node.right, trueState, falseStateAfterRHS);
_mergeVariableValues(falseState, falseStateAfterRHS);
}
- _variableValues = null;
+ _variableValues = const <TypeExpr?>[]; // Should not be used.
return;
} else if (node is VariableGet ||
(node is AsExpression && node.operand is VariableGet)) {
@@ -1359,12 +1346,12 @@
_addUse(_visit(node));
final variableGet =
(node is AsExpression ? node.operand : node) as VariableGet;
- final int varIndex = _variablesInfo.varIndex[variableGet.variable];
+ final int varIndex = _variablesInfo.varIndex[variableGet.variable]!;
if (_variableCells[varIndex] == null) {
trueState[varIndex] = _boolTrue;
falseState[varIndex] = _boolFalse;
}
- _variableValues = null;
+ _variableValues = const <TypeExpr?>[]; // Should not be used.
return;
} else if (node is EqualsCall && node.left is VariableGet) {
final lhs = node.left as VariableGet;
@@ -1379,11 +1366,11 @@
!_hasOverriddenEquals(lhs.variable.type))) {
// 'x == c', where x is a variable and c is a constant.
_addUse(_visit(node));
- final int varIndex = _variablesInfo.varIndex[lhs.variable];
+ final int varIndex = _variablesInfo.varIndex[lhs.variable]!;
if (_variableCells[varIndex] == null) {
trueState[varIndex] = _visit(rhs);
}
- _variableValues = null;
+ _variableValues = const <TypeExpr?>[]; // Should not be used.
return;
}
} else if (node is EqualsNull && node.expression is VariableGet) {
@@ -1393,12 +1380,12 @@
_makeCall(node, DirectSelector(_environment.coreTypes.objectEquals),
Args<TypeExpr>([expr, _nullType]));
final narrowedNotNull = _makeNarrowNotNull(node, expr);
- final int varIndex = _variablesInfo.varIndex[lhs.variable];
+ final int varIndex = _variablesInfo.varIndex[lhs.variable]!;
if (_variableCells[varIndex] == null) {
trueState[varIndex] = _nullType;
falseState[varIndex] = narrowedNotNull;
}
- _variableValues = null;
+ _variableValues = const <TypeExpr?>[]; // Should not be used.
return;
} else if (node is IsExpression && node.operand is VariableGet) {
// Handle 'x is T', where x is a variable.
@@ -1406,17 +1393,17 @@
final TypeCheck typeCheck =
_typeCheck(_visit(operand), node.type, node, SubtypeTestKind.IsTest);
isTests[node] = typeCheck;
- final int varIndex = _variablesInfo.varIndex[operand.variable];
+ final int varIndex = _variablesInfo.varIndex[operand.variable]!;
if (_variableCells[varIndex] == null) {
trueState[varIndex] = typeCheck;
}
- _variableValues = null;
+ _variableValues = const <TypeExpr?>[]; // Should not be used.
return;
}
_addUse(_visit(node));
_copyVariableValues(trueState, _variableValues);
_copyVariableValues(falseState, _variableValues);
- _variableValues = null;
+ _variableValues = const <TypeExpr?>[]; // Should not be used.
}
void _updateReceiverAfterCall(
@@ -1425,7 +1412,7 @@
if (receiverNode is VariableGet) {
final nullSelectors = isSetter ? _nullSetters : _nullMethodsAndGetters;
if (!nullSelectors.contains(selector)) {
- final int varIndex = _variablesInfo.varIndex[receiverNode.variable];
+ final int varIndex = _variablesInfo.varIndex[receiverNode.variable]!;
if (_variableCells[varIndex] == null) {
_variableValues[varIndex] =
_makeNarrow(receiverValue, const AnyType());
@@ -1434,9 +1421,8 @@
}
}
- Procedure _cachedUnsafeCast;
- Procedure get unsafeCast => _cachedUnsafeCast ??= _environment.coreTypes.index
- .getTopLevelMember('dart:_internal', 'unsafeCast');
+ late final Procedure unsafeCast = _environment.coreTypes.index
+ .getTopLevelProcedure('dart:_internal', 'unsafeCast');
@override
defaultTreeNode(TreeNode node) =>
@@ -1446,10 +1432,10 @@
TypeExpr visitAsExpression(AsExpression node) {
final operandNode = node.operand;
final TypeExpr operand = _visit(operandNode);
- final TypeExpr result = _typeCheck(operand, node.type, node);
+ final TypeCheck result = _typeCheck(operand, node.type, node);
explicitCasts[node] = result;
if (operandNode is VariableGet) {
- final int varIndex = _variablesInfo.varIndex[operandNode.variable];
+ final int varIndex = _variablesInfo.varIndex[operandNode.variable]!;
if (_variableCells[varIndex] == null) {
_variableValues[varIndex] = result;
}
@@ -1462,7 +1448,7 @@
final operandNode = node.operand;
final TypeExpr result = _makeNarrowNotNull(node, _visit(operandNode));
if (operandNode is VariableGet) {
- final int varIndex = _variablesInfo.varIndex[operandNode.variable];
+ final int varIndex = _variablesInfo.varIndex[operandNode.variable]!;
if (_variableCells[varIndex] == null) {
_variableValues[varIndex] = result;
}
@@ -1549,20 +1535,20 @@
@override
TypeExpr visitLet(Let node) {
- _declareVariable(node.variable, _visit(node.variable.initializer));
+ _declareVariable(node.variable, _visit(node.variable.initializer!));
return _visit(node.body);
}
@override
TypeExpr visitBlockExpression(BlockExpression node) {
- _visit(node.body);
+ _visitWithoutResult(node.body);
return _visit(node.value);
}
@override
TypeExpr visitListLiteral(ListLiteral node) {
node.expressions.forEach(_visit);
- Class concreteClass =
+ Class? concreteClass =
target.concreteListLiteralClass(_environment.coreTypes);
if (concreteClass != null) {
return _translator.instantiateConcreteType(
@@ -1588,7 +1574,7 @@
_visit(entry.key);
_visit(entry.value);
}
- Class concreteClass =
+ Class? concreteClass =
target.concreteMapLiteralClass(_environment.coreTypes);
if (concreteClass != null) {
return _translator.instantiateConcreteType(
@@ -1690,7 +1676,7 @@
}
TypeExpr _handlePropertyGet(
- TreeNode node, Expression receiverNode, Member target, Name selector) {
+ TreeNode node, Expression receiverNode, Member? target, Name selector) {
var receiver = _visit(receiverNode);
var args = new Args<TypeExpr>([receiver]);
TypeExpr result;
@@ -1779,8 +1765,7 @@
@override
TypeExpr visitSuperPropertyGet(SuperPropertyGet node) {
assert(kPartialMixinResolution);
- assert(_receiver != null, "Should have receiver. Node: $node");
- final args = new Args<TypeExpr>([_receiver]);
+ final args = new Args<TypeExpr>([_receiver!]);
// Re-resolve target due to partial mixin resolution.
final target = _hierarchy.getDispatchTarget(_superclass, node.name);
if (target == null) {
@@ -1794,9 +1779,8 @@
@override
TypeExpr visitSuperPropertySet(SuperPropertySet node) {
assert(kPartialMixinResolution);
- assert(_receiver != null, "Should have receiver. Node: $node");
final value = _visit(node.value);
- final args = new Args<TypeExpr>([_receiver, value]);
+ final args = new Args<TypeExpr>([_receiver!, value]);
// Re-resolve target due to partial mixin resolution.
final target =
_hierarchy.getDispatchTarget(_superclass, node.name, setter: true);
@@ -1882,8 +1866,7 @@
@override
TypeExpr visitThisExpression(ThisExpression node) {
- assert(_receiver != null, "Should have receiver. Node: $node");
- return _receiver;
+ return _receiver!;
}
@override
@@ -1900,7 +1883,7 @@
@override
TypeExpr visitVariableGet(VariableGet node) {
- final v = _variableValues[_variablesInfo.varIndex[node.variable]];
+ final v = _variableValues[_variablesInfo.varIndex[node.variable]!];
if (v == null) {
throw 'Unable to find variable ${node.variable} at ${node.location}';
}
@@ -1925,56 +1908,60 @@
}
@override
- TypeExpr visitAssertStatement(AssertStatement node) {
+ TypeExpr? visitAssertStatement(AssertStatement node) {
if (!kRemoveAsserts) {
_addUse(_visit(node.condition));
- if (node.message != null) {
- _visit(node.message);
+ final message = node.message;
+ if (message != null) {
+ _visit(message);
}
}
return null;
}
@override
- TypeExpr visitBlock(Block node) {
- node.statements.forEach(_visit);
+ TypeExpr? visitBlock(Block node) {
+ node.statements.forEach(_visitWithoutResult);
return null;
}
@override
- TypeExpr visitAssertBlock(AssertBlock node) {
+ TypeExpr? visitAssertBlock(AssertBlock node) {
if (!kRemoveAsserts) {
- node.statements.forEach(_visit);
+ node.statements.forEach(_visitWithoutResult);
}
return null;
}
@override
- TypeExpr visitBreakStatement(BreakStatement node) {
- _variableValuesAfterLabeledStatements ??=
- <LabeledStatement, List<TypeExpr>>{};
- final state = _variableValuesAfterLabeledStatements[node.target];
+ TypeExpr? visitBreakStatement(BreakStatement node) {
+ var afterLabels = _variableValuesAfterLabeledStatements;
+ if (afterLabels == null) {
+ _variableValuesAfterLabeledStatements =
+ afterLabels = <LabeledStatement, List<TypeExpr?>>{};
+ }
+ final state = afterLabels[node.target];
if (state != null) {
_mergeVariableValues(state, _variableValues);
} else {
- _variableValuesAfterLabeledStatements[node.target] = _variableValues;
+ afterLabels[node.target] = _variableValues;
}
_variableValues = _makeEmptyVariableValues();
return null;
}
@override
- TypeExpr visitContinueSwitchStatement(ContinueSwitchStatement node) {
+ TypeExpr? visitContinueSwitchStatement(ContinueSwitchStatement node) {
_mergeVariableValuesToJoins(
- _variableValues, _joinsAtSwitchCases[node.target]);
+ _variableValues, _joinsAtSwitchCases![node.target]!);
_variableValues = _makeEmptyVariableValues();
return null;
}
@override
- TypeExpr visitDoStatement(DoStatement node) {
- final List<Join> joins = _insertJoinsForModifiedVariables(node, false);
- _visit(node.body);
+ TypeExpr? visitDoStatement(DoStatement node) {
+ final List<Join?> joins = _insertJoinsForModifiedVariables(node, false);
+ _visitWithoutResult(node.body);
final trueState = _cloneVariableValues(_variableValues);
final falseState = _cloneVariableValues(_variableValues);
_visitCondition(node.condition, trueState, falseState);
@@ -1988,39 +1975,39 @@
}
@override
- TypeExpr visitEmptyStatement(EmptyStatement node) => null;
+ TypeExpr? visitEmptyStatement(EmptyStatement node) => null;
@override
- TypeExpr visitExpressionStatement(ExpressionStatement node) {
+ TypeExpr? visitExpressionStatement(ExpressionStatement node) {
_visit(node.expression);
return null;
}
@override
- TypeExpr visitForInStatement(ForInStatement node) {
+ TypeExpr? visitForInStatement(ForInStatement node) {
_visit(node.iterable);
// TODO(alexmarkov): try to infer more precise type from 'iterable'
_declareVariableWithStaticType(node.variable);
- final List<Join> joins = _insertJoinsForModifiedVariables(node, false);
+ final List<Join?> joins = _insertJoinsForModifiedVariables(node, false);
final stateAfterLoop = _cloneVariableValues(_variableValues);
- _visit(node.body);
+ _visitWithoutResult(node.body);
_mergeVariableValuesToJoins(_variableValues, joins);
_variableValues = stateAfterLoop;
return null;
}
@override
- TypeExpr visitForStatement(ForStatement node) {
+ TypeExpr? visitForStatement(ForStatement node) {
node.variables.forEach(visitVariableDeclaration);
- final List<Join> joins = _insertJoinsForModifiedVariables(node, false);
+ final List<Join?> joins = _insertJoinsForModifiedVariables(node, false);
final trueState = _cloneVariableValues(_variableValues);
final falseState = _cloneVariableValues(_variableValues);
if (node.condition != null) {
- _visitCondition(node.condition, trueState, falseState);
+ _visitCondition(node.condition!, trueState, falseState);
}
_variableValues = trueState;
- _visit(node.body);
+ _visitWithoutResult(node.body);
node.updates.forEach(_visit);
_mergeVariableValuesToJoins(_variableValues, joins);
// Kernel represents 'break;' as a BreakStatement referring to a
@@ -2032,7 +2019,7 @@
}
@override
- TypeExpr visitFunctionDeclaration(FunctionDeclaration node) {
+ TypeExpr? visitFunctionDeclaration(FunctionDeclaration node) {
// TODO(alexmarkov): support function types.
node.variable.annotations.forEach(_visit);
_declareVariableWithStaticType(node.variable);
@@ -2041,18 +2028,18 @@
}
@override
- TypeExpr visitIfStatement(IfStatement node) {
+ TypeExpr? visitIfStatement(IfStatement node) {
final trueState = _cloneVariableValues(_variableValues);
final falseState = _cloneVariableValues(_variableValues);
_visitCondition(node.condition, trueState, falseState);
_variableValues = trueState;
- _visit(node.then);
+ _visitWithoutResult(node.then);
final stateAfter = _variableValues;
_variableValues = falseState;
if (node.otherwise != null) {
- _visit(node.otherwise);
+ _visitWithoutResult(node.otherwise!);
}
_mergeVariableValues(stateAfter, _variableValues);
@@ -2061,8 +2048,8 @@
}
@override
- TypeExpr visitLabeledStatement(LabeledStatement node) {
- _visit(node.body);
+ TypeExpr? visitLabeledStatement(LabeledStatement node) {
+ _visitWithoutResult(node.body);
final state = _variableValuesAfterLabeledStatements?.remove(node);
if (state != null) {
_mergeVariableValues(_variableValues, state);
@@ -2071,34 +2058,35 @@
}
@override
- TypeExpr visitReturnStatement(ReturnStatement node) {
- TypeExpr ret =
- (node.expression != null) ? _visit(node.expression) : _nullType;
- if (_returnValue != null) {
- _returnValue.values.add(ret);
- }
+ TypeExpr? visitReturnStatement(ReturnStatement node) {
+ final expression = node.expression;
+ TypeExpr ret = (expression != null) ? _visit(expression) : _nullType;
+ _returnValue?.values.add(ret);
_variableValues = _makeEmptyVariableValues();
return null;
}
@override
- TypeExpr visitSwitchStatement(SwitchStatement node) {
+ TypeExpr? visitSwitchStatement(SwitchStatement node) {
_visit(node.expression);
// Insert joins at each case in case there are 'continue' statements.
final stateOnEntry = _variableValues;
- final variableValuesAtCaseEntry = <SwitchCase, List<TypeExpr>>{};
- _joinsAtSwitchCases ??= <SwitchCase, List<Join>>{};
+ final variableValuesAtCaseEntry = <SwitchCase, List<TypeExpr?>>{};
+ Map<SwitchCase, List<Join?>>? joinsAtSwitchCases = _joinsAtSwitchCases;
+ if (joinsAtSwitchCases == null) {
+ _joinsAtSwitchCases = joinsAtSwitchCases = <SwitchCase, List<Join?>>{};
+ }
for (var switchCase in node.cases) {
_variableValues = _cloneVariableValues(stateOnEntry);
- _joinsAtSwitchCases[switchCase] =
+ joinsAtSwitchCases[switchCase] =
_insertJoinsForModifiedVariables(node, false);
variableValuesAtCaseEntry[switchCase] = _variableValues;
}
bool hasDefault = false;
for (var switchCase in node.cases) {
- _variableValues = variableValuesAtCaseEntry[switchCase];
+ _variableValues = variableValuesAtCaseEntry[switchCase]!;
switchCase.expressions.forEach(_visit);
- _visit(switchCase.body);
+ _visitWithoutResult(switchCase.body);
hasDefault = hasDefault || switchCase.isDefault;
}
if (!hasDefault) {
@@ -2108,21 +2096,21 @@
}
@override
- TypeExpr visitTryCatch(TryCatch node) {
+ TypeExpr? visitTryCatch(TryCatch node) {
final joins = _insertJoinsForModifiedVariables(node, true);
final stateAfterTry = _cloneVariableValues(_variableValues);
- _visit(node.body);
+ _visitWithoutResult(node.body);
_restoreVariableCellsAfterTry(joins);
- List<TypeExpr> stateAfterCatch;
+ List<TypeExpr?>? stateAfterCatch;
for (var catchClause in node.catches) {
_variableValues = _cloneVariableValues(stateAfterTry);
if (catchClause.exception != null) {
- _declareVariableWithStaticType(catchClause.exception);
+ _declareVariableWithStaticType(catchClause.exception!);
}
if (catchClause.stackTrace != null) {
- _declareVariableWithStaticType(catchClause.stackTrace);
+ _declareVariableWithStaticType(catchClause.stackTrace!);
}
- _visit(catchClause.body);
+ _visitWithoutResult(catchClause.body);
if (stateAfterCatch == null) {
stateAfterCatch = _variableValues;
} else {
@@ -2130,38 +2118,39 @@
}
}
_variableValues = stateAfterTry;
- _mergeVariableValues(_variableValues, stateAfterCatch);
+ _mergeVariableValues(_variableValues, stateAfterCatch!);
return null;
}
@override
- TypeExpr visitTryFinally(TryFinally node) {
+ TypeExpr? visitTryFinally(TryFinally node) {
final joins = _insertJoinsForModifiedVariables(node, true);
final stateAfterTry = _cloneVariableValues(_variableValues);
- _visit(node.body);
+ _visitWithoutResult(node.body);
_restoreVariableCellsAfterTry(joins);
_variableValues = stateAfterTry;
- _visit(node.finalizer);
+ _visitWithoutResult(node.finalizer);
return null;
}
@override
- TypeExpr visitVariableDeclaration(VariableDeclaration node) {
+ TypeExpr? visitVariableDeclaration(VariableDeclaration node) {
node.annotations.forEach(_visit);
+ final initializer = node.initializer;
final TypeExpr initialValue =
- node.initializer == null ? _nullType : _visit(node.initializer);
+ initializer == null ? _nullType : _visit(initializer);
_declareVariable(node, initialValue);
return null;
}
@override
- TypeExpr visitWhileStatement(WhileStatement node) {
- final List<Join> joins = _insertJoinsForModifiedVariables(node, false);
+ TypeExpr? visitWhileStatement(WhileStatement node) {
+ final List<Join?> joins = _insertJoinsForModifiedVariables(node, false);
final trueState = _cloneVariableValues(_variableValues);
final falseState = _cloneVariableValues(_variableValues);
_visitCondition(node.condition, trueState, falseState);
_variableValues = trueState;
- _visit(node.body);
+ _visitWithoutResult(node.body);
_mergeVariableValuesToJoins(_variableValues, joins);
// Kernel represents 'break;' as a BreakStatement referring to a
// LabeledStatement. We are therefore guaranteed to always have the
@@ -2172,15 +2161,15 @@
}
@override
- TypeExpr visitYieldStatement(YieldStatement node) {
+ TypeExpr? visitYieldStatement(YieldStatement node) {
_visit(node.expression);
return null;
}
@override
- TypeExpr visitFieldInitializer(FieldInitializer node) {
+ TypeExpr? visitFieldInitializer(FieldInitializer node) {
final value = _visit(node.value);
- final args = new Args<TypeExpr>([_receiver, value]);
+ final args = new Args<TypeExpr>([_receiver!, value]);
_makeCall(
node,
new DirectSelector(node.field,
@@ -2190,17 +2179,17 @@
}
@override
- TypeExpr visitRedirectingInitializer(RedirectingInitializer node) {
+ TypeExpr? visitRedirectingInitializer(RedirectingInitializer node) {
final args = _visitArguments(_receiver, node.arguments);
_makeCall(node, new DirectSelector(node.target), args);
return null;
}
@override
- TypeExpr visitSuperInitializer(SuperInitializer node) {
+ TypeExpr? visitSuperInitializer(SuperInitializer node) {
final args = _visitArguments(_receiver, node.arguments);
- Constructor target = null;
+ Constructor? target = null;
if (kPartialMixinResolution) {
// Re-resolve target due to partial mixin resolution.
for (var replacement in _superclass.constructors) {
@@ -2212,27 +2201,26 @@
} else {
target = node.target;
}
- assert(target != null);
- _makeCall(node, new DirectSelector(target), args);
+ _makeCall(node, new DirectSelector(target!), args);
return null;
}
@override
- TypeExpr visitLocalInitializer(LocalInitializer node) {
+ TypeExpr? visitLocalInitializer(LocalInitializer node) {
visitVariableDeclaration(node.variable);
return null;
}
@override
- TypeExpr visitAssertInitializer(AssertInitializer node) {
+ TypeExpr? visitAssertInitializer(AssertInitializer node) {
if (!kRemoveAsserts) {
- _visit(node.statement);
+ _visitWithoutResult(node.statement);
}
return null;
}
@override
- TypeExpr visitInvalidInitializer(InvalidInitializer node) {
+ TypeExpr? visitInvalidInitializer(InvalidInitializer node) {
return null;
}
@@ -2244,21 +2232,21 @@
class RuntimeTypeTranslatorImpl extends DartTypeVisitor<TypeExpr>
implements RuntimeTypeTranslator {
- final Summary summary;
- final Map<TypeParameter, TypeExpr> functionTypeVariables;
+ final CoreTypes coreTypes;
+ final Summary? summary;
+ final Map<TypeParameter, TypeExpr>? functionTypeVariables;
final Map<DartType, TypeExpr> typesCache = <DartType, TypeExpr>{};
- final TypeExpr receiver;
+ final TypeExpr? receiver;
final GenericInterfacesInfo genericInterfacesInfo;
- final SummaryCollector summaryCollector;
- RuntimeTypeTranslatorImpl(this.summaryCollector, this.summary, this.receiver,
+ RuntimeTypeTranslatorImpl(this.coreTypes, this.summary, this.receiver,
this.functionTypeVariables, this.genericInterfacesInfo) {}
// Create a type translator which can be used only for types with no free type
// variables.
- RuntimeTypeTranslatorImpl.forClosedTypes(this.genericInterfacesInfo)
- : summaryCollector = null,
- summary = null,
+ RuntimeTypeTranslatorImpl.forClosedTypes(
+ this.coreTypes, this.genericInterfacesInfo)
+ : summary = null,
functionTypeVariables = null,
receiver = null {}
@@ -2271,8 +2259,7 @@
final substitution = Substitution.fromPairs(klass.typeParameters, typeArgs);
final flattenedTypeArgs =
genericInterfacesInfo.flattenedTypeArgumentsFor(klass);
- final flattenedTypeExprs =
- new List<TypeExpr>.filled(flattenedTypeArgs.length, null);
+ final flattenedTypeExprs = <TypeExpr>[];
bool createConcreteType = true;
bool allUnknown = true;
@@ -2281,7 +2268,7 @@
translate(substitution.substituteType(flattenedTypeArgs[i]));
if (typeExpr is! UnknownType) allUnknown = false;
if (typeExpr is Statement) createConcreteType = false;
- flattenedTypeExprs[i] = typeExpr;
+ flattenedTypeExprs.add(typeExpr);
}
if (allUnknown) return type;
@@ -2291,7 +2278,7 @@
type.cls, new List<Type>.from(flattenedTypeExprs));
} else {
final instantiate = new CreateConcreteType(type.cls, flattenedTypeExprs);
- summary.add(instantiate);
+ summary!.add(instantiate);
return instantiate;
}
}
@@ -2341,8 +2328,7 @@
type.classNode.typeParameters, type.typeArguments);
final flattenedTypeArgs =
genericInterfacesInfo.flattenedTypeArgumentsFor(type.classNode);
- final flattenedTypeExprs =
- new List<TypeExpr>.filled(flattenedTypeArgs.length, null);
+ final flattenedTypeExprs = <TypeExpr>[];
bool createRuntimeType = true;
for (var i = 0; i < flattenedTypeArgs.length; ++i) {
@@ -2350,7 +2336,7 @@
translate(substitution.substituteType(flattenedTypeArgs[i]));
if (typeExpr == const UnknownType()) return const UnknownType();
if (typeExpr is! RuntimeType) createRuntimeType = false;
- flattenedTypeExprs[i] = typeExpr;
+ flattenedTypeExprs.add(typeExpr);
}
if (createRuntimeType) {
@@ -2360,7 +2346,7 @@
} else {
final instantiate = new CreateRuntimeType(
type.classNode, type.nullability, flattenedTypeExprs);
- summary.add(instantiate);
+ summary!.add(instantiate);
return instantiate;
}
}
@@ -2375,32 +2361,32 @@
<RuntimeType>[typeArg]);
} else {
final instantiate = new CreateRuntimeType(
- summaryCollector._environment.coreTypes.deprecatedFutureOrClass,
+ coreTypes.deprecatedFutureOrClass,
type.nullability,
<TypeExpr>[typeArg]);
- summary.add(instantiate);
+ summary!.add(instantiate);
return instantiate;
}
}
@override
visitTypeParameterType(TypeParameterType type) {
+ final functionTypeVariables = this.functionTypeVariables;
if (functionTypeVariables != null) {
final result = functionTypeVariables[type.parameter];
if (result != null) return result;
}
if (type.parameter.parent is! Class) return const UnknownType();
final interfaceClass = type.parameter.parent as Class;
- assert(receiver != null);
// Undetermined nullability is equivalent to nonNullable when
// instantiating type parameter, so convert it right away.
Nullability nullability = type.nullability;
if (nullability == Nullability.undetermined) {
nullability = Nullability.nonNullable;
}
- final extract = new Extract(receiver, interfaceClass,
+ final extract = new Extract(receiver!, interfaceClass,
interfaceClass.typeParameters.indexOf(type.parameter), nullability);
- summary.add(extract);
+ summary!.add(extract);
return extract;
}
}
@@ -2420,7 +2406,7 @@
Type _getStaticType(Constant constant) =>
summaryCollector._typesBuilder.fromStaticType(
- constant.getType(summaryCollector._staticTypeContext), false);
+ constant.getType(summaryCollector._staticTypeContext!), false);
@override
defaultConstant(Constant constant) {
@@ -2467,7 +2453,7 @@
for (final Constant entry in constant.entries) {
typeFor(entry);
}
- final Class concreteClass = summaryCollector.target
+ final Class? concreteClass = summaryCollector.target
.concreteConstListLiteralClass(summaryCollector._environment.coreTypes);
if (concreteClass != null) {
return new ConcreteType(
diff --git a/pkg/vm/lib/transformations/type_flow/table_selector_assigner.dart b/pkg/vm/lib/transformations/type_flow/table_selector_assigner.dart
index f1901e7..0080748 100644
--- a/pkg/vm/lib/transformations/type_flow/table_selector_assigner.dart
+++ b/pkg/vm/lib/transformations/type_flow/table_selector_assigner.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
import 'package:kernel/ast.dart';
import 'utils.dart' show UnionFind;
@@ -18,7 +16,7 @@
final Map<Class, Map<Name, int>> _methodOrSetterMemberIds = {};
final UnionFind _unionFind = UnionFind();
- List<int> _selectorIdForMemberId;
+ late List<int?> _selectorIdForMemberId;
TableSelectorAssigner(Component component) {
for (Library library in component.libraries) {
@@ -44,20 +42,21 @@
}
}
- Map<Name, int> _memberIdsForClass(Class cls, {bool getter}) {
+ Map<Name, int> _memberIdsForClass(Class? cls, {required bool getter}) {
if (cls == null) return {};
final cache = getter ? _getterMemberIds : _methodOrSetterMemberIds;
// Already computed for this class?
- Map<Name, int> memberIds = cache[cls];
- if (memberIds != null) return memberIds;
+ final cachedMemberIds = cache[cls];
+ if (cachedMemberIds != null) return cachedMemberIds;
// Merge maps from supertypes.
- memberIds = Map.from(_memberIdsForClass(cls.superclass, getter: getter));
+ final memberIds =
+ Map<Name, int>.from(_memberIdsForClass(cls.superclass, getter: getter));
for (Supertype impl in cls.implementedTypes) {
_memberIdsForClass(impl.classNode, getter: getter).forEach((name, id) {
- final int firstId = memberIds[name];
+ final int? firstId = memberIds[name];
if (firstId == null) {
memberIds[name] = id;
} else if (firstId != id) {
@@ -99,9 +98,9 @@
return cache[cls] = memberIds;
}
- int _selectorIdForMember(Member member, {bool getter}) {
+ int _selectorIdForMember(Member member, {required bool getter}) {
final map = getter ? _getterMemberIds : _methodOrSetterMemberIds;
- int memberId = map[member.enclosingClass][member.name];
+ int? memberId = map[member.enclosingClass!]![member.name];
if (memberId == null) {
assert(member is Procedure &&
((identical(map, _getterMemberIds) &&
@@ -115,7 +114,7 @@
return ProcedureAttributesMetadata.kInvalidSelectorId;
}
memberId = _unionFind.find(memberId);
- int selectorId = _selectorIdForMemberId[memberId];
+ int? selectorId = _selectorIdForMemberId[memberId];
if (selectorId == null) {
_selectorIdForMemberId[memberId] = selectorId = metadata.addSelector();
}
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index feb185d..82bebec 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -2,10 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
/// Transformations based on type flow analysis.
-library vm.transformations.type_flow.transformer;
import 'dart:core' hide Type;
@@ -14,7 +11,8 @@
import 'package:kernel/ast.dart' as ast show Statement;
import 'package:kernel/clone.dart' show CloneVisitorNotMembers;
import 'package:kernel/core_types.dart' show CoreTypes;
-import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+import 'package:kernel/class_hierarchy.dart'
+ show ClassHierarchy, ClosedWorldClassHierarchy;
import 'package:kernel/library_index.dart' show LibraryIndex;
import 'package:kernel/type_environment.dart';
@@ -43,16 +41,18 @@
/// Assumes strong mode and closed world.
Component transformComponent(
Target target, CoreTypes coreTypes, Component component,
- {PragmaAnnotationParser matcher,
+ {PragmaAnnotationParser? matcher,
bool treeShakeSignatures: true,
bool treeShakeWriteOnlyFields: true,
bool treeShakeProtobufs: false}) {
void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
final hierarchy = new ClassHierarchy(component, coreTypes,
- onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
+ onAmbiguousSupertypes: ignoreAmbiguousSupertypes)
+ as ClosedWorldClassHierarchy;
final types = new TypeEnvironment(coreTypes, hierarchy);
final libraryIndex = new LibraryIndex.all(component);
- final genericInterfacesInfo = new GenericInterfacesInfoImpl(hierarchy);
+ final genericInterfacesInfo =
+ new GenericInterfacesInfoImpl(coreTypes, hierarchy);
final protobufHandler = treeShakeProtobufs
? ProtobufHandler.forComponent(component, coreTypes)
: null;
@@ -73,7 +73,7 @@
protobufHandler,
matcher);
- Procedure main = component.mainMethod;
+ Procedure? main = component.mainMethod;
// `main` can be null, roots can also come from @pragma("vm:entry-point").
if (main != null) {
@@ -149,7 +149,7 @@
if (!f.isStatic &&
!f.isLate &&
f.initializer != null &&
- mayHaveSideEffects(f.initializer))
+ mayHaveSideEffects(f.initializer!))
f
];
if (fields.isEmpty) return;
@@ -173,7 +173,7 @@
};
final List<Initializer> newInitializers = [];
for (Field f in fields) {
- Expression initExpr = f.initializer;
+ Expression initExpr = f.initializer!;
if (!isFirst) {
initExpr = CloneVisitorNotMembers().clone(initExpr);
}
@@ -204,7 +204,7 @@
class CleanupAnnotations extends RecursiveVisitor {
final Class externalNameClass;
final Class pragmaClass;
- final ProtobufHandler protobufHandler;
+ final ProtobufHandler? protobufHandler;
CleanupAnnotations(
CoreTypes coreTypes, LibraryIndex index, this.protobufHandler)
@@ -238,7 +238,7 @@
return (cls == externalNameClass) ||
(cls == pragmaClass) ||
(protobufHandler != null &&
- protobufHandler.usesAnnotationClass(cls));
+ protobufHandler!.usesAnnotationClass(cls));
}
}
return false;
@@ -255,11 +255,11 @@
: super(_typeFlowAnalysis.environment.coreTypes, component, hierarchy);
@override
- DirectCallMetadata getDirectCall(TreeNode node, Member interfaceTarget,
+ DirectCallMetadata? getDirectCall(TreeNode node, Member? interfaceTarget,
{bool setter = false}) {
final callSite = _typeFlowAnalysis.callSite(node);
if (callSite != null) {
- final Member singleTarget = fieldMorpher
+ final Member? singleTarget = fieldMorpher
.getMorphedMember(callSite.monomorphicTarget, isSetter: setter);
if (singleTarget != null) {
return new DirectCallMetadata(
@@ -283,12 +283,13 @@
final UnboxingInfoMetadataRepository _unboxingInfoMetadata;
final UnboxingInfoManager _unboxingInfo;
final Class _intClass;
- Constant _nullConstant;
+ late final Constant _nullConstant = NullConstant();
AnnotateKernel(Component component, this._typeFlowAnalysis, this.fieldMorpher,
this._tableSelectorAssigner, this._unboxingInfo)
: _directCallMetadataRepository =
- component.metadata[DirectCallMetadataRepository.repositoryTag],
+ component.metadata[DirectCallMetadataRepository.repositoryTag]
+ as DirectCallMetadataRepository,
_inferredTypeMetadata = new InferredTypeMetadataRepository(),
_unreachableNodeMetadata = new UnreachableNodeMetadataRepository(),
_procedureAttributesMetadata =
@@ -308,12 +309,10 @@
return _directCallMetadataRepository.mapping.containsKey(node);
}
- InferredType _convertType(Type type,
+ InferredType? _convertType(Type type,
{bool skipCheck: false, bool receiverNotInt: false}) {
- assert(type != null);
-
- Class concreteClass;
- Constant constantValue;
+ Class? concreteClass;
+ Constant? constantValue;
bool isInt = false;
final nullable = type is NullableType;
@@ -324,7 +323,7 @@
if (nullable && type == const EmptyType()) {
concreteClass =
_typeFlowAnalysis.environment.coreTypes.deprecatedNullClass;
- constantValue = _nullConstant ??= new NullConstant();
+ constantValue = _nullConstant;
} else {
concreteClass = type.getConcreteClass(_typeFlowAnalysis.hierarchyCache);
@@ -337,9 +336,9 @@
}
}
- List<DartType> typeArgs;
+ List<DartType?>? typeArgs;
if (type is ConcreteType && type.typeArgs != null) {
- typeArgs = type.typeArgs
+ typeArgs = type.typeArgs!
.take(type.numImmediateTypeArgs)
.map((t) =>
t is UnknownType ? null : (t as RuntimeType).representedType)
@@ -374,7 +373,7 @@
_unreachableNodeMetadata.mapping[node] = const UnreachableNode();
}
- void _annotateCallSite(TreeNode node, Member interfaceTarget) {
+ void _annotateCallSite(TreeNode node, Member? interfaceTarget) {
final callSite = _typeFlowAnalysis.callSite(node);
if (callSite == null) return;
if (!callSite.isReachable) {
@@ -405,7 +404,7 @@
if (interfaceTarget == null ||
_typeFlowAnalysis.hierarchyCache.hierarchy.isSubtypeOf(
_typeFlowAnalysis.hierarchyCache.coreTypes.intClass,
- interfaceTarget.enclosingClass)) {
+ interfaceTarget.enclosingClass!)) {
markReceiverNotInt = true;
}
}
@@ -446,35 +445,33 @@
void _annotateMember(Member member) {
if (_typeFlowAnalysis.isMemberUsed(member)) {
if (member is Field) {
- _setInferredType(member, _typeFlowAnalysis.fieldType(member));
+ _setInferredType(member, _typeFlowAnalysis.fieldType(member)!);
} else {
- Args<Type> argTypes = _typeFlowAnalysis.argumentTypes(member);
+ Args<Type> argTypes = _typeFlowAnalysis.argumentTypes(member)!;
final uncheckedParameters =
_typeFlowAnalysis.uncheckedParameters(member);
- assert(argTypes != null);
final int firstParamIndex =
numTypeParams(member) + (hasReceiverArg(member) ? 1 : 0);
- final positionalParams = member.function.positionalParameters;
+ final positionalParams = member.function!.positionalParameters;
assert(argTypes.positionalCount ==
firstParamIndex + positionalParams.length);
for (int i = 0; i < positionalParams.length; i++) {
_setInferredType(
positionalParams[i], argTypes.values[firstParamIndex + i],
- skipCheck: uncheckedParameters.contains(positionalParams[i]));
+ skipCheck: uncheckedParameters!.contains(positionalParams[i]));
}
// TODO(dartbug.com/32292): make sure parameters are sorted in kernel
// AST and iterate parameters in parallel, without lookup.
final names = argTypes.names;
for (int i = 0; i < names.length; i++) {
- final param = findNamedParameter(member.function, names[i]);
- assert(param != null);
+ final param = findNamedParameter(member.function!, names[i])!;
_setInferredType(param,
argTypes.values[firstParamIndex + positionalParams.length + i],
- skipCheck: uncheckedParameters.contains(param));
+ skipCheck: uncheckedParameters!.contains(param));
}
// TODO(alexmarkov): figure out how to pass receiver type.
@@ -521,7 +518,7 @@
// interface target, and table dispatch calls need selector IDs for all
// interface targets.
if (member.isInstanceMember) {
- final original = fieldMorpher.getOriginalMember(member);
+ final original = fieldMorpher.getOriginalMember(member)!;
final attrs = new ProcedureAttributesMetadata(
methodOrSetterCalledDynamically:
_typeFlowAnalysis.isCalledDynamically(original),
@@ -689,11 +686,11 @@
final Set<Member> _usedMembers = new Set<Member>();
final Set<Extension> _usedExtensions = new Set<Extension>();
final Set<Typedef> _usedTypedefs = new Set<Typedef>();
- FieldMorpher fieldMorpher;
- _TreeShakerTypeVisitor typeVisitor;
- _TreeShakerConstantVisitor constantVisitor;
- _TreeShakerPass1 _pass1;
- _TreeShakerPass2 _pass2;
+ late final FieldMorpher fieldMorpher;
+ late final _TreeShakerTypeVisitor typeVisitor;
+ late final _TreeShakerConstantVisitor constantVisitor;
+ late final _TreeShakerPass1 _pass1;
+ late final _TreeShakerPass2 _pass2;
TreeShaker(Component component, this.typeFlowAnalysis,
{this.treeShakeWriteOnlyFields: true}) {
@@ -734,7 +731,7 @@
(!f.isStatic &&
f.initializer != null &&
isFieldInitializerReachable(f) &&
- mayHaveSideEffects(f.initializer)) ||
+ mayHaveSideEffects(f.initializer!)) ||
(f.isLate && f.isFinal)) ||
isMemberReferencedFromNativeCode(f) ||
_isInstanceFieldOfAllocatedEnum(f);
@@ -745,8 +742,8 @@
bool _isInstanceFieldOfAllocatedEnum(Field node) =>
!node.isStatic &&
node.enclosingClass != null &&
- node.enclosingClass.isEnum &&
- isClassAllocated(node.enclosingClass);
+ node.enclosingClass!.isEnum &&
+ isClassAllocated(node.enclosingClass!);
void addClassUsedInType(Class c) {
if (_classesUsedInType.add(c)) {
@@ -777,7 +774,7 @@
_usedClasses.add(enclosingClass);
}
- FunctionNode func = null;
+ FunctionNode? func = null;
if (m is Field) {
m.type.accept(typeVisitor);
} else if (m is Procedure) {
@@ -786,19 +783,19 @@
m.stubTarget = fieldMorpher.adjustInstanceCallTarget(
m.concreteForwardingStubTarget,
isSetter: m.isSetter);
- addUsedMember(m.concreteForwardingStubTarget);
+ addUsedMember(m.concreteForwardingStubTarget!);
}
if (m.abstractForwardingStubTarget != null) {
m.stubTarget = fieldMorpher.adjustInstanceCallTarget(
m.abstractForwardingStubTarget,
isSetter: m.isSetter);
- addUsedMember(m.abstractForwardingStubTarget);
+ addUsedMember(m.abstractForwardingStubTarget!);
}
if (m.memberSignatureOrigin != null) {
m.stubTarget = fieldMorpher.adjustInstanceCallTarget(
m.memberSignatureOrigin,
isSetter: m.isSetter);
- addUsedMember(m.memberSignatureOrigin);
+ addUsedMember(m.memberSignatureOrigin!);
}
} else if (m is Constructor) {
func = m.function;
@@ -821,8 +818,7 @@
final extension = m.enclosingLibrary.extensions.firstWhere((extension) {
return extension.members
.any((descriptor) => descriptor.member.asMember == m);
- }, orElse: () => null);
- assert(extension != null);
+ });
// Ensure we retain the [Extension] itself (though members might be
// shaken)
@@ -844,7 +840,7 @@
if (_usedExtensions.add(node)) {
node.annotations = const <Expression>[];
_pass1.transformTypeParameterList(node.typeParameters, node);
- node.onType?.accept(typeVisitor);
+ node.onType.accept(typeVisitor);
}
}
@@ -898,7 +894,7 @@
isAbstract: true, fileUri: field.fileUri);
}
accessor.fileOffset = field.fileOffset;
- field.enclosingClass.addProcedure(accessor);
+ field.enclosingClass!.addProcedure(accessor);
_removedFields[accessor] = field;
shaker.addUsedMember(accessor);
return accessor;
@@ -908,7 +904,7 @@
/// If necessary, creates a getter or setter as a replacement if target is a
/// field which is going to be removed by the tree shaker.
/// This method is used during tree shaker pass 1.
- Member adjustInstanceCallTarget(Member target, {bool isSetter = false}) {
+ Member? adjustInstanceCallTarget(Member? target, {bool isSetter = false}) {
if (target is Field && !shaker.retainField(target)) {
final targets =
isSetter ? _settersForRemovedFields : _gettersForRemovedFields;
@@ -923,9 +919,9 @@
/// Return a member which replaced [target] in instance calls.
/// This method can be used after tree shaking to discover replacement.
- Member getMorphedMember(Member target, {bool isSetter = false}) {
- if (target == null) {
- return null;
+ Member? getMorphedMember(Member? target, {bool isSetter = false}) {
+ if (target is! Field) {
+ return target;
}
final targets =
isSetter ? _settersForRemovedFields : _gettersForRemovedFields;
@@ -934,7 +930,7 @@
/// Return original member which was replaced by [target] in instance calls.
/// This method can be used after tree shaking.
- Member getOriginalMember(Member target) {
+ Member? getOriginalMember(Member? target) {
if (target == null) {
return null;
}
@@ -994,16 +990,15 @@
final TreeShaker shaker;
final FieldMorpher fieldMorpher;
final TypeEnvironment environment;
- Procedure _unsafeCast;
- StaticTypeContext _staticTypeContext;
- Member _currentMember;
+ StaticTypeContext? _staticTypeContext;
+ Member? _currentMember;
StaticTypeContext get staticTypeContext =>
_staticTypeContext ??= StaticTypeContext(currentMember, environment);
- Member get currentMember => _currentMember;
- set currentMember(Member m) {
+ Member get currentMember => _currentMember!;
+ set currentMember(Member? m) {
_currentMember = m;
_staticTypeContext = null;
}
@@ -1022,7 +1017,7 @@
}
List<Expression> _flattenArguments(Arguments arguments,
- {Expression receiver}) {
+ {Expression? receiver}) {
final args = <Expression>[];
if (receiver != null) {
args.add(receiver);
@@ -1035,9 +1030,9 @@
bool _isThrowExpression(Expression expr) {
for (;;) {
if (expr is Let) {
- expr = (expr as Let).body;
+ expr = expr.body;
} else if (expr is BlockExpression) {
- expr = (expr as BlockExpression).value;
+ expr = expr.value;
} else {
break;
}
@@ -1068,7 +1063,7 @@
return BlockExpression(Block(statements), value);
}
- TreeNode _makeUnreachableCall(List<Expression> args) {
+ Expression _makeUnreachableCall(List<Expression> args) {
Expression node;
final int last = args.indexWhere(_isThrowExpression);
if (last >= 0) {
@@ -1090,12 +1085,12 @@
new VariableDeclaration(null, initializer: _makeUnreachableCall(args)));
}
- NarrowNotNull _getNullTest(TreeNode node) =>
+ NarrowNotNull? _getNullTest(TreeNode node) =>
shaker.typeFlowAnalysis.nullTest(node);
- TreeNode _visitAssertNode(TreeNode node, TreeNode removalSentinel) {
+ TreeNode _visitAssertNode(TreeNode node, TreeNode? removalSentinel) {
if (kRemoveAsserts) {
- return removalSentinel;
+ return removalSentinel!;
} else {
node.transformOrRemoveChildren(this);
return node;
@@ -1103,31 +1098,31 @@
}
@override
- DartType visitDartType(DartType node, DartType removalSentinel) {
+ DartType visitDartType(DartType node, DartType? removalSentinel) {
node.accept(shaker.typeVisitor);
return node;
}
@override
- Supertype visitSupertype(Supertype node, Supertype removalSentinel) {
+ Supertype visitSupertype(Supertype node, Supertype? removalSentinel) {
node.accept(shaker.typeVisitor);
return node;
}
@override
- TreeNode visitTypedef(Typedef node, TreeNode removalSentinel) {
+ TreeNode visitTypedef(Typedef node, TreeNode? removalSentinel) {
return node; // Do not go deeper.
}
@override
- Extension visitExtension(Extension node, TreeNode removalSentinel) {
+ TreeNode visitExtension(Extension node, TreeNode? removalSentinel) {
// The extension can be considered a weak node, we'll only retain it if
// normal code references any of it's members.
return node;
}
@override
- TreeNode visitClass(Class node, TreeNode removalSentinel) {
+ TreeNode visitClass(Class node, TreeNode? removalSentinel) {
if (shaker.isClassAllocated(node) ||
shaker.isClassReferencedFromNativeCode(node)) {
shaker.addClassUsedInType(node);
@@ -1140,7 +1135,7 @@
}
@override
- TreeNode defaultMember(Member node, TreeNode removalSentinel) {
+ TreeNode defaultMember(Member node, TreeNode? removalSentinel) {
currentMember = node;
if (shaker.isMemberBodyReachable(node)) {
if (kPrintTrace) {
@@ -1160,7 +1155,7 @@
}
@override
- TreeNode visitField(Field node, TreeNode removalSentinel) {
+ TreeNode visitField(Field node, TreeNode? removalSentinel) {
currentMember = node;
if (shaker.retainField(node)) {
if (kPrintTrace) {
@@ -1185,21 +1180,21 @@
@override
TreeNode visitInstanceInvocation(
- InstanceInvocation node, TreeNode removalSentinel) {
+ InstanceInvocation node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall(
_flattenArguments(node.arguments, receiver: node.receiver));
}
- node.interfaceTarget =
- fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget);
+ node.interfaceTarget = fieldMorpher
+ .adjustInstanceCallTarget(node.interfaceTarget) as Procedure;
shaker.addUsedMember(node.interfaceTarget);
return node;
}
@override
TreeNode visitDynamicInvocation(
- DynamicInvocation node, TreeNode removalSentinel) {
+ DynamicInvocation node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall(
@@ -1210,7 +1205,7 @@
@override
TreeNode visitLocalFunctionInvocation(
- LocalFunctionInvocation node, TreeNode removalSentinel) {
+ LocalFunctionInvocation node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall(_flattenArguments(node.arguments));
@@ -1220,7 +1215,7 @@
@override
TreeNode visitFunctionInvocation(
- FunctionInvocation node, TreeNode removalSentinel) {
+ FunctionInvocation node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall(
@@ -1230,24 +1225,24 @@
}
@override
- TreeNode visitEqualsCall(EqualsCall node, TreeNode removalSentinel) {
+ TreeNode visitEqualsCall(EqualsCall node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.left, node.right]);
}
- node.interfaceTarget =
- fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget);
+ node.interfaceTarget = fieldMorpher
+ .adjustInstanceCallTarget(node.interfaceTarget) as Procedure;
shaker.addUsedMember(node.interfaceTarget);
return node;
}
@override
- TreeNode visitEqualsNull(EqualsNull node, TreeNode removalSentinel) {
+ TreeNode visitEqualsNull(EqualsNull node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.expression]);
}
- final nullTest = _getNullTest(node);
+ final nullTest = _getNullTest(node)!;
if (nullTest.isAlwaysNull || nullTest.isAlwaysNotNull) {
return _evaluateArguments([node.expression],
BoolLiteral(nullTest.isAlwaysNull)..fileOffset = node.fileOffset);
@@ -1256,13 +1251,13 @@
}
@override
- TreeNode visitInstanceGet(InstanceGet node, TreeNode removalSentinel) {
+ TreeNode visitInstanceGet(InstanceGet node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.receiver]);
} else {
node.interfaceTarget =
- fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget);
+ fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget)!;
shaker.addUsedMember(node.interfaceTarget);
return node;
}
@@ -1270,20 +1265,20 @@
@override
TreeNode visitInstanceTearOff(
- InstanceTearOff node, TreeNode removalSentinel) {
+ InstanceTearOff node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.receiver]);
} else {
- node.interfaceTarget =
- fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget);
+ node.interfaceTarget = fieldMorpher
+ .adjustInstanceCallTarget(node.interfaceTarget) as Procedure;
shaker.addUsedMember(node.interfaceTarget);
return node;
}
}
@override
- TreeNode visitDynamicGet(DynamicGet node, TreeNode removalSentinel) {
+ TreeNode visitDynamicGet(DynamicGet node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.receiver]);
@@ -1294,7 +1289,7 @@
@override
TreeNode visitFunctionTearOff(
- FunctionTearOff node, TreeNode removalSentinel) {
+ FunctionTearOff node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.receiver]);
@@ -1304,20 +1299,20 @@
}
@override
- TreeNode visitInstanceSet(InstanceSet node, TreeNode removalSentinel) {
+ TreeNode visitInstanceSet(InstanceSet node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.receiver, node.value]);
} else {
node.interfaceTarget = fieldMorpher
- .adjustInstanceCallTarget(node.interfaceTarget, isSetter: true);
+ .adjustInstanceCallTarget(node.interfaceTarget, isSetter: true)!;
shaker.addUsedMember(node.interfaceTarget);
return node;
}
}
@override
- TreeNode visitDynamicSet(DynamicSet node, TreeNode removalSentinel) {
+ TreeNode visitDynamicSet(DynamicSet node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.receiver, node.value]);
@@ -1328,15 +1323,15 @@
@override
TreeNode visitSuperMethodInvocation(
- SuperMethodInvocation node, TreeNode removalSentinel) {
+ SuperMethodInvocation node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall(_flattenArguments(node.arguments));
} else {
- node.interfaceTarget =
- fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget);
+ node.interfaceTarget = fieldMorpher
+ .adjustInstanceCallTarget(node.interfaceTarget) as Procedure?;
if (node.interfaceTarget != null) {
- shaker.addUsedMember(node.interfaceTarget);
+ shaker.addUsedMember(node.interfaceTarget!);
}
return node;
}
@@ -1344,7 +1339,7 @@
@override
TreeNode visitSuperPropertyGet(
- SuperPropertyGet node, TreeNode removalSentinel) {
+ SuperPropertyGet node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([]);
@@ -1352,7 +1347,7 @@
node.interfaceTarget =
fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget);
if (node.interfaceTarget != null) {
- shaker.addUsedMember(node.interfaceTarget);
+ shaker.addUsedMember(node.interfaceTarget!);
}
return node;
}
@@ -1360,7 +1355,7 @@
@override
TreeNode visitSuperPropertySet(
- SuperPropertySet node, TreeNode removalSentinel) {
+ SuperPropertySet node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.value]);
@@ -1368,7 +1363,7 @@
node.interfaceTarget = fieldMorpher
.adjustInstanceCallTarget(node.interfaceTarget, isSetter: true);
if (node.interfaceTarget != null) {
- shaker.addUsedMember(node.interfaceTarget);
+ shaker.addUsedMember(node.interfaceTarget!);
}
return node;
}
@@ -1376,7 +1371,7 @@
@override
TreeNode visitStaticInvocation(
- StaticInvocation node, TreeNode removalSentinel) {
+ StaticInvocation node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall(_flattenArguments(node.arguments));
@@ -1390,7 +1385,7 @@
}
@override
- TreeNode visitStaticGet(StaticGet node, TreeNode removalSentinel) {
+ TreeNode visitStaticGet(StaticGet node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([]);
@@ -1405,13 +1400,13 @@
}
@override
- Constant visitConstant(Constant node, Constant removalSentinel) {
+ Constant visitConstant(Constant node, Constant? removalSentinel) {
shaker.constantVisitor.analyzeConstant(node);
return node;
}
@override
- TreeNode visitStaticSet(StaticSet node, TreeNode removalSentinel) {
+ TreeNode visitStaticSet(StaticSet node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.value]);
@@ -1428,7 +1423,7 @@
@override
TreeNode visitConstructorInvocation(
- ConstructorInvocation node, TreeNode removalSentinel) {
+ ConstructorInvocation node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall(_flattenArguments(node.arguments));
@@ -1444,7 +1439,7 @@
@override
TreeNode visitRedirectingInitializer(
- RedirectingInitializer node, TreeNode removalSentinel) {
+ RedirectingInitializer node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableInitializer(_flattenArguments(node.arguments));
@@ -1457,7 +1452,7 @@
@override
TreeNode visitSuperInitializer(
- SuperInitializer node, TreeNode removalSentinel) {
+ SuperInitializer node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableInitializer(_flattenArguments(node.arguments));
@@ -1469,7 +1464,7 @@
@override
TreeNode visitFieldInitializer(
- FieldInitializer node, TreeNode removalSentinel) {
+ FieldInitializer node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableInitializer([node.value]);
@@ -1482,7 +1477,7 @@
return LocalInitializer(
VariableDeclaration(null, initializer: node.value));
} else {
- return removalSentinel;
+ return removalSentinel!;
}
}
return node;
@@ -1491,18 +1486,18 @@
@override
TreeNode visitAssertStatement(
- AssertStatement node, TreeNode removalSentinel) {
+ AssertStatement node, TreeNode? removalSentinel) {
return _visitAssertNode(node, removalSentinel);
}
@override
- TreeNode visitAssertBlock(AssertBlock node, TreeNode removalSentinel) {
+ TreeNode visitAssertBlock(AssertBlock node, TreeNode? removalSentinel) {
return _visitAssertNode(node, removalSentinel);
}
@override
TreeNode visitAssertInitializer(
- AssertInitializer node, TreeNode removalSentinel) {
+ AssertInitializer node, TreeNode? removalSentinel) {
return _visitAssertNode(node, removalSentinel);
}
@@ -1520,21 +1515,21 @@
// Returns Block corresponding to the given extended bool literal,
// or null if the expression is a simple bool literal.
- Block _getExtendedBoolLiteralBlock(Expression expr) =>
+ Block? _getExtendedBoolLiteralBlock(Expression expr) =>
(expr is BoolLiteral) ? null : (expr as BlockExpression).body;
@override
- TreeNode visitIfStatement(IfStatement node, TreeNode removalSentinel) {
+ TreeNode visitIfStatement(IfStatement node, TreeNode? removalSentinel) {
final condition = transform(node.condition);
if (_isExtendedBoolLiteral(condition)) {
final bool conditionValue = _getExtendedBoolLiteralValue(condition);
- final Block conditionBlock = _getExtendedBoolLiteralBlock(condition);
- ast.Statement body;
+ final Block? conditionBlock = _getExtendedBoolLiteralBlock(condition);
+ ast.Statement? body;
if (conditionValue) {
body = transform(node.then);
} else {
if (node.otherwise != null) {
- body = transformOrRemoveStatement(node.otherwise);
+ body = transformOrRemoveStatement(node.otherwise!);
}
}
if (conditionBlock != null) {
@@ -1549,7 +1544,7 @@
node.condition = condition..parent = node;
node.then = transform(node.then)..parent = node;
if (node.otherwise != null) {
- node.otherwise = transformOrRemoveStatement(node.otherwise);
+ node.otherwise = transformOrRemoveStatement(node.otherwise!);
node.otherwise?.parent = node;
}
return node;
@@ -1557,7 +1552,7 @@
@override
visitConditionalExpression(
- ConditionalExpression node, TreeNode removalSentinel) {
+ ConditionalExpression node, TreeNode? removalSentinel) {
final condition = transform(node.condition);
if (_isExtendedBoolLiteral(condition)) {
final bool value = _getExtendedBoolLiteralValue(condition);
@@ -1578,7 +1573,7 @@
}
@override
- TreeNode visitNot(Not node, TreeNode removalSentinel) {
+ TreeNode visitNot(Not node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
final operand = node.operand;
if (_isExtendedBoolLiteral(operand)) {
@@ -1595,7 +1590,7 @@
@override
TreeNode visitLogicalExpression(
- LogicalExpression node, TreeNode removalSentinel) {
+ LogicalExpression node, TreeNode? removalSentinel) {
final left = transform(node.left);
final operatorEnum = node.operatorEnum;
if (_isExtendedBoolLiteral(left)) {
@@ -1621,8 +1616,8 @@
}
@override
- TreeNode visitIsExpression(IsExpression node, TreeNode removalSentinel) {
- TypeCheck check = shaker.typeFlowAnalysis.isTest(node);
+ TreeNode visitIsExpression(IsExpression node, TreeNode? removalSentinel) {
+ TypeCheck? check = shaker.typeFlowAnalysis.isTest(node);
if (check != null && (check.alwaysFail || check.alwaysPass)) {
final operand = transform(node.operand);
final result = BoolLiteral(!check.alwaysFail)
@@ -1634,9 +1629,9 @@
}
@override
- TreeNode visitAsExpression(AsExpression node, TreeNode removalSentinel) {
+ TreeNode visitAsExpression(AsExpression node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
- TypeCheck check = shaker.typeFlowAnalysis.explicitCast(node);
+ TypeCheck? check = shaker.typeFlowAnalysis.explicitCast(node);
if (check != null && check.alwaysPass) {
return StaticInvocation(
unsafeCast, Arguments([node.operand], types: [node.type]))
@@ -1646,9 +1641,9 @@
}
@override
- TreeNode visitNullCheck(NullCheck node, TreeNode removalSentinel) {
+ TreeNode visitNullCheck(NullCheck node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
- final nullTest = _getNullTest(node);
+ final nullTest = _getNullTest(node)!;
if (nullTest.isAlwaysNotNull) {
return StaticInvocation(
unsafeCast,
@@ -1659,12 +1654,9 @@
return node;
}
- Procedure get unsafeCast {
- _unsafeCast ??= shaker.typeFlowAnalysis.environment.coreTypes.index
- .getTopLevelMember('dart:_internal', 'unsafeCast');
- assert(_unsafeCast != null);
- return _unsafeCast;
- }
+ late final Procedure unsafeCast = shaker
+ .typeFlowAnalysis.environment.coreTypes.index
+ .getTopLevelProcedure('dart:_internal', 'unsafeCast');
}
/// The second pass of [TreeShaker]. It is called after set of used
@@ -1680,7 +1672,7 @@
void transformComponent(Component component) {
component.transformOrRemoveChildren(this);
for (Source source in component.uriToSource.values) {
- source?.constantCoverageConstructors?.removeWhere((Reference reference) {
+ source.constantCoverageConstructors?.removeWhere((Reference reference) {
Member node = reference.asMember;
return !shaker.isMemberUsed(node);
});
@@ -1688,7 +1680,7 @@
}
@override
- TreeNode visitLibrary(Library node, TreeNode removalSentinel) {
+ TreeNode visitLibrary(Library node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
// The transformer API does not iterate over `Library.additionalExports`,
// so we manually delete the references to shaken nodes.
@@ -1708,12 +1700,12 @@
}
@override
- Typedef visitTypedef(Typedef node, TreeNode removalSentinel) {
- return shaker.isTypedefUsed(node) ? node : removalSentinel;
+ TreeNode visitTypedef(Typedef node, TreeNode? removalSentinel) {
+ return shaker.isTypedefUsed(node) ? node : removalSentinel!;
}
@override
- Class visitClass(Class node, TreeNode removalSentinel) {
+ TreeNode visitClass(Class node, TreeNode? removalSentinel) {
if (!shaker.isClassUsed(node)) {
debugPrint('Dropped class ${node.name}');
// Ensure that kernel file writer will not be able to
@@ -1724,7 +1716,7 @@
"been repurposed for ${node.reference.node}.");
node.reference.canonicalName?.unbind();
Statistics.classesDropped++;
- return removalSentinel; // Remove the class.
+ return removalSentinel!; // Remove the class.
}
if (!shaker.isClassUsedInType(node)) {
@@ -1755,7 +1747,7 @@
}
@override
- Member defaultMember(Member node, TreeNode removalSentinel) {
+ TreeNode defaultMember(Member node, TreeNode? removalSentinel) {
if (!shaker.isMemberUsed(node)) {
// Ensure that kernel file writer will not be able to
// write a dangling reference to the deleted member.
@@ -1767,10 +1759,10 @@
node.getterReference.canonicalName?.unbind();
if (node.hasSetter) {
assert(
- node.setterReference.node == node,
+ node.setterReference!.node == node,
"Trying to remove canonical name from reference on $node which "
- "has been repurposed for ${node.setterReference.node}.");
- node.setterReference.canonicalName?.unbind();
+ "has been repurposed for ${node.setterReference!.node}.");
+ node.setterReference!.canonicalName?.unbind();
}
} else {
assert(
@@ -1780,13 +1772,13 @@
node.reference.canonicalName?.unbind();
}
Statistics.membersDropped++;
- return removalSentinel;
+ return removalSentinel!;
}
if (!shaker.isMemberBodyReachable(node)) {
if (node is Procedure) {
// Remove body of unused member.
- if (!node.isStatic && node.enclosingClass.isAbstract) {
+ if (!node.isStatic && node.enclosingClass!.isAbstract) {
node.isAbstract = true;
node.function.body = null;
} else {
@@ -1829,7 +1821,7 @@
}
@override
- Extension visitExtension(Extension node, TreeNode removalSentinel) {
+ TreeNode visitExtension(Extension node, TreeNode? removalSentinel) {
if (shaker.isExtensionUsed(node)) {
int writeIndex = 0;
for (int i = 0; i < node.members.length; ++i) {
@@ -1840,7 +1832,7 @@
// member was already removed or it will be removed later.
final Reference memberReference = descriptor.member;
final bool isBound = memberReference.node != null;
- if (isBound && shaker.isMemberUsed(memberReference.node)) {
+ if (isBound && shaker.isMemberUsed(memberReference.asMember)) {
node.members[writeIndex++] = descriptor;
}
}
@@ -1850,7 +1842,7 @@
assert(node.members.length > 0);
return node;
}
- return removalSentinel;
+ return removalSentinel!;
}
void _makeUnreachableBody(FunctionNode function) {
@@ -1871,7 +1863,7 @@
}
@override
- TreeNode defaultTreeNode(TreeNode node, TreeNode removalSentinel) {
+ TreeNode defaultTreeNode(TreeNode node, TreeNode? removalSentinel) {
return node; // Do not traverse into other nodes.
}
}
diff --git a/pkg/vm/lib/transformations/type_flow/types.dart b/pkg/vm/lib/transformations/type_flow/types.dart
index 588512c..3ed7b9b 100644
--- a/pkg/vm/lib/transformations/type_flow/types.dart
+++ b/pkg/vm/lib/transformations/type_flow/types.dart
@@ -2,10 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
/// Declares the type system used by global type flow analysis.
-library vm.transformations.type_flow.types;
import 'dart:core' hide Type;
@@ -138,10 +135,7 @@
/// values can flow through the program.
Type specializeTypeCone(TFClass base, {bool allowWideCone = false});
- Type _cachedIntType;
- Type get intType {
- return _cachedIntType ??= fromStaticType(coreTypes.intLegacyRawType, true);
- }
+ late final Type intType = fromStaticType(coreTypes.intLegacyRawType, true);
}
/// Base class for type expressions.
@@ -151,7 +145,7 @@
/// Returns computed type of this type expression.
/// [types] is the list of types computed for the statements in the summary.
- Type getComputedType(List<Type> types);
+ Type getComputedType(List<Type?> types);
}
/// Kind of a subtype test: subtype/cast/'as' test or instance check/'is' test.
@@ -174,7 +168,7 @@
/// Create a type representing arbitrary nullable object (`dynamic`).
factory Type.nullableAny() => new NullableType(const AnyType());
- Class getConcreteClass(TypeHierarchy typeHierarchy) => null;
+ Class? getConcreteClass(TypeHierarchy typeHierarchy) => null;
bool isSubtypeOf(TypeHierarchy typeHierarchy, Class cls) => false;
@@ -185,7 +179,7 @@
RuntimeType runtimeType, SubtypeTestKind kind);
@override
- Type getComputedType(List<Type> types) => this;
+ Type getComputedType(List<Type?> types) => this;
/// Order of precedence for evaluation of union/intersection.
int get order;
@@ -260,7 +254,6 @@
final Type baseType;
NullableType(this.baseType) {
- assert(baseType != null);
assert(baseType is! NullableType);
}
@@ -387,7 +380,9 @@
class SetType extends Type {
/// List of concrete types, sorted by classId.
final List<ConcreteType> types;
- int _hashCode;
+
+ @override
+ late final int hashCode = _computeHashCode();
/// Creates a new SetType using list of concrete types sorted by classId.
SetType(this.types) {
@@ -395,9 +390,6 @@
assert(isSorted(types));
}
- @override
- int get hashCode => _hashCode ??= _computeHashCode();
-
int _computeHashCode() {
int hash = 1237;
for (var t in types) {
@@ -470,8 +462,8 @@
return types;
}
- static List<ConcreteType> _intersectLists(
- List<ConcreteType> types1, List<ConcreteType> types2) {
+ static List<ConcreteType> _intersectLists(List<ConcreteType> types1,
+ List<ConcreteType> types2, TypeHierarchy typeHierarchy) {
int i1 = 0;
int i2 = 0;
List<ConcreteType> types = <ConcreteType>[];
@@ -491,9 +483,9 @@
t2.constant == null) {
types.add(t1);
} else {
- final intersect = t1.intersection(t2, null);
+ final intersect = t1.intersection(t2, typeHierarchy);
if (intersect is! EmptyType) {
- types.add(intersect);
+ types.add(intersect as ConcreteType);
}
}
++i1;
@@ -558,7 +550,8 @@
return other.intersection(this, typeHierarchy);
}
if (other is SetType) {
- List<ConcreteType> list = _intersectLists(types, other.types);
+ List<ConcreteType> list =
+ _intersectLists(types, other.types, typeHierarchy);
final size = list.length;
if (size == 0) {
return const EmptyType();
@@ -594,7 +587,7 @@
ConeType(this.cls);
@override
- Class getConcreteClass(TypeHierarchy typeHierarchy) => typeHierarchy
+ Class? getConcreteClass(TypeHierarchy typeHierarchy) => typeHierarchy
.specializeTypeCone(cls, allowWideCone: true)
.getConcreteClass(typeHierarchy);
@@ -696,7 +689,7 @@
WideConeType(TFClass cls) : super(cls);
@override
- Class getConcreteClass(TypeHierarchy typeHierarchy) => null;
+ Class? getConcreteClass(TypeHierarchy typeHierarchy) => null;
@override
int get hashCode => (cls.id + 41) & kHashMask;
@@ -783,7 +776,9 @@
/// or `null` object).
class ConcreteType extends Type implements Comparable<ConcreteType> {
final TFClass cls;
- int _hashCode;
+
+ @override
+ late final int hashCode = _computeHashCode();
// May be null if there are no type arguments constraints. The type arguments
// should represent type sets, i.e. `UnknownType` or `RuntimeType`. The type
@@ -796,19 +791,19 @@
// 'numImmediateTypeArgs' is the length of the prefix of 'typeArgs' which
// holds the type arguments to the class itself.
final int numImmediateTypeArgs;
- final List<Type> typeArgs;
+ final List<Type>? typeArgs;
// May be null if constant value is not inferred.
- final Constant constant;
+ final Constant? constant;
- ConcreteType(this.cls, [List<Type> typeArgs_, this.constant])
+ ConcreteType(this.cls, [List<Type>? typeArgs_, this.constant])
: typeArgs = typeArgs_,
numImmediateTypeArgs =
typeArgs_ != null ? cls.classNode.typeParameters.length : 0 {
// TODO(alexmarkov): support closures
assert(!cls.classNode.isAbstract);
assert(typeArgs == null || cls.classNode.typeParameters.isNotEmpty);
- assert(typeArgs == null || typeArgs.any((t) => t is RuntimeType));
+ assert(typeArgs == null || typeArgs!.any((t) => t is RuntimeType));
}
ConcreteType get raw => cls.concreteType;
@@ -839,7 +834,7 @@
if (rhs.typeArguments.isEmpty) return true;
- List<Type> usableTypeArgs = typeArgs;
+ List<Type>? usableTypeArgs = typeArgs;
if (usableTypeArgs == null) {
if (cls.classNode.typeParameters.isEmpty) {
usableTypeArgs =
@@ -862,7 +857,7 @@
}
assert(ta is RuntimeType);
if (!ta.isSubtypeOfRuntimeType(
- typeHierarchy, runtimeType.typeArgs[i], SubtypeTestKind.Subtype)) {
+ typeHierarchy, runtimeType.typeArgs![i], SubtypeTestKind.Subtype)) {
return false;
}
}
@@ -877,29 +872,26 @@
} else {
final interfaceOffset = typeHierarchy.genericInterfaceOffsetFor(
cls.classNode, typeHierarchy.coreTypes.futureClass);
- typeArg = typeArgs[interfaceOffset];
+ typeArg = typeArgs![interfaceOffset];
}
final RuntimeType lhs =
typeArg is RuntimeType ? typeArg : RuntimeType(DynamicType(), null);
return lhs.isSubtypeOfRuntimeType(
- typeHierarchy, runtimeType.typeArgs[0], SubtypeTestKind.Subtype);
+ typeHierarchy, runtimeType.typeArgs![0], SubtypeTestKind.Subtype);
} else {
return isSubtypeOfRuntimeType(
- typeHierarchy, runtimeType.typeArgs[0], SubtypeTestKind.Subtype);
+ typeHierarchy, runtimeType.typeArgs![0], SubtypeTestKind.Subtype);
}
}
return false;
}
- @override
- int get hashCode => _hashCode ??= _computeHashCode();
-
int _computeHashCode() {
int hash = cls.hashCode ^ 0x1234 & kHashMask;
// We only need to hash the first type arguments vector, since the type
// arguments of the implemented interfaces are implied by it.
for (int i = 0; i < numImmediateTypeArgs; ++i) {
- hash = (((hash * 31) & kHashMask) + typeArgs[i].hashCode) & kHashMask;
+ hash = (((hash * 31) & kHashMask) + typeArgs![i].hashCode) & kHashMask;
}
hash = ((hash * 31) & kHashMask) + constant.hashCode;
return hash;
@@ -915,7 +907,7 @@
}
if (this.typeArgs != null) {
for (int i = 0; i < numImmediateTypeArgs; ++i) {
- if (this.typeArgs[i] != other.typeArgs[i]) {
+ if (this.typeArgs![i] != other.typeArgs![i]) {
return false;
}
}
@@ -942,10 +934,10 @@
final StringBuffer buf = new StringBuffer();
buf.write("_T (${cls}");
if (typeArgs != null) {
- buf.write("<${typeArgs.take(numImmediateTypeArgs).join(', ')}>");
+ buf.write("<${typeArgs!.take(numImmediateTypeArgs).join(', ')}>");
}
if (constant != null) {
- buf.write(", ${nodeToText(constant)}");
+ buf.write(", ${nodeToText(constant!)}");
}
buf.write(")");
return buf.toString();
@@ -997,17 +989,21 @@
return this;
}
- List<Type> mergedTypeArgs;
- if (typeArgs == null) {
- mergedTypeArgs = other.typeArgs;
- } else if (other.typeArgs == null) {
- mergedTypeArgs = typeArgs;
+ List<Type>? mergedTypeArgs;
+ final thisTypeArgs = this.typeArgs;
+ final otherTypeArgs = other.typeArgs;
+ if (thisTypeArgs == null) {
+ mergedTypeArgs = otherTypeArgs;
+ } else if (otherTypeArgs == null) {
+ mergedTypeArgs = thisTypeArgs;
} else {
- mergedTypeArgs = new List<Type>.filled(typeArgs.length, null);
+ assert(thisTypeArgs.length == otherTypeArgs.length);
+ mergedTypeArgs =
+ new List<Type>.filled(thisTypeArgs.length, const EmptyType());
bool hasRuntimeType = false;
- for (int i = 0; i < typeArgs.length; ++i) {
+ for (int i = 0; i < thisTypeArgs.length; ++i) {
final merged =
- typeArgs[i].intersection(other.typeArgs[i], typeHierarchy);
+ thisTypeArgs[i].intersection(otherTypeArgs[i], typeHierarchy);
if (merged is EmptyType) {
return const EmptyType();
} else if (merged is RuntimeType) {
@@ -1020,7 +1016,7 @@
}
}
- Constant mergedConstant;
+ Constant? mergedConstant;
if (constant == null) {
mergedConstant = other.constant;
} else if (other.constant == null || constant == other.constant) {
@@ -1062,7 +1058,7 @@
final DartType _type; // Doesn't contain type args.
final int numImmediateTypeArgs;
- final List<RuntimeType> typeArgs;
+ final List<RuntimeType>? typeArgs;
RuntimeType(DartType type, this.typeArgs)
: _type = type,
@@ -1070,14 +1066,12 @@
? type.classNode.typeParameters.length
: (type is FutureOrType ? 1 : 0) {
if (_type is InterfaceType && numImmediateTypeArgs > 0) {
- assert(typeArgs != null);
- assert(typeArgs.length >= numImmediateTypeArgs);
+ assert(typeArgs!.length >= numImmediateTypeArgs);
assert((_type as InterfaceType)
.typeArguments
.every((t) => t == const DynamicType()));
} else if (_type is FutureOrType) {
- assert(typeArgs != null);
- assert(typeArgs.length >= numImmediateTypeArgs);
+ assert(typeArgs!.length >= numImmediateTypeArgs);
DartType typeArgument = (_type as FutureOrType).typeArgument;
assert(typeArgument == const DynamicType());
} else {
@@ -1098,25 +1092,27 @@
final type = _type;
if (type is InterfaceType && typeArgs != null) {
final klass = type.classNode;
- final typeArguments = typeArgs
+ final typeArguments = typeArgs!
.take(klass.typeParameters.length)
.map((pt) => pt.representedType)
.toList();
return new InterfaceType(klass, type.nullability, typeArguments);
} else if (type is FutureOrType) {
- return new FutureOrType(typeArgs[0].representedType, type.nullability);
+ return new FutureOrType(typeArgs![0].representedType, type.nullability);
} else {
return type;
}
}
@override
- int get hashCode {
+ late final int hashCode = _computeHashCode();
+
+ int _computeHashCode() {
int hash = _type.hashCode ^ 0x1234 & kHashMask;
// Only hash by the type arguments of the class. The type arguments of
// supertypes are are implied by them.
for (int i = 0; i < numImmediateTypeArgs; ++i) {
- hash = (((hash * 31) & kHashMask) + typeArgs[i].hashCode) & kHashMask;
+ hash = (((hash * 31) & kHashMask) + typeArgs![i].hashCode) & kHashMask;
}
return hash;
}
@@ -1127,7 +1123,7 @@
if (other is RuntimeType) {
if (other._type != _type) return false;
assert(numImmediateTypeArgs == other.numImmediateTypeArgs);
- return typeArgs == null || listEquals(typeArgs, other.typeArgs);
+ return typeArgs == null || listEquals(typeArgs!, other.typeArgs!);
}
return false;
}
@@ -1139,7 +1135,7 @@
: "${nodeToText(_type)}";
final typeArgsStrs = (numImmediateTypeArgs == 0)
? ""
- : "<${typeArgs.take(numImmediateTypeArgs).map((t) => "$t").join(", ")}>";
+ : "<${typeArgs!.take(numImmediateTypeArgs).map((t) => "$t").join(", ")}>";
final nullability = _type.nullability.suffix;
return "$head$typeArgsStrs$nullability";
}
@@ -1200,15 +1196,15 @@
if (_type is InterfaceType) {
Class thisClass = (_type as InterfaceType).classNode;
if (thisClass == typeHierarchy.coreTypes.futureClass) {
- return typeArgs[0].isSubtypeOfRuntimeType(
- typeHierarchy, runtimeType.typeArgs[0], SubtypeTestKind.Subtype);
+ return typeArgs![0].isSubtypeOfRuntimeType(
+ typeHierarchy, runtimeType.typeArgs![0], SubtypeTestKind.Subtype);
} else {
return isSubtypeOfRuntimeType(
- typeHierarchy, runtimeType.typeArgs[0], SubtypeTestKind.Subtype);
+ typeHierarchy, runtimeType.typeArgs![0], SubtypeTestKind.Subtype);
}
} else if (_type is FutureOrType) {
- return typeArgs[0].isSubtypeOfRuntimeType(
- typeHierarchy, runtimeType.typeArgs[0], SubtypeTestKind.Subtype);
+ return typeArgs![0].isSubtypeOfRuntimeType(
+ typeHierarchy, runtimeType.typeArgs![0], SubtypeTestKind.Subtype);
}
}
@@ -1236,7 +1232,7 @@
return true;
}
- List<Type> usableTypeArgs = typeArgs;
+ List<Type>? usableTypeArgs = typeArgs;
if (usableTypeArgs == null) {
assert(thisClass.typeParameters.isEmpty);
usableTypeArgs =
@@ -1248,7 +1244,7 @@
runtimeType.numImmediateTypeArgs);
for (int i = 0; i < runtimeType.numImmediateTypeArgs; ++i) {
if (!usableTypeArgs[interfaceOffset + i].isSubtypeOfRuntimeType(
- typeHierarchy, runtimeType.typeArgs[i], SubtypeTestKind.Subtype)) {
+ typeHierarchy, runtimeType.typeArgs![i], SubtypeTestKind.Subtype)) {
return false;
}
}
diff --git a/pkg/vm/lib/transformations/type_flow/unboxing_info.dart b/pkg/vm/lib/transformations/type_flow/unboxing_info.dart
index 723e673..682cf58 100644
--- a/pkg/vm/lib/transformations/type_flow/unboxing_info.dart
+++ b/pkg/vm/lib/transformations/type_flow/unboxing_info.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart';
import 'package:kernel/external_name.dart' show getExternalName;
@@ -30,12 +28,12 @@
_coreTypes = typeFlowAnalysis.environment.coreTypes,
_nativeCodeOracle = typeFlowAnalysis.nativeCodeOracle;
- UnboxingInfoMetadata getUnboxingInfoOfMember(Member member) {
- final UnboxingInfoMetadata info = _memberInfo[member];
+ UnboxingInfoMetadata? getUnboxingInfoOfMember(Member member) {
+ final UnboxingInfoMetadata? info = _memberInfo[member];
if (member is Procedure && member.isGetter) {
// Remove placeholder parameter info slot for setters that the getter is
// grouped with.
- return UnboxingInfoMetadata(0)..returnInfo = info.returnInfo;
+ return UnboxingInfoMetadata(0)..returnInfo = info!.returnInfo;
}
return info;
}
@@ -81,8 +79,8 @@
? (member.hasSetter ? 1 : 0)
: member is Procedure && member.isGetter
? 1
- : member.function.requiredParameterCount;
- UnboxingInfoMetadata info;
+ : member.function!.requiredParameterCount;
+ UnboxingInfoMetadata? info;
if (member.isInstanceMember) {
int selectorId =
member is Field || member is Procedure && member.isGetter
@@ -121,20 +119,18 @@
void _updateUnboxingInfoOfMember(
Member member, TypeFlowAnalysis typeFlowAnalysis) {
if (typeFlowAnalysis.isMemberUsed(member)) {
- final UnboxingInfoMetadata unboxingInfo = _memberInfo[member];
+ final UnboxingInfoMetadata unboxingInfo = _memberInfo[member]!;
if (_cannotUnbox(member)) {
unboxingInfo.unboxedArgsInfo.length = 0;
unboxingInfo.returnInfo = UnboxingInfoMetadata.kBoxed;
return;
}
if (member is Procedure || member is Constructor) {
- final Args<Type> argTypes = typeFlowAnalysis.argumentTypes(member);
- assert(argTypes != null);
-
+ final Args<Type> argTypes = typeFlowAnalysis.argumentTypes(member)!;
final int firstParamIndex =
numTypeParams(member) + (hasReceiverArg(member) ? 1 : 0);
- final positionalParams = member.function.positionalParameters;
+ final positionalParams = member.function!.positionalParameters;
assert(argTypes.positionalCount ==
firstParamIndex + positionalParams.length);
diff --git a/pkg/vm/lib/transformations/type_flow/utils.dart b/pkg/vm/lib/transformations/type_flow/utils.dart
index b04e69e..c85dfc7 100644
--- a/pkg/vm/lib/transformations/type_flow/utils.dart
+++ b/pkg/vm/lib/transformations/type_flow/utils.dart
@@ -2,12 +2,11 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
/// Declares miscellaneous utility functions and constants for type flow
/// analysis.
library vm.transformations.type_flow.utils;
+import 'package:collection/collection.dart' show IterableExtension;
import 'package:kernel/ast.dart';
import 'package:kernel/src/printer.dart';
@@ -123,9 +122,8 @@
return true;
}
-VariableDeclaration findNamedParameter(FunctionNode function, String name) {
- return function.namedParameters
- .firstWhere((p) => p.name == name, orElse: () => null);
+VariableDeclaration? findNamedParameter(FunctionNode function, String name) {
+ return function.namedParameters.firstWhereOrNull((p) => p.name == name);
}
class Histogram<K> {
@@ -143,7 +141,7 @@
print(
'-------------------------------------------------------------------');
List<K> keys = values.keys.toList();
- keys.sort((k1, k2) => values[k1].compareTo(values[k2]));
+ keys.sort((k1, k2) => values[k1]!.compareTo(values[k2]!));
final cut = keys.length < n ? 0 : keys.length - n;
for (int i = keys.length - 1; i >= cut; --i) {
final k = keys[i];
@@ -376,7 +374,7 @@
};
extension NullabilitySuffix on Nullability {
- String get suffix => nullabilitySuffix[this];
+ String get suffix => nullabilitySuffix[this]!;
}
bool mayHaveSideEffects(Expression node) {
diff --git a/pkg/vm/pubspec.yaml b/pkg/vm/pubspec.yaml
index f57cf389..0e78a09 100644
--- a/pkg/vm/pubspec.yaml
+++ b/pkg/vm/pubspec.yaml
@@ -18,6 +18,7 @@
meta:
path: ../meta
package_config: any
+ collection: ^1.15.0
dev_dependencies:
expect:
diff --git a/pkg/vm/test/common_test_utils.dart b/pkg/vm/test/common_test_utils.dart
index 3f8bf9c..1ff586a 100644
--- a/pkg/vm/test/common_test_utils.dart
+++ b/pkg/vm/test/common_test_utils.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
import 'dart:async';
import 'dart:io';
@@ -37,11 +35,11 @@
}
Future<Component> compileTestCaseToKernelProgram(Uri sourceUri,
- {Target target,
+ {Target? target,
bool enableSuperMixins = false,
- List<String> experimentalFlags,
- Map<String, String> environmentDefines,
- Uri packagesFileUri}) async {
+ List<String>? experimentalFlags,
+ Map<String, String>? environmentDefines,
+ Uri? packagesFileUri}) async {
final platformKernel =
computePlatformBinariesLocation().resolve('vm_platform_strong.dill');
target ??= new TestingVmTarget(new TargetFlags())
@@ -62,11 +60,11 @@
};
final Component component =
- (await kernelForProgram(sourceUri, options)).component;
+ (await kernelForProgram(sourceUri, options))!.component!;
// Make sure the library name is the same and does not depend on the order
// of test cases.
- component.mainMethod.enclosingLibrary.name = '#lib';
+ component.mainMethod!.enclosingLibrary.name = '#lib';
return component;
}
@@ -75,19 +73,19 @@
final StringBuffer buffer = new StringBuffer();
final printer = new Printer(buffer, showMetadata: true);
printer.writeLibraryFile(library);
- printer.writeConstantTable(library.enclosingComponent);
+ printer.writeConstantTable(library.enclosingComponent!);
return buffer
.toString()
- .replaceAll(library.importUri.toString(), library.name);
+ .replaceAll(library.importUri.toString(), library.name!);
}
String kernelComponentToString(Component component) {
final StringBuffer buffer = new StringBuffer();
new Printer(buffer, showMetadata: true).writeComponentFile(component);
- final mainLibrary = component.mainMethod.enclosingLibrary;
+ final mainLibrary = component.mainMethod!.enclosingLibrary;
return buffer
.toString()
- .replaceAll(mainLibrary.importUri.toString(), mainLibrary.name);
+ .replaceAll(mainLibrary.importUri.toString(), mainLibrary.name!);
}
class DevNullSink<T> extends Sink<T> {
diff --git a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
index f9ea8d7..2e25344 100644
--- a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
+++ b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
@@ -60,7 +60,7 @@
void recordMemberCalledViaThis(Member target) {}
@override
- void recordTearOff(Procedure target) {}
+ void recordTearOff(Member target) {}
}
class PrintSummaries extends RecursiveVisitor {
@@ -78,7 +78,7 @@
typesBuilder,
new NativeCodeOracle(
null, new ConstantPragmaAnnotationParser(coreTypes)),
- new GenericInterfacesInfoImpl(hierarchy),
+ new GenericInterfacesInfoImpl(coreTypes, hierarchy),
/*_protobufHandler=*/ null);
}
diff --git a/runtime/tests/vm/dart/isolates/dart_api_create_lightweight_isolate_test.dart b/runtime/tests/vm/dart/isolates/dart_api_create_lightweight_isolate_test.dart
index 0087928..2fa4962 100644
--- a/runtime/tests/vm/dart/isolates/dart_api_create_lightweight_isolate_test.dart
+++ b/runtime/tests/vm/dart/isolates/dart_api_create_lightweight_isolate_test.dart
@@ -14,6 +14,7 @@
import 'package:expect/expect.dart';
import 'package:ffi/ffi.dart';
+import 'test_utils.dart' show isArtificialReloadMode;
import '../../../../../tests/ffi/dylib_utils.dart';
final bool isolateGroupsEnabled =
@@ -240,5 +241,10 @@
await testNotSupported();
return;
}
+
+ // This test should not run in hot-reload because of the way it is written
+ // (embedder related code written in Dart instead of C)
+ if (isArtificialReloadMode) return;
+
await testJitOrAot();
}
diff --git a/runtime/tests/vm/dart_2/isolates/dart_api_create_lightweight_isolate_test.dart b/runtime/tests/vm/dart_2/isolates/dart_api_create_lightweight_isolate_test.dart
index 5ce5984..8b92de1 100644
--- a/runtime/tests/vm/dart_2/isolates/dart_api_create_lightweight_isolate_test.dart
+++ b/runtime/tests/vm/dart_2/isolates/dart_api_create_lightweight_isolate_test.dart
@@ -14,6 +14,7 @@
import 'package:expect/expect.dart';
import 'package:ffi/ffi.dart';
+import 'test_utils.dart' show isArtificialReloadMode;
import '../../../../../tests/ffi/dylib_utils.dart';
final bool isolateGroupsEnabled =
@@ -240,5 +241,10 @@
await testNotSupported();
return;
}
+
+ // This test should not run in hot-reload because of the way it is written
+ // (embedder related code written in Dart instead of C)
+ if (isArtificialReloadMode) return;
+
await testJitOrAot();
}
diff --git a/tools/VERSION b/tools/VERSION
index 8235dad..3b8e28a 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 14
PATCH 0
-PRERELEASE 357
+PRERELEASE 358
PRERELEASE_PATCH 0
\ No newline at end of file