diff --git a/src/tink/MacroApi.hx b/src/tink/MacroApi.hx index d4449ff..1b7eb31 100644 --- a/src/tink/MacroApi.hx +++ b/src/tink/MacroApi.hx @@ -19,7 +19,6 @@ typedef Unops = tink.macro.Ops.Unary; typedef MacroOutcome = tink.core.Outcome; typedef MacroOutcomeTools = tink.OutcomeTools; -typedef Option = haxe.ds.Option; typedef Member = tink.macro.Member; typedef Constructor = tink.macro.Constructor; diff --git a/src/tink/macro/BuildCache.hx b/src/tink/macro/BuildCache.hx index c1878f4..0a8037e 100644 --- a/src/tink/macro/BuildCache.hx +++ b/src/tink/macro/BuildCache.hx @@ -5,8 +5,15 @@ import haxe.macro.Expr; import haxe.macro.Type; import tink.macro.TypeMap; -using haxe.macro.ComplexTypeTools; -using haxe.macro.TypeTools; +using haxe.macro.Tools; + +typedef BuildContextN = { + pos:Position, + types:Array, + usings:Array, + name:String, +} + typedef BuildContext = { pos:Position, @@ -25,20 +32,7 @@ typedef BuildContext3 = {>BuildContext2, class BuildCache { - static var cache = init(); - - static function init() { - - function refresh() { - cache = new Map(); - return true; - } - - Context.onMacroContextReused(refresh); - refresh(); - - return cache; - } + static var cache = new Map(); static public function getType3(name, ?types, ?pos:Position, build:BuildContext3->TypeDefinition) { if (types == null) @@ -63,6 +57,33 @@ class BuildCache { })); } + static public function getTypeN(name, ?types, ?pos:Position, build:BuildContextN->TypeDefinition) { + + if (pos == null) + pos = Context.currentPos(); + + if (types == null) + switch Context.getLocalType() { + case TInst(_.toString() == name => true, params): + types = params; + default: + throw 'assert'; + } + + var compound = ComplexType.TAnonymous([for (i in 0...types.length) { + name: 't$i', + pos: pos, + kind: FVar(types[i].toComplexType()), + }]).toType(); + + return getType(name, compound, pos, function (ctx) return build({ + types: types, + pos: ctx.pos, + name: ctx.name, + usings: ctx.usings + })); + } + static public function getType2(name, ?types, ?pos:Position, build:BuildContext2->TypeDefinition) { if (types == null) switch Context.getLocalType() { @@ -103,14 +124,32 @@ class BuildCache { var forName = switch cache[name] { - case null: cache[name] = new TypeMap(); + case null: cache[name] = new Group(name); case v: v; } - - if (!forName.exists(type)) { - var path = '$name${Lambda.count(forName)}', - usings = []; - + + return forName.get(type, pos, build); + } +} + +private typedef Entry = { + name:String, +} + +private class Group { + + var name:String; + var counter = 0; + var entries = new TypeMap(); + + public function new(name) { + this.name = name; + } + + public function get(type:Type, pos:Position, build:BuildContext->TypeDefinition):Type { + + function make(path:String) { + var usings = []; var def = build({ pos: pos, type: type, @@ -119,9 +158,21 @@ class BuildCache { }); Context.defineModule(path, [def], usings); - forName.set(type, Context.getType(path)); + entries.set(type, { name: path } ); + return Context.getType(path); } - return forName.get(type); + return + switch entries.get(type) { + case null: + make('$name${counter++}'); + case v: + try { + Context.getType(v.name); + } + catch (e:Dynamic) { + make(v.name); + } + } } } \ No newline at end of file