[cfe] Wildcard import prefixes are non-binding.
Bug: https://github.com/dart-lang/sdk/issues/55655
Change-Id: I938c254fad2c656c9342e9cea5b146373b9f63e5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/372603
Commit-Queue: Kallen Tu <kallentu@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/front_end/lib/src/fasta/builder/prefix_builder.dart b/pkg/front_end/lib/src/fasta/builder/prefix_builder.dart
index c986a85..66b116e 100644
--- a/pkg/front_end/lib/src/fasta/builder/prefix_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/prefix_builder.dart
@@ -30,8 +30,11 @@
final LoadLibraryBuilder? loadLibraryBuilder;
+ final bool isWildcard;
+
PrefixBuilder(this.name, this.deferred, this.parent, this.loadLibraryBuilder,
- this.charOffset, this.importIndex) {
+ this.charOffset, this.importIndex)
+ : isWildcard = name == '_' {
assert(deferred == (loadLibraryBuilder != null),
"LoadLibraryBuilder must be provided iff prefix is deferred.");
if (loadLibraryBuilder != null) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 04d16c6..63d56c1 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -3515,6 +3515,14 @@
memberBuilder.parent, memberBuilder.member, null);
} else if (declaration is PrefixBuilder) {
assert(prefix == null);
+ // Wildcard import prefixes are non-binding and cannot be used.
+ if (libraryFeatures.wildcardVariables.isEnabled &&
+ declaration.isWildcard) {
+ // TODO(kallentu): Provide a helpful error related to wildcard prefixes.
+ return new UnresolvedNameGenerator(this, nameToken,
+ new Name(declaration.name, libraryBuilder.nameOrigin),
+ unresolvedReadKind: UnresolvedKind.Unknown);
+ }
return new PrefixUseGenerator(this, nameToken, declaration);
} else if (declaration is LoadLibraryBuilder) {
return new LoadLibraryGenerator(this, nameToken, declaration);
diff --git a/pkg/front_end/testcases/wildcard_variables/import_prefix.dart b/pkg/front_end/testcases/wildcard_variables/import_prefix.dart
new file mode 100644
index 0000000..12132e4
--- /dev/null
+++ b/pkg/front_end/testcases/wildcard_variables/import_prefix.dart
@@ -0,0 +1,11 @@
+// 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.
+
+import 'dart:collection' as _;
+
+test() {
+ _.Queue<int>();
+ Queue<int>();
+ [1].firstOrNull;
+}
diff --git a/pkg/front_end/testcases/wildcard_variables/import_prefix.dart.strong.expect b/pkg/front_end/testcases/wildcard_variables/import_prefix.dart.strong.expect
new file mode 100644
index 0000000..322536e
--- /dev/null
+++ b/pkg/front_end/testcases/wildcard_variables/import_prefix.dart.strong.expect
@@ -0,0 +1,27 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/wildcard_variables/import_prefix.dart:8:3: Error: Undefined name '_'.
+// _.Queue<int>();
+// ^
+//
+// pkg/front_end/testcases/wildcard_variables/import_prefix.dart:9:3: Error: Method not found: 'Queue'.
+// Queue<int>();
+// ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+
+import "dart:collection" as _;
+
+static method test() → dynamic {
+ invalid-expression "pkg/front_end/testcases/wildcard_variables/import_prefix.dart:8:3: Error: Undefined name '_'.
+ _.Queue<int>();
+ ^"{dynamic}.Queue<core::int>();
+ invalid-expression "pkg/front_end/testcases/wildcard_variables/import_prefix.dart:9:3: Error: Method not found: 'Queue'.
+ Queue<int>();
+ ^^^^^";
+ col::IterableExtensions|get#firstOrNull<core::int>(<core::int>[1]);
+}
diff --git a/pkg/front_end/testcases/wildcard_variables/import_prefix.dart.strong.modular.expect b/pkg/front_end/testcases/wildcard_variables/import_prefix.dart.strong.modular.expect
new file mode 100644
index 0000000..322536e
--- /dev/null
+++ b/pkg/front_end/testcases/wildcard_variables/import_prefix.dart.strong.modular.expect
@@ -0,0 +1,27 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/wildcard_variables/import_prefix.dart:8:3: Error: Undefined name '_'.
+// _.Queue<int>();
+// ^
+//
+// pkg/front_end/testcases/wildcard_variables/import_prefix.dart:9:3: Error: Method not found: 'Queue'.
+// Queue<int>();
+// ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+
+import "dart:collection" as _;
+
+static method test() → dynamic {
+ invalid-expression "pkg/front_end/testcases/wildcard_variables/import_prefix.dart:8:3: Error: Undefined name '_'.
+ _.Queue<int>();
+ ^"{dynamic}.Queue<core::int>();
+ invalid-expression "pkg/front_end/testcases/wildcard_variables/import_prefix.dart:9:3: Error: Method not found: 'Queue'.
+ Queue<int>();
+ ^^^^^";
+ col::IterableExtensions|get#firstOrNull<core::int>(<core::int>[1]);
+}
diff --git a/pkg/front_end/testcases/wildcard_variables/import_prefix.dart.strong.outline.expect b/pkg/front_end/testcases/wildcard_variables/import_prefix.dart.strong.outline.expect
new file mode 100644
index 0000000..f5a4c94
--- /dev/null
+++ b/pkg/front_end/testcases/wildcard_variables/import_prefix.dart.strong.outline.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+import "dart:collection" as _;
+
+static method test() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/wildcard_variables/import_prefix.dart.strong.transformed.expect b/pkg/front_end/testcases/wildcard_variables/import_prefix.dart.strong.transformed.expect
new file mode 100644
index 0000000..26d2c51
--- /dev/null
+++ b/pkg/front_end/testcases/wildcard_variables/import_prefix.dart.strong.transformed.expect
@@ -0,0 +1,27 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/wildcard_variables/import_prefix.dart:8:3: Error: Undefined name '_'.
+// _.Queue<int>();
+// ^
+//
+// pkg/front_end/testcases/wildcard_variables/import_prefix.dart:9:3: Error: Method not found: 'Queue'.
+// Queue<int>();
+// ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+
+import "dart:collection" as _;
+
+static method test() → dynamic {
+ invalid-expression "pkg/front_end/testcases/wildcard_variables/import_prefix.dart:8:3: Error: Undefined name '_'.
+ _.Queue<int>();
+ ^"{dynamic}.Queue<core::int>();
+ invalid-expression "pkg/front_end/testcases/wildcard_variables/import_prefix.dart:9:3: Error: Method not found: 'Queue'.
+ Queue<int>();
+ ^^^^^";
+ col::IterableExtensions|get#firstOrNull<core::int>(core::_GrowableList::_literal1<core::int>(1));
+}
diff --git a/pkg/front_end/testcases/wildcard_variables/import_prefix.dart.textual_outline.expect b/pkg/front_end/testcases/wildcard_variables/import_prefix.dart.textual_outline.expect
new file mode 100644
index 0000000..638e0bf
--- /dev/null
+++ b/pkg/front_end/testcases/wildcard_variables/import_prefix.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'dart:collection' as _;
+
+test() {}
diff --git a/pkg/front_end/testcases/wildcard_variables/import_prefix.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/wildcard_variables/import_prefix.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..638e0bf
--- /dev/null
+++ b/pkg/front_end/testcases/wildcard_variables/import_prefix.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'dart:collection' as _;
+
+test() {}
diff --git a/tests/language/wildcard_variables/import/import_error_test.dart b/tests/language/wildcard_variables/import/import_error_test.dart
index 65f8e68..0d62785 100644
--- a/tests/language/wildcard_variables/import/import_error_test.dart
+++ b/tests/language/wildcard_variables/import/import_error_test.dart
@@ -15,21 +15,21 @@
_.topLevel;
//^
// [analyzer] unspecified
-// [cfe] unspecified
+// [cfe] Undefined name '_'.
_.C(value);
//^
// [analyzer] unspecified
-// [cfe] unspecified
+// [cfe] Undefined name '_'.
// Private extensions can't be used.
value.bar;
-//^
-// [analyzer] unspecified
-// [cfe] unspecified
+// ^^^
+// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
+// [cfe] The getter 'bar' isn't defined for the class 'String'.
value.fn;
-//^
-// [analyzer] unspecified
-// [cfe] unspecified
+// ^^
+// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
+// [cfe] The getter 'fn' isn't defined for the class 'String'.
}