mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
Initial draft of a custom LSP protocol for refactoring
Change-Id: Ib7a6b6bd0b2e0dccd8e7b6c117dc284b0e5a95cd Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/253361 Commit-Queue: Brian Wilkerson <brianwilkerson@google.com> Reviewed-by: Phil Quitslund <pquitslund@google.com> Reviewed-by: Danny Tuppeny <danny@tuppeny.com>
This commit is contained in:
parent
106c4a5e1c
commit
023c6df3b4
|
@ -136,6 +136,130 @@ class ClosingLabel implements ToJsonable {
|
|||
String toString() => jsonEncoder.convert(toJson());
|
||||
}
|
||||
|
||||
/// Information about one of the arguments needed by the command.
|
||||
///
|
||||
/// A list of parameters is sent in the `data` field of the `CodeAction`
|
||||
/// returned by the server. The values of the parameters should appear in the
|
||||
/// `args` field of the `Command` sent to the server in the same order as the
|
||||
/// corresponding parameters.
|
||||
class CommandParameter implements ToJsonable {
|
||||
static const jsonHandler = LspJsonHandler(
|
||||
CommandParameter.canParse,
|
||||
CommandParameter.fromJson,
|
||||
);
|
||||
|
||||
CommandParameter({
|
||||
required this.defaultValue,
|
||||
required this.label,
|
||||
required this.type,
|
||||
});
|
||||
static CommandParameter fromJson(Map<String, Object?> json) {
|
||||
final defaultValueJson = json['defaultValue'];
|
||||
final defaultValue = defaultValueJson as String;
|
||||
final labelJson = json['label'];
|
||||
final label = labelJson as String;
|
||||
final typeJson = json['type'];
|
||||
final type = CommandParameterType.fromJson(typeJson as String);
|
||||
return CommandParameter(
|
||||
defaultValue: defaultValue,
|
||||
label: label,
|
||||
type: type,
|
||||
);
|
||||
}
|
||||
|
||||
/// The default value for the parameter.
|
||||
final String defaultValue;
|
||||
|
||||
/// A human-readable label to be displayed in the UI affordance used to prompt
|
||||
/// the user for the value of the parameter.
|
||||
final String label;
|
||||
|
||||
/// The type of the value of the parameter.
|
||||
final CommandParameterType type;
|
||||
|
||||
@override
|
||||
Map<String, Object?> toJson() {
|
||||
var result = <String, Object?>{};
|
||||
result['defaultValue'] = defaultValue;
|
||||
result['label'] = label;
|
||||
result['type'] = type.toJson();
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool canParse(Object? obj, LspJsonReporter reporter) {
|
||||
if (obj is Map<String, Object?>) {
|
||||
if (!_canParseString(obj, reporter, 'defaultValue',
|
||||
allowsUndefined: false, allowsNull: false)) {
|
||||
return false;
|
||||
}
|
||||
if (!_canParseString(obj, reporter, 'label',
|
||||
allowsUndefined: false, allowsNull: false)) {
|
||||
return false;
|
||||
}
|
||||
return _canParseCommandParameterType(obj, reporter, 'type',
|
||||
allowsUndefined: false, allowsNull: false);
|
||||
} else {
|
||||
reporter.reportError('must be of type CommandParameter');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is CommandParameter &&
|
||||
other.runtimeType == CommandParameter &&
|
||||
defaultValue == other.defaultValue &&
|
||||
label == other.label &&
|
||||
type == other.type;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
defaultValue,
|
||||
label,
|
||||
type,
|
||||
);
|
||||
|
||||
@override
|
||||
String toString() => jsonEncoder.convert(toJson());
|
||||
}
|
||||
|
||||
/// The type of the value associated with a CommandParameter. All values are
|
||||
/// encoded as strings, but the type indicates how the string will be decoded by
|
||||
/// the server.
|
||||
class CommandParameterType implements ToJsonable {
|
||||
const CommandParameterType(this._value);
|
||||
const CommandParameterType.fromJson(this._value);
|
||||
|
||||
final String _value;
|
||||
|
||||
static bool canParse(Object? obj, LspJsonReporter reporter) => obj is String;
|
||||
|
||||
/// The type associated with a bool value.
|
||||
///
|
||||
/// The value must either be `'true'` or `'false'`.
|
||||
static const boolean = CommandParameterType('boolean');
|
||||
|
||||
/// The type associated with a value representing a path to a file.
|
||||
static const filePath = CommandParameterType('filePath');
|
||||
|
||||
/// The type associated with a string value.
|
||||
static const string = CommandParameterType('string');
|
||||
|
||||
@override
|
||||
Object toJson() => _value;
|
||||
|
||||
@override
|
||||
String toString() => _value.toString();
|
||||
|
||||
@override
|
||||
int get hashCode => _value.hashCode;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
other is CommandParameterType && other._value == _value;
|
||||
}
|
||||
|
||||
class CompletionItemResolutionInfo implements ToJsonable {
|
||||
static const jsonHandler = LspJsonHandler(
|
||||
CompletionItemResolutionInfo.canParse,
|
||||
|
@ -1811,6 +1935,32 @@ bool _canParseBool(
|
|||
return true;
|
||||
}
|
||||
|
||||
bool _canParseCommandParameterType(
|
||||
Map<String, Object?> map, LspJsonReporter reporter, String fieldName,
|
||||
{required bool allowsUndefined, required bool allowsNull}) {
|
||||
reporter.push(fieldName);
|
||||
try {
|
||||
if (!allowsUndefined && !map.containsKey(fieldName)) {
|
||||
reporter.reportError('must not be undefined');
|
||||
return false;
|
||||
}
|
||||
final value = map[fieldName];
|
||||
final nullCheck = allowsNull || allowsUndefined;
|
||||
if (!nullCheck && value == null) {
|
||||
reporter.reportError('must not be null');
|
||||
return false;
|
||||
}
|
||||
if ((!nullCheck || value != null) &&
|
||||
!CommandParameterType.canParse(value, reporter)) {
|
||||
reporter.reportError('must be of type CommandParameterType');
|
||||
return false;
|
||||
}
|
||||
} finally {
|
||||
reporter.pop();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool _canParseElement(
|
||||
Map<String, Object?> map, LspJsonReporter reporter, String fieldName,
|
||||
{required bool allowsUndefined, required bool allowsNull}) {
|
||||
|
|
|
@ -306,7 +306,7 @@ typedef TextDocumentSignatureHelpResult = SignatureHelp?;
|
|||
|
||||
/// Result for a request to resolve the type definition locations of a symbol at
|
||||
/// a given text document position. The request's parameter is of type
|
||||
/// TextDocumentPositionParams the response is of type Definition or a Thenable
|
||||
/// TextDocumentPositioParams the response is of type Definition or a Thenable
|
||||
/// that resolves to such.
|
||||
typedef TextDocumentTypeDefinitionResult
|
||||
= Either2<Definition, List<DefinitionLink>>?;
|
||||
|
@ -21955,7 +21955,7 @@ class PreviousResultId implements ToJsonable {
|
|||
);
|
||||
}
|
||||
|
||||
/// The URI for which the client knows a result id.
|
||||
/// The URI for which the client knowns a result id.
|
||||
final DocumentUri uri;
|
||||
|
||||
/// The value of the previous result id.
|
||||
|
|
|
@ -111,9 +111,11 @@ const jsonEncoder = JsonEncoder.withIndent(' ');
|
|||
|
||||
List<LspEntity> getCustomClasses() {
|
||||
/// Helper to create an interface type.
|
||||
Interface interface(String name, List<Member> fields, {String? baseType}) {
|
||||
Interface interface(String name, List<Member> fields,
|
||||
{String? baseType, String? comment}) {
|
||||
return Interface(
|
||||
name: name,
|
||||
comment: comment,
|
||||
baseTypes: [if (baseType != null) TypeReference(baseType)],
|
||||
members: fields,
|
||||
);
|
||||
|
@ -353,7 +355,68 @@ List<LspEntity> getCustomClasses() {
|
|||
]),
|
||||
),
|
||||
isRename: false,
|
||||
)
|
||||
),
|
||||
//
|
||||
// Command parameter support
|
||||
//
|
||||
interface(
|
||||
'CommandParameter',
|
||||
[
|
||||
field(
|
||||
'label',
|
||||
type: 'String',
|
||||
comment:
|
||||
'A human-readable label to be displayed in the UI affordance '
|
||||
'used to prompt the user for the value of the parameter.',
|
||||
),
|
||||
field(
|
||||
'type',
|
||||
type: 'CommandParameterType',
|
||||
comment: 'The type of the value of the parameter.',
|
||||
),
|
||||
field(
|
||||
'defaultValue',
|
||||
type: 'String',
|
||||
comment: 'The default value for the parameter.',
|
||||
),
|
||||
],
|
||||
comment: 'Information about one of the arguments needed by the command.'
|
||||
'\n\n'
|
||||
'A list of parameters is sent in the `data` field of the '
|
||||
'`CodeAction` returned by the server. The values of the parameters '
|
||||
'should appear in the `args` field of the `Command` sent to the '
|
||||
'server in the same order as the corresponding parameters.',
|
||||
),
|
||||
LspEnum(
|
||||
name: 'CommandParameterType',
|
||||
comment: 'The type of the value associated with a CommandParameter. All '
|
||||
'values are encoded as strings, but the type indicates how the '
|
||||
'string will be decoded by the server.',
|
||||
members: [
|
||||
Constant(
|
||||
name: 'boolean',
|
||||
value: 'boolean',
|
||||
type: TypeReference('String'),
|
||||
comment: 'The type associated with a bool value.'
|
||||
'\n\n'
|
||||
"The value must either be `'true'` or `'false'`.",
|
||||
),
|
||||
Constant(
|
||||
name: 'string',
|
||||
value: 'string',
|
||||
type: TypeReference('String'),
|
||||
comment: 'The type associated with a string value.',
|
||||
),
|
||||
Constant(
|
||||
name: 'filePath',
|
||||
value: 'filePath',
|
||||
type: TypeReference('String'),
|
||||
comment:
|
||||
'The type associated with a value representing a path to a file.',
|
||||
),
|
||||
],
|
||||
typeOfValues: TypeReference('String'),
|
||||
),
|
||||
];
|
||||
return customTypes;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue