| 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 | 5 |
| 6 /** | 6 /** |
| 7 * If true, print a warning for each method that was resolved, but not | 7 * If true, print a warning for each method that was resolved, but not |
| 8 * compiled. | 8 * compiled. |
| 9 */ | 9 */ |
| 10 final bool REPORT_EXCESS_RESOLUTION = false; | 10 final bool REPORT_EXCESS_RESOLUTION = false; |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 _currentElement = element; | 262 _currentElement = element; |
| 263 try { | 263 try { |
| 264 return f(); | 264 return f(); |
| 265 } catch (CompilerCancelledException ex) { | 265 } catch (CompilerCancelledException ex) { |
| 266 throw; | 266 throw; |
| 267 } catch (StackOverflowException ex) { | 267 } catch (StackOverflowException ex) { |
| 268 // We cannot report anything useful in this case, because we | 268 // We cannot report anything useful in this case, because we |
| 269 // do not have enough stack space. | 269 // do not have enough stack space. |
| 270 throw; | 270 throw; |
| 271 } catch (var ex) { | 271 } catch (var ex) { |
| 272 unhandledExceptionOnElement(element); | 272 try { |
| 273 unhandledExceptionOnElement(element); |
| 274 } catch (var doubleFault) { |
| 275 // Ignoring exceptions in exception handling. |
| 276 } |
| 273 throw; | 277 throw; |
| 274 } finally { | 278 } finally { |
| 275 _currentElement = old; | 279 _currentElement = old; |
| 276 } | 280 } |
| 277 } | 281 } |
| 278 | 282 |
| 279 List<CompilerTask> tasks; | 283 List<CompilerTask> tasks; |
| 280 ScannerTask scanner; | 284 ScannerTask scanner; |
| 281 DietParserTask dietParser; | 285 DietParserTask dietParser; |
| 282 ParserTask parser; | 286 ParserTask parser; |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 if (patchUri !== null) { | 522 if (patchUri !== null) { |
| 519 // TODO(lrn): Use a different parser to allow for "patch" annotations. | 523 // TODO(lrn): Use a different parser to allow for "patch" annotations. |
| 520 // For now just assume everything in the patch library is a patch | 524 // For now just assume everything in the patch library is a patch |
| 521 // function. | 525 // function. |
| 522 LibraryElement patchLibrary = scanner.loadLibrary(patchUri, null); | 526 LibraryElement patchLibrary = scanner.loadLibrary(patchUri, null); |
| 523 applyLibraryPatch(library, patchLibrary); | 527 applyLibraryPatch(library, patchLibrary); |
| 524 } | 528 } |
| 525 } | 529 } |
| 526 | 530 |
| 527 void applyLibraryPatch(LibraryElement library, LibraryElement patch) { | 531 void applyLibraryPatch(LibraryElement library, LibraryElement patch) { |
| 532 // We allow foreign functions in patched libraries. |
| 533 addForeignFunctions(library); // Is safe even if already added. |
| 534 |
| 535 // Copy/patch top-level elements. |
| 528 Link<Element> patches = patch.topLevelElements; | 536 Link<Element> patches = patch.topLevelElements; |
| 529 while (!patches.isEmpty()) { | 537 while (!patches.isEmpty()) { |
| 530 Element patchElement = patches.head; | 538 Element patchElement = patches.head; |
| 531 Element originalElement = library.elements[patchElement.name]; | 539 Element originalElement = library.elements[patchElement.name]; |
| 532 if (originalElement !== null) { | 540 if (originalElement !== null) { |
| 533 // Assume that we are patching if the original exists. | 541 // Assume that we are patching if the original exists. |
| 534 if (originalElement is! FunctionElement) { | 542 if (originalElement is! FunctionElement) { |
| 535 // TODO(lrn): Handle class declarations too. | 543 // TODO(lrn): Handle class declarations too. |
| 536 internalError("Can only patch functions", element: originalElement); | 544 internalError("Can only patch functions", element: originalElement); |
| 537 } | 545 } |
| 538 // TODO(lrn): Abort if the original isn't marked external, when | 546 // TODO(lrn): Abort if the original isn't marked external, when |
| 539 // that is added to the language. | 547 // that is added to the language. |
| 540 if (patchElement is! FunctionElement || | 548 if (patchElement is! FunctionElement || |
| 541 !patchSignatureMatches(originalElement, patchElement)) { | 549 !patchSignatureMatches(originalElement, patchElement)) { |
| 542 internalError("Can only patch functions with matching signatures", | 550 internalError("Can only patch functions with matching signatures", |
| 543 element: originalElement); | 551 element: originalElement); |
| 544 } | 552 } |
| 545 applyFunctionPatch(originalElement, patchElement); | 553 applyFunctionPatch(originalElement, patchElement); |
| 546 } else { | 554 } else { |
| 547 // TODO(lrn): Allow adding private elements to the original library. | 555 // TODO(lrn): Allow adding private elements to the original library. |
| 548 } | 556 } |
| 549 patches = patches.tail; | 557 patches = patches.tail; |
| 550 } | 558 } |
| 559 |
| 560 // Copy imports. |
| 561 Map<String, LibraryElement> delayedPatches = <LibraryElement>{}; |
| 562 Uri base = patch.script.uri; |
| 563 for (ScriptTag tag in patch.tags.reverse()) { |
| 564 if (tag.isImport()) { |
| 565 StringNode argument = tag.argument; |
| 566 Uri resolved = base.resolve(argument.dartString.slowToString()); |
| 567 LibraryElement importedLibrary = |
| 568 scanner.loadLibrary(resolved, argument); |
| 569 scanner.importLibrary(library, importedLibrary, tag, patch); |
| 570 if (resolved.scheme == "dart") { |
| 571 delayedPatches[resolved.path] = importedLibrary; |
| 572 } |
| 573 } |
| 574 } |
| 575 // Mark library as already patched. |
| 551 library.patch = patch; | 576 library.patch = patch; |
| 577 // We patch imported libraries after marking the current library as patched, |
| 578 // to avoid problems with cyclic dependencies. |
| 579 delayedPatches.forEach((String path, LibraryElement importedLibrary) { |
| 580 patchDartLibrary(importedLibrary, path); |
| 581 }); |
| 552 } | 582 } |
| 553 | 583 |
| 554 bool patchSignatureMatches(FunctionElement original, FunctionElement patch) { | 584 bool patchSignatureMatches(FunctionElement original, FunctionElement patch) { |
| 555 // TODO(lrn): Check that patches actually match the signature of | 585 // TODO(lrn): Check that patches actually match the signature of |
| 556 // the function it's patching. | 586 // the function it's patching. |
| 557 return true; | 587 return true; |
| 558 } | 588 } |
| 559 | 589 |
| 560 void applyFunctionPatch(FunctionElement element, | 590 void applyFunctionPatch(FunctionElement element, |
| 561 FunctionElement patchElement) { | 591 FunctionElement patchElement) { |
| (...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 f(int beginOffset, int endOffset)) { | 992 f(int beginOffset, int endOffset)) { |
| 963 final beginOffset = begin.charOffset; | 993 final beginOffset = begin.charOffset; |
| 964 final endOffset = end.charOffset + end.slowCharCount; | 994 final endOffset = end.charOffset + end.slowCharCount; |
| 965 | 995 |
| 966 // [begin] and [end] might be the same for the same empty token. This | 996 // [begin] and [end] might be the same for the same empty token. This |
| 967 // happens for instance when scanning '$$'. | 997 // happens for instance when scanning '$$'. |
| 968 assert(endOffset >= beginOffset); | 998 assert(endOffset >= beginOffset); |
| 969 return f(beginOffset, endOffset); | 999 return f(beginOffset, endOffset); |
| 970 } | 1000 } |
| 971 } | 1001 } |
| OLD | NEW |