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

Side by Side Diff: lib/compiler/implementation/compiler.dart

Issue 10735051: Fix usage of UNKNOWN/CONFLICTING types for union. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Cosmetic change in comment. Created 8 years, 5 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 5
6 /** 6 /**
7 * If true, print a warning for each method that was resolved, but not 7 * If true, print a warning for each method that was resolved, but not
8 * compiled. 8 * compiled.
9 */ 9 */
10 final bool REPORT_EXCESS_RESOLUTION = false; 10 final bool REPORT_EXCESS_RESOLUTION = false;
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 fields[field] = propagatedType; 118 fields[field] = propagatedType;
119 } else { 119 } else {
120 fields[field] = fields[field].union(propagatedType); 120 fields[field] = fields[field].union(propagatedType);
121 } 121 }
122 } 122 }
123 123
124 HType typeFromInitializersSoFar(Element field) { 124 HType typeFromInitializersSoFar(Element field) {
125 assert(field.isField()); 125 assert(field.isField());
126 assert(field.enclosingElement.isClass()); 126 assert(field.enclosingElement.isClass());
127 if (!fieldInitializers.containsKey(field.enclosingElement)) { 127 if (!fieldInitializers.containsKey(field.enclosingElement)) {
128 return HType.UNKNOWN; 128 return HType.CONFLICTING;
129 } 129 }
130 Map<Element, HType> fields = fieldInitializers[field.enclosingElement]; 130 Map<Element, HType> fields = fieldInitializers[field.enclosingElement];
131 return fields[field]; 131 return fields[field];
132 } 132 }
133 133
134 void updateFieldConstructorSetters(Element field, HType type) { 134 void updateFieldConstructorSetters(Element field, HType type) {
135 assert(field.isField()); 135 assert(field.isField());
136 assert(field.enclosingElement.isClass()); 136 assert(field.enclosingElement.isClass());
137 Map<Element, HType> fields = 137 Map<Element, HType> fields =
138 fieldConstructorSetters.putIfAbsent( 138 fieldConstructorSetters.putIfAbsent(
139 field.enclosingElement, () => new Map<Element, HType>()); 139 field.enclosingElement, () => new Map<Element, HType>());
140 if (!fields.containsKey(field)) { 140 if (!fields.containsKey(field)) {
141 fields[field] = type; 141 fields[field] = type;
142 } else { 142 } else {
143 fields[field] = fields[field].union(type); 143 fields[field] = fields[field].union(type);
144 } 144 }
145 } 145 }
146 146
147 // Check if this field is set in the constructor body. 147 // Check if this field is set in the constructor body.
148 bool hasConstructorBodyFieldSetter(Element field) { 148 bool hasConstructorBodyFieldSetter(Element field) {
149 if (!fieldConstructorSetters.containsKey(field.enclosingElement)) { 149 if (!fieldConstructorSetters.containsKey(field.enclosingElement)) {
150 return false; 150 return false;
151 } 151 }
152 return fieldConstructorSetters[field.enclosingElement][field] != null; 152 return fieldConstructorSetters[field.enclosingElement][field] != null;
153 } 153 }
154 154
155 // Provide an optimistic estimate of the type of a field after construction. 155 // Provide an optimistic estimate of the type of a field after construction.
156 // If the constructor body has setters for fields returns HType.UNKNOWN.
156 // This only takes the initializer lists and field assignments in the 157 // This only takes the initializer lists and field assignments in the
157 // constructor body into account. The constructor body might have method calls 158 // constructor body into account. The constructor body might have method calls
158 // that could alter the field. 159 // that could alter the field.
159 HType optimisticFieldTypeAfterConstruction(Element field) { 160 HType optimisticFieldTypeAfterConstruction(Element field) {
160 assert(field.isField()); 161 assert(field.isField());
161 assert(field.enclosingElement.isClass()); 162 assert(field.enclosingElement.isClass());
162 163
163 if (hasConstructorBodyFieldSetter(field)) { 164 if (hasConstructorBodyFieldSetter(field)) {
164 // If there are field setters for this field in some constructor only one 165 // If there are field setters but there is only constructor then the type
165 // constructor then the type set will be the field type after 166 // of the field is determined by the assignments in the constructor
166 // construction. 167 // body.
167 if (field.enclosingElement.constructors.length == 1) { 168 ClassElement classElement = field.enclosingElement;
169 if (classElement.constructors.length == 1) {
168 return fieldConstructorSetters[field.enclosingElement][field]; 170 return fieldConstructorSetters[field.enclosingElement][field];
169 } else { 171 } else {
170 return HType.UNKNOWN; 172 return HType.UNKNOWN;
171 } 173 }
172 } else if (fieldInitializers.containsKey(field.enclosingElement)) { 174 } else if (fieldInitializers.containsKey(field.enclosingElement)) {
173 HType type = fieldInitializers[field.enclosingElement][field]; 175 HType type = fieldInitializers[field.enclosingElement][field];
174 return type == null ? HType.UNKNOWN : type; 176 return type == null ? HType.CONFLICTING : type;
175 } else { 177 } else {
176 return HType.UNKNOWN; 178 return HType.CONFLICTING;
177 } 179 }
178 } 180 }
179 181
180 void updateFieldSetters(Element field, HType type) { 182 void updateFieldSetters(Element field, HType type) {
181 assert(field.isField()); 183 assert(field.isField());
182 assert(field.enclosingElement.isClass()); 184 assert(field.enclosingElement.isClass());
183 Map<Element, HType> fields = 185 Map<Element, HType> fields =
184 fieldSettersType.putIfAbsent( 186 fieldSettersType.putIfAbsent(
185 field.enclosingElement, () => new Map<Element, HType>()); 187 field.enclosingElement, () => new Map<Element, HType>());
186 if (!fields.containsKey(field)) { 188 if (!fields.containsKey(field)) {
187 fields[field] = type; 189 fields[field] = type;
188 } else { 190 } else {
189 fields[field] = fields[field].union(type); 191 fields[field] = fields[field].union(type);
190 } 192 }
191 } 193 }
192 194
193 // Returns the type that field setters are setting the field to based on what 195 // Returns the type that field setters are setting the field to based on what
194 // have been seen during compilation so far. 196 // have been seen during compilation so far.
195 HType fieldSettersTypeSoFar(Element field) { 197 HType fieldSettersTypeSoFar(Element field) {
196 assert(field.isField()); 198 assert(field.isField());
197 assert(field.enclosingElement.isClass()); 199 assert(field.enclosingElement.isClass());
198 if (!fieldSettersType.containsKey(field.enclosingElement)) { 200 if (!fieldSettersType.containsKey(field.enclosingElement)) {
199 return HType.UNKNOWN; 201 return HType.CONFLICTING;
200 } 202 }
201 Map<Element, HType> fields = fieldSettersType[field.enclosingElement]; 203 Map<Element, HType> fields = fieldSettersType[field.enclosingElement];
202 if (!fields.containsKey(field)) return HType.UNKNOWN; 204 if (!fields.containsKey(field)) return HType.CONFLICTING;
203 return fields[field]; 205 return fields[field];
204 } 206 }
205 } 207 }
206 208
207 class Compiler implements DiagnosticListener { 209 class Compiler implements DiagnosticListener {
208 final Map<String, LibraryElement> libraries; 210 final Map<String, LibraryElement> libraries;
209 int nextFreeClassId = 0; 211 int nextFreeClassId = 0;
210 World world; 212 World world;
211 String assembledCode; 213 String assembledCode;
212 Namer namer; 214 Namer namer;
(...skipping 830 matching lines...) Expand 10 before | Expand all | Expand 10 after
1043 f(int beginOffset, int endOffset)) { 1045 f(int beginOffset, int endOffset)) {
1044 final beginOffset = begin.charOffset; 1046 final beginOffset = begin.charOffset;
1045 final endOffset = end.charOffset + end.slowCharCount; 1047 final endOffset = end.charOffset + end.slowCharCount;
1046 1048
1047 // [begin] and [end] might be the same for the same empty token. This 1049 // [begin] and [end] might be the same for the same empty token. This
1048 // happens for instance when scanning '$$'. 1050 // happens for instance when scanning '$$'.
1049 assert(endOffset >= beginOffset); 1051 assert(endOffset >= beginOffset);
1050 return f(beginOffset, endOffset); 1052 return f(beginOffset, endOffset);
1051 } 1053 }
1052 } 1054 }
OLDNEW
« no previous file with comments | « no previous file | lib/compiler/implementation/ssa/nodes.dart » ('j') | lib/compiler/implementation/ssa/optimize.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698