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:
Kallen Tu 2019-09-26 18:11:10 +00:00 committed by commit-bot@chromium.org
parent 07db94d454
commit 327bc451f8
22 changed files with 176 additions and 48 deletions

View file

@ -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) ||

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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");
}

View file

@ -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;

View file

@ -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");
}

View file

@ -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);
}
}
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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) {

View file

@ -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

View file

@ -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();
}

View file

@ -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
;

View file

@ -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>();
}

View file

@ -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>();
}

View file

@ -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() {}

View file

@ -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
;

View file

@ -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 {}

View file

@ -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 {}

View file

@ -0,0 +1 @@
--enable-experiment=variance

View file

@ -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.