File: java_analysis.ml

package info (click to toggle)
why 2.30%2Bdfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 26,916 kB
  • sloc: ml: 116,979; java: 9,376; ansic: 5,175; makefile: 1,335; sh: 531; lisp: 127
file content (310 lines) | stat: -rw-r--r-- 10,147 bytes parent folder | download
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
(**************************************************************************)
(*                                                                        *)
(*  The Why platform for program certification                            *)
(*                                                                        *)
(*  Copyright (C) 2002-2011                                               *)
(*                                                                        *)
(*    Jean-Christophe FILLIATRE, CNRS & Univ. Paris-sud 11                *)
(*    Claude MARCHE, INRIA & Univ. Paris-sud 11                           *)
(*    Yannick MOY, Univ. Paris-sud 11                                     *)
(*    Romain BARDOU, Univ. Paris-sud 11                                   *)
(*                                                                        *)
(*  Secondary contributors:                                               *)
(*                                                                        *)
(*    Thierry HUBERT, Univ. Paris-sud 11  (former Caduceus front-end)     *)
(*    Nicolas ROUSSET, Univ. Paris-sud 11 (on Jessie & Krakatoa)          *)
(*    Ali AYAD, CNRS & CEA Saclay         (floating-point support)        *)
(*    Sylvie BOLDO, INRIA                 (floating-point support)        *)
(*    Jean-Francois COUCHOT, INRIA        (sort encodings, hyps pruning)  *)
(*    Mehdi DOGGUY, Univ. Paris-sud 11    (Why GUI)                       *)
(*                                                                        *)
(*  This software is free software; you can redistribute it and/or        *)
(*  modify it under the terms of the GNU Lesser General Public            *)
(*  License version 2.1, with the special exception on linking            *)
(*  described in file LICENSE.                                            *)
(*                                                                        *)
(*  This software is distributed in the hope that it will be useful,      *)
(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)
(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)
(*                                                                        *)
(**************************************************************************)

(*

  Performs several analyses after Java typing and before interpretation into Jessie code.

  1) determines which structure type to introduce for arrays
  2) disambiguates names:
     . different constructors for the same class are named
         Class_typearg1_..._typeargn
     . methods
         * with same names in different classes or interfaces
             Class_or_Interface_method_name
         * with same names in same class or interface
             Class_or_Interface_method_name_typearg1_..._typeargn

*)

open Java_pervasives
open Java_env
open Java_tast
open Format

let array_struct_table = Hashtbl.create 17

let name_base_type t =
  match t with
    | Tboolean -> "boolean"
    | Tchar -> "char"
    | Tbyte -> "byte"
    | Tinteger -> "integer" 
    | Tshort -> "short"
    | Tlong -> "long"
    | Tint -> "int" 
    | Tunit -> "unit"
    | Tfloat -> "float"
    | Treal -> "real"
    | Tdouble -> "double"
    | Tstring -> "string"

let rec name_type t =
  match t with
    | JTYbase t -> name_base_type t
    | JTYclass(_,c) -> c.class_info_name
    | JTYinterface i -> i.interface_info_name
    | JTYarray (_, ty) -> name_type ty ^ "A"
    | JTYnull -> assert false
    | JTYlogic _ -> assert false

let rec intro_array_struct t =
  let n = name_type t in 
  try
    let _ = Hashtbl.find array_struct_table n in ()
  with Not_found ->
    Java_options.lprintf "Adding array struct for type %a under name %s@." 
      Java_typing.print_type t n;
      (* array structs indexed by name rather than by type,
	 to void generation of two structs for nullable and non_null types
	 of the same name.
	 - Nicolas R. *)
      Hashtbl.add array_struct_table n (t, n ^ "M", n ^ "P")

let term _t = () (* TODO *)

let assertion _a = () (* TODO *)

let rec expr e = 
  match e.java_expr_node with
    | JElit _l -> ()
    | JEincr_local_var(_op,_v) -> ()
    | JEincr_field(_op,e1,_fi) -> expr e1
    | JEun (_, e1) -> expr e1
    | JEbin (e1, _, e2) | JEincr_array (_, e1, e2) -> expr e1; expr e2 
    | JEvar _vi -> ()
    | JEstatic_field_access(_ci,_fi) -> ()
    | JEfield_access(e1,_fi) -> expr e1
    | JEarray_length e -> 
	begin
	  match e.java_expr_type with
	    | JTYarray (_, ty) -> intro_array_struct ty 
	    | _ -> assert false
	end
    | JEarray_access(e1,e2) -> 
	expr e1; expr e2;
	begin
	  match e1.java_expr_type with
	    | JTYarray (_, ty) -> intro_array_struct ty
	    | _ -> assert false
	end
    | JEassign_local_var (_, e)
    | JEassign_local_var_op (_, _, e)
    | JEassign_static_field (_, e) 
    | JEassign_static_field_op (_, _, e) -> expr e
    | JEassign_field(e1,_fi,e2) -> expr e1; expr e2
    | JEassign_field_op(e1,_fi,_op,e2) -> expr e1; expr e2
    | JEif(e1,e2,e3) -> expr e1; expr e2; expr e3
    | JEassign_array(e1,e2,e3) 
    | JEassign_array_op(e1,e2,_,e3) -> 
	expr e1; expr e2; expr e3;
	begin
	  match e1.java_expr_type with
	    | JTYarray (_, ty) -> intro_array_struct ty
	    | _ -> 
		eprintf "unexpected type: e1:%a e2:%a e3:%a@." 
		  Java_typing.print_type e1.java_expr_type
		  Java_typing.print_type e2.java_expr_type
		  Java_typing.print_type e3.java_expr_type;
		assert false
	end
    | JEcall(e,_mi,args) ->
	expr e;	List.iter expr args
    | JEconstr_call (e, _, args) ->
	expr e; List.iter expr args
    | JEstatic_call(_mi,args) ->
	List.iter expr args
    | JEnew_array(_ty,dims) ->
	List.iter expr dims
	(* intro_array_struct ty ??? *)
    | JEnew_object(_ci,args) ->
	List.iter expr args
    | JEinstanceof(e,_)
    | JEcast(_,e) -> expr e

let do_initializer i = 
  match i with
    | JIexpr e -> expr e
    | _ -> assert false (* TODO *)

let switch_label = function
  | Java_ast.Default -> ()
  | Java_ast.Case e -> expr e
  
let behavior (_id,assumes,_throws,assigns,ensures) =
  Option_misc.iter assertion assumes;
  Option_misc.iter (fun (_,l) -> List.iter term l) assigns;
  assertion ensures

let loop_annot annot =
  assertion annot.loop_inv;
  List.iter (fun (_,a) -> assertion a) annot.behs_loop_inv;
  Option_misc.iter term annot.loop_var

let rec statement s =
  match s.java_statement_node with
    | JSskip 
    | JSreturn_void
    | JSbreak _ | JScontinue _ -> ()
    | JSlabel(_lab,s) -> statement s
    | JSblock l -> List.iter statement l	  
    | JSvar_decl (_vi, init, s) ->
	Option_misc.iter do_initializer init;
	statement s
    | JSif (e, s1, s2) -> expr e; statement s1; statement s2
    | JSdo (s, annot, e) ->
	statement s; loop_annot annot; expr e
    | JSwhile(e,annot,s) ->
	  expr e; loop_annot annot; statement s
    | JSfor (el1, e, annot, el2, body) ->
	List.iter expr el1;
	expr e;
	loop_annot annot;
	List.iter expr el2;
	statement body
    | JSfor_decl(decls,e,annot,sl,body) ->
	List.iter 
	  (fun (_,init) -> Option_misc.iter do_initializer init) decls;
	expr e;
	loop_annot annot;
	List.iter expr sl;
	statement body
    | JSthrow e
    | JSreturn e 
    | JSexpr e -> expr e
    | JSassert(_,_,e) -> assertion e
    | JSswitch(e,l) -> 
	expr e;
	List.iter (fun (labels,b) ->
		     List.iter switch_label labels;
		     List.iter statement b)
	  l
    | JStry(s, catches, finally) ->
	List.iter statement s;
	List.iter (fun (_,s) -> List.iter statement s) catches;
	Option_misc.iter (List.iter statement) finally
    | JSstatement_spec(req,dec,behs,s) ->
	Option_misc.iter assertion req;
	Option_misc.iter term dec;
	List.iter behavior behs;
	statement s

let param vi =
  match vi.java_var_info_type with
    | JTYarray (_, ty) -> intro_array_struct ty
    | _ -> ()

let string_of_parameters vil =
  (List.fold_right
     (fun (vi, _) acc -> "_" ^ name_type vi.java_var_info_type ^ acc) vil "")

let disambiguates_method_names () =
  let methods_list =
    Hashtbl.fold (fun _ mt acc -> mt :: acc) Java_typing.methods_table []
  in
  let methods_list =
    List.sort 
      (fun mt1 mt2 -> 
	 let mi1 = mt1.Java_typing.mt_method_info in
	 let mi2 = mt2.Java_typing.mt_method_info in
	   String.compare mi1.method_info_trans_name mi2.method_info_trans_name)
      methods_list 
  in
  let rec disambiguates methods_list =
    match methods_list with
      | [] | [_] -> ()
      | mt1::(mt2::_ as tl) ->
	  let mi1 = mt1.Java_typing.mt_method_info in
	  let mi2 = mt2.Java_typing.mt_method_info in
	    if mi1.method_info_trans_name = mi2.method_info_trans_name then
	      begin
		mi1.method_info_trans_name <-
		  mi1.method_info_trans_name ^
		  string_of_parameters mi1.method_info_parameters;
		mi2.method_info_trans_name <-
		  mi2.method_info_trans_name ^
		  string_of_parameters mi2.method_info_parameters;
	      end;
	    disambiguates tl
  in
    disambiguates methods_list;
    List.iter
      (fun mt -> Hashtbl.replace Java_typing.methods_table
	 mt.Java_typing.mt_method_info.method_info_tag mt)
      methods_list

let do_method mi _req _behs body =
(*
  Option_misc.iter assertion req;
  ... behs
*)
  mi.method_info_trans_name <-
    (get_method_info_class_or_interface_name mi) ^ "_" ^
    mi.method_info_name;
  disambiguates_method_names ();
  List.iter param (List.map fst mi.method_info_parameters);
  Option_misc.iter (List.iter statement) body;
  Option_misc.iter param mi.method_info_result


let do_constructor ci _req _behs body =
(*
  let l = ci.constr_info_class.class_info_constructors in
  if List.length l >= 2 then
    begin
*)
      ci.constr_info_trans_name <-
	"cons_" ^ ci.constr_info_class.class_info_name ^
	string_of_parameters ci.constr_info_parameters;
(*
    end;
*)
  List.iter statement body

let do_field fi =
  match fi.java_field_info_type with
    | JTYarray (_, ty) -> intro_array_struct ty
    | _ -> ()

let do_type ty =
  match ty with
    | TypeClass ci -> 
	List.iter do_field ci.class_info_fields
    | TypeInterface ii -> 
	List.iter do_field ii.interface_info_fields


(*
Local Variables: 
compile-command: "make -j -C .. bin/krakatoa.byte"
End: 
*)