Files
sdk/pkg/analysis_server/tool/spec/codegen_protocol_constants.dart
Paul Berry afcfbbeba8 Migrate developer experience packages to new constructor decl syntax.
(Part of https://github.com/dart-lang/sdk/issues/63288)

This change migrates the packages owned by the developer experience
team to use the new constructor declaration syntax, described in
https://github.com/dart-lang/language/blob/main/accepted/future-releases/primary-constructors/feature-specification.md#abbreviations-of-in-body-constructor-declarations.

This change was performed in an automated fashion, by (a) bumping the
packages' SDK constraints to `3.13.0-0`, (b) enabling the lints
`unnecessary_type_name_in_constructor` and
`unnecessary_const_in_enum_constructor`, (c) fixing the resulting lint
failures using `dart fix`, and then (d) reformatting the affected
files.

To ease code review, I've reverted unrelated formatting changes.

Since this change requires bumping SDK constaints to `3.13.0-0`, it
was only performed on packages that are *not* published on
pub. (Packages that *are* published on pub should remain on lower
language versions until at least after the stable version of 3.13 is
released, so that we don't block users on the stable channel from
receiving updates to those packages.)

Change-Id: Ibb4daebafd239da58251e838ea6a3f336a6a6964
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/505046
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
SLSA-Policy-Verified: SLSA Policy Verification Service <devtools-gerritcodereview-exitgate@google.com>
2026-05-27 14:52:58 -07:00

161 lines
5.0 KiB
Dart

// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer_utilities/tools.dart';
import 'api.dart';
import 'codegen_dart.dart';
import 'from_html.dart';
final GeneratedFile clientTarget = GeneratedFile(
'analysis_server_client/lib/src/protocol/protocol_constants.dart',
(pkgRoot) async {
var visitor = _CodegenVisitor(readApi(pkgRoot));
return visitor.collectCode(visitor.visitApi);
},
);
final GeneratedFile serverTarget = GeneratedFile(
'analysis_server/lib/protocol/protocol_constants.dart',
(pkgRoot) async {
var visitor = _CodegenVisitor(readApi(pkgRoot));
return visitor.collectCode(visitor.visitApi);
},
);
final _upperCaseLettersPattern = RegExp('[A-Z]');
/// Generate a name from the [domainName], [kind] and [name] components.
String generateConstName(String domainName, String kind, String name) {
return _fromComponents([..._split(domainName), kind, ..._split(name)]);
}
/// Returns a name generated by converting each of the given [components] to an
/// uppercase equivalent, then joining them with underscores.
String _fromComponents(List<String> components) {
var joinedName = components
.map((s) => '${s[0].toUpperCase()}${s.substring(1)}')
.join();
return '${joinedName[0].toLowerCase()}${joinedName.substring(1)}';
}
/// Returns the components of the given String that are indicated by an upper
/// case letter.
Iterable<String> _split(String first) {
var components = <String>[];
var start = 1;
var index = first.indexOf(_upperCaseLettersPattern, start);
while (index >= 0) {
components.add(first.substring(start - 1, index));
start = index + 1;
index = first.indexOf(_upperCaseLettersPattern, start);
}
components.add(first.substring(start - 1));
return components;
}
/// A visitor that produces Dart code defining constants associated with the
/// API.
class _CodegenVisitor extends DartCodegenVisitor with CodeGenerator {
new(super.api) {
codeGeneratorSettings.commentLineLength = 79;
codeGeneratorSettings.docCommentStartMarker = null;
codeGeneratorSettings.docCommentLineLeader = '/// ';
codeGeneratorSettings.docCommentEndMarker = null;
codeGeneratorSettings.languageName = 'dart';
}
/// Generate the given [constant].
void generateConstant(_Constant constant) {
write('const String ');
write(constant.name);
write(' = ');
write(constant.value);
writeln(';');
}
/// Generate all of the constants associated with the [api].
void generateConstants() {
writeln('// ignore: constant_identifier_names');
writeln("const String PROTOCOL_VERSION = '${api.version}';");
writeln();
var visitor = _ConstantVisitor(api);
visitor.visitApi();
var constants = visitor.constants;
constants.sort((first, second) => first.name.compareTo(second.name));
for (var constant in constants) {
generateConstant(constant);
}
}
@override
void visitApi() {
outputHeader(year: '2017');
writeln();
generateConstants();
}
}
/// A representation of a constant that is to be generated.
class _Constant {
/// The name of the constant.
final String name;
/// The value of the constant.
final String value;
/// Initialize a newly created constant.
new(this.name, this.value);
}
/// A visitor that visits an API to compute a list of constants to be generated.
class _ConstantVisitor extends HierarchicalApiVisitor {
/// The list of constants to be generated.
List<_Constant> constants = <_Constant>[];
/// Initialize a newly created visitor to visit the given [api].
new(super.api);
@override
void visitNotification(Notification notification) {
var domainName = notification.domainName;
var event = notification.event;
var constantName = generateConstName(domainName, 'notification', event);
constants.add(_Constant(constantName, "'$domainName.$event'"));
_addFieldConstants(constantName, notification.params);
}
@override
void visitRequest(Request request) {
var domainName = request.domainName;
var method = request.method;
var requestConstantName = generateConstName(domainName, 'request', method);
constants.add(_Constant(requestConstantName, "'$domainName.$method'"));
_addFieldConstants(requestConstantName, request.params);
var responseConstantName = generateConstName(
domainName,
'response',
method,
);
_addFieldConstants(responseConstantName, request.result);
}
/// Generate a constant for each of the fields in the given [type], where the
/// name of each constant will be composed from the [parentName] and the name
/// of the field.
void _addFieldConstants(String parentName, TypeObject? type) {
if (type == null) {
return;
}
for (var field in type.fields) {
var name = field.name;
var fieldConstantName = _fromComponents([parentName, ..._split(name)]);
constants.add(_Constant(fieldConstantName, "'$name'"));
}
}
}