Skip to content

Commit c3dfe51

Browse files
committed
Adds status entries for initializing_formal tests.
This CL should fix the problem that arose with commit 543a51f. Here's the description from that CL: This CL adds tests for previously uncovered elements of the semantics and includes fixes such that the desired behavior is obtained. In particular, an `isInitializingFormal` element may now occur in contexts where it wasn't expected until now, and changes were made to handle it. It is also checked that a capture of an initializing formal (in a function literal) captures the parameter, not the field. [email protected] Review URL: https://codereview.chromium.org/2042293002 .
1 parent 0f061f1 commit c3dfe51

11 files changed

+129
-6
lines changed

pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3859,7 +3859,7 @@ class TryBoxedVariables extends ast.Visitor {
38593859
if (Elements.isLocal(element)) {
38603860
LocalElement local = element;
38613861
if (insideInitializer &&
3862-
local.isParameter &&
3862+
(local.isParameter || local.isInitializingFormal) &&
38633863
local.enclosingElement == currentFunction) {
38643864
assert(local.enclosingElement.isConstructor);
38653865
// Initializers in an initializer-list can communicate via parameters.
@@ -3871,7 +3871,9 @@ class TryBoxedVariables extends ast.Visitor {
38713871
// outlive the activation of the function).
38723872
markAsCaptured(local);
38733873
} else if (inTryStatement) {
3874-
assert(local.isParameter || local.isVariable);
3874+
assert(local.isParameter ||
3875+
local.isVariable ||
3876+
local.isInitializingFormal);
38753877
// Search for the position of the try block containing the variable
38763878
// declaration, or -1 if it is declared outside the outermost try.
38773879
int i = tryNestingStack.length - 1;

pkg/compiler/lib/src/resolution/members.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2573,6 +2573,11 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
25732573
} else {
25742574
semantics = new StaticAccess.parameter(element);
25752575
}
2576+
} else if (element.isInitializingFormal &&
2577+
compiler.options.enableInitializingFormalAccess) {
2578+
error = reportAndCreateErroneousElement(node.selector, name.text,
2579+
MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name});
2580+
semantics = new StaticAccess.finalParameter(element);
25762581
} else if (element.isVariable) {
25772582
if (element.isFinal || element.isConst) {
25782583
error = reportAndCreateErroneousElement(node.selector, name.text,

pkg/compiler/lib/src/typechecker.dart

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,12 @@ class TypeCheckerVisitor extends Visitor<DartType> {
681681
assert(invariant(node, element != null,
682682
message: 'Missing element for identifier'));
683683
assert(invariant(
684-
node, element.isVariable || element.isParameter || element.isField,
684+
node,
685+
element.isVariable ||
686+
element.isParameter ||
687+
element.isField ||
688+
(element.isInitializingFormal &&
689+
compiler.options.enableInitializingFormalAccess),
685690
message: 'Unexpected context element ${element}'));
686691
return element.computeType(resolution);
687692
}
@@ -766,7 +771,9 @@ class TypeCheckerVisitor extends Visitor<DartType> {
766771
return access;
767772
}
768773
if (receiverElement != null &&
769-
(receiverElement.isVariable || receiverElement.isParameter)) {
774+
(receiverElement.isVariable || receiverElement.isParameter ||
775+
(receiverElement.isInitializingFormal &&
776+
compiler.options.enableInitializingFormalAccess))) {
770777
Link<TypePromotion> typePromotions = typePromotionsMap[receiverElement];
771778
if (typePromotions != null) {
772779
while (!typePromotions.isEmpty) {
@@ -1082,7 +1089,9 @@ class TypeCheckerVisitor extends Visitor<DartType> {
10821089
}
10831090

10841091
ElementAccess createPromotedAccess(Element element) {
1085-
if (element.isVariable || element.isParameter) {
1092+
if (element.isVariable || element.isParameter ||
1093+
(element.isInitializingFormal &&
1094+
compiler.options.enableInitializingFormalAccess)) {
10861095
TypePromotion typePromotion = getKnownTypePromotion(element);
10871096
if (typePromotion != null) {
10881097
return new PromotedAccess(element, typePromotion.type);
@@ -1217,7 +1226,11 @@ class TypeCheckerVisitor extends Visitor<DartType> {
12171226
}
12181227
}
12191228

1220-
if (variable != null && (variable.isVariable || variable.isParameter)) {
1229+
if (variable != null &&
1230+
(variable.isVariable ||
1231+
variable.isParameter ||
1232+
(variable.isInitializingFormal &&
1233+
compiler.options.enableInitializingFormalAccess))) {
12211234
DartType knownType = getKnownType(variable);
12221235
if (!knownType.isDynamic) {
12231236
DartType shownType = elements.getType(node.arguments.head);

pkg/dart_messages/lib/shared_messages.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,8 @@ final Map<String, Message> MESSAGES = {
682682
template: "The setter '#{memberName}' is not defined for the "
683683
"class '#{className}'.",
684684
usedBy: [dart2js, analyzer],
685+
// TODO(eernst): When this.x access is available, add examples here,
686+
// e.g., "class A { var x; A(this.x) : x = 3; } main() => new A(2);"
685687
examples: const ["class A {} main() { new A().x = 499; }",]),
686688

687689
'NO_SUCH_SUPER_MEMBER': new Message(
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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+
// DartOptions=--initializing-formal-access
6+
7+
import "package:expect/expect.dart";
8+
9+
class A {
10+
var x, y;
11+
A(this.x) : y = (() => x);
12+
}
13+
14+
main() {
15+
A a = new A(2);
16+
a.x = 3;
17+
Expect.equals(a.x, 3);
18+
Expect.equals(a.y(), 2);
19+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
// DartOptions=--initializing-formal-access
6+
7+
import "package:expect/expect.dart";
8+
9+
class A {
10+
var x, y;
11+
// This should cause a warning because `x` is final when
12+
// accessed as an initializing formal.
13+
A(this.x) : y = (() { x = 3; });
14+
}
15+
16+
main() {
17+
A a = new A(2);
18+
Expect.equals(a.x, 2);
19+
Expect.throws(() => a.y(), (e) => e is NoSuchMethodError);
20+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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+
// DartOptions=--initializing-formal-access
6+
7+
import "package:expect/expect.dart";
8+
9+
class B {}
10+
11+
class A {
12+
B x, y;
13+
A(this.x) {
14+
// Promote to subtype.
15+
if (x is C) y = x.x;
16+
// Promotion fails, not a subtype.
17+
if (x is A) y = x;
18+
}
19+
}
20+
21+
class C extends A implements B {
22+
C(B x) : super(x);
23+
}
24+
25+
main() {
26+
C c2 = new C(null);
27+
C cc = new C(c2);
28+
Expect.equals(c2.y, null);
29+
Expect.equals(cc.y, c2);
30+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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+
// DartOptions=--initializing-formal-access
6+
7+
import "package:expect/expect.dart";
8+
9+
class A {
10+
int x;
11+
String y;
12+
A(this.x) : y = x { y = x; }
13+
}
14+
15+
main() {
16+
A a = new A(null);
17+
Expect.equals(a.x, null);
18+
Expect.equals(a.y, null);
19+
}

tests/language/language.status

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ generic_methods_type_expression_test: CompiletimeError # Issue 25869
5555

5656
# Experimental feature: Use initializing formals in initializers and constructor body.
5757
initializing_formal_access_test: CompiletimeError # TODO(eernst): Create a suitable sdk issue.
58+
initializing_formal_capture_test: CompiletimeError # TODO(eernst): Create a suitable sdk issue.
59+
initializing_formal_final_test: CompiletimeError # TODO(eernst): Create a suitable sdk issue.
60+
initializing_formal_type_test: CompiletimeError # TODO(eernst): Create a suitable sdk issue.
5861

5962
[ ($compiler == none || $compiler == precompiler || $compiler == dart2app || $compiler == dart2appjit) && ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_app) ]
6063

@@ -107,6 +110,9 @@ generic_methods_type_expression_test: RuntimeError # Issue 25869
107110

108111
# Experimental feature: Use initializing formals in initializers and constructor body.
109112
initializing_formal_access_test: RuntimeError # TODO(eernst): create a suitable sdk issue.
113+
initializing_formal_capture_test: RuntimeError # TODO(eernst): create a suitable sdk issue.
114+
initializing_formal_final_test: RuntimeError # TODO(eernst): create a suitable sdk issue.
115+
initializing_formal_type_test: RuntimeError # TODO(eernst): create a suitable sdk issue.
110116

111117
config_import_test: Skip # Issue 26250
112118

tests/language/language_analyzer2.status

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,3 +512,7 @@ generic_methods_type_expression_test: CompiletimeError # Issue 25868
512512

513513
# Experimental feature: Use initializing formals in initializers and constructor body.
514514
initializing_formal_access_test: CompiletimeError # TODO(eernst): Create a suitable sdk issue.
515+
initializing_formal_capture_test: CompiletimeError # TODO(eernst): Create a suitable sdk issue.
516+
initializing_formal_final_test: CompiletimeError # TODO(eernst): Create a suitable sdk issue.
517+
initializing_formal_promotion_test: StaticWarning # TODO(eernst): Create a suitable sdk issue.
518+
initializing_formal_type_test: CompiletimeError # TODO(eernst): Create a suitable sdk issue.

tests/language/language_dart2js.status

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ generic_methods_type_expression_test: CompiletimeError # DartOptions not passed
5656

5757
# Experimental feature: Use initializing formals in initializers and constructor body.
5858
initializing_formal_access_test: CompiletimeError # DartOptions not passed to compiler.
59+
initializing_formal_capture_test: CompiletimeError # DartOptions not passed to compiler.
60+
initializing_formal_final_test: CompiletimeError # DartOptions not passed to compiler.
61+
initializing_formal_type_test: CompiletimeError # DartOptions not passed to compiler.
5962

6063
[ $compiler == dart2js ]
6164
invocation_mirror_empty_arguments_test: Fail # Issue 24331

0 commit comments

Comments
 (0)