-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
85 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,92 @@ | ||
//! Take all the comments found in the original body and assign them to statements. | ||
use std::mem; | ||
|
||
use crate::llbc_ast::*; | ||
use crate::ast::*; | ||
use crate::transform::TransformCtx; | ||
|
||
use super::ctx::LlbcPass; | ||
use super::ctx::TransformPass; | ||
|
||
trait IsStatement { | ||
fn get_span(&self) -> Span; | ||
fn get_comments_before(&mut self) -> &mut Vec<String>; | ||
} | ||
|
||
impl IsStatement for llbc_ast::Statement { | ||
fn get_span(&self) -> Span { | ||
self.span | ||
} | ||
fn get_comments_before(&mut self) -> &mut Vec<String> { | ||
&mut self.comments_before | ||
} | ||
} | ||
impl IsStatement for ullbc_ast::Statement { | ||
fn get_span(&self) -> Span { | ||
self.span | ||
} | ||
fn get_comments_before(&mut self) -> &mut Vec<String> { | ||
&mut self.comments_before | ||
} | ||
} | ||
impl IsStatement for ullbc_ast::Terminator { | ||
fn get_span(&self) -> Span { | ||
self.span | ||
} | ||
fn get_comments_before(&mut self) -> &mut Vec<String> { | ||
&mut self.comments_before | ||
} | ||
} | ||
|
||
struct CommentsCtx { | ||
comments: Vec<(usize, Vec<String>)>, | ||
} | ||
impl CommentsCtx { | ||
fn visit<St: IsStatement>(&mut self, st: &mut St) { | ||
let st_line = st.get_span().span.beg.line; | ||
self.comments = mem::take(&mut self.comments) | ||
.into_iter() | ||
.filter_map(|(line, comments)| { | ||
if line <= st_line { | ||
st.get_comments_before().extend(comments); | ||
None | ||
} else { | ||
Some((line, comments)) | ||
} | ||
}) | ||
.collect(); | ||
} | ||
} | ||
|
||
pub struct Transform; | ||
impl LlbcPass for Transform { | ||
fn transform_body(&self, _ctx: &mut TransformCtx, b: &mut ExprBody) { | ||
// Constraints in the ideal case: | ||
// - each comment should be assigned to exactly one statement; | ||
// - the order of comments in the source should refine the partial order of control flow; | ||
// - a comment should come before the statement it was applied to. | ||
impl TransformPass for Transform { | ||
fn transform_ctx(&self, ctx: &mut TransformCtx) { | ||
ctx.for_each_fun_decl(|_ctx, fun| { | ||
if let Ok(body) = &mut fun.body { | ||
// Constraints in the ideal case: | ||
// - each comment should be assigned to exactly one statement; | ||
// - the order of comments in the source should refine the partial order of control flow; | ||
// - a comment should come before the statement it was applied to. | ||
|
||
// This is a pretty simple heuristic which is good enough for now. | ||
let mut comments: Vec<(usize, Vec<String>)> = b.comments.clone(); | ||
b.body.visit_statements(|st: &mut Statement| { | ||
let st_line = st.span.span.beg.line; | ||
comments = mem::take(&mut comments) | ||
.into_iter() | ||
.filter_map(|(line, comments)| { | ||
if line <= st_line { | ||
st.comments_before.extend(comments); | ||
None | ||
} else { | ||
Some((line, comments)) | ||
// This is a pretty simple heuristic which is good enough for now. | ||
let mut ctx = CommentsCtx { | ||
comments: match body { | ||
Body::Unstructured(b) => b.comments.clone(), | ||
Body::Structured(b) => b.comments.clone(), | ||
}, | ||
}; | ||
match body { | ||
Body::Unstructured(b) => { | ||
for block in &mut b.body { | ||
for st in &mut block.statements { | ||
ctx.visit(st); | ||
} | ||
ctx.visit(&mut block.terminator); | ||
} | ||
} | ||
}) | ||
.collect(); | ||
Body::Structured(b) => b.body.visit_statements(|st| { | ||
ctx.visit(st); | ||
}), | ||
} | ||
} | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters