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

Side by Side Diff: tool/input_sdk/private/ddc_runtime/operations.dart

Issue 1926283002: implement generic method runtime behavior, fixes #301 (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 4 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 runtime operations on objects used by the code 5 /// This library defines runtime operations on objects used by the code
6 /// generator. 6 /// generator.
7 part of dart._runtime; 7 part of dart._runtime;
8 8
9 _canonicalFieldName(obj, name, args, displayName) => JS('', '''(() => { 9 _canonicalFieldName(obj, name, args, displayName) => JS('', '''(() => {
10 $name = $canonicalMember($obj, $name); 10 $name = $canonicalMember($obj, $name);
(...skipping 21 matching lines...) Expand all
32 dput(obj, field, value) => JS('', '''(() => { 32 dput(obj, field, value) => JS('', '''(() => {
33 $field = $_canonicalFieldName($obj, $field, [$value], $field); 33 $field = $_canonicalFieldName($obj, $field, [$value], $field);
34 // TODO(vsm): Implement NSM and type checks. 34 // TODO(vsm): Implement NSM and type checks.
35 // See: https://github.com/dart-lang/dev_compiler/issues/170 35 // See: https://github.com/dart-lang/dev_compiler/issues/170
36 $obj[$field] = $value; 36 $obj[$field] = $value;
37 return $value; 37 return $value;
38 })()'''); 38 })()''');
39 39
40 /// Check that a function of a given type can be applied to 40 /// Check that a function of a given type can be applied to
41 /// actuals. 41 /// actuals.
42 checkApply(type, actuals) => JS('', '''(() => { 42 _checkApply(type, actuals) => JS('', '''(() => {
43 if ($actuals.length < $type.args.length) return false; 43 if ($actuals.length < $type.args.length) return false;
44 let index = 0; 44 let index = 0;
45 for(let i = 0; i < $type.args.length; ++i) { 45 for(let i = 0; i < $type.args.length; ++i) {
46 if (!$instanceOfOrNull($actuals[i], $type.args[i])) return false; 46 if (!$instanceOfOrNull($actuals[i], $type.args[i])) return false;
47 ++index; 47 ++index;
48 } 48 }
49 if ($actuals.length == $type.args.length) return true; 49 if ($actuals.length == $type.args.length) return true;
50 let extras = $actuals.length - $type.args.length; 50 let extras = $actuals.length - $type.args.length;
51 if ($type.optionals.length > 0) { 51 if ($type.optionals.length > 0) {
52 if (extras > $type.optionals.length) return false; 52 if (extras > $type.optionals.length) return false;
(...skipping 27 matching lines...) Expand all
80 80
81 throwNoSuchMethod(obj, name, pArgs, nArgs, extras) => JS('', '''(() => { 81 throwNoSuchMethod(obj, name, pArgs, nArgs, extras) => JS('', '''(() => {
82 $throw_(new $NoSuchMethodError($obj, $_dartSymbol($name), $pArgs, $nArgs, $ext ras)); 82 $throw_(new $NoSuchMethodError($obj, $_dartSymbol($name), $pArgs, $nArgs, $ext ras));
83 })()'''); 83 })()''');
84 84
85 throwNoSuchMethodFunc(obj, name, pArgs, opt_func) => JS('', '''(() => { 85 throwNoSuchMethodFunc(obj, name, pArgs, opt_func) => JS('', '''(() => {
86 if ($obj === void 0) $obj = $opt_func; 86 if ($obj === void 0) $obj = $opt_func;
87 $throwNoSuchMethod($obj, $name, $pArgs); 87 $throwNoSuchMethod($obj, $name, $pArgs);
88 })()'''); 88 })()''');
89 89
90 checkAndCall(f, ftype, obj, args, name) => JS('', '''(() => { 90 _checkAndCall(f, ftype, obj, typeArgs, args, name) => JS('', '''(() => {
91 let originalFunction = $f; 91 let originalFunction = $f;
92 if (!($f instanceof Function)) { 92 if (!($f instanceof Function)) {
93 // We're not a function (and hence not a method either) 93 // We're not a function (and hence not a method either)
94 // Grab the `call` method if it's not a function. 94 // Grab the `call` method if it's not a function.
95 if ($f != null) { 95 if ($f != null) {
96 $ftype = $getMethodType($f, 'call'); 96 $ftype = $getMethodType($f, 'call');
97 $f = $f.call; 97 $f = $f.call;
98 } 98 }
99 if (!($f instanceof Function)) { 99 if (!($f instanceof Function)) {
100 $throwNoSuchMethodFunc($obj, $name, $args, originalFunction); 100 $throwNoSuchMethodFunc($obj, $name, $args, originalFunction);
101 } 101 }
102 } 102 }
103 // If f is a function, but not a method (no method type) 103 // If f is a function, but not a method (no method type)
104 // then it should have been a function valued field, so 104 // then it should have been a function valued field, so
105 // get the type from the function. 105 // get the type from the function.
106 if ($ftype === void 0) { 106 if ($ftype === void 0) {
107 $ftype = $read($f); 107 $ftype = $read($f);
108 } 108 }
109 109
110 if (!$ftype) { 110 if (!$ftype) {
111 // TODO(leafp): Allow JS objects to go through? 111 // TODO(leafp): Allow JS objects to go through?
112 // This includes the DOM. 112 if ($typeArgs != null) {
113 // TODO(jmesserly): is there a sensible way to handle these?
114 $throwStrongModeError('call to JS object `' + $obj +
115 '` with type arguments <' + $typeArgs + '> is not supported.');
116 }
113 return $f.apply($obj, $args); 117 return $f.apply($obj, $args);
114 } 118 }
115 119
116 if ($checkApply($ftype, $args)) { 120 // Apply type arguments
121 let formalCount = $ftype[$_typeFormalCount];
122 if (formalCount != null) {
123 if ($typeArgs == null) {
124 $typeArgs = Array(formalCount).fill($dynamicR);
Jennifer Messerly 2016/04/28 23:28:54 This should be instantiating to bounds. Related to
125 } else if ($typeArgs.length != formalCount) {
126 // TODO(jmesserly): is this the right error?
127 $throwStrongModeError(
128 'incorrect number of arguments to generic function ' +
129 $typeName($ftype) + ', got <' + $typeArgs + '> expected ' +
130 formalCount + '.');
131 }
132 // Instantiate the function.
133 $ftype = $ftype(...$typeArgs);
134 } else if ($typeArgs != null) {
135 $throwStrongModeError(
136 'got type arguments to non-generic function ' + $typeName($ftype) +
137 ', got <' + $typeArgs + '> expected none.');
138 }
139
140 if ($_checkApply($ftype, $args)) {
141 if ($typeArgs != null) {
142 return $f.apply($obj, $typeArgs).apply($obj, $args);
143 }
117 return $f.apply($obj, $args); 144 return $f.apply($obj, $args);
118 } 145 }
119 146
120 // TODO(leafp): throw a type error (rather than NSM) 147 // TODO(leafp): throw a type error (rather than NSM)
121 // if the arity matches but the types are wrong. 148 // if the arity matches but the types are wrong.
149 // TODO(jmesserly): nSM should include type args?
122 $throwNoSuchMethodFunc($obj, $name, $args, originalFunction); 150 $throwNoSuchMethodFunc($obj, $name, $args, originalFunction);
123 })()'''); 151 })()''');
124 152
125 dcall(f, @rest args) => JS('', '''(() => { 153 dcall(f, @rest args) =>
126 let ftype = $read($f); 154 _checkAndCall(f, read(f), JS('', 'void 0'), null, args, 'call');
127 return $checkAndCall($f, ftype, void 0, $args, 'call');
128 })()''');
129 155
130 /// Shared code for dsend, dindex, and dsetindex. */
131 callMethod(obj, name, args, displayName) => JS('', '''(() => {
132 let symbol = $_canonicalFieldName($obj, $name, $args, $displayName);
133 let f = $obj != null ? $obj[symbol] : null;
134 let ftype = $getMethodType($obj, $name);
135 return $checkAndCall(f, ftype, $obj, $args, $displayName);
136 })()''');
137 156
138 dsend(obj, method, @rest args) => JS('', '''(() => { 157 dgcall(f, typeArgs, @rest args) =>
139 return $callMethod($obj, $method, $args, $method); 158 _checkAndCall(f, read(f), JS('', 'void 0'), typeArgs, args, 'call');
140 })()''');
141 159
142 dindex(obj, index) => JS('', '''(() => {
143 return $callMethod($obj, 'get', [$index], '[]');
144 })()''');
145 160
146 dsetindex(obj, index, value) => JS('', '''(() => { 161 /// Shared code for dsend, dindex, and dsetindex.
147 $callMethod($obj, 'set', [$index, $value], '[]='); 162 _callMethod(obj, name, typeArgs, args, displayName) {
148 return $value; 163 var symbol = _canonicalFieldName(obj, name, args, displayName);
149 })()'''); 164 var f = obj != null ? JS('', '#[#]', obj, symbol) : null;
165 var ftype = getMethodType(obj, symbol);
166 return _checkAndCall(f, ftype, obj, typeArgs, args, displayName);
167 }
168
169 dsend(obj, method, @rest args) => _callMethod(obj, method, null, args, method);
170
171 dgsend(obj, typeArgs, method, @rest args) =>
172 _callMethod(obj, method, typeArgs, args, method);
173
174 dindex(obj, index) => _callMethod(obj, 'get', null, JS('', '[#]', index), '[]');
175
176 dsetindex(obj, index, value) =>
177 _callMethod(obj, 'set', null, JS('', '[#, #]', index, value), '[]=');
150 178
151 _ignoreTypeFailure(actual, type) => JS('', '''(() => { 179 _ignoreTypeFailure(actual, type) => JS('', '''(() => {
152 // TODO(vsm): Remove this hack ... 180 // TODO(vsm): Remove this hack ...
153 // This is primarily due to the lack of generic methods, 181 // This is primarily due to the lack of generic methods,
154 // but we need to triage all the types. 182 // but we need to triage all the types.
155 if ($isSubtype($type, $Iterable) && $isSubtype($actual, $Iterable) || 183 if ($isSubtype($type, $Iterable) && $isSubtype($actual, $Iterable) ||
156 $isSubtype($type, $Future) && $isSubtype($actual, $Future) || 184 $isSubtype($type, $Future) && $isSubtype($actual, $Future) ||
157 $isSubtype($type, $Map) && $isSubtype($actual, $Map) || 185 $isSubtype($type, $Map) && $isSubtype($actual, $Map) ||
158 $isSubtype($type, $Function) && $isSubtype($actual, $Function) || 186 $isSubtype($type, $Function) && $isSubtype($actual, $Function) ||
159 $isSubtype($type, $Stream) && $isSubtype($actual, $Stream) || 187 $isSubtype($type, $Stream) && $isSubtype($actual, $Stream) ||
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 constructor(dartIterator) { 455 constructor(dartIterator) {
428 this.dartIterator = dartIterator; 456 this.dartIterator = dartIterator;
429 } 457 }
430 next() { 458 next() {
431 let i = this.dartIterator; 459 let i = this.dartIterator;
432 let done = !i.moveNext(); 460 let done = !i.moveNext();
433 return { done: done, value: done ? void 0 : i.current }; 461 return { done: done, value: done ? void 0 : i.current };
434 } 462 }
435 } 463 }
436 '''); 464 ''');
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698