diff --git a/src/json2object/TypeUtils.hx b/src/json2object/TypeUtils.hx index 5be4cd3..5e88ed5 100644 --- a/src/json2object/TypeUtils.hx +++ b/src/json2object/TypeUtils.hx @@ -118,5 +118,9 @@ class TypeUtils return t; } + + public static function isAlive(ct:ComplexType, pos:Position):Type { + return try Context.resolveType(ct, pos) catch(e) null; + } } #end diff --git a/src/json2object/reader/DataBuilder.hx b/src/json2object/reader/DataBuilder.hx index 7860aac..f23433c 100644 --- a/src/json2object/reader/DataBuilder.hx +++ b/src/json2object/reader/DataBuilder.hx @@ -39,10 +39,8 @@ typedef JsonType = {jtype:String, name:String, params:Array} typedef ParserInfo = {packs:Array, clsName:String} class DataBuilder { - @:persistent - private static var counter = 0; - private static var parsers = new Map(); + private static var parsers = new Map(); private static var callPosition:Null = null; private static var jcustom = ":jcustomparse"; @@ -936,9 +934,14 @@ class DataBuilder { public static function makeParser(c:BaseType, type:Type, ?base:Type=null) { if (base == null) { base = type; } - var parserMapName = base.toString(); - if (parsers.exists(parserMapName)) { - return parsers.get(parserMapName); + var parserName = c.name + "_" + haxe.crypto.Md5.encode(base.toString()); + var parser_cls = { name: parserName, pack: [], params: null, sub: null }; + + if (parsers.exists(parserName)) { + var resolved = TypeUtils.isAlive(TPath(parser_cls), Context.currentPos()); + if (resolved != null) { + return resolved; + } } var defaultValueExpr:Expr = switch (type) { @@ -955,7 +958,6 @@ class DataBuilder { default: macro {}; } - var parserName = c.name + "_" + (counter++); var parent = {name:"BaseParser", pack:["json2object", "reader"], params:[TPType(base.toComplexType())]}; var parser = macro class $parserName extends $parent { public function new(?errors:Array=null, ?putils:json2object.PositionUtils=null, ?errorType:json2object.Error.ErrorType=json2object.Error.ErrorType.NONE) { @@ -991,7 +993,6 @@ class DataBuilder { }); } - var parser_cls = { name: parserName, pack: [], params: null, sub: null }; var getAutoExpr = macro return new $parser_cls([], putils, NONE).loadJson({value:JNull, pos:{file:"",min:0, max:1}}); var getAuto:Field = { doc: null, @@ -1080,9 +1081,9 @@ class DataBuilder { haxe.macro.Context.defineType(parser); - var constructedType = haxe.macro.Context.getType(parserName); - parsers.set(parserMapName, constructedType); - return constructedType; + parsers.set(parserName, true); + + return haxe.macro.Context.resolveType(TPath(parser_cls), Context.currentPos()); } diff --git a/src/json2object/utils/schema/DataBuilder.hx b/src/json2object/utils/schema/DataBuilder.hx index f7b1541..47c990a 100644 --- a/src/json2object/utils/schema/DataBuilder.hx +++ b/src/json2object/utils/schema/DataBuilder.hx @@ -42,12 +42,43 @@ typedef Definitions = Map; class DataBuilder { - static var BOOL = Context.getType("Bool"); - static var FLOAT = Context.getType("Float"); - static var STRING = Context.getType("String"); + static var cachedBool:Type = null; + static var cachedFloat:Type = null; + static var cachedString:Type = null; + + static var BOOL(get, never):Type; + static var FLOAT(get, never):Type; + static var STRING(get, never):Type; + + static function get_BOOL() { + return switch cachedBool { + case null: + cachedBool = Context.getType("Bool"); + case cached: + cached; + } + } + + static function get_FLOAT() { + return switch cachedFloat { + case null: + cachedFloat = Context.getType("Float"); + case cached: + cached; + } + } + + static function get_STRING() { + return switch cachedString { + case null: + cachedString = Context.getType("String"); + case cached: + cached; + } + } - static var counter:Int = 0; - private static var writers = new Map(); + @:persistent + private static var writers = new Map(); private inline static function describe (type:JsonType, descr:Null) { return (descr == null) ? type : JTWithDescr(type, descr); @@ -413,7 +444,15 @@ class DataBuilder { } static function makeSchemaWriter(c:BaseType, type:Type, parsingType:ParsingType) { - var swriterName = c.name + "_" + (counter++); + var swriterName = c.name + "_" + haxe.crypto.Md5.encode(type.toString() + Std.string(parsingType)); + var swriter_cls = { name: swriterName, pack: [], params: null, sub: null }; + + if (writers.exists(swriterName)) { + var resolved = TypeUtils.isAlive(TPath(swriter_cls), Context.currentPos()); + if (resolved != null) { + return resolved; + } + } var definitions = new Definitions(); var obj = format(makeSchema(type, definitions), definitions, parsingType); @@ -436,8 +475,9 @@ class DataBuilder { } haxe.macro.Context.defineType(schemaWriter); - var constructedType = haxe.macro.Context.getType(swriterName); - return haxe.macro.Context.getType(swriterName); + writers.set(swriterName, true); + + return Context.resolveType(TPath(swriter_cls), Context.currentPos()); } public static function build() { diff --git a/src/json2object/writer/DataBuilder.hx b/src/json2object/writer/DataBuilder.hx index 4016a79..1d7f602 100644 --- a/src/json2object/writer/DataBuilder.hx +++ b/src/json2object/writer/DataBuilder.hx @@ -36,8 +36,7 @@ using json2object.utils.TypeTools; class DataBuilder { @:persistent - private static var counter = 0; - private static var writers = new Map(); + private static var writers = new Map(); private static var jcustom = ":jcustomwrite"; private static function notNull (type:Type) : Type { @@ -383,12 +382,16 @@ class DataBuilder { public static function makeWriter (c:BaseType, type:Type, base:Type) { if (base == null) { base = type; } - var writerMapName = base.toString(); - if (writers.exists(writerMapName)) { - return writers.get(writerMapName); - } + var writerName = c.name + "_" + haxe.crypto.Md5.encode(base.toString()); + var writer_cls = { name: writerName, pack: [], params: null, sub: null }; - var writerName = c.name + "_" + (counter++); + if (writers.exists(writerName)) { + var resolved = TypeUtils.isAlive(TPath(writer_cls), Context.currentPos()); + if (resolved != null) { + return resolved; + } + } + var writerClass = macro class $writerName { public var ignoreNullOptionals : Bool; private var shouldQuote : Bool = true; @@ -514,10 +517,9 @@ class DataBuilder { haxe.macro.Context.defineType(writerClass); - var constructedType = haxe.macro.Context.getType(writerName); - writers.set(writerMapName, constructedType); - return constructedType; + writers.set(writerName, true); + return Context.resolveType(TPath(writer_cls), Context.currentPos()); } public static function build() {