| 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 class ClosureFieldElement extends Element { | 5 class ClosureFieldElement extends Element { |
| 6 ClosureFieldElement(SourceString name, ClassElement enclosing) | 6 ClosureFieldElement(SourceString name, ClassElement enclosing) |
| 7 : super(name, ElementKind.FIELD, enclosing); | 7 : super(name, ElementKind.FIELD, enclosing); |
| 8 | 8 |
| 9 bool isInstanceMember() => true; | 9 bool isInstanceMember() => true; |
| 10 bool isAssignable() => false; | 10 bool isAssignable() => false; |
| 11 | 11 |
| 12 String toString() => "ClosureFieldElement($name)"; | 12 String toString() => "ClosureFieldElement($name)"; |
| 13 } | 13 } |
| 14 | 14 |
| 15 class ClosureClassElement extends ClassElement { | 15 class ClosureClassElement extends ClassElement { |
| 16 ClosureClassElement(Compiler compiler, Element enclosingElement) | 16 ClosureClassElement(SourceString name, |
| 17 : super(compiler.closureClass.name, | 17 Compiler compiler, |
| 18 Element enclosingElement) |
| 19 : super(name, |
| 18 enclosingElement, | 20 enclosingElement, |
| 19 // By assigning a fresh class-id we make sure that the hashcode | 21 // By assigning a fresh class-id we make sure that the hashcode |
| 20 // is unique, but also emit closure class after all other | 22 // is unique, but also emit closure classes after all other |
| 21 // classes (since the emitter sorts classes by their id). | 23 // classes (since the emitter sorts classes by their id). |
| 22 compiler.getNextFreeClassId()) { | 24 compiler.getNextFreeClassId()) { |
| 23 isResolved = true; | 25 isResolved = true; |
| 24 compiler.closureClass.ensureResolved(compiler); | 26 compiler.closureClass.ensureResolved(compiler); |
| 25 supertype = compiler.closureClass.computeType(compiler); | 27 supertype = compiler.closureClass.computeType(compiler); |
| 26 } | 28 } |
| 29 bool isClosure() => true; |
| 27 } | 30 } |
| 28 | 31 |
| 29 class BoxElement extends Element { | 32 class BoxElement extends Element { |
| 30 BoxElement(SourceString name, Element enclosingElement) | 33 BoxElement(SourceString name, Element enclosingElement) |
| 31 : super(name, ElementKind.VARIABLE, enclosingElement); | 34 : super(name, ElementKind.VARIABLE, enclosingElement); |
| 32 } | 35 } |
| 33 | 36 |
| 34 class ThisElement extends Element { | 37 class ThisElement extends Element { |
| 35 ThisElement(Element enclosing) | 38 ThisElement(Element enclosing) |
| 36 : super(const SourceString('this'), ElementKind.PARAMETER, enclosing); | 39 : super(const SourceString('this'), ElementKind.PARAMETER, enclosing); |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 link = link.tail) { | 349 link = link.tail) { |
| 347 Node definition = link.head; | 350 Node definition = link.head; |
| 348 Element element = elements[definition]; | 351 Element element = elements[definition]; |
| 349 if (capturedVariableMapping.containsKey(element)) { | 352 if (capturedVariableMapping.containsKey(element)) { |
| 350 result.add(element); | 353 result.add(element); |
| 351 }; | 354 }; |
| 352 } | 355 } |
| 353 scopeData.boxedLoopVariables = result; | 356 scopeData.boxedLoopVariables = result; |
| 354 } | 357 } |
| 355 | 358 |
| 356 ClosureData globalizeClosure(FunctionExpression node) { | 359 ClosureData globalizeClosure(FunctionExpression node, Element element) { |
| 357 FunctionElement element = elements[node]; | 360 SourceString closureName = |
| 358 ClassElement globalizedElement = | 361 new SourceString(compiler.namer.closureName(element)); |
| 359 new ClosureClassElement(compiler, element.getCompilationUnit()); | 362 ClassElement globalizedElement = new ClosureClassElement( |
| 363 closureName, compiler, element.getCompilationUnit()); |
| 360 FunctionElement callElement = | 364 FunctionElement callElement = |
| 361 new FunctionElement.from(compiler.namer.CLOSURE_INVOCATION_NAME, | 365 new FunctionElement.from(compiler.namer.CLOSURE_INVOCATION_NAME, |
| 362 element, | 366 element, |
| 363 globalizedElement); | 367 globalizedElement); |
| 364 globalizedElement.backendMembers = | 368 globalizedElement.backendMembers = |
| 365 const EmptyLink<Element>().prepend(callElement); | 369 const EmptyLink<Element>().prepend(callElement); |
| 366 // The nested function's 'this' is the same as the one for the outer | 370 // The nested function's 'this' is the same as the one for the outer |
| 367 // function. It could be [null] if we are inside a static method. | 371 // function. It could be [null] if we are inside a static method. |
| 368 Element thisElement = closureData.thisElement; | 372 Element thisElement = closureData.thisElement; |
| 369 return new ClosureData(element, globalizedElement, | 373 return new ClosureData(element, globalizedElement, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 381 | 385 |
| 382 if (isClosure) closures.add(node); | 386 if (isClosure) closures.add(node); |
| 383 | 387 |
| 384 bool oldInsideClosure = insideClosure; | 388 bool oldInsideClosure = insideClosure; |
| 385 FunctionElement oldFunctionElement = currentFunctionElement; | 389 FunctionElement oldFunctionElement = currentFunctionElement; |
| 386 ClosureData oldClosureData = closureData; | 390 ClosureData oldClosureData = closureData; |
| 387 | 391 |
| 388 insideClosure = isClosure; | 392 insideClosure = isClosure; |
| 389 currentFunctionElement = elements[node]; | 393 currentFunctionElement = elements[node]; |
| 390 if (insideClosure) { | 394 if (insideClosure) { |
| 391 closureData = globalizeClosure(node); | 395 closureData = globalizeClosure(node, element); |
| 392 } else { | 396 } else { |
| 393 Element thisElement = null; | 397 Element thisElement = null; |
| 394 // TODO(floitsch): we should not need to look for generative constructors. | 398 // TODO(floitsch): we should not need to look for generative constructors. |
| 395 // At the moment we store only one ClosureData for both the factory and | 399 // At the moment we store only one ClosureData for both the factory and |
| 396 // the body. | 400 // the body. |
| 397 if (element.isInstanceMember() || | 401 if (element.isInstanceMember() || |
| 398 element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) { | 402 element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) { |
| 399 // TODO(floitsch): currently all variables are considered to be | 403 // TODO(floitsch): currently all variables are considered to be |
| 400 // declared in the GENERATIVE_CONSTRUCTOR. Including the 'this'. | 404 // declared in the GENERATIVE_CONSTRUCTOR. Including the 'this'. |
| 401 Element thisEnclosingElement = element; | 405 Element thisEnclosingElement = element; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 } | 464 } |
| 461 | 465 |
| 462 visitTryStatement(TryStatement node) { | 466 visitTryStatement(TryStatement node) { |
| 463 // TODO(ngeoffray): implement finer grain state. | 467 // TODO(ngeoffray): implement finer grain state. |
| 464 bool oldInTryStatement = inTryStatement; | 468 bool oldInTryStatement = inTryStatement; |
| 465 inTryStatement = true; | 469 inTryStatement = true; |
| 466 node.visitChildren(this); | 470 node.visitChildren(this); |
| 467 inTryStatement = oldInTryStatement; | 471 inTryStatement = oldInTryStatement; |
| 468 } | 472 } |
| 469 } | 473 } |
| OLD | NEW |