[Analyzer] Make LSP literal types optional in constructors and validate their values
Change-Id: Id6dddd4ed4819a75da4226ee57d73a65c15c9048
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/164965
Commit-Queue: Danny Tuppeny <danny@tuppeny.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
index daf702f..6578de6 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
@@ -4897,9 +4897,9 @@
static const jsonHandler =
LspJsonHandler(CreateFile.canParse, CreateFile.fromJson);
- CreateFile({@required this.kind, @required this.uri, this.options}) {
- if (kind == null) {
- throw 'kind is required but was not provided';
+ CreateFile({this.kind = 'create', @required this.uri, this.options}) {
+ if (kind != 'create') {
+ throw 'kind may only be the literal \'create\'';
}
if (uri == null) {
throw 'uri is required but was not provided';
@@ -5922,9 +5922,9 @@
static const jsonHandler =
LspJsonHandler(DeleteFile.canParse, DeleteFile.fromJson);
- DeleteFile({@required this.kind, @required this.uri, this.options}) {
- if (kind == null) {
- throw 'kind is required but was not provided';
+ DeleteFile({this.kind = 'delete', @required this.uri, this.options}) {
+ if (kind != 'delete') {
+ throw 'kind may only be the literal \'delete\'';
}
if (uri == null) {
throw 'uri is required but was not provided';
@@ -16615,12 +16615,12 @@
LspJsonHandler(RenameFile.canParse, RenameFile.fromJson);
RenameFile(
- {@required this.kind,
+ {this.kind = 'rename',
@required this.oldUri,
@required this.newUri,
this.options}) {
- if (kind == null) {
- throw 'kind is required but was not provided';
+ if (kind != 'rename') {
+ throw 'kind may only be the literal \'rename\'';
}
if (oldUri == null) {
throw 'oldUri is required but was not provided';
@@ -23768,13 +23768,13 @@
WorkDoneProgressBegin.canParse, WorkDoneProgressBegin.fromJson);
WorkDoneProgressBegin(
- {@required this.kind,
+ {this.kind = 'begin',
@required this.title,
this.cancellable,
this.message,
this.percentage}) {
- if (kind == null) {
- throw 'kind is required but was not provided';
+ if (kind != 'begin') {
+ throw 'kind may only be the literal \'begin\'';
}
if (title == null) {
throw 'title is required but was not provided';
@@ -24088,9 +24088,9 @@
static const jsonHandler = LspJsonHandler(
WorkDoneProgressEnd.canParse, WorkDoneProgressEnd.fromJson);
- WorkDoneProgressEnd({@required this.kind, this.message}) {
- if (kind == null) {
- throw 'kind is required but was not provided';
+ WorkDoneProgressEnd({this.kind = 'end', this.message}) {
+ if (kind != 'end') {
+ throw 'kind may only be the literal \'end\'';
}
}
static WorkDoneProgressEnd fromJson(Map<String, dynamic> json) {
@@ -24433,9 +24433,9 @@
WorkDoneProgressReport.canParse, WorkDoneProgressReport.fromJson);
WorkDoneProgressReport(
- {@required this.kind, this.cancellable, this.message, this.percentage}) {
- if (kind == null) {
- throw 'kind is required but was not provided';
+ {this.kind = 'report', this.cancellable, this.message, this.percentage}) {
+ if (kind != 'report') {
+ throw 'kind may only be the literal \'report\'';
}
}
static WorkDoneProgressReport fromJson(Map<String, dynamic> json) {
diff --git a/pkg/analysis_server/lib/src/lsp/constants.dart b/pkg/analysis_server/lib/src/lsp/constants.dart
index 57febf1..b65a4ca 100644
--- a/pkg/analysis_server/lib/src/lsp/constants.dart
+++ b/pkg/analysis_server/lib/src/lsp/constants.dart
@@ -49,10 +49,9 @@
/// Characters to trigger formatting when format-on-type is enabled.
const dartTypeFormattingCharacters = ['}', ';'];
-final analyzingProgressBegin =
- WorkDoneProgressBegin(kind: 'begin', title: 'Analyzing…');
+final analyzingProgressBegin = WorkDoneProgressBegin(title: 'Analyzing…');
-final analyzingProgressEnd = WorkDoneProgressEnd(kind: 'end');
+final analyzingProgressEnd = WorkDoneProgressEnd();
/// A [ProgressToken] used for reporting progress when the server is analyzing.
final analyzingProgressToken = Either2<num, String>.t2('ANALYZING');
diff --git a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
index 415f142..b911615 100644
--- a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
+++ b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
@@ -272,25 +272,42 @@
buffer
..writeIndented('${interface.name}({')
..write(allFields.map((field) {
- final annotation =
- !field.allowsNull && !field.allowsUndefined ? '@required' : '';
- return '$annotation this.${field.name}';
+ final isLiteral = field.type is LiteralType;
+ final isRequired =
+ !isLiteral && !field.allowsNull && !field.allowsUndefined;
+ final annotation = isRequired ? '@required' : '';
+ final valueCode =
+ isLiteral ? ' = ${(field.type as LiteralType).literal}' : '';
+ return '$annotation this.${field.name}$valueCode';
}).join(', '))
..write('})');
- final fieldsWithValidation =
- allFields.where((f) => !f.allowsNull && !f.allowsUndefined).toList();
+ final fieldsWithValidation = allFields
+ .where(
+ (f) => (!f.allowsNull && !f.allowsUndefined) || f.type is LiteralType)
+ .toList();
if (fieldsWithValidation.isNotEmpty) {
buffer
..writeIndentedln(' {')
..indent();
for (var field in fieldsWithValidation) {
- buffer
- ..writeIndentedln('if (${field.name} == null) {')
- ..indent()
- ..writeIndentedln(
- "throw '${field.name} is required but was not provided';")
- ..outdent()
- ..writeIndentedln('}');
+ final type = field.type;
+ if (type is LiteralType) {
+ buffer
+ ..writeIndentedln('if (${field.name} != ${type.literal}) {')
+ ..indent()
+ ..writeIndentedln(
+ "throw '${field.name} may only be the literal ${type.literal.replaceAll("'", "\\'")}';")
+ ..outdent()
+ ..writeIndentedln('}');
+ } else if (!field.allowsNull && !field.allowsUndefined) {
+ buffer
+ ..writeIndentedln('if (${field.name} == null) {')
+ ..indent()
+ ..writeIndentedln(
+ "throw '${field.name} is required but was not provided';")
+ ..outdent()
+ ..writeIndentedln('}');
+ }
}
buffer
..outdent()