| // Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'dart:convert'; |
| |
| import 'package:json_rpc_2/json_rpc_2.dart' show RpcException; |
| |
| import '../constants.dart'; |
| import '../dart_tooling_daemon.dart'; |
| |
| import '../response_types/response_types.dart'; |
| import '../rpc_error_codes.dart' show RpcErrorCodes; |
| |
| extension FileSystemService on DartToolingDaemon { |
| /// Reads the file at [uri] from disk in the environment where the Dart |
| /// Tooling Daemon is running. |
| /// |
| /// If [uri] is not contained in the IDE workspace roots, then an |
| /// [RpcException] with [RpcErrorCodes.kPermissionDenied] is thrown. |
| /// |
| /// If [uri] does not exist, then an [RpcException] exception with error |
| /// code [RpcErrorCodes.kFileDoesNotExist] is thrown. |
| /// |
| /// If [uri] does not have a file scheme, then an [RpcException] with |
| /// [RpcErrorCodes.kExpectsUriParamWithFileScheme] is thrown. |
| Future<FileContent> readFileAsString( |
| Uri uri, { |
| Encoding encoding = utf8, |
| }) async { |
| final result = await call( |
| FileSystemServiceConstants.serviceName, |
| FileSystemServiceConstants.readFileAsString, |
| params: { |
| DtdParameters.uri: uri.toString(), |
| DtdParameters.encoding: encoding.name, |
| }, |
| ); |
| return FileContent.fromDTDResponse(result); |
| } |
| |
| /// Writes [contents] to the file at [uri] in the environment where the Dart |
| /// Tooling Daemon is running. |
| /// |
| /// The file will be created if it does not exist, and it will be overwritten |
| /// if it already exist. |
| /// |
| /// If [uri] is not contained in the IDE workspace roots, then an |
| /// [RpcException] with [RpcErrorCodes.kPermissionDenied] is thrown. |
| /// |
| /// If [uri] does not have a file scheme, then an [RpcException] with |
| /// [RpcErrorCodes.kExpectsUriParamWithFileScheme] is thrown. |
| Future<void> writeFileAsString( |
| Uri uri, |
| String contents, { |
| Encoding encoding = utf8, |
| }) async { |
| await call( |
| FileSystemServiceConstants.serviceName, |
| FileSystemServiceConstants.writeFileAsString, |
| params: { |
| DtdParameters.uri: uri.toString(), |
| DtdParameters.contents: contents, |
| DtdParameters.encoding: encoding.name, |
| }, |
| ); |
| } |
| |
| /// Lists the directories and files under the directory at [uri] in the |
| /// environment where the Dart Tooling Daemon is running. |
| /// |
| /// If [uri] is not a directory, throws an [RpcException] exception with error |
| /// code [RpcErrorCodes.kDirectoryDoesNotExist]. |
| /// |
| /// If [uri] is not contained in the IDE workspace roots, then an |
| /// [RpcException] with [RpcErrorCodes.kPermissionDenied] is thrown. |
| /// |
| /// If [uri] does not have a file scheme, then an [RpcException] with |
| /// [RpcErrorCodes.kExpectsUriParamWithFileScheme] is thrown. |
| /// |
| /// The returned uris will be `file://` Uris. |
| Future<UriList> listDirectoryContents(Uri uri) async { |
| final result = await call( |
| FileSystemServiceConstants.serviceName, |
| FileSystemServiceConstants.listDirectoryContents, |
| params: { |
| DtdParameters.uri: uri.toString(), |
| }, |
| ); |
| return UriList.fromDTDResponse(result); |
| } |
| |
| /// Sets the IDE workspace roots for the FileSystem service. |
| /// |
| /// This is a privileged RPC that require's a [secret], which is provided by |
| /// the Dart Tooling Daemon, to be called successfully. This secret is |
| /// generated by the daemon and provided to its spawner to ensure only trusted |
| /// clients can set workspace roots. If [secret] is invalid, an [RpcException] |
| /// with error code [RpcErrorCodes.kPermissionDenied] is thrown. |
| /// |
| /// If [secret] does not match the secret created when Dart Tooling Daemon was |
| /// created, then an [RpcException] with [RpcErrorCodes.kPermissionDenied] is |
| /// thrown. |
| /// |
| /// If one of the [roots] is missing a "file" scheme then an [RpcException] |
| /// with [RpcErrorCodes.kExpectsUriParamWithFileScheme] is thrown. |
| Future<void> setIDEWorkspaceRoots(String secret, List<Uri> roots) async { |
| await call( |
| FileSystemServiceConstants.serviceName, |
| FileSystemServiceConstants.setIDEWorkspaceRoots, |
| params: { |
| DtdParameters.roots: roots.map<String>((e) => e.toString()).toList(), |
| DtdParameters.secret: secret, |
| }, |
| ); |
| } |
| |
| /// Gets the IDE workspace roots for the FileSystem service. |
| /// |
| /// The returned uris will be `file://` Uris. |
| Future<IDEWorkspaceRoots> getIDEWorkspaceRoots() async { |
| final result = await call( |
| FileSystemServiceConstants.serviceName, |
| FileSystemServiceConstants.getIDEWorkspaceRoots, |
| ); |
| return IDEWorkspaceRoots.fromDTDResponse(result); |
| } |
| |
| /// Gets the project roots contained within the current set of IDE workspace |
| /// roots. |
| /// |
| /// A project root is any directory that contains a 'pubspec.yaml' file. If |
| /// IDE workspace roots are not set, or if there are no project roots within |
| /// the IDE workspace roots, this method will return an empty [UriList]. |
| /// |
| /// [depth] is the maximum depth that each IDE workspace root directory tree |
| /// will be searched for project roots. |
| /// |
| /// The returned uris will be `file://` Uris. |
| Future<UriList> getProjectRoots({ |
| int depth = defaultGetProjectRootsDepth, |
| }) async { |
| final result = await call( |
| FileSystemServiceConstants.serviceName, |
| FileSystemServiceConstants.getProjectRoots, |
| params: {DtdParameters.depth: depth}, |
| ); |
| return UriList.fromDTDResponse(result); |
| } |
| } |