// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. import 'package:_fe_analyzer_shared/src/base/analyzer_public_api.dart'; import 'package:_fe_analyzer_shared/src/scanner/string_canonicalizer.dart'; import 'package:analyzer/dart/analysis/analysis_options.dart'; import 'package:analyzer/dart/analysis/declared_variables.dart'; import 'package:analyzer/file_system/file_system.dart'; import 'package:analyzer/instrumentation/instrumentation.dart'; import 'package:analyzer/src/generated/source.dart' show SourceFactory; export 'package:analyzer/dart/analysis/analysis_options.dart'; export 'package:analyzer/error/listener.dart' show RecordingDiagnosticListener; export 'package:analyzer/source/timestamped_data.dart' show TimestampedData; export 'package:analyzer/src/dart/analysis/analysis_options.dart'; /// A context in which a single analysis can be performed and incrementally /// maintained. The context includes such information as the version of the SDK /// being analyzed against, and how to resolve 'package:' URI's. (Both of which /// are known indirectly through the [SourceFactory].) /// /// An analysis context also represents the state of the analysis, which includes /// knowing which sources have been included in the analysis (either directly or /// indirectly) and the results of the analysis. Sources must be added and /// removed from the context, which is also used to notify the context when /// sources have been modified and, consequently, previously known results might /// have been invalidated. /// /// There are two ways to access the results of the analysis. The most common is /// to use one of the 'get' methods to access the results. The 'get' methods have /// the advantage that they will always return quickly, but have the disadvantage /// that if the results are not currently available they will return either /// nothing or in some cases an incomplete result. The second way to access /// results is by using one of the 'compute' methods. The 'compute' methods will /// always attempt to compute the requested results but might block the caller /// for a significant period of time. /// /// When results have been invalidated, have never been computed (as is the case /// for newly added sources), or have been removed from the cache, they are /// not automatically recreated. They will only be recreated if one of the /// 'compute' methods is invoked. /// /// However, this is not always acceptable. Some clients need to keep the /// analysis results up-to-date. For such clients there is a mechanism that /// allows them to incrementally perform needed analysis and get notified of the /// consequent changes to the analysis results. /// /// Analysis engine allows for having more than one context. This can be used, /// for example, to perform one analysis based on the state of files on disk and /// a separate analysis based on the state of those files in open editors. It can /// also be used to perform an analysis based on a proposed future state, such as /// the state after a refactoring. @AnalyzerPublicApi(message: 'exposed by Element.context') abstract class AnalysisContext { /// Return the set of declared variables used when computing constant values. DeclaredVariables get declaredVariables; /// Return the source factory used to create the sources that can be analyzed /// in this context. // ignore: analyzer_public_api_bad_type SourceFactory get sourceFactory; /// Get the [AnalysisOptions] instance for the given [file]. /// /// NOTE: this API is experimental and subject to change in a future /// release (see https://github.com/dart-lang/sdk/issues/53876 for context). AnalysisOptions getAnalysisOptionsForFile(File file); } /// The entry point for the functionality provided by the analysis engine. There /// is a single instance of this class. class AnalysisEngine { /// The unique instance of this class. static final AnalysisEngine instance = AnalysisEngine._(); /// The instrumentation service that is to be used by this analysis engine. InstrumentationService _instrumentationService = InstrumentationService.NULL_SERVICE; AnalysisEngine._(); /// Return the instrumentation service that is to be used by this analysis /// engine. InstrumentationService get instrumentationService => _instrumentationService; /// Set the instrumentation service that is to be used by this analysis engine /// to the given [service]. set instrumentationService(InstrumentationService? service) { if (service == null) { _instrumentationService = InstrumentationService.NULL_SERVICE; } else { _instrumentationService = service; } } /// Clear any caches holding on to analysis results so that a full re-analysis /// will be performed the next time an analysis context is created. void clearCaches() { // Ensure the string canonicalization cache size is reasonable. pruneStringCanonicalizationCache(); } }