From eaae6fe386078bfa2994bfa2e96818bb37e97285 Mon Sep 17 00:00:00 2001 From: Caijinglong Date: Tue, 7 Aug 2018 15:14:39 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=BA=86=E4=B8=BB=E9=A2=98?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/generator.dart | 51 +++++++++-- lib/json_generator.dart | 108 ++++++++++++++++++++++ lib/template.dart | 195 ++++++++++++++++++++++++++++++++++++++-- lib/test.dart | 3 + web/index.html | 6 ++ web/main.dart | 41 +-------- web/styles.css | 8 ++ 7 files changed, 359 insertions(+), 53 deletions(-) create mode 100644 lib/json_generator.dart create mode 100644 lib/test.dart diff --git a/lib/generator.dart b/lib/generator.dart index a071d93..2fc616c 100644 --- a/lib/generator.dart +++ b/lib/generator.dart @@ -1,17 +1,58 @@ +import 'dart:convert'; + import 'package:json2dart_serialization/template.dart'; class Generator { String jsonString; String fileName; - Generator(this.jsonString, this.fileName); + String entityName; + + Generator(this.jsonString, this.fileName, [this.entityName]); + + List templateList = []; String makeDartCode() { - Template template = DefaultTemplate(); - return jsonString; + var entityName = this.entityName ?? "Entity"; + DefaultTemplate template = + DefaultTemplate(srcJson: jsonString, className: entityName); + StringBuffer resultSb = StringBuffer(); + templateList.add(template); + refreshTemplate(template); + + resultSb.writeln(header); + templateList.forEach((template) { + resultSb.writeln(template.toString()); + }); + return resultSb.toString(); } - static const String importString = "import 'package:json_annotation/json_annotation.dart';"; + void refreshTemplate(DefaultTemplate template) { + var fieldList = template.fieldList; + bool needRefresh = false; + fieldList.forEach((filed) { + if (filed is MapField) { +// filed.typeString + DefaultTemplate template = DefaultTemplate( + srcJson: json.encode(filed.map), className: filed.typeString); + templateList.add(template); + refreshTemplate(template); + } else if (filed is ListField) { + if (filed.childIsObject) { + DefaultTemplate template = DefaultTemplate( + srcJson: json.encode(filed.list[0]), className: filed.typeName); + templateList.add(template); + refreshTemplate(template); + } + } + }); + } + + static const String importString = + "import 'package:json_annotation/json_annotation.dart';"; String get header => """$importString - part $fileName.g.dart;"""; + +part $fileName.g.dart; + +"""; } diff --git a/lib/json_generator.dart b/lib/json_generator.dart new file mode 100644 index 0000000..36ccfba --- /dev/null +++ b/lib/json_generator.dart @@ -0,0 +1,108 @@ +import 'dart:convert'; +import 'dart:html'; + +import 'package:json2dart_serialization/generator.dart'; + +String entityName = null; + +bool useJsonKey = true; + +bool isCamelCase = true; + +const defaultValue = """{ + "body": "", + "data": [1], + "input_content":["1"], + "list1":[{"name":"hello"}], + "number": [1.02], + "user":{"name":"abc"} +}"""; + +void main() { + TextAreaElement jsonInput = querySelector("#json"); + jsonInput.value = defaultValue; + + jsonInput.onInput.listen((event) { + refreshData(); + }); + + InputElement entityNameEle = querySelector("#out_entity_name"); + entityNameEle.onInput.listen((event) { + entityName = entityNameEle.value; + refreshData(); + }); + + ButtonElement formatButton = querySelector("#format"); + formatButton.onClick.listen((click) { + String pretty; + try { + pretty = formatJson(jsonInput.value); + } on Exception { + return; + } + jsonInput.value = pretty; + }); + + InputElement eJsonKey = querySelector("#use_json_key"); + InputElement eCamelCase = querySelector("#camelCase"); + + void onJsonKeyChange() { + useJsonKey = eJsonKey.checked; + eCamelCase.disabled = !useJsonKey; + isCamelCase = false; + refreshData(); + } + + eJsonKey.checked = useJsonKey; + eJsonKey.onInput.listen((event) { + onJsonKeyChange(); + }); + + querySelector("#check_label").onClick.listen((event) { + eJsonKey.checked = !eJsonKey.checked; + onJsonKeyChange(); + }); + + eCamelCase.checked = isCamelCase; + eCamelCase.onInput.listen((event) { + isCamelCase = eCamelCase.checked; + refreshData(); + }); + + querySelector("#camelCaseLabel").onClick.listen((event) { + eCamelCase.checked = !eCamelCase.checked; + refreshData(); + }); + + refreshData(); +} + +void refreshData() { + TextAreaElement jsonInput = querySelector("#json"); + var string = jsonInput.value; + String pretty; + TextAreaElement result = querySelector("#result"); + try { + pretty = formatJson(string); + } on Exception { + result.value = "不是一个正确的json"; + return; + } + String entityClassName; + if (entityName == null || entityName == "" || entityName.trim() == "") { + entityClassName = "Entity"; + } else { + entityClassName = entityName; + } + + var generator = Generator(string, 'test.dart', entityClassName); + var dartCode = generator.makeDartCode(); + + result.value = dartCode; +} + +String formatJson(String jsonString) { + var map = json.decode(jsonString); + var prettyString = JsonEncoder.withIndent(" ").convert(map); + return prettyString; +} diff --git a/lib/template.dart b/lib/template.dart index 2a8cb60..8549bd1 100644 --- a/lib/template.dart +++ b/lib/template.dart @@ -1,3 +1,6 @@ +import 'dart:convert'; +import 'package:json2dart_serialization/json_generator.dart' as main; + abstract class Template { String declare(); @@ -8,43 +11,217 @@ abstract class Template { String method(); String end(); + + @override + String toString() { + return createCode(this); + } } class DefaultTemplate extends Template { + String srcJson; + String className; + + String tab = " "; + + DefaultTemplate({this.srcJson, this.className = "Entity"}); + @override String constructor() { - // TODO: implement constructor + var fieldList = FieldHelper(srcJson).getFields(); + var filedString = StringBuffer(); + fieldList.forEach((f) { + filedString.write("this.${f.nameString},"); + }); + return "${tab}$className($filedString);"; } @override String declare() { - // TODO: implement declare + return """@JsonSerializable() +class $className extends Object with _\$${className}SerializerMixin {"""; } @override String end() { - // TODO: implement end + return "}"; } @override String field() { - // TODO: implement field +// var useJsonKey + + var fieldList = FieldHelper(srcJson).getFields(); + var sb = StringBuffer(); + fieldList.forEach((f) { + sb.writeln(); + if (main.useJsonKey) { + sb.writeln(" @JsonKey(name: '${f.nameString}')"); + } + String nameString; + if (main.isCamelCase) { + nameString = camelCase(f.nameString); + } else { + nameString = f.nameString; + } + sb.writeln(" ${f.typeString} $nameString;"); + }); + return sb.toString(); + } + + String camelCase(String name) { + StringBuffer sb = StringBuffer(); + var list = name.split("_"); + for (int i = 0; i < list.length; i++) { + var item = list[i]; + String name = ""; + if (i == 0) { + name = firstLetterLower(item); + } else { + name = firstLetterUpper(item); + } + sb.write(name); + } + return sb.toString(); } @override String method() { - // TODO: implement method + return " factory $className.fromJson(Map srcJson) => _\$${className}(srcJson);"; + } + + List get fieldList => FieldHelper(srcJson).getFields(); +} + +class FieldHelper { + String srcJson; + + FieldHelper(this.srcJson); + + List getFields() { + var j = json.decode(srcJson); + if (j is Map) { + List list = []; + j.forEach((k, v) { + if (v is List) { + list.add(ListField(v, k)); + } else if (v is String) { + list.add(SimpleField("String", k)); + } else if (v is int) { + list.add(SimpleField("int", k)); + } else if (v is double) { + list.add(SimpleField("double", k)); + } else if (v is bool) { + list.add(SimpleField("bool", k)); + } else if (v is Map) { + list.add(MapField(v, k)); + } + }); + return list; + } + return []; + } +} + +abstract class Field { + String get typeString; + + String get nameString; +} + +class SimpleField extends Field { + @override + String typeString; + + @override + String nameString; + + SimpleField(this.typeString, this.nameString); +} + +class ListField extends Field { + List list; + + @override + String nameString; + + ListField(this.list, this.nameString); + + bool get childIsObject { + if (list == null || list.isEmpty) { + return false; + } + if (list[0] is Map) { + return true; + } + return false; + } + + String get typeName { + String type = "dynamic"; + if (list == null || list.isEmpty) { + return type; + } + var item = list[0]; + + if (item is List) { + type = "${ListField(item, "").typeString}"; + } else if (item is Map) { + type = "${firstLetterUpper(nameString)}"; + } else if (item is int) { + type = "int"; + } else if (item is double) { + type = "double"; + } else if (item is String) { + type = "String"; + } else if (item is bool) { + type = "bool"; + } + + return type; + } + + @override + String get typeString { + return "List<$typeName>"; + } +} + +class MapField extends Field { + Map map; + String nameString; + + MapField(this.map, this.nameString); + + @override + String get typeString { + return firstLetterUpper(nameString); } } String createCode(Template template) { var code = """${template.declare()} - ${template.field()} - ${template.constructor()} +${template.field()} +${template.constructor()} - ${template.method()} +${template.method()} + +${template.end()} - ${template.end()} """; return code; } + +String firstLetterUpper(String value) { + if (value == null || value.isEmpty) { + return ""; + } + return value[0].toUpperCase() + value.substring(1); +} + +String firstLetterLower(String value) { + if (value == null || value.isEmpty) { + return ""; + } + return value[0].toLowerCase() + value.substring(1); +} diff --git a/lib/test.dart b/lib/test.dart new file mode 100644 index 0000000..70610ba --- /dev/null +++ b/lib/test.dart @@ -0,0 +1,3 @@ +void main() { + print(1.0 is int); +} diff --git a/web/index.html b/web/index.html index d42fff9..d6bba0b 100644 --- a/web/index.html +++ b/web/index.html @@ -27,6 +27,12 @@
+
+ 类名称 + + jsonKey annotation + use camelCase +
diff --git a/web/main.dart b/web/main.dart index 50ffa91..65a918c 100644 --- a/web/main.dart +++ b/web/main.dart @@ -1,42 +1,5 @@ -import 'dart:convert'; -import 'dart:html'; - -import 'package:json2dart_serialization/generator.dart'; +import 'package:json2dart_serialization/json_generator.dart' as app; void main() { - TextAreaElement jsonInput = querySelector("#json"); - jsonInput.onInput.listen((event) { - var string = jsonInput.value; - String pretty; - TextAreaElement result = querySelector("#result"); - try { - pretty = formatJson(string); - } on Exception { - print("格式化错误"); - result.value = "不是一个正确的json"; - return; - } - - var generator = Generator(string, 'test.dart'); - var dartCode = generator.makeDartCode(); - - result.value = dartCode; - }); - - ButtonElement formatButton = querySelector("#format"); - formatButton.onClick.listen((click) { - String pretty; - try { - pretty = formatJson(jsonInput.value); - } on Exception { - return; - } - jsonInput.value = pretty; - }); -} - -String formatJson(String jsonString) { - var map = json.decode(jsonString); - var prettyString = JsonEncoder.withIndent(" ").convert(map); - return prettyString; + app.main(); } diff --git a/web/styles.css b/web/styles.css index c4de2f5..2a56106 100644 --- a/web/styles.css +++ b/web/styles.css @@ -25,4 +25,12 @@ body { textarea { width: 90%; height: 90vh; +} + +.result_title { + padding-bottom: 15px; +} + +.out_entity_name{ + height: 40px; } \ No newline at end of file