| 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 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 scanner.importLibrary(interceptorsLibrary, coreLibrary, null); | 500 scanner.importLibrary(interceptorsLibrary, coreLibrary, null); |
| 501 addForeignFunctions(jsHelperLibrary); | 501 addForeignFunctions(jsHelperLibrary); |
| 502 addForeignFunctions(interceptorsLibrary); | 502 addForeignFunctions(interceptorsLibrary); |
| 503 | 503 |
| 504 libraries['dart:core'] = coreLibrary; | 504 libraries['dart:core'] = coreLibrary; |
| 505 libraries['dart:coreimpl'] = coreImplLibrary; | 505 libraries['dart:coreimpl'] = coreImplLibrary; |
| 506 | 506 |
| 507 assertMethod = coreLibrary.find(const SourceString('assert')); | 507 assertMethod = coreLibrary.find(const SourceString('assert')); |
| 508 | 508 |
| 509 initializeSpecialClasses(); | 509 initializeSpecialClasses(); |
| 510 | |
| 511 patchDartLibrary(coreLibrary, 'core'); | |
| 512 patchDartLibrary(coreImplLibrary, 'coreimpl'); | |
| 513 } | 510 } |
| 514 | 511 |
| 515 void patchDartLibrary(LibraryElement library, String dartLibraryPath) { | |
| 516 if (library.isPatched) return; | |
| 517 Uri patchUri = resolvePatchUri(dartLibraryPath); | |
| 518 if (patchUri !== null) { | |
| 519 // TODO(lrn): Use a different parser to allow for "patch" annotations. | |
| 520 // For now just assume everything in the patch library is a patch | |
| 521 // function. | |
| 522 LibraryElement patchLibrary = scanner.loadLibrary(patchUri, null); | |
| 523 applyLibraryPatch(library, patchLibrary); | |
| 524 } | |
| 525 } | |
| 526 | |
| 527 void applyLibraryPatch(LibraryElement library, LibraryElement patch) { | |
| 528 Link<Element> patches = patch.topLevelElements; | |
| 529 while (!patches.isEmpty()) { | |
| 530 Element patchElement = patches.head; | |
| 531 Element originalElement = library.elements[patchElement.name]; | |
| 532 if (originalElement !== null) { | |
| 533 // Assume that we are patching if the original exists. | |
| 534 if (originalElement is! FunctionElement) { | |
| 535 // TODO(lrn): Handle class declarations too. | |
| 536 internalError("Can only patch functions", element: originalElement); | |
| 537 } | |
| 538 // TODO(lrn): Abort if the original isn't marked external, when | |
| 539 // that is added to the language. | |
| 540 if (patchElement is! FunctionElement || | |
| 541 !patchSignatureMatches(originalElement, patchElement)) { | |
| 542 internalError("Can only patch functions with matching signatures", | |
| 543 element: originalElement); | |
| 544 } | |
| 545 applyFunctionPatch(originalElement, patchElement); | |
| 546 } else { | |
| 547 // TODO(lrn): Allow adding private elements to the original library. | |
| 548 } | |
| 549 patches = patches.tail; | |
| 550 } | |
| 551 library.patch = patch; | |
| 552 } | |
| 553 | |
| 554 bool patchSignatureMatches(FunctionElement original, FunctionElement patch) { | |
| 555 // TODO(lrn): Check that patches actually match the signature of | |
| 556 // the function it's patching. | |
| 557 return true; | |
| 558 } | |
| 559 | |
| 560 void applyFunctionPatch(FunctionElement element, | |
| 561 FunctionElement patchElement) { | |
| 562 // Don't just assign the patch field. This also updates the cachedNode. | |
| 563 if (element.isPatched) { | |
| 564 internalError("Trying to patch a function more than once.", | |
| 565 element: element); | |
| 566 } | |
| 567 if (element.cachedNode !== null) { | |
| 568 internalError("Trying to patch an already compiled function.", | |
| 569 element: element); | |
| 570 } | |
| 571 element.setPatch(patchElement); | |
| 572 } | |
| 573 | |
| 574 /** | |
| 575 * Get an [Uri] pointing to a patch for the dart: library with | |
| 576 * the given path. Returns null if there is no patch. | |
| 577 */ | |
| 578 abstract Uri resolvePatchUri(String dartLibraryPath); | |
| 579 | |
| 580 /** Define the JS helper functions in the given library. */ | 512 /** Define the JS helper functions in the given library. */ |
| 581 void addForeignFunctions(LibraryElement library) { | 513 void addForeignFunctions(LibraryElement library) { |
| 582 library.define(new ForeignElement( | 514 library.define(new ForeignElement( |
| 583 const SourceString('JS'), library), this); | 515 const SourceString('JS'), library), this); |
| 584 library.define(new ForeignElement( | 516 library.define(new ForeignElement( |
| 585 const SourceString('UNINTERCEPTED'), library), this); | 517 const SourceString('UNINTERCEPTED'), library), this); |
| 586 library.define(new ForeignElement( | 518 library.define(new ForeignElement( |
| 587 const SourceString('JS_HAS_EQUALS'), library), this); | 519 const SourceString('JS_HAS_EQUALS'), library), this); |
| 588 library.define(new ForeignElement( | 520 library.define(new ForeignElement( |
| 589 const SourceString('JS_CURRENT_ISOLATE'), library), this); | 521 const SourceString('JS_CURRENT_ISOLATE'), library), this); |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 f(int beginOffset, int endOffset)) { | 894 f(int beginOffset, int endOffset)) { |
| 963 final beginOffset = begin.charOffset; | 895 final beginOffset = begin.charOffset; |
| 964 final endOffset = end.charOffset + end.slowCharCount; | 896 final endOffset = end.charOffset + end.slowCharCount; |
| 965 | 897 |
| 966 // [begin] and [end] might be the same for the same empty token. This | 898 // [begin] and [end] might be the same for the same empty token. This |
| 967 // happens for instance when scanning '$$'. | 899 // happens for instance when scanning '$$'. |
| 968 assert(endOffset >= beginOffset); | 900 assert(endOffset >= beginOffset); |
| 969 return f(beginOffset, endOffset); | 901 return f(beginOffset, endOffset); |
| 970 } | 902 } |
| 971 } | 903 } |
| OLD | NEW |