Allow for typemaps that reduce everything except null.

This commit is contained in:
Juraj Kirchheim
2020-04-24 15:29:24 +02:00
parent 34516086c9
commit e3bac681ce
3 changed files with 53 additions and 15 deletions

View File

@@ -8,14 +8,33 @@ import haxe.macro.Type;
using tink.MacroApi; using tink.MacroApi;
class TypeMap<V> extends BalancedTree<Type, V> implements IMap<Type, V> { class TypeMap<V> extends BalancedTree<Type, V> implements IMap<Type, V> {
var follow:Bool; var normalize:Type->Type;
public function new(?noFollow:Bool) { public function new(?normalize:Type->Type) {
this.follow = noFollow != true; this.normalize = switch normalize {
case null: function (t) return t.reduce();
case fn: fn;
}
super(); super();
} }
override function compare(k1:Type, k2:Type):Int override function compare(k1:Type, k2:Type):Int
return k1.compare(k2, follow); return normalize(k1).compare(normalize(k2), false);
static public function noFollow(t:Type)
return t;
static public function keepNull(t:Type):Type
return switch t {
case TAbstract(_.get() => { name: 'Null', pack: [] }, [t])
#if !haxe4 | TType(_.get() => { name: 'Null', pack: []}, [t]) #end
:
var ct = keepNull(t).toComplex({ direct: true });
(macro : Null<$ct>).toType().sure();
case TLazy(f): keepNull(f());
case TType(_, _): keepNull(Context.follow(t, true));
default: t;
}
} }

1
tests/MyString.hx Normal file
View File

@@ -0,0 +1 @@
typedef MyString = String;

View File

@@ -1,17 +1,17 @@
package; package;
import haxe.unit.TestCase; import haxe.unit.TestCase;
import haxe.macro.Expr;
import tink.macro.TypeMap; using tink.MacroApi;
using haxe.macro.Context;
class TypeMapTest extends TestCase { class TypeMapTest extends TestCase {
function testMap() { function testMap() {
var t = new TypeMap(); var t = new TypeMap();
var t1 = (macro [{ foo: [{ bar: '5' }]}]).typeof(); var t1 = (macro [{ foo: [{ bar: '5' }]}]).typeof().sure();
var t2 = (macro [{ foo: [{ bar: 5 }]}]).typeof(); var t2 = (macro [{ foo: [{ bar: 5 }]}]).typeof().sure();
t.set(t1, 0); t.set(t1, 0);
assertEquals(Lambda.count(t), 1); assertEquals(Lambda.count(t), 1);
t.set(t2, 1); t.set(t2, 1);
@@ -20,11 +20,29 @@ class TypeMapTest extends TestCase {
assertEquals(Lambda.count(t), 2); assertEquals(Lambda.count(t), 2);
t.set(t2, 3); t.set(t2, 3);
assertEquals(Lambda.count(t), 2); assertEquals(Lambda.count(t), 2);
assertEquals(t.get(t1), 2); assertEquals(t.get(t1), 2);
assertEquals(t.get(t2), 3); assertEquals(t.get(t2), 3);
assertTrue(true); assertTrue(true);
} }
function testNormalization() {
for (settings in [
{ count: 4, map: new TypeMap(TypeMap.noFollow)},
{ count: 2, map: new TypeMap(TypeMap.keepNull)},
{ count: 1, map: new TypeMap()},
]) {
function set(ct:ComplexType)
settings.map.set(ct.toType().sure(), ct);
set(macro : String);
set(macro : MyString);
set(macro : Null<String>);
set(macro : Null<MyString>);
assertEquals(settings.count, Lambda.count(settings.map));
}
}
} }