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

Side by Side Diff: dart/pkg/dart2js_incremental/lib/library_updater.dart

Issue 715783002: Implement removal of top-level methods. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 1 month 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 | « no previous file | dart/tests/try/web/incremental_compilation_update_test.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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 library dart2js_incremental.library_updater; 5 library dart2js_incremental.library_updater;
6 6
7 import 'dart:async' show 7 import 'dart:async' show
8 Future; 8 Future;
9 9
10 import 'dart:convert' show 10 import 'dart:convert' show
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 MemberInfo; 48 MemberInfo;
49 49
50 import 'package:_internal/compiler/js_lib/shared/embedded_names.dart' 50 import 'package:_internal/compiler/js_lib/shared/embedded_names.dart'
51 as embeddedNames; 51 as embeddedNames;
52 52
53 import 'package:compiler/src/js_backend/js_backend.dart' show 53 import 'package:compiler/src/js_backend/js_backend.dart' show
54 JavaScriptBackend, 54 JavaScriptBackend,
55 Namer; 55 Namer;
56 56
57 import 'package:compiler/src/util/util.dart' show 57 import 'package:compiler/src/util/util.dart' show
58 Link; 58 Link,
59 LinkBuilder;
59 60
60 import 'package:compiler/src/elements/modelx.dart' show 61 import 'package:compiler/src/elements/modelx.dart' show
61 DeclarationSite, 62 DeclarationSite,
62 ElementX; 63 ElementX;
63 64
64 import 'diff.dart' show 65 import 'diff.dart' show
65 Difference, 66 Difference,
66 computeDifference; 67 computeDifference;
67 68
68 typedef void Logger(message); 69 typedef void Logger(message);
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 223
223 bool canReuseRemovedElement(PartialElement element) { 224 bool canReuseRemovedElement(PartialElement element) {
224 if (element is PartialFunctionElement) { 225 if (element is PartialFunctionElement) {
225 return canReuseRemovedFunction(element); 226 return canReuseRemovedFunction(element);
226 } 227 }
227 return cannotReuse( 228 return cannotReuse(
228 element, "Removed element that isn't a method."); 229 element, "Removed element that isn't a method.");
229 } 230 }
230 231
231 bool canReuseRemovedFunction(PartialFunctionElement element) { 232 bool canReuseRemovedFunction(PartialFunctionElement element) {
232 if (!element.isInstanceMember) { 233 logVerbose("Removed method $element.");
233 return cannotReuse(
234 element, "Removed function that isn't an instance method.");
235 }
236 logVerbose("Removed instance method $element.");
237 234
238 PartialClassElement cls = element.enclosingClass; 235 PartialClassElement cls = element.enclosingClass;
236 if (cls != null && !element.isInstanceMember) {
237 return cannotReuse(element, "Removed static method");
238 }
239 for (ScopeContainerElement scope in scopesAffectedBy(element, cls)) { 239 for (ScopeContainerElement scope in scopesAffectedBy(element, cls)) {
240 scanSites(scope, (Element member, DeclarationSite site) { 240 scanSites(scope, (Element member, DeclarationSite site) {
241 // TODO(ahe): Cache qualifiedNamesIn to avoid quadratic behavior. 241 // TODO(ahe): Cache qualifiedNamesIn to avoid quadratic behavior.
242 Map<String, List<String>> names = qualifiedNamesIn(site); 242 Map<String, List<String>> names = qualifiedNamesIn(site);
243 if (canNamesResolveTo(names, element, cls)) { 243 if (canNamesResolveTo(names, element, cls)) {
244 _elementsToInvalidate.add(member); 244 _elementsToInvalidate.add(member);
245 } 245 }
246 }); 246 });
247 } 247 }
248 248
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 /// state. 520 /// state.
521 void reuseElement() { 521 void reuseElement() {
522 compiler.forgetElement(before); 522 compiler.forgetElement(before);
523 before.reuseElement(); 523 before.reuseElement();
524 } 524 }
525 } 525 }
526 526
527 class RemovedFunctionUpdate extends Update with JsFeatures, ReuseFunction { 527 class RemovedFunctionUpdate extends Update with JsFeatures, ReuseFunction {
528 final PartialFunctionElement element; 528 final PartialFunctionElement element;
529 529
530 /// Name of property to remove using JavaScript "delete". 530 /// Name of property to remove using JavaScript "delete". Null for
531 /// non-instance methods.
531 String name; 532 String name;
532 533
533 /// Name of super-alias property to remove using JavaScript "delete". Null 534 /// Name of super-alias property to remove using JavaScript "delete". Null
534 /// for methods that aren't "super aliased" (should imply that this field is 535 /// for methods that aren't "super aliased", and non-instance methods.
535 /// null for all non-instance methods).
536 String superName; 536 String superName;
537 537
538 /// For instance methods, access to class object. Otherwise, access to the
539 /// method itself.
540 jsAst.Node elementAccess;
541
538 bool wasStateCaptured = false; 542 bool wasStateCaptured = false;
539 543
540 RemovedFunctionUpdate(Compiler compiler, this.element) 544 RemovedFunctionUpdate(Compiler compiler, this.element)
541 : super(compiler); 545 : super(compiler);
542 546
543 PartialFunctionElement get before => element; 547 PartialFunctionElement get before => element;
544 548
545 PartialElement get after => null; 549 PartialElement get after => null;
546 550
547 bool get isRemoval => true; 551 bool get isRemoval => true;
548 552
549 void captureState() { 553 void captureState() {
550 if (wasStateCaptured) throw "captureState was called twice."; 554 if (wasStateCaptured) throw "captureState was called twice.";
551 555
552 if (element.isInstanceMember) { 556 if (element.isInstanceMember) {
557 elementAccess = namer.elementAccess(element.enclosingClass);
553 name = namer.getNameOfMember(element); 558 name = namer.getNameOfMember(element);
554 } 559 if (backend.isAliasedSuperMember(element)) {
555 if (backend.isAliasedSuperMember(element)) { 560 superName = namer.getNameOfAliasedSuperMember(element);
556 superName = namer.getNameOfAliasedSuperMember(element); 561 }
562 } else {
563 elementAccess = namer.elementAccess(element);
557 } 564 }
558 565
559 wasStateCaptured = true; 566 wasStateCaptured = true;
560 } 567 }
561 568
562 PartialElement apply() { 569 PartialElement apply() {
563 if (!wasStateCaptured) throw "captureState must be called before apply."; 570 if (!wasStateCaptured) throw "captureState must be called before apply.";
564 removeFromEnclosingClass(); 571 removeFromEnclosing();
565 reuseElement(); 572 reuseElement();
566 return null; 573 return null;
567 } 574 }
568 575
569 void removeFromEnclosingClass() { 576 void removeFromEnclosing() {
570 PartialClassElement cls = element.enclosingClass; 577 PartialClassElement cls = element.enclosingClass;
578 if (cls == null) {
579 removeFromLibrary(element.library);
580 } else {
581 removeFromEnclosingClass(cls);
582 }
583 }
571 584
572 Link<Element> localMembersReversed = const Link<Element>(); 585 void removeFromEnclosingClass(PartialClassElement cls) {
573 bool foundElement = false; 586 cls.localMembersCache = null;
574 cls.forEachLocalMember((member) { 587 cls.localMembersReversed =
575 if (member != element) { 588 copyLinkWithout(element, cls.localMembersReversed);
576 localMembersReversed = localMembersReversed.prepend(member); 589 cls.localScope.contents.remove(element.name);
577 } else { 590 }
578 if (foundElement) { 591
579 throw "Found '$element' twice in '$cls'."; 592 void removeFromLibrary(LibraryElementX library) {
580 } 593 library.localMembers = copyLinkWithout(element, library.localMembers);
581 foundElement = true; 594 library.localScope.contents.remove(element.name);
595 }
596
597 Link copyLinkWithout(e, Link link) {
598 // TODO(ahe): Consider adding to [Link].
599 LinkBuilder copy = new LinkBuilder();
600
601 for (; !link.isEmpty; link = link.tail) {
602 if (link.head != e) {
603 copy.addLast(e);
582 } 604 }
583 });
584 if (!foundElement) {
585 throw "Don't find '$element' in '$cls'.";
586 } 605 }
587 cls.localMembersCache = null;
588 cls.localMembersReversed = localMembersReversed;
589 cls.localScope.contents.remove(element.name);
590 606
591 return null; 607 return copy.toLink(link);
592 } 608 }
593 609
594 void writeUpdateJsOn(List<jsAst.Statement> updates) { 610 void writeUpdateJsOn(List<jsAst.Statement> updates) {
595 if (name == null) { 611 if (elementAccess == null) {
596 compiler.internalError(element, '${element.runtimeType}'); 612 compiler.internalError(
613 element, 'No elementAccess for ${element.runtimeType}');
597 } 614 }
598 if (element.isInstanceMember) { 615 if (element.isInstanceMember) {
599 jsAst.Node elementAccess = namer.elementAccess(element.enclosingClass); 616 if (name == null) {
617 compiler.internalError(element, 'No name for ${element.runtimeType}');
618 }
600 updates.add( 619 updates.add(
601 js.statement('delete #.prototype.#', [elementAccess, name])); 620 js.statement('delete #.prototype.#', [elementAccess, name]));
602 621
603 if (superName != null) { 622 if (superName != null) {
604 updates.add( 623 updates.add(
605 js.statement('delete #.prototype.#', [elementAccess, superName])); 624 js.statement('delete #.prototype.#', [elementAccess, superName]));
606 } 625 }
607 } else { 626 } else {
608 compiler.internalError( 627 updates.add(js.statement('delete #', [elementAccess]));
609 element, 'Removal of non-instance methods not yest supported.');
610 } 628 }
611 } 629 }
612 } 630 }
613 631
614 Map<String, List<String>> qualifiedNamesIn(PartialElement element) { 632 Map<String, List<String>> qualifiedNamesIn(PartialElement element) {
615 Token beginToken = element.beginToken; 633 Token beginToken = element.beginToken;
616 Token endToken = element.endToken; 634 Token endToken = element.endToken;
617 Token token = beginToken; 635 Token token = beginToken;
618 if (element is PartialClassElement) { 636 if (element is PartialClassElement) {
619 ClassNode node = element.cachedNode; 637 ClassNode node = element.cachedNode;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 682
665 abstract class JsFeatures { 683 abstract class JsFeatures {
666 Compiler get compiler; 684 Compiler get compiler;
667 685
668 JavaScriptBackend get backend => compiler.backend; 686 JavaScriptBackend get backend => compiler.backend;
669 687
670 Namer get namer => backend.namer; 688 Namer get namer => backend.namer;
671 689
672 CodeEmitterTask get emitter => backend.emitter; 690 CodeEmitterTask get emitter => backend.emitter;
673 } 691 }
OLDNEW
« no previous file with comments | « no previous file | dart/tests/try/web/incremental_compilation_update_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698