Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 var dart; | 5 var dart; |
| 6 (function (dart) { | 6 (function (dart) { |
| 7 var defineProperty = Object.defineProperty; | 7 var defineProperty = Object.defineProperty; |
| 8 var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; | 8 var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; |
| 9 var getOwnPropertyNames = Object.getOwnPropertyNames; | 9 var getOwnPropertyNames = Object.getOwnPropertyNames; |
| 10 | 10 |
| 11 // Adapted from Angular.js | 11 // Adapted from Angular.js |
| 12 var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m; | 12 var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m; |
| 13 var METHOD_ARGS = /^[^\(]*\(\s*([^\)]*)\)/m | |
| 13 var FN_ARG_SPLIT = /,/; | 14 var FN_ARG_SPLIT = /,/; |
| 14 var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/; | 15 var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/; |
| 15 var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; | 16 var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; |
| 16 | 17 |
| 17 function formalParameterList(fn) { | 18 function formalParameterList(fn) { |
| 18 var fnText,argDecl; | 19 var fnText,argDecl; |
| 19 var args=[]; | 20 var args=[]; |
| 20 fnText = fn.toString().replace(STRIP_COMMENTS, ''); | 21 fnText = fn.toString().replace(STRIP_COMMENTS, ''); |
| 21 argDecl = fnText.match(FN_ARGS); | 22 argDecl = fnText.match(FN_ARGS); |
| 23 if (!argDecl) { | |
| 24 // TODO(vsm): This appears to match current V8. I don't see this spec'ed. | |
| 25 // ES 6 methods have a different syntax. | |
|
Jennifer Messerly
2015/02/26 20:53:16
fyi, this is spec'd in Function.prototype.toString
vsm
2015/03/03 21:06:12
Thanks! I made pointer to the spec and filed an i
| |
| 26 argDecl = fnText.match(METHOD_ARGS); | |
| 27 } | |
| 22 | 28 |
| 23 var r = argDecl[1].split(FN_ARG_SPLIT); | 29 var r = argDecl[1].split(FN_ARG_SPLIT); |
| 24 for(var a in r){ | 30 for(var a in r){ |
| 25 var arg = r[a]; | 31 var arg = r[a]; |
| 26 arg.replace(FN_ARG, function(all, underscore, name){ | 32 arg.replace(FN_ARG, function(all, underscore, name){ |
| 27 args.push(name); | 33 args.push(name); |
| 28 }); | 34 }); |
| 29 } | 35 } |
| 30 return args; | 36 return args; |
| 31 } | 37 } |
| 32 | 38 |
| 39 function isDartFunction(fn) { | |
| 40 // TODO(vsm): How do we differentiate? For now, just reject native methods. | |
|
Jennifer Messerly
2015/02/26 20:53:16
Assuming we still have the target object, "obj ins
vsm
2015/03/03 21:06:12
Thanks, added a pointer to the issue.
| |
| 41 // TODO(vsm): Make this more robust - e.g., a regexp. | |
| 42 return fn.toString().indexOf('[native code]') == -1; | |
| 43 } | |
| 44 | |
| 33 function dload(obj, field) { | 45 function dload(obj, field) { |
| 34 if (!(field in obj)) { | 46 if (!(field in obj)) { |
| 35 throw new core.NoSuchMethodError(obj, field); | 47 throw new core.NoSuchMethodError(obj, field); |
| 36 } | 48 } |
| 37 return obj[field]; | 49 return obj[field]; |
| 38 } | 50 } |
| 39 dart.dload = dload; | 51 dart.dload = dload; |
| 40 | 52 |
| 41 // TODO(jmesserly): this should call noSuchMethod, not throw. | 53 // TODO(jmesserly): this should call noSuchMethod, not throw. |
| 54 function dput(obj, field, value) { | |
| 55 if (!(field in obj)) { | |
| 56 throw new core.NoSuchMethodError(obj, field); | |
| 57 } | |
| 58 // TODO(vsm): Type check required. | |
| 59 obj[field] = value; | |
| 60 } | |
| 61 dart.dput = dput; | |
| 62 | |
| 42 function throwNoSuchMethod(obj, name, args, opt_func) { | 63 function throwNoSuchMethod(obj, name, args, opt_func) { |
| 43 if (obj === void 0) obj = opt_func; | 64 if (obj === void 0) obj = opt_func; |
| 44 throw new core.NoSuchMethodError(obj, name, args); | 65 throw new core.NoSuchMethodError(obj, name, args); |
| 45 } | 66 } |
| 46 | 67 |
| 68 function _numberInvoke(f, obj, args, name) { | |
| 69 var checkArg = function () { | |
| 70 var arg = args[0]; | |
| 71 if (typeof(arg) != 'number') { | |
| 72 throw 'invalid operation'; | |
| 73 } | |
| 74 return arg; | |
| 75 } | |
| 76 | |
| 77 // TODO(vsm): Implement all Dart int and double instance methods. | |
| 78 switch (name) { | |
| 79 case '+': | |
|
vsm
2015/02/26 00:34:00
Not sure which way we ought to go with these. Are
Jennifer Messerly
2015/02/26 20:53:16
probably not anymore, given the generalize type pr
| |
| 80 return (args.length == 0) ? obj : obj + checkArg(); | |
| 81 case '-': | |
| 82 return (args.length == 0) ? - obj : obj - checkArg(); | |
| 83 case '*': | |
| 84 return obj * checkArg(); | |
| 85 case '/': | |
| 86 return obj / checkArg(); | |
| 87 case '~/': | |
| 88 return (obj / checkArg()).truncate(); | |
| 89 case '<': | |
| 90 return obj < checkArg(); | |
| 91 } | |
| 92 throw new core.UnimplementedError(); | |
| 93 } | |
| 94 | |
| 95 function _booleanInvoke(f, obj, args, name) { | |
| 96 // TODO(vsm): Implement all Dart bool instance methods. | |
| 97 throw new core.UnimplementedError(); | |
| 98 } | |
| 99 | |
| 100 function _stringInvoke(f, obj, args, name) { | |
| 101 // TODO(vsm): Implement all Dart string instance methods. | |
| 102 throw new core.UnimplementedError(); | |
| 103 } | |
| 104 | |
| 47 function checkAndCall(f, obj, args, name) { | 105 function checkAndCall(f, obj, args, name) { |
| 106 if (obj != null && !(obj instanceof dart.Object)) { | |
| 107 // Check for primitive types. | |
|
Jennifer Messerly
2015/02/26 20:53:16
to build on previous comments ... Ideally, this wo
| |
| 108 if (typeof(obj) == 'number') { | |
| 109 return _numberInvoke(f, obj, args, name); | |
| 110 } else if (typeof(obj) == 'boolean') { | |
| 111 return _booleanInvoke(f, obj, args, name); | |
| 112 } else if (typeof(obj) == 'string') { | |
| 113 return _stringInvoke(f, obj, args, name); | |
| 114 } else { | |
| 115 // obj is a JavaScript or native object. Just call. | |
| 116 return f.apply(obj, args); | |
| 117 } | |
| 118 } | |
| 119 | |
| 48 if (!(f instanceof Function)) { | 120 if (!(f instanceof Function)) { |
| 49 // Grab the `call` method if it's not a function. | 121 // Grab the `call` method if it's not a function. |
| 50 if (f !== null) f = f.call; | 122 if (f !== null) f = f.call; |
| 51 if (!(f instanceof Function)) { | 123 if (!(f instanceof Function)) { |
| 52 throwNoSuchMethod(obj, method, args); | 124 throwNoSuchMethod(obj, method, args); |
| 53 } | 125 } |
| 54 } | 126 } |
| 127 | |
| 128 if (!isDartFunction(f)) { | |
|
Jennifer Messerly
2015/02/26 20:53:16
we could also just see if it has our type signatur
vsm
2015/03/03 21:06:12
Right, thinking isDartFunction would do something
| |
| 129 // A JS or native function. Just call. | |
| 130 return f.apply(obj, args); | |
| 131 } | |
| 132 | |
| 55 var formals = formalParameterList(f); | 133 var formals = formalParameterList(f); |
| 56 // TODO(vsm): Type check args! We need to encode sufficient type info on f. | 134 // TODO(vsm): Type check args! We need to encode sufficient type info on f. |
| 57 if (formals.length < args.length) { | 135 if (formals.length < args.length) { |
| 58 throwNoSuchMethod(obj, name, args, f); | 136 throwNoSuchMethod(obj, name, args, f); |
| 59 } else if (formals.length > args.length) { | 137 } else if (formals.length > args.length) { |
| 60 for (var i = args.length; i < formals.length; ++i) { | 138 for (var i = args.length; i < formals.length; ++i) { |
| 61 if (formals[i].indexOf("opt$") != 0) { | 139 if (formals[i].indexOf("opt$") != 0) { |
| 62 throwNoSuchMethod(obj, name, args, f); | 140 throwNoSuchMethod(obj, name, args, f); |
| 63 } | 141 } |
| 64 } | 142 } |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 348 var init = this[name]; | 426 var init = this[name]; |
| 349 var result = void 0; | 427 var result = void 0; |
| 350 if (init) result = init.apply(this, arguments); | 428 if (init) result = init.apply(this, arguments); |
| 351 return result === void 0 ? this : result; | 429 return result === void 0 ? this : result; |
| 352 }; | 430 }; |
| 353 // The initializer for dart.Object | 431 // The initializer for dart.Object |
| 354 dart.Object.prototype.Object = function() {}; | 432 dart.Object.prototype.Object = function() {}; |
| 355 dart.Object.prototype.constructor = dart.Object; | 433 dart.Object.prototype.constructor = dart.Object; |
| 356 | 434 |
| 357 })(dart || (dart = {})); | 435 })(dart || (dart = {})); |
| OLD | NEW |