afcfbbeba8
(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>
192 lines
5.2 KiB
Dart
192 lines
5.2 KiB
Dart
// Copyright (c) 2014, 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.
|
|
|
|
/// Code generation for the file "matchers.dart".
|
|
library;
|
|
|
|
import 'package:analyzer_utilities/tools.dart';
|
|
|
|
import 'api.dart';
|
|
import 'from_html.dart';
|
|
import 'implied_types.dart';
|
|
import 'to_html.dart';
|
|
|
|
final GeneratedFile target = GeneratedFile(
|
|
'analysis_server/integration_test/support/protocol_matchers.dart',
|
|
(pkgRoot) async {
|
|
var visitor = CodegenMatchersVisitor(readApi(pkgRoot));
|
|
return visitor.collectCode(visitor.visitApi);
|
|
},
|
|
);
|
|
|
|
class CodegenMatchersVisitor extends HierarchicalApiVisitor with CodeGenerator {
|
|
/// Visitor used to produce doc comments.
|
|
final ToHtmlVisitor toHtmlVisitor;
|
|
|
|
/// Short human-readable string describing the context of the matcher being
|
|
/// created.
|
|
late String context;
|
|
|
|
new(super.api) : toHtmlVisitor = ToHtmlVisitor(api) {
|
|
codeGeneratorSettings.commentLineLength = 79;
|
|
codeGeneratorSettings.docCommentStartMarker = null;
|
|
codeGeneratorSettings.docCommentLineLeader = '/// ';
|
|
codeGeneratorSettings.docCommentEndMarker = null;
|
|
codeGeneratorSettings.languageName = 'dart';
|
|
}
|
|
|
|
/// Create a matcher for the part of the API called [name], optionally
|
|
/// clarified by [nameSuffix]. The matcher should verify that its input
|
|
/// matches the given [type].
|
|
void makeMatcher(ImpliedType impliedType) {
|
|
context = impliedType.humanReadableName;
|
|
var impliedTypeType = impliedType.type;
|
|
docComment(
|
|
toHtmlVisitor.collectHtml(() {
|
|
toHtmlVisitor.p(() {
|
|
toHtmlVisitor.write(context);
|
|
});
|
|
if (impliedTypeType != null) {
|
|
toHtmlVisitor.showType(null, impliedTypeType);
|
|
}
|
|
}),
|
|
);
|
|
write('final Matcher ${camelJoin(['is', impliedType.camelName])} = ');
|
|
if (impliedTypeType == null) {
|
|
write('isNull');
|
|
} else {
|
|
visitTypeDecl(impliedTypeType);
|
|
}
|
|
writeln(';');
|
|
writeln();
|
|
}
|
|
|
|
/// Generate a map describing the given set of fields, for use as the
|
|
/// 'requiredFields' or 'optionalFields' argument to the [MatchesJsonObject]
|
|
/// constructor.
|
|
void outputObjectFields(Iterable<TypeObjectField> fields) {
|
|
if (fields.isEmpty) {
|
|
write('null');
|
|
return;
|
|
}
|
|
writeln('{');
|
|
indent(() {
|
|
var commaNeeded = false;
|
|
for (var field in fields) {
|
|
if (commaNeeded) {
|
|
writeln(',');
|
|
}
|
|
write("'${field.name}': ");
|
|
if (field.value != null) {
|
|
write("equals('${field.value}')");
|
|
} else {
|
|
visitTypeDecl(field.type);
|
|
}
|
|
commaNeeded = true;
|
|
}
|
|
writeln();
|
|
});
|
|
write('}');
|
|
}
|
|
|
|
@override
|
|
void visitApi() {
|
|
outputHeader(year: '2017');
|
|
writeln();
|
|
writeln('/// Matchers for data types defined in the analysis server API.');
|
|
writeln('library;');
|
|
writeln();
|
|
writeln("import 'package:test/test.dart';");
|
|
writeln();
|
|
writeln("import 'integration_tests.dart';");
|
|
writeln();
|
|
writeln('// ignore_for_file: flutter_style_todos');
|
|
writeln();
|
|
var impliedTypes = computeImpliedTypes(api).values.toList();
|
|
impliedTypes.sort(
|
|
(ImpliedType first, ImpliedType second) =>
|
|
first.camelName.compareTo(second.camelName),
|
|
);
|
|
for (var impliedType in impliedTypes) {
|
|
makeMatcher(impliedType);
|
|
}
|
|
}
|
|
|
|
@override
|
|
void visitTypeEnum(TypeEnum typeEnum) {
|
|
writeln("MatchesEnum('$context', [");
|
|
indent(() {
|
|
var commaNeeded = false;
|
|
for (var value in typeEnum.values) {
|
|
if (commaNeeded) {
|
|
writeln(',');
|
|
}
|
|
write("'${value.value}'");
|
|
commaNeeded = true;
|
|
}
|
|
writeln();
|
|
});
|
|
write('])');
|
|
}
|
|
|
|
@override
|
|
void visitTypeList(TypeList typeList) {
|
|
write('isListOf(');
|
|
visitTypeDecl(typeList.itemType);
|
|
write(')');
|
|
}
|
|
|
|
@override
|
|
void visitTypeMap(TypeMap typeMap) {
|
|
write('isMapOf(');
|
|
visitTypeDecl(typeMap.keyType);
|
|
write(', ');
|
|
visitTypeDecl(typeMap.valueType);
|
|
write(')');
|
|
}
|
|
|
|
@override
|
|
void visitTypeObject(TypeObject typeObject) {
|
|
writeln('LazyMatcher(() => MatchesJsonObject(');
|
|
indent(() {
|
|
write("'$context', ");
|
|
var requiredFields = typeObject.fields.where(
|
|
(TypeObjectField field) => !field.optional,
|
|
);
|
|
outputObjectFields(requiredFields);
|
|
var optionalFields = typeObject.fields
|
|
.where((TypeObjectField field) => field.optional)
|
|
.toList();
|
|
if (optionalFields.isNotEmpty) {
|
|
write(', optionalFields: ');
|
|
outputObjectFields(optionalFields);
|
|
}
|
|
});
|
|
write('))');
|
|
}
|
|
|
|
@override
|
|
void visitTypeReference(TypeReference typeReference) {
|
|
var typeName = typeReference.typeName;
|
|
if (typeName == 'long') {
|
|
typeName = 'int';
|
|
}
|
|
write(camelJoin(['is', typeName]));
|
|
}
|
|
|
|
@override
|
|
void visitTypeUnion(TypeUnion typeUnion) {
|
|
var commaNeeded = false;
|
|
write('isOneOf([');
|
|
for (var choice in typeUnion.choices) {
|
|
if (commaNeeded) {
|
|
write(', ');
|
|
}
|
|
visitTypeDecl(choice);
|
|
commaNeeded = true;
|
|
}
|
|
write('])');
|
|
}
|
|
}
|