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 | 4 |
5 import 'dart:async'; | 5 import 'dart:async'; |
6 import 'dart:collection'; | 6 import 'dart:collection'; |
7 import 'dart:typed_data'; | 7 import 'dart:typed_data'; |
8 | 8 |
9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
10 import 'package:analyzer/error/error.dart'; | 10 import 'package:analyzer/error/error.dart'; |
11 import 'package:analyzer/error/listener.dart'; | 11 import 'package:analyzer/error/listener.dart'; |
12 import 'package:analyzer/file_system/file_system.dart'; | 12 import 'package:analyzer/file_system/file_system.dart'; |
13 import 'package:analyzer/src/context/context.dart'; | 13 import 'package:analyzer/src/context/context.dart'; |
14 import 'package:analyzer/src/dart/analysis/byte_store.dart'; | 14 import 'package:analyzer/src/dart/analysis/byte_store.dart'; |
15 import 'package:analyzer/src/dart/analysis/file_state.dart'; | 15 import 'package:analyzer/src/dart/analysis/file_state.dart'; |
| 16 import 'package:analyzer/src/dart/analysis/index.dart'; |
16 import 'package:analyzer/src/dart/analysis/status.dart'; | 17 import 'package:analyzer/src/dart/analysis/status.dart'; |
17 import 'package:analyzer/src/generated/engine.dart' | 18 import 'package:analyzer/src/generated/engine.dart' |
18 show AnalysisContext, AnalysisEngine, AnalysisOptions, ChangeSet; | 19 show AnalysisContext, AnalysisEngine, AnalysisOptions, ChangeSet; |
19 import 'package:analyzer/src/generated/source.dart'; | 20 import 'package:analyzer/src/generated/source.dart'; |
20 import 'package:analyzer/src/summary/api_signature.dart'; | 21 import 'package:analyzer/src/summary/api_signature.dart'; |
21 import 'package:analyzer/src/summary/format.dart'; | 22 import 'package:analyzer/src/summary/format.dart'; |
22 import 'package:analyzer/src/summary/idl.dart'; | 23 import 'package:analyzer/src/summary/idl.dart'; |
23 import 'package:analyzer/src/summary/link.dart'; | 24 import 'package:analyzer/src/summary/link.dart'; |
24 import 'package:analyzer/src/summary/package_bundle_reader.dart'; | 25 import 'package:analyzer/src/summary/package_bundle_reader.dart'; |
25 import 'package:analyzer/src/summary/summarize_elements.dart'; | 26 import 'package:analyzer/src/summary/summarize_elements.dart'; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 * | 61 * |
61 * | 62 * |
62 * TODO(scheglov) Clean up the list of implicitly analyzed files. | 63 * TODO(scheglov) Clean up the list of implicitly analyzed files. |
63 * | 64 * |
64 * TODO(scheglov) Handle not existing 'dart:x' URIs (while user is typing). | 65 * TODO(scheglov) Handle not existing 'dart:x' URIs (while user is typing). |
65 */ | 66 */ |
66 class AnalysisDriver { | 67 class AnalysisDriver { |
67 /** | 68 /** |
68 * The version of data format, should be incremented on every format change. | 69 * The version of data format, should be incremented on every format change. |
69 */ | 70 */ |
70 static const int DATA_VERSION = 6; | 71 static const int DATA_VERSION = 7; |
71 | 72 |
72 /** | 73 /** |
73 * The name of the driver, e.g. the name of the folder. | 74 * The name of the driver, e.g. the name of the folder. |
74 */ | 75 */ |
75 String name; | 76 String name; |
76 | 77 |
77 /** | 78 /** |
78 * The scheduler that schedules analysis work in this, and possibly other | 79 * The scheduler that schedules analysis work in this, and possibly other |
79 * analysis drivers. | 80 * analysis drivers. |
80 */ | 81 */ |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 // Prepare the key for the cached result. | 468 // Prepare the key for the cached result. |
468 String key = _getResolvedUnitKey(libraryFile, file); | 469 String key = _getResolvedUnitKey(libraryFile, file); |
469 if (key == null) { | 470 if (key == null) { |
470 _logger.run('Compute the dependency hash for $path', () { | 471 _logger.run('Compute the dependency hash for $path', () { |
471 _createLibraryContext(libraryFile); | 472 _createLibraryContext(libraryFile); |
472 key = _getResolvedUnitKey(libraryFile, file); | 473 key = _getResolvedUnitKey(libraryFile, file); |
473 }); | 474 }); |
474 } | 475 } |
475 | 476 |
476 // Check for the cached result. | 477 // Check for the cached result. |
477 AnalysisResult result = _getCachedAnalysisResult(file, key); | 478 List<int> bytes = _byteStore.get(key); |
478 if (result != null) { | 479 if (bytes != null) { |
479 return result; | 480 return _getAnalysisResultFromBytes(file, bytes); |
480 } | 481 } |
481 } | 482 } |
482 | 483 |
483 // We need the fully resolved unit, or the result is not cached. | 484 // We need the fully resolved unit, or the result is not cached. |
484 return _logger.run('Compute analysis result for $path', () { | 485 return _logger.run('Compute analysis result for $path', () { |
485 FileState file = _verifyApiSignature(path); | 486 FileState file = _verifyApiSignature(path); |
486 | 487 |
487 // Prepare the library file - the file itself, or the known library. | 488 // Prepare the library file - the file itself, or the known library. |
488 FileState libraryFile = getLibraryFile(file); | 489 FileState libraryFile = getLibraryFile(file); |
489 if (libraryFile == null) { | 490 if (libraryFile == null) { |
490 return null; | 491 return null; |
491 } | 492 } |
492 | 493 |
493 _LibraryContext libraryContext = _createLibraryContext(libraryFile); | 494 _LibraryContext libraryContext = _createLibraryContext(libraryFile); |
494 AnalysisContext analysisContext = _createAnalysisContext(libraryContext); | 495 AnalysisContext analysisContext = _createAnalysisContext(libraryContext); |
495 try { | 496 try { |
496 analysisContext.setContents(file.source, file.content); | 497 analysisContext.setContents(file.source, file.content); |
497 // TODO(scheglov) Add support for parts. | 498 CompilationUnit resolvedUnit = analysisContext.resolveCompilationUnit2( |
498 CompilationUnit resolvedUnit = withUnit | 499 file.source, libraryFile.source); |
499 ? analysisContext.resolveCompilationUnit2( | |
500 file.source, libraryFile.source) | |
501 : null; | |
502 List<AnalysisError> errors = analysisContext.computeErrors(file.source); | 500 List<AnalysisError> errors = analysisContext.computeErrors(file.source); |
| 501 AnalysisDriverUnitIndexBuilder index = indexUnit(resolvedUnit); |
503 | 502 |
504 // Store the result into the cache. | 503 // Store the result into the cache. |
| 504 List<int> bytes; |
505 { | 505 { |
506 List<int> bytes = new AnalysisDriverResolvedUnitBuilder( | 506 bytes = new AnalysisDriverResolvedUnitBuilder( |
507 errors: errors | 507 errors: errors |
508 .map((error) => new AnalysisDriverUnitErrorBuilder( | 508 .map((error) => new AnalysisDriverUnitErrorBuilder( |
509 offset: error.offset, | 509 offset: error.offset, |
510 length: error.length, | 510 length: error.length, |
511 uniqueName: error.errorCode.uniqueName, | 511 uniqueName: error.errorCode.uniqueName, |
512 message: error.message, | 512 message: error.message, |
513 correction: error.correction)) | 513 correction: error.correction)) |
514 .toList()) | 514 .toList(), |
| 515 index: index) |
515 .toBuffer(); | 516 .toBuffer(); |
516 String key = _getResolvedUnitKey(libraryFile, file); | 517 String key = _getResolvedUnitKey(libraryFile, file); |
517 _byteStore.put(key, bytes); | 518 _byteStore.put(key, bytes); |
518 } | 519 } |
519 | 520 |
520 // Return the result, full or partial. | 521 // Return the result, full or partial. |
521 _logger.writeln('Computed new analysis result.'); | 522 _logger.writeln('Computed new analysis result.'); |
522 return new AnalysisResult( | 523 return _getAnalysisResultFromBytes(file, bytes, |
523 _sourceFactory, | 524 content: withUnit ? file.content : null, |
524 file.path, | 525 resolvedUnit: withUnit ? resolvedUnit : null); |
525 file.uri, | |
526 withUnit ? file.content : null, | |
527 file.contentHash, | |
528 file.lineInfo, | |
529 resolvedUnit, | |
530 errors); | |
531 } finally { | 526 } finally { |
532 analysisContext.dispose(); | 527 analysisContext.dispose(); |
533 } | 528 } |
534 }); | 529 }); |
535 } | 530 } |
536 | 531 |
537 AnalysisContext _createAnalysisContext(_LibraryContext libraryContext) { | 532 AnalysisContext _createAnalysisContext(_LibraryContext libraryContext) { |
538 AnalysisContextImpl analysisContext = | 533 AnalysisContextImpl analysisContext = |
539 AnalysisEngine.instance.createAnalysisContext(); | 534 AnalysisEngine.instance.createAnalysisContext(); |
540 analysisContext.analysisOptions = _analysisOptions; | 535 analysisContext.analysisOptions = _analysisOptions; |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 List<int> crossContextOptions = | 649 List<int> crossContextOptions = |
655 _analysisOptions.encodeCrossContextOptions(); | 650 _analysisOptions.encodeCrossContextOptions(); |
656 assert(crossContextOptions.length == | 651 assert(crossContextOptions.length == |
657 AnalysisOptions.crossContextOptionsLength); | 652 AnalysisOptions.crossContextOptionsLength); |
658 for (int i = 0; i < crossContextOptions.length; i++) { | 653 for (int i = 0; i < crossContextOptions.length; i++) { |
659 _salt[i + 1] = crossContextOptions[i]; | 654 _salt[i + 1] = crossContextOptions[i]; |
660 } | 655 } |
661 } | 656 } |
662 | 657 |
663 /** | 658 /** |
664 * If we know the result [key] for the [file], try to load the analysis | 659 * Load the [AnalysisResult] for the given [file] from the [bytes]. Set |
665 * result from the cache. Return `null` if not found. | 660 * optional [content] and [resolvedUnit]. |
666 */ | 661 */ |
667 AnalysisResult _getCachedAnalysisResult(FileState file, String key) { | 662 AnalysisResult _getAnalysisResultFromBytes(FileState file, List<int> bytes, |
668 List<int> bytes = _byteStore.get(key); | 663 {String content, CompilationUnit resolvedUnit}) { |
669 if (bytes != null) { | 664 var unit = new AnalysisDriverResolvedUnit.fromBuffer(bytes); |
670 var unit = new AnalysisDriverResolvedUnit.fromBuffer(bytes); | 665 List<AnalysisError> errors = unit.errors |
671 List<AnalysisError> errors = unit.errors | 666 .map((error) => new AnalysisError.forValues( |
672 .map((error) => new AnalysisError.forValues( | 667 file.source, |
673 file.source, | 668 error.offset, |
674 error.offset, | 669 error.length, |
675 error.length, | 670 errorCodeByUniqueName(error.uniqueName), |
676 errorCodeByUniqueName(error.uniqueName), | 671 error.message, |
677 error.message, | 672 error.correction)) |
678 error.correction)) | 673 .toList(); |
679 .toList(); | 674 return new AnalysisResult(_sourceFactory, file.path, file.uri, content, |
680 return new AnalysisResult(_sourceFactory, file.path, file.uri, null, | 675 file.contentHash, file.lineInfo, resolvedUnit, errors, unit.index); |
681 file.contentHash, file.lineInfo, null, errors); | |
682 } | |
683 return null; | |
684 } | 676 } |
685 | 677 |
686 /** | 678 /** |
687 * Return the key to store fully resolved results for the [file] in the | 679 * Return the key to store fully resolved results for the [file] in the |
688 * [library] into the cache. Return `null` if the dependency signature is | 680 * [library] into the cache. Return `null` if the dependency signature is |
689 * not known yet. | 681 * not known yet. |
690 */ | 682 */ |
691 String _getResolvedUnitKey(FileState library, FileState file) { | 683 String _getResolvedUnitKey(FileState library, FileState file) { |
692 ApiSignature signature = new ApiSignature(); | 684 ApiSignature signature = new ApiSignature(); |
693 signature.addUint32List(_salt); | 685 signature.addUint32List(_salt); |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
990 /** | 982 /** |
991 * The fully resolved compilation unit for the [content]. | 983 * The fully resolved compilation unit for the [content]. |
992 */ | 984 */ |
993 final CompilationUnit unit; | 985 final CompilationUnit unit; |
994 | 986 |
995 /** | 987 /** |
996 * The full list of computed analysis errors, both syntactic and semantic. | 988 * The full list of computed analysis errors, both syntactic and semantic. |
997 */ | 989 */ |
998 final List<AnalysisError> errors; | 990 final List<AnalysisError> errors; |
999 | 991 |
| 992 /** |
| 993 * The index of the unit. |
| 994 */ |
| 995 final AnalysisDriverUnitIndex index; |
| 996 |
1000 AnalysisResult(this.sourceFactory, this.path, this.uri, this.content, | 997 AnalysisResult(this.sourceFactory, this.path, this.uri, this.content, |
1001 this.contentHash, this.lineInfo, this.unit, this.errors); | 998 this.contentHash, this.lineInfo, this.unit, this.errors, this.index); |
1002 } | 999 } |
1003 | 1000 |
1004 /** | 1001 /** |
1005 * The result of parsing of a single file. | 1002 * The result of parsing of a single file. |
1006 * | 1003 * |
1007 * These results are self-consistent, i.e. [content], [contentHash], the | 1004 * These results are self-consistent, i.e. [content], [contentHash], the |
1008 * resolved [unit] correspond to each other. But none of the results is | 1005 * resolved [unit] correspond to each other. But none of the results is |
1009 * guaranteed to be consistent with the state of the files. | 1006 * guaranteed to be consistent with the state of the files. |
1010 */ | 1007 */ |
1011 class ParseResult { | 1008 class ParseResult { |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1146 @override | 1143 @override |
1147 int get hashCode => uri.hashCode; | 1144 int get hashCode => uri.hashCode; |
1148 | 1145 |
1149 bool operator ==(other) { | 1146 bool operator ==(other) { |
1150 return other is _LibraryNode && other.uri == uri; | 1147 return other is _LibraryNode && other.uri == uri; |
1151 } | 1148 } |
1152 | 1149 |
1153 @override | 1150 @override |
1154 String toString() => uri.toString(); | 1151 String toString() => uri.toString(); |
1155 } | 1152 } |
OLD | NEW |