| OLD | NEW |
| 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 import 'package:compiler/src/js_backend/js_backend.dart' show | 57 import 'package:compiler/src/js_backend/js_backend.dart' show |
| 58 JavaScriptBackend, | 58 JavaScriptBackend, |
| 59 Namer; | 59 Namer; |
| 60 | 60 |
| 61 import 'package:compiler/src/util/util.dart' show | 61 import 'package:compiler/src/util/util.dart' show |
| 62 Link, | 62 Link, |
| 63 LinkBuilder; | 63 LinkBuilder; |
| 64 | 64 |
| 65 import 'package:compiler/src/elements/modelx.dart' show | 65 import 'package:compiler/src/elements/modelx.dart' show |
| 66 ClassElementX, | 66 ClassElementX, |
| 67 CompilationUnitElementX, |
| 67 DeclarationSite, | 68 DeclarationSite, |
| 68 ElementX, | 69 ElementX, |
| 69 LibraryElementX; | 70 LibraryElementX; |
| 70 | 71 |
| 71 import 'diff.dart' show | 72 import 'diff.dart' show |
| 72 Difference, | 73 Difference, |
| 73 computeDifference; | 74 computeDifference; |
| 74 | 75 |
| 75 typedef void Logger(message); | 76 typedef void Logger(message); |
| 76 | 77 |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 return true; | 232 return true; |
| 232 } else if (element is PartialClassElement) { | 233 } else if (element is PartialClassElement) { |
| 233 addClass(element, container); | 234 addClass(element, container); |
| 234 return true; | 235 return true; |
| 235 } | 236 } |
| 236 return cannotReuse(element, "Added element that isn't a function."); | 237 return cannotReuse(element, "Added element that isn't a function."); |
| 237 } | 238 } |
| 238 | 239 |
| 239 void addFunction( | 240 void addFunction( |
| 240 PartialFunctionElement element, | 241 PartialFunctionElement element, |
| 241 ScopeContainerElement container) { | 242 /* ScopeContainerElement */ container) { |
| 242 invalidateScopesAffectedBy(element, container); | 243 invalidateScopesAffectedBy(element, container); |
| 243 | 244 |
| 244 updates.add(new AddedFunctionUpdate(compiler, element, container)); | 245 updates.add(new AddedFunctionUpdate(compiler, element, container)); |
| 245 } | 246 } |
| 246 | 247 |
| 247 void addClass( | 248 void addClass( |
| 248 PartialClassElement element, | 249 PartialClassElement element, |
| 249 LibraryElementX library) { | 250 LibraryElementX library) { |
| 250 invalidateScopesAffectedBy(element, library); | 251 invalidateScopesAffectedBy(element, library); |
| 251 | 252 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 281 _removedElements.add(element); | 282 _removedElements.add(element); |
| 282 element.forEachLocalMember((ElementX member) { | 283 element.forEachLocalMember((ElementX member) { |
| 283 _removedElements.add(member); | 284 _removedElements.add(member); |
| 284 }); | 285 }); |
| 285 | 286 |
| 286 updates.add(new RemovedClassUpdate(compiler, element)); | 287 updates.add(new RemovedClassUpdate(compiler, element)); |
| 287 } | 288 } |
| 288 | 289 |
| 289 void invalidateScopesAffectedBy( | 290 void invalidateScopesAffectedBy( |
| 290 ElementX element, | 291 ElementX element, |
| 291 ScopeContainerElement container) { | 292 /* ScopeContainerElement */ container) { |
| 292 for (ScopeContainerElement scope in scopesAffectedBy(element, container)) { | 293 for (ScopeContainerElement scope in scopesAffectedBy(element, container)) { |
| 293 scanSites(scope, (Element member, DeclarationSite site) { | 294 scanSites(scope, (Element member, DeclarationSite site) { |
| 294 // TODO(ahe): Cache qualifiedNamesIn to avoid quadratic behavior. | 295 // TODO(ahe): Cache qualifiedNamesIn to avoid quadratic behavior. |
| 295 Set<String> names = qualifiedNamesIn(site); | 296 Set<String> names = qualifiedNamesIn(site); |
| 296 if (canNamesResolveStaticallyTo(names, element, container)) { | 297 if (canNamesResolveStaticallyTo(names, element, container)) { |
| 297 _elementsToInvalidate.add(member); | 298 _elementsToInvalidate.add(member); |
| 298 } | 299 } |
| 299 }); | 300 }); |
| 300 } | 301 } |
| 301 } | 302 } |
| 302 | 303 |
| 303 /// Invoke [f] on each [DeclarationSite] in [element]. If [element] is a | 304 /// Invoke [f] on each [DeclarationSite] in [element]. If [element] is a |
| 304 /// [ScopeContainerElement], invoke f on all local members as well. | 305 /// [ScopeContainerElement], invoke f on all local members as well. |
| 305 void scanSites( | 306 void scanSites( |
| 306 Element element, | 307 Element element, |
| 307 void f(ElementX element, DeclarationSite site)) { | 308 void f(ElementX element, DeclarationSite site)) { |
| 308 DeclarationSite site = declarationSite(element); | 309 DeclarationSite site = declarationSite(element); |
| 309 if (site != null) { | 310 if (site != null) { |
| 310 f(element, site); | 311 f(element, site); |
| 311 } | 312 } |
| 312 if (element is ScopeContainerElement) { | 313 if (element is ScopeContainerElement) { |
| 313 element.forEachLocalMember((member) { scanSites(member, f); }); | 314 element.forEachLocalMember((member) { scanSites(member, f); }); |
| 314 } | 315 } |
| 315 } | 316 } |
| 316 | 317 |
| 317 /// Assume [element] is either removed from or added to [container], and | 318 /// Assume [element] is either removed from or added to [container], and |
| 318 /// return all [ScopeContainerElement] that can see this change. | 319 /// return all [ScopeContainerElement] that can see this change. |
| 319 List<ScopeContainerElement> scopesAffectedBy( | 320 List<ScopeContainerElement> scopesAffectedBy( |
| 320 Element element, | 321 Element element, |
| 321 ScopeContainerElement container) { | 322 /* ScopeContainerElement */ container) { |
| 322 // TODO(ahe): Use library export graph to compute this. | 323 // TODO(ahe): Use library export graph to compute this. |
| 323 // TODO(ahe): Should return all user-defined libraries and packages. | 324 // TODO(ahe): Should return all user-defined libraries and packages. |
| 324 LibraryElement library = container.library; | 325 LibraryElement library = container.library; |
| 325 List<ScopeContainerElement> result = <ScopeContainerElement>[library]; | 326 List<ScopeContainerElement> result = <ScopeContainerElement>[library]; |
| 326 | 327 |
| 327 if (!container.isClass) return result; | 328 if (!container.isClass) return result; |
| 328 | 329 |
| 329 ClassElement cls = container; | 330 ClassElement cls = container; |
| 330 | 331 |
| 331 var externalSubtypes = | 332 var externalSubtypes = |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 452 if (!element.isClass) { | 453 if (!element.isClass) { |
| 453 compiler.enqueuer.resolution.addToWorkList(element); | 454 compiler.enqueuer.resolution.addToWorkList(element); |
| 454 } else { | 455 } else { |
| 455 element.ensureResolved(compiler); | 456 element.ensureResolved(compiler); |
| 456 } | 457 } |
| 457 } | 458 } |
| 458 compiler.processQueue(compiler.enqueuer.resolution, null); | 459 compiler.processQueue(compiler.enqueuer.resolution, null); |
| 459 | 460 |
| 460 compiler.phase = Compiler.PHASE_DONE_RESOLVING; | 461 compiler.phase = Compiler.PHASE_DONE_RESOLVING; |
| 461 | 462 |
| 463 // TODO(ahe): Clean this up. Don't call this method in analyze-only mode. |
| 464 if (compiler.analyzeOnly) return "/* analyze only */"; |
| 465 |
| 462 Set<PartialClassElement> changedClasses = new Set<PartialClassElement>(); | 466 Set<PartialClassElement> changedClasses = new Set<PartialClassElement>(); |
| 463 for (Element element in updatedElements) { | 467 for (Element element in updatedElements) { |
| 464 if (!element.isClass) { | 468 if (!element.isClass) { |
| 465 compiler.enqueuer.codegen.addToWorkList(element); | 469 compiler.enqueuer.codegen.addToWorkList(element); |
| 466 } else { | 470 } else { |
| 467 changedClasses.add(element); | 471 changedClasses.add(element); |
| 468 } | 472 } |
| 469 } | 473 } |
| 470 compiler.processQueue(compiler.enqueuer.codegen, null); | 474 compiler.processQueue(compiler.enqueuer.codegen, null); |
| 471 | 475 |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 | 834 |
| 831 for (jsAst.Node access in accessToStatics) { | 835 for (jsAst.Node access in accessToStatics) { |
| 832 updates.add(js.statement('delete #', [access])); | 836 updates.add(js.statement('delete #', [access])); |
| 833 } | 837 } |
| 834 } | 838 } |
| 835 } | 839 } |
| 836 | 840 |
| 837 class AddedFunctionUpdate extends Update with JsFeatures { | 841 class AddedFunctionUpdate extends Update with JsFeatures { |
| 838 final PartialFunctionElement element; | 842 final PartialFunctionElement element; |
| 839 | 843 |
| 840 final ScopeContainerElement container; | 844 final /* ScopeContainerElement */ container; |
| 841 | 845 |
| 842 AddedFunctionUpdate(Compiler compiler, this.element, this.container) | 846 AddedFunctionUpdate(Compiler compiler, this.element, this.container) |
| 843 : super(compiler) { | 847 : super(compiler) { |
| 844 if (container == null) { | 848 if (container == null) { |
| 845 throw "container is null"; | 849 throw "container is null"; |
| 846 } | 850 } |
| 847 } | 851 } |
| 848 | 852 |
| 849 PartialFunctionElement get before => null; | 853 PartialFunctionElement get before => null; |
| 850 | 854 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 867 | 871 |
| 868 final LibraryElementX library; | 872 final LibraryElementX library; |
| 869 | 873 |
| 870 AddedClassUpdate(Compiler compiler, this.element, this.library) | 874 AddedClassUpdate(Compiler compiler, this.element, this.library) |
| 871 : super(compiler); | 875 : super(compiler); |
| 872 | 876 |
| 873 PartialClassElement get before => null; | 877 PartialClassElement get before => null; |
| 874 | 878 |
| 875 PartialClassElement get after => element; | 879 PartialClassElement get after => element; |
| 876 | 880 |
| 877 PartialFunctionElement apply() { | 881 PartialClassElement apply() { |
| 878 // TODO(ahe): Reuse compilation unit of element instead? | 882 // TODO(ahe): Reuse compilation unit of element instead? |
| 879 CompilationUnitElementX compilationUnit = library.compilationUnit; | 883 CompilationUnitElementX compilationUnit = library.compilationUnit; |
| 880 PartialClassElement copy = element.copyWithEnclosing(compilationUnit); | 884 PartialClassElement copy = element.copyWithEnclosing(compilationUnit); |
| 881 compilationUnit.addMember(copy, compiler); | 885 compilationUnit.addMember(copy, compiler); |
| 882 return copy; | 886 return copy; |
| 883 } | 887 } |
| 884 } | 888 } |
| 885 | 889 |
| 886 class ClassUpdate extends Update with JsFeatures { | 890 class ClassUpdate extends Update with JsFeatures { |
| 887 final PartialClassElement before; | 891 final PartialClassElement before; |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 971 token = token.next; | 975 token = token.next; |
| 972 } while (token.kind != EOF_TOKEN && token != endToken); | 976 } while (token.kind != EOF_TOKEN && token != endToken); |
| 973 return names; | 977 return names; |
| 974 } | 978 } |
| 975 | 979 |
| 976 /// Returns true if one of the qualified names in names (as computed by | 980 /// Returns true if one of the qualified names in names (as computed by |
| 977 /// [qualifiedNamesIn]) could be a static reference to [element]. | 981 /// [qualifiedNamesIn]) could be a static reference to [element]. |
| 978 bool canNamesResolveStaticallyTo( | 982 bool canNamesResolveStaticallyTo( |
| 979 Set<String> names, | 983 Set<String> names, |
| 980 Element element, | 984 Element element, |
| 981 ScopeContainerElement container) { | 985 /* ScopeContainerElement */ container) { |
| 982 if (names.contains(element.name)) return true; | 986 if (names.contains(element.name)) return true; |
| 983 if (container != null && container.isClass) { | 987 if (container != null && container.isClass) { |
| 984 // [names] contains C.m, where C is the name of [container], and m is the | 988 // [names] contains C.m, where C is the name of [container], and m is the |
| 985 // name of [element]. | 989 // name of [element]. |
| 986 if (names.contains("${container.name}.${element.name}")) return true; | 990 if (names.contains("${container.name}.${element.name}")) return true; |
| 987 } | 991 } |
| 988 // TODO(ahe): Check for prefixes as well. | 992 // TODO(ahe): Check for prefixes as well. |
| 989 return false; | 993 return false; |
| 990 } | 994 } |
| 991 | 995 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1010 | 1014 |
| 1011 ClassEmitter get classEmitter => backend.emitter.oldEmitter.classEmitter; | 1015 ClassEmitter get classEmitter => backend.emitter.oldEmitter.classEmitter; |
| 1012 | 1016 |
| 1013 List<String> computeFields(ClassElement cls) { | 1017 List<String> computeFields(ClassElement cls) { |
| 1014 // TODO(ahe): Rewrite for new emitter. | 1018 // TODO(ahe): Rewrite for new emitter. |
| 1015 ClassBuilder builder = new ClassBuilder(cls, namer); | 1019 ClassBuilder builder = new ClassBuilder(cls, namer); |
| 1016 classEmitter.emitFields(cls, builder, ""); | 1020 classEmitter.emitFields(cls, builder, ""); |
| 1017 return builder.fields; | 1021 return builder.fields; |
| 1018 } | 1022 } |
| 1019 } | 1023 } |
| OLD | NEW |