OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 import 'dart:_internal' as internal; | 5 import 'dart:_internal' as internal; |
6 import 'dart:convert' show JSON; | 6 import 'dart:convert' show JSON; |
7 | 7 |
8 @patch class Error { | 8 @patch class Error { |
9 @patch static String _objectToString(Object object) { | 9 @patch static String _objectToString(Object object) { |
10 return Object._toString(object); | 10 return Object._toString(object); |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
159 static void _throwNew(Object receiver, | 159 static void _throwNew(Object receiver, |
160 String memberName, | 160 String memberName, |
161 int invocation_type, | 161 int invocation_type, |
162 List arguments, | 162 List arguments, |
163 List argumentNames, | 163 List argumentNames, |
164 List existingArgumentNames) { | 164 List existingArgumentNames) { |
165 int numNamedArguments = argumentNames == null ? 0 : argumentNames.length; | 165 int numNamedArguments = argumentNames == null ? 0 : argumentNames.length; |
166 int numPositionalArguments = arguments == null ? 0 : arguments.length; | 166 int numPositionalArguments = arguments == null ? 0 : arguments.length; |
167 numPositionalArguments -= numNamedArguments; | 167 numPositionalArguments -= numNamedArguments; |
168 List positionalArguments; | 168 List positionalArguments; |
169 if (numPositionalArguments == 0) { | 169 if (numPositionalArguments > 0) { |
170 // Differ between no arguments specified and 0 arguments. | 170 // TODO(srdjan): Unresolvable static methods sometimes do not provide the |
171 // TODO(srdjan): This can currently occur for unresolvable static methods. | 171 // arguments, because the arguments are evaluated but not passed to the |
172 // In that case, the arguments are evaluated but not passed to the | |
173 // throwing stub (see EffectGraphVisitor::BuildThrowNoSuchMethodError and | 172 // throwing stub (see EffectGraphVisitor::BuildThrowNoSuchMethodError and |
174 // Parser::ThrowNoSuchMethodError)). | 173 // Parser::ThrowNoSuchMethodError)). There is no way to distinguish the |
175 positionalArguments = argumentNames == null ? null : []; | 174 // case of no arguments from the case of the arguments not being passed |
176 } else { | 175 // in here, though. See https://github.com/dart-lang/sdk/issues/27572 |
177 positionalArguments = arguments.sublist(0, numPositionalArguments); | 176 positionalArguments = arguments.sublist(0, numPositionalArguments); |
178 } | 177 } |
179 Map<Symbol, dynamic> namedArguments = new Map<Symbol, dynamic>(); | 178 Map<Symbol, dynamic> namedArguments = new Map<Symbol, dynamic>(); |
180 for (int i = 0; i < numNamedArguments; i++) { | 179 for (int i = 0; i < numNamedArguments; i++) { |
181 var arg_value = arguments[numPositionalArguments + i]; | 180 var arg_value = arguments[numPositionalArguments + i]; |
182 namedArguments[new Symbol(argumentNames[i])] = arg_value; | 181 namedArguments[new Symbol(argumentNames[i])] = arg_value; |
183 } | 182 } |
184 throw new NoSuchMethodError._withType(receiver, | 183 throw new NoSuchMethodError._withType(receiver, |
185 new Symbol(memberName), | 184 new Symbol(memberName), |
186 invocation_type, | 185 invocation_type, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
227 (memberName is String) ? new Symbol(memberName) : memberName, | 226 (memberName is String) ? new Symbol(memberName) : memberName, |
228 this._namedArguments = | 227 this._namedArguments = |
229 (namedArguments == null) | 228 (namedArguments == null) |
230 ? null | 229 ? null |
231 : new Map<Symbol, dynamic>.fromIterable( | 230 : new Map<Symbol, dynamic>.fromIterable( |
232 namedArguments.keys, | 231 namedArguments.keys, |
233 key: (k) => (k is String) ? new Symbol(k) : k, | 232 key: (k) => (k is String) ? new Symbol(k) : k, |
234 value: (k) => namedArguments[k]), | 233 value: (k) => namedArguments[k]), |
235 this._existingArgumentNames = existingArgumentNames; | 234 this._existingArgumentNames = existingArgumentNames; |
236 | 235 |
237 | 236 @patch String toString() { |
238 String _developerMessage(args_mismatch) { | 237 var level = (_invocation_type >> _InvocationMirror._CALL_SHIFT) & |
239 if (_invocation_type < 0) { | 238 _InvocationMirror._CALL_MASK; |
240 return ""; | |
241 } | |
242 var type = _invocation_type & _InvocationMirror._TYPE_MASK; | 239 var type = _invocation_type & _InvocationMirror._TYPE_MASK; |
243 var level = (_invocation_type >> _InvocationMirror._CALL_SHIFT) & | 240 String memberName = (_memberName == null) ? "" : |
244 _InvocationMirror._CALL_MASK; | 241 internal.Symbol.getUnmangledName(_memberName); |
245 var type_str = | |
246 (const ["method", "getter", "setter", "getter or setter", "variable"])[t ype]; | |
247 var args_message = args_mismatch ? " with matching arguments" : ""; | |
248 var msg; | |
249 var memberName = | |
250 (_memberName == null) ? "" : internal.Symbol.getUnmangledName(_memberNam e); | |
251 | 242 |
252 if (type == _InvocationMirror._LOCAL_VAR) { | 243 if (type == _InvocationMirror._LOCAL_VAR) { |
253 return "cannot assign to final variable '$memberName'.\n\n"; | 244 return "NoSuchMethodError: Cannot assign to final variable '$memberName'"; |
254 } | 245 } |
246 | |
247 StringBuffer arguments = new StringBuffer(); | |
248 int argumentCount = 0; | |
249 if (_arguments == null) { | |
250 argumentCount = 0; | |
Cutch
2016/10/11 22:34:59
redundant
| |
251 } else { | |
252 for (; argumentCount < _arguments.length; argumentCount++) { | |
253 if (argumentCount > 0) { | |
254 arguments.write(", "); | |
255 } | |
256 arguments.write(Error.safeToString(_arguments[argumentCount])); | |
257 } | |
258 } | |
259 if (_namedArguments != null) { | |
260 _namedArguments.forEach((Symbol key, var value) { | |
261 if (argumentCount > 0) { | |
262 arguments.write(", "); | |
263 } | |
264 arguments.write(internal.Symbol.getUnmangledName(key)); | |
265 arguments.write(": "); | |
266 arguments.write(Error.safeToString(value)); | |
267 argumentCount++; | |
268 }); | |
269 } | |
270 bool args_mismatch = _existingArgumentNames != null; | |
271 String args_message = args_mismatch ? " with matching arguments" : ""; | |
272 | |
273 String type_str; | |
274 if (type >= 0 && type < 5) { | |
275 type_str = (const ["method", "getter", "setter", "getter or setter", | |
276 "variable"])[type]; | |
277 } | |
278 | |
279 StringBuffer msg_buf = new StringBuffer("NoSuchMethodError: "); | |
255 switch (level) { | 280 switch (level) { |
256 case _InvocationMirror._DYNAMIC: { | 281 case _InvocationMirror._DYNAMIC: { |
257 if (_receiver == null) { | 282 if (_receiver == null) { |
258 msg = "The null object does not have a $type_str '$memberName'" | 283 if (args_mismatch) { |
259 "$args_message."; | 284 msg_buf.writeln("The null object does not have a $type_str " |
285 "'$memberName'$args_message."); | |
286 } else { | |
287 msg_buf.writeln("The $type_str '$memberName' was called on null."); | |
288 } | |
260 } else { | 289 } else { |
261 if (_receiver is Function) { | 290 if (_receiver is Function) { |
262 msg = "Closure call with mismatched arguments: " | 291 msg_buf.writeln("Closure call with mismatched arguments: " |
263 "function '$memberName'"; | 292 "function '$memberName'"); |
264 } else { | 293 } else { |
265 msg = "Class '${_receiver.runtimeType}' has no instance $type_str " | 294 msg_buf.writeln("Class '${_receiver.runtimeType}' has no instance " |
266 "'$memberName'$args_message."; | 295 "$type_str '$memberName'$args_message."); |
267 } | 296 } |
268 } | 297 } |
269 break; | 298 break; |
270 } | 299 } |
271 case _InvocationMirror._SUPER: { | 300 case _InvocationMirror._SUPER: { |
272 msg = "Super class of class '${_receiver.runtimeType}' has no instance " | 301 msg_buf.writeln("Super class of class '${_receiver.runtimeType}' has " |
273 "$type_str '$memberName'$args_message."; | 302 "no instance $type_str '$memberName'$args_message."); |
303 memberName = "super.$memberName"; | |
274 break; | 304 break; |
275 } | 305 } |
276 case _InvocationMirror._STATIC: { | 306 case _InvocationMirror._STATIC: { |
277 msg = "No static $type_str '$memberName' declared in class " | 307 msg_buf.writeln("No static $type_str '$memberName'$args_message " |
278 "'$_receiver'."; | 308 "declared in class '$_receiver'."); |
279 break; | 309 break; |
280 } | 310 } |
281 case _InvocationMirror._CONSTRUCTOR: { | 311 case _InvocationMirror._CONSTRUCTOR: { |
282 msg = "No constructor '$memberName'$args_message declared in class '$_re ceiver'."; | 312 msg_buf.writeln("No constructor '$memberName'$args_message declared " |
313 "in class '$_receiver'."); | |
314 memberName = "new $memberName"; | |
283 break; | 315 break; |
284 } | 316 } |
285 case _InvocationMirror._TOP_LEVEL: { | 317 case _InvocationMirror._TOP_LEVEL: { |
286 msg = "No top-level $type_str '$memberName'$args_message declared."; | 318 msg_buf.writeln("No top-level $type_str '$memberName'$args_message " |
319 "declared."); | |
287 break; | 320 break; |
288 } | 321 } |
289 } | 322 } |
290 return "$msg\n\n"; | |
291 } | |
292 | 323 |
293 @patch String toString() { | 324 if (level == _InvocationMirror._TOP_LEVEL) { |
294 StringBuffer actual_buf = new StringBuffer(); | 325 msg_buf.writeln("Receiver: top-level"); |
295 int i = 0; | 326 } else if (_receiver == null) { |
rmacnak
2016/10/11 22:55:01
Redundant with else case.
| |
296 if (_arguments == null) { | 327 msg_buf.writeln("Receiver: null"); |
297 // Actual arguments unknown. | |
298 // TODO(srdjan): Remove once arguments are passed for unresolvable | |
299 // static methods. | |
300 actual_buf.write("..."); | |
301 } else { | 328 } else { |
302 for (; i < _arguments.length; i++) { | 329 msg_buf.writeln("Receiver: ${Error.safeToString(_receiver)}"); |
303 if (i > 0) { | |
304 actual_buf.write(", "); | |
305 } | |
306 actual_buf.write(Error.safeToString(_arguments[i])); | |
307 } | |
308 } | 330 } |
309 if (_namedArguments != null) { | 331 |
310 _namedArguments.forEach((Symbol key, var value) { | 332 if (type == _InvocationMirror._METHOD) { |
311 if (i > 0) { | 333 msg_buf.write("Tried calling: $memberName($arguments)"); |
312 actual_buf.write(", "); | 334 } else if (argumentCount == 0) { |
313 } | 335 msg_buf.write("Tried calling: $memberName"); |
314 actual_buf.write(internal.Symbol.getUnmangledName(key)); | 336 } else if (type == _InvocationMirror._SETTER) { |
315 actual_buf.write(": "); | 337 msg_buf.write("Tried calling: $memberName$arguments"); |
316 actual_buf.write(Error.safeToString(value)); | 338 } else { |
317 i++; | 339 msg_buf.write("Tried calling: $memberName = $arguments"); |
318 }); | |
319 } | 340 } |
320 var args_mismatch = _existingArgumentNames != null; | 341 |
321 StringBuffer msg_buf = new StringBuffer(_developerMessage(args_mismatch)); | 342 if (args_mismatch) { |
322 String receiver_str; | 343 StringBuffer formalParameters = new StringBuffer(); |
323 var level = (_invocation_type >> _InvocationMirror._CALL_SHIFT) & | |
324 _InvocationMirror._CALL_MASK; | |
325 if ( level == _InvocationMirror._TOP_LEVEL) { | |
326 receiver_str = "top-level"; | |
327 } else { | |
328 receiver_str = Error.safeToString(_receiver); | |
329 } | |
330 var memberName = | |
331 (_memberName == null) ? "" : internal.Symbol.getUnmangledName(_memberNam e); | |
332 var type = _invocation_type & _InvocationMirror._TYPE_MASK; | |
333 if (type == _InvocationMirror._LOCAL_VAR) { | |
334 msg_buf.write( | |
335 "NoSuchMethodError: cannot assign to final variable '$memberName'"); | |
336 } else if (!args_mismatch) { | |
337 msg_buf.write( | |
338 "NoSuchMethodError: method not found: '$memberName'\n" | |
339 "Receiver: $receiver_str\n" | |
340 "Arguments: [$actual_buf]"); | |
341 } else { | |
342 String actualParameters = actual_buf.toString(); | |
343 StringBuffer formal_buf = new StringBuffer(); | |
344 for (int i = 0; i < _existingArgumentNames.length; i++) { | 344 for (int i = 0; i < _existingArgumentNames.length; i++) { |
345 if (i > 0) { | 345 if (i > 0) { |
346 formal_buf.write(", "); | 346 formalParameters.write(", "); |
347 } | 347 } |
348 formal_buf.write(_existingArgumentNames[i]); | 348 formalParameters.write(_existingArgumentNames[i]); |
349 } | 349 } |
350 String formalParameters = formal_buf.toString(); | 350 msg_buf.write("\nFound: $memberName($formalParameters)"); |
351 msg_buf.write( | |
352 "NoSuchMethodError: incorrect number of arguments passed to " | |
353 "method named '$memberName'\n" | |
354 "Receiver: $receiver_str\n" | |
355 "Tried calling: $memberName($actualParameters)\n" | |
356 "Found: $memberName($formalParameters)"); | |
357 } | 351 } |
352 | |
358 return msg_buf.toString(); | 353 return msg_buf.toString(); |
359 } | 354 } |
360 } | 355 } |
361 | 356 |
362 | 357 |
363 class _CompileTimeError extends Error { | 358 class _CompileTimeError extends Error { |
364 final String _errorMsg; | 359 final String _errorMsg; |
365 _CompileTimeError(this._errorMsg); | 360 _CompileTimeError(this._errorMsg); |
366 String toString() => _errorMsg; | 361 String toString() => _errorMsg; |
367 } | 362 } |
OLD | NEW |