OLD | NEW |
---|---|
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 */ |
(...skipping 17 matching lines...) Expand all Loading... | |
69 for(var i = this.typeArgs.length - 1; i >= 0; i--) { | 74 for(var i = this.typeArgs.length - 1; i >= 0; i--) { |
70 if (!this.typeArgs[i].implementedByType(targetTypeInfo.typeArgs[i])) { | 75 if (!this.typeArgs[i].implementedByType(targetTypeInfo.typeArgs[i])) { |
71 return false; | 76 return false; |
72 } | 77 } |
73 } | 78 } |
74 } | 79 } |
75 return true; | 80 return true; |
76 }; | 81 }; |
77 | 82 |
78 /** | 83 /** |
84 * @param {!RTT} other | |
85 * @return {boolean} Whether this type is implement by other | |
86 */ | |
87 RTT.prototype.implementedByTypeFunc = function(otherType) { | |
88 if (otherType === this || otherType === RTT.dynamicType) { | |
89 return true; | |
90 } | |
91 var found = true; | |
92 var props = Object.getOwnPropertyNames(otherType.implementedTypes); | |
93 for (var i = 0 ; i < props.length; i++) { | |
94 found = true; | |
95 var mapped = otherType.implementedTypes[props[i]]; | |
96 if (mapped.returnType && this.returnType) { | |
97 if (!this.returnType.implementedByType(mapped.returnType)) { | |
98 continue; | |
99 } | |
100 } else if (mapped.returnType || this.returnType) { | |
101 continue; //handles mixed undef/defined. undef/undef falls through | |
102 } | |
103 if (mapped.typeArgs && this.typeArgs) { | |
104 for(var i = this.typeArgs.length - 1; i >= 0; i--) { | |
zundel
2011/11/08 15:28:42
you are re-using 'i' here, its already used as an
codefu
2011/11/14 19:33:40
Done.
| |
105 if (!this.typeArgs[i].implementedByType(mapped.typeArgs[i])) { | |
106 found = false; | |
107 break; // fall through and search the next property | |
zundel
2011/11/08 15:28:42
So, one of the type args doesn't match. From what
codefu
2011/11/14 19:33:40
I've changed this around a little in the new patch
| |
108 } | |
109 } | |
110 } else if (mapped.typeArgs || this.typeArgs) { | |
111 continue; //handles mixed undef/defined. undef/undef falls through | |
112 } | |
113 if ( found == true ) { | |
114 return true; | |
115 } | |
116 } | |
117 return false; | |
118 }; | |
119 | |
120 /** | |
79 * @return {string} the class name associated with this type | 121 * @return {string} the class name associated with this type |
80 */ | 122 */ |
81 RTT.prototype.getClassName = function() { | 123 RTT.prototype.getClassName = function() { |
82 var name = this.classKey; | 124 var name = this.classKey; |
83 if (name.substr(0, 4) == "cls:") { | 125 if (name.substr(0, 4) == "cls:") { |
84 name = name.substr(4); | 126 name = name.substr(4); |
85 } | 127 } |
86 if (name.substr(-5) == "$Dart") { | 128 if (name.substr(-5) == "$Dart") { |
87 name = name.substr(0, name.length - 5); | 129 name = name.substr(0, name.length - 5); |
88 } | 130 } |
(...skipping 19 matching lines...) Expand all Loading... | |
108 case 'number': return Number.$lookupRTT(); | 150 case 'number': return Number.$lookupRTT(); |
109 case 'boolean': return Boolean.$lookupRTT(); | 151 case 'boolean': return Boolean.$lookupRTT(); |
110 } | 152 } |
111 return RTT.placeholderType; | 153 return RTT.placeholderType; |
112 }; | 154 }; |
113 | 155 |
114 /** | 156 /** |
115 * @param {string} name | 157 * @param {string} name |
116 * @param {function(RTT,Array.<RTT>)=} implementsSupplier | 158 * @param {function(RTT,Array.<RTT>)=} implementsSupplier |
117 * @param {Array.<RTT>=} typeArgs | 159 * @param {Array.<RTT>=} typeArgs |
160 * @param {<RTT>=} returnType (if defined) | |
161 * @param {bool} type is a function | |
118 * @return {RTT} The RTT information object | 162 * @return {RTT} The RTT information object |
119 */ | 163 */ |
120 RTT.create = function(name, implementsSupplier, typeArgs) { | 164 RTT.create = function(name, implementsSupplier, typeArgs, returnType, funtionTyp e) { |
121 if (name == $cls("Object")) return RTT.objectType; | 165 if (name == $cls("Object")) return RTT.objectType; |
122 var typekey = RTT.getTypeKey(name, typeArgs); | 166 var typekey = RTT.getTypeKey(name, typeArgs, returnType); |
123 var rtt = $mapLookup(RTT.types, typekey); | 167 var rtt = $mapLookup(RTT.types, typekey); |
124 if (rtt) { | 168 if (rtt) { |
125 return rtt; | 169 return rtt; |
126 } | 170 } |
127 var classkey = RTT.getTypeKey(name); | 171 var classkey = RTT.getTypeKey(name); |
128 rtt = new RTT(classkey, typekey, typeArgs); | 172 rtt = new RTT(classkey, typekey, typeArgs, returnType, funtionType); |
129 RTT.types[typekey] = rtt; | 173 RTT.types[typekey] = rtt; |
130 if (implementsSupplier) { | 174 if (!funtionType && implementsSupplier) { |
131 implementsSupplier(rtt, typeArgs); | 175 implementsSupplier(rtt, typeArgs); |
132 } | 176 } |
133 return rtt; | 177 return rtt; |
134 }; | 178 }; |
135 | 179 |
136 /** | 180 /** |
137 * @param {string} classkey | 181 * @param {string} classkey |
138 * @param {Array.<(RTT|string)>=} typeargs | 182 * @param {Array.<(RTT|string)>=} typeargs |
183 * @param {string} returntype | |
139 * @return {string} | 184 * @return {string} |
140 */ | 185 */ |
141 RTT.getTypeKey = function(classkey, typeargs) { | 186 RTT.getTypeKey = function(classkey, typeargs, returntype) { |
142 var key = classkey; | 187 var key = classkey; |
143 if (typeargs) { | 188 if (typeargs) { |
144 key += "<" + typeargs.join(",") + ">"; | 189 key += "<" + typeargs.join(",") + ">"; |
145 } | 190 } |
191 if (returntype) { | |
192 key += "-><" + returntype + ">"; | |
193 } | |
146 return key; | 194 return key; |
147 }; | 195 }; |
148 | 196 |
149 /** | 197 /** |
150 * @return {*} value | 198 * @return {*} value |
151 * @return {RTT} return the RTT information object for the value | 199 * @return {RTT} return the RTT information object for the value |
152 */ | 200 */ |
153 RTT.getTypeInfo = function(value) { | 201 RTT.getTypeInfo = function(value) { |
154 return (value.$typeInfo) ? value.$typeInfo : RTT.getNativeTypeInfo(value); | 202 return (value.$typeInfo) ? value.$typeInfo : RTT.getNativeTypeInfo(value); |
155 }; | 203 }; |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
280 return typeof o == 'number'; | 328 return typeof o == 'number'; |
281 } | 329 } |
282 | 330 |
283 /** | 331 /** |
284 * @param {*} o | 332 * @param {*} o |
285 * @return {boolean} | 333 * @return {boolean} |
286 */ | 334 */ |
287 function $isString(o) { | 335 function $isString(o) { |
288 return typeof o == 'string'; | 336 return typeof o == 'string'; |
289 } | 337 } |
OLD | NEW |