[cfe] Wildcard behaviour with this._ and super._.

No initializer list variable is created with this._ and super._ initializing formals.

this._ will still initialize fields and super._ will forward the argument's value to the super constructor invocation.

Bug: https://github.com/dart-lang/sdk/issues/55655
Change-Id: Id4cb25d0ecaf3518cc577e37b74a349d19418679
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/372600
Commit-Queue: Kallen Tu <kallentu@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Kallen Tu 2024-06-24 20:59:39 +00:00 committed by Commit Queue
parent 56851e50e2
commit fbf0b08568
10 changed files with 348 additions and 1 deletions

View file

@ -3328,7 +3328,8 @@ class BodyBuilder extends StackListenerImpl
@override
VariableGet createVariableGet(VariableDeclaration variable, int charOffset,
{bool forNullGuardedAccess = false}) {
if (!(variable as VariableDeclarationImpl).isLocalFunction) {
if (!(variable as VariableDeclarationImpl).isLocalFunction &&
!variable.isWildcard) {
typeInferrer.assignedVariables.read(variable);
}
return new VariableGetImpl(variable,

View file

@ -244,6 +244,10 @@ abstract class SourceFunctionBuilderImpl extends SourceMemberBuilderImpl
if (formals == null) return parent;
Map<String, Builder> local = <String, Builder>{};
for (FormalParameterBuilder formal in formals!) {
// Wildcard initializing formal parameters do not introduce a local
// variable in the initializer list.
if (formal.isWildcard) continue;
local[formal.name] = formal.forFormalParameterInitializerScope();
}
return new Scope(

View file

@ -311,6 +311,7 @@ value_class/simple: RuntimeError # Expected
value_class/value_extends_non_value: RuntimeError # Expected
value_class/value_implements_non_value: RuntimeError # Expected
wildcard_variables/class_type_parameters: semiFuzzFailureOnForceRebuildBodies # Expected
wildcard_variables/initializing_formals: RuntimeError # Expected
wildcard_variables/local_var_no_shadowing: semiFuzzFailureOnForceRebuildBodies # Expected
wildcard_variables/top_level_function_no_shadow: semiFuzzFailureOnForceRebuildBodies # Expected

View file

@ -0,0 +1,43 @@
// Copyright (c) 2024, 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.
class A {
final int _;
A(this._) {
print(_);
}
}
class InitializerListError {
final int _;
final int x;
InitializerListError(this._) : x = _; // Error. `_` in initializer list.
}
class MultipleThisError {
final int _;
MultipleThisError(this._, this._); // Error. Multiple `this._`.
}
class B {
final int _, v, w;
B(this._, this.v, this.w);
}
class C extends B {
final int z;
C(super.x, super._, super._, this.z)
: assert(x > 0),
assert(_ >= 0) // Error: no `_` in scope.
{
print(_); // OK, means `this._` and refers to `A._`.
}
}
main() {
A(1);
InitializerListError(1);
MultipleThisError(1, 2);
C(1, 2, 3, 4);
}

View file

@ -0,0 +1,66 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/wildcard_variables/initializing_formals.dart:32:16: Error: Undefined name '_'.
// assert(_ >= 0) // Error: no `_` in scope.
// ^
//
// pkg/front_end/testcases/wildcard_variables/initializing_formals.dart:15:38: Error: Can't access 'this' in a field initializer to read '_'.
// InitializerListError(this._) : x = _; // Error. `_` in initializer list.
// ^
//
// pkg/front_end/testcases/wildcard_variables/initializing_formals.dart:20:34: Error: '_' was already initialized by this constructor.
// MultipleThisError(this._, this._); // Error. Multiple `this._`.
// ^
//
import self as self;
import "dart:core" as core;
class A extends core::Object {
final field core::int _;
constructor •(wildcard core::int _) → self::A
: self::A::_ = _, super core::Object::•() {
core::print(this.{self::A::_}{core::int});
}
}
class InitializerListError extends core::Object {
final field core::int _;
final field core::int x;
constructor •(wildcard core::int _) → self::InitializerListError
: self::InitializerListError::_ = _, self::InitializerListError::x = invalid-expression "pkg/front_end/testcases/wildcard_variables/initializing_formals.dart:15:38: Error: Can't access 'this' in a field initializer to read '_'.
InitializerListError(this._) : x = _; // Error. `_` in initializer list.
^", super core::Object::•()
;
}
class MultipleThisError extends core::Object {
final field core::int _;
constructor •(wildcard core::int _, wildcard core::int _) → self::MultipleThisError
: self::MultipleThisError::_ = _, final dynamic #t1 = invalid-expression "pkg/front_end/testcases/wildcard_variables/initializing_formals.dart:20:34: Error: '_' was already initialized by this constructor.
MultipleThisError(this._, this._); // Error. Multiple `this._`.
^", super core::Object::•()
;
}
class B extends core::Object {
final field core::int _;
final field core::int v;
final field core::int w;
constructor •(wildcard core::int _, core::int v, core::int w) → self::B
: self::B::_ = _, self::B::v = v, self::B::w = w, super core::Object::•()
;
}
class C extends self::B {
final field core::int z;
constructor •(core::int x, wildcard core::int _, wildcard core::int _, core::int z) → self::C
: self::C::z = z, assert(x.{core::num::>}(0){(core::num) → core::bool}), assert(invalid-expression "pkg/front_end/testcases/wildcard_variables/initializing_formals.dart:32:16: Error: Undefined name '_'.
assert(_ >= 0) // Error: no `_` in scope.
^"{<invalid>}.>=(0)), super self::B::•(x, _, _) {
core::print(this.{self::B::_}{core::int});
}
}
static method main() → dynamic {
new self::A::•(1);
new self::InitializerListError::•(1);
new self::MultipleThisError::•(1, 2);
new self::C::•(1, 2, 3, 4);
}

View file

@ -0,0 +1,66 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/wildcard_variables/initializing_formals.dart:32:16: Error: Undefined name '_'.
// assert(_ >= 0) // Error: no `_` in scope.
// ^
//
// pkg/front_end/testcases/wildcard_variables/initializing_formals.dart:15:38: Error: Can't access 'this' in a field initializer to read '_'.
// InitializerListError(this._) : x = _; // Error. `_` in initializer list.
// ^
//
// pkg/front_end/testcases/wildcard_variables/initializing_formals.dart:20:34: Error: '_' was already initialized by this constructor.
// MultipleThisError(this._, this._); // Error. Multiple `this._`.
// ^
//
import self as self;
import "dart:core" as core;
class A extends core::Object {
final field core::int _;
constructor •(wildcard core::int _) → self::A
: self::A::_ = _, super core::Object::•() {
core::print(this.{self::A::_}{core::int});
}
}
class InitializerListError extends core::Object {
final field core::int _;
final field core::int x;
constructor •(wildcard core::int _) → self::InitializerListError
: self::InitializerListError::_ = _, self::InitializerListError::x = invalid-expression "pkg/front_end/testcases/wildcard_variables/initializing_formals.dart:15:38: Error: Can't access 'this' in a field initializer to read '_'.
InitializerListError(this._) : x = _; // Error. `_` in initializer list.
^", super core::Object::•()
;
}
class MultipleThisError extends core::Object {
final field core::int _;
constructor •(wildcard core::int _, wildcard core::int _) → self::MultipleThisError
: self::MultipleThisError::_ = _, final dynamic #t1 = invalid-expression "pkg/front_end/testcases/wildcard_variables/initializing_formals.dart:20:34: Error: '_' was already initialized by this constructor.
MultipleThisError(this._, this._); // Error. Multiple `this._`.
^", super core::Object::•()
;
}
class B extends core::Object {
final field core::int _;
final field core::int v;
final field core::int w;
constructor •(wildcard core::int _, core::int v, core::int w) → self::B
: self::B::_ = _, self::B::v = v, self::B::w = w, super core::Object::•()
;
}
class C extends self::B {
final field core::int z;
constructor •(core::int x, wildcard core::int _, wildcard core::int _, core::int z) → self::C
: self::C::z = z, assert(x.{core::num::>}(0){(core::num) → core::bool}), assert(invalid-expression "pkg/front_end/testcases/wildcard_variables/initializing_formals.dart:32:16: Error: Undefined name '_'.
assert(_ >= 0) // Error: no `_` in scope.
^"{<invalid>}.>=(0)), super self::B::•(x, _, _) {
core::print(this.{self::B::_}{core::int});
}
}
static method main() → dynamic {
new self::A::•(1);
new self::InitializerListError::•(1);
new self::MultipleThisError::•(1, 2);
new self::C::•(1, 2, 3, 4);
}

View file

@ -0,0 +1,42 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/wildcard_variables/initializing_formals.dart:32:16: Error: Undefined name '_'.
// assert(_ >= 0) // Error: no `_` in scope.
// ^
//
import self as self;
import "dart:core" as core;
class A extends core::Object {
final field core::int _;
constructor •(wildcard core::int _) → self::A
;
}
class InitializerListError extends core::Object {
final field core::int _;
final field core::int x;
constructor •(wildcard core::int _) → self::InitializerListError
;
}
class MultipleThisError extends core::Object {
final field core::int _;
constructor •(wildcard core::int _, wildcard core::int _) → self::MultipleThisError
;
}
class B extends core::Object {
final field core::int _;
final field core::int v;
final field core::int w;
constructor •(wildcard core::int _, core::int v, core::int w) → self::B
;
}
class C extends self::B {
final field core::int z;
constructor •(core::int x, wildcard core::int _, wildcard core::int _, core::int z) → self::C
: self::C::z = z
;
}
static method main() → dynamic
;

View file

@ -0,0 +1,66 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/wildcard_variables/initializing_formals.dart:32:16: Error: Undefined name '_'.
// assert(_ >= 0) // Error: no `_` in scope.
// ^
//
// pkg/front_end/testcases/wildcard_variables/initializing_formals.dart:15:38: Error: Can't access 'this' in a field initializer to read '_'.
// InitializerListError(this._) : x = _; // Error. `_` in initializer list.
// ^
//
// pkg/front_end/testcases/wildcard_variables/initializing_formals.dart:20:34: Error: '_' was already initialized by this constructor.
// MultipleThisError(this._, this._); // Error. Multiple `this._`.
// ^
//
import self as self;
import "dart:core" as core;
class A extends core::Object {
final field core::int _;
constructor •(wildcard core::int _) → self::A
: self::A::_ = _, super core::Object::•() {
core::print(this.{self::A::_}{core::int});
}
}
class InitializerListError extends core::Object {
final field core::int _;
final field core::int x;
constructor •(wildcard core::int _) → self::InitializerListError
: self::InitializerListError::_ = _, self::InitializerListError::x = invalid-expression "pkg/front_end/testcases/wildcard_variables/initializing_formals.dart:15:38: Error: Can't access 'this' in a field initializer to read '_'.
InitializerListError(this._) : x = _; // Error. `_` in initializer list.
^", super core::Object::•()
;
}
class MultipleThisError extends core::Object {
final field core::int _;
constructor •(wildcard core::int _, wildcard core::int _) → self::MultipleThisError
: self::MultipleThisError::_ = _, final dynamic #t1 = invalid-expression "pkg/front_end/testcases/wildcard_variables/initializing_formals.dart:20:34: Error: '_' was already initialized by this constructor.
MultipleThisError(this._, this._); // Error. Multiple `this._`.
^", super core::Object::•()
;
}
class B extends core::Object {
final field core::int _;
final field core::int v;
final field core::int w;
constructor •(wildcard core::int _, core::int v, core::int w) → self::B
: self::B::_ = _, self::B::v = v, self::B::w = w, super core::Object::•()
;
}
class C extends self::B {
final field core::int z;
constructor •(core::int x, wildcard core::int _, wildcard core::int _, core::int z) → self::C
: self::C::z = z, assert(x.{core::num::>}(0){(core::num) → core::bool}), assert(invalid-expression "pkg/front_end/testcases/wildcard_variables/initializing_formals.dart:32:16: Error: Undefined name '_'.
assert(_ >= 0) // Error: no `_` in scope.
^"{<invalid>}.>=(0)), super self::B::•(x, _, _) {
core::print(this.{self::B::_}{core::int});
}
}
static method main() → dynamic {
new self::A::•(1);
new self::InitializerListError::•(1);
new self::MultipleThisError::•(1, 2);
new self::C::•(1, 2, 3, 4);
}

View file

@ -0,0 +1,29 @@
class A {
final int _;
A(this._) {}
}
class InitializerListError {
final int _;
final int x;
InitializerListError(this._) : x = _;
}
class MultipleThisError {
final int _;
MultipleThisError(this._, this._);
}
class B {
final int _, v, w;
B(this._, this.v, this.w);
}
class C extends B {
final int z;
C(super.x, super._, super._, this.z)
: assert(x > 0),
assert(_ >= 0) {}
}
main() {}

View file

@ -0,0 +1,29 @@
class A {
A(this._) {}
final int _;
}
class B {
B(this._, this.v, this.w);
final int _, v, w;
}
class C extends B {
C(super.x, super._, super._, this.z)
: assert(x > 0),
assert(_ >= 0) {}
final int z;
}
class InitializerListError {
InitializerListError(this._) : x = _;
final int _;
final int x;
}
class MultipleThisError {
MultipleThisError(this._, this._);
final int _;
}
main() {}