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

Side by Side Diff: pkg/dev_compiler/lib/src/compiler/compiler.dart

Issue 2757753002: Migrate DDC to the new analysis driver.
Patch Set: Created 3 years, 9 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 4
5 import 'dart:async';
5 import 'dart:collection' show HashSet, Queue; 6 import 'dart:collection' show HashSet, Queue;
6 import 'dart:convert' show BASE64, JSON, UTF8; 7 import 'dart:convert' show JSON;
7 import 'dart:io' show File; 8 import 'dart:io' show File;
8 9
9 import 'package:analyzer/analyzer.dart' 10 import 'package:analyzer/analyzer.dart'
10 show AnalysisError, CompilationUnit, ErrorSeverity; 11 show AnalysisError, CompilationUnit, ErrorSeverity;
12 import 'package:analyzer/context/declared_variables.dart';
11 import 'package:analyzer/dart/element/element.dart' show LibraryElement; 13 import 'package:analyzer/dart/element/element.dart' show LibraryElement;
12 import 'package:analyzer/file_system/file_system.dart' show ResourceProvider; 14 import 'package:analyzer/file_system/file_system.dart' show ResourceProvider;
13 import 'package:analyzer/file_system/physical_file_system.dart' 15 import 'package:analyzer/file_system/physical_file_system.dart'
14 show PhysicalResourceProvider; 16 show PhysicalResourceProvider;
15 import 'package:analyzer/src/context/builder.dart' show ContextBuilder; 17 import 'package:analyzer/src/context/builder.dart' show ContextBuilder;
16 import 'package:analyzer/src/context/context.dart' show AnalysisContextImpl; 18 import 'package:analyzer/src/dart/analysis/byte_store.dart';
19 import 'package:analyzer/src/dart/analysis/driver.dart';
20 import 'package:analyzer/src/dart/analysis/file_state.dart';
17 import 'package:analyzer/src/error/codes.dart' show StaticTypeWarningCode; 21 import 'package:analyzer/src/error/codes.dart' show StaticTypeWarningCode;
18 import 'package:analyzer/src/generated/engine.dart' 22 import 'package:analyzer/src/generated/engine.dart'
19 show AnalysisContext, AnalysisEngine; 23 show AnalysisContext, AnalysisEngine;
20 import 'package:analyzer/src/generated/sdk.dart' show DartSdkManager; 24 import 'package:analyzer/src/generated/sdk.dart' show DartSdkManager;
21 import 'package:analyzer/src/generated/source.dart' 25 import 'package:analyzer/src/generated/source.dart'
22 show ContentCache, DartUriResolver; 26 show ContentCache, DartUriResolver, LineInfo;
23 import 'package:analyzer/src/generated/source_io.dart' 27 import 'package:analyzer/src/generated/source_io.dart'
24 show Source, SourceKind, UriResolver; 28 show Source, SourceKind, UriResolver;
25 import 'package:analyzer/src/summary/package_bundle_reader.dart' 29 import 'package:analyzer/src/summary/package_bundle_reader.dart'
26 show InSummarySource, InputPackagesResultProvider, SummaryDataStore; 30 show InSummarySource, SummaryDataStore;
27 import 'package:args/args.dart' show ArgParser, ArgResults; 31 import 'package:args/args.dart' show ArgParser, ArgResults;
28 import 'package:args/src/usage_exception.dart' show UsageException; 32 import 'package:args/src/usage_exception.dart' show UsageException;
29 import 'package:func/func.dart' show Func1; 33 import 'package:func/func.dart' show Func1;
30 import 'package:path/path.dart' as path; 34 import 'package:path/path.dart' as path;
31 import 'package:source_maps/source_maps.dart'; 35 import 'package:source_maps/source_maps.dart';
32 36
33 import '../analyzer/context.dart' show AnalyzerOptions, createSourceFactory; 37 import '../analyzer/context.dart' show AnalyzerOptions, createSourceFactory;
34 import '../js_ast/js_ast.dart' as JS; 38 import '../js_ast/js_ast.dart' as JS;
35 import 'code_generator.dart' show CodeGenerator; 39 import 'code_generator.dart' show CodeGenerator;
36 import 'error_helpers.dart' show errorSeverity, formatError, sortErrors; 40 import 'error_helpers.dart' show errorSeverity, formatError, sortErrors;
(...skipping 13 matching lines...) Expand all
50 /// It can be used once to produce a single module, or reused to save warm-up 54 /// It can be used once to produce a single module, or reused to save warm-up
51 /// time. (Currently there is no warm up, but there may be in the future.) 55 /// time. (Currently there is no warm up, but there may be in the future.)
52 /// 56 ///
53 /// The SDK source code is assumed to be immutable for the life of this class. 57 /// The SDK source code is assumed to be immutable for the life of this class.
54 /// 58 ///
55 /// For all other files, it is up to the [AnalysisContext] to decide whether or 59 /// For all other files, it is up to the [AnalysisContext] to decide whether or
56 /// not any caching is performed. By default an analysis context will assume 60 /// not any caching is performed. By default an analysis context will assume
57 /// sources are immutable for the life of the context, and cache information 61 /// sources are immutable for the life of the context, and cache information
58 /// about them. 62 /// about them.
59 class ModuleCompiler { 63 class ModuleCompiler {
60 final AnalysisContext context; 64 final AnalysisDriver driver;
61 final SummaryDataStore summaryData; 65 final SummaryDataStore summaryData;
62 final ExtensionTypeSet _extensionTypes; 66 ExtensionTypeSet _extensionTypes;
63 67
64 ModuleCompiler._(AnalysisContext context, this.summaryData) 68 ModuleCompiler._(this.driver, this.summaryData);
65 : context = context,
66 _extensionTypes = new ExtensionTypeSet(context);
67 69
68 factory ModuleCompiler(AnalyzerOptions options, 70 factory ModuleCompiler(AnalyzerOptions options,
69 {ResourceProvider resourceProvider, 71 {ResourceProvider resourceProvider,
70 String analysisRoot, 72 String analysisRoot,
71 List<UriResolver> fileResolvers, 73 List<UriResolver> fileResolvers,
72 SummaryDataStore summaryData}) { 74 SummaryDataStore summaryData}) {
73 // TODO(danrubel): refactor with analyzer CLI into analyzer common code 75 // TODO(danrubel): refactor with analyzer CLI into analyzer common code
74 AnalysisEngine.instance.processRequiredPlugins(); 76 AnalysisEngine.instance.processRequiredPlugins();
75 77
76 resourceProvider ??= PhysicalResourceProvider.INSTANCE; 78 resourceProvider ??= PhysicalResourceProvider.INSTANCE;
(...skipping 15 matching lines...) Expand all
92 if (sdkSummaryBundle != null) { 94 if (sdkSummaryBundle != null) {
93 summaryData.addBundle(null, sdkSummaryBundle); 95 summaryData.addBundle(null, sdkSummaryBundle);
94 } 96 }
95 97
96 var srcFactory = createSourceFactory(options, 98 var srcFactory = createSourceFactory(options,
97 sdkResolver: sdkResolver, 99 sdkResolver: sdkResolver,
98 fileResolvers: fileResolvers, 100 fileResolvers: fileResolvers,
99 summaryData: summaryData, 101 summaryData: summaryData,
100 resourceProvider: resourceProvider); 102 resourceProvider: resourceProvider);
101 103
102 var context = 104 var declaredVariables = new DeclaredVariables();
103 AnalysisEngine.instance.createAnalysisContext() as AnalysisContextImpl; 105 options.declaredVariables.forEach(declaredVariables.define);
104 context.analysisOptions = analysisOptions; 106 declaredVariables.define('dart.isVM', 'false');
105 context.sourceFactory = srcFactory; 107 // TODO(vsm): Should this be hardcoded?
106 if (sdkSummaryBundle != null) { 108 declaredVariables.define('dart.library.html', 'true');
107 context.resultProvider = 109 declaredVariables.define('dart.library.io', 'false');
108 new InputPackagesResultProvider(context, summaryData); 110
111 if (!analysisOptions.strongMode) {
112 throw new ArgumentError('AnalysisOptions must be strong mode');
109 } 113 }
110 options.declaredVariables.forEach(context.declaredVariables.define); 114 if (!srcFactory.dartSdk.context.analysisOptions.strongMode) {
111 context.declaredVariables.define('dart.isVM', 'false'); 115 throw new ArgumentError('AnalysisOptions must have strong mode SDK');
112
113 // TODO(vsm): Should this be hardcoded?
114 context.declaredVariables.define('dart.library.html', 'true');
115 context.declaredVariables.define('dart.library.io', 'false');
116
117 if (!context.analysisOptions.strongMode) {
118 throw new ArgumentError('AnalysisContext must be strong mode');
119 }
120 if (!context.sourceFactory.dartSdk.context.analysisOptions.strongMode) {
121 throw new ArgumentError('AnalysisContext must have strong mode SDK');
122 } 116 }
123 117
124 return new ModuleCompiler._(context, summaryData); 118 AnalysisDriver driver;
119 {
Jennifer Messerly 2017/03/17 18:33:37 i'm not sure this block is necessary
scheglov 2017/04/25 17:07:35 We defined a couple of variables that are not usef
120 var logger = new PerformanceLog(new StringBuffer());
121 // var logger = new PerformanceLog(stdout);
Jennifer Messerly 2017/03/17 18:33:38 remove?
scheglov 2017/04/25 17:07:35 Done.
122 var scheduler = new AnalysisDriverScheduler(logger);
123 driver = new AnalysisDriver(
124 scheduler,
125 logger,
126 resourceProvider,
127 new MemoryByteStore(),
128 new FileContentOverlay(),
129 'DDC',
130 srcFactory,
131 analysisOptions,
132 externalSummaries: summaryData);
133 scheduler.start();
134 }
135
136 return new ModuleCompiler._(driver, summaryData);
125 } 137 }
126 138
127 bool _isFatalError(AnalysisError e, CompilerOptions options) { 139 bool _isFatalError(AnalysisError e, CompilerOptions options) {
128 if (errorSeverity(context, e) != ErrorSeverity.ERROR) return false; 140 if (errorSeverity(driver.analysisOptions, e) != ErrorSeverity.ERROR)
141 return false;
129 142
130 // These errors are not fatal in the REPL compile mode as we 143 // These errors are not fatal in the REPL compile mode as we
131 // allow access to private members across library boundaries 144 // allow access to private members across library boundaries
132 // and those accesses will show up as undefined members unless 145 // and those accesses will show up as undefined members unless
133 // additional analyzer changes are made to support them. 146 // additional analyzer changes are made to support them.
134 // TODO(jacobr): consider checking that the identifier name 147 // TODO(jacobr): consider checking that the identifier name
135 // referenced by the error is private. 148 // referenced by the error is private.
136 return !options.replCompile || 149 return !options.replCompile ||
137 (e.errorCode != StaticTypeWarningCode.UNDEFINED_GETTER && 150 (e.errorCode != StaticTypeWarningCode.UNDEFINED_GETTER &&
138 e.errorCode != StaticTypeWarningCode.UNDEFINED_SETTER && 151 e.errorCode != StaticTypeWarningCode.UNDEFINED_SETTER &&
139 e.errorCode != StaticTypeWarningCode.UNDEFINED_METHOD); 152 e.errorCode != StaticTypeWarningCode.UNDEFINED_METHOD);
140 } 153 }
141 154
142 /// Compiles a single Dart build unit into a JavaScript module. 155 /// Compiles a single Dart build unit into a JavaScript module.
143 /// 156 ///
144 /// *Warning* - this may require resolving the entire world. 157 /// *Warning* - this may require resolving the entire world.
145 /// If that is not desired, the analysis context must be pre-configured using 158 /// If that is not desired, the analysis context must be pre-configured using
146 /// summaries before calling this method. 159 /// summaries before calling this method.
147 JSModuleFile compile(BuildUnit unit, CompilerOptions options) { 160 Future<JSModuleFile> compile(BuildUnit unit, CompilerOptions options) async {
148 var trees = <CompilationUnit>[]; 161 var trees = <CompilationUnit>[];
149 var errors = <AnalysisError>[]; 162 var errors = <AnalysisError>[];
163 var lineInfoMap = <String, LineInfo>{};
150 164
151 var librariesToCompile = new Queue<LibraryElement>(); 165 var librariesToCompile = new Queue<LibraryElement>();
152 166
153 var compilingSdk = false; 167 var compilingSdk = false;
154 for (var sourcePath in unit.sources) { 168 for (var sourceUriStr in unit.sources) {
155 var sourceUri = Uri.parse(sourcePath); 169 var sourceUri = Uri.parse(sourceUriStr);
156 if (sourceUri.scheme == '') { 170 if (sourceUri.scheme == '') {
157 sourceUri = path.toUri(path.absolute(sourcePath)); 171 sourceUri = path.toUri(path.absolute(sourceUriStr));
158 } else if (sourceUri.scheme == 'dart') { 172 } else if (sourceUri.scheme == 'dart') {
159 compilingSdk = true; 173 compilingSdk = true;
160 } 174 }
161 Source source = context.sourceFactory.forUri2(sourceUri); 175 Source source = driver.sourceFactory.forUri2(sourceUri);
176 String sourcePath = source.fullName;
162 177
163 var fileUsage = 'You need to pass at least one existing .dart file as an' 178 var fileUsage = 'You need to pass at least one existing .dart file as an'
164 ' argument.'; 179 ' argument.';
165 if (source == null) { 180 if (source == null) {
166 throw new UsageException( 181 throw new UsageException(
167 'Could not create a source for "$sourcePath". The file name is in' 182 'Could not create a source for "$sourceUriStr". The file name is in'
168 ' the wrong format or was not found.', 183 ' the wrong format or was not found.',
169 fileUsage); 184 fileUsage);
170 } else if (!source.exists()) { 185 } else if (!source.exists()) {
171 throw new UsageException( 186 throw new UsageException(
172 'Given file "$sourcePath" does not exist.', fileUsage); 187 'Given file "$sourceUriStr" does not exist.', fileUsage);
173 } 188 }
174 189
175 // Ignore parts. They need to be handled in the context of their library. 190 // Ignore parts. They need to be handled in the context of their library.
176 if (context.computeKindOf(source) == SourceKind.PART) { 191 SourceKind sourceKind = await driver.getSourceKind(sourcePath);
192 if (sourceKind == SourceKind.PART) {
177 continue; 193 continue;
178 } 194 }
179 195
180 librariesToCompile.add(context.computeLibraryElement(source)); 196 UnitElementResult unitResult = await driver.getUnitElement(sourcePath);
197 LibraryElement library = unitResult.element.library;
198 librariesToCompile.add(library);
181 } 199 }
182 200
183 var libraries = new HashSet<LibraryElement>(); 201 var libraries = new HashSet<LibraryElement>();
184 while (librariesToCompile.isNotEmpty) { 202 while (librariesToCompile.isNotEmpty) {
185 var library = librariesToCompile.removeFirst(); 203 var library = librariesToCompile.removeFirst();
186 if (library.source is InSummarySource) continue; 204 if (library.source is InSummarySource) continue;
187 if (!compilingSdk && library.source.isInSystemLibrary) continue; 205 if (!compilingSdk && library.source.isInSystemLibrary) continue;
188 if (!libraries.add(library)) continue; 206 if (!libraries.add(library)) continue;
189 207
190 librariesToCompile.addAll(library.importedLibraries); 208 librariesToCompile.addAll(library.importedLibraries);
191 librariesToCompile.addAll(library.exportedLibraries); 209 librariesToCompile.addAll(library.exportedLibraries);
192 210
193 var tree = context.resolveCompilationUnit(library.source, library); 211 var definingResult = await driver.getResult(library.source.fullName);
194 trees.add(tree); 212 trees.add(definingResult.unit);
195 errors.addAll(context.computeErrors(library.source)); 213 errors.addAll(definingResult.errors);
214 lineInfoMap[definingResult.path] = definingResult.lineInfo;
196 215
197 for (var part in library.parts) { 216 for (var part in library.parts) {
198 trees.add(context.resolveCompilationUnit(part.source, library)); 217 var partResult = await driver.getResult(part.source.fullName);
199 errors.addAll(context.computeErrors(part.source)); 218 trees.add(partResult.unit);
219 errors.addAll(partResult.errors);
220 lineInfoMap[partResult.path] = partResult.lineInfo;
200 } 221 }
201 } 222 }
202 223
203 sortErrors(context, errors); 224 sortErrors(driver.analysisOptions, errors);
225
226 _extensionTypes ??= await ExtensionTypeSet.create(driver);
204 227
205 var messages = <String>[]; 228 var messages = <String>[];
206 for (var e in errors) { 229 for (AnalysisError e in errors) {
207 var m = formatError(context, e); 230 var lineInfo = lineInfoMap[e.source.fullName];
231 var m = formatError(driver.analysisOptions, lineInfo, e);
208 if (m != null) messages.add(m); 232 if (m != null) messages.add(m);
209 } 233 }
210 234
211 if (!options.unsafeForceCompile && 235 if (!options.unsafeForceCompile &&
212 errors.any((e) => _isFatalError(e, options))) { 236 errors.any((e) => _isFatalError(e, options))) {
213 return new JSModuleFile.invalid(unit.name, messages, options); 237 return new JSModuleFile.invalid(unit.name, messages, options);
214 } 238 }
215 var codeGenerator = 239 var codeGenerator = await CodeGenerator.create(
Jennifer Messerly 2017/03/17 18:33:38 I would rather keep async out of CodeGenerator, an
scheglov 2017/04/25 17:07:35 Done.
216 new CodeGenerator(context, summaryData, options, _extensionTypes); 240 driver, summaryData, options, _extensionTypes);
217 return codeGenerator.compile(unit, trees, messages); 241 return codeGenerator.compile(unit, trees, messages);
218 } 242 }
219 } 243 }
220 244
221 class CompilerOptions { 245 class CompilerOptions {
222 /// Whether to emit the source mapping file. 246 /// Whether to emit the source mapping file.
223 /// 247 ///
224 /// This supports debugging the original source code instead of the generated 248 /// This supports debugging the original source code instead of the generated
225 /// code. 249 /// code.
226 final bool sourceMap; 250 final bool sourceMap;
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 /// are implementation details that would just confuse users. 623 /// are implementation details that would just confuse users.
600 /// Normalize sdk urls to use "dart:" for more understandable stack traces. 624 /// Normalize sdk urls to use "dart:" for more understandable stack traces.
601 Map cleanupSdkSourcemap(Map sourceMap) { 625 Map cleanupSdkSourcemap(Map sourceMap) {
602 var map = new Map.from(sourceMap); 626 var map = new Map.from(sourceMap);
603 var list = new List.from(map['sources']); 627 var list = new List.from(map['sources']);
604 map['sources'] = map['sources'] 628 map['sources'] = map['sources']
605 .map((url) => url.contains('/_internal/') ? null : url) 629 .map((url) => url.contains('/_internal/') ? null : url)
606 .toList(); 630 .toList();
607 return map; 631 return map;
608 } 632 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698