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

Side by Side Diff: compiler/lib/implementation/rtt.js

Issue 8913006: Expands on previous function RTT to support named/optional parameters. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 9 years 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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 // The following methods are used to handle type information 5 // The following methods are used to handle type information
6 // 6 //
7 7
8 /** 8 /**
9 * @constructor 9 * @constructor
10 * @param {string} classkey 10 * @param {string} classkey
11 * @param {string=} typekey 11 * @param {string=} typekey
12 * @param {Array.<RTT>=} typeargs 12 * @param {Array.<RTT>=} typeargs
13 * @param {RTT} returnType 13 * @param {RTT} returnType
14 * @param {bool} functionType 14 * @param {bool} functionType
15 * @param {string=} named optional
15 */ 16 */
16 function RTT(classkey, typekey, typeargs, returnType, functionType) { 17 function RTT(classkey, typekey, typeargs, returnType, functionType, named) {
17 this.classKey = classkey; 18 this.classKey = classkey;
18 this.typeKey = typekey ? typekey : classkey; 19 this.typeKey = typekey ? typekey : classkey;
19 this.typeArgs = typeargs; 20 this.typeArgs = typeargs;
20 this.returnType = returnType; // key for the return type 21 this.returnType = returnType; // key for the return type
22 this.named = named;
21 this.implementedTypes = {}; 23 this.implementedTypes = {};
22 this.functionType = functionType; 24 this.functionType = functionType;
23 // Add self 25 // Add self
24 this.implementedTypes[classkey] = this; 26 this.implementedTypes[classkey] = this;
25 // Add Object 27 // Add Object
26 if (!functionType && classkey != $cls('Object')) { 28 if (!functionType && classkey != $cls('Object')) {
27 this.implementedTypes[$cls('Object')] = RTT.objectType; 29 this.implementedTypes[$cls('Object')] = RTT.objectType;
28 } 30 }
29 } 31 }
30 32
(...skipping 30 matching lines...) Expand all
61 RTT.prototype.implementedByTypeSwitch = function(value){ 63 RTT.prototype.implementedByTypeSwitch = function(value){
62 return this.functionType ? this.implementedByTypeFunc(value) : 64 return this.functionType ? this.implementedByTypeFunc(value) :
63 this.implementedByType(value); 65 this.implementedByType(value);
64 }; 66 };
65 67
66 /** 68 /**
67 * @param {!RTT} other 69 * @param {!RTT} other
68 * @return {boolean} Whether this type is implement by other 70 * @return {boolean} Whether this type is implement by other
69 */ 71 */
70 RTT.prototype.implementedByType = function(otherType) { 72 RTT.prototype.implementedByType = function(otherType) {
71 if (otherType === this || otherType === RTT.dynamicType) { 73 if (otherType === this || otherType === RTT.dynamicType.$lookupRTT(null,otherT ype.named)) {
72 return true; 74 return true;
73 } 75 }
74 var targetTypeInfo = $mapLookup(otherType.implementedTypes, this.classKey); 76 var targetTypeInfo = $mapLookup(otherType.implementedTypes, this.classKey);
75 if (targetTypeInfo == null) { 77 if (targetTypeInfo == null) {
76 return false; 78 return false;
77 } 79 }
78 if (targetTypeInfo.typeArgs && this.typeArgs) { 80 if (targetTypeInfo.typeArgs && this.typeArgs) {
79 for(var i = this.typeArgs.length - 1; i >= 0; i--) { 81 for(var i = this.typeArgs.length - 1; i >= 0; i--) {
80 if (!this.typeArgs[i].implementedByTypeSwitch(targetTypeInfo.typeArgs[i])) { 82 if (!this.typeArgs[i].implementedByTypeSwitch(targetTypeInfo.typeArgs[i])) {
81 return false; 83 return false;
82 } 84 }
83 } 85 }
84 } 86 }
85 return true; 87 return true;
86 }; 88 };
87 89
88 /** 90 /**
89 * @param {!RTT} other 91 * @param {!RTT} other
90 * @return {boolean} Whether this type is assignable by other 92 * @return {boolean} Whether this type is assignable by other
91 */ 93 */
92 RTT.prototype.assignableByType = function(otherType) { 94 RTT.prototype.assignableByType = function(otherType) {
93 if (otherType === this || otherType === RTT.dynamicType || this === RTT.dynami cType) { 95 if (otherType === this || otherType === RTT.dynamicType.$lookupRTT(null,otherT ype.named)
96 || this === RTT.dynamicType.$lookupRTT(null,this.named)) {
94 return true; 97 return true;
95 } 98 }
96 var targetTypeInfo = $mapLookup(otherType.implementedTypes, this.classKey); 99 var targetTypeInfo = $mapLookup(otherType.implementedTypes, this.classKey);
97 if (targetTypeInfo == null) { 100 if (targetTypeInfo == null) {
98 targetTypeInfo = $mapLookup(this.implementedTypes, otherType.classKey); 101 targetTypeInfo = $mapLookup(this.implementedTypes, otherType.classKey);
99 if (targetTypeInfo == null) { 102 if (targetTypeInfo == null) {
100 return false; 103 return false;
101 } 104 }
102 } 105 }
103 if (targetTypeInfo.typeArgs && this.typeArgs) { 106 if (targetTypeInfo.typeArgs && this.typeArgs) {
(...skipping 10 matching lines...) Expand all
114 /** 117 /**
115 * @param {!RTT} other 118 * @param {!RTT} other
116 * @return {boolean} Whether this type is implemented by other 119 * @return {boolean} Whether this type is implemented by other
117 */ 120 */
118 RTT.prototype.implementedByTypeFunc = function(otherType) { 121 RTT.prototype.implementedByTypeFunc = function(otherType) {
119 if (otherType.$lookupRTT) { 122 if (otherType.$lookupRTT) {
120 otherType = otherType.$lookupRTT(); 123 otherType = otherType.$lookupRTT();
121 } else if (!(otherType instanceof RTT)) { 124 } else if (!(otherType instanceof RTT)) {
122 return false; 125 return false;
123 } 126 }
124 if (otherType === this || otherType === RTT.dynamicType) { 127 if (otherType === this || otherType === RTT.dynamicType.$lookupRTT(null,otherT ype.named)) {
125 return true; 128 return true;
126 } 129 }
127 var props = Object.getOwnPropertyNames(otherType.implementedTypes); 130 var props = Object.getOwnPropertyNames(otherType.implementedTypes);
128 NEXT_PROPERTY: for (var i = 0 ; i < props.length; i++) { 131 NEXT_PROPERTY: for (var i = 0 ; i < props.length; i++) {
129 var mapped = otherType.implementedTypes[props[i]]; 132 var mapped = otherType.implementedTypes[props[i]];
130 if (mapped.returnType && this.returnType && 133 if (mapped.returnType && this.returnType &&
131 !this.returnType.assignableByType(mapped.returnType)) { 134 !this.returnType.assignableByType(mapped.returnType)) {
132 continue; 135 continue;
133 } 136 }
134 if (mapped.typeArgs && this.typeArgs) { 137 if (mapped.typeArgs && this.typeArgs) {
135 if (this.typeArgs.length != mapped.typeArgs.length) { 138 var named = false;
mmendez 2011/12/14 20:48:13 Nit: could move below continue.
codefu 2011/12/15 13:01:53 Done.
139 if (mapped.typeArgs.length < this.typeArgs.length) {
136 continue; 140 continue;
137 } 141 }
138 for (var x = this.typeArgs.length - 1; x >= 0; x--) { 142 var x;
143 for (x = 0; x < this.typeArgs.length; x++) {
144 if (this.typeArgs[x].named || mapped.typeArgs[x].named) {
145 named = true;
146 break;
147 }
139 if (!this.typeArgs[x].assignableByType(mapped.typeArgs[x])) { 148 if (!this.typeArgs[x].assignableByType(mapped.typeArgs[x])) {
140 continue NEXT_PROPERTY; 149 continue NEXT_PROPERTY;
141 } 150 }
142 } 151 }
152 if (!named && x < this.typeArgs.length) {
153 continue NEXT_PROPERTY;
154 }
155 for (; x < this.typeArgs.length; x++) {
156 if (!this.typeArgs[x].assignableByType(mapped.typeArgs[x])
157 || !(this.typeArgs[x].named === mapped.typeArgs[x].named)) {
158 continue NEXT_PROPERTY;
159 }
160 }
143 } else if (mapped.typeArgs || this.typeArgs) { 161 } else if (mapped.typeArgs || this.typeArgs) {
144 return false; 162 continue NEXT_PROPERTY;
145 } 163 }
146 return true; 164 return true;
147 } 165 }
148 return false; 166 return false;
149 }; 167 };
150 168
151 /** 169 /**
152 * @return {string} the class name associated with this type 170 * @return {string} the class name associated with this type
153 */ 171 */
154 RTT.prototype.getClassName = function() { 172 RTT.prototype.getClassName = function() {
155 var name = this.classKey; 173 var name = this.classKey;
156 if (name.substr(0, 4) == "cls:") { 174 if (name.substr(0, 4) == "cls:") {
157 name = name.substr(4); 175 name = name.substr(4);
158 } 176 }
159 if (name.substr(-5) == "$Dart") { 177 if (name.substr(-5) == "$Dart") {
160 name = name.substr(0, name.length - 5); 178 name = name.substr(0, name.length - 5);
161 } 179 }
162 return name; 180 return name;
163 } 181 }
164 182
165 /** 183 /**
166 * @param {RTT} 184 * @param {RTT}
167 * @return {boolean} 185 * @return {boolean}
168 */ 186 */
169 RTT.nullInstanceOf = function(type) { 187 RTT.nullInstanceOf = function(type) {
170 return type === RTT.objectType || type === RTT.dynamicType; 188 return type === RTT.objectType || type === RTT.dynamicType.$lookupRTT(null,typ e.named);
171 }; 189 };
172 190
173 /** 191 /**
174 * @param {*} value The value to retrieve type information for 192 * @param {*} value The value to retrieve type information for
175 * @return {RTT} 193 * @return {RTT}
176 */ 194 */
177 RTT.getNativeTypeInfo = function(value) { 195 RTT.getNativeTypeInfo = function(value) {
178 if (value instanceof Array) return Array.$lookupRTT(); 196 if (value instanceof Array) return Array.$lookupRTT();
179 switch (typeof value) { 197 switch (typeof value) {
180 case 'string': return String.$lookupRTT(); 198 case 'string': return String.$lookupRTT();
181 case 'number': return Number.$lookupRTT(); 199 case 'number': return Number.$lookupRTT();
182 case 'boolean': return Boolean.$lookupRTT(); 200 case 'boolean': return Boolean.$lookupRTT();
183 } 201 }
184 return RTT.placeholderType; 202 return RTT.placeholderType;
185 }; 203 };
186 204
187 /** 205 /**
188 * @param {string} name 206 * @param {string} name
189 * @param {function(RTT,Array.<RTT>)=} implementsSupplier 207 * @param {function(RTT,Array.<RTT>)=} implementsSupplier
190 * @param {Array.<RTT>=} typeArgs 208 * @param {Array.<RTT>=} typeArgs
209 * @param {string} named optional value
191 * @return {RTT} The RTT information object 210 * @return {RTT} The RTT information object
192 */ 211 */
193 RTT.create = function(name, implementsSupplier, typeArgs) { 212 RTT.create = function(name, implementsSupplier, typeArgs, named) {
194 if (name == $cls("Object")) return RTT.objectType; 213 if (name == $cls("Object") && !named) return RTT.objectType;
195 var typekey = RTT.getTypeKey(name, typeArgs); 214 var typekey = RTT.getTypeKey(name, typeArgs, null, named);
196 var rtt = $mapLookup(RTT.types, typekey); 215 var rtt = $mapLookup(RTT.types, typekey);
197 if (rtt) { 216 if (rtt) {
198 return rtt; 217 return rtt;
199 } 218 }
200 var classkey = RTT.getTypeKey(name); 219 var classkey = RTT.getTypeKey(name);
201 rtt = new RTT(classkey, typekey, typeArgs); 220 rtt = new RTT(classkey, typekey, typeArgs, null, false, named);
202 RTT.types[typekey] = rtt; 221 RTT.types[typekey] = rtt;
203 if (implementsSupplier) { 222 if (implementsSupplier) {
204 implementsSupplier(rtt, typeArgs); 223 implementsSupplier(rtt, typeArgs);
205 } 224 }
206 return rtt; 225 return rtt;
207 }; 226 };
208 227
209 /** 228 /**
210 * @param {Array.<RTT>=} typeArgs 229 * @param {Array.<RTT>=} typeArgs
211 * @param {<RTT>=} returnType (if defined) 230 * @param {<RTT>=} returnType (if defined)
231 * @param {string} named optional value
212 * @return {RTT} The RTT information object 232 * @return {RTT} The RTT information object
213 */ 233 */
214 RTT.createFunction = function(typeArgs, returnType) { 234 RTT.createFunction = function(typeArgs, returnType, named) {
215 var name = $cls("Function"); 235 var name = $cls("Function$Dart");
216 var typekey = RTT.getTypeKey(name, typeArgs, returnType); 236 var typekey = RTT.getTypeKey(name, typeArgs, returnType, named);
217 var rtt = $mapLookup(RTT.types, typekey); 237 var rtt = $mapLookup(RTT.types, typekey);
218 if (rtt) { 238 if (rtt) {
219 return rtt; 239 return rtt;
220 } 240 }
221 var classkey = RTT.getTypeKey(name); 241 var classkey = RTT.getTypeKey(name);
222 rtt = new RTT(classkey, typekey, typeArgs, returnType, true); 242 rtt = new RTT(classkey, typekey, typeArgs, returnType, true, named);
223 RTT.types[typekey] = rtt; 243 RTT.types[typekey] = rtt;
224 return rtt; 244 return rtt;
225 }; 245 };
226 246
247 /**
248 * @param {RTT} old
249 * @param {string} named optional
250 * @return {RTT} The RTT information object with named
251 */
252 RTT.clone = function(old, named) {
253 var name = old.getClassName();
254 var typekey = RTT.getTypeKey(name, old.typeArgs, old.returnType, named);
255 var rtt = $mapLookup(RTT.types, typekey);
256 if (rtt) {
257 return rtt;
258 }
259 var classkey = RTT.getTypeKey(name);
260 rtt = new RTT(classkey, typekey, old.typeArgs, old.returnType, old.functionTyp e, named);
261 RTT.types[typekey] = rtt;
262 rtt.implementedTypes = old.implementedTypes
263 return rtt;
264 };
265
227 /** 266 /**
228 * @param {string} classkey 267 * @param {string} classkey
229 * @param {Array.<(RTT|string)>=} typeargs 268 * @param {Array.<(RTT|string)>=} typeargs
230 * @param {string} returntype 269 * @param {string} returntype
270 * @param {string=} named optional
231 * @return {string} 271 * @return {string}
232 */ 272 */
233 RTT.getTypeKey = function(classkey, typeargs, returntype) { 273 RTT.getTypeKey = function(classkey, typeargs, returntype, named) {
234 var key = classkey; 274 var key = classkey;
275 if (named) {
276 key += ":" + named;
277 }
235 if (typeargs) { 278 if (typeargs) {
236 key += "<" + typeargs.join(",") + ">"; 279 key += "<" + typeargs.join(",") + ">";
237 } 280 }
238 if (returntype) { 281 if (returntype) {
239 key += "-><" + returntype + ">"; 282 key += "-><" + returntype + ">";
240 } 283 }
241 return key; 284 return key;
242 }; 285 };
243 286
244 /** 287 /**
(...skipping 20 matching lines...) Expand all
265 */ 308 */
266 RTT.removeTypeInfo = function(o) { 309 RTT.removeTypeInfo = function(o) {
267 o.$typeInfo = null; 310 o.$typeInfo = null;
268 return o; 311 return o;
269 }; 312 };
270 313
271 /** 314 /**
272 * The typeArg array is optional 315 * The typeArg array is optional
273 * @param {Array.<RTT>=} typeArgs 316 * @param {Array.<RTT>=} typeArgs
274 * @param {number} i 317 * @param {number} i
318 * @param {string=} named optional
275 * @return {RTT} 319 * @return {RTT}
276 */ 320 */
277 RTT.getTypeArg = function(typeArgs, i) { 321 RTT.getTypeArg = function(typeArgs, i, named) {
278 if (typeArgs) { 322 if (typeArgs) {
279 if (typeArgs.length > i) { 323 if (typeArgs.length > i) {
324 if (named && named != typeArgs[i].named) {
325 return RTT.clone(typeArgs[i], named);
326 }
280 return typeArgs[i]; 327 return typeArgs[i];
281 } else { 328 } else {
282 throw new Error("Missing type arg"); 329 throw new Error("Missing type arg");
283 } 330 }
284 } 331 }
285 return RTT.dynamicType; 332 return RTT.dynamicType.$lookupRTT(null,named);
286 }; 333 };
287 334
288 /** 335 /**
289 * The typeArg array is optional 336 * The typeArg array is optional
290 * @param {*} o 337 * @param {*} o
291 * @param {string} classkey 338 * @param {string} classkey
292 * @return {Array.<RTT>} 339 * @return {Array.<RTT>}
293 */ 340 */
294 RTT.getTypeArgsFor = function(o, classkey) { 341 RTT.getTypeArgsFor = function(o, classkey) {
295 var rtt = $mapLookup(RTT.getTypeInfo(o).implementedTypes, classkey); 342 var rtt = $mapLookup(RTT.getTypeInfo(o).implementedTypes, classkey);
296 if (!rtt) { 343 if (!rtt) {
297 throw new Error("internal error: can not find " + 344 throw new Error("internal error: can not find " +
298 classkey + " in " + JSON.stringify(o)); 345 classkey + " in " + JSON.stringify(o));
299 } 346 }
300 return rtt.typeArgs; 347 return rtt.typeArgs;
301 }; 348 };
302 349
303 // Base types for runtime type information 350 // Base types for runtime type information
304 351
305 /** @type {!RTT} */ 352 /** @type {!RTT} */
306 function ImplementsAll(name) { 353 function ImplementsAll(name,named) {
307 RTT.call(this,name); 354 var typeKey = RTT.getTypeKey(name, null, null, named);
355 RTT.call(this,name,typeKey,null,null,null,named);
308 } 356 }
309 $inherits(ImplementsAll,RTT); 357 $inherits(ImplementsAll,RTT);
310 ImplementsAll.prototype.implementedBy = function(o) {return true}; 358 ImplementsAll.prototype.implementedBy = function(o) {return true};
311 ImplementsAll.prototype.implementedByType = function(o) {return true}; 359 ImplementsAll.prototype.implementedByType = function(o) {return true};
312 360
313 RTT.objectType = new ImplementsAll($cls('Object')); 361 RTT.objectType = new ImplementsAll($cls('Object'));
314 RTT.dynamicType = new ImplementsAll($cls('Dynamic'));
315 RTT.placeholderType = new ImplementsAll($cls('::')); 362 RTT.placeholderType = new ImplementsAll($cls('::'));
316 363
364 function ImplementsDynamic(named) {
365 ImplementsAll.call(this,$cls('Dynamic'),named);
366 }
367 $inherits(ImplementsDynamic,ImplementsAll);
368 ImplementsDynamic.prototype.$lookupRTT = function(typeArgs, named) {
369 var typekey = RTT.getTypeKey($cls('Dynamic'), null, null, named);
370 var rtt = $mapLookup(RTT.types, typekey);
371 if (rtt) {
372 return rtt;
373 }
374 rtt = new ImplementsDynamic(named);
375 RTT.types[typekey] = rtt;
376 return rtt;
377 }
378 RTT.dynamicType = ImplementsDynamic.prototype.$lookupRTT();
379
317 /** 380 /**
318 * Checks that a value is assignable to an expected type, and either returns tha t 381 * Checks that a value is assignable to an expected type, and either returns tha t
319 * value if it is, or else throws a TypeMismatchException. 382 * value if it is, or else throws a TypeMismatchException.
320 * 383 *
321 * @param {!RTT} the expected type 384 * @param {!RTT} the expected type
322 * @param {*} the value to check 385 * @param {*} the value to check
323 * @return {*} the value 386 * @return {*} the value
324 */ 387 */
325 function $chk(rtt, value) { 388 function $chk(rtt, value) {
326 // null can be assigned to any type 389 // null can be assigned to any type
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 return typeof o == 'number'; 435 return typeof o == 'number';
373 } 436 }
374 437
375 /** 438 /**
376 * @param {*} o 439 * @param {*} o
377 * @return {boolean} 440 * @return {boolean}
378 */ 441 */
379 function $isString(o) { 442 function $isString(o) {
380 return typeof o == 'string'; 443 return typeof o == 'string';
381 } 444 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698