Skip to content

Commit

Permalink
[wildcards] local and parameter scopes
Browse files Browse the repository at this point in the history
Update wildcard variable scopes.

See:  #55862 and #55680.

See discussion on related/ updated co19 test (`co19/LanguageFeatures/Wildcards/wildcards_do_not_shadow_A01_t04`) here: dart-lang/co19#2698.





Change-Id: I388895ef7bac69617700504a964ce9f3021b2d24
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/368526
Commit-Queue: Phil Quitslund <[email protected]>
Reviewed-by: Brian Wilkerson <[email protected]>
Reviewed-by: Konstantin Shcheglov <[email protected]>
  • Loading branch information
pq authored and Commit Queue committed Jun 11, 2024
1 parent 7ead4b5 commit 9544fe9
Show file tree
Hide file tree
Showing 7 changed files with 212 additions and 154 deletions.
15 changes: 13 additions & 2 deletions pkg/analyzer/lib/src/dart/element/scope.dart
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ class FormalParameterScope extends EnclosedScope {
for (var parameter in elements) {
if (parameter is! FieldFormalParameterElement &&
parameter is! SuperFormalParameterElement) {
_addGetter(parameter);
if (!parameter.isWildcardVariable) {
_addGetter(parameter);
}
}
}
}
Expand Down Expand Up @@ -174,7 +176,9 @@ class LocalScope extends EnclosedScope {
LocalScope(super.parent);

void add(Element element) {
_addGetter(element);
if (!element.isWildcardVariable) {
_addGetter(element);
}
}
}

Expand Down Expand Up @@ -436,3 +440,10 @@ class _LibraryOrAugmentationImportScope implements Scope {
return _nullPrefixScope.lookup(id);
}
}

extension on Element {
bool get isWildcardVariable =>
name == '_' &&
(this is LocalVariableElement || this is ParameterElement) &&
(library?.featureSet.isEnabled(Feature.wildcard_variables) ?? false);
}
39 changes: 39 additions & 0 deletions pkg/analyzer/test/src/dart/resolution/local_variable_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,43 @@ void f() {
expect(x.isLate, isTrue);
expect(x.isStatic, isFalse);
}

test_localVariable_wildcardVariable_field() async {
await assertNoErrorsInCode('''
class C {
var _ = 1;
void m() {
var _ = 0;
_;
}
}
''');

var node = findNode.simple('_;');
assertResolvedNodeText(node, r'''
SimpleIdentifier
token: _
staticElement: self::@class::C::@getter::_
staticType: int
''');
}

test_localVariable_wildcardVariable_topLevel() async {
await assertNoErrorsInCode('''
var _ = 1;
void f() {
var _ = 0;
_;
}
''');

var node = findNode.simple('_;');
assertResolvedNodeText(node, r'''
SimpleIdentifier
token: _
staticElement: self::@getter::_
staticType: int
''');
}
}
19 changes: 19 additions & 0 deletions pkg/analyzer/test/src/dart/resolution/method_declaration_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,23 @@ class B {
findElement.parameter('a'),
);
}

test_formalParameterScope_wildcardVariable() async {
await assertNoErrorsInCode('''
class A {
var _ = 1;
void m(int? _) {
_;
}
}
''');

var node = findNode.simple('_;');
assertResolvedNodeText(node, r'''
SimpleIdentifier
token: _
staticElement: self::@class::A::@getter::_
staticType: int
''');
}
}
53 changes: 21 additions & 32 deletions pkg/analyzer/test/src/diagnostics/unused_catch_clause_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,46 @@
// 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:analyzer/dart/analysis/features.dart';
import 'package:analyzer/src/error/codes.g.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../dart/resolution/context_collection_resolution.dart';

main() {
defineReflectiveSuite(() {
defineReflectiveTests(UnusedCatchClauseTest);
defineReflectiveTests(UnusedCatchClauseTestWildCardVariablesTest);
});
}

@reflectiveTest
class UnusedCatchClauseTest extends PubPackageResolutionTest {
test_on_unusedException() async {
await assertErrorsInCode(r'''
main() {
f() {
try {
} on String catch (exception) {
}
}
''', [
error(WarningCode.UNUSED_CATCH_CLAUSE, 38, 9),
error(WarningCode.UNUSED_CATCH_CLAUSE, 35, 9),
]);
}

test_on_unusedStack_underscores() async {
await assertErrorsInCode(r'''
f() {
try {
} on String catch (exception, __) {
}
}
''', [
error(WarningCode.UNUSED_CATCH_STACK, 46, 2),
]);
}

test_on_unusedStack_wildcard() async {
await assertNoErrorsInCode(r'''
main() {
f() {
try {
} on String catch (exception, _) {
}
Expand All @@ -41,7 +51,7 @@ main() {

test_on_usedException() async {
await assertNoErrorsInCode(r'''
main() {
f() {
try {
} on String catch (exception) {
print(exception);
Expand All @@ -52,7 +62,7 @@ main() {

test_unusedException() async {
await assertNoErrorsInCode(r'''
main() {
f() {
try {
} catch (exception) {
}
Expand All @@ -62,7 +72,7 @@ main() {

test_unusedException_underscores() async {
await assertNoErrorsInCode(r'''
main() {
f() {
try {
} catch (__) {
}
Expand All @@ -72,7 +82,7 @@ main() {

test_unusedException_wildcard() async {
await assertNoErrorsInCode(r'''
main() {
f() {
try {
} catch (_) {
}
Expand All @@ -82,7 +92,7 @@ main() {

test_usedException() async {
await assertNoErrorsInCode(r'''
main() {
f() {
try {
} catch (exception) {
print(exception);
Expand All @@ -91,24 +101,3 @@ main() {
''');
}
}

@reflectiveTest
class UnusedCatchClauseTestWildCardVariablesTest extends UnusedCatchClauseTest {
@override
List<String> get experiments => [
...super.experiments,
Feature.wildcard_variables.enableString,
];

test_on_unusedStack_underscores() async {
await assertErrorsInCode(r'''
main() {
try {
} on String catch (exception, __) {
}
}
''', [
error(WarningCode.UNUSED_CATCH_STACK, 49, 2),
]);
}
}
24 changes: 24 additions & 0 deletions pkg/analyzer/test/src/diagnostics/unused_field_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,30 @@ print(x) {}
''');
}

test_isUsed_underscoreField_shadowsLocal() async {
await assertNoErrorsInCode(r'''
class A {
var _ = 1;
void m() {
var _ = 0;
print(_);
}
}
''');
}

// See: https://github.com/dart-lang/sdk/issues/55862
test_isUsed_underscoreField_shadowsParameter() async {
await assertNoErrorsInCode(r'''
class A {
var _ = 1;
void m(int? _) {
print(_);
}
}
''');
}

test_notUsed_compoundAssign() async {
await assertErrorsInCode(r'''
class A {
Expand Down
Loading

0 comments on commit 9544fe9

Please sign in to comment.