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

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

Issue 10702204: Revert "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: 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
« no previous file with comments | « corelib/unified/math/random.dart ('k') | lib/compiler/implementation/elements/elements.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.script); 537 scanner.importLibrary(original, importedLibrary, tag, patch);
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
548 // patched, to avoid problems with cyclic dependencies. 548 // patched, to avoid problems with cyclic dependencies.
549 delayedPatches.forEach((String path, LibraryElement importedLibrary) { 549 delayedPatches.forEach((String path, LibraryElement importedLibrary) {
550 patchDartLibrary(importedLibrary, path); 550 patchDartLibrary(importedLibrary, path);
551 }); 551 });
552 } 552 }
553 553
554 void applyContainerPatch(ContainerElement original, Link<Element> patches, 554 void applyContainerPatch(ContainerElement original, Link<Element> patches,
555 Element lookup(SourceString name)) { 555 Element lookup(SourceString name)) {
556 while (!patches.isEmpty()) { 556 while (!patches.isEmpty()) {
557 Element patchElement = patches.head; 557 Element patchElement = patches.head;
558 Element originalElement = lookup(patchElement.name); 558 Element originalElement = lookup(patchElement.name);
559 assert(patchElement.kind !== ElementKind.ABSTRACT_FIELD); 559 // Getters and setters are kept inside a synthetic field.
560 if (originalElement !== null && 560 if (patchElement.kind === ElementKind.ABSTRACT_FIELD) {
561 originalElement.kind === ElementKind.ABSTRACT_FIELD) { 561 if (originalElement !== null &&
562 originalElement.kind !== ElementKind.ABSTRACT_FIELD) {
563 internalError("Cannot patch non-getter/setter with getter/setter",
564 element: originalElement);
565 }
566 AbstractFieldElement patchField = patchElement;
562 AbstractFieldElement originalField = originalElement; 567 AbstractFieldElement originalField = originalElement;
563 if (patchElement.kind === ElementKind.GETTER) { 568 if (patchField.getter !== null) {
564 originalElement = originalField.getter; 569 if (originalField === null || originalField.getter === null) {
565 } else if (patchElement.kind === ElementKind.SETTER) { 570 original.addGetterOrSetter(clonePatch(patchField.getter),
566 originalElement = originalField.setter; 571 originalField,
567 } else { 572 this);
568 internalError("Cannot patch a getter/setter field with a " 573 if (originalField === null && patchField.setter !== null) {
569 "non-getter/setter patch", element: originalElement); 574 // It exists now, so find it for the setter patching.
575 originalField = lookup(patchElement.name);
576 }
577 } else {
578 patchMember(originalField.getter, patchField.getter);
579 }
570 } 580 }
571 } 581 if (patchField.setter !== null) {
572 if (originalElement === null) { 582 if (originalField === null || originalField.setter === null) {
573 // The original library does not have an element with the same name 583 original.addGetterOrSetter(clonePatch(patchField.setter),
574 // as the patch library element. 584 originalField,
575 // In this case, the patch library element must not be marked as 585 this);
576 // "patch", and its name must make it private. 586 } else {
587 patchMember(originalField.setter, patchField.setter);
588 }
589 }
590 } else if (originalElement === null) {
577 if (isPatchElement(patchElement)) { 591 if (isPatchElement(patchElement)) {
578 internalError("Cannot patch non-existing member '" 592 internalError("Cannot patch non-existing member '"
579 "${patchElement.name.slowToString()}'."); 593 "${patchElement.name.slowToString()}'.");
580 } 594 }
581 if (!patchElement.name.isPrivate()) { 595 original.addMember(clonePatch(patchElement), this);
582 internalError("Cannot add non-private member '"
583 "${patchElement.name.slowToString()}' from patch.");
584 }
585 Element cloneElement = patchElement.cloneTo(original, this);
586 original.addMember(cloneElement, this);
587 } else { 596 } else {
588 patchMember(originalElement, patchElement); 597 patchMember(originalElement, patchElement);
589 } 598 }
590 patches = patches.tail; 599 patches = patches.tail;
591 } 600 }
592 } 601 }
593 602
594 bool isPatchElement(Element element) { 603 bool isPatchElement(Element element) {
595 // TODO(lrn): More checks needed if we introduce metadata for real. 604 // TODO(lrn): More checks needed if we introduce metadata for real.
596 // In that case, it must have the identifier "native" as metadata. 605 // In that case, it must have the identifier "native" as metadata.
597 return !element.metadata.isEmpty(); 606 return !element.metadata.isEmpty();
598 } 607 }
599 608
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
600 void patchMember(Element originalElement, Element patchElement) { 623 void patchMember(Element originalElement, Element patchElement) {
601 // The original library has an element with the same name as the patch 624 // The original library has an element with the same name as the patch
602 // library element. 625 // library element.
603 // In this case, the patch library element must be a function marked as 626 // In this case, the patch library element must be a function marked as
604 // "patch" and it must have the same signature as the function it patches. 627 // "patch" and it must have the same signature as the function it patches.
605 if (!isPatchElement(patchElement)) { 628 if (!isPatchElement(patchElement)) {
606 internalError("Cannot overwrite existing '" 629 internalError("Cannot overwrite existing '"
607 "${originalElement.name.slowToString()}' with non-patch."); 630 "${originalElement.name.slowToString()}' with non-patch.");
608 } 631 }
609 if (originalElement is PartialClassElement) { 632 if (originalElement is PartialClassElement) {
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
948 api.Diagnostic kind); 971 api.Diagnostic kind);
949 972
950 SourceSpan spanFromTokens(Token begin, Token end, [Uri uri]) { 973 SourceSpan spanFromTokens(Token begin, Token end, [Uri uri]) {
951 if (begin === null || end === null) { 974 if (begin === null || end === null) {
952 // TODO(ahe): We can almost always do better. Often it is only 975 // TODO(ahe): We can almost always do better. Often it is only
953 // end that is null. Otherwise, we probably know the current 976 // end that is null. Otherwise, we probably know the current
954 // URI. 977 // URI.
955 throw 'Cannot find tokens to produce error message.'; 978 throw 'Cannot find tokens to produce error message.';
956 } 979 }
957 if (uri === null && currentElement !== null) { 980 if (uri === null && currentElement !== null) {
958 uri = currentElement.getScript().uri; 981 uri = currentElement.getCompilationUnit().script.uri;
959 } 982 }
960 return SourceSpan.withCharacterOffsets(begin, end, 983 return SourceSpan.withCharacterOffsets(begin, end,
961 (beginOffset, endOffset) => new SourceSpan(uri, beginOffset, endOffset)); 984 (beginOffset, endOffset) => new SourceSpan(uri, beginOffset, endOffset));
962 } 985 }
963 986
964 SourceSpan spanFromNode(Node node, [Uri uri]) { 987 SourceSpan spanFromNode(Node node, [Uri uri]) {
965 return spanFromTokens(node.getBeginToken(), node.getEndToken(), uri); 988 return spanFromTokens(node.getBeginToken(), node.getEndToken(), uri);
966 } 989 }
967 990
968 SourceSpan spanFromElement(Element element) { 991 SourceSpan spanFromElement(Element element) {
969 if (element.position() === null) { 992 if (element.position() === null) {
970 // Sometimes, the backend fakes up elements that have no 993 // Sometimes, the backend fakes up elements that have no
971 // position. So we use the enclosing element instead. It is 994 // position. So we use the enclosing element instead. It is
972 // not a good error location, but cancel really is "internal 995 // not a good error location, but cancel really is "internal
973 // error" or "not implemented yet", so the vicinity is good 996 // error" or "not implemented yet", so the vicinity is good
974 // enough for now. 997 // enough for now.
975 element = element.enclosingElement; 998 element = element.enclosingElement;
976 // TODO(ahe): I plan to overhaul this infrastructure anyways. 999 // TODO(ahe): I plan to overhaul this infrastructure anyways.
977 } 1000 }
978 if (element === null) { 1001 if (element === null) {
979 element = currentElement; 1002 element = currentElement;
980 } 1003 }
981 Token position = element.position(); 1004 Token position = element.position();
982 Uri uri = element.getScript().uri; 1005 Uri uri = element.getCompilationUnit().script.uri;
983 return (position === null) 1006 return (position === null)
984 ? new SourceSpan(uri, 0, 0) 1007 ? new SourceSpan(uri, 0, 0)
985 : spanFromTokens(position, position, uri); 1008 : spanFromTokens(position, position, uri);
986 } 1009 }
987 1010
988 Script readScript(Uri uri, [ScriptTag node]) { 1011 Script readScript(Uri uri, [ScriptTag node]) {
989 unimplemented('Compiler.readScript'); 1012 unimplemented('Compiler.readScript');
990 } 1013 }
991 1014
992 String get legDirectory() { 1015 String get legDirectory() {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1062 final endOffset = end.charOffset + end.slowCharCount; 1085 final endOffset = end.charOffset + end.slowCharCount;
1063 1086
1064 // [begin] and [end] might be the same for the same empty token. This 1087 // [begin] and [end] might be the same for the same empty token. This
1065 // happens for instance when scanning '$$'. 1088 // happens for instance when scanning '$$'.
1066 assert(endOffset >= beginOffset); 1089 assert(endOffset >= beginOffset);
1067 return f(beginOffset, endOffset); 1090 return f(beginOffset, endOffset);
1068 } 1091 }
1069 1092
1070 String toString() => 'SourceSpan($uri, $begin, $end)'; 1093 String toString() => 'SourceSpan($uri, $begin, $end)';
1071 } 1094 }
OLDNEW
« no previous file with comments | « corelib/unified/math/random.dart ('k') | lib/compiler/implementation/elements/elements.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698