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

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: Fix a bug. Created 7 years, 8 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 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 // TODO(ngeoffray): only do this if the variable is mutated. 368 // TODO(ngeoffray): only do this if the variable is mutated.
369 closureData.usedVariablesInTry.add(element); 369 closureData.usedVariablesInTry.add(element);
370 } 370 }
371 } 371 }
372 } 372 }
373 373
374 void declareLocal(Element element) { 374 void declareLocal(Element element) {
375 scopeVariables.add(element); 375 scopeVariables.add(element);
376 } 376 }
377 377
378 void registerNeedsThis() {
379 if (closureData.thisElement != null) {
380 useLocal(closureData.thisElement);
381 }
382 }
383
378 visit(Node node) => node.accept(this); 384 visit(Node node) => node.accept(this);
379 385
380 visitNode(Node node) => node.visitChildren(this); 386 visitNode(Node node) => node.visitChildren(this);
381 387
382 visitVariableDefinitions(VariableDefinitions node) { 388 visitVariableDefinitions(VariableDefinitions node) {
389 if (node.type != null) {
390 visit(node.type);
391 }
383 for (Link<Node> link = node.definitions.nodes; 392 for (Link<Node> link = node.definitions.nodes;
384 !link.isEmpty; 393 !link.isEmpty;
385 link = link.tail) { 394 link = link.tail) {
386 Node definition = link.head; 395 Node definition = link.head;
387 Element element = elements[definition]; 396 Element element = elements[definition];
388 assert(element != null); 397 assert(element != null);
389 declareLocal(element); 398 declareLocal(element);
390 // We still need to visit the right-hand sides of the init-assignments. 399 // We still need to visit the right-hand sides of the init-assignments.
391 // For SendSets don't visit the left again. Otherwise it would be marked 400 // For SendSets don't visit the left again. Otherwise it would be marked
392 // as mutated. 401 // as mutated.
393 if (definition is Send) { 402 if (definition is Send) {
394 Send assignment = definition; 403 Send assignment = definition;
395 Node arguments = assignment.argumentsNode; 404 Node arguments = assignment.argumentsNode;
396 if (arguments != null) { 405 if (arguments != null) {
397 visit(arguments); 406 visit(arguments);
398 } 407 }
399 } else { 408 } else {
400 visit(definition); 409 visit(definition);
401 } 410 }
402 } 411 }
403 } 412 }
404 413
414 visitTypeAnnotation(TypeAnnotation node) {
415 if (compiler.enableTypeAssertions && currentElement.isInstanceMember()) {
416 DartType type = elements.getType(node);
417 // In checked mode, using a type variable in a type annotation may lead
418 // to a runtime type check that needs to access the type argument and
419 // therefor the closure needs a this-element.
ngeoffray 2013/04/15 10:59:14 therefore
karlklose 2013/05/02 15:04:54 Done.
420 // TODO(karlklose,johnniwinther): if the type is null, the annotation is
421 // from a parameter; in checked mode, we need to resolve all types.
ngeoffray 2013/04/15 10:59:14 I don't understand this TODO. How can it be null?
karlklose 2013/05/02 15:04:54 Maybe we do not store the result in the TreeElemen
422 if (type != null && type.containsTypeVariables) {
423 registerNeedsThis();
424 }
425 }
426 node.visitChildren(this);
427 }
428
405 visitIdentifier(Identifier node) { 429 visitIdentifier(Identifier node) {
406 if (node.isThis()) { 430 if (node.isThis()) {
407 useLocal(closureData.thisElement); 431 registerNeedsThis();
408 } else { 432 } else {
409 Element element = elements[node]; 433 Element element = elements[node];
410 if (element != null && element.kind == ElementKind.TYPE_VARIABLE) { 434 if (element != null && element.kind == ElementKind.TYPE_VARIABLE) {
411 useLocal(closureData.thisElement); 435 registerNeedsThis();
412 } 436 }
413 } 437 }
414 node.visitChildren(this); 438 node.visitChildren(this);
415 } 439 }
416 440
417 visitSend(Send node) { 441 visitSend(Send node) {
418 Element element = elements[node]; 442 Element element = elements[node];
419 if (Elements.isLocal(element)) { 443 if (Elements.isLocal(element)) {
420 useLocal(element); 444 useLocal(element);
421 } else if (node.receiver == null && 445 } else if (node.receiver == null &&
422 Elements.isInstanceSend(node, elements)) { 446 Elements.isInstanceSend(node, elements)) {
423 useLocal(closureData.thisElement); 447 registerNeedsThis();
424 } else if (node.isSuperCall) { 448 } else if (node.isSuperCall) {
425 useLocal(closureData.thisElement); 449 registerNeedsThis();
426 } else if (node.isParameterCheck) { 450 } else if (node.isParameterCheck) {
427 Element parameter = elements[node.receiver]; 451 Element parameter = elements[node.receiver];
428 FunctionElement enclosing = parameter.enclosingElement; 452 FunctionElement enclosing = parameter.enclosingElement;
429 FunctionExpression function = enclosing.parseNode(compiler); 453 FunctionExpression function = enclosing.parseNode(compiler);
430 ClosureClassMap cached = closureMappingCache[function]; 454 ClosureClassMap cached = closureMappingCache[function];
431 if (!cached.parametersWithSentinel.containsKey(parameter)) { 455 if (!cached.parametersWithSentinel.containsKey(parameter)) {
432 SourceString parameterName = parameter.name; 456 SourceString parameterName = parameter.name;
433 String name = '${parameterName.slowToString()}_check'; 457 String name = '${parameterName.slowToString()}_check';
434 Element newElement = new CheckVariableElement(new SourceString(name), 458 Element newElement = new CheckVariableElement(new SourceString(name),
435 parameter, 459 parameter,
436 enclosing); 460 enclosing);
437 useLocal(newElement); 461 useLocal(newElement);
438 cached.parametersWithSentinel[parameter] = newElement; 462 cached.parametersWithSentinel[parameter] = newElement;
439 } 463 }
440 } 464 }
441 node.visitChildren(this); 465 node.visitChildren(this);
442 } 466 }
443 467
444 visitSendSet(SendSet node) { 468 visitSendSet(SendSet node) {
445 Element element = elements[node]; 469 Element element = elements[node];
446 if (Elements.isLocal(element)) { 470 if (Elements.isLocal(element)) {
447 mutatedVariables.add(element); 471 mutatedVariables.add(element);
448 } 472 }
473 if (element != null && element is VariableElement) {
474 VariableElement variable = element;
475 if (variable.variables.type.containsTypeVariables) {
476 registerNeedsThis();
ngeoffray 2013/04/15 10:59:14 Not sure you need this: - If element is a field, t
karlklose 2013/05/02 15:04:54 It is needed.
477 }
478 }
449 super.visitSendSet(node); 479 super.visitSendSet(node);
450 } 480 }
451 481
452 visitNewExpression(NewExpression node) { 482 visitNewExpression(NewExpression node) {
453 DartType type = elements.getType(node); 483 DartType type = elements.getType(node);
454 484
455 bool hasTypeVariable(DartType type) { 485 bool hasTypeVariable(DartType type) {
456 if (type is TypeVariableType) { 486 if (type is TypeVariableType) {
457 return true; 487 return true;
458 } else if (type is InterfaceType) { 488 } else if (type is InterfaceType) {
(...skipping 16 matching lines...) Expand all
475 analyzeTypeVariables(argument); 505 analyzeTypeVariables(argument);
476 } 506 }
477 } 507 }
478 } 508 }
479 509
480 if (outermostElement.isMember() && 510 if (outermostElement.isMember() &&
481 compiler.backend.needsRti(outermostElement.getEnclosingClass())) { 511 compiler.backend.needsRti(outermostElement.getEnclosingClass())) {
482 if (outermostElement.isConstructor() || outermostElement.isField()) { 512 if (outermostElement.isConstructor() || outermostElement.isField()) {
483 analyzeTypeVariables(type); 513 analyzeTypeVariables(type);
484 } else if (outermostElement.isInstanceMember()) { 514 } else if (outermostElement.isInstanceMember()) {
485 if (hasTypeVariable(type)) useLocal(closureData.thisElement); 515 if (hasTypeVariable(type)) {
516 registerNeedsThis();
517 }
486 } 518 }
487 } 519 }
488 520
489 node.visitChildren(this); 521 node.visitChildren(this);
490 } 522 }
491 523
492 // If variables that are declared in the [node] scope are captured and need 524 // If variables that are declared in the [node] scope are captured and need
493 // to be boxed create a box-element and update the [capturingScopes] in the 525 // to be boxed create a box-element and update the [capturingScopes] in the
494 // current [closureData]. 526 // current [closureData].
495 // The boxed variables are updated in the [capturedVariableMapping]. 527 // The boxed variables are updated in the [capturedVariableMapping].
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 if (currentElement.isFactoryConstructor() && 676 if (currentElement.isFactoryConstructor() &&
645 compiler.backend.needsRti(currentElement.enclosingElement)) { 677 compiler.backend.needsRti(currentElement.enclosingElement)) {
646 // Declare the type parameters in the scope. Generative 678 // Declare the type parameters in the scope. Generative
647 // constructors just use 'this'. 679 // constructors just use 'this'.
648 ClassElement cls = currentElement.enclosingElement; 680 ClassElement cls = currentElement.enclosingElement;
649 cls.typeVariables.forEach((TypeVariableType typeVariable) { 681 cls.typeVariables.forEach((TypeVariableType typeVariable) {
650 declareLocal(typeVariable.element); 682 declareLocal(typeVariable.element);
651 }); 683 });
652 } 684 }
653 685
686 if (element.computeType(compiler).containsTypeVariables) {
ngeoffray 2013/04/15 10:59:14 So that's the function type if the element? It mat
karlklose 2013/05/02 15:04:54 Done.
687 registerNeedsThis();
688 }
689
654 visitChildren(); 690 visitChildren();
655 }); 691 });
656 692
657 693
658 ClosureClassMap savedClosureData = closureData; 694 ClosureClassMap savedClosureData = closureData;
659 bool savedInsideClosure = insideClosure; 695 bool savedInsideClosure = insideClosure;
660 696
661 // Restore old values. 697 // Restore old values.
662 insideClosure = oldInsideClosure; 698 insideClosure = oldInsideClosure;
663 closureData = oldClosureData; 699 closureData = oldClosureData;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 } 737 }
702 738
703 visitTryStatement(TryStatement node) { 739 visitTryStatement(TryStatement node) {
704 // TODO(ngeoffray): implement finer grain state. 740 // TODO(ngeoffray): implement finer grain state.
705 bool oldInTryStatement = inTryStatement; 741 bool oldInTryStatement = inTryStatement;
706 inTryStatement = true; 742 inTryStatement = true;
707 node.visitChildren(this); 743 node.visitChildren(this);
708 inTryStatement = oldInTryStatement; 744 inTryStatement = oldInTryStatement;
709 } 745 }
710 } 746 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698