-
Notifications
You must be signed in to change notification settings - Fork 35
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
Mutagen architecure proposal #142
Comments
The code can be tested using what? I'm a bit short on time right now, but I'll review your code during the next week, I promise! |
Next week is fine 👍 |
misclick :( |
So if I understand your proposal right, you want to decouple various mutation-embedding parts of the plugin so that each implements its own What I like:
What I dislike:
What I'm unsure about:
|
Thank you for your review. For the most part, we come to the same conclusions about my proposal. Some opinions:
How should we go from here? I would like to resolve any issues with you before finishing my implementation. |
I think we can have the best of both worlds. We would need to create our own trait that deviates from In general, we have three kinds of mutators: Statement mutators (not yet implemented), Expr mutators (see above) and function body block mutators. The Mutator trait should reflect this. |
I do not think the restriction to only convert each variant of the AST to one of the same type is a big issue - semantically, this has to happen anyway for the generated code to be correct. I am currently looking out for a good restriction-system. I did not really understand what you did in the current version. Could you explain that system to me or point to the relevant parts in the code? I am in favor of distinguishing different kinds of mutators and have tried to do so, but have not yet found a satisfying design. I have implemented a statement mutator, but the generated code is not like the other (expr-) mutators. It would be great if we could find something that works the same as the following snippet. (This is the current implementation of if /* check if mutation is active */ {
// run statement
} // else: do not run statement PS: I am currently working on mutation of the |
The idea behind the restrictions system is that we may sometimes have two mutations that lead to the same outcome. For example, if we mutate Statement mutations are really hard, because you have to keep track of so many things to keep the build from failing. I have a draft blog post with all kinds of corner cases you have to care about, perhaps I should post it. |
Personally, I have no problems with duplicate mutations and have decided not to include logic to prevent this. I think this will not affect the overall mutation coverage too much and will not be a large problem when reviewing the survived mutants. Since almost everything in rust is a expression, expressions mutators will get quite far and I will focus on implementing more of them next. |
There was a paper from google that introduced the duplicate avoidance logic. This has multiple benefits: Duplicate mutations cost time to run, skew the coverage results and are actually quite easy to avoid (as in the above example; a simple bitset goes a long way). There's a mutation testing implementer's slack that I frequent who eagerly discuss those results, and I know of 3 frameworks that either already have implemented something like this or have it on the roadmap. Yes, expression mutations already go a long way, but I'd love to see statement mutations. Gotta get that blog post out first. |
Interesting. If you could point me to some source (academic or not), I will habe a look. Would you think it makes sense to continue my effort with my current approach? |
Maybe I should clarify my preferred approach: I am not opposed to duplication-detection, but do not see this as an immediate issue that needs to be solved within this proposal. It can be an item on the roadmap. |
Again, I'd like to change the approach so that the expressions are walked in post-order (first all subexpressions are mutated, then all mutators for the current expressions are called). Also pulling the dispatch between expression types into the mutator calling logic will make the mutator code simpler, which is a win in my book. Otherwise I'm completely fine with this proposal. By the way, here is the blog post I promised. |
I think I understand your suggestion and have implemented the approach how I understand it. Some documentation is still required. Could you have a look at the different implementation in For now, I removed the statement-mutator until we agree on a comprehensive plan how to go forward. |
fold_expr still relies on the With those nits out of he way, I'll gladly accept a PR to change mutagen over to your architecture. |
I am pretty sure I have already implemented your suggestions. The transformers do not implement I have: /// trait that is implemented by all transformers.
///
/// each transformer should not inspect the expression recursively since recursion is performed by the `MutagenTransformerBundle`
pub trait MutagenExprTransformer {
fn map_expr(&mut self, expr: Expr) -> Expr;
}
impl Fold for MutagenTransformerBundle {
fn fold_expr(&mut self, e: Expr) -> Expr {
// transform content of the expression first
let mut result = match e {
// recurse on ALL patterns
};
// call all transformers on this expression
for t in &mut self.expr_transformers {
result = t.map_expr(result);
}
result
}
} |
Ah, I misread the code. Ok then. I still one problem: The lit_int transformer only deals with the literal, it cannot know that the literal is part of an |
Regarding the transformer Seeing the parent |
Ok then. I think we should move forward with this – I can add extensions I feel are warranted later. Can you set up a pull request so we can get this merged? |
I will try to get a pull-request ready in the next few days. |
Closing this issue after merge of pr #149 is merged. |
Hi, I've been working on re-structuring your project
mutagen
to be more production ready.https://github.com/power-fungus/mutagen-preview
I spent the last weeks reading into the current project and re-writing parts of mutagen using the same interface, but with a different architecture. It's not completed yet but should give a rough outline of what the finished project will look like: the backbone and glue code already exists and will probably not change too widely.
@llogiq I would like to know if you are interested in my approach and if you would consider merging my proposal in your project. If so, I will finish this preview into production quality in the next months. Also I am open to any discussion about interface and design decisions.
I would like to have this rewrite published (once finished) under the "brand" of
mutagen
:#[mutate]
MUTATION_ID
(renamed for clarity)mutagen
proc-macro-attribute
branchsyn
andquote
For details about the architecture, see: https://github.com/power-fungus/mutagen-preview/tree/master/docs
Main Benefits are:
MUTATION_ID
variable.#[mutate]
attribute@llogiq I would like to read from you soon! :)
The text was updated successfully, but these errors were encountered: