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

Side by Side Diff: pkg/analyzer/lib/src/dart/analysis/driver.dart

Issue 2663903002: Store exceptions with transitive files context into ByteStore. (Closed)
Patch Set: Created 3 years, 10 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: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/context/declared_variables.dart'; 9 import 'package:analyzer/context/declared_variables.dart';
10 import 'package:analyzer/dart/ast/ast.dart'; 10 import 'package:analyzer/dart/ast/ast.dart';
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 * 70 *
71 * TODO(scheglov) Clean up the list of implicitly analyzed files. 71 * TODO(scheglov) Clean up the list of implicitly analyzed files.
72 */ 72 */
73 class AnalysisDriver { 73 class AnalysisDriver {
74 /** 74 /**
75 * The version of data format, should be incremented on every format change. 75 * The version of data format, should be incremented on every format change.
76 */ 76 */
77 static const int DATA_VERSION = 15; 77 static const int DATA_VERSION = 15;
78 78
79 /** 79 /**
80 * The number of exception contexts allowed to write. Once this field is
81 * zero, we stop writing any new exception contexts in this process.
82 */
83 static int allowedNumberOfContextsToWrite = 10;
84
85 /**
80 * The name of the driver, e.g. the name of the folder. 86 * The name of the driver, e.g. the name of the folder.
81 */ 87 */
82 final String name; 88 final String name;
83 89
84 /** 90 /**
85 * The scheduler that schedules analysis work in this, and possibly other 91 * The scheduler that schedules analysis work in this, and possibly other
86 * analysis drivers. 92 * analysis drivers.
87 */ 93 */
88 final AnalysisDriverScheduler _scheduler; 94 final AnalysisDriverScheduler _scheduler;
89 95
(...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 // We need the fully resolved unit, or the result is not cached. 731 // We need the fully resolved unit, or the result is not cached.
726 return _logger.run('Compute analysis result for $path', () { 732 return _logger.run('Compute analysis result for $path', () {
727 FileState file = _verifyApiSignature(path); 733 FileState file = _verifyApiSignature(path);
728 734
729 // Prepare the library file - the file itself, or the known library. 735 // Prepare the library file - the file itself, or the known library.
730 FileState libraryFile = getLibraryFile(file); 736 FileState libraryFile = getLibraryFile(file);
731 if (libraryFile == null) { 737 if (libraryFile == null) {
732 return null; 738 return null;
733 } 739 }
734 740
735 _LibraryContext libraryContext = _createLibraryContext(libraryFile);
736 AnalysisContext analysisContext = _createAnalysisContext(libraryContext);
737 try { 741 try {
738 CompilationUnit resolvedUnit = analysisContext.resolveCompilationUnit2( 742 _LibraryContext libraryContext = _createLibraryContext(libraryFile);
739 file.source, libraryFile.source); 743 AnalysisContext analysisContext =
740 List<AnalysisError> errors = analysisContext.computeErrors(file.source); 744 _createAnalysisContext(libraryContext);
741 AnalysisDriverUnitIndexBuilder index = indexUnit(resolvedUnit); 745 try {
746 CompilationUnit resolvedUnit = analysisContext
747 .resolveCompilationUnit2(file.source, libraryFile.source);
748 List<AnalysisError> errors =
749 analysisContext.computeErrors(file.source);
750 AnalysisDriverUnitIndexBuilder index = indexUnit(resolvedUnit);
742 751
743 // Store the result into the cache. 752 // Store the result into the cache.
744 List<int> bytes; 753 List<int> bytes;
745 { 754 {
746 bytes = new AnalysisDriverResolvedUnitBuilder( 755 bytes = new AnalysisDriverResolvedUnitBuilder(
747 errors: errors 756 errors: errors
748 .map((error) => new AnalysisDriverUnitErrorBuilder( 757 .map((error) => new AnalysisDriverUnitErrorBuilder(
749 offset: error.offset, 758 offset: error.offset,
750 length: error.length, 759 length: error.length,
751 uniqueName: error.errorCode.uniqueName, 760 uniqueName: error.errorCode.uniqueName,
752 message: error.message, 761 message: error.message,
753 correction: error.correction)) 762 correction: error.correction))
754 .toList(), 763 .toList(),
755 index: index) 764 index: index)
756 .toBuffer(); 765 .toBuffer();
757 String key = _getResolvedUnitKey(libraryFile, file); 766 String key = _getResolvedUnitKey(libraryFile, file);
758 _byteStore.put(key, bytes); 767 _byteStore.put(key, bytes);
768 }
769
770 // Return the result, full or partial.
771 _logger.writeln('Computed new analysis result.');
772 AnalysisResult result = _getAnalysisResultFromBytes(file, bytes,
773 content: withUnit ? file.content : null,
774 withErrors: _addedFiles.contains(path),
775 resolvedUnit: withUnit ? resolvedUnit : null);
776 if (withUnit && _priorityFiles.contains(path)) {
777 _priorityResults[path] = result;
778 }
779 return result;
780 } finally {
781 analysisContext.dispose();
759 } 782 }
760 783 } catch (exception, stackTrace) {
761 // Return the result, full or partial. 784 String contextKey =
762 _logger.writeln('Computed new analysis result.'); 785 _storeExceptionContext(path, libraryFile, exception, stackTrace);
763 AnalysisResult result = _getAnalysisResultFromBytes(file, bytes, 786 throw new _ExceptionState(exception, stackTrace, contextKey);
764 content: withUnit ? file.content : null,
765 withErrors: _addedFiles.contains(path),
766 resolvedUnit: withUnit ? resolvedUnit : null);
767 if (withUnit && _priorityFiles.contains(path)) {
768 _priorityResults[path] = result;
769 }
770 return result;
771 } finally {
772 analysisContext.dispose();
773 } 787 }
774 }); 788 });
775 } 789 }
776 790
777 AnalysisDriverUnitIndex _computeIndex(String path) { 791 AnalysisDriverUnitIndex _computeIndex(String path) {
778 AnalysisResult analysisResult = _computeAnalysisResult(path, 792 AnalysisResult analysisResult = _computeAnalysisResult(path,
779 withUnit: false, asIsIfPartWithoutLibrary: true); 793 withUnit: false, asIsIfPartWithoutLibrary: true);
780 return analysisResult._index; 794 return analysisResult._index;
781 } 795 }
782 796
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 if (_filesToAnalyze.remove(path)) { 1083 if (_filesToAnalyze.remove(path)) {
1070 try { 1084 try {
1071 AnalysisResult result = 1085 AnalysisResult result =
1072 _computeAnalysisResult(path, withUnit: true); 1086 _computeAnalysisResult(path, withUnit: true);
1073 if (result == null) { 1087 if (result == null) {
1074 _partsToAnalyze.add(path); 1088 _partsToAnalyze.add(path);
1075 } else { 1089 } else {
1076 _resultController.add(result); 1090 _resultController.add(result);
1077 } 1091 }
1078 } catch (exception, stackTrace) { 1092 } catch (exception, stackTrace) {
1079 _reportError(path, exception, stackTrace); 1093 _reportException(path, exception, stackTrace);
1080 } 1094 }
1081 return; 1095 return;
1082 } 1096 }
1083 } 1097 }
1084 } 1098 }
1085 1099
1086 // Analyze a general file. 1100 // Analyze a general file.
1087 if (_filesToAnalyze.isNotEmpty) { 1101 if (_filesToAnalyze.isNotEmpty) {
1088 String path = _removeFirst(_filesToAnalyze); 1102 String path = _removeFirst(_filesToAnalyze);
1089 try { 1103 try {
1090 AnalysisResult result = _computeAnalysisResult(path, withUnit: false); 1104 AnalysisResult result = _computeAnalysisResult(path, withUnit: false);
1091 if (result == null) { 1105 if (result == null) {
1092 _partsToAnalyze.add(path); 1106 _partsToAnalyze.add(path);
1093 } else { 1107 } else {
1094 _resultController.add(result); 1108 _resultController.add(result);
1095 } 1109 }
1096 } catch (exception, stackTrace) { 1110 } catch (exception, stackTrace) {
1097 _reportError(path, exception, stackTrace); 1111 _reportException(path, exception, stackTrace);
1098 } 1112 }
1099 return; 1113 return;
1100 } 1114 }
1101 1115
1102 // Analyze a requested part file. 1116 // Analyze a requested part file.
1103 if (_requestedParts.isNotEmpty) { 1117 if (_requestedParts.isNotEmpty) {
1104 String path = _requestedParts.keys.first; 1118 String path = _requestedParts.keys.first;
1105 try { 1119 try {
1106 AnalysisResult result = _computeAnalysisResult(path, 1120 AnalysisResult result = _computeAnalysisResult(path,
1107 withUnit: true, asIsIfPartWithoutLibrary: true); 1121 withUnit: true, asIsIfPartWithoutLibrary: true);
(...skipping 15 matching lines...) Expand all
1123 1137
1124 // Analyze a general part. 1138 // Analyze a general part.
1125 if (_partsToAnalyze.isNotEmpty) { 1139 if (_partsToAnalyze.isNotEmpty) {
1126 String path = _removeFirst(_partsToAnalyze); 1140 String path = _removeFirst(_partsToAnalyze);
1127 try { 1141 try {
1128 AnalysisResult result = _computeAnalysisResult(path, 1142 AnalysisResult result = _computeAnalysisResult(path,
1129 withUnit: _priorityFiles.contains(path), 1143 withUnit: _priorityFiles.contains(path),
1130 asIsIfPartWithoutLibrary: true); 1144 asIsIfPartWithoutLibrary: true);
1131 _resultController.add(result); 1145 _resultController.add(result);
1132 } catch (exception, stackTrace) { 1146 } catch (exception, stackTrace) {
1133 _reportError(path, exception, stackTrace); 1147 _reportException(path, exception, stackTrace);
1134 } 1148 }
1135 return; 1149 return;
1136 } 1150 }
1137 } 1151 }
1138 1152
1139 void _reportError(String path, exception, StackTrace stackTrace) { 1153 void _reportException(String path, exception, StackTrace stackTrace) {
1154 String contextKey = null;
1155 if (exception is _ExceptionState) {
1156 var state = exception as _ExceptionState;
1157 exception = state.exception;
1158 stackTrace = state.stackTrace;
1159 contextKey = state.contextKey;
1160 }
1140 CaughtException caught = new CaughtException(exception, stackTrace); 1161 CaughtException caught = new CaughtException(exception, stackTrace);
1141 _exceptionController.add(new ExceptionResult(path, caught)); 1162 _exceptionController.add(new ExceptionResult(path, caught, contextKey));
1163 }
1164
1165 String _storeExceptionContext(
1166 String path, FileState libraryFile, exception, StackTrace stackTrace) {
1167 if (allowedNumberOfContextsToWrite > 0) {
1168 allowedNumberOfContextsToWrite--;
1169 }
1170 try {
1171 List<AnalysisDriverExceptionFileBuilder> contextFiles = libraryFile
1172 .transitiveFiles
1173 .map((file) => new AnalysisDriverExceptionFileBuilder(
1174 path: file.path, content: file.content))
1175 .toList();
1176 contextFiles.sort((a, b) => a.path.compareTo(b.path));
1177 AnalysisDriverExceptionContextBuilder contextBuilder =
1178 new AnalysisDriverExceptionContextBuilder(
1179 path: path,
1180 exception: exception.toString(),
1181 stackTrace: stackTrace.toString(),
1182 files: contextFiles);
1183 List<int> bytes = contextBuilder.toBuffer();
1184
1185 String _twoDigits(int n) {
1186 if (n >= 10) return '$n';
1187 return '0$n';
1188 }
1189
1190 String _threeDigits(int n) {
1191 if (n >= 100) return '$n';
1192 if (n >= 10) return '0$n';
1193 return '00$n';
1194 }
1195
1196 DateTime time = new DateTime.now();
1197 String m = _twoDigits(time.month);
1198 String d = _twoDigits(time.day);
1199 String h = _twoDigits(time.hour);
1200 String min = _twoDigits(time.minute);
1201 String sec = _twoDigits(time.second);
1202 String ms = _threeDigits(time.millisecond);
1203 String key = 'exception_${time.year}$m$d' '_$h$min$sec' + '_$ms';
1204
1205 _byteStore.put(key, bytes);
1206 return key;
1207 } catch (_) {
1208 return null;
1209 }
1142 } 1210 }
1143 1211
1144 /** 1212 /**
1145 * Verify the API signature for the file with the given [path], and decide 1213 * Verify the API signature for the file with the given [path], and decide
1146 * which linked libraries should be invalidated, and files reanalyzed. 1214 * which linked libraries should be invalidated, and files reanalyzed.
1147 */ 1215 */
1148 FileState _verifyApiSignature(String path) { 1216 FileState _verifyApiSignature(String path) {
1149 return _logger.run('Verify API signature of $path', () { 1217 return _logger.run('Verify API signature of $path', () {
1150 bool anyApiChanged = false; 1218 bool anyApiChanged = false;
1151 List<FileState> files = _fsState.getFilesForPath(path); 1219 List<FileState> files = _fsState.getFilesForPath(path);
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
1480 * 1548 *
1481 * Absolute and normalized. 1549 * Absolute and normalized.
1482 */ 1550 */
1483 final String path; 1551 final String path;
1484 1552
1485 /** 1553 /**
1486 * The exception during analysis of the file with the [path]. 1554 * The exception during analysis of the file with the [path].
1487 */ 1555 */
1488 final CaughtException exception; 1556 final CaughtException exception;
1489 1557
1490 ExceptionResult(this.path, this.exception); 1558 /**
1559 * If the exception happened during a file analysis, and the context in which
1560 * the exception happened was stores, this field is the key of the context
Paul Berry 2017/01/30 20:16:41 s/stores/stored/
1561 * in the byte store. May be `null` if the context is unknown, the maximum
1562 * number of context to store was reached, etc.
1563 */
1564 final String contextKey;
1565
1566 ExceptionResult(this.path, this.exception, this.contextKey);
1491 } 1567 }
1492 1568
1493 /** 1569 /**
1494 * The result of parsing of a single file. 1570 * The result of parsing of a single file.
1495 * 1571 *
1496 * These results are self-consistent, i.e. [content], [contentHash], the 1572 * These results are self-consistent, i.e. [content], [contentHash], the
1497 * resolved [unit] correspond to each other. But none of the results is 1573 * resolved [unit] correspond to each other. But none of the results is
1498 * guaranteed to be consistent with the state of the files. 1574 * guaranteed to be consistent with the state of the files.
1499 */ 1575 */
1500 class ParseResult { 1576 class ParseResult {
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1652 throw new UnimplementedError(); 1728 throw new UnimplementedError();
1653 } 1729 }
1654 1730
1655 FileState _getFileForSource(Source source) { 1731 FileState _getFileForSource(Source source) {
1656 String path = source.fullName; 1732 String path = source.fullName;
1657 return fsState.getFileForPath(path); 1733 return fsState.getFileForPath(path);
1658 } 1734 }
1659 } 1735 }
1660 1736
1661 /** 1737 /**
1738 * Information about an exception and its context.
1739 */
1740 class _ExceptionState {
1741 final exception;
1742 final StackTrace stackTrace;
1743
1744 /**
1745 * The key under which the context of the exception was stored, or `null`
1746 * if unknown, the maximum number of context to store was reached, etc.
1747 */
1748 final String contextKey;
1749
1750 _ExceptionState(this.exception, this.stackTrace, this.contextKey);
1751 }
1752
1753 /**
1662 * Task that computes the list of files that were added to the driver and 1754 * Task that computes the list of files that were added to the driver and
1663 * have at least one reference to an identifier [name] defined outside of the 1755 * have at least one reference to an identifier [name] defined outside of the
1664 * file. 1756 * file.
1665 */ 1757 */
1666 class _FilesReferencingNameTask { 1758 class _FilesReferencingNameTask {
1667 static const int _MS_WORK_INTERVAL = 5; 1759 static const int _MS_WORK_INTERVAL = 5;
1668 1760
1669 final AnalysisDriver driver; 1761 final AnalysisDriver driver;
1670 final String name; 1762 final String name;
1671 final Completer<List<String>> completer = new Completer<List<String>>(); 1763 final Completer<List<String>> completer = new Completer<List<String>>();
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1777 libraryDeclarations.add(new TopLevelDeclarationInSource( 1869 libraryDeclarations.add(new TopLevelDeclarationInSource(
1778 file.source, declaration, isExported)); 1870 file.source, declaration, isExported));
1779 } 1871 }
1780 } 1872 }
1781 } 1873 }
1782 1874
1783 // We're not done yet. 1875 // We're not done yet.
1784 return false; 1876 return false;
1785 } 1877 }
1786 } 1878 }
OLDNEW
« no previous file with comments | « pkg/analysis_server/lib/src/analysis_server.dart ('k') | pkg/analyzer/lib/src/summary/format.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698