| // Copyright (c) 2017, Devon Carew. 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. |
| |
| // This is a generated file. |
| |
| /// A library to access the analysis server API. |
| /// |
| /// [AnalysisServer] is the main entry-point to this library. |
| library analysis_server_lib; |
| |
| import 'dart:async'; |
| import 'dart:convert'; |
| import 'dart:io'; |
| |
| import 'package:logging/logging.dart'; |
| import 'package:path/path.dart' as path; |
| |
| /// @optional |
| const String optional = 'optional'; |
| |
| /// @experimental |
| const String experimental = 'experimental'; |
| |
| final Logger _logger = new Logger('analysis_server'); |
| |
| const String generatedProtocolVersion = '1.20.0'; |
| |
| typedef void MethodSend(String methodName); |
| |
| /// A class to communicate with an analysis server instance. |
| /// |
| /// Here's a simple example of starting and communicating with the server: |
| /// |
| /// ```dart |
| /// import 'package:analysis_server_lib/analysis_server_lib.dart'; |
| /// |
| /// main() async { |
| /// AnalysisServer server = await AnalysisServer.create(); |
| /// await server.server.onConnected.first; |
| /// |
| /// VersionResult version = await server.server.getVersion(); |
| /// print(version.version); |
| /// |
| /// server.dispose(); |
| /// } |
| /// ``` |
| class AnalysisServer { |
| /// Create and connect to a new analysis server instance. |
| /// |
| /// - [sdkPath] override the default sdk path |
| /// - [scriptPath] override the default entry-point script to use for the |
| /// analysis server |
| /// - [onRead] called every time data is read from the server |
| /// - [onWrite] called every time data is written to the server |
| static Future<AnalysisServer> create( |
| {String sdkPath, |
| String scriptPath, |
| void onRead(String str), |
| void onWrite(String str), |
| List<String> vmArgs, |
| List<String> serverArgs, |
| String clientId, |
| String clientVersion, |
| Map<String, String> processEnvironment}) async { |
| Completer<int> processCompleter = new Completer(); |
| |
| String vmPath; |
| if (sdkPath != null) { |
| vmPath = |
| path.join(sdkPath, 'bin', Platform.isWindows ? 'dart.exe' : 'dart'); |
| } else { |
| sdkPath = path.dirname(path.dirname(Platform.resolvedExecutable)); |
| vmPath = Platform.resolvedExecutable; |
| } |
| scriptPath ??= '$sdkPath/bin/snapshots/analysis_server.dart.snapshot'; |
| |
| List<String> args = [scriptPath, '--sdk', sdkPath]; |
| if (vmArgs != null) args.insertAll(0, vmArgs); |
| if (serverArgs != null) args.addAll(serverArgs); |
| if (clientId != null) args.add('--client-id=$clientId'); |
| if (clientVersion != null) args.add('--client-version=$clientVersion'); |
| |
| Process process = |
| await Process.start(vmPath, args, environment: processEnvironment); |
| process.exitCode.then((code) => processCompleter.complete(code)); |
| |
| Stream<String> inStream = process.stdout |
| .transform(utf8.decoder) |
| .transform(const LineSplitter()) |
| .map((String message) { |
| if (onRead != null) onRead(message); |
| return message; |
| }); |
| |
| AnalysisServer server = new AnalysisServer(inStream, (String message) { |
| if (onWrite != null) onWrite(message); |
| process.stdin.writeln(message); |
| }, processCompleter, process.kill); |
| |
| return server; |
| } |
| |
| final Completer<int> processCompleter; |
| final Function _processKillHandler; |
| |
| StreamSubscription _streamSub; |
| Function _writeMessage; |
| int _id = 0; |
| Map<String, Completer> _completers = {}; |
| Map<String, String> _methodNames = {}; |
| JsonCodec _jsonEncoder = new JsonCodec(toEncodable: _toEncodable); |
| Map<String, Domain> _domains = {}; |
| StreamController<String> _onSend = new StreamController.broadcast(); |
| StreamController<String> _onReceive = new StreamController.broadcast(); |
| MethodSend _willSend; |
| |
| ServerDomain _server; |
| AnalysisDomain _analysis; |
| CompletionDomain _completion; |
| SearchDomain _search; |
| EditDomain _edit; |
| ExecutionDomain _execution; |
| DiagnosticDomain _diagnostic; |
| AnalyticsDomain _analytics; |
| KytheDomain _kythe; |
| FlutterDomain _flutter; |
| |
| /// Connect to an existing analysis server instance. |
| AnalysisServer(Stream<String> inStream, void writeMessage(String message), |
| this.processCompleter, |
| [this._processKillHandler]) { |
| configure(inStream, writeMessage); |
| |
| _server = new ServerDomain(this); |
| _analysis = new AnalysisDomain(this); |
| _completion = new CompletionDomain(this); |
| _search = new SearchDomain(this); |
| _edit = new EditDomain(this); |
| _execution = new ExecutionDomain(this); |
| _diagnostic = new DiagnosticDomain(this); |
| _analytics = new AnalyticsDomain(this); |
| _kythe = new KytheDomain(this); |
| _flutter = new FlutterDomain(this); |
| } |
| |
| ServerDomain get server => _server; |
| AnalysisDomain get analysis => _analysis; |
| CompletionDomain get completion => _completion; |
| SearchDomain get search => _search; |
| EditDomain get edit => _edit; |
| ExecutionDomain get execution => _execution; |
| DiagnosticDomain get diagnostic => _diagnostic; |
| AnalyticsDomain get analytics => _analytics; |
| KytheDomain get kythe => _kythe; |
| FlutterDomain get flutter => _flutter; |
| |
| Stream<String> get onSend => _onSend.stream; |
| Stream<String> get onReceive => _onReceive.stream; |
| |
| set willSend(MethodSend fn) { |
| _willSend = fn; |
| } |
| |
| void configure(Stream<String> inStream, void writeMessage(String message)) { |
| _streamSub = inStream.listen(_processMessage); |
| _writeMessage = writeMessage; |
| } |
| |
| void dispose() { |
| if (_streamSub != null) _streamSub.cancel(); |
| //_completers.values.forEach((c) => c.completeError('disposed')); |
| _completers.clear(); |
| |
| if (_processKillHandler != null) { |
| _processKillHandler(); |
| } |
| } |
| |
| void _processMessage(String message) { |
| _onReceive.add(message); |
| |
| if (!message.startsWith('{')) { |
| _logger.warning('unknown message: ${message}'); |
| return; |
| } |
| |
| try { |
| var json = jsonDecode(message); |
| |
| if (json['id'] == null) { |
| // Handle a notification. |
| String event = json['event']; |
| if (event == null) { |
| _logger.severe('invalid message: ${message}'); |
| } else { |
| String prefix = event.substring(0, event.indexOf('.')); |
| if (_domains[prefix] == null) { |
| _logger.severe('no domain for notification: ${message}'); |
| } else { |
| _domains[prefix]._handleEvent(event, json['params']); |
| } |
| } |
| } else { |
| Completer completer = _completers.remove(json['id']); |
| String methodName = _methodNames.remove(json['id']); |
| |
| if (completer == null) { |
| _logger.severe('unmatched request response: ${message}'); |
| } else if (json['error'] != null) { |
| completer |
| .completeError(RequestError.parse(methodName, json['error'])); |
| } else { |
| completer.complete(json['result']); |
| } |
| } |
| } catch (e) { |
| _logger.severe('unable to decode message: ${message}, ${e}'); |
| } |
| } |
| |
| Future<Map> _call(String method, [Map args]) { |
| String id = '${++_id}'; |
| _completers[id] = new Completer<Map>(); |
| _methodNames[id] = method; |
| Map m = {'id': id, 'method': method}; |
| if (args != null) m['params'] = args; |
| String message = _jsonEncoder.encode(m); |
| if (_willSend != null) _willSend(method); |
| _onSend.add(message); |
| _writeMessage(message); |
| return _completers[id].future; |
| } |
| |
| static dynamic _toEncodable(obj) => obj is Jsonable ? obj.toMap() : obj; |
| } |
| |
| abstract class Domain { |
| final AnalysisServer server; |
| final String name; |
| |
| Map<String, StreamController<Map>> _controllers = {}; |
| Map<String, Stream> _streams = {}; |
| |
| Domain(this.server, this.name) { |
| server._domains[name] = this; |
| } |
| |
| Future<Map> _call(String method, [Map args]) => server._call(method, args); |
| |
| Stream<E> _listen<E>(String name, E cvt(Map m)) { |
| if (_streams[name] == null) { |
| _controllers[name] = new StreamController<Map>.broadcast(); |
| _streams[name] = _controllers[name].stream.map<E>(cvt); |
| } |
| |
| return _streams[name]; |
| } |
| |
| void _handleEvent(String name, dynamic event) { |
| if (_controllers[name] != null) { |
| _controllers[name].add(event); |
| } |
| } |
| |
| String toString() => 'Domain ${name}'; |
| } |
| |
| abstract class Jsonable { |
| Map toMap(); |
| } |
| |
| abstract class RefactoringOptions implements Jsonable {} |
| |
| abstract class ContentOverlayType { |
| final String type; |
| |
| ContentOverlayType(this.type); |
| } |
| |
| class RequestError { |
| static RequestError parse(String method, Map m) { |
| if (m == null) return null; |
| return new RequestError(method, m['code'], m['message'], |
| stackTrace: m['stackTrace']); |
| } |
| |
| final String method; |
| final String code; |
| final String message; |
| @optional |
| final String stackTrace; |
| |
| RequestError(this.method, this.code, this.message, {this.stackTrace}); |
| |
| String toString() => |
| '[Analyzer RequestError method: ${method}, code: ${code}, message: ${message}]'; |
| } |
| |
| Map _stripNullValues(Map m) { |
| Map copy = {}; |
| |
| for (var key in m.keys) { |
| var value = m[key]; |
| if (value != null) copy[key] = value; |
| } |
| |
| return copy; |
| } |
| |
| // server domain |
| |
| /// The server domain contains API’s related to the execution of the server. |
| class ServerDomain extends Domain { |
| ServerDomain(AnalysisServer server) : super(server, 'server'); |
| |
| /// Reports that the server is running. This notification is issued once after |
| /// the server has started running but before any requests are processed to |
| /// let the client know that it started correctly. |
| /// |
| /// It is not possible to subscribe to or unsubscribe from this notification. |
| Stream<ServerConnected> get onConnected { |
| return _listen('server.connected', ServerConnected.parse); |
| } |
| |
| /// Reports that an unexpected error has occurred while executing the server. |
| /// This notification is not used for problems with specific requests (which |
| /// are returned as part of the response) but is used for exceptions that |
| /// occur while performing other tasks, such as analysis or preparing |
| /// notifications. |
| /// |
| /// It is not possible to subscribe to or unsubscribe from this notification. |
| Stream<ServerError> get onError { |
| return _listen('server.error', ServerError.parse); |
| } |
| |
| /// Reports the current status of the server. Parameters are omitted if there |
| /// has been no change in the status represented by that parameter. |
| /// |
| /// This notification is not subscribed to by default. Clients can subscribe |
| /// by including the value `"STATUS"` in the list of services passed in a |
| /// server.setSubscriptions request. |
| Stream<ServerStatus> get onStatus { |
| return _listen('server.status', ServerStatus.parse); |
| } |
| |
| /// Return the version number of the analysis server. |
| Future<VersionResult> getVersion() => |
| _call('server.getVersion').then(VersionResult.parse); |
| |
| /// Cleanly shutdown the analysis server. Requests that are received after |
| /// this request will not be processed. Requests that were received before |
| /// this request, but for which a response has not yet been sent, will not be |
| /// responded to. No further responses or notifications will be sent after the |
| /// response to this request has been sent. |
| Future shutdown() => _call('server.shutdown'); |
| |
| /// Subscribe for services. All previous subscriptions are replaced by the |
| /// given set of services. |
| /// |
| /// It is an error if any of the elements in the list are not valid services. |
| /// If there is an error, then the current subscriptions will remain |
| /// unchanged. |
| Future setSubscriptions(List<String> subscriptions) => |
| _call('server.setSubscriptions', {'subscriptions': subscriptions}); |
| } |
| |
| class ServerConnected { |
| static ServerConnected parse(Map m) => |
| new ServerConnected(m['version'], m['pid'], sessionId: m['sessionId']); |
| |
| /// The version number of the analysis server. |
| final String version; |
| |
| /// The process id of the analysis server process. |
| final int pid; |
| |
| /// The session id for this session. |
| @optional |
| final String sessionId; |
| |
| ServerConnected(this.version, this.pid, {this.sessionId}); |
| } |
| |
| class ServerError { |
| static ServerError parse(Map m) => |
| new ServerError(m['isFatal'], m['message'], m['stackTrace']); |
| |
| /// True if the error is a fatal error, meaning that the server will shutdown |
| /// automatically after sending this notification. |
| final bool isFatal; |
| |
| /// The error message indicating what kind of error was encountered. |
| final String message; |
| |
| /// The stack trace associated with the generation of the error, used for |
| /// debugging the server. |
| final String stackTrace; |
| |
| ServerError(this.isFatal, this.message, this.stackTrace); |
| } |
| |
| class ServerStatus { |
| static ServerStatus parse(Map m) => new ServerStatus( |
| analysis: AnalysisStatus.parse(m['analysis']), |
| pub: PubStatus.parse(m['pub'])); |
| |
| /// The current status of analysis, including whether analysis is being |
| /// performed and if so what is being analyzed. |
| @optional |
| final AnalysisStatus analysis; |
| |
| /// The current status of pub execution, indicating whether we are currently |
| /// running pub. |
| @optional |
| final PubStatus pub; |
| |
| ServerStatus({this.analysis, this.pub}); |
| } |
| |
| class VersionResult { |
| static VersionResult parse(Map m) => new VersionResult(m['version']); |
| |
| /// The version number of the analysis server. |
| final String version; |
| |
| VersionResult(this.version); |
| } |
| |
| // analysis domain |
| |
| /// The analysis domain contains API’s related to the analysis of files. |
| class AnalysisDomain extends Domain { |
| AnalysisDomain(AnalysisServer server) : super(server, 'analysis'); |
| |
| /// Reports the paths of the files that are being analyzed. |
| /// |
| /// This notification is not subscribed to by default. Clients can subscribe |
| /// by including the value `"ANALYZED_FILES"` in the list of services passed |
| /// in an analysis.setGeneralSubscriptions request. |
| Stream<AnalysisAnalyzedFiles> get onAnalyzedFiles { |
| return _listen('analysis.analyzedFiles', AnalysisAnalyzedFiles.parse); |
| } |
| |
| /// Reports closing labels relevant to a given file. |
| /// |
| /// This notification is not subscribed to by default. Clients can subscribe |
| /// by including the value `"CLOSING_LABELS"` in the list of services passed |
| /// in an analysis.setSubscriptions request. |
| Stream<AnalysisClosingLabels> get onClosingLabels { |
| return _listen('analysis.closingLabels', AnalysisClosingLabels.parse); |
| } |
| |
| /// Reports the errors associated with a given file. The set of errors |
| /// included in the notification is always a complete list that supersedes any |
| /// previously reported errors. |
| Stream<AnalysisErrors> get onErrors { |
| return _listen('analysis.errors', AnalysisErrors.parse); |
| } |
| |
| /// Reports that any analysis results that were previously associated with the |
| /// given files should be considered to be invalid because those files are no |
| /// longer being analyzed, either because the analysis root that contained it |
| /// is no longer being analyzed or because the file no longer exists. |
| /// |
| /// If a file is included in this notification and at some later time a |
| /// notification with results for the file is received, clients should assume |
| /// that the file is once again being analyzed and the information should be |
| /// processed. |
| /// |
| /// It is not possible to subscribe to or unsubscribe from this notification. |
| Stream<AnalysisFlushResults> get onFlushResults { |
| return _listen('analysis.flushResults', AnalysisFlushResults.parse); |
| } |
| |
| /// Reports the folding regions associated with a given file. Folding regions |
| /// can be nested, but will not be overlapping. Nesting occurs when a foldable |
| /// element, such as a method, is nested inside another foldable element such |
| /// as a class. |
| /// |
| /// This notification is not subscribed to by default. Clients can subscribe |
| /// by including the value `"FOLDING"` in the list of services passed in an |
| /// analysis.setSubscriptions request. |
| Stream<AnalysisFolding> get onFolding { |
| return _listen('analysis.folding', AnalysisFolding.parse); |
| } |
| |
| /// Reports the highlight regions associated with a given file. |
| /// |
| /// This notification is not subscribed to by default. Clients can subscribe |
| /// by including the value `"HIGHLIGHTS"` in the list of services passed in an |
| /// analysis.setSubscriptions request. |
| Stream<AnalysisHighlights> get onHighlights { |
| return _listen('analysis.highlights', AnalysisHighlights.parse); |
| } |
| |
| /// Reports the classes that are implemented or extended and class members |
| /// that are implemented or overridden in a file. |
| /// |
| /// This notification is not subscribed to by default. Clients can subscribe |
| /// by including the value `"IMPLEMENTED"` in the list of services passed in |
| /// an analysis.setSubscriptions request. |
| Stream<AnalysisImplemented> get onImplemented { |
| return _listen('analysis.implemented', AnalysisImplemented.parse); |
| } |
| |
| /// Reports that the navigation information associated with a region of a |
| /// single file has become invalid and should be re-requested. |
| /// |
| /// This notification is not subscribed to by default. Clients can subscribe |
| /// by including the value `"INVALIDATE"` in the list of services passed in an |
| /// analysis.setSubscriptions request. |
| Stream<AnalysisInvalidate> get onInvalidate { |
| return _listen('analysis.invalidate', AnalysisInvalidate.parse); |
| } |
| |
| /// Reports the navigation targets associated with a given file. |
| /// |
| /// This notification is not subscribed to by default. Clients can subscribe |
| /// by including the value `"NAVIGATION"` in the list of services passed in an |
| /// analysis.setSubscriptions request. |
| Stream<AnalysisNavigation> get onNavigation { |
| return _listen('analysis.navigation', AnalysisNavigation.parse); |
| } |
| |
| /// Reports the occurrences of references to elements within a single file. |
| /// |
| /// This notification is not subscribed to by default. Clients can subscribe |
| /// by including the value `"OCCURRENCES"` in the list of services passed in |
| /// an analysis.setSubscriptions request. |
| Stream<AnalysisOccurrences> get onOccurrences { |
| return _listen('analysis.occurrences', AnalysisOccurrences.parse); |
| } |
| |
| /// Reports the outline associated with a single file. |
| /// |
| /// This notification is not subscribed to by default. Clients can subscribe |
| /// by including the value `"OUTLINE"` in the list of services passed in an |
| /// analysis.setSubscriptions request. |
| Stream<AnalysisOutline> get onOutline { |
| return _listen('analysis.outline', AnalysisOutline.parse); |
| } |
| |
| /// Reports the overriding members in a file. |
| /// |
| /// This notification is not subscribed to by default. Clients can subscribe |
| /// by including the value `"OVERRIDES"` in the list of services passed in an |
| /// analysis.setSubscriptions request. |
| Stream<AnalysisOverrides> get onOverrides { |
| return _listen('analysis.overrides', AnalysisOverrides.parse); |
| } |
| |
| /// Return the errors associated with the given file. If the errors for the |
| /// given file have not yet been computed, or the most recently computed |
| /// errors for the given file are out of date, then the response for this |
| /// request will be delayed until they have been computed. If some or all of |
| /// the errors for the file cannot be computed, then the subset of the errors |
| /// that can be computed will be returned and the response will contain an |
| /// error to indicate why the errors could not be computed. If the content of |
| /// the file changes after this request was received but before a response |
| /// could be sent, then an error of type `CONTENT_MODIFIED` will be generated. |
| /// |
| /// This request is intended to be used by clients that cannot asynchronously |
| /// apply updated error information. Clients that **can** apply error |
| /// information as it becomes available should use the information provided by |
| /// the 'analysis.errors' notification. |
| /// |
| /// If a request is made for a file which does not exist, or which is not |
| /// currently subject to analysis (e.g. because it is not associated with any |
| /// analysis root specified to analysis.setAnalysisRoots), an error of type |
| /// `GET_ERRORS_INVALID_FILE` will be generated. |
| Future<ErrorsResult> getErrors(String file) { |
| Map m = {'file': file}; |
| return _call('analysis.getErrors', m).then(ErrorsResult.parse); |
| } |
| |
| /// Return the hover information associate with the given location. If some or |
| /// all of the hover information is not available at the time this request is |
| /// processed the information will be omitted from the response. |
| Future<HoverResult> getHover(String file, int offset) { |
| Map m = {'file': file, 'offset': offset}; |
| return _call('analysis.getHover', m).then(HoverResult.parse); |
| } |
| |
| /// Return a description of all of the elements referenced in a given region |
| /// of a given file that come from imported libraries. |
| /// |
| /// If a request is made for a file that does not exist, or that is not |
| /// currently subject to analysis (e.g. because it is not associated with any |
| /// analysis root specified via analysis.setAnalysisRoots), an error of type |
| /// `GET_IMPORTED_ELEMENTS_INVALID_FILE` will be generated. |
| @experimental |
| Future<ImportedElementsResult> getImportedElements( |
| String file, int offset, int length) { |
| Map m = {'file': file, 'offset': offset, 'length': length}; |
| return _call('analysis.getImportedElements', m) |
| .then(ImportedElementsResult.parse); |
| } |
| |
| /// Return library dependency information for use in client-side indexing and |
| /// package URI resolution. |
| /// |
| /// Clients that are only using the libraries field should consider using the |
| /// analyzedFiles notification instead. |
| Future<LibraryDependenciesResult> getLibraryDependencies() => |
| _call('analysis.getLibraryDependencies') |
| .then(LibraryDependenciesResult.parse); |
| |
| /// Return the navigation information associated with the given region of the |
| /// given file. If the navigation information for the given file has not yet |
| /// been computed, or the most recently computed navigation information for |
| /// the given file is out of date, then the response for this request will be |
| /// delayed until it has been computed. If the content of the file changes |
| /// after this request was received but before a response could be sent, then |
| /// an error of type `CONTENT_MODIFIED` will be generated. |
| /// |
| /// If a navigation region overlaps (but extends either before or after) the |
| /// given region of the file it will be included in the result. This means |
| /// that it is theoretically possible to get the same navigation region in |
| /// response to multiple requests. Clients can avoid this by always choosing a |
| /// region that starts at the beginning of a line and ends at the end of a |
| /// (possibly different) line in the file. |
| /// |
| /// If a request is made for a file which does not exist, or which is not |
| /// currently subject to analysis (e.g. because it is not associated with any |
| /// analysis root specified to analysis.setAnalysisRoots), an error of type |
| /// `GET_NAVIGATION_INVALID_FILE` will be generated. |
| Future<NavigationResult> getNavigation(String file, int offset, int length) { |
| Map m = {'file': file, 'offset': offset, 'length': length}; |
| return _call('analysis.getNavigation', m).then(NavigationResult.parse); |
| } |
| |
| /// Return the transitive closure of reachable sources for a given file. |
| /// |
| /// If a request is made for a file which does not exist, or which is not |
| /// currently subject to analysis (e.g. because it is not associated with any |
| /// analysis root specified to analysis.setAnalysisRoots), an error of type |
| /// `GET_REACHABLE_SOURCES_INVALID_FILE` will be generated. |
| Future<ReachableSourcesResult> getReachableSources(String file) { |
| Map m = {'file': file}; |
| return _call('analysis.getReachableSources', m) |
| .then(ReachableSourcesResult.parse); |
| } |
| |
| /// Force the re-analysis of everything contained in the specified analysis |
| /// roots. This will cause all previously computed analysis results to be |
| /// discarded and recomputed, and will cause all subscribed notifications to |
| /// be re-sent. |
| /// |
| /// If no analysis roots are provided, then all current analysis roots will be |
| /// re-analyzed. If an empty list of analysis roots is provided, then nothing |
| /// will be re-analyzed. If the list contains one or more paths that are not |
| /// currently analysis roots, then an error of type `INVALID_ANALYSIS_ROOT` |
| /// will be generated. |
| Future reanalyze({List<String> roots}) { |
| Map m = {}; |
| if (roots != null) m['roots'] = roots; |
| return _call('analysis.reanalyze', m); |
| } |
| |
| /// Sets the root paths used to determine which files to analyze. The set of |
| /// files to be analyzed are all of the files in one of the root paths that |
| /// are not either explicitly or implicitly excluded. A file is explicitly |
| /// excluded if it is in one of the excluded paths. A file is implicitly |
| /// excluded if it is in a subdirectory of one of the root paths where the |
| /// name of the subdirectory starts with a period (that is, a hidden |
| /// directory). |
| /// |
| /// Note that this request determines the set of requested analysis roots. The |
| /// actual set of analysis roots at any given time is the intersection of this |
| /// set with the set of files and directories actually present on the |
| /// filesystem. When the filesystem changes, the actual set of analysis roots |
| /// is automatically updated, but the set of requested analysis roots is |
| /// unchanged. This means that if the client sets an analysis root before the |
| /// root becomes visible to server in the filesystem, there is no error; once |
| /// the server sees the root in the filesystem it will start analyzing it. |
| /// Similarly, server will stop analyzing files that are removed from the file |
| /// system but they will remain in the set of requested roots. |
| /// |
| /// If an included path represents a file, then server will look in the |
| /// directory containing the file for a pubspec.yaml file. If none is found, |
| /// then the parents of the directory will be searched until such a file is |
| /// found or the root of the file system is reached. If such a file is found, |
| /// it will be used to resolve package: URI’s within the file. |
| Future setAnalysisRoots(List<String> included, List<String> excluded, |
| {Map<String, String> packageRoots}) { |
| Map m = {'included': included, 'excluded': excluded}; |
| if (packageRoots != null) m['packageRoots'] = packageRoots; |
| return _call('analysis.setAnalysisRoots', m); |
| } |
| |
| /// Subscribe for general services (that is, services that are not specific to |
| /// individual files). All previous subscriptions are replaced by the given |
| /// set of services. |
| /// |
| /// It is an error if any of the elements in the list are not valid services. |
| /// If there is an error, then the current subscriptions will remain |
| /// unchanged. |
| Future setGeneralSubscriptions(List<String> subscriptions) => _call( |
| 'analysis.setGeneralSubscriptions', {'subscriptions': subscriptions}); |
| |
| /// Set the priority files to the files in the given list. A priority file is |
| /// a file that is given priority when scheduling which analysis work to do |
| /// first. The list typically contains those files that are visible to the |
| /// user and those for which analysis results will have the biggest impact on |
| /// the user experience. The order of the files within the list is |
| /// significant: the first file will be given higher priority than the second, |
| /// the second higher priority than the third, and so on. |
| /// |
| /// Note that this request determines the set of requested priority files. The |
| /// actual set of priority files is the intersection of the requested set of |
| /// priority files with the set of files currently subject to analysis. (See |
| /// analysis.setSubscriptions for a description of files that are subject to |
| /// analysis.) |
| /// |
| /// If a requested priority file is a directory it is ignored, but remains in |
| /// the set of requested priority files so that if it later becomes a file it |
| /// can be included in the set of actual priority files. |
| Future setPriorityFiles(List<String> files) => |
| _call('analysis.setPriorityFiles', {'files': files}); |
| |
| /// Subscribe for services that are specific to individual files. All previous |
| /// subscriptions are replaced by the current set of subscriptions. If a given |
| /// service is not included as a key in the map then no files will be |
| /// subscribed to the service, exactly as if the service had been included in |
| /// the map with an explicit empty list of files. |
| /// |
| /// Note that this request determines the set of requested subscriptions. The |
| /// actual set of subscriptions at any given time is the intersection of this |
| /// set with the set of files currently subject to analysis. The files |
| /// currently subject to analysis are the set of files contained within an |
| /// actual analysis root but not excluded, plus all of the files transitively |
| /// reachable from those files via import, export and part directives. (See |
| /// analysis.setAnalysisRoots for an explanation of how the actual analysis |
| /// roots are determined.) When the actual analysis roots change, the actual |
| /// set of subscriptions is automatically updated, but the set of requested |
| /// subscriptions is unchanged. |
| /// |
| /// If a requested subscription is a directory it is ignored, but remains in |
| /// the set of requested subscriptions so that if it later becomes a file it |
| /// can be included in the set of actual subscriptions. |
| /// |
| /// It is an error if any of the keys in the map are not valid services. If |
| /// there is an error, then the existing subscriptions will remain unchanged. |
| Future setSubscriptions(Map<String, List<String>> subscriptions) => |
| _call('analysis.setSubscriptions', {'subscriptions': subscriptions}); |
| |
| /// Update the content of one or more files. Files that were previously |
| /// updated but not included in this update remain unchanged. This effectively |
| /// represents an overlay of the filesystem. The files whose content is |
| /// overridden are therefore seen by server as being files with the given |
| /// content, even if the files do not exist on the filesystem or if the file |
| /// path represents the path to a directory on the filesystem. |
| Future updateContent(Map<String, ContentOverlayType> files) => |
| _call('analysis.updateContent', {'files': files}); |
| |
| @deprecated |
| Future updateOptions(AnalysisOptions options) => |
| _call('analysis.updateOptions', {'options': options}); |
| } |
| |
| class AnalysisAnalyzedFiles { |
| static AnalysisAnalyzedFiles parse(Map m) => new AnalysisAnalyzedFiles( |
| m['directories'] == null ? null : new List.from(m['directories'])); |
| |
| /// A list of the paths of the files that are being analyzed. |
| final List<String> directories; |
| |
| AnalysisAnalyzedFiles(this.directories); |
| } |
| |
| class AnalysisClosingLabels { |
| static AnalysisClosingLabels parse(Map m) => new AnalysisClosingLabels( |
| m['file'], |
| m['labels'] == null |
| ? null |
| : new List.from(m['labels'].map((obj) => ClosingLabel.parse(obj)))); |
| |
| /// The file the closing labels relate to. |
| final String file; |
| |
| /// Closing labels relevant to the file. Each item represents a useful label |
| /// associated with some range with may be useful to display to the user |
| /// within the editor at the end of the range to indicate what construct is |
| /// closed at that location. Closing labels include constructor/method calls |
| /// and List arguments that span multiple lines. Note that the ranges that are |
| /// returned can overlap each other because they may be associated with |
| /// constructs that can be nested. |
| final List<ClosingLabel> labels; |
| |
| AnalysisClosingLabels(this.file, this.labels); |
| } |
| |
| class AnalysisErrors { |
| static AnalysisErrors parse(Map m) => new AnalysisErrors( |
| m['file'], |
| m['errors'] == null |
| ? null |
| : new List.from(m['errors'].map((obj) => AnalysisError.parse(obj)))); |
| |
| /// The file containing the errors. |
| final String file; |
| |
| /// The errors contained in the file. |
| final List<AnalysisError> errors; |
| |
| AnalysisErrors(this.file, this.errors); |
| } |
| |
| class AnalysisFlushResults { |
| static AnalysisFlushResults parse(Map m) => new AnalysisFlushResults( |
| m['files'] == null ? null : new List.from(m['files'])); |
| |
| /// The files that are no longer being analyzed. |
| final List<String> files; |
| |
| AnalysisFlushResults(this.files); |
| } |
| |
| class AnalysisFolding { |
| static AnalysisFolding parse(Map m) => new AnalysisFolding( |
| m['file'], |
| m['regions'] == null |
| ? null |
| : new List.from(m['regions'].map((obj) => FoldingRegion.parse(obj)))); |
| |
| /// The file containing the folding regions. |
| final String file; |
| |
| /// The folding regions contained in the file. |
| final List<FoldingRegion> regions; |
| |
| AnalysisFolding(this.file, this.regions); |
| } |
| |
| class AnalysisHighlights { |
| static AnalysisHighlights parse(Map m) => new AnalysisHighlights( |
| m['file'], |
| m['regions'] == null |
| ? null |
| : new List.from( |
| m['regions'].map((obj) => HighlightRegion.parse(obj)))); |
| |
| /// The file containing the highlight regions. |
| final String file; |
| |
| /// The highlight regions contained in the file. Each highlight region |
| /// represents a particular syntactic or semantic meaning associated with some |
| /// range. Note that the highlight regions that are returned can overlap other |
| /// highlight regions if there is more than one meaning associated with a |
| /// particular region. |
| final List<HighlightRegion> regions; |
| |
| AnalysisHighlights(this.file, this.regions); |
| } |
| |
| class AnalysisImplemented { |
| static AnalysisImplemented parse(Map m) => new AnalysisImplemented( |
| m['file'], |
| m['classes'] == null |
| ? null |
| : new List.from( |
| m['classes'].map((obj) => ImplementedClass.parse(obj))), |
| m['members'] == null |
| ? null |
| : new List.from( |
| m['members'].map((obj) => ImplementedMember.parse(obj)))); |
| |
| /// The file with which the implementations are associated. |
| final String file; |
| |
| /// The classes defined in the file that are implemented or extended. |
| final List<ImplementedClass> classes; |
| |
| /// The member defined in the file that are implemented or overridden. |
| final List<ImplementedMember> members; |
| |
| AnalysisImplemented(this.file, this.classes, this.members); |
| } |
| |
| class AnalysisInvalidate { |
| static AnalysisInvalidate parse(Map m) => |
| new AnalysisInvalidate(m['file'], m['offset'], m['length'], m['delta']); |
| |
| /// The file whose information has been invalidated. |
| final String file; |
| |
| /// The offset of the invalidated region. |
| final int offset; |
| |
| /// The length of the invalidated region. |
| final int length; |
| |
| /// The delta to be applied to the offsets in information that follows the |
| /// invalidated region in order to update it so that it doesn't need to be |
| /// re-requested. |
| final int delta; |
| |
| AnalysisInvalidate(this.file, this.offset, this.length, this.delta); |
| } |
| |
| class AnalysisNavigation { |
| static AnalysisNavigation parse(Map m) => new AnalysisNavigation( |
| m['file'], |
| m['regions'] == null |
| ? null |
| : new List.from( |
| m['regions'].map((obj) => NavigationRegion.parse(obj))), |
| m['targets'] == null |
| ? null |
| : new List.from( |
| m['targets'].map((obj) => NavigationTarget.parse(obj))), |
| m['files'] == null ? null : new List.from(m['files'])); |
| |
| /// The file containing the navigation regions. |
| final String file; |
| |
| /// The navigation regions contained in the file. The regions are sorted by |
| /// their offsets. Each navigation region represents a list of targets |
| /// associated with some range. The lists will usually contain a single |
| /// target, but can contain more in the case of a part that is included in |
| /// multiple libraries or in Dart code that is compiled against multiple |
| /// versions of a package. Note that the navigation regions that are returned |
| /// do not overlap other navigation regions. |
| final List<NavigationRegion> regions; |
| |
| /// The navigation targets referenced in the file. They are referenced by |
| /// `NavigationRegion`s by their index in this array. |
| final List<NavigationTarget> targets; |
| |
| /// The files containing navigation targets referenced in the file. They are |
| /// referenced by `NavigationTarget`s by their index in this array. |
| final List<String> files; |
| |
| AnalysisNavigation(this.file, this.regions, this.targets, this.files); |
| } |
| |
| class AnalysisOccurrences { |
| static AnalysisOccurrences parse(Map m) => new AnalysisOccurrences( |
| m['file'], |
| m['occurrences'] == null |
| ? null |
| : new List.from( |
| m['occurrences'].map((obj) => Occurrences.parse(obj)))); |
| |
| /// The file in which the references occur. |
| final String file; |
| |
| /// The occurrences of references to elements within the file. |
| final List<Occurrences> occurrences; |
| |
| AnalysisOccurrences(this.file, this.occurrences); |
| } |
| |
| class AnalysisOutline { |
| static AnalysisOutline parse(Map m) => |
| new AnalysisOutline(m['file'], m['kind'], Outline.parse(m['outline']), |
| libraryName: m['libraryName']); |
| |
| /// The file with which the outline is associated. |
| final String file; |
| |
| /// The kind of the file. |
| final String kind; |
| |
| /// The outline associated with the file. |
| final Outline outline; |
| |
| /// The name of the library defined by the file using a "library" directive, |
| /// or referenced by a "part of" directive. If both "library" and "part of" |
| /// directives are present, then the "library" directive takes precedence. |
| /// This field will be omitted if the file has neither "library" nor "part of" |
| /// directives. |
| @optional |
| final String libraryName; |
| |
| AnalysisOutline(this.file, this.kind, this.outline, {this.libraryName}); |
| } |
| |
| class AnalysisOverrides { |
| static AnalysisOverrides parse(Map m) => new AnalysisOverrides( |
| m['file'], |
| m['overrides'] == null |
| ? null |
| : new List.from(m['overrides'].map((obj) => Override.parse(obj)))); |
| |
| /// The file with which the overrides are associated. |
| final String file; |
| |
| /// The overrides associated with the file. |
| final List<Override> overrides; |
| |
| AnalysisOverrides(this.file, this.overrides); |
| } |
| |
| class ErrorsResult { |
| static ErrorsResult parse(Map m) => new ErrorsResult(m['errors'] == null |
| ? null |
| : new List.from(m['errors'].map((obj) => AnalysisError.parse(obj)))); |
| |
| /// The errors associated with the file. |
| final List<AnalysisError> errors; |
| |
| ErrorsResult(this.errors); |
| } |
| |
| class HoverResult { |
| static HoverResult parse(Map m) => new HoverResult(m['hovers'] == null |
| ? null |
| : new List.from(m['hovers'].map((obj) => HoverInformation.parse(obj)))); |
| |
| /// The hover information associated with the location. The list will be empty |
| /// if no information could be determined for the location. The list can |
| /// contain multiple items if the file is being analyzed in multiple contexts |
| /// in conflicting ways (such as a part that is included in multiple |
| /// libraries). |
| final List<HoverInformation> hovers; |
| |
| HoverResult(this.hovers); |
| } |
| |
| class ImportedElementsResult { |
| static ImportedElementsResult parse(Map m) => |
| new ImportedElementsResult(m['elements'] == null |
| ? null |
| : new List.from( |
| m['elements'].map((obj) => ImportedElements.parse(obj)))); |
| |
| /// The information about the elements that are referenced in the specified |
| /// region of the specified file that come from imported libraries. |
| final List<ImportedElements> elements; |
| |
| ImportedElementsResult(this.elements); |
| } |
| |
| class LibraryDependenciesResult { |
| static LibraryDependenciesResult parse(Map m) => |
| new LibraryDependenciesResult( |
| m['libraries'] == null ? null : new List.from(m['libraries']), |
| new Map.from(m['packageMap'])); |
| |
| /// A list of the paths of library elements referenced by files in existing |
| /// analysis roots. |
| final List<String> libraries; |
| |
| /// A mapping from context source roots to package maps which map package |
| /// names to source directories for use in client-side package URI resolution. |
| final Map<String, Map<String, List<String>>> packageMap; |
| |
| LibraryDependenciesResult(this.libraries, this.packageMap); |
| } |
| |
| class NavigationResult { |
| static NavigationResult parse(Map m) => new NavigationResult( |
| m['files'] == null ? null : new List.from(m['files']), |
| m['targets'] == null |
| ? null |
| : new List.from( |
| m['targets'].map((obj) => NavigationTarget.parse(obj))), |
| m['regions'] == null |
| ? null |
| : new List.from( |
| m['regions'].map((obj) => NavigationRegion.parse(obj)))); |
| |
| /// A list of the paths of files that are referenced by the navigation |
| /// targets. |
| final List<String> files; |
| |
| /// A list of the navigation targets that are referenced by the navigation |
| /// regions. |
| final List<NavigationTarget> targets; |
| |
| /// A list of the navigation regions within the requested region of the file. |
| final List<NavigationRegion> regions; |
| |
| NavigationResult(this.files, this.targets, this.regions); |
| } |
| |
| class ReachableSourcesResult { |
| static ReachableSourcesResult parse(Map m) => |
| new ReachableSourcesResult(new Map.from(m['sources'])); |
| |
| /// A mapping from source URIs to directly reachable source URIs. For example, |
| /// a file "foo.dart" that imports "bar.dart" would have the corresponding |
| /// mapping { "file:///foo.dart" : ["file:///bar.dart"] }. If "bar.dart" has |
| /// further imports (or exports) there will be a mapping from the URI |
| /// "file:///bar.dart" to them. To check if a specific URI is reachable from a |
| /// given file, clients can check for its presence in the resulting key set. |
| final Map<String, List<String>> sources; |
| |
| ReachableSourcesResult(this.sources); |
| } |
| |
| // completion domain |
| |
| /// The code completion domain contains commands related to getting code |
| /// completion suggestions. |
| class CompletionDomain extends Domain { |
| CompletionDomain(AnalysisServer server) : super(server, 'completion'); |
| |
| /// Reports the completion suggestions that should be presented to the user. |
| /// The set of suggestions included in the notification is always a complete |
| /// list that supersedes any previously reported suggestions. |
| Stream<CompletionResults> get onResults { |
| return _listen('completion.results', CompletionResults.parse); |
| } |
| |
| /// Request that completion suggestions for the given offset in the given file |
| /// be returned. |
| Future<SuggestionsResult> getSuggestions(String file, int offset) { |
| Map m = {'file': file, 'offset': offset}; |
| return _call('completion.getSuggestions', m).then(SuggestionsResult.parse); |
| } |
| } |
| |
| class CompletionResults { |
| static CompletionResults parse(Map m) => new CompletionResults( |
| m['id'], |
| m['replacementOffset'], |
| m['replacementLength'], |
| m['results'] == null |
| ? null |
| : new List.from( |
| m['results'].map((obj) => CompletionSuggestion.parse(obj))), |
| m['isLast']); |
| |
| /// The id associated with the completion. |
| final String id; |
| |
| /// The offset of the start of the text to be replaced. This will be different |
| /// than the offset used to request the completion suggestions if there was a |
| /// portion of an identifier before the original offset. In particular, the |
| /// replacementOffset will be the offset of the beginning of said identifier. |
| final int replacementOffset; |
| |
| /// The length of the text to be replaced if the remainder of the identifier |
| /// containing the cursor is to be replaced when the suggestion is applied |
| /// (that is, the number of characters in the existing identifier). |
| final int replacementLength; |
| |
| /// The completion suggestions being reported. The notification contains all |
| /// possible completions at the requested cursor position, even those that do |
| /// not match the characters the user has already typed. This allows the |
| /// client to respond to further keystrokes from the user without having to |
| /// make additional requests. |
| final List<CompletionSuggestion> results; |
| |
| /// True if this is that last set of results that will be returned for the |
| /// indicated completion. |
| final bool isLast; |
| |
| CompletionResults(this.id, this.replacementOffset, this.replacementLength, |
| this.results, this.isLast); |
| } |
| |
| class SuggestionsResult { |
| static SuggestionsResult parse(Map m) => new SuggestionsResult(m['id']); |
| |
| /// The identifier used to associate results with this completion request. |
| final String id; |
| |
| SuggestionsResult(this.id); |
| } |
| |
| // search domain |
| |
| /// The search domain contains commands related to searches that can be |
| /// performed against the code base. |
| class SearchDomain extends Domain { |
| SearchDomain(AnalysisServer server) : super(server, 'search'); |
| |
| /// Reports some or all of the results of performing a requested search. |
| /// Unlike other notifications, this notification contains search results that |
| /// should be added to any previously received search results associated with |
| /// the same search id. |
| Stream<SearchResults> get onResults { |
| return _listen('search.results', SearchResults.parse); |
| } |
| |
| /// Perform a search for references to the element defined or referenced at |
| /// the given offset in the given file. |
| /// |
| /// An identifier is returned immediately, and individual results will be |
| /// returned via the search.results notification as they become available. |
| Future<FindElementReferencesResult> findElementReferences( |
| String file, int offset, bool includePotential) { |
| Map m = { |
| 'file': file, |
| 'offset': offset, |
| 'includePotential': includePotential |
| }; |
| return _call('search.findElementReferences', m) |
| .then(FindElementReferencesResult.parse); |
| } |
| |
| /// Perform a search for declarations of members whose name is equal to the |
| /// given name. |
| /// |
| /// An identifier is returned immediately, and individual results will be |
| /// returned via the search.results notification as they become available. |
| Future<FindMemberDeclarationsResult> findMemberDeclarations(String name) { |
| Map m = {'name': name}; |
| return _call('search.findMemberDeclarations', m) |
| .then(FindMemberDeclarationsResult.parse); |
| } |
| |
| /// Perform a search for references to members whose name is equal to the |
| /// given name. This search does not check to see that there is a member |
| /// defined with the given name, so it is able to find references to undefined |
| /// members as well. |
| /// |
| /// An identifier is returned immediately, and individual results will be |
| /// returned via the search.results notification as they become available. |
| Future<FindMemberReferencesResult> findMemberReferences(String name) { |
| Map m = {'name': name}; |
| return _call('search.findMemberReferences', m) |
| .then(FindMemberReferencesResult.parse); |
| } |
| |
| /// Perform a search for declarations of top-level elements (classes, |
| /// typedefs, getters, setters, functions and fields) whose name matches the |
| /// given pattern. |
| /// |
| /// An identifier is returned immediately, and individual results will be |
| /// returned via the search.results notification as they become available. |
| Future<FindTopLevelDeclarationsResult> findTopLevelDeclarations( |
| String pattern) { |
| Map m = {'pattern': pattern}; |
| return _call('search.findTopLevelDeclarations', m) |
| .then(FindTopLevelDeclarationsResult.parse); |
| } |
| |
| /// Return top-level and class member declarations. |
| @experimental |
| Future<ElementDeclarationsResult> getElementDeclarations( |
| {String file, String pattern, int maxResults}) { |
| Map m = {}; |
| if (file != null) m['file'] = file; |
| if (pattern != null) m['pattern'] = pattern; |
| if (maxResults != null) m['maxResults'] = maxResults; |
| return _call('search.getElementDeclarations', m) |
| .then(ElementDeclarationsResult.parse); |
| } |
| |
| /// Return the type hierarchy of the class declared or referenced at the given |
| /// location. |
| Future<TypeHierarchyResult> getTypeHierarchy(String file, int offset, |
| {bool superOnly}) { |
| Map m = {'file': file, 'offset': offset}; |
| if (superOnly != null) m['superOnly'] = superOnly; |
| return _call('search.getTypeHierarchy', m).then(TypeHierarchyResult.parse); |
| } |
| } |
| |
| class SearchResults { |
| static SearchResults parse(Map m) => new SearchResults( |
| m['id'], |
| m['results'] == null |
| ? null |
| : new List.from(m['results'].map((obj) => SearchResult.parse(obj))), |
| m['isLast']); |
| |
| /// The id associated with the search. |
| final String id; |
| |
| /// The search results being reported. |
| final List<SearchResult> results; |
| |
| /// True if this is that last set of results that will be returned for the |
| /// indicated search. |
| final bool isLast; |
| |
| SearchResults(this.id, this.results, this.isLast); |
| } |
| |
| class FindElementReferencesResult { |
| static FindElementReferencesResult parse(Map m) => |
| new FindElementReferencesResult( |
| id: m['id'], element: Element.parse(m['element'])); |
| |
| /// The identifier used to associate results with this search request. |
| /// |
| /// If no element was found at the given location, this field will be absent, |
| /// and no results will be reported via the search.results notification. |
| @optional |
| final String id; |
| |
| /// The element referenced or defined at the given offset and whose references |
| /// will be returned in the search results. |
| /// |
| /// If no element was found at the given location, this field will be absent. |
| @optional |
| final Element element; |
| |
| FindElementReferencesResult({this.id, this.element}); |
| } |
| |
| class FindMemberDeclarationsResult { |
| static FindMemberDeclarationsResult parse(Map m) => |
| new FindMemberDeclarationsResult(m['id']); |
| |
| /// The identifier used to associate results with this search request. |
| final String id; |
| |
| FindMemberDeclarationsResult(this.id); |
| } |
| |
| class FindMemberReferencesResult { |
| static FindMemberReferencesResult parse(Map m) => |
| new FindMemberReferencesResult(m['id']); |
| |
| /// The identifier used to associate results with this search request. |
| final String id; |
| |
| FindMemberReferencesResult(this.id); |
| } |
| |
| class FindTopLevelDeclarationsResult { |
| static FindTopLevelDeclarationsResult parse(Map m) => |
| new FindTopLevelDeclarationsResult(m['id']); |
| |
| /// The identifier used to associate results with this search request. |
| final String id; |
| |
| FindTopLevelDeclarationsResult(this.id); |
| } |
| |
| class ElementDeclarationsResult { |
| static ElementDeclarationsResult parse(Map m) => |
| new ElementDeclarationsResult( |
| m['declarations'] == null |
| ? null |
| : new List.from(m['declarations'] |
| .map((obj) => ElementDeclaration.parse(obj))), |
| m['files'] == null ? null : new List.from(m['files'])); |
| |
| /// The list of declarations. |
| final List<ElementDeclaration> declarations; |
| |
| /// The list of the paths of files with declarations. |
| final List<String> files; |
| |
| ElementDeclarationsResult(this.declarations, this.files); |
| } |
| |
| class TypeHierarchyResult { |
| static TypeHierarchyResult parse(Map m) => new TypeHierarchyResult( |
| hierarchyItems: m['hierarchyItems'] == null |
| ? null |
| : new List.from( |
| m['hierarchyItems'].map((obj) => TypeHierarchyItem.parse(obj)))); |
| |
| /// A list of the types in the requested hierarchy. The first element of the |
| /// list is the item representing the type for which the hierarchy was |
| /// requested. The index of other elements of the list is unspecified, but |
| /// correspond to the integers used to reference supertype and subtype items |
| /// within the items. |
| /// |
| /// This field will be absent if the code at the given file and offset does |
| /// not represent a type, or if the file has not been sufficiently analyzed to |
| /// allow a type hierarchy to be produced. |
| @optional |
| final List<TypeHierarchyItem> hierarchyItems; |
| |
| TypeHierarchyResult({this.hierarchyItems}); |
| } |
| |
| // edit domain |
| |
| /// The edit domain contains commands related to edits that can be applied to |
| /// the code. |
| class EditDomain extends Domain { |
| EditDomain(AnalysisServer server) : super(server, 'edit'); |
| |
| /// Format the contents of a single file. The currently selected region of |
| /// text is passed in so that the selection can be preserved across the |
| /// formatting operation. The updated selection will be as close to matching |
| /// the original as possible, but whitespace at the beginning or end of the |
| /// selected region will be ignored. If preserving selection information is |
| /// not required, zero (0) can be specified for both the selection offset and |
| /// selection length. |
| /// |
| /// If a request is made for a file which does not exist, or which is not |
| /// currently subject to analysis (e.g. because it is not associated with any |
| /// analysis root specified to analysis.setAnalysisRoots), an error of type |
| /// `FORMAT_INVALID_FILE` will be generated. If the source contains syntax |
| /// errors, an error of type `FORMAT_WITH_ERRORS` will be generated. |
| Future<FormatResult> format( |
| String file, int selectionOffset, int selectionLength, |
| {int lineLength}) { |
| Map m = { |
| 'file': file, |
| 'selectionOffset': selectionOffset, |
| 'selectionLength': selectionLength |
| }; |
| if (lineLength != null) m['lineLength'] = lineLength; |
| return _call('edit.format', m).then(FormatResult.parse); |
| } |
| |
| /// Return the set of assists that are available at the given location. An |
| /// assist is distinguished from a refactoring primarily by the fact that it |
| /// affects a single file and does not require user input in order to be |
| /// performed. |
| Future<AssistsResult> getAssists(String file, int offset, int length) { |
| Map m = {'file': file, 'offset': offset, 'length': length}; |
| return _call('edit.getAssists', m).then(AssistsResult.parse); |
| } |
| |
| /// Get a list of the kinds of refactorings that are valid for the given |
| /// selection in the given file. |
| Future<AvailableRefactoringsResult> getAvailableRefactorings( |
| String file, int offset, int length) { |
| Map m = {'file': file, 'offset': offset, 'length': length}; |
| return _call('edit.getAvailableRefactorings', m) |
| .then(AvailableRefactoringsResult.parse); |
| } |
| |
| /// Return the set of fixes that are available for the errors at a given |
| /// offset in a given file. |
| Future<FixesResult> getFixes(String file, int offset) { |
| Map m = {'file': file, 'offset': offset}; |
| return _call('edit.getFixes', m).then(FixesResult.parse); |
| } |
| |
| /// Get the changes required to convert the postfix template at the given |
| /// location into the template's expanded form. |
| @experimental |
| Future<PostfixCompletionResult> getPostfixCompletion( |
| String file, String key, int offset) { |
| Map m = {'file': file, 'key': key, 'offset': offset}; |
| return _call('edit.getPostfixCompletion', m) |
| .then(PostfixCompletionResult.parse); |
| } |
| |
| /// Get the changes required to perform a refactoring. |
| /// |
| /// If another refactoring request is received during the processing of this |
| /// one, an error of type `REFACTORING_REQUEST_CANCELLED` will be generated. |
| Future<RefactoringResult> getRefactoring( |
| String kind, String file, int offset, int length, bool validateOnly, |
| {RefactoringOptions options}) { |
| Map m = { |
| 'kind': kind, |
| 'file': file, |
| 'offset': offset, |
| 'length': length, |
| 'validateOnly': validateOnly |
| }; |
| if (options != null) m['options'] = options; |
| return _call('edit.getRefactoring', m) |
| .then((m) => RefactoringResult.parse(kind, m)); |
| } |
| |
| /// Get the changes required to convert the partial statement at the given |
| /// location into a syntactically valid statement. If the current statement is |
| /// already valid the change will insert a newline plus appropriate |
| /// indentation at the end of the line containing the offset. If a change that |
| /// makes the statement valid cannot be determined (perhaps because it has not |
| /// yet been implemented) the statement will be considered already valid and |
| /// the appropriate change returned. |
| @experimental |
| Future<StatementCompletionResult> getStatementCompletion( |
| String file, int offset) { |
| Map m = {'file': file, 'offset': offset}; |
| return _call('edit.getStatementCompletion', m) |
| .then(StatementCompletionResult.parse); |
| } |
| |
| /// Determine if the request postfix completion template is applicable at the |
| /// given location in the given file. |
| @experimental |
| Future<IsPostfixCompletionApplicableResult> isPostfixCompletionApplicable( |
| String file, String key, int offset) { |
| Map m = {'file': file, 'key': key, 'offset': offset}; |
| return _call('edit.isPostfixCompletionApplicable', m) |
| .then(IsPostfixCompletionApplicableResult.parse); |
| } |
| |
| /// Return a list of all postfix templates currently available. |
| @experimental |
| Future<ListPostfixCompletionTemplatesResult> |
| listPostfixCompletionTemplates() => |
| _call('edit.listPostfixCompletionTemplates') |
| .then(ListPostfixCompletionTemplatesResult.parse); |
| |
| /// Return a list of edits that would need to be applied in order to ensure |
| /// that all of the elements in the specified list of imported elements are |
| /// accessible within the library. |
| /// |
| /// If a request is made for a file that does not exist, or that is not |
| /// currently subject to analysis (e.g. because it is not associated with any |
| /// analysis root specified via analysis.setAnalysisRoots), an error of type |
| /// `IMPORT_ELEMENTS_INVALID_FILE` will be generated. |
| @experimental |
| Future<ImportElementsResult> importElements( |
| String file, List<ImportedElements> elements) { |
| Map m = {'file': file, 'elements': elements}; |
| return _call('edit.importElements', m).then(ImportElementsResult.parse); |
| } |
| |
| /// Sort all of the directives, unit and class members of the given Dart file. |
| /// |
| /// If a request is made for a file that does not exist, does not belong to an |
| /// analysis root or is not a Dart file, `SORT_MEMBERS_INVALID_FILE` will be |
| /// generated. |
| /// |
| /// If the Dart file has scan or parse errors, `SORT_MEMBERS_PARSE_ERRORS` |
| /// will be generated. |
| Future<SortMembersResult> sortMembers(String file) { |
| Map m = {'file': file}; |
| return _call('edit.sortMembers', m).then(SortMembersResult.parse); |
| } |
| |
| /// Organizes all of the directives - removes unused imports and sorts |
| /// directives of the given Dart file according to the (Dart Style |
| /// Guide)[https://www.dartlang.org/articles/style-guide/]. |
| /// |
| /// If a request is made for a file that does not exist, does not belong to an |
| /// analysis root or is not a Dart file, `FILE_NOT_ANALYZED` will be |
| /// generated. |
| /// |
| /// If directives of the Dart file cannot be organized, for example because it |
| /// has scan or parse errors, or by other reasons, `ORGANIZE_DIRECTIVES_ERROR` |
| /// will be generated. The message will provide details about the reason. |
| Future<OrganizeDirectivesResult> organizeDirectives(String file) { |
| Map m = {'file': file}; |
| return _call('edit.organizeDirectives', m) |
| .then(OrganizeDirectivesResult.parse); |
| } |
| } |
| |
| class FormatResult { |
| static FormatResult parse(Map m) => new FormatResult( |
| m['edits'] == null |
| ? null |
| : new List.from(m['edits'].map((obj) => SourceEdit.parse(obj))), |
| m['selectionOffset'], |
| m['selectionLength']); |
| |
| /// The edit(s) to be applied in order to format the code. The list will be |
| /// empty if the code was already formatted (there are no changes). |
| final List<SourceEdit> edits; |
| |
| /// The offset of the selection after formatting the code. |
| final int selectionOffset; |
| |
| /// The length of the selection after formatting the code. |
| final int selectionLength; |
| |
| FormatResult(this.edits, this.selectionOffset, this.selectionLength); |
| } |
| |
| class AssistsResult { |
| static AssistsResult parse(Map m) => new AssistsResult(m['assists'] == null |
| ? null |
| : new List.from(m['assists'].map((obj) => SourceChange.parse(obj)))); |
| |
| /// The assists that are available at the given location. |
| final List<SourceChange> assists; |
| |
| AssistsResult(this.assists); |
| } |
| |
| class AvailableRefactoringsResult { |
| static AvailableRefactoringsResult parse(Map m) => |
| new AvailableRefactoringsResult( |
| m['kinds'] == null ? null : new List.from(m['kinds'])); |
| |
| /// The kinds of refactorings that are valid for the given selection. |
| final List<String> kinds; |
| |
| AvailableRefactoringsResult(this.kinds); |
| } |
| |
| class FixesResult { |
| static FixesResult parse(Map m) => new FixesResult(m['fixes'] == null |
| ? null |
| : new List.from(m['fixes'].map((obj) => AnalysisErrorFixes.parse(obj)))); |
| |
| /// The fixes that are available for the errors at the given offset. |
| final List<AnalysisErrorFixes> fixes; |
| |
| FixesResult(this.fixes); |
| } |
| |
| class PostfixCompletionResult { |
| static PostfixCompletionResult parse(Map m) => |
| new PostfixCompletionResult(SourceChange.parse(m['change'])); |
| |
| /// The change to be applied in order to complete the statement. |
| final SourceChange change; |
| |
| PostfixCompletionResult(this.change); |
| } |
| |
| class RefactoringResult { |
| static RefactoringResult parse(String kind, Map m) => new RefactoringResult( |
| m['initialProblems'] == null |
| ? null |
| : new List.from( |
| m['initialProblems'].map((obj) => RefactoringProblem.parse(obj))), |
| m['optionsProblems'] == null |
| ? null |
| : new List.from( |
| m['optionsProblems'].map((obj) => RefactoringProblem.parse(obj))), |
| m['finalProblems'] == null |
| ? null |
| : new List.from( |
| m['finalProblems'].map((obj) => RefactoringProblem.parse(obj))), |
| feedback: RefactoringFeedback.parse(kind, m['feedback']), |
| change: SourceChange.parse(m['change']), |
| potentialEdits: m['potentialEdits'] == null |
| ? null |
| : new List.from(m['potentialEdits'])); |
| |
| /// The initial status of the refactoring, i.e. problems related to the |
| /// context in which the refactoring is requested. The array will be empty if |
| /// there are no known problems. |
| final List<RefactoringProblem> initialProblems; |
| |
| /// The options validation status, i.e. problems in the given options, such as |
| /// light-weight validation of a new name, flags compatibility, etc. The array |
| /// will be empty if there are no known problems. |
| final List<RefactoringProblem> optionsProblems; |
| |
| /// The final status of the refactoring, i.e. problems identified in the |
| /// result of a full, potentially expensive validation and / or change |
| /// creation. The array will be empty if there are no known problems. |
| final List<RefactoringProblem> finalProblems; |
| |
| /// Data used to provide feedback to the user. The structure of the data is |
| /// dependent on the kind of refactoring being created. The data that is |
| /// returned is documented in the section titled |
| /// (Refactorings)[#refactorings], labeled as "Feedback". |
| @optional |
| final RefactoringFeedback feedback; |
| |
| /// The changes that are to be applied to affect the refactoring. This field |
| /// will be omitted if there are problems that prevent a set of changes from |
| /// being computed, such as having no options specified for a refactoring that |
| /// requires them, or if only validation was requested. |
| @optional |
| final SourceChange change; |
| |
| /// The ids of source edits that are not known to be valid. An edit is not |
| /// known to be valid if there was insufficient type information for the |
| /// server to be able to determine whether or not the code needs to be |
| /// modified, such as when a member is being renamed and there is a reference |
| /// to a member from an unknown type. This field will be omitted if the change |
| /// field is omitted or if there are no potential edits for the refactoring. |
| @optional |
| final List<String> potentialEdits; |
| |
| RefactoringResult( |
| this.initialProblems, this.optionsProblems, this.finalProblems, |
| {this.feedback, this.change, this.potentialEdits}); |
| } |
| |
| class StatementCompletionResult { |
| static StatementCompletionResult parse(Map m) => |
| new StatementCompletionResult( |
| SourceChange.parse(m['change']), m['whitespaceOnly']); |
| |
| /// The change to be applied in order to complete the statement. |
| final SourceChange change; |
| |
| /// Will be true if the change contains nothing but whitespace characters, or |
| /// is empty. |
| final bool whitespaceOnly; |
| |
| StatementCompletionResult(this.change, this.whitespaceOnly); |
| } |
| |
| class IsPostfixCompletionApplicableResult { |
| static IsPostfixCompletionApplicableResult parse(Map m) => |
| new IsPostfixCompletionApplicableResult(m['value']); |
| |
| /// True if the template can be expanded at the given location. |
| final bool value; |
| |
| IsPostfixCompletionApplicableResult(this.value); |
| } |
| |
| class ListPostfixCompletionTemplatesResult { |
| static ListPostfixCompletionTemplatesResult parse(Map m) => |
| new ListPostfixCompletionTemplatesResult(m['templates'] == null |
| ? null |
| : new List.from(m['templates'] |
| .map((obj) => PostfixTemplateDescriptor.parse(obj)))); |
| |
| /// The list of available templates. |
| final List<PostfixTemplateDescriptor> templates; |
| |
| ListPostfixCompletionTemplatesResult(this.templates); |
| } |
| |
| class ImportElementsResult { |
| static ImportElementsResult parse(Map m) => |
| new ImportElementsResult(SourceFileEdit.parse(m['edit'])); |
| |
| /// The edits to be applied in order to make the specified elements |
| /// accessible. The file to be edited will be the defining compilation unit of |
| /// the library containing the file specified in the request, which can be |
| /// different than the file specified in the request if the specified file is |
| /// a part file. |
| final SourceFileEdit edit; |
| |
| ImportElementsResult(this.edit); |
| } |
| |
| class SortMembersResult { |
| static SortMembersResult parse(Map m) => |
| new SortMembersResult(SourceFileEdit.parse(m['edit'])); |
| |
| /// The file edit that is to be applied to the given file to effect the |
| /// sorting. |
| final SourceFileEdit edit; |
| |
| SortMembersResult(this.edit); |
| } |
| |
| class OrganizeDirectivesResult { |
| static OrganizeDirectivesResult parse(Map m) => |
| new OrganizeDirectivesResult(SourceFileEdit.parse(m['edit'])); |
| |
| /// The file edit that is to be applied to the given file to effect the |
| /// organizing. |
| final SourceFileEdit edit; |
| |
| OrganizeDirectivesResult(this.edit); |
| } |
| |
| // execution domain |
| |
| /// The execution domain contains commands related to providing an execution or |
| /// debugging experience. |
| class ExecutionDomain extends Domain { |
| ExecutionDomain(AnalysisServer server) : super(server, 'execution'); |
| |
| /// Reports information needed to allow a single file to be launched. |
| /// |
| /// This notification is not subscribed to by default. Clients can subscribe |
| /// by including the value "LAUNCH_DATA" in the list of services passed in an |
| /// `execution.setSubscriptions` request. |
| Stream<ExecutionLaunchData> get onLaunchData { |
| return _listen('execution.launchData', ExecutionLaunchData.parse); |
| } |
| |
| /// Create an execution context for the executable file with the given path. |
| /// The context that is created will persist until execution.deleteContext is |
| /// used to delete it. Clients, therefore, are responsible for managing the |
| /// lifetime of execution contexts. |
| Future<CreateContextResult> createContext(String contextRoot) { |
| Map m = {'contextRoot': contextRoot}; |
| return _call('execution.createContext', m).then(CreateContextResult.parse); |
| } |
| |
| /// Delete the execution context with the given identifier. The context id is |
| /// no longer valid after this command. The server is allowed to re-use ids |
| /// when they are no longer valid. |
| Future deleteContext(String id) => |
| _call('execution.deleteContext', {'id': id}); |
| |
| /// Map a URI from the execution context to the file that it corresponds to, |
| /// or map a file to the URI that it corresponds to in the execution context. |
| /// |
| /// Exactly one of the file and uri fields must be provided. If both fields |
| /// are provided, then an error of type `INVALID_PARAMETER` will be generated. |
| /// Similarly, if neither field is provided, then an error of type |
| /// `INVALID_PARAMETER` will be generated. |
| /// |
| /// If the file field is provided and the value is not the path of a file |
| /// (either the file does not exist or the path references something other |
| /// than a file), then an error of type `INVALID_PARAMETER` will be generated. |
| /// |
| /// If the uri field is provided and the value is not a valid URI or if the |
| /// URI references something that is not a file (either a file that does not |
| /// exist or something other than a file), then an error of type |
| /// `INVALID_PARAMETER` will be generated. |
| /// |
| /// If the contextRoot used to create the execution context does not exist, |
| /// then an error of type `INVALID_EXECUTION_CONTEXT` will be generated. |
| Future<MapUriResult> mapUri(String id, {String file, String uri}) { |
| Map m = {'id': id}; |
| if (file != null) m['file'] = file; |
| if (uri != null) m['uri'] = uri; |
| return _call('execution.mapUri', m).then(MapUriResult.parse); |
| } |
| |
| @deprecated |
| Future setSubscriptions(List<String> subscriptions) => |
| _call('execution.setSubscriptions', {'subscriptions': subscriptions}); |
| } |
| |
| class ExecutionLaunchData { |
| static ExecutionLaunchData parse(Map m) => new ExecutionLaunchData(m['file'], |
| kind: m['kind'], |
| referencedFiles: m['referencedFiles'] == null |
| ? null |
| : new List.from(m['referencedFiles'])); |
| |
| /// The file for which launch data is being provided. This will either be a |
| /// Dart library or an HTML file. |
| final String file; |
| |
| /// The kind of the executable file. This field is omitted if the file is not |
| /// a Dart file. |
| @optional |
| final String kind; |
| |
| /// A list of the Dart files that are referenced by the file. This field is |
| /// omitted if the file is not an HTML file. |
| @optional |
| final List<String> referencedFiles; |
| |
| ExecutionLaunchData(this.file, {this.kind, this.referencedFiles}); |
| } |
| |
| class CreateContextResult { |
| static CreateContextResult parse(Map m) => new CreateContextResult(m['id']); |
| |
| /// The identifier used to refer to the execution context that was created. |
| final String id; |
| |
| CreateContextResult(this.id); |
| } |
| |
| class MapUriResult { |
| static MapUriResult parse(Map m) => |
| new MapUriResult(file: m['file'], uri: m['uri']); |
| |
| /// The file to which the URI was mapped. This field is omitted if the uri |
| /// field was not given in the request. |
| @optional |
| final String file; |
| |
| /// The URI to which the file path was mapped. This field is omitted if the |
| /// file field was not given in the request. |
| @optional |
| final String uri; |
| |
| MapUriResult({this.file, this.uri}); |
| } |
| |
| // diagnostic domain |
| |
| /// The diagnostic domain contains server diagnostics APIs. |
| class DiagnosticDomain extends Domain { |
| DiagnosticDomain(AnalysisServer server) : super(server, 'diagnostic'); |
| |
| /// Return server diagnostics. |
| Future<DiagnosticsResult> getDiagnostics() => |
| _call('diagnostic.getDiagnostics').then(DiagnosticsResult.parse); |
| |
| /// Return the port of the diagnostic web server. If the server is not running |
| /// this call will start the server. If unable to start the diagnostic web |
| /// server, this call will return an error of |
| /// `DEBUG_PORT_COULD_NOT_BE_OPENED`. |
| Future<ServerPortResult> getServerPort() => |
| _call('diagnostic.getServerPort').then(ServerPortResult.parse); |
| } |
| |
| class DiagnosticsResult { |
| static DiagnosticsResult parse(Map m) => |
| new DiagnosticsResult(m['contexts'] == null |
| ? null |
| : new List.from(m['contexts'].map((obj) => ContextData.parse(obj)))); |
| |
| /// The list of analysis contexts. |
| final List<ContextData> contexts; |
| |
| DiagnosticsResult(this.contexts); |
| } |
| |
| class ServerPortResult { |
| static ServerPortResult parse(Map m) => new ServerPortResult(m['port']); |
| |
| /// The diagnostic server port. |
| final int port; |
| |
| ServerPortResult(this.port); |
| } |
| |
| // analytics domain |
| |
| /// The analytics domain contains APIs related to reporting analytics. |
| /// |
| /// This API allows clients to expose a UI option to enable and disable the |
| /// analysis server's reporting of analytics. This value is shared with other |
| /// tools and can change outside of this API; because of this, clients should |
| /// use the analysis server's flag as the system of record. Clients can choose |
| /// to send in additional analytics (see `sendEvent` and `sendTiming`) if they |
| /// so choose. Dart command-line tools provide a disclaimer similar to: ` Dart |
| /// SDK tools anonymously report feature usage statistics and basic crash |
| /// reports to help improve Dart tools over time. See Google's privacy policy: |
| /// https://www.google.com/intl/en/policies/privacy/. ` |
| /// |
| /// The analysis server will send it's own analytics data (for example, |
| /// operations performed, operating system type, SDK version). No data (from the |
| /// analysis server or from clients) will be sent if analytics is disabled. |
| @experimental |
| class AnalyticsDomain extends Domain { |
| AnalyticsDomain(AnalysisServer server) : super(server, 'analytics'); |
| |
| /// Query whether analytics is enabled. |
| /// |
| /// This flag controls whether the analysis server sends any analytics data to |
| /// the cloud. If disabled, the analysis server does not send any analytics |
| /// data, and any data sent to it by clients (from `sendEvent` and |
| /// `sendTiming`) will be ignored. |
| /// |
| /// The value of this flag can be changed by other tools outside of the |
| /// analysis server's process. When you query the flag, you get the value of |
| /// the flag at a given moment. Clients should not use the value returned to |
| /// decide whether or not to send the `sendEvent` and `sendTiming` requests. |
| /// Those requests should be used unconditionally and server will determine |
| /// whether or not it is appropriate to forward the information to the cloud |
| /// at the time each request is received. |
| Future<IsEnabledResult> isEnabled() => |
| _call('analytics.isEnabled').then(IsEnabledResult.parse); |
| |
| /// Enable or disable the sending of analytics data. Note that there are other |
| /// ways for users to change this setting, so clients cannot assume that they |
| /// have complete control over this setting. In particular, there is no |
| /// guarantee that the result returned by the `isEnabled` request will match |
| /// the last value set via this request. |
| Future enable(bool value) => _call('analytics.enable', {'value': value}); |
| |
| /// Send information about client events. |
| /// |
| /// Ask the analysis server to include the fact that an action was performed |
| /// in the client as part of the analytics data being sent. The data will only |
| /// be included if the sending of analytics data is enabled at the time the |
| /// request is processed. The action that was performed is indicated by the |
| /// value of the `action` field. |
| /// |
| /// The value of the action field should not include the identity of the |
| /// client. The analytics data sent by server will include the client id |
| /// passed in using the `--client-id` command-line argument. The request will |
| /// be ignored if the client id was not provided when server was started. |
| Future sendEvent(String action) => |
| _call('analytics.sendEvent', {'action': action}); |
| |
| /// Send timing information for client events (e.g. code completions). |
| /// |
| /// Ask the analysis server to include the fact that a timed event occurred as |
| /// part of the analytics data being sent. The data will only be included if |
| /// the sending of analytics data is enabled at the time the request is |
| /// processed. |
| /// |
| /// The value of the event field should not include the identity of the |
| /// client. The analytics data sent by server will include the client id |
| /// passed in using the `--client-id` command-line argument. The request will |
| /// be ignored if the client id was not provided when server was started. |
| Future sendTiming(String event, int millis) { |
| Map m = {'event': event, 'millis': millis}; |
| return _call('analytics.sendTiming', m); |
| } |
| } |
| |
| class IsEnabledResult { |
| static IsEnabledResult parse(Map m) => new IsEnabledResult(m['enabled']); |
| |
| /// Whether sending analytics is enabled or not. |
| final bool enabled; |
| |
| IsEnabledResult(this.enabled); |
| } |
| |
| // kythe domain |
| |
| /// The kythe domain contains APIs related to generating Dart content in the |
| /// (Kythe)[http://kythe.io/] format. |
| @experimental |
| class KytheDomain extends Domain { |
| KytheDomain(AnalysisServer server) : super(server, 'kythe'); |
| |
| /// Return the list of `KytheEntry` objects for some file, given the current |
| /// state of the file system populated by "analysis.updateContent". |
| /// |
| /// If a request is made for a file that does not exist, or that is not |
| /// currently subject to analysis (e.g. because it is not associated with any |
| /// analysis root specified to analysis.setAnalysisRoots), an error of type |
| /// `GET_KYTHE_ENTRIES_INVALID_FILE` will be generated. |
| Future<KytheEntriesResult> getKytheEntries(String file) { |
| Map m = {'file': file}; |
| return _call('kythe.getKytheEntries', m).then(KytheEntriesResult.parse); |
| } |
| } |
| |
| class KytheEntriesResult { |
| static KytheEntriesResult parse(Map m) => new KytheEntriesResult( |
| m['entries'] == null |
| ? null |
| : new List.from(m['entries'].map((obj) => KytheEntry.parse(obj))), |
| m['files'] == null ? null : new List.from(m['files'])); |
| |
| /// The list of `KytheEntry` objects for the queried file. |
| final List<KytheEntry> entries; |
| |
| /// The set of files paths that were required, but not in the file system, to |
| /// give a complete and accurate Kythe graph for the file. This could be due |
| /// to a referenced file that does not exist or generated files not being |
| /// generated or passed before the call to "getKytheEntries". |
| final List<String> files; |
| |
| KytheEntriesResult(this.entries, this.files); |
| } |
| |
| // flutter domain |
| |
| /// The analysis domain contains API’s related to Flutter support. |
| @experimental |
| class FlutterDomain extends Domain { |
| FlutterDomain(AnalysisServer server) : super(server, 'flutter'); |
| |
| /// Reports the Flutter outline associated with a single file. |
| /// |
| /// This notification is not subscribed to by default. Clients can subscribe |
| /// by including the value `"OUTLINE"` in the list of services passed in an |
| /// flutter.setSubscriptions request. |
| Stream<FlutterOutlineEvent> get onOutline { |
| return _listen('flutter.outline', FlutterOutlineEvent.parse); |
| } |
| |
| /// Return the change that adds the forDesignTime() constructor for the widget |
| /// class at the given offset. |
| Future<ChangeAddForDesignTimeConstructorResult> |
| getChangeAddForDesignTimeConstructor(String file, int offset) { |
| Map m = {'file': file, 'offset': offset}; |
| return _call('flutter.getChangeAddForDesignTimeConstructor', m) |
| .then(ChangeAddForDesignTimeConstructorResult.parse); |
| } |
| |
| /// Subscribe for services that are specific to individual files. All previous |
| /// subscriptions are replaced by the current set of subscriptions. If a given |
| /// service is not included as a key in the map then no files will be |
| /// subscribed to the service, exactly as if the service had been included in |
| /// the map with an explicit empty list of files. |
| /// |
| /// Note that this request determines the set of requested subscriptions. The |
| /// actual set of subscriptions at any given time is the intersection of this |
| /// set with the set of files currently subject to analysis. The files |
| /// currently subject to analysis are the set of files contained within an |
| /// actual analysis root but not excluded, plus all of the files transitively |
| /// reachable from those files via import, export and part directives. (See |
| /// analysis.setAnalysisRoots for an explanation of how the actual analysis |
| /// roots are determined.) When the actual analysis roots change, the actual |
| /// set of subscriptions is automatically updated, but the set of requested |
| /// subscriptions is unchanged. |
| /// |
| /// If a requested subscription is a directory it is ignored, but remains in |
| /// the set of requested subscriptions so that if it later becomes a file it |
| /// can be included in the set of actual subscriptions. |
| /// |
| /// It is an error if any of the keys in the map are not valid services. If |
| /// there is an error, then the existing subscriptions will remain unchanged. |
| Future setSubscriptions(Map<String, List<String>> subscriptions) => |
| _call('flutter.setSubscriptions', {'subscriptions': subscriptions}); |
| } |
| |
| class FlutterOutlineEvent { |
| static FlutterOutlineEvent parse(Map m) => |
| new FlutterOutlineEvent(m['file'], FlutterOutline.parse(m['outline']), |
| instrumentedCode: m['instrumentedCode']); |
| |
| /// The file with which the outline is associated. |
| final String file; |
| |
| /// The outline associated with the file. |
| final FlutterOutline outline; |
| |
| /// If the file has Flutter widgets that can be rendered, this field has the |
| /// instrumented content of the file, that allows associating widgets with |
| /// corresponding outline nodes. If there are no widgets to render, this field |
| /// is absent. |
| @optional |
| final String instrumentedCode; |
| |
| FlutterOutlineEvent(this.file, this.outline, {this.instrumentedCode}); |
| } |
| |
| class ChangeAddForDesignTimeConstructorResult { |
| static ChangeAddForDesignTimeConstructorResult parse(Map m) => |
| new ChangeAddForDesignTimeConstructorResult( |
| SourceChange.parse(m['change'])); |
| |
| /// The change that adds the forDesignTime() constructor. If the change cannot |
| /// be produced, an error is returned. |
| final SourceChange change; |
| |
| ChangeAddForDesignTimeConstructorResult(this.change); |
| } |
| |
| // type definitions |
| |
| /// A directive to begin overlaying the contents of a file. The supplied content |
| /// will be used for analysis in place of the file contents in the filesystem. |
| /// |
| /// If this directive is used on a file that already has a file content overlay, |
| /// the old overlay is discarded and replaced with the new one. |
| class AddContentOverlay extends ContentOverlayType implements Jsonable { |
| static AddContentOverlay parse(Map m) { |
| if (m == null) return null; |
| return new AddContentOverlay(m['content']); |
| } |
| |
| /// The new content of the file. |
| final String content; |
| |
| AddContentOverlay(this.content) : super('add'); |
| |
| Map toMap() => _stripNullValues({'type': type, 'content': content}); |
| } |
| |
| /// An indication of an error, warning, or hint that was produced by the |
| /// analysis. |
| class AnalysisError { |
| static AnalysisError parse(Map m) { |
| if (m == null) return null; |
| return new AnalysisError(m['severity'], m['type'], |
| Location.parse(m['location']), m['message'], m['code'], |
| correction: m['correction'], hasFix: m['hasFix']); |
| } |
| |
| /// The severity of the error. |
| final String severity; |
| |
| /// The type of the error. |
| final String type; |
| |
| /// The location associated with the error. |
| final Location location; |
| |
| /// The message to be displayed for this error. The message should indicate |
| /// what is wrong with the code and why it is wrong. |
| final String message; |
| |
| /// The name, as a string, of the error code associated with this error. |
| final String code; |
| |
| /// The correction message to be displayed for this error. The correction |
| /// message should indicate how the user can fix the error. The field is |
| /// omitted if there is no correction message associated with the error code. |
| @optional |
| final String correction; |
| |
| /// A hint to indicate to interested clients that this error has an associated |
| /// fix (or fixes). The absence of this field implies there are not known to |
| /// be fixes. Note that since the operation to calculate whether fixes apply |
| /// needs to be performant it is possible that complicated tests will be |
| /// skipped and a false negative returned. For this reason, this attribute |
| /// should be treated as a "hint". Despite the possibility of false negatives, |
| /// no false positives should be returned. If a client sees this flag set they |
| /// can proceed with the confidence that there are in fact associated fixes. |
| @optional |
| final bool hasFix; |
| |
| AnalysisError( |
| this.severity, this.type, this.location, this.message, this.code, |
| {this.correction, this.hasFix}); |
| |
| bool operator ==(o) => |
| o is AnalysisError && |
| severity == o.severity && |
| type == o.type && |
| location == o.location && |
| message == o.message && |
| code == o.code && |
| correction == o.correction && |
| hasFix == o.hasFix; |
| |
| int get hashCode => |
| severity.hashCode ^ |
| type.hashCode ^ |
| location.hashCode ^ |
| message.hashCode ^ |
| code.hashCode; |
| |
| String toString() => |
| '[AnalysisError severity: ${severity}, type: ${type}, location: ${location}, message: ${message}, code: ${code}]'; |
| } |
| |
| /// A list of fixes associated with a specific error. |
| class AnalysisErrorFixes { |
| static AnalysisErrorFixes parse(Map m) { |
| if (m == null) return null; |
| return new AnalysisErrorFixes( |
| AnalysisError.parse(m['error']), |
| m['fixes'] == null |
| ? null |
| : new List.from(m['fixes'].map((obj) => SourceChange.parse(obj)))); |
| } |
| |
| /// The error with which the fixes are associated. |
| final AnalysisError error; |
| |
| /// The fixes associated with the error. |
| final List<SourceChange> fixes; |
| |
| AnalysisErrorFixes(this.error, this.fixes); |
| } |
| |
| @deprecated |
| class AnalysisOptions implements Jsonable { |
| static AnalysisOptions parse(Map m) { |
| if (m == null) return null; |
| return new AnalysisOptions( |
| enableAsync: m['enableAsync'], |
| enableDeferredLoading: m['enableDeferredLoading'], |
| enableEnums: m['enableEnums'], |
| enableNullAwareOperators: m['enableNullAwareOperators'], |
| enableSuperMixins: m['enableSuperMixins'], |
| generateDart2jsHints: m['generateDart2jsHints'], |
| generateHints: m['generateHints'], |
| generateLints: m['generateLints']); |
| } |
| |
| /// **Deprecated:** this feature is always enabled. |
| /// |
| /// True if the client wants to enable support for the proposed async feature. |
| @deprecated |
| @optional |
| final bool enableAsync; |
| |
| /// **Deprecated:** this feature is always enabled. |
| /// |
| /// True if the client wants to enable support for the proposed deferred |
| /// loading feature. |
| @deprecated |
| @optional |
| final bool enableDeferredLoading; |
| |
| /// **Deprecated:** this feature is always enabled. |
| /// |
| /// True if the client wants to enable support for the proposed enum feature. |
| @deprecated |
| @optional |
| final bool enableEnums; |
| |
| /// **Deprecated:** this feature is always enabled. |
| /// |
| /// True if the client wants to enable support for the proposed "null aware |
| /// operators" feature. |
| @deprecated |
| @optional |
| final bool enableNullAwareOperators; |
| |
| /// True if the client wants to enable support for the proposed "less |
| /// restricted mixins" proposal (DEP 34). |
| @optional |
| final bool enableSuperMixins; |
| |
| /// True if hints that are specific to dart2js should be generated. This |
| /// option is ignored if generateHints is false. |
| @optional |
| final bool generateDart2jsHints; |
| |
| /// True if hints should be generated as part of generating errors and |
| /// warnings. |
| @optional |
| final bool generateHints; |
| |
| /// True if lints should be generated as part of generating errors and |
| /// warnings. |
| @optional |
| final bool generateLints; |
| |
| AnalysisOptions( |
| {this.enableAsync, |
| this.enableDeferredLoading, |
| this.enableEnums, |
| this.enableNullAwareOperators, |
| this.enableSuperMixins, |
| this.generateDart2jsHints, |
| this.generateHints, |
| this.generateLints}); |
| |
| Map toMap() => _stripNullValues({ |
| 'enableAsync': enableAsync, |
| 'enableDeferredLoading': enableDeferredLoading, |
| 'enableEnums': enableEnums, |
| 'enableNullAwareOperators': enableNullAwareOperators, |
| 'enableSuperMixins': enableSuperMixins, |
| 'generateDart2jsHints': generateDart2jsHints, |
| 'generateHints': generateHints, |
| 'generateLints': generateLints |
| }); |
| } |
| |
| /// An indication of the current state of analysis. |
| class AnalysisStatus { |
| static AnalysisStatus parse(Map m) { |
| if (m == null) return null; |
| return new AnalysisStatus(m['isAnalyzing'], |
| analysisTarget: m['analysisTarget']); |
| } |
| |
| /// True if analysis is currently being performed. |
| final bool isAnalyzing; |
| |
| /// The name of the current target of analysis. This field is omitted if |
| /// analyzing is false. |
| @optional |
| final String analysisTarget; |
| |
| AnalysisStatus(this.isAnalyzing, {this.analysisTarget}); |
| |
| String toString() => '[AnalysisStatus isAnalyzing: ${isAnalyzing}]'; |
| } |
| |
| /// A directive to modify an existing file content overlay. One or more ranges |
| /// of text are deleted from the old file content overlay and replaced with new |
| /// text. |
| /// |
| /// The edits are applied in the order in which they occur in the list. This |
| /// means that the offset of each edit must be correct under the assumption that |
| /// all previous edits have been applied. |
| /// |
| /// It is an error to use this overlay on a file that does not yet have a file |
| /// content overlay or that has had its overlay removed via |
| /// (RemoveContentOverlay)[#type_RemoveContentOverlay]. |
| /// |
| /// If any of the edits cannot be applied due to its offset or length being out |
| /// of range, an `INVALID_OVERLAY_CHANGE` error will be reported. |
| class ChangeContentOverlay extends ContentOverlayType implements Jsonable { |
| static ChangeContentOverlay parse(Map m) { |
| if (m == null) return null; |
| return new ChangeContentOverlay(m['edits'] == null |
| ? null |
| : new List.from(m['edits'].map((obj) => SourceEdit.parse(obj)))); |
| } |
| |
| /// The edits to be applied to the file. |
| final List<SourceEdit> edits; |
| |
| ChangeContentOverlay(this.edits) : super('change'); |
| |
| Map toMap() => _stripNullValues({'type': type, 'edits': edits}); |
| } |
| |
| /// A label that is associated with a range of code that may be useful to render |
| /// at the end of the range to aid code readability. For example, a constructor |
| /// call that spans multiple lines may result in a closing label to allow the |
| /// constructor type/name to be rendered alongside the closing parenthesis. |
| class ClosingLabel { |
| static ClosingLabel parse(Map m) { |
| if (m == null) return null; |
| return new ClosingLabel(m['offset'], m['length'], m['label']); |
| } |
| |
| /// The offset of the construct being labelled. |
| final int offset; |
| |
| /// The length of the whole construct to be labelled. |
| final int length; |
| |
| /// The label associated with this range that should be displayed to the user. |
| final String label; |
| |
| ClosingLabel(this.offset, this.length, this.label); |
| } |
| |
| /// A suggestion for how to complete partially entered text. Many of the fields |
| /// are optional, depending on the kind of element being suggested. |
| class CompletionSuggestion implements Jsonable { |
| static CompletionSuggestion parse(Map m) { |
| if (m == null) return null; |
| return new CompletionSuggestion( |
| m['kind'], |
| m['relevance'], |
| m['completion'], |
| m['selectionOffset'], |
| m['selectionLength'], |
| m['isDeprecated'], |
| m['isPotential'], |
| displayText: m['displayText'], |
| docSummary: m['docSummary'], |
| docComplete: m['docComplete'], |
| declaringType: m['declaringType'], |
| defaultArgumentListString: m['defaultArgumentListString'], |
| defaultArgumentListTextRanges: |
| m['defaultArgumentListTextRanges'] == null |
| ? null |
| : new List.from(m['defaultArgumentListTextRanges']), |
| element: Element.parse(m['element']), |
| returnType: m['returnType'], |
| parameterNames: m['parameterNames'] == null |
| ? null |
| : new List.from(m['parameterNames']), |
| parameterTypes: m['parameterTypes'] == null |
| ? null |
| : new List.from(m['parameterTypes']), |
| requiredParameterCount: m['requiredParameterCount'], |
| hasNamedParameters: m['hasNamedParameters'], |
| parameterName: m['parameterName'], |
| parameterType: m['parameterType'], |
| importUri: m['importUri']); |
| } |
| |
| /// The kind of element being suggested. |
| final String kind; |
| |
| /// The relevance of this completion suggestion where a higher number |
| /// indicates a higher relevance. |
| final int relevance; |
| |
| /// The identifier to be inserted if the suggestion is selected. If the |
| /// suggestion is for a method or function, the client might want to |
| /// additionally insert a template for the parameters. The information |
| /// required in order to do so is contained in other fields. |
| final String completion; |
| |
| /// The offset, relative to the beginning of the completion, of where the |
| /// selection should be placed after insertion. |
| final int selectionOffset; |
| |
| /// The number of characters that should be selected after insertion. |
| final int selectionLength; |
| |
| /// True if the suggested element is deprecated. |
| final bool isDeprecated; |
| |
| /// True if the element is not known to be valid for the target. This happens |
| /// if the type of the target is dynamic. |
| final bool isPotential; |
| |
| /// Text to be displayed in, for example, a completion pop-up. This field is |
| /// only defined if the displayed text should be different than the |
| /// completion. Otherwise it is omitted. |
| @optional |
| final String displayText; |
| |
| /// An abbreviated version of the Dartdoc associated with the element being |
| /// suggested. This field is omitted if there is no Dartdoc associated with |
| /// the element. |
| @optional |
| final String docSummary; |
| |
| /// The Dartdoc associated with the element being suggested. This field is |
| /// omitted if there is no Dartdoc associated with the element. |
| @optional |
| final String docComplete; |
| |
| /// The class that declares the element being suggested. This field is omitted |
| /// if the suggested element is not a member of a class. |
| @optional |
| final String declaringType; |
| |
| /// A default String for use in generating argument list source contents on |
| /// the client side. |
| @optional |
| final String defaultArgumentListString; |
| |
| /// Pairs of offsets and lengths describing 'defaultArgumentListString' text |
| /// ranges suitable for use by clients to set up linked edits of default |
| /// argument source contents. For example, given an argument list string 'x, |
| /// y', the corresponding text range [0, 1, 3, 1], indicates two text ranges |
| /// of length 1, starting at offsets 0 and 3. Clients can use these ranges to |
| /// treat the 'x' and 'y' values specially for linked edits. |
| @optional |
| final List<int> defaultArgumentListTextRanges; |
| |
| /// Information about the element reference being suggested. |
| @optional |
| final Element element; |
| |
| /// The return type of the getter, function or method or the type of the field |
| /// being suggested. This field is omitted if the suggested element is not a |
| /// getter, function or method. |
| @optional |
| final String returnType; |
| |
| /// The names of the parameters of the function or method being suggested. |
| /// This field is omitted if the suggested element is not a setter, function |
| /// or method. |
| @optional |
| final List<String> parameterNames; |
| |
| /// The types of the parameters of the function or method being suggested. |
| /// This field is omitted if the parameterNames field is omitted. |
| @optional |
| final List<String> parameterTypes; |
| |
| /// The number of required parameters for the function or method being |
| /// suggested. This field is omitted if the parameterNames field is omitted. |
| @optional |
| final int requiredParameterCount; |
| |
| /// True if the function or method being suggested has at least one named |
| /// parameter. This field is omitted if the parameterNames field is omitted. |
| @optional |
| final bool hasNamedParameters; |
| |
| /// The name of the optional parameter being suggested. This field is omitted |
| /// if the suggestion is not the addition of an optional argument within an |
| /// argument list. |
| @optional |
| final String parameterName; |
| |
| /// The type of the options parameter being suggested. This field is omitted |
| /// if the parameterName field is omitted. |
| @optional |
| final String parameterType; |
| |
| /// The import to be added if the suggestion is out of scope and needs an |
| /// import to be added to be in scope. |
| @optional |
| final String importUri; |
| |
| CompletionSuggestion( |
| this.kind, |
| this.relevance, |
| this.completion, |
| this.selectionOffset, |
| this.selectionLength, |
| this.isDeprecated, |
| this.isPotential, |
| {this.displayText, |
| this.docSummary, |
| this.docComplete, |
| this.declaringType, |
| this.defaultArgumentListString, |
| this.defaultArgumentListTextRanges, |
| this.element, |
| this.returnType, |
| this.parameterNames, |
| this.parameterTypes, |
| this.requiredParameterCount, |
| this.hasNamedParameters, |
| this.parameterName, |
| this.parameterType, |
| this.importUri}); |
| |
| Map toMap() => _stripNullValues({ |
| 'kind': kind, |
| 'relevance': relevance, |
| 'completion': completion, |
| 'selectionOffset': selectionOffset, |
| 'selectionLength': selectionLength, |
| 'isDeprecated': isDeprecated, |
| 'isPotential': isPotential, |
| 'displayText': displayText, |
| 'docSummary': docSummary, |
| 'docComplete': docComplete, |
| 'declaringType': declaringType, |
| 'defaultArgumentListString': defaultArgumentListString, |
| 'defaultArgumentListTextRanges': defaultArgumentListTextRanges, |
| 'element': element?.toMap(), |
| 'returnType': returnType, |
| 'parameterNames': parameterNames, |
| 'parameterTypes': parameterTypes, |
| 'requiredParameterCount': requiredParameterCount, |
| 'hasNamedParameters': hasNamedParameters, |
| 'parameterName': parameterName, |
| 'parameterType': parameterType, |
| 'importUri': importUri |
| }); |
| |
| String toString() => |
| '[CompletionSuggestion kind: ${kind}, relevance: ${relevance}, completion: ${completion}, selectionOffset: ${selectionOffset}, selectionLength: ${selectionLength}, isDeprecated: ${isDeprecated}, isPotential: ${isPotential}]'; |
| } |
| |
| /// Information about an analysis context. |
| class ContextData { |
| static ContextData parse(Map m) { |
| if (m == null) return null; |
| return new ContextData( |
| m['name'], |
| m['explicitFileCount'], |
| m['implicitFileCount'], |
| m['workItemQueueLength'], |
| m['cacheEntryExceptions'] == null |
| ? null |
| : new List.from(m['cacheEntryExceptions'])); |
| } |
| |
| /// The name of the context. |
| final String name; |
| |
| /// Explicitly analyzed files. |
| final int explicitFileCount; |
| |
| /// Implicitly analyzed files. |
| final int implicitFileCount; |
| |
| /// The number of work items in the queue. |
| final int workItemQueueLength; |
| |
| /// Exceptions associated with cache entries. |
| final List<String> cacheEntryExceptions; |
| |
| ContextData(this.name, this.explicitFileCount, this.implicitFileCount, |
| this.workItemQueueLength, this.cacheEntryExceptions); |
| } |
| |
| /// Information about an element (something that can be declared in code). |
| class Element implements Jsonable { |
| static Element parse(Map m) { |
| if (m == null) return null; |
| return new Element(m['kind'], m['name'], m['flags'], |
| location: Location.parse(m['location']), |
| parameters: m['parameters'], |
| returnType: m['returnType'], |
| typeParameters: m['typeParameters']); |
| } |
| |
| /// The kind of the element. |
| final String kind; |
| |
| /// The name of the element. This is typically used as the label in the |
| /// outline. |
| final String name; |
| |
| /// A bit-map containing the following flags: |
| final int flags; |
| |
| /// The location of the name in the declaration of the element. |
| @optional |
| final Location location; |
| |
| /// The parameter list for the element. If the element is not a method or |
| /// function this field will not be defined. If the element doesn't have |
| /// parameters (e.g. getter), this field will not be defined. If the element |
| /// has zero parameters, this field will have a value of "()". |
| @optional |
| final String parameters; |
| |
| /// The return type of the element. If the element is not a method or function |
| /// this field will not be defined. If the element does not have a declared |
| /// return type, this field will contain an empty string. |
| @optional |
| final String returnType; |
| |
| /// The type parameter list for the element. If the element doesn't have type |
| /// parameters, this field will not be defined. |
| @optional |
| final String typeParameters; |
| |
| Element(this.kind, this.name, this.flags, |
| {this.location, this.parameters, this.returnType, this.typeParameters}); |
| |
| Map toMap() => _stripNullValues({ |
| 'kind': kind, |
| 'name': name, |
| 'flags': flags, |
| 'location': location?.toMap(), |
| 'parameters': parameters, |
| 'returnType': returnType, |
| 'typeParameters': typeParameters |
| }); |
| |
| String toString() => |
| '[Element kind: ${kind}, name: ${name}, flags: ${flags}]'; |
| } |
| |
| /// A declaration - top-level (class, field, etc) or a class member (method, |
| /// field, etc). |
| class ElementDeclaration { |
| static ElementDeclaration parse(Map m) { |
| if (m == null) return null; |
| return new ElementDeclaration(m['name'], m['kind'], m['fileIndex'], |
| m['offset'], m['line'], m['column'], m['codeOffset'], m['codeLength'], |
| className: m['className'], parameters: m['parameters']); |
| } |
| |
| /// The name of the declaration. |
| final String name; |
| |
| /// The kind of the element that corresponds to the declaration. |
| final String kind; |
| |
| /// The index of the file (in the enclosing response). |
| final int fileIndex; |
| |
| /// The offset of the declaration name in the file. |
| final int offset; |
| |
| /// The one-based index of the line containing the declaration name. |
| final int line; |
| |
| /// The one-based index of the column containing the declaration name. |
| final int column; |
| |
| /// The offset of the first character of the declaration code in the file. |
| final int codeOffset; |
| |
| /// The length of the declaration code in the file. |
| final int codeLength; |
| |
| /// The name of the class enclosing this declaration. If the declaration is |
| /// not a class member, this field will be absent. |
| @optional |
| final String className; |
| |
| /// The parameter list for the element. If the element is not a method or |
| /// function this field will not be defined. If the element doesn't have |
| /// parameters (e.g. getter), this field will not be defined. If the element |
| /// has zero parameters, this field will have a value of "()". The value |
| /// should not be treated as exact presentation of parameters, it is just |
| /// approximation of parameters to give the user general idea. |
| @optional |
| final String parameters; |
| |
| ElementDeclaration(this.name, this.kind, this.fileIndex, this.offset, |
| this.line, this.column, this.codeOffset, this.codeLength, |
| {this.className, this.parameters}); |
| } |
| |
| /// A description of an executable file. |
| class ExecutableFile { |
| static ExecutableFile parse(Map m) { |
| if (m == null) return null; |
| return new ExecutableFile(m['file'], m['kind']); |
| } |
| |
| /// The path of the executable file. |
| final String file; |
| |
| /// The kind of the executable file. |
| final String kind; |
| |
| ExecutableFile(this.file, this.kind); |
| } |
| |
| /// An node in the Flutter specific outline structure of a file. |
| @experimental |
| class FlutterOutline { |
| static FlutterOutline parse(Map m) { |
| if (m == null) return null; |
| return new FlutterOutline( |
| m['kind'], m['offset'], m['length'], m['codeOffset'], m['codeLength'], |
| label: m['label'], |
| dartElement: Element.parse(m['dartElement']), |
| attributes: m['attributes'] == null |
| ? null |
| : new List.from(m['attributes'] |
| .map((obj) => FlutterOutlineAttribute.parse(obj))), |
| className: m['className'], |
| parentAssociationLabel: m['parentAssociationLabel'], |
| variableName: m['variableName'], |
| children: m['children'] == null |
| ? null |
| : new List.from( |
| m['children'].map((obj) => FlutterOutline.parse(obj))), |
| id: m['id'], |
| isWidgetClass: m['isWidgetClass'], |
| renderConstructor: m['renderConstructor'], |
| stateClassName: m['stateClassName'], |
| stateOffset: m['stateOffset'], |
| stateLength: m['stateLength']); |
| } |
| |
| /// The kind of the node. |
| final String kind; |
| |
| /// The offset of the first character of the element. This is different than |
| /// the offset in the Element, which is the offset of the name of the element. |
| /// It can be used, for example, to map locations in the file back to an |
| /// outline. |
| final int offset; |
| |
| /// The length of the element. |
| final int length; |
| |
| /// The offset of the first character of the element code, which is neither |
| /// documentation, nor annotation. |
| final int codeOffset; |
| |
| /// The length of the element code. |
| final int codeLength; |
| |
| /// The text label of the node children of the node. It is provided for any |
| /// FlutterOutlineKind.GENERIC node, where better information is not |
| /// available. |
| @optional |
| final String label; |
| |
| /// If this node is a Dart element, the description of it; omitted otherwise. |
| @optional |
| final Element dartElement; |
| |
| /// Additional attributes for this node, which might be interesting to display |
| /// on the client. These attributes are usually arguments for the instance |
| /// creation or the invocation that created the widget. |
| @optional |
| final List<FlutterOutlineAttribute> attributes; |
| |
| /// If the node creates a new class instance, or a reference to an instance, |
| /// this field has the name of the class. |
| @optional |
| final String className; |
| |
| /// A short text description how this node is associated with the parent node. |
| /// For example "appBar" or "body" in Scaffold. |
| @optional |
| final String parentAssociationLabel; |
| |
| /// If FlutterOutlineKind.VARIABLE, the name of the variable. |
| @optional |
| final String variableName; |
| |
| /// The children of the node. The field will be omitted if the node has no |
| /// children. |
| @optional |
| final List<FlutterOutline> children; |
| |
| /// If the node is a widget, and it is instrumented, the unique identifier of |
| /// this widget, that can be used to associate rendering information with this |
| /// node. |
| @optional |
| final int id; |
| |
| /// True if the node is a widget class, so it can potentially be rendered, |
| /// even if it does not yet have the rendering constructor. This field is |
| /// omitted if the node is not a widget class. |
| @optional |
| final bool isWidgetClass; |
| |
| /// If the node is a widget class that can be rendered for IDE, the name of |
| /// the constructor that should be used to instantiate the widget. Empty |
| /// string for default constructor. Absent if the node is not a widget class |
| /// that can be rendered. |
| @optional |
| final String renderConstructor; |
| |
| /// If the node is a StatefulWidget, and its state class is defined in the |
| /// same file, the name of the state class. |
| @optional |
| final String stateClassName; |
| |
| /// If the node is a StatefulWidget that can be rendered, and its state class |
| /// is defined in the same file, the offset of the state class code in the |
| /// file. |
| @optional |
| final int stateOffset; |
| |
| /// If the node is a StatefulWidget that can be rendered, and its state class |
| /// is defined in the same file, the length of the state class code in the |
| /// file. |
| @optional |
| final int stateLength; |
| |
| FlutterOutline( |
| this.kind, this.offset, this.length, this.codeOffset, this.codeLength, |
| {this.label, |
| this.dartElement, |
| this.attributes, |
| this.className, |
| this.parentAssociationLabel, |
| this.variableName, |
| this.children, |
| this.id, |
| this.isWidgetClass, |
| this.renderConstructor, |
| this.stateClassName, |
| this.stateOffset, |
| this.stateLength}); |
| } |
| |
| /// An attribute for a FlutterOutline. |
| @experimental |
| class FlutterOutlineAttribute { |
| static FlutterOutlineAttribute parse(Map m) { |
| if (m == null) return null; |
| return new FlutterOutlineAttribute(m['name'], m['label'], |
| literalValueBoolean: m['literalValueBoolean'], |
| literalValueInteger: m['literalValueInteger'], |
| literalValueString: m['literalValueString']); |
| } |
| |
| /// The name of the attribute. |
| final String name; |
| |
| /// The label of the attribute value, usually the Dart code. It might be quite |
| /// long, the client should abbreviate as needed. |
| final String label; |
| |
| /// The boolean literal value of the attribute. This field is absent if the |
| /// value is not a boolean literal. |
| @optional |
| final bool literalValueBoolean; |
| |
| /// The integer literal value of the attribute. This field is absent if the |
| /// value is not an integer literal. |
| @optional |
| final int literalValueInteger; |
| |
| /// The string literal value of the attribute. This field is absent if the |
| /// value is not a string literal. |
| @optional |
| final String literalValueString; |
| |
| FlutterOutlineAttribute(this.name, this.label, |
| {this.literalValueBoolean, |
| this.literalValueInteger, |
| this.literalValueString}); |
| } |
| |
| /// A description of a region that can be folded. |
| class FoldingRegion { |
| static FoldingRegion parse(Map m) { |
| if (m == null) return null; |
| return new FoldingRegion(m['kind'], m['offset'], m['length']); |
| } |
| |
| /// The kind of the region. |
| final String kind; |
| |
| /// The offset of the region to be folded. |
| final int offset; |
| |
| /// The length of the region to be folded. |
| final int length; |
| |
| FoldingRegion(this.kind, this.offset, this.length); |
| } |
| |
| /// A description of a region that could have special highlighting associated |
| /// with it. |
| class HighlightRegion { |
| static HighlightRegion parse(Map m) { |
| if (m == null) return null; |
| return new HighlightRegion(m['type'], m['offset'], m['length']); |
| } |
| |
| /// The type of highlight associated with the region. |
| final String type; |
| |
| /// The offset of the region to be highlighted. |
| final int offset; |
| |
| /// The length of the region to be highlighted. |
| final int length; |
| |
| HighlightRegion(this.type, this.offset, this.length); |
| } |
| |
| /// The hover information associated with a specific location. |
| class HoverInformation { |
| static HoverInformation parse(Map m) { |
| if (m == null) return null; |
| return new HoverInformation(m['offset'], m['length'], |
| containingLibraryPath: m['containingLibraryPath'], |
| containingLibraryName: m['containingLibraryName'], |
| containingClassDescription: m['containingClassDescription'], |
| dartdoc: m['dartdoc'], |
| elementDescription: m['elementDescription'], |
| elementKind: m['elementKind'], |
| isDeprecated: m['isDeprecated'], |
| parameter: m['parameter'], |
| propagatedType: m['propagatedType'], |
| staticType: m['staticType']); |
| } |
| |
| /// The offset of the range of characters that encompasses the cursor position |
| /// and has the same hover information as the cursor position. |
| final int offset; |
| |
| /// The length of the range of characters that encompasses the cursor position |
| /// and has the same hover information as the cursor position. |
| final int length; |
| |
| /// The path to the defining compilation unit of the library in which the |
| /// referenced element is declared. This data is omitted if there is no |
| /// referenced element, or if the element is declared inside an HTML file. |
| @optional |
| final String containingLibraryPath; |
| |
| /// The name of the library in which the referenced element is declared. This |
| /// data is omitted if there is no referenced element, or if the element is |
| /// declared inside an HTML file. |
| @optional |
| final String containingLibraryName; |
| |
| /// A human-readable description of the class declaring the element being |
| /// referenced. This data is omitted if there is no referenced element, or if |
| /// the element is not a class member. |
| @optional |
| final String containingClassDescription; |
| |
| /// The dartdoc associated with the referenced element. Other than the removal |
| /// of the comment delimiters, including leading asterisks in the case of a |
| /// block comment, the dartdoc is unprocessed markdown. This data is omitted |
| /// if there is no referenced element, or if the element has no dartdoc. |
| @optional |
| final String dartdoc; |
| |
| /// A human-readable description of the element being referenced. This data is |
| /// omitted if there is no referenced element. |
| @optional |
| final String elementDescription; |
| |
| /// A human-readable description of the kind of element being referenced (such |
| /// as "class" or "function type alias"). This data is omitted if there is no |
| /// referenced element. |
| @optional |
| final String elementKind; |
| |
| /// True if the referenced element is deprecated. |
| @optional |
| final bool isDeprecated; |
| |
| /// A human-readable description of the parameter corresponding to the |
| /// expression being hovered over. This data is omitted if the location is not |
| /// in an argument to a function. |
| @optional |
| final String parameter; |
| |
| /// The name of the propagated type of the expression. This data is omitted if |
| /// the location does not correspond to an expression or if there is no |
| /// propagated type information. |
| @optional |
| final String propagatedType; |
| |
| /// The name of the static type of the expression. This data is omitted if the |
| /// location does not correspond to an expression. |
| @optional |
| final String staticType; |
| |
| HoverInformation(this.offset, this.length, |
| {this.containingLibraryPath, |
| this.containingLibraryName, |
| this.containingClassDescription, |
| this.dartdoc, |
| this.elementDescription, |
| this.elementKind, |
| this.isDeprecated, |
| this.parameter, |
| this.propagatedType, |
| this.staticType}); |
| } |
| |
| /// A description of a class that is implemented or extended. |
| class ImplementedClass { |
| static ImplementedClass parse(Map m) { |
| if (m == null) return null; |
| return new ImplementedClass(m['offset'], m['length']); |
| } |
| |
| /// The offset of the name of the implemented class. |
| final int offset; |
| |
| /// The length of the name of the implemented class. |
| final int length; |
| |
| ImplementedClass(this.offset, this.length); |
| } |
| |
| /// A description of a class member that is implemented or overridden. |
| class ImplementedMember { |
| static ImplementedMember parse(Map m) { |
| if (m == null) return null; |
| return new ImplementedMember(m['offset'], m['length']); |
| } |
| |
| /// The offset of the name of the implemented member. |
| final int offset; |
| |
| /// The length of the name of the implemented member. |
| final int length; |
| |
| ImplementedMember(this.offset, this.length); |
| } |
| |
| /// A description of the elements that are referenced in a region of a file that |
| /// come from a single imported library. |
| class ImportedElements implements Jsonable { |
| static ImportedElements parse(Map m) { |
| if (m == null) return null; |
| return new ImportedElements(m['path'], m['prefix'], |
| m['elements'] == null ? null : new List.from(m['elements'])); |
| } |
| |
| /// The absolute and normalized path of the file containing the library. |
| final String path; |
| |
| /// The prefix that was used when importing the library into the original |
| /// source. |
| final String prefix; |
| |
| /// The names of the elements imported from the library. |
| final List<String> elements; |
| |
| ImportedElements(this.path, this.prefix, this.elements); |
| |
| Map toMap() => |
| _stripNullValues({'path': path, 'prefix': prefix, 'elements': elements}); |
| } |
| |
| /// This object matches the format and documentation of the Entry object |
| /// documented in the (Kythe Storage |
| /// Model)[https://kythe.io/docs/kythe-storage.html#_entry]. |
| class KytheEntry { |
| static KytheEntry parse(Map m) { |
| if (m == null) return null; |
| return new KytheEntry(KytheVName.parse(m['source']), m['fact'], |
| kind: m['kind'], |
| target: KytheVName.parse(m['target']), |
| value: m['value'] == null ? null : new List.from(m['value'])); |
| } |
| |
| /// The ticket of the source node. |
| final KytheVName source; |
| |
| /// A fact label. The schema defines which fact labels are meaningful. |
| final String fact; |
| |
| /// An edge label. The schema defines which labels are meaningful. |
| @optional |
| final String kind; |
| |
| /// The ticket of the target node. |
| @optional |
| final KytheVName target; |
| |
| /// The `String` value of the fact. |
| @optional |
| final List<int> value; |
| |
| KytheEntry(this.source, this.fact, {this.kind, this.target, this.value}); |
| } |
| |
| /// This object matches the format and documentation of the Vector-Name object |
| /// documented in the (Kythe Storage |
| /// Model)[https://kythe.io/docs/kythe-storage.html#_a_id_termvname_a_vector_name_strong_vname_strong]. |
| class KytheVName { |
| static KytheVName parse(Map m) { |
| if (m == null) return null; |
| return new KytheVName( |
| m['signature'], m['corpus'], m['root'], m['path'], m['language']); |
| } |
| |
| /// An opaque signature generated by the analyzer. |
| final String signature; |
| |
| /// The corpus of source code this `KytheVName` belongs to. Loosely, a corpus |
| /// is a collection of related files, such as the contents of a given source |
| /// repository. |
| final String corpus; |
| |
| /// A corpus-specific root label, typically a directory path or project |
| /// identifier, denoting a distinct subset of the corpus. This may also be |
| /// used to designate virtual collections like generated files. |
| final String root; |
| |
| /// A path-structured label describing the “location” of the named object |
| /// relative to the corpus and the root. |
| final String path; |
| |
| /// The language this name belongs to. |
| final String language; |
| |
| KytheVName(this.signature, this.corpus, this.root, this.path, this.language); |
| } |
| |
| /// A collection of positions that should be linked (edited simultaneously) for |
| /// the purposes of updating code after a source change. For example, if a set |
| /// of edits introduced a new variable name, the group would contain all of the |
| /// positions of the variable name so that if the client wanted to let the user |
| /// edit the variable name after the operation, all occurrences of the name |
| /// could be edited simultaneously. |
| class LinkedEditGroup { |
| static LinkedEditGroup parse(Map m) { |
| if (m == null) return null; |
| return new LinkedEditGroup( |
| m['positions'] == null |
| ? null |
| : new List.from(m['positions'].map((obj) => Position.parse(obj))), |
| m['length'], |
| m['suggestions'] == null |
| ? null |
| : new List.from(m['suggestions'] |
| .map((obj) => LinkedEditSuggestion.parse(obj)))); |
| } |
| |
| /// The positions of the regions that should be edited simultaneously. |
| final List<Position> positions; |
| |
| /// The length of the regions that should be edited simultaneously. |
| final int length; |
| |
| /// Pre-computed suggestions for what every region might want to be changed |
| /// to. |
| final List<LinkedEditSuggestion> suggestions; |
| |
| LinkedEditGroup(this.positions, this.length, this.suggestions); |
| |
| String toString() => |
| '[LinkedEditGroup positions: ${positions}, length: ${length}, suggestions: ${suggestions}]'; |
| } |
| |
| /// A suggestion of a value that could be used to replace all of the linked edit |
| /// regions in a (LinkedEditGroup)[#type_LinkedEditGroup]. |
| class LinkedEditSuggestion { |
| static LinkedEditSuggestion parse(Map m) { |
| if (m == null) return null; |
| return new LinkedEditSuggestion(m['value'], m['kind']); |
| } |
| |
| /// The value that could be used to replace all of the linked edit regions. |
| final String value; |
| |
| /// The kind of value being proposed. |
| final String kind; |
| |
| LinkedEditSuggestion(this.value, this.kind); |
| } |
| |
| /// A location (character range) within a file. |
| class Location implements Jsonable { |
| static Location parse(Map m) { |
| if (m == null) return null; |
| return new Location( |
| m['file'], m['offset'], m['length'], m['startLine'], m['startColumn']); |
| } |
| |
| /// The file containing the range. |
| final String file; |
| |
| /// The offset of the range. |
| final int offset; |
| |
| /// The length of the range. |
| final int length; |
| |
| /// The one-based index of the line containing the first character of the |
| /// range. |
| final int startLine; |
| |
| /// The one-based index of the column containing the first character of the |
| /// range. |
| final int startColumn; |
| |
| Location( |
| this.file, this.offset, this.length, this.startLine, this.startColumn); |
| |
| Map toMap() => _stripNullValues({ |
| 'file': file, |
| 'offset': offset, |
| 'length': length, |
| 'startLine': startLine, |
| 'startColumn': startColumn |
| }); |
| |
| bool operator ==(o) => |
| o is Location && |
| file == o.file && |
| offset == o.offset && |
| length == o.length && |
| startLine == o.startLine && |
| startColumn == o.startColumn; |
| |
| int get hashCode => |
| file.hashCode ^ |
| offset.hashCode ^ |
| length.hashCode ^ |
| startLine.hashCode ^ |
| startColumn.hashCode; |
| |
| String toString() => |
| '[Location file: ${file}, offset: ${offset}, length: ${length}, startLine: ${startLine}, startColumn: ${startColumn}]'; |
| } |
| |
| /// A description of a region from which the user can navigate to the |
| /// declaration of an element. |
| class NavigationRegion { |
| static NavigationRegion parse(Map m) { |
| if (m == null) return null; |
| return new NavigationRegion(m['offset'], m['length'], |
| m['targets'] == null ? null : new List.from(m['targets'])); |
| } |
| |
| /// The offset of the region from which the user can navigate. |
| final int offset; |
| |
| /// The length of the region from which the user can navigate. |
| final int length; |
| |
| /// The indexes of the targets (in the enclosing navigation response) to which |
| /// the given region is bound. By opening the target, clients can implement |
| /// one form of navigation. This list cannot be empty. |
| final List<int> targets; |
| |
| NavigationRegion(this.offset, this.length, this.targets); |
| |
| String toString() => |
| '[NavigationRegion offset: ${offset}, length: ${length}, targets: ${targets}]'; |
| } |
| |
| /// A description of a target to which the user can navigate. |
| class NavigationTarget { |
| static NavigationTarget parse(Map m) { |
| if (m == null) return null; |
| return new NavigationTarget(m['kind'], m['fileIndex'], m['offset'], |
| m['length'], m['startLine'], m['startColumn']); |
| } |
| |
| /// The kind of the element. |
| final String kind; |
| |
| /// The index of the file (in the enclosing navigation response) to navigate |
| /// to. |
| final int fileIndex; |
| |
| /// The offset of the region to which the user can navigate. |
| final int offset; |
| |
| /// The length of the region to which the user can navigate. |
| final int length; |
| |
| /// The one-based index of the line containing the first character of the |
| /// region. |
| final int startLine; |
| |
| /// The one-based index of the column containing the first character of the |
| /// region. |
| final int startColumn; |
| |
| NavigationTarget(this.kind, this.fileIndex, this.offset, this.length, |
| this.startLine, this.startColumn); |
| |
| String toString() => |
| '[NavigationTarget kind: ${kind}, fileIndex: ${fileIndex}, offset: ${offset}, length: ${length}, startLine: ${startLine}, startColumn: ${startColumn}]'; |
| } |
| |
| /// A description of the references to a single element within a single file. |
| class Occurrences { |
| static Occurrences parse(Map m) { |
| if (m == null) return null; |
| return new Occurrences(Element.parse(m['element']), |
| m['offsets'] == null ? null : new List.from(m['offsets']), m['length']); |
| } |
| |
| /// The element that was referenced. |
| final Element element; |
| |
| /// The offsets of the name of the referenced element within the file. |
| final List<int> offsets; |
| |
| /// The length of the name of the referenced element. |
| final int length; |
| |
| Occurrences(this.element, this.offsets, this.length); |
| } |
| |
| /// An node in the outline structure of a file. |
| class Outline { |
| static Outline parse(Map m) { |
| if (m == null) return null; |
| return new Outline(Element.parse(m['element']), m['offset'], m['length'], |
| children: m['children'] == null |
| ? null |
| : new List.from(m['children'].map((obj) => Outline.parse(obj)))); |
| } |
| |
| /// A description of the element represented by this node. |
| final Element element; |
| |
| /// The offset of the first character of the element. This is different than |
| /// the offset in the Element, which is the offset of the name of the element. |
| /// It can be used, for example, to map locations in the file back to an |
| /// outline. |
| final int offset; |
| |
| /// The length of the element. |
| final int length; |
| |
| /// The children of the node. The field will be omitted if the node has no |
| /// children. |
| @optional |
| final List<Outline> children; |
| |
| Outline(this.element, this.offset, this.length, {this.children}); |
| } |
| |
| /// A description of a member that is being overridden. |
| class OverriddenMember { |
| static OverriddenMember parse(Map m) { |
| if (m == null) return null; |
| return new OverriddenMember(Element.parse(m['element']), m['className']); |
| } |
| |
| /// The element that is being overridden. |
| final Element element; |
| |
| /// The name of the class in which the member is defined. |
| final String className; |
| |
| OverriddenMember(this.element, this.className); |
| } |
| |
| /// A description of a member that overrides an inherited member. |
| class Override { |
| static Override parse(Map m) { |
| if (m == null) return null; |
| return new Override(m['offset'], m['length'], |
| superclassMember: OverriddenMember.parse(m['superclassMember']), |
| interfaceMembers: m['interfaceMembers'] == null |
| ? null |
| : new List.from(m['interfaceMembers'] |
| .map((obj) => OverriddenMember.parse(obj)))); |
| } |
| |
| /// The offset of the name of the overriding member. |
| final int offset; |
| |
| /// The length of the name of the overriding member. |
| final int length; |
| |
| /// The member inherited from a superclass that is overridden by the |
| /// overriding member. The field is omitted if there is no superclass member, |
| /// in which case there must be at least one interface member. |
| @optional |
| final OverriddenMember superclassMember; |
| |
| /// The members inherited from interfaces that are overridden by the |
| /// overriding member. The field is omitted if there are no interface members, |
| /// in which case there must be a superclass member. |
| @optional |
| final List<OverriddenMember> interfaceMembers; |
| |
| Override(this.offset, this.length, |
| {this.superclassMember, this.interfaceMembers}); |
| } |
| |
| /// A position within a file. |
| class Position { |
| static Position parse(Map m) { |
| if (m == null) return null; |
| return new Position(m['file'], m['offset']); |
| } |
| |
| /// The file containing the position. |
| final String file; |
| |
| /// The offset of the position. |
| final int offset; |
| |
| Position(this.file, this.offset); |
| |
| String toString() => '[Position file: ${file}, offset: ${offset}]'; |
| } |
| |
| /// The description of a postfix completion template. |
| class PostfixTemplateDescriptor { |
| static PostfixTemplateDescriptor parse(Map m) { |
| if (m == null) return null; |
| return new PostfixTemplateDescriptor(m['name'], m['key'], m['example']); |
| } |
| |
| /// The template name, shown in the UI. |
| final String name; |
| |
| /// The unique template key, not shown in the UI. |
| final String key; |
| |
| /// A short example of the transformation performed when the template is |
| /// applied. |
| final String example; |
| |
| PostfixTemplateDescriptor(this.name, this.key, this.example); |
| } |
| |
| /// An indication of the current state of pub execution. |
| class PubStatus { |
| static PubStatus parse(Map m) { |
| if (m == null) return null; |
| return new PubStatus(m['isListingPackageDirs']); |
| } |
| |
| /// True if the server is currently running pub to produce a list of package |
| /// directories. |
| final bool isListingPackageDirs; |
| |
| PubStatus(this.isListingPackageDirs); |
| |
| String toString() => |
| '[PubStatus isListingPackageDirs: ${isListingPackageDirs}]'; |
| } |
| |
| /// A description of a parameter in a method refactoring. |
| class RefactoringMethodParameter { |
| static RefactoringMethodParameter parse(Map m) { |
| if (m == null) return null; |
| return new RefactoringMethodParameter(m['kind'], m['type'], m['name'], |
| id: m['id'], parameters: m['parameters']); |
| } |
| |
| /// The kind of the parameter. |
| final String kind; |
| |
| /// The type that should be given to the parameter, or the return type of the |
| /// parameter's function type. |
| final String type; |
| |
| /// The name that should be given to the parameter. |
| final String name; |
| |
| /// The unique identifier of the parameter. Clients may omit this field for |
| /// the parameters they want to add. |
| @optional |
| final String id; |
| |
| /// The parameter list of the parameter's function type. If the parameter is |
| /// not of a function type, this field will not be defined. If the function |
| /// type has zero parameters, this field will have a value of '()'. |
| @optional |
| final String parameters; |
| |
| RefactoringMethodParameter(this.kind, this.type, this.name, |
| {this.id, this.parameters}); |
| } |
| |
| /// A description of a problem related to a refactoring. |
| class RefactoringProblem { |
| static RefactoringProblem parse(Map m) { |
| if (m == null) return null; |
| return new RefactoringProblem(m['severity'], m['message'], |
| location: Location.parse(m['location'])); |
| } |
| |
| /// The severity of the problem being represented. |
| final String severity; |
| |
| /// A human-readable description of the problem being represented. |
| final String message; |
| |
| /// The location of the problem being represented. This field is omitted |
| /// unless there is a specific location associated with the problem (such as a |
| /// location where an element being renamed will be shadowed). |
| @optional |
| final Location location; |
| |
| RefactoringProblem(this.severity, this.message, {this.location}); |
| } |
| |
| /// A directive to remove an existing file content overlay. After processing |
| /// this directive, the file contents will once again be read from the file |
| /// system. |
| /// |
| /// If this directive is used on a file that doesn't currently have a content |
| /// overlay, it has no effect. |
| class RemoveContentOverlay extends ContentOverlayType implements Jsonable { |
| static RemoveContentOverlay parse(Map m) { |
| if (m == null) return null; |
| return new RemoveContentOverlay(); |
| } |
| |
| RemoveContentOverlay() : super('remove'); |
| |
| Map toMap() => _stripNullValues({'type': type}); |
| } |
| |
| /// A single result from a search request. |
| class SearchResult { |
| static SearchResult parse(Map m) { |
| if (m == null) return null; |
| return new SearchResult( |
| Location.parse(m['location']), |
| m['kind'], |
| m['isPotential'], |
| m['path'] == null |
| ? null |
| : new List.from(m['path'].map((obj) => Element.parse(obj)))); |
| } |
| |
| /// The location of the code that matched the search criteria. |
| final Location location; |
| |
| /// The kind of element that was found or the kind of reference that was |
| /// found. |
| final String kind; |
| |
| /// True if the result is a potential match but cannot be confirmed to be a |
| /// match. For example, if all references to a method m defined in some class |
| /// were requested, and a reference to a method m from an unknown class were |
| /// found, it would be marked as being a potential match. |
| final bool isPotential; |
| |
| /// The elements that contain the result, starting with the most immediately |
| /// enclosing ancestor and ending with the library. |
| final List<Element> path; |
| |
| SearchResult(this.location, this.kind, this.isPotential, this.path); |
| |
| String toString() => |
| '[SearchResult location: ${location}, kind: ${kind}, isPotential: ${isPotential}, path: ${path}]'; |
| } |
| |
| /// A description of a set of edits that implement a single conceptual change. |
| class SourceChange { |
| static SourceChange parse(Map m) { |
| if (m == null) return null; |
| return new SourceChange( |
| m['message'], |
| m['edits'] == null |
| ? null |
| : new List.from(m['edits'].map((obj) => SourceFileEdit.parse(obj))), |
| m['linkedEditGroups'] == null |
| ? null |
| : new List.from( |
| m['linkedEditGroups'].map((obj) => LinkedEditGroup.parse(obj))), |
| selection: Position.parse(m['selection']), |
| id: m['id']); |
| } |
| |
| /// A human-readable description of the change to be applied. |
| final String message; |
| |
| /// A list of the edits used to effect the change, grouped by file. |
| final List<SourceFileEdit> edits; |
| |
| /// A list of the linked editing groups used to customize the changes that |
| /// were made. |
| final List<LinkedEditGroup> linkedEditGroups; |
| |
| /// The position that should be selected after the edits have been applied. |
| @optional |
| final Position selection; |
| |
| /// The optional identifier of the change kind. The identifier remains stable |
| /// even if the message changes, or is parameterized. |
| @optional |
| final String id; |
| |
| SourceChange(this.message, this.edits, this.linkedEditGroups, |
| {this.selection, this.id}); |
| |
| String toString() => |
| '[SourceChange message: ${message}, edits: ${edits}, linkedEditGroups: ${linkedEditGroups}]'; |
| } |
| |
| /// A description of a single change to a single file. |
| class SourceEdit implements Jsonable { |
| static SourceEdit parse(Map m) { |
| if (m == null) return null; |
| return new SourceEdit(m['offset'], m['length'], m['replacement'], |
| id: m['id']); |
| } |
| |
| /// The offset of the region to be modified. |
| final int offset; |
| |
| /// The length of the region to be modified. |
| final int length; |
| |
| /// The code that is to replace the specified region in the original code. |
| final String replacement; |
| |
| /// An identifier that uniquely identifies this source edit from other edits |
| /// in the same response. This field is omitted unless a containing structure |
| /// needs to be able to identify the edit for some reason. |
| /// |
| /// For example, some refactoring operations can produce edits that might not |
| /// be appropriate (referred to as potential edits). Such edits will have an |
| /// id so that they can be referenced. Edits in the same response that do not |
| /// need to be referenced will not have an id. |
| @optional |
| final String id; |
| |
| SourceEdit(this.offset, this.length, this.replacement, {this.id}); |
| |
| Map toMap() => _stripNullValues({ |
| 'offset': offset, |
| 'length': length, |
| 'replacement': replacement, |
| 'id': id |
| }); |
| |
| String toString() => |
| '[SourceEdit offset: ${offset}, length: ${length}, replacement: ${replacement}]'; |
| } |
| |
| /// A description of a set of changes to a single file. |
| class SourceFileEdit { |
| static SourceFileEdit parse(Map m) { |
| if (m == null) return null; |
| return new SourceFileEdit( |
| m['file'], |
| m['fileStamp'], |
| m['edits'] == null |
| ? null |
| : new List.from(m['edits'].map((obj) => SourceEdit.parse(obj)))); |
| } |
| |
| /// The file containing the code to be modified. |
| final String file; |
| |
| /// The modification stamp of the file at the moment when the change was |
| /// created, in milliseconds since the "Unix epoch". Will be -1 if the file |
| /// did not exist and should be created. The client may use this field to make |
| /// sure that the file was not changed since then, so it is safe to apply the |
| /// change. |
| @deprecated |
| final int fileStamp; |
| |
| /// A list of the edits used to effect the change. |
| final List<SourceEdit> edits; |
| |
| SourceFileEdit(this.file, this.fileStamp, this.edits); |
| |
| String toString() => '[SourceFileEdit file: ${file}, edits: ${edits}]'; |
| } |
| |
| /// A representation of a class in a type hierarchy. |
| class TypeHierarchyItem { |
| static TypeHierarchyItem parse(Map m) { |
| if (m == null) return null; |
| return new TypeHierarchyItem( |
| Element.parse(m['classElement']), |
| m['interfaces'] == null ? null : new List.from(m['interfaces']), |
| m['mixins'] == null ? null : new List.from(m['mixins']), |
| m['subclasses'] == null ? null : new List.from(m['subclasses']), |
| displayName: m['displayName'], |
| memberElement: Element.parse(m['memberElement']), |
| superclass: m['superclass']); |
| } |
| |
| /// The class element represented by this item. |
| final Element classElement; |
| |
| /// The indexes of the items representing the interfaces implemented by this |
| /// class. The list will be empty if there are no implemented interfaces. |
| final List<int> interfaces; |
| |
| /// The indexes of the items representing the mixins referenced by this class. |
| /// The list will be empty if there are no classes mixed in to this class. |
| final List<int> mixins; |
| |
| /// The indexes of the items representing the subtypes of this class. The list |
| /// will be empty if there are no subtypes or if this item represents a |
| /// supertype of the pivot type. |
| final List<int> subclasses; |
| |
| /// The name to be displayed for the class. This field will be omitted if the |
| /// display name is the same as the name of the element. The display name is |
| /// different if there is additional type information to be displayed, such as |
| /// type arguments. |
| @optional |
| final String displayName; |
| |
| /// The member in the class corresponding to the member on which the hierarchy |
| /// was requested. This field will be omitted if the hierarchy was not |
| /// requested for a member or if the class does not have a corresponding |
| /// member. |
| @optional |
| final Element memberElement; |
| |
| /// The index of the item representing the superclass of this class. This |
| /// field will be omitted if this item represents the class Object. |
| @optional |
| final int superclass; |
| |
| TypeHierarchyItem( |
| this.classElement, this.interfaces, this.mixins, this.subclasses, |
| {this.displayName, this.memberElement, this.superclass}); |
| } |
| |
| // refactorings |
| |
| class Refactorings { |
| static const String CONVERT_GETTER_TO_METHOD = 'CONVERT_GETTER_TO_METHOD'; |
| static const String CONVERT_METHOD_TO_GETTER = 'CONVERT_METHOD_TO_GETTER'; |
| static const String EXTRACT_LOCAL_VARIABLE = 'EXTRACT_LOCAL_VARIABLE'; |
| static const String EXTRACT_METHOD = 'EXTRACT_METHOD'; |
| static const String EXTRACT_WIDGET = 'EXTRACT_WIDGET'; |
| static const String INLINE_LOCAL_VARIABLE = 'INLINE_LOCAL_VARIABLE'; |
| static const String INLINE_METHOD = 'INLINE_METHOD'; |
| static const String MOVE_FILE = 'MOVE_FILE'; |
| static const String RENAME = 'RENAME'; |
| } |
| |
| /// Create a local variable initialized by the expression that covers the |
| /// specified selection. |
| /// |
| /// It is an error if the selection range is not covered by a complete |
| /// expression. |
| class ExtractLocalVariableRefactoringOptions extends RefactoringOptions { |
| /// The name that the local variable should be given. |
| final String name; |
| |
| /// True if all occurrences of the expression within the scope in which the |
| /// variable will be defined should be replaced by a reference to the local |
| /// variable. The expression used to initiate the refactoring will always be |
| /// replaced. |
| final bool extractAll; |
| |
| ExtractLocalVariableRefactoringOptions({this.name, this.extractAll}); |
| |
| Map toMap() => _stripNullValues({'name': name, 'extractAll': extractAll}); |
| } |
| |
| /// Create a method whose body is the specified expression or list of |
| /// statements, possibly augmented with a return statement. |
| /// |
| /// It is an error if the range contains anything other than a complete |
| /// expression (no partial expressions are allowed) or a complete sequence of |
| /// statements. |
| class ExtractMethodRefactoringOptions extends RefactoringOptions { |
| /// The return type that should be defined for the method. |
| final String returnType; |
| |
| /// True if a getter should be created rather than a method. It is an error if |
| /// this field is true and the list of parameters is non-empty. |
| final bool createGetter; |
| |
| /// The name that the method should be given. |
| final String name; |
| |
| /// The parameters that should be defined for the method. |
| /// |
| /// It is an error if a REQUIRED or NAMED parameter follows a POSITIONAL |
| /// parameter. It is an error if a REQUIRED or POSITIONAL parameter follows a |
| /// NAMED parameter. |
| final List<RefactoringMethodParameter> parameters; |
| |
| /// True if all occurrences of the expression or statements should be replaced |
| /// by an invocation of the method. The expression or statements used to |
| /// initiate the refactoring will always be replaced. |
| final bool extractAll; |
| |
| ExtractMethodRefactoringOptions( |
| {this.returnType, |
| this.createGetter, |
| this.name, |
| this.parameters, |
| this.extractAll}); |
| |
| Map toMap() => _stripNullValues({ |
| 'returnType': returnType, |
| 'createGetter': createGetter, |
| 'name': name, |
| 'parameters': parameters, |
| 'extractAll': extractAll |
| }); |
| } |
| |
| /// Create a new class that extends StatelessWidget, whose build() method is the |
| /// widget creation expression, or a method returning a Flutter widget, at the |
| /// specified offset. |
| class ExtractWidgetRefactoringOptions extends RefactoringOptions { |
| /// The name that the widget class should be given. |
| final String name; |
| |
| ExtractWidgetRefactoringOptions({this.name}); |
| |
| Map toMap() => _stripNullValues({'name': name}); |
| } |
| |
| /// Inline a method in place of one or all references to that method. |
| /// |
| /// It is an error if the range contains anything other than all or part of the |
| /// name of a single method. |
| class InlineMethodRefactoringOptions extends RefactoringOptions { |
| /// True if the method being inlined should be removed. It is an error if this |
| /// field is true and inlineAll is false. |
| final bool deleteSource; |
| |
| /// True if all invocations of the method should be inlined, or false if only |
| /// the invocation site used to create this refactoring should be inlined. |
| final bool inlineAll; |
| |
| InlineMethodRefactoringOptions({this.deleteSource, this.inlineAll}); |
| |
| Map toMap() => |
| _stripNullValues({'deleteSource': deleteSource, 'inlineAll': inlineAll}); |
| } |
| |
| /// Move the given file and update all of the references to that file and from |
| /// it. The move operation is supported in general case - for renaming a file in |
| /// the same folder, moving it to a different folder or both. |
| /// |
| /// The refactoring must be activated before an actual file moving operation is |
| /// performed. |
| /// |
| /// The "offset" and "length" fields from the request are ignored, but the file |
| /// specified in the request specifies the file to be moved. |
| class MoveFileRefactoringOptions extends RefactoringOptions { |
| /// The new file path to which the given file is being moved. |
| final String newFile; |
| |
| MoveFileRefactoringOptions({this.newFile}); |
| |
| Map toMap() => _stripNullValues({'newFile': newFile}); |
| } |
| |
| /// Rename a given element and all of the references to that element. |
| /// |
| /// It is an error if the range contains anything other than all or part of the |
| /// name of a single function (including methods, getters and setters), variable |
| /// (including fields, parameters and local variables), class or function type. |
| class RenameRefactoringOptions extends RefactoringOptions { |
| /// The name that the element should have after the refactoring. |
| final String newName; |
| |
| RenameRefactoringOptions({this.newName}); |
| |
| Map toMap() => _stripNullValues({'newName': newName}); |
| } |
| |
| abstract class RefactoringFeedback { |
| static RefactoringFeedback parse(String kind, Map m) { |
| if (m == null) return null; |
| |
| switch (kind) { |
| case Refactorings.EXTRACT_LOCAL_VARIABLE: |
| return ExtractLocalVariableFeedback.parse(m); |
| case Refactorings.EXTRACT_METHOD: |
| return ExtractMethodFeedback.parse(m); |
| case Refactorings.INLINE_LOCAL_VARIABLE: |
| return InlineLocalVariableFeedback.parse(m); |
| case Refactorings.INLINE_METHOD: |
| return InlineMethodFeedback.parse(m); |
| case Refactorings.RENAME: |
| return RenameFeedback.parse(m); |
| } |
| |
| return null; |
| } |
| } |
| |
| /// Feedback class for the `EXTRACT_LOCAL_VARIABLE` refactoring. |
| class ExtractLocalVariableFeedback extends RefactoringFeedback { |
| static ExtractLocalVariableFeedback parse(Map m) => |
| new ExtractLocalVariableFeedback( |
| m['names'] == null ? null : new List.from(m['names']), |
| m['offsets'] == null ? null : new List.from(m['offsets']), |
| m['lengths'] == null ? null : new List.from(m['lengths']), |
| coveringExpressionOffsets: m['coveringExpressionOffsets'] == null |
| ? null |
| : new List.from(m['coveringExpressionOffsets']), |
| coveringExpressionLengths: m['coveringExpressionLengths'] == null |
| ? null |
| : new List.from(m['coveringExpressionLengths'])); |
| |
| /// The proposed names for the local variable. |
| final List<String> names; |
| |
| /// The offsets of the expressions that would be replaced by a reference to |
| /// the variable. |
| final List<int> offsets; |
| |
| /// The lengths of the expressions that would be replaced by a reference to |
| /// the variable. The lengths correspond to the offsets. In other words, for a |
| /// given expression, if the offset of that expression is `offsets[i]`, then |
| /// the length of that expression is `lengths[i]`. |
| final List<int> lengths; |
| |
| /// The offsets of the expressions that cover the specified selection, from |
| /// the down most to the up most. |
| @optional |
| final List<int> coveringExpressionOffsets; |
| |
| /// The lengths of the expressions that cover the specified selection, from |
| /// the down most to the up most. |
| @optional |
| final List<int> coveringExpressionLengths; |
| |
| ExtractLocalVariableFeedback(this.names, this.offsets, this.lengths, |
| {this.coveringExpressionOffsets, this.coveringExpressionLengths}); |
| } |
| |
| /// Feedback class for the `EXTRACT_METHOD` refactoring. |
| class ExtractMethodFeedback extends RefactoringFeedback { |
| static ExtractMethodFeedback parse(Map m) => new ExtractMethodFeedback( |
| m['offset'], |
| m['length'], |
| m['returnType'], |
| m['names'] == null ? null : new List.from(m['names']), |
| m['canCreateGetter'], |
| m['parameters'] == null |
| ? null |
| : new List.from(m['parameters'] |
| .map((obj) => RefactoringMethodParameter.parse(obj))), |
| m['offsets'] == null ? null : new List.from(m['offsets']), |
| m['lengths'] == null ? null : new List.from(m['lengths'])); |
| |
| /// The offset to the beginning of the expression or statements that will be |
| /// extracted. |
| final int offset; |
| |
| /// The length of the expression or statements that will be extracted. |
| final int length; |
| |
| /// The proposed return type for the method. If the returned element does not |
| /// have a declared return type, this field will contain an empty string. |
| final String returnType; |
| |
| /// The proposed names for the method. |
| final List<String> names; |
| |
| /// True if a getter could be created rather than a method. |
| final bool canCreateGetter; |
| |
| /// The proposed parameters for the method. |
| final List<RefactoringMethodParameter> parameters; |
| |
| /// The offsets of the expressions or statements that would be replaced by an |
| /// invocation of the method. |
| final List<int> offsets; |
| |
| /// The lengths of the expressions or statements that would be replaced by an |
| /// invocation of the method. The lengths correspond to the offsets. In other |
| /// words, for a given expression (or block of statements), if the offset of |
| /// that expression is `offsets[i]`, then the length of that expression is |
| /// `lengths[i]`. |
| final List<int> lengths; |
| |
| ExtractMethodFeedback(this.offset, this.length, this.returnType, this.names, |
| this.canCreateGetter, this.parameters, this.offsets, this.lengths); |
| } |
| |
| /// Feedback class for the `INLINE_LOCAL_VARIABLE` refactoring. |
| class InlineLocalVariableFeedback extends RefactoringFeedback { |
| static InlineLocalVariableFeedback parse(Map m) => |
| new InlineLocalVariableFeedback(m['name'], m['occurrences']); |
| |
| /// The name of the variable being inlined. |
| final String name; |
| |
| /// The number of times the variable occurs. |
| final int occurrences; |
| |
| InlineLocalVariableFeedback(this.name, this.occurrences); |
| } |
| |
| /// Feedback class for the `INLINE_METHOD` refactoring. |
| class InlineMethodFeedback extends RefactoringFeedback { |
| static InlineMethodFeedback parse(Map m) => |
| new InlineMethodFeedback(m['methodName'], m['isDeclaration'], |
| className: m['className']); |
| |
| /// The name of the method (or function) being inlined. |
| final String methodName; |
| |
| /// True if the declaration of the method is selected. So all references |
| /// should be inlined. |
| final bool isDeclaration; |
| |
| /// The name of the class enclosing the method being inlined. If not a class |
| /// member is being inlined, this field will be absent. |
| @optional |
| final String className; |
| |
| InlineMethodFeedback(this.methodName, this.isDeclaration, {this.className}); |
| } |
| |
| /// Feedback class for the `RENAME` refactoring. |
| class RenameFeedback extends RefactoringFeedback { |
| static RenameFeedback parse(Map m) => new RenameFeedback( |
| m['offset'], m['length'], m['elementKindName'], m['oldName']); |
| |
| /// The offset to the beginning of the name selected to be renamed, or -1 if |
| /// the name does not exist yet. |
| final int offset; |
| |
| /// The length of the name selected to be renamed. |
| final int length; |
| |
| /// The human-readable description of the kind of element being renamed (such |
| /// as "class" or "function type alias"). |
| final String elementKindName; |
| |
| /// The old name of the element before the refactoring. |
| final String oldName; |
| |
| RenameFeedback(this.offset, this.length, this.elementKindName, this.oldName); |
| } |