blob: 836d98e3c6a7c63ccafb877e89104b896c74ddb7 [file] [log] [blame]
// 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:analysis_server_lib/analysis_server_lib.dart';
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() {
Map<String, dynamic> 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) {
Map<String, String> newMap = <String, String>{};
for (var 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]);
}
/// 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';
}
String pre = '${target.substring(0, offset)}';
String 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;
VersionResponse(
{this.sdkVersion,
this.sdkVersionFull,
this.runtimeVersion,
this.appEngineVersion,
this.servicesVersion});
}