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:
committed by
commit-bot@chromium.org
parent
0f70ef1a6d
commit
bf79e4604c
@@ -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 {}
|
||||
|
||||
Reference in New Issue
Block a user