Chromium Code Reviews| 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 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 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 425 ClosureClassMap cached = closureMappingCache[function]; | 425 ClosureClassMap cached = closureMappingCache[function]; |
| 426 if (!cached.parametersWithSentinel.containsKey(parameter)) { | 426 if (!cached.parametersWithSentinel.containsKey(parameter)) { |
| 427 SourceString parameterName = parameter.name; | 427 SourceString parameterName = parameter.name; |
| 428 String name = '${parameterName.slowToString()}_check'; | 428 String name = '${parameterName.slowToString()}_check'; |
| 429 Element newElement = new CheckVariableElement(new SourceString(name), | 429 Element newElement = new CheckVariableElement(new SourceString(name), |
| 430 parameter, | 430 parameter, |
| 431 enclosing); | 431 enclosing); |
| 432 useLocal(newElement); | 432 useLocal(newElement); |
| 433 cached.parametersWithSentinel[parameter] = newElement; | 433 cached.parametersWithSentinel[parameter] = newElement; |
| 434 } | 434 } |
| 435 } else if (node.isOperator) { | |
| 436 String operatorString = node.selector.asOperator().source.stringValue; | |
| 437 if (operatorString == 'is' || operatorString == 'as') { | |
|
karlklose
2013/03/22 13:17:46
I would really like to encapsulate this pattern. I
Johnni Winther
2013/06/12 14:39:10
I looked. They are all slightly different.
| |
| 438 DartType type = elements.getType(node.arguments.head); | |
| 439 analyzeType(type); | |
| 440 } | |
| 435 } | 441 } |
| 436 node.visitChildren(this); | 442 node.visitChildren(this); |
| 437 } | 443 } |
| 438 | 444 |
| 439 visitSendSet(SendSet node) { | 445 visitSendSet(SendSet node) { |
| 440 Element element = elements[node]; | 446 Element element = elements[node]; |
| 441 if (Elements.isLocal(element)) { | 447 if (Elements.isLocal(element)) { |
| 442 mutatedVariables.add(element); | 448 mutatedVariables.add(element); |
| 443 } | 449 } |
| 444 super.visitSendSet(node); | 450 super.visitSendSet(node); |
| 445 } | 451 } |
| 446 | 452 |
| 447 visitNewExpression(NewExpression node) { | 453 visitNewExpression(NewExpression node) { |
| 448 DartType type = elements.getType(node); | 454 DartType type = elements.getType(node); |
| 455 analyzeType(type); | |
| 456 node.visitChildren(this); | |
| 457 } | |
| 449 | 458 |
| 450 bool hasTypeVariable(DartType type) { | 459 void analyzeTypeVariables(DartType type) { |
| 451 if (type is TypeVariableType) { | 460 if (type is TypeVariableType) { |
| 452 return true; | 461 useLocal(type.element); |
| 453 } else if (type is InterfaceType) { | 462 } else if (type is InterfaceType) { |
| 454 InterfaceType ifcType = type; | 463 InterfaceType ifcType = type; |
| 455 for (DartType argument in ifcType.typeArguments) { | 464 for (DartType argument in ifcType.typeArguments) { |
| 456 if (hasTypeVariable(argument)) { | 465 analyzeTypeVariables(argument); |
| 457 return true; | |
| 458 } | |
| 459 } | |
| 460 } | 466 } |
| 461 return false; | |
| 462 } | 467 } |
| 468 } | |
| 463 | 469 |
| 464 void analyzeTypeVariables(DartType type) { | 470 void analyzeType(DartType type) { |
| 465 if (type is TypeVariableType) { | 471 if (type == null) return; |
|
karlklose
2013/03/22 13:17:46
How can this happen?
Johnni Winther
2013/06/21 12:19:14
Bad handling of is!
Now fixed.
| |
| 466 useLocal(type.element); | 472 if (outermostElement.isMember() && |
| 467 } else if (type is InterfaceType) { | 473 compiler.backend.needsRti(outermostElement.getEnclosingClass())) { |
| 468 InterfaceType ifcType = type; | 474 if (outermostElement.isConstructor() || |
| 469 for (DartType argument in ifcType.typeArguments) { | 475 outermostElement.isField()) { |
| 470 analyzeTypeVariables(argument); | 476 analyzeTypeVariables(type); |
| 477 } else if (outermostElement.isInstanceMember()) { | |
| 478 if (type.containsTypeVariables) { | |
| 479 useLocal(closureData.thisElement); | |
| 471 } | 480 } |
| 472 } | 481 } |
| 473 } | 482 } |
| 474 | |
| 475 if (outermostElement.isMember() && | |
| 476 compiler.backend.needsRti(outermostElement.getEnclosingClass())) { | |
| 477 if (outermostElement.isConstructor() || outermostElement.isField()) { | |
| 478 analyzeTypeVariables(type); | |
| 479 } else if (outermostElement.isInstanceMember()) { | |
| 480 if (hasTypeVariable(type)) useLocal(closureData.thisElement); | |
| 481 } | |
| 482 } | |
| 483 | |
| 484 node.visitChildren(this); | |
| 485 } | 483 } |
| 486 | 484 |
| 487 // If variables that are declared in the [node] scope are captured and need | 485 // If variables that are declared in the [node] scope are captured and need |
| 488 // to be boxed create a box-element and update the [capturingScopes] in the | 486 // to be boxed create a box-element and update the [capturingScopes] in the |
| 489 // current [closureData]. | 487 // current [closureData]. |
| 490 // The boxed variables are updated in the [capturedVariableMapping]. | 488 // The boxed variables are updated in the [capturedVariableMapping]. |
| 491 void attachCapturedScopeVariables(Node node) { | 489 void attachCapturedScopeVariables(Node node) { |
| 492 Element box = null; | 490 Element box = null; |
| 493 Map<Element, Element> scopeMapping = new Map<Element, Element>(); | 491 Map<Element, Element> scopeMapping = new Map<Element, Element>(); |
| 494 for (Element element in scopeVariables) { | 492 for (Element element in scopeVariables) { |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 639 if (currentElement.isFactoryConstructor() && | 637 if (currentElement.isFactoryConstructor() && |
| 640 compiler.backend.needsRti(currentElement.enclosingElement)) { | 638 compiler.backend.needsRti(currentElement.enclosingElement)) { |
| 641 // Declare the type parameters in the scope. Generative | 639 // Declare the type parameters in the scope. Generative |
| 642 // constructors just use 'this'. | 640 // constructors just use 'this'. |
| 643 ClassElement cls = currentElement.enclosingElement; | 641 ClassElement cls = currentElement.enclosingElement; |
| 644 cls.typeVariables.forEach((TypeVariableType typeVariable) { | 642 cls.typeVariables.forEach((TypeVariableType typeVariable) { |
| 645 declareLocal(typeVariable.element); | 643 declareLocal(typeVariable.element); |
| 646 }); | 644 }); |
| 647 } | 645 } |
| 648 | 646 |
| 647 // Ensure that closure that need runtime type information has access to | |
| 648 // this of the enclosing class. | |
| 649 if (closureData.thisElement != null && | |
| 650 compiler.backend.methodNeedsRti(element)) { | |
| 651 useLocal(closureData.thisElement); | |
| 652 } | |
| 653 | |
| 649 visitChildren(); | 654 visitChildren(); |
| 650 }); | 655 }); |
| 651 | 656 |
| 652 | 657 |
| 653 ClosureClassMap savedClosureData = closureData; | 658 ClosureClassMap savedClosureData = closureData; |
| 654 bool savedInsideClosure = insideClosure; | 659 bool savedInsideClosure = insideClosure; |
| 655 | 660 |
| 656 // Restore old values. | 661 // Restore old values. |
| 657 insideClosure = oldInsideClosure; | 662 insideClosure = oldInsideClosure; |
| 658 closureData = oldClosureData; | 663 closureData = oldClosureData; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 696 } | 701 } |
| 697 | 702 |
| 698 visitTryStatement(TryStatement node) { | 703 visitTryStatement(TryStatement node) { |
| 699 // TODO(ngeoffray): implement finer grain state. | 704 // TODO(ngeoffray): implement finer grain state. |
| 700 bool oldInTryStatement = inTryStatement; | 705 bool oldInTryStatement = inTryStatement; |
| 701 inTryStatement = true; | 706 inTryStatement = true; |
| 702 node.visitChildren(this); | 707 node.visitChildren(this); |
| 703 inTryStatement = oldInTryStatement; | 708 inTryStatement = oldInTryStatement; |
| 704 } | 709 } |
| 705 } | 710 } |
| OLD | NEW |