Migration: Add support for synthetic constructors in generic class type aliases.

Change-Id: I8eee88e4dd607623fe109143d01438a5271b3230
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/107521
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This commit is contained in:
Paul Berry
2019-06-27 19:34:05 +00:00
committed by commit-bot@chromium.org
parent 0f70ef1a6d
commit bf79e4604c
4 changed files with 117 additions and 0 deletions
@@ -146,6 +146,8 @@ class DecoratedType {
} else if (type is FunctionType) {
return DecoratedType.forImplicitFunction(
type, NullabilityNode.forInferredType(), graph);
} else if (type is TypeParameterType) {
return DecoratedType(type, NullabilityNode.forInferredType());
}
// TODO(paulberry)
throw UnimplementedError(
@@ -7,6 +7,7 @@ import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/handle.dart';
import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/generated/resolver.dart';
@@ -287,6 +288,9 @@ class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType> {
var classElement = node.declaredElement;
var supertype = classElement.supertype;
var superElement = supertype.element;
if (superElement is ClassElementHandle) {
superElement = (superElement as ClassElementHandle).actualElement;
}
for (var constructorElement in classElement.constructors) {
assert(constructorElement.isSynthetic);
var superConstructorElement =
@@ -558,6 +558,21 @@ D f(MyList<int>/*2*/ x) => D(x);
decoratedTypeAnnotation('int>/*1*/').node);
}
test_class_alias_synthetic_constructor_with_parameters_generic() async {
await analyze('''
class C<T> {
C(T t);
}
mixin M {}
class D<U> = C<U> with M;
''');
var syntheticConstructor = findElement.unnamedConstructor('D');
var constructorType = variables.decoratedElementType(syntheticConstructor);
var constructorParameterType = constructorType.positionalParameters[0];
assertUnion(
constructorParameterType.node, decoratedTypeAnnotation('T t').node);
}
test_class_alias_synthetic_constructor_with_parameters_named() async {
await analyze('''
class C {
@@ -707,6 +722,74 @@ class C {
// exception to be thrown.
}
test_constructorDeclaration_returnType_generic() async {
await analyze('''
class C<T, U> {
C();
}
''');
var constructor = findElement.unnamedConstructor('C');
var constructorDecoratedType = variables.decoratedElementType(constructor);
expect(constructorDecoratedType.type.toString(), 'C<T, U> Function()');
expect(constructorDecoratedType.node, same(never));
expect(constructorDecoratedType.typeFormals, isEmpty);
expect(constructorDecoratedType.returnType.node, same(never));
expect(constructorDecoratedType.returnType.type.toString(), 'C<T, U>');
var typeArguments = constructorDecoratedType.returnType.typeArguments;
expect(typeArguments, hasLength(2));
expect(typeArguments[0].type.toString(), 'T');
expect(typeArguments[0].node, same(never));
expect(typeArguments[1].type.toString(), 'U');
expect(typeArguments[1].node, same(never));
}
test_constructorDeclaration_returnType_generic_implicit() async {
await analyze('''
class C<T, U> {}
''');
var constructor = findElement.unnamedConstructor('C');
var constructorDecoratedType = variables.decoratedElementType(constructor);
expect(constructorDecoratedType.type.toString(), 'C<T, U> Function()');
expect(constructorDecoratedType.node, same(never));
expect(constructorDecoratedType.typeFormals, isEmpty);
expect(constructorDecoratedType.returnType.node, same(never));
expect(constructorDecoratedType.returnType.type.toString(), 'C<T, U>');
var typeArguments = constructorDecoratedType.returnType.typeArguments;
expect(typeArguments, hasLength(2));
expect(typeArguments[0].type.toString(), 'T');
expect(typeArguments[0].node, same(never));
expect(typeArguments[1].type.toString(), 'U');
expect(typeArguments[1].node, same(never));
}
test_constructorDeclaration_returnType_simple() async {
await analyze('''
class C {
C();
}
''');
var constructorDecoratedType =
variables.decoratedElementType(findElement.unnamedConstructor('C'));
expect(constructorDecoratedType.type.toString(), 'C Function()');
expect(constructorDecoratedType.node, same(never));
expect(constructorDecoratedType.typeFormals, isEmpty);
expect(constructorDecoratedType.returnType.node, same(never));
expect(constructorDecoratedType.returnType.typeArguments, isEmpty);
}
test_constructorDeclaration_returnType_simple_implicit() async {
await analyze('''
class C {}
''');
var constructorDecoratedType =
variables.decoratedElementType(findElement.unnamedConstructor('C'));
expect(constructorDecoratedType.type.toString(), 'C Function()');
expect(constructorDecoratedType.node, same(never));
expect(constructorDecoratedType.typeFormals, isEmpty);
expect(constructorDecoratedType.returnType.node, same(never));
expect(constructorDecoratedType.returnType.typeArguments, isEmpty);
}
test_doubleLiteral() async {
await analyze('''
double f() {
@@ -127,6 +127,34 @@ class D = C with M;
expect(dType.namedParameters, isEmpty);
}
test_class_alias_synthetic_constructors_with_parameters_generic() async {
await analyze('''
class C<T> {
C(T t);
}
mixin M {}
class D<U> = C<U> with M;
''');
var cConstructor = findElement.unnamedConstructor('C');
var dConstructor = findElement.unnamedConstructor('D');
var cConstructorType = variables.decoratedElementType(cConstructor);
var dConstructorType = variables.decoratedElementType(dConstructor);
expect(dConstructorType.type.toString(), 'D<U> Function(U)');
expect(dConstructorType.node, same(never));
expect(dConstructorType.typeFormals, isEmpty);
expect(dConstructorType.returnType.type.toString(), 'D<U>');
expect(dConstructorType.returnType.node, same(never));
var typeArguments = dConstructorType.returnType.typeArguments;
expect(typeArguments, hasLength(1));
expect(typeArguments[0].type.toString(), 'U');
expect(typeArguments[0].node, same(never));
var cParams = cConstructorType.positionalParameters;
var dParams = dConstructorType.positionalParameters;
expect(dParams, hasLength(1));
expect(dParams[0].type.toString(), 'U');
expect(dParams[0].node, TypeMatcher<NullabilityNodeMutable>());
}
test_class_with_default_constructor() async {
await analyze('''
class C {}