[L] Change in dart/sdk[main]: CQ. Start using InstanceScope in ResolutionVisitor, a little.

0 views
Skip to first unread message

Johnni Winther (Gerrit)

unread,
Feb 10, 2026, 8:23:55 AM (6 days ago) Feb 10
to Konstantin Shcheglov, Paul Berry, Commit Queue, dart-analys...@google.com, rev...@dartlang.org
Attention needed from Konstantin Shcheglov and Paul Berry

Johnni Winther added 1 comment

Patchset-level comments
File-level comment, Patchset 2 (Latest):
Johnni Winther . resolved

I'm a bit surprised that instance member are not normal returned from scope lookups within the body scope. In the CFE they are always part of the body scope and will there naturally resolve (shadow) without additional action.

Open in Gerrit

Related details

Attention is currently required from:
  • Konstantin Shcheglov
  • Paul Berry
Submit Requirements:
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: sdk
Gerrit-Branch: main
Gerrit-Change-Id: Ib5fa23b97d1e6938eb00a2d2b6659eecae86b3b0
Gerrit-Change-Number: 479380
Gerrit-PatchSet: 2
Gerrit-Owner: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Johnni Winther <johnni...@google.com>
Gerrit-Reviewer: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Paul Berry <paul...@google.com>
Gerrit-Attention: Paul Berry <paul...@google.com>
Gerrit-Attention: Konstantin Shcheglov <sche...@google.com>
Gerrit-Comment-Date: Tue, 10 Feb 2026 13:23:50 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
unsatisfied_requirement
open
diffy

Paul Berry (Gerrit)

unread,
Feb 10, 2026, 9:25:27 AM (6 days ago) Feb 10
to Konstantin Shcheglov, Johnni Winther, Commit Queue, dart-analys...@google.com, rev...@dartlang.org
Attention needed from Konstantin Shcheglov

Paul Berry added 2 comments

File pkg/analyzer/lib/src/dart/element/scope.dart
Line 316, Patchset 2 (Latest): /// This getter is not in the instance scope, but it shadows whatever
Paul Berry . unresolved

I don't understand this comment (or the one on line 320). Can you please add a doc comment to this class with a brief code sample, and an explanation of what `InstanceScopeLookupResultImpl` results from analyzing it?

File pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart
Line 93, Patchset 2 (Latest): var prefixElement = nameScope.lookup(prefixName).getter;

// Might be shadowed by an instance member.
// Look again to report `prefixShadowedByLocalDeclaration`.
if (prefixElement == null) {
var result = nameScope.lookup(prefixName);
if (result is InstanceScopeLookupResultImpl) {
prefixElement = result.instanceGetter ?? result.instanceSetter;
}
}
Paul Berry . unresolved

It's inefficient to call `nameScope.lookup` twice.

```suggestion
var lookupResult = nameScope.lookup(prefixName);
var prefixElement = lookupResult.getter;
      // Might be shadowed by an instance member.
// Look again to report `prefixShadowedByLocalDeclaration`.
if (prefixElement == null) {
if (lookupResult is InstanceScopeLookupResultImpl) {
prefixElement =
lookupResult.instanceGetter ?? result.instanceSetter;
}
}

```

Open in Gerrit

Related details

Attention is currently required from:
  • Konstantin Shcheglov
Submit Requirements:
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: sdk
Gerrit-Branch: main
Gerrit-Change-Id: Ib5fa23b97d1e6938eb00a2d2b6659eecae86b3b0
Gerrit-Change-Number: 479380
Gerrit-PatchSet: 2
Gerrit-Owner: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Johnni Winther <johnni...@google.com>
Gerrit-Reviewer: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Paul Berry <paul...@google.com>
Gerrit-Attention: Konstantin Shcheglov <sche...@google.com>
Gerrit-Comment-Date: Tue, 10 Feb 2026 14:25:24 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
unsatisfied_requirement
open
diffy

Konstantin Shcheglov (Gerrit)

unread,
Feb 10, 2026, 1:21:40 PM (6 days ago) Feb 10
to Paul Berry, Johnni Winther, Commit Queue, dart-analys...@google.com, rev...@dartlang.org
Attention needed from Johnni Winther and Paul Berry

Konstantin Shcheglov added 3 comments

Patchset-level comments
Johnni Winther . resolved

I'm a bit surprised that instance member are not normal returned from scope lookups within the body scope. In the CFE they are always part of the body scope and will there naturally resolve (shadow) without additional action.

Konstantin Shcheglov

See "17.37 Lexical Lookup": Consider the case where D is an instance member declaration in a class or mixin A. The lexical lookup then yields nothing. In this case it is guaranteed that ℓ has access to this.

File pkg/analyzer/lib/src/dart/element/scope.dart
Line 316, Patchset 2: /// This getter is not in the instance scope, but it shadows whatever
Paul Berry . unresolved

I don't understand this comment (or the one on line 320). Can you please add a doc comment to this class with a brief code sample, and an explanation of what `InstanceScopeLookupResultImpl` results from analyzing it?

Konstantin Shcheglov

The scope :-P of using this class was reduced, so I decided to remove it altogether.

File pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart
Line 93, Patchset 2: var prefixElement = nameScope.lookup(prefixName).getter;


// Might be shadowed by an instance member.
// Look again to report `prefixShadowedByLocalDeclaration`.
if (prefixElement == null) {
var result = nameScope.lookup(prefixName);
if (result is InstanceScopeLookupResultImpl) {
prefixElement = result.instanceGetter ?? result.instanceSetter;
}
}
Paul Berry . unresolved

It's inefficient to call `nameScope.lookup` twice.

```suggestion
var lookupResult = nameScope.lookup(prefixName);
var prefixElement = lookupResult.getter;
      // Might be shadowed by an instance member.
// Look again to report `prefixShadowedByLocalDeclaration`.
if (prefixElement == null) {
if (lookupResult is InstanceScopeLookupResultImpl) {
prefixElement =
lookupResult.instanceGetter ?? result.instanceSetter;
}
}

```

Konstantin Shcheglov

True, this is more efficient. It does not matter though, this branch is taken only if there is an error to be reported. I changed it to different re-lookup code.

Open in Gerrit

Related details

Attention is currently required from:
  • Johnni Winther
  • Paul Berry
Submit Requirements:
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: sdk
Gerrit-Branch: main
Gerrit-Change-Id: Ib5fa23b97d1e6938eb00a2d2b6659eecae86b3b0
Gerrit-Change-Number: 479380
Gerrit-PatchSet: 3
Gerrit-Owner: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Johnni Winther <johnni...@google.com>
Gerrit-Reviewer: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Paul Berry <paul...@google.com>
Gerrit-Attention: Paul Berry <paul...@google.com>
Gerrit-Attention: Johnni Winther <johnni...@google.com>
Gerrit-Comment-Date: Tue, 10 Feb 2026 18:21:36 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Paul Berry <paul...@google.com>
Comment-In-Reply-To: Johnni Winther <johnni...@google.com>
unsatisfied_requirement
open
diffy

Konstantin Shcheglov (Gerrit)

unread,
Feb 10, 2026, 10:20:18 PM (6 days ago) Feb 10
to Paul Berry, Johnni Winther, Commit Queue, dart-analys...@google.com, rev...@dartlang.org
Attention needed from Johnni Winther and Paul Berry

Konstantin Shcheglov added 3 comments

Patchset-level comments
File-level comment, Patchset 3 (Latest):
Konstantin Shcheglov . resolved

PTAL

File pkg/analyzer/lib/src/dart/element/scope.dart
Line 316, Patchset 2: /// This getter is not in the instance scope, but it shadows whatever
Paul Berry . resolved

I don't understand this comment (or the one on line 320). Can you please add a doc comment to this class with a brief code sample, and an explanation of what `InstanceScopeLookupResultImpl` results from analyzing it?

Konstantin Shcheglov

The scope :-P of using this class was reduced, so I decided to remove it altogether.

Konstantin Shcheglov

Done

File pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart
Line 93, Patchset 2: var prefixElement = nameScope.lookup(prefixName).getter;

// Might be shadowed by an instance member.
// Look again to report `prefixShadowedByLocalDeclaration`.
if (prefixElement == null) {
var result = nameScope.lookup(prefixName);
if (result is InstanceScopeLookupResultImpl) {
prefixElement = result.instanceGetter ?? result.instanceSetter;
}
}
Paul Berry . resolved

It's inefficient to call `nameScope.lookup` twice.

```suggestion
var lookupResult = nameScope.lookup(prefixName);
var prefixElement = lookupResult.getter;
      // Might be shadowed by an instance member.
// Look again to report `prefixShadowedByLocalDeclaration`.
if (prefixElement == null) {
if (lookupResult is InstanceScopeLookupResultImpl) {
prefixElement =
lookupResult.instanceGetter ?? result.instanceSetter;
}
}

```

Konstantin Shcheglov

True, this is more efficient. It does not matter though, this branch is taken only if there is an error to be reported. I changed it to different re-lookup code.

Konstantin Shcheglov

Done

Open in Gerrit

Related details

Attention is currently required from:
  • Johnni Winther
  • Paul Berry
Submit Requirements:
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: sdk
Gerrit-Branch: main
Gerrit-Change-Id: Ib5fa23b97d1e6938eb00a2d2b6659eecae86b3b0
Gerrit-Change-Number: 479380
Gerrit-PatchSet: 3
Gerrit-Owner: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Johnni Winther <johnni...@google.com>
Gerrit-Reviewer: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Paul Berry <paul...@google.com>
Gerrit-Attention: Paul Berry <paul...@google.com>
Gerrit-Attention: Johnni Winther <johnni...@google.com>
Gerrit-Comment-Date: Wed, 11 Feb 2026 03:20:14 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Paul Berry <paul...@google.com>
Comment-In-Reply-To: Konstantin Shcheglov <sche...@google.com>
unsatisfied_requirement
open
diffy

Johnni Winther (Gerrit)

unread,
Feb 11, 2026, 3:23:15 AM (6 days ago) Feb 11
to Konstantin Shcheglov, Paul Berry, Commit Queue, dart-analys...@google.com, rev...@dartlang.org
Attention needed from Konstantin Shcheglov and Paul Berry

Johnni Winther added 1 comment

Patchset-level comments
Johnni Winther . resolved

I'm a bit surprised that instance member are not normal returned from scope lookups within the body scope. In the CFE they are always part of the body scope and will there naturally resolve (shadow) without additional action.

Konstantin Shcheglov

See "17.37 Lexical Lookup": Consider the case where D is an instance member declaration in a class or mixin A. The lexical lookup then yields nothing. In this case it is guaranteed that ℓ has access to this.

Johnni Winther

In the CFE the body scope contains the members declared (not inherited) in the enclosing declaration. This would match the case in spec

    Case <D exists> ...
Open in Gerrit

Related details

Attention is currently required from:
  • Konstantin Shcheglov
  • Paul Berry
Submit Requirements:
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: sdk
Gerrit-Branch: main
Gerrit-Change-Id: Ib5fa23b97d1e6938eb00a2d2b6659eecae86b3b0
Gerrit-Change-Number: 479380
Gerrit-PatchSet: 3
Gerrit-Owner: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Johnni Winther <johnni...@google.com>
Gerrit-Reviewer: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Paul Berry <paul...@google.com>
Gerrit-Attention: Paul Berry <paul...@google.com>
Gerrit-Attention: Konstantin Shcheglov <sche...@google.com>
Gerrit-Comment-Date: Wed, 11 Feb 2026 08:23:09 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Konstantin Shcheglov <sche...@google.com>
Comment-In-Reply-To: Johnni Winther <johnni...@google.com>
unsatisfied_requirement
open
diffy

Paul Berry (Gerrit)

unread,
Feb 11, 2026, 8:56:36 AM (5 days ago) Feb 11
to Konstantin Shcheglov, Johnni Winther, Commit Queue, dart-analys...@google.com, rev...@dartlang.org
Attention needed from Konstantin Shcheglov

Paul Berry voted and added 1 comment

Votes added by Paul Berry

Code-Review+1

1 comment

Patchset-level comments
File-level comment, Patchset 3 (Latest):
Paul Berry . resolved

lgtm assuming Johnni's concerns are addressed.

Open in Gerrit

Related details

Attention is currently required from:
  • Konstantin Shcheglov
Submit Requirements:
  • requirement satisfiedCode-Owners
  • requirement satisfiedCode-Review
  • requirement satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: sdk
Gerrit-Branch: main
Gerrit-Change-Id: Ib5fa23b97d1e6938eb00a2d2b6659eecae86b3b0
Gerrit-Change-Number: 479380
Gerrit-PatchSet: 3
Gerrit-Owner: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Johnni Winther <johnni...@google.com>
Gerrit-Reviewer: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Paul Berry <paul...@google.com>
Gerrit-Attention: Konstantin Shcheglov <sche...@google.com>
Gerrit-Comment-Date: Wed, 11 Feb 2026 13:56:32 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: Yes
satisfied_requirement
open
diffy

Konstantin Shcheglov (Gerrit)

unread,
Feb 11, 2026, 12:35:33 PM (5 days ago) Feb 11
to Erik Ernst, Paul Berry, Johnni Winther, Commit Queue, dart-analys...@google.com, rev...@dartlang.org
Attention needed from Erik Ernst and Johnni Winther

Konstantin Shcheglov added 1 comment

Patchset-level comments
File-level comment, Patchset 2:
Johnni Winther . unresolved

I'm a bit surprised that instance member are not normal returned from scope lookups within the body scope. In the CFE they are always part of the body scope and will there naturally resolve (shadow) without additional action.

Konstantin Shcheglov

See "17.37 Lexical Lookup": Consider the case where D is an instance member declaration in a class or mixin A. The lexical lookup then yields nothing. In this case it is guaranteed that ℓ has access to this.

Johnni Winther

In the CFE the body scope contains the members declared (not inherited) in the enclosing declaration. This would match the case in spec

    Case <D exists> ...
Konstantin Shcheglov

I'm not sure what you mean by this. The specification say that the lookup yields nothing. My understanding is that the instance members are in the scope, and they do shadow whatever could otherwise be accessible via scope lookup in the enclosing (library, or library fragment) scope. But the specification is written in this way to force going through `this.` for instance members.

"Case ⟨D exists⟩" is only the first step in the lexical lookup.

There is also "In the second and last step" that has this quote: "Consider the case where D is an instance member declaration in a class or mixin A. The lexical lookup then yields nothing. In this case it is guaranteed that ℓ has access to this."

The change to `InstanceScope` was done by Erik in https://dart-review.googlesource.com/c/sdk/+/459740/23/pkg/analyzer/lib/src/dart/element/scope.dart

Open in Gerrit

Related details

Attention is currently required from:
  • Erik Ernst
  • Johnni Winther
Submit Requirements:
  • requirement satisfiedCode-Owners
  • requirement satisfiedCode-Review
  • requirement satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: sdk
Gerrit-Branch: main
Gerrit-Change-Id: Ib5fa23b97d1e6938eb00a2d2b6659eecae86b3b0
Gerrit-Change-Number: 479380
Gerrit-PatchSet: 3
Gerrit-Owner: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Erik Ernst <eer...@google.com>
Gerrit-Reviewer: Johnni Winther <johnni...@google.com>
Gerrit-Reviewer: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Paul Berry <paul...@google.com>
Gerrit-Attention: Erik Ernst <eer...@google.com>
Gerrit-Attention: Johnni Winther <johnni...@google.com>
Gerrit-Comment-Date: Wed, 11 Feb 2026 17:35:30 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Johnni Winther <johnni...@google.com>
Comment-In-Reply-To: Konstantin Shcheglov <sche...@google.com>
satisfied_requirement
open
diffy

Johnni Winther (Gerrit)

unread,
Feb 12, 2026, 3:37:20 AM (5 days ago) Feb 12
to Konstantin Shcheglov, Erik Ernst, Paul Berry, Commit Queue, dart-analys...@google.com, rev...@dartlang.org
Attention needed from Erik Ernst and Konstantin Shcheglov

Johnni Winther added 1 comment

Patchset-level comments
File-level comment, Patchset 2:
Johnni Winther . resolved

I'm a bit surprised that instance member are not normal returned from scope lookups within the body scope. In the CFE they are always part of the body scope and will there naturally resolve (shadow) without additional action.

Konstantin Shcheglov

See "17.37 Lexical Lookup": Consider the case where D is an instance member declaration in a class or mixin A. The lexical lookup then yields nothing. In this case it is guaranteed that ℓ has access to this.

Johnni Winther

In the CFE the body scope contains the members declared (not inherited) in the enclosing declaration. This would match the case in spec

    Case <D exists> ...
Konstantin Shcheglov

I'm not sure what you mean by this. The specification say that the lookup yields nothing. My understanding is that the instance members are in the scope, and they do shadow whatever could otherwise be accessible via scope lookup in the enclosing (library, or library fragment) scope. But the specification is written in this way to force going through `this.` for instance members.

"Case ⟨D exists⟩" is only the first step in the lexical lookup.

There is also "In the second and last step" that has this quote: "Consider the case where D is an instance member declaration in a class or mixin A. The lexical lookup then yields nothing. In this case it is guaranteed that ℓ has access to this."

The change to `InstanceScope` was done by Erik in https://dart-review.googlesource.com/c/sdk/+/459740/23/pkg/analyzer/lib/src/dart/element/scope.dart

Johnni Winther

I'm asking, not because it is blocker for this CL, but because it is a difference between the scopes in the CFE and analyzer, which could indicate that one of us is wrong. I'll talk to Erik as well.

Open in Gerrit

Related details

Attention is currently required from:
  • Erik Ernst
  • Konstantin Shcheglov
Submit Requirements:
  • requirement satisfiedCode-Owners
  • requirement satisfiedCode-Review
  • requirement satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: sdk
Gerrit-Branch: main
Gerrit-Change-Id: Ib5fa23b97d1e6938eb00a2d2b6659eecae86b3b0
Gerrit-Change-Number: 479380
Gerrit-PatchSet: 3
Gerrit-Owner: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Erik Ernst <eer...@google.com>
Gerrit-Reviewer: Johnni Winther <johnni...@google.com>
Gerrit-Reviewer: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Paul Berry <paul...@google.com>
Gerrit-Attention: Erik Ernst <eer...@google.com>
Gerrit-Attention: Konstantin Shcheglov <sche...@google.com>
Gerrit-Comment-Date: Thu, 12 Feb 2026 08:37:16 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
satisfied_requirement
open
diffy

Johnni Winther (Gerrit)

unread,
Feb 12, 2026, 3:37:56 AM (5 days ago) Feb 12
to Konstantin Shcheglov, Erik Ernst, Paul Berry, Commit Queue, dart-analys...@google.com, rev...@dartlang.org
Attention needed from Erik Ernst and Konstantin Shcheglov

Johnni Winther voted Code-Review+1

Code-Review+1
Gerrit-Comment-Date: Thu, 12 Feb 2026 08:37:51 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
satisfied_requirement
open
diffy

Erik Ernst (Gerrit)

unread,
Feb 12, 2026, 4:43:49 AM (4 days ago) Feb 12
to Konstantin Shcheglov, Johnni Winther, Paul Berry, Commit Queue, dart-analys...@google.com, rev...@dartlang.org
Attention needed from Konstantin Shcheglov

Erik Ernst added 2 comments

Patchset-level comments
File-level comment, Patchset 2:
Johnni Winther . unresolved

I'm a bit surprised that instance member are not normal returned from scope lookups within the body scope. In the CFE they are always part of the body scope and will there naturally resolve (shadow) without additional action.

Konstantin Shcheglov

See "17.37 Lexical Lookup": Consider the case where D is an instance member declaration in a class or mixin A. The lexical lookup then yields nothing. In this case it is guaranteed that ℓ has access to this.

Johnni Winther

In the CFE the body scope contains the members declared (not inherited) in the enclosing declaration. This would match the case in spec

    Case <D exists> ...
Konstantin Shcheglov

I'm not sure what you mean by this. The specification say that the lookup yields nothing. My understanding is that the instance members are in the scope, and they do shadow whatever could otherwise be accessible via scope lookup in the enclosing (library, or library fragment) scope. But the specification is written in this way to force going through `this.` for instance members.

"Case ⟨D exists⟩" is only the first step in the lexical lookup.

There is also "In the second and last step" that has this quote: "Consider the case where D is an instance member declaration in a class or mixin A. The lexical lookup then yields nothing. In this case it is guaranteed that ℓ has access to this."

The change to `InstanceScope` was done by Erik in https://dart-review.googlesource.com/c/sdk/+/459740/23/pkg/analyzer/lib/src/dart/element/scope.dart

Erik Ernst

In the specification, a lexical lookup that finds an instance member with the given basename yields the result "nothing" (and the search stops there, it does not continue to search the library scope). This means that the resolution of an identifier expression `id` is treated uniformly when it denotes an instance member (it makes no difference whether it's declared in the enclosing syntax or inherited), because the expression is then treated as `this.id`. Similarly for an assignable expression which is an identifier. When the instance member is inherited or doesn't exist at all, the result is also "nothing". This means that the subsequent processing based on `this.id` is able to resolve `id` to an instance member or to an extension member access on `this`. However, when we're not looking up an identifier to evaluate or assign, the transformation from `id` to `this.id` does not take place; for example, this covers the case where we're looking up a type. In this case the error message should reflect the fact that either nothing was found ("unknown identifier" or the like), or an instance member was found, and we definitely can't use it ("`foo` is not a type"). So we should probably have a slightly richer result from the lexical lookup: In the case where the result is "nothing", we should be able to see whether the search ended because we found an instance member, or it was because we didn't find anything at all with that basename.

Erik Ernst . resolved

Commented on the 'lexical lookup' thread.

Open in Gerrit

Related details

Attention is currently required from:
  • Konstantin Shcheglov
Submit Requirements:
  • requirement satisfiedCode-Owners
  • requirement satisfiedCode-Review
  • requirement satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: sdk
Gerrit-Branch: main
Gerrit-Change-Id: Ib5fa23b97d1e6938eb00a2d2b6659eecae86b3b0
Gerrit-Change-Number: 479380
Gerrit-PatchSet: 3
Gerrit-Owner: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Erik Ernst <eer...@google.com>
Gerrit-Reviewer: Johnni Winther <johnni...@google.com>
Gerrit-Reviewer: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Paul Berry <paul...@google.com>
Gerrit-Attention: Konstantin Shcheglov <sche...@google.com>
Gerrit-Comment-Date: Thu, 12 Feb 2026 09:43:45 +0000
satisfied_requirement
open
diffy

Johnni Winther (Gerrit)

unread,
Feb 12, 2026, 5:09:39 AM (4 days ago) Feb 12
to Konstantin Shcheglov, Erik Ernst, Paul Berry, Commit Queue, dart-analys...@google.com, rev...@dartlang.org
Attention needed from Konstantin Shcheglov

Johnni Winther added 1 comment

Patchset-level comments
Johnni Winther . unresolved

I'm a bit surprised that instance member are not normal returned from scope lookups within the body scope. In the CFE they are always part of the body scope and will there naturally resolve (shadow) without additional action.

Konstantin Shcheglov

See "17.37 Lexical Lookup": Consider the case where D is an instance member declaration in a class or mixin A. The lexical lookup then yields nothing. In this case it is guaranteed that ℓ has access to this.

Johnni Winther

In the CFE the body scope contains the members declared (not inherited) in the enclosing declaration. This would match the case in spec

    Case <D exists> ...
Konstantin Shcheglov

I'm not sure what you mean by this. The specification say that the lookup yields nothing. My understanding is that the instance members are in the scope, and they do shadow whatever could otherwise be accessible via scope lookup in the enclosing (library, or library fragment) scope. But the specification is written in this way to force going through `this.` for instance members.

"Case ⟨D exists⟩" is only the first step in the lexical lookup.

There is also "In the second and last step" that has this quote: "Consider the case where D is an instance member declaration in a class or mixin A. The lexical lookup then yields nothing. In this case it is guaranteed that ℓ has access to this."

The change to `InstanceScope` was done by Erik in https://dart-review.googlesource.com/c/sdk/+/459740/23/pkg/analyzer/lib/src/dart/element/scope.dart

Erik Ernst

In the specification, a lexical lookup that finds an instance member with the given basename yields the result "nothing" (and the search stops there, it does not continue to search the library scope). This means that the resolution of an identifier expression `id` is treated uniformly when it denotes an instance member (it makes no difference whether it's declared in the enclosing syntax or inherited), because the expression is then treated as `this.id`. Similarly for an assignable expression which is an identifier. When the instance member is inherited or doesn't exist at all, the result is also "nothing". This means that the subsequent processing based on `this.id` is able to resolve `id` to an instance member or to an extension member access on `this`. However, when we're not looking up an identifier to evaluate or assign, the transformation from `id` to `this.id` does not take place; for example, this covers the case where we're looking up a type. In this case the error message should reflect the fact that either nothing was found ("unknown identifier" or the like), or an instance member was found, and we definitely can't use it ("`foo` is not a type"). So we should probably have a slightly richer result from the lexical lookup: In the case where the result is "nothing", we should be able to see whether the search ended because we found an instance member, or it was because we didn't find anything at all with that basename.

Johnni Winther

The danger of the result "nothing" is that since scopes are nested, a local lookup resulting in "nothing", normally means look in the parent scope. This is why I prefer the uniform handling that it *is* found, but rejected when it cannot be transformed into `this.id` either because we are looking for a type or `this` is not in scope, or some other reason (there are probably more).

Note that this interpretation is also used in the definition of documentation comment use of `[id]`, where an (instance) member declared in the same class-like declaration can be accessed through simple name, even though there is no notion here for transforming to `this.id`.

Open in Gerrit

Related details

Attention is currently required from:
  • Konstantin Shcheglov
Submit Requirements:
  • requirement satisfiedCode-Owners
  • requirement satisfiedCode-Review
  • requirement satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: sdk
Gerrit-Branch: main
Gerrit-Change-Id: Ib5fa23b97d1e6938eb00a2d2b6659eecae86b3b0
Gerrit-Change-Number: 479380
Gerrit-PatchSet: 3
Gerrit-Owner: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Erik Ernst <eer...@google.com>
Gerrit-Reviewer: Johnni Winther <johnni...@google.com>
Gerrit-Reviewer: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Paul Berry <paul...@google.com>
Gerrit-Attention: Konstantin Shcheglov <sche...@google.com>
Gerrit-Comment-Date: Thu, 12 Feb 2026 10:09:33 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Erik Ernst <eer...@google.com>
satisfied_requirement
open
diffy

Erik Ernst (Gerrit)

unread,
Feb 12, 2026, 6:56:39 AM (4 days ago) Feb 12
to Konstantin Shcheglov, Johnni Winther, Paul Berry, Commit Queue, dart-analys...@google.com, rev...@dartlang.org
Attention needed from Konstantin Shcheglov

Erik Ernst added 1 comment

Patchset-level comments
Johnni Winther . unresolved

I'm a bit surprised that instance member are not normal returned from scope lookups within the body scope. In the CFE they are always part of the body scope and will there naturally resolve (shadow) without additional action.

Konstantin Shcheglov

See "17.37 Lexical Lookup": Consider the case where D is an instance member declaration in a class or mixin A. The lexical lookup then yields nothing. In this case it is guaranteed that ℓ has access to this.

Johnni Winther

In the CFE the body scope contains the members declared (not inherited) in the enclosing declaration. This would match the case in spec

    Case <D exists> ...
Konstantin Shcheglov

I'm not sure what you mean by this. The specification say that the lookup yields nothing. My understanding is that the instance members are in the scope, and they do shadow whatever could otherwise be accessible via scope lookup in the enclosing (library, or library fragment) scope. But the specification is written in this way to force going through `this.` for instance members.

"Case ⟨D exists⟩" is only the first step in the lexical lookup.

There is also "In the second and last step" that has this quote: "Consider the case where D is an instance member declaration in a class or mixin A. The lexical lookup then yields nothing. In this case it is guaranteed that ℓ has access to this."

The change to `InstanceScope` was done by Erik in https://dart-review.googlesource.com/c/sdk/+/459740/23/pkg/analyzer/lib/src/dart/element/scope.dart

Erik Ernst

In the specification, a lexical lookup that finds an instance member with the given basename yields the result "nothing" (and the search stops there, it does not continue to search the library scope). This means that the resolution of an identifier expression `id` is treated uniformly when it denotes an instance member (it makes no difference whether it's declared in the enclosing syntax or inherited), because the expression is then treated as `this.id`. Similarly for an assignable expression which is an identifier. When the instance member is inherited or doesn't exist at all, the result is also "nothing". This means that the subsequent processing based on `this.id` is able to resolve `id` to an instance member or to an extension member access on `this`. However, when we're not looking up an identifier to evaluate or assign, the transformation from `id` to `this.id` does not take place; for example, this covers the case where we're looking up a type. In this case the error message should reflect the fact that either nothing was found ("unknown identifier" or the like), or an instance member was found, and we definitely can't use it ("`foo` is not a type"). So we should probably have a slightly richer result from the lexical lookup: In the case where the result is "nothing", we should be able to see whether the search ended because we found an instance member, or it was because we didn't find anything at all with that basename.

Johnni Winther

The danger of the result "nothing" is that since scopes are nested, a local lookup resulting in "nothing", normally means look in the parent scope. This is why I prefer the uniform handling that it *is* found, but rejected when it cannot be transformed into `this.id` either because we are looking for a type or `this` is not in scope, or some other reason (there are probably more).

Note that this interpretation is also used in the definition of documentation comment use of `[id]`, where an (instance) member declared in the same class-like declaration can be accessed through simple name, even though there is no notion here for transforming to `this.id`.

Erik Ernst

Any approach that has the same behavior is of course fine as an implementation strategy.

However, with features like anonymous methods where the type of `this` may differ from the statically known type of an enclosing class/mixin/... declaration, it's important that we don't commit to the choice of an instance member of the enclosing type-introducing declaration. For example, the original `this` could have an `int get foo` and the current `this` in an anonymous method could have a `void foo()`, and this means that we need to consider `this.id` to find the right member to use during the subsequent analysis. In this case it would be directly misleading to receive that `int get foo` reference as the result of the lookup.

Open in Gerrit

Related details

Attention is currently required from:
  • Konstantin Shcheglov
Submit Requirements:
  • requirement satisfiedCode-Owners
  • requirement satisfiedCode-Review
  • requirement satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: sdk
Gerrit-Branch: main
Gerrit-Change-Id: Ib5fa23b97d1e6938eb00a2d2b6659eecae86b3b0
Gerrit-Change-Number: 479380
Gerrit-PatchSet: 3
Gerrit-Owner: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Erik Ernst <eer...@google.com>
Gerrit-Reviewer: Johnni Winther <johnni...@google.com>
Gerrit-Reviewer: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Paul Berry <paul...@google.com>
Gerrit-Attention: Konstantin Shcheglov <sche...@google.com>
Gerrit-Comment-Date: Thu, 12 Feb 2026 11:56:34 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Erik Ernst <eer...@google.com>
satisfied_requirement
open
diffy

Konstantin Shcheglov (Gerrit)

unread,
Feb 12, 2026, 4:02:38 PM (4 days ago) Feb 12
to Johnni Winther, Erik Ernst, Paul Berry, Commit Queue, dart-analys...@google.com, rev...@dartlang.org

Konstantin Shcheglov voted Commit-Queue+2

Commit-Queue+2
Open in Gerrit

Related details

Attention set is empty
Submit Requirements:
  • requirement satisfiedCode-Owners
  • requirement satisfiedCode-Review
  • requirement satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: sdk
Gerrit-Branch: main
Gerrit-Change-Id: Ib5fa23b97d1e6938eb00a2d2b6659eecae86b3b0
Gerrit-Change-Number: 479380
Gerrit-PatchSet: 3
Gerrit-Owner: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Erik Ernst <eer...@google.com>
Gerrit-Reviewer: Johnni Winther <johnni...@google.com>
Gerrit-Reviewer: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Paul Berry <paul...@google.com>
Gerrit-Comment-Date: Thu, 12 Feb 2026 21:02:34 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
satisfied_requirement
open
diffy

Commit Queue (Gerrit)

unread,
Feb 12, 2026, 4:03:01 PM (4 days ago) Feb 12
to Konstantin Shcheglov, Johnni Winther, Erik Ernst, Paul Berry, dart-analys...@google.com, rev...@dartlang.org

Commit Queue submitted the change

Change information

Commit message:
CQ. Start using InstanceScope in ResolutionVisitor, a little.

The previous implementation was using LocalScope that does not do
filtering out instance members as required by the specification.

I also added a few tests, some of which demonstrate what was worked,
what was broken, and what is still broken.

Work toward fixing https://github.com/dart-lang/sdk/issues/62622
Change-Id: Ib5fa23b97d1e6938eb00a2d2b6659eecae86b3b0
Reviewed-by: Paul Berry <paul...@google.com>
Reviewed-by: Johnni Winther <johnni...@google.com>
Commit-Queue: Konstantin Shcheglov <sche...@google.com>
Files:
  • M pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
  • M pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart
  • M pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
  • M pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
  • M pkg/analyzer/test/src/diagnostics/pattern_assignment_not_local_variable_test.dart
  • M pkg/analyzer/test/src/diagnostics/prefix_shadowed_by_local_declaration_test.dart
  • M tests/language/class_modifiers/base/base_class_syntax_error_test.dart
  • M tests/language/sealed_class/sealed_class_syntax_error_test.dart
Change size: L
Delta: 8 files changed, 464 insertions(+), 37 deletions(-)
Branch: refs/heads/main
Submit Requirements:
  • requirement satisfiedCode-Review: +1 by Johnni Winther, +1 by Paul Berry
Open in Gerrit
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: merged
Gerrit-Project: sdk
Gerrit-Branch: main
Gerrit-Change-Id: Ib5fa23b97d1e6938eb00a2d2b6659eecae86b3b0
Gerrit-Change-Number: 479380
Gerrit-PatchSet: 4
Gerrit-Owner: Konstantin Shcheglov <sche...@google.com>
open
diffy
satisfied_requirement

Erik Ernst (Gerrit)

unread,
Feb 13, 2026, 10:06:44 AM (3 days ago) Feb 13
to Konstantin Shcheglov, Commit Queue, Johnni Winther, Paul Berry, dart-analys...@google.com, rev...@dartlang.org

Erik Ernst added 2 comments

Patchset-level comments
File-level comment, Patchset 2:
Johnni Winther . resolved

I'm a bit surprised that instance member are not normal returned from scope lookups within the body scope. In the CFE they are always part of the body scope and will there naturally resolve (shadow) without additional action.

Konstantin Shcheglov

See "17.37 Lexical Lookup": Consider the case where D is an instance member declaration in a class or mixin A. The lexical lookup then yields nothing. In this case it is guaranteed that ℓ has access to this.

Johnni Winther

In the CFE the body scope contains the members declared (not inherited) in the enclosing declaration. This would match the case in spec

    Case <D exists> ...
Konstantin Shcheglov

I'm not sure what you mean by this. The specification say that the lookup yields nothing. My understanding is that the instance members are in the scope, and they do shadow whatever could otherwise be accessible via scope lookup in the enclosing (library, or library fragment) scope. But the specification is written in this way to force going through `this.` for instance members.

"Case ⟨D exists⟩" is only the first step in the lexical lookup.

There is also "In the second and last step" that has this quote: "Consider the case where D is an instance member declaration in a class or mixin A. The lexical lookup then yields nothing. In this case it is guaranteed that ℓ has access to this."

The change to `InstanceScope` was done by Erik in https://dart-review.googlesource.com/c/sdk/+/459740/23/pkg/analyzer/lib/src/dart/element/scope.dart

Erik Ernst

In the specification, a lexical lookup that finds an instance member with the given basename yields the result "nothing" (and the search stops there, it does not continue to search the library scope). This means that the resolution of an identifier expression `id` is treated uniformly when it denotes an instance member (it makes no difference whether it's declared in the enclosing syntax or inherited), because the expression is then treated as `this.id`. Similarly for an assignable expression which is an identifier. When the instance member is inherited or doesn't exist at all, the result is also "nothing". This means that the subsequent processing based on `this.id` is able to resolve `id` to an instance member or to an extension member access on `this`. However, when we're not looking up an identifier to evaluate or assign, the transformation from `id` to `this.id` does not take place; for example, this covers the case where we're looking up a type. In this case the error message should reflect the fact that either nothing was found ("unknown identifier" or the like), or an instance member was found, and we definitely can't use it ("`foo` is not a type"). So we should probably have a slightly richer result from the lexical lookup: In the case where the result is "nothing", we should be able to see whether the search ended because we found an instance member, or it was because we didn't find anything at all with that basename.

Johnni Winther

The danger of the result "nothing" is that since scopes are nested, a local lookup resulting in "nothing", normally means look in the parent scope. This is why I prefer the uniform handling that it *is* found, but rejected when it cannot be transformed into `this.id` either because we are looking for a type or `this` is not in scope, or some other reason (there are probably more).

Note that this interpretation is also used in the definition of documentation comment use of `[id]`, where an (instance) member declared in the same class-like declaration can be accessed through simple name, even though there is no notion here for transforming to `this.id`.

Erik Ernst

Any approach that has the same behavior is of course fine as an implementation strategy.

However, with features like anonymous methods where the type of `this` may differ from the statically known type of an enclosing class/mixin/... declaration, it's important that we don't commit to the choice of an instance member of the enclosing type-introducing declaration. For example, the original `this` could have an `int get foo` and the current `this` in an anonymous method could have a `void foo()`, and this means that we need to consider `this.id` to find the right member to use during the subsequent analysis. In this case it would be directly misleading to receive that `int get foo` reference as the result of the lookup.

Erik Ernst

(Just closing the thread, I don't think any further actions are needed in response to this discussion).

File-level comment, Patchset 4 (Latest):
Erik Ernst . resolved

(Just closing a thread that I had commented on.)

Open in Gerrit

Related details

Attention set is empty
Submit Requirements:
  • requirement satisfiedCode-Owners
  • requirement satisfiedCode-Review
  • requirement satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: sdk
Gerrit-Branch: main
Gerrit-Change-Id: Ib5fa23b97d1e6938eb00a2d2b6659eecae86b3b0
Gerrit-Change-Number: 479380
Gerrit-PatchSet: 4
Gerrit-Owner: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Erik Ernst <eer...@google.com>
Gerrit-Reviewer: Johnni Winther <johnni...@google.com>
Gerrit-Reviewer: Konstantin Shcheglov <sche...@google.com>
Gerrit-Reviewer: Paul Berry <paul...@google.com>
Gerrit-Comment-Date: Fri, 13 Feb 2026 15:06:39 +0000
satisfied_requirement
open
diffy
Reply all
Reply to author
Forward
0 new messages