3 * Copyright (C) 2010, University of Copenhagen DIKU and INRIA.
4 * Copyright (C) 2009, University of Urbana Champaign.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License (GPL)
8 * version 2 as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * file license.txt for more details.
21 (*****************************************************************************)
23 (*****************************************************************************)
25 (* A trimmed down version of my comment_annotater of CComment. In CComment
26 * I was also trying to associate the comment to the relevant entity, not
27 * just the closest token (e.g. a function comment is not placed next to the
28 * identifier of the function but before its return type or storage).
32 (*****************************************************************************)
34 (*****************************************************************************)
36 let is_comment_or_space_or_stuff tok
=
37 Token_helpers.is_not_in_ast tok
&& Token_helpers.is_origin tok
39 (* coupling with token_helpers.is_not_in_ast, and of course with tokens_c.ml *)
40 let convert_relevant_tokens x
=
41 assert (Token_helpers.is_origin x
);
44 | Parser_c.TCommentSpace info
->
45 Token_c.TCommentSpace
, (Ast_c.parse_info_of_info info
)
46 | Parser_c.TCommentNewline info
->
47 Token_c.TCommentNewline
, (Ast_c.parse_info_of_info info
)
49 | Parser_c.TComment info
->
50 Token_c.TComment
, (Ast_c.parse_info_of_info info
)
52 (* the passed tokens because of our limited handling of cpp *)
53 | Parser_c.TCommentCpp
(cppcommentkind
, info
) ->
54 Token_c.TCommentCpp cppcommentkind
, (Ast_c.parse_info_of_info info
)
56 | _
-> raise
(Impossible
61)
59 (*****************************************************************************)
61 (*****************************************************************************)
63 (* right now we just add comment-like and origin-tok tokens,
64 * as explained in token_c.ml.
66 * This simplified comment_annotater (compared to CComment) is really
67 * simple as the tokens and the Ast_c.info in the asts actually share
69 * So, modifying fields in the tokens will also modify the info in
70 * the ast. Sometimes side effects simplify programming ...
71 * We use similar tricks in unparse_c.ml. So really the asts argument
74 * ex: C1 C2 T1 T2 C3 C4 T3 C5 T4.
75 * => infoT1(-C1C2,+), infoT2(-,+C3C4), infoT3(-C3C4,+C5), infoT4(-C5,+)
79 let (agglomerate_either:
80 ('a, 'a) Common.either list -> ('a list, 'a list) Common.either list) = fun xs ->
84 ('a -> ('a, 'a) Common.either) -> 'a list ->
85 ('a list, 'a list) Common.either list) = fun f_either xs ->
86 let xs' = List.map f_either xs in
87 agglomerate_either xs'
91 (* the asts is not really used, we do all via side effect on the tokens,
92 * which share the info reference with the elements in the ast.
94 let annotate_program toks asts
=
95 (* Common.exclude_but_keep_attached gather all comments before a
96 * token and then associates to this token those comments. Note that
97 * if reverse the list of tokens then this function can also be used
98 * to gather all the comments after a token :)
102 let toks_with_before =
103 Common.exclude_but_keep_attached
is_comment_or_space_or_stuff
107 (* after phase. trick: reverse the tokens and reuse previous func *)
108 let toks_with_after =
111 (function (x
,l
) -> (x
,List.rev l
))
112 (Common.exclude_but_keep_attached
is_comment_or_space_or_stuff
117 assert(List.length
toks_with_after =|= List.length
toks_with_before);
119 Common.zip
toks_with_before toks_with_after
120 +> List.iter
(fun ((t1
, before
), (t2
, after
)) ->
124 let before'
= before +> List.map
convert_relevant_tokens in
125 let after'
= after +> List.map
convert_relevant_tokens in
127 let info = Token_helpers.info_of_tok t1
in
128 info.Ast_c.comments_tag
:=
129 { Ast_c.mbefore
= before'
;
130 Ast_c.mafter
= after'
;
136 (* modified via side effect. I return it just to have a