mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 16:37:43 +00:00
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 <kallentu@google.com> Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
This commit is contained in:
parent
07db94d454
commit
327bc451f8
|
@ -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) ||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -4767,7 +4767,8 @@ class BodyBuilder extends ScopeListener<JumpTarget>
|
|||
}
|
||||
|
||||
@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<JumpTarget>
|
|||
|
||||
TypeVariableBuilder variable = typeVariables[index];
|
||||
variable.bound = bound?.builder;
|
||||
if (variance != null) {
|
||||
variable.variance = Variance.fromString(variance.lexeme);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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<TypeVariableBuilder> typeParameters = peek();
|
||||
if (typeParameters != null) {
|
||||
typeParameters[index].bound = bound;
|
||||
if (variance != null) {
|
||||
typeParameters[index].variance = Variance.fromString(variance.lexeme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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('<S extends T>',
|
||||
|
@ -2040,7 +2040,7 @@ class TypeParamOrArgInfoTest {
|
|||
'handleIdentifier T typeReference',
|
||||
'handleNoTypeArguments >',
|
||||
'handleType T null',
|
||||
'endTypeVariable > 0 extends',
|
||||
'endTypeVariable > 0 extends null',
|
||||
'endTypeVariables < >',
|
||||
]);
|
||||
expectComplexTypeParam('<S extends List<T>>',
|
||||
|
@ -2059,7 +2059,7 @@ class TypeParamOrArgInfoTest {
|
|||
'handleType T null',
|
||||
'endTypeArguments 1 < >',
|
||||
'handleType List null',
|
||||
'endTypeVariable > 0 extends',
|
||||
'endTypeVariable > 0 extends null',
|
||||
'endTypeVariables < >',
|
||||
]);
|
||||
expectComplexTypeParam('<R, S extends void Function()>',
|
||||
|
@ -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('<void Function()>',
|
||||
|
@ -2214,7 +2214,7 @@ class TypeParamOrArgInfoTest {
|
|||
'beginTypeVariable ',
|
||||
'handleTypeVariablesDefined 1',
|
||||
'handleNoType ',
|
||||
'endTypeVariable void 0 null',
|
||||
'endTypeVariable void 0 null null',
|
||||
'endTypeVariables < >',
|
||||
]);
|
||||
expectComplexTypeParam('<S<T>>', 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('<S T>',
|
||||
|
@ -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('<T extends Comparable<S>, 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('<T extends Function(T)>',
|
||||
|
@ -2345,7 +2345,7 @@ class TypeParamOrArgInfoTest {
|
|||
'MemberKind.GeneralizedFunctionType',
|
||||
'endFormalParameters 1 ( ) MemberKind.GeneralizedFunctionType',
|
||||
'endFunctionType Function null',
|
||||
'endTypeVariable > 0 extends',
|
||||
'endTypeVariable > 0 extends null',
|
||||
'endTypeVariables < >'
|
||||
]);
|
||||
expectComplexTypeParam('<T extends List<List<T>>>',
|
||||
|
@ -2368,7 +2368,7 @@ class TypeParamOrArgInfoTest {
|
|||
'handleType List null',
|
||||
'endTypeArguments 1 < >',
|
||||
'handleType List null',
|
||||
'endTypeVariable > 0 extends',
|
||||
'endTypeVariable > 0 extends null',
|
||||
'endTypeVariables < >'
|
||||
]);
|
||||
expectComplexTypeParam('<T extends List<Map<S, T>>>',
|
||||
|
@ -2394,7 +2394,7 @@ class TypeParamOrArgInfoTest {
|
|||
'handleType Map null',
|
||||
'endTypeArguments 1 < >',
|
||||
'handleType List null',
|
||||
'endTypeVariable > 0 extends',
|
||||
'endTypeVariable > 0 extends null',
|
||||
'endTypeVariables < >'
|
||||
]);
|
||||
expectComplexTypeParam('<T extends List<Map<S, T>>>=',
|
||||
|
@ -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('<S();> 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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<out X, in Y, inout Z> {}
|
||||
|
||||
main() {
|
||||
A a = new A();
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class A<X extends core::Object* = dynamic, contravariant Y extends core::Object* = dynamic, invariant Z extends core::Object* = dynamic> extends core::Object {
|
||||
synthetic constructor •() → self::A<self::A::X*, self::A::Y*, self::A::Z*>*
|
||||
;
|
||||
}
|
||||
static method main() → dynamic
|
||||
;
|
|
@ -0,0 +1,12 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class A<X extends core::Object* = dynamic, contravariant Y extends core::Object* = dynamic, invariant Z extends core::Object* = dynamic> extends core::Object {
|
||||
synthetic constructor •() → self::A<self::A::X*, self::A::Y*, self::A::Z*>*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
static method main() → dynamic {
|
||||
self::A<dynamic, dynamic, dynamic>* a = new self::A::•<dynamic, dynamic, dynamic>();
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class A<X extends core::Object* = dynamic, contravariant Y extends core::Object* = dynamic, invariant Z extends core::Object* = dynamic> extends core::Object {
|
||||
synthetic constructor •() → self::A<self::A::X*, self::A::Y*, self::A::Z*>*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
static method main() → dynamic {
|
||||
self::A<dynamic, dynamic, dynamic>* a = new self::A::•<dynamic, dynamic, dynamic>();
|
||||
}
|
|
@ -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<inout X, out Y, in Z> on A {}
|
||||
|
||||
main() {}
|
|
@ -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<invariant X extends core::Object* = dynamic, Y extends core::Object* = dynamic, contravariant Z extends core::Object* = dynamic> extends self::A {
|
||||
}
|
||||
static method main() → dynamic
|
||||
;
|
|
@ -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<invariant X extends core::Object* = dynamic, Y extends core::Object* = dynamic, contravariant Z extends core::Object* = dynamic> extends self::A {
|
||||
}
|
||||
static method main() → dynamic {}
|
|
@ -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<invariant X extends core::Object* = dynamic, Y extends core::Object* = dynamic, contravariant Z extends core::Object* = dynamic> extends self::A {
|
||||
}
|
||||
static method main() → dynamic {}
|
1
pkg/front_end/testcases/variance/test.options
Normal file
1
pkg/front_end/testcases/variance/test.options
Normal file
|
@ -0,0 +1 @@
|
|||
--enable-experiment=variance
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue