Skip to content

Commit ec60f35

Browse files
authored
Create test-plan/overview for constructor tear-off (#1678)
* Create test-plan/overview for constructor tear-off
1 parent 532f1d9 commit ec60f35

File tree

1 file changed

+174
-0
lines changed

1 file changed

+174
-0
lines changed
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
# Dart Constructor Tear-Offs Test Plan
2+
3+
The Dart constructor tear-off feature contains multiple independent language changes. Each should be tested, as should their combination with each other and with other relevant language features.
4+
5+
The features can be summarized as:
6+
7+
* Named constructor tear-offs
8+
* Expressions of the for <code>*C*.*name*</code>. or <code>*C*\<*typeArgs*>.*name*</code>, with type arguments potentially being inferred, evaluate to functions.
9+
* Preserves identity as specified.
10+
* Unnamed constructor syntax alternative
11+
* Everywhere you can currently reference or declare an unnamed constructor, you can also refer to it or declare it as <code>*C*.new</code>.
12+
* The unnamed and `new`-named constructors are two ways to refer to the *same* thing. (Can't declare both).
13+
* Unnamed constructor tear-offs
14+
* Expressions of the for <code>*C*.new</code>. or <code>*C*\<*typeArgs*>.new</code>, with type arguments potentially being inferred, evaluate to functions.
15+
* Preserves identity as specified.
16+
* Explicit instantiated function tear-off
17+
* Expressions of the form <code>*f*\<*typeArgs*></code>, not followed by an argument list and where *f* denotes a generic function declaration or generic instance method, now does instantiated tear-off.
18+
* Explicit type literal instantiation
19+
* Expressions of the form <code>*T*\<*typeArgs*></code>, not followed by an argument list and where *T* denotes a type declaration (class, mixin or type alias), now evaluates to a `Type` object for the instantiated type.
20+
21+
Each feature should be tested, both for correct and incorrect usage. Further, we should check that any new syntax is not allowed in places where it isn't defined.
22+
23+
## Named constructor tear-off
24+
25+
### Correct usage
26+
27+
The possible constructors tear-offs
28+
29+
* Check that constructors of non-generic classes can be torn off (`C.foo`).
30+
* Check that constructors of instantiated generic classes can be torn off (`G<int>.foo`).
31+
* Check that constructors of uninstantiated generic classes can be torn off, and that type inference infers the correct type arguments.
32+
* Instantiate to bounds if not context type, or not relevant context type (`var x = G.foo`).
33+
* Based on context type if relevant (`G<int> Function() f = G.foo1`).
34+
* Check that the inferred cannot be super-bounded or malbounded.
35+
* Check that the resulting function has the correct static type and runtime type.
36+
37+
The possible constructor types (all combinations except "const factory non-redirecting" exist):
38+
39+
* Constant or not
40+
* Factory or not
41+
* Redirecting or not
42+
43+
The possible sources of tear-offs:
44+
45+
* From a class declaring the constructor.
46+
* From a mixin-application which introduces a forwarding constructor.
47+
* Any of those through an alias which is:
48+
* Not generic.
49+
* A proper rename (static type may not match runtime type, static type is based on alias type argument bounds, runtime type is based on class type argument bounds).
50+
* Not a proper rename
51+
* Not same number of type arguments (fewer or more)
52+
* Not same order of type arguments
53+
54+
#### Covered by tests
55+
56+
* [tear_off_test][]
57+
* [aliased_constructor_tear_off_test][]
58+
59+
### Incorrect usage
60+
61+
* Attempting to tear-off non-constructors using new instantiated <Code>*C*\<*typeArgs*>.*name*</code> syntax.
62+
* (If <code>*name*</code> doesn't refer to a constructor, must then treat <code>*C*\<*typeArgs*></code> as type literal, and therefore only allow members of `Type`, which are also members of `Object` and therefore never valid as constructor names).
63+
* Incorrect number or type of explicit type arguments.
64+
* Unsatisfiable type parameters for inferred type arguments.
65+
66+
#### Covered by tests
67+
68+
* [tear_off_error_test][]
69+
70+
## Unnamed constructor alternative syntax
71+
72+
### Correct usage
73+
74+
* The `.new` name can be used anywhere the plain constructor name can.
75+
* Declarations
76+
* Invocations
77+
* Generative constructor super-constructor invocation in initializer list
78+
* Redirecting generative constructor target
79+
* Redirecting factory constructor target
80+
* (Dartdoc?)
81+
* The two naming conventions can be used interchangeably, both refer to the same constructor
82+
83+
#### Covered by tests
84+
85+
* [unnamed_new_test][]
86+
87+
## Incorrect usage
88+
89+
* Can't use `.new` or `new` to declare non-constructors, nor to call methods.
90+
* The `new` name is not in *scope* (like constructor names generally aren't).
91+
92+
#### Covered by tests
93+
94+
* [unnamed_new_error_test][]
95+
96+
## Unnamed/`new`-named constructor tearoffs
97+
98+
* Same tests as for named constructor tearoffs.
99+
100+
#### Covered by tests
101+
102+
* [tear_off_test][]
103+
* [aliased_constructor_tear_off_test][]
104+
* [tear_off_error_test][]
105+
106+
## Explicit instantiated function tear-off
107+
108+
### Correct usage
109+
110+
* Works for any static, top-level, local function declaration.
111+
* Also static functions accessed through a type alias.
112+
* Through import prefix.
113+
* Works for instance methods other than `call` methods of `Function`-typed objects.
114+
* Result has expected static and runtime type.
115+
116+
#### Covered by tests
117+
118+
* [explicit_instantiated_tearoff_test][]
119+
120+
### Incorrect usage
121+
122+
* Does not work for function values.
123+
* Including torn off methods and constructors.
124+
* Includes function-typed getters.
125+
* Does not work for `call` methods of function values.
126+
* Does not work for *constructors* (`class C<T> { C.name();}` does not allow `C.name<int>`).
127+
* Non-constant instantiation in constant context.
128+
* Type bounds must not be violated.
129+
130+
#### Covered by tests
131+
132+
* ?
133+
134+
## Explicit instantiated type literal
135+
136+
### Correct usage
137+
138+
* Can instantiate any generic type (class, mixin, type alias).
139+
* Allows super-bounded types.
140+
* Result is `Type` object.
141+
* `Type` objects for same generic type are equal if created using equal type arguments.
142+
* Identical if passed equal and constant type arguments.
143+
* Through type aliases, equal/identical if expansion is equal.
144+
145+
#### Covered by tests
146+
147+
* [explicit_instantiated_type_literal_test][]
148+
* [aliased_type_literal_instantiation_test][]
149+
150+
### Incorrect usage
151+
152+
* Non-constant instantiation in constant context.
153+
* Even if type parameter of type alias is not used in result.
154+
155+
* Cannot call static members on instantiated type literals. (That's a constructor reference, if anything).
156+
* <code>*C*\<*typeArgs*>.anything</code> does not create a type literal.
157+
* <code>*C*\<*typeArgs*>..anything</code> *probably does* (<code>*C*..toString()</code> works today, invokes `toString` of `Type` object).
158+
* <code>*C*\<*typeArgs*>?.anything</code> also works (possibly with a warning about the `?` being unnecessary).
159+
* Does not allow malbounded types.
160+
161+
#### Covered by tests
162+
163+
* [explicit_instantiated_type_literal_error_test][]
164+
165+
166+
167+
[tear_off_test]: http://github.com/dart-lang/sdk/blob/master/tests/language/constructor/tear_off_test.dart
168+
[unnamed_new_error_test]: http://github.com/dart-lang/sdk/blob/master/tests/language/constructor/unnamed_new_error_test.dart
169+
[unnamed_new_test]: (http://github.com/dart-lang/sdk/blob/master/tests/language/constructor/unnamed_new_test.dart
170+
[explicit_instantiated_tearoff_test]: http://github.com/dart-lang/sdk/blob/master/tests/language/generic_methods/explicit_instantiated_tearoff_test.dart
171+
[explicit_instantiated_type_literal_error_test]: http://github.com/dart-lang/sdk/blob/master/tests/language/type_object/explicit_instantiated_type_literal_error_test.dart
172+
[explicit_instantiated_type_literal_test]: http://github.com/dart-lang/sdk/blob/master/tests/language/type_object/explicit_instantiated_type_literal_test.dart
173+
[aliased_constructor_tear_off_test]: http://github.com/dart-lang/sdk/blob/master/tests/language/typedef/aliased_constructor_tear_off_test.dart
174+
[aliased_type_literal_instantiation_test]: http://github.com/dart-lang/sdk/blob/master/tests/language/typedef/aliased_type_literal_instantiation_test.dart

0 commit comments

Comments
 (0)