| // Copyright (c) 2015, 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. |
| |
| /// All classes exported over the RPC protocol. |
| library services.api_classes; |
| |
| import 'dart:convert'; |
| |
| import 'package:rpc/rpc.dart'; |
| |
| class AnalysisResults { |
| final List<AnalysisIssue> issues; |
| |
| @ApiProperty(description: 'The package imports parsed from the source.') |
| final List<String> packageImports; |
| |
| AnalysisResults(this.issues, this.packageImports); |
| } |
| |
| class AnalysisIssue implements Comparable<AnalysisIssue> { |
| final String kind; |
| final int line; |
| final String message; |
| final String sourceName; |
| |
| final bool hasFixes; |
| |
| final int charStart; |
| final int charLength; |
| |
| AnalysisIssue.fromIssue(this.kind, this.line, this.message, |
| {this.charStart, |
| this.charLength, |
| this.sourceName, |
| this.hasFixes = false}); |
| |
| Map<String, dynamic> toMap() { |
| final m = <String, dynamic>{'kind': kind, 'line': line, 'message': message}; |
| if (charStart != null) m['charStart'] = charStart; |
| if (charLength != null) m['charLength'] = charLength; |
| if (hasFixes != null) m['hasFixes'] = hasFixes; |
| if (sourceName != null) m['sourceName'] = sourceName; |
| |
| return m; |
| } |
| |
| @override |
| int compareTo(AnalysisIssue other) => line - other.line; |
| |
| @override |
| String toString() => '$kind: $message [$line]'; |
| } |
| |
| class SourceRequest { |
| @ApiProperty(required: true, description: 'The Dart source.') |
| String source; |
| |
| @ApiProperty(description: 'An optional offset into the source code.') |
| int offset; |
| } |
| |
| class SourcesRequest { |
| @ApiProperty(required: true, description: 'Map of names to Sources.') |
| Map<String, String> sources; |
| |
| @ApiProperty(description: 'An optional location in the source code.') |
| Location location; |
| |
| @ApiProperty(description: 'Ignored: always treated as true.') |
| @deprecated |
| bool strongMode; |
| } |
| |
| class Location { |
| String sourceName; |
| int offset; |
| |
| Location(); |
| |
| Location.from(this.sourceName, this.offset); |
| } |
| |
| class CompileRequest { |
| @ApiProperty(required: true, description: 'The Dart source.') |
| String source; |
| |
| @ApiProperty( |
| description: |
| 'Return the Dart to JS source map; optional (defaults to false).') |
| bool returnSourceMap; |
| } |
| |
| class CompileResponse { |
| final String result; |
| final String sourceMap; |
| |
| CompileResponse(this.result, [this.sourceMap]); |
| } |
| |
| class CompileDDCRequest { |
| @ApiProperty(required: true, description: 'The Dart source.') |
| String source; |
| } |
| |
| class CompileDDCResponse { |
| final String result; |
| final String modulesBaseUrl; |
| |
| CompileDDCResponse(this.result, this.modulesBaseUrl); |
| } |
| |
| class CounterRequest { |
| @ApiProperty(required: true) |
| String name; |
| } |
| |
| class CounterResponse { |
| final int count; |
| |
| CounterResponse(this.count); |
| } |
| |
| class DocumentResponse { |
| final Map<String, String> info; |
| |
| DocumentResponse(this.info); |
| } |
| |
| class CompleteResponse { |
| @ApiProperty( |
| description: 'The offset of the start of the text to be replaced.') |
| final int replacementOffset; |
| |
| @ApiProperty(description: 'The length of the text to be replaced.') |
| final int replacementLength; |
| |
| final List<Map<String, String>> completions; |
| |
| CompleteResponse(this.replacementOffset, this.replacementLength, |
| List<Map<dynamic, dynamic>> completions) |
| : completions = _convert(completions); |
| |
| /// Convert any non-string values from the contained maps. |
| static List<Map<String, String>> _convert(List<Map<dynamic, dynamic>> list) { |
| return list.map<Map<String, String>>((Map<dynamic, dynamic> m) { |
| final newMap = <String, String>{}; |
| for (final key in m.keys.cast<String>()) { |
| dynamic data = m[key]; |
| // TODO: Properly support Lists, Maps (this is a hack). |
| if (data is Map || data is List) { |
| data = json.encode(data); |
| } |
| newMap[key.toString()] = '$data'; |
| } |
| return newMap; |
| }).toList(); |
| } |
| } |
| |
| class FixesResponse { |
| final List<ProblemAndFixes> fixes; |
| |
| FixesResponse(this.fixes); |
| } |
| |
| /// Represents a problem detected during analysis, and a set of possible |
| /// ways of resolving the problem. |
| class ProblemAndFixes { |
| // TODO(lukechurch): consider consolidating this with [AnalysisIssue] |
| final List<CandidateFix> fixes; |
| final String problemMessage; |
| final int offset; |
| final int length; |
| |
| ProblemAndFixes() : this.fromList(<CandidateFix>[]); |
| |
| ProblemAndFixes.fromList( |
| [this.fixes, this.problemMessage, this.offset, this.length]); |
| } |
| |
| class LinkedEditSuggestion { |
| @ApiProperty( |
| description: 'The value that could be used to replace all of the linked ' |
| 'edit regions.') |
| final String value; |
| |
| @ApiProperty(description: 'The kind of value being proposed.') |
| final String kind; |
| |
| LinkedEditSuggestion(this.value, this.kind); |
| } |
| |
| class LinkedEditGroup { |
| @ApiProperty( |
| description: 'The positions of the regions that should be edited ' |
| 'simultaneously.') |
| final List<int> positions; |
| |
| @ApiProperty( |
| description: 'The length of the regions that should be edited ' |
| 'simultaneously.') |
| final int length; |
| |
| @ApiProperty( |
| description: 'Pre-computed suggestions for what every region might want ' |
| 'to be changed to.') |
| final List<LinkedEditSuggestion> suggestions; |
| |
| LinkedEditGroup(this.positions, this.length, this.suggestions); |
| } |
| |
| /// Represents a possible way of solving an Analysis Problem. |
| class CandidateFix { |
| final String message; |
| final List<SourceEdit> edits; |
| final int selectionOffset; |
| final List<LinkedEditGroup> linkedEditGroups; |
| |
| CandidateFix() : this.fromEdits(); |
| |
| CandidateFix.fromEdits([ |
| this.message, |
| this.edits, |
| this.selectionOffset, |
| this.linkedEditGroups, |
| ]); |
| } |
| |
| /// Represents a reformatting of the code. |
| class FormatResponse { |
| @ApiProperty(description: 'The formatted source code.') |
| final String newString; |
| |
| @ApiProperty( |
| description: 'The (optional) new offset of the cursor; can be `null`.') |
| final int offset; |
| |
| FormatResponse(this.newString, [this.offset = 0]); |
| } |
| |
| /// Represents a single edit-point change to a source file. |
| class SourceEdit { |
| final int offset; |
| final int length; |
| final String replacement; |
| |
| SourceEdit() : this.fromChanges(); |
| |
| SourceEdit.fromChanges([this.offset, this.length, this.replacement]); |
| |
| String applyTo(String target) { |
| if (offset >= replacement.length) { |
| throw 'Offset beyond end of string'; |
| } else if (offset + length >= replacement.length) { |
| throw 'Change beyond end of string'; |
| } |
| |
| final pre = '${target.substring(0, offset)}'; |
| final post = '${target.substring(offset + length)}'; |
| return '$pre$replacement$post'; |
| } |
| } |
| |
| /// The response from the `/assists` service call. |
| class AssistsResponse { |
| final List<CandidateFix> assists; |
| |
| AssistsResponse(this.assists); |
| } |
| |
| /// The response from the `/version` service call. |
| class VersionResponse { |
| @ApiProperty( |
| description: 'The Dart SDK version that DartServices is compatible with. ' |
| 'This will be a semver string.') |
| final String sdkVersion; |
| |
| @ApiProperty( |
| description: |
| 'The full Dart SDK version that DartServices is compatible with.') |
| final String sdkVersionFull; |
| |
| @ApiProperty( |
| description: 'The Dart SDK version that the server is running on. This ' |
| 'will start with a semver string, and have a space and other build ' |
| 'details appended.') |
| final String runtimeVersion; |
| |
| @ApiProperty(description: 'The App Engine version.') |
| final String appEngineVersion; |
| |
| @ApiProperty(description: 'The dart-services backend version.') |
| final String servicesVersion; |
| |
| @ApiProperty(description: 'The Flutter SDK version.') |
| final String flutterVersion; |
| |
| @ApiProperty(description: "The Flutter SDK's Dart version.") |
| final String flutterDartVersion; |
| |
| @ApiProperty(description: "The Flutter SDK's full Dart version.") |
| final String flutterDartVersionFull; |
| |
| VersionResponse( |
| {this.sdkVersion, |
| this.sdkVersionFull, |
| this.runtimeVersion, |
| this.appEngineVersion, |
| this.servicesVersion, |
| this.flutterDartVersion, |
| this.flutterDartVersionFull, |
| this.flutterVersion}); |
| } |