| 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 |