Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Hongbo Zhang committed Jun 17, 2016
1 parent b1c1592 commit b181f82
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 7 deletions.
2 changes: 1 addition & 1 deletion jscomp/bin/ocaml_pack.ml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(** Bundled by ocaml_pack 06/17-13:23 *)
(** Bundled by ocaml_pack 06/17-14:07 *)
module Ext_bytes : sig
#1 "ext_bytes.mli"
(* Copyright (C) 2015-2016 Bloomberg Finance L.P.
Expand Down
2 changes: 2 additions & 0 deletions jscomp/ext/hash_set.mli
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,5 @@ val mem : 'a hashset -> 'a -> bool
val iter : ('a -> unit) -> 'a hashset -> unit

val elements : 'a hashset -> 'a list

val length : 'a hashset -> int
25 changes: 20 additions & 5 deletions jscomp/js_main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ let process_implementation_file ppf name =
let opref = output_prefix name in
Js_implementation.implementation ppf name opref


let process_file ppf name =
if Filename.check_suffix name ".ml"
|| Filename.check_suffix name ".mlt" then begin
Expand All @@ -71,6 +72,22 @@ let impl filename =
let intf filename =
readenv ppf Before_compile; process_interface_file ppf filename;;

let batch_files : Ast_extract.info Hash_set.hashset = Hash_set.create 31

let collect_file name =
if Filename.check_suffix name ".ml"
|| Filename.check_suffix name ".mlt" then
Hash_set.add batch_files
{ source_file = name ;
ast = Ml (Pparse.parse_implementation ~tool_name:"bsc" ppf name) }
else if Filename.check_suffix name !Config.interface_suffix then
begin
Hash_set.add batch_files
{ source_file = name ;
ast = Mli (Pparse.parse_interface ~tool_name:"bsc" ppf name) }
end


let show_config () =
Config.print_config stdout;
exit 0;
Expand Down Expand Up @@ -310,10 +327,6 @@ let add_include_path s =
Ext_pervasives.failwithf ~loc:__LOC__ "%s is not a directory" s


let batch_files = ref []

let collect_file file =
batch_files := file :: !batch_files

let buckle_script_flags =
("-bs-npm-output-path", Arg.String Js_config.set_npm_package_path,
Expand Down Expand Up @@ -441,7 +454,9 @@ let main () =
try
readenv ppf Before_args;
Arg.parse buckle_script_flags anonymous usage;
List.iter (prerr_endline ) !batch_files;
( if Hash_set.length batch_files > 0 then
let stck = Ast_extract.prepare batch_files in
Stack.iter (prerr_endline ) stck);
exit 0
with x ->
Location.report_exception ppf x;
Expand Down
130 changes: 130 additions & 0 deletions jscomp/syntax/ast_extract.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
(* Copyright (C) 2015-2016 Bloomberg Finance L.P.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition to the permissions granted to you by the LGPL, you may combine
* or link a "work that uses the Library" with a publicly distributed version
* of this file to produce a combined library or application, then distribute
* that combined work under the terms of your choosing, with no requirement
* to comply with the obligations normally placed on you by section 4 of the
* LGPL version 3 (or the corresponding section of a later version of the LGPL
* should you choose to use a later version).
*
* This program 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. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)


module C = Stack


let read_parse_and_extract ast extract_function =
Depend.free_structure_names := Depend.StringSet.empty;
(let bound_vars = Depend.StringSet.empty in
List.iter
(fun modname ->
Depend.open_module bound_vars (Longident.Lident modname))
(!Clflags.open_modules);
extract_function bound_vars ast;
!Depend.free_structure_names)




type ast =
| Ml of Parsetree.structure
| Mli of Parsetree.signature

type info =
{ source_file : string ;
ast : ast
}

let file_dependencies (files : (info * Depend.StringSet.t) list ref)
({source_file; ast} as v) =
let extracted_deps =
read_parse_and_extract ast
( match ast with
| Ml ast -> fun set _ -> Depend.add_implementation set ast
| Mli ast -> fun set _ -> Depend.add_signature set ast ) in
files := (v, extracted_deps) :: !files


let normalize file =
let modname = String.capitalize
(Filename.chop_extension @@ Filename.basename file) in
modname

let merge (files : (info * Depend.StringSet.t) list ) :
(string, Depend.StringSet.t) Hashtbl.t
=
let tbl = Hashtbl.create 31 in

let domain =
Depend.StringSet.of_list
(List.map (fun ({ source_file },_)-> normalize source_file) files) in
List.iter
(fun ({source_file = file; _}, deps) ->
let modname = String.capitalize
(Filename.chop_extension @@ Filename.basename file) in
match Hashtbl.find tbl modname with
| new_deps ->
Hashtbl.replace tbl modname
(Depend.StringSet.inter domain
(Depend.StringSet.union deps new_deps))
| exception Not_found ->
Hashtbl.add tbl modname (Depend.StringSet.inter deps domain)
) files ;
tbl


let sort_files_by_dependencies files
=
let h = merge files in
let worklist = Stack.create () in
let ()=
Hashtbl.iter (fun key _ -> Stack.push key worklist ) h in
let result = C.create () in
let visited = Hashtbl.create 31 in

while not @@ Stack.is_empty worklist do
let current = Stack.top worklist in
if Hashtbl.mem visited current then
ignore @@ Stack.pop worklist
else
match Depend.StringSet.elements (Hashtbl.find h current) with
| depends ->
let really_depends =
List.filter
(fun x -> (Hashtbl.mem h x && (not (Hashtbl.mem visited x ))))
depends in
begin match really_depends with
|[] ->
begin
let v = Stack.pop worklist in
Hashtbl.add visited v () ;
C.push current result
end
| _ ->
List.iter (fun x -> Stack.push x worklist) really_depends
end
| exception Not_found -> assert false
done;
result
;;



let prepare ast_table =
let files = ref [] in
Hash_set.iter (file_dependencies files) ast_table;
sort_files_by_dependencies (!files)

39 changes: 39 additions & 0 deletions jscomp/syntax/ast_extract.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
(* Copyright (C) 2015-2016 Bloomberg Finance L.P.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition to the permissions granted to you by the LGPL, you may combine
* or link a "work that uses the Library" with a publicly distributed version
* of this file to produce a combined library or application, then distribute
* that combined work under the terms of your choosing, with no requirement
* to comply with the obligations normally placed on you by section 4 of the
* LGPL version 3 (or the corresponding section of a later version of the LGPL
* should you choose to use a later version).
*
* This program 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. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)


type ast =
| Ml of Parsetree.structure
| Mli of Parsetree.signature

type info =
{ source_file : string ;
ast : ast
}





val prepare : info Hash_set.hashset -> string Stack.t
3 changes: 2 additions & 1 deletion jscomp/syntax/syntax.mllib
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ ast_payload
ppx_entry
ast_literal
ast_comb
depend
depend
ast_extract

0 comments on commit b181f82

Please sign in to comment.