Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove @:excluded/not-@:included tests at compile time #17

Open
kevinresol opened this issue Feb 26, 2019 · 5 comments
Open

Remove @:excluded/not-@:included tests at compile time #17

kevinresol opened this issue Feb 26, 2019 · 5 comments

Comments

@kevinresol
Copy link
Member

For @:exclude it should be easy. Just inject build macro and remove fields with such meta.

For @:include it might be tricky. We need to process all test classes too see if there are any @:include first, then exclude anything else.

Any ideas?

@back2dos
Copy link
Member

For what purpose exactly?

@kevinresol
Copy link
Member Author

Main advantage is that those excluded tests are no longer required to be type-able, only valid syntax is enough. It is useful when in the middle of refactoring, etc.

@back2dos
Copy link
Member

For that we'd have to make the suite be processed by a build macro though.

Pruning non-included tests might work if you delay typing of the function bodies (e.g. via tink.macro.Exprs.bounce), hoping that all the build macros are triggered up front. What this means though is that you have to be very careful about what you're typing when. I think passing every expression to Context.typeof in TestBatch.make might trigger things in the right order.

@kevinresol
Copy link
Member Author

First of all I need to understand bounce(), which I have been failed to do so.

@back2dos
Copy link
Member

It "bounces" macro execution through the compiler. It takes a function that is meant to produce an expression "later". So it registers that function with an id, then it returns a macro call with that id is param. When the typer gets to that macro call, it executes it, the delayed call is looked up by id, executed and the resulting expression is returned.

Example:

myMacro(
  for (i in 0...100)
    @magic i;
);
//where
macro static function myMacro(e:Expr)
  return (function applyMagic(e:Expr) return switch e {
    case macro @magic $v: 
      trace(Context.typeof(v));
      v;
    default: e.map(applyMagic);
  })(e);

This will give you unknown identifier i, because while mapping the loop body, the containing loop is not typed yet. Instead, you can do this:

macro static function myMacro(e:Expr)
  return (function applyMagic(e:Expr) return switch e {
    case macro @magic $v: 
      (function () {
        trace(Context.typeof(v));
        return v;
      }).bounce();
    default: e.map(applyMagic);
  })(e);

It's kind of like return a call to another macro from a macro, except that instead of having to define the returned macro, you can just pass an anonymous function.

That said, given how typing works, there's a chance (limited as it may be) that actually you don't even need to delay expression typing, because the compiler tries to do that as late as possible anyway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants