From 327bc451f8397f393808454ff65ee09bc2cb18ed Mon Sep 17 00:00:00 2001 From: Kallen Tu Date: Thu, 26 Sep 2019 18:11:10 +0000 Subject: [PATCH] Added variance support in listeners to ast. Pass variance data to field in TypeParameter through the listeners. ast_to_text will print variances for classes and mixins if specified. Avoids serialization/deserialization (impl in future CL). Change-Id: I298537604823710f0d30001f4cb5f1e81530959f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/118464 Commit-Queue: Kallen Tu Reviewed-by: Dmitry Stefantsov --- pkg/analyzer/lib/src/fasta/ast_builder.dart | 3 +- .../test/generated/parser_fasta_listener.dart | 5 +- .../lib/src/fasta/kernel/body_builder.dart | 6 +- .../src/fasta/parser/forwarding_listener.dart | 5 +- .../lib/src/fasta/parser/listener.dart | 3 +- .../lib/src/fasta/parser/type_info_impl.dart | 4 +- .../lib/src/fasta/source/diet_listener.dart | 3 +- .../lib/src/fasta/source/outline_builder.dart | 8 ++- .../type_promotion_look_ahead_listener.dart | 8 ++- .../test/fasta/parser/type_info_test.dart | 67 ++++++++++--------- pkg/front_end/test/parser_test_listener.dart | 9 ++- .../testcases/text_serialization.status | 2 + .../class_type_parameter_modifier.dart | 9 +++ ...ype_parameter_modifier.dart.outline.expect | 10 +++ ...type_parameter_modifier.dart.strong.expect | 12 ++++ ...er_modifier.dart.strong.transformed.expect | 12 ++++ .../mixin_type_parameter_modifier.dart | 9 +++ ...ype_parameter_modifier.dart.outline.expect | 12 ++++ ...type_parameter_modifier.dart.strong.expect | 12 ++++ ...er_modifier.dart.strong.transformed.expect | 12 ++++ pkg/front_end/testcases/variance/test.options | 1 + pkg/kernel/lib/ast.dart | 12 ++++ 22 files changed, 176 insertions(+), 48 deletions(-) create mode 100644 pkg/front_end/testcases/variance/class_type_parameter_modifier.dart create mode 100644 pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.outline.expect create mode 100644 pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.strong.expect create mode 100644 pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart create mode 100644 pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.outline.expect create mode 100644 pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.strong.expect create mode 100644 pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/variance/test.options diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart index 078a9da4e91..df889e02256 100644 --- a/pkg/analyzer/lib/src/fasta/ast_builder.dart +++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart @@ -2090,7 +2090,8 @@ class AstBuilder extends StackListener { } @override - void endTypeVariable(Token token, int index, Token extendsOrSuper) { + void endTypeVariable( + Token token, int index, Token extendsOrSuper, Token variance) { debugEvent("TypeVariable"); assert(extendsOrSuper == null || optional('extends', extendsOrSuper) || diff --git a/pkg/analyzer/test/generated/parser_fasta_listener.dart b/pkg/analyzer/test/generated/parser_fasta_listener.dart index f3145f8ae58..203d6db4f10 100644 --- a/pkg/analyzer/test/generated/parser_fasta_listener.dart +++ b/pkg/analyzer/test/generated/parser_fasta_listener.dart @@ -1152,9 +1152,10 @@ class ForwardingTestListener extends ForwardingListener { } @override - void endTypeVariable(Token token, int index, Token extendsOrSuper) { + void endTypeVariable( + Token token, int index, Token extendsOrSuper, Token variance) { end('TypeVariable'); - super.endTypeVariable(token, index, extendsOrSuper); + super.endTypeVariable(token, index, extendsOrSuper, variance); } @override diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart index dd4884bc232..656b1ae6d1a 100644 --- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart @@ -4767,7 +4767,8 @@ class BodyBuilder extends ScopeListener } @override - void endTypeVariable(Token token, int index, Token extendsOrSuper) { + void endTypeVariable( + Token token, int index, Token extendsOrSuper, Token variance) { debugEvent("TypeVariable"); UnresolvedType bound = pop(); // Peek to leave type parameters on top of stack. @@ -4775,6 +4776,9 @@ class BodyBuilder extends ScopeListener TypeVariableBuilder variable = typeVariables[index]; variable.bound = bound?.builder; + if (variance != null) { + variable.variance = Variance.fromString(variance.lexeme); + } } @override diff --git a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart index af3ed3bddb8..f5e93205813 100644 --- a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart +++ b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart @@ -993,8 +993,9 @@ class ForwardingListener implements Listener { } @override - void endTypeVariable(Token token, int index, Token extendsOrSuper) { - listener?.endTypeVariable(token, index, extendsOrSuper); + void endTypeVariable( + Token token, int index, Token extendsOrSuper, Token variance) { + listener?.endTypeVariable(token, index, extendsOrSuper, variance); } @override diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart index 9c67ac48988..e5f5fad0a93 100644 --- a/pkg/front_end/lib/src/fasta/parser/listener.dart +++ b/pkg/front_end/lib/src/fasta/parser/listener.dart @@ -1220,7 +1220,8 @@ class Listener implements UnescapeErrorListener { /// - Type bound /// /// See [beginTypeVariable] for additional substructures. - void endTypeVariable(Token token, int index, Token extendsOrSuper) { + void endTypeVariable( + Token token, int index, Token extendsOrSuper, Token variance) { logEvent("TypeVariable"); } diff --git a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart index 2a16412ec05..de9c32dd3c5 100644 --- a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart +++ b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart @@ -763,7 +763,7 @@ class SimpleTypeArgument1 extends TypeParamOrArgInfo { listener.beginTypeVariable(token); listener.handleTypeVariablesDefined(token, 1); listener.handleNoType(token); - listener.endTypeVariable(endGroup, 0, null); + listener.endTypeVariable(endGroup, 0, null, null); listener.endTypeVariables(beginGroup, endGroup); return endGroup; } @@ -1075,7 +1075,7 @@ class ComplexTypeParamOrArgInfo extends TypeParamOrArgInfo { // Type variables are "completed" in reverse order, so capture the last // consumed token from the first "completed" type variable. token ??= token2; - listener.endTypeVariable(next2, --count, extendsOrSuper); + listener.endTypeVariable(next2, --count, extendsOrSuper, variance); typeStarts = typeStarts.tail; superTypeInfos = superTypeInfos.tail; diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart index e24dd3c3e15..10bb91eb352 100644 --- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart +++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart @@ -544,7 +544,8 @@ class DietListener extends StackListener { } @override - void endTypeVariable(Token token, int index, Token extendsOrSuper) { + void endTypeVariable( + Token token, int index, Token extendsOrSuper, Token variance) { debugEvent("endTypeVariable"); } diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart index 77ca872f32f..03775991ea9 100644 --- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart +++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart @@ -4,7 +4,7 @@ library fasta.outline_builder; -import 'package:kernel/ast.dart' show ProcedureKind; +import 'package:kernel/ast.dart' show ProcedureKind, Variance; import '../builder/builder.dart'; @@ -1574,13 +1574,17 @@ class OutlineBuilder extends StackListener { } @override - void endTypeVariable(Token token, int index, Token extendsOrSuper) { + void endTypeVariable( + Token token, int index, Token extendsOrSuper, Token variance) { debugEvent("endTypeVariable"); TypeBuilder bound = nullIfParserRecovery(pop()); // Peek to leave type parameters on top of stack. List typeParameters = peek(); if (typeParameters != null) { typeParameters[index].bound = bound; + if (variance != null) { + typeParameters[index].variance = Variance.fromString(variance.lexeme); + } } } diff --git a/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart b/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart index 8a1c08d928e..67cdaec9ac9 100644 --- a/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart +++ b/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart @@ -1316,7 +1316,8 @@ class TypePromotionLookAheadListener extends Listener { } @override - void endTypeVariable(Token token, int index, Token extendsOrSuper) { + void endTypeVariable( + Token token, int index, Token extendsOrSuper, Token variance) { debugEvent("TypeVariable", token); state.pop(); // Name. } @@ -1326,6 +1327,11 @@ class TypePromotionLookAheadListener extends Listener { debugEvent("TypeVariables", beginToken); } + @override + void handleVarianceModifier(Token variance) { + debugEvent("VarianceModifier", variance); + } + @override void handleNoTypeVariables(Token token) { debugEvent("NoTypeVariables", token); diff --git a/pkg/front_end/test/fasta/parser/type_info_test.dart b/pkg/front_end/test/fasta/parser/type_info_test.dart index 1dd605140c8..dc5203c2ab0 100644 --- a/pkg/front_end/test/fasta/parser/type_info_test.dart +++ b/pkg/front_end/test/fasta/parser/type_info_test.dart @@ -695,7 +695,7 @@ class TypeInfoTest { 'beginTypeVariable T', 'handleTypeVariablesDefined T 1', 'handleNoType T', - 'endTypeVariable > 0 null', + 'endTypeVariable > 0 null null', 'endTypeVariables < >', 'beginFunctionType Function', 'handleNoType ', @@ -729,7 +729,7 @@ class TypeInfoTest { 'beginTypeVariable T', 'handleTypeVariablesDefined T 1', 'handleNoType T', - 'endTypeVariable > 0 null', + 'endTypeVariable > 0 null null', 'endTypeVariables < >', 'beginFunctionType Function', 'handleNoType ', @@ -1377,7 +1377,7 @@ class TypeInfoTest { 'beginTypeVariable T', 'handleTypeVariablesDefined T 1', 'handleNoType T', - 'endTypeVariable > 0 null', + 'endTypeVariable > 0 null null', 'endTypeVariables < >', 'beginFunctionType C', 'beginTypeVariables <', @@ -1387,7 +1387,7 @@ class TypeInfoTest { 'beginTypeVariable T', 'handleTypeVariablesDefined T 1', 'handleNoType T', - 'endTypeVariable > 0 null', + 'endTypeVariable > 0 null null', 'endTypeVariables < >', 'beginFunctionType C', 'handleIdentifier C prefixedTypeReference', @@ -1638,7 +1638,7 @@ class SimpleTypeParamOrArgTest { 'beginTypeVariable T', 'handleTypeVariablesDefined T 1', 'handleNoType T', - 'endTypeVariable > 0 null', + 'endTypeVariable > 0 null null', 'endTypeVariables < >', ]); expect(listener.errors, isNull); @@ -2023,9 +2023,9 @@ class TypeParamOrArgInfoTest { 'beginTypeVariable T', 'handleTypeVariablesDefined T 2', 'handleNoType T', - 'endTypeVariable > 1 null', + 'endTypeVariable > 1 null null', 'handleNoType S', - 'endTypeVariable , 0 null', + 'endTypeVariable , 0 null null', 'endTypeVariables < >', ]); expectComplexTypeParam('', @@ -2040,7 +2040,7 @@ class TypeParamOrArgInfoTest { 'handleIdentifier T typeReference', 'handleNoTypeArguments >', 'handleType T null', - 'endTypeVariable > 0 extends', + 'endTypeVariable > 0 extends null', 'endTypeVariables < >', ]); expectComplexTypeParam('>', @@ -2059,7 +2059,7 @@ class TypeParamOrArgInfoTest { 'handleType T null', 'endTypeArguments 1 < >', 'handleType List null', - 'endTypeVariable > 0 extends', + 'endTypeVariable > 0 extends null', 'endTypeVariables < >', ]); expectComplexTypeParam('', @@ -2081,9 +2081,9 @@ class TypeParamOrArgInfoTest { 'beginFormalParameters ( MemberKind.GeneralizedFunctionType', 'endFormalParameters 0 ( ) MemberKind.GeneralizedFunctionType', 'endFunctionType Function null', - 'endTypeVariable > 1 extends', + 'endTypeVariable > 1 extends null', 'handleNoType R', - 'endTypeVariable , 0 null', + 'endTypeVariable , 0 null null', 'endTypeVariables < >', ]); expectComplexTypeParam('<@A S,T>', typeArgumentCount: 2, expectedCalls: [ @@ -2103,9 +2103,9 @@ class TypeParamOrArgInfoTest { 'beginTypeVariable T', 'handleTypeVariablesDefined T 2', 'handleNoType T', - 'endTypeVariable > 1 null', + 'endTypeVariable > 1 null null', 'handleNoType S', - 'endTypeVariable , 0 null', + 'endTypeVariable , 0 null null', 'endTypeVariables < >', ]); expectComplexTypeParam('<@A() S,T>', typeArgumentCount: 2, expectedCalls: [ @@ -2126,9 +2126,9 @@ class TypeParamOrArgInfoTest { 'beginTypeVariable T', 'handleTypeVariablesDefined T 2', 'handleNoType T', - 'endTypeVariable > 1 null', + 'endTypeVariable > 1 null null', 'handleNoType S', - 'endTypeVariable , 0 null', + 'endTypeVariable , 0 null null', 'endTypeVariables < >', ]); expectComplexTypeParam('<@A() @B S,T>', @@ -2156,9 +2156,9 @@ class TypeParamOrArgInfoTest { 'beginTypeVariable T', 'handleTypeVariablesDefined T 2', 'handleNoType T', - 'endTypeVariable > 1 null', + 'endTypeVariable > 1 null null', 'handleNoType S', - 'endTypeVariable , 0 null', + 'endTypeVariable , 0 null null', 'endTypeVariables < >', ]); } @@ -2179,7 +2179,7 @@ class TypeParamOrArgInfoTest { 'handleIdentifier void typeReference', 'handleNoTypeArguments >', 'handleType void null', - 'endTypeVariable > 0 extends', + 'endTypeVariable > 0 extends null', 'endTypeVariables < >' ]); } @@ -2198,7 +2198,7 @@ class TypeParamOrArgInfoTest { 'beginTypeVariable S', 'handleTypeVariablesDefined S 1', 'handleNoType S', - 'endTypeVariable Function 0 null', + 'endTypeVariable Function 0 null null', 'endTypeVariables < >', ]); expectComplexTypeParam('', @@ -2214,7 +2214,7 @@ class TypeParamOrArgInfoTest { 'beginTypeVariable ', 'handleTypeVariablesDefined 1', 'handleNoType ', - 'endTypeVariable void 0 null', + 'endTypeVariable void 0 null null', 'endTypeVariables < >', ]); expectComplexTypeParam('>', typeArgumentCount: 1, expectedErrors: [ @@ -2227,7 +2227,7 @@ class TypeParamOrArgInfoTest { 'beginTypeVariable S', 'handleTypeVariablesDefined S 1', 'handleNoType S', - 'endTypeVariable < 0 null', + 'endTypeVariable < 0 null null', 'endTypeVariables < >', ]); expectComplexTypeParam('', @@ -2270,7 +2270,7 @@ class TypeParamOrArgInfoTest { 'handleType T null', 'endTypeArguments 1 < >', 'handleType List null', - 'endTypeVariable fieldName 0 extends', + 'endTypeVariable fieldName 0 extends null', 'endTypeVariables < >', ]); } @@ -2292,7 +2292,7 @@ class TypeParamOrArgInfoTest { 'handleType T null', 'endTypeArguments 1 < >', 'handleType Comparable null', - 'endTypeVariable > 0 extends', + 'endTypeVariable > 0 extends null', 'endTypeVariables < >', ]); expectComplexTypeParam(', S>', @@ -2309,7 +2309,7 @@ class TypeParamOrArgInfoTest { 'beginTypeVariable S', 'handleTypeVariablesDefined S 2', 'handleNoType S', - 'endTypeVariable > 1 null', + 'endTypeVariable > 1 null null', 'handleIdentifier Comparable typeReference', 'beginTypeArguments <', 'handleIdentifier S typeReference', @@ -2317,7 +2317,7 @@ class TypeParamOrArgInfoTest { 'handleType S null', 'endTypeArguments 1 < >', 'handleType Comparable null', - 'endTypeVariable , 0 extends', + 'endTypeVariable , 0 extends null', 'endTypeVariables < >' ]); expectComplexTypeParam('', @@ -2345,7 +2345,7 @@ class TypeParamOrArgInfoTest { 'MemberKind.GeneralizedFunctionType', 'endFormalParameters 1 ( ) MemberKind.GeneralizedFunctionType', 'endFunctionType Function null', - 'endTypeVariable > 0 extends', + 'endTypeVariable > 0 extends null', 'endTypeVariables < >' ]); expectComplexTypeParam('>>', @@ -2368,7 +2368,7 @@ class TypeParamOrArgInfoTest { 'handleType List null', 'endTypeArguments 1 < >', 'handleType List null', - 'endTypeVariable > 0 extends', + 'endTypeVariable > 0 extends null', 'endTypeVariables < >' ]); expectComplexTypeParam('>>', @@ -2394,7 +2394,7 @@ class TypeParamOrArgInfoTest { 'handleType Map null', 'endTypeArguments 1 < >', 'handleType List null', - 'endTypeVariable > 0 extends', + 'endTypeVariable > 0 extends null', 'endTypeVariables < >' ]); expectComplexTypeParam('>>=', @@ -2421,7 +2421,7 @@ class TypeParamOrArgInfoTest { 'handleType Map null', 'endTypeArguments 1 < >', 'handleType List null', - 'endTypeVariable >= 0 extends', + 'endTypeVariable >= 0 extends null', 'endTypeVariables < >' ]); } @@ -2441,7 +2441,7 @@ class TypeParamOrArgInfoTest { 'beginTypeVariable S', 'handleTypeVariablesDefined S 1', 'handleNoType S', - 'endTypeVariable < 0 null', + 'endTypeVariable < 0 null null', 'endTypeVariables < >', ]); expectComplexTypeParam(' A', @@ -2459,7 +2459,7 @@ class TypeParamOrArgInfoTest { 'beginTypeVariable S', 'handleTypeVariablesDefined S 1', 'handleNoType S', - 'endTypeVariable ( 0 null', + 'endTypeVariable ( 0 null null', 'endTypeVariables < >', ]); } @@ -2842,8 +2842,9 @@ class TypeInfoListener implements Listener { } @override - void endTypeVariable(Token token, int index, Token extendsOrSuper) { - calls.add('endTypeVariable $token $index $extendsOrSuper'); + void endTypeVariable( + Token token, int index, Token extendsOrSuper, Token variance) { + calls.add('endTypeVariable $token $index $extendsOrSuper $variance'); assertTokenInStream(token); assertTokenInStream(extendsOrSuper); } diff --git a/pkg/front_end/test/parser_test_listener.dart b/pkg/front_end/test/parser_test_listener.dart index 2877ed29bbd..8bd1eadfb91 100644 --- a/pkg/front_end/test/parser_test_listener.dart +++ b/pkg/front_end/test/parser_test_listener.dart @@ -1204,9 +1204,14 @@ class ParserTestListener implements Listener { doPrint('handleTypeVariablesDefined(' '$token, ' '$count)'); } - void endTypeVariable(Token token, int index, Token extendsOrSuper) { + void endTypeVariable( + Token token, int index, Token extendsOrSuper, Token variance) { indent--; - doPrint('endTypeVariable(' '$token, ' '$index, ' '$extendsOrSuper)'); + doPrint('endTypeVariable(' + '$token, ' + '$index, ' + '$extendsOrSuper, ' + '$variance)'); } void beginTypeVariables(Token token) { diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status index da0cb3de945..6bafcf8a4e2 100644 --- a/pkg/front_end/testcases/text_serialization.status +++ b/pkg/front_end/testcases/text_serialization.status @@ -1118,4 +1118,6 @@ runtime_checks_new/stub_from_interface_covariantInterface_from_class: TextSerial runtime_checks_new/stub_from_interface_covariant_from_interface: TextSerializationFailure # Was: Pass runtime_checks_new/stub_from_interface_covariant_from_super: TextSerializationFailure # Was: Pass set_literals/disambiguation_rule: TextSerializationFailure # Was: RuntimeError +variance/class_type_parameter_modifier: TextSerializationFailure +variance/mixin_type_parameter_modifier: TextSerializationFailure top_level_variance_test: TextSerializationFailure diff --git a/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart new file mode 100644 index 00000000000..71aa5cf6b90 --- /dev/null +++ b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +class A {} + +main() { + A a = new A(); +} diff --git a/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.outline.expect b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.outline.expect new file mode 100644 index 00000000000..05b61d880a7 --- /dev/null +++ b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.outline.expect @@ -0,0 +1,10 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A* + ; +} +static method main() → dynamic + ; diff --git a/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.strong.expect b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.strong.expect new file mode 100644 index 00000000000..cb21b6a71d4 --- /dev/null +++ b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.strong.expect @@ -0,0 +1,12 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A* + : super core::Object::•() + ; +} +static method main() → dynamic { + self::A* a = new self::A::•(); +} diff --git a/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.strong.transformed.expect b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.strong.transformed.expect new file mode 100644 index 00000000000..cb21b6a71d4 --- /dev/null +++ b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.strong.transformed.expect @@ -0,0 +1,12 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A* + : super core::Object::•() + ; +} +static method main() → dynamic { + self::A* a = new self::A::•(); +} diff --git a/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart new file mode 100644 index 00000000000..2aefefba907 --- /dev/null +++ b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +class A {} + +mixin B on A {} + +main() {} diff --git a/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.outline.expect b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.outline.expect new file mode 100644 index 00000000000..44fe61abe9f --- /dev/null +++ b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.outline.expect @@ -0,0 +1,12 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A* + ; +} +abstract class B extends self::A { +} +static method main() → dynamic + ; diff --git a/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.strong.expect b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.strong.expect new file mode 100644 index 00000000000..0c6c3cdf00a --- /dev/null +++ b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.strong.expect @@ -0,0 +1,12 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A* + : super core::Object::•() + ; +} +abstract class B extends self::A { +} +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.strong.transformed.expect b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.strong.transformed.expect new file mode 100644 index 00000000000..0c6c3cdf00a --- /dev/null +++ b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.strong.transformed.expect @@ -0,0 +1,12 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A* + : super core::Object::•() + ; +} +abstract class B extends self::A { +} +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/variance/test.options b/pkg/front_end/testcases/variance/test.options new file mode 100644 index 00000000000..3ce5008900a --- /dev/null +++ b/pkg/front_end/testcases/variance/test.options @@ -0,0 +1 @@ +--enable-experiment=variance diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart index 1f1835c1258..cd777e3a370 100644 --- a/pkg/kernel/lib/ast.dart +++ b/pkg/kernel/lib/ast.dart @@ -6003,6 +6003,18 @@ class Variance { if (a == invariant || b == invariant) return invariant; return a == b ? covariant : contravariant; } + + static int fromString(String variance) { + if (variance == "in") { + return contravariant; + } else if (variance == "inout") { + return invariant; + } else if (variance == "out") { + return covariant; + } else { + return unrelated; + } + } } /// Declaration of a type variable.