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