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

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

Issue 2757753002: Migrate DDC to the new analysis driver.
Patch Set: Rebase Created 3 years, 6 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 JSON; 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/driver.dart';
19 import 'package:analyzer/src/dart/analysis/file_state.dart';
17 import 'package:analyzer/src/error/codes.dart' show StaticTypeWarningCode; 20 import 'package:analyzer/src/error/codes.dart' show StaticTypeWarningCode;
18 import 'package:analyzer/src/generated/engine.dart' 21 import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
19 show AnalysisContext, AnalysisEngine; 22 import 'package:analyzer/src/generated/resolver.dart';
20 import 'package:analyzer/src/generated/sdk.dart' show DartSdkManager; 23 import 'package:analyzer/src/generated/sdk.dart' show DartSdkManager;
21 import 'package:analyzer/src/generated/source.dart' 24 import 'package:analyzer/src/generated/source.dart'
22 show ContentCache, DartUriResolver; 25 show ContentCache, DartUriResolver, LineInfo;
23 import 'package:analyzer/src/generated/source_io.dart' 26 import 'package:analyzer/src/generated/source_io.dart'
24 show Source, SourceKind, UriResolver; 27 show Source, SourceKind, UriResolver;
25 import 'package:analyzer/src/summary/package_bundle_reader.dart' 28 import 'package:analyzer/src/summary/package_bundle_reader.dart'
26 show InSummarySource, InputPackagesResultProvider, SummaryDataStore; 29 show InSummarySource, SummaryDataStore;
27 import 'package:args/args.dart' show ArgParser, ArgResults; 30 import 'package:args/args.dart' show ArgParser, ArgResults;
28 import 'package:args/src/usage_exception.dart' show UsageException; 31 import 'package:args/src/usage_exception.dart' show UsageException;
32 import 'package:front_end/src/base/performace_logger.dart';
33 import 'package:front_end/src/incremental/byte_store.dart';
29 import 'package:func/func.dart' show Func1; 34 import 'package:func/func.dart' show Func1;
30 import 'package:path/path.dart' as path; 35 import 'package:path/path.dart' as path;
31 import 'package:source_maps/source_maps.dart'; 36 import 'package:source_maps/source_maps.dart';
32 37
33 import '../analyzer/context.dart' show AnalyzerOptions, createSourceFactory; 38 import '../analyzer/context.dart' show AnalyzerOptions, createSourceFactory;
34 import '../js_ast/js_ast.dart' as JS; 39 import '../js_ast/js_ast.dart' as JS;
35 import '../js_ast/js_ast.dart' show js; 40 import '../js_ast/js_ast.dart' show js;
36 import 'code_generator.dart' show CodeGenerator; 41 import 'code_generator.dart' show CodeGenerator;
37 import 'error_helpers.dart' show errorSeverity, formatError, sortErrors; 42 import 'error_helpers.dart' show errorSeverity, formatError, sortErrors;
38 import 'extension_types.dart' show ExtensionTypeSet; 43 import 'extension_types.dart' show ExtensionTypeSet;
39 import 'js_names.dart' as JS; 44 import 'js_names.dart' as JS;
40 import 'module_builder.dart' show transformModuleFormat, ModuleFormat; 45 import 'module_builder.dart' show transformModuleFormat, ModuleFormat;
41 import 'source_map_printer.dart' show SourceMapPrintingContext; 46 import 'source_map_printer.dart' show SourceMapPrintingContext;
42 47
43 /// Compiles a set of Dart files into a single JavaScript module. 48 /// Compiles a set of Dart files into a single JavaScript module.
44 /// 49 ///
45 /// For a single [BuildUnit] definition, this will produce a [JSModuleFile]. 50 /// For a single [BuildUnit] definition, this will produce a [JSModuleFile].
46 /// Those objects are record types that record the data consumed and produced 51 /// Those objects are record types that record the data consumed and produced
47 /// for a single compile. 52 /// for a single compile.
48 /// 53 ///
49 /// This class exists to cache global state associated with a single in-memory 54 /// This class exists to cache global state associated with a single in-memory
50 /// AnalysisContext, such as information about extension types in the Dart SDK. 55 /// [AnalysisDriver], such as information about extension types in the Dart SDK.
51 /// It can be used once to produce a single module, or reused to save warm-up 56 /// It can be used once to produce a single module, or reused to save warm-up
52 /// time. (Currently there is no warm up, but there may be in the future.) 57 /// time. (Currently there is no warm up, but there may be in the future.)
53 /// 58 ///
54 /// The SDK source code is assumed to be immutable for the life of this class. 59 /// The SDK source code is assumed to be immutable for the life of this class.
55 /// 60 ///
56 /// For all other files, it is up to the [AnalysisContext] to decide whether or 61 /// For all other files, it is up to the [AnalysisDriver] to decide whether or
57 /// not any caching is performed. By default an analysis context will assume 62 /// not any caching is performed. By default an analysis context will assume
58 /// sources are immutable for the life of the context, and cache information 63 /// sources are immutable for the life of the context, and cache information
59 /// about them. 64 /// about them.
60 class ModuleCompiler { 65 class ModuleCompiler {
61 final AnalysisContext context; 66 final AnalysisDriver driver;
62 final SummaryDataStore summaryData; 67 final SummaryDataStore summaryData;
63 final ExtensionTypeSet _extensionTypes;
64 68
65 ModuleCompiler._(AnalysisContext context, this.summaryData) 69 final Map<String, LibraryElement> _dartLibraries = {};
66 : context = context, 70 TypeProviderImpl _typeProvider;
67 _extensionTypes = new ExtensionTypeSet(context); 71
72 ExtensionTypeSet _extensionTypes;
73
74 ModuleCompiler._(this.driver, this.summaryData);
68 75
69 factory ModuleCompiler(AnalyzerOptions options, 76 factory ModuleCompiler(AnalyzerOptions options,
70 {ResourceProvider resourceProvider, 77 {ResourceProvider resourceProvider,
71 String analysisRoot, 78 String analysisRoot,
72 List<UriResolver> fileResolvers, 79 List<UriResolver> fileResolvers,
73 SummaryDataStore summaryData}) { 80 SummaryDataStore summaryData}) {
74 // TODO(danrubel): refactor with analyzer CLI into analyzer common code 81 // TODO(danrubel): refactor with analyzer CLI into analyzer common code
75 AnalysisEngine.instance.processRequiredPlugins(); 82 AnalysisEngine.instance.processRequiredPlugins();
76 83
77 resourceProvider ??= PhysicalResourceProvider.INSTANCE; 84 resourceProvider ??= PhysicalResourceProvider.INSTANCE;
(...skipping 19 matching lines...) Expand all
97 if (sdkSummaryBundle != null) { 104 if (sdkSummaryBundle != null) {
98 summaryData.addBundle(null, sdkSummaryBundle); 105 summaryData.addBundle(null, sdkSummaryBundle);
99 } 106 }
100 107
101 var srcFactory = createSourceFactory(options, 108 var srcFactory = createSourceFactory(options,
102 sdkResolver: sdkResolver, 109 sdkResolver: sdkResolver,
103 fileResolvers: fileResolvers, 110 fileResolvers: fileResolvers,
104 summaryData: summaryData, 111 summaryData: summaryData,
105 resourceProvider: resourceProvider); 112 resourceProvider: resourceProvider);
106 113
107 var context = 114 var declaredVariables = new DeclaredVariables();
108 AnalysisEngine.instance.createAnalysisContext() as AnalysisContextImpl; 115 options.declaredVariables.forEach(declaredVariables.define);
109 context.analysisOptions = analysisOptions; 116 declaredVariables.define('dart.isVM', 'false');
110 context.sourceFactory = srcFactory; 117 // TODO(vsm): Should this be hardcoded?
111 if (sdkSummaryBundle != null) { 118 declaredVariables.define('dart.library.html', 'true');
112 context.resultProvider = 119 declaredVariables.define('dart.library.io', 'false');
113 new InputPackagesResultProvider(context, summaryData); 120
121 if (!analysisOptions.strongMode) {
122 throw new ArgumentError('AnalysisOptions must be strong mode');
114 } 123 }
115 options.declaredVariables.forEach(context.declaredVariables.define); 124 if (!srcFactory.dartSdk.context.analysisOptions.strongMode) {
116 context.declaredVariables.define('dart.isVM', 'false'); 125 throw new ArgumentError('AnalysisOptions must have strong mode SDK');
117
118 // TODO(vsm): Should this be hardcoded?
119 context.declaredVariables.define('dart.library.html', 'true');
120 context.declaredVariables.define('dart.library.io', 'false');
121
122 if (!context.analysisOptions.strongMode) {
123 throw new ArgumentError('AnalysisContext must be strong mode');
124 }
125 if (!context.sourceFactory.dartSdk.context.analysisOptions.strongMode) {
126 throw new ArgumentError('AnalysisContext must have strong mode SDK');
127 } 126 }
128 127
129 return new ModuleCompiler._(context, summaryData); 128 AnalysisDriver driver;
129 {
130 var logger = new PerformanceLog(new StringBuffer());
131 var scheduler = new AnalysisDriverScheduler(logger);
132 driver = new AnalysisDriver(
133 scheduler,
134 logger,
135 resourceProvider,
136 new MemoryByteStore(),
137 new FileContentOverlay(),
138 null,
139 srcFactory,
140 analysisOptions,
141 disableChangesAndCacheAllResults: true,
142 externalSummaries: summaryData);
143 scheduler.start();
144 }
145
146 return new ModuleCompiler._(driver, summaryData);
130 } 147 }
131 148
132 bool _isFatalError(AnalysisError e, CompilerOptions options) { 149 bool _isFatalError(AnalysisError e, CompilerOptions options) {
133 if (errorSeverity(context, e) != ErrorSeverity.ERROR) return false; 150 if (errorSeverity(driver.analysisOptions, e) != ErrorSeverity.ERROR)
151 return false;
134 152
135 // These errors are not fatal in the REPL compile mode as we 153 // These errors are not fatal in the REPL compile mode as we
136 // allow access to private members across library boundaries 154 // allow access to private members across library boundaries
137 // and those accesses will show up as undefined members unless 155 // and those accesses will show up as undefined members unless
138 // additional analyzer changes are made to support them. 156 // additional analyzer changes are made to support them.
139 // TODO(jacobr): consider checking that the identifier name 157 // TODO(jacobr): consider checking that the identifier name
140 // referenced by the error is private. 158 // referenced by the error is private.
141 return !options.replCompile || 159 return !options.replCompile ||
142 (e.errorCode != StaticTypeWarningCode.UNDEFINED_GETTER && 160 (e.errorCode != StaticTypeWarningCode.UNDEFINED_GETTER &&
143 e.errorCode != StaticTypeWarningCode.UNDEFINED_SETTER && 161 e.errorCode != StaticTypeWarningCode.UNDEFINED_SETTER &&
144 e.errorCode != StaticTypeWarningCode.UNDEFINED_METHOD); 162 e.errorCode != StaticTypeWarningCode.UNDEFINED_METHOD);
145 } 163 }
146 164
147 /// Compiles a single Dart build unit into a JavaScript module. 165 /// Compiles a single Dart build unit into a JavaScript module.
148 /// 166 ///
149 /// *Warning* - this may require resolving the entire world. 167 /// *Warning* - this may require resolving the entire world.
150 /// If that is not desired, the analysis context must be pre-configured using 168 /// If that is not desired, the analysis context must be pre-configured using
151 /// summaries before calling this method. 169 /// summaries before calling this method.
152 JSModuleFile compile(BuildUnit unit, CompilerOptions options) { 170 Future<JSModuleFile> compile(BuildUnit unit, CompilerOptions options) async {
153 var trees = <CompilationUnit>[]; 171 var trees = <CompilationUnit>[];
154 var errors = <AnalysisError>[]; 172 var errors = <AnalysisError>[];
173 var lineInfoMap = <String, LineInfo>{};
155 174
156 var librariesToCompile = new Queue<LibraryElement>(); 175 var librariesToCompile = new Queue<LibraryElement>();
157 176
158 var compilingSdk = false; 177 var compilingSdk = false;
159 for (var sourcePath in unit.sources) { 178 for (var sourceUriStr in unit.sources) {
160 var sourceUri = _sourceToUri(sourcePath); 179 var sourceUri = _sourceToUri(sourceUriStr);
161 if (sourceUri.scheme == "dart") { 180 if (sourceUri.scheme == "dart") {
162 compilingSdk = true; 181 compilingSdk = true;
163 } 182 }
164 var source = context.sourceFactory.forUri2(sourceUri); 183 var source = driver.sourceFactory.forUri2(sourceUri);
184 String sourcePath = source.fullName;
165 185
166 var fileUsage = 'You need to pass at least one existing .dart file as an' 186 var fileUsage = 'You need to pass at least one existing .dart file as an'
167 ' argument.'; 187 ' argument.';
168 if (source == null) { 188 if (source == null) {
169 throw new UsageException( 189 throw new UsageException(
170 'Could not create a source for "$sourcePath". The file name is in' 190 'Could not create a source for "$sourceUriStr". The file name is in'
171 ' the wrong format or was not found.', 191 ' the wrong format or was not found.',
172 fileUsage); 192 fileUsage);
173 } else if (!source.exists()) { 193 } else if (!source.exists()) {
174 throw new UsageException( 194 throw new UsageException(
175 'Given file "$sourcePath" does not exist.', fileUsage); 195 'Given file "$sourceUriStr" does not exist.', fileUsage);
176 } 196 }
177 197
178 // Ignore parts. They need to be handled in the context of their library. 198 // Ignore parts. They need to be handled in the context of their library.
179 if (context.computeKindOf(source) == SourceKind.PART) { 199 SourceKind sourceKind = await driver.getSourceKind(sourcePath);
200 if (sourceKind == SourceKind.PART) {
180 continue; 201 continue;
181 } 202 }
182 203
183 librariesToCompile.add(context.computeLibraryElement(source)); 204 UnitElementResult unitResult = await driver.getUnitElement(sourcePath);
205 LibraryElement library = unitResult.element.library;
206 librariesToCompile.add(library);
184 } 207 }
185 208
186 var libraries = new HashSet<LibraryElement>(); 209 var libraries = new HashSet<LibraryElement>();
187 while (librariesToCompile.isNotEmpty) { 210 while (librariesToCompile.isNotEmpty) {
188 var library = librariesToCompile.removeFirst(); 211 var library = librariesToCompile.removeFirst();
189 if (library.source is InSummarySource) continue; 212 if (library.source is InSummarySource) continue;
190 if (!compilingSdk && library.source.isInSystemLibrary) continue; 213 if (!compilingSdk && library.source.isInSystemLibrary) continue;
191 if (!libraries.add(library)) continue; 214 if (!libraries.add(library)) continue;
192 215
193 librariesToCompile.addAll(library.importedLibraries); 216 librariesToCompile.addAll(library.importedLibraries);
194 librariesToCompile.addAll(library.exportedLibraries); 217 librariesToCompile.addAll(library.exportedLibraries);
195 218
196 var tree = context.resolveCompilationUnit(library.source, library); 219 var definingResult = await driver.getResult(library.source.fullName);
197 trees.add(tree); 220 trees.add(definingResult.unit);
198 errors.addAll(context.computeErrors(library.source)); 221 errors.addAll(definingResult.errors);
222 lineInfoMap[definingResult.path] = definingResult.lineInfo;
199 223
200 for (var part in library.parts) { 224 for (var part in library.parts) {
201 trees.add(context.resolveCompilationUnit(part.source, library)); 225 var partResult = await driver.getResult(part.source.fullName);
202 errors.addAll(context.computeErrors(part.source)); 226 trees.add(partResult.unit);
227 errors.addAll(partResult.errors);
228 lineInfoMap[partResult.path] = partResult.lineInfo;
203 } 229 }
204 } 230 }
205 231
206 sortErrors(context, errors); 232 sortErrors(driver.analysisOptions, errors);
233
234 LibraryElement coreLibrary = await _getDartLibrary('dart:core');
235 LibraryElement asyncLibrary = await _getDartLibrary('dart:async');
236 _typeProvider ??= new TypeProviderImpl(coreLibrary, asyncLibrary);
237 _extensionTypes ??= await _newExtensionTypeSet();
207 238
208 var messages = <String>[]; 239 var messages = <String>[];
209 for (var e in errors) { 240 for (AnalysisError e in errors) {
210 var m = formatError(context, e); 241 var lineInfo = lineInfoMap[e.source.fullName];
242 var m = formatError(driver.analysisOptions, lineInfo, e);
211 if (m != null) messages.add(m); 243 if (m != null) messages.add(m);
212 } 244 }
213 245
214 if (!options.unsafeForceCompile && 246 if (!options.unsafeForceCompile &&
215 errors.any((e) => _isFatalError(e, options))) { 247 errors.any((e) => _isFatalError(e, options))) {
216 return new JSModuleFile.invalid(unit.name, messages, options); 248 return new JSModuleFile.invalid(unit.name, messages, options);
217 } 249 }
218 250
219 try { 251 try {
220 var codeGenerator = 252 var codeGenerator = new CodeGenerator(
221 new CodeGenerator(context, summaryData, options, _extensionTypes); 253 driver, summaryData, options, _extensionTypes,
254 types: _typeProvider,
255 coreLibrary: coreLibrary,
256 asyncLibrary: asyncLibrary,
257 interceptorsLibrary: await _getDartLibrary('dart:_interceptors'),
258 internalLibrary: await _getDartLibrary('dart:_internal'),
259 jsLibrary: await _getDartLibrary('dart:js'));
222 return codeGenerator.compile(unit, trees, messages); 260 return codeGenerator.compile(unit, trees, messages);
223 } catch (e) { 261 } catch (e) {
224 if (errors.any((e) => _isFatalError(e, options))) { 262 if (errors.any((e) => _isFatalError(e, options))) {
225 // Force compilation failed. Suppress the exception and report 263 // Force compilation failed. Suppress the exception and report
226 // the static errors instead. 264 // the static errors instead.
227 assert(options.unsafeForceCompile); 265 assert(options.unsafeForceCompile);
228 return new JSModuleFile.invalid(unit.name, messages, options); 266 return new JSModuleFile.invalid(unit.name, messages, options);
229 } 267 }
230 rethrow; 268 rethrow;
231 } 269 }
232 } 270 }
271
272 Future<LibraryElement> _getDartLibrary(String uri) async {
273 assert(uri.startsWith('dart:'));
274 LibraryElement library = _dartLibraries[uri];
275 if (library == null) {
276 library = await driver.getLibraryByUri(uri);
277 _dartLibraries[uri] = library;
278 }
279 return library;
280 }
281
282 Future<ExtensionTypeSet> _newExtensionTypeSet() async {
283 return new ExtensionTypeSet(
284 coreLibrary: await _getDartLibrary('dart:core'),
285 collectionLibrary: await _getDartLibrary('dart:collection'),
286 mathLibrary: await _getDartLibrary('dart:math'),
287 htmlLibrary: await _getDartLibrary('dart:html'),
288 indexedDbLibrary: await _getDartLibrary('dart:indexed_db'),
289 svgLibrary: await _getDartLibrary('dart:svg'),
290 webAudioLibrary: await _getDartLibrary('dart:web_audio'),
291 webGlLibrary: await _getDartLibrary('dart:web_gl'),
292 webSqlLibrary: await _getDartLibrary('dart:web_sql'),
293 interceptorsLibrary: await _getDartLibrary('dart:_interceptors'),
294 nativeTypedDataLibrary:
295 await _getDartLibrary('dart:_native_typed_data'));
296 }
233 } 297 }
234 298
235 class CompilerOptions { 299 class CompilerOptions {
236 /// Whether to emit the source mapping file. 300 /// Whether to emit the source mapping file.
237 /// 301 ///
238 /// This supports debugging the original source code instead of the generated 302 /// This supports debugging the original source code instead of the generated
239 /// code. 303 /// code.
240 final bool sourceMap; 304 final bool sourceMap;
241 305
242 /// If [sourceMap] is emitted, this will emit a `sourceMappingUrl` comment 306 /// If [sourceMap] is emitted, this will emit a `sourceMappingUrl` comment
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
627 case "dart": 691 case "dart":
628 case "package": 692 case "package":
629 case "file": 693 case "file":
630 // A valid URI. 694 // A valid URI.
631 return uri; 695 return uri;
632 default: 696 default:
633 // Assume a file path. 697 // Assume a file path.
634 return new Uri.file(path.absolute(source)); 698 return new Uri.file(path.absolute(source));
635 } 699 }
636 } 700 }
OLDNEW
« no previous file with comments | « pkg/dev_compiler/lib/src/compiler/command.dart ('k') | pkg/dev_compiler/lib/src/compiler/element_helpers.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698