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'; |
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:kernel/application_root.dart'; |
19 import 'package:package_config/discovery.dart'; | 20 import 'package:package_config/discovery.dart'; |
20 import 'package:package_config/packages.dart'; | 21 import 'package:package_config/packages.dart'; |
21 | 22 |
22 import '../ast.dart' as ast; | 23 import '../ast.dart' as ast; |
23 import '../repository.dart'; | 24 import '../repository.dart'; |
24 import '../target/targets.dart' show Target; | 25 import '../target/targets.dart' show Target; |
25 import '../type_algebra.dart'; | 26 import '../type_algebra.dart'; |
26 import 'analyzer.dart'; | 27 import 'analyzer.dart'; |
27 import 'ast_from_analyzer.dart'; | 28 import 'ast_from_analyzer.dart'; |
28 | 29 |
29 /// Options passed to the Dart frontend. | 30 /// Options passed to the Dart frontend. |
30 class DartOptions { | 31 class DartOptions { |
31 /// True if user code should be loaded in strong mode. | 32 /// True if user code should be loaded in strong mode. |
32 bool strongMode; | 33 bool strongMode; |
33 | 34 |
34 /// True if the Dart SDK should be loaded in strong mode. | 35 /// True if the Dart SDK should be loaded in strong mode. |
35 bool strongModeSdk; | 36 bool strongModeSdk; |
36 String sdk; | 37 String sdk; |
37 String packagePath; | 38 String packagePath; |
| 39 ApplicationRoot applicationRoot; |
38 Map<Uri, Uri> customUriMappings; | 40 Map<Uri, Uri> customUriMappings; |
39 Map<String, String> declaredVariables; | 41 Map<String, String> declaredVariables; |
40 | 42 |
41 DartOptions( | 43 DartOptions( |
42 {bool strongMode: false, | 44 {bool strongMode: false, |
43 bool strongModeSdk, | 45 bool strongModeSdk, |
44 this.sdk, | 46 this.sdk, |
45 this.packagePath, | 47 this.packagePath, |
| 48 ApplicationRoot applicationRoot, |
46 Map<Uri, Uri> customUriMappings, | 49 Map<Uri, Uri> customUriMappings, |
47 Map<String, String> declaredVariables}) | 50 Map<String, String> declaredVariables}) |
48 : this.customUriMappings = customUriMappings ?? <Uri, Uri>{}, | 51 : this.customUriMappings = customUriMappings ?? <Uri, Uri>{}, |
49 this.declaredVariables = declaredVariables ?? <String, String>{}, | 52 this.declaredVariables = declaredVariables ?? <String, String>{}, |
50 this.strongMode = strongMode, | 53 this.strongMode = strongMode, |
51 this.strongModeSdk = strongModeSdk ?? strongMode; | 54 this.strongModeSdk = strongModeSdk ?? strongMode, |
| 55 this.applicationRoot = applicationRoot ?? new ApplicationRoot.none(); |
52 } | 56 } |
53 | 57 |
54 abstract class ReferenceLevelLoader { | 58 abstract class ReferenceLevelLoader { |
55 ast.Library getLibraryReference(LibraryElement element); | 59 ast.Library getLibraryReference(LibraryElement element); |
56 ast.Class getClassReference(ClassElement element); | 60 ast.Class getClassReference(ClassElement element); |
57 ast.Member getMemberReference(Element element); | 61 ast.Member getMemberReference(Element element); |
58 ast.Class getRootClassReference(); | 62 ast.Class getRootClassReference(); |
59 ast.Constructor getRootClassConstructorReference(); | 63 ast.Constructor getRootClassConstructorReference(); |
60 ast.Class getCoreClassReference(String className); | 64 ast.Class getCoreClassReference(String className); |
61 ast.Constructor getCoreClassConstructorReference(String className, | 65 ast.Constructor getCoreClassConstructorReference(String className, |
62 {String constructorName, String library}); | 66 {String constructorName, String library}); |
63 ast.TypeParameter tryGetClassTypeParameter(TypeParameterElement element); | 67 ast.TypeParameter tryGetClassTypeParameter(TypeParameterElement element); |
64 ast.Class getSharedMixinApplicationClass( | 68 ast.Class getSharedMixinApplicationClass( |
65 ast.Library library, ast.Class supertype, ast.Class mixin); | 69 ast.Library library, ast.Class supertype, ast.Class mixin); |
66 bool get strongMode; | 70 bool get strongMode; |
67 } | 71 } |
68 | 72 |
69 class DartLoader implements ReferenceLevelLoader { | 73 class DartLoader implements ReferenceLevelLoader { |
70 final Repository repository; | 74 final Repository repository; |
| 75 final ApplicationRoot applicationRoot; |
71 final Bimap<ClassElement, ast.Class> _classes = | 76 final Bimap<ClassElement, ast.Class> _classes = |
72 new Bimap<ClassElement, ast.Class>(); | 77 new Bimap<ClassElement, ast.Class>(); |
73 final Bimap<Element, ast.Member> _members = new Bimap<Element, ast.Member>(); | 78 final Bimap<Element, ast.Member> _members = new Bimap<Element, ast.Member>(); |
74 final Map<TypeParameterElement, ast.TypeParameter> _classTypeParameters = | 79 final Map<TypeParameterElement, ast.TypeParameter> _classTypeParameters = |
75 <TypeParameterElement, ast.TypeParameter>{}; | 80 <TypeParameterElement, ast.TypeParameter>{}; |
76 final Map<ast.Library, Map<String, ast.Class>> _mixinApplications = | 81 final Map<ast.Library, Map<String, ast.Class>> _mixinApplications = |
77 <ast.Library, Map<String, ast.Class>>{}; | 82 <ast.Library, Map<String, ast.Class>>{}; |
78 final AnalysisContext context; | 83 final AnalysisContext context; |
79 LibraryElement _dartCoreLibrary; | 84 LibraryElement _dartCoreLibrary; |
80 final List errors = []; | 85 final List errors = []; |
81 final List libraryElements = []; | 86 final List libraryElements = []; |
82 | 87 |
83 /// Classes that have been referenced, and must be promoted to type level | 88 /// Classes that have been referenced, and must be promoted to type level |
84 /// so as not to expose partially initialized classes. | 89 /// so as not to expose partially initialized classes. |
85 final List<ast.Class> temporaryClassWorklist = []; | 90 final List<ast.Class> temporaryClassWorklist = []; |
86 | 91 |
87 LibraryElement _libraryBeingLoaded = null; | 92 LibraryElement _libraryBeingLoaded = null; |
88 | 93 |
89 bool get strongMode => context.analysisOptions.strongMode; | 94 bool get strongMode => context.analysisOptions.strongMode; |
90 | 95 |
91 DartLoader(this.repository, DartOptions options, Packages packages, | 96 DartLoader(this.repository, DartOptions options, Packages packages, |
92 {DartSdk dartSdk}) | 97 {DartSdk dartSdk}) |
93 : this.context = createContext(options, packages, dartSdk: dartSdk); | 98 : this.context = createContext(options, packages, dartSdk: dartSdk), |
94 | 99 this.applicationRoot = options.applicationRoot; |
95 LibraryElement getLibraryElement(ast.Library node) { | |
96 return context | |
97 .getLibraryElement(context.sourceFactory.forUri2(node.importUri)); | |
98 } | |
99 | 100 |
100 String getLibraryName(LibraryElement element) { | 101 String getLibraryName(LibraryElement element) { |
101 return element.name.isEmpty ? null : element.name; | 102 return element.name.isEmpty ? null : element.name; |
102 } | 103 } |
103 | 104 |
104 ast.Library getLibraryReference(LibraryElement element) { | 105 ast.Library getLibraryReference(LibraryElement element) { |
105 return repository.getLibraryReference(element.source.uri) | 106 var uri = applicationRoot.relativeUri(element.source.uri); |
| 107 return repository.getLibraryReference(uri) |
106 ..name ??= getLibraryName(element) | 108 ..name ??= getLibraryName(element) |
107 ..fileUri = "file://${element.source.fullName}"; | 109 ..fileUri = "file://${element.source.fullName}"; |
108 } | 110 } |
109 | 111 |
110 void _buildTopLevelMember(ast.Member member, Element element) { | 112 void _buildTopLevelMember(ast.Member member, Element element) { |
111 var astNode = element.computeNode(); | 113 var astNode = element.computeNode(); |
112 assert(member.parent != null); | 114 assert(member.parent != null); |
113 new MemberBodyBuilder(this, member, element).build(astNode); | 115 new MemberBodyBuilder(this, member, element).build(astNode); |
114 } | 116 } |
115 | 117 |
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 AnalysisError error, String filename, LineInfo lines) { | 574 AnalysisError error, String filename, LineInfo lines) { |
573 var location = lines.getLocation(error.offset); | 575 var location = lines.getLocation(error.offset); |
574 return '[error] ${error.message} ($filename, ' | 576 return '[error] ${error.message} ($filename, ' |
575 'line ${location.lineNumber}, ' | 577 'line ${location.lineNumber}, ' |
576 'col ${location.columnNumber})'; | 578 'col ${location.columnNumber})'; |
577 } | 579 } |
578 | 580 |
579 void ensureLibraryIsLoaded(ast.Library node) { | 581 void ensureLibraryIsLoaded(ast.Library node) { |
580 if (!node.isExternal) return; | 582 if (!node.isExternal) return; |
581 node.isExternal = false; | 583 node.isExternal = false; |
582 var source = context.sourceFactory.forUri2(node.importUri); | 584 var source = context.sourceFactory |
| 585 .forUri2(applicationRoot.absoluteUri(node.importUri)); |
583 assert(source != null); | 586 assert(source != null); |
584 var element = context.computeLibraryElement(source); | 587 var element = context.computeLibraryElement(source); |
585 context.resolveCompilationUnit(source, element); | 588 context.resolveCompilationUnit(source, element); |
586 _buildLibraryBody(element, node); | 589 _buildLibraryBody(element, node); |
587 if (node.importUri.scheme != 'dart') { | 590 if (node.importUri.scheme != 'dart') { |
588 for (var unit in element.units) { | 591 for (var unit in element.units) { |
589 LineInfo lines; | 592 LineInfo lines; |
590 for (var error in context.computeErrors(unit.source)) { | 593 for (var error in context.computeErrors(unit.source)) { |
591 if (error.errorCode is CompileTimeErrorCode || | 594 if (error.errorCode is CompileTimeErrorCode || |
592 error.errorCode is ParserErrorCode || | 595 error.errorCode is ParserErrorCode || |
(...skipping 23 matching lines...) Expand all Loading... |
616 ensureLibraryIsLoaded(repository.libraries[i]); | 619 ensureLibraryIsLoaded(repository.libraries[i]); |
617 } | 620 } |
618 } | 621 } |
619 | 622 |
620 /// Builds a list of sources that have been loaded. | 623 /// Builds a list of sources that have been loaded. |
621 /// | 624 /// |
622 /// This operation may be expensive and should only be used for diagnostics. | 625 /// This operation may be expensive and should only be used for diagnostics. |
623 List<String> getLoadedFileNames() { | 626 List<String> getLoadedFileNames() { |
624 var list = <String>[]; | 627 var list = <String>[]; |
625 for (var library in repository.libraries) { | 628 for (var library in repository.libraries) { |
626 LibraryElement element = context.computeLibraryElement( | 629 LibraryElement element = context.computeLibraryElement(context |
627 context.sourceFactory.forUri2(library.importUri)); | 630 .sourceFactory |
| 631 .forUri2(applicationRoot.absoluteUri(library.importUri))); |
628 for (var unit in element.units) { | 632 for (var unit in element.units) { |
629 list.add(unit.source.fullName); | 633 list.add(unit.source.fullName); |
630 } | 634 } |
631 } | 635 } |
632 return list; | 636 return list; |
633 } | 637 } |
634 | 638 |
635 void _iterateWorklist() { | 639 void _iterateWorklist() { |
636 while (temporaryClassWorklist.isNotEmpty) { | 640 while (temporaryClassWorklist.isNotEmpty) { |
637 var element = temporaryClassWorklist.removeLast(); | 641 var element = temporaryClassWorklist.removeLast(); |
638 promoteToTypeLevel(element); | 642 promoteToTypeLevel(element); |
639 } | 643 } |
640 } | 644 } |
641 | 645 |
642 ast.Program loadProgram(String mainLibrary, {Target target}) { | 646 ast.Program loadProgram(Uri mainLibrary, {Target target}) { |
643 ast.Library library = repository.getLibrary(mainLibrary); | 647 ast.Library library = repository |
| 648 .getLibraryReference(applicationRoot.relativeUri(mainLibrary)); |
644 ensureLibraryIsLoaded(library); | 649 ensureLibraryIsLoaded(library); |
645 loadEverything(target: target); | 650 loadEverything(target: target); |
646 var program = new ast.Program(repository.libraries); | 651 var program = new ast.Program(repository.libraries); |
647 program.mainMethod = library.procedures.firstWhere( | 652 program.mainMethod = library.procedures.firstWhere( |
648 (member) => member.name?.name == 'main', | 653 (member) => member.name?.name == 'main', |
649 orElse: () => null); | 654 orElse: () => null); |
650 for (LibraryElement libraryElement in libraryElements) { | 655 for (LibraryElement libraryElement in libraryElements) { |
651 for (CompilationUnitElement compilationUnitElement | 656 for (CompilationUnitElement compilationUnitElement |
652 in libraryElement.units) { | 657 in libraryElement.units) { |
653 // TODO(jensj): Get this another way? | 658 // TODO(jensj): Get this another way? |
654 LineInfo lineInfo = compilationUnitElement.computeNode().lineInfo; | 659 LineInfo lineInfo = compilationUnitElement.computeNode().lineInfo; |
655 program.uriToLineStarts[ | 660 program.uriToLineStarts[ |
656 "file://${compilationUnitElement.source.source.fullName}"] = | 661 "file://${compilationUnitElement.source.source.fullName}"] = |
657 new List<int>.generate(lineInfo.lineCount, lineInfo.getOffsetOfLine, | 662 new List<int>.generate(lineInfo.lineCount, lineInfo.getOffsetOfLine, |
658 growable: false); | 663 growable: false); |
659 } | 664 } |
660 } | 665 } |
661 return program; | 666 return program; |
662 } | 667 } |
663 | 668 |
664 ast.Library loadLibrary(String mainLibrary) { | 669 ast.Library loadLibrary(Uri uri) { |
665 ast.Library library = repository.getLibrary(mainLibrary); | 670 ast.Library library = |
| 671 repository.getLibraryReference(applicationRoot.relativeUri(uri)); |
666 ensureLibraryIsLoaded(library); | 672 ensureLibraryIsLoaded(library); |
667 return library; | 673 return library; |
668 } | 674 } |
669 } | 675 } |
670 | 676 |
671 class Bimap<K, V> { | 677 class Bimap<K, V> { |
672 final Map<K, V> nodeMap = <K, V>{}; | 678 final Map<K, V> nodeMap = <K, V>{}; |
673 final Map<V, K> inverse = <V, K>{}; | 679 final Map<V, K> inverse = <V, K>{}; |
674 | 680 |
675 bool containsKey(K key) => nodeMap.containsKey(key); | 681 bool containsKey(K key) => nodeMap.containsKey(key); |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
809 AnalysisContext context = AnalysisEngine.instance.createAnalysisContext() | 815 AnalysisContext context = AnalysisEngine.instance.createAnalysisContext() |
810 ..sourceFactory = new SourceFactory(resolvers) | 816 ..sourceFactory = new SourceFactory(resolvers) |
811 ..analysisOptions = createAnalysisOptions(options.strongMode); | 817 ..analysisOptions = createAnalysisOptions(options.strongMode); |
812 | 818 |
813 options.declaredVariables.forEach((String name, String value) { | 819 options.declaredVariables.forEach((String name, String value) { |
814 context.declaredVariables.define(name, value); | 820 context.declaredVariables.define(name, value); |
815 }); | 821 }); |
816 | 822 |
817 return context; | 823 return context; |
818 } | 824 } |
OLD | NEW |