Make TypeMap work exacly with anons.

This commit is contained in:
Juraj Kirchheim
2021-03-14 13:25:20 +01:00
parent 94d02c91a8
commit 7e2dfad607
5 changed files with 47 additions and 25 deletions

View File

@@ -138,7 +138,7 @@ class Sisyphus {
} }
} }
static function exactBase<T:BaseType>(r:haxe.macro.Type.Ref<T>, params:Array<Type>) { static function exactBase<T:BaseType>(r:Ref<T>, params:Array<Type>) {
var t = r.get(); var t = r.get();
var isMain = !t.isPrivate && switch t.pack { var isMain = !t.isPrivate && switch t.pack {
case []: t.module == t.name || t.module == 'StdTypes'; case []: t.module == t.name || t.module == 'StdTypes';
@@ -197,4 +197,29 @@ class Sisyphus {
case TLazy(f): toExactString(f()); case TLazy(f): toExactString(f());
} }
static function eager(t:Type)
return switch t {
case TLazy(f): eager(f());
default: t;
}
static public function compare(t1:Type, t2:Type, ?follow:Bool = true) {
if (follow) {
t1 = t1.reduce();
t2 = t2.reduce();
}
else {
t1 = eager(t1);
t2 = eager(t2);
}
return switch t1.getIndex() - t2.getIndex() {
case 0:
switch Reflect.compare(t1.toString(), t2.toString()) {
case 0: Reflect.compare(t1.toExactString(), t2.toExactString());
case v: v;
}
case v: v;
}
}
} }

View File

@@ -10,6 +10,8 @@ using haxe.macro.Tools;
using tink.MacroApi; using tink.MacroApi;
using tink.CoreApi; using tink.CoreApi;
import haxe.macro.Type.Ref;
class Types { class Types {
static public function definedType(typeName:String) static public function definedType(typeName:String)
@@ -355,18 +357,8 @@ class Types {
throw 'assert'; throw 'assert';
} }
static public function compare(t1:Type, t2:Type, ?follow:Bool = true) { static public function compare(t1:Type, t2:Type, ?follow:Bool = true)
if (follow) { return Sisyphus.compare(t1, t2, follow);
t1 = t1.reduce();
t2 = t2.reduce();
}
return switch t1.getIndex() - t2.getIndex() {
case 0:
Reflect.compare(t1.toString(), t2.toString());//much to my surprise, this actually seems to work (at least with 3.4)
case v: v;
}
}
static var SUGGESTIONS = ~/ \(Suggestions?: .*\)$/; static var SUGGESTIONS = ~/ \(Suggestions?: .*\)$/;

View File

@@ -1,4 +1,3 @@
import haxe.macro.Context;
import haxe.macro.Context.typeof; import haxe.macro.Context.typeof;
using tink.MacroApi; using tink.MacroApi;
@@ -12,6 +11,8 @@ class ExactStrings extends Base {
expect('Dummy.Private', macro Dummy.p); expect('Dummy.Private', macro Dummy.p);
expect('nested.Dummy.Private', macro nested.Dummy.p); expect('nested.Dummy.Private', macro nested.Dummy.p);
expect('{ @foo var x:Int; }', macro (null:{@foo var x:Int;})); expect('{ @foo var x:Int; }', macro (null:{@foo var x:Int;}));
expect('{ @foo @bar var x:Int; }', macro (null:{@foo @bar var x:Int;}));
expect('{ @bar @foo var x:Int; }', macro (null:{@bar @foo var x:Int;}));// not 100% sure this is always the best choice, but let's roll with it
expect('{ @bar var x:Int; }', macro (null:{@bar var x:Int;})); expect('{ @bar var x:Int; }', macro (null:{@bar var x:Int;}));
expect('{ var x:Int; var y:Int; }', macro (null:{x:Int,y:Int})); expect('{ var x:Int; var y:Int; }', macro (null:{x:Int,y:Int}));
expect('{ var x:Int; var y:Int; }', macro (null:{y:Int,x:Int})); expect('{ var x:Int; var y:Int; }', macro (null:{y:Int,x:Int}));

View File

@@ -11,6 +11,8 @@ class TypeMapTest extends TestCase {
var t = new TypeMap(); var t = new TypeMap();
var t1 = (macro [{ foo: [{ bar: '5' }]}]).typeof().sure(); var t1 = (macro [{ foo: [{ bar: '5' }]}]).typeof().sure();
var t2 = (macro [{ foo: [{ bar: 5 }]}]).typeof().sure(); var t2 = (macro [{ foo: [{ bar: 5 }]}]).typeof().sure();
var t3 = (macro [{ foo: [{ bar: 5 }]}]).typeof().sure();
var t4 = (macro [{ foo: [({ bar: 5 }:{ @foo var bar:Int; })]}]).typeof().sure();
t.set(t1, 0); t.set(t1, 0);
assertEquals(Lambda.count(t), 1); assertEquals(Lambda.count(t), 1);
@@ -19,7 +21,10 @@ class TypeMapTest extends TestCase {
t.set(t1, 2); t.set(t1, 2);
assertEquals(Lambda.count(t), 2); assertEquals(Lambda.count(t), 2);
t.set(t2, 3); t.set(t2, 3);
t.set(t3, 3);
assertEquals(Lambda.count(t), 2); assertEquals(Lambda.count(t), 2);
t.set(t4, 4);
assertEquals(Lambda.count(t), 3);
assertEquals(t.get(t1), 2); assertEquals(t.get(t1), 2);
assertEquals(t.get(t2), 3); assertEquals(t.get(t2), 3);

View File

@@ -10,36 +10,35 @@ using tink.MacroApi;
class Types extends Base { class Types extends Base {
function type(c:ComplexType) function type(c:ComplexType)
return c.toType().sure(); return c.toType().sure();
function resolve(type:String) function resolve(type:String)
return Context.getType(type); return Context.getType(type);
inline function assertSuccess<S, F>(o:Outcome<S, F>) inline function assertSuccess<S, F>(o:Outcome<S, F>)
assertTrue(o.isSuccess()); assertTrue(o.isSuccess());
inline function assertFailure<S, F>(o:Outcome<S, F>) inline function assertFailure<S, F>(o:Outcome<S, F>)
assertFalse(o.isSuccess()); assertFalse(o.isSuccess());
function testIs() { function testIs() {
assertSuccess(resolve('Int').isSubTypeOf(resolve('Float'))); assertSuccess(resolve('Int').isSubTypeOf(resolve('Float')));
assertFailure(resolve('Float').isSubTypeOf(resolve('Int'))); assertFailure(resolve('Float').isSubTypeOf(resolve('Int')));
} }
function testFields() { function testFields() {
var expected = type(macro : Void -> Iterator<Arrayish>), var expected = type(macro : Void -> Iterator<Arrayish>),
iterator = type(macro : haxe.ds.StringMap<Arrayish>).getFields(true).sure().filter(function (c) return c.name == 'iterator')[0]; iterator = type(macro : haxe.ds.StringMap<Arrayish>).getFields(true).sure().filter(function (c) return c.name == 'iterator')[0];
assertSuccess(iterator.type.isSubTypeOf(expected)); assertSuccess(iterator.type.isSubTypeOf(expected));
assertSuccess(expected.isSubTypeOf(iterator.type)); assertSuccess(expected.isSubTypeOf(iterator.type));
} }
function testConvert() { function testConvert() {
assertSuccess((macro : Int).toType()); assertSuccess((macro : Int).toType());
assertFailure((macro : Tni).toType()); assertFailure((macro : Tni).toType());
function blank() function blank()
return type(MacroApi.pos().makeBlankType()); return type(MacroApi.pos().makeBlankType());
var bool = type(macro : Bool); var bool = type(macro : Bool);
assertTrue(blank().isSubTypeOf(bool).isSuccess()); assertTrue(blank().isSubTypeOf(bool).isSuccess());
assertTrue(bool.isSubTypeOf(blank()).isSuccess()); assertTrue(bool.isSubTypeOf(blank()).isSuccess());
@@ -65,7 +64,7 @@ class Types extends Base {
assertEquals('String', Context.getType('String').toComplex().toString()); assertEquals('String', Context.getType('String').toComplex().toString());
assertEquals('tink.CoreApi.Noise', Context.getType('tink.CoreApi.Noise').toComplex().toString()); assertEquals('tink.CoreApi.Noise', Context.getType('tink.CoreApi.Noise').toComplex().toString());
} }
function testDeduceCommonType() { function testDeduceCommonType() {
function ct2t(ct:ComplexType) return ct.toType().sure(); function ct2t(ct:ComplexType) return ct.toType().sure();
assertEquals('StdTypes.Float', tink.macro.Types.deduceCommonType([(macro:Float), (macro:Int)].map(ct2t)).sure().toComplex().toString()); assertEquals('StdTypes.Float', tink.macro.Types.deduceCommonType([(macro:Float), (macro:Int)].map(ct2t)).sure().toComplex().toString());