@ -52,16 +52,20 @@ let read_package_declaration source_file =
Utils . with_file_in path ~ f : loop | > Option . value ~ default : " "
Utils . with_file_in path ~ f : loop | > Option . value ~ default : " "
let add_source_file path map =
let add_source_file =
let cwd = lazy ( Sys . getcwd () ) in
let convert_to_absolute p =
let convert_to_absolute p =
if Filename . is_relative p then Filename . concat ( Sys. getcwd () ) p else p
if Filename . is_relative p then Filename . concat ( Lazy. force cwd ) p else p
in
in
fun path map ->
let basename = Filename . basename path in
let basename = Filename . basename path in
let entry =
let entry =
let current_source_file = SourceFile . from_abs_path ( convert_to_absolute path ) in
let current_source_file = SourceFile . from_abs_path ( convert_to_absolute path ) in
try
match String . Map . find map basename with
match String . Map . find_exn map basename with
| None ->
| Singleton previous_source_file ->
(* Most common case: there is no conflict with the base name of the source file *)
Singleton current_source_file
| Some ( Singleton previous_source_file ) ->
(* Another source file with the same base name has been found.
(* Another source file with the same base name has been found.
Reading the package from the source file to resolve the ambiguity
Reading the package from the source file to resolve the ambiguity
only happens in this case * )
only happens in this case * )
@ -71,24 +75,19 @@ let add_source_file path map =
[ ( current_package , current_source_file ) ; ( previous_package , previous_source_file ) ]
[ ( current_package , current_source_file ) ; ( previous_package , previous_source_file ) ]
in
in
Duplicate source_list
Duplicate source_list
| Duplicate previous_source_files ->
| Some ( Duplicate previous_source_files ) ->
(* Two or more source file with the same base name have been found *)
(* Two or more source file with the same base name have been found *)
let current_package = read_package_declaration current_source_file in
let current_package = read_package_declaration current_source_file in
Duplicate ( ( current_package , current_source_file ) :: previous_source_files )
Duplicate ( ( current_package , current_source_file ) :: previous_source_files )
with Not_found_s _ | Caml . Not_found ->
(* Most common case: there is no conflict with the base name of the source file *)
Singleton current_source_file
in
in
String . Map . set ~ key : basename ~ data : entry map
String . Map . set ~ key : basename ~ data : entry map
let add_root_path path roots = String . Set . add roots path
let add_root_path path roots = String . Set . add roots path
let load_from_verbose_output javac_verbose_out =
let load_from_verbose_output =
let file_in = In_channel . create javac_verbose_out in
let class_filename_re =
let class_filename_re =
Str . regexp
Printf . sprintf
( Printf . sprintf
(* the unreadable regexp below captures 3 possible forms:
(* the unreadable regexp below captures 3 possible forms:
1 . [ wrote DirectoryFileObject [ / path / to / classes_out : path / to / File . java ] ] , leaves ` path / to / File . java ` in match group 2
1 . [ wrote DirectoryFileObject [ / path / to / classes_out : path / to / File . java ] ] , leaves ` path / to / File . java ` in match group 2
2 . [ wrote RegularFileObject [ path / to / File . java ] ] , leaves ` path / to / File . java ` in match group 5
2 . [ wrote RegularFileObject [ path / to / File . java ] ] , leaves ` path / to / File . java ` in match group 5
@ -96,20 +95,19 @@ let load_from_verbose_output javac_verbose_out =
4 . [ wrote path / to / File . java ] leaves ` path / to / File . java ` in match group 6 ( from java 11 ) * )
4 . [ wrote path / to / File . java ] leaves ` path / to / File . java ` in match group 6 ( from java 11 ) * )
" \\ [wrote \
" \\ [wrote \
\ \ ( DirectoryFileObject \ \ [ % s : \ \ ( . * \ \ ) \ \ | \ \ ( \ \ ( Regular \ \ | Simple \ \ ) FileObject \ \ [ \ \ ( . * \ \ ) \ \ ) \ \ ] \ \ | \ \ ( . * \ \ ) \ \ ) \ \ ] "
\ \ ( DirectoryFileObject \ \ [ % s : \ \ ( . * \ \ ) \ \ | \ \ ( \ \ ( Regular \ \ | Simple \ \ ) FileObject \ \ [ \ \ ( . * \ \ ) \ \ ) \ \ ] \ \ | \ \ ( . * \ \ ) \ \ ) \ \ ] "
Config . javac_classes_out )
Config . javac_classes_out
| > Str . regexp
in
in
let source_filename_re =
let source_filename_re =
Str . regexp " \\ [parsing started \\ (Regular \\ |Simple \\ )FileObject \\ [ \\ (.* \\ ) \\ ] \\ ] "
Str . regexp " \\ [parsing started \\ (Regular \\ |Simple \\ )FileObject \\ [ \\ (.* \\ ) \\ ] \\ ] "
in
in
let classpath_re = Str . regexp " \\ [search path for class files: \\ (.* \\ ) \\ ] " in
let classpath_re = Str . regexp " \\ [search path for class files: \\ (.* \\ ) \\ ] " in
let rec loop paths roots sources classes =
let rec loop paths roots sources classes file_in =
match In_channel . input_line_exn file_in with
match In_channel . input_line file_in with
| exception End_of_file ->
| None ->
In_channel . close file_in ;
let classpath = classpath_of_paths ( String . Set . elements roots @ paths ) in
let classpath = classpath_of_paths ( String . Set . elements roots @ paths ) in
{ classpath ; sources ; classes }
{ classpath ; sources ; classes }
| line ->
| Some line when Str . string_match class_filename_re line 0 -> (
if Str . string_match class_filename_re line 0 then
let path =
let path =
try Str . matched_group 5 line
try Str . matched_group 5 line
with Caml . Not_found -> (
with Caml . Not_found -> (
@ -120,24 +118,27 @@ let load_from_verbose_output javac_verbose_out =
in
in
match Javalib . extract_class_name_from_file path with
match Javalib . extract_class_name_from_file path with
| exception ( JBasics . Class_structure_error _ | Invalid_argument _ ) ->
| exception ( JBasics . Class_structure_error _ | Invalid_argument _ ) ->
( loop [ @ tailcall ] ) paths roots sources classes
loop paths roots sources classes file_in
| cn , root_info ->
| cn , root_info ->
let root_dir =
let root_dir =
if String . equal root_info " " then Filename . current_dir_name else root_info
if String . equal root_info " " then Filename . current_dir_name else root_info
in
in
( loop [ @ tailcall ] ) paths ( add_root_path root_dir roots ) sources
loop paths ( add_root_path root_dir roots ) sources ( JBasics . ClassSet . add cn classes )
( JBasics . ClassSet . add cn classes )
file_in )
else if Str . string_match source_filename_re line 0 then
| Some line when Str . string_match source_filename_re line 0 ->
let path = Str . matched_group 2 line in
let path = Str . matched_group 2 line in
( loop [ @ tailcall ] ) paths roots ( add_source_file path sources ) classes
loop paths roots ( add_source_file path sources ) classes file_in
else if Str . string_match classpath_re line 0 then
| Some line when Str . string_match classpath_re line 0 ->
let classpath = Str . matched_group 1 line in
let classpath = Str . matched_group 1 line in
let parsed_paths = String . split ~ on : ',' classpath in
let parsed_paths = String . split ~ on : ',' classpath in
( loop [ @ tailcall ] ) parsed_paths roots sources classes
loop parsed_paths roots sources classes file_in
else (* skip this line *)
| _ ->
( loop [ @ tailcall ] ) paths roots sources classes
(* skip this line *)
loop paths roots sources classes file_in
in
in
loop [] String . Set . empty String . Map . empty JBasics . ClassSet . empty
fun javac_verbose_out ->
Utils . with_file_in javac_verbose_out
~ f : ( loop [] String . Set . empty String . Map . empty JBasics . ClassSet . empty )
let collect_classnames init jar_filename =
let collect_classnames init jar_filename =
@ -187,6 +188,7 @@ let load_from_arguments classes_out_path =
let roots , classes = search_classes classes_out_path in
let roots , classes = search_classes classes_out_path in
let split cp_option = Option . value_map ~ f : split_classpath ~ default : [] cp_option in
let split cp_option = Option . value_map ~ f : split_classpath ~ default : [] cp_option in
let classpath =
let classpath =
(* order follows https://docs.oracle.com/javase/7/docs/technotes/tools/windows/classpath.html *)
split Config . bootclasspath @ split Config . classpath @ String . Set . elements roots
split Config . bootclasspath @ split Config . classpath @ String . Set . elements roots
| > classpath_of_paths
| > classpath_of_paths
in
in