├── .dockerignore ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ └── ocaml_issue.md └── workflows │ └── ci.yml ├── .gitignore ├── .npmignore ├── .ocamlformat ├── .vscode └── settings.json ├── CONTRIBUTING.md ├── Changes.md ├── Dockerfile ├── EXCEPTION.md ├── LICENSE ├── README.md ├── TERMINATION.md ├── assets ├── genFlow.png ├── genFlowInAction.png ├── genFlowWrapJsComponent.png └── genTypeDemo.png ├── create-release.sh ├── dead-code-ppx ├── DeadCodePPX.ml └── dune ├── dist ├── .npmignore ├── README.md ├── postinstall.js ├── reanalyze.exe ├── vendor-darwin │ └── .keep ├── vendor-darwinarm64 │ └── .keep ├── vendor-linux │ └── .keep └── vendor-win32 │ └── .keep ├── dune ├── dune-project ├── examples ├── deadcode │ ├── .gitignore │ ├── .watchmanconfig │ ├── bsconfig.json │ ├── package-lock.json │ ├── package.json │ └── src │ │ ├── AutoAnnotate.bs.js │ │ ├── AutoAnnotate.gen.tsx │ │ ├── AutoAnnotate.res │ │ ├── BootloaderResource.bs.js │ │ ├── BootloaderResource.res │ │ ├── BucklescriptAnnotations.bs.js │ │ ├── BucklescriptAnnotations.gen.tsx │ │ ├── BucklescriptAnnotations.res │ │ ├── ComponentAsProp.bs.js │ │ ├── ComponentAsProp.gen.tsx │ │ ├── ComponentAsProp.res │ │ ├── CreateErrorHandler1.bs.js │ │ ├── CreateErrorHandler1.res │ │ ├── CreateErrorHandler2.bs.js │ │ ├── CreateErrorHandler2.res │ │ ├── DeadCodeImplementation.bs.js │ │ ├── DeadCodeImplementation.res │ │ ├── DeadCodeInterface.bs.js │ │ ├── DeadCodeInterface.res │ │ ├── DeadExn.bs.js │ │ ├── DeadExn.res │ │ ├── DeadExn.resi │ │ ├── DeadMl.bs.js │ │ ├── DeadMl.ml │ │ ├── DeadRT.bs.js │ │ ├── DeadRT.res │ │ ├── DeadRT.resi │ │ ├── DeadTest.bs.js │ │ ├── DeadTest.gen.tsx │ │ ├── DeadTest.res │ │ ├── DeadTestBlacklist.bs.js │ │ ├── DeadTestBlacklist.res │ │ ├── DeadTestWithInterface.bs.js │ │ ├── DeadTestWithInterface.res │ │ ├── DeadTestWithInterface.resi │ │ ├── DeadTypeTest.bs.js │ │ ├── DeadTypeTest.res │ │ ├── DeadTypeTest.resi │ │ ├── DeadValueTest.bs.js │ │ ├── DeadValueTest.res │ │ ├── DeadValueTest.resi │ │ ├── Docstrings.bs.js │ │ ├── Docstrings.gen.tsx │ │ ├── Docstrings.res │ │ ├── DynamicallyLoadedComponent.bs.js │ │ ├── DynamicallyLoadedComponent.res │ │ ├── EmptyArray.bs.js │ │ ├── EmptyArray.res │ │ ├── ErrorHandler.bs.js │ │ ├── ErrorHandler.res │ │ ├── ErrorHandler.resi │ │ ├── EverythingLiveHere.bs.js │ │ ├── EverythingLiveHere.res │ │ ├── FC.bs.js │ │ ├── FC.res │ │ ├── FirstClassModules.bs.js │ │ ├── FirstClassModules.gen.tsx │ │ ├── FirstClassModules.res │ │ ├── FirstClassModulesInterface.bs.js │ │ ├── FirstClassModulesInterface.gen.tsx │ │ ├── FirstClassModulesInterface.res │ │ ├── FirstClassModulesInterface.resi │ │ ├── Hooks.bs.js │ │ ├── Hooks.gen.tsx │ │ ├── Hooks.res │ │ ├── IgnoreInterface.bs.js │ │ ├── IgnoreInterface.gen.tsx │ │ ├── IgnoreInterface.res │ │ ├── IgnoreInterface.resi │ │ ├── ImmutableArray.bs.js │ │ ├── ImmutableArray.res │ │ ├── ImmutableArray.resi │ │ ├── ImportHookDefault.bs.js │ │ ├── ImportHookDefault.gen.tsx │ │ ├── ImportHookDefault.res │ │ ├── ImportHooks.bs.js │ │ ├── ImportHooks.gen.tsx │ │ ├── ImportHooks.res │ │ ├── ImportIndex.bs.js │ │ ├── ImportIndex.gen.tsx │ │ ├── ImportIndex.res │ │ ├── ImportJsValue.bs.js │ │ ├── ImportJsValue.gen.tsx │ │ ├── ImportJsValue.res │ │ ├── ImportMyBanner.bs.js │ │ ├── ImportMyBanner.gen.tsx │ │ ├── ImportMyBanner.res │ │ ├── JSResource.bs.js │ │ ├── JSResource.res │ │ ├── LetPrivate.bs.js │ │ ├── LetPrivate.gen.tsx │ │ ├── LetPrivate.res │ │ ├── ModuleAliases.bs.js │ │ ├── ModuleAliases.gen.tsx │ │ ├── ModuleAliases.res │ │ ├── ModuleAliases2.bs.js │ │ ├── ModuleAliases2.gen.tsx │ │ ├── ModuleAliases2.res │ │ ├── ModuleExceptionBug.bs.js │ │ ├── ModuleExceptionBug.res │ │ ├── NestedModules.bs.js │ │ ├── NestedModules.gen.tsx │ │ ├── NestedModules.res │ │ ├── NestedModulesInSignature.bs.js │ │ ├── NestedModulesInSignature.gen.tsx │ │ ├── NestedModulesInSignature.res │ │ ├── NestedModulesInSignature.resi │ │ ├── Newsyntax.bs.js │ │ ├── Newsyntax.res │ │ ├── Newton.bs.js │ │ ├── Newton.res │ │ ├── Opaque.bs.js │ │ ├── Opaque.gen.tsx │ │ ├── Opaque.res │ │ ├── OptArg.bs.js │ │ ├── OptArg.res │ │ ├── OptArg.resi │ │ ├── Records.bs.js │ │ ├── Records.gen.tsx │ │ ├── Records.res │ │ ├── References.bs.js │ │ ├── References.gen.tsx │ │ ├── References.res │ │ ├── RepeatedLabel.bs.js │ │ ├── RepeatedLabel.res │ │ ├── RequireCond.bs.js │ │ ├── RequireCond.res │ │ ├── Shadow.bs.js │ │ ├── Shadow.gen.tsx │ │ ├── Shadow.res │ │ ├── TestDeadExn.bs.js │ │ ├── TestDeadExn.res │ │ ├── TestEmitInnerModules.bs.js │ │ ├── TestEmitInnerModules.gen.tsx │ │ ├── TestEmitInnerModules.res │ │ ├── TestFirstClassModules.bs.js │ │ ├── TestFirstClassModules.gen.tsx │ │ ├── TestFirstClassModules.res │ │ ├── TestImmutableArray.bs.js │ │ ├── TestImmutableArray.gen.tsx │ │ ├── TestImmutableArray.res │ │ ├── TestImport.bs.js │ │ ├── TestImport.gen.tsx │ │ ├── TestImport.res │ │ ├── TestModuleAliases.bs.js │ │ ├── TestModuleAliases.gen.tsx │ │ ├── TestModuleAliases.res │ │ ├── TestOptArg.bs.js │ │ ├── TestOptArg.res │ │ ├── TestPromise.bs.js │ │ ├── TestPromise.gen.tsx │ │ ├── TestPromise.res │ │ ├── ToSuppress.bs.js │ │ ├── ToSuppress.res │ │ ├── TransitiveType1.bs.js │ │ ├── TransitiveType1.gen.tsx │ │ ├── TransitiveType1.res │ │ ├── TransitiveType2.bs.js │ │ ├── TransitiveType2.gen.tsx │ │ ├── TransitiveType2.res │ │ ├── TransitiveType3.bs.js │ │ ├── TransitiveType3.gen.tsx │ │ ├── TransitiveType3.res │ │ ├── Tuples.bs.js │ │ ├── Tuples.gen.tsx │ │ ├── Tuples.res │ │ ├── TypeParams1.bs.js │ │ ├── TypeParams1.gen.tsx │ │ ├── TypeParams1.res │ │ ├── TypeParams2.bs.js │ │ ├── TypeParams2.gen.tsx │ │ ├── TypeParams2.res │ │ ├── TypeParams3.bs.js │ │ ├── TypeParams3.gen.tsx │ │ ├── TypeParams3.res │ │ ├── Types.bs.js │ │ ├── Types.gen.tsx │ │ ├── Types.res │ │ ├── Unboxed.bs.js │ │ ├── Unboxed.gen.tsx │ │ ├── Unboxed.res │ │ ├── Uncurried.bs.js │ │ ├── Uncurried.gen.tsx │ │ ├── Uncurried.res │ │ ├── Unison.bs.js │ │ ├── Unison.res │ │ ├── UseImportJsValue.bs.js │ │ ├── UseImportJsValue.gen.tsx │ │ ├── UseImportJsValue.res │ │ ├── Variants.bs.js │ │ ├── Variants.gen.tsx │ │ ├── Variants.res │ │ ├── VariantsWithPayload.bs.js │ │ ├── VariantsWithPayload.gen.tsx │ │ ├── VariantsWithPayload.res │ │ ├── deadcode.txt │ │ ├── exception.txt │ │ ├── exception │ │ ├── Arr.bs.js │ │ ├── Arr.res │ │ ├── BeltTest.bs.js │ │ ├── BeltTest.res │ │ ├── BsJson.bs.js │ │ ├── BsJson.res │ │ ├── Exn.bs.js │ │ ├── Exn.res │ │ ├── ExnA.bs.js │ │ ├── ExnA.res │ │ ├── ExnB.bs.js │ │ ├── ExnB.res │ │ ├── ExportWithRename.bs.js │ │ ├── ExportWithRename.gen.tsx │ │ ├── ExportWithRename.res │ │ ├── InnerModules.bs.js │ │ ├── InnerModules.res │ │ ├── TestInnerModules.bs.js │ │ ├── TestInnerModules.res │ │ ├── TestYojson.bs.js │ │ ├── TestYojson.res │ │ ├── Yojson.bs.js │ │ └── Yojson.res │ │ ├── exportNestedValues.js │ │ ├── noalloc.txt │ │ └── noalloc │ │ ├── Chess.bs.js │ │ ├── Chess.res │ │ ├── Matrix.bs.js │ │ ├── Matrix.res │ │ ├── TestNoalloc.bs.js │ │ └── TestNoalloc.res └── termination │ ├── .gitignore │ ├── .watchmanconfig │ ├── Makefile │ ├── README.md │ ├── bsconfig.json │ ├── package-lock.json │ ├── package.json │ └── src │ ├── TestCyberTruck.bs.js │ ├── TestCyberTruck.res │ └── termination.txt ├── lazyload-ppx ├── LazyLoad.ml └── dune ├── package-lock.json ├── package.json ├── reanalyze.opam ├── scripts ├── bump_version_module.js ├── download_dist.js ├── prepare_release.js └── run_integration_tests.js └── src ├── Annotation.ml ├── Arnold.ml ├── CL.ml ├── Common.ml ├── Compat.ml ├── DeadCode.ml ├── DeadCommon.ml ├── DeadException.ml ├── DeadModules.ml ├── DeadOptionalArgs.ml ├── DeadType.ml ├── DeadValue.ml ├── EmitJson.ml ├── Exception.ml ├── Exceptions.ml ├── Exceptions.mli ├── Exn.ml ├── Exn.mli ├── ExnLib.ml ├── FindSourceFile.ml ├── Il.ml ├── Log_.ml ├── ModulePath.ml ├── Name.ml ├── Name.mli ├── Noalloc.ml ├── Paths.ml ├── Reanalyze.ml ├── RunConfig.ml ├── SideEffects.ml ├── Suppress.ml ├── Version.ml ├── compiler-libs-406 ├── ast_helper.ml ├── ast_helper.mli ├── ast_mapper.ml ├── ast_mapper.mli ├── asttypes.mli ├── bsc_warnings.ml ├── btype.ml ├── builtin_attributes.ml ├── builtin_attributes.mli ├── clflags.ml ├── clflags.mli ├── cmi_format.ml ├── cmi_format.mli ├── cmt_format.ml ├── cmt_format.mli ├── config.ml ├── config.mli ├── consistbl.ml ├── consistbl.mli ├── datarepr.ml ├── datarepr.mli ├── docstrings.ml ├── docstrings.mli ├── dune ├── env.ml ├── env.mli ├── ext_pervasives.ml ├── ident.ml ├── ident.mli ├── identifiable.ml ├── identifiable.mli ├── lexer.ml ├── lexer.mli ├── location.ml ├── location.mli ├── longident.ml ├── longident.mli ├── misc.ml ├── outcometree.mli ├── parser.ml ├── parser.mli ├── parsetree.mli ├── path.ml ├── path.mli ├── predef.ml ├── predef.mli ├── primitive.ml ├── primitive.mli ├── subst.ml ├── subst.mli ├── syntaxerr.ml ├── syntaxerr.mli ├── tast_mapper.ml ├── tast_mapper.mli ├── tbl.ml ├── tbl.mli ├── typedtree.ml ├── typedtree.mli ├── types.ml ├── types.mli └── warnings.ml ├── dune ├── dune.406 ├── ext ├── ext_json_parse.ml ├── ext_json_types.ml └── ext_position.ml └── vendor └── Json.ml /.dockerignore: -------------------------------------------------------------------------------- 1 | examples 2 | assets 3 | node_modules 4 | npm-debug.log 5 | Dockerfile* 6 | docker-compose* 7 | .dockerignore 8 | .git 9 | .gitignore 10 | README.md 11 | LICENSE 12 | .vscode 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Using Reanalyze with ReScript? 4 | url: https://github.com/rescript-lang/rescript-vscode/issues/new 5 | about: Reanalyze is being developed in the rescript-vscode repo. Please open your issue there. 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/ocaml_issue.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Using Reanalyze with OCaml? 3 | about: Create an issue here 4 | title: "" 5 | labels: "" 6 | assignees: "" 7 | --- 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store* 2 | *.merlin* 3 | *.bsb.lock* 4 | *.coverage 5 | bundledOutputs/ 6 | _coverage/ 7 | 8 | lib/ 9 | node_modules/ 10 | /_build 11 | /_release 12 | /reanalyze.install 13 | /yarn-error.log 14 | 15 | # npm publish related stuff 16 | reanalyze-*.tgz 17 | 18 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | * 2 | !lib/gen*.tar.gz -------------------------------------------------------------------------------- /.ocamlformat: -------------------------------------------------------------------------------- 1 | cases-exp-indent = 2 2 | space-around-arrays = false 3 | space-around-lists = false 4 | space-around-records = false 5 | space-around-variants = false 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ocaml.sandbox": { 3 | "switch": "4.06.1", 4 | "kind": "opam" 5 | } 6 | } -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Development 2 | 3 | ## Build reanalyze 4 | 5 | Assumes opam with OCaml 4.08 or later. 6 | 7 | ``` 8 | # Installs all dependencies (if needed) and builds reanalyze 9 | npm install 10 | npm run build 11 | ``` 12 | 13 | To build targeting 4.06 compiler libs (needed for ReScript projects) whatever the compiler version used: 14 | 15 | ``` 16 | npm run build406 17 | ``` 18 | 19 | 20 | ## Test reanalyze 21 | 22 | Make sure to always run the tests before submitting any changes (CI usually takes 23 | longer to give you feedback). 24 | 25 | ``` 26 | npm run build406 27 | npm test 28 | ``` 29 | 30 | ## Releases (for Maintainers) 31 | 32 | The project is compatible with the [`npm 33 | version`](https://docs.npmjs.com/cli/version) workflow. After using the `npm 34 | version [major|minor|patch|...]` command, npm will automatically tag the 35 | current commit, bump all the necessary version numbers (also the number in 36 | `src/Version.ml`) and push it to the current remote branch. 37 | 38 | Use the `...` menu next to the [tag](https://github.com/rescript-association/reanalyze/tags) to create a release manually. (To be automated later). 39 | 40 | **Here are the concrete commands to run:** 41 | 42 | ``` 43 | # Make sure to commit & push all current changes, the working branch should be clean 44 | # and synced up with your remote branch 45 | 46 | # Also make sure that your current branch is explicitly set to the relevant remote 47 | # (`git push` instead of `git push origin master`) 48 | git status 49 | 50 | # For patches (0.0.X+1) 51 | npm version patch 52 | 53 | # For minor (0.X+1.0) 54 | npm version minor 55 | 56 | # For major (X+1.0.0) 57 | npm version major 58 | ``` 59 | 60 | ## Releasing to npm (Maintainers only) 61 | 62 | Use the GitHub web iterface to download the artifact `reanalyze-npm.tar` and zip it. 63 | 64 | ``` 65 | # Dry run for testing 66 | npm publish reanalyze-npm.tar.gz --dry-run 67 | 68 | # Publish package as @latest 69 | npm publish reanalyze-npm.tar.gz 70 | 71 | # Publish package with @beta tag 72 | npm publish reanalyze-npm.tar.gz --tag beta 73 | ``` 74 | 75 | Consult the [npm publish](https://docs.npmjs.com/cli/publish) documentation for more options. 76 | In case you get an `ENEEDAUTH` error, use `npm adduser` and authenticate with your npm account first. 77 | 78 | ## Releasing ot opam (Maintainers only) 79 | 80 | ``` 81 | docker build -t opam-publish --pull . 82 | docker run --rm -it -v ~/.ssh:/home/opam/.ssh -v `pwd`:/data opam-publish bash 83 | cd /data 84 | opam publish 85 | ``` 86 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ocaml/opam:debian-11-ocaml-4.14 2 | 3 | USER root 4 | RUN apt-get update \ 5 | && apt-get install -y pkg-config libgmp-dev libssl-dev \ 6 | && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 7 | 8 | USER opam 9 | RUN opam update 10 | RUN opam install opam-publish 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 reasonml 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /assets/genFlow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rescript-lang/reanalyze/650bd42a933feb3f7b9631a85b6910d8e7a97839/assets/genFlow.png -------------------------------------------------------------------------------- /assets/genFlowInAction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rescript-lang/reanalyze/650bd42a933feb3f7b9631a85b6910d8e7a97839/assets/genFlowInAction.png -------------------------------------------------------------------------------- /assets/genFlowWrapJsComponent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rescript-lang/reanalyze/650bd42a933feb3f7b9631a85b6910d8e7a97839/assets/genFlowWrapJsComponent.png -------------------------------------------------------------------------------- /assets/genTypeDemo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rescript-lang/reanalyze/650bd42a933feb3f7b9631a85b6910d8e7a97839/assets/genTypeDemo.png -------------------------------------------------------------------------------- /create-release.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | 3 | # Cleanup 4 | rm -f lib/reanalyze-*.tar.gz 5 | 6 | # MacOS 7 | npm install 8 | npm run clean && npm run build && npm run test 9 | tar czvf lib/reanalyze-macos.tar.gz -C src/lib/bs/native reanalyze.native 10 | 11 | 12 | # Linux 13 | # Copies package.json etc. and runs `npm install`. 14 | docker build -t reanalyze . 15 | 16 | # Mounts only the lib and src volume and runs `npm run build` 17 | docker run -it -v $PWD/lib:/reanalyze/lib -v $PWD/src:/reanalyze/src reanalyze bash -c "npm run clean && npm run build" 18 | 19 | tar czvf lib/reanalyze-linux.tar.gz -C src/lib/bs/native reanalyze.native 20 | -------------------------------------------------------------------------------- /dead-code-ppx/DeadCodePPX.ml: -------------------------------------------------------------------------------- 1 | open Compilerlibs406 2 | 3 | (* Remove code annotated with @dead *) 4 | 5 | let hasDeadAnnotation attributes = 6 | attributes 7 | |> List.exists (fun (({txt}, _) : Parsetree.attribute) -> txt = "dead") 8 | 9 | let rec filter_map l ~f = 10 | match l with 11 | | [] -> [] 12 | | x :: rest -> ( 13 | match f x with 14 | | None -> filter_map rest ~f 15 | | Some y -> y :: filter_map rest ~f) 16 | 17 | let value_binding_list mapper value_bindings = 18 | value_bindings 19 | |> filter_map ~f:(fun (value_binding : Parsetree.value_binding) -> 20 | if value_binding.pvb_attributes |> hasDeadAnnotation then None 21 | else 22 | Some (Ast_mapper.default_mapper.value_binding mapper value_binding)) 23 | 24 | let structure mapper structure = 25 | structure 26 | |> filter_map ~f:(fun (structure_item : Parsetree.structure_item) -> 27 | match structure_item.pstr_desc with 28 | | Pstr_value (rec_value, value_bindings) -> 29 | let value_bindings = value_binding_list mapper value_bindings in 30 | if value_bindings = [] then None 31 | else 32 | Some 33 | { 34 | structure_item with 35 | pstr_desc = Pstr_value (rec_value, value_bindings); 36 | } 37 | | Pstr_primitive {pval_attributes} -> 38 | if pval_attributes |> hasDeadAnnotation then None 39 | else 40 | Some 41 | (Ast_mapper.default_mapper.structure_item mapper structure_item) 42 | | Pstr_exception x -> 43 | if x.pext_attributes |> hasDeadAnnotation then None 44 | else 45 | Some 46 | (Ast_mapper.default_mapper.structure_item mapper structure_item) 47 | | _ -> 48 | Some (Ast_mapper.default_mapper.structure_item mapper structure_item)) 49 | 50 | let signature mapper signature = 51 | signature 52 | |> filter_map ~f:(fun (signature_item : Parsetree.signature_item) -> 53 | let test = 54 | match signature_item.psig_desc with 55 | | Psig_value {pval_attributes} -> 56 | not (pval_attributes |> hasDeadAnnotation) 57 | | _ -> true 58 | in 59 | if test then 60 | Some (Ast_mapper.default_mapper.signature_item mapper signature_item) 61 | else None) 62 | 63 | let () = 64 | Ast_mapper.register "DeadPPX" (fun _argv -> 65 | {Ast_mapper.default_mapper with signature; structure}) 66 | -------------------------------------------------------------------------------- /dead-code-ppx/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name DeadCodePPX) 3 | (public_name deadcodeppx.exe) 4 | (preprocess 5 | (action 6 | (run %{bin:cppo} -V OCAML:%{ocaml_version} %{input-file}))) 7 | (libraries compilerlibs406) 8 | (flags 9 | (:standard -w -9))) 10 | -------------------------------------------------------------------------------- /dist/.npmignore: -------------------------------------------------------------------------------- 1 | **/.keep 2 | -------------------------------------------------------------------------------- /dist/README.md: -------------------------------------------------------------------------------- 1 | # reanalyze 2 | 3 | Please refer to the [Github repository](https://github.com/cristianoc/reanalyze) for now. -------------------------------------------------------------------------------- /dist/postinstall.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const fs = require("fs"); 3 | 4 | const platformAndArch = 5 | process.arch === "x64" ? process.platform : process.platform + process.arch; 6 | 7 | function fail(msg) { 8 | console.warn(msg); 9 | process.exit(1); 10 | } 11 | 12 | function movePlatformBinary() { 13 | const binDirName = "vendor-" + platformAndArch; 14 | const sourcePath = path.join(__dirname, binDirName, "reanalyze.exe"); 15 | 16 | if (!fs.existsSync(sourcePath)) { 17 | return fail("error: executable not found: " + sourcePath); 18 | } 19 | 20 | // We always use the .exe extension, no matter if unix / win32 21 | const targetPath = path.join(__dirname, "reanalyze.exe"); 22 | 23 | fs.renameSync(sourcePath, targetPath); 24 | fs.chmodSync(targetPath, 0777); 25 | } 26 | 27 | switch (platformAndArch) { 28 | case "win32": 29 | case "linux": 30 | case "darwin": 31 | case "darwinarm64": 32 | movePlatformBinary(); 33 | break; 34 | default: 35 | fail("error: no release built for the " + platform + " platform"); 36 | } 37 | -------------------------------------------------------------------------------- /dist/reanalyze.exe: -------------------------------------------------------------------------------- 1 | echo "reanalyze was not installed correctly" 2 | exit 1 3 | -------------------------------------------------------------------------------- /dist/vendor-darwin/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rescript-lang/reanalyze/650bd42a933feb3f7b9631a85b6910d8e7a97839/dist/vendor-darwin/.keep -------------------------------------------------------------------------------- /dist/vendor-darwinarm64/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rescript-lang/reanalyze/650bd42a933feb3f7b9631a85b6910d8e7a97839/dist/vendor-darwinarm64/.keep -------------------------------------------------------------------------------- /dist/vendor-linux/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rescript-lang/reanalyze/650bd42a933feb3f7b9631a85b6910d8e7a97839/dist/vendor-linux/.keep -------------------------------------------------------------------------------- /dist/vendor-win32/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rescript-lang/reanalyze/650bd42a933feb3f7b9631a85b6910d8e7a97839/dist/vendor-win32/.keep -------------------------------------------------------------------------------- /dune: -------------------------------------------------------------------------------- 1 | (dirs :standard \ node_modules examples) -------------------------------------------------------------------------------- /dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 2.0) 2 | (name reanalyze) 3 | -------------------------------------------------------------------------------- /examples/deadcode/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /examples/deadcode/.watchmanconfig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rescript-lang/reanalyze/650bd42a933feb3f7b9631a85b6910d8e7a97839/examples/deadcode/.watchmanconfig -------------------------------------------------------------------------------- /examples/deadcode/bsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "reanalyze": { 3 | "analysis": ["dce"], 4 | "suppress": ["src/ToSuppress.res"], 5 | "unsuppress": [] 6 | }, 7 | "gentypeconfig": { 8 | "language": "typescript", 9 | "module": "es6", 10 | "importPath": "relative", 11 | "debug": { 12 | "all": false 13 | }, 14 | "exportInterfaces": false 15 | }, 16 | "name": "sample-typescript-app", 17 | "bsc-flags": ["-bs-super-errors -w a"], 18 | "ppx-flags": [ 19 | "../../_build/default/dead-code-ppx/DeadCodePPX.exe", 20 | "../../_build/default/lazyload-ppx/LazyLoad.exe" 21 | ], 22 | "reason": { "react-jsx": 3 }, 23 | "bs-dependencies": ["@rescript/react", "@glennsl/bs-json"], 24 | "sources": [ 25 | { 26 | "dir": "src", 27 | "subdirs": true 28 | } 29 | ], 30 | "package-specs": { 31 | "module": "es6", 32 | "in-source": true 33 | }, 34 | "suffix": ".bs.js", 35 | "refmt": 3 36 | } 37 | -------------------------------------------------------------------------------- /examples/deadcode/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "deadcode", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "rescript build -w", 7 | "build": "rescript build", 8 | "clean": "rescript clean -with-deps", 9 | "dce": "npx reanalyze.exe -config -debug -ci -exclude-paths src/noalloc,src/exception -live-names globallyLive1 -live-names globallyLive2,globallyLive3 >src/deadcode.txt", 10 | "exception": "npx reanalyze.exe -exception -ci -suppress src -unsuppress src/exception >src/exception.txt", 11 | "noalloc": "npx reanalyze.exe -ci -noalloc >src/noalloc.txt", 12 | "analyze": "npm run dce && npm run exception && npm run noalloc" 13 | }, 14 | "devDependencies": { 15 | "gentype": "^4.5.0", 16 | "react": "^16.13.1", 17 | "react-dom": "^16.8.6", 18 | "rescript": "^10.0.0-beta.3" 19 | }, 20 | "dependencies": { 21 | "@glennsl/bs-json": "^5.0.4", 22 | "@rescript/react": "^0.10.3", 23 | "reanalyze": "file:../.." 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/deadcode/src/AutoAnnotate.bs.js: -------------------------------------------------------------------------------- 1 | // Generated by ReScript, PLEASE EDIT WITH CARE 2 | /* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ 3 | -------------------------------------------------------------------------------- /examples/deadcode/src/AutoAnnotate.gen.tsx: -------------------------------------------------------------------------------- 1 | /* TypeScript file generated from AutoAnnotate.res by genType. */ 2 | /* eslint-disable import/first */ 3 | 4 | 5 | // tslint:disable-next-line:interface-over-type-literal 6 | export type variant = { tag: "R"; value: number }; 7 | 8 | // tslint:disable-next-line:interface-over-type-literal 9 | export type record = { readonly variant: variant }; 10 | 11 | // tslint:disable-next-line:interface-over-type-literal 12 | export type r2 = { readonly r2: number }; 13 | 14 | // tslint:disable-next-line:interface-over-type-literal 15 | export type r3 = { readonly r3: number }; 16 | 17 | // tslint:disable-next-line:interface-over-type-literal 18 | export type r4 = { readonly r4: number }; 19 | 20 | // tslint:disable-next-line:interface-over-type-literal 21 | export type annotatedVariant = 22 | { tag: "R2"; value: [r2, r3] } 23 | | { tag: "R4"; value: r4 }; 24 | -------------------------------------------------------------------------------- /examples/deadcode/src/AutoAnnotate.res: -------------------------------------------------------------------------------- 1 | type variant = R(int) 2 | 3 | @genType 4 | type record = {variant: variant} 5 | 6 | type r2 = {r2: int} 7 | 8 | type r3 = {r3: int} 9 | 10 | type r4 = {r4: int} 11 | 12 | @genType 13 | type annotatedVariant = 14 | | R2(r2, r3) 15 | | R4(r4) 16 | 17 | -------------------------------------------------------------------------------- /examples/deadcode/src/BootloaderResource.bs.js: -------------------------------------------------------------------------------- 1 | // Generated by ReScript, PLEASE EDIT WITH CARE 2 | /* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ 3 | -------------------------------------------------------------------------------- /examples/deadcode/src/BootloaderResource.res: -------------------------------------------------------------------------------- 1 | /* NOTE: This is a spooky interface that provides no type safety. It should be 2 | * improved. Use with caution. */ 3 | @module("BootloaderResource") 4 | external read: JSResource.t<'a> => 'a = "read" 5 | 6 | -------------------------------------------------------------------------------- /examples/deadcode/src/BucklescriptAnnotations.bs.js: -------------------------------------------------------------------------------- 1 | // Generated by ReScript, PLEASE EDIT WITH CARE 2 | 3 | 4 | function bar(x) { 5 | var f = x.twoArgs; 6 | return f(3, "a"); 7 | } 8 | 9 | export { 10 | bar , 11 | } 12 | /* No side effect */ 13 | -------------------------------------------------------------------------------- /examples/deadcode/src/BucklescriptAnnotations.gen.tsx: -------------------------------------------------------------------------------- 1 | /* TypeScript file generated from BucklescriptAnnotations.res by genType. */ 2 | /* eslint-disable import/first */ 3 | 4 | 5 | // tslint:disable-next-line:interface-over-type-literal 6 | export type someMutableFields = { 7 | mutable0: string; 8 | readonly immutable: number; 9 | mutable1: string; 10 | mutable2: string 11 | }; 12 | 13 | // tslint:disable-next-line:interface-over-type-literal 14 | export type someMethods = { 15 | readonly send: (_1:string) => void; 16 | readonly on: (_1:string, _2:((_1:number) => void)) => void; 17 | readonly threeargs: (_1:number, _2:string, _3:number) => string; 18 | readonly twoArgs: (_1:number, _2:string) => number 19 | }; 20 | -------------------------------------------------------------------------------- /examples/deadcode/src/BucklescriptAnnotations.res: -------------------------------------------------------------------------------- 1 | @genType 2 | type someMutableFields = { 3 | @set 4 | "mutable0": string, 5 | "immutable": int, 6 | @set 7 | "mutable1": string, 8 | @set 9 | "mutable2": string, 10 | } 11 | 12 | @genType 13 | type someMethods = { 14 | @meth 15 | "send": string => unit, 16 | @meth 17 | "on": (string, (. int) => unit) => unit, 18 | @meth 19 | "threeargs": (int, string, int) => string, 20 | "twoArgs": (. int, string) => int, 21 | } 22 | 23 | // let foo = (x: someMethods) => x["threeargs"](3, "a", 4) 24 | 25 | let bar = (x: someMethods) => { 26 | let f = x["twoArgs"] 27 | f(. 3, "a") 28 | } 29 | 30 | -------------------------------------------------------------------------------- /examples/deadcode/src/ComponentAsProp.bs.js: -------------------------------------------------------------------------------- 1 | // Generated by ReScript, PLEASE EDIT WITH CARE 2 | 3 | import * as React from "react"; 4 | import * as Caml_option from "rescript/lib/es6/caml_option.js"; 5 | 6 | function ComponentAsProp(Props) { 7 | var title = Props.title; 8 | var description = Props.description; 9 | var button = Props.button; 10 | return React.createElement("div", undefined, React.createElement("div", undefined, title, description, button !== undefined ? Caml_option.valFromOption(button) : null)); 11 | } 12 | 13 | var make = ComponentAsProp; 14 | 15 | export { 16 | make , 17 | } 18 | /* react Not a pure module */ 19 | -------------------------------------------------------------------------------- /examples/deadcode/src/ComponentAsProp.gen.tsx: -------------------------------------------------------------------------------- 1 | /* TypeScript file generated from ComponentAsProp.res by genType. */ 2 | /* eslint-disable import/first */ 3 | 4 | 5 | import * as React from 'react'; 6 | 7 | // @ts-ignore: Implicit any on import 8 | import * as ComponentAsPropBS__Es6Import from './ComponentAsProp.bs'; 9 | const ComponentAsPropBS: any = ComponentAsPropBS__Es6Import; 10 | 11 | // tslint:disable-next-line:interface-over-type-literal 12 | export type Props = { 13 | readonly button?: JSX.Element; 14 | readonly description: JSX.Element; 15 | readonly title: JSX.Element 16 | }; 17 | 18 | /** This is like declaring a normal ReasonReact component's `make` function, except the body is a the interop hook wrapJsForReason */ 19 | export const make: React.ComponentType<{ 20 | readonly button?: JSX.Element; 21 | readonly description: JSX.Element; 22 | readonly title: JSX.Element 23 | }> = ComponentAsPropBS.make; 24 | -------------------------------------------------------------------------------- /examples/deadcode/src/ComponentAsProp.res: -------------------------------------------------------------------------------- 1 | @ocaml.doc( 2 | " This is like declaring a normal ReasonReact component's `make` function, except the body is a the interop hook wrapJsForReason " 3 | ) 4 | @genType 5 | @react.component 6 | let make = (~title, ~description, ~button=?) => { 7 |