module Ast = Ast_cocci
module Ast0 = Ast0_cocci
module V0 = Visitor_ast0
+module VT0 = Visitor_ast0_types
module U = Unparse_ast0
(* --------------------------------------------------------------------- *)
let bind x y = () in
let option_default = () in
let donothing r k e = k e in
- let mcode (_,_,info,mcodekind,_) =
+ let mcode (_,_,info,mcodekind,_,_) =
match mcodekind with
Ast0.PLUS -> insert info.Ast0.pos_info.Ast0.line_start
| _ -> () in
let fn =
- V0.combiner bind option_default
+ V0.flat_combiner bind option_default
mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
donothing donothing donothing donothing donothing donothing
donothing donothing donothing donothing donothing donothing donothing
donothing donothing in
- fn.V0.combiner_top_level top
+ fn.VT0.combiner_rec_top_level top
(* --------------------------------------------------------------------- *)
let option_default = (*Bind(Neutral,[],[],[],[],[])*)
Recursor(Neutral,[],[],[])
-let mcode (_,_,info,mcodekind,pos) =
+let mcode (_,_,info,mcodekind,pos,_) =
let offset = info.Ast0.pos_info.Ast0.offset in
match mcodekind with
Ast0.MINUS(_) -> Token(AllMarked,offset,mcodekind,[])
| Ast0.CONTEXT(_) -> Token(NotAllMarked,offset,mcodekind,[offset])
| _ -> failwith "not possible"
-let neutral_mcode (_,_,info,mcodekind,pos) =
+let neutral_mcode (_,_,info,mcodekind,pos,_) =
let offset = info.Ast0.pos_info.Ast0.offset in
match mcodekind with
Ast0.MINUS(_) -> Token(Neutral,offset,mcodekind,[])
(* neutral for context; used for mcode in bef aft nodes that don't represent
anything if they don't contain some information *)
-let nc_mcode (_,_,info,mcodekind,pos) =
- let offset = info.Ast0.pos_info.Ast0.offset in
+let nc_mcode (_,_,info,mcodekind,pos,_) =
+ (* distinguish from the offset of some real token *)
+ let offset = (-1) * info.Ast0.pos_info.Ast0.offset in
match mcodekind with
Ast0.MINUS(_) -> Token(AllMarked,offset,mcodekind,[])
| Ast0.PLUS -> Token(AllMarked,offset,mcodekind,[])
- | Ast0.CONTEXT(_) -> Token(Neutral,offset,mcodekind,[offset])
+ | Ast0.CONTEXT(_) ->
+ (* Unlike the other mcode cases, we drop the offset from the context
+ offsets. This is because we don't know whether the term this is
+ associated with is - or context. In any case, the context offsets are
+ used for identification, and this invisible node should not be needed
+ for this purpose. *)
+ Token(Neutral,offset,mcodekind,[])
| _ -> failwith "not possible"
let is_context = function Ast0.CONTEXT(_) -> true | _ -> false
| Ast0.Estars(dots,whencode) ->
k (Ast0.rewrap e (Ast0.Estars(dots,None)))
| Ast0.DisjExpr(starter,expr_list,_,ender) ->
- disj_cases e starter expr_list r.V0.combiner_expression ender
+ disj_cases e starter expr_list r.VT0.combiner_rec_expression ender
| _ -> k e) in
(* not clear why we have the next two cases, since DisjDecl and
compute_result Ast0.decl e
(match Ast0.unwrap e with
Ast0.DisjDecl(starter,decls,_,ender) ->
- disj_cases e starter decls r.V0.combiner_declaration ender
+ disj_cases e starter decls r.VT0.combiner_rec_declaration ender
| Ast0.Ddots(dots,whencode) ->
k (Ast0.rewrap e (Ast0.Ddots(dots,None)))
(* Need special cases for the following so that the type will be
reordering their components. *)
| Ast0.Init(stg,ty,id,eq,ini,sem) ->
bind (match stg with Some stg -> mcode stg | _ -> option_default)
- (bind (r.V0.combiner_typeC ty)
- (bind (r.V0.combiner_ident id)
+ (bind (r.VT0.combiner_rec_typeC ty)
+ (bind (r.VT0.combiner_rec_ident id)
(bind (mcode eq)
- (bind (r.V0.combiner_initialiser ini) (mcode sem)))))
+ (bind (r.VT0.combiner_rec_initialiser ini) (mcode sem)))))
| Ast0.UnInit(stg,ty,id,sem) ->
bind (match stg with Some stg -> mcode stg | _ -> option_default)
- (bind (r.V0.combiner_typeC ty)
- (bind (r.V0.combiner_ident id) (mcode sem)))
+ (bind (r.VT0.combiner_rec_typeC ty)
+ (bind (r.VT0.combiner_rec_ident id) (mcode sem)))
| _ -> k e) in
let param r k e =
(match Ast0.unwrap e with
Ast0.Param(ty,Some id) ->
(* needed for the same reason as in the Init and UnInit cases *)
- bind (r.V0.combiner_typeC ty) (r.V0.combiner_ident id)
+ bind (r.VT0.combiner_rec_typeC ty) (r.VT0.combiner_rec_ident id)
| _ -> k e) in
let typeC r k e =
compute_result Ast0.typeC e
(match Ast0.unwrap e with
Ast0.DisjType(starter,types,_,ender) ->
- disj_cases e starter types r.V0.combiner_typeC ender
+ disj_cases e starter types r.VT0.combiner_rec_typeC ender
| _ -> k e) in
let initialiser r k i =
k (Ast0.rewrap i (Ast0.Idots(dots,None)))
| _ -> k i) in
+ let case_line r k e =
+ compute_result Ast0.case_line e
+ (match Ast0.unwrap e with
+ Ast0.DisjCase(starter,case_list,_,ender) ->
+ disj_cases e starter case_list r.VT0.combiner_rec_case_line ender
+ | _ -> k e) in
+
let statement r k s =
compute_result Ast0.stmt s
(match Ast0.unwrap s with
| Ast0.Stars(dots,whencode) ->
k (Ast0.rewrap s (Ast0.Stars(dots,[])))
| Ast0.Disj(starter,statement_dots_list,_,ender) ->
- disj_cases s starter statement_dots_list r.V0.combiner_statement_dots
+ disj_cases s starter statement_dots_list r.VT0.combiner_rec_statement_dots
ender
(* cases for everything with extra mcode *)
| Ast0.FunDecl((info,bef),_,_,_,_,_,_,_,_)
| Ast0.Decl((info,bef),_) ->
- bind (nc_mcode ((),(),info,bef,())) (k s)
+ bind (nc_mcode ((),(),info,bef,(),-1)) (k s)
| Ast0.IfThen(_,_,_,_,_,(info,aft))
| Ast0.IfThenElse(_,_,_,_,_,_,_,(info,aft))
| Ast0.Iterator(_,_,_,_,_,(info,aft))
| Ast0.While(_,_,_,_,_,(info,aft))
| Ast0.For(_,_,_,_,_,_,_,_,_,(info,aft)) ->
- bind (k s) (nc_mcode ((),(),info,aft,()))
+ bind (k s) (nc_mcode ((),(),info,aft,(),-1))
| _ -> k s
) in
let do_top builder r k e = compute_result builder e (k e) in
let combiner =
- V0.combiner bind option_default
+ V0.flat_combiner bind option_default
mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
(do_nothing Ast0.dotsExpr) (do_nothing Ast0.dotsInit)
(do_nothing Ast0.dotsParam) (do_nothing Ast0.dotsStmt)
(do_nothing Ast0.dotsDecl) (do_nothing Ast0.dotsCase)
(do_nothing Ast0.ident) expression typeC initialiser param declaration
- statement (do_nothing Ast0.case_line) (do_top Ast0.top) in
- combiner.V0.combiner_top_level code
+ statement case_line (do_top Ast0.top) in
+ combiner.VT0.combiner_rec_top_level code
(* --------------------------------------------------------------------- *)
(* Traverse the hash tables and find corresponding context nodes that have
(* this is just a sanity check - really only need to look at the top-level
structure *)
-let equal_mcode (_,_,info1,_,_) (_,_,info2,_,_) =
+let equal_mcode (_,_,info1,_,_,_) (_,_,info2,_,_,_) =
info1.Ast0.pos_info.Ast0.offset = info2.Ast0.pos_info.Ast0.offset
let equal_option e1 e2 =
equal_mcode rp1 rp2
| (Ast0.Iterator(nm1,lp1,_,rp1,_,_),Ast0.Iterator(nm2,lp2,_,rp2,_,_)) ->
equal_mcode lp1 lp2 && equal_mcode rp1 rp2
- | (Ast0.Switch(switch1,lp1,_,rp1,lb1,case1,rb1),
- Ast0.Switch(switch2,lp2,_,rp2,lb2,case2,rb2)) ->
+ | (Ast0.Switch(switch1,lp1,_,rp1,lb1,_,_,rb1),
+ Ast0.Switch(switch2,lp2,_,rp2,lb2,_,_,rb2)) ->
equal_mcode switch1 switch2 && equal_mcode lp1 lp2 &&
equal_mcode rp1 rp2 && equal_mcode lb1 lb2 &&
equal_mcode rb1 rb2
equal_mcode def1 def2 && equal_mcode colon1 colon2
| (Ast0.Case(case1,_,colon1,_),Ast0.Case(case2,_,colon2,_)) ->
equal_mcode case1 case2 && equal_mcode colon1 colon2
+ | (Ast0.DisjCase(starter1,_,mids1,ender1),
+ Ast0.DisjCase(starter2,_,mids2,ender2)) ->
+ equal_mcode starter1 starter2 &&
+ List.for_all2 equal_mcode mids1 mids2 &&
+ equal_mcode ender1 ender2
| (Ast0.OptCase(_),Ast0.OptCase(_)) -> true
| _ -> false
let mcode x = () in
let do_nothing r k e = Ast0.set_mcodekind e (default_context()); k e in
- V0.combiner bind option_default
+ V0.flat_combiner bind option_default
mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
do_nothing do_nothing do_nothing do_nothing do_nothing do_nothing
do_nothing do_nothing do_nothing do_nothing do_nothing do_nothing
let contextify_whencode =
let bind x y = () in
let option_default = () in
- let mcode x = () in
- let do_nothing r k e = k e in
let expression r k e =
k e;
| Ast0.Edots(_,Some whencode)
| Ast0.Ecircles(_,Some whencode)
| Ast0.Estars(_,Some whencode) ->
- contextify_all.V0.combiner_expression whencode
+ contextify_all.VT0.combiner_rec_expression whencode
| _ -> () in
let initialiser r k i =
match Ast0.unwrap i with
Ast0.Idots(dots,Some whencode) ->
- contextify_all.V0.combiner_initialiser whencode
+ contextify_all.VT0.combiner_rec_initialiser whencode
| _ -> k i in
let whencode = function
- Ast0.WhenNot sd -> contextify_all.V0.combiner_statement_dots sd
- | Ast0.WhenAlways s -> contextify_all.V0.combiner_statement s
+ Ast0.WhenNot sd -> contextify_all.VT0.combiner_rec_statement_dots sd
+ | Ast0.WhenAlways s -> contextify_all.VT0.combiner_rec_statement s
| Ast0.WhenModifier(_) -> ()
- | Ast0.WhenNotTrue(e) -> contextify_all.V0.combiner_expression e
- | Ast0.WhenNotFalse(e) -> contextify_all.V0.combiner_expression e in
+ | Ast0.WhenNotTrue(e) -> contextify_all.VT0.combiner_rec_expression e
+ | Ast0.WhenNotFalse(e) -> contextify_all.VT0.combiner_rec_expression e in
let statement r k (s : Ast0.statement) =
k s;
let combiner =
V0.combiner bind option_default
- mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
- do_nothing do_nothing do_nothing do_nothing do_nothing do_nothing
- do_nothing
- expression
- do_nothing initialiser do_nothing do_nothing statement do_nothing
- do_nothing in
- combiner.V0.combiner_top_level
+ {V0.combiner_functions with
+ VT0.combiner_exprfn = expression;
+ VT0.combiner_initfn = initialiser;
+ VT0.combiner_stmtfn = statement} in
+ combiner.VT0.combiner_rec_top_level
(* --------------------------------------------------------------------- *)
| _ -> failwith "no dots allowed in pure plus code")
| _ -> failwith "plus code is being discarded") in
let res =
- Compute_lines.statement_dots
+ Compute_lines.compute_statement_dots_lines false
(Ast0.rewrap (List.hd l) (Ast0.DOTS (loop l))) in
[Ast0.rewrap res (Ast0.CODE res)]