Chromium Code Reviews| Index: pkg/analysis_server/tool/spec/codegen_java_types.dart |
| diff --git a/pkg/analysis_server/tool/spec/codegen_java_types.dart b/pkg/analysis_server/tool/spec/codegen_java_types.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..b17be3790a3993487764942f7b198efe1fcb4f36 |
| --- /dev/null |
| +++ b/pkg/analysis_server/tool/spec/codegen_java_types.dart |
| @@ -0,0 +1,213 @@ |
| +// 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 "AnalysisServer.java". |
| + */ |
| +library java.generator.types; |
| + |
| +import 'api.dart'; |
| +import 'codegen_java.dart'; |
| +import 'codegen_tools.dart'; |
| +import 'from_html.dart'; |
| + |
| + |
| +/** |
| + * Type references in the spec that are named something else in Java. |
| + */ |
| +const Map<String, String> _typeRenames = const { |
| + 'Override': 'OverrideMember', |
| +}; |
| + |
| +class CodegenJavaType extends CodegenJavaVisitor { |
| + |
| + String className; |
| + TypeDefinition typeDef; |
| + |
| + CodegenJavaType(Api api, String className, TypeDefinition typeDef) |
| + : super(api), |
| + this.className = className, |
| + this.typeDef = typeDef; |
| + |
| + @override |
| + void visitApi() { |
|
Paul Berry
2014/08/13 21:39:07
There's no need for visitApi() to be the main entr
jwren
2014/08/13 22:29:16
Done.
|
| + outputHeader(javaStyle: true); |
| + writeln('package com.google.dart.server.generated.types;'); |
| + writeln(); |
| + // Currently non TypeObjects aren't being passed this visitor, but it may soon to generate enums or classes |
| + // that hold onto the values of a particular enum from the spec. |
| + if (typeDef.type is TypeObject) { |
| + writeln('import java.util.Arrays;'); |
| + writeln('import java.util.List;'); |
| + writeln('import java.util.Map;'); |
| + writeln('import com.google.dart.server.utilities.general.ObjectUtilities;'); |
| + writeln('import org.apache.commons.lang3.StringUtils;'); |
| + writeln(); |
| + docComment(toHtmlVisitor.collectHtml(() { |
| + toHtmlVisitor.translateHtml(typeDef.html); |
| + toHtmlVisitor.br(); |
| + toHtmlVisitor.write('@coverage dart.server.generated.types'); |
| + }), width: 99, javadocStyle: true); |
| + writeln('@SuppressWarnings("unused")'); |
| + makeClass('public class ${className}', () { |
| + // |
| + // fields |
| + // |
| + TypeObject type = typeDef.type as TypeObject; |
| + List<TypeObjectField> fields = type.fields; |
| + for (TypeObjectField field in fields) { |
| + privateField(javaName(field.name), () { |
| + docComment(toHtmlVisitor.collectHtml(() { |
| + toHtmlVisitor.translateHtml(field.html); |
| + }), width: 99, javadocStyle: true); |
|
Paul Berry
2014/08/13 21:39:06
(Not really a comment on this CL, just an idea for
jwren
2014/08/13 22:29:16
Subclasses can't override with different default v
|
| + writeln('private final ${javaType(field.type)} ${javaName(field.name)};'); |
| + }); |
| + } |
| + // |
| + // constructor |
| + // |
| + constructor(className, () { |
| + docComment(toHtmlVisitor.collectHtml(() { |
| + toHtmlVisitor.write('Constructor for {@link ${className}}.'); |
| + }), width: 99, javadocStyle: true); |
| + write('public ${className}('); |
| + // write out parameters to constructor: |
| + List<String> parameters = new List(); |
| + for (TypeObjectField field in fields) { |
| + parameters.add('${javaType(field.type)} ${javaName(field.name)}'); |
| + } |
| + write(parameters.join(', ')); |
| + writeln(') {'); |
| + // write out the assignments in the |
|
Paul Berry
2014/08/13 21:39:06
Incomplete comment?
jwren
2014/08/13 22:29:16
Done.
|
| + for (TypeObjectField field in fields) { |
| + writeln(' this.${javaName(field.name)} = ${javaName(field.name)};'); |
| + } |
| + writeln('}'); |
| + }); |
| + // |
| + // getter methods |
| + // |
| + for (TypeObjectField field in fields) { |
| + publicMethod('get${javaName(field.name)}', () { |
| + docComment(toHtmlVisitor.collectHtml(() { |
| + toHtmlVisitor.translateHtml(field.html); |
| + }), width: 99, javadocStyle: true); |
| + writeln('public ${javaType(field.type)} get${capitalize(javaName(field.name))}() {'); |
| + writeln(' return ${javaName(field.name)};'); |
| + writeln('}'); |
| + }); |
| + } |
| + // |
| + // equals method |
| + // |
| + publicMethod('equals', () { |
| + writeln('@Override'); |
| + writeln('public boolean equals(Object obj) {'); |
| + indent(() { |
| + writeln('if (obj instanceof ${className}) {'); |
| + indent(() { |
| + writeln('${className} other = (${className}) obj;'); |
| + writeln('return'); |
| + indent(() { |
| + List<String> equalsForField = new List<String>(); |
| + for (TypeObjectField field in fields) { |
| + equalsForField.add(_equalsLogicForField(field, 'other')); |
| + } |
| + write(equalsForField.join(' && \n')); |
| + }); |
| + writeln(';'); |
| + }); |
| + writeln('}'); |
| + writeln('return false;'); |
| + }); |
| + writeln('}'); |
| + }); |
| + // |
| + // hashCode |
| + // |
| + // TODO (jwren) have hashCode written out |
| + // |
| + // toString |
| + // |
| + publicMethod('toString', () { |
| + writeln('@Override'); |
| + writeln('public String toString() {'); |
| + indent(() { |
| + writeln('StringBuilder builder = new StringBuilder();'); |
| + writeln('builder.append(\"[\");'); |
| + for (TypeObjectField field in fields) { |
| + // TODO (jwren) nit: don't print the last ", " |
| + writeln("builder.append(\"${javaName(field.name)}=\");"); |
| + writeln("builder.append(${_toStringForField(field)} + \", \");"); |
| + } |
| + writeln('builder.append(\"]\");'); |
| + writeln('return builder.toString();'); |
| + }); |
| + writeln('}'); |
| + writeln(); |
| + }); |
| + super.visitApi(); |
|
Paul Berry
2014/08/13 21:39:06
This will call HierarchicalApiVisitor.visitApi(),
jwren
2014/08/13 22:29:16
Fixed.
|
| + }); |
| + } |
| + } |
| + |
| + String _equalsLogicForField(TypeObjectField field, String other) { |
| + String name = javaName(field.name); |
| + if (isPrimitive(field.type)) { |
| + return 'other.${name} == ${name}'; |
| + } else if (isArray(field.type)) { |
| + return 'Arrays.equals(other.${name}, ${name})'; |
| + } else { |
| + return 'ObjectUtilities.equals(other.${name}, ${name})'; |
| + } |
| + } |
| + |
| + String _toStringForField(TypeObjectField field) { |
| + String name = javaName(field.name); |
| + if (isPrimitive(field.type)) { |
| + return name; |
| + } else if (isArray(field.type) || isList(field.type)) { |
| + return 'StringUtils.join(${name}, ", ")'; |
| + } else { |
| + return '${name}.toString()'; |
| + } |
| + } |
| + |
| + /** |
| + * Get the name of the consumer class for responses to this request. |
| + */ |
| + String consumerName(Request request) { |
| + return camelJoin([request.method, 'consumer'], capitalize: true); |
| + } |
| +} |
| + |
| +final String pathToGenTypes = '../../../../editor/tools/plugins/com.google.dart.server/src/com/google/dart/server/generated/types/'; |
| + |
| +final GeneratedDirectory targetDir = new GeneratedDirectory(pathToGenTypes, () { |
| + Api api = readApi(); |
| + Map<String, FileContentsComputer> map = new Map<String, FileContentsComputer>(); |
| + for (String typeNameInSpec in api.types.keys) { |
| + TypeDefinition typeDef = api.types[typeNameInSpec]; |
| + if (typeDef.type is TypeObject) { |
| + // for situations such as 'Override' where the name in the spec doesn't match the java object that we generate: |
| + String typeNameInJava = typeNameInSpec; |
| + if (_typeRenames.containsKey(typeNameInSpec)) { |
| + typeNameInJava = _typeRenames[typeNameInSpec]; |
| + } |
| + map['${typeNameInJava}.java'] = () { |
| + // create the visitor |
| + CodegenJavaType visitor = new CodegenJavaType(api, typeNameInJava, typeDef); |
| + return visitor.collectCode(visitor.visitApi); |
|
Paul Berry
2014/08/13 21:39:06
Assuming you take my first suggestion in this file
jwren
2014/08/13 22:29:15
Done.
jwren
2014/08/13 22:29:15
Done.
|
| + }; |
| + } |
| + } |
| + return map; |
| +}); |
| + |
| +/** |
| + * Translate spec_input.html into AnalysisServer.java. |
| + */ |
| +main() { |
| + targetDir.generate(); |
| +} |