Handle generic redirecting generative constructors

Closes #34479

Change-Id: I47f90891fa04d121ed2c3a10878b969b0f95729d
Reviewed-on: https://dart-review.googlesource.com/77062
Auto-Submit: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Sigmund Cherem <sigmund@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
Johnni Winther 2018-09-28 20:33:10 +00:00 committed by commit-bot@chromium.org
parent 749cf15dcf
commit 085a63d2e7
2 changed files with 41 additions and 27 deletions

View file

@ -94,11 +94,16 @@ class Constantifier extends ir.ExpressionVisitor<ConstantExpression> {
}
ConstructedConstantExpression _computeConstructorInvocation(
ir.Constructor target, ir.Arguments arguments) {
ir.Constructor target,
ir.Arguments arguments,
// TODO(johnniwinther): Remove this when correct type arguments are passed
// through [arguments]. Current [ir.RedirectingInitializer] doesn't have
// any type arguments.
List<ir.DartType> types) {
List<ConstantExpression> expressions = _computeArguments(arguments);
if (expressions == null) return null;
return new ConstructedConstantExpression(
elementMap.createInterfaceType(target.enclosingClass, arguments.types),
elementMap.createInterfaceType(target.enclosingClass, types),
elementMap.getConstructor(target),
elementMap.getCallStructure(arguments),
expressions);
@ -107,7 +112,8 @@ class Constantifier extends ir.ExpressionVisitor<ConstantExpression> {
@override
ConstantExpression visitConstructorInvocation(ir.ConstructorInvocation node) {
if (!node.isConst) return null;
return _computeConstructorInvocation(node.target, node.arguments);
return _computeConstructorInvocation(
node.target, node.arguments, node.arguments.types);
}
@override
@ -465,10 +471,14 @@ class Constantifier extends ir.ExpressionVisitor<ConstantExpression> {
registerField(initializer.field, visit(initializer.value));
} else if (initializer is ir.SuperInitializer) {
superConstructorInvocation = _computeConstructorInvocation(
initializer.target, initializer.arguments);
initializer.target,
initializer.arguments,
initializer.arguments.types);
} else if (initializer is ir.RedirectingInitializer) {
superConstructorInvocation = _computeConstructorInvocation(
initializer.target, initializer.arguments);
initializer.target,
initializer.arguments,
node.enclosingClass.thisType.typeArguments);
} else if (initializer is ir.AssertInitializer) {
ConstantExpression condition = visit(initializer.statement.condition);
ConstantExpression message = initializer.statement.message != null

View file

@ -31,10 +31,7 @@ class TestData {
/// Tested constants.
final List<ConstantData> constants;
final bool strongModeOnly;
const TestData(this.name, this.declarations, this.constants,
{this.strongModeOnly: false});
const TestData(this.name, this.declarations, this.constants);
}
class ConstantData {
@ -539,9 +536,7 @@ class B extends A {
const ConstantData(r'const D(0)',
'ConstructedConstant(D(a=IntConstant(1),b=IntConstant(2)))'),
]),
const TestData(
'instantiations',
'''
const TestData('instantiations', '''
T identity<T>(T t) => t;
class C<T> {
final T defaultValue;
@ -549,21 +544,30 @@ class C<T> {
const C(this.defaultValue, this.identityFunction);
}
''',
const <ConstantData>[
const ConstantData('identity', 'FunctionConstant(identity)'),
const ConstantData(
'const C<int>(0, identity)',
'ConstructedConstant(C<int>(defaultValue=IntConstant(0),'
'identityFunction=InstantiationConstant([int],'
'FunctionConstant(identity))))'),
const ConstantData(
'const C<double>(0.5, identity)',
'ConstructedConstant(C<double>(defaultValue=DoubleConstant(0.5),'
'identityFunction=InstantiationConstant([double],'
'FunctionConstant(identity))))'),
],
strongModeOnly: true)
''', const <ConstantData>[
const ConstantData('identity', 'FunctionConstant(identity)'),
const ConstantData(
'const C<int>(0, identity)',
'ConstructedConstant(C<int>(defaultValue=IntConstant(0),'
'identityFunction=InstantiationConstant([int],'
'FunctionConstant(identity))))'),
const ConstantData(
'const C<double>(0.5, identity)',
'ConstructedConstant(C<double>(defaultValue=DoubleConstant(0.5),'
'identityFunction=InstantiationConstant([double],'
'FunctionConstant(identity))))'),
]),
const TestData('generic class', '''
class C<T> {
const C.generative();
const C.redirect() : this.generative();
}
''', const <ConstantData>[
const ConstantData(
'const C<int>.generative()', 'ConstructedConstant(C<int>())'),
const ConstantData(
'const C<int>.redirect()', 'ConstructedConstant(C<int>())'),
])
];
main(List<String> args) {