Version 2.13.0-201.0.dev
Merge commit 'f1fb297ad90c619af90aeeec3abe1e6c6a379c0e' into 'dev'
diff --git a/pkg/analysis_server/tool/spec/api.dart b/pkg/analysis_server/tool/spec/api.dart
index fd40a3b..95fddb4f 100644
--- a/pkg/analysis_server/tool/spec/api.dart
+++ b/pkg/analysis_server/tool/spec/api.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart = 2.9
-
/// Data structures representing an API definition, and visitor base classes
/// for visiting those data structures.
import 'dart:collection';
@@ -19,8 +17,8 @@
Api(this.version, this.domains, this.types, this.refactorings,
dom.Element html,
- {bool experimental})
- : super(html, experimental, false);
+ {bool experimental = false})
+ : super(html, experimental: experimental, deprecated: false);
}
/// Base class for objects in the API model.
@@ -31,12 +29,10 @@
/// A flag to indicate if this API is deprecated.
final bool deprecated;
- /// Html element representing this part of the API.
- final dom.Element html;
+ /// Html element representing this part of the API, `null` if built-in.
+ final dom.Element? html;
- ApiNode(this.html, bool experimental, bool deprecated)
- : experimental = experimental ?? false,
- deprecated = deprecated ?? false;
+ ApiNode(this.html, {this.experimental = false, this.deprecated = false});
}
/// Base class for visiting the API definition.
@@ -59,8 +55,11 @@
final List<Notification> notifications;
Domain(this.name, this.requests, this.notifications, dom.Element html,
- {bool experimental, bool deprecated})
- : super(html, experimental, deprecated);
+ {bool experimental = false, bool deprecated = false})
+ : super(html, experimental: experimental, deprecated: deprecated);
+
+ @override
+ dom.Element get html => super.html!;
}
/// API visitor that visits the entire API hierarchically by default.
@@ -76,8 +75,12 @@
/// If it is not possible (because the chain ends with a [TypeReference] that
/// is not defined in the API), then that final [TypeReference] is returned.
TypeDecl resolveTypeReferenceChain(TypeDecl type) {
- while (type is TypeReference && api.types.containsKey(type.typeName)) {
- type = api.types[(type as TypeReference).typeName].type;
+ while (type is TypeReference) {
+ var newTypeRef = api.types[type.typeName];
+ if (newTypeRef == null) {
+ break;
+ }
+ type = newTypeRef.type;
}
return type;
}
@@ -94,30 +97,37 @@
}
void visitNotification(Notification notification) {
- if (notification.params != null) {
- visitTypeDecl(notification.params);
+ var params = notification.params;
+ if (params != null) {
+ visitTypeDecl(params);
}
}
void visitRefactoring(Refactoring refactoring) {
- if (refactoring.feedback != null) {
- visitTypeDecl(refactoring.feedback);
+ var feedback = refactoring.feedback;
+ if (feedback != null) {
+ visitTypeDecl(feedback);
}
- if (refactoring.options != null) {
- visitTypeDecl(refactoring.options);
+
+ var options = refactoring.options;
+ if (options != null) {
+ visitTypeDecl(options);
}
}
void visitRefactorings(Refactorings refactorings) {
- refactorings?.forEach(visitRefactoring);
+ refactorings.forEach(visitRefactoring);
}
void visitRequest(Request request) {
- if (request.params != null) {
- visitTypeDecl(request.params);
+ var params = request.params;
+ if (params != null) {
+ visitTypeDecl(params);
}
- if (request.result != null) {
- visitTypeDecl(request.result);
+
+ var result = request.result;
+ if (result != null) {
+ visitTypeDecl(result);
}
}
@@ -175,11 +185,11 @@
/// Type of the object associated with the "params" key in the notification
/// object, or null if the notification has no parameters.
- final TypeObject params;
+ final TypeObject? params;
Notification(this.domainName, this.event, this.params, dom.Element html,
- {bool experimental})
- : super(html, experimental, false);
+ {bool experimental = false})
+ : super(html, experimental: experimental, deprecated: false);
/// Get the name of the notification, including the domain prefix.
String get longEvent => '$domainName.$event';
@@ -191,9 +201,12 @@
TypeObjectField('event', TypeReference('String', null), null,
value: '$domainName.$event')
];
+
+ var params = this.params;
if (params != null) {
fields.add(TypeObjectField('params', params, null));
}
+
return TypeObject(fields, null);
}
}
@@ -206,23 +219,24 @@
/// Type of the refactoring feedback, or null if the refactoring has no
/// feedback.
- final TypeObject feedback;
+ final TypeObject? feedback;
/// Type of the refactoring options, or null if the refactoring has no
/// options.
- final TypeObject options;
+ final TypeObject? options;
Refactoring(this.kind, this.feedback, this.options, dom.Element html,
- {bool experimental})
- : super(html, experimental, false);
+ {bool experimental = false})
+ : super(html, experimental: experimental, deprecated: false);
}
/// A collection of refactoring definitions.
class Refactorings extends ApiNode with IterableMixin<Refactoring> {
final List<Refactoring> refactorings;
- Refactorings(this.refactorings, dom.Element html, {bool experimental})
- : super(html, experimental, false);
+ Refactorings(this.refactorings, dom.Element? html,
+ {bool experimental = false})
+ : super(html, experimental: experimental, deprecated: false);
@override
Iterator<Refactoring> get iterator => refactorings.iterator;
@@ -238,16 +252,16 @@
/// Type of the object associated with the "params" key in the request object,
/// or null if the request has no parameters.
- final TypeObject params;
+ final TypeObject? params;
/// Type of the object associated with the "result" key in the response
/// object, or `null` if the response has no results.
- final TypeObject result;
+ final TypeObject? result;
Request(
this.domainName, this.method, this.params, this.result, dom.Element html,
- {bool experimental, bool deprecated})
- : super(html, experimental, deprecated);
+ {bool experimental = false, bool deprecated = false})
+ : super(html, experimental: experimental, deprecated: deprecated);
/// Get the name of the request, including the domain prefix.
String get longMethod => '$domainName.$method';
@@ -260,9 +274,12 @@
TypeObjectField('method', TypeReference('String', null), null,
value: '$domainName.$method')
];
+
+ var params = this.params;
if (params != null) {
fields.add(TypeObjectField('params', params, null));
}
+
return TypeObject(fields, null);
}
@@ -274,17 +291,21 @@
TypeObjectField('error', TypeReference('RequestError', null), null,
optional: true)
];
+
+ var result = this.result;
if (result != null) {
fields.add(TypeObjectField('result', result, null));
}
+
return TypeObject(fields, null);
}
}
/// Base class for all possible types.
abstract class TypeDecl extends ApiNode {
- TypeDecl(dom.Element html, bool experimental, bool deprecated)
- : super(html, experimental, deprecated);
+ TypeDecl(dom.Element? html,
+ {bool experimental = false, bool deprecated = false})
+ : super(html, experimental: experimental, deprecated: deprecated);
T accept<T>(ApiVisitor<T> visitor);
}
@@ -297,8 +318,8 @@
bool isExternal = false;
TypeDefinition(this.name, this.type, dom.Element html,
- {bool experimental, bool deprecated})
- : super(html, experimental, deprecated);
+ {bool experimental = false, bool deprecated = false})
+ : super(html, experimental: experimental, deprecated: deprecated);
}
/// Type of an enum. We represent enums in JSON as strings, so this type
@@ -306,8 +327,9 @@
class TypeEnum extends TypeDecl {
final List<TypeEnumValue> values;
- TypeEnum(this.values, dom.Element html, {bool experimental, bool deprecated})
- : super(html, experimental, deprecated);
+ TypeEnum(this.values, dom.Element html,
+ {bool experimental = false, bool deprecated = false})
+ : super(html, experimental: experimental, deprecated: deprecated);
@override
T accept<T>(ApiVisitor<T> visitor) => visitor.visitTypeEnum(this);
@@ -318,16 +340,19 @@
final String value;
TypeEnumValue(this.value, dom.Element html,
- {bool experimental, bool deprecated})
- : super(html, experimental, deprecated);
+ {bool experimental = false, bool deprecated = false})
+ : super(html, experimental: experimental, deprecated: deprecated);
+
+ @override
+ dom.Element get html => super.html!;
}
/// Type of a JSON list.
class TypeList extends TypeDecl {
final TypeDecl itemType;
- TypeList(this.itemType, dom.Element html, {bool experimental})
- : super(html, experimental, false);
+ TypeList(this.itemType, dom.Element html, {bool experimental = false})
+ : super(html, experimental: experimental, deprecated: false);
@override
T accept<T>(ApiVisitor<T> visitor) => visitor.visitTypeList(this);
@@ -344,8 +369,9 @@
/// Type of map values.
final TypeDecl valueType;
- TypeMap(this.keyType, this.valueType, dom.Element html, {bool experimental})
- : super(html, experimental, false);
+ TypeMap(this.keyType, this.valueType, dom.Element html,
+ {bool experimental = false})
+ : super(html, experimental: experimental, deprecated: false);
@override
T accept<T>(ApiVisitor<T> visitor) => visitor.visitTypeMap(this);
@@ -355,15 +381,15 @@
class TypeObject extends TypeDecl {
final List<TypeObjectField> fields;
- TypeObject(this.fields, dom.Element html,
- {bool experimental, bool deprecated})
- : super(html, experimental, deprecated);
+ TypeObject(this.fields, dom.Element? html,
+ {bool experimental = false, bool deprecated = false})
+ : super(html, experimental: experimental, deprecated: deprecated);
@override
T accept<T>(ApiVisitor<T> visitor) => visitor.visitTypeObject(this);
/// Return the field with the given [name], or null if there is no such field.
- TypeObjectField getField(String name) {
+ TypeObjectField? getField(String name) {
for (var field in fields) {
if (field.name == name) {
return field;
@@ -380,11 +406,14 @@
final bool optional;
/// Value that the field is required to contain, or null if it may vary.
- final Object value;
+ final Object? value;
- TypeObjectField(this.name, this.type, dom.Element html,
- {this.optional = false, this.value, bool experimental, bool deprecated})
- : super(html, experimental, deprecated);
+ TypeObjectField(this.name, this.type, dom.Element? html,
+ {this.optional = false,
+ this.value,
+ bool experimental = false,
+ bool deprecated = false})
+ : super(html, experimental: experimental, deprecated: deprecated);
}
/// A reference to a type which is either defined elsewhere in the API or which
@@ -392,8 +421,8 @@
class TypeReference extends TypeDecl {
final String typeName;
- TypeReference(this.typeName, dom.Element html, {bool experimental})
- : super(html, experimental, false) {
+ TypeReference(this.typeName, dom.Element? html, {bool experimental = false})
+ : super(html, experimental: experimental, deprecated: false) {
if (typeName.isEmpty) {
throw Exception('Empty type name');
}
@@ -409,15 +438,15 @@
List<String> importUris = <String>[];
- Types(this.types, dom.Element html, {bool experimental})
- : super(html, experimental, false);
+ Types(this.types, dom.Element? html, {bool experimental = false})
+ : super(html, experimental: experimental, deprecated: false);
@override
Iterator<TypeDefinition> get iterator => types.values.iterator;
Iterable<String> get keys => types.keys;
- TypeDefinition operator [](String typeName) => types[typeName];
+ TypeDefinition? operator [](String typeName) => types[typeName];
bool containsKey(String typeName) => types.containsKey(typeName);
}
@@ -429,8 +458,9 @@
/// The field that is used to disambiguate this union
final String field;
- TypeUnion(this.choices, this.field, dom.Element html, {bool experimental})
- : super(html, experimental, false);
+ TypeUnion(this.choices, this.field, dom.Element html,
+ {bool experimental = false})
+ : super(html, experimental: experimental, deprecated: false);
@override
T accept<T>(ApiVisitor<T> visitor) => visitor.visitTypeUnion(this);
diff --git a/pkg/analysis_server/tool/spec/check_all_test.dart b/pkg/analysis_server/tool/spec/check_all_test.dart
index 14ede1c..3be8ed7 100644
--- a/pkg/analysis_server/tool/spec/check_all_test.dart
+++ b/pkg/analysis_server/tool/spec/check_all_test.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart = 2.9
-
import 'dart:io';
import 'package:analyzer_utilities/tools.dart';
diff --git a/pkg/analysis_server/tool/spec/codegen_analysis_server.dart b/pkg/analysis_server/tool/spec/codegen_analysis_server.dart
index a41e9ad..096db25 100644
--- a/pkg/analysis_server/tool/spec/codegen_analysis_server.dart
+++ b/pkg/analysis_server/tool/spec/codegen_analysis_server.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart = 2.9
-
/// Code generation for the file "AnalysisServer.java".
import 'package:analyzer_utilities/tools.dart';
@@ -167,14 +165,18 @@
}));
write('public void $methodName(');
var arguments = <String>[];
- if (request.params != null) {
- for (var field in request.params.fields) {
+
+ var params = request.params;
+ if (params != null) {
+ for (var field in params.fields) {
arguments.add('${javaType(field.type)} ${javaName(field.name)}');
}
}
+
if (request.result != null) {
arguments.add('${consumerName(request)} consumer');
}
+
write(arguments.join(', '));
writeln(');');
});
diff --git a/pkg/analysis_server/tool/spec/codegen_dart.dart b/pkg/analysis_server/tool/spec/codegen_dart.dart
index b38ba00..7069dc0 100644
--- a/pkg/analysis_server/tool/spec/codegen_dart.dart
+++ b/pkg/analysis_server/tool/spec/codegen_dart.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart = 2.9
-
import 'api.dart';
/// Visitor specialized for generating Dart code.
@@ -21,8 +19,9 @@
if (type is TypeReference) {
var typeName = type.typeName;
var referencedDefinition = api.types[typeName];
- if (_typeRenames.containsKey(typeName)) {
- return _typeRenames[typeName];
+ var typeRename = _typeRenames[typeName];
+ if (typeRename != null) {
+ return typeRename;
}
if (referencedDefinition == null) {
return typeName;
diff --git a/pkg/analysis_server/tool/spec/codegen_dart_notification_handler.dart b/pkg/analysis_server/tool/spec/codegen_dart_notification_handler.dart
index a1ae0ab..160c52d 100644
--- a/pkg/analysis_server/tool/spec/codegen_dart_notification_handler.dart
+++ b/pkg/analysis_server/tool/spec/codegen_dart_notification_handler.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart = 2.9
-
import 'package:analyzer_utilities/tools.dart';
import 'package:html/dom.dart';
@@ -140,6 +138,6 @@
_generateNotificationMethodName(
notification.domainName, notification.event),
_generateParamTypeName(notification.domainName, notification.event),
- _generateDartDoc(notification.html)));
+ _generateDartDoc(notification.html!)));
}
}
diff --git a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
index 7410305..c17e46f 100644
--- a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
+++ b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart = 2.9
-
import 'dart:convert';
import 'package:analyzer_utilities/tools.dart';
@@ -268,8 +266,9 @@
toHtmlVisitor.p(() {
toHtmlVisitor.write(impliedType.humanReadableName);
});
- if (impliedType.type != null) {
- toHtmlVisitor.showType(null, impliedType.type);
+ var impliedTypeType = impliedType.type;
+ if (impliedTypeType != null) {
+ toHtmlVisitor.showType(null, impliedTypeType);
}
toHtmlVisitor.p(() {
toHtmlVisitor.write(disclaimer);
@@ -412,8 +411,9 @@
toHtmlVisitor.p(() {
toHtmlVisitor.write(impliedType.humanReadableName);
});
- if (impliedType.type != null) {
- toHtmlVisitor.showType(null, impliedType.type);
+ var impliedTypeType = impliedType.type;
+ if (impliedTypeType != null) {
+ toHtmlVisitor.showType(null, impliedTypeType);
}
toHtmlVisitor.p(() {
toHtmlVisitor.write(disclaimer);
@@ -523,7 +523,7 @@
}
/// Emit the operator== code for an object class.
- void emitObjectEqualsMember(TypeObject type, String className) {
+ void emitObjectEqualsMember(TypeObject? type, String className) {
writeln('@override');
writeln('bool operator ==(other) {');
indent(() {
@@ -639,7 +639,7 @@
}
/// Emit the hashCode getter for an object class.
- void emitObjectHashCode(TypeObject type, String className) {
+ void emitObjectHashCode(TypeObject? type, String className) {
writeln('@override');
writeln('int get hashCode {');
indent(() {
diff --git a/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart b/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
index 1ed8a77..5864cb2 100644
--- a/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
+++ b/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart = 2.9
-
/// Code generation for the file "integration_test_methods.dart".
import 'package:analyzer_utilities/tools.dart';
import 'package:path/path.dart' as path;
@@ -186,8 +184,9 @@
var methodName = camelJoin(['send', request.domainName, request.method]);
var args = <String>[];
var optionalArgs = <String>[];
- if (request.params != null) {
- for (var field in request.params.fields) {
+ var params = request.params;
+ if (params != null) {
+ for (var field in params.fields) {
if (field.optional) {
optionalArgs.add(formatArgument(field));
} else {
@@ -201,32 +200,35 @@
writeln();
docComment(toHtmlVisitor.collectHtml(() {
toHtmlVisitor.translateHtml(request.html);
- toHtmlVisitor.describePayload(request.params, 'Parameters');
+ toHtmlVisitor.describePayload(params, 'Parameters');
toHtmlVisitor.describePayload(request.result, 'Returns');
}));
if (request.deprecated) {
writeln('@deprecated');
}
- String resultClass;
+
+ String? resultClass;
String futureClass;
- if (request.result == null) {
- futureClass = 'Future';
- } else {
+ var hasResult = request.result != null;
+ if (hasResult) {
resultClass = camelJoin([request.domainName, request.method, 'result'],
doCapitalize: true);
futureClass = 'Future<$resultClass>';
+ } else {
+ futureClass = 'Future';
}
+
writeln('$futureClass $methodName(${args.join(', ')}) async {');
indent(() {
var requestClass = camelJoin(
[request.domainName, request.method, 'params'],
doCapitalize: true);
var paramsVar = 'null';
- if (request.params != null) {
+ if (params != null) {
paramsVar = 'params';
var args = <String>[];
var optionalArgs = <String>[];
- for (var field in request.params.fields) {
+ for (var field in params.fields) {
if (field.optional) {
optionalArgs.add('${field.name}: ${field.name}');
} else {
@@ -238,7 +240,7 @@
}
var methodJson = "'${request.longMethod}'";
writeln('var result = await server.send($methodJson, $paramsVar);');
- if (request.result != null) {
+ if (resultClass != null) {
var kind = 'null';
if (requestClass == 'EditGetRefactoringParams') {
kind = 'kind';
diff --git a/pkg/analysis_server/tool/spec/codegen_java.dart b/pkg/analysis_server/tool/spec/codegen_java.dart
index ea62d4a..54b48e8 100644
--- a/pkg/analysis_server/tool/spec/codegen_java.dart
+++ b/pkg/analysis_server/tool/spec/codegen_java.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart = 2.9
-
/// Tools for Java code generation.
import 'package:analyzer_utilities/tools.dart';
import 'package:html/dom.dart' as dom;
@@ -24,9 +22,9 @@
/// Iterate through the values in [map] in the order of increasing keys.
Iterable<String> _valuesSortedByKey(Map<String, String> map) {
- var keys = map.keys.toList();
- keys.sort();
- return keys.map((String key) => map[key]);
+ var entries = map.entries.toList();
+ entries.sort((a, b) => a.key.compareTo(b.key));
+ return entries.map((e) => e.value);
}
/// Common code for all Java code generation.
@@ -48,7 +46,7 @@
'Override': 'OverrideMember',
};
- _CodegenJavaState _state;
+ _CodegenJavaState _state = _CodegenJavaState();
/// Visitor used to produce doc comments.
final ToHtmlVisitor toHtmlVisitor;
@@ -127,19 +125,17 @@
/// Return a suitable representation of [name] as the name of a Java variable.
String javaName(String name) {
- if (_variableRenames.containsKey(name)) {
- return _variableRenames[name];
- }
- return name;
+ return _variableRenames[name] ?? name;
}
/// Convert the given [TypeDecl] to a Java type.
String javaType(TypeDecl type, [bool optional = false]) {
if (type is TypeReference) {
- TypeReference resolvedType = resolveTypeReferenceChain(type);
+ var resolvedType = resolveTypeReferenceChain(type) as TypeReference;
var typeName = resolvedType.typeName;
- if (_typeRenames.containsKey(typeName)) {
- typeName = _typeRenames[typeName];
+ var renameTo = _typeRenames[typeName];
+ if (renameTo != null) {
+ typeName = renameTo;
if (optional) {
if (typeName == 'boolean') {
typeName = 'Boolean';
diff --git a/pkg/analysis_server/tool/spec/codegen_java_types.dart b/pkg/analysis_server/tool/spec/codegen_java_types.dart
index 8b2d471..cd11d2c 100644
--- a/pkg/analysis_server/tool/spec/codegen_java_types.dart
+++ b/pkg/analysis_server/tool/spec/codegen_java_types.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart = 2.9
-
/// Code generation for the file "AnalysisServer.java".
import 'package:analyzer_utilities/tools.dart';
import 'package:html/dom.dart' as dom;
@@ -60,15 +58,16 @@
isRefactoringFeedback ||
isRefactoringOption) {
var type = impliedType.type;
- if (type is TypeObject || type is TypeEnum) {
+ if (type != null && (type is TypeObject || type is TypeEnum)) {
// This is for situations such as 'Override' where the name in the spec
// doesn't match the java object that we generate:
var typeNameInJava = typeNameInSpec;
- if (_typeRenames.containsKey(typeNameInSpec)) {
- typeNameInJava = _typeRenames[typeNameInSpec];
+ var renamedTo = _typeRenames[typeNameInSpec];
+ if (renamedTo != null) {
+ typeNameInJava = renamedTo;
}
map['$typeNameInJava.java'] = (String pkgPath) async {
- String superclassName;
+ String? superclassName;
if (isRefactoringFeedback) {
superclassName = 'RefactoringFeedback';
}
@@ -102,7 +101,7 @@
class CodegenJavaType extends CodegenJavaVisitor {
final String className;
- final String superclassName;
+ final String? superclassName;
final bool generateGetters;
final bool generateSetters;
@@ -116,7 +115,7 @@
return camelJoin([request.method, 'consumer'], doCapitalize: true);
}
- void emitType(TypeDecl type, dom.Element html) {
+ void emitType(TypeDecl type, dom.Element? html) {
outputHeader(javaStyle: true);
writeln('package org.dartlang.analysis.server.protocol;');
writeln();
@@ -233,7 +232,7 @@
}
}
- void _writeTypeEnum(TypeDecl type, dom.Element html) {
+ void _writeTypeEnum(TypeDecl type, dom.Element? html) {
javadocComment(toHtmlVisitor.collectHtml(() {
toHtmlVisitor.translateHtml(html);
toHtmlVisitor.br();
@@ -257,7 +256,7 @@
});
}
- void _writeTypeObject(TypeDecl type, dom.Element html) {
+ void _writeTypeObject(TypeDecl type, dom.Element? html) {
writeln('import java.util.Arrays;');
writeln('import java.util.List;');
writeln('import java.util.Map;');
diff --git a/pkg/analysis_server/tool/spec/codegen_matchers.dart b/pkg/analysis_server/tool/spec/codegen_matchers.dart
index 1a55c6e..9e0a9d1 100644
--- a/pkg/analysis_server/tool/spec/codegen_matchers.dart
+++ b/pkg/analysis_server/tool/spec/codegen_matchers.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart = 2.9
-
/// Code generation for the file "matchers.dart".
import 'package:analyzer_utilities/tools.dart';
@@ -24,7 +22,7 @@
/// Short human-readable string describing the context of the matcher being
/// created.
- String context;
+ late String context;
CodegenMatchersVisitor(Api api)
: toHtmlVisitor = ToHtmlVisitor(api),
@@ -41,19 +39,20 @@
/// matches the given [type].
void makeMatcher(ImpliedType impliedType) {
context = impliedType.humanReadableName;
+ var impliedTypeType = impliedType.type;
docComment(toHtmlVisitor.collectHtml(() {
toHtmlVisitor.p(() {
toHtmlVisitor.write(context);
});
- if (impliedType.type != null) {
- toHtmlVisitor.showType(null, impliedType.type);
+ if (impliedTypeType != null) {
+ toHtmlVisitor.showType(null, impliedTypeType);
}
}));
write('final Matcher ${camelJoin(['is', impliedType.camelName])} = ');
- if (impliedType.type == null) {
+ if (impliedTypeType == null) {
write('isNull');
} else {
- visitTypeDecl(impliedType.type);
+ visitTypeDecl(impliedTypeType);
}
writeln(';');
writeln();
diff --git a/pkg/analysis_server/tool/spec/codegen_protocol_constants.dart b/pkg/analysis_server/tool/spec/codegen_protocol_constants.dart
index a81d141..f6cf4f0 100644
--- a/pkg/analysis_server/tool/spec/codegen_protocol_constants.dart
+++ b/pkg/analysis_server/tool/spec/codegen_protocol_constants.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart = 2.9
-
import 'package:analyzer_utilities/tools.dart';
import 'api.dart';
@@ -64,6 +62,15 @@
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 associates with the [api].
void generateConstants() {
writeln("const String PROTOCOL_VERSION = '${api.version}';");
@@ -73,19 +80,10 @@
var constants = visitor.constants;
constants.sort((first, second) => first.name.compareTo(second.name));
for (var constant in constants) {
- generateContant(constant);
+ generateConstant(constant);
}
}
- /// Generate the given [constant].
- void generateContant(_Constant constant) {
- write('const String ');
- write(constant.name);
- write(' = ');
- write(constant.value);
- writeln(';');
- }
-
@override
void visitApi() {
outputHeader(year: '2017');
@@ -141,7 +139,7 @@
/// 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) {
+ void _addFieldConstants(String parentName, TypeObject? type) {
if (type == null) {
return;
}
diff --git a/pkg/analysis_server/tool/spec/from_html.dart b/pkg/analysis_server/tool/spec/from_html.dart
index de97dc7..bf64d22 100644
--- a/pkg/analysis_server/tool/spec/from_html.dart
+++ b/pkg/analysis_server/tool/spec/from_html.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart = 2.9
-
/// Code for reading an HTML API description.
import 'dart:io';
@@ -77,8 +75,8 @@
Api api;
var versions = <String>[];
var domains = <Domain>[];
- Types types;
- Refactorings refactorings;
+ var types = Types({}, null);
+ var refactorings = Refactorings([], null);
recurse(html, 'api', {
'domain': (dom.Element element) {
domains.add(domainFromHtml(element));
@@ -111,6 +109,10 @@
{List<String> optionalAttributes = const []}) {
var attributesFound = <String>{};
element.attributes.forEach((name, value) {
+ if (name is! String) {
+ throw Exception(
+ '$context: Only string attribute names expected: $name');
+ }
if (!requiredAttributes.contains(name) &&
!optionalAttributes.contains(name)) {
throw Exception(
@@ -127,7 +129,7 @@
}
/// Check that the given [element] has the given [expectedName].
- void checkName(dom.Element element, String expectedName, [String context]) {
+ void checkName(dom.Element element, String expectedName, [String? context]) {
if (element.localName != expectedName) {
context ??= element.localName;
throw Exception(
@@ -145,19 +147,22 @@
/// Child elements can occur in any order.
Domain domainFromHtml(dom.Element html) {
checkName(html, 'domain');
+
var name = html.attributes['name'];
- var context = name ?? 'domain';
+ if (name == null) {
+ throw Exception('domains: name not specified');
+ }
+
var experimental = html.attributes['experimental'] == 'true';
- checkAttributes(html, ['name'], context,
- optionalAttributes: ['experimental']);
+ checkAttributes(html, ['name'], name, optionalAttributes: ['experimental']);
var requests = <Request>[];
var notifications = <Notification>[];
- recurse(html, context, {
+ recurse(html, name, {
'request': (dom.Element child) {
- requests.add(requestFromHtml(child, context));
+ requests.add(requestFromHtml(child, name));
},
'notification': (dom.Element child) {
- notifications.add(notificationFromHtml(child, context));
+ notifications.add(notificationFromHtml(child, name));
}
});
return Domain(name, requests, notifications, html,
@@ -190,18 +195,30 @@
/// Child elements can occur in any order.
Notification notificationFromHtml(dom.Element html, String context) {
var domainName = getAncestor(html, 'domain', context).attributes['name'];
+ if (domainName == null) {
+ throw Exception('$context: domain not specified');
+ }
+
checkName(html, 'notification', context);
+
var event = html.attributes['event'];
- context = '$context.${event ?? 'event'}';
- checkAttributes(html, ['event'], context,
- optionalAttributes: ['experimental']);
- var experimental = html.attributes['experimental'] == 'true';
- TypeObject params;
+ if (event == null) {
+ throw Exception('$context: event not specified');
+ }
+
+ context = '$context.$event';
+
+ TypeObject? params;
recurse(html, context, {
'params': (dom.Element child) {
params = typeObjectFromHtml(child, '$context.params');
}
});
+
+ checkAttributes(html, ['event'], context,
+ optionalAttributes: ['experimental']);
+ var experimental = html.attributes['experimental'] == 'true';
+
return Notification(domainName, event, params, html,
experimental: experimental);
}
@@ -255,25 +272,29 @@
},
'map': (dom.Element child) {
checkAttributes(child, [], context);
- TypeDecl keyType;
- TypeDecl valueType;
+ TypeDecl? keyTypeNullable;
+ TypeDecl? valueTypeNullable;
recurse(child, context, {
'key': (dom.Element child) {
- if (keyType != null) {
+ if (keyTypeNullable != null) {
throw Exception('$context: Key type already specified');
}
- keyType = processContentsAsType(child, '$context.key');
+ keyTypeNullable = processContentsAsType(child, '$context.key');
},
'value': (dom.Element child) {
- if (valueType != null) {
+ if (valueTypeNullable != null) {
throw Exception('$context: Value type already specified');
}
- valueType = processContentsAsType(child, '$context.value');
+ valueTypeNullable = processContentsAsType(child, '$context.value');
}
});
- if (keyType == null) {
- throw Exception('$context: Key type not specified');
+ var keyType = keyTypeNullable;
+ if (keyType is! TypeReference) {
+ throw Exception(
+ '$context: Key type not specified, or not a reference',
+ );
}
+ var valueType = valueTypeNullable;
if (valueType == null) {
throw Exception('$context: Value type not specified');
}
@@ -288,7 +309,7 @@
},
'union': (dom.Element child) {
checkAttributes(child, ['field'], context);
- var field = child.attributes['field'];
+ var field = child.attributes['field']!;
types.add(
TypeUnion(processContentsAsTypes(child, context), field, child));
}
@@ -301,7 +322,7 @@
var htmlContents = File(filePath).readAsStringSync();
var document = parser.parse(htmlContents);
var htmlElement = document.children
- .singleWhere((element) => element.localName.toLowerCase() == 'html');
+ .singleWhere((element) => element.localName!.toLowerCase() == 'html');
return apiFromHtml(htmlElement);
}
@@ -314,8 +335,9 @@
}
for (var node in parent.nodes) {
if (node is dom.Element) {
- if (elementProcessors.containsKey(node.localName)) {
- elementProcessors[node.localName](node);
+ var processor = elementProcessors[node.localName];
+ if (processor != null) {
+ processor(node);
} else if (specialElements.contains(node.localName)) {
throw Exception('$context: Unexpected use of <${node.localName}>');
} else {
@@ -338,17 +360,21 @@
/// Child elements can occur in any order.
Refactoring refactoringFromHtml(dom.Element html) {
checkName(html, 'refactoring');
+
var kind = html.attributes['kind'];
- var context = kind ?? 'refactoring';
- checkAttributes(html, ['kind'], context);
- TypeObject feedback;
- TypeObject options;
- recurse(html, context, {
+ if (kind == null) {
+ throw Exception('refactorings: kind not specified');
+ }
+
+ checkAttributes(html, ['kind'], kind);
+ TypeObject? feedback;
+ TypeObject? options;
+ recurse(html, kind, {
'feedback': (dom.Element child) {
- feedback = typeObjectFromHtml(child, '$context.feedback');
+ feedback = typeObjectFromHtml(child, '$kind.feedback');
},
'options': (dom.Element child) {
- options = typeObjectFromHtml(child, '$context.options');
+ options = typeObjectFromHtml(child, '$kind.options');
}
});
return Refactoring(kind, feedback, options, html);
@@ -387,15 +413,24 @@
/// Child elements can occur in any order.
Request requestFromHtml(dom.Element html, String context) {
var domainName = getAncestor(html, 'domain', context).attributes['name'];
+ if (domainName == null) {
+ throw Exception('$context: domain not specified');
+ }
+
checkName(html, 'request', context);
+
var method = html.attributes['method'];
- context = '$context.${method ?? 'method'}';
+ if (method == null) {
+ throw Exception('$context: method not specified');
+ }
+
+ context = '$context.$method}';
checkAttributes(html, ['method'], context,
optionalAttributes: ['experimental', 'deprecated']);
var experimental = html.attributes['experimental'] == 'true';
var deprecated = html.attributes['deprecated'] == 'true';
- TypeObject params;
- TypeObject result;
+ TypeObject? params;
+ TypeObject? result;
recurse(html, context, {
'params': (dom.Element child) {
params = typeObjectFromHtml(child, '$context.params');
@@ -419,11 +454,15 @@
/// Child elements can occur in any order.
TypeDefinition typeDefinitionFromHtml(dom.Element html) {
checkName(html, 'type');
+
var name = html.attributes['name'];
- var context = name ?? 'type';
- checkAttributes(html, ['name'], context,
+ if (name == null) {
+ throw Exception('types: name not specified');
+ }
+
+ checkAttributes(html, ['name'], name,
optionalAttributes: ['experimental', 'deprecated']);
- var type = processContentsAsType(html, context);
+ var type = processContentsAsType(html, name);
var experimental = html.attributes['experimental'] == 'true';
var deprecated = html.attributes['deprecated'] == 'true';
return TypeDefinition(name, type, html,
@@ -484,8 +523,13 @@
/// Child elements can occur in any order.
TypeObjectField typeObjectFieldFromHtml(dom.Element html, String context) {
checkName(html, 'field', context);
+
var name = html.attributes['name'];
- context = '$context.${name ?? 'field'}';
+ if (name == null) {
+ throw Exception('$context: name not specified');
+ }
+
+ context = '$context.$name}';
checkAttributes(html, ['name'], context,
optionalAttributes: [
'optional',
@@ -556,7 +600,7 @@
var api = reader.readApi();
for (var typeDefinition in api.types) {
typeDefinition.isExternal = true;
- childElements.add(typeDefinition.html);
+ childElements.add(typeDefinition.html!);
typeMap[typeDefinition.name] = typeDefinition;
}
},
diff --git a/pkg/analysis_server/tool/spec/generate_all.dart b/pkg/analysis_server/tool/spec/generate_all.dart
index 30fb5f3..20840ce 100644
--- a/pkg/analysis_server/tool/spec/generate_all.dart
+++ b/pkg/analysis_server/tool/spec/generate_all.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart = 2.9
-
import 'dart:io';
import 'package:analyzer_utilities/tools.dart';
diff --git a/pkg/analysis_server/tool/spec/implied_types.dart b/pkg/analysis_server/tool/spec/implied_types.dart
index 521485c..6a49fcc 100644
--- a/pkg/analysis_server/tool/spec/implied_types.dart
+++ b/pkg/analysis_server/tool/spec/implied_types.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart = 2.9
-
/// Code for enumerating the set of types implied by the API.
import 'package:analyzer_utilities/tools.dart';
@@ -18,7 +16,7 @@
class ImpliedType {
final String camelName;
final String humanReadableName;
- final TypeDecl type;
+ final TypeDecl? type;
/// Kind of implied type this is. One of:
/// - 'requestParams'
@@ -41,7 +39,7 @@
_ImpliedTypesVisitor(Api api) : super(api);
- void storeType(String name, String nameSuffix, TypeDecl type, String kind,
+ void storeType(String name, String? nameSuffix, TypeDecl? type, String kind,
ApiNode apiNode) {
var humanReadableName = name;
var camelNameParts = name.split('.');
diff --git a/pkg/analysis_server/tool/spec/to_html.dart b/pkg/analysis_server/tool/spec/to_html.dart
index 3d13b63..0bcc45e 100644
--- a/pkg/analysis_server/tool/spec/to_html.dart
+++ b/pkg/analysis_server/tool/spec/to_html.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart = 2.9
-
/// Code for displaying the API as HTML. This is used both for generating a
/// full description of the API as a web page, and for generating doc comments
/// in generated code.
@@ -177,9 +175,6 @@
element('span', {'style': 'color:#999999'}, callback);
void h1(void Function() callback) => element('h1', {}, callback);
void h2(String cls, void Function() callback) {
- if (cls == null) {
- return element('h2', {}, callback);
- }
return element('h2', {'class': cls}, callback);
}
@@ -193,7 +188,7 @@
void i(void Function() callback) => element('i', {}, callback);
void li(void Function() callback) => element('li', {}, callback);
void link(String id, void Function() callback,
- [Map<dynamic, String> attributes]) {
+ [Map<Object, String>? attributes]) {
attributes ??= {};
attributes['href'] = '#$id';
element('a', attributes, callback);
@@ -228,7 +223,7 @@
///
/// If [force] is true, then a section is inserted even if the payload is
/// null.
- void describePayload(TypeObject subType, String name, {bool force = false}) {
+ void describePayload(TypeObject? subType, String name, {bool force = false}) {
if (force || subType != null) {
h4(() {
write(name);
@@ -300,9 +295,6 @@
}
void generateRefactoringsIndex(Iterable<Refactoring> refactorings) {
- if (refactorings == null) {
- return;
- }
h3(() {
write('Refactorings');
write(' (');
@@ -385,7 +377,7 @@
});
}
- void javadocParams(TypeObject typeObject) {
+ void javadocParams(TypeObject? typeObject) {
if (typeObject != null) {
for (var field in typeObject.fields) {
hangingIndent(() {
@@ -403,7 +395,8 @@
///
/// If [typeForBolding] is supplied, then fields in this type are shown in
/// boldface.
- void showType(String shortDesc, TypeDecl type, [TypeObject typeForBolding]) {
+ void showType(String? shortDesc, TypeDecl type,
+ [TypeObject? typeForBolding]) {
var fieldsToBold = <String>{};
if (typeForBolding != null) {
for (var field in typeForBolding.fields) {
@@ -423,19 +416,23 @@
/// Copy the contents of the given HTML element, translating the special
/// elements that define the API appropriately.
- void translateHtml(dom.Element html, {bool squashParagraphs = false}) {
+ void translateHtml(dom.Element? html, {bool squashParagraphs = false}) {
+ if (html == null) {
+ return;
+ }
for (var node in html.nodes) {
if (node is dom.Element) {
- if (squashParagraphs && node.localName == 'p') {
+ var localName = node.localName!;
+ if (squashParagraphs && localName == 'p') {
translateHtml(node, squashParagraphs: squashParagraphs);
continue;
}
- switch (node.localName) {
+ switch (localName) {
case 'domains':
generateDomainsHeader();
break;
case 'domain':
- visitDomain(apiMappings.domains[node]);
+ visitDomain(apiMappings.domains[node]!);
break;
case 'head':
head(() {
@@ -467,8 +464,8 @@
generateIndex();
break;
default:
- if (!ApiReader.specialElements.contains(node.localName)) {
- element(node.localName, node.attributes, () {
+ if (!ApiReader.specialElements.contains(localName)) {
+ element(localName, node.attributes, () {
translateHtml(node, squashParagraphs: squashParagraphs);
});
}
@@ -707,15 +704,15 @@
/// }
class TypeVisitor extends HierarchicalApiVisitor
with HtmlMixin, HtmlCodeGenerator {
- /// Set of fields which should be shown in boldface, or null if no field
- /// should be shown in boldface.
+ /// Set of fields which should be shown in boldface.
final Set<String> fieldsToBold;
/// True if a short description should be generated. In a short description,
/// objects are shown as simply "object", and enums are shown as "String".
final bool short;
- TypeVisitor(Api api, {this.fieldsToBold, this.short = false}) : super(api);
+ TypeVisitor(Api api, {this.fieldsToBold = const {}, this.short = false})
+ : super(api);
@override
void visitTypeEnum(TypeEnum typeEnum) {
@@ -758,7 +755,7 @@
indent(() {
for (var field in typeObject.fields) {
write('"');
- if (fieldsToBold != null && fieldsToBold.contains(field.name)) {
+ if (fieldsToBold.contains(field.name)) {
b(() {
write(field.name);
});
diff --git a/tools/VERSION b/tools/VERSION
index 5e77d8c..6086192 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 13
PATCH 0
-PRERELEASE 200
+PRERELEASE 201
PRERELEASE_PATCH 0
\ No newline at end of file