| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 library kernel.analyzer.loader; | 4 library kernel.analyzer.loader; |
| 5 | 5 |
| 6 import 'dart:async'; | 6 import 'dart:async'; |
| 7 import 'dart:io' as io; | 7 import 'dart:io' as io; |
| 8 | 8 |
| 9 import 'package:analyzer/analyzer.dart'; | 9 import 'package:analyzer/analyzer.dart'; |
| 10 import 'package:analyzer/file_system/file_system.dart'; | 10 import 'package:analyzer/file_system/file_system.dart'; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 | 104 |
| 105 /// Classes that have been referenced, and must be promoted to type level | 105 /// Classes that have been referenced, and must be promoted to type level |
| 106 /// so as not to expose partially initialized classes. | 106 /// so as not to expose partially initialized classes. |
| 107 final List<ast.Class> temporaryClassWorklist = []; | 107 final List<ast.Class> temporaryClassWorklist = []; |
| 108 | 108 |
| 109 final Map<LibraryElement, List<ClassElement>> mixinLibraryWorklist = {}; | 109 final Map<LibraryElement, List<ClassElement>> mixinLibraryWorklist = {}; |
| 110 | 110 |
| 111 final bool ignoreRedirectingFactories; | 111 final bool ignoreRedirectingFactories; |
| 112 | 112 |
| 113 LibraryElement _libraryBeingLoaded = null; | 113 LibraryElement _libraryBeingLoaded = null; |
| 114 ClassElement _classBeingPromotedToMixin = null; |
| 114 | 115 |
| 115 bool get strongMode => context.analysisOptions.strongMode; | 116 bool get strongMode => context.analysisOptions.strongMode; |
| 116 | 117 |
| 117 DartLoader(this.repository, DartOptions options, Packages packages, | 118 DartLoader(this.repository, DartOptions options, Packages packages, |
| 118 {DartSdk dartSdk, | 119 {DartSdk dartSdk, |
| 119 AnalysisContext context, | 120 AnalysisContext context, |
| 120 this.ignoreRedirectingFactories: true}) | 121 this.ignoreRedirectingFactories: true}) |
| 121 : this.context = | 122 : this.context = |
| 122 context ?? createContext(options, packages, dartSdk: dartSdk), | 123 context ?? createContext(options, packages, dartSdk: dartSdk), |
| 123 this.applicationRoot = options.applicationRoot; | 124 this.applicationRoot = options.applicationRoot; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 141 | 142 |
| 142 /// True if [element] is in the process of being loaded by | 143 /// True if [element] is in the process of being loaded by |
| 143 /// [_buildLibraryBody]. | 144 /// [_buildLibraryBody]. |
| 144 /// | 145 /// |
| 145 /// If this is the case, we should avoid adding new members to the classes | 146 /// If this is the case, we should avoid adding new members to the classes |
| 146 /// in the library, since the AST builder will rebuild the member lists. | 147 /// in the library, since the AST builder will rebuild the member lists. |
| 147 bool isLibraryBeingLoaded(LibraryElement element) { | 148 bool isLibraryBeingLoaded(LibraryElement element) { |
| 148 return _libraryBeingLoaded == element; | 149 return _libraryBeingLoaded == element; |
| 149 } | 150 } |
| 150 | 151 |
| 152 bool isClassBeingPromotedToMixin(ClassElement element) { |
| 153 return _classBeingPromotedToMixin == element; |
| 154 } |
| 155 |
| 151 void _buildLibraryBody(LibraryElement element, ast.Library library, | 156 void _buildLibraryBody(LibraryElement element, ast.Library library, |
| 152 List<CompilationUnit> units) { | 157 List<CompilationUnit> units) { |
| 153 assert(_libraryBeingLoaded == null); | 158 assert(_libraryBeingLoaded == null); |
| 154 _libraryBeingLoaded = element; | 159 _libraryBeingLoaded = element; |
| 155 var classes = <ast.Class>[]; | 160 var classes = <ast.Class>[]; |
| 156 var procedures = <ast.Procedure>[]; | 161 var procedures = <ast.Procedure>[]; |
| 157 var fields = <ast.Field>[]; | 162 var fields = <ast.Field>[]; |
| 158 | 163 |
| 159 void loadClass(NamedCompilationUnitMember declaration) { | 164 void loadClass(NamedCompilationUnitMember declaration) { |
| 160 // [declaration] can be a ClassDeclaration, EnumDeclaration, or a | 165 // [declaration] can be a ClassDeclaration, EnumDeclaration, or a |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 } | 392 } |
| 388 } | 393 } |
| 389 for (var supertype in classNode.supers) { | 394 for (var supertype in classNode.supers) { |
| 390 promoteToHierarchyLevel(supertype.classNode); | 395 promoteToHierarchyLevel(supertype.classNode); |
| 391 } | 396 } |
| 392 } | 397 } |
| 393 | 398 |
| 394 void promoteToMixinLevel(ast.Class classNode, ClassElement element, | 399 void promoteToMixinLevel(ast.Class classNode, ClassElement element, |
| 395 NamedCompilationUnitMember astNode) { | 400 NamedCompilationUnitMember astNode) { |
| 396 if (classNode.level.index >= ast.ClassLevel.Mixin.index) return; | 401 if (classNode.level.index >= ast.ClassLevel.Mixin.index) return; |
| 402 _classBeingPromotedToMixin = element; |
| 397 promoteToHierarchyLevel(classNode); | 403 promoteToHierarchyLevel(classNode); |
| 398 classNode.level = ast.ClassLevel.Mixin; | 404 classNode.level = ast.ClassLevel.Mixin; |
| 399 // Clear out the member references that were put in the class. | 405 // Clear out the member references that were put in the class. |
| 400 // The AST builder will load them all put back in the right order. | 406 // The AST builder will load them all put back in the right order. |
| 401 classNode..fields.clear()..procedures.clear()..constructors.clear(); | 407 classNode..fields.clear()..procedures.clear()..constructors.clear(); |
| 402 new ClassBodyBuilder(this, classNode, element).build(astNode); | 408 new ClassBodyBuilder(this, classNode, element).build(astNode); |
| 409 _classBeingPromotedToMixin = null; |
| 403 | 410 |
| 404 // Ensure mixed-in classes are available. | 411 // Ensure mixed-in classes are available. |
| 405 for (var mixin in element.mixins) { | 412 for (var mixin in element.mixins) { |
| 406 _ensureMixinBecomesLoaded(mixin.element); | 413 _ensureMixinBecomesLoaded(mixin.element); |
| 407 } | 414 } |
| 408 } | 415 } |
| 409 | 416 |
| 410 /// Ensures that [element] eventually becomes loaded at least at mixin level. | 417 /// Ensures that [element] eventually becomes loaded at least at mixin level. |
| 411 void _ensureMixinBecomesLoaded(ClassElement element) { | 418 void _ensureMixinBecomesLoaded(ClassElement element) { |
| 412 if (isLibraryBeingLoaded(element.library)) { | 419 if (isClassBeingPromotedToMixin(element)) { |
| 413 return; | 420 return; |
| 414 } | 421 } |
| 415 var class_ = getClassReference(element); | 422 var class_ = getClassReference(element); |
| 416 if (class_.level.index >= ast.ClassLevel.Mixin.index) { | 423 if (class_.level.index >= ast.ClassLevel.Mixin.index) { |
| 417 return; | 424 return; |
| 418 } | 425 } |
| 419 var list = mixinLibraryWorklist[element.library] ??= <ClassElement>[]; | 426 var list = mixinLibraryWorklist[element.library] ??= <ClassElement>[]; |
| 420 list.add(element); | 427 list.add(element); |
| 421 } | 428 } |
| 422 | 429 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 447 ast.Member _buildMemberReference(Element element) { | 454 ast.Member _buildMemberReference(Element element) { |
| 448 assert(element != null); | 455 assert(element != null); |
| 449 var node = _buildOrphanedMemberReference(element); | 456 var node = _buildOrphanedMemberReference(element); |
| 450 // Set the parent pointer and store it in the enclosing class or library. | 457 // Set the parent pointer and store it in the enclosing class or library. |
| 451 // If the enclosing library is being built from the AST, do not add the | 458 // If the enclosing library is being built from the AST, do not add the |
| 452 // member, since the AST builder will put it in there. | 459 // member, since the AST builder will put it in there. |
| 453 var parent = element.enclosingElement; | 460 var parent = element.enclosingElement; |
| 454 if (parent is ClassElement) { | 461 if (parent is ClassElement) { |
| 455 var class_ = getClassReference(parent); | 462 var class_ = getClassReference(parent); |
| 456 node.parent = class_; | 463 node.parent = class_; |
| 457 if (!isLibraryBeingLoaded(element.library)) { | 464 if (!isClassBeingPromotedToMixin(parent)) { |
| 458 class_.addMember(node); | 465 class_.addMember(node); |
| 459 } | 466 } |
| 460 } else { | 467 } else { |
| 461 var library = getLibraryReference(element.library); | 468 var library = getLibraryReference(element.library); |
| 462 node.parent = library; | 469 node.parent = library; |
| 463 if (!isLibraryBeingLoaded(element.library)) { | 470 if (!isLibraryBeingLoaded(element.library)) { |
| 464 library.addMember(node); | 471 library.addMember(node); |
| 465 } | 472 } |
| 466 } | 473 } |
| 467 return node; | 474 return node; |
| (...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 972 AnalysisContext context = AnalysisEngine.instance.createAnalysisContext() | 979 AnalysisContext context = AnalysisEngine.instance.createAnalysisContext() |
| 973 ..sourceFactory = new SourceFactory(resolvers) | 980 ..sourceFactory = new SourceFactory(resolvers) |
| 974 ..analysisOptions = createAnalysisOptions(options.strongMode); | 981 ..analysisOptions = createAnalysisOptions(options.strongMode); |
| 975 | 982 |
| 976 options.declaredVariables.forEach((String name, String value) { | 983 options.declaredVariables.forEach((String name, String value) { |
| 977 context.declaredVariables.define(name, value); | 984 context.declaredVariables.define(name, value); |
| 978 }); | 985 }); |
| 979 | 986 |
| 980 return context; | 987 return context; |
| 981 } | 988 } |
| OLD | NEW |