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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/closure.dart

Issue 15299002: Reapply "Enable full type-checks in checked mode." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/dart_types.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) 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 library closureToClassMapper; 5 library closureToClassMapper;
6 6
7 import "elements/elements.dart"; 7 import "elements/elements.dart";
8 import "dart2jslib.dart"; 8 import "dart2jslib.dart";
9 import "dart_types.dart"; 9 import "dart_types.dart";
10 import "scanner/scannerlib.dart" show Token; 10 import "scanner/scannerlib.dart" show Token;
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 // TODO(ngeoffray): only do this if the variable is mutated. 383 // TODO(ngeoffray): only do this if the variable is mutated.
384 closureData.usedVariablesInTry.add(element); 384 closureData.usedVariablesInTry.add(element);
385 } 385 }
386 } 386 }
387 } 387 }
388 388
389 void declareLocal(Element element) { 389 void declareLocal(Element element) {
390 scopeVariables.add(element); 390 scopeVariables.add(element);
391 } 391 }
392 392
393 void registerNeedsThis() {
394 if (closureData.thisElement != null) {
395 useLocal(closureData.thisElement);
396 }
397 }
398
393 visit(Node node) => node.accept(this); 399 visit(Node node) => node.accept(this);
394 400
395 visitNode(Node node) => node.visitChildren(this); 401 visitNode(Node node) => node.visitChildren(this);
396 402
397 visitVariableDefinitions(VariableDefinitions node) { 403 visitVariableDefinitions(VariableDefinitions node) {
404 if (node.type != null) {
405 visit(node.type);
406 }
398 for (Link<Node> link = node.definitions.nodes; 407 for (Link<Node> link = node.definitions.nodes;
399 !link.isEmpty; 408 !link.isEmpty;
400 link = link.tail) { 409 link = link.tail) {
401 Node definition = link.head; 410 Node definition = link.head;
402 Element element = elements[definition]; 411 Element element = elements[definition];
403 assert(element != null); 412 assert(element != null);
404 declareLocal(element); 413 declareLocal(element);
405 // We still need to visit the right-hand sides of the init-assignments. 414 // We still need to visit the right-hand sides of the init-assignments.
406 // For SendSets don't visit the left again. Otherwise it would be marked 415 // For SendSets don't visit the left again. Otherwise it would be marked
407 // as mutated. 416 // as mutated.
408 if (definition is Send) { 417 if (definition is Send) {
409 Send assignment = definition; 418 Send assignment = definition;
410 Node arguments = assignment.argumentsNode; 419 Node arguments = assignment.argumentsNode;
411 if (arguments != null) { 420 if (arguments != null) {
412 visit(arguments); 421 visit(arguments);
413 } 422 }
414 } else { 423 } else {
415 visit(definition); 424 visit(definition);
416 } 425 }
417 } 426 }
418 } 427 }
419 428
429 visitTypeAnnotation(TypeAnnotation node) {
430 Element member = currentElement.getEnclosingMember();
431 DartType type = elements.getType(node);
432 // TODO(karlklose,johnniwinther): if the type is null, the annotation is
433 // from a parameter which has been analyzed before the method has been
434 // resolved and the result has been thrown away.
435 if (compiler.enableTypeAssertions && type != null &&
436 type.containsTypeVariables) {
437 if (insideClosure && member.isFactoryConstructor()) {
438 // This is a closure in a factory constructor. Since there is no
439 // [:this:], we have to mark the type arguments as free variables to
440 // capture them in the closure.
441 type.forEachTypeVariable((variable) => useLocal(variable.element));
442 }
443 // TODO(karlklose): try to get rid of the isField check; there is a bug
444 // with type variable use in field initializer (in both modes).
445 if (member.isInstanceMember() && !member.isField()) {
446 // In checked mode, using a type variable in a type annotation may lead
447 // to a runtime type check that needs to access the type argument and
448 // therefore the closure needs a this-element.
449 registerNeedsThis();
450 }
451 }
452 }
453
420 visitIdentifier(Identifier node) { 454 visitIdentifier(Identifier node) {
421 if (node.isThis()) { 455 if (node.isThis()) {
422 useLocal(closureData.thisElement); 456 registerNeedsThis();
423 } else { 457 } else {
424 Element element = elements[node]; 458 Element element = elements[node];
425 if (element != null && element.kind == ElementKind.TYPE_VARIABLE) { 459 if (element != null && element.kind == ElementKind.TYPE_VARIABLE) {
426 useLocal(closureData.thisElement); 460 registerNeedsThis();
427 } 461 }
428 } 462 }
429 node.visitChildren(this); 463 node.visitChildren(this);
430 } 464 }
431 465
432 visitSend(Send node) { 466 visitSend(Send node) {
433 Element element = elements[node]; 467 Element element = elements[node];
434 if (Elements.isLocal(element)) { 468 if (Elements.isLocal(element)) {
435 useLocal(element); 469 useLocal(element);
436 } else if (node.receiver == null && 470 } else if (node.receiver == null &&
437 Elements.isInstanceSend(node, elements)) { 471 Elements.isInstanceSend(node, elements)) {
438 useLocal(closureData.thisElement); 472 registerNeedsThis();
439 } else if (node.isSuperCall) { 473 } else if (node.isSuperCall) {
440 useLocal(closureData.thisElement); 474 registerNeedsThis();
441 } else if (node.isParameterCheck) { 475 } else if (node.isParameterCheck) {
442 Element parameter = elements[node.receiver]; 476 Element parameter = elements[node.receiver];
443 FunctionElement enclosing = parameter.enclosingElement; 477 FunctionElement enclosing = parameter.enclosingElement;
444 FunctionExpression function = enclosing.parseNode(compiler); 478 FunctionExpression function = enclosing.parseNode(compiler);
445 ClosureClassMap cached = closureMappingCache[function]; 479 ClosureClassMap cached = closureMappingCache[function];
446 if (!cached.parametersWithSentinel.containsKey(parameter)) { 480 if (!cached.parametersWithSentinel.containsKey(parameter)) {
447 SourceString parameterName = parameter.name; 481 SourceString parameterName = parameter.name;
448 String name = '${parameterName.slowToString()}_check'; 482 String name = '${parameterName.slowToString()}_check';
449 Element newElement = new CheckVariableElement(new SourceString(name), 483 Element newElement = new CheckVariableElement(new SourceString(name),
450 parameter, 484 parameter,
451 enclosing); 485 enclosing);
452 useLocal(newElement); 486 useLocal(newElement);
453 cached.parametersWithSentinel[parameter] = newElement; 487 cached.parametersWithSentinel[parameter] = newElement;
454 } 488 }
455 } 489 }
456 node.visitChildren(this); 490 node.visitChildren(this);
457 } 491 }
458 492
459 visitSendSet(SendSet node) { 493 visitSendSet(SendSet node) {
460 Element element = elements[node]; 494 Element element = elements[node];
461 if (Elements.isLocal(element)) { 495 if (Elements.isLocal(element)) {
462 mutatedVariables.add(element); 496 mutatedVariables.add(element);
463 } 497 }
498 if (Elements.isLocal(element) &&
499 element.computeType(compiler).containsTypeVariables) {
500 registerNeedsThis();
501 }
464 super.visitSendSet(node); 502 super.visitSendSet(node);
465 } 503 }
466 504
467 visitNewExpression(NewExpression node) { 505 visitNewExpression(NewExpression node) {
468 DartType type = elements.getType(node); 506 DartType type = elements.getType(node);
469 507
470 bool hasTypeVariable(DartType type) { 508 bool hasTypeVariable(DartType type) {
471 if (type is TypeVariableType) { 509 if (type is TypeVariableType) {
472 return true; 510 return true;
473 } else if (type is InterfaceType) { 511 } else if (type is InterfaceType) {
(...skipping 16 matching lines...) Expand all
490 analyzeTypeVariables(argument); 528 analyzeTypeVariables(argument);
491 } 529 }
492 } 530 }
493 } 531 }
494 532
495 if (outermostElement.isMember() && 533 if (outermostElement.isMember() &&
496 compiler.backend.needsRti(outermostElement.getEnclosingClass())) { 534 compiler.backend.needsRti(outermostElement.getEnclosingClass())) {
497 if (outermostElement.isConstructor() || outermostElement.isField()) { 535 if (outermostElement.isConstructor() || outermostElement.isField()) {
498 analyzeTypeVariables(type); 536 analyzeTypeVariables(type);
499 } else if (outermostElement.isInstanceMember()) { 537 } else if (outermostElement.isInstanceMember()) {
500 if (hasTypeVariable(type)) useLocal(closureData.thisElement); 538 if (hasTypeVariable(type)) {
539 registerNeedsThis();
540 }
501 } 541 }
502 } 542 }
503 543
504 node.visitChildren(this); 544 node.visitChildren(this);
505 } 545 }
506 546
507 // If variables that are declared in the [node] scope are captured and need 547 // If variables that are declared in the [node] scope are captured and need
508 // to be boxed create a box-element and update the [capturingScopes] in the 548 // to be boxed create a box-element and update the [capturingScopes] in the
509 // current [closureData]. 549 // current [closureData].
510 // The boxed variables are updated in the [capturedVariableMapping]. 550 // The boxed variables are updated in the [capturedVariableMapping].
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
662 if (currentElement.isFactoryConstructor() && 702 if (currentElement.isFactoryConstructor() &&
663 compiler.backend.needsRti(currentElement.enclosingElement)) { 703 compiler.backend.needsRti(currentElement.enclosingElement)) {
664 // Declare the type parameters in the scope. Generative 704 // Declare the type parameters in the scope. Generative
665 // constructors just use 'this'. 705 // constructors just use 'this'.
666 ClassElement cls = currentElement.enclosingElement; 706 ClassElement cls = currentElement.enclosingElement;
667 cls.typeVariables.forEach((TypeVariableType typeVariable) { 707 cls.typeVariables.forEach((TypeVariableType typeVariable) {
668 declareLocal(typeVariable.element); 708 declareLocal(typeVariable.element);
669 }); 709 });
670 } 710 }
671 711
712 // Compute the function type and check for type variables in return or
713 // parameter types.
714 if (element.computeType(compiler).containsTypeVariables) {
715 registerNeedsThis();
716 }
717
672 visitChildren(); 718 visitChildren();
673 }); 719 });
674 720
675 721
676 ClosureClassMap savedClosureData = closureData; 722 ClosureClassMap savedClosureData = closureData;
677 bool savedInsideClosure = insideClosure; 723 bool savedInsideClosure = insideClosure;
678 724
679 // Restore old values. 725 // Restore old values.
680 insideClosure = oldInsideClosure; 726 insideClosure = oldInsideClosure;
681 closureData = oldClosureData; 727 closureData = oldClosureData;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 } 765 }
720 766
721 visitTryStatement(TryStatement node) { 767 visitTryStatement(TryStatement node) {
722 // TODO(ngeoffray): implement finer grain state. 768 // TODO(ngeoffray): implement finer grain state.
723 bool oldInTryStatement = inTryStatement; 769 bool oldInTryStatement = inTryStatement;
724 inTryStatement = true; 770 inTryStatement = true;
725 node.visitChildren(this); 771 node.visitChildren(this);
726 inTryStatement = oldInTryStatement; 772 inTryStatement = oldInTryStatement;
727 } 773 }
728 } 774 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/dart_types.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698