| 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 try { | 272 unhandledExceptionOnElement(element); |
| 273 unhandledExceptionOnElement(element); | |
| 274 } catch (var doubleFault) { | |
| 275 // Ignoring exceptions in exception handling. | |
| 276 } | |
| 277 throw; | 273 throw; |
| 278 } finally { | 274 } finally { |
| 279 _currentElement = old; | 275 _currentElement = old; |
| 280 } | 276 } |
| 281 } | 277 } |
| 282 | 278 |
| 283 List<CompilerTask> tasks; | 279 List<CompilerTask> tasks; |
| 284 ScannerTask scanner; | 280 ScannerTask scanner; |
| 285 DietParserTask dietParser; | 281 DietParserTask dietParser; |
| 286 ParserTask parser; | 282 ParserTask parser; |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 if (patchUri !== null) { | 518 if (patchUri !== null) { |
| 523 // TODO(lrn): Use a different parser to allow for "patch" annotations. | 519 // TODO(lrn): Use a different parser to allow for "patch" annotations. |
| 524 // For now just assume everything in the patch library is a patch | 520 // For now just assume everything in the patch library is a patch |
| 525 // function. | 521 // function. |
| 526 LibraryElement patchLibrary = scanner.loadLibrary(patchUri, null); | 522 LibraryElement patchLibrary = scanner.loadLibrary(patchUri, null); |
| 527 applyLibraryPatch(library, patchLibrary); | 523 applyLibraryPatch(library, patchLibrary); |
| 528 } | 524 } |
| 529 } | 525 } |
| 530 | 526 |
| 531 void applyLibraryPatch(LibraryElement library, LibraryElement patch) { | 527 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. | |
| 536 Link<Element> patches = patch.topLevelElements; | 528 Link<Element> patches = patch.topLevelElements; |
| 537 while (!patches.isEmpty()) { | 529 while (!patches.isEmpty()) { |
| 538 Element patchElement = patches.head; | 530 Element patchElement = patches.head; |
| 539 Element originalElement = library.elements[patchElement.name]; | 531 Element originalElement = library.elements[patchElement.name]; |
| 540 if (originalElement !== null) { | 532 if (originalElement !== null) { |
| 541 // Assume that we are patching if the original exists. | 533 // Assume that we are patching if the original exists. |
| 542 if (originalElement is! FunctionElement) { | 534 if (originalElement is! FunctionElement) { |
| 543 // TODO(lrn): Handle class declarations too. | 535 // TODO(lrn): Handle class declarations too. |
| 544 internalError("Can only patch functions", element: originalElement); | 536 internalError("Can only patch functions", element: originalElement); |
| 545 } | 537 } |
| 546 // TODO(lrn): Abort if the original isn't marked external, when | 538 // TODO(lrn): Abort if the original isn't marked external, when |
| 547 // that is added to the language. | 539 // that is added to the language. |
| 548 if (patchElement is! FunctionElement || | 540 if (patchElement is! FunctionElement || |
| 549 !patchSignatureMatches(originalElement, patchElement)) { | 541 !patchSignatureMatches(originalElement, patchElement)) { |
| 550 internalError("Can only patch functions with matching signatures", | 542 internalError("Can only patch functions with matching signatures", |
| 551 element: originalElement); | 543 element: originalElement); |
| 552 } | 544 } |
| 553 applyFunctionPatch(originalElement, patchElement); | 545 applyFunctionPatch(originalElement, patchElement); |
| 554 } else { | 546 } else { |
| 555 // TODO(lrn): Allow adding private elements to the original library. | 547 // TODO(lrn): Allow adding private elements to the original library. |
| 556 } | 548 } |
| 557 patches = patches.tail; | 549 patches = patches.tail; |
| 558 } | 550 } |
| 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. | |
| 576 library.patch = patch; | 551 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 }); | |
| 582 } | 552 } |
| 583 | 553 |
| 584 bool patchSignatureMatches(FunctionElement original, FunctionElement patch) { | 554 bool patchSignatureMatches(FunctionElement original, FunctionElement patch) { |
| 585 // TODO(lrn): Check that patches actually match the signature of | 555 // TODO(lrn): Check that patches actually match the signature of |
| 586 // the function it's patching. | 556 // the function it's patching. |
| 587 return true; | 557 return true; |
| 588 } | 558 } |
| 589 | 559 |
| 590 void applyFunctionPatch(FunctionElement element, | 560 void applyFunctionPatch(FunctionElement element, |
| 591 FunctionElement patchElement) { | 561 FunctionElement patchElement) { |
| (...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 992 f(int beginOffset, int endOffset)) { | 962 f(int beginOffset, int endOffset)) { |
| 993 final beginOffset = begin.charOffset; | 963 final beginOffset = begin.charOffset; |
| 994 final endOffset = end.charOffset + end.slowCharCount; | 964 final endOffset = end.charOffset + end.slowCharCount; |
| 995 | 965 |
| 996 // [begin] and [end] might be the same for the same empty token. This | 966 // [begin] and [end] might be the same for the same empty token. This |
| 997 // happens for instance when scanning '$$'. | 967 // happens for instance when scanning '$$'. |
| 998 assert(endOffset >= beginOffset); | 968 assert(endOffset >= beginOffset); |
| 999 return f(beginOffset, endOffset); | 969 return f(beginOffset, endOffset); |
| 1000 } | 970 } |
| 1001 } | 971 } |
| OLD | NEW |