Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: pkg/compiler/lib/src/inferrer/locals_handler.dart

Issue 2799763003: Fix for type analysis bug in constructor with early return (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library locals_handler; 5 library locals_handler;
6 6
7 import 'dart:collection' show IterableMixin; 7 import 'dart:collection' show IterableMixin;
8 8
9 import '../options.dart' show CompilerOptions; 9 import '../options.dart' show CompilerOptions;
10 import '../elements/elements.dart'; 10 import '../elements/elements.dart';
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 if (variables == null) return false; 95 if (variables == null) return false;
96 return variables.containsKey(variable); 96 return variables.containsKey(variable);
97 } 97 }
98 98
99 String toString() { 99 String toString() {
100 String rest = parent == null ? "null" : parent.toString(); 100 String rest = parent == null ? "null" : parent.toString();
101 return '$variables $rest'; 101 return '$variables $rest';
102 } 102 }
103 } 103 }
104 104
105 /// Tracks initializers via initializations and assignments.
105 class FieldInitializationScope { 106 class FieldInitializationScope {
106 final TypeSystem types; 107 final TypeSystem types;
107 Map<Element, TypeInformation> fields; 108 Map<Element, TypeInformation> fields;
108 bool isThisExposed; 109 bool isThisExposed;
109 110
110 FieldInitializationScope(this.types) : isThisExposed = false; 111 /// `true` when control flow prevents accumulating definite assignments,
112 /// e.g. an early return or caught exception.
113 bool isIndefinite;
114
115 FieldInitializationScope(this.types)
116 : isThisExposed = false,
117 isIndefinite = false;
111 118
112 FieldInitializationScope.internalFrom(FieldInitializationScope other) 119 FieldInitializationScope.internalFrom(FieldInitializationScope other)
113 : types = other.types, 120 : types = other.types,
114 isThisExposed = other.isThisExposed; 121 isThisExposed = other.isThisExposed,
122 isIndefinite = other.isIndefinite;
115 123
116 factory FieldInitializationScope.from(FieldInitializationScope other) { 124 factory FieldInitializationScope.from(FieldInitializationScope other) {
117 if (other == null) return null; 125 if (other == null) return null;
118 return new FieldInitializationScope.internalFrom(other); 126 return new FieldInitializationScope.internalFrom(other);
119 } 127 }
120 128
121 void updateField(Element field, TypeInformation type) { 129 void updateField(Element field, TypeInformation type) {
122 if (isThisExposed) return; 130 if (isThisExposed) return;
123 if (fields == null) fields = new Map<Element, TypeInformation>(); 131 if (isIndefinite) return;
132 fields ??= new Map<Element, TypeInformation>();
124 fields[field] = type; 133 fields[field] = type;
125 } 134 }
126 135
127 TypeInformation readField(Element field) { 136 TypeInformation readField(Element field) {
128 return fields == null ? null : fields[field]; 137 return fields == null ? null : fields[field];
129 } 138 }
130 139
131 void forEach(void f(Element element, TypeInformation type)) { 140 void forEach(void f(Element element, TypeInformation type)) {
132 if (fields == null) return; 141 fields?.forEach(f);
133 fields.forEach(f);
134 } 142 }
135 143
136 void mergeDiamondFlow( 144 void mergeDiamondFlow(
137 FieldInitializationScope thenScope, FieldInitializationScope elseScope) { 145 FieldInitializationScope thenScope, FieldInitializationScope elseScope) {
138 // Quick bailout check. If [isThisExposed] is true, we know the 146 // Quick bailout check. If [isThisExposed] or [isIndefinite] is true, we
139 // code following won'TypeInformation do anything. 147 // know the code following won'TypeInformation do anything.
140 if (isThisExposed) return; 148 if (isThisExposed) return;
141 if (elseScope == null || elseScope.fields == null) { 149 if (isIndefinite) return;
142 elseScope = this; 150
143 } 151 FieldInitializationScope otherScope =
152 (elseScope == null || elseScope.fields == null) ? this : elseScope;
144 153
145 thenScope.forEach((Element field, TypeInformation type) { 154 thenScope.forEach((Element field, TypeInformation type) {
146 TypeInformation otherType = elseScope.readField(field); 155 TypeInformation otherType = otherScope.readField(field);
147 if (otherType == null) return; 156 if (otherType == null) return;
148 updateField(field, types.allocateDiamondPhi(type, otherType)); 157 updateField(field, types.allocateDiamondPhi(type, otherType));
149 }); 158 });
159
150 isThisExposed = thenScope.isThisExposed || elseScope.isThisExposed; 160 isThisExposed = thenScope.isThisExposed || elseScope.isThisExposed;
161 isIndefinite = thenScope.isIndefinite || elseScope.isIndefinite;
151 } 162 }
152 } 163 }
153 164
154 /** 165 /**
155 * Placeholder for inferred arguments types on sends. 166 * Placeholder for inferred arguments types on sends.
156 */ 167 */
157 class ArgumentsTypes extends IterableMixin<TypeInformation> { 168 class ArgumentsTypes extends IterableMixin<TypeInformation> {
158 final List<TypeInformation> positional; 169 final List<TypeInformation> positional;
159 final Map<String, TypeInformation> named; 170 final Map<String, TypeInformation> named;
160 ArgumentsTypes(this.positional, named) 171 ArgumentsTypes(this.positional, named)
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 if (newType != type) { 543 if (newType != type) {
533 locals[variable] = newType; 544 locals[variable] = newType;
534 } 545 }
535 }); 546 });
536 } 547 }
537 548
538 void updateField(Element element, TypeInformation type) { 549 void updateField(Element element, TypeInformation type) {
539 fieldScope.updateField(element, type); 550 fieldScope.updateField(element, type);
540 } 551 }
541 } 552 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/inferrer/builder.dart ('k') | tests/compiler/dart2js/field_type_simple_inferer_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698