| OLD | NEW |
| 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.src.context.context; | 5 library analyzer.src.context.context; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 | 9 |
| 10 import 'package:analyzer/instrumentation/instrumentation.dart'; | 10 import 'package:analyzer/instrumentation/instrumentation.dart'; |
| (...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 return null; | 601 return null; |
| 602 } | 602 } |
| 603 | 603 |
| 604 @override | 604 @override |
| 605 CancelableFuture<CompilationUnit> computeResolvedCompilationUnitAsync( | 605 CancelableFuture<CompilationUnit> computeResolvedCompilationUnitAsync( |
| 606 Source unitSource, Source librarySource) { | 606 Source unitSource, Source librarySource) { |
| 607 if (!AnalysisEngine.isDartFileName(unitSource.shortName) || | 607 if (!AnalysisEngine.isDartFileName(unitSource.shortName) || |
| 608 !AnalysisEngine.isDartFileName(librarySource.shortName)) { | 608 !AnalysisEngine.isDartFileName(librarySource.shortName)) { |
| 609 return new CancelableFuture.error(new AnalysisNotScheduledError()); | 609 return new CancelableFuture.error(new AnalysisNotScheduledError()); |
| 610 } | 610 } |
| 611 var unitTarget = new LibrarySpecificUnit(librarySource, unitSource); |
| 611 return new _AnalysisFutureHelper<CompilationUnit>(this).computeAsync( | 612 return new _AnalysisFutureHelper<CompilationUnit>(this).computeAsync( |
| 612 new LibrarySpecificUnit(librarySource, unitSource), (CacheEntry entry) { | 613 unitTarget, (CacheEntry entry) { |
| 613 CacheState state = entry.getState(RESOLVED_UNIT); | 614 CacheState state = entry.getState(RESOLVED_UNIT); |
| 614 if (state == CacheState.ERROR) { | 615 if (state == CacheState.ERROR) { |
| 615 throw entry.exception; | 616 throw entry.exception; |
| 616 } else if (state == CacheState.INVALID) { | 617 } else if (state == CacheState.INVALID) { |
| 617 return null; | 618 return null; |
| 618 } | 619 } |
| 619 return entry.getValue(RESOLVED_UNIT); | 620 return entry.getValue(RESOLVED_UNIT); |
| 621 }, () { |
| 622 dartWorkManager.addPriorityResult(unitTarget, RESOLVED_UNIT); |
| 620 }); | 623 }); |
| 621 } | 624 } |
| 622 | 625 |
| 623 /** | 626 /** |
| 624 * Create an analysis cache based on the given source [factory]. | 627 * Create an analysis cache based on the given source [factory]. |
| 625 */ | 628 */ |
| 626 AnalysisCache createCacheFromSourceFactory(SourceFactory factory) { | 629 AnalysisCache createCacheFromSourceFactory(SourceFactory factory) { |
| 627 if (factory == null) { | 630 if (factory == null) { |
| 628 return new AnalysisCache(<CachePartition>[_privatePartition]); | 631 return new AnalysisCache(<CachePartition>[_privatePartition]); |
| 629 } | 632 } |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 892 // Note that this is not part of the API of the interface. | 895 // Note that this is not part of the API of the interface. |
| 893 // TODO(brianwilkerson) The public namespace used to be cached, but no | 896 // TODO(brianwilkerson) The public namespace used to be cached, but no |
| 894 // longer is. Konstantin adds: | 897 // longer is. Konstantin adds: |
| 895 // The only client of this method is NamespaceBuilder._createExportMapping()
, | 898 // The only client of this method is NamespaceBuilder._createExportMapping()
, |
| 896 // and it is not used with tasks - instead we compute export namespace once | 899 // and it is not used with tasks - instead we compute export namespace once |
| 897 // using BuildExportNamespaceTask and reuse in scopes. | 900 // using BuildExportNamespaceTask and reuse in scopes. |
| 898 NamespaceBuilder builder = new NamespaceBuilder(); | 901 NamespaceBuilder builder = new NamespaceBuilder(); |
| 899 return builder.createPublicNamespaceForLibrary(library); | 902 return builder.createPublicNamespaceForLibrary(library); |
| 900 } | 903 } |
| 901 | 904 |
| 902 /** | |
| 903 * Return the cache entry associated with the given [target], or `null` if | |
| 904 * there is no entry associated with the target. | |
| 905 */ | |
| 906 CacheEntry getReadableSourceEntryOrNull(AnalysisTarget target) => | |
| 907 _cache.get(target); | |
| 908 | |
| 909 @override | 905 @override |
| 910 CompilationUnit getResolvedCompilationUnit( | 906 CompilationUnit getResolvedCompilationUnit( |
| 911 Source unitSource, LibraryElement library) { | 907 Source unitSource, LibraryElement library) { |
| 912 if (library == null || | 908 if (library == null || |
| 913 !AnalysisEngine.isDartFileName(unitSource.shortName)) { | 909 !AnalysisEngine.isDartFileName(unitSource.shortName)) { |
| 914 return null; | 910 return null; |
| 915 } | 911 } |
| 916 return getResolvedCompilationUnit2(unitSource, library.source); | 912 return getResolvedCompilationUnit2(unitSource, library.source); |
| 917 } | 913 } |
| 918 | 914 |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1038 if (!AnalysisEngine.isHtmlFileName(source.shortName)) { | 1034 if (!AnalysisEngine.isHtmlFileName(source.shortName)) { |
| 1039 return null; | 1035 return null; |
| 1040 } | 1036 } |
| 1041 // TODO(brianwilkerson) Implement HTML analysis. | 1037 // TODO(brianwilkerson) Implement HTML analysis. |
| 1042 return null; //_computeResult(source, null); | 1038 return null; //_computeResult(source, null); |
| 1043 } | 1039 } |
| 1044 | 1040 |
| 1045 @override | 1041 @override |
| 1046 AnalysisResult performAnalysisTask() { | 1042 AnalysisResult performAnalysisTask() { |
| 1047 return PerformanceStatistics.performAnaysis.makeCurrentWhile(() { | 1043 return PerformanceStatistics.performAnaysis.makeCurrentWhile(() { |
| 1044 _evaluatePendingFutures(); |
| 1048 bool done = !driver.performAnalysisTask(); | 1045 bool done = !driver.performAnalysisTask(); |
| 1049 if (done) { | 1046 if (done) { |
| 1050 done = !_validateCacheConsistency(); | 1047 done = !_validateCacheConsistency(); |
| 1051 } | 1048 } |
| 1052 List<ChangeNotice> notices = _getChangeNotices(done); | 1049 List<ChangeNotice> notices = _getChangeNotices(done); |
| 1053 if (notices != null) { | 1050 if (notices != null) { |
| 1054 int noticeCount = notices.length; | 1051 int noticeCount = notices.length; |
| 1055 for (int i = 0; i < noticeCount; i++) { | 1052 for (int i = 0; i < noticeCount; i++) { |
| 1056 ChangeNotice notice = notices[i]; | 1053 ChangeNotice notice = notices[i]; |
| 1057 _notifyErrors(notice.source, notice.errors, notice.lineInfo); | 1054 _notifyErrors(notice.source, notice.errors, notice.lineInfo); |
| 1058 } | 1055 } |
| 1059 } | 1056 } |
| 1060 return new AnalysisResult(notices, -1, '', -1); | 1057 return new AnalysisResult(notices, -1, '', -1); |
| 1061 }); | 1058 }); |
| 1062 } | 1059 } |
| 1063 | 1060 |
| 1061 void _evaluatePendingFutures() { |
| 1062 for (AnalysisTarget target in _pendingFutureTargets.keys) { |
| 1063 CacheEntry cacheEntry = _cache.get(target); |
| 1064 List<PendingFuture> pendingFutures = _pendingFutureTargets[target]; |
| 1065 for (int i = 0; i < pendingFutures.length;) { |
| 1066 if (pendingFutures[i].evaluate(cacheEntry)) { |
| 1067 pendingFutures.removeAt(i); |
| 1068 } else { |
| 1069 i++; |
| 1070 } |
| 1071 } |
| 1072 } |
| 1073 } |
| 1074 |
| 1064 @override | 1075 @override |
| 1065 void recordLibraryElements(Map<Source, LibraryElement> elementMap) { | 1076 void recordLibraryElements(Map<Source, LibraryElement> elementMap) { |
| 1066 elementMap.forEach((Source librarySource, LibraryElement library) { | 1077 elementMap.forEach((Source librarySource, LibraryElement library) { |
| 1067 // | 1078 // |
| 1068 // Cache the element in the library's info. | 1079 // Cache the element in the library's info. |
| 1069 // | 1080 // |
| 1070 CacheEntry entry = getCacheEntry(librarySource); | 1081 CacheEntry entry = getCacheEntry(librarySource); |
| 1071 setValue(ResultDescriptor result, value) { | 1082 setValue(ResultDescriptor result, value) { |
| 1072 entry.setValue(result, value, TargetedResult.EMPTY_LIST); | 1083 entry.setValue(result, value, TargetedResult.EMPTY_LIST); |
| 1073 } | 1084 } |
| (...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1919 throw new IllegalArgumentException( | 1930 throw new IllegalArgumentException( |
| 1920 "The source factory for an SDK analysis context must have a DartUriRes
olver"); | 1931 "The source factory for an SDK analysis context must have a DartUriRes
olver"); |
| 1921 } | 1932 } |
| 1922 return new AnalysisCache(<CachePartition>[ | 1933 return new AnalysisCache(<CachePartition>[ |
| 1923 AnalysisEngine.instance.partitionManager_new.forSdk(sdk) | 1934 AnalysisEngine.instance.partitionManager_new.forSdk(sdk) |
| 1924 ]); | 1935 ]); |
| 1925 } | 1936 } |
| 1926 } | 1937 } |
| 1927 | 1938 |
| 1928 /** | 1939 /** |
| 1929 * A helper class used to create futures for AnalysisContextImpl. Using a helper | 1940 * A helper class used to create futures for [AnalysisContextImpl]. |
| 1930 * class allows us to preserve the generic parameter T. | 1941 * Using a helper class allows us to preserve the generic parameter T. |
| 1931 */ | 1942 */ |
| 1932 class _AnalysisFutureHelper<T> { | 1943 class _AnalysisFutureHelper<T> { |
| 1933 final AnalysisContextImpl _context; | 1944 final AnalysisContextImpl _context; |
| 1934 | 1945 |
| 1935 _AnalysisFutureHelper(this._context); | 1946 _AnalysisFutureHelper(this._context); |
| 1936 | 1947 |
| 1937 /** | 1948 /** |
| 1938 * Return a future that will be completed with the result of calling | 1949 * Return a future that will be completed with the result of calling |
| 1939 * [computeValue]. If [computeValue] returns non-`null`, the future will be | 1950 * [computeValue]. If [computeValue] returns non-`null`, the future will be |
| 1940 * completed immediately with the resulting value. If it returns `null`, then | 1951 * completed immediately with the resulting value. If it returns `null`, then |
| 1941 * it will be re-executed in the future, after the next time the cached | 1952 * [scheduleComputation] is invoked to schedule analysis that will produce |
| 1942 * information for [target] has changed. If [computeValue] throws an | 1953 * the required result, and [computeValue] will be re-executed in the future, |
| 1943 * exception, the future will fail with that exception. | 1954 * after the next time the cached information for [target] has changed. If |
| 1955 * [computeValue] throws an exception, the future will fail with that |
| 1956 * exception. |
| 1944 * | 1957 * |
| 1945 * If the [computeValue] still returns `null` after there is no further | 1958 * If the [computeValue] still returns `null` after there is no further |
| 1946 * analysis to be done for [target], then the future will be completed with | 1959 * analysis to be done for [target], then the future will be completed with |
| 1947 * the error AnalysisNotScheduledError. | 1960 * the error AnalysisNotScheduledError. |
| 1948 * | 1961 * |
| 1949 * Since [computeValue] will be called while the state of analysis is being | 1962 * Since [computeValue] will be called while the state of analysis is being |
| 1950 * updated, it should be free of side effects so that it doesn't cause | 1963 * updated, it should be free of side effects so that it doesn't cause |
| 1951 * reentrant changes to the analysis state. | 1964 * reentrant changes to the analysis state. |
| 1952 */ | 1965 */ |
| 1953 CancelableFuture<T> computeAsync( | 1966 CancelableFuture<T> computeAsync(AnalysisTarget target, |
| 1954 AnalysisTarget target, T computeValue(CacheEntry entry)) { | 1967 T computeValue(CacheEntry entry), void scheduleComputation()) { |
| 1955 if (_context.isDisposed) { | 1968 if (_context.isDisposed) { |
| 1956 // No further analysis is expected, so return a future that completes | 1969 // No further analysis is expected, so return a future that completes |
| 1957 // immediately with AnalysisNotScheduledError. | 1970 // immediately with AnalysisNotScheduledError. |
| 1958 return new CancelableFuture.error(new AnalysisNotScheduledError()); | 1971 return new CancelableFuture.error(new AnalysisNotScheduledError()); |
| 1959 } | 1972 } |
| 1960 CacheEntry entry = _context.getReadableSourceEntryOrNull(target); | 1973 CacheEntry entry = _context.getCacheEntry(target); |
| 1961 if (entry == null) { | |
| 1962 return new CancelableFuture.error(new AnalysisNotScheduledError()); | |
| 1963 } | |
| 1964 PendingFuture pendingFuture = | 1974 PendingFuture pendingFuture = |
| 1965 new PendingFuture<T>(_context, target, computeValue); | 1975 new PendingFuture<T>(_context, target, computeValue); |
| 1966 if (!pendingFuture.evaluate(entry)) { | 1976 if (!pendingFuture.evaluate(entry)) { |
| 1967 _context._pendingFutureTargets | 1977 _context._pendingFutureTargets |
| 1968 .putIfAbsent(target, () => <PendingFuture>[]) | 1978 .putIfAbsent(target, () => <PendingFuture>[]) |
| 1969 .add(pendingFuture); | 1979 .add(pendingFuture); |
| 1980 scheduleComputation(); |
| 1970 } | 1981 } |
| 1971 return pendingFuture.future; | 1982 return pendingFuture.future; |
| 1972 } | 1983 } |
| 1973 } | 1984 } |
| OLD | NEW |