Skip to content

Commit 4dd22a8

Browse files
committed
Adds tests for syntactic support for generic methods.
This CL adds tests for syntactic support for declaration of type parameters on methods and named functions, and for passing actual type parameters in invocations. The status files declare all the tests to be `CompiletimeError`s (there is no support for `// AnalyzerOptions=`, so no `--options=..` can be passed to `dartanalyzer`, even though it does succeed with `--options=tests/language/X.options` where `X` is the name of the test). BUG= [email protected], [email protected], [email protected] Review URL: https://codereview.chromium.org/1779173003 .
1 parent dc95698 commit 4dd22a8

9 files changed

+261
-0
lines changed
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import "package:expect/expect.dart";
6+
7+
// Dart test verifying that the parser can handle type parameterization of
8+
// function declarations and function invocations. Variant of code from
9+
// DEP #22, adjusted to use generic top level functions.
10+
11+
class BinaryTreeNode<K extends Comparable<K>, V> {
12+
final K _key;
13+
final V _value;
14+
final BinaryTreeNode<K, V> _left;
15+
final BinaryTreeNode<K, V> _right;
16+
17+
BinaryTreeNode(this._key, this._value,
18+
{BinaryTreeNode<K, V> left: null, BinaryTreeNode<K, V> right: null}) :
19+
_left = left, _right = right;
20+
21+
BinaryTreeNode<K, V> insert(K key, V value) {
22+
int c = key.compareTo(_key);
23+
if (c == 0) return this;
24+
var _insert = (BinaryTreeNode<K, V> t, K key, V value) =>
25+
insertOpt<K, V>(t, key, value);
26+
BinaryTreeNode<K, V> left = _left;
27+
BinaryTreeNode<K, V> right = _right;
28+
if (c < 0) {
29+
left = _insert(_left, key, value);
30+
} else {
31+
right = _insert(_right, key, value);
32+
}
33+
return new BinaryTreeNode<K, V>(_key, _value, left: left, right: right);
34+
}
35+
36+
BinaryTreeNode<K, U> map<U>(U f(V x)){
37+
var _map = (BinaryTreeNode<K, V> t, U f(V x)) => mapOpt<K, V, U>(t, f);
38+
return new BinaryTreeNode<K, U>(
39+
_key,
40+
f(_value),
41+
left: _map(_left, f),
42+
right: _map(_right, f));
43+
}
44+
45+
S foldPre<S>(S init, S f(V t, S s)) {
46+
var _fold = (BinaryTreeNode<K, V> t, S s, S f(V t, S s)) =>
47+
foldPreOpt<K, V, S>(t, s, f);
48+
S s = init;
49+
s = f(_value, s);
50+
s = _fold(_left, s, f);
51+
s = _fold(_right, s, f);
52+
return s;
53+
}
54+
}
55+
56+
// Use fresh type variables.
57+
BinaryTreeNode<K2, V2> insertOpt<K2 extends Comparable<K2>, V2>(
58+
BinaryTreeNode<K2, V2> t, K2 key, V2 value) {
59+
return (t == null) ? new BinaryTreeNode(key, value) : t.insert(key, value);
60+
}
61+
62+
// Reuse type variables [K], [V] to test shadowing.
63+
BinaryTreeNode<K, U> mapOpt<K extends Comparable<K>, V, U>(
64+
BinaryTreeNode<K, V> t, U f(V x)) {
65+
return (t == null) ? null : t.map<U>(f);
66+
}
67+
68+
// Use fresh [K2], shadowing [V].
69+
S foldPreOpt<K2 extends Comparable<K2>, V, S>(
70+
BinaryTreeNode<K2, V> t, S init, S f(V t, S s)) {
71+
return (t == null) ? init : t.foldPre<S>(init, f);
72+
}
73+
74+
class BinaryTree<K extends Comparable<K>, V> {
75+
final BinaryTreeNode<K, V> _root;
76+
77+
BinaryTree._internal(this._root);
78+
BinaryTree.empty() : this._internal(null);
79+
80+
BinaryTree<K, V> insert(K key, V value) {
81+
BinaryTreeNode<K, V> root = insertOpt<K, V>(_root, key, value);
82+
return new BinaryTree<K, V>._internal(root);
83+
}
84+
85+
BinaryTree<K, U> map<U>(U f(V x)) {
86+
BinaryTreeNode<K, U> root = mapOpt<K, V, U>(_root, f);
87+
return new BinaryTree<K, U>._internal(root);
88+
}
89+
90+
S foldPre<S>(S init, S f(V t, S s)) {
91+
return foldPreOpt<K, V, S>(_root, init, f);
92+
}
93+
}
94+
95+
main() {
96+
BinaryTree<num, String> sT = new BinaryTree<num, String>.empty();
97+
98+
sT = sT.insert(0, "");
99+
sT = sT.insert(1, " ");
100+
sT = sT.insert(2, " ");
101+
sT = sT.insert(3, " ");
102+
103+
BinaryTree<num, num> iT = sT.map<num>((String s) => s.length);
104+
105+
Expect.equals(iT.foldPre<num>(0, (int i, num s) => i + s), 6);
106+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
analyzer:
2+
language:
3+
enableGenericMethods: true
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import "package:expect/expect.dart";
6+
7+
// Dart test verifying that the parser can handle type parameterization of
8+
// method declarations and method invocations. Slightly adjusted version of
9+
// code from DEP #22.
10+
11+
class BinaryTreeNode<K extends Comparable<K>, V> {
12+
final K _key;
13+
final V _value;
14+
final BinaryTreeNode<K, V> _left;
15+
final BinaryTreeNode<K, V> _right;
16+
17+
BinaryTreeNode(this._key, this._value,
18+
{BinaryTreeNode<K, V> left: null, BinaryTreeNode<K, V> right: null}) :
19+
_left = left, _right = right;
20+
21+
// Use fresh type variables.
22+
static BinaryTreeNode<K2, V2> insertOpt<K2 extends Comparable<K2>, V2>(
23+
BinaryTreeNode<K2, V2> t, K2 key, V2 value) {
24+
return (t == null) ? new BinaryTreeNode(key, value) : t.insert(key, value);
25+
}
26+
27+
BinaryTreeNode<K, V> insert(K key, V value) {
28+
int c = key.compareTo(_key);
29+
if (c == 0) return this;
30+
var _insert = (BinaryTreeNode<K, V> node, K key, V value) =>
31+
insertOpt<K, V>(node, key, value);
32+
BinaryTreeNode<K, V> left = _left;
33+
BinaryTreeNode<K, V> right = _right;
34+
if (c < 0) {
35+
left = _insert(_left, key, value);
36+
} else {
37+
right = _insert(_right, key, value);
38+
}
39+
return new BinaryTreeNode<K, V>(_key, _value, left: left, right: right);
40+
}
41+
42+
// Reuse type variables [K], [V] to test shadowing.
43+
static BinaryTreeNode<K, U> mapOpt<K extends Comparable<K>, V, U>
44+
(BinaryTreeNode<K, V> t, U f(V x)) {
45+
return (t == null) ? null : t.map<U>(f);
46+
}
47+
48+
BinaryTreeNode<K, U> map<U>(U f(V x)){
49+
var _map = (BinaryTreeNode<K, V> t, U f(V x)) => mapOpt<K, V, U>(t, f);
50+
return new BinaryTreeNode<K, U>(
51+
_key,
52+
f(_value),
53+
left: _map(_left, f),
54+
right: _map(_right, f));
55+
}
56+
57+
// Use fresh [K2], shadowing [V].
58+
static S foldPreOpt<K2 extends Comparable<K2>, V, S>(
59+
BinaryTreeNode<K2, V> t, S init, S f(V t, S s)) {
60+
return (t == null) ? init : t.foldPre<S>(init, f);
61+
}
62+
63+
S foldPre<S>(S init, S f(V t, S s)) {
64+
var _fold = (BinaryTreeNode<K, V> t, S s, S f(V t, S s)) =>
65+
foldPreOpt<K, V, S>(t, s, f);
66+
S s = init;
67+
s = f(_value, s);
68+
s = _fold(_left, s, f);
69+
s = _fold(_right, s, f);
70+
return s;
71+
}
72+
}
73+
74+
class BinaryTree<K extends Comparable<K>, V> {
75+
final BinaryTreeNode<K, V> _root;
76+
77+
BinaryTree._internal(this._root);
78+
BinaryTree.empty() : this._internal(null);
79+
80+
BinaryTree<K, V> insert(K key, V value) {
81+
BinaryTreeNode<K, V> root =
82+
BinaryTreeNode.insertOpt<K, V>(_root, key, value);
83+
return new BinaryTree<K, V>._internal(root);
84+
}
85+
86+
BinaryTree<K, U> map<U>(U f(V x)) {
87+
BinaryTreeNode<K, U> root = BinaryTreeNode.mapOpt<K, V, U>(_root, f);
88+
return new BinaryTree<K, U>._internal(root);
89+
}
90+
91+
S foldPre<S>(S init, S f(V t, S s)) {
92+
return BinaryTreeNode.foldPreOpt<K, V, S>(_root, init, f);
93+
}
94+
}
95+
96+
main() {
97+
BinaryTree<num, String> sT = new BinaryTree<num, String>.empty();
98+
99+
sT = sT.insert(0, "");
100+
sT = sT.insert(1, " ");
101+
sT = sT.insert(2, " ");
102+
sT = sT.insert(3, " ");
103+
104+
BinaryTree<num, num> iT = sT.map<num>((String s) => s.length);
105+
106+
Expect.equals(iT.foldPre<num>(0, (int i, num s) => i + s), 6);
107+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
analyzer:
2+
language:
3+
enableGenericMethods: true
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// Dart test verifying that the parser can handle certain cases where
6+
// grammar ambiguity is resolved in favor of generic sends, not
7+
// relational expressions.
8+
9+
f(arg1, [arg2]) => null;
10+
g<X, Y>(arg) => null;
11+
12+
main() {
13+
// Generic invocations.
14+
f(g<int, String>(3));
15+
f(g<int, List<String>>(3));
16+
f(g<int, String>(3), 4);
17+
f(g<int, List<String>>(3), 4);
18+
19+
// Relational expressions.
20+
int a = 0, b = 1, c = 2, d = 3;
21+
f(a < b, c > 3);
22+
f(a < b, c >> 3);
23+
f(a < b, c < d >> 3);
24+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
analyzer:
2+
language:
3+
enableGenericMethods: true

tests/language/language.status

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ async_star_regression_2238_test: CompileTimeError, RuntimeError # drt only runti
4545
async_star_cancel_while_paused_test: RuntimeError
4646
async_star_await_pauses_test: Skip # Times out. Issue 23996
4747

48+
# Experimental feature: Syntactic support for generic methods.
49+
generic_methods_test: CompiletimeError # Issue 25869
50+
generic_functions_test: CompiletimeError # Issue 25869
51+
generic_sends_test: CompiletimeError # Issue 25869
52+
4853
[ ($compiler == none || $compiler == precompiler || $compiler == dart2app) && ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) ]
4954

5055
class_keyword_test/02: MissingCompileTimeError # Issue 13627

tests/language/language_analyzer2.status

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,3 +520,8 @@ accessor_conflict_import_test: StaticWarning # Issue 25624
520520

521521
for_in3_test: StaticWarning, OK # Test should have warning by design.
522522
for_in_side_effects_test: StaticWarning, OK # Test uses custom class that does not implement Iterable in for-in.
523+
524+
# Experimental feature: Syntactic support for generic methods.
525+
generic_functions_test: CompileTimeError # Issue 25868
526+
generic_methods_test: CompileTimeError # Issue 25868
527+
generic_sends_test: CompileTimeError # Issue 25868

tests/language/language_dart2js.status

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ accessor_conflict_import_prefixed2_test: RuntimeError # Issue 25626
3636
accessor_conflict_import_prefixed_test: RuntimeError # Issue 25626
3737
accessor_conflict_import_test: RuntimeError # Issue 25626
3838

39+
# Experimental feature: Syntactic support for generic methods.
40+
generic_functions_test: CompileTimeError # Issue 25835
41+
generic_methods_test: CompileTimeError # Issue 25835
42+
generic_sends_test: CompileTimeError # Issue 25835
43+
3944
[ $compiler == dart2js && $runtime == jsshell ]
4045
await_for_test: Skip # Jsshell does not provide periodic timers, Issue 7728
4146
async_star_test: RuntimeError # Jsshell does not provide non-zero timers, Issue 7728

0 commit comments

Comments
 (0)