mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 08:44:27 +00:00
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:
parent
749cf15dcf
commit
085a63d2e7
2 changed files with 41 additions and 27 deletions
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue