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

Side by Side Diff: pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart

Issue 2847893002: fix #27258, don't allow dynamic set of a final field (Closed)
Patch Set: format Created 3 years, 7 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
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 /// This library defines the operations that define and manipulate Dart 5 /// This library defines the operations that define and manipulate Dart
6 /// classes. Included in this are: 6 /// classes. Included in this are:
7 /// - Generics 7 /// - Generics
8 /// - Class metadata 8 /// - Class metadata
9 /// - Extension methods 9 /// - Extension methods
10 /// 10 ///
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 getGetterSig(value) => JS('', '#[#]', value, _getterSig); 190 getGetterSig(value) => JS('', '#[#]', value, _getterSig);
191 getSetterSig(value) => JS('', '#[#]', value, _setterSig); 191 getSetterSig(value) => JS('', '#[#]', value, _setterSig);
192 getStaticSig(value) => JS('', '#[#]', value, _staticSig); 192 getStaticSig(value) => JS('', '#[#]', value, _staticSig);
193 getStaticFieldSig(value) => JS('', '#[#]', value, _staticFieldSig); 193 getStaticFieldSig(value) => JS('', '#[#]', value, _staticFieldSig);
194 getStaticGetterSig(value) => JS('', '#[#]', value, _staticGetterSig); 194 getStaticGetterSig(value) => JS('', '#[#]', value, _staticGetterSig);
195 getStaticSetterSig(value) => JS('', '#[#]', value, _staticSetterSig); 195 getStaticSetterSig(value) => JS('', '#[#]', value, _staticSetterSig);
196 196
197 getGenericTypeCtor(value) => JS('', '#[#]', value, _genericTypeCtor); 197 getGenericTypeCtor(value) => JS('', '#[#]', value, _genericTypeCtor);
198 198
199 /// Get the type of a method from an object using the stored signature 199 /// Get the type of a method from an object using the stored signature
200 getType(obj) => JS( 200 getType(obj) =>
201 '', 201 JS('', '# == null ? # : #.__proto__.constructor', obj, Object, obj);
202 '''(() => {
203 return $obj == null ? $Object : $obj.__proto__.constructor;
204 })()''');
205 202
206 bool isJsInterop(obj) { 203 bool isJsInterop(obj) {
207 if (JS('bool', 'typeof # === "function"', obj)) { 204 if (JS('bool', 'typeof # === "function"', obj)) {
208 // A function is a Dart function if it has runtime type information. 205 // A function is a Dart function if it has runtime type information.
209 return _getRuntimeType(obj) == null; 206 return _getRuntimeType(obj) == null;
210 } 207 }
211 // Primitive types are not JS interop types. 208 // Primitive types are not JS interop types.
212 if (JS('bool', 'typeof # !== "object"', obj)) return false; 209 if (JS('bool', 'typeof # !== "object"', obj)) return false;
213 210
214 // Extension types are not considered JS interop types. 211 // Extension types are not considered JS interop types.
215 // Note that it is still possible to call typed JS interop methods on 212 // Note that it is still possible to call typed JS interop methods on
216 // extension types but the calls must be statically typed. 213 // extension types but the calls must be statically typed.
217 if (getExtensionType(obj) != null) return false; 214 if (getExtensionType(obj) != null) return false;
218 return JS('bool', '!($obj instanceof $Object)'); 215 return JS('bool', '!($obj instanceof $Object)');
219 } 216 }
220 217
221 /// Get the type of a method from a type using the stored signature 218 /// Get the type of a method from a type using the stored signature
222 getMethodType(type, name) => JS( 219 getMethodType(type, name) {
223 '', 220 var m = JS('', '#[#]', type, _methodSig);
224 '''(() => { 221 return m != null ? JS('', '#[#]', m, name) : null;
225 let sigObj = $type[$_methodSig]; 222 }
226 if (sigObj === void 0) return void 0;
227 return sigObj[$name];
228 })()''');
229 223
230 getFieldType(type, name) => JS( 224 /// Gets the type of the corresponding setter (this includes writable fields).
231 '', 225 getSetterType(type, name) {
232 '''(() => { 226 var signature = JS('', '#[#]', type, _setterSig);
233 let sigObj = $type[$_fieldSig]; 227 if (signature != null) {
234 if (sigObj === void 0) return void 0; 228 var type = JS('', '#[#]', signature, name);
235 let fieldType = sigObj[$name]; 229 if (type != null) {
236 // workaround to handle metadata. 230 // TODO(jmesserly): it would be nice not to encode setters with a full
237 return (fieldType instanceof Array) ? fieldType[0] : fieldType; 231 // function type.
238 })()'''); 232 return JS('', '#.args[0]', type);
233 }
234 }
235 signature = JS('', '#[#]', type, _fieldSig);
236 if (signature != null) {
237 var fieldInfo = JS('', '#[#]', signature, name);
238 if (fieldInfo != null && JS('bool', '!#.isFinal', fieldInfo)) {
239 return JS('', '#.type', fieldInfo);
240 }
241 }
242 return null;
243 }
239 244
240 getSetterType(type, name) => JS( 245 finalFieldType(type, metadata) =>
241 '', 246 JS('', '{ type: #, isFinal: true, metadata: # }', type, metadata);
242 '''(() => { 247
243 let sigObj = $type[$_setterSig]; 248 fieldType(type, metadata) =>
244 if (sigObj === void 0) return void 0; 249 JS('', '{ type: #, isFinal: false, metadata: # }', type, metadata);
245 return sigObj[$name];
246 })()''');
247 250
248 /// Get the type of a constructor from a class using the stored signature 251 /// Get the type of a constructor from a class using the stored signature
249 /// If name is undefined, returns the type of the default constructor 252 /// If name is undefined, returns the type of the default constructor
250 /// Returns undefined if the constructor is not found. 253 /// Returns undefined if the constructor is not found.
251 classGetConstructorType(cls, name) => JS( 254 classGetConstructorType(cls, name) => JS(
252 '', 255 '',
253 '''(() => { 256 '''(() => {
254 if(!$name) $name = 'new'; 257 if(!$name) $name = 'new';
255 if ($cls === void 0) return void 0; 258 if ($cls === void 0) return void 0;
256 if ($cls == null) return void 0; 259 if ($cls == null) return void 0;
(...skipping 14 matching lines...) Expand all
271 '', 274 '',
272 '''(() => { 275 '''(() => {
273 if ($f === void 0) $f = $obj[$name]; 276 if ($f === void 0) $f = $obj[$name];
274 // TODO(jmesserly): track the function's signature on the function, instead 277 // TODO(jmesserly): track the function's signature on the function, instead
275 // of having to go back to the class? 278 // of having to go back to the class?
276 let sig = $getMethodType($getType($obj), $name); 279 let sig = $getMethodType($getType($obj), $name);
277 280
278 // JS interop case: do not bind this for compatibility with the dart2js 281 // JS interop case: do not bind this for compatibility with the dart2js
279 // implementation where we cannot bind this reliably here until we trust 282 // implementation where we cannot bind this reliably here until we trust
280 // types more. 283 // types more.
281 if (sig === void 0) return $f; 284 if (sig == null) return $f;
282 285
283 $f = $f.bind($obj); 286 $f = $f.bind($obj);
284 $tag($f, sig); 287 $tag($f, sig);
285 return $f; 288 return $f;
286 })()'''); 289 })()''');
287 290
288 /// Instantiate a generic method. 291 /// Instantiate a generic method.
289 /// 292 ///
290 /// We need to apply the type arguments both to the function, as well as its 293 /// We need to apply the type arguments both to the function, as well as its
291 /// associated function type. 294 /// associated function type.
292 gbind(f, @rest typeArgs) { 295 gbind(f, @rest typeArgs) {
293 var result = JS('', '#.apply(null, #)', f, typeArgs); 296 var result = JS('', '#.apply(null, #)', f, typeArgs);
294 var sig = JS('', '#.instantiate(#)', _getRuntimeType(f), typeArgs); 297 var sig = JS('', '#.instantiate(#)', _getRuntimeType(f), typeArgs);
295 tag(result, sig); 298 tag(result, sig);
296 return result; 299 return result;
297 } 300 }
298 301
299 // Set up the method signature field on the constructor 302 // Set up the method signature field on the constructor
300 _setInstanceSignature(f, sigF, kind) => JS( 303 _setInstanceSignature(f, sigF, kind) => defineMemoizedGetter(
301 '', 304 f,
302 '''(() => { 305 kind,
303 $defineMemoizedGetter($f, $kind, () => { 306 JS(
304 let sigObj = $sigF(); 307 '',
305 let proto = $f.__proto__; 308 '''() => {
306 // We need to set the root proto to null not undefined. 309 let sigObj = #();
307 sigObj.__proto__ = ($kind in proto) ? proto[$kind] : null; 310 let proto = #.__proto__;
308 return sigObj; 311 // We need to set the root proto to null not undefined.
309 }); 312 sigObj.__proto__ = (# in proto) ? proto[#] : null;
310 })()'''); 313 return sigObj;
314 }''',
315 sigF,
316 f,
317 kind,
318 kind));
311 319
312 _setMethodSignature(f, sigF) => _setInstanceSignature(f, sigF, _methodSig); 320 _setMethodSignature(f, sigF) => _setInstanceSignature(f, sigF, _methodSig);
313 _setFieldSignature(f, sigF) => _setInstanceSignature(f, sigF, _fieldSig); 321 _setFieldSignature(f, sigF) => _setInstanceSignature(f, sigF, _fieldSig);
314 _setGetterSignature(f, sigF) => _setInstanceSignature(f, sigF, _getterSig); 322 _setGetterSignature(f, sigF) => _setInstanceSignature(f, sigF, _getterSig);
315 _setSetterSignature(f, sigF) => _setInstanceSignature(f, sigF, _setterSig); 323 _setSetterSignature(f, sigF) => _setInstanceSignature(f, sigF, _setterSig);
316 324
317 // Set up the constructor signature field on the constructor 325 // Set up the constructor signature field on the constructor
318 _setConstructorSignature(f, sigF) => 326 _setConstructorSignature(f, sigF) =>
319 JS('', '$defineMemoizedGetter($f, $_constructorSig, $sigF)'); 327 JS('', '$defineMemoizedGetter($f, $_constructorSig, $sigF)');
320 328
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 '''(() => { 651 '''(() => {
644 let values = []; 652 let values = [];
645 for (var i = 0; i < $names.length; i++) { 653 for (var i = 0; i < $names.length; i++) {
646 let value = $const_(new $enumClass(i)); 654 let value = $const_(new $enumClass(i));
647 values.push(value); 655 values.push(value);
648 Object.defineProperty($enumClass, $names[i], 656 Object.defineProperty($enumClass, $names[i],
649 { value: value, configurable: true }); 657 { value: value, configurable: true });
650 } 658 }
651 $enumClass.values = $constList(values, $enumClass); 659 $enumClass.values = $constList(values, $enumClass);
652 })()'''); 660 })()''');
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698