Skip to content

Commit

Permalink
Add tests for mixin application constructor forwarding.
Browse files Browse the repository at this point in the history
Forwarding should work for constructors with optional parameters,
and for const constructors as long as the mixin doesn't declare any
instance variables.

Add tests for forwarding of constructors in mixin applications.

Bug: http://dartbug.com/31543, http://dartbug.com/32223
Change-Id: Iaf950f48703e14391050338f7ae2d80854ec8286
Reviewed-on: https://dart-review.googlesource.com/50460
Commit-Queue: Lasse R.H. Nielsen <[email protected]>
Reviewed-by: Erik Ernst <[email protected]>
  • Loading branch information
lrhn authored and [email protected] committed Apr 10, 2018
1 parent e696279 commit 5d89a1a
Show file tree
Hide file tree
Showing 5 changed files with 352 additions and 0 deletions.
5 changes: 5 additions & 0 deletions tests/language_2/language_2.status
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
# 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.

mixin_constructor_forwarding/const_constructor_test/none: CompileTimeError # Issue 32223
mixin_constructor_forwarding/const_constructor_with_field_test/none: CompileTimeError # Issue 32223
mixin_constructor_forwarding/optional_named_parameters_test/none: CompileTimeError # Issue 31543
mixin_constructor_forwarding/optional_positional_parameters_test/none: CompileTimeError # Issue 31543

[ $compiler == app_jit ]
deferred_inheritance_constraints_test/redirecting_constructor: Crash

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Copyright (c) 2018, 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.

import "package:expect/expect.dart";

abstract class Mixin {
// Declares no instance variable.
int get x;
int get m => x;
}

class Base {
final int x;

// Non-const constructors.
Base.c1(this.x);
Base.c2([this.x = 37]);
Base.c3({this.x = 37});

// Non-forwarding generative const constructors.
const Base.c4(this.x);
const Base.c5([this.x = 37]);
const Base.c6({this.x = 37});

// Forwarding generative const constructors.
const Base.c7(int x) : this.c4(x);
const Base.c8([int x = 87]) : this.c4(x);
const Base.c9({int x = 87}) : this.c4(x);
const Base.c10(int x) : this.c5(x);
const Base.c11([int x = 87]) : this.c5(x);
const Base.c12({int x = 87}) : this.c5(x);
const Base.c13(int x) : this.c6(x: x);
const Base.c14([int x = 87]) : this.c6(x: x);
const Base.c15({int x = 87}) : this.c6(x: x);

// Non-generative constructor.
const factory Base() = Base.c5;
}

class Application = Base with Mixin;

class Application2 extends Base with Mixin {}

main() {
Expect.equals(42, new Application.c1(42).m);
Expect.equals(42, new Application.c2(42).m);
Expect.equals(42, new Application.c3(x: 42).m);
Expect.equals(42, const Application.c4(42).m);
Expect.equals(42, const Application.c5(42).m);
Expect.equals(42, const Application.c6(x: 42).m);
Expect.equals(42, const Application.c7(42).m);
Expect.equals(42, const Application.c8(42).m);
Expect.equals(42, const Application.c9(x: 42).m);
Expect.equals(42, const Application.c10(42).m);
Expect.equals(42, const Application.c11(42).m);
Expect.equals(42, const Application.c12(x: 42).m);
Expect.equals(42, const Application.c13(42).m);
Expect.equals(42, const Application.c14(42).m);
Expect.equals(42, const Application.c15(x: 42).m);

Expect.equals(37, new Application.c2().m);
Expect.equals(37, new Application.c3().m);
Expect.equals(37, const Application.c5().m);
Expect.equals(37, const Application.c6().m);
Expect.equals(87, const Application.c8().m);
Expect.equals(87, const Application.c9().m);
Expect.equals(87, const Application.c11().m);
Expect.equals(87, const Application.c12().m);
Expect.equals(87, const Application.c14().m);
Expect.equals(87, const Application.c15().m);

Expect.equals(42, new Application2.c1(42).m);
Expect.equals(42, new Application2.c2(42).m);
Expect.equals(42, new Application2.c3(x: 42).m);
Expect.equals(42, const Application2.c4(42).m);
Expect.equals(42, const Application2.c5(42).m);
Expect.equals(42, const Application2.c6(x: 42).m);
Expect.equals(42, const Application2.c7(42).m);
Expect.equals(42, const Application2.c8(42).m);
Expect.equals(42, const Application2.c9(x: 42).m);
Expect.equals(42, const Application2.c10(42).m);
Expect.equals(42, const Application2.c11(42).m);
Expect.equals(42, const Application2.c12(x: 42).m);
Expect.equals(42, const Application2.c13(42).m);
Expect.equals(42, const Application2.c14(42).m);
Expect.equals(42, const Application2.c15(x: 42).m);

Expect.equals(37, new Application2.c2().m);
Expect.equals(37, new Application2.c3().m);
Expect.equals(37, const Application2.c5().m);
Expect.equals(37, const Application2.c6().m);
Expect.equals(87, const Application2.c8().m);
Expect.equals(87, const Application2.c9().m);
Expect.equals(87, const Application2.c11().m);
Expect.equals(87, const Application2.c12().m);
Expect.equals(87, const Application2.c14().m);
Expect.equals(87, const Application2.c15().m);

// Only make forwarders const if original constructor is const.
const Application.c1(0); //# 01: compile-time error
const Application.c2(0); //# 02: compile-time error
const Application.c3(x: 0); //# 03: compile-time error
const Application2.c1(0); //# 04: compile-time error
const Application2.c2(0); //# 05: compile-time error
const Application2.c3(x: 0); //# 06: compile-time error

// Only insert forwarders for generative constructors.
new Application(); //# 07: compile-time error
new Application2(); //# 08: compile-time error
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// Copyright (c) 2018, 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.

import "package:expect/expect.dart";

abstract class Mixin {
// Declares an instance variable.
// Declaration would be valid in a "const class", but mixin application
// won't get const constructor forwarders.
final int y = 0;

int get x;
int get m => x;
}

class Base {
final int x;

// Non-const constructors.
Base.c1(this.x);
Base.c2([this.x = 37]);
Base.c3({this.x = 37});

// Non-forwarding generative const constructors.
const Base.c4(this.x);
const Base.c5([this.x = 37]);
const Base.c6({this.x = 37});

// Forwarding generative const constructors.
const Base.c7(int x) : this.c4(x);
const Base.c8([int x = 87]) : this.c4(x);
const Base.c9({int x = 87}) : this.c4(x);
const Base.c10(int x) : this.c5(x);
const Base.c11([int x = 87]) : this.c5(x);
const Base.c12({int x = 87}) : this.c5(x);
const Base.c13(int x) : this.c6(x: x);
const Base.c14([int x = 87]) : this.c6(x: x);
const Base.c15({int x = 87}) : this.c6(x: x);

// Non-generative constructor.
const factory Base() = Base.c5;
}

class Application = Base with Mixin;

class Application2 extends Base with Mixin {}

main() {
Expect.equals(42, new Application.c1(42).m);
Expect.equals(42, new Application.c2(42).m);
Expect.equals(42, new Application.c3(x: 42).m);
Expect.equals(42, new Application.c4(42).m);
Expect.equals(42, new Application.c5(42).m);
Expect.equals(42, new Application.c6(x: 42).m);
Expect.equals(42, new Application.c7(42).m);
Expect.equals(42, new Application.c8(42).m);
Expect.equals(42, new Application.c9(x: 42).m);
Expect.equals(42, new Application.c10(42).m);
Expect.equals(42, new Application.c11(42).m);
Expect.equals(42, new Application.c12(x: 42).m);
Expect.equals(42, new Application.c13(42).m);
Expect.equals(42, new Application.c14(42).m);
Expect.equals(42, new Application.c15(x: 42).m);

Expect.equals(37, new Application.c2().m);
Expect.equals(37, new Application.c3().m);
Expect.equals(37, new Application.c5().m);
Expect.equals(37, new Application.c6().m);
Expect.equals(87, new Application.c8().m);
Expect.equals(87, new Application.c9().m);
Expect.equals(87, new Application.c11().m);
Expect.equals(87, new Application.c12().m);
Expect.equals(87, new Application.c14().m);
Expect.equals(87, new Application.c15().m);

Expect.equals(42, new Application2.c1(42).m);
Expect.equals(42, new Application2.c2(42).m);
Expect.equals(42, new Application2.c3(x: 42).m);
Expect.equals(42, new Application2.c4(42).m);
Expect.equals(42, new Application2.c5(42).m);
Expect.equals(42, new Application2.c6(x: 42).m);
Expect.equals(42, new Application2.c7(42).m);
Expect.equals(42, new Application2.c8(42).m);
Expect.equals(42, new Application2.c9(x: 42).m);
Expect.equals(42, new Application2.c10(42).m);
Expect.equals(42, new Application2.c11(42).m);
Expect.equals(42, new Application2.c12(x: 42).m);
Expect.equals(42, new Application2.c13(42).m);
Expect.equals(42, new Application2.c14(42).m);
Expect.equals(42, new Application2.c15(x: 42).m);

Expect.equals(37, new Application2.c2().m);
Expect.equals(37, new Application2.c3().m);
Expect.equals(37, new Application2.c5().m);
Expect.equals(37, new Application2.c6().m);
Expect.equals(87, new Application2.c8().m);
Expect.equals(87, new Application2.c9().m);
Expect.equals(87, new Application2.c11().m);
Expect.equals(87, new Application2.c12().m);
Expect.equals(87, new Application2.c14().m);
Expect.equals(87, new Application2.c15().m);

// Don't make constructors const if mixin declares instance variable.
const Application.c4(42); //# 00: compile-time error
const Application.c5(42); //# 01: compile-time error
const Application.c6(x: 42); //# 02: compile-time error
const Application.c7(42); //# 03: compile-time error
const Application.c8(42); //# 04: compile-time error
const Application.c9(x: 42); //# 05: compile-time error
const Application.c10(42); //# 06: compile-time error
const Application.c11(42); //# 07: compile-time error
const Application.c12(x: 42); //# 08: compile-time error
const Application.c13(42); //# 09: compile-time error
const Application.c14(42); //# 10: compile-time error
const Application.c15(x: 42); //# 11: compile-time error

const Application2.c4(42); //# 12: compile-time error
const Application2.c5(42); //# 13: compile-time error
const Application2.c6(x: 42); //# 14: compile-time error
const Application2.c7(42); //# 15: compile-time error
const Application2.c8(42); //# 16: compile-time error
const Application2.c9(x: 42); //# 17: compile-time error
const Application2.c10(42); //# 18: compile-time error
const Application2.c11(42); //# 19: compile-time error
const Application2.c12(x: 42); //# 20: compile-time error
const Application2.c13(42); //# 21: compile-time error
const Application2.c14(42); //# 22: compile-time error
const Application2.c15(x: 42); //# 23: compile-time error

// Only insert forwarders for generative constructors.
new Application(); //# 24: compile-time error
new Application2(); //# 25: compile-time error
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) 2018, 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.

import "package:expect/expect.dart";

abstract class Mixin {
int get x;
int get m => x;
}

class Base {
final int x;
Base.c1(this.x);
Base.c2({this.x = 37});
Base.c3(int x) : this.c1(x);
Base.c4({int x = 37}) : this.c1(x);
Base.c5(int x) : this.c2(x: x);
Base.c6({int x = 37}) : this.c2(x: x);
factory Base() = Base.c2;
}

class Application = Base with Mixin;

class Application2 extends Base with Mixin {}

main() {
Expect.equals(42, new Application.c1(42).m);
Expect.equals(42, new Application.c2(x: 42).m);
Expect.equals(42, new Application.c3(42).m);
Expect.equals(42, new Application.c4(x: 42).m);
Expect.equals(42, new Application.c5(42).m);
Expect.equals(42, new Application.c6(x: 42).m);
Expect.equals(37, new Application.c2().m);
Expect.equals(37, new Application.c4().m);
Expect.equals(37, new Application.c6().m);

Expect.equals(42, new Application2.c1(42).m);
Expect.equals(42, new Application2.c2(x: 42).m);
Expect.equals(42, new Application2.c3(42).m);
Expect.equals(42, new Application2.c4(x: 42).m);
Expect.equals(42, new Application2.c5(42).m);
Expect.equals(42, new Application2.c6(x: 42).m);
Expect.equals(37, new Application2.c2().m);
Expect.equals(37, new Application2.c4().m);
Expect.equals(37, new Application2.c6().m);

// Only insert forwarders for generative constructors.
new Application(); //# 01: compile-time error
new Application2(); //# 02: compile-time error
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) 2018, 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.

import "package:expect/expect.dart";

abstract class Mixin {
int get x;
int get m => x;
}

class Base {
final int x;
Base.c1(this.x);
Base.c2([this.x = 37]);
Base.c3(int x) : this.c1(x);
Base.c4([int x = 37]) : this.c1(x);
Base.c5(int x) : this.c2(x);
Base.c6([int x = 37]) : this.c2(x);
factory Base() = Base.c2;
}

class Application = Base with Mixin;

class Application2 extends Base with Mixin {}

main() {
Expect.equals(42, new Application.c1(42).m);
Expect.equals(42, new Application.c2(42).m);
Expect.equals(42, new Application.c3(42).m);
Expect.equals(42, new Application.c4(42).m);
Expect.equals(42, new Application.c5(42).m);
Expect.equals(42, new Application.c6(42).m);
Expect.equals(37, new Application.c2().m);
Expect.equals(37, new Application.c4().m);
Expect.equals(37, new Application.c6().m);

Expect.equals(42, new Application2.c1(42).m);
Expect.equals(42, new Application2.c2(42).m);
Expect.equals(42, new Application2.c3(42).m);
Expect.equals(42, new Application2.c4(42).m);
Expect.equals(42, new Application2.c5(42).m);
Expect.equals(42, new Application2.c6(42).m);
Expect.equals(37, new Application2.c2().m);
Expect.equals(37, new Application2.c4().m);
Expect.equals(37, new Application2.c6().m);

// Only insert forwarders for generative constructors.
new Application(); //# 01: compile-time error
new Application2(); //# 02: compile-time error
}

0 comments on commit 5d89a1a

Please sign in to comment.