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

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

Issue 13019003: Enable full type-checks in checked mode. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Use HTypeConversion instead of HIs. 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
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 if (compiler.enableTypeAssertions && currentElement.isInstanceMember()) {
431 DartType type = elements.getType(node);
432 // In checked mode, using a type variable in a type annotation may lead
433 // to a runtime type check that needs to access the type argument and
434 // therefore the closure needs a this-element.
435 // TODO(karlklose,johnniwinther): if the type is null, the annotation is
436 // from a parameter; in checked mode, we need to resolve all types.
ngeoffray 2013/05/13 09:10:59 So for foo(T a), we don't resolve the "T" ?
karlklose 2013/05/14 13:49:41 I updated the comment to be more precise.
ngeoffray 2013/05/15 08:45:32 Thank you. I still find it a bit obscure: what is
437 if (type != null && type.containsTypeVariables) {
438 registerNeedsThis();
439 }
440 }
441 node.visitChildren(this);
442 }
443
420 visitIdentifier(Identifier node) { 444 visitIdentifier(Identifier node) {
421 if (node.isThis()) { 445 if (node.isThis()) {
422 useLocal(closureData.thisElement); 446 registerNeedsThis();
423 } else { 447 } else {
424 Element element = elements[node]; 448 Element element = elements[node];
425 if (element != null && element.kind == ElementKind.TYPE_VARIABLE) { 449 if (element != null && element.kind == ElementKind.TYPE_VARIABLE) {
426 useLocal(closureData.thisElement); 450 registerNeedsThis();
427 } 451 }
428 } 452 }
429 node.visitChildren(this); 453 node.visitChildren(this);
430 } 454 }
431 455
432 visitSend(Send node) { 456 visitSend(Send node) {
433 Element element = elements[node]; 457 Element element = elements[node];
434 if (Elements.isLocal(element)) { 458 if (Elements.isLocal(element)) {
435 useLocal(element); 459 useLocal(element);
436 } else if (node.receiver == null && 460 } else if (node.receiver == null &&
437 Elements.isInstanceSend(node, elements)) { 461 Elements.isInstanceSend(node, elements)) {
438 useLocal(closureData.thisElement); 462 registerNeedsThis();
439 } else if (node.isSuperCall) { 463 } else if (node.isSuperCall) {
440 useLocal(closureData.thisElement); 464 registerNeedsThis();
441 } else if (node.isParameterCheck) { 465 } else if (node.isParameterCheck) {
442 Element parameter = elements[node.receiver]; 466 Element parameter = elements[node.receiver];
443 FunctionElement enclosing = parameter.enclosingElement; 467 FunctionElement enclosing = parameter.enclosingElement;
444 FunctionExpression function = enclosing.parseNode(compiler); 468 FunctionExpression function = enclosing.parseNode(compiler);
445 ClosureClassMap cached = closureMappingCache[function]; 469 ClosureClassMap cached = closureMappingCache[function];
446 if (!cached.parametersWithSentinel.containsKey(parameter)) { 470 if (!cached.parametersWithSentinel.containsKey(parameter)) {
447 SourceString parameterName = parameter.name; 471 SourceString parameterName = parameter.name;
448 String name = '${parameterName.slowToString()}_check'; 472 String name = '${parameterName.slowToString()}_check';
449 Element newElement = new CheckVariableElement(new SourceString(name), 473 Element newElement = new CheckVariableElement(new SourceString(name),
450 parameter, 474 parameter,
451 enclosing); 475 enclosing);
452 useLocal(newElement); 476 useLocal(newElement);
453 cached.parametersWithSentinel[parameter] = newElement; 477 cached.parametersWithSentinel[parameter] = newElement;
454 } 478 }
455 } 479 }
456 node.visitChildren(this); 480 node.visitChildren(this);
457 } 481 }
458 482
459 visitSendSet(SendSet node) { 483 visitSendSet(SendSet node) {
460 Element element = elements[node]; 484 Element element = elements[node];
461 if (Elements.isLocal(element)) { 485 if (Elements.isLocal(element)) {
462 mutatedVariables.add(element); 486 mutatedVariables.add(element);
463 } 487 }
488 if (element != null && element is VariableElement) {
ngeoffray 2013/05/13 09:10:59 Should that be Elements.isLocal(element) ?
karlklose 2013/05/14 13:49:41 Done.
karlklose 2013/05/14 13:49:41 Done.
489 VariableElement variable = element;
490 if (variable.variables.type.containsTypeVariables) {
ngeoffray 2013/05/13 09:10:59 Change to element.computeType(compiler).containsTy
karlklose 2013/05/14 13:49:41 Done.
491 registerNeedsThis();
492 }
493 }
464 super.visitSendSet(node); 494 super.visitSendSet(node);
465 } 495 }
466 496
467 visitNewExpression(NewExpression node) { 497 visitNewExpression(NewExpression node) {
468 DartType type = elements.getType(node); 498 DartType type = elements.getType(node);
469 499
470 bool hasTypeVariable(DartType type) { 500 bool hasTypeVariable(DartType type) {
471 if (type is TypeVariableType) { 501 if (type is TypeVariableType) {
472 return true; 502 return true;
473 } else if (type is InterfaceType) { 503 } else if (type is InterfaceType) {
(...skipping 16 matching lines...) Expand all
490 analyzeTypeVariables(argument); 520 analyzeTypeVariables(argument);
491 } 521 }
492 } 522 }
493 } 523 }
494 524
495 if (outermostElement.isMember() && 525 if (outermostElement.isMember() &&
496 compiler.backend.needsRti(outermostElement.getEnclosingClass())) { 526 compiler.backend.needsRti(outermostElement.getEnclosingClass())) {
497 if (outermostElement.isConstructor() || outermostElement.isField()) { 527 if (outermostElement.isConstructor() || outermostElement.isField()) {
498 analyzeTypeVariables(type); 528 analyzeTypeVariables(type);
499 } else if (outermostElement.isInstanceMember()) { 529 } else if (outermostElement.isInstanceMember()) {
500 if (hasTypeVariable(type)) useLocal(closureData.thisElement); 530 if (hasTypeVariable(type)) {
531 registerNeedsThis();
532 }
501 } 533 }
502 } 534 }
503 535
504 node.visitChildren(this); 536 node.visitChildren(this);
505 } 537 }
506 538
507 // If variables that are declared in the [node] scope are captured and need 539 // 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 540 // to be boxed create a box-element and update the [capturingScopes] in the
509 // current [closureData]. 541 // current [closureData].
510 // The boxed variables are updated in the [capturedVariableMapping]. 542 // The boxed variables are updated in the [capturedVariableMapping].
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 if (currentElement.isFactoryConstructor() && 691 if (currentElement.isFactoryConstructor() &&
660 compiler.backend.needsRti(currentElement.enclosingElement)) { 692 compiler.backend.needsRti(currentElement.enclosingElement)) {
661 // Declare the type parameters in the scope. Generative 693 // Declare the type parameters in the scope. Generative
662 // constructors just use 'this'. 694 // constructors just use 'this'.
663 ClassElement cls = currentElement.enclosingElement; 695 ClassElement cls = currentElement.enclosingElement;
664 cls.typeVariables.forEach((TypeVariableType typeVariable) { 696 cls.typeVariables.forEach((TypeVariableType typeVariable) {
665 declareLocal(typeVariable.element); 697 declareLocal(typeVariable.element);
666 }); 698 });
667 } 699 }
668 700
701 // Compute the function type and check for type variables in return or
702 // parameter types.
703 if (element.computeType(compiler).containsTypeVariables) {
704 registerNeedsThis();
705 }
706
669 visitChildren(); 707 visitChildren();
670 }); 708 });
671 709
672 710
673 ClosureClassMap savedClosureData = closureData; 711 ClosureClassMap savedClosureData = closureData;
674 bool savedInsideClosure = insideClosure; 712 bool savedInsideClosure = insideClosure;
675 713
676 // Restore old values. 714 // Restore old values.
677 insideClosure = oldInsideClosure; 715 insideClosure = oldInsideClosure;
678 closureData = oldClosureData; 716 closureData = oldClosureData;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 } 754 }
717 755
718 visitTryStatement(TryStatement node) { 756 visitTryStatement(TryStatement node) {
719 // TODO(ngeoffray): implement finer grain state. 757 // TODO(ngeoffray): implement finer grain state.
720 bool oldInTryStatement = inTryStatement; 758 bool oldInTryStatement = inTryStatement;
721 inTryStatement = true; 759 inTryStatement = true;
722 node.visitChildren(this); 760 node.visitChildren(this);
723 inTryStatement = oldInTryStatement; 761 inTryStatement = oldInTryStatement;
724 } 762 }
725 } 763 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698