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

Side by Side Diff: lib/compiler/implementation/ssa/types.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 abstract class HType { 5 abstract class HType {
6 const HType(); 6 const HType();
7 7
8 /** 8 /**
9 * Returns an [HType] that represents [type] and all types that have 9 * Returns an [HType] that represents [type] and all types that have
10 * [type] as supertype. 10 * [type] as supertype.
(...skipping 23 matching lines...) Expand all
34 return new HBoundedPotentialPrimitiveArray(type, canBeNull); 34 return new HBoundedPotentialPrimitiveArray(type, canBeNull);
35 } else if (Elements.isStringSupertype(element, compiler)) { 35 } else if (Elements.isStringSupertype(element, compiler)) {
36 return new HBoundedPotentialPrimitiveString(type, canBeNull); 36 return new HBoundedPotentialPrimitiveString(type, canBeNull);
37 } else { 37 } else {
38 return canBeNull ? new HBoundedType.withNull(type) 38 return canBeNull ? new HBoundedType.withNull(type)
39 : new HBoundedType.nonNull(type); 39 : new HBoundedType.nonNull(type);
40 } 40 }
41 } 41 }
42 42
43 static final HType CONFLICTING = const HConflictingType(); 43 static final HType CONFLICTING = const HConflictingType();
44 static final HType UNKNOWN = const HAnalysisType("unknown"); 44 static final HType UNKNOWN = const HUnknownType();
45 static final HType BOOLEAN = const HBooleanType(); 45 static final HType BOOLEAN = const HBooleanType();
46 static final HType NUMBER = const HNumberType(); 46 static final HType NUMBER = const HNumberType();
47 static final HType INTEGER = const HIntegerType(); 47 static final HType INTEGER = const HIntegerType();
48 static final HType DOUBLE = const HDoubleType(); 48 static final HType DOUBLE = const HDoubleType();
49 static final HType INDEXABLE_PRIMITIVE = const HIndexablePrimitiveType(); 49 static final HType INDEXABLE_PRIMITIVE = const HIndexablePrimitiveType();
50 static final HType STRING = const HStringType(); 50 static final HType STRING = const HStringType();
51 static final HType READABLE_ARRAY = const HReadableArrayType(); 51 static final HType READABLE_ARRAY = const HReadableArrayType();
52 static final HType MUTABLE_ARRAY = const HMutableArrayType(); 52 static final HType MUTABLE_ARRAY = const HMutableArrayType();
53 static final HType EXTENDABLE_ARRAY = const HExtendableArrayType(); 53 static final HType EXTENDABLE_ARRAY = const HExtendableArrayType();
54 static final HType NULL = const HNullType(); 54 static final HType NULL = const HNullType();
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 */ 104 */
105 abstract HType intersection(HType other); 105 abstract HType intersection(HType other);
106 106
107 /** 107 /**
108 * The union of two types is the union of its values. For example: 108 * The union of two types is the union of its values. For example:
109 * * INTEGER.union(NUMBER) => NUMBER. 109 * * INTEGER.union(NUMBER) => NUMBER.
110 * * DOUBLE.union(INTEGER) => NUMBER. 110 * * DOUBLE.union(INTEGER) => NUMBER.
111 * * MUTABLE_ARRAY.union(READABLE_ARRAY) => READABLE_ARRAY. 111 * * MUTABLE_ARRAY.union(READABLE_ARRAY) => READABLE_ARRAY.
112 * 112 *
113 * When there is no predefined type to represent the union returns 113 * When there is no predefined type to represent the union returns
114 * [CONFLICTING]. 114 * [UNKNOWN].
115 * 115 *
116 * A union with [UNKNOWN] returns the non-UNKNOWN type. A union with 116 * A union with [UNKNOWN] returns [UNKNOWN].
117 * [CONFLICTING] returns [CONFLICTING]. 117 * A union of [CONFLICTING] with any other types returns the other type.
sra1 2012/07/11 20:04:34 I find CONFLICTING to be a confusing name. The ele
118 */ 118 */
119 abstract HType union(HType other); 119 abstract HType union(HType other);
120 } 120 }
121 121
122 /** Used to represent [HType.UNKNOWN] and [HType.CONFLICTING]. */ 122 /** Used to represent [HType.UNKNOWN] and [HType.CONFLICTING]. */
123 class HAnalysisType extends HType { 123 abstract class HAnalysisType extends HType {
124 final String name; 124 final String name;
125 const HAnalysisType(this.name); 125 const HAnalysisType(this.name);
126 String toString() => name; 126 String toString() => name;
127
128 Type computeType(Compiler compiler) => null;
129 }
130
131 class HUnknownType extends HAnalysisType {
132 const HUnknownType() : super("unknown");
127 bool canBePrimitive() => true; 133 bool canBePrimitive() => true;
128 bool canBeNull() => true; 134 bool canBeNull() => true;
129 135
130 Type computeType(Compiler compiler) => null; 136 HType union(HType other) => this;
131 137 HType intersection(HType other) => other;
132 HType combine(HType other) {
133 if (isUnknown()) return other;
134 if (other.isUnknown()) return this;
135 return HType.CONFLICTING;
136 }
137
138 HType union(HType other) => combine(other);
139 HType intersection(HType other) => combine(other);
140 } 138 }
141 139
142 class HConflictingType extends HAnalysisType { 140 class HConflictingType extends HAnalysisType {
143 const HConflictingType() : super("conflicting"); 141 const HConflictingType() : super("conflicting");
144 bool canBePrimitive() => false; 142 bool canBePrimitive() => false;
145 bool canBeNull() => false; 143 bool canBeNull() => false;
144
145 HType union(HType other) => other;
146 HType intersection(HType other) => this;
146 } 147 }
147 148
148 abstract class HPrimitiveType extends HType { 149 abstract class HPrimitiveType extends HType {
149 const HPrimitiveType(); 150 const HPrimitiveType();
150 bool isPrimitive() => true; 151 bool isPrimitive() => true;
151 bool canBePrimitive() => true; 152 bool canBePrimitive() => true;
152 } 153 }
153 154
154 class HNullType extends HPrimitiveType { 155 class HNullType extends HPrimitiveType {
155 const HNullType(); 156 const HNullType();
156 bool canBeNull() => true; 157 bool canBeNull() => true;
157 bool isNull() => true; 158 bool isNull() => true;
158 String toString() => 'null'; 159 String toString() => 'null';
159 160
160 Type computeType(Compiler compiler) => null; 161 Type computeType(Compiler compiler) => null;
161 162
162 HType union(HType other) { 163 HType union(HType other) {
163 if (other.isUnknown()) return HType.NULL; 164 if (other.isConflicting()) return HType.NULL;
165 if (other.isUnknown()) return HType.UNKNOWN;
sra1 2012/07/11 20:04:34 Every union method needs to accomplish the bounded
164 if (other.isString()) return HType.STRING_OR_NULL; 166 if (other.isString()) return HType.STRING_OR_NULL;
165 if (other.isInteger()) return HType.INTEGER_OR_NULL; 167 if (other.isInteger()) return HType.INTEGER_OR_NULL;
166 if (other.isDouble()) return HType.DOUBLE_OR_NULL; 168 if (other.isDouble()) return HType.DOUBLE_OR_NULL;
167 if (other.isNumber()) return HType.NUMBER_OR_NULL; 169 if (other.isNumber()) return HType.NUMBER_OR_NULL;
168 if (other.isBoolean()) return HType.BOOLEAN_OR_NULL; 170 if (other.isBoolean()) return HType.BOOLEAN_OR_NULL;
169 if (!other.canBeNull()) return HType.CONFLICTING; 171 if (!other.canBeNull()) return HType.UNKNOWN;
sra1 2012/07/11 20:04:34 This is too pessimistic. HBoundedType should beco
170 return other; 172 return other;
171 } 173 }
172 174
173 HType intersection(HType other) { 175 HType intersection(HType other) {
174 if (other.isUnknown()) return HType.NULL; 176 if (other.isUnknown()) return HType.NULL;
175 if (other.isConflicting()) return HType.CONFLICTING; 177 if (other.isConflicting()) return HType.CONFLICTING;
176 if (!other.canBeNull()) return HType.CONFLICTING; 178 if (!other.canBeNull()) return HType.CONFLICTING;
177 return HType.NULL; 179 return HType.NULL;
178 } 180 }
179 } 181 }
180 182
181 abstract class HPrimitiveOrNullType extends HType { 183 abstract class HPrimitiveOrNullType extends HType {
182 const HPrimitiveOrNullType(); 184 const HPrimitiveOrNullType();
183 bool canBePrimitive() => true; 185 bool canBePrimitive() => true;
184 bool canBeNull() => true; 186 bool canBeNull() => true;
185 } 187 }
186 188
187 class HBooleanOrNullType extends HPrimitiveOrNullType { 189 class HBooleanOrNullType extends HPrimitiveOrNullType {
188 const HBooleanOrNullType(); 190 const HBooleanOrNullType();
189 String toString() => "boolean or null"; 191 String toString() => "boolean or null";
190 bool isBooleanOrNull() => true; 192 bool isBooleanOrNull() => true;
191 193
192 Type computeType(Compiler compiler) { 194 Type computeType(Compiler compiler) {
193 return compiler.boolClass.computeType(compiler); 195 return compiler.boolClass.computeType(compiler);
194 } 196 }
195 197
196 HType union(HType other) { 198 HType union(HType other) {
197 if (other.isUnknown()) return HType.BOOLEAN_OR_NULL; 199 if (other.isConflicting()) return HType.BOOLEAN_OR_NULL;
200 if (other.isUnknown()) return HType.UNKNOWN;
198 if (other.isBooleanOrNull()) return HType.BOOLEAN_OR_NULL; 201 if (other.isBooleanOrNull()) return HType.BOOLEAN_OR_NULL;
199 if (other.isBoolean()) return HType.BOOLEAN_OR_NULL; 202 if (other.isBoolean()) return HType.BOOLEAN_OR_NULL;
200 if (other.isNull()) return HType.BOOLEAN_OR_NULL; 203 if (other.isNull()) return HType.BOOLEAN_OR_NULL;
201 return HType.CONFLICTING; 204 return HType.UNKNOWN;
202 } 205 }
203 206
204 HType intersection(HType other) { 207 HType intersection(HType other) {
205 if (other.isUnknown()) return HType.BOOLEAN_OR_NULL; 208 if (other.isUnknown()) return HType.BOOLEAN_OR_NULL;
206 if (other.isBooleanOrNull()) return HType.BOOLEAN_OR_NULL; 209 if (other.isBooleanOrNull()) return HType.BOOLEAN_OR_NULL;
207 if (other.isBoolean()) return HType.BOOLEAN; 210 if (other.isBoolean()) return HType.BOOLEAN;
208 if (other.canBeNull()) return HType.NULL; 211 if (other.canBeNull()) return HType.NULL;
209 return HType.CONFLICTING; 212 return HType.CONFLICTING;
210 } 213 }
211 } 214 }
212 215
213 class HBooleanType extends HPrimitiveType { 216 class HBooleanType extends HPrimitiveType {
214 const HBooleanType(); 217 const HBooleanType();
215 bool isBoolean() => true; 218 bool isBoolean() => true;
216 String toString() => "boolean"; 219 String toString() => "boolean";
217 220
218 Type computeType(Compiler compiler) { 221 Type computeType(Compiler compiler) {
219 return compiler.boolClass.computeType(compiler); 222 return compiler.boolClass.computeType(compiler);
220 } 223 }
221 224
222 HType union(HType other) { 225 HType union(HType other) {
223 if (other.isUnknown()) return HType.BOOLEAN; 226 if (other.isConflicting()) return HType.BOOLEAN;
227 if (other.isUnknown()) return HType.UNKNOWN;
224 if (other.isBoolean()) return HType.BOOLEAN; 228 if (other.isBoolean()) return HType.BOOLEAN;
225 if (other.isBooleanOrNull()) return HType.BOOLEAN_OR_NULL; 229 if (other.isBooleanOrNull()) return HType.BOOLEAN_OR_NULL;
226 if (other.isNull()) return HType.BOOLEAN_OR_NULL; 230 if (other.isNull()) return HType.BOOLEAN_OR_NULL;
227 return HType.CONFLICTING; 231 return HType.UNKNOWN;
228 } 232 }
229 233
230 HType intersection(HType other) { 234 HType intersection(HType other) {
231 if (other.isUnknown()) return HType.BOOLEAN; 235 if (other.isUnknown()) return HType.BOOLEAN;
232 if (other.isBooleanOrNull()) return HType.BOOLEAN; 236 if (other.isBooleanOrNull()) return HType.BOOLEAN;
233 if (other.isBoolean()) return HType.BOOLEAN; 237 if (other.isBoolean()) return HType.BOOLEAN;
234 return HType.CONFLICTING; 238 return HType.CONFLICTING;
235 } 239 }
236 } 240 }
237 241
238 class HNumberOrNullType extends HPrimitiveOrNullType { 242 class HNumberOrNullType extends HPrimitiveOrNullType {
239 const HNumberOrNullType(); 243 const HNumberOrNullType();
240 bool isNumberOrNull() => true; 244 bool isNumberOrNull() => true;
241 String toString() => "number or null"; 245 String toString() => "number or null";
242 246
243 Type computeType(Compiler compiler) { 247 Type computeType(Compiler compiler) {
244 return compiler.numClass.computeType(compiler); 248 return compiler.numClass.computeType(compiler);
245 } 249 }
246 250
247 HType union(HType other) { 251 HType union(HType other) {
248 if (other.isUnknown()) return HType.NUMBER_OR_NULL; 252 if (other.isConflicting()) return HType.NUMBER_OR_NULL;
253 if (other.isUnknown()) return HType.UNKNOWN;
249 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL; 254 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
250 if (other.isNumber()) return HType.NUMBER_OR_NULL; 255 if (other.isNumber()) return HType.NUMBER_OR_NULL;
251 if (other.isNull()) return HType.NUMBER_OR_NULL; 256 if (other.isNull()) return HType.NUMBER_OR_NULL;
252 return HType.CONFLICTING; 257 return HType.UNKNOWN;
253 } 258 }
254 259
255 HType intersection(HType other) { 260 HType intersection(HType other) {
256 if (other.isUnknown()) return HType.NUMBER_OR_NULL; 261 if (other.isUnknown()) return HType.NUMBER_OR_NULL;
257 if (other.isInteger()) return HType.INTEGER; 262 if (other.isInteger()) return HType.INTEGER;
258 if (other.isDouble()) return HType.DOUBLE; 263 if (other.isDouble()) return HType.DOUBLE;
259 if (other.isNumber()) return HType.NUMBER; 264 if (other.isNumber()) return HType.NUMBER;
260 if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL; 265 if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL;
261 if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL; 266 if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL;
262 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL; 267 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
263 if (other.canBeNull()) return HType.NULL; 268 if (other.canBeNull()) return HType.NULL;
264 return HType.CONFLICTING; 269 return HType.CONFLICTING;
265 } 270 }
266 } 271 }
267 272
268 class HNumberType extends HPrimitiveType { 273 class HNumberType extends HPrimitiveType {
269 const HNumberType(); 274 const HNumberType();
270 bool isNumber() => true; 275 bool isNumber() => true;
271 String toString() => "number"; 276 String toString() => "number";
272 277
273 Type computeType(Compiler compiler) { 278 Type computeType(Compiler compiler) {
274 return compiler.numClass.computeType(compiler); 279 return compiler.numClass.computeType(compiler);
275 } 280 }
276 281
277 HType union(HType other) { 282 HType union(HType other) {
283 if (other.isConflicting()) return HType.NUMBER;
284 if (other.isUnknown()) return HType.UNKNOWN;
278 if (other.isNumber()) return HType.NUMBER; 285 if (other.isNumber()) return HType.NUMBER;
279 if (other.isUnknown()) return HType.NUMBER;
280 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL; 286 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
281 if (other.isNull()) return HType.NUMBER_OR_NULL; 287 if (other.isNull()) return HType.NUMBER_OR_NULL;
282 return HType.CONFLICTING; 288 return HType.UNKNOWN;
283 } 289 }
284 290
285 HType intersection(HType other) { 291 HType intersection(HType other) {
286 if (other.isUnknown()) return HType.NUMBER; 292 if (other.isUnknown()) return HType.NUMBER;
287 if (other.isNumber()) return other; 293 if (other.isNumber()) return other;
288 if (other.isIntegerOrNull()) return HType.INTEGER; 294 if (other.isIntegerOrNull()) return HType.INTEGER;
289 if (other.isDoubleOrNull()) return HType.DOUBLE; 295 if (other.isDoubleOrNull()) return HType.DOUBLE;
290 if (other.isNumberOrNull()) return HType.NUMBER; 296 if (other.isNumberOrNull()) return HType.NUMBER;
291 return HType.CONFLICTING; 297 return HType.CONFLICTING;
292 } 298 }
293 } 299 }
294 300
295 class HIntegerOrNullType extends HNumberOrNullType { 301 class HIntegerOrNullType extends HNumberOrNullType {
296 const HIntegerOrNullType(); 302 const HIntegerOrNullType();
297 bool isIntegerOrNull() => true; 303 bool isIntegerOrNull() => true;
298 String toString() => "integer or null"; 304 String toString() => "integer or null";
299 305
300 Type computeType(Compiler compiler) { 306 Type computeType(Compiler compiler) {
301 return compiler.intClass.computeType(compiler); 307 return compiler.intClass.computeType(compiler);
302 } 308 }
303 309
304 HType union(HType other) { 310 HType union(HType other) {
305 if (other.isUnknown()) return HType.INTEGER_OR_NULL; 311 if (other.isConflicting()) return HType.INTEGER_OR_NULL;
312 if (other.isUnknown()) return HType.UNKNOWN;
306 if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL; 313 if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL;
307 if (other.isInteger()) return HType.INTEGER_OR_NULL; 314 if (other.isInteger()) return HType.INTEGER_OR_NULL;
308 if (other.isNumber()) return HType.NUMBER_OR_NULL; 315 if (other.isNumber()) return HType.NUMBER_OR_NULL;
309 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL; 316 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
310 if (other.isNull()) return HType.INTEGER_OR_NULL; 317 if (other.isNull()) return HType.INTEGER_OR_NULL;
311 return HType.CONFLICTING; 318 return HType.UNKNOWN;
312 } 319 }
313 320
314 HType intersection(HType other) { 321 HType intersection(HType other) {
315 if (other.isUnknown()) return HType.INTEGER_OR_NULL; 322 if (other.isUnknown()) return HType.INTEGER_OR_NULL;
316 if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL; 323 if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL;
317 if (other.isInteger()) return HType.INTEGER; 324 if (other.isInteger()) return HType.INTEGER;
318 if (other.isDouble()) return HType.CONFLICTING; 325 if (other.isDouble()) return HType.CONFLICTING;
319 if (other.isDoubleOrNull()) return HType.NULL; 326 if (other.isDoubleOrNull()) return HType.NULL;
320 if (other.isNumber()) return HType.INTEGER; 327 if (other.isNumber()) return HType.INTEGER;
321 if (other.isNumberOrNull()) return HType.INTEGER_OR_NULL; 328 if (other.isNumberOrNull()) return HType.INTEGER_OR_NULL;
322 if (other.canBeNull()) return HType.NULL; 329 if (other.canBeNull()) return HType.NULL;
323 return HType.CONFLICTING; 330 return HType.CONFLICTING;
324 } 331 }
325 } 332 }
326 333
327 class HIntegerType extends HNumberType { 334 class HIntegerType extends HNumberType {
328 const HIntegerType(); 335 const HIntegerType();
329 bool isInteger() => true; 336 bool isInteger() => true;
330 String toString() => "integer"; 337 String toString() => "integer";
331 338
332 Type computeType(Compiler compiler) { 339 Type computeType(Compiler compiler) {
333 return compiler.intClass.computeType(compiler); 340 return compiler.intClass.computeType(compiler);
334 } 341 }
335 342
336 HType union(HType other) { 343 HType union(HType other) {
337 if (other.isUnknown()) return HType.INTEGER; 344 if (other.isConflicting()) return HType.INTEGER;
345 if (other.isUnknown()) return HType.UNKNOWN;
338 if (other.isInteger()) return HType.INTEGER; 346 if (other.isInteger()) return HType.INTEGER;
339 if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL; 347 if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL;
340 if (other.isNumber()) return HType.NUMBER; 348 if (other.isNumber()) return HType.NUMBER;
341 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL; 349 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
342 if (other.isNull()) return HType.INTEGER_OR_NULL; 350 if (other.isNull()) return HType.INTEGER_OR_NULL;
343 return HType.CONFLICTING; 351 return HType.UNKNOWN;
344 } 352 }
345 353
346 HType intersection(HType other) { 354 HType intersection(HType other) {
347 if (other.isUnknown()) return HType.INTEGER; 355 if (other.isUnknown()) return HType.INTEGER;
348 if (other.isIntegerOrNull()) return HType.INTEGER; 356 if (other.isIntegerOrNull()) return HType.INTEGER;
349 if (other.isInteger()) return HType.INTEGER; 357 if (other.isInteger()) return HType.INTEGER;
350 if (other.isDouble()) return HType.CONFLICTING; 358 if (other.isDouble()) return HType.CONFLICTING;
351 if (other.isDoubleOrNull()) return HType.CONFLICTING; 359 if (other.isDoubleOrNull()) return HType.CONFLICTING;
352 if (other.isNumber()) return HType.INTEGER; 360 if (other.isNumber()) return HType.INTEGER;
353 if (other.isNumberOrNull()) return HType.INTEGER; 361 if (other.isNumberOrNull()) return HType.INTEGER;
354 return HType.CONFLICTING; 362 return HType.CONFLICTING;
355 } 363 }
356 } 364 }
357 365
358 class HDoubleOrNullType extends HNumberOrNullType { 366 class HDoubleOrNullType extends HNumberOrNullType {
359 const HDoubleOrNullType(); 367 const HDoubleOrNullType();
360 bool isDoubleOrNull() => true; 368 bool isDoubleOrNull() => true;
361 String toString() => "double or null"; 369 String toString() => "double or null";
362 370
363 Type computeType(Compiler compiler) { 371 Type computeType(Compiler compiler) {
364 return compiler.doubleClass.computeType(compiler); 372 return compiler.doubleClass.computeType(compiler);
365 } 373 }
366 374
367 HType union(HType other) { 375 HType union(HType other) {
368 if (other.isUnknown()) return HType.DOUBLE_OR_NULL; 376 if (other.isConflicting()) return HType.DOUBLE_OR_NULL;
377 if (other.isUnknown()) return HType.UNKNOWN;
369 if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL; 378 if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL;
370 if (other.isDouble()) return HType.DOUBLE_OR_NULL; 379 if (other.isDouble()) return HType.DOUBLE_OR_NULL;
371 if (other.isNumber()) return HType.NUMBER_OR_NULL; 380 if (other.isNumber()) return HType.NUMBER_OR_NULL;
372 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL; 381 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
373 if (other.isNull()) return HType.DOUBLE_OR_NULL; 382 if (other.isNull()) return HType.DOUBLE_OR_NULL;
374 return HType.CONFLICTING; 383 return HType.UNKNOWN;
375 } 384 }
376 385
377 HType intersection(HType other) { 386 HType intersection(HType other) {
378 if (other.isUnknown()) return HType.DOUBLE_OR_NULL; 387 if (other.isUnknown()) return HType.DOUBLE_OR_NULL;
379 if (other.isIntegerOrNull()) return HType.NULL; 388 if (other.isIntegerOrNull()) return HType.NULL;
380 if (other.isInteger()) return HType.CONFLICTING; 389 if (other.isInteger()) return HType.CONFLICTING;
381 if (other.isDouble()) return HType.DOUBLE; 390 if (other.isDouble()) return HType.DOUBLE;
382 if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL; 391 if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL;
383 if (other.isNumber()) return HType.DOUBLE; 392 if (other.isNumber()) return HType.DOUBLE;
384 if (other.isNumberOrNull()) return HType.DOUBLE_OR_NULL; 393 if (other.isNumberOrNull()) return HType.DOUBLE_OR_NULL;
385 if (other.canBeNull()) return HType.NULL; 394 if (other.canBeNull()) return HType.NULL;
386 return HType.CONFLICTING; 395 return HType.CONFLICTING;
387 } 396 }
388 } 397 }
389 398
390 class HDoubleType extends HNumberType { 399 class HDoubleType extends HNumberType {
391 const HDoubleType(); 400 const HDoubleType();
392 bool isDouble() => true; 401 bool isDouble() => true;
393 String toString() => "double"; 402 String toString() => "double";
394 403
395 Type computeType(Compiler compiler) { 404 Type computeType(Compiler compiler) {
396 return compiler.doubleClass.computeType(compiler); 405 return compiler.doubleClass.computeType(compiler);
397 } 406 }
398 407
399 HType union(HType other) { 408 HType union(HType other) {
400 if (other.isUnknown()) return HType.DOUBLE; 409 if (other.isConflicting()) return HType.DOUBLE;
410 if (other.isUnknown()) return HType.UNKNOWN;
401 if (other.isDouble()) return HType.DOUBLE; 411 if (other.isDouble()) return HType.DOUBLE;
402 if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL; 412 if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL;
403 if (other.isNumber()) return HType.NUMBER; 413 if (other.isNumber()) return HType.NUMBER;
404 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL; 414 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
405 if (other.isNull()) return HType.DOUBLE_OR_NULL; 415 if (other.isNull()) return HType.DOUBLE_OR_NULL;
406 return HType.CONFLICTING; 416 return HType.UNKNOWN;
407 } 417 }
408 418
409 HType intersection(HType other) { 419 HType intersection(HType other) {
410 if (other.isUnknown()) return HType.DOUBLE; 420 if (other.isUnknown()) return HType.DOUBLE;
411 if (other.isIntegerOrNull()) return HType.CONFLICTING; 421 if (other.isIntegerOrNull()) return HType.CONFLICTING;
412 if (other.isInteger()) return HType.CONFLICTING; 422 if (other.isInteger()) return HType.CONFLICTING;
413 if (other.isDouble()) return HType.DOUBLE; 423 if (other.isDouble()) return HType.DOUBLE;
414 if (other.isDoubleOrNull()) return HType.DOUBLE; 424 if (other.isDoubleOrNull()) return HType.DOUBLE;
415 if (other.isNumber()) return HType.DOUBLE; 425 if (other.isNumber()) return HType.DOUBLE;
416 if (other.isNumberOrNull()) return HType.DOUBLE; 426 if (other.isNumberOrNull()) return HType.DOUBLE;
417 return HType.CONFLICTING; 427 return HType.CONFLICTING;
418 } 428 }
419 } 429 }
420 430
421 class HIndexablePrimitiveType extends HPrimitiveType { 431 class HIndexablePrimitiveType extends HPrimitiveType {
422 const HIndexablePrimitiveType(); 432 const HIndexablePrimitiveType();
423 bool isIndexablePrimitive() => true; 433 bool isIndexablePrimitive() => true;
424 String toString() => "indexable"; 434 String toString() => "indexable";
425 435
426 Type computeType(Compiler compiler) { 436 Type computeType(Compiler compiler) {
427 // TODO(ngeoffray): Represent union types. 437 // TODO(ngeoffray): Represent union types.
428 return null; 438 return null;
429 } 439 }
430 440
431 HType union(HType other) { 441 HType union(HType other) {
432 if (other.isUnknown()) return HType.INDEXABLE_PRIMITIVE; 442 if (other.isConflicting()) return HType.INDEXABLE_PRIMITIVE;
443 if (other.isUnknown()) return HType.UNKNOWN;
433 if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE; 444 if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE;
434 if (other is HBoundedPotentialPrimitiveString) { 445 if (other is HBoundedPotentialPrimitiveString) {
435 // TODO(ngeoffray): Represent union types. 446 // TODO(ngeoffray): Represent union types.
436 return HType.CONFLICTING; 447 return HType.UNKNOWN;
437 } 448 }
438 if (other is HBoundedPotentialPrimitiveArray) { 449 if (other is HBoundedPotentialPrimitiveArray) {
439 // TODO(ngeoffray): Represent union types. 450 // TODO(ngeoffray): Represent union types.
440 return HType.CONFLICTING; 451 return HType.UNKNOWN;
441 } 452 }
442 return HType.CONFLICTING; 453 return HType.UNKNOWN;
443 } 454 }
444 455
445 HType intersection(HType other) { 456 HType intersection(HType other) {
446 if (other.isUnknown()) return HType.INDEXABLE_PRIMITIVE; 457 if (other.isUnknown()) return HType.INDEXABLE_PRIMITIVE;
447 if (other.isIndexablePrimitive()) return other; 458 if (other.isIndexablePrimitive()) return other;
448 if (other is HBoundedPotentialPrimitiveString) return HType.STRING; 459 if (other is HBoundedPotentialPrimitiveString) return HType.STRING;
449 if (other is HBoundedPotentialPrimitiveArray) return HType.READABLE_ARRAY; 460 if (other is HBoundedPotentialPrimitiveArray) return HType.READABLE_ARRAY;
450 return HType.CONFLICTING; 461 return HType.CONFLICTING;
451 } 462 }
452 } 463 }
453 464
454 class HStringOrNullType extends HPrimitiveOrNullType { 465 class HStringOrNullType extends HPrimitiveOrNullType {
455 const HStringOrNullType(); 466 const HStringOrNullType();
456 bool isStringOrNull() => true; 467 bool isStringOrNull() => true;
457 String toString() => "String or null"; 468 String toString() => "String or null";
458 469
459 Type computeType(Compiler compiler) { 470 Type computeType(Compiler compiler) {
460 return compiler.stringClass.computeType(compiler); 471 return compiler.stringClass.computeType(compiler);
461 } 472 }
462 473
463 HType union(HType other) { 474 HType union(HType other) {
464 if (other.isUnknown()) return HType.STRING_OR_NULL; 475 if (other.isConflicting()) return HType.STRING_OR_NULL;
476 if (other.isUnknown()) return HType.UNKNOWN;
465 if (other.isString()) return HType.STRING_OR_NULL; 477 if (other.isString()) return HType.STRING_OR_NULL;
466 if (other.isStringOrNull()) return HType.STRING_OR_NULL; 478 if (other.isStringOrNull()) return HType.STRING_OR_NULL;
467 if (other.isIndexablePrimitive()) { 479 if (other.isIndexablePrimitive()) {
468 // We don't have a type that represents the nullable indexable 480 // We don't have a type that represents the nullable indexable
469 // primitive. 481 // primitive.
470 return HType.CONFLICTING; 482 return HType.UNKNOWN;
471 } 483 }
472 if (other is HBoundedPotentialPrimitiveString) { 484 if (other is HBoundedPotentialPrimitiveString) {
473 if (other.canBeNull()) { 485 if (other.canBeNull()) {
474 return other; 486 return other;
475 } else { 487 } else {
476 HBoundedType boundedType = other; 488 HBoundedType boundedType = other;
477 return new HBoundedPotentialPrimitiveString(boundedType.type, true); 489 return new HBoundedPotentialPrimitiveString(boundedType.type, true);
478 } 490 }
479 } 491 }
480 if (other.isNull()) return HType.STRING_OR_NULL; 492 if (other.isNull()) return HType.STRING_OR_NULL;
481 return HType.CONFLICTING; 493 return HType.UNKNOWN;
482 } 494 }
483 495
484 HType intersection(HType other) { 496 HType intersection(HType other) {
485 if (other.isUnknown()) return HType.STRING_OR_NULL; 497 if (other.isUnknown()) return HType.STRING_OR_NULL;
486 if (other.isString()) return HType.STRING; 498 if (other.isString()) return HType.STRING;
487 if (other.isStringOrNull()) return HType.STRING_OR_NULL; 499 if (other.isStringOrNull()) return HType.STRING_OR_NULL;
488 if (other.isArray()) return HType.CONFLICTING; 500 if (other.isArray()) return HType.CONFLICTING;
489 if (other.isIndexablePrimitive()) return HType.STRING; 501 if (other.isIndexablePrimitive()) return HType.STRING;
490 if (other is HBoundedPotentialPrimitiveString) { 502 if (other is HBoundedPotentialPrimitiveString) {
491 return other.canBeNull() ? HType.STRING_OR_NULL : HType.STRING; 503 return other.canBeNull() ? HType.STRING_OR_NULL : HType.STRING;
492 } 504 }
493 if (other.canBeNull()) return HType.NULL; 505 if (other.canBeNull()) return HType.NULL;
494 return HType.CONFLICTING; 506 return HType.CONFLICTING;
495 } 507 }
496 } 508 }
497 509
498 class HStringType extends HIndexablePrimitiveType { 510 class HStringType extends HIndexablePrimitiveType {
499 const HStringType(); 511 const HStringType();
500 bool isString() => true; 512 bool isString() => true;
501 String toString() => "String"; 513 String toString() => "String";
502 514
503 Type computeType(Compiler compiler) { 515 Type computeType(Compiler compiler) {
504 return compiler.stringClass.computeType(compiler); 516 return compiler.stringClass.computeType(compiler);
505 } 517 }
506 518
507 HType union(HType other) { 519 HType union(HType other) {
508 if (other.isUnknown()) return HType.STRING; 520 if (other.isConflicting()) return HType.STRING;
521 if (other.isUnknown()) return HType.UNKNOWN;
509 if (other.isString()) return HType.STRING; 522 if (other.isString()) return HType.STRING;
510 if (other.isStringOrNull()) return HType.STRING_OR_NULL; 523 if (other.isStringOrNull()) return HType.STRING_OR_NULL;
511 if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE; 524 if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE;
512 if (other is HBoundedPotentialPrimitiveString) return other; 525 if (other is HBoundedPotentialPrimitiveString) return other;
513 if (other.isNull()) return HType.STRING_OR_NULL; 526 if (other.isNull()) return HType.STRING_OR_NULL;
514 return HType.CONFLICTING; 527 return HType.UNKNOWN;
515 } 528 }
516 529
517 HType intersection(HType other) { 530 HType intersection(HType other) {
518 if (other.isUnknown()) return HType.STRING; 531 if (other.isUnknown()) return HType.STRING;
519 if (other.isString()) return HType.STRING; 532 if (other.isString()) return HType.STRING;
520 if (other.isArray()) return HType.CONFLICTING; 533 if (other.isArray()) return HType.CONFLICTING;
521 if (other.isIndexablePrimitive()) return HType.STRING; 534 if (other.isIndexablePrimitive()) return HType.STRING;
522 if (other.isStringOrNull()) return HType.STRING; 535 if (other.isStringOrNull()) return HType.STRING;
523 if (other is HBoundedPotentialPrimitiveString) return HType.STRING; 536 if (other is HBoundedPotentialPrimitiveString) return HType.STRING;
524 return HType.CONFLICTING; 537 return HType.CONFLICTING;
525 } 538 }
526 } 539 }
527 540
528 class HReadableArrayType extends HIndexablePrimitiveType { 541 class HReadableArrayType extends HIndexablePrimitiveType {
529 const HReadableArrayType(); 542 const HReadableArrayType();
530 bool isReadableArray() => true; 543 bool isReadableArray() => true;
531 String toString() => "readable array"; 544 String toString() => "readable array";
532 545
533 Type computeType(Compiler compiler) { 546 Type computeType(Compiler compiler) {
534 return compiler.listClass.computeType(compiler); 547 return compiler.listClass.computeType(compiler);
535 } 548 }
536 549
537 HType union(HType other) { 550 HType union(HType other) {
538 if (other.isUnknown()) return HType.READABLE_ARRAY; 551 if (other.isConflicting()) return HType.READABLE_ARRAY;
552 if (other.isUnknown()) return HType.UNKNOWN;
539 if (other.isReadableArray()) return HType.READABLE_ARRAY; 553 if (other.isReadableArray()) return HType.READABLE_ARRAY;
540 if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE; 554 if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE;
541 if (other is HBoundedPotentialPrimitiveArray) return other; 555 if (other is HBoundedPotentialPrimitiveArray) return other;
542 return HType.CONFLICTING; 556 return HType.UNKNOWN;
543 } 557 }
544 558
545 HType intersection(HType other) { 559 HType intersection(HType other) {
546 if (other.isUnknown()) return HType.READABLE_ARRAY; 560 if (other.isUnknown()) return HType.READABLE_ARRAY;
547 if (other.isString()) return HType.CONFLICTING; 561 if (other.isString()) return HType.CONFLICTING;
548 if (other.isReadableArray()) return other; 562 if (other.isReadableArray()) return other;
549 if (other.isIndexablePrimitive()) return HType.READABLE_ARRAY; 563 if (other.isIndexablePrimitive()) return HType.READABLE_ARRAY;
550 if (other is HBoundedPotentialPrimitiveArray) return HType.READABLE_ARRAY; 564 if (other is HBoundedPotentialPrimitiveArray) return HType.READABLE_ARRAY;
551 return HType.CONFLICTING; 565 return HType.CONFLICTING;
552 } 566 }
553 } 567 }
554 568
555 class HMutableArrayType extends HReadableArrayType { 569 class HMutableArrayType extends HReadableArrayType {
556 const HMutableArrayType(); 570 const HMutableArrayType();
557 bool isMutableArray() => true; 571 bool isMutableArray() => true;
558 String toString() => "mutable array"; 572 String toString() => "mutable array";
559 573
560 HType union(HType other) { 574 HType union(HType other) {
561 if (other.isUnknown()) return HType.MUTABLE_ARRAY; 575 if (other.isConflicting()) return HType.MUTABLE_ARRAY;
576 if (other.isUnknown()) return HType.UNKNOWN;
562 if (other.isMutableArray()) return HType.MUTABLE_ARRAY; 577 if (other.isMutableArray()) return HType.MUTABLE_ARRAY;
563 if (other.isReadableArray()) return HType.READABLE_ARRAY; 578 if (other.isReadableArray()) return HType.READABLE_ARRAY;
564 if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE; 579 if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE;
565 if (other is HBoundedPotentialPrimitiveArray) return other; 580 if (other is HBoundedPotentialPrimitiveArray) return other;
566 return HType.CONFLICTING; 581 return HType.UNKNOWN;
567 } 582 }
568 583
569 HType intersection(HType other) { 584 HType intersection(HType other) {
570 if (other.isUnknown()) return HType.MUTABLE_ARRAY; 585 if (other.isUnknown()) return HType.MUTABLE_ARRAY;
571 if (other.isMutableArray()) return other; 586 if (other.isMutableArray()) return other;
572 if (other.isString()) return HType.CONFLICTING; 587 if (other.isString()) return HType.CONFLICTING;
573 if (other.isIndexablePrimitive()) return HType.MUTABLE_ARRAY; 588 if (other.isIndexablePrimitive()) return HType.MUTABLE_ARRAY;
574 if (other is HBoundedPotentialPrimitiveArray) return HType.MUTABLE_ARRAY; 589 if (other is HBoundedPotentialPrimitiveArray) return HType.MUTABLE_ARRAY;
575 return HType.CONFLICTING; 590 return HType.CONFLICTING;
576 } 591 }
577 } 592 }
578 593
579 class HExtendableArrayType extends HMutableArrayType { 594 class HExtendableArrayType extends HMutableArrayType {
580 const HExtendableArrayType(); 595 const HExtendableArrayType();
581 bool isExtendableArray() => true; 596 bool isExtendableArray() => true;
582 String toString() => "extendable array"; 597 String toString() => "extendable array";
583 598
584 HType union(HType other) { 599 HType union(HType other) {
585 if (other.isUnknown()) return HType.EXTENDABLE_ARRAY; 600 if (other.isConflicting()) return HType.EXTENDABLE_ARRAY;
601 if (other.isUnknown()) return HType.UNKNOWN;
586 if (other.isExtendableArray()) return HType.EXTENDABLE_ARRAY; 602 if (other.isExtendableArray()) return HType.EXTENDABLE_ARRAY;
587 if (other.isMutableArray()) return HType.MUTABLE_ARRAY; 603 if (other.isMutableArray()) return HType.MUTABLE_ARRAY;
588 if (other.isReadableArray()) return HType.READABLE_ARRAY; 604 if (other.isReadableArray()) return HType.READABLE_ARRAY;
589 if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE; 605 if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE;
590 if (other is HBoundedPotentialPrimitiveArray) return other; 606 if (other is HBoundedPotentialPrimitiveArray) return other;
591 return HType.CONFLICTING; 607 return HType.UNKNOWN;
592 } 608 }
593 609
594 HType intersection(HType other) { 610 HType intersection(HType other) {
595 if (other.isUnknown()) return HType.EXTENDABLE_ARRAY; 611 if (other.isUnknown()) return HType.EXTENDABLE_ARRAY;
596 if (other.isExtendableArray()) return HType.EXTENDABLE_ARRAY; 612 if (other.isExtendableArray()) return HType.EXTENDABLE_ARRAY;
597 if (other.isString()) return HType.CONFLICTING; 613 if (other.isString()) return HType.CONFLICTING;
598 if (other.isIndexablePrimitive()) return HType.EXTENDABLE_ARRAY; 614 if (other.isIndexablePrimitive()) return HType.EXTENDABLE_ARRAY;
599 if (other is HBoundedPotentialPrimitiveArray) return HType.EXTENDABLE_ARRAY; 615 if (other is HBoundedPotentialPrimitiveArray) return HType.EXTENDABLE_ARRAY;
600 return HType.CONFLICTING; 616 return HType.CONFLICTING;
601 } 617 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 HType union(HType other) { 677 HType union(HType other) {
662 if (other.isNull()) { 678 if (other.isNull()) {
663 if (canBeNull()) { 679 if (canBeNull()) {
664 return this; 680 return this;
665 } else { 681 } else {
666 return new HBoundedType.withNull(type); 682 return new HBoundedType.withNull(type);
667 } 683 }
668 } 684 }
669 if (other is HBoundedType) { 685 if (other is HBoundedType) {
670 HBoundedType temp = other; 686 HBoundedType temp = other;
671 if (type !== temp.type) return HType.CONFLICTING; 687 if (type !== temp.type) return HType.UNKNOWN;
672 if (isExact()) return other; 688 if (isExact()) return other;
673 if (other.isExact()) return this; 689 if (other.isExact()) return this;
674 return canBeNull() ? this : other; 690 return canBeNull() ? this : other;
675 } 691 }
676 if (other.isUnknown()) return this; 692 if (other.isConflicting()) return this;
677 return HType.CONFLICTING; 693 return HType.UNKNOWN;
678 } 694 }
679 } 695 }
680 696
681 class HBoundedPotentialPrimitiveType extends HBoundedType { 697 class HBoundedPotentialPrimitiveType extends HBoundedType {
682 const HBoundedPotentialPrimitiveType(Type type, bool canBeNull) 698 const HBoundedPotentialPrimitiveType(Type type, bool canBeNull)
683 : super(type, canBeNull, false); 699 : super(type, canBeNull, false);
684 bool canBePrimitive() => true; 700 bool canBePrimitive() => true;
685 } 701 }
686 702
687 class HBoundedPotentialPrimitiveArray extends HBoundedPotentialPrimitiveType { 703 class HBoundedPotentialPrimitiveArray extends HBoundedPotentialPrimitiveType {
688 const HBoundedPotentialPrimitiveArray(Type type, bool canBeNull) 704 const HBoundedPotentialPrimitiveArray(Type type, bool canBeNull)
689 : super(type, canBeNull); 705 : super(type, canBeNull);
690 706
691 HType union(HType other) { 707 HType union(HType other) {
692 if (other.isString()) return HType.CONFLICTING; 708 if (other.isString()) return HType.UNKNOWN;
693 if (other.isReadableArray()) return this; 709 if (other.isReadableArray()) return this;
694 // TODO(ngeoffray): implement union types. 710 // TODO(ngeoffray): implement union types.
695 if (other.isIndexablePrimitive()) return HType.CONFLICTING; 711 if (other.isIndexablePrimitive()) return HType.UNKNOWN;
696 if (other.isNull()) { 712 if (other.isNull()) {
697 if (canBeNull()) { 713 if (canBeNull()) {
698 return this; 714 return this;
699 } else { 715 } else {
700 return new HBoundedPotentialPrimitiveArray(type, true); 716 return new HBoundedPotentialPrimitiveArray(type, true);
701 } 717 }
702 } 718 }
703 return super.union(other); 719 return super.union(other);
704 } 720 }
705 721
(...skipping 19 matching lines...) Expand all
725 } 741 }
726 } 742 }
727 if (other.isNull()) { 743 if (other.isNull()) {
728 if (canBeNull()) { 744 if (canBeNull()) {
729 return this; 745 return this;
730 } else { 746 } else {
731 return new HBoundedPotentialPrimitiveString(type, true); 747 return new HBoundedPotentialPrimitiveString(type, true);
732 } 748 }
733 } 749 }
734 // TODO(ngeoffray): implement union types. 750 // TODO(ngeoffray): implement union types.
735 if (other.isIndexablePrimitive()) return HType.CONFLICTING; 751 if (other.isIndexablePrimitive()) return HType.UNKNOWN;
736 return super.union(other); 752 return super.union(other);
737 } 753 }
738 754
739 HType intersection(HType other) { 755 HType intersection(HType other) {
740 if (other.isString()) return HType.STRING; 756 if (other.isString()) return HType.STRING;
741 if (other.isStringOrNull()) { 757 if (other.isStringOrNull()) {
742 return canBeNull() ? HType.STRING_OR_NULL : HType.STRING; 758 return canBeNull() ? HType.STRING_OR_NULL : HType.STRING;
743 } 759 }
744 if (other.isReadableArray()) return HType.CONFLICTING; 760 if (other.isReadableArray()) return HType.CONFLICTING;
745 if (other.isIndexablePrimitive()) return HType.STRING; 761 if (other.isIndexablePrimitive()) return HType.STRING;
746 return super.intersection(other); 762 return super.intersection(other);
747 } 763 }
748 } 764 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698