Version 1.19.0-dev.7.1
Cherry-pick d4d5a48c109a4908bed944b8251f049255dfe4ac into dev
diff --git a/pkg/compiler/lib/src/typechecker.dart b/pkg/compiler/lib/src/typechecker.dart
index 17f9c68..01cff2d 100644
--- a/pkg/compiler/lib/src/typechecker.dart
+++ b/pkg/compiler/lib/src/typechecker.dart
@@ -64,8 +64,12 @@
compiler, resolvedAst.elements, compiler.types);
if (element.isField) {
visitor.analyzingInitializer = true;
+ DartType type =
+ visitor.analyzeVariableTypeAnnotation(resolvedAst.node);
+ visitor.analyzeVariableInitializer(element, type, resolvedAst.body);
+ } else {
+ resolvedAst.node.accept(visitor);
}
- resolvedAst.node.accept(visitor);
});
});
}
@@ -1641,6 +1645,8 @@
checkPrivateAccess(node, element, element.name);
DartType newType = elements.getType(node);
+ assert(invariant(node, newType != null,
+ message: "No new type registered in $elements."));
DartType constructorType = computeConstructorType(element, newType);
analyzeArguments(node.send, element, constructorType);
return newType;
@@ -1758,12 +1764,25 @@
return elements.getType(node);
}
- DartType visitVariableDefinitions(VariableDefinitions node) {
+ DartType analyzeVariableTypeAnnotation(VariableDefinitions node) {
DartType type = analyzeWithDefault(node.type, const DynamicType());
if (type.isVoid) {
reportTypeWarning(node.type, MessageKind.VOID_VARIABLE);
type = const DynamicType();
}
+ return type;
+ }
+
+ void analyzeVariableInitializer(
+ Spannable spannable, DartType declaredType, Node initializer) {
+ if (initializer == null) return;
+
+ DartType expressionType = analyzeNonVoid(initializer);
+ checkAssignable(spannable, expressionType, declaredType);
+ }
+
+ DartType visitVariableDefinitions(VariableDefinitions node) {
+ DartType type = analyzeVariableTypeAnnotation(node);
for (Link<Node> link = node.definitions.nodes;
!link.isEmpty;
link = link.tail) {
@@ -1772,8 +1791,10 @@
message: 'expected identifier or initialization');
if (definition is SendSet) {
SendSet initialization = definition;
- DartType initializer = analyzeNonVoid(initialization.arguments.head);
- checkAssignable(initialization.assignmentOperator, initializer, type);
+ analyzeVariableInitializer(
+ initialization.assignmentOperator,
+ type,
+ initialization.arguments.head);
// TODO(sigmund): explore inferring a type for `var` using the RHS (like
// DDC does), for example:
// if (node.type == null && node.modifiers.isVar &&
diff --git a/tests/language/typecheck_multifield_declaration_test.dart b/tests/language/typecheck_multifield_declaration_test.dart
new file mode 100644
index 0000000..bbd0cba
--- /dev/null
+++ b/tests/language/typecheck_multifield_declaration_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2016, 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.
+
+/// Checks that we can correctly typecheck multi-variable declarations on fields
+/// and top-levels. This is also a regression test for Issue 27401.
+
+class A {}
+
+A a = new A(), b = new A();
+
+class B {
+ A a = new A(), b = new A();
+}
+
+main() => [a, b, new B().a, new B().b];
\ No newline at end of file
diff --git a/tools/VERSION b/tools/VERSION
index 1a31718..c7cc232 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
MINOR 19
PATCH 0
PRERELEASE 7
-PRERELEASE_PATCH 0
+PRERELEASE_PATCH 1