Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(298)

Side by Side Diff: lib/compiler/implementation/compiler.dart

Issue 10703188: Allow patch files to add top-level declarations to the patched library. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated min/max in unified/math library. Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 527
528 // Copy imports from patch to original library. 528 // Copy imports from patch to original library.
529 Map<String, LibraryElement> delayedPatches = <LibraryElement>{}; 529 Map<String, LibraryElement> delayedPatches = <LibraryElement>{};
530 Uri patchBase = patch.script.uri; 530 Uri patchBase = patch.script.uri;
531 for (ScriptTag tag in patch.tags.reverse()) { 531 for (ScriptTag tag in patch.tags.reverse()) {
532 if (tag.isImport()) { 532 if (tag.isImport()) {
533 StringNode argument = tag.argument; 533 StringNode argument = tag.argument;
534 Uri resolved = patchBase.resolve(argument.dartString.slowToString()); 534 Uri resolved = patchBase.resolve(argument.dartString.slowToString());
535 LibraryElement importedLibrary = 535 LibraryElement importedLibrary =
536 scanner.loadLibrary(resolved, argument); 536 scanner.loadLibrary(resolved, argument);
537 scanner.importLibrary(original, importedLibrary, tag, patch); 537 scanner.importLibrary(original, importedLibrary, tag, patch.script);
538 if (resolved.scheme == "dart") { 538 if (resolved.scheme == "dart") {
539 delayedPatches[resolved.path] = importedLibrary; 539 delayedPatches[resolved.path] = importedLibrary;
540 } 540 }
541 } 541 }
542 } 542 }
543 543
544 // Mark library as already patched. 544 // Mark library as already patched.
545 original.patch = patch; 545 original.patch = patch;
546 546
547 // We patch imported libraries after marking the current library as 547 // We patch imported libraries after marking the current library as
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 if (patchField.setter !== null) { 581 if (patchField.setter !== null) {
582 if (originalField === null || originalField.setter === null) { 582 if (originalField === null || originalField.setter === null) {
583 original.addGetterOrSetter(clonePatch(patchField.setter), 583 original.addGetterOrSetter(clonePatch(patchField.setter),
584 originalField, 584 originalField,
585 this); 585 this);
586 } else { 586 } else {
587 patchMember(originalField.setter, patchField.setter); 587 patchMember(originalField.setter, patchField.setter);
588 } 588 }
589 } 589 }
590 } else if (originalElement === null) { 590 } else if (originalElement === null) {
591 // The original library does not have an element with the same name
592 // as the patch library element.
593 // In this case, the patch library element must not be marked as
594 // "patch", and its name must make it private.
591 if (isPatchElement(patchElement)) { 595 if (isPatchElement(patchElement)) {
592 internalError("Cannot patch non-existing member '" 596 internalError("Cannot patch non-existing member '"
593 "${patchElement.name.slowToString()}'."); 597 "${patchElement.name.slowToString()}'.");
594 } 598 }
595 original.addMember(clonePatch(patchElement), this); 599 if (!patchElement.name.isPrivate()) {
600 internalError("Cannot add non-private member '"
601 "${patchElement.name.slowToString()}' from patch.");
602 }
603 Element cloneElement = patchElement.cloneTo(original, this);
604 original.addMember(cloneElement, this);
596 } else { 605 } else {
597 patchMember(originalElement, patchElement); 606 patchMember(originalElement, patchElement);
598 } 607 }
599 patches = patches.tail; 608 patches = patches.tail;
600 } 609 }
601 } 610 }
602 611
603 bool isPatchElement(Element element) { 612 bool isPatchElement(Element element) {
604 // TODO(lrn): More checks needed if we introduce metadata for real. 613 // TODO(lrn): More checks needed if we introduce metadata for real.
605 // In that case, it must have the identifier "native" as metadata. 614 // In that case, it must have the identifier "native" as metadata.
606 return !element.metadata.isEmpty(); 615 return !element.metadata.isEmpty();
607 } 616 }
608 617
609 Element clonePatch(Element patchElement) {
610 // The original library does not have an element with the same name
611 // as the patch library element.
612 // In this case, the patch library element must not be marked as "patch",
613 // and its name must make it private.
614 if (!patchElement.name.isPrivate()) {
615 internalError("Cannot add non-private member '"
616 "${patchElement.name.slowToString()}' from patch.");
617 }
618 // TODO(lrn): Create a copy of patchElement that isn't added to any
619 // object/library yet, but which takes its source from patchElement.
620 throw "Adding members from patch is unsupported";
621 }
622
623 void patchMember(Element originalElement, Element patchElement) { 618 void patchMember(Element originalElement, Element patchElement) {
624 // The original library has an element with the same name as the patch 619 // The original library has an element with the same name as the patch
625 // library element. 620 // library element.
626 // In this case, the patch library element must be a function marked as 621 // In this case, the patch library element must be a function marked as
627 // "patch" and it must have the same signature as the function it patches. 622 // "patch" and it must have the same signature as the function it patches.
628 if (!isPatchElement(patchElement)) { 623 if (!isPatchElement(patchElement)) {
629 internalError("Cannot overwrite existing '" 624 internalError("Cannot overwrite existing '"
630 "${originalElement.name.slowToString()}' with non-patch."); 625 "${originalElement.name.slowToString()}' with non-patch.");
631 } 626 }
632 if (originalElement is PartialClassElement) { 627 if (originalElement is PartialClassElement) {
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
971 api.Diagnostic kind); 966 api.Diagnostic kind);
972 967
973 SourceSpan spanFromTokens(Token begin, Token end, [Uri uri]) { 968 SourceSpan spanFromTokens(Token begin, Token end, [Uri uri]) {
974 if (begin === null || end === null) { 969 if (begin === null || end === null) {
975 // TODO(ahe): We can almost always do better. Often it is only 970 // TODO(ahe): We can almost always do better. Often it is only
976 // end that is null. Otherwise, we probably know the current 971 // end that is null. Otherwise, we probably know the current
977 // URI. 972 // URI.
978 throw 'Cannot find tokens to produce error message.'; 973 throw 'Cannot find tokens to produce error message.';
979 } 974 }
980 if (uri === null && currentElement !== null) { 975 if (uri === null && currentElement !== null) {
981 uri = currentElement.getCompilationUnit().script.uri; 976 uri = currentElement.getScript().uri;
982 } 977 }
983 return SourceSpan.withCharacterOffsets(begin, end, 978 return SourceSpan.withCharacterOffsets(begin, end,
984 (beginOffset, endOffset) => new SourceSpan(uri, beginOffset, endOffset)); 979 (beginOffset, endOffset) => new SourceSpan(uri, beginOffset, endOffset));
985 } 980 }
986 981
987 SourceSpan spanFromNode(Node node, [Uri uri]) { 982 SourceSpan spanFromNode(Node node, [Uri uri]) {
988 return spanFromTokens(node.getBeginToken(), node.getEndToken(), uri); 983 return spanFromTokens(node.getBeginToken(), node.getEndToken(), uri);
989 } 984 }
990 985
991 SourceSpan spanFromElement(Element element) { 986 SourceSpan spanFromElement(Element element) {
992 if (element.position() === null) { 987 if (element.position() === null) {
993 // Sometimes, the backend fakes up elements that have no 988 // Sometimes, the backend fakes up elements that have no
994 // position. So we use the enclosing element instead. It is 989 // position. So we use the enclosing element instead. It is
995 // not a good error location, but cancel really is "internal 990 // not a good error location, but cancel really is "internal
996 // error" or "not implemented yet", so the vicinity is good 991 // error" or "not implemented yet", so the vicinity is good
997 // enough for now. 992 // enough for now.
998 element = element.enclosingElement; 993 element = element.enclosingElement;
999 // TODO(ahe): I plan to overhaul this infrastructure anyways. 994 // TODO(ahe): I plan to overhaul this infrastructure anyways.
1000 } 995 }
1001 if (element === null) { 996 if (element === null) {
1002 element = currentElement; 997 element = currentElement;
1003 } 998 }
1004 Token position = element.position(); 999 Token position = element.position();
1005 Uri uri = element.getCompilationUnit().script.uri; 1000 Uri uri = element.getScript().uri;
1006 return (position === null) 1001 return (position === null)
1007 ? new SourceSpan(uri, 0, 0) 1002 ? new SourceSpan(uri, 0, 0)
1008 : spanFromTokens(position, position, uri); 1003 : spanFromTokens(position, position, uri);
1009 } 1004 }
1010 1005
1011 Script readScript(Uri uri, [ScriptTag node]) { 1006 Script readScript(Uri uri, [ScriptTag node]) {
1012 unimplemented('Compiler.readScript'); 1007 unimplemented('Compiler.readScript');
1013 } 1008 }
1014 1009
1015 String get legDirectory() { 1010 String get legDirectory() {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1085 final endOffset = end.charOffset + end.slowCharCount; 1080 final endOffset = end.charOffset + end.slowCharCount;
1086 1081
1087 // [begin] and [end] might be the same for the same empty token. This 1082 // [begin] and [end] might be the same for the same empty token. This
1088 // happens for instance when scanning '$$'. 1083 // happens for instance when scanning '$$'.
1089 assert(endOffset >= beginOffset); 1084 assert(endOffset >= beginOffset);
1090 return f(beginOffset, endOffset); 1085 return f(beginOffset, endOffset);
1091 } 1086 }
1092 1087
1093 String toString() => 'SourceSpan($uri, $begin, $end)'; 1088 String toString() => 'SourceSpan($uri, $begin, $end)';
1094 } 1089 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698