dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.25k stars 1.58k forks source link

[Augmentations] Initializer list in augmenting constructor produces errors in the analyzer #56493

Open sgrekhov opened 2 months ago

sgrekhov commented 2 months ago

Feature specification

If the augmenting constructor has an initializer list then:

  • It's a compile-time error if the augmented constructor has super-initializer, and the augmenting constructor's initializer list also contains a super-initializer.

  • Otherwise the result of applying the augmenting constructor has an initializer list containing first the assertions and field initializers of the augmented constructor, if any, then the assertions and field initializers of the augmenting constructor, and finally any super-initializer of either the augmeted or augmenting constructor.

The code below must be valid

class A {
  int z;
  A(this.z);
}

class C extends A {
  int x, y;
  C(int x, int y, int z): this.x = x, assert(x++ == 0), super(z);
  C.foo(int x, int y, int z): this.x = x, assert(y++ == 0); //  COMPILE_TIME_ERROR.IMPLICIT_SUPER_INITIALIZER_MISSING_ARGUMENTS
  C.bar(int x, int y, int z); //  COMPILE_TIME_ERROR.IMPLICIT_SUPER_INITIALIZER_MISSING_ARGUMENTS
}
augment class C {
  augment C(int x, int y, int z): assert(x++ == 1), this.y = y; //  COMPILE_TIME_ERROR.IMPLICIT_SUPER_INITIALIZER_MISSING_ARGUMENTS
  augment C.foo(int x, int y, int z): this.y = y, assert(y++ == 1), super(++z);
  augment C.bar(int x, int y, int z): this.x = x, this.y = y, super(z);
}
sgrekhov commented 1 week ago

Also

class C {
  String x;
  C(): x = "Original";
  augment C(): x = "Augmented"; // Error. The field 'x' can't be initialized twice in the same constructor. 
}