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

Side by Side Diff: pkg/kernel/lib/analyzer/loader.dart

Issue 2665723002: Implement canonical name scheme in kernel. (Closed)
Patch Set: Address comments Created 3 years, 10 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
OLDNEW
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';
11 import 'package:analyzer/file_system/physical_file_system.dart'; 11 import 'package:analyzer/file_system/physical_file_system.dart';
12 import 'package:analyzer/source/package_map_resolver.dart'; 12 import 'package:analyzer/source/package_map_resolver.dart';
13 import 'package:analyzer/src/dart/scanner/scanner.dart'; 13 import 'package:analyzer/src/dart/scanner/scanner.dart';
14 import 'package:analyzer/src/dart/sdk/sdk.dart'; 14 import 'package:analyzer/src/dart/sdk/sdk.dart';
15 import 'package:analyzer/src/generated/engine.dart'; 15 import 'package:analyzer/src/generated/engine.dart';
16 import 'package:analyzer/src/generated/parser.dart'; 16 import 'package:analyzer/src/generated/parser.dart';
17 import 'package:analyzer/src/generated/sdk.dart'; 17 import 'package:analyzer/src/generated/sdk.dart';
18 import 'package:analyzer/src/generated/source_io.dart'; 18 import 'package:analyzer/src/generated/source_io.dart';
19 import 'package:analyzer/src/summary/summary_sdk.dart'; 19 import 'package:analyzer/src/summary/summary_sdk.dart';
20 import 'package:kernel/application_root.dart'; 20 import 'package:kernel/application_root.dart';
21 import 'package:package_config/discovery.dart'; 21 import 'package:package_config/discovery.dart';
22 import 'package:package_config/packages.dart'; 22 import 'package:package_config/packages.dart';
23 23
24 import '../ast.dart' as ast; 24 import '../ast.dart' as ast;
25 import '../repository.dart';
26 import '../target/targets.dart' show Target; 25 import '../target/targets.dart' show Target;
27 import '../type_algebra.dart'; 26 import '../type_algebra.dart';
28 import 'analyzer.dart'; 27 import 'analyzer.dart';
29 import 'ast_from_analyzer.dart'; 28 import 'ast_from_analyzer.dart';
30 29
31 /// Options passed to the Dart frontend. 30 /// Options passed to the Dart frontend.
32 class DartOptions { 31 class DartOptions {
33 /// True if user code should be loaded in strong mode. 32 /// True if user code should be loaded in strong mode.
34 bool strongMode; 33 bool strongMode;
35 34
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 ast.Class getCoreClassReference(String className); 77 ast.Class getCoreClassReference(String className);
79 ast.Constructor getCoreClassConstructorReference(String className, 78 ast.Constructor getCoreClassConstructorReference(String className,
80 {String constructorName, String library}); 79 {String constructorName, String library});
81 ast.TypeParameter tryGetClassTypeParameter(TypeParameterElement element); 80 ast.TypeParameter tryGetClassTypeParameter(TypeParameterElement element);
82 ast.Class getSharedMixinApplicationClass( 81 ast.Class getSharedMixinApplicationClass(
83 ast.Library library, ast.Class supertype, ast.Class mixin); 82 ast.Library library, ast.Class supertype, ast.Class mixin);
84 bool get strongMode; 83 bool get strongMode;
85 } 84 }
86 85
87 class DartLoader implements ReferenceLevelLoader { 86 class DartLoader implements ReferenceLevelLoader {
88 final Repository repository; 87 final ast.Program program;
89 final ApplicationRoot applicationRoot; 88 final ApplicationRoot applicationRoot;
90 final Bimap<ClassElement, ast.Class> _classes = 89 final Bimap<ClassElement, ast.Class> _classes =
91 new Bimap<ClassElement, ast.Class>(); 90 new Bimap<ClassElement, ast.Class>();
92 final Bimap<Element, ast.Member> _members = new Bimap<Element, ast.Member>(); 91 final Bimap<Element, ast.Member> _members = new Bimap<Element, ast.Member>();
93 final Map<TypeParameterElement, ast.TypeParameter> _classTypeParameters = 92 final Map<TypeParameterElement, ast.TypeParameter> _classTypeParameters =
94 <TypeParameterElement, ast.TypeParameter>{}; 93 <TypeParameterElement, ast.TypeParameter>{};
95 final Map<ast.Library, Map<String, ast.Class>> _mixinApplications = 94 final Map<ast.Library, Map<String, ast.Class>> _mixinApplications =
96 <ast.Library, Map<String, ast.Class>>{}; 95 <ast.Library, Map<String, ast.Class>>{};
97 final AnalysisContext context; 96 final AnalysisContext context;
98 LibraryElement _dartCoreLibrary; 97 LibraryElement _dartCoreLibrary;
99 final List errors = []; 98 final List errors = [];
100 final List libraryElements = []; 99 final List libraryElements = [];
101 100
102 /// Classes that have been referenced, and must be promoted to type level 101 /// Classes that have been referenced, and must be promoted to type level
103 /// so as not to expose partially initialized classes. 102 /// so as not to expose partially initialized classes.
104 final List<ast.Class> temporaryClassWorklist = []; 103 final List<ast.Class> temporaryClassWorklist = [];
105 104
106 LibraryElement _libraryBeingLoaded = null; 105 LibraryElement _libraryBeingLoaded = null;
107 106
108 bool get strongMode => context.analysisOptions.strongMode; 107 bool get strongMode => context.analysisOptions.strongMode;
109 108
110 DartLoader(this.repository, DartOptions options, Packages packages, 109 DartLoader(this.program, DartOptions options, Packages packages,
111 {DartSdk dartSdk, AnalysisContext context}) 110 {DartSdk dartSdk, AnalysisContext context})
112 : this.context = 111 : this.context = context ?? createContext(options, packages, dartSdk: dart Sdk),
113 context ?? createContext(options, packages, dartSdk: dartSdk),
114 this.applicationRoot = options.applicationRoot; 112 this.applicationRoot = options.applicationRoot;
115 113
116 String getLibraryName(LibraryElement element) { 114 String getLibraryName(LibraryElement element) {
117 return element.name.isEmpty ? null : element.name; 115 return element.name.isEmpty ? null : element.name;
118 } 116 }
119 117
120 ast.Library getLibraryReference(LibraryElement element) { 118 ast.Library getLibraryReference(LibraryElement element) {
121 var uri = applicationRoot.relativeUri(element.source.uri); 119 var uri = applicationRoot.relativeUri(element.source.uri);
122 return repository.getLibraryReference(uri) 120 return program.getLibraryReference(uri)
123 ..name ??= getLibraryName(element) 121 ..name ??= getLibraryName(element)
124 ..fileUri = '${element.source.uri}'; 122 ..fileUri = '${element.source.uri}';
125 } 123 }
126 124
127 void _buildTopLevelMember( 125 void _buildTopLevelMember(
128 ast.Member member, Element element, Declaration astNode) { 126 ast.Member member, Element element, Declaration astNode) {
129 assert(member.parent != null); 127 assert(member.parent != null);
130 new MemberBodyBuilder(this, member, element).build(astNode); 128 new MemberBodyBuilder(this, member, element).build(astNode);
131 } 129 }
132 130
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 var freshParameters = 330 var freshParameters =
333 getFreshTypeParameters(classNode.typeParameters); 331 getFreshTypeParameters(classNode.typeParameters);
334 var mixinClass = new ast.Class( 332 var mixinClass = new ast.Class(
335 name: '${classNode.name}^${mixinType.classNode.name}', 333 name: '${classNode.name}^${mixinType.classNode.name}',
336 isAbstract: true, 334 isAbstract: true,
337 typeParameters: freshParameters.freshTypeParameters, 335 typeParameters: freshParameters.freshTypeParameters,
338 supertype: freshParameters.substituteSuper(supertype), 336 supertype: freshParameters.substituteSuper(supertype),
339 mixedInType: freshParameters.substituteSuper(mixinType), 337 mixedInType: freshParameters.substituteSuper(mixinType),
340 fileUri: classNode.fileUri)..fileOffset = element.nameOffset; 338 fileUri: classNode.fileUri)..fileOffset = element.nameOffset;
341 mixinClass.level = ast.ClassLevel.Type; 339 mixinClass.level = ast.ClassLevel.Type;
340 addMixinClassToLibrary(mixinClass, classNode.enclosingLibrary);
342 supertype = new ast.Supertype(mixinClass, 341 supertype = new ast.Supertype(mixinClass,
343 classNode.typeParameters.map(makeTypeParameterType).toList()); 342 classNode.typeParameters.map(makeTypeParameterType).toList());
344 addMixinClassToLibrary(mixinClass, classNode.enclosingLibrary);
345 // This class cannot be used from anywhere else, so don't try to 343 // This class cannot be used from anywhere else, so don't try to
346 // generate shared mixin applications using it. 344 // generate shared mixin applications using it.
347 useSharedMixin = false; 345 useSharedMixin = false;
348 } 346 }
349 } 347 }
350 classNode.supertype = supertype; 348 classNode.supertype = supertype;
351 for (var implementedType in element.interfaces) { 349 for (var implementedType in element.interfaces) {
352 classNode.implementedTypes.add(scope.buildSupertype(implementedType)); 350 classNode.implementedTypes.add(scope.buildSupertype(implementedType));
353 } 351 }
354 } 352 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 } 400 }
403 401
404 ast.Member getMemberReference(Element element) { 402 ast.Member getMemberReference(Element element) {
405 assert(element != null); 403 assert(element != null);
406 assert(element is! Member); // Use the "base element". 404 assert(element is! Member); // Use the "base element".
407 return _members[element] ??= _buildMemberReference(element); 405 return _members[element] ??= _buildMemberReference(element);
408 } 406 }
409 407
410 ast.Member _buildMemberReference(Element element) { 408 ast.Member _buildMemberReference(Element element) {
411 assert(element != null); 409 assert(element != null);
412 var node = _buildOrphanedMemberReference(element); 410 var member = _buildOrphanedMemberReference(element);
413 // Set the parent pointer and store it in the enclosing class or library. 411 // Set the parent pointer and store it in the enclosing class or library.
414 // If the enclosing library is being built from the AST, do not add the 412 // If the enclosing library is being built from the AST, do not add the
415 // member, since the AST builder will put it in there. 413 // member, since the AST builder will put it in there.
416 var parent = element.enclosingElement; 414 var parent = element.enclosingElement;
417 if (parent is ClassElement) { 415 if (parent is ClassElement) {
418 var class_ = getClassReference(parent); 416 var class_ = getClassReference(parent);
419 node.parent = class_; 417 member.parent = class_;
420 if (!isLibraryBeingLoaded(element.library)) { 418 if (!isLibraryBeingLoaded(element.library)) {
421 class_.addMember(node); 419 class_.addMember(member);
422 } 420 }
421 class_.canonicalName.getChildFromMember(member).bindTo(member);
423 } else { 422 } else {
424 var library = getLibraryReference(element.library); 423 var library = getLibraryReference(element.library);
425 node.parent = library; 424 member.parent = library;
426 if (!isLibraryBeingLoaded(element.library)) { 425 if (!isLibraryBeingLoaded(element.library)) {
427 library.addMember(node); 426 library.addMember(member);
428 } 427 }
428 library.canonicalName.getChildFromMember(member).bindTo(member);
429 } 429 }
430 return node; 430 return member;
431 } 431 }
432 432
433 ast.Member _buildOrphanedMemberReference(Element element) { 433 ast.Member _buildOrphanedMemberReference(Element element) {
434 assert(element != null); 434 assert(element != null);
435 ClassElement classElement = element.enclosingElement is ClassElement 435 ClassElement classElement = element.enclosingElement is ClassElement
436 ? element.enclosingElement 436 ? element.enclosingElement
437 : null; 437 : null;
438 TypeScope scope = classElement != null 438 TypeScope scope = classElement != null
439 ? new ClassScope(this, getLibraryReference(element.library)) 439 ? new ClassScope(this, getLibraryReference(element.library))
440 : new TypeScope(this); 440 : new TypeScope(this);
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 for (var uri in target.extraRequiredLibraries) { 651 for (var uri in target.extraRequiredLibraries) {
652 var library = _findLibraryElement(uri); 652 var library = _findLibraryElement(uri);
653 if (library == null) { 653 if (library == null) {
654 errors.add('Could not find required library $uri'); 654 errors.add('Could not find required library $uri');
655 continue; 655 continue;
656 } 656 }
657 ensureLibraryIsLoaded(getLibraryReference(library)); 657 ensureLibraryIsLoaded(getLibraryReference(library));
658 } 658 }
659 } 659 }
660 } 660 }
661 for (int i = 0; i < repository.libraries.length; ++i) { 661 for (int i = 0; i < program.libraries.length; ++i) {
662 var library = repository.libraries[i]; 662 var library = program.libraries[i];
663 if (compileSdk || library.importUri.scheme != 'dart') { 663 if (compileSdk || library.importUri.scheme != 'dart') {
664 ensureLibraryIsLoaded(library); 664 ensureLibraryIsLoaded(library);
665 } 665 }
666 } 666 }
667 } 667 }
668 668
669 /// Builds a list of sources that have been loaded. 669 /// Builds a list of sources that have been loaded.
670 /// 670 ///
671 /// This operation may be expensive and should only be used for diagnostics. 671 /// This operation may be expensive and should only be used for diagnostics.
672 List<String> getLoadedFileNames() { 672 List<String> getLoadedFileNames() {
673 var list = <String>[]; 673 var list = <String>[];
674 for (var library in repository.libraries) { 674 for (var library in program.libraries) {
675 LibraryElement element = context.computeLibraryElement(context 675 LibraryElement element = context.computeLibraryElement(context
676 .sourceFactory 676 .sourceFactory
677 .forUri2(applicationRoot.absoluteUri(library.importUri))); 677 .forUri2(applicationRoot.absoluteUri(library.importUri)));
678 for (var unit in element.units) { 678 for (var unit in element.units) {
679 list.add(unit.source.fullName); 679 list.add(unit.source.fullName);
680 } 680 }
681 } 681 }
682 return list; 682 return list;
683 } 683 }
684 684
(...skipping 24 matching lines...) Expand all
709 new ast.FunctionNode(new ast.ExpressionStatement(new ast.Throw( 709 new ast.FunctionNode(new ast.ExpressionStatement(new ast.Throw(
710 new ast.StringLiteral('Program has no main method')))), 710 new ast.StringLiteral('Program has no main method')))),
711 isStatic: true) 711 isStatic: true)
712 ..fileUri = library.fileUri; 712 ..fileUri = library.fileUri;
713 library.addMember(main); 713 library.addMember(main);
714 return main; 714 return main;
715 } 715 }
716 716
717 ast.Program loadProgram(Uri mainLibrary, {Target target, bool compileSdk}) { 717 ast.Program loadProgram(Uri mainLibrary, {Target target, bool compileSdk}) {
718 Uri uri = applicationRoot.relativeUri(mainLibrary); 718 Uri uri = applicationRoot.relativeUri(mainLibrary);
719 ast.Library library = repository.getLibraryReference(uri); 719 ast.Library library = program.getLibraryReference(uri);
720 ensureLibraryIsLoaded(library); 720 ensureLibraryIsLoaded(library);
721 var mainMethod = _getMainMethod(mainLibrary); 721 var mainMethod = _getMainMethod(mainLibrary);
722 loadEverything(target: target, compileSdk: compileSdk); 722 loadEverything(target: target, compileSdk: compileSdk);
723 var program = new ast.Program(repository.libraries);
724 if (mainMethod == null) { 723 if (mainMethod == null) {
725 mainMethod = _makeMissingMainMethod(library); 724 mainMethod = _makeMissingMainMethod(library);
726 } 725 }
727 program.mainMethod = mainMethod; 726 program.mainMethod = mainMethod;
728 for (LibraryElement libraryElement in libraryElements) { 727 for (LibraryElement libraryElement in libraryElements) {
729 for (CompilationUnitElement compilationUnitElement 728 for (CompilationUnitElement compilationUnitElement
730 in libraryElement.units) { 729 in libraryElement.units) {
731 var source = compilationUnitElement.source; 730 var source = compilationUnitElement.source;
732 LineInfo lineInfo = context.computeLineInfo(source); 731 LineInfo lineInfo = context.computeLineInfo(source);
733 String sourceCode; 732 String sourceCode;
734 try { 733 try {
735 sourceCode = context.getContents(source).data; 734 sourceCode = context.getContents(source).data;
736 } catch (e) { 735 } catch (e) {
737 // The source's contents could not be accessed. 736 // The source's contents could not be accessed.
738 sourceCode = ''; 737 sourceCode = '';
739 } 738 }
740 program.uriToSource['${source.uri}'] = 739 program.uriToSource['${source.uri}'] =
741 new ast.Source(lineInfo.lineStarts, sourceCode); 740 new ast.Source(lineInfo.lineStarts, sourceCode);
742 } 741 }
743 } 742 }
744 return program; 743 return program;
745 } 744 }
746 745
747 ast.Library loadLibrary(Uri uri) { 746 ast.Library loadLibrary(Uri uri) {
748 ast.Library library = 747 ast.Library library =
749 repository.getLibraryReference(applicationRoot.relativeUri(uri)); 748 program.getLibraryReference(applicationRoot.relativeUri(uri));
750 ensureLibraryIsLoaded(library); 749 ensureLibraryIsLoaded(library);
751 return library; 750 return library;
752 } 751 }
753 } 752 }
754 753
755 class Bimap<K, V> { 754 class Bimap<K, V> {
756 final Map<K, V> nodeMap = <K, V>{}; 755 final Map<K, V> nodeMap = <K, V>{};
757 final Map<V, K> inverse = <V, K>{}; 756 final Map<V, K> inverse = <V, K>{};
758 757
759 bool containsKey(K key) => nodeMap.containsKey(key); 758 bool containsKey(K key) => nodeMap.containsKey(key);
(...skipping 10 matching lines...) Expand all
770 /// Creates [DartLoader]s for a given configuration, while reusing the 769 /// Creates [DartLoader]s for a given configuration, while reusing the
771 /// [DartSdk] and [Packages] object if possible. 770 /// [DartSdk] and [Packages] object if possible.
772 class DartLoaderBatch { 771 class DartLoaderBatch {
773 Packages packages; 772 Packages packages;
774 DartSdk dartSdk; 773 DartSdk dartSdk;
775 774
776 String lastSdk; 775 String lastSdk;
777 String lastPackagePath; 776 String lastPackagePath;
778 bool lastStrongMode; 777 bool lastStrongMode;
779 778
780 Future<DartLoader> getLoader(Repository repository, DartOptions options, 779 Future<DartLoader> getLoader(ast.Program program, DartOptions options,
781 {String packageDiscoveryPath}) async { 780 {String packageDiscoveryPath}) async {
782 if (dartSdk == null || 781 if (dartSdk == null ||
783 lastSdk != options.sdk || 782 lastSdk != options.sdk ||
784 lastStrongMode != options.strongMode) { 783 lastStrongMode != options.strongMode) {
785 lastSdk = options.sdk; 784 lastSdk = options.sdk;
786 lastStrongMode = options.strongMode; 785 lastStrongMode = options.strongMode;
787 dartSdk = createDartSdk(options.sdk, strongMode: options.strongModeSdk); 786 dartSdk = createDartSdk(options.sdk, strongMode: options.strongModeSdk);
788 } 787 }
789 if (packages == null || 788 if (packages == null ||
790 lastPackagePath != options.packagePath || 789 lastPackagePath != options.packagePath ||
791 packageDiscoveryPath != null) { 790 packageDiscoveryPath != null) {
792 lastPackagePath = options.packagePath; 791 lastPackagePath = options.packagePath;
793 packages = await createPackages(options.packagePath, 792 packages = await createPackages(options.packagePath,
794 discoveryPath: packageDiscoveryPath); 793 discoveryPath: packageDiscoveryPath);
795 } 794 }
796 return new DartLoader(repository, options, packages, dartSdk: dartSdk); 795 return new DartLoader(program, options, packages, dartSdk: dartSdk);
797 } 796 }
798 } 797 }
799 798
800 Future<Packages> createPackages(String packagePath, 799 Future<Packages> createPackages(String packagePath,
801 {String discoveryPath}) async { 800 {String discoveryPath}) async {
802 if (packagePath != null) { 801 if (packagePath != null) {
803 var absolutePath = new io.File(packagePath).absolute.path; 802 var absolutePath = new io.File(packagePath).absolute.path;
804 if (await new io.Directory(packagePath).exists()) { 803 if (await new io.Directory(packagePath).exists()) {
805 return getPackagesDirectory(new Uri.file(absolutePath)); 804 return getPackagesDirectory(new Uri.file(absolutePath));
806 } else if (await new io.File(packagePath).exists()) { 805 } else if (await new io.File(packagePath).exists()) {
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 AnalysisContext context = AnalysisEngine.instance.createAnalysisContext() 897 AnalysisContext context = AnalysisEngine.instance.createAnalysisContext()
899 ..sourceFactory = new SourceFactory(resolvers) 898 ..sourceFactory = new SourceFactory(resolvers)
900 ..analysisOptions = createAnalysisOptions(options.strongMode); 899 ..analysisOptions = createAnalysisOptions(options.strongMode);
901 900
902 options.declaredVariables.forEach((String name, String value) { 901 options.declaredVariables.forEach((String name, String value) {
903 context.declaredVariables.define(name, value); 902 context.declaredVariables.define(name, value);
904 }); 903 });
905 904
906 return context; 905 return context;
907 } 906 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698