Allow for typemaps that reduce everything except null.
This commit is contained in:
@@ -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
1
tests/MyString.hx
Normal file
@@ -0,0 +1 @@
|
|||||||
|
typedef MyString = String;
|
@@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user