Skip to content

Commit

Permalink
Fix dart-lang#2485. Updateas and is expressions tests with a func…
Browse files Browse the repository at this point in the history
…tion type (dart-lang#2538)

Update`as` and `is` expressions tests with a function type
  • Loading branch information
sgrekhov committed Feb 15, 2024
1 parent d88733c commit c462960
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Language/Expressions/Constants/as_type_A01_t02.dart
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ main() {

const f1 = foo as void Function();
const f2 = as as void Function();
const f3 = bar<int> as int Function(int);
const f3 = (bar<int>) as int Function(int);

const d = 2 as dynamic;

Expand Down
2 changes: 1 addition & 1 deletion Language/Expressions/Constants/is_not_type_A01_t02.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ main() {
const fo7 = IntET2(1) is! FutureOr<IntET1Alias>;

const f1 = foo is! void Function();
const f2 = bar<int> is! int Function(int);
const f2 = (bar<int>) is! int Function(int);

const d = 2 is! dynamic;

Expand Down
2 changes: 1 addition & 1 deletion Language/Expressions/Constants/is_type_A01_t02.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ main() {
const fo7 = IntET2(1) is FutureOr<IntET1Alias>;

const f1 = foo is void Function();
const f2 = bar<int> is int Function<int>(int);
const f2 = (bar<int>) is int Function(int);

const d = 2 is dynamic;

Expand Down
84 changes: 84 additions & 0 deletions LanguageFeatures/Constructor-tear-offs/ambiguities_A36_t04.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// 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.

/// @assertion This new syntax also introduces new ambiguities in the grammar,
/// similar to the one we introduced with generic functions. Examples include:
///
/// f(a<b,c>(d)); // Existing ambiguity, resolved to a generic method call.
/// f(x.a<b,c>[d]); // f((x.a<b, c>)[d]) or f((x.a < b), (c > [d]))
/// f(x.a<b,c>-d); // f((x.a<b, c>)-d) or f((x.a < b), (c > -d]))
/// The x.a<b,c> can be an explicitly instantiated generic function tear-off or
/// an explicitly instantiated type literal named using a prefix, which is new.
/// While neither type objects nor functions declare operator- or operator[],
/// such could be added using extension methods.
///
/// We will disambiguate such situations heuristically based on the token
/// following the > that matches the < we are ambiguous about. In the existing
/// ambiguity we treat ( as a sign that the < starts a generic invocation. We
/// extend the number of tokens which, when following a potential type argument
/// list, makes us choose to parse the previous tokens as that type argument
/// list.
///
/// There is a number of tokens which very consistently end an expression, and
/// we include all those:
///
/// ), }, ], ;, :, ,
///
/// Then we include tokens which we predict will continue a generic instantiation:
///
/// ( . == !=
///
/// The first six are tokens which cannot possibly start an expression, and
/// therefore cannot occur after a greater-than infix operator. The last four
/// tokens can continue an expression, and of those only ( can also start an
/// expression, and we already decided how to disambiguate that).
///
/// There are many other tokens which currently cannot continue an expression
/// (and therefore cannot validly follow a type argument list) or which cannot
/// start an expression (and therefore cannot validly follow a greater-than
/// operator), but in the service of keeping our future options open, we choose
/// a design that does not rely on those restrictions. For example we omit most
/// infix operators from being "continuation tokens", even though they currently
/// cannot start a new expression, and therefore cannot follow a > infix
/// operator. This leaves us open to allowing some of those operators as prefix
/// operators in the future, like we currently allow the - operator.
///
/// @description Checks that it is a syntax error if function with type argument
/// specified is part of `as`, `as!` or `is` expressions
/// @author sgrekhov22@gmail.com
int bar<T>(T t) => 42;
void foo<T1, T2, T3>() {}

main() {
const c1 = bar<int> as int Function(int);
// ^^^
// [analyzer] unspecified
// [cfe] unspecified

const c2 = bar<int> is! int Function(int);
// ^^^
// [analyzer] unspecified
// [cfe] unspecified

const c3 = bar<int> is int Function(int);
// ^^^
// [analyzer] unspecified
// [cfe] unspecified

const c4 = foo<int, String, bool> as void Function();
// ^
// [analyzer] unspecified
// [cfe] unspecified

const c5 = foo<int, String, bool> is! void Function();
// ^
// [analyzer] unspecified
// [cfe] unspecified

const c6 = foo<int, String, bool> is void Function();
// ^
// [analyzer] unspecified
// [cfe] unspecified
}

0 comments on commit c462960

Please sign in to comment.