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

Side by Side Diff: pkg/analyzer_cli/lib/src/build_mode.dart

Issue 2994753002: Prepare all unlinked units before linking. (Closed)
Patch Set: Created 3 years, 4 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 library analyzer_cli.src.build_mode; 5 library analyzer_cli.src.build_mode;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:io' as io; 8 import 'dart:io' as io;
9 9
10 import 'package:analyzer/dart/ast/ast.dart' show CompilationUnit; 10 import 'package:analyzer/dart/ast/ast.dart' show CompilationUnit;
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 final AnalysisStats stats; 129 final AnalysisStats stats;
130 130
131 SummaryDataStore summaryDataStore; 131 SummaryDataStore summaryDataStore;
132 InternalAnalysisContext context; 132 InternalAnalysisContext context;
133 Map<Uri, File> uriToFileMap; 133 Map<Uri, File> uriToFileMap;
134 final List<Source> explicitSources = <Source>[]; 134 final List<Source> explicitSources = <Source>[];
135 final List<PackageBundle> unlinkedBundles = <PackageBundle>[]; 135 final List<PackageBundle> unlinkedBundles = <PackageBundle>[];
136 136
137 PackageBundleAssembler assembler; 137 PackageBundleAssembler assembler;
138 final Set<Source> processedSources = new Set<Source>(); 138 final Set<Source> processedSources = new Set<Source>();
139 final Map<Uri, UnlinkedUnit> uriToUnit = <Uri, UnlinkedUnit>{}; 139 final Map<String, UnlinkedUnit> uriToUnit = <String, UnlinkedUnit>{};
140 140
141 BuildMode(this.resourceProvider, this.options, this.stats); 141 BuildMode(this.resourceProvider, this.options, this.stats);
142 142
143 bool get _shouldOutputSummary => 143 bool get _shouldOutputSummary =>
144 options.buildSummaryOutput != null || 144 options.buildSummaryOutput != null ||
145 options.buildSummaryOutputSemantic != null; 145 options.buildSummaryOutputSemantic != null;
146 146
147 /** 147 /**
148 * Perform package analysis according to the given [options]. 148 * Perform package analysis according to the given [options].
149 */ 149 */
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 AnalysisResult analysisResult = context.performAnalysisTask(); 199 AnalysisResult analysisResult = context.performAnalysisTask();
200 if (!analysisResult.hasMoreWork) { 200 if (!analysisResult.hasMoreWork) {
201 break; 201 break;
202 } 202 }
203 } 203 }
204 } 204 }
205 205
206 // Write summary. 206 // Write summary.
207 assembler = new PackageBundleAssembler(); 207 assembler = new PackageBundleAssembler();
208 if (_shouldOutputSummary) { 208 if (_shouldOutputSummary) {
209 if (options.buildSummaryOnlyUnlinked) { 209 // Prepare all unlinked units.
210 for (var src in explicitSources) { 210 for (var src in explicitSources) {
211 // Note: This adds the unit to the assembler if it needed to be 211 _prepareUnlinkedUnit('${src.uri}');
212 // computed, so we don't need to explicitly do that. 212 }
213 _unlinkedUnitForUri('${src.uri}'); 213
214 } 214 // Build and assemble linked libraries.
215 } else { 215 if (!options.buildSummaryOnlyUnlinked) {
216 Set<String> unlinkedUris = 216 // Prepare URIs of unlinked units that should be linked.
217 explicitSources.map((Source s) => s.uri.toString()).toSet(); 217 var unlinkedUris = new Set<String>();
218 for (var bundle in unlinkedBundles) { 218 for (var bundle in unlinkedBundles) {
219 unlinkedUris.addAll(bundle.unlinkedUnitUris); 219 unlinkedUris.addAll(bundle.unlinkedUnitUris);
220 } 220 }
221 221 for (var src in explicitSources) {
222 _serializeAstBasedSummary(unlinkedUris); 222 unlinkedUris.add('${src.uri}');
223 }
224 // Perform linking.
225 _computeLinkedLibraries(unlinkedUris);
223 assembler.recordDependencies(summaryDataStore); 226 assembler.recordDependencies(summaryDataStore);
224 } 227 }
228
225 // Write the whole package bundle. 229 // Write the whole package bundle.
226 PackageBundleBuilder bundle = assembler.assemble(); 230 PackageBundleBuilder bundle = assembler.assemble();
227 if (options.buildSummaryOutput != null) { 231 if (options.buildSummaryOutput != null) {
228 io.File file = new io.File(options.buildSummaryOutput); 232 io.File file = new io.File(options.buildSummaryOutput);
229 file.writeAsBytesSync(bundle.toBuffer(), mode: io.FileMode.WRITE_ONLY); 233 file.writeAsBytesSync(bundle.toBuffer(), mode: io.FileMode.WRITE_ONLY);
230 } 234 }
231 if (options.buildSummaryOutputSemantic != null) { 235 if (options.buildSummaryOutputSemantic != null) {
232 bundle.flushInformative(); 236 bundle.flushInformative();
233 io.File file = new io.File(options.buildSummaryOutputSemantic); 237 io.File file = new io.File(options.buildSummaryOutputSemantic);
234 file.writeAsBytesSync(bundle.toBuffer(), mode: io.FileMode.WRITE_ONLY); 238 file.writeAsBytesSync(bundle.toBuffer(), mode: io.FileMode.WRITE_ONLY);
235 } 239 }
236 } 240 }
237 241
238 if (options.buildSummaryOnly) { 242 if (options.buildSummaryOnly) {
239 return ErrorSeverity.NONE; 243 return ErrorSeverity.NONE;
240 } else { 244 } else {
241 // Process errors. 245 // Process errors.
242 _printErrors(outputPath: options.buildAnalysisOutput); 246 _printErrors(outputPath: options.buildAnalysisOutput);
243 return _computeMaxSeverity(); 247 return _computeMaxSeverity();
244 } 248 }
245 } 249 }
246 250
251 /**
252 * Compute linked libraries for the given [libraryUris] using the linked
253 * libraries of the [summaryDataStore] and unlinked units in [uriToUnit], and
254 * add them to the [assembler].
255 */
256 void _computeLinkedLibraries(Set<String> libraryUris) {
257 LinkedLibrary getDependency(String absoluteUri) =>
258 summaryDataStore.linkedMap[absoluteUri];
259
260 UnlinkedUnit getUnit(String absoluteUri) =>
261 summaryDataStore.unlinkedMap[absoluteUri] ?? uriToUnit[absoluteUri];
262
263 Map<String, LinkedLibraryBuilder> linkResult = link(
264 libraryUris,
265 getDependency,
266 getUnit,
267 context.declaredVariables.get,
268 options.strongMode);
269 linkResult.forEach(assembler.addLinkedLibrary);
270 }
271
247 ErrorSeverity _computeMaxSeverity() { 272 ErrorSeverity _computeMaxSeverity() {
248 ErrorSeverity maxSeverity = ErrorSeverity.NONE; 273 ErrorSeverity maxSeverity = ErrorSeverity.NONE;
249 if (!options.buildSuppressExitCode) { 274 if (!options.buildSuppressExitCode) {
250 for (Source source in explicitSources) { 275 for (Source source in explicitSources) {
251 AnalysisErrorInfo errorInfo = context.getErrors(source); 276 AnalysisErrorInfo errorInfo = context.getErrors(source);
252 for (AnalysisError error in errorInfo.errors) { 277 for (AnalysisError error in errorInfo.errors) {
253 ErrorSeverity processedSeverity = determineProcessedSeverity( 278 ErrorSeverity processedSeverity = determineProcessedSeverity(
254 error, options, context.analysisOptions); 279 error, options, context.analysisOptions);
255 if (processedSeverity != null) { 280 if (processedSeverity != null) {
256 maxSeverity = maxSeverity.max(processedSeverity); 281 maxSeverity = maxSeverity.max(processedSeverity);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 return null; 380 return null;
356 } 381 }
357 Uri uri = Uri.parse(sourceFile.substring(0, pipeIndex)); 382 Uri uri = Uri.parse(sourceFile.substring(0, pipeIndex));
358 String path = sourceFile.substring(pipeIndex + 1); 383 String path = sourceFile.substring(pipeIndex + 1);
359 uriToFileMap[uri] = resourceProvider.getFile(path); 384 uriToFileMap[uri] = resourceProvider.getFile(path);
360 } 385 }
361 return uriToFileMap; 386 return uriToFileMap;
362 } 387 }
363 388
364 /** 389 /**
390 * Ensure that the [UnlinkedUnit] for [absoluteUri] is available.
391 *
392 * If the unit is in the input [summaryDataStore], do nothing.
393 *
394 * Otherwise compute it and store into the [uriToUnit] and [assembler].
395 */
396 void _prepareUnlinkedUnit(String absoluteUri) {
397 // Maybe an input package contains the source.
398 if (summaryDataStore.unlinkedMap[absoluteUri] != null) {
399 return;
400 }
401 // Parse the source and serialize its AST.
402 Uri uri = Uri.parse(absoluteUri);
403 Source source = context.sourceFactory.forUri2(uri);
404 if (!source.exists()) {
405 // TODO(paulberry): we should report a warning/error because DDC
406 // compilations are unlikely to work.
407 return;
408 }
409 CompilationUnit unit = context.computeResult(source, PARSED_UNIT);
410 UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit);
411 uriToUnit[absoluteUri] = unlinkedUnit;
412 assembler.addUnlinkedUnit(source, unlinkedUnit);
413 }
414
415 /**
365 * Print errors for all explicit sources. If [outputPath] is supplied, output 416 * Print errors for all explicit sources. If [outputPath] is supplied, output
366 * is sent to a new file at that path. 417 * is sent to a new file at that path.
367 */ 418 */
368 void _printErrors({String outputPath}) { 419 void _printErrors({String outputPath}) {
369 StringBuffer buffer = new StringBuffer(); 420 StringBuffer buffer = new StringBuffer();
370 var severityProcessor = (AnalysisError error) => 421 var severityProcessor = (AnalysisError error) =>
371 determineProcessedSeverity(error, options, context.analysisOptions); 422 determineProcessedSeverity(error, options, context.analysisOptions);
372 ErrorFormatter formatter = options.machineFormat 423 ErrorFormatter formatter = options.machineFormat
373 ? new MachineErrorFormatter(buffer, options, stats, 424 ? new MachineErrorFormatter(buffer, options, stats,
374 severityProcessor: severityProcessor) 425 severityProcessor: severityProcessor)
375 : new HumanErrorFormatter(buffer, options, stats, 426 : new HumanErrorFormatter(buffer, options, stats,
376 severityProcessor: severityProcessor); 427 severityProcessor: severityProcessor);
377 for (Source source in explicitSources) { 428 for (Source source in explicitSources) {
378 AnalysisErrorInfo errorInfo = context.getErrors(source); 429 AnalysisErrorInfo errorInfo = context.getErrors(source);
379 formatter.formatErrors([errorInfo]); 430 formatter.formatErrors([errorInfo]);
380 } 431 }
381 formatter.flush(); 432 formatter.flush();
382 if (!options.machineFormat) { 433 if (!options.machineFormat) {
383 stats.print(buffer); 434 stats.print(buffer);
384 } 435 }
385 if (outputPath == null) { 436 if (outputPath == null) {
386 StringSink sink = options.machineFormat ? errorSink : outSink; 437 StringSink sink = options.machineFormat ? errorSink : outSink;
387 sink.write(buffer); 438 sink.write(buffer);
388 } else { 439 } else {
389 new io.File(outputPath).writeAsStringSync(buffer.toString()); 440 new io.File(outputPath).writeAsStringSync(buffer.toString());
390 } 441 }
391 } 442 }
392
393 /**
394 * Serialize the package with the given [sources] into [assembler] using only
395 * their ASTs and [LinkedUnit]s of input packages.
396 */
397 void _serializeAstBasedSummary(Set<String> unlinkedUris) {
398 LinkedLibrary _getDependency(String absoluteUri) =>
399 summaryDataStore.linkedMap[absoluteUri];
400
401 Map<String, LinkedLibraryBuilder> linkResult = link(
402 unlinkedUris,
403 _getDependency,
404 _unlinkedUnitForUri,
405 context.declaredVariables.get,
406 options.strongMode);
407 linkResult.forEach(assembler.addLinkedLibrary);
408 }
409
410 /**
411 * Returns the [UnlinkedUnit] for [absoluteUri], either by computing it or
412 * using the stored one in [uriToUnit].
413 *
414 * If the [UnlinkedUnit] needed to be computed, it will also be added to the
415 * [assembler].
416 */
417 UnlinkedUnit _unlinkedUnitForUri(String absoluteUri) {
418 // Maybe an input package contains the source.
419 {
420 UnlinkedUnit unlinkedUnit = summaryDataStore.unlinkedMap[absoluteUri];
421 if (unlinkedUnit != null) {
422 return unlinkedUnit;
423 }
424 }
425 // Parse the source and serialize its AST.
426 Uri uri = Uri.parse(absoluteUri);
427 Source source = context.sourceFactory.forUri2(uri);
428 if (!source.exists()) {
429 // TODO(paulberry): we should report a warning/error because DDC
430 // compilations are unlikely to work.
431 return null;
432 }
433 return uriToUnit.putIfAbsent(uri, () {
434 CompilationUnit unit = context.computeResult(source, PARSED_UNIT);
435 UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit);
436 assembler.addUnlinkedUnit(source, unlinkedUnit);
437 return unlinkedUnit;
438 });
439 }
440 } 443 }
441 444
442 /** 445 /**
443 * Instances of the class [ExplicitSourceResolver] map URIs to files on disk 446 * Instances of the class [ExplicitSourceResolver] map URIs to files on disk
444 * using a fixed mapping provided at construction time. 447 * using a fixed mapping provided at construction time.
445 */ 448 */
446 class ExplicitSourceResolver extends UriResolver { 449 class ExplicitSourceResolver extends UriResolver {
447 final Map<Uri, File> uriToFileMap; 450 final Map<Uri, File> uriToFileMap;
448 final Map<String, Uri> pathToUriMap; 451 final Map<String, Uri> pathToUriMap;
449 452
(...skipping 25 matching lines...) Expand all
475 * Build the inverse mapping of [uriToSourceMap]. 478 * Build the inverse mapping of [uriToSourceMap].
476 */ 479 */
477 static Map<String, Uri> _computePathToUriMap(Map<Uri, File> uriToSourceMap) { 480 static Map<String, Uri> _computePathToUriMap(Map<Uri, File> uriToSourceMap) {
478 Map<String, Uri> pathToUriMap = <String, Uri>{}; 481 Map<String, Uri> pathToUriMap = <String, Uri>{};
479 uriToSourceMap.forEach((Uri uri, File file) { 482 uriToSourceMap.forEach((Uri uri, File file) {
480 pathToUriMap[file.path] = uri; 483 pathToUriMap[file.path] = uri;
481 }); 484 });
482 return pathToUriMap; 485 return pathToUriMap;
483 } 486 }
484 } 487 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698