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

Side by Side Diff: lib/src/checker/rules.dart

Issue 1171713002: remove ClosureWrap option and related implementation (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 6 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
« no previous file with comments | « no previous file | lib/src/codegen/reify_coercions.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 library dev_compiler.src.checker.rules; 5 library dev_compiler.src.checker.rules;
6 6
7 import 'package:analyzer/src/generated/ast.dart'; 7 import 'package:analyzer/src/generated/ast.dart';
8 import 'package:analyzer/src/generated/element.dart'; 8 import 'package:analyzer/src/generated/element.dart';
9 import 'package:analyzer/src/generated/resolver.dart'; 9 import 'package:analyzer/src/generated/resolver.dart';
10 10
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 // but doesn't properly mix with class subtyping. I suspect Java 8 lambdas 403 // but doesn't properly mix with class subtyping. I suspect Java 8 lambdas
404 // essentially map to dynamic (and rely on invokedynamic) due to similar 404 // essentially map to dynamic (and rely on invokedynamic) due to similar
405 // issues. 405 // issues.
406 return isFunctionSubTypeOf(t1 as FunctionType, t2 as FunctionType); 406 return isFunctionSubTypeOf(t1 as FunctionType, t2 as FunctionType);
407 } 407 }
408 408
409 bool isAssignable(DartType t1, DartType t2) { 409 bool isAssignable(DartType t1, DartType t2) {
410 return isSubTypeOf(t1, t2); 410 return isSubTypeOf(t1, t2);
411 } 411 }
412 412
413 // If fromT <: toT, returns the identity coercion.
414 // Otherwise, creates a coercion wrapping a function of
415 // type fromT as a function of type toT, if:
416 // 1) this can be done without changing the reified type
417 // 2) The arguments can be coerced (see _coerceTo below)
418 // 3) The return value can be coerced or wrapped
419 // Otherwise, returns the error coercion
420 Coercion _wrapTo(FunctionType fromT, FunctionType toT) {
421 final r1s = fromT.normalParameterTypes;
422 final o1s = fromT.optionalParameterTypes;
423 final n1s = fromT.namedParameterTypes;
424 final ret1 = fromT.returnType;
425
426 final r2s = toT.normalParameterTypes;
427 final o2s = toT.optionalParameterTypes;
428 final n2s = toT.namedParameterTypes;
429 final ret2 = toT.returnType;
430
431 Coercion ret = _coerceTo(ret1, ret2, options.wrapClosures);
432
433 // Reject if one has named and the other has optional
434 if (n1s.length > 0 && o2s.length > 0) return Coercion.error();
435 if (n2s.length > 0 && o1s.length > 0) return Coercion.error();
436
437 Map<String, Coercion> ns = new Map<String, Coercion>();
438 // toT has named parameters
439 if (n2s.length > 0) {
440 // Coerce each named parameter from toT to the expected
441 // type in fromT (note the contravariance)
442 for (String k2 in n2s.keys) {
443 if (!n1s.containsKey(k2)) return Coercion.error();
444 ns[k2] = _coerceTo(n2s[k2], n1s[k2]);
445 }
446 }
447
448 // If fromT has more required parameters, reject
449 if (r1s.length > r2s.length) return Coercion.error();
450
451 // If toT has more required + optional parameters, reject
452 if (r2s.length + o2s.length > r1s.length + o1s.length) {
453 return Coercion.error();
454 }
455
456 // The parameter lists must look like the following at this point
457 // where rrr is a region of required, and ooo is a region of optionals.
458 // fromT: rrr ooo ooo ooo
459 // toT : rrr rrr ooo
460 int rr = r1s.length; // required in both
461 int or = r2s.length - r1s.length; // optional in fromT, required in toT
462 int oo = o2s.length; // optional in both
463
464 List<Coercion> rs = new List<Coercion>(r1s.length);
465 for (int i = 0; i < rr; ++i) {
466 rs[i] = _coerceTo(r2s[i], r1s[i]);
467 }
468 List<Coercion> os = new List<Coercion>(o1s.length);
469 for (int i = 0, j = rr; i < or; ++i, ++j) {
470 os[i] = _coerceTo(r2s[j], o1s[i]);
471 }
472 for (int i = or, j = 0; i < oo; ++i, ++j) {
473 os[i] = _coerceTo(o2s[j], o1s[i]);
474 }
475 for (int i = oo; i < o1s.length; ++i) {
476 os[i] = Coercion.identity(o1s[i]);
477 }
478 return Coercion.wrapper(fromT, toT, rs, os, ns, ret);
479 }
480
481 // Produce a coercion which coerces something of type fromT 413 // Produce a coercion which coerces something of type fromT
482 // to something of type toT. 414 // to something of type toT.
483 // If wrap is true and both are function types, a closure 415 // If wrap is true and both are function types, a closure
484 // wrapper coercion is produced using _wrapTo (see above) 416 // wrapper coercion is produced using _wrapTo (see above)
485 // Returns the error coercion if the types cannot be coerced 417 // Returns the error coercion if the types cannot be coerced
486 // according to our current criteria. 418 // according to our current criteria.
487 Coercion _coerceTo(DartType fromT, DartType toT, [bool wrap = false]) { 419 Coercion _coerceTo(DartType fromT, DartType toT) {
488 // We can use anything as void 420 // We can use anything as void
489 if (toT.isVoid) return Coercion.identity(toT); 421 if (toT.isVoid) return Coercion.identity(toT);
490 422
491 // fromT <: toT, no coercion needed 423 // fromT <: toT, no coercion needed
492 if (isSubTypeOf(fromT, toT)) return Coercion.identity(toT); 424 if (isSubTypeOf(fromT, toT)) return Coercion.identity(toT);
493 425
494 // For now, we always wrap closures.
495 if (wrap && fromT is FunctionType && toT is FunctionType) {
496 return _wrapTo(fromT, toT);
497 }
498
499 // For now, reject conversions between function types and 426 // For now, reject conversions between function types and
500 // call method objects. We could choose to allow casts here. 427 // call method objects. We could choose to allow casts here.
501 // Wrapping a function type to assign it to a call method 428 // Wrapping a function type to assign it to a call method
502 // object will never succeed. Wrapping the other way could 429 // object will never succeed. Wrapping the other way could
503 // be allowed. 430 // be allowed.
504 if ((fromT is FunctionType && getCallMethodType(toT) != null) || 431 if ((fromT is FunctionType && getCallMethodType(toT) != null) ||
505 (toT is FunctionType && getCallMethodType(fromT) != null)) { 432 (toT is FunctionType && getCallMethodType(fromT) != null)) {
506 return Coercion.error(); 433 return Coercion.error();
507 } 434 }
508 435
509 // Downcast if toT <: fromT 436 // Downcast if toT <: fromT
510 if (isSubTypeOf(toT, fromT)) return Coercion.cast(fromT, toT); 437 if (isSubTypeOf(toT, fromT)) return Coercion.cast(fromT, toT);
511 438
512 // Downcast if toT <===> fromT 439 // Downcast if toT <===> fromT
513 // The intention here is to allow casts that are sideways in the restricted 440 // The intention here is to allow casts that are sideways in the restricted
514 // type system, but allowed in the regular dart type system, since these 441 // type system, but allowed in the regular dart type system, since these
515 // are likely to succeed. The canonical example is List<dynamic> and 442 // are likely to succeed. The canonical example is List<dynamic> and
516 // Iterable<T> for some concrete T (e.g. Object). These are unrelated 443 // Iterable<T> for some concrete T (e.g. Object). These are unrelated
517 // in the restricted system, but List<dynamic> <: Iterable<T> in dart. 444 // in the restricted system, but List<dynamic> <: Iterable<T> in dart.
518 if (options.relaxedCasts && fromT.isAssignableTo(toT)) { 445 if (options.relaxedCasts && fromT.isAssignableTo(toT)) {
519 return Coercion.cast(fromT, toT); 446 return Coercion.cast(fromT, toT);
520 } 447 }
521 return Coercion.error(); 448 return Coercion.error();
522 } 449 }
523 450
524 StaticInfo checkAssignment(Expression expr, DartType toT, bool constContext) { 451 StaticInfo checkAssignment(Expression expr, DartType toT, bool constContext) {
525 final fromT = getStaticType(expr); 452 final fromT = getStaticType(expr);
526 final Coercion c = _coerceTo(fromT, toT, options.wrapClosures); 453 final Coercion c = _coerceTo(fromT, toT);
527 if (c is Identity) return null; 454 if (c is Identity) return null;
528 if (c is CoercionError) return new StaticTypeError(this, expr, toT); 455 if (c is CoercionError) return new StaticTypeError(this, expr, toT);
529 var reason = null; 456 var reason = null;
530 if (options.inferDownwards) { 457 if (options.inferDownwards) {
531 var errors = <String>[]; 458 var errors = <String>[];
532 var ok = inferrer.inferExpression(expr, toT, errors); 459 var ok = inferrer.inferExpression(expr, toT, errors);
533 if (ok) return InferredType.create(this, expr, toT); 460 if (ok) return InferredType.create(this, expr, toT);
534 reason = (errors.isNotEmpty) ? errors.first : null; 461 reason = (errors.isNotEmpty) ? errors.first : null;
535 } 462 }
536 if (c is Cast) return DownCast.create(this, expr, c, reason: reason); 463 if (c is Cast) return DownCast.create(this, expr, c, reason: reason);
537 if (c is Wrapper) return ClosureWrap.create(this, expr, c, toT);
538 assert(false); 464 assert(false);
539 return null; 465 return null;
540 } 466 }
541 467
542 DartType elementType(Element e) { 468 DartType elementType(Element e) {
543 return (e as dynamic).type; 469 return (e as dynamic).type;
544 } 470 }
545 471
546 bool isDynamic(DartType t) => options.ignoreTypes || t.isDynamic; 472 bool isDynamic(DartType t) => options.ignoreTypes || t.isDynamic;
547 473
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
860 var entries = e.entries; 786 var entries = e.entries;
861 bool inferEntry(MapLiteralEntry entry) { 787 bool inferEntry(MapLiteralEntry entry) {
862 return _inferExpression(entry.key, kType, errors) && 788 return _inferExpression(entry.key, kType, errors) &&
863 _inferExpression(entry.value, vType, errors); 789 _inferExpression(entry.value, vType, errors);
864 } 790 }
865 var b = entries.every(inferEntry); 791 var b = entries.every(inferEntry);
866 if (b) annotateMapLiteral(e, targs); 792 if (b) annotateMapLiteral(e, targs);
867 return b; 793 return b;
868 } 794 }
869 } 795 }
OLDNEW
« no previous file with comments | « no previous file | lib/src/codegen/reify_coercions.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698