[java][2/n] refactor classpath

Summary: Make the module interface safe wrt closing the classpath channel when done, plus reducing the exposed API.

Reviewed By: skcho

Differential Revision: D22411685

fbshipit-source-id: 11316c577
master
Nikos Gorogiannis 4 years ago committed by Facebook GitHub Bot
parent d35807223b
commit 34f7741ad9

@ -28,7 +28,10 @@ let classpath_of_paths paths =
type file_entry = Singleton of SourceFile.t | Duplicate of (string * SourceFile.t) list
type t = {classpath: string; sources: file_entry String.Map.t; classes: JBasics.ClassSet.t}
type t =
{ classpath_channel: Javalib.class_path
; sources: file_entry String.Map.t
; classes: JBasics.ClassSet.t }
(* Open the source file and search for the package declaration.
Only the case where the package is declared in a single line is supported *)
@ -103,7 +106,7 @@ let load_from_verbose_output =
match In_channel.input_line file_in with
| None ->
let classpath = classpath_of_paths (String.Set.elements roots @ paths) in
{classpath; sources; classes}
{classpath_channel= Javalib.class_path classpath; sources; classes}
| Some line when Str.string_match class_filename_re line 0 -> (
let path =
try Str.matched_group 5 line
@ -189,4 +192,24 @@ let load_from_arguments classes_out_path =
split Config.bootclasspath @ split Config.classpath @ String.Set.elements roots
|> classpath_of_paths
in
{classpath; sources= search_sources (); classes}
{classpath_channel= Javalib.class_path classpath; sources= search_sources (); classes}
type source = FromVerboseOut of {verbose_out_file: string} | FromArguments of {path: string}
let with_classpath ~f source =
let classpath =
match source with
| FromVerboseOut {verbose_out_file} ->
load_from_verbose_output verbose_out_file
| FromArguments {path} ->
load_from_arguments path
in
if String.Map.is_empty classpath.sources then
L.(die InternalError) "Failed to load any Java source code" ;
L.(debug Capture Quiet)
"Translating %d source files (%d classes)@."
(String.Map.length classpath.sources)
(JBasics.ClassSet.cardinal classpath.classes) ;
f classpath ;
Javalib.close_class_path classpath.classpath_channel

@ -12,10 +12,16 @@ open Javalib_pack
(** map entry for source files with potential basename collision within the same compiler call *)
type file_entry = Singleton of SourceFile.t | Duplicate of (string * SourceFile.t) list
type t = {classpath: string; sources: file_entry String.Map.t; classes: JBasics.ClassSet.t}
type t =
{ classpath_channel: Javalib.class_path
; sources: file_entry String.Map.t
; classes: JBasics.ClassSet.t }
val load_from_verbose_output : string -> t
(** load the list of source files and the list of classes from the javac verbose file *)
type source =
| FromVerboseOut of {verbose_out_file: string}
(** load the list of source files and the list of classes from the javac verbose file *)
| FromArguments of {path: string}
(** load the list of source files and the list of classes from [Config.generated_classes] *)
val load_from_arguments : string -> t
(** load the list of source files and the list of classes from Config.generated_classes *)
val with_classpath : f:(t -> unit) -> source -> unit
(** load a class path, pass it to [f] and cleanup after [f] is done *)

@ -106,7 +106,6 @@ let do_all_files sources program =
if Config.dependency_mode then capture_libs program tenv ;
store_callee_attributes tenv program ;
save_tenv tenv ;
JProgramDesc.cleanup program ;
L.(debug Capture Quiet) "done capturing all files@."
@ -122,21 +121,11 @@ let main load_sources_and_classes =
| false, true ->
JModels.load_models ~jar_filename:Config.biabduction_models_jar ) ;
JBasics.set_permissive true ;
let JClasspath.{classpath; sources; classes} =
match load_sources_and_classes with
| `FromVerboseOut verbose_out_file ->
JClasspath.load_from_verbose_output verbose_out_file
| `FromArguments path ->
JClasspath.load_from_arguments path
in
if String.Map.is_empty sources then L.(die InternalError) "Failed to load any Java source code" ;
L.(debug Capture Quiet)
"Translating %d source files (%d classes)@." (String.Map.length sources)
(JBasics.ClassSet.cardinal classes) ;
let program = JProgramDesc.load_program ~classpath classes in
do_all_files sources program
JClasspath.with_classpath load_sources_and_classes ~f:(fun classpath ->
let program = JProgramDesc.load classpath in
do_all_files classpath.sources program )
let from_arguments path = main (`FromArguments path)
let from_arguments path = main (JClasspath.FromArguments {path})
let from_verbose_out verbose_out_file = main (`FromVerboseOut verbose_out_file)
let from_verbose_out verbose_out_file = main (JClasspath.FromVerboseOut {verbose_out_file})

@ -67,8 +67,6 @@ let iter_missing_callees program ~f =
Procname.Hash.iter select program.callees
let cleanup program = Javalib.close_class_path program.classpath_channel
let lookup_node cn program =
try Some (JBasics.ClassMap.find cn (get_classmap program))
with Caml.Not_found -> (
@ -84,10 +82,10 @@ let lookup_node cn program =
None )
let load_program ~classpath classes =
let load JClasspath.{classpath_channel; classes} =
L.(debug Capture Medium) "loading program ... %!" ;
let program =
{ classpath_channel= Javalib.class_path classpath
{ classpath_channel
; classmap= JBasics.ClassMap.empty
; java_location_map= JBasics.ClassMap.empty
; callees= Procname.Hash.create 128 }

@ -21,9 +21,7 @@ val get_java_location : t -> JBasics.class_name -> Location.t option
val mem_classmap : JBasics.class_name -> t -> bool
val cleanup : t -> unit
val load_program : classpath:string -> JBasics.ClassSet.t -> t
val load : JClasspath.t -> t
(** load a java program *)
val lookup_node : JBasics.class_name -> t -> JCode.jcode Javalib.interface_or_class option

Loading…
Cancel
Save