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

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

Issue 8566022: Function type checking (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Cleanup / refactor 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
14 * @param {bool} functionType
13 */ 15 */
14 function RTT(classkey, typekey, typeargs) { 16 function RTT(classkey, typekey, typeargs, returnType, functionType) {
15 this.classKey = classkey; 17 this.classKey = classkey;
16 this.typeKey = typekey ? typekey : classkey; 18 this.typeKey = typekey ? typekey : classkey;
17 this.typeArgs = typeargs; 19 this.typeArgs = typeargs;
20 this.returnType = returnType; // key for the return type
18 this.implementedTypes = {}; 21 this.implementedTypes = {};
22 this.functionType = functionType;
19 // Add self 23 // Add self
20 this.implementedTypes[classkey] = this; 24 this.implementedTypes[classkey] = this;
21 // Add Object 25 // Add Object
22 if (classkey != $cls('Object')) { 26 if (!functionType && classkey != $cls('Object')) {
23 this.implementedTypes[$cls('Object')] = RTT.objectType; 27 this.implementedTypes[$cls('Object')] = RTT.objectType;
24 } 28 }
25 } 29 }
26 30
27 /** @type {Object.<string, Object>} */ 31 /** @type {Object.<string, Object>} */
28 RTT.types = {}; 32 RTT.types = {};
29 33
30 /** @type {Array.<RTT>} */ 34 /** @type {Array.<RTT>} */
31 RTT.prototype.derivedTypes = []; 35 RTT.prototype.derivedTypes = [];
32 36
33 /** @return {string} */ 37 /** @return {string} */
34 RTT.prototype.toString = function() { return this.typeKey; } 38 RTT.prototype.toString = function() { return this.typeKey; }
35 39
36 /** 40 /**
37 * @param {*} value 41 * @param {*} value
38 * @return {boolean} Whether this type is implemented by the value 42 * @return {boolean} Whether this type is implemented by the value
39 */ 43 */
40 RTT.prototype.implementedBy = function(value){ 44 RTT.prototype.implementedBy = function(value){
41 return (value == null) ? RTT.nullInstanceOf(this) : 45 return (value == null) ? RTT.nullInstanceOf(this) :
46 this.functionType ? this.implementedByTypeFunc(value) :
42 this.implementedByType(RTT.getTypeInfo(value)); 47 this.implementedByType(RTT.getTypeInfo(value));
43 }; 48 };
44 49
45 /** 50 /**
46 * A helper function for safely looking up a value 51 * A helper function for safely looking up a value
47 * in a Object used as a map. 52 * in a Object used as a map.
48 * @param {Object.<*>} map 53 * @param {Object.<*>} map
49 * @param {srting} key 54 * @param {srting} key
50 * @return {*} the value or null; 55 * @return {*} the value or null;
51 */ 56 */
52 function $mapLookup(map, key) { 57 function $mapLookup(map, key) {
53 return map.hasOwnProperty(key) ? map[key] : null; 58 return map.hasOwnProperty(key) ? map[key] : null;
54 } 59 }
55 60
61 RTT.prototype.implementedByTypeSwitch = function(value){
62 return this.functionType ? this.implementedByTypeFunc(value) :
63 this.implementedByType(value);
64 };
65
56 /** 66 /**
57 * @param {!RTT} other 67 * @param {!RTT} other
58 * @return {boolean} Whether this type is implement by other 68 * @return {boolean} Whether this type is implement by other
59 */ 69 */
60 RTT.prototype.implementedByType = function(otherType) { 70 RTT.prototype.implementedByType = function(otherType) {
61 if (otherType === this || otherType === RTT.dynamicType) { 71 if (otherType === this || otherType === RTT.dynamicType) {
62 return true; 72 return true;
63 } 73 }
64 var targetTypeInfo = $mapLookup(otherType.implementedTypes, this.classKey); 74 var targetTypeInfo = $mapLookup(otherType.implementedTypes, this.classKey);
65 if (targetTypeInfo == null) { 75 if (targetTypeInfo == null) {
66 return false; 76 return false;
67 } 77 }
68 if (targetTypeInfo.typeArgs && this.typeArgs) { 78 if (targetTypeInfo.typeArgs && this.typeArgs) {
69 for(var i = this.typeArgs.length - 1; i >= 0; i--) { 79 for(var i = this.typeArgs.length - 1; i >= 0; i--) {
70 if (!this.typeArgs[i].implementedByType(targetTypeInfo.typeArgs[i])) { 80 if (!this.typeArgs[i].implementedByTypeSwitch(targetTypeInfo.typeArgs[i])) {
71 return false; 81 return false;
72 } 82 }
73 } 83 }
74 } 84 }
75 return true; 85 return true;
76 }; 86 };
77 87
78 /** 88 /**
89 * @param {!RTT} other
90 * @return {boolean} Whether this type is assignable by other
91 */
92 RTT.prototype.assignableByType = function(otherType) {
93 if (otherType === this || otherType === RTT.dynamicType || this === RTT.dynami cType) {
94 return true;
95 }
96 var targetTypeInfo = $mapLookup(otherType.implementedTypes, this.classKey);
97 if (targetTypeInfo == null) {
98 targetTypeInfo = $mapLookup(this.implementedTypes, otherType.classKey);
99 if (targetTypeInfo == null) {
100 return false;
101 }
102 }
103 if (targetTypeInfo.typeArgs && this.typeArgs) {
104 for(var i = this.typeArgs.length - 1; i >= 0; i--) {
105 if (!this.typeArgs[i].assignableByType(targetTypeInfo.typeArgs[i])) {
106 return false;
107 }
108 }
109 }
110 return true;
111 };
112
113
114 /**
115 * @param {!RTT} other
116 * @return {boolean} Whether this type is implement by other
zundel 2011/11/29 21:53:46 implement --> implemented
codefu 2011/11/29 22:42:13 Done.
117 */
118 RTT.prototype.implementedByTypeFunc = function(otherType) {
119 if (otherType.hasOwnProperty("$lookupRTT")) {
120 otherType = otherType.$lookupRTT();
121 } else if (!(otherType instanceof RTT)) {
122 return false;
123 }
124 if (otherType === this || otherType === RTT.dynamicType) {
125 return true;
126 }
127 var props = Object.getOwnPropertyNames(otherType.implementedTypes);
128 NEXT_PROPERTY: for (var i = 0 ; i < props.length; i++) {
129 var mapped = otherType.implementedTypes[props[i]];
130 if (mapped.returnType && this.returnType &&
131 !this.returnType.assignableByType(mapped.returnType)) {
132 continue;
133 }
134 if (mapped.typeArgs && this.typeArgs) {
135 if (this.typeArgs.length != mapped.typeArgs.length) {
136 continue;
137 }
138 for (var x = this.typeArgs.length - 1; x >= 0; x--) {
139 if (!this.typeArgs[x].assignableByType(mapped.typeArgs[x])) {
140 continue NEXT_PROPERTY;
141 }
142 }
143 }
144 return true;
145 }
146 return false;
147 };
148
149 /**
79 * @return {string} the class name associated with this type 150 * @return {string} the class name associated with this type
80 */ 151 */
81 RTT.prototype.getClassName = function() { 152 RTT.prototype.getClassName = function() {
82 var name = this.classKey; 153 var name = this.classKey;
83 if (name.substr(0, 4) == "cls:") { 154 if (name.substr(0, 4) == "cls:") {
84 name = name.substr(4); 155 name = name.substr(4);
85 } 156 }
86 if (name.substr(-5) == "$Dart") { 157 if (name.substr(-5) == "$Dart") {
87 name = name.substr(0, name.length - 5); 158 name = name.substr(0, name.length - 5);
88 } 159 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 var classkey = RTT.getTypeKey(name); 198 var classkey = RTT.getTypeKey(name);
128 rtt = new RTT(classkey, typekey, typeArgs); 199 rtt = new RTT(classkey, typekey, typeArgs);
129 RTT.types[typekey] = rtt; 200 RTT.types[typekey] = rtt;
130 if (implementsSupplier) { 201 if (implementsSupplier) {
131 implementsSupplier(rtt, typeArgs); 202 implementsSupplier(rtt, typeArgs);
132 } 203 }
133 return rtt; 204 return rtt;
134 }; 205 };
135 206
136 /** 207 /**
208 * @param {Array.<RTT>=} typeArgs
209 * @param {<RTT>=} returnType (if defined)
210 * @return {RTT} The RTT information object
211 */
212 RTT.createFunction = function(typeArgs, returnType) {
213 var name = $cls("Function");
214 var typekey = RTT.getTypeKey(name, typeArgs, returnType);
215 var rtt = $mapLookup(RTT.types, typekey);
216 if (rtt) {
217 return rtt;
218 }
219 var classkey = RTT.getTypeKey(name);
220 rtt = new RTT(classkey, typekey, typeArgs, returnType, true);
221 RTT.types[typekey] = rtt;
222 return rtt;
223 };
224
225 /**
137 * @param {string} classkey 226 * @param {string} classkey
138 * @param {Array.<(RTT|string)>=} typeargs 227 * @param {Array.<(RTT|string)>=} typeargs
228 * @param {string} returntype
139 * @return {string} 229 * @return {string}
140 */ 230 */
141 RTT.getTypeKey = function(classkey, typeargs) { 231 RTT.getTypeKey = function(classkey, typeargs, returntype) {
142 var key = classkey; 232 var key = classkey;
143 if (typeargs) { 233 if (typeargs) {
144 key += "<" + typeargs.join(",") + ">"; 234 key += "<" + typeargs.join(",") + ">";
145 } 235 }
236 if (returntype) {
237 key += "-><" + returntype + ">";
238 }
146 return key; 239 return key;
147 }; 240 };
148 241
149 /** 242 /**
150 * @return {*} value 243 * @return {*} value
151 * @return {RTT} return the RTT information object for the value 244 * @return {RTT} return the RTT information object for the value
152 */ 245 */
153 RTT.getTypeInfo = function(value) { 246 RTT.getTypeInfo = function(value) {
154 return (value.$typeInfo) ? value.$typeInfo : RTT.getNativeTypeInfo(value); 247 return (value.$typeInfo) ? value.$typeInfo : RTT.getNativeTypeInfo(value);
155 }; 248 };
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 return typeof o == 'number'; 373 return typeof o == 'number';
281 } 374 }
282 375
283 /** 376 /**
284 * @param {*} o 377 * @param {*} o
285 * @return {boolean} 378 * @return {boolean}
286 */ 379 */
287 function $isString(o) { 380 function $isString(o) {
288 return typeof o == 'string'; 381 return typeof o == 'string';
289 } 382 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698