1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
[%%prepare_logger]
module Xprint = Diffast_misc.Xprint
module PB = Langs_common.Parserlib_base
type java_language_specification =
| JLSnone
| JLS of int
let default_java_lang_spec_level = 17
let default_java_lang_spec = JLS default_java_lang_spec_level
exception Internal_error of string
exception Parse_error = PB.Parse_error
exception Pkg_found of string
let warning_loc loc = PB.parse_warning_loc ~head:"[Java]" loc
let fail_to_parse = PB.fail_to_parse
let warning_msg = Xprint.warning ~head:"[Java]"
let find_package_name file =
let pat = Str.regexp "^[ \t]*package[ \t]+\\(.+\\)[ \t]*;.*$" in
try
let ich = file#get_channel in
try
while true do
let line = ich#input_line() in
if Str.string_match pat line 0 then
raise (Pkg_found (Str.matched_group 1 line))
done;
raise Not_found
with
| Pkg_found p -> ich#close(); p
| _ -> ich#close(); raise Not_found
with
_ -> raise Not_found
let pkg_to_path, path_to_pkg =
let dot_pat = Str.regexp_string "." in
let sep_pat = Str.regexp Filename.dir_sep in
let pkg_to_path pkg =
Str.global_replace dot_pat Filename.dir_sep pkg
in
let path_to_pkg path =
Str.global_replace sep_pat "." path
in
pkg_to_path, path_to_pkg
type src_dir = SD_unnamed of string | SD_named of string
[%%capture_path
let guess_src_dir file =
try
let pkg = find_package_name file in
let pkg_p = pkg_to_path pkg in
[%debug_log "package path: \"%s\"" pkg_p];
let pkg_pat = Str.regexp (Filename.dir_sep^pkg_p^".*$") in
let apath = file#path in
if String.starts_with ~prefix:pkg_p apath then
SD_named ""
else
try
let _ = Str.search_forward pkg_pat apath 0 in
SD_named (Str.global_replace pkg_pat "" apath)
with
| Not_found ->
failwith (Printf.sprintf "cannot guess source directory for \"%s\"" apath)
with
| Not_found -> SD_unnamed file#dirname
]
let decompose_qname qname =
let len = String.length qname in
try
let i =
try
String.rindex qname '.'
with
Not_found -> String.rindex qname '$'
in
let prefix = String.sub qname 0 i in
let base = String.sub qname (i + 1) (len - i - 1) in
prefix, base
with
Not_found -> raise (Invalid_argument "Common.decompose_qname")
let is_qualified_qname qname =
try
let _ = String.rindex qname '.' in
true
with
Not_found ->
try
let _ = String.rindex qname '$' in
true
with
Not_found -> false
let dot_pat = Str.regexp_string "."
let replace_dot_with_dollar s =
Str.global_replace dot_pat "$" s
let dollar_pat = Str.regexp_string "$"
let replace_dollar_with_dot s =
Str.global_replace dollar_pat "." s
let token_queue_to_string token_to_string tq =
let is_alpha_numeric c =
match c with
| '0'..'9' | 'a'..'z' | 'A'..'Z' -> true
| _ -> false
in
let buf = Buffer.create 0 in
tq#iter
(fun t ->
let s = token_to_string t in
begin
match s with
| "." | ")" | "," | ";" | "}" | "]" -> ()
| _ -> begin
let buf_len = Buffer.length buf in
if buf_len > 0 then
match Buffer.nth buf (buf_len - 1) with
| '.' | '(' | '@' | '[' -> ()
| c when is_alpha_numeric c && s = "(" -> ()
| _ -> Buffer.add_string buf " "
end
end;
Buffer.add_string buf s
);
Buffer.contents buf