using compiler abstract class MagicPlugin : DslPlugin { new make(Compiler c) : super(c) {} override Expr compile(DslExpr expr) { loc := expr.loc doMagic(type(loc, expr), slot(loc, expr), loc, expr.src) return LiteralExpr.makeNull(expr.loc, ns) } private CompilationUnit unit(Loc loc) { units.find { it.loc.file == loc.file } } //facet qname private static const Str fn := "magic::Magic" private TypeDef type(Loc loc, Expr expr) { unit(loc).types.find { (it.facets?.any { it.vals.contains(expr) } ?: false) || it.slotDefs.any { it.facets?.any { it.vals.contains(expr) } ?: false } } } private SlotDef? slot(Loc loc, Expr expr) { type(loc, expr).slotDefs.find { it.facets?.any { it.vals.contains(expr) } ?: false } } ** ** type - type definition of enclosing type ** method - method definition. If method is null, ** then magic applied to type, otherwise - to method ** abstract Void doMagic(TypeDef type, SlotDef? slot, Loc loc, Str src) }