123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153(* Yoann Padioleau
*
* Copyright (C) 2019 r2c
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1 as published by the Free Software Foundation, with the
* special exception on linking described in file license.txt.
*
* This library 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 file
* license.txt for more details.
*)openCommonmoduleTH=Token_helpers_jsmoduleE=Entity_codemoduleF=Ast_fuzzy(*****************************************************************************)(* Prelude *)(*****************************************************************************)(* This module gives access to the Javascript standard library entities,
* which is especially useful for Graph_code_js.
*
* related:
* - Flow standard lib definitions (small set)
* https://github.com/facebook/flow/tree/master/lib
* - Typescript standard lib definitions (bigger set)
* https://github.com/microsoft/TypeScript/tree/master/src/lib
* - TypeScript generator, which generates the .generated.d.ts above
* https://github.com/Microsoft/TSJS-lib-generator
* - Closure compiler lib definitions (untyped)
* https://github.com/google/closure-compiler/tree/master/externs
* extended in Semmle
* https://github.com/Semmle/ql/tree/master/javascript/externs
*
* - TypeScript definition manager (deprecated)
* https://github.com/typings/typings
* - High quality Typescript type definitions (looks like the new standard)
* http://definitelytyped.org/ especially
* https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/globals.d.ts
*
* src: https://stackoverflow.com/questions/46696266/where-can-i-find-documentation-for-typescripts-built-in-types-and-standard-libr
*)(*****************************************************************************)(* Types *)(*****************************************************************************)(*****************************************************************************)(* Constants *)(*****************************************************************************)letpath_stdlib=Filename.concatConfig_pfff.path"data/js_stdlib/stdlib.js"(*****************************************************************************)(* Helpers *)(*****************************************************************************)letextract_defsfile=lettoks=(* Flow/Typescript and JSX have lexing conflicts *)Common.save_excursionFlag_parsing_js.jsxfalse(fun()->Parse_js.tokensfile)inlettoks=Common.excludeTH.is_commenttoksinlettrees=Lib_ast_fuzzy.mk_trees{Lib_ast_fuzzy.tokf=TH.info_of_tok;kind=TH.token_kind_of_tok;}toksin(* process only toplevel elements, not the one
* under 'declare module xx { ... }', by not recursing inside
* F.Braces
*)letrecauxacc=function|[]->List.revacc|F.Tok("function",_)::F.Tok(s,_)::xs->aux((E.Function,s)::acc)xs|F.Tok("var",_)::F.Tok(s,_)::xs->aux((E.Global,s)::acc)xs|F.Tok("class",_)::F.Tok(s,_)::xs->aux((E.Class,s)::acc)xs|_x::xs->auxaccxsinaux[]treesletadd_and_report_if_already_therealreadyfilestr=ifHashtbl.memalreadystrthenbeginletdupfile=Hashtbl.findalreadystrinpr2(spf"entity %s defined both in %s and %s"strdupfilefile);trueendelsebeginHashtbl.replacealreadystrfile;falseend(*****************************************************************************)(* Stdlib.js generator *)(*****************************************************************************)(* example of use:
* ./codegraph_build -lang js -build_stdlib ~/r2c/other-progs/facebook/flow/lib/core.js ~/pfff/data/js_stdlib/
*)letextract_from_sourcesfilesdst=letdefs=files|>List.map(funfile->file,extract_defsfile)inletdstfile=Filename.concatdst"stdlib.js"inletauxfile=Filename.concatdst"aux.js"inletalready=Hashtbl.create101inletlines=defs|>List.map(fun(file,xs)->["";"// ------------------------------------------------------";spf"// from %s"file;"// ------------------------------------------------------";]@(xs|>Common.map_filter(fun(kind,s)->letstr=matchkindwith|E.Function->spf"function %s() { }"s|E.Class->spf"class %s { }"s|E.Global->spf"var %s;"s|_->failwith(spf"extract_from_source: unrecognized kind %s"(E.string_of_entity_kindkind))in(* Flow allow some overloading so the same function can be defined twice
* but with different types. Codegraph does not like that.
* Flow also have the same function name or class in different files.
*)ifadd_and_report_if_already_therealreadyfilestrthenNoneelseSomestr)))|>List.flatteninletlines=["//Auto-generated by extract_from_sources (do not edit this file)";]@lines@["";"// ------------------------------------------------------";"// Aux file";"// ------------------------------------------------------";]@Common.catauxfileinlets=String.concat"\n"linesinCommon.write_file~file:dstfiles;pr2(spf"Standard Javascript library file %s is ready"dstfile);()