Skip to content

Commit 47f1415

Browse files
johnniwintherwhesse
authored andcommitted
Type check field initializers in the correct context.
Closes #27104 [email protected] Review URL: https://codereview.chromium.org/2250433007 .
1 parent e872a1b commit 47f1415

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

pkg/compiler/lib/src/typechecker.dart

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,12 @@ class TypeCheckerTask extends CompilerTask {
6464
compiler, resolvedAst.elements, compiler.types);
6565
if (element.isField) {
6666
visitor.analyzingInitializer = true;
67+
DartType type =
68+
visitor.analyzeVariableTypeAnnotation(resolvedAst.node);
69+
visitor.analyzeVariableInitializer(element, type, resolvedAst.body);
70+
} else {
71+
resolvedAst.node.accept(visitor);
6772
}
68-
resolvedAst.node.accept(visitor);
6973
});
7074
});
7175
}
@@ -1641,6 +1645,8 @@ class TypeCheckerVisitor extends Visitor<DartType> {
16411645
checkPrivateAccess(node, element, element.name);
16421646

16431647
DartType newType = elements.getType(node);
1648+
assert(invariant(node, newType != null,
1649+
message: "No new type registered in $elements."));
16441650
DartType constructorType = computeConstructorType(element, newType);
16451651
analyzeArguments(node.send, element, constructorType);
16461652
return newType;
@@ -1758,12 +1764,25 @@ class TypeCheckerVisitor extends Visitor<DartType> {
17581764
return elements.getType(node);
17591765
}
17601766

1761-
DartType visitVariableDefinitions(VariableDefinitions node) {
1767+
DartType analyzeVariableTypeAnnotation(VariableDefinitions node) {
17621768
DartType type = analyzeWithDefault(node.type, const DynamicType());
17631769
if (type.isVoid) {
17641770
reportTypeWarning(node.type, MessageKind.VOID_VARIABLE);
17651771
type = const DynamicType();
17661772
}
1773+
return type;
1774+
}
1775+
1776+
void analyzeVariableInitializer(
1777+
Spannable spannable, DartType declaredType, Node initializer) {
1778+
if (initializer == null) return;
1779+
1780+
DartType expressionType = analyzeNonVoid(initializer);
1781+
checkAssignable(spannable, expressionType, declaredType);
1782+
}
1783+
1784+
DartType visitVariableDefinitions(VariableDefinitions node) {
1785+
DartType type = analyzeVariableTypeAnnotation(node);
17671786
for (Link<Node> link = node.definitions.nodes;
17681787
!link.isEmpty;
17691788
link = link.tail) {
@@ -1772,8 +1791,10 @@ class TypeCheckerVisitor extends Visitor<DartType> {
17721791
message: 'expected identifier or initialization');
17731792
if (definition is SendSet) {
17741793
SendSet initialization = definition;
1775-
DartType initializer = analyzeNonVoid(initialization.arguments.head);
1776-
checkAssignable(initialization.assignmentOperator, initializer, type);
1794+
analyzeVariableInitializer(
1795+
initialization.assignmentOperator,
1796+
type,
1797+
initialization.arguments.head);
17771798
// TODO(sigmund): explore inferring a type for `var` using the RHS (like
17781799
// DDC does), for example:
17791800
// if (node.type == null && node.modifiers.isVar &&
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
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+
/// Checks that we can correctly typecheck multi-variable declarations on fields
6+
/// and top-levels. This is also a regression test for Issue 27401.
7+
8+
class A {}
9+
10+
A a = new A(), b = new A();
11+
12+
class B {
13+
A a = new A(), b = new A();
14+
}
15+
16+
main() => [a, b, new B().a, new B().b];

0 commit comments

Comments
 (0)