Switch all generated LSP classes to use named constructor arguments

Change-Id: I111b58fa5d04314247d5f92650491cdeef6bd4a3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/153841
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Danny Tuppeny <danny@tuppeny.com>
This commit is contained in:
Danny Tuppeny 2020-07-09 17:18:07 +00:00 committed by commit-bot@chromium.org
parent 6db0396c83
commit c4a2efd6e7
51 changed files with 1880 additions and 1318 deletions

View file

@ -22,6 +22,7 @@ import 'package:analysis_server/src/lsp/json_parsing.dart';
import 'package:analysis_server/src/protocol/protocol_internal.dart' import 'package:analysis_server/src/protocol/protocol_internal.dart'
show listEqual, mapEqual; show listEqual, mapEqual;
import 'package:analyzer/src/generated/utilities_general.dart'; import 'package:analyzer/src/generated/utilities_general.dart';
import 'package:meta/meta.dart';
const jsonEncoder = JsonEncoder.withIndent(' '); const jsonEncoder = JsonEncoder.withIndent(' ');
@ -29,14 +30,14 @@ class AnalyzerStatusParams implements ToJsonable {
static const jsonHandler = LspJsonHandler( static const jsonHandler = LspJsonHandler(
AnalyzerStatusParams.canParse, AnalyzerStatusParams.fromJson); AnalyzerStatusParams.canParse, AnalyzerStatusParams.fromJson);
AnalyzerStatusParams(this.isAnalyzing) { AnalyzerStatusParams({@required this.isAnalyzing}) {
if (isAnalyzing == null) { if (isAnalyzing == null) {
throw 'isAnalyzing is required but was not provided'; throw 'isAnalyzing is required but was not provided';
} }
} }
static AnalyzerStatusParams fromJson(Map<String, dynamic> json) { static AnalyzerStatusParams fromJson(Map<String, dynamic> json) {
final isAnalyzing = json['isAnalyzing']; final isAnalyzing = json['isAnalyzing'];
return AnalyzerStatusParams(isAnalyzing); return AnalyzerStatusParams(isAnalyzing: isAnalyzing);
} }
final bool isAnalyzing; final bool isAnalyzing;
@ -98,7 +99,7 @@ class ClosingLabel implements ToJsonable {
static const jsonHandler = static const jsonHandler =
LspJsonHandler(ClosingLabel.canParse, ClosingLabel.fromJson); LspJsonHandler(ClosingLabel.canParse, ClosingLabel.fromJson);
ClosingLabel(this.range, this.label) { ClosingLabel({@required this.range, @required this.label}) {
if (range == null) { if (range == null) {
throw 'range is required but was not provided'; throw 'range is required but was not provided';
} }
@ -109,7 +110,7 @@ class ClosingLabel implements ToJsonable {
static ClosingLabel fromJson(Map<String, dynamic> json) { static ClosingLabel fromJson(Map<String, dynamic> json) {
final range = json['range'] != null ? Range.fromJson(json['range']) : null; final range = json['range'] != null ? Range.fromJson(json['range']) : null;
final label = json['label']; final label = json['label'];
return ClosingLabel(range, label); return ClosingLabel(range: range, label: label);
} }
final String label; final String label;
@ -190,8 +191,13 @@ class CompletionItemResolutionInfo implements ToJsonable {
CompletionItemResolutionInfo.canParse, CompletionItemResolutionInfo.canParse,
CompletionItemResolutionInfo.fromJson); CompletionItemResolutionInfo.fromJson);
CompletionItemResolutionInfo(this.file, this.offset, this.libId, CompletionItemResolutionInfo(
this.displayUri, this.rOffset, this.rLength) { {@required this.file,
@required this.offset,
@required this.libId,
@required this.displayUri,
@required this.rOffset,
@required this.rLength}) {
if (file == null) { if (file == null) {
throw 'file is required but was not provided'; throw 'file is required but was not provided';
} }
@ -219,7 +225,12 @@ class CompletionItemResolutionInfo implements ToJsonable {
final rOffset = json['rOffset']; final rOffset = json['rOffset'];
final rLength = json['rLength']; final rLength = json['rLength'];
return CompletionItemResolutionInfo( return CompletionItemResolutionInfo(
file, offset, libId, displayUri, rOffset, rLength); file: file,
offset: offset,
libId: libId,
displayUri: displayUri,
rOffset: rOffset,
rLength: rLength);
} }
final String displayUri; final String displayUri;
@ -389,14 +400,14 @@ class DartDiagnosticServer implements ToJsonable {
static const jsonHandler = LspJsonHandler( static const jsonHandler = LspJsonHandler(
DartDiagnosticServer.canParse, DartDiagnosticServer.fromJson); DartDiagnosticServer.canParse, DartDiagnosticServer.fromJson);
DartDiagnosticServer(this.port) { DartDiagnosticServer({@required this.port}) {
if (port == null) { if (port == null) {
throw 'port is required but was not provided'; throw 'port is required but was not provided';
} }
} }
static DartDiagnosticServer fromJson(Map<String, dynamic> json) { static DartDiagnosticServer fromJson(Map<String, dynamic> json) {
final port = json['port']; final port = json['port'];
return DartDiagnosticServer(port); return DartDiagnosticServer(port: port);
} }
final num port; final num port;
@ -456,8 +467,13 @@ class DartDiagnosticServer implements ToJsonable {
class Element implements ToJsonable { class Element implements ToJsonable {
static const jsonHandler = LspJsonHandler(Element.canParse, Element.fromJson); static const jsonHandler = LspJsonHandler(Element.canParse, Element.fromJson);
Element(this.range, this.name, this.kind, this.parameters, Element(
this.typeParameters, this.returnType) { {this.range,
@required this.name,
@required this.kind,
this.parameters,
this.typeParameters,
this.returnType}) {
if (name == null) { if (name == null) {
throw 'name is required but was not provided'; throw 'name is required but was not provided';
} }
@ -472,7 +488,13 @@ class Element implements ToJsonable {
final parameters = json['parameters']; final parameters = json['parameters'];
final typeParameters = json['typeParameters']; final typeParameters = json['typeParameters'];
final returnType = json['returnType']; final returnType = json['returnType'];
return Element(range, name, kind, parameters, typeParameters, returnType); return Element(
range: range,
name: name,
kind: kind,
parameters: parameters,
typeParameters: typeParameters,
returnType: returnType);
} }
final String kind; final String kind;
@ -616,15 +638,15 @@ class FlutterOutline implements ToJsonable {
LspJsonHandler(FlutterOutline.canParse, FlutterOutline.fromJson); LspJsonHandler(FlutterOutline.canParse, FlutterOutline.fromJson);
FlutterOutline( FlutterOutline(
this.kind, {@required this.kind,
this.label, this.label,
this.className, this.className,
this.variableName, this.variableName,
this.attributes, this.attributes,
this.dartElement, this.dartElement,
this.range, @required this.range,
this.codeRange, @required this.codeRange,
this.children) { this.children}) {
if (kind == null) { if (kind == null) {
throw 'kind is required but was not provided'; throw 'kind is required but was not provided';
} }
@ -655,8 +677,16 @@ class FlutterOutline implements ToJsonable {
?.map((item) => item != null ? FlutterOutline.fromJson(item) : null) ?.map((item) => item != null ? FlutterOutline.fromJson(item) : null)
?.cast<FlutterOutline>() ?.cast<FlutterOutline>()
?.toList(); ?.toList();
return FlutterOutline(kind, label, className, variableName, attributes, return FlutterOutline(
dartElement, range, codeRange, children); kind: kind,
label: label,
className: className,
variableName: variableName,
attributes: attributes,
dartElement: dartElement,
range: range,
codeRange: codeRange,
children: children);
} }
final List<FlutterOutlineAttribute> attributes; final List<FlutterOutlineAttribute> attributes;
@ -862,7 +892,8 @@ class FlutterOutlineAttribute implements ToJsonable {
static const jsonHandler = LspJsonHandler( static const jsonHandler = LspJsonHandler(
FlutterOutlineAttribute.canParse, FlutterOutlineAttribute.fromJson); FlutterOutlineAttribute.canParse, FlutterOutlineAttribute.fromJson);
FlutterOutlineAttribute(this.name, this.label, this.valueRange) { FlutterOutlineAttribute(
{@required this.name, @required this.label, this.valueRange}) {
if (name == null) { if (name == null) {
throw 'name is required but was not provided'; throw 'name is required but was not provided';
} }
@ -875,7 +906,8 @@ class FlutterOutlineAttribute implements ToJsonable {
final label = json['label']; final label = json['label'];
final valueRange = final valueRange =
json['valueRange'] != null ? Range.fromJson(json['valueRange']) : null; json['valueRange'] != null ? Range.fromJson(json['valueRange']) : null;
return FlutterOutlineAttribute(name, label, valueRange); return FlutterOutlineAttribute(
name: name, label: label, valueRange: valueRange);
} }
final String label; final String label;
@ -973,7 +1005,11 @@ class FlutterOutlineAttribute implements ToJsonable {
class Outline implements ToJsonable { class Outline implements ToJsonable {
static const jsonHandler = LspJsonHandler(Outline.canParse, Outline.fromJson); static const jsonHandler = LspJsonHandler(Outline.canParse, Outline.fromJson);
Outline(this.element, this.range, this.codeRange, this.children) { Outline(
{@required this.element,
@required this.range,
@required this.codeRange,
this.children}) {
if (element == null) { if (element == null) {
throw 'element is required but was not provided'; throw 'element is required but was not provided';
} }
@ -994,7 +1030,11 @@ class Outline implements ToJsonable {
?.map((item) => item != null ? Outline.fromJson(item) : null) ?.map((item) => item != null ? Outline.fromJson(item) : null)
?.cast<Outline>() ?.cast<Outline>()
?.toList(); ?.toList();
return Outline(element, range, codeRange, children); return Outline(
element: element,
range: range,
codeRange: codeRange,
children: children);
} }
final List<Outline> children; final List<Outline> children;
@ -1118,7 +1158,7 @@ class PublishClosingLabelsParams implements ToJsonable {
static const jsonHandler = LspJsonHandler( static const jsonHandler = LspJsonHandler(
PublishClosingLabelsParams.canParse, PublishClosingLabelsParams.fromJson); PublishClosingLabelsParams.canParse, PublishClosingLabelsParams.fromJson);
PublishClosingLabelsParams(this.uri, this.labels) { PublishClosingLabelsParams({@required this.uri, @required this.labels}) {
if (uri == null) { if (uri == null) {
throw 'uri is required but was not provided'; throw 'uri is required but was not provided';
} }
@ -1132,7 +1172,7 @@ class PublishClosingLabelsParams implements ToJsonable {
?.map((item) => item != null ? ClosingLabel.fromJson(item) : null) ?.map((item) => item != null ? ClosingLabel.fromJson(item) : null)
?.cast<ClosingLabel>() ?.cast<ClosingLabel>()
?.toList(); ?.toList();
return PublishClosingLabelsParams(uri, labels); return PublishClosingLabelsParams(uri: uri, labels: labels);
} }
final List<ClosingLabel> labels; final List<ClosingLabel> labels;
@ -1219,7 +1259,7 @@ class PublishFlutterOutlineParams implements ToJsonable {
PublishFlutterOutlineParams.canParse, PublishFlutterOutlineParams.canParse,
PublishFlutterOutlineParams.fromJson); PublishFlutterOutlineParams.fromJson);
PublishFlutterOutlineParams(this.uri, this.outline) { PublishFlutterOutlineParams({@required this.uri, @required this.outline}) {
if (uri == null) { if (uri == null) {
throw 'uri is required but was not provided'; throw 'uri is required but was not provided';
} }
@ -1232,7 +1272,7 @@ class PublishFlutterOutlineParams implements ToJsonable {
final outline = json['outline'] != null final outline = json['outline'] != null
? FlutterOutline.fromJson(json['outline']) ? FlutterOutline.fromJson(json['outline'])
: null; : null;
return PublishFlutterOutlineParams(uri, outline); return PublishFlutterOutlineParams(uri: uri, outline: outline);
} }
final FlutterOutline outline; final FlutterOutline outline;
@ -1314,7 +1354,7 @@ class PublishOutlineParams implements ToJsonable {
static const jsonHandler = LspJsonHandler( static const jsonHandler = LspJsonHandler(
PublishOutlineParams.canParse, PublishOutlineParams.fromJson); PublishOutlineParams.canParse, PublishOutlineParams.fromJson);
PublishOutlineParams(this.uri, this.outline) { PublishOutlineParams({@required this.uri, @required this.outline}) {
if (uri == null) { if (uri == null) {
throw 'uri is required but was not provided'; throw 'uri is required but was not provided';
} }
@ -1326,7 +1366,7 @@ class PublishOutlineParams implements ToJsonable {
final uri = json['uri']; final uri = json['uri'];
final outline = final outline =
json['outline'] != null ? Outline.fromJson(json['outline']) : null; json['outline'] != null ? Outline.fromJson(json['outline']) : null;
return PublishOutlineParams(uri, outline); return PublishOutlineParams(uri: uri, outline: outline);
} }
final Outline outline; final Outline outline;

File diff suppressed because it is too large Load diff

View file

@ -17,7 +17,7 @@ ErrorOr<R> cancelled<R>([R t]) =>
error(ErrorCodes.RequestCancelled, 'Request was cancelled', null); error(ErrorCodes.RequestCancelled, 'Request was cancelled', null);
ErrorOr<R> error<R>(ErrorCodes code, String message, [String data]) => ErrorOr<R> error<R>(ErrorCodes code, String message, [String data]) =>
ErrorOr<R>.error(ResponseError(code, message, data)); ErrorOr<R>.error(ResponseError(code: code, message: message, data: data));
ErrorOr<R> failure<R>(ErrorOr<dynamic> error) => ErrorOr<R>.error(error.error); ErrorOr<R> failure<R>(ErrorOr<dynamic> error) => ErrorOr<R>.error(error.error);

View file

@ -119,10 +119,9 @@ class LspByteStreamServerChannel implements LspServerCommunicationChannel {
void _sendParseError() { void _sendParseError() {
final error = ResponseMessage( final error = ResponseMessage(
null, error: ResponseError(
null, code: ErrorCodes.ParseError, message: 'Unable to parse message'),
ResponseError(ErrorCodes.ParseError, 'Unable to parse message', null), jsonrpc: jsonRpcVersion);
jsonRpcVersion);
sendResponse(error); sendResponse(error);
} }

View file

@ -21,9 +21,9 @@ class OrganizeImportsCommandHandler extends SimpleEditCommandHandler {
Future<ErrorOr<void>> handle(List<dynamic> arguments) async { Future<ErrorOr<void>> handle(List<dynamic> arguments) async {
if (arguments == null || arguments.length != 1 || arguments[0] is! String) { if (arguments == null || arguments.length != 1 || arguments[0] is! String) {
return ErrorOr.error(ResponseError( return ErrorOr.error(ResponseError(
ServerErrorCodes.InvalidCommandArguments, code: ServerErrorCodes.InvalidCommandArguments,
'$commandName requires a single String parameter containing the path of a Dart file', message:
null, '$commandName requires a single String parameter containing the path of a Dart file',
)); ));
} }

View file

@ -33,9 +33,9 @@ class PerformRefactorCommandHandler extends SimpleEditCommandHandler {
(arguments[5] != null && arguments[5] is! Map<String, dynamic>)) { (arguments[5] != null && arguments[5] is! Map<String, dynamic>)) {
// length // length
return ErrorOr.error(ResponseError( return ErrorOr.error(ResponseError(
ServerErrorCodes.InvalidCommandArguments, code: ServerErrorCodes.InvalidCommandArguments,
'$commandName requires 6 parameters: RefactoringKind, docVersion, filePath, offset, length, options (optional)', message:
null, '$commandName requires 6 parameters: RefactoringKind, docVersion, filePath, offset, length, options (optional)',
)); ));
} }

View file

@ -29,9 +29,9 @@ class SendWorkspaceEditCommandHandler extends SimpleEditCommandHandler {
arguments.length != 1 || arguments.length != 1 ||
arguments[0] is! Map<String, dynamic>) { arguments[0] is! Map<String, dynamic>) {
return ErrorOr.error(ResponseError( return ErrorOr.error(ResponseError(
ServerErrorCodes.InvalidCommandArguments, code: ServerErrorCodes.InvalidCommandArguments,
'$commandName requires a single List argument of WorkspaceEdit', message:
null, '$commandName requires a single List argument of WorkspaceEdit',
)); ));
} }

View file

@ -52,7 +52,7 @@ abstract class SimpleEditCommandHandler
// Send the edit to the client via a applyEdit request (this is a request // Send the edit to the client via a applyEdit request (this is a request
// from server -> client and the client will provide a response). // from server -> client and the client will provide a response).
final editResponse = await server.sendRequest(Method.workspace_applyEdit, final editResponse = await server.sendRequest(Method.workspace_applyEdit,
ApplyWorkspaceEditParams(commandName, workspaceEdit)); ApplyWorkspaceEditParams(label: commandName, edit: workspaceEdit));
if (editResponse.error != null) { if (editResponse.error != null) {
return error( return error(

View file

@ -21,9 +21,9 @@ class SortMembersCommandHandler extends SimpleEditCommandHandler {
Future<ErrorOr<void>> handle(List<dynamic> arguments) async { Future<ErrorOr<void>> handle(List<dynamic> arguments) async {
if (arguments == null || arguments.length != 1 || arguments[0] is! String) { if (arguments == null || arguments.length != 1 || arguments[0] is! String) {
return ErrorOr.error(ResponseError( return ErrorOr.error(ResponseError(
ServerErrorCodes.InvalidCommandArguments, code: ServerErrorCodes.InvalidCommandArguments,
'$commandName requires a single String parameter containing the path of a Dart file', message:
null, '$commandName requires a single String parameter containing the path of a Dart file',
)); ));
} }
@ -37,9 +37,8 @@ class SortMembersCommandHandler extends SimpleEditCommandHandler {
final result = await driver?.parseFile(path); final result = await driver?.parseFile(path);
if (result == null) { if (result == null) {
return ErrorOr.error(ResponseError( return ErrorOr.error(ResponseError(
ServerErrorCodes.FileNotAnalyzed, code: ServerErrorCodes.FileNotAnalyzed,
'$commandName is only available for analyzed files', message: '$commandName is only available for analyzed files',
null,
)); ));
} }
final code = result.content; final code = result.content;
@ -47,9 +46,10 @@ class SortMembersCommandHandler extends SimpleEditCommandHandler {
if (hasScanParseErrors(result.errors)) { if (hasScanParseErrors(result.errors)) {
return ErrorOr.error(ResponseError( return ErrorOr.error(ResponseError(
ServerErrorCodes.FileHasErrors, code: ServerErrorCodes.FileHasErrors,
'Unable to $commandName because the file contains parse errors', message:
path, 'Unable to $commandName because the file contains parse errors',
data: path,
)); ));
} }

View file

@ -24,6 +24,6 @@ class DiagnosticServerHandler
Future<ErrorOr<DartDiagnosticServer>> handle( Future<ErrorOr<DartDiagnosticServer>> handle(
void _, CancellationToken token) async { void _, CancellationToken token) async {
final port = await server.diagnosticServer.getServerPort(); final port = await server.diagnosticServer.getServerPort();
return success(DartDiagnosticServer(port)); return success(DartDiagnosticServer(port: port));
} }
} }

View file

@ -89,7 +89,7 @@ class CodeActionHandler extends MessageHandler<CodeActionParams,
) { ) {
return clientSupportsLiteralCodeActions return clientSupportsLiteralCodeActions
? Either2<Command, CodeAction>.t2( ? Either2<Command, CodeAction>.t2(
CodeAction(command.title, kind, null, false, null, command), CodeAction(title: command.title, kind: kind, command: command),
) )
: Either2<Command, CodeAction>.t1(command); : Either2<Command, CodeAction>.t1(command);
} }
@ -100,12 +100,10 @@ class CodeActionHandler extends MessageHandler<CodeActionParams,
/// before the version number is read. /// before the version number is read.
CodeAction _createAssistAction(Assist assist) { CodeAction _createAssistAction(Assist assist) {
return CodeAction( return CodeAction(
assist.change.message, title: assist.change.message,
toCodeActionKind(assist.change.id, CodeActionKind.Refactor), kind: toCodeActionKind(assist.change.id, CodeActionKind.Refactor),
const [], diagnostics: const [],
false, edit: createWorkspaceEdit(server, assist.change.edits),
createWorkspaceEdit(server, assist.change.edits),
null,
); );
} }
@ -115,12 +113,10 @@ class CodeActionHandler extends MessageHandler<CodeActionParams,
/// before the version number is read. /// before the version number is read.
CodeAction _createFixAction(Fix fix, Diagnostic diagnostic) { CodeAction _createFixAction(Fix fix, Diagnostic diagnostic) {
return CodeAction( return CodeAction(
fix.change.message, title: fix.change.message,
toCodeActionKind(fix.change.id, CodeActionKind.QuickFix), kind: toCodeActionKind(fix.change.id, CodeActionKind.QuickFix),
[diagnostic], diagnostics: [diagnostic],
false, edit: createWorkspaceEdit(server, fix.change.edits),
createWorkspaceEdit(server, fix.change.edits),
null,
); );
} }
@ -139,13 +135,12 @@ class CodeActionHandler extends MessageHandler<CodeActionParams,
// Build a new CodeAction that merges the diagnostics from each same // Build a new CodeAction that merges the diagnostics from each same
// code action onto a single one. // code action onto a single one.
return CodeAction( return CodeAction(
first.title, title: first.title,
first.kind, kind: first.kind,
// Merge diagnostics from all of the CodeActions. // Merge diagnostics from all of the CodeActions.
groups[edit].expand((r) => r.diagnostics).toList(), diagnostics: groups[edit].expand((r) => r.diagnostics).toList(),
false, edit: first.edit,
first.edit, command: first.command);
first.command);
}).toList(); }).toList();
} }
@ -294,14 +289,18 @@ class CodeActionHandler extends MessageHandler<CodeActionParams,
return _commandOrCodeAction( return _commandOrCodeAction(
clientSupportsLiteralCodeActions, clientSupportsLiteralCodeActions,
actionKind, actionKind,
Command(name, Commands.performRefactor, [ Command(
refactorKind.toJson(), title: name,
path, command: Commands.performRefactor,
server.getVersionedDocumentIdentifier(path).version, arguments: [
offset, refactorKind.toJson(),
length, path,
options, server.getVersionedDocumentIdentifier(path).version,
])); offset,
length,
options,
],
));
} }
try { try {
@ -360,12 +359,18 @@ class CodeActionHandler extends MessageHandler<CodeActionParams,
_commandOrCodeAction( _commandOrCodeAction(
clientSupportsLiteralCodeActions, clientSupportsLiteralCodeActions,
DartCodeActionKind.SortMembers, DartCodeActionKind.SortMembers,
Command('Sort Members', Commands.sortMembers, [path]), Command(
title: 'Sort Members',
command: Commands.sortMembers,
arguments: [path]),
), ),
_commandOrCodeAction( _commandOrCodeAction(
clientSupportsLiteralCodeActions, clientSupportsLiteralCodeActions,
CodeActionKind.SourceOrganizeImports, CodeActionKind.SourceOrganizeImports,
Command('Organize Imports', Commands.organizeImports, [path]), Command(
title: 'Organize Imports',
command: Commands.organizeImports,
arguments: [path]),
), ),
]; ];
} }

View file

@ -135,7 +135,9 @@ class CompletionResolveHandler
if (otherFilesChanges.isNotEmpty) { if (otherFilesChanges.isNotEmpty) {
final workspaceEdit = createWorkspaceEdit(server, otherFilesChanges); final workspaceEdit = createWorkspaceEdit(server, otherFilesChanges);
command = Command( command = Command(
'Add import', Commands.sendWorkspaceEdit, [workspaceEdit]); title: 'Add import',
command: Commands.sendWorkspaceEdit,
arguments: [workspaceEdit]);
} }
// Documentation is added on during resolve for LSP. // Documentation is added on during resolve for LSP.
@ -146,36 +148,36 @@ class CompletionResolveHandler
final documentation = asStringOrMarkupContent(formats, dartDoc); final documentation = asStringOrMarkupContent(formats, dartDoc);
return success(CompletionItem( return success(CompletionItem(
item.label, label: item.label,
item.kind, kind: item.kind,
null, // TODO(dantup): CompletionItemTags (eg. deprecated) tags: null, // TODO(dantup): CompletionItemTags (eg. deprecated)
data.displayUri != null && thisFilesChanges.isNotEmpty detail: data.displayUri != null && thisFilesChanges.isNotEmpty
? "Auto import from '${data.displayUri}'\n\n${item.detail ?? ''}" ? "Auto import from '${data.displayUri}'\n\n${item.detail ?? ''}"
.trim() .trim()
: item.detail, : item.detail,
documentation, documentation: documentation,
// The deprecated field is deprecated, but we should still supply it // The deprecated field is deprecated, but we should still supply it
// for clients that have not adopted CompletionItemTags. // for clients that have not adopted CompletionItemTags.
// ignore: deprecated_member_use_from_same_package // ignore: deprecated_member_use_from_same_package
item.deprecated, deprecated: item.deprecated,
item.preselect, preselect: item.preselect,
item.sortText, sortText: item.sortText,
item.filterText, filterText: item.filterText,
newInsertText, insertText: newInsertText,
item.insertTextFormat, insertTextFormat: item.insertTextFormat,
TextEdit( textEdit: TextEdit(
// TODO(dantup): If `clientSupportsSnippets == true` then we should map // TODO(dantup): If `clientSupportsSnippets == true` then we should map
// `selection` in to a snippet (see how Dart Code does this). // `selection` in to a snippet (see how Dart Code does this).
toRange(lineInfo, item.data.rOffset, item.data.rLength), range: toRange(lineInfo, item.data.rOffset, item.data.rLength),
newInsertText, newText: newInsertText,
), ),
thisFilesChanges additionalTextEdits: thisFilesChanges
.expand((change) => .expand((change) =>
change.edits.map((edit) => toTextEdit(lineInfo, edit))) change.edits.map((edit) => toTextEdit(lineInfo, edit)))
.toList(), .toList(),
item.commitCharacters, commitCharacters: item.commitCharacters,
command ?? item.command, command: command ?? item.command,
item.data, data: item.data,
)); ));
} on InconsistentAnalysisException { } on InconsistentAnalysisException {
// Loop around to try again. // Loop around to try again.

View file

@ -80,14 +80,15 @@ class DocumentSymbolHandler extends MessageHandler<DocumentSymbolParams,
Outline outline, Outline outline,
) { ) {
return DocumentSymbol( return DocumentSymbol(
toElementName(outline.element), name: toElementName(outline.element),
outline.element.parameters, detail: outline.element.parameters,
elementKindToSymbolKind(clientSupportedSymbolKinds, outline.element.kind), kind: elementKindToSymbolKind(
outline.element.isDeprecated, clientSupportedSymbolKinds, outline.element.kind),
toRange(lineInfo, outline.codeOffset, outline.codeLength), deprecated: outline.element.isDeprecated,
toRange(lineInfo, outline.element.location.offset, range: toRange(lineInfo, outline.codeOffset, outline.codeLength),
selectionRange: toRange(lineInfo, outline.element.location.offset,
outline.element.location.length), outline.element.location.length),
outline.children children: outline.children
?.map((child) => ?.map((child) =>
_asDocumentSymbol(clientSupportedSymbolKinds, lineInfo, child)) _asDocumentSymbol(clientSupportedSymbolKinds, lineInfo, child))
?.toList(), ?.toList(),
@ -102,15 +103,16 @@ class DocumentSymbolHandler extends MessageHandler<DocumentSymbolParams,
Outline outline, Outline outline,
) { ) {
return SymbolInformation( return SymbolInformation(
toElementName(outline.element), name: toElementName(outline.element),
elementKindToSymbolKind(clientSupportedSymbolKinds, outline.element.kind), kind: elementKindToSymbolKind(
outline.element.isDeprecated, clientSupportedSymbolKinds, outline.element.kind),
Location( deprecated: outline.element.isDeprecated,
documentUri, location: Location(
toRange(lineInfo, outline.element.location.offset, uri: documentUri,
range: toRange(lineInfo, outline.element.location.offset,
outline.element.location.length), outline.element.location.length),
), ),
containerName, containerName: containerName,
); );
} }

View file

@ -78,8 +78,9 @@ class HoverHandler extends MessageHandler<TextDocumentPositionParams, Hover> {
final formats = final formats =
server?.clientCapabilities?.textDocument?.hover?.contentFormat; server?.clientCapabilities?.textDocument?.hover?.contentFormat;
return Hover( return Hover(
asStringOrMarkupContent(formats, content.toString().trimRight()), contents:
toRange(lineInfo, hover.offset, hover.length), asStringOrMarkupContent(formats, content.toString().trimRight()),
range: toRange(lineInfo, hover.offset, hover.length),
); );
} }

View file

@ -82,8 +82,9 @@ class ImplementationHandler
item.memberElement?.location ?? item.classElement?.location; item.memberElement?.location ?? item.classElement?.location;
final lineInfo = server.getLineInfo(elementLocation.file); final lineInfo = server.getLineInfo(elementLocation.file);
return Location( return Location(
Uri.file(elementLocation.file).toString(), uri: Uri.file(elementLocation.file).toString(),
toRange(lineInfo, elementLocation.offset, elementLocation.length), range:
toRange(lineInfo, elementLocation.offset, elementLocation.length),
); );
}).toList(); }).toList();

View file

@ -64,10 +64,10 @@ class InitializeMessageHandler
} }
return success(InitializeResult( return success(InitializeResult(
server.capabilities, capabilities: server.capabilities,
InitializeResultServerInfo( serverInfo: InitializeResultServerInfo(
'Dart SDK LSP Analysis Server', name: 'Dart SDK LSP Analysis Server',
sdkVersion, version: sdkVersion,
), ),
)); ));
} }

View file

@ -55,7 +55,7 @@ class PrepareRenameHandler
} }
return success(RangeAndPlaceholder( return success(RangeAndPlaceholder(
toRange( range: toRange(
unit.result.lineInfo, unit.result.lineInfo,
// If the offset is set to -1 it means there is no location for the // If the offset is set to -1 it means there is no location for the
// old name. However since we must provide a range for LSP, we'll use // old name. However since we must provide a range for LSP, we'll use
@ -64,7 +64,7 @@ class PrepareRenameHandler
refactorDetails.offset == -1 ? offset : refactorDetails.offset, refactorDetails.offset == -1 ? offset : refactorDetails.offset,
refactorDetails.length, refactorDetails.length,
), ),
refactoring.oldName, placeholder: refactoring.oldName,
)); ));
}); });
} }

View file

@ -149,8 +149,8 @@ class TextDocumentOpenHandler
// We don't get a VersionedTextDocumentIdentifier with a didOpen but we // We don't get a VersionedTextDocumentIdentifier with a didOpen but we
// do get the necessary info to create one. // do get the necessary info to create one.
server.documentVersions[path] = VersionedTextDocumentIdentifier( server.documentVersions[path] = VersionedTextDocumentIdentifier(
params.textDocument.version, version: params.textDocument.version,
params.textDocument.uri, uri: params.textDocument.uri,
); );
server.onOverlayCreated(path, doc.text); server.onOverlayCreated(path, doc.text);

View file

@ -93,8 +93,8 @@ class WorkspaceSymbolHandler
declaration.codeLength, declaration.codeLength,
); );
final location = Location( final location = Location(
Uri.file(filePath).toString(), uri: Uri.file(filePath).toString(),
range, range: range,
); );
final hasParameters = final hasParameters =
@ -103,10 +103,10 @@ class WorkspaceSymbolHandler
hasParameters ? (declaration.parameters == '()' ? '()' : '(…)') : ''; hasParameters ? (declaration.parameters == '()' ? '()' : '(…)') : '';
return SymbolInformation( return SymbolInformation(
'${declaration.name}$nameSuffix', name: '${declaration.name}$nameSuffix',
kind, kind: kind,
null, // We don't have easy access to isDeprecated here. deprecated: null, // We don't have easy access to isDeprecated here.
location, location: location,
declaration.className ?? declaration.mixinName); containerName: declaration.className ?? declaration.mixinName);
} }
} }

View file

@ -182,8 +182,8 @@ class LspAnalysisServer extends AbstractAnalysisServer {
// others (for example "flutter"). // others (for example "flutter").
final response = await sendRequest( final response = await sendRequest(
Method.workspace_configuration, Method.workspace_configuration,
ConfigurationParams([ ConfigurationParams(items: [
ConfigurationItem(null, 'dart'), ConfigurationItem(section: 'dart'),
])); ]));
final result = response.result; final result = response.result;
@ -218,7 +218,7 @@ class LspAnalysisServer extends AbstractAnalysisServer {
/// version is not known. /// version is not known.
VersionedTextDocumentIdentifier getVersionedDocumentIdentifier(String path) { VersionedTextDocumentIdentifier getVersionedDocumentIdentifier(String path) {
return documentVersions[path] ?? return documentVersions[path] ??
VersionedTextDocumentIdentifier(null, Uri.file(path).toString()); VersionedTextDocumentIdentifier(uri: Uri.file(path).toString());
} }
void handleClientConnection( void handleClientConnection(
@ -269,7 +269,9 @@ class LspAnalysisServer extends AbstractAnalysisServer {
sendErrorResponse(message, result.error); sendErrorResponse(message, result.error);
} else { } else {
channel.sendResponse(ResponseMessage( channel.sendResponse(ResponseMessage(
message.id, result.result, null, jsonRpcVersion)); id: message.id,
result: result.result,
jsonrpc: jsonRpcVersion));
} }
} else if (message is NotificationMessage) { } else if (message is NotificationMessage) {
final result = await messageHandler.handleMessage(message); final result = await messageHandler.handleMessage(message);
@ -290,9 +292,8 @@ class LspAnalysisServer extends AbstractAnalysisServer {
sendErrorResponse( sendErrorResponse(
message, message,
ResponseError( ResponseError(
ServerErrorCodes.UnhandledError, code: ServerErrorCodes.UnhandledError,
errorMessage, message: errorMessage,
null,
)); ));
logException(errorMessage, error, stackTrace); logException(errorMessage, error, stackTrace);
} }
@ -303,9 +304,9 @@ class LspAnalysisServer extends AbstractAnalysisServer {
/// Logs the error on the client using window/logMessage. /// Logs the error on the client using window/logMessage.
void logErrorToClient(String message) { void logErrorToClient(String message) {
channel.sendNotification(NotificationMessage( channel.sendNotification(NotificationMessage(
Method.window_logMessage, method: Method.window_logMessage,
LogMessageParams(MessageType.Error, message), params: LogMessageParams(type: MessageType.Error, message: message),
jsonRpcVersion, jsonrpc: jsonRpcVersion,
)); ));
} }
@ -366,44 +367,45 @@ class LspAnalysisServer extends AbstractAnalysisServer {
} }
void publishClosingLabels(String path, List<ClosingLabel> labels) { void publishClosingLabels(String path, List<ClosingLabel> labels) {
final params = final params = PublishClosingLabelsParams(
PublishClosingLabelsParams(Uri.file(path).toString(), labels); uri: Uri.file(path).toString(), labels: labels);
final message = NotificationMessage( final message = NotificationMessage(
CustomMethods.PublishClosingLabels, method: CustomMethods.PublishClosingLabels,
params, params: params,
jsonRpcVersion, jsonrpc: jsonRpcVersion,
); );
sendNotification(message); sendNotification(message);
} }
void publishDiagnostics(String path, List<Diagnostic> errors) { void publishDiagnostics(String path, List<Diagnostic> errors) {
final params = final params = PublishDiagnosticsParams(
PublishDiagnosticsParams(Uri.file(path).toString(), null, errors); uri: Uri.file(path).toString(), diagnostics: errors);
final message = NotificationMessage( final message = NotificationMessage(
Method.textDocument_publishDiagnostics, method: Method.textDocument_publishDiagnostics,
params, params: params,
jsonRpcVersion, jsonrpc: jsonRpcVersion,
); );
sendNotification(message); sendNotification(message);
} }
void publishFlutterOutline(String path, FlutterOutline outline) { void publishFlutterOutline(String path, FlutterOutline outline) {
final params = final params = PublishFlutterOutlineParams(
PublishFlutterOutlineParams(Uri.file(path).toString(), outline); uri: Uri.file(path).toString(), outline: outline);
final message = NotificationMessage( final message = NotificationMessage(
CustomMethods.PublishFlutterOutline, method: CustomMethods.PublishFlutterOutline,
params, params: params,
jsonRpcVersion, jsonrpc: jsonRpcVersion,
); );
sendNotification(message); sendNotification(message);
} }
void publishOutline(String path, Outline outline) { void publishOutline(String path, Outline outline) {
final params = PublishOutlineParams(Uri.file(path).toString(), outline); final params =
PublishOutlineParams(uri: Uri.file(path).toString(), outline: outline);
final message = NotificationMessage( final message = NotificationMessage(
CustomMethods.PublishOutline, method: CustomMethods.PublishOutline,
params, params: params,
jsonRpcVersion, jsonrpc: jsonRpcVersion,
); );
sendNotification(message); sendNotification(message);
} }
@ -418,8 +420,8 @@ class LspAnalysisServer extends AbstractAnalysisServer {
void sendErrorResponse(Message message, ResponseError error) { void sendErrorResponse(Message message, ResponseError error) {
if (message is RequestMessage) { if (message is RequestMessage) {
channel.sendResponse( channel.sendResponse(ResponseMessage(
ResponseMessage(message.id, null, error, jsonRpcVersion)); id: message.id, error: error, jsonrpc: jsonRpcVersion));
} else if (message is ResponseMessage) { } else if (message is ResponseMessage) {
// For bad response messages where we can't respond with an error, send it // For bad response messages where we can't respond with an error, send it
// as show instead of log. // as show instead of log.
@ -456,10 +458,10 @@ class LspAnalysisServer extends AbstractAnalysisServer {
completers[requestId] = completer; completers[requestId] = completer;
channel.sendRequest(RequestMessage( channel.sendRequest(RequestMessage(
Either2<num, String>.t1(requestId), id: Either2<num, String>.t1(requestId),
method, method: method,
params, params: params,
jsonRpcVersion, jsonrpc: jsonRpcVersion,
)); ));
return completer.future; return completer.future;
@ -485,9 +487,9 @@ class LspAnalysisServer extends AbstractAnalysisServer {
/// the [status] information. /// the [status] information.
void sendStatusNotification(nd.AnalysisStatus status) { void sendStatusNotification(nd.AnalysisStatus status) {
channel.sendNotification(NotificationMessage( channel.sendNotification(NotificationMessage(
CustomMethods.AnalyzerStatus, method: CustomMethods.AnalyzerStatus,
AnalyzerStatusParams(status.isAnalyzing), params: AnalyzerStatusParams(isAnalyzing: status.isAnalyzing),
jsonRpcVersion, jsonrpc: jsonRpcVersion,
)); ));
} }
@ -539,9 +541,9 @@ class LspAnalysisServer extends AbstractAnalysisServer {
void showMessageToUser(MessageType type, String message) { void showMessageToUser(MessageType type, String message) {
channel.sendNotification(NotificationMessage( channel.sendNotification(NotificationMessage(
Method.window_showMessage, method: Method.window_showMessage,
ShowMessageParams(type, message), params: ShowMessageParams(type: type, message: message),
jsonRpcVersion, jsonrpc: jsonRpcVersion,
)); ));
} }

View file

@ -46,19 +46,19 @@ class LspSocketServer implements AbstractSocketServer {
void createAnalysisServer(LspServerCommunicationChannel serverChannel) { void createAnalysisServer(LspServerCommunicationChannel serverChannel) {
if (analysisServer != null) { if (analysisServer != null) {
final error = ResponseError( final error = ResponseError(
ServerErrorCodes.ServerAlreadyStarted, code: ServerErrorCodes.ServerAlreadyStarted,
'Server already started', message: 'Server already started',
null,
); );
serverChannel.sendNotification(NotificationMessage( serverChannel.sendNotification(NotificationMessage(
Method.window_showMessage, method: Method.window_showMessage,
ShowMessageParams(MessageType.Error, error.message), params:
jsonRpcVersion, ShowMessageParams(type: MessageType.Error, message: error.message),
jsonrpc: jsonRpcVersion,
)); ));
serverChannel.listen((Message message) { serverChannel.listen((Message message) {
if (message is RequestMessage) { if (message is RequestMessage) {
serverChannel.sendResponse( serverChannel.sendResponse(ResponseMessage(
ResponseMessage(message.id, null, error, jsonRpcVersion)); id: message.id, error: error, jsonrpc: jsonRpcVersion));
} }
}); });
return; return;

View file

@ -241,34 +241,32 @@ lsp.CompletionItem declarationToCompletionItem(
// the generated JSON as much as possible - for example using nulls in place // the generated JSON as much as possible - for example using nulls in place
// of empty lists/false where possible. // of empty lists/false where possible.
return lsp.CompletionItem( return lsp.CompletionItem(
label, label: label,
completionKind, kind: completionKind,
null, // TODO(dantup): CompletionItemTags tags: null, // TODO(dantup): CompletionItemTags
getDeclarationCompletionDetail(declaration, completionKind, useDeprecated), detail: getDeclarationCompletionDetail(
null, // documentation - will be added during resolve. declaration, completionKind, useDeprecated),
useDeprecated && declaration.isDeprecated ? true : null, deprecated: useDeprecated && declaration.isDeprecated ? true : null,
null, // preselect
// Relevance is a number, highest being best. LSP does text sort so subtract // Relevance is a number, highest being best. LSP does text sort so subtract
// from a large number so that a text sort will result in the correct order. // from a large number so that a text sort will result in the correct order.
// 555 -> 999455 // 555 -> 999455
// 10 -> 999990 // 10 -> 999990
// 1 -> 999999 // 1 -> 999999
(1000000 - itemRelevance).toString(), sortText: (1000000 - itemRelevance).toString(),
filterText != label ? filterText : null, // filterText uses label if not set filterText: filterText != label
insertText != label ? insertText : null, // insertText uses label if not set ? filterText
null, // insertTextFormat (we always use plain text so can ommit this) : null, // filterText uses label if not set
null, // textEdit - added on during resolve insertText: insertText != label
null, // additionalTextEdits, used for adding imports, etc. ? insertText
null, // commitCharacters : null, // insertText uses label if not set
null, // command
// data, used for completionItem/resolve. // data, used for completionItem/resolve.
lsp.CompletionItemResolutionInfo( data: lsp.CompletionItemResolutionInfo(
file, file: file,
offset, offset: offset,
includedSuggestionSet.id, libId: includedSuggestionSet.id,
includedSuggestionSet.displayUri ?? library.uri?.toString(), displayUri: includedSuggestionSet.displayUri ?? library.uri?.toString(),
replacementOffset, rOffset: replacementOffset,
replacementLength), rLength: replacementLength),
); );
} }
@ -510,8 +508,8 @@ lsp.Location navigationTargetToLocation(String targetFilePath,
} }
return lsp.Location( return lsp.Location(
Uri.file(targetFilePath).toString(), uri: Uri.file(targetFilePath).toString(),
toRange(lineInfo, target.offset, target.length), range: toRange(lineInfo, target.offset, target.length),
); );
} }
@ -527,16 +525,17 @@ ErrorOr<String> pathOfDocItem(lsp.TextDocumentItem doc) =>
ErrorOr<String> pathOfUri(Uri uri) { ErrorOr<String> pathOfUri(Uri uri) {
if (uri == null) { if (uri == null) {
return ErrorOr<String>.error(ResponseError( return ErrorOr<String>.error(ResponseError(
lsp.ServerErrorCodes.InvalidFilePath, code: lsp.ServerErrorCodes.InvalidFilePath,
'Document URI was not supplied', message: 'Document URI was not supplied',
null)); ));
} }
final isValidFileUri = (uri?.isScheme('file') ?? false); final isValidFileUri = (uri?.isScheme('file') ?? false);
if (!isValidFileUri) { if (!isValidFileUri) {
return ErrorOr<String>.error(ResponseError( return ErrorOr<String>.error(ResponseError(
lsp.ServerErrorCodes.InvalidFilePath, code: lsp.ServerErrorCodes.InvalidFilePath,
'URI was not a valid file:// URI', message: 'URI was not a valid file:// URI',
uri.toString())); data: uri.toString(),
));
} }
try { try {
return ErrorOr<String>.success(uri.toFilePath()); return ErrorOr<String>.success(uri.toFilePath());
@ -544,9 +543,9 @@ ErrorOr<String> pathOfUri(Uri uri) {
// Even if tryParse() works and file == scheme, toFilePath() can throw on // Even if tryParse() works and file == scheme, toFilePath() can throw on
// Windows if there are invalid characters. // Windows if there are invalid characters.
return ErrorOr<String>.error(ResponseError( return ErrorOr<String>.error(ResponseError(
lsp.ServerErrorCodes.InvalidFilePath, code: lsp.ServerErrorCodes.InvalidFilePath,
'File URI did not contain a valid file path', message: 'File URI did not contain a valid file path',
uri.toString())); data: uri.toString()));
} }
} }
@ -569,13 +568,13 @@ lsp.Diagnostic pluginToDiagnostic(
var lineInfo = getLineInfo(error.location.file); var lineInfo = getLineInfo(error.location.file);
return lsp.Diagnostic( return lsp.Diagnostic(
toRange(lineInfo, error.location.offset, error.location.length), range: toRange(lineInfo, error.location.offset, error.location.length),
pluginToDiagnosticSeverity(error.severity), severity: pluginToDiagnosticSeverity(error.severity),
error.code, code: error.code,
languageSourceName, source: languageSourceName,
message, message: message,
null, // TODO(dantup): DiagnosticTags tags: null, // TODO(dantup): DiagnosticTags
relatedInformation, relatedInformation: relatedInformation,
); );
} }
@ -585,15 +584,15 @@ lsp.DiagnosticRelatedInformation pluginToDiagnosticRelatedInformation(
var file = message.location.file; var file = message.location.file;
var lineInfo = getLineInfo(file); var lineInfo = getLineInfo(file);
return lsp.DiagnosticRelatedInformation( return lsp.DiagnosticRelatedInformation(
lsp.Location( location: lsp.Location(
Uri.file(file).toString(), uri: Uri.file(file).toString(),
toRange( range: toRange(
lineInfo, lineInfo,
message.location.offset, message.location.offset,
message.location.length, message.location.length,
), ),
), ),
message.message); message: message.message);
} }
lsp.DiagnosticSeverity pluginToDiagnosticSeverity( lsp.DiagnosticSeverity pluginToDiagnosticSeverity(
@ -623,8 +622,8 @@ lsp.Location searchResultToLocation(
} }
return lsp.Location( return lsp.Location(
Uri.file(result.location.file).toString(), uri: Uri.file(result.location.file).toString(),
toRange(lineInfo, location.offset, location.length), range: toRange(lineInfo, location.offset, location.length),
); );
} }
@ -677,7 +676,8 @@ lsp.CompletionItemKind suggestionKindToCompletionItemKind(
lsp.ClosingLabel toClosingLabel( lsp.ClosingLabel toClosingLabel(
server.LineInfo lineInfo, server.ClosingLabel label) => server.LineInfo lineInfo, server.ClosingLabel label) =>
lsp.ClosingLabel( lsp.ClosingLabel(
toRange(lineInfo, label.offset, label.length), label.label); range: toRange(lineInfo, label.offset, label.length),
label: label.label);
CodeActionKind toCodeActionKind(String id, lsp.CodeActionKind fallback) { CodeActionKind toCodeActionKind(String id, lsp.CodeActionKind fallback) {
if (id == null) { if (id == null) {
@ -749,32 +749,32 @@ lsp.CompletionItem toCompletionItem(
// the generated JSON as much as possible - for example using nulls in place // the generated JSON as much as possible - for example using nulls in place
// of empty lists/false where possible. // of empty lists/false where possible.
return lsp.CompletionItem( return lsp.CompletionItem(
label, label: label,
completionKind, kind: completionKind,
null, // TODO(dantup): CompletionItemTags tags: null, // TODO(dantup): CompletionItemTags
getCompletionDetail(suggestion, completionKind, useDeprecated), detail: getCompletionDetail(suggestion, completionKind, useDeprecated),
asStringOrMarkupContent(formats, cleanDartdoc(suggestion.docComplete)), documentation:
useDeprecated && suggestion.isDeprecated ? true : null, asStringOrMarkupContent(formats, cleanDartdoc(suggestion.docComplete)),
null, // preselect deprecated: useDeprecated && suggestion.isDeprecated ? true : null,
// Relevance is a number, highest being best. LSP does text sort so subtract // Relevance is a number, highest being best. LSP does text sort so subtract
// from a large number so that a text sort will result in the correct order. // from a large number so that a text sort will result in the correct order.
// 555 -> 999455 // 555 -> 999455
// 10 -> 999990 // 10 -> 999990
// 1 -> 999999 // 1 -> 999999
(1000000 - suggestion.relevance).toString(), sortText: (1000000 - suggestion.relevance).toString(),
filterText != label ? filterText : null, // filterText uses label if not set filterText: filterText != label
insertText != label ? insertText : null, // insertText uses label if not set ? filterText
insertTextFormat != lsp.InsertTextFormat.PlainText : null, // filterText uses label if not set
insertText: insertText != label
? insertText
: null, // insertText uses label if not set
insertTextFormat: insertTextFormat != lsp.InsertTextFormat.PlainText
? insertTextFormat ? insertTextFormat
: null, // Defaults to PlainText if not supplied : null, // Defaults to PlainText if not supplied
lsp.TextEdit( textEdit: lsp.TextEdit(
toRange(lineInfo, replacementOffset, replacementLength), range: toRange(lineInfo, replacementOffset, replacementLength),
insertText, newText: insertText,
), ),
null, // additionalTextEdits, used for adding imports, etc.
null, // commitCharacters
null, // command
null, // data, useful for if using lazy resolve, this comes back to us
); );
} }
@ -799,13 +799,13 @@ lsp.Diagnostic toDiagnostic(
} }
return lsp.Diagnostic( return lsp.Diagnostic(
toRange(result.lineInfo, error.offset, error.length), range: toRange(result.lineInfo, error.offset, error.length),
toDiagnosticSeverity(errorSeverity), severity: toDiagnosticSeverity(errorSeverity),
errorCode.name.toLowerCase(), code: errorCode.name.toLowerCase(),
languageSourceName, source: languageSourceName,
message, message: message,
null, // TODO(dantup): DiagnosticTags tags: null, // TODO(dantup): DiagnosticTags
relatedInformation, relatedInformation: relatedInformation,
); );
} }
@ -814,15 +814,15 @@ lsp.DiagnosticRelatedInformation toDiagnosticRelatedInformation(
var file = message.filePath; var file = message.filePath;
var lineInfo = result.session.getFile(file).lineInfo; var lineInfo = result.session.getFile(file).lineInfo;
return lsp.DiagnosticRelatedInformation( return lsp.DiagnosticRelatedInformation(
lsp.Location( location: lsp.Location(
Uri.file(file).toString(), uri: Uri.file(file).toString(),
toRange( range: toRange(
lineInfo, lineInfo,
message.offset, message.offset,
message.length, message.length,
), ),
), ),
message.message); message: message.message);
} }
lsp.DiagnosticSeverity toDiagnosticSeverity(server.ErrorSeverity severity) { lsp.DiagnosticSeverity toDiagnosticSeverity(server.ErrorSeverity severity) {
@ -844,14 +844,14 @@ lsp.DiagnosticSeverity toDiagnosticSeverity(server.ErrorSeverity severity) {
lsp.Element toElement(server.LineInfo lineInfo, server.Element element) => lsp.Element toElement(server.LineInfo lineInfo, server.Element element) =>
lsp.Element( lsp.Element(
element.location != null range: element.location != null
? toRange(lineInfo, element.location.offset, element.location.length) ? toRange(lineInfo, element.location.offset, element.location.length)
: null, : null,
toElementName(element), name: toElementName(element),
element.kind.name, kind: element.kind.name,
element.parameters, parameters: element.parameters,
element.typeParameters, typeParameters: element.typeParameters,
element.returnType, returnType: element.returnType,
); );
String toElementName(server.Element element) { String toElementName(server.Element element) {
@ -865,22 +865,22 @@ String toElementName(server.Element element) {
lsp.FlutterOutline toFlutterOutline( lsp.FlutterOutline toFlutterOutline(
server.LineInfo lineInfo, server.FlutterOutline outline) => server.LineInfo lineInfo, server.FlutterOutline outline) =>
lsp.FlutterOutline( lsp.FlutterOutline(
outline.kind.name, kind: outline.kind.name,
outline.label, label: outline.label,
outline.className, className: outline.className,
outline.variableName, variableName: outline.variableName,
outline.attributes != null attributes: outline.attributes != null
? outline.attributes ? outline.attributes
.map( .map(
(attribute) => toFlutterOutlineAttribute(lineInfo, attribute)) (attribute) => toFlutterOutlineAttribute(lineInfo, attribute))
.toList() .toList()
: null, : null,
outline.dartElement != null dartElement: outline.dartElement != null
? toElement(lineInfo, outline.dartElement) ? toElement(lineInfo, outline.dartElement)
: null, : null,
toRange(lineInfo, outline.offset, outline.length), range: toRange(lineInfo, outline.offset, outline.length),
toRange(lineInfo, outline.codeOffset, outline.codeLength), codeRange: toRange(lineInfo, outline.codeOffset, outline.codeLength),
outline.children != null children: outline.children != null
? outline.children.map((c) => toFlutterOutline(lineInfo, c)).toList() ? outline.children.map((c) => toFlutterOutline(lineInfo, c)).toList()
: null, : null,
); );
@ -888,9 +888,9 @@ lsp.FlutterOutline toFlutterOutline(
lsp.FlutterOutlineAttribute toFlutterOutlineAttribute( lsp.FlutterOutlineAttribute toFlutterOutlineAttribute(
server.LineInfo lineInfo, server.FlutterOutlineAttribute attribute) => server.LineInfo lineInfo, server.FlutterOutlineAttribute attribute) =>
lsp.FlutterOutlineAttribute( lsp.FlutterOutlineAttribute(
attribute.name, name: attribute.name,
attribute.label, label: attribute.label,
attribute.valueLocation != null valueRange: attribute.valueLocation != null
? toRange(lineInfo, attribute.valueLocation.offset, ? toRange(lineInfo, attribute.valueLocation.offset,
attribute.valueLocation.length) attribute.valueLocation.length)
: null); : null);
@ -898,8 +898,12 @@ lsp.FlutterOutlineAttribute toFlutterOutlineAttribute(
lsp.FoldingRange toFoldingRange( lsp.FoldingRange toFoldingRange(
server.LineInfo lineInfo, server.FoldingRegion region) { server.LineInfo lineInfo, server.FoldingRegion region) {
final range = toRange(lineInfo, region.offset, region.length); final range = toRange(lineInfo, region.offset, region.length);
return lsp.FoldingRange(range.start.line, range.start.character, return lsp.FoldingRange(
range.end.line, range.end.character, toFoldingRangeKind(region.kind)); startLine: range.start.line,
startCharacter: range.start.character,
endLine: range.end.line,
endCharacter: range.end.character,
kind: toFoldingRangeKind(region.kind));
} }
lsp.FoldingRangeKind toFoldingRangeKind(server.FoldingKind kind) { lsp.FoldingRangeKind toFoldingRangeKind(server.FoldingKind kind) {
@ -921,14 +925,14 @@ List<lsp.DocumentHighlight> toHighlights(
server.LineInfo lineInfo, server.Occurrences occurrences) { server.LineInfo lineInfo, server.Occurrences occurrences) {
return occurrences.offsets return occurrences.offsets
.map((offset) => lsp.DocumentHighlight( .map((offset) => lsp.DocumentHighlight(
toRange(lineInfo, offset, occurrences.length), null)) range: toRange(lineInfo, offset, occurrences.length)))
.toList(); .toList();
} }
lsp.Location toLocation(server.Location location, server.LineInfo lineInfo) => lsp.Location toLocation(server.Location location, server.LineInfo lineInfo) =>
lsp.Location( lsp.Location(
Uri.file(location.file).toString(), uri: Uri.file(location.file).toString(),
toRange( range: toRange(
lineInfo, lineInfo,
location.offset, location.offset,
location.length, location.length,
@ -942,11 +946,11 @@ ErrorOr<int> toOffset(
}) { }) {
if (pos.line > lineInfo.lineCount) { if (pos.line > lineInfo.lineCount) {
return ErrorOr<int>.error(lsp.ResponseError( return ErrorOr<int>.error(lsp.ResponseError(
failureIsCritial code: failureIsCritial
? lsp.ServerErrorCodes.ClientServerInconsistentState ? lsp.ServerErrorCodes.ClientServerInconsistentState
: lsp.ServerErrorCodes.InvalidFileLineCol, : lsp.ServerErrorCodes.InvalidFileLineCol,
'Invalid line number', message: 'Invalid line number',
pos.line.toString())); data: pos.line.toString()));
} }
// TODO(dantup): Is there any way to validate the character? We could ensure // TODO(dantup): Is there any way to validate the character? We could ensure
// it's less than the offset of the next line, but that would only work for // it's less than the offset of the next line, but that would only work for
@ -957,17 +961,18 @@ ErrorOr<int> toOffset(
lsp.Outline toOutline(server.LineInfo lineInfo, server.Outline outline) => lsp.Outline toOutline(server.LineInfo lineInfo, server.Outline outline) =>
lsp.Outline( lsp.Outline(
toElement(lineInfo, outline.element), element: toElement(lineInfo, outline.element),
toRange(lineInfo, outline.offset, outline.length), range: toRange(lineInfo, outline.offset, outline.length),
toRange(lineInfo, outline.codeOffset, outline.codeLength), codeRange: toRange(lineInfo, outline.codeOffset, outline.codeLength),
outline.children != null children: outline.children != null
? outline.children.map((c) => toOutline(lineInfo, c)).toList() ? outline.children.map((c) => toOutline(lineInfo, c)).toList()
: null, : null,
); );
lsp.Position toPosition(server.CharacterLocation location) { lsp.Position toPosition(server.CharacterLocation location) {
// LSP is zero-based, but analysis server is 1-based. // LSP is zero-based, but analysis server is 1-based.
return lsp.Position(location.lineNumber - 1, location.columnNumber - 1); return lsp.Position(
line: location.lineNumber - 1, character: location.columnNumber - 1);
} }
lsp.Range toRange(server.LineInfo lineInfo, int offset, int length) { lsp.Range toRange(server.LineInfo lineInfo, int offset, int length) {
@ -975,8 +980,8 @@ lsp.Range toRange(server.LineInfo lineInfo, int offset, int length) {
server.CharacterLocation end = lineInfo.getLocation(offset + length); server.CharacterLocation end = lineInfo.getLocation(offset + length);
return lsp.Range( return lsp.Range(
toPosition(start), start: toPosition(start),
toPosition(end), end: toPosition(end),
); );
} }
@ -1023,20 +1028,20 @@ lsp.SignatureHelp toSignatureHelp(List<lsp.MarkupKind> preferredFormats,
// to guess based on substrings). We should check the // to guess based on substrings). We should check the
// signatureHelp.signatureInformation.parameterInformation.labelOffsetSupport // signatureHelp.signatureInformation.parameterInformation.labelOffsetSupport
// capability when deciding to send that. // capability when deciding to send that.
return lsp.ParameterInformation(getParamLabel(param), null); return lsp.ParameterInformation(label: getParamLabel(param));
} }
final cleanDoc = cleanDartdoc(signature.dartdoc); final cleanDoc = cleanDartdoc(signature.dartdoc);
return lsp.SignatureHelp( return lsp.SignatureHelp(
[ signatures: [
lsp.SignatureInformation( lsp.SignatureInformation(
getSignatureLabel(signature), label: getSignatureLabel(signature),
asStringOrMarkupContent(preferredFormats, cleanDoc), documentation: asStringOrMarkupContent(preferredFormats, cleanDoc),
signature.parameters.map(toParameterInfo).toList(), parameters: signature.parameters.map(toParameterInfo).toList(),
), ),
], ],
0, // activeSignature activeSignature: 0, // activeSignature
// TODO(dantup): The LSP spec says this value will default to 0 if it's // TODO(dantup): The LSP spec says this value will default to 0 if it's
// not supplied or outside of the value range. However, setting -1 results // not supplied or outside of the value range. However, setting -1 results
// in no parameters being selected in VS Code, whereas null/0 will select the first. // in no parameters being selected in VS Code, whereas null/0 will select the first.
@ -1045,21 +1050,21 @@ lsp.SignatureHelp toSignatureHelp(List<lsp.MarkupKind> preferredFormats,
// (because you could also be on param 5 of an invalid call to a function // (because you could also be on param 5 of an invalid call to a function
// taking only 3 arguments) here: // taking only 3 arguments) here:
// https://github.com/Microsoft/language-server-protocol/issues/456#issuecomment-452318297 // https://github.com/Microsoft/language-server-protocol/issues/456#issuecomment-452318297
-1, // activeParameter activeParameter: -1, // activeParameter
); );
} }
lsp.TextDocumentEdit toTextDocumentEdit(FileEditInformation edit) { lsp.TextDocumentEdit toTextDocumentEdit(FileEditInformation edit) {
return lsp.TextDocumentEdit( return lsp.TextDocumentEdit(
edit.doc, textDocument: edit.doc,
edit.edits.map((e) => toTextEdit(edit.lineInfo, e)).toList(), edits: edit.edits.map((e) => toTextEdit(edit.lineInfo, e)).toList(),
); );
} }
lsp.TextEdit toTextEdit(server.LineInfo lineInfo, server.SourceEdit edit) { lsp.TextEdit toTextEdit(server.LineInfo lineInfo, server.SourceEdit edit) {
return lsp.TextEdit( return lsp.TextEdit(
toRange(lineInfo, edit.offset, edit.length), range: toRange(lineInfo, edit.offset, edit.length),
edit.replacement, newText: edit.replacement,
); );
} }
@ -1071,16 +1076,15 @@ lsp.WorkspaceEdit toWorkspaceEdit(
capabilities?.workspaceEdit?.documentChanges == true; capabilities?.workspaceEdit?.documentChanges == true;
if (clientSupportsTextDocumentEdits) { if (clientSupportsTextDocumentEdits) {
return lsp.WorkspaceEdit( return lsp.WorkspaceEdit(
null, documentChanges: Either2<
Either2<
List<lsp.TextDocumentEdit>, List<lsp.TextDocumentEdit>,
List< List<
Either4<lsp.TextDocumentEdit, lsp.CreateFile, lsp.RenameFile, Either4<lsp.TextDocumentEdit, lsp.CreateFile, lsp.RenameFile,
lsp.DeleteFile>>>.t1( lsp.DeleteFile>>>.t1(
edits.map(toTextDocumentEdit).toList(), edits.map(toTextDocumentEdit).toList(),
)); ));
} else { } else {
return lsp.WorkspaceEdit(toWorkspaceEditChanges(edits), null); return lsp.WorkspaceEdit(changes: toWorkspaceEditChanges(edits));
} }
} }
@ -1118,5 +1122,5 @@ lsp.MarkupContent _asMarkup(
? lsp.MarkupKind.PlainText ? lsp.MarkupKind.PlainText
: lsp.MarkupKind.Markdown; : lsp.MarkupKind.Markdown;
return lsp.MarkupContent(format, content); return lsp.MarkupContent(kind: format, value: content);
} }

View file

@ -33,11 +33,11 @@ class LspNotificationManager extends AbstractNotificationManager {
.toList(); .toList();
final params = PublishDiagnosticsParams( final params = PublishDiagnosticsParams(
Uri.file(filePath).toString(), null, diagnostics); uri: Uri.file(filePath).toString(), diagnostics: diagnostics);
final message = NotificationMessage( final message = NotificationMessage(
Method.textDocument_publishDiagnostics, method: Method.textDocument_publishDiagnostics,
params, params: params,
jsonRpcVersion, jsonrpc: jsonRpcVersion,
); );
channel.sendNotification(message); channel.sendNotification(message);

View file

@ -116,106 +116,93 @@ class ServerCapabilitiesComputer {
// list of what files types we support (and allows them to avoid sending // list of what files types we support (and allows them to avoid sending
// requests where we have only partial support for some types). // requests where we have only partial support for some types).
return ServerCapabilities( return ServerCapabilities(
dynamicRegistrations.textSync textDocumentSync: dynamicRegistrations.textSync
? null ? null
: Either2<TextDocumentSyncOptions, num>.t1(TextDocumentSyncOptions( : Either2<TextDocumentSyncOptions, num>.t1(TextDocumentSyncOptions(
// The open/close and sync kind flags are registered dynamically if the // The open/close and sync kind flags are registered dynamically if the
// client supports them, so these static registrations are based on whether // client supports them, so these static registrations are based on whether
// the client supports dynamic registration. // the client supports dynamic registration.
true, openClose: true,
TextDocumentSyncKind.Incremental, change: TextDocumentSyncKind.Incremental,
false, willSave: false,
false, willSaveWaitUntil: false,
null, save: null,
)), )),
dynamicRegistrations.completion completionProvider: dynamicRegistrations.completion
? null ? null
: CompletionOptions( : CompletionOptions(
dartCompletionTriggerCharacters, triggerCharacters: dartCompletionTriggerCharacters,
null, // allCommitCharacters resolveProvider: true,
true, // resolveProvider ),
null, // workDoneProgress hoverProvider: dynamicRegistrations.hover
), // completionProvider ? null
dynamicRegistrations.hover : Either2<bool, HoverOptions>.t1(true),
? null signatureHelpProvider: dynamicRegistrations.signatureHelp
: Either2<bool, HoverOptions>.t1(true), // hoverProvider ? null
dynamicRegistrations.signatureHelp : SignatureHelpOptions(
? null triggerCharacters: dartSignatureHelpTriggerCharacters,
: SignatureHelpOptions( ),
dartSignatureHelpTriggerCharacters, definitionProvider: dynamicRegistrations.definition
null, // retriggerCharacters ? null
null, // workDoneProgress : Either2<bool, DefinitionOptions>.t1(true),
), implementationProvider: dynamicRegistrations.implementation
null, // declarationProvider ? null
dynamicRegistrations.definition : Either3<bool, ImplementationOptions,
? null ImplementationRegistrationOptions>.t1(
: Either2<bool, DefinitionOptions>.t1(true), // definitionProvider true,
null, ),
dynamicRegistrations.implementation referencesProvider: dynamicRegistrations.references
? null ? null
: Either3<bool, ImplementationOptions, : Either2<bool, ReferenceOptions>.t1(true),
ImplementationRegistrationOptions>.t1( documentHighlightProvider: dynamicRegistrations.documentHighlights
true, ? null
), // implementationProvider : Either2<bool, DocumentHighlightOptions>.t1(true),
dynamicRegistrations.references documentSymbolProvider: dynamicRegistrations.documentSymbol
? null ? null
: Either2<bool, ReferenceOptions>.t1(true), // referencesProvider : Either2<bool, DocumentSymbolOptions>.t1(true),
dynamicRegistrations.documentHighlights // "The `CodeActionOptions` return type is only valid if the client
? null // signals code action literal support via the property
: Either2<bool, DocumentHighlightOptions>.t1( // `textDocument.codeAction.codeActionLiteralSupport`."
true), // documentHighlightProvider codeActionProvider: dynamicRegistrations.codeActions
dynamicRegistrations.documentSymbol ? null
? null : codeActionLiteralSupport != null
: Either2<bool, DocumentSymbolOptions>.t1( ? Either2<bool, CodeActionOptions>.t2(CodeActionOptions(
true), // documentSymbolProvider codeActionKinds: DartCodeActionKind.serverSupportedKinds,
// "The `CodeActionOptions` return type is only valid if the client ))
// signals code action literal support via the property : Either2<bool, CodeActionOptions>.t1(true),
// `textDocument.codeAction.codeActionLiteralSupport`." documentFormattingProvider: dynamicRegistrations.formatting
dynamicRegistrations.codeActions ? null
? null : Either2<bool, DocumentFormattingOptions>.t1(enableFormatter),
: codeActionLiteralSupport != null documentOnTypeFormattingProvider: dynamicRegistrations.typeFormatting
? Either2<bool, CodeActionOptions>.t2(CodeActionOptions( ? null
DartCodeActionKind.serverSupportedKinds, : enableFormatter
null, // workDoneProgress ? DocumentOnTypeFormattingOptions(
)) firstTriggerCharacter: dartTypeFormattingCharacters.first,
: Either2<bool, CodeActionOptions>.t1(true), moreTriggerCharacter:
null, // codeLensProvider dartTypeFormattingCharacters.skip(1).toList())
null, // documentLinkProvider : null,
null, // colorProvider renameProvider: dynamicRegistrations.rename
dynamicRegistrations.formatting ? null
? null : renameOptionsSupport
: Either2<bool, DocumentFormattingOptions>.t1( ? Either2<bool, RenameOptions>.t2(
enableFormatter), // documentFormattingProvider RenameOptions(prepareProvider: true))
null, // documentRangeFormattingProvider : Either2<bool, RenameOptions>.t1(true),
dynamicRegistrations.typeFormatting foldingRangeProvider: dynamicRegistrations.folding
? null ? null
: enableFormatter : Either3<bool, FoldingRangeOptions,
? DocumentOnTypeFormattingOptions( FoldingRangeRegistrationOptions>.t1(
dartTypeFormattingCharacters.first, true,
dartTypeFormattingCharacters.skip(1).toList()) ),
: null, executeCommandProvider: ExecuteCommandOptions(
dynamicRegistrations.rename commands: Commands.serverSupportedCommands,
? null ),
: renameOptionsSupport workspaceSymbolProvider: true,
? Either2<bool, RenameOptions>.t2(RenameOptions(true, null)) workspace: ServerCapabilitiesWorkspace(
: Either2<bool, RenameOptions>.t1(true), workspaceFolders: WorkspaceFoldersServerCapabilities(
dynamicRegistrations.folding supported: true,
? null changeNotifications: Either2<String, bool>.t2(true),
: Either3<bool, FoldingRangeOptions, )),
FoldingRangeRegistrationOptions>.t1( );
true,
),
ExecuteCommandOptions(
Commands.serverSupportedCommands,
null, // workDoneProgress
),
null, // selectionRangeProvider
true, // workspaceSymbolProvider
ServerCapabilitiesWorkspace(WorkspaceFoldersServerCapabilities(
true,
Either2<String, bool>.t2(true),
)),
null);
} }
/// If the client supports dynamic registrations we can tell it what methods /// If the client supports dynamic registrations we can tell it what methods
@ -226,17 +213,18 @@ class ServerCapabilitiesComputer {
/// support and it will be up to them to decide which file types they will /// support and it will be up to them to decide which file types they will
/// send requests for. /// send requests for.
Future<void> performDynamicRegistration() async { Future<void> performDynamicRegistration() async {
final dartFiles = DocumentFilter('dart', 'file', null); final dartFiles = DocumentFilter(language: 'dart', scheme: 'file');
final pubspecFile = DocumentFilter('yaml', 'file', '**/pubspec.yaml'); final pubspecFile = DocumentFilter(
final analysisOptionsFile = language: 'yaml', scheme: 'file', pattern: '**/pubspec.yaml');
DocumentFilter('yaml', 'file', '**/analysis_options.yaml'); final analysisOptionsFile = DocumentFilter(
language: 'yaml', scheme: 'file', pattern: '**/analysis_options.yaml');
final pluginTypes = _server.pluginManager.plugins final pluginTypes = _server.pluginManager.plugins
.expand((plugin) => plugin.currentSession?.interestingFiles ?? const []) .expand((plugin) => plugin.currentSession?.interestingFiles ?? const [])
// All published plugins use something like `*.extension` as // All published plugins use something like `*.extension` as
// interestingFiles. Prefix a `**/` so that the glob matches nested // interestingFiles. Prefix a `**/` so that the glob matches nested
// folders as well. // folders as well.
.map((glob) => DocumentFilter(null, 'file', '**/$glob')); .map((glob) => DocumentFilter(scheme: 'file', pattern: '**/$glob'));
final allTypes = {dartFiles, ...pluginTypes}.toList(); final allTypes = {dartFiles, ...pluginTypes}.toList();
@ -259,7 +247,9 @@ class ServerCapabilitiesComputer {
void register(bool condition, Method method, [ToJsonable options]) { void register(bool condition, Method method, [ToJsonable options]) {
if (condition == true) { if (condition == true) {
registrations.add(Registration( registrations.add(Registration(
(_lastRegistrationId++).toString(), method.toJson(), options)); id: (_lastRegistrationId++).toString(),
method: method.toJson(),
registerOptions: options));
} }
} }
@ -269,102 +259,99 @@ class ServerCapabilitiesComputer {
register( register(
dynamicRegistrations.textSync, dynamicRegistrations.textSync,
Method.textDocument_didOpen, Method.textDocument_didOpen,
TextDocumentRegistrationOptions(allSynchronisedTypes), TextDocumentRegistrationOptions(documentSelector: allSynchronisedTypes),
); );
register( register(
dynamicRegistrations.textSync, dynamicRegistrations.textSync,
Method.textDocument_didClose, Method.textDocument_didClose,
TextDocumentRegistrationOptions(allSynchronisedTypes), TextDocumentRegistrationOptions(documentSelector: allSynchronisedTypes),
); );
register( register(
dynamicRegistrations.textSync, dynamicRegistrations.textSync,
Method.textDocument_didChange, Method.textDocument_didChange,
TextDocumentChangeRegistrationOptions( TextDocumentChangeRegistrationOptions(
TextDocumentSyncKind.Incremental, allSynchronisedTypes), syncKind: TextDocumentSyncKind.Incremental,
documentSelector: allSynchronisedTypes),
); );
register( register(
dynamicRegistrations.completion, dynamicRegistrations.completion,
Method.textDocument_completion, Method.textDocument_completion,
CompletionRegistrationOptions( CompletionRegistrationOptions(
allTypes, documentSelector: allTypes,
dartCompletionTriggerCharacters, triggerCharacters: dartCompletionTriggerCharacters,
null, resolveProvider: true,
true,
null,
), ),
); );
register( register(
dynamicRegistrations.hover, dynamicRegistrations.hover,
Method.textDocument_hover, Method.textDocument_hover,
TextDocumentRegistrationOptions(allTypes), TextDocumentRegistrationOptions(documentSelector: allTypes),
); );
register( register(
dynamicRegistrations.signatureHelp, dynamicRegistrations.signatureHelp,
Method.textDocument_signatureHelp, Method.textDocument_signatureHelp,
SignatureHelpRegistrationOptions( SignatureHelpRegistrationOptions(
allTypes, documentSelector: allTypes,
dartSignatureHelpTriggerCharacters, triggerCharacters: dartSignatureHelpTriggerCharacters,
null,
null,
), ),
); );
register( register(
dynamicRegistrations.references, dynamicRegistrations.references,
Method.textDocument_references, Method.textDocument_references,
TextDocumentRegistrationOptions(allTypes), TextDocumentRegistrationOptions(documentSelector: allTypes),
); );
register( register(
dynamicRegistrations.documentHighlights, dynamicRegistrations.documentHighlights,
Method.textDocument_documentHighlight, Method.textDocument_documentHighlight,
TextDocumentRegistrationOptions(allTypes), TextDocumentRegistrationOptions(documentSelector: allTypes),
); );
register( register(
dynamicRegistrations.documentSymbol, dynamicRegistrations.documentSymbol,
Method.textDocument_documentSymbol, Method.textDocument_documentSymbol,
TextDocumentRegistrationOptions(allTypes), TextDocumentRegistrationOptions(documentSelector: allTypes),
); );
register( register(
enableFormatter && dynamicRegistrations.formatting, enableFormatter && dynamicRegistrations.formatting,
Method.textDocument_formatting, Method.textDocument_formatting,
TextDocumentRegistrationOptions(allTypes), TextDocumentRegistrationOptions(documentSelector: allTypes),
); );
register( register(
enableFormatter && dynamicRegistrations.typeFormatting, enableFormatter && dynamicRegistrations.typeFormatting,
Method.textDocument_onTypeFormatting, Method.textDocument_onTypeFormatting,
DocumentOnTypeFormattingRegistrationOptions( DocumentOnTypeFormattingRegistrationOptions(
[dartFiles], // This one is currently Dart-specific documentSelector: [dartFiles], // This one is currently Dart-specific
dartTypeFormattingCharacters.first, firstTriggerCharacter: dartTypeFormattingCharacters.first,
dartTypeFormattingCharacters.skip(1).toList(), moreTriggerCharacter: dartTypeFormattingCharacters.skip(1).toList(),
), ),
); );
register( register(
dynamicRegistrations.definition, dynamicRegistrations.definition,
Method.textDocument_definition, Method.textDocument_definition,
TextDocumentRegistrationOptions(allTypes), TextDocumentRegistrationOptions(documentSelector: allTypes),
); );
register( register(
dynamicRegistrations.implementation, dynamicRegistrations.implementation,
Method.textDocument_implementation, Method.textDocument_implementation,
TextDocumentRegistrationOptions(allTypes), TextDocumentRegistrationOptions(documentSelector: allTypes),
); );
register( register(
dynamicRegistrations.codeActions, dynamicRegistrations.codeActions,
Method.textDocument_codeAction, Method.textDocument_codeAction,
CodeActionRegistrationOptions( CodeActionRegistrationOptions(
allTypes, documentSelector: allTypes,
DartCodeActionKind.serverSupportedKinds, codeActionKinds: DartCodeActionKind.serverSupportedKinds,
null,
), ),
); );
register( register(
dynamicRegistrations.rename, dynamicRegistrations.rename,
Method.textDocument_rename, Method.textDocument_rename,
RenameRegistrationOptions(allTypes, true, null), RenameRegistrationOptions(
documentSelector: allTypes, prepareProvider: true),
); );
register( register(
dynamicRegistrations.folding, dynamicRegistrations.folding,
Method.textDocument_foldingRange, Method.textDocument_foldingRange,
TextDocumentRegistrationOptions(allTypes), TextDocumentRegistrationOptions(documentSelector: allTypes),
); );
register( register(
dynamicRegistrations.didChangeConfiguration, dynamicRegistrations.didChangeConfiguration,
@ -395,8 +382,8 @@ class ServerCapabilitiesComputer {
registration.registerOptions; registration.registerOptions;
if (entryRemovedOrChanged) { if (entryRemovedOrChanged) {
removedRegistrations removedRegistrations.add(
.add(Unregistration(registration.id, registration.method)); Unregistration(id: registration.id, method: registration.method));
} else { } else {
// Replace the registration in our new set with the original registration // Replace the registration in our new set with the original registration
// so that we retain the original ID sent to the client (otherwise we // so that we retain the original ID sent to the client (otherwise we
@ -410,7 +397,7 @@ class ServerCapabilitiesComputer {
if (removedRegistrations.isNotEmpty) { if (removedRegistrations.isNotEmpty) {
await _server.sendRequest(Method.client_unregisterCapability, await _server.sendRequest(Method.client_unregisterCapability,
UnregistrationParams(removedRegistrations)); UnregistrationParams(unregisterations: removedRegistrations));
} }
// Only send the registration request if we have at least one (since // Only send the registration request if we have at least one (since
@ -418,7 +405,7 @@ class ServerCapabilitiesComputer {
if (additionalRegistrations.isNotEmpty) { if (additionalRegistrations.isNotEmpty) {
final registrationResponse = await _server.sendRequest( final registrationResponse = await _server.sendRequest(
Method.client_registerCapability, Method.client_registerCapability,
RegistrationParams(additionalRegistrations), RegistrationParams(registrations: additionalRegistrations),
); );
if (registrationResponse.error != null) { if (registrationResponse.error != null) {

View file

@ -91,8 +91,9 @@ List<TextEdit> generateEditsForFormatting(String unformattedSource) {
final end = lineInfo.getLocation(unformattedSource.length); final end = lineInfo.getLocation(unformattedSource.length);
return [ return [
TextEdit( TextEdit(
Range(Position(0, 0), toPosition(end)), range:
formattedSource, Range(start: Position(line: 0, character: 0), end: toPosition(end)),
newText: formattedSource,
) )
]; ];
} }

View file

@ -20,10 +20,10 @@ class InitializationTest extends AbstractLspAnalysisServerIntegrationTest {
Future<void> test_initialize_invalidParams() async { Future<void> test_initialize_invalidParams() async {
final params = {'processId': 'invalid'}; final params = {'processId': 'invalid'};
final request = RequestMessage( final request = RequestMessage(
Either2<num, String>.t1(1), id: Either2<num, String>.t1(1),
Method.initialize, method: Method.initialize,
params, params: params,
jsonRpcVersion, jsonrpc: jsonRpcVersion,
); );
final response = await sendRequestToServer(request); final response = await sendRequestToServer(request);
expect(response.id, equals(request.id)); expect(response.id, equals(request.id));

View file

@ -33,16 +33,13 @@ main() {
final completionRequest = makeRequest( final completionRequest = makeRequest(
Method.textDocument_completion, Method.textDocument_completion,
CompletionParams( CompletionParams(
null, textDocument: TextDocumentIdentifier(uri: mainFileUri.toString()),
TextDocumentIdentifier(mainFileUri.toString()), position: positionFromMarker(content),
positionFromMarker(content),
null,
null,
), ),
); );
// And a request to cancel it. // And a request to cancel it.
final cancelNotification = makeNotification( final cancelNotification = makeNotification(
Method.cancelRequest, CancelParams(completionRequest.id)); Method.cancelRequest, CancelParams(id: completionRequest.id));
// Send both (without waiting for the results of the first). // Send both (without waiting for the results of the first).
final completionRequestFuture = sendRequestToServer(completionRequest); final completionRequestFuture = sendRequestToServer(completionRequest);

View file

@ -105,7 +105,7 @@ abstract class AbstractCodeActionsTest extends AbstractLspAnalysisServerTest {
// When the server sends the edit back, just keep a copy and say we // When the server sends the edit back, just keep a copy and say we
// applied successfully (it'll be verified below). // applied successfully (it'll be verified below).
editParams = edit; editParams = edit;
return ApplyWorkspaceEditResponse(true, null); return ApplyWorkspaceEditResponse(applied: true);
}, },
); );
// Successful edits return an empty success() response. // Successful edits return an empty success() response.

View file

@ -281,7 +281,8 @@ class SortMembersSourceCodeActionsTest extends AbstractCodeActionsTest {
// Claim that we failed tpo apply the edits. This is what the client // Claim that we failed tpo apply the edits. This is what the client
// would do if the edits provided were for an old version of the // would do if the edits provided were for an old version of the
// document. // document.
handler: (edit) => ApplyWorkspaceEditResponse(false, 'Document changed'), handler: (edit) => ApplyWorkspaceEditResponse(
applied: false, failureReason: 'Document changed'),
); );
// Ensure the request returned an error (error repsonses are thrown by // Ensure the request returned an error (error repsonses are thrown by

View file

@ -108,8 +108,9 @@ class CompletionTest extends AbstractLspAnalysisServerTest {
final invalidTriggerKind = CompletionTriggerKind.fromJson(-1); final invalidTriggerKind = CompletionTriggerKind.fromJson(-1);
final request = getCompletion( final request = getCompletion(
mainFileUri, mainFileUri,
Position(0, 0), Position(line: 0, character: 0),
context: CompletionContext(invalidTriggerKind, 'A'), context: CompletionContext(
triggerKind: invalidTriggerKind, triggerCharacter: 'A'),
); );
await expectLater( await expectLater(
@ -365,7 +366,9 @@ class CompletionTest extends AbstractLspAnalysisServerTest {
expect(item.textEdit.newText, equals(r'one: ${1:}')); expect(item.textEdit.newText, equals(r'one: ${1:}'));
expect( expect(
item.textEdit.range, item.textEdit.range,
equals(Range(positionFromMarker(content), positionFromMarker(content))), equals(Range(
start: positionFromMarker(content),
end: positionFromMarker(content))),
); );
} }
@ -852,7 +855,7 @@ main() {
// When the server sends the edit back, just keep a copy and say we // When the server sends the edit back, just keep a copy and say we
// applied successfully (it'll be verified below). // applied successfully (it'll be verified below).
editParams = edit; editParams = edit;
return ApplyWorkspaceEditResponse(true, null); return ApplyWorkspaceEditResponse(applied: true);
}, },
); );
// Successful edits return an empty success() response. // Successful edits return an empty success() response.

View file

@ -69,12 +69,16 @@ class DefinitionTest extends AbstractLspAnalysisServerTest {
newFile(pluginAnalyzedFilePath); newFile(pluginAnalyzedFilePath);
await initialize(); await initialize();
final res = await getDefinition(pluginAnalyzedFileUri, lsp.Position(0, 0)); final res = await getDefinition(
pluginAnalyzedFileUri, lsp.Position(line: 0, character: 0));
expect(res, hasLength(1)); expect(res, hasLength(1));
var loc = res.single; var loc = res.single;
expect( expect(
loc.range, equals(lsp.Range(lsp.Position(0, 0), lsp.Position(0, 5)))); loc.range,
equals(lsp.Range(
start: lsp.Position(line: 0, character: 0),
end: lsp.Position(line: 0, character: 5))));
expect(loc.uri, equals(pluginAnalyzedFileUri.toString())); expect(loc.uri, equals(pluginAnalyzedFileUri.toString()));
} }

View file

@ -139,7 +139,7 @@ void f() {
// Send a request for a hover. // Send a request for a hover.
await initialize(); await initialize();
await getHover(dotFolderFileUri, Position(0, 0)); await getHover(dotFolderFileUri, Position(line: 0, character: 0));
// Ensure that as part of responding to getHover, diagnostics were not // Ensure that as part of responding to getHover, diagnostics were not
// transmitted. // transmitted.

View file

@ -32,15 +32,17 @@ class Bar {
await changeFile(2, mainFileUri, [ await changeFile(2, mainFileUri, [
Either2<TextDocumentContentChangeEvent1, Either2<TextDocumentContentChangeEvent1,
TextDocumentContentChangeEvent2>.t1(TextDocumentContentChangeEvent1( TextDocumentContentChangeEvent2>.t1(TextDocumentContentChangeEvent1(
Range(Position(0, 6), Position(0, 9)), range: Range(
0, start: Position(line: 0, character: 6),
'Bar', end: Position(line: 0, character: 9)),
text: 'Bar',
)), )),
Either2<TextDocumentContentChangeEvent1, Either2<TextDocumentContentChangeEvent1,
TextDocumentContentChangeEvent2>.t1(TextDocumentContentChangeEvent1( TextDocumentContentChangeEvent2>.t1(TextDocumentContentChangeEvent1(
Range(Position(1, 21), Position(1, 24)), range: Range(
0, start: Position(line: 1, character: 21),
'updated', end: Position(line: 1, character: 24)),
text: 'updated',
)), )),
]); ]);
@ -58,15 +60,17 @@ class Bar {
await changeFile(2, mainFileUri, [ await changeFile(2, mainFileUri, [
Either2<TextDocumentContentChangeEvent1, Either2<TextDocumentContentChangeEvent1,
TextDocumentContentChangeEvent2>.t1(TextDocumentContentChangeEvent1( TextDocumentContentChangeEvent2>.t1(TextDocumentContentChangeEvent1(
Range(Position(0, 6), Position(0, 9)), range: Range(
0, start: Position(line: 0, character: 6),
'Bar', end: Position(line: 0, character: 9)),
text: 'Bar',
)), )),
Either2<TextDocumentContentChangeEvent1, Either2<TextDocumentContentChangeEvent1,
TextDocumentContentChangeEvent2>.t1(TextDocumentContentChangeEvent1( TextDocumentContentChangeEvent2>.t1(TextDocumentContentChangeEvent1(
Range(Position(1, 21), Position(1, 24)), range: Range(
0, start: Position(line: 1, character: 21),
'updated', end: Position(line: 1, character: 24)),
text: 'updated',
)), )),
]); ]);

View file

@ -29,9 +29,10 @@ class FileModificationTest extends AbstractLspAnalysisServerTest {
await changeFile(222, mainFileUri, [ await changeFile(222, mainFileUri, [
Either2<TextDocumentContentChangeEvent1, Either2<TextDocumentContentChangeEvent1,
TextDocumentContentChangeEvent2>.t1(TextDocumentContentChangeEvent1( TextDocumentContentChangeEvent2>.t1(TextDocumentContentChangeEvent1(
Range(Position(999, 999), Position(999, 999)), range: Range(
null, start: Position(line: 999, character: 999),
' ', end: Position(line: 999, character: 999)),
text: ' ',
)) ))
]); ]);
}); });
@ -62,9 +63,10 @@ class FileModificationTest extends AbstractLspAnalysisServerTest {
// Replace line1:5-1:8 with spaces. // Replace line1:5-1:8 with spaces.
Either2<TextDocumentContentChangeEvent1, Either2<TextDocumentContentChangeEvent1,
TextDocumentContentChangeEvent2>.t1(TextDocumentContentChangeEvent1( TextDocumentContentChangeEvent2>.t1(TextDocumentContentChangeEvent1(
Range(Position(1, 5), Position(1, 8)), range: Range(
null, start: Position(line: 1, character: 5),
' ', end: Position(line: 1, character: 8)),
text: ' ',
)) ))
]); ]);
expect(_getOverlay(mainFilePath), equals(expectedUpdatedContent)); expect(_getOverlay(mainFilePath), equals(expectedUpdatedContent));
@ -79,9 +81,10 @@ class FileModificationTest extends AbstractLspAnalysisServerTest {
// ensure it generates an obvious error that the user can understand. // ensure it generates an obvious error that the user can understand.
final simpleEdit = Either2<TextDocumentContentChangeEvent1, final simpleEdit = Either2<TextDocumentContentChangeEvent1,
TextDocumentContentChangeEvent2>.t1(TextDocumentContentChangeEvent1( TextDocumentContentChangeEvent2>.t1(TextDocumentContentChangeEvent1(
Range(Position(1, 1), Position(1, 1)), range: Range(
null, start: Position(line: 1, character: 1),
'test', end: Position(line: 1, character: 1)),
text: 'test',
)); ));
await initialize(); await initialize();
final notificationParams = await expectErrorNotification<ShowMessageParams>( final notificationParams = await expectErrorNotification<ShowMessageParams>(

View file

@ -88,18 +88,33 @@ Widget build(BuildContext context) => Container(
expect(outline, isNotNull); expect(outline, isNotNull);
// Root node is entire document // Root node is entire document
expect(outline.range, equals(Range(Position(0, 0), Position(15, 0)))); expect(
outline.range,
equals(Range(
start: Position(line: 0, character: 0),
end: Position(line: 15, character: 0))));
expect(outline.children, hasLength(1)); expect(outline.children, hasLength(1));
final build = outline.children[0]; final build = outline.children[0];
expect(build.kind, equals('DART_ELEMENT')); expect(build.kind, equals('DART_ELEMENT'));
expect(build.range, equals(Range(Position(2, 0), Position(14, 6)))); expect(
expect(build.codeRange, equals(Range(Position(3, 0), Position(14, 6)))); build.range,
equals(Range(
start: Position(line: 2, character: 0),
end: Position(line: 14, character: 6))));
expect(
build.codeRange,
equals(Range(
start: Position(line: 3, character: 0),
end: Position(line: 14, character: 6))));
expect(build.dartElement.kind, equals('FUNCTION')); expect(build.dartElement.kind, equals('FUNCTION'));
expect(build.dartElement.name, equals('build')); expect(build.dartElement.name, equals('build'));
expect(build.dartElement.parameters, equals('(BuildContext context)')); expect(build.dartElement.parameters, equals('(BuildContext context)'));
expect(build.dartElement.range, expect(
equals(Range(Position(3, 7), Position(3, 12)))); build.dartElement.range,
equals(Range(
start: Position(line: 3, character: 7),
end: Position(line: 3, character: 12))));
expect(build.dartElement.returnType, equals('Widget')); expect(build.dartElement.returnType, equals('Widget'));
expect(build.children, hasLength(1)); expect(build.children, hasLength(1));
@ -107,13 +122,20 @@ Widget build(BuildContext context) => Container(
build.children[0].children[0].children[0].children[0].children[0]; build.children[0].children[0].children[0].children[0].children[0];
expect(icon.kind, equals('NEW_INSTANCE')); expect(icon.kind, equals('NEW_INSTANCE'));
expect(icon.className, 'Icon'); expect(icon.className, 'Icon');
expect(icon.range, equals(Range(Position(8, 31), Position(8, 50)))); expect(
icon.range,
equals(Range(
start: Position(line: 8, character: 31),
end: Position(line: 8, character: 50))));
expect(icon.codeRange, equals(icon.range)); expect(icon.codeRange, equals(icon.range));
expect(icon.attributes, hasLength(1)); expect(icon.attributes, hasLength(1));
expect(icon.attributes[0].name, equals('icon')); expect(icon.attributes[0].name, equals('icon'));
expect(icon.attributes[0].label, equals('Icons.ac_unit')); expect(icon.attributes[0].label, equals('Icons.ac_unit'));
expect(icon.attributes[0].valueRange, expect(
equals(Range(Position(8, 36), Position(8, 49)))); icon.attributes[0].valueRange,
equals(Range(
start: Position(line: 8, character: 36),
end: Position(line: 8, character: 49))));
expect(icon.dartElement, isNull); expect(icon.dartElement, isNull);
expect(icon.children, hasLength(0)); expect(icon.children, hasLength(0));
} }

View file

@ -28,11 +28,10 @@ class FoldingTest extends AbstractLspAnalysisServerTest {
final range1 = rangeFromMarkers(content); final range1 = rangeFromMarkers(content);
final expectedRegions = [ final expectedRegions = [
FoldingRange( FoldingRange(
range1.start.line, startLine: range1.start.line,
range1.start.character, startCharacter: range1.start.character,
range1.end.line, endLine: range1.end.line,
range1.end.character, endCharacter: range1.end.character,
null,
) )
]; ];
@ -53,11 +52,11 @@ class FoldingTest extends AbstractLspAnalysisServerTest {
final range1 = rangeFromMarkers(content); final range1 = rangeFromMarkers(content);
final expectedRegions = [ final expectedRegions = [
FoldingRange( FoldingRange(
range1.start.line, startLine: range1.start.line,
range1.start.character, startCharacter: range1.start.character,
range1.end.line, endLine: range1.end.line,
range1.end.character, endCharacter: range1.end.character,
FoldingRangeKind.Comment, kind: FoldingRangeKind.Comment,
) )
]; ];
@ -91,11 +90,10 @@ class FoldingTest extends AbstractLspAnalysisServerTest {
final ranges = rangesFromMarkers(content); final ranges = rangesFromMarkers(content);
final expectedRegions = ranges final expectedRegions = ranges
.map((range) => FoldingRange( .map((range) => FoldingRange(
range.start.line, startLine: range.start.line,
range.start.character, startCharacter: range.start.character,
range.end.line, endLine: range.end.line,
range.end.character, endCharacter: range.end.character,
null,
)) ))
.toList(); .toList();
@ -219,11 +217,10 @@ class FoldingTest extends AbstractLspAnalysisServerTest {
final ranges = rangesFromMarkers(content); final ranges = rangesFromMarkers(content);
final expectedRegions = ranges final expectedRegions = ranges
.map((range) => FoldingRange( .map((range) => FoldingRange(
range.start.line, startLine: range.start.line,
range.start.character, startCharacter: range.start.character,
range.end.line, endLine: range.end.line,
range.end.character, endCharacter: range.end.character,
null,
)) ))
.toList(); .toList();
@ -265,11 +262,10 @@ class FoldingTest extends AbstractLspAnalysisServerTest {
final ranges = rangesFromMarkers(content); final ranges = rangesFromMarkers(content);
final expectedRegions = ranges final expectedRegions = ranges
.map((range) => FoldingRange( .map((range) => FoldingRange(
range.start.line, startLine: range.start.line,
range.start.character, startCharacter: range.start.character,
range.end.line, endLine: range.end.line,
range.end.character, endCharacter: range.end.character,
null,
)) ))
.toList(); .toList();
@ -282,11 +278,11 @@ class FoldingTest extends AbstractLspAnalysisServerTest {
FoldingRange _toFoldingRange(Range range, FoldingRangeKind kind) { FoldingRange _toFoldingRange(Range range, FoldingRangeKind kind) {
return FoldingRange( return FoldingRange(
range.start.line, startLine: range.start.line,
range.start.character, startCharacter: range.start.character,
range.end.line, endLine: range.end.line,
range.end.character, endCharacter: range.end.character,
kind, kind: kind,
); );
} }
} }

View file

@ -43,7 +43,7 @@ class HoverTest extends AbstractLspAnalysisServerTest {
await initialize(); await initialize();
await openFile(mainFileUri, ''); await openFile(mainFileUri, '');
await expectLater( await expectLater(
() => getHover(mainFileUri, Position(999, 999)), () => getHover(mainFileUri, Position(line: 999, character: 999)),
throwsA(isResponseError(ServerErrorCodes.InvalidFileLineCol)), throwsA(isResponseError(ServerErrorCodes.InvalidFileLineCol)),
); );
} }

View file

@ -173,7 +173,7 @@ class ImplementationTest extends AbstractLspAnalysisServerTest {
); );
final expectedLocations = rangesFromMarkers(content) final expectedLocations = rangesFromMarkers(content)
.map((r) => Location(mainFileUri.toString(), r)); .map((r) => Location(uri: mainFileUri.toString(), range: r));
if (shouldMatch) { if (shouldMatch) {
expect(res, equals(expectedLocations)); expect(res, equals(expectedLocations));

View file

@ -237,8 +237,9 @@ class InitializationTest extends AbstractLspAnalysisServerTest {
final registrations = (request.params as RegistrationParams).registrations; final registrations = (request.params as RegistrationParams).registrations;
final documentFilterSql = DocumentFilter(null, 'file', '**/*.sql'); final documentFilterSql =
final documentFilterDart = DocumentFilter('dart', 'file', null); DocumentFilter(scheme: 'file', pattern: '**/*.sql');
final documentFilterDart = DocumentFilter(language: 'dart', scheme: 'file');
final expectedFoldingRegistration = final expectedFoldingRegistration =
isA<TextDocumentRegistrationOptions>().having( isA<TextDocumentRegistrationOptions>().having(
(o) => o.documentSelector, (o) => o.documentSelector,
@ -279,10 +280,10 @@ class InitializationTest extends AbstractLspAnalysisServerTest {
Future<void> test_initialize_invalidParams() async { Future<void> test_initialize_invalidParams() async {
final params = {'processId': 'invalid'}; final params = {'processId': 'invalid'};
final request = RequestMessage( final request = RequestMessage(
Either2<num, String>.t1(1), id: Either2<num, String>.t1(1),
Method.initialize, method: Method.initialize,
params, params: params,
jsonRpcVersion, jsonrpc: jsonRpcVersion,
); );
final response = await sendRequestToServer(request); final response = await sendRequestToServer(request);
expect(response.id, equals(request.id)); expect(response.id, equals(request.id));

View file

@ -78,16 +78,32 @@ class A {
expect(outline, isNotNull); expect(outline, isNotNull);
// Root node is entire document // Root node is entire document
expect(outline.range, equals(Range(Position(0, 0), Position(11, 0)))); expect(
outline.range,
equals(Range(
start: Position(line: 0, character: 0),
end: Position(line: 11, character: 0))));
expect(outline.children, hasLength(1)); expect(outline.children, hasLength(1));
// class A // class A
final classA = outline.children[0]; final classA = outline.children[0];
expect(classA.element.name, equals('A')); expect(classA.element.name, equals('A'));
expect(classA.element.kind, equals('CLASS')); expect(classA.element.kind, equals('CLASS'));
expect(classA.element.range, equals(Range(Position(1, 6), Position(1, 7)))); expect(
expect(classA.range, equals(Range(Position(0, 0), Position(10, 1)))); classA.element.range,
expect(classA.codeRange, equals(Range(Position(1, 0), Position(10, 1)))); equals(Range(
start: Position(line: 1, character: 6),
end: Position(line: 1, character: 7))));
expect(
classA.range,
equals(Range(
start: Position(line: 0, character: 0),
end: Position(line: 10, character: 1))));
expect(
classA.codeRange,
equals(Range(
start: Position(line: 1, character: 0),
end: Position(line: 10, character: 1))));
expect(classA.children, hasLength(2)); expect(classA.children, hasLength(2));
// b() // b()
@ -95,9 +111,20 @@ class A {
expect(methodB.element.name, equals('b')); expect(methodB.element.name, equals('b'));
expect(methodB.element.kind, equals('METHOD')); expect(methodB.element.kind, equals('METHOD'));
expect( expect(
methodB.element.range, equals(Range(Position(3, 2), Position(3, 3)))); methodB.element.range,
expect(methodB.range, equals(Range(Position(2, 2), Position(6, 3)))); equals(Range(
expect(methodB.codeRange, equals(Range(Position(3, 2), Position(6, 3)))); start: Position(line: 3, character: 2),
end: Position(line: 3, character: 3))));
expect(
methodB.range,
equals(Range(
start: Position(line: 2, character: 2),
end: Position(line: 6, character: 3))));
expect(
methodB.codeRange,
equals(Range(
start: Position(line: 3, character: 2),
end: Position(line: 6, character: 3))));
expect(methodB.children, hasLength(1)); expect(methodB.children, hasLength(1));
// c() // c()
@ -105,12 +132,23 @@ class A {
expect(methodC.element.name, equals('c')); expect(methodC.element.name, equals('c'));
expect(methodC.element.kind, equals('FUNCTION')); expect(methodC.element.kind, equals('FUNCTION'));
expect( expect(
methodC.element.range, equals(Range(Position(5, 4), Position(5, 5)))); methodC.element.range,
equals(Range(
start: Position(line: 5, character: 4),
end: Position(line: 5, character: 5))));
// TODO(dantup): This one seems to be excluding its dartdoc? // TODO(dantup): This one seems to be excluding its dartdoc?
// should be line 4 for the starting range. // should be line 4 for the starting range.
// https://github.com/dart-lang/sdk/issues/39746 // https://github.com/dart-lang/sdk/issues/39746
expect(methodC.range, equals(Range(Position(5, 4), Position(5, 10)))); expect(
expect(methodC.codeRange, equals(Range(Position(5, 4), Position(5, 10)))); methodC.range,
equals(Range(
start: Position(line: 5, character: 4),
end: Position(line: 5, character: 10))));
expect(
methodC.codeRange,
equals(Range(
start: Position(line: 5, character: 4),
end: Position(line: 5, character: 10))));
expect(methodC.children, isNull); expect(methodC.children, isNull);
// num get d // num get d
@ -118,9 +156,20 @@ class A {
expect(fieldD.element.name, equals('d')); expect(fieldD.element.name, equals('d'));
expect(fieldD.element.kind, equals('GETTER')); expect(fieldD.element.kind, equals('GETTER'));
expect( expect(
fieldD.element.range, equals(Range(Position(9, 10), Position(9, 11)))); fieldD.element.range,
expect(fieldD.range, equals(Range(Position(8, 2), Position(9, 17)))); equals(Range(
expect(fieldD.codeRange, equals(Range(Position(9, 2), Position(9, 17)))); start: Position(line: 9, character: 10),
end: Position(line: 9, character: 11))));
expect(
fieldD.range,
equals(Range(
start: Position(line: 8, character: 2),
end: Position(line: 9, character: 17))));
expect(
fieldD.codeRange,
equals(Range(
start: Position(line: 9, character: 2),
end: Position(line: 9, character: 17))));
expect(fieldD.children, isNull); expect(fieldD.children, isNull);
} }
} }

View file

@ -54,12 +54,14 @@ class ReferencesTest extends AbstractLspAnalysisServerTest {
expect(res, hasLength(2)); expect(res, hasLength(2));
expect( expect(
res, res,
contains( contains(Location(
Location(mainFileUri.toString(), rangeFromMarkers(mainContents)))); uri: mainFileUri.toString(),
range: rangeFromMarkers(mainContents))));
expect( expect(
res, res,
contains(Location(referencedFileUri.toString(), contains(Location(
rangeFromMarkers(referencedContents)))); uri: referencedFileUri.toString(),
range: rangeFromMarkers(referencedContents))));
} }
Future<void> test_acrossFiles_withoutDeclaration() async { Future<void> test_acrossFiles_withoutDeclaration() async {
@ -122,7 +124,8 @@ class ReferencesTest extends AbstractLspAnalysisServerTest {
expect( expect(
res, res,
contains( contains(
Location(mainFileUri.toString(), rangeFromMarkers(contents)), Location(
uri: mainFileUri.toString(), range: rangeFromMarkers(contents)),
), ),
); );
} }
@ -142,7 +145,8 @@ class ReferencesTest extends AbstractLspAnalysisServerTest {
expect( expect(
res, res,
contains( contains(
Location(mainFileUri.toString(), rangeFromMarkers(contents)), Location(
uri: mainFileUri.toString(), range: rangeFromMarkers(contents)),
), ),
); );
} }

View file

@ -80,8 +80,8 @@ class RenameTest extends AbstractLspAnalysisServerTest {
final request = makeRequest( final request = makeRequest(
Method.textDocument_prepareRename, Method.textDocument_prepareRename,
TextDocumentPositionParams( TextDocumentPositionParams(
TextDocumentIdentifier(mainFileUri.toString()), textDocument: TextDocumentIdentifier(uri: mainFileUri.toString()),
positionFromMarker(content), position: positionFromMarker(content),
), ),
); );
final response = await channel.sendRequestToServer(request); final response = await channel.sendRequestToServer(request);
@ -296,10 +296,9 @@ class RenameTest extends AbstractLspAnalysisServerTest {
final request = makeRequest( final request = makeRequest(
Method.textDocument_rename, Method.textDocument_rename,
RenameParams( RenameParams(
'Object2', newName: 'Object2',
TextDocumentIdentifier(mainFileUri.toString()), textDocument: TextDocumentIdentifier(uri: mainFileUri.toString()),
positionFromMarker(content), position: positionFromMarker(content),
null,
), ),
); );
final response = await channel.sendRequestToServer(request); final response = await channel.sendRequestToServer(request);

View file

@ -35,7 +35,9 @@ const dartLanguageId = 'dart';
/// communication to be printed to stdout. /// communication to be printed to stdout.
const debugPrintCommunication = false; const debugPrintCommunication = false;
final beginningOfDocument = Range(Position(0, 0), Position(0, 0)); final beginningOfDocument = Range(
start: Position(line: 0, character: 0),
end: Position(line: 0, character: 0));
abstract class AbstractLspAnalysisServerTest abstract class AbstractLspAnalysisServerTest
with with
@ -145,32 +147,9 @@ abstract class AbstractLspAnalysisServerTest
} }
mixin ClientCapabilitiesHelperMixin { mixin ClientCapabilitiesHelperMixin {
final emptyTextDocumentClientCapabilities = TextDocumentClientCapabilities( final emptyTextDocumentClientCapabilities = TextDocumentClientCapabilities();
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null);
final emptyWorkspaceClientCapabilities = ClientCapabilitiesWorkspace( final emptyWorkspaceClientCapabilities = ClientCapabilitiesWorkspace();
null, null, null, null, null, null, null, null);
TextDocumentClientCapabilities extendTextDocumentCapabilities( TextDocumentClientCapabilities extendTextDocumentCapabilities(
TextDocumentClientCapabilities source, TextDocumentClientCapabilities source,
@ -371,8 +350,10 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
String projectFolderPath, mainFilePath, pubspecFilePath, analysisOptionsPath; String projectFolderPath, mainFilePath, pubspecFilePath, analysisOptionsPath;
Uri projectFolderUri, mainFileUri, pubspecFileUri, analysisOptionsUri; Uri projectFolderUri, mainFileUri, pubspecFileUri, analysisOptionsUri;
final String simplePubspecContent = 'name: my_project'; final String simplePubspecContent = 'name: my_project';
final startOfDocPos = Position(0, 0); final startOfDocPos = Position(line: 0, character: 0);
final startOfDocRange = Range(Position(0, 0), Position(0, 0)); final startOfDocRange = Range(
start: Position(line: 0, character: 0),
end: Position(line: 0, character: 0));
/// A stream of [NotificationMessage]s from the server that may be errors. /// A stream of [NotificationMessage]s from the server that may be errors.
Stream<NotificationMessage> get errorNotificationsFromServer { Stream<NotificationMessage> get errorNotificationsFromServer {
@ -523,8 +504,9 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
var notification = makeNotification( var notification = makeNotification(
Method.textDocument_didChange, Method.textDocument_didChange,
DidChangeTextDocumentParams( DidChangeTextDocumentParams(
VersionedTextDocumentIdentifier(newVersion, uri.toString()), textDocument: VersionedTextDocumentIdentifier(
changes, version: newVersion, uri: uri.toString()),
contentChanges: changes,
), ),
); );
await sendNotificationToServer(notification); await sendNotificationToServer(notification);
@ -534,9 +516,9 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
var notification = makeNotification( var notification = makeNotification(
Method.workspace_didChangeWorkspaceFolders, Method.workspace_didChangeWorkspaceFolders,
DidChangeWorkspaceFoldersParams( DidChangeWorkspaceFoldersParams(
WorkspaceFoldersChangeEvent( event: WorkspaceFoldersChangeEvent(
add?.map(toWorkspaceFolder)?.toList() ?? const [], added: add?.map(toWorkspaceFolder)?.toList() ?? const [],
remove?.map(toWorkspaceFolder)?.toList() ?? const [], removed: remove?.map(toWorkspaceFolder)?.toList() ?? const [],
), ),
), ),
); );
@ -546,7 +528,8 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
Future closeFile(Uri uri) async { Future closeFile(Uri uri) async {
var notification = makeNotification( var notification = makeNotification(
Method.textDocument_didClose, Method.textDocument_didClose,
DidCloseTextDocumentParams(TextDocumentIdentifier(uri.toString())), DidCloseTextDocumentParams(
textDocument: TextDocumentIdentifier(uri: uri.toString())),
); );
await sendNotificationToServer(notification); await sendNotificationToServer(notification);
} }
@ -555,9 +538,8 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
final request = makeRequest( final request = makeRequest(
Method.workspace_executeCommand, Method.workspace_executeCommand,
ExecuteCommandParams( ExecuteCommandParams(
command.command, command: command.command,
command.arguments, arguments: command.arguments,
null,
), ),
); );
return expectSuccessfulResponseTo(request); return expectSuccessfulResponseTo(request);
@ -651,10 +633,10 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
final request = makeRequest( final request = makeRequest(
Method.textDocument_formatting, Method.textDocument_formatting,
DocumentFormattingParams( DocumentFormattingParams(
TextDocumentIdentifier(fileUri), textDocument: TextDocumentIdentifier(uri: fileUri),
FormattingOptions( options: FormattingOptions(
2, true, false, false, false), // These currently don't do anything tabSize: 2,
null, insertSpaces: true), // These currently don't do anything
), ),
); );
return expectSuccessfulResponseTo(request); return expectSuccessfulResponseTo(request);
@ -665,11 +647,12 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
final request = makeRequest( final request = makeRequest(
Method.textDocument_onTypeFormatting, Method.textDocument_onTypeFormatting,
DocumentOnTypeFormattingParams( DocumentOnTypeFormattingParams(
character, ch: character,
FormattingOptions( options: FormattingOptions(
2, true, false, false, false), // These currently don't do anything tabSize: 2,
TextDocumentIdentifier(fileUri), insertSpaces: true), // These currently don't do anything
pos, textDocument: TextDocumentIdentifier(uri: fileUri),
position: pos,
), ),
); );
return expectSuccessfulResponseTo(request); return expectSuccessfulResponseTo(request);
@ -683,14 +666,12 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
final request = makeRequest( final request = makeRequest(
Method.textDocument_codeAction, Method.textDocument_codeAction,
CodeActionParams( CodeActionParams(
TextDocumentIdentifier(fileUri), textDocument: TextDocumentIdentifier(uri: fileUri),
range ?? beginningOfDocument, range: range ?? beginningOfDocument,
// TODO(dantup): We may need to revise the tests/implementation when // TODO(dantup): We may need to revise the tests/implementation when
// it's clear how we're supposed to handle diagnostics: // it's clear how we're supposed to handle diagnostics:
// https://github.com/Microsoft/language-server-protocol/issues/583 // https://github.com/Microsoft/language-server-protocol/issues/583
CodeActionContext([], kinds), context: CodeActionContext(diagnostics: [], only: kinds),
null,
null,
), ),
); );
return expectSuccessfulResponseTo(request); return expectSuccessfulResponseTo(request);
@ -701,11 +682,9 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
final request = makeRequest( final request = makeRequest(
Method.textDocument_completion, Method.textDocument_completion,
CompletionParams( CompletionParams(
context, context: context,
TextDocumentIdentifier(uri.toString()), textDocument: TextDocumentIdentifier(uri: uri.toString()),
pos, position: pos,
null,
null,
), ),
); );
return expectSuccessfulResponseTo<List<CompletionItem>>(request); return expectSuccessfulResponseTo<List<CompletionItem>>(request);
@ -715,8 +694,8 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
final request = makeRequest( final request = makeRequest(
Method.textDocument_definition, Method.textDocument_definition,
TextDocumentPositionParams( TextDocumentPositionParams(
TextDocumentIdentifier(uri.toString()), textDocument: TextDocumentIdentifier(uri: uri.toString()),
pos, position: pos,
), ),
); );
return expectSuccessfulResponseTo<List<Location>>(request); return expectSuccessfulResponseTo<List<Location>>(request);
@ -734,8 +713,8 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
final request = makeRequest( final request = makeRequest(
Method.textDocument_documentHighlight, Method.textDocument_documentHighlight,
TextDocumentPositionParams( TextDocumentPositionParams(
TextDocumentIdentifier(uri.toString()), textDocument: TextDocumentIdentifier(uri: uri.toString()),
pos, position: pos,
), ),
); );
return expectSuccessfulResponseTo<List<DocumentHighlight>>(request); return expectSuccessfulResponseTo<List<DocumentHighlight>>(request);
@ -746,9 +725,7 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
final request = makeRequest( final request = makeRequest(
Method.textDocument_documentSymbol, Method.textDocument_documentSymbol,
DocumentSymbolParams( DocumentSymbolParams(
TextDocumentIdentifier(fileUri), textDocument: TextDocumentIdentifier(uri: fileUri),
null,
null,
), ),
); );
return expectSuccessfulResponseTo(request); return expectSuccessfulResponseTo(request);
@ -758,9 +735,7 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
final request = makeRequest( final request = makeRequest(
Method.textDocument_foldingRange, Method.textDocument_foldingRange,
FoldingRangeParams( FoldingRangeParams(
TextDocumentIdentifier(uri.toString()), textDocument: TextDocumentIdentifier(uri: uri.toString()),
null,
null,
), ),
); );
return expectSuccessfulResponseTo<List<FoldingRange>>(request); return expectSuccessfulResponseTo<List<FoldingRange>>(request);
@ -769,7 +744,9 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
Future<Hover> getHover(Uri uri, Position pos) { Future<Hover> getHover(Uri uri, Position pos) {
final request = makeRequest( final request = makeRequest(
Method.textDocument_hover, Method.textDocument_hover,
TextDocumentPositionParams(TextDocumentIdentifier(uri.toString()), pos), TextDocumentPositionParams(
textDocument: TextDocumentIdentifier(uri: uri.toString()),
position: pos),
); );
return expectSuccessfulResponseTo<Hover>(request); return expectSuccessfulResponseTo<Hover>(request);
} }
@ -782,8 +759,8 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
final request = makeRequest( final request = makeRequest(
Method.textDocument_implementation, Method.textDocument_implementation,
TextDocumentPositionParams( TextDocumentPositionParams(
TextDocumentIdentifier(uri.toString()), textDocument: TextDocumentIdentifier(uri: uri.toString()),
pos, position: pos,
), ),
); );
return expectSuccessfulResponseTo<List<Location>>(request); return expectSuccessfulResponseTo<List<Location>>(request);
@ -797,11 +774,9 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
final request = makeRequest( final request = makeRequest(
Method.textDocument_references, Method.textDocument_references,
ReferenceParams( ReferenceParams(
ReferenceContext(includeDeclarations), context: ReferenceContext(includeDeclaration: includeDeclarations),
TextDocumentIdentifier(uri.toString()), textDocument: TextDocumentIdentifier(uri: uri.toString()),
pos, position: pos,
null,
null,
), ),
); );
return expectSuccessfulResponseTo<List<Location>>(request); return expectSuccessfulResponseTo<List<Location>>(request);
@ -811,8 +786,8 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
final request = makeRequest( final request = makeRequest(
Method.textDocument_signatureHelp, Method.textDocument_signatureHelp,
TextDocumentPositionParams( TextDocumentPositionParams(
TextDocumentIdentifier(uri.toString()), textDocument: TextDocumentIdentifier(uri: uri.toString()),
pos, position: pos,
), ),
); );
return expectSuccessfulResponseTo<SignatureHelp>(request); return expectSuccessfulResponseTo<SignatureHelp>(request);
@ -825,8 +800,8 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
final request = makeRequest( final request = makeRequest(
CustomMethods.Super, CustomMethods.Super,
TextDocumentPositionParams( TextDocumentPositionParams(
TextDocumentIdentifier(uri.toString()), textDocument: TextDocumentIdentifier(uri: uri.toString()),
pos, position: pos,
), ),
); );
return expectSuccessfulResponseTo<Location>(request); return expectSuccessfulResponseTo<Location>(request);
@ -835,11 +810,7 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
Future<List<SymbolInformation>> getWorkspaceSymbols(String query) { Future<List<SymbolInformation>> getWorkspaceSymbols(String query) {
final request = makeRequest( final request = makeRequest(
Method.workspace_symbol, Method.workspace_symbol,
WorkspaceSymbolParams( WorkspaceSymbolParams(query: query),
query,
null,
null,
),
); );
return expectSuccessfulResponseTo(request); return expectSuccessfulResponseTo(request);
} }
@ -910,20 +881,15 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
final request = makeRequest( final request = makeRequest(
Method.initialize, Method.initialize,
InitializeParams( InitializeParams(
null, rootPath: rootPath,
null, rootUri: rootUri?.toString(),
rootPath, initializationOptions: initializationOptions,
rootUri?.toString(), capabilities: ClientCapabilities(
initializationOptions, workspace: workspaceCapabilities,
ClientCapabilities( textDocument: textDocumentCapabilities,
workspaceCapabilities, window: windowCapabilities,
textDocumentCapabilities,
windowCapabilities,
null,
), ),
null, workspaceFolders: workspaceFolders?.map(toWorkspaceFolder)?.toList(),
workspaceFolders?.map(toWorkspaceFolder)?.toList(),
null,
)); ));
final response = await sendRequestToServer(request); final response = await sendRequestToServer(request);
expect(response.id, equals(request.id)); expect(response.id, equals(request.id));
@ -942,24 +908,27 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
} }
NotificationMessage makeNotification(Method method, ToJsonable params) { NotificationMessage makeNotification(Method method, ToJsonable params) {
return NotificationMessage(method, params, jsonRpcVersion); return NotificationMessage(
method: method, params: params, jsonrpc: jsonRpcVersion);
} }
RequestMessage makeRenameRequest( RequestMessage makeRenameRequest(
int version, Uri uri, Position pos, String newName) { int version, Uri uri, Position pos, String newName) {
final docIdentifier = version != null final docIdentifier = version != null
? VersionedTextDocumentIdentifier(version, uri.toString()) ? VersionedTextDocumentIdentifier(version: version, uri: uri.toString())
: TextDocumentIdentifier(uri.toString()); : TextDocumentIdentifier(uri: uri.toString());
final request = makeRequest( final request = makeRequest(
Method.textDocument_rename, Method.textDocument_rename,
RenameParams(newName, docIdentifier, pos, null), RenameParams(
newName: newName, textDocument: docIdentifier, position: pos),
); );
return request; return request;
} }
RequestMessage makeRequest(Method method, ToJsonable params) { RequestMessage makeRequest(Method method, ToJsonable params) {
final id = Either2<num, String>.t1(_id++); final id = Either2<num, String>.t1(_id++);
return RequestMessage(id, method, params, jsonRpcVersion); return RequestMessage(
id: id, method: method, params: params, jsonrpc: jsonRpcVersion);
} }
/// Watches for `client/registerCapability` requests and updates /// Watches for `client/registerCapability` requests and updates
@ -998,7 +967,11 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
var notification = makeNotification( var notification = makeNotification(
Method.textDocument_didOpen, Method.textDocument_didOpen,
DidOpenTextDocumentParams( DidOpenTextDocumentParams(
TextDocumentItem(uri.toString(), dartLanguageId, version, content)), textDocument: TextDocumentItem(
uri: uri.toString(),
languageId: dartLanguageId,
version: version,
text: content)),
); );
await sendNotificationToServer(notification); await sendNotificationToServer(notification);
await pumpEventQueue(); await pumpEventQueue();
@ -1026,8 +999,8 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
final request = makeRequest( final request = makeRequest(
Method.textDocument_prepareRename, Method.textDocument_prepareRename,
TextDocumentPositionParams( TextDocumentPositionParams(
TextDocumentIdentifier(uri.toString()), textDocument: TextDocumentIdentifier(uri: uri.toString()),
pos, position: pos,
), ),
); );
return expectSuccessfulResponseTo<RangeAndPlaceholder>(request); return expectSuccessfulResponseTo<RangeAndPlaceholder>(request);
@ -1078,9 +1051,9 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
throw 'Found unclosed range starting at offset $startMarker'; throw 'Found unclosed range starting at offset $startMarker';
} }
yield Range( yield Range(
positionFromOffset( start: positionFromOffset(
startMarker + offsetForEarlierMarkers, contentsWithoutMarkers), startMarker + offsetForEarlierMarkers, contentsWithoutMarkers),
positionFromOffset( end: positionFromOffset(
endMarker + offsetForEarlierMarkers - rangeMarkerStart.length, endMarker + offsetForEarlierMarkers - rangeMarkerStart.length,
contentsWithoutMarkers), contentsWithoutMarkers),
); );
@ -1123,7 +1096,7 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
[ [
Either2<TextDocumentContentChangeEvent1, Either2<TextDocumentContentChangeEvent1,
TextDocumentContentChangeEvent2>.t2( TextDocumentContentChangeEvent2>.t2(
TextDocumentContentChangeEvent2(content)) TextDocumentContentChangeEvent2(text: content))
], ],
); );
} }
@ -1139,14 +1112,14 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
/// Sends [responseParams] to the server as a successful response to /// Sends [responseParams] to the server as a successful response to
/// a server-initiated [request]. /// a server-initiated [request].
void respondTo<T>(RequestMessage request, T responseParams) { void respondTo<T>(RequestMessage request, T responseParams) {
sendResponseToServer( sendResponseToServer(ResponseMessage(
ResponseMessage(request.id, responseParams, null, jsonRpcVersion)); id: request.id, result: responseParams, jsonrpc: jsonRpcVersion));
} }
Future<ResponseMessage> sendDidChangeConfiguration() { Future<ResponseMessage> sendDidChangeConfiguration() {
final request = makeRequest( final request = makeRequest(
Method.workspace_didChangeConfiguration, Method.workspace_didChangeConfiguration,
DidChangeConfigurationParams(null), DidChangeConfigurationParams(),
); );
return sendRequestToServer(request); return sendRequestToServer(request);
} }
@ -1168,7 +1141,10 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
} }
WorkspaceFolder toWorkspaceFolder(Uri uri) { WorkspaceFolder toWorkspaceFolder(Uri uri) {
return WorkspaceFolder(uri.toString(), path.basename(uri.toFilePath())); return WorkspaceFolder(
uri: uri.toString(),
name: path.basename(uri.toFilePath()),
);
} }
/// Tells the server the config has changed, and provides the supplied config /// Tells the server the config has changed, and provides the supplied config

View file

@ -27,7 +27,10 @@ class ServerTest extends AbstractLspAnalysisServerTest {
Either2<TextDocumentContentChangeEvent1, Either2<TextDocumentContentChangeEvent1,
TextDocumentContentChangeEvent2>.t1( TextDocumentContentChangeEvent2>.t1(
TextDocumentContentChangeEvent1( TextDocumentContentChangeEvent1(
Range(Position(99, 99), Position(99, 99)), null, ' ')), range: Range(
start: Position(line: 99, character: 99),
end: Position(line: 99, character: 99)),
text: ' ')),
]); ]);
}); });

View file

@ -40,8 +40,8 @@ class SignatureHelpTest extends AbstractLspAnalysisServerTest {
expectedLabel, expectedLabel,
expectedDoc, expectedDoc,
[ [
ParameterInformation('String s', null), ParameterInformation(label: 'String s'),
ParameterInformation('int i', null), ParameterInformation(label: 'int i'),
], ],
expectedFormat: null, expectedFormat: null,
); );
@ -66,8 +66,8 @@ class SignatureHelpTest extends AbstractLspAnalysisServerTest {
expectedLabel, expectedLabel,
expectedDoc, expectedDoc,
[ [
ParameterInformation('String s', null), ParameterInformation(label: 'String s'),
ParameterInformation('int i', null), ParameterInformation(label: 'int i'),
], ],
expectedFormat: MarkupKind.Markdown, expectedFormat: MarkupKind.Markdown,
); );
@ -90,8 +90,8 @@ class SignatureHelpTest extends AbstractLspAnalysisServerTest {
expectedLabel, expectedLabel,
expectedDoc, expectedDoc,
[ [
ParameterInformation('String s', null), ParameterInformation(label: 'String s'),
ParameterInformation('int i', null), ParameterInformation(label: 'int i'),
], ],
expectedFormat: null, expectedFormat: null,
); );
@ -116,8 +116,8 @@ class SignatureHelpTest extends AbstractLspAnalysisServerTest {
expectedLabel, expectedLabel,
expectedDoc, expectedDoc,
[ [
ParameterInformation('String s', null), ParameterInformation(label: 'String s'),
ParameterInformation('int i', null), ParameterInformation(label: 'int i'),
], ],
expectedFormat: MarkupKind.PlainText, expectedFormat: MarkupKind.PlainText,
); );
@ -146,8 +146,8 @@ class SignatureHelpTest extends AbstractLspAnalysisServerTest {
expectedLabel, expectedLabel,
expectedDoc, expectedDoc,
[ [
ParameterInformation('String s', null), ParameterInformation(label: 'String s'),
ParameterInformation('int i', null), ParameterInformation(label: 'int i'),
], ],
expectedFormat: MarkupKind.Markdown, expectedFormat: MarkupKind.Markdown,
); );
@ -182,9 +182,9 @@ class SignatureHelpTest extends AbstractLspAnalysisServerTest {
expectedLabel, expectedLabel,
expectedDoc, expectedDoc,
[ [
ParameterInformation('String s', null), ParameterInformation(label: 'String s'),
ParameterInformation('bool b = true', null), ParameterInformation(label: 'bool b = true'),
ParameterInformation('bool a', null), ParameterInformation(label: 'bool a'),
], ],
); );
} }
@ -209,9 +209,9 @@ class SignatureHelpTest extends AbstractLspAnalysisServerTest {
expectedLabel, expectedLabel,
expectedDoc, expectedDoc,
[ [
ParameterInformation('String s', null), ParameterInformation(label: 'String s'),
ParameterInformation('bool b = true', null), ParameterInformation(label: 'bool b = true'),
ParameterInformation('bool a', null), ParameterInformation(label: 'bool a'),
], ],
); );
} }
@ -236,8 +236,8 @@ class SignatureHelpTest extends AbstractLspAnalysisServerTest {
expectedLabel, expectedLabel,
expectedDoc, expectedDoc,
[ [
ParameterInformation('String s', null), ParameterInformation(label: 'String s'),
ParameterInformation('bool b = true', null), ParameterInformation(label: 'bool b = true'),
], ],
); );
} }
@ -262,8 +262,8 @@ class SignatureHelpTest extends AbstractLspAnalysisServerTest {
expectedLabel, expectedLabel,
expectedDoc, expectedDoc,
[ [
ParameterInformation('String s', null), ParameterInformation(label: 'String s'),
ParameterInformation('bool b = true', null), ParameterInformation(label: 'bool b = true'),
], ],
); );
} }
@ -287,8 +287,8 @@ class SignatureHelpTest extends AbstractLspAnalysisServerTest {
expectedLabel, expectedLabel,
expectedDoc, expectedDoc,
[ [
ParameterInformation('String s', null), ParameterInformation(label: 'String s'),
ParameterInformation('int i', null), ParameterInformation(label: 'int i'),
], ],
); );
} }
@ -312,8 +312,8 @@ class SignatureHelpTest extends AbstractLspAnalysisServerTest {
expectedLabel, expectedLabel,
expectedDoc, expectedDoc,
[ [
ParameterInformation('String s', null), ParameterInformation(label: 'String s'),
ParameterInformation('int i', null), ParameterInformation(label: 'int i'),
], ],
); );
} }
@ -345,7 +345,7 @@ class SignatureHelpTest extends AbstractLspAnalysisServerTest {
// Plain string. // Plain string.
expect(doc.valueEquals(expectedDoc), isTrue); expect(doc.valueEquals(expectedDoc), isTrue);
} else { } else {
final expected = MarkupContent(expectedFormat, expectedDoc); final expected = MarkupContent(kind: expectedFormat, value: expectedDoc);
expect(doc.valueEquals(expected), isTrue); expect(doc.valueEquals(expected), isTrue);
} }
} }

View file

@ -31,8 +31,10 @@ class C^ extends B {}
positionFromMarker(content), positionFromMarker(content),
); );
expect(res, expect(
equals(Location(mainFileUri.toString(), rangeFromMarkers(content)))); res,
equals(Location(
uri: mainFileUri.toString(), range: rangeFromMarkers(content))));
} }
Future<void> test_insideClass() async { Future<void> test_insideClass() async {
@ -52,8 +54,10 @@ class C extends B {
positionFromMarker(content), positionFromMarker(content),
); );
expect(res, expect(
equals(Location(mainFileUri.toString(), rangeFromMarkers(content)))); res,
equals(Location(
uri: mainFileUri.toString(), range: rangeFromMarkers(content))));
} }
Future<void> test_insideMethod() async { Future<void> test_insideMethod() async {
@ -78,8 +82,10 @@ class C extends B {
positionFromMarker(content), positionFromMarker(content),
); );
expect(res, expect(
equals(Location(mainFileUri.toString(), rangeFromMarkers(content)))); res,
equals(Location(
uri: mainFileUri.toString(), range: rangeFromMarkers(content))));
} }
Future<void> test_methodName() async { Future<void> test_methodName() async {
@ -104,8 +110,10 @@ class C extends B {
positionFromMarker(content), positionFromMarker(content),
); );
expect(res, expect(
equals(Location(mainFileUri.toString(), rangeFromMarkers(content)))); res,
equals(Location(
uri: mainFileUri.toString(), range: rangeFromMarkers(content))));
} }
Future<void> test_methodReturnType() async { Future<void> test_methodReturnType() async {
@ -130,7 +138,9 @@ class C extends B {
positionFromMarker(content), positionFromMarker(content),
); );
expect(res, expect(
equals(Location(mainFileUri.toString(), rangeFromMarkers(content)))); res,
equals(Location(
uri: mainFileUri.toString(), range: rangeFromMarkers(content))));
} }
} }

View file

@ -91,10 +91,10 @@ class WorkspaceSymbolsTest extends AbstractLspAnalysisServerTest {
// Create a request that doesn't supply the query param. // Create a request that doesn't supply the query param.
final request = RequestMessage( final request = RequestMessage(
Either2<num, String>.t1(1), id: Either2<num, String>.t1(1),
Method.workspace_symbol, method: Method.workspace_symbol,
<String, dynamic>{}, params: <String, dynamic>{},
jsonRpcVersion, jsonrpc: jsonRpcVersion,
); );
final response = await sendRequestToServer(request); final response = await sendRequestToServer(request);

View file

@ -9,8 +9,8 @@ import 'package:test/test.dart';
void main() { void main() {
group('generated classes', () { group('generated classes', () {
test('can be checked for equality', () { test('can be checked for equality', () {
final a = TextDocumentIdentifier('/a'); final a = TextDocumentIdentifier(uri: '/a');
final b = TextDocumentIdentifier('/a'); final b = TextDocumentIdentifier(uri: '/a');
expect(a, equals(b)); expect(a, equals(b));
expect(a.hashCode, equals(b.hashCode)); expect(a.hashCode, equals(b.hashCode));
@ -18,10 +18,10 @@ void main() {
test('with list fields can be checked for equality', () { test('with list fields can be checked for equality', () {
final a = CodeActionClientCapabilitiesCodeActionKind( final a = CodeActionClientCapabilitiesCodeActionKind(
[CodeActionKind.QuickFix], valueSet: [CodeActionKind.QuickFix],
); );
final b = CodeActionClientCapabilitiesCodeActionKind( final b = CodeActionClientCapabilitiesCodeActionKind(
[CodeActionKind.QuickFix], valueSet: [CodeActionKind.QuickFix],
); );
expect(a, equals(b)); expect(a, equals(b));
@ -30,21 +30,33 @@ void main() {
test('with aliased list fields can be checked for equality', () { test('with aliased list fields can be checked for equality', () {
final a = TextDocumentRegistrationOptions( final a = TextDocumentRegistrationOptions(
[DocumentFilter('dart', 'file', null)]); documentSelector: [DocumentFilter(language: 'dart', scheme: 'file')]);
final b = TextDocumentRegistrationOptions( final b = TextDocumentRegistrationOptions(
[DocumentFilter('dart', 'file', null)]); documentSelector: [DocumentFilter(language: 'dart', scheme: 'file')]);
expect(a, equals(b)); expect(a, equals(b));
expect(a.hashCode, equals(b.hashCode)); expect(a.hashCode, equals(b.hashCode));
}); });
test('with map fields can be checked for equality', () { test('with map fields can be checked for equality', () {
final a = WorkspaceEdit({ final a = WorkspaceEdit(changes: {
'a': [TextEdit(Range(Position(0, 0), Position(0, 0)), 'a')] 'a': [
}, null); TextEdit(
final b = WorkspaceEdit({ range: Range(
'a': [TextEdit(Range(Position(0, 0), Position(0, 0)), 'a')] start: Position(line: 0, character: 0),
}, null); end: Position(line: 0, character: 0)),
newText: 'a')
]
});
final b = WorkspaceEdit(changes: {
'a': [
TextEdit(
range: Range(
start: Position(line: 0, character: 0),
end: Position(line: 0, character: 0)),
newText: 'a')
]
});
expect(a, equals(b)); expect(a, equals(b));
expect(a.hashCode, equals(b.hashCode)); expect(a.hashCode, equals(b.hashCode));
@ -59,10 +71,14 @@ void main() {
}); });
test('with union fields can be checked for equality', () { test('with union fields can be checked for equality', () {
final a = final a = SignatureInformation(
SignatureInformation('a', Either2<String, MarkupContent>.t1('a'), []); label: 'a',
final b = documentation: Either2<String, MarkupContent>.t1('a'),
SignatureInformation('a', Either2<String, MarkupContent>.t1('a'), []); parameters: []);
final b = SignatureInformation(
label: 'a',
documentation: Either2<String, MarkupContent>.t1('a'),
parameters: []);
expect(a, equals(b)); expect(a, equals(b));
expect(a.hashCode, equals(b.hashCode)); expect(a.hashCode, equals(b.hashCode));
@ -70,9 +86,10 @@ void main() {
test('consider subclasses when checking for equality', () { test('consider subclasses when checking for equality', () {
final a = TextDocumentRegistrationOptions( final a = TextDocumentRegistrationOptions(
[DocumentFilter('dart', 'file', null)]); documentSelector: [DocumentFilter(language: 'dart', scheme: 'file')]);
final b = TextDocumentSaveRegistrationOptions( final b = TextDocumentSaveRegistrationOptions(
true, [DocumentFilter('dart', 'file', null)]); includeText: true,
documentSelector: [DocumentFilter(language: 'dart', scheme: 'file')]);
expect(a, isNot(equals(b))); expect(a, isNot(equals(b)));
expect(b, isNot(equals(a))); expect(b, isNot(equals(a)));

View file

@ -20,15 +20,17 @@ void main() {
test('returns correct output for union types', () { test('returns correct output for union types', () {
final message = RequestMessage( final message = RequestMessage(
Either2<num, String>.t1(1), Method.shutdown, null, 'test'); id: Either2<num, String>.t1(1),
method: Method.shutdown,
jsonrpc: 'test');
final output = json.encode(message.toJson()); final output = json.encode(message.toJson());
expect(output, equals('{"id":1,"method":"shutdown","jsonrpc":"test"}')); expect(output, equals('{"id":1,"method":"shutdown","jsonrpc":"test"}'));
}); });
test('returns correct output for union types containing interface types', test('returns correct output for union types containing interface types',
() { () {
final params = Either2<String, TextDocumentItem>.t2( final params = Either2<String, TextDocumentItem>.t2(TextDocumentItem(
TextDocumentItem('!uri', '!language', 1, '!text')); uri: '!uri', languageId: '!language', version: 1, text: '!text'));
final output = json.encode(params); final output = json.encode(params);
expect( expect(
output, output,
@ -37,18 +39,19 @@ void main() {
}); });
test('returns correct output for types with lists', () { test('returns correct output for types with lists', () {
final start = Position(1, 1); final start = Position(line: 1, character: 1);
final end = Position(2, 2); final end = Position(line: 2, character: 2);
final range = Range(start, end); final range = Range(start: start, end: end);
final location = Location('y-uri', range); final location = Location(uri: 'y-uri', range: range);
final codeAction = Diagnostic( final codeAction = Diagnostic(
range, range: range,
DiagnosticSeverity.Error, severity: DiagnosticSeverity.Error,
'test_err', code: 'test_err',
'/tmp/source.dart', source: '/tmp/source.dart',
'err!!', message: 'err!!',
null, relatedInformation: [
[DiagnosticRelatedInformation(location, 'message')], DiagnosticRelatedInformation(location: location, message: 'message')
],
); );
final output = json.encode(codeAction.toJson()); final output = json.encode(codeAction.toJson());
final expected = '''{ final expected = '''{
@ -78,7 +81,12 @@ void main() {
}); });
test('serialises enums to their underlying values', () { test('serialises enums to their underlying values', () {
final foldingRange = FoldingRange(1, 2, 3, 4, FoldingRangeKind.Comment); final foldingRange = FoldingRange(
startLine: 1,
startCharacter: 2,
endLine: 3,
endCharacter: 4,
kind: FoldingRangeKind.Comment);
final output = json.encode(foldingRange.toJson()); final output = json.encode(foldingRange.toJson());
final expected = '''{ final expected = '''{
"startLine":1, "startLine":1,
@ -94,7 +102,8 @@ void main() {
test('ResponseMessage does not include an error with a result', () { test('ResponseMessage does not include an error with a result', () {
final id = Either2<num, String>.t1(1); final id = Either2<num, String>.t1(1);
final result = 'my result'; final result = 'my result';
final resp = ResponseMessage(id, result, null, jsonRpcVersion); final resp =
ResponseMessage(id: id, result: result, jsonrpc: jsonRpcVersion);
final jsonMap = resp.toJson(); final jsonMap = resp.toJson();
expect(jsonMap, contains('result')); expect(jsonMap, contains('result'));
expect(jsonMap, isNot(contains('error'))); expect(jsonMap, isNot(contains('error')));
@ -237,7 +246,7 @@ void main() {
test('ResponseMessage can include a null result', () { test('ResponseMessage can include a null result', () {
final id = Either2<num, String>.t1(1); final id = Either2<num, String>.t1(1);
final resp = ResponseMessage(id, null, null, jsonRpcVersion); final resp = ResponseMessage(id: id, jsonrpc: jsonRpcVersion);
final jsonMap = resp.toJson(); final jsonMap = resp.toJson();
expect(jsonMap, contains('result')); expect(jsonMap, contains('result'));
expect(jsonMap, isNot(contains('error'))); expect(jsonMap, isNot(contains('error')));
@ -245,8 +254,10 @@ void main() {
test('ResponseMessage does not include a result for an error', () { test('ResponseMessage does not include a result for an error', () {
final id = Either2<num, String>.t1(1); final id = Either2<num, String>.t1(1);
final error = ResponseError(ErrorCodes.ParseError, 'Error', null); final error =
final resp = ResponseMessage(id, null, error, jsonRpcVersion); ResponseError(code: ErrorCodes.ParseError, message: 'Error');
final resp =
ResponseMessage(id: id, error: error, jsonrpc: jsonRpcVersion);
final jsonMap = resp.toJson(); final jsonMap = resp.toJson();
expect(jsonMap, contains('error')); expect(jsonMap, contains('error'));
expect(jsonMap, isNot(contains('result'))); expect(jsonMap, isNot(contains('result')));
@ -255,8 +266,10 @@ void main() {
test('ResponseMessage throws if both result and error are non-null', () { test('ResponseMessage throws if both result and error are non-null', () {
final id = Either2<num, String>.t1(1); final id = Either2<num, String>.t1(1);
final result = 'my result'; final result = 'my result';
final error = ResponseError(ErrorCodes.ParseError, 'Error', null); final error =
final resp = ResponseMessage(id, result, error, jsonRpcVersion); ResponseError(code: ErrorCodes.ParseError, message: 'Error');
final resp = ResponseMessage(
id: id, result: result, error: error, jsonrpc: jsonRpcVersion);
expect(resp.toJson, throwsA(TypeMatcher<String>())); expect(resp.toJson, throwsA(TypeMatcher<String>()));
}); });
}); });
@ -296,8 +309,9 @@ void main() {
// Create some JSON that includes a VersionedTextDocumentIdenfitier but // Create some JSON that includes a VersionedTextDocumentIdenfitier but
// where the class definition only references a TextDocumentIdemntifier. // where the class definition only references a TextDocumentIdemntifier.
final input = jsonEncode(TextDocumentPositionParams( final input = jsonEncode(TextDocumentPositionParams(
VersionedTextDocumentIdentifier(111, 'file:///foo/bar.dart'), textDocument: VersionedTextDocumentIdentifier(
Position(1, 1), version: 111, uri: 'file:///foo/bar.dart'),
position: Position(line: 1, character: 1),
).toJson()); ).toJson());
final params = TextDocumentPositionParams.fromJson(jsonDecode(input)); final params = TextDocumentPositionParams.fromJson(jsonDecode(input));
expect(params.textDocument, expect(params.textDocument,
@ -317,18 +331,16 @@ void main() {
test('objects with lists can round-trip through to json and back', () { test('objects with lists can round-trip through to json and back', () {
final obj = InitializeParams( final obj = InitializeParams(
1, processId: 1,
InitializeParamsClientInfo('server name', '1.2.3'), clientInfo:
'!root', InitializeParamsClientInfo(name: 'server name', version: '1.2.3'),
null, rootPath: '!root',
null, capabilities: ClientCapabilities(),
ClientCapabilities(null, null, null, null), trace: '!trace',
'!trace', workspaceFolders: [
[ WorkspaceFolder(uri: '!uri1', name: '!name1'),
WorkspaceFolder('!uri1', '!name1'), WorkspaceFolder(uri: '!uri2', name: '!name2'),
WorkspaceFolder('!uri2', '!name2'),
], ],
null,
); );
final json = jsonEncode(obj); final json = jsonEncode(obj);
final restoredObj = InitializeParams.fromJson(jsonDecode(json)); final restoredObj = InitializeParams.fromJson(jsonDecode(json));
@ -344,7 +356,12 @@ void main() {
}); });
test('objects with enums can round-trip through to json and back', () { test('objects with enums can round-trip through to json and back', () {
final obj = FoldingRange(1, 2, 3, 4, FoldingRangeKind.Comment); final obj = FoldingRange(
startLine: 1,
startCharacter: 2,
endLine: 3,
endCharacter: 4,
kind: FoldingRangeKind.Comment);
final json = jsonEncode(obj); final json = jsonEncode(obj);
final restoredObj = FoldingRange.fromJson(jsonDecode(json)); final restoredObj = FoldingRange.fromJson(jsonDecode(json));
@ -356,13 +373,13 @@ void main() {
}); });
test('objects with maps can round-trip through to json and back', () { test('objects with maps can round-trip through to json and back', () {
final start = Position(1, 1); final start = Position(line: 1, character: 1);
final end = Position(2, 2); final end = Position(line: 2, character: 2);
final range = Range(start, end); final range = Range(start: start, end: end);
final obj = WorkspaceEdit(<String, List<TextEdit>>{ final obj = WorkspaceEdit(changes: <String, List<TextEdit>>{
'fileA': [TextEdit(range, 'text A')], 'fileA': [TextEdit(range: range, newText: 'text A')],
'fileB': [TextEdit(range, 'text B')] 'fileB': [TextEdit(range: range, newText: 'text B')]
}, null); });
final json = jsonEncode(obj); final json = jsonEncode(obj);
final restoredObj = WorkspaceEdit.fromJson(jsonDecode(json)); final restoredObj = WorkspaceEdit.fromJson(jsonDecode(json));

View file

@ -258,9 +258,13 @@ void _writeConstructor(IndentableStringBuffer buffer, Interface interface) {
return; return;
} }
buffer buffer
..writeIndented('${interface.name}(') ..writeIndented('${interface.name}({')
..write(allFields.map((field) => 'this.${field.name}').join(', ')) ..write(allFields.map((field) {
..write(')'); final annotation =
!field.allowsNull && !field.allowsUndefined ? '@required' : '';
return '$annotation this.${field.name}';
}).join(', '))
..write('})');
final fieldsWithValidation = final fieldsWithValidation =
allFields.where((f) => !f.allowsNull && !f.allowsUndefined).toList(); allFields.where((f) => !f.allowsNull && !f.allowsUndefined).toList();
if (fieldsWithValidation.isNotEmpty) { if (fieldsWithValidation.isNotEmpty) {
@ -522,7 +526,7 @@ void _writeFromJsonConstructor(
} }
buffer buffer
..writeIndented('return ${interface.nameWithTypeArgs}(') ..writeIndented('return ${interface.nameWithTypeArgs}(')
..write(allFields.map((field) => '${field.name}').join(', ')) ..write(allFields.map((field) => '${field.name}: ${field.name}').join(', '))
..writeln(');') ..writeln(');')
..outdent() ..outdent()
..writeIndented('}'); ..writeIndented('}');

View file

@ -176,6 +176,7 @@ import 'package:analysis_server/src/lsp/json_parsing.dart';
import 'package:analysis_server/src/protocol/protocol_internal.dart' import 'package:analysis_server/src/protocol/protocol_internal.dart'
show listEqual, mapEqual; show listEqual, mapEqual;
import 'package:analyzer/src/generated/utilities_general.dart'; import 'package:analyzer/src/generated/utilities_general.dart';
import 'package:meta/meta.dart';
const jsonEncoder = JsonEncoder.withIndent(' '); const jsonEncoder = JsonEncoder.withIndent(' ');