Index: pkg/analysis_server/tool/spec/codegen_dart_protocol.dart |
diff --git a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart |
index ef16e1dcd11911e829f82376c76e1fd2c23deac9..941b881d85a43f48d50728e83811fb96be7382cb 100644 |
--- a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart |
+++ b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart |
@@ -2,13 +2,12 @@ |
// 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. |
-library codegen.protocol; |
- |
import 'dart:convert'; |
import 'package:analyzer/src/codegen/tools.dart'; |
import 'package:front_end/src/codegen/tools.dart'; |
import 'package:html/dom.dart' as dom; |
+import 'package:path/path.dart' as path; |
import 'api.dart'; |
import 'codegen_dart.dart'; |
@@ -29,9 +28,10 @@ const Map<String, String> specialElementFlags = const { |
'deprecated': '0x20' |
}; |
-final GeneratedFile target = new GeneratedFile( |
- 'lib/plugin/protocol/generated_protocol.dart', (String pkgPath) { |
- CodegenProtocolVisitor visitor = new CodegenProtocolVisitor(readApi(pkgPath)); |
+final GeneratedFile target = |
+ new GeneratedFile('lib/protocol/protocol_generated.dart', (String pkgPath) { |
+ CodegenProtocolVisitor visitor = |
+ new CodegenProtocolVisitor(path.basename(pkgPath), readApi(pkgPath)); |
return visitor.collectCode(visitor.visitApi); |
}); |
@@ -68,6 +68,11 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator { |
'Clients may not extend, implement or mix-in this class.'; |
/** |
+ * The name of the package into which code is being generated. |
+ */ |
+ final String packageName; |
+ |
+ /** |
* Visitor used to produce doc comments. |
*/ |
final ToHtmlVisitor toHtmlVisitor; |
@@ -79,7 +84,7 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator { |
*/ |
final Map<String, ImpliedType> impliedTypes; |
- CodegenProtocolVisitor(Api api) |
+ CodegenProtocolVisitor(this.packageName, Api api) |
: toHtmlVisitor = new ToHtmlVisitor(api), |
impliedTypes = computeImpliedTypes(api), |
super(api) { |
@@ -117,10 +122,14 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator { |
* Translate each type implied by the API to a class. |
*/ |
void emitClasses() { |
- for (ImpliedType impliedType in impliedTypes.values) { |
+ List<ImpliedType> types = impliedTypes.values.toList(); |
+ types.sort((first, second) => |
+ capitalize(first.camelName).compareTo(capitalize(second.camelName))); |
+ for (ImpliedType impliedType in types) { |
TypeDecl type = impliedType.type; |
String dartTypeName = capitalize(impliedType.camelName); |
if (type == null) { |
+ writeln(); |
emitEmptyObjectClass(dartTypeName, impliedType); |
} else if (type is TypeObject) { |
writeln(); |
@@ -153,14 +162,14 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator { |
case 'requestParams': |
inputType = 'Request'; |
inputName = 'request'; |
- fieldName = '_params'; |
+ fieldName = 'params'; |
makeDecoder = 'new RequestDecoder(request)'; |
constructorName = 'fromRequest'; |
break; |
case 'requestResult': |
inputType = 'Response'; |
inputName = 'response'; |
- fieldName = '_result'; |
+ fieldName = 'result'; |
makeDecoder = |
'new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id))'; |
constructorName = 'fromResponse'; |
@@ -168,7 +177,7 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator { |
case 'notificationParams': |
inputType = 'Notification'; |
inputName = 'notification'; |
- fieldName = '_params'; |
+ fieldName = 'params'; |
makeDecoder = 'new ResponseDecoder(null)'; |
constructorName = 'fromNotification'; |
break; |
@@ -219,13 +228,22 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator { |
})); |
write('class $className'); |
if (impliedType.kind == 'refactoringFeedback') { |
- writeln(' extends RefactoringFeedback {'); |
+ writeln(' extends RefactoringFeedback implements HasToJson {'); |
} else if (impliedType.kind == 'refactoringOptions') { |
- writeln(' extends RefactoringOptions {'); |
+ writeln(' extends RefactoringOptions implements HasToJson {'); |
+ } else if (impliedType.kind == 'requestParams') { |
+ writeln(' implements RequestParams {'); |
+ } else if (impliedType.kind == 'requestResult') { |
+ writeln(' implements ResponseResult {'); |
} else { |
writeln(' {'); |
} |
indent(() { |
+ if (impliedType.kind == 'requestResult' || |
+ impliedType.kind == 'requestParams') { |
+ emitEmptyToJsonMember(); |
+ writeln(); |
+ } |
if (emitToRequestMember(impliedType)) { |
writeln(); |
} |
@@ -243,6 +261,14 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator { |
} |
/** |
+ * Emit the toJson() code for an empty class. |
+ */ |
+ void emitEmptyToJsonMember() { |
+ writeln('@override'); |
+ writeln('Map<String, dynamic> toJson() => <String, dynamic>{};'); |
+ } |
+ |
+ /** |
* Emit a class to encapsulate an enum. |
*/ |
void emitEnumClass(String className, TypeEnum type, ImpliedType impliedType) { |
@@ -292,6 +318,7 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator { |
writeln('];'); |
writeln(); |
+ writeln('@override'); |
writeln('final String name;'); |
writeln(); |
writeln('const $className._(this.name);'); |
@@ -389,6 +416,10 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator { |
writeln(' extends RefactoringFeedback {'); |
} else if (impliedType.kind == 'refactoringOptions') { |
writeln(' extends RefactoringOptions {'); |
+ } else if (impliedType.kind == 'requestParams') { |
+ writeln(' implements RequestParams {'); |
+ } else if (impliedType.kind == 'requestResult') { |
+ writeln(' implements ResponseResult {'); |
} else { |
writeln(' implements HasToJson {'); |
} |
@@ -631,7 +662,7 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator { |
writeln(' else {'); |
indent(() { |
writeln( |
- "throw jsonDecoder.missingKey(jsonPath, $fieldNameString);"); |
+ "throw jsonDecoder.mismatch(jsonPath, $fieldNameString);"); |
}); |
writeln('}'); |
} else { |
@@ -840,6 +871,7 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator { |
* Emit the toJson() code for an object class. |
*/ |
void emitToJsonMember(TypeObject type) { |
+ writeln('@override'); |
writeln('Map<String, dynamic> toJson() {'); |
indent(() { |
writeln('Map<String, dynamic> result = {};'); |
@@ -891,6 +923,7 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator { |
*/ |
bool emitToRequestMember(ImpliedType impliedType) { |
if (impliedType.kind == 'requestParams') { |
+ writeln('@override'); |
writeln('Request toRequest(String id) {'); |
indent(() { |
String methodString = |
@@ -910,6 +943,7 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator { |
*/ |
bool emitToResponseMember(ImpliedType impliedType) { |
if (impliedType.kind == 'requestResult') { |
+ writeln('@override'); |
writeln('Response toResponse(String id) {'); |
indent(() { |
String jsonPart = impliedType.type != null ? 'toJson()' : 'null'; |
@@ -1095,10 +1129,14 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator { |
@override |
visitApi() { |
- outputHeader(); |
+ outputHeader(year: '2017'); |
writeln(); |
- writeln('part of analysis_server.plugin.protocol.protocol;'); |
+ writeln("import 'dart:convert' hide JsonDecoder;"); |
writeln(); |
+ writeln("import 'package:analyzer/src/generated/utilities_general.dart';"); |
+ writeln("import 'package:$packageName/protocol/protocol.dart';"); |
+ writeln( |
+ "import 'package:$packageName/src/protocol/protocol_internal.dart';"); |
emitClasses(); |
} |
} |
@@ -1130,6 +1168,7 @@ abstract class FromJsonCode { |
* Representation of FromJsonCode for a function defined elsewhere. |
*/ |
class FromJsonFunction extends FromJsonCode { |
+ @override |
final String asClosure; |
FromJsonFunction(this.asClosure); |
@@ -1201,6 +1240,7 @@ abstract class ToJsonCode { |
* Representation of ToJsonCode for a function defined elsewhere. |
*/ |
class ToJsonFunction extends ToJsonCode { |
+ @override |
final String asClosure; |
ToJsonFunction(this.asClosure); |