diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b117771204..3ad07e8f6d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -320,6 +320,10 @@ jobs: - name: Check for diffs in tests folder run: git diff --ignore-cr-at-eol --exit-code tests + - name: Run analysis / tools tests + if: runner.os != 'Windows' && matrix.os != 'buildjet-2vcpu-ubuntu-2204-arm' + run: opam exec -- make -C tests/analysis_tests test && make -C tests/tools_tests test + - name: Run gentype tests if: runner.os != 'Windows' run: make -C tests/gentype_tests/typescript-react-example clean test diff --git a/.gitignore b/.gitignore index 5165ad1cba..45475b4fad 100644 --- a/.gitignore +++ b/.gitignore @@ -76,3 +76,8 @@ playground/compiler.js rewatch/target/ rewatch/rewatch + +tests/tools_tests/**/*.res.js +tests/tools_tests/lib +tests/analysis_tests*/lib +tests/analysis_tests/**/*.bs.js diff --git a/CHANGELOG.md b/CHANGELOG.md index d31df4e152..2985a80e16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,11 +17,12 @@ - Introduce "Unified operators" for arithmetic operators (`+`, `-`, `*`, `/`, `mod`). https://github.com/rescript-lang/rescript-compiler/pull/7057 - Add remainder (`%`, aka modulus) operator. https://github.com/rescript-lang/rescript-compiler/pull/7152 - #### :bug: Bug fix + - Fix and clean up boolean and/or optimizations. https://github.com/rescript-lang/rescript-compiler/pull/7134 https://github.com/rescript-lang/rescript-compiler/pull/7151 #### :nail_care: Polish + - Improve code generation for pattern matching of untagged variants. https://github.com/rescript-lang/rescript-compiler/pull/7128 - Improve negation handling in combination with and/or to simplify generated code (especially coming out of pattern matching). https://github.com/rescript-lang/rescript-compiler/pull/7138 - optimize JavaScript code generation by using x == null checks and improving type-based optimizations for string/number literals. https://github.com/rescript-lang/rescript-compiler/pull/7141 @@ -30,6 +31,9 @@ - Further improve boolean optimizations. https://github.com/rescript-lang/rescript-compiler/pull/7149 - Simplify code generated for conditionals. https://github.com/rescript-lang/rescript-compiler/pull/7151 +#### :house: Internal + +- Move rescript-editor-analysis and rescript-tools into compiler repo. https://github.com/rescript-lang/rescript-compiler/pull/7000 # 12.0.0-alpha.4 @@ -61,6 +65,7 @@ - Fix genType JSX component compilation. https://github.com/rescript-lang/rescript-compiler/pull/7107 #### :nail_care: Polish + - Add some context to error message for unused variables. https://github.com/rescript-lang/rescript-compiler/pull/7050 - Improve error message when passing `children` prop to a component that doesn't accept it. https://github.com/rescript-lang/rescript-compiler/pull/7044 - Improve error messages for pattern matching on option vs non-option, and vice versa. https://github.com/rescript-lang/rescript-compiler/pull/7035 @@ -71,7 +76,6 @@ - Provide additional context in error message when `unit` is expected. https://github.com/rescript-lang/rescript-compiler/pull/7045 - Improve error message when passing an object where a record is expected. https://github.com/rescript-lang/rescript-compiler/pull/7101 - #### :house: Internal - Remove uncurried flag from bsb. https://github.com/rescript-lang/rescript-compiler/pull/7049 diff --git a/analysis.opam b/analysis.opam new file mode 100644 index 0000000000..65bd0be75e --- /dev/null +++ b/analysis.opam @@ -0,0 +1,27 @@ +# This file is generated by dune, edit dune-project instead +opam-version: "2.0" +synopsis: "ReScript Analysis" +maintainer: ["Hongbo Zhang " "Cristiano Calcagno"] +authors: ["Hongbo Zhang "] +license: "LGPL-3.0-or-later" +homepage: "https://github.com/rescript-lang/rescript-compiler" +bug-reports: "https://github.com/rescript-lang/rescript-compiler/issues" +depends: [ + "ocaml" {>= "4.10"} + "cppo" {= "1.6.9"} + "dune" +] +build: [ + ["dune" "subst"] {pinned} + [ + "dune" + "build" + "-p" + name + "-j" + jobs + "@install" + "@runtest" {with-test} + "@doc" {with-doc} + ] +] diff --git a/analysis/README.md b/analysis/README.md new file mode 100644 index 0000000000..2ce1bf5a2d --- /dev/null +++ b/analysis/README.md @@ -0,0 +1,26 @@ +# Analysis Library and Binary + +This subfolder builds a private command line binary used by the plugin to power a few functionalities such as jump to definition, hover and autocomplete. + +The binary reads the `.cmt` and `.cmti` files and analyses them. + +For installation & build instructions, see the main CONTRIBUTING.md. + +## Overview + +See main CONTRIBUTING.md's repo structure. Additionally, `examples/` is a convenience debugging repo. Check out `test.sh` (invoked through `make test`) to see the snapshots testing workflow stored in `tests/`. + +## Usage + +At root: +```sh +./rescript-editor-analysis.exe --help + +# or + +dune exec -- rescript-editor-analysis --help +``` + +## History + +This project is based on a fork of [Reason Language Server](https://github.com/jaredly/reason-language-server). diff --git a/analysis/bin/dune b/analysis/bin/dune new file mode 100644 index 0000000000..64c2a78156 --- /dev/null +++ b/analysis/bin/dune @@ -0,0 +1,11 @@ +(env + (static + (flags + (:standard -ccopt -static)))) + +(executable + (public_name rescript-editor-analysis) + (package analysis) + (modes byte exe) + (name main) + (libraries analysis)) diff --git a/analysis/bin/main.ml b/analysis/bin/main.ml new file mode 100644 index 0000000000..259b1a3004 --- /dev/null +++ b/analysis/bin/main.ml @@ -0,0 +1,218 @@ +open Analysis + +let help = + {| +**Private CLI For rescript-vscode usage only** + +API examples: + ./rescript-editor-analysis.exe completion src/MyFile.res 0 4 currentContent.res true + ./rescript-editor-analysis.exe definition src/MyFile.res 9 3 + ./rescript-editor-analysis.exe typeDefinition src/MyFile.res 9 3 + ./rescript-editor-analysis.exe documentSymbol src/Foo.res + ./rescript-editor-analysis.exe hover src/MyFile.res 10 2 true + ./rescript-editor-analysis.exe references src/MyFile.res 10 2 + ./rescript-editor-analysis.exe rename src/MyFile.res 10 2 foo + ./rescript-editor-analysis.exe diagnosticSyntax src/MyFile.res + ./rescript-editor-analysis.exe inlayHint src/MyFile.res 0 3 25 + ./rescript-editor-analysis.exe codeLens src/MyFile.res + +Dev-time examples: + ./rescript-editor-analysis.exe dump src/MyFile.res src/MyFile2.res + ./rescript-editor-analysis.exe test src/MyFile.res + +Note: positions are zero-indexed (start at 0 0), following LSP. +https://microsoft.github.io/language-server-protocol/specification#position + +Options: + completion: compute autocomplete for MyFile.res at line 0 and column 4, + where MyFile.res is being edited and the editor content is in file current.res. + + ./rescript-editor-analysis.exe completion src/MyFile.res 0 4 current.res + + definition: get definition for item in MyFile.res at line 10 column 2: + + ./rescript-editor-analysis.exe definition src/MyFile.res 10 2 + + typeDefinition: get type definition for item in MyFile.res at line 10 column 2: + + ./rescript-editor-analysis.exe typeDefinition src/MyFile.res 10 2 + + documentSymbol: get all symbols declared in MyFile.res + + ./rescript-editor-analysis.exe documentSymbol src/MyFile.res + + hover: get inferred type for MyFile.res at line 10 column 2 (supporting markdown links): + + ./rescript-editor-analysis.exe hover src/MyFile.res 10 2 true + + references: get all references to item in MyFile.res at line 10 column 2: + + ./rescript-editor-analysis.exe references src/MyFile.res 10 2 + + rename: rename all appearances of item in MyFile.res at line 10 column 2 with foo: + + ./rescript-editor-analysis.exe rename src/MyFile.res 10 2 foo + + semanticTokens: return token semantic highlighting info for MyFile.res + + ./rescript-editor-analysis.exe semanticTokens src/MyFile.res + + createInterface: print to stdout the interface file for src/MyFile.res + + ./rescript-editor-analysis.exe createInterface src/MyFile.res lib/bs/src/MyFile.cmi + + format: print to stdout the formatted version of the provided file + + ./rescript-editor-analysis.exe format src/MyFile.res + + diagnosticSyntax: print to stdout diagnostic for syntax + + ./rescript-editor-analysis.exe diagnosticSyntax src/MyFile.res + + inlayHint: get all inlay Hint between line 0 and 3 declared in MyFile.res. Last argument is maximum of character length for inlay hints + + ./rescript-editor-analysis.exe inlayHint src/MyFile.res 0 3 25 + + codeLens: get all code lens entries for file src/MyFile.res + + ./rescript-editor-analysis.exe codeLens src/MyFile.res + + signatureHelp: get signature help if available for position at line 10 column 2 in src/MyFile.res + + ./rescript-editor-analysis.exe signatureHelp src/MyFile.res 10 2 + + test: run tests specified by special comments in file src/MyFile.res + + ./rescript-editor-analysis.exe test src/src/MyFile.res +|} + +let main () = + let args = Array.to_list Sys.argv in + let debugLevel, args = + match args with + | _ :: "debug-dump" :: logLevel :: rest -> + ( (match logLevel with + | "verbose" -> Debug.Verbose + | "regular" -> Regular + | _ -> Off), + "dummy" :: rest ) + | args -> (Off, args) + in + Debug.debugLevel := debugLevel; + let debug = debugLevel <> Debug.Off in + let printHeaderInfo path line col = + if debug then + Printf.printf "Debug level: %s\n%s:%s-%s\n\n" + (match debugLevel with + | Debug.Verbose -> "verbose" + | Regular -> "regular" + | Off -> "off") + path line col + in + match args with + | [_; "cache-project"; rootPath] -> ( + Cfg.readProjectConfigCache := false; + let uri = Uri.fromPath rootPath in + match Packages.getPackage ~uri with + | Some package -> Cache.cacheProject package + | None -> print_endline "\"ERR\"") + | [_; "cache-delete"; rootPath] -> ( + Cfg.readProjectConfigCache := false; + let uri = Uri.fromPath rootPath in + match Packages.findRoot ~uri (Hashtbl.create 0) with + | Some (`Bs rootPath) -> ( + match BuildSystem.getLibBs rootPath with + | None -> print_endline "\"ERR\"" + | Some libBs -> + Cache.deleteCache (Cache.targetFileFromLibBs libBs); + print_endline "\"OK\"") + | _ -> print_endline "\"ERR: Did not find root \"") + | [_; "completion"; path; line; col; currentFile] -> + printHeaderInfo path line col; + Commands.completion ~debug ~path + ~pos:(int_of_string line, int_of_string col) + ~currentFile + | [_; "completionResolve"; path; modulePath] -> + Commands.completionResolve ~path ~modulePath + | [_; "definition"; path; line; col] -> + Commands.definition ~path + ~pos:(int_of_string line, int_of_string col) + ~debug + | [_; "typeDefinition"; path; line; col] -> + Commands.typeDefinition ~path + ~pos:(int_of_string line, int_of_string col) + ~debug + | [_; "documentSymbol"; path] -> DocumentSymbol.command ~path + | [_; "hover"; path; line; col; currentFile; supportsMarkdownLinks] -> + Commands.hover ~path + ~pos:(int_of_string line, int_of_string col) + ~currentFile ~debug + ~supportsMarkdownLinks: + (match supportsMarkdownLinks with + | "true" -> true + | _ -> false) + | [ + _; "signatureHelp"; path; line; col; currentFile; allowForConstructorPayloads; + ] -> + Commands.signatureHelp ~path + ~pos:(int_of_string line, int_of_string col) + ~currentFile ~debug + ~allowForConstructorPayloads: + (match allowForConstructorPayloads with + | "true" -> true + | _ -> false) + | [_; "inlayHint"; path; line_start; line_end; maxLength] -> + Commands.inlayhint ~path + ~pos:(int_of_string line_start, int_of_string line_end) + ~maxLength ~debug + | [_; "codeLens"; path] -> Commands.codeLens ~path ~debug + | [_; "codeAction"; path; startLine; startCol; endLine; endCol; currentFile] + -> + Commands.codeAction ~path + ~startPos:(int_of_string startLine, int_of_string startCol) + ~endPos:(int_of_string endLine, int_of_string endCol) + ~currentFile ~debug + | [_; "codemod"; path; line; col; typ; hint] -> + let typ = + match typ with + | "add-missing-cases" -> Codemod.AddMissingCases + | _ -> raise (Failure "unsupported type") + in + let res = + Codemod.transform ~path + ~pos:(int_of_string line, int_of_string col) + ~debug ~typ ~hint + |> Json.escape + in + Printf.printf "\"%s\"" res + | [_; "diagnosticSyntax"; path] -> Commands.diagnosticSyntax ~path + | _ :: "reanalyze" :: _ -> + let len = Array.length Sys.argv in + for i = 1 to len - 2 do + Sys.argv.(i) <- Sys.argv.(i + 1) + done; + Sys.argv.(len - 1) <- ""; + Reanalyze.cli () + | [_; "references"; path; line; col] -> + Commands.references ~path + ~pos:(int_of_string line, int_of_string col) + ~debug + | [_; "rename"; path; line; col; newName] -> + Commands.rename ~path + ~pos:(int_of_string line, int_of_string col) + ~newName ~debug + | [_; "semanticTokens"; currentFile] -> + SemanticTokens.semanticTokens ~currentFile + | [_; "createInterface"; path; cmiFile] -> + Printf.printf "\"%s\"" + (Json.escape (CreateInterface.command ~path ~cmiFile)) + | [_; "format"; path] -> + Printf.printf "\"%s\"" (Json.escape (Commands.format ~path)) + | [_; "test"; path] -> Commands.test ~path + | args when List.mem "-h" args || List.mem "--help" args -> prerr_endline help + | _ -> + prerr_endline help; + exit 1 +;; + +main () diff --git a/analysis/dune b/analysis/dune new file mode 100644 index 0000000000..6b297d2e58 --- /dev/null +++ b/analysis/dune @@ -0,0 +1,16 @@ +(dirs bin src reanalyze vendor) + +(env + (dev + (env-vars + (CPPO_FLAGS -U=RELEASE))) + (release + (env-vars + (CPPO_FLAGS -D=RELEASE)) + (ocamlopt_flags + (:standard -O3 -unbox-closures))) + (static + (env-vars + (CPPO_FLAGS -D=RELEASE)) + (ocamlopt_flags + (:standard -O3 -unbox-closures)))) diff --git a/analysis/examples/example-project/.gitignore b/analysis/examples/example-project/.gitignore new file mode 100644 index 0000000000..4ae6e66ef3 --- /dev/null +++ b/analysis/examples/example-project/.gitignore @@ -0,0 +1,2 @@ +lib +.merlin \ No newline at end of file diff --git a/analysis/examples/example-project/bsconfig.json b/analysis/examples/example-project/bsconfig.json new file mode 100644 index 0000000000..f592900000 --- /dev/null +++ b/analysis/examples/example-project/bsconfig.json @@ -0,0 +1,14 @@ +{ + "name": "tryit", + "sources": "src", + "bsc-flags": ["-bs-super-errors", "-open Belt"], + "warnings": { + "number": "-32-26-27-33" + }, + "bs-dependencies": ["reason-react"], + "reason": { "react-jsx": 3 }, + "namespace": "my-namespace", + "reanalyze": { + "analysis": ["dce", "exception"] + } +} diff --git a/analysis/examples/example-project/package-lock.json b/analysis/examples/example-project/package-lock.json new file mode 100644 index 0000000000..61650f5294 --- /dev/null +++ b/analysis/examples/example-project/package-lock.json @@ -0,0 +1,16 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "reason-react": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/reason-react/-/reason-react-0.9.1.tgz", + "integrity": "sha512-nlH0O2TDy9KzOLOW+vlEQk4ExHOeciyzFdoLcsmmiit6hx6H5+CVDrwJ+8aiaLT/kqK5xFOjy4PS7PftWz4plA==" + }, + "rescript": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/rescript/-/rescript-9.1.2.tgz", + "integrity": "sha512-4wHvTDv3nyYnAPJHcg1RGG8z7u3HDiBf6RN3P/dITDv859Qo35aKOzJWQtfBzbAs0EKNafLqei3TnUqiAv6BwQ==" + } + } +} diff --git a/analysis/examples/example-project/package.json b/analysis/examples/example-project/package.json new file mode 100644 index 0000000000..b948ffc3a9 --- /dev/null +++ b/analysis/examples/example-project/package.json @@ -0,0 +1,11 @@ +{ + "dependencies": { + "reason-react": "^0.9.1", + "rescript": "^9.1.2" + }, + "scripts": { + "build": "rescript", + "start": "rescript build -w", + "clean": "rescript clean -with-deps" + } +} diff --git a/analysis/examples/example-project/src/B.re b/analysis/examples/example-project/src/B.re new file mode 100644 index 0000000000..2ad1ee8305 --- /dev/null +++ b/analysis/examples/example-project/src/B.re @@ -0,0 +1,9 @@ + + +let x = 12 + + +let y = 44 + + +let z = 123 diff --git a/analysis/examples/example-project/src/Embeded.md b/analysis/examples/example-project/src/Embeded.md new file mode 100644 index 0000000000..ede126c0f2 --- /dev/null +++ b/analysis/examples/example-project/src/Embeded.md @@ -0,0 +1,55 @@ +# Markdown Embedded Fenced Code Regression Test + +```re +module Something = { + open Other; + + let m = {name: "Me", age: 0}; + let animal = Things(10); + let other = Things(2); + let me: animals = People("Hie"); + let x = something + 10; + let r = m.name; + + let awesome = 20; + if (true) { + () + } +}; +``` + +```reason +module Something = { + open Other; + + let m = {name: "Me", age: 0}; + let animal = Things(10); + let other = Things(2); + let me: animals = People("Hie"); + let x = something + 10; + let r = m.name; + + let awesome = 20; + if (true) { + () + } +}; +``` + +```reasonml +module Something = { + open Other; + + let m = {name: "Me", age: 0}; + let animal = Things(10); + let other = Things(2); + let me: animals = People("Hie"); + let x = something + 10; + let r = m.name; + + let awesome = 20; + if (true) { + () + } +}; +``` \ No newline at end of file diff --git a/analysis/examples/example-project/src/Hello.res b/analysis/examples/example-project/src/Hello.res new file mode 100644 index 0000000000..db525a7e73 --- /dev/null +++ b/analysis/examples/example-project/src/Hello.res @@ -0,0 +1,173 @@ +let someLongName = 10 + +let otherLongName = "string" + +let x = {"a": 3} + +let r = Other.something + +let l = More.inner + More.n + Other.inner + +let n = More.n + +let _ = More.party +let _ = string_of_bool + +/* let m = {More.a: 2, b: 32.}; */ + +module Something = { + open Other + + let m = {name: "Me", age: 0} + let animal = Things(10) + let other = Things(2) + let me: animals = People("Hie") + let x = something + 10 + let r = m.name + + let awesome = 20 + if true { + () + } +} + +open! Something + +let y = x + 10 + +switch me { +| Things(n) => () +| _ => () +} + +let z = x * x + +let aThing = 10 + Other.something + +@ocaml.doc(" Some docs about this **awesome** thing. ") +let awesome = + 100 + m.age + +let thing = "thing" + +let transform = (x, y) => x ++ Js.Float.toString(y) + +let z = transform("hello ", 5.) + +let zzz = 1 + +let more = 20 + +@ocaml.doc(" Something here ") +let added = + 10 + awesome + +open Other + +open Hashtbl + +@ocaml.doc(" Some more documentation about this ") +let awesome = x => x + 2 + +let a = list{"hello", "my fine" ++ "folks", "in boonville"} + +let div = (~x, ~y, ~children, ()) => 10 + +let m =
+ +let something = animal => + switch animal { + | blank => () + } + +something(animal) + +let someFunction = (memorableName, {contents}) => { + let innerMemorable = 20 + memorableName + innerMemorable +} + +/* let awesome = 10000; */ + +/* let awesome = 111; */ + +let z = 10 + +let z = find + +let z = later + +let m = Other.later + +for _index in 0 to 10 { + print_endline("hellO") +} + +module OneOneOneOne = { + module TwoTwoTwoTwo = { + let xxxxxxxxxx = 10 + } +} +let r = OneOneOneOne.TwoTwoTwoTwo.xxxxxxxxxx + +type awesome = { + one: string, + two: float, +} + +open OneOneOneOne.TwoTwoTwoTwo + +include OneOneOneOne.TwoTwoTwoTwo + +include More + +let _ = Other.oo.person.name + +type lots = + | Parties + | Plutocrats(int, float) + | Possums + | Oppossums + +let y = Some(10 + awesome(3)) + +let z = {contents: 30} +let party = {one: "one", two: 2.} + +let {one, two} = party + +let thing = () => 34 + 43 + +type more = awesome + +let {contents} = z + +switch y { +| Some(u) => () +| None => () +} + +/* let x = [%raw " hello"]; */ + +let awesome = "hello" + +type shortReference = (string, list, string) + +type reference = { + uri: string, + moduleName: string, + modulePath: list, + name: string, +} + +type typeSource = + | Builtin(string) + | Public(reference) + | NotFound + +type lockfile = { + version: int, + pastVersions: Belt.HashMap.Int.t>, + current: list<(shortReference, int)>, +} + diff --git a/analysis/examples/example-project/src/Json.res b/analysis/examples/example-project/src/Json.res new file mode 100644 index 0000000000..7cbfbbe037 --- /dev/null +++ b/analysis/examples/example-project/src/Json.res @@ -0,0 +1,607 @@ +@@ocaml.doc(" # Json parser + * + * Works with bucklescript and bsb-native + * + * ## Basics + * + * ``` + * open Json.Infix; /* for the nice infix operators */ + * let raw = {|{\"hello\": \"folks\"}|}; + * let who = Json.parse(raw) |> Json.get(\"hello\") |?> Json.string; + * Js.log(who); + * ``` + * + * ## Parse & stringify + * + * @doc parse, stringify + * + * ## Accessing descendents + * + * @doc get, nth, getPath + * + * ## Coercing to types + * + * @doc string, number, array, obj, bool, null + * + * ## The JSON type + * + * @doc t + * + * ## Infix operators for easier working + * + * @doc Infix + ") + +type rec t = + | String(string) + | Number(float) + | Array(list) + | Object(list<(string, t)>) + | True + | False + | Null + +let string_of_number = f => { + let s = Js.Float.toString(f) + if String.get(s, String.length(s) - 1) == '.' { + String.sub(s, 0, String.length(s) - 1) + } else { + s + } +} + +@ocaml.doc(" + * This module is provided for easier working with optional values. + ") +module Infix = { + @ocaml.doc(" The \"force unwrap\" operator + * + * If you're sure there's a value, you can force it. + * ``` + * open Json.Infix; + * let x: int = Some(10) |! \"Expected this to be present\"; + * Js.log(x); + * ``` + * + * But you gotta be sure, otherwise it will throw. + * ```reason;raises + * open Json.Infix; + * let x: int = None |! \"This will throw\"; + * ``` + ") + let \"|!" = (o, d) => + switch o { + | None => failwith(d) + | Some(v) => v + } + @ocaml.doc(" The \"upwrap with default\" operator + * ``` + * open Json.Infix; + * let x: int = Some(10) |? 4; + * let y: int = None |? 5; + * Js.log2(x, y); + * ``` + ") + let \"|?" = (o, d) => + switch o { + | None => d + | Some(v) => v + } + @ocaml.doc(" The \"transform contents into new optional\" operator + * ``` + * open Json.Infix; + * let maybeInc = x => x > 5 ? Some(x + 1) : None; + * let x: option(int) = Some(14) |?> maybeInc; + * let y: option(int) = None |?> maybeInc; + * ``` + ") + let \"|?>" = (o, fn) => + switch o { + | None => None + | Some(v) => fn(v) + } + @ocaml.doc(" The \"transform contents into new value & then re-wrap\" operator + * ``` + * open Json.Infix; + * let inc = x => x + 1; + * let x: option(int) = Some(7) |?>> inc; + * let y: option(int) = None |?>> inc; + * Js.log2(x, y); + * ``` + ") + let \"|?>>" = (o, fn) => + switch o { + | None => None + | Some(v) => Some(fn(v)) + } + @ocaml.doc(" \"handle the value if present, otherwise here's the default\" + * + * It's called fold because that's what people call it :?. It's the same as \"transform contents to new value\" + \"unwrap with default\". + * + * ``` + * open Json.Infix; + * let inc = x => x + 1; + * let x: int = fold(Some(4), 10, inc); + * let y: int = fold(None, 2, inc); + * Js.log2(x, y); + * ``` + ") + let fold = (o, d, f) => + switch o { + | None => d + | Some(v) => f(v) + } +} + +let escape = text => { + let ln = String.length(text) + let buf = Buffer.create(ln) + let rec loop = i => + if i < ln { + switch String.get(text, i) { + | '\012' => Buffer.add_string(buf, "\\f") + | '\\' => Buffer.add_string(buf, "\\\\") + | '"' => Buffer.add_string(buf, "\\\"") + | '\n' => Buffer.add_string(buf, "\\n") + | '\b' => Buffer.add_string(buf, "\\b") + | '\r' => Buffer.add_string(buf, "\\r") + | '\t' => Buffer.add_string(buf, "\\t") + | c => Buffer.add_char(buf, c) + } + loop(i + 1) + } + loop(0) + Buffer.contents(buf) +} + +@ocaml.doc(" ``` + * let text = {|{\"hello\": \"folks\", \"aa\": [2, 3, \"four\"]}|}; + * let result = Json.stringify(Json.parse(text)); + * Js.log(result); + * assert(text == result); + * ``` + ") +let rec stringify = t => + switch t { + | String(value) => "\"" ++ (escape(value) ++ "\"") + | Number(num) => string_of_number(num) + | Array(items) => "[" ++ (String.concat(", ", List.map(items, stringify)) ++ "]") + | Object(items) => + "{" ++ + (String.concat( + ", ", + List.map(items, ((k, v)) => "\"" ++ (String.escaped(k) ++ ("\": " ++ stringify(v)))), + ) ++ + "}") + | True => "true" + | False => "false" + | Null => "null" + } + +let white = n => { + let buffer = Buffer.create(n) + for _ in 0 to n - 1 { + Buffer.add_char(buffer, ' ') + } + Buffer.contents(buffer) +} + +let rec stringifyPretty = (~indent=0, t) => + switch t { + | String(value) => "\"" ++ (escape(value) ++ "\"") + | Number(num) => string_of_number(num) + | Array(list{}) => "[]" + | Array(items) => + "[\n" ++ + (white(indent) ++ + (String.concat(",\n" ++ white(indent), List.map(items, stringifyPretty(~indent=indent + 2))) ++ + ("\n" ++ + (white(indent) ++ "]")))) + | Object(list{}) => "{}" + | Object(items) => + "{\n" ++ + (white(indent) ++ + (String.concat( + ",\n" ++ white(indent), + List.map(items, ((k, v)) => + "\"" ++ (String.escaped(k) ++ ("\": " ++ stringifyPretty(~indent=indent + 2, v))) + ), + ) ++ + ("\n" ++ + (white(indent) ++ "}")))) + | True => "true" + | False => "false" + | Null => "null" + } + +let unwrap = (message, t) => + switch t { + | Some(v) => v + | None => failwith(message) + } + +@nodoc +module Parser = { + let split_by = (~keep_empty=false, is_delim, str) => { + let len = String.length(str) + let rec loop = (acc, last_pos, pos) => + if pos == -1 { + if last_pos == 0 && !keep_empty { + acc + } else { + list{String.sub(str, 0, last_pos), ...acc} + } + } else if is_delim(String.get(str, pos)) { + let new_len = last_pos - pos - 1 + if new_len != 0 || keep_empty { + let v = String.sub(str, pos + 1, new_len) + loop(list{v, ...acc}, pos, pos - 1) + } else { + loop(acc, pos, pos - 1) + } + } else { + loop(acc, last_pos, pos - 1) + } + loop(list{}, len, len - 1) + } + let fail = (text, pos, message) => { + let pre = String.sub(text, 0, pos) + let lines = split_by(c => c == '\n', pre) + let count = List.length(lines) + let last = count > 0 ? List.getExn(lines, count - 1) : "" + let col = String.length(last) + 1 + let line = List.length(lines) + let string = Printf.sprintf("Error \"%s\" at %d:%d -> %s\n", message, line, col, last) + failwith(string) + } + let rec skipToNewline = (text, pos) => + if pos >= String.length(text) { + pos + } else if String.get(text, pos) == '\n' { + pos + 1 + } else { + skipToNewline(text, pos + 1) + } + let stringTail = text => { + let len = String.length(text) + if len > 1 { + String.sub(text, 1, len - 1) + } else { + "" + } + } + let rec skipToCloseMultilineComment = (text, pos) => + if pos + 1 >= String.length(text) { + failwith("Unterminated comment") + } else if String.get(text, pos) == '*' && String.get(text, pos + 1) == '/' { + pos + 2 + } else { + skipToCloseMultilineComment(text, pos + 1) + } + let rec skipWhite = (text, pos) => + if ( + pos < String.length(text) && + (String.get(text, pos) == ' ' || + (String.get(text, pos) == '\t' || + (String.get(text, pos) == '\n' || String.get(text, pos) == '\r'))) + ) { + skipWhite(text, pos + 1) + } else { + pos + } + let parseString = (text, pos) => { + /* let i = ref(pos); */ + let buffer = Buffer.create(String.length(text)) + let ln = String.length(text) + let rec loop = i => + i >= ln + ? fail(text, i, "Unterminated string") + : switch String.get(text, i) { + | '"' => i + 1 + | '\\' => + i + 1 >= ln + ? fail(text, i, "Unterminated string") + : switch String.get(text, i + 1) { + | '/' => + Buffer.add_char(buffer, '/') + loop(i + 2) + | 'f' => + Buffer.add_char(buffer, '\012') + loop(i + 2) + | _ => + Buffer.add_string(buffer, Scanf.unescaped(String.sub(text, i, 2))) + loop(i + 2) + } + | c => + Buffer.add_char(buffer, c) + loop(i + 1) + } + let final = loop(pos) + (Buffer.contents(buffer), final) + } + let parseDigits = (text, pos) => { + let len = String.length(text) + let rec loop = i => + if i >= len { + i + } else { + switch String.get(text, i) { + | '0' .. '9' => loop(i + 1) + | _ => i + } + } + loop(pos + 1) + } + let parseWithDecimal = (text, pos) => { + let pos = parseDigits(text, pos) + if pos < String.length(text) && String.get(text, pos) == '.' { + let pos = parseDigits(text, pos + 1) + pos + } else { + pos + } + } + let parseNumber = (text, pos) => { + let pos = parseWithDecimal(text, pos) + let ln = String.length(text) + if pos < ln - 1 && (String.get(text, pos) == 'E' || String.get(text, pos) == 'e') { + let pos = switch String.get(text, pos + 1) { + | '-' + | '+' => + pos + 2 + | _ => pos + 1 + } + parseDigits(text, pos) + } else { + pos + } + } + let parseNegativeNumber = (text, pos) => { + let final = if String.get(text, pos) == '-' { + parseNumber(text, pos + 1) + } else { + parseNumber(text, pos) + } + (Number(float_of_string(String.sub(text, pos, final - pos))), final) + } + let expect = (char, text, pos, message) => + if String.get(text, pos) != char { + fail(text, pos, "Expected: " ++ message) + } else { + pos + 1 + } + let parseComment: 'a. (string, int, (string, int) => 'a) => 'a = (text, pos, next) => + if String.get(text, pos) != '/' { + if String.get(text, pos) == '*' { + next(text, skipToCloseMultilineComment(text, pos + 1)) + } else { + failwith("Invalid syntax") + } + } else { + next(text, skipToNewline(text, pos + 1)) + } + let maybeSkipComment = (text, pos) => + if pos < String.length(text) && String.get(text, pos) == '/' { + if pos + 1 < String.length(text) && String.get(text, pos + 1) == '/' { + skipToNewline(text, pos + 1) + } else if pos + 1 < String.length(text) && String.get(text, pos + 1) == '*' { + skipToCloseMultilineComment(text, pos + 1) + } else { + fail(text, pos, "Invalid synatx") + } + } else { + pos + } + let rec skip = (text, pos) => + if pos == String.length(text) { + pos + } else { + let n = skipWhite(text, pos) |> maybeSkipComment(text) + if n > pos { + skip(text, n) + } else { + n + } + } + let rec parse = (text, pos) => + if pos >= String.length(text) { + fail(text, pos, "Reached end of file without being done parsing") + } else { + switch String.get(text, pos) { + | '/' => parseComment(text, pos + 1, parse) + | '[' => parseArray(text, pos + 1) + | '{' => parseObject(text, pos + 1) + | 'n' => + if String.sub(text, pos, 4) == "null" { + (Null, pos + 4) + } else { + fail(text, pos, "unexpected character") + } + | 't' => + if String.sub(text, pos, 4) == "true" { + (True, pos + 4) + } else { + fail(text, pos, "unexpected character") + } + | 'f' => + if String.sub(text, pos, 5) == "false" { + (False, pos + 5) + } else { + fail(text, pos, "unexpected character") + } + | '\n' + | '\t' + | ' ' + | '\r' => + parse(text, skipWhite(text, pos)) + | '"' => + let (s, pos) = parseString(text, pos + 1) + (String(s), pos) + | '-' + | '0' .. '9' => + parseNegativeNumber(text, pos) + | _ => fail(text, pos, "unexpected character") + } + } + and parseArrayValue = (text, pos) => { + let pos = skip(text, pos) + let (value, pos) = parse(text, pos) + let pos = skip(text, pos) + switch String.get(text, pos) { + | ',' => + let pos = skip(text, pos + 1) + if String.get(text, pos) == ']' { + (list{value}, pos + 1) + } else { + let (rest, pos) = parseArrayValue(text, pos) + (list{value, ...rest}, pos) + } + | ']' => (list{value}, pos + 1) + | _ => fail(text, pos, "unexpected character") + } + } + and parseArray = (text, pos) => { + let pos = skip(text, pos) + switch String.get(text, pos) { + | ']' => (Array(list{}), pos + 1) + | _ => + let (items, pos) = parseArrayValue(text, pos) + (Array(items), pos) + } + } + and parseObjectValue = (text, pos) => { + let pos = skip(text, pos) + if String.get(text, pos) != '"' { + fail(text, pos, "Expected string") + } else { + let (key, pos) = parseString(text, pos + 1) + let pos = skip(text, pos) + let pos = expect(':', text, pos, "Colon") + let (value, pos) = parse(text, pos) + let pos = skip(text, pos) + switch String.get(text, pos) { + | ',' => + let pos = skip(text, pos + 1) + if String.get(text, pos) == '}' { + (list{(key, value)}, pos + 1) + } else { + let (rest, pos) = parseObjectValue(text, pos) + (list{(key, value), ...rest}, pos) + } + | '}' => (list{(key, value)}, pos + 1) + | _ => + let (rest, pos) = parseObjectValue(text, pos) + (list{(key, value), ...rest}, pos) + } + } + } + and parseObject = (text, pos) => { + let pos = skip(text, pos) + if String.get(text, pos) == '}' { + (Object(list{}), pos + 1) + } else { + let (pairs, pos) = parseObjectValue(text, pos) + (Object(pairs), pos) + } + } +} + +@ocaml.doc(" Turns some text into a json object. throws on failure ") +let parse = text => { + let (item, pos) = Parser.parse(text, 0) + let pos = Parser.skip(text, pos) + if pos < String.length(text) { + failwith( + "Extra data after parse finished: " ++ String.sub(text, pos, String.length(text) - pos), + ) + } else { + item + } +} + +/* Accessor helpers */ +let bind = (v, fn) => + switch v { + | None => None + | Some(v) => fn(v) + } + +@ocaml.doc(" If `t` is an object, get the value associated with the given string key ") +let get = (key, t) => + switch t { + | Object(items) => List.getAssoc(items, key, \"=") + | _ => None + } + +@ocaml.doc(" If `t` is an array, get the value associated with the given index ") +let nth = (n, t) => + switch t { + | Array(items) => + if n < List.length(items) { + Some(List.getExn(items, n)) + } else { + None + } + | _ => None + } + +let string = t => + switch t { + | String(s) => Some(s) + | _ => None + } + +let number = t => + switch t { + | Number(s) => Some(s) + | _ => None + } + +let array = t => + switch t { + | Array(s) => Some(s) + | _ => None + } + +let obj = t => + switch t { + | Object(s) => Some(s) + | _ => None + } + +let bool = t => + switch t { + | True => Some(true) + | False => Some(false) + | _ => None + } + +let null = t => + switch t { + | Null => Some() + | _ => None + } + +let rec parsePath = (keyList, t) => + switch keyList { + | list{} => Some(t) + | list{head, ...rest} => + switch get(head, t) { + | None => None + | Some(value) => parsePath(rest, value) + } + } + +@ocaml.doc(" Get a deeply nested value from an object `t`. + * ``` + * open Json.Infix; + * let json = Json.parse({|{\"a\": {\"b\": {\"c\": 2}}}|}); + * let num = Json.getPath(\"a.b.c\", json) |?> Json.number; + * assert(num == Some(2.)) + * ``` + ") +let getPath = (path, t) => { + let keys = Parser.split_by(c => c == '.', path) + parsePath(keys, t) +} + diff --git a/analysis/examples/example-project/src/ModuleWithDocComment.res b/analysis/examples/example-project/src/ModuleWithDocComment.res new file mode 100644 index 0000000000..a09e2692f9 --- /dev/null +++ b/analysis/examples/example-project/src/ModuleWithDocComment.res @@ -0,0 +1,13 @@ +@@ocaml.doc("This comment is for the **toplevel** module.") + +@ocaml.doc("This comment is for the first **nested** module.") +module Nested = { + let x = "123" + + @ocaml.doc("This comment is for the inner **nested-again** module.") + module NestedAgain = { + let y = 123 + } +} + +module M = Nested.NestedAgain diff --git a/analysis/examples/example-project/src/More.res b/analysis/examples/example-project/src/More.res new file mode 100644 index 0000000000..a1775e21ae --- /dev/null +++ b/analysis/examples/example-project/src/More.res @@ -0,0 +1,13 @@ +@@ocaml.doc(" Toplevel docs ") + +@ocaml.doc(" Some contents ") +let contnets = "here" + +let inner = 20 + +let n = 10 + +let party = 30 + +let awesome = 200 + diff --git a/analysis/examples/example-project/src/More.resi b/analysis/examples/example-project/src/More.resi new file mode 100644 index 0000000000..023a7222cb --- /dev/null +++ b/analysis/examples/example-project/src/More.resi @@ -0,0 +1,5 @@ +let contnets: string +let inner: int +let n: int +let party: int + diff --git a/analysis/examples/example-project/src/Other.res b/analysis/examples/example-project/src/Other.res new file mode 100644 index 0000000000..d7a5bf4329 --- /dev/null +++ b/analysis/examples/example-project/src/Other.res @@ -0,0 +1,30 @@ +/* let later = 10; */ + +/* Ok testing things */ + +let something = 10 + +type person = {name: string, age: int} + +type animals = Things(int) | People(string) | Mouse + +let inner = 10 +/* More.outer; */ + +let m = Things(1) + +/* working on things. */ + +let z = {name: "hi", age: 20} + +let later = 20 + +let concat = (~first, ~second) => first + second + +type other = {person: person, height: float} +let oo = {person: z, height: 34.2} + +let show = o => { + let m = o.height +} + diff --git a/analysis/examples/example-project/src/Serde.res b/analysis/examples/example-project/src/Serde.res new file mode 100644 index 0000000000..1c516c2100 --- /dev/null +++ b/analysis/examples/example-project/src/Serde.res @@ -0,0 +1,222 @@ +let rec deserialize_Hello__TryIt____lockfile: Json.t => Belt.Result.t< + MyNamespace.Hello.lockfile, + string, +> = record => + switch record { + | Json.Object(items) => + switch Belt.List.getAssoc(items, "current", \"=") { + | None => Belt.Result.Error(@reason.raw_literal("No attribute ") "No attribute " ++ "current") + | Some(json) => + switch ( + list => + switch list { + | Json.Array(items) => + let transformer = json => + switch json { + | Json.Array(list{arg0, arg1}) => + switch ( + number => + switch number { + | Json.Number(number) => Belt.Result.Ok(int_of_float(number)) + | _ => Error(@reason.raw_literal("Expected a float") "Expected a float") + } + )(arg1) { + | Belt.Result.Ok(arg1) => + switch deserialize_Hello__TryIt____shortReference(arg0) { + | Belt.Result.Ok(arg0) => Belt.Result.Ok(arg0, arg1) + | Error(error) => Error(error) + } + | Error(error) => Error(error) + } + | _ => Belt.Result.Error(@reason.raw_literal("Expected array") "Expected array") + } + let rec loop = items => + switch items { + | list{} => Belt.Result.Ok(list{}) + | list{one, ...rest} => + switch transformer(one) { + | Belt.Result.Error(error) => Belt.Result.Error(error) + | Belt.Result.Ok(value) => + switch loop(rest) { + | Belt.Result.Error(error) => Belt.Result.Error(error) + | Belt.Result.Ok(rest) => Belt.Result.Ok(list{value, ...rest}) + } + } + } + loop(items) + | _ => Belt.Result.Error(@reason.raw_literal("expected an array") "expected an array") + } + )(json) { + | Belt.Result.Error(error) => Belt.Result.Error(error) + | Belt.Result.Ok(attr_current) => + switch Belt.List.getAssoc(items, "pastVersions", \"=") { + | None => + Belt.Result.Error(@reason.raw_literal("No attribute ") "No attribute " ++ "pastVersions") + | Some(json) => + switch deserialize_Belt_HashMapInt____t(list => + switch list { + | Json.Array(items) => + let transformer = json => + switch json { + | Json.Array(list{arg0, arg1}) => + switch ( + number => + switch number { + | Json.Number(number) => Belt.Result.Ok(int_of_float(number)) + | _ => Error(@reason.raw_literal("Expected a float") "Expected a float") + } + )(arg1) { + | Belt.Result.Ok(arg1) => + switch deserialize_Hello__TryIt____shortReference(arg0) { + | Belt.Result.Ok(arg0) => Belt.Result.Ok(arg0, arg1) + | Error(error) => Error(error) + } + | Error(error) => Error(error) + } + | _ => Belt.Result.Error(@reason.raw_literal("Expected array") "Expected array") + } + let rec loop = items => + switch items { + | list{} => Belt.Result.Ok(list{}) + | list{one, ...rest} => + switch transformer(one) { + | Belt.Result.Error(error) => Belt.Result.Error(error) + | Belt.Result.Ok(value) => + switch loop(rest) { + | Belt.Result.Error(error) => Belt.Result.Error(error) + | Belt.Result.Ok(rest) => Belt.Result.Ok(list{value, ...rest}) + } + } + } + loop(items) + | _ => Belt.Result.Error(@reason.raw_literal("expected an array") "expected an array") + } + )(json) { + | Belt.Result.Error(error) => Belt.Result.Error(error) + | Belt.Result.Ok(attr_pastVersions) => + switch Belt.List.getAssoc(items, "version", \"=") { + | None => + Belt.Result.Error(@reason.raw_literal("No attribute ") "No attribute " ++ "version") + | Some(json) => + switch ( + number => + switch number { + | Json.Number(number) => Belt.Result.Ok(int_of_float(number)) + | _ => Error(@reason.raw_literal("Expected a float") "Expected a float") + } + )(json) { + | Belt.Result.Error(error) => Belt.Result.Error(error) + | Belt.Result.Ok(attr_version) => + Belt.Result.Ok({ + version: attr_version, + pastVersions: attr_pastVersions, + current: attr_current, + }) + } + } + } + } + } + } + | _ => Belt.Result.Error(@reason.raw_literal("Expected an object") "Expected an object") + } +and deserialize_Hello__TryIt____shortReference: Json.t => Belt.Result.t< + MyNamespace.Hello.shortReference, + string, +> = value => + ( + json => + switch json { + | Json.Array(list{arg0, arg1, arg2}) => + switch ( + string => + switch string { + | Json.String(string) => Belt.Result.Ok(string) + | _ => Error(@reason.raw_literal("epected a string") "epected a string") + } + )(arg2) { + | Belt.Result.Ok(arg2) => + switch ( + list => + switch list { + | Json.Array(items) => + let transformer = string => + switch string { + | Json.String(string) => Belt.Result.Ok(string) + | _ => Error(@reason.raw_literal("epected a string") "epected a string") + } + let rec loop = items => + switch items { + | list{} => Belt.Result.Ok(list{}) + | list{one, ...rest} => + switch transformer(one) { + | Belt.Result.Error(error) => Belt.Result.Error(error) + | Belt.Result.Ok(value) => + switch loop(rest) { + | Belt.Result.Error(error) => Belt.Result.Error(error) + | Belt.Result.Ok(rest) => Belt.Result.Ok(list{value, ...rest}) + } + } + } + loop(items) + | _ => Belt.Result.Error(@reason.raw_literal("expected an array") "expected an array") + } + )(arg1) { + | Belt.Result.Ok(arg1) => + switch ( + string => + switch string { + | Json.String(string) => Belt.Result.Ok(string) + | _ => Error(@reason.raw_literal("epected a string") "epected a string") + } + )(arg0) { + | Belt.Result.Ok(arg0) => Belt.Result.Ok(arg0, arg1, arg2) + | Error(error) => Error(error) + } + | Error(error) => Error(error) + } + | Error(error) => Error(error) + } + | _ => Belt.Result.Error(@reason.raw_literal("Expected array") "Expected array") + } + )(value) +and deserialize_Belt_HashMapInt____t: 'arg0. ( + Json.t => Belt.Result.t<'arg0, string>, + Json.t, +) => Belt.Result.t, string> = bTransformer => + TransformHelpers.deserialize_Belt_HashMapInt____t(bTransformer) +let rec serialize_Hello__TryIt____lockfile: MyNamespace.Hello.lockfile => Json.t = record => Json.Object(list{ + ("version", (i => Json.Number(float_of_int(i)))(record.version)), + ( + "pastVersions", + serialize_Belt_HashMapInt____t(list => Json.Array( + Belt.List.map(list, ((arg0, arg1)) => Json.Array(list{ + serialize_Hello__TryIt____shortReference(arg0), + (i => Json.Number(float_of_int(i)))(arg1), + })), + ))(record.pastVersions), + ), + ( + "current", + ( + list => Json.Array( + Belt.List.map(list, ((arg0, arg1)) => Json.Array(list{ + serialize_Hello__TryIt____shortReference(arg0), + (i => Json.Number(float_of_int(i)))(arg1), + })), + ) + )(record.current), + ), +}) +and serialize_Hello__TryIt____shortReference: MyNamespace.Hello.shortReference => Json.t = value => + ( + ((arg0, arg1, arg2)) => Json.Array(list{ + (s => Json.String(s))(arg0), + (list => Json.Array(Belt.List.map(list, s => Json.String(s))))(arg1), + (s => Json.String(s))(arg2), + }) + )(value) +and serialize_Belt_HashMapInt____t: 'arg0. ( + 'arg0 => Json.t, + Belt_HashMapInt.t<'arg0>, +) => Json.t = bTransformer => TransformHelpers.serialize_Belt_HashMapInt____t(bTransformer) diff --git a/analysis/examples/example-project/src/TransformHelpers.res b/analysis/examples/example-project/src/TransformHelpers.res new file mode 100644 index 0000000000..b0ab646850 --- /dev/null +++ b/analysis/examples/example-project/src/TransformHelpers.res @@ -0,0 +1,12 @@ +let deserialize_Belt__HashMapInt__t = (transformer, t) => assert false + +let deserialize_Belt_HashMapInt____t = (a, b) => assert false + +let deserialize_Belt__HashMap__Int__t = (a, b) => assert false + +let serialize_Belt_HashMapInt____t = (a, b) => assert false + +let serialize_Belt__HashMap__Int__t = (a, b) => assert false + +let serialize_Belt_HashMapInt____t = (transformer, t) => assert false + diff --git a/analysis/examples/example-project/src/ZZ.res b/analysis/examples/example-project/src/ZZ.res new file mode 100644 index 0000000000..6a3c9ddcd5 --- /dev/null +++ b/analysis/examples/example-project/src/ZZ.res @@ -0,0 +1,145 @@ +let a = 12 + +let b = [1, 2, 3, a] + +let c =
+ +let s = React.string + +module M = { + @react.component + let make = (~x) => React.string(x) +} + +let d = + +module J = { + @react.component + export make = (~children: React.element) => React.null +} + +let z = {React.string("")} {React.string("")} + +type inline = + | A({x: int, y: string}) + | B({x: int, y: string}) + | C({ + x: int, + y: string, + z: string, + w: string, + x0: string, + q1: string, + q2: string, + q3: string, + q4: string, + }) + | D({x: int, y: string}) + | E({x: int, y: string}) + | F + +module MSig: { + type rec t = A(list) + and s = list + + let x: int +} = { + type rec t = A(list) + and s = list + + let x = 14 +} + +module Impl = { + type rec t = A(list) + and s = list + + type w = int + + let x = 14 +} + +module Impl2 = { + include Impl +} + +module D = MSig +module E = Impl +module F = Impl2 + +@ocaml.doc("str docstring") +type str = string + +@ocaml.doc("gr docstring") +type gr = {x: int, s: str} + +let testRecordFields = (gr: gr) => { + let str = gr.s + str +} + +@ocaml.doc("vr docstring") +type vr = V1 | V2 + +let v1 = V1 + +module DoubleNested = ModuleWithDocComment.Nested.NestedAgain + +let uncurried = (. x) => x + 1 + +module Inner = { + type tInner = int + let vInner = 34 +} + +type typeInner = Inner.tInner + +let valueInner = Inner.vInner + +@ocaml.doc("Doc comment for functionWithTypeAnnotation") +let functionWithTypeAnnotation: unit => int = () => 1 + +module HoverInsideModuleWithComponent = { + let x = 2 // check that hover on x works + + @react.component + let make = () => React.null +} + +module Lib = { + let foo = (~age, ~name) => name ++ string_of_int(age) + let next = (~number=0, ~year) => number + year +} + +@ocaml.doc("This module is commented") @deprecated("This module is deprecated") +module Dep: { + @ocaml.doc("Some doc comment") @deprecated("Use customDouble instead") + let customDouble: int => int + + let customDouble2: int => int +} = { + let customDouble = foo => foo * 2 + let customDouble2 = foo => foo * 2 +} + +let cc = Dep.customDouble(11) + +module O = { + module Comp = { + @react.component + let make = (~first="", ~kas=11, ~foo=3, ~second, ~v) => + React.string(first ++ second ++ string_of_int(foo)) + } +} + +let comp = + +let lll = List.make(3, 4) + +let abc = "abc" + +let arr = [1, 2, 3] + +let some7 = Some(7) + + diff --git a/analysis/examples/example-project/src/syntax/sample-highlighting.res b/analysis/examples/example-project/src/syntax/sample-highlighting.res new file mode 100644 index 0000000000..3d8930c31e --- /dev/null +++ b/analysis/examples/example-project/src/syntax/sample-highlighting.res @@ -0,0 +1,77 @@ +// Bindings +let numberBinding = 123 + +let someFunction = (param: int): int => { + let innerBinding = param + 2 + innerBinding +} + +// Types +type someRecord<'typeParameter> = { + someField: int, + someOtherField: string, + theParam: typeParameter, + another: bool, + to: string, +} + +type someEnum = + | SomeMember + | AnotherMember + | SomeMemberWithPayload(someRecord) + +type somePolyEnum = [ + | #someMember + | #AnotherMember + | #SomeMemberWithPayload(someRecord) + | #"fourth Member" +] + +// Destructuring +let destructuring = () => { + let someVar = (1, 2, 3) + let (one, two, three) = someVar + let someObj: someRecord = { + someField: 1, + someOtherField: "hello", + theParam: 2, + another: true, + to: "123", + } + let {someField, someOtherField, theParam} = someObj + + someField +} + +module SomeModule = { + type t = Some | Value | Here +} + +// Strings +let interpolated = `${numberBinding} ${"123"}` + +// JSX +module SomeComponent = { + @react.component + let make = ( + ~someProp: int, + ~otherProp: string, + ~thirdProp: SomeModule.t, + ~fourth: somePolyEnum=#"fourth member", + ) => { + React.null + } + + module Nested = { + @react.component + let make = (~children) => { + <> {children} + } + } +} + +let jsx = +
+ + {React.string("Nested")} +
diff --git a/analysis/examples/example-project/src/syntax/sample-highlighting.rs b/analysis/examples/example-project/src/syntax/sample-highlighting.rs new file mode 100644 index 0000000000..7131ba6008 --- /dev/null +++ b/analysis/examples/example-project/src/syntax/sample-highlighting.rs @@ -0,0 +1,31 @@ +// Bindings +fn some_function(param: usize) -> usize { + let innerBinding = param + 2; + innerBinding +} + +// Types +struct someRecord { + someField: usize, + someOtherField: String, + theParam: typeParameter, +} + +enum someEnum { + SomeMember, + AnotherMember, + SomeMemberWithPayload(someRecord), +} + +// Destructuring +fn destructuring() -> usize { + let someVar = (1, 2, 3); + let (one, two, three) = someVar; + let someObj = someRecord:: { + someField: 1, + someOtherField: String::new("HEllo"), + theParam: 2, + }; + + someObj.someField +} diff --git a/analysis/examples/example-project/src/syntax/sample-highlighting.tsx b/analysis/examples/example-project/src/syntax/sample-highlighting.tsx new file mode 100644 index 0000000000..b646a4cfb1 --- /dev/null +++ b/analysis/examples/example-project/src/syntax/sample-highlighting.tsx @@ -0,0 +1,94 @@ +// Bindings +let numberBinding = 123; + +const SomeComp = { + Nested: () => null, +}; + +let someFunction = (param: number): number => { + let innerBinding = param + 2; + return innerBinding; +}; + +// Types +type someRecord = { + someField: number; + someOtherField: string; + theParam: typeParameter; + another: boolean; + to: string; +}; + +enum someEnum { + SomeMember, + AnotherMember, +} + +// Destructuring +let destructuring = () => { + let someVar = [1, 2, 3]; + let [one, two, three] = someVar; + let someObj: someRecord = { + someField: 1, + someOtherField: "hello", + theParam: 2, + another: true, + to: "123", + }; + let { someField, someOtherField, theParam } = someObj; + + return someField; +}; + +namespace SomeModule { + export enum t { + Some, + Value, + Here, + } +} + +// Decorators and classes +function someDecorator() { + return function ( + target: any, + propertyKey: string, + descriptor: PropertyDescriptor + ) { + console.log("first(): called"); + }; +} + +class SomeClass { + @someDecorator() doStuff() { + return 123; + } +} + +// Strings +let interpolated = `${numberBinding} ${"123"}`; + +// JSX +interface Props { + someProp: number; + otherProp: string; + thirdProp: SomeModule.t; +} +const SomeComponent = ({ someProp, otherProp, thirdProp }: Props) => { + return null; +}; + +let jsx = ( +
+ + + {"Hello"} +
+); +function Property() { + throw new Error("Function not implemented."); +} diff --git a/analysis/examples/example-project/types.json b/analysis/examples/example-project/types.json new file mode 100644 index 0000000000..904cdf616e --- /dev/null +++ b/analysis/examples/example-project/types.json @@ -0,0 +1,13 @@ +{ + "output": "src/Serde.ml", + "engine": "rex-json", + "entries": [ + { + "file": "src/Hello.re", + "type": "lockfile" + } + ], + "custom": [ + {"module": "Belt_HashMapInt", "path": [], "name": "t", "args": 1} + ] +} \ No newline at end of file diff --git a/analysis/examples/larger-project/.gitignore b/analysis/examples/larger-project/.gitignore new file mode 100644 index 0000000000..1ccc52a7fb --- /dev/null +++ b/analysis/examples/larger-project/.gitignore @@ -0,0 +1,2 @@ +/node_modules +/lib \ No newline at end of file diff --git a/analysis/examples/larger-project/.merlin b/analysis/examples/larger-project/.merlin new file mode 100644 index 0000000000..05434917e9 --- /dev/null +++ b/analysis/examples/larger-project/.merlin @@ -0,0 +1,14 @@ +####{BSB GENERATED: NO EDIT +FLG -ppx '/home/pedro/Desktop/Projects/rescript-vscode/analysis/examples/larger-project/node_modules/rescript/linux/bsc.exe -as-ppx -bs-jsx 3' +S /home/pedro/Desktop/Projects/rescript-vscode/analysis/examples/larger-project/node_modules/rescript/lib/ocaml +B /home/pedro/Desktop/Projects/rescript-vscode/analysis/examples/larger-project/node_modules/rescript/lib/ocaml +FLG -w +a-4-9-20-40-41-42-50-61-102 +S /home/pedro/Desktop/Projects/rescript-vscode/analysis/examples/larger-project/node_modules/@rescript/react/lib/ocaml +B /home/pedro/Desktop/Projects/rescript-vscode/analysis/examples/larger-project/node_modules/@rescript/react/lib/ocaml +S /home/pedro/Desktop/Projects/rescript-vscode/analysis/examples/larger-project/node_modules/@glennsl/bs-json/lib/ocaml +B /home/pedro/Desktop/Projects/rescript-vscode/analysis/examples/larger-project/node_modules/@glennsl/bs-json/lib/ocaml +S src +B lib/bs/src +S src/exception +B lib/bs/src/exception +####BSB GENERATED: NO EDIT} diff --git a/analysis/examples/larger-project/.watchmanconfig b/analysis/examples/larger-project/.watchmanconfig new file mode 100644 index 0000000000..e69de29bb2 diff --git a/analysis/examples/larger-project/bsconfig.json b/analysis/examples/larger-project/bsconfig.json new file mode 100644 index 0000000000..e3a2f6f551 --- /dev/null +++ b/analysis/examples/larger-project/bsconfig.json @@ -0,0 +1,21 @@ +{ + "reanalyze": { + "analysis": ["dce"], + "suppress": [], + "unsuppress": [] + }, + "name": "sample-typescript-app", + "bsc-flags": ["-bs-super-errors -w a"], + "reason": { "react-jsx": 3 }, + "bs-dependencies": ["@rescript/react", "@glennsl/bs-json"], + "sources": [ + { + "dir": "src", + "subdirs": true + } + ], + "package-specs": { + "module": "es6", + "in-source": true + } +} diff --git a/analysis/examples/larger-project/package-lock.json b/analysis/examples/larger-project/package-lock.json new file mode 100644 index 0000000000..8747db2f28 --- /dev/null +++ b/analysis/examples/larger-project/package-lock.json @@ -0,0 +1,192 @@ +{ + "name": "large-project", + "version": "0.1.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "large-project", + "version": "0.1.0", + "dependencies": { + "@glennsl/bs-json": "^5.0.4", + "@rescript/react": "^0.10.3" + }, + "devDependencies": { + "react": "^16.13.1", + "react-dom": "^16.8.6", + "rescript": "^9.1.4" + } + }, + "../../../../../rescript-compiler": { + "name": "rescript", + "version": "10.0.0", + "extraneous": true, + "hasInstallScript": true, + "license": "SEE LICENSE IN LICENSE", + "bin": { + "bsc": "bsc", + "bsrefmt": "bsrefmt", + "bstracing": "lib/bstracing", + "rescript": "rescript" + }, + "devDependencies": { + "mocha": "^7.2.0", + "nyc": "^15.0.0" + } + }, + "node_modules/@glennsl/bs-json": { + "version": "5.0.4", + "license": "(LGPL-3.0 OR MPL-2.0)" + }, + "node_modules/@rescript/react": { + "version": "0.10.3", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.1", + "react-dom": ">=16.8.1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/react": { + "version": "16.14.0", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "16.14.0", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.19.1" + }, + "peerDependencies": { + "react": "^16.14.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "license": "MIT" + }, + "node_modules/rescript": { + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/rescript/-/rescript-9.1.4.tgz", + "integrity": "sha512-aXANK4IqecJzdnDpJUsU6pxMViCR5ogAxzuqS0mOr8TloMnzAjJFu63fjD6LCkWrKAhlMkFFzQvVQYaAaVkFXw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "bsc": "bsc", + "bsrefmt": "bsrefmt", + "bstracing": "lib/bstracing", + "rescript": "rescript" + } + }, + "node_modules/scheduler": { + "version": "0.19.1", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + } + }, + "dependencies": { + "@glennsl/bs-json": { + "version": "5.0.4" + }, + "@rescript/react": { + "version": "0.10.3", + "requires": {} + }, + "js-tokens": { + "version": "4.0.0" + }, + "loose-envify": { + "version": "1.4.0", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "object-assign": { + "version": "4.1.1" + }, + "prop-types": { + "version": "15.8.1", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "react": { + "version": "16.14.0", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + } + }, + "react-dom": { + "version": "16.14.0", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.19.1" + } + }, + "react-is": { + "version": "16.13.1" + }, + "rescript": { + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/rescript/-/rescript-9.1.4.tgz", + "integrity": "sha512-aXANK4IqecJzdnDpJUsU6pxMViCR5ogAxzuqS0mOr8TloMnzAjJFu63fjD6LCkWrKAhlMkFFzQvVQYaAaVkFXw==", + "dev": true + }, + "scheduler": { + "version": "0.19.1", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + } + } +} diff --git a/analysis/examples/larger-project/package.json b/analysis/examples/larger-project/package.json new file mode 100644 index 0000000000..1426ee18c6 --- /dev/null +++ b/analysis/examples/larger-project/package.json @@ -0,0 +1,19 @@ +{ + "name": "large-project", + "version": "0.1.0", + "private": true, + "scripts": { + "start": "rescript build -w", + "build": "rescript build", + "clean": "rescript clean -with-deps" + }, + "devDependencies": { + "react": "^16.13.1", + "react-dom": "^16.8.6", + "rescript": "^9.1.4" + }, + "dependencies": { + "@glennsl/bs-json": "^5.0.4", + "@rescript/react": "^0.10.3" + } +} diff --git a/analysis/examples/larger-project/src/AutoAnnotate.js b/analysis/examples/larger-project/src/AutoAnnotate.js new file mode 100644 index 0000000000..d856702bfe --- /dev/null +++ b/analysis/examples/larger-project/src/AutoAnnotate.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/analysis/examples/larger-project/src/AutoAnnotate.res b/analysis/examples/larger-project/src/AutoAnnotate.res new file mode 100644 index 0000000000..71f125728a --- /dev/null +++ b/analysis/examples/larger-project/src/AutoAnnotate.res @@ -0,0 +1,15 @@ +type variant = R(int) + +@genType +type record = {variant: variant} + +type r2 = {r2: int} + +type r3 = {r3: int} + +type r4 = {r4: int} + +@genType +type annotatedVariant = + | R2(r2, r3) + | R4(r4) diff --git a/analysis/examples/larger-project/src/BootloaderResource.js b/analysis/examples/larger-project/src/BootloaderResource.js new file mode 100644 index 0000000000..d856702bfe --- /dev/null +++ b/analysis/examples/larger-project/src/BootloaderResource.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/analysis/examples/larger-project/src/BootloaderResource.res b/analysis/examples/larger-project/src/BootloaderResource.res new file mode 100644 index 0000000000..a215607645 --- /dev/null +++ b/analysis/examples/larger-project/src/BootloaderResource.res @@ -0,0 +1,4 @@ +/* NOTE: This is a spooky interface that provides no type safety. It should be + * improved. Use with caution. */ +@module("BootloaderResource") +external read: JSResource.t<'a> => 'a = "read" diff --git a/analysis/examples/larger-project/src/BucklescriptAnnotations.js b/analysis/examples/larger-project/src/BucklescriptAnnotations.js new file mode 100644 index 0000000000..7dab449cd0 --- /dev/null +++ b/analysis/examples/larger-project/src/BucklescriptAnnotations.js @@ -0,0 +1,13 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function bar(x) { + var f = x.twoArgs; + return f(3, "a"); +} + +export { + bar , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/BucklescriptAnnotations.res b/analysis/examples/larger-project/src/BucklescriptAnnotations.res new file mode 100644 index 0000000000..053bca66b0 --- /dev/null +++ b/analysis/examples/larger-project/src/BucklescriptAnnotations.res @@ -0,0 +1,28 @@ +@genType +type someMutableFields = { + @set + "mutable0": string, + "immutable": int, + @set + "mutable1": string, + @set + "mutable2": string, +} + +@genType +type someMethods = { + @meth + "send": string => unit, + @meth + "on": (string, (. int) => unit) => unit, + @meth + "threeargs": (int, string, int) => string, + "twoArgs": (. int, string) => int, +} + +// let foo = (x: someMethods) => x["threeargs"](3, "a", 4) + +let bar = (x: someMethods) => { + let f = x["twoArgs"] + f(. 3, "a") +} diff --git a/analysis/examples/larger-project/src/ComponentAsProp.js b/analysis/examples/larger-project/src/ComponentAsProp.js new file mode 100644 index 0000000000..f3eba08a72 --- /dev/null +++ b/analysis/examples/larger-project/src/ComponentAsProp.js @@ -0,0 +1,19 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as React from "react"; +import * as Caml_option from "rescript/lib/es6/caml_option.js"; + +function ComponentAsProp(Props) { + var title = Props.title; + var description = Props.description; + var button = Props.button; + return React.createElement("div", undefined, React.createElement("div", undefined, title, description, button !== undefined ? Caml_option.valFromOption(button) : null)); +} + +var make = ComponentAsProp; + +export { + make , + +} +/* react Not a pure module */ diff --git a/analysis/examples/larger-project/src/ComponentAsProp.res b/analysis/examples/larger-project/src/ComponentAsProp.res new file mode 100644 index 0000000000..a1f3d45658 --- /dev/null +++ b/analysis/examples/larger-project/src/ComponentAsProp.res @@ -0,0 +1,17 @@ +@ocaml.doc( + " This is like declaring a normal ReasonReact component's `make` function, except the body is a the interop hook wrapJsForReason " +) +@genType +@react.component +let make = (~title, ~description, ~button=?) => { +
+
+ title + description + {switch button { + | Some(button) => button + | None => React.null + }} +
+
+} diff --git a/analysis/examples/larger-project/src/CreateErrorHandler1.js b/analysis/examples/larger-project/src/CreateErrorHandler1.js new file mode 100644 index 0000000000..6adeaad3fe --- /dev/null +++ b/analysis/examples/larger-project/src/CreateErrorHandler1.js @@ -0,0 +1,26 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Curry from "rescript/lib/es6/curry.js"; +import * as ErrorHandler from "./ErrorHandler.js"; + +function notification(s) { + return [ + s, + s + ]; +} + +var Error1 = { + notification: notification +}; + +var MyErrorHandler = ErrorHandler.Make(Error1); + +Curry._1(MyErrorHandler.notify, "abc"); + +export { + Error1 , + MyErrorHandler , + +} +/* MyErrorHandler Not a pure module */ diff --git a/analysis/examples/larger-project/src/CreateErrorHandler1.res b/analysis/examples/larger-project/src/CreateErrorHandler1.res new file mode 100644 index 0000000000..e10b58c1d3 --- /dev/null +++ b/analysis/examples/larger-project/src/CreateErrorHandler1.res @@ -0,0 +1,8 @@ +module Error1 = { + type t = string + let notification = s => (s, s) +} + +module MyErrorHandler = ErrorHandler.Make(Error1) + +MyErrorHandler.notify("abc") diff --git a/analysis/examples/larger-project/src/CreateErrorHandler2.js b/analysis/examples/larger-project/src/CreateErrorHandler2.js new file mode 100644 index 0000000000..6855cbd830 --- /dev/null +++ b/analysis/examples/larger-project/src/CreateErrorHandler2.js @@ -0,0 +1,23 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as ErrorHandler from "./ErrorHandler.js"; + +function notification(n) { + return [ + String(n), + "" + ]; +} + +var Error2 = { + notification: notification +}; + +var MyErrorHandler = ErrorHandler.Make(Error2); + +export { + Error2 , + MyErrorHandler , + +} +/* MyErrorHandler Not a pure module */ diff --git a/analysis/examples/larger-project/src/CreateErrorHandler2.res b/analysis/examples/larger-project/src/CreateErrorHandler2.res new file mode 100644 index 0000000000..394907545e --- /dev/null +++ b/analysis/examples/larger-project/src/CreateErrorHandler2.res @@ -0,0 +1,6 @@ +module Error2 = { + type t = int + let notification = n => (string_of_int(n), "") +} + +module MyErrorHandler = ErrorHandler.Make(Error2) /* MyErrorHandler.notify(42) */ diff --git a/analysis/examples/larger-project/src/DeadCodeImplementation.js b/analysis/examples/larger-project/src/DeadCodeImplementation.js new file mode 100644 index 0000000000..457027834c --- /dev/null +++ b/analysis/examples/larger-project/src/DeadCodeImplementation.js @@ -0,0 +1,12 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +var M = { + x: 42 +}; + +export { + M , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/DeadCodeImplementation.res b/analysis/examples/larger-project/src/DeadCodeImplementation.res new file mode 100644 index 0000000000..54abe4eadf --- /dev/null +++ b/analysis/examples/larger-project/src/DeadCodeImplementation.res @@ -0,0 +1,3 @@ +module M: DeadCodeInterface.T = { + let x = 42 +} diff --git a/analysis/examples/larger-project/src/DeadCodeInterface.js b/analysis/examples/larger-project/src/DeadCodeInterface.js new file mode 100644 index 0000000000..d856702bfe --- /dev/null +++ b/analysis/examples/larger-project/src/DeadCodeInterface.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/analysis/examples/larger-project/src/DeadCodeInterface.res b/analysis/examples/larger-project/src/DeadCodeInterface.res new file mode 100644 index 0000000000..069bea77a0 --- /dev/null +++ b/analysis/examples/larger-project/src/DeadCodeInterface.res @@ -0,0 +1,3 @@ +module type T = { + let x: int +} diff --git a/analysis/examples/larger-project/src/DeadExn.js b/analysis/examples/larger-project/src/DeadExn.js new file mode 100644 index 0000000000..c2a21594d7 --- /dev/null +++ b/analysis/examples/larger-project/src/DeadExn.js @@ -0,0 +1,19 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Caml_exceptions from "rescript/lib/es6/caml_exceptions.js"; + +var Etoplevel = /* @__PURE__ */Caml_exceptions.create("DeadExn.Etoplevel"); + +var Einside = /* @__PURE__ */Caml_exceptions.create("DeadExn.Inside.Einside"); + +var eInside = { + RE_EXN_ID: Einside +}; + +console.log(eInside); + +export { + Etoplevel , + +} +/* Not a pure module */ diff --git a/analysis/examples/larger-project/src/DeadExn.res b/analysis/examples/larger-project/src/DeadExn.res new file mode 100644 index 0000000000..a515033a0d --- /dev/null +++ b/analysis/examples/larger-project/src/DeadExn.res @@ -0,0 +1,12 @@ +exception Etoplevel + +module Inside = { + exception Einside +} + +exception DeadE +let eToplevel = Etoplevel + +let eInside = Inside.Einside + +Js.log(eInside) diff --git a/analysis/examples/larger-project/src/DeadExn.resi b/analysis/examples/larger-project/src/DeadExn.resi new file mode 100644 index 0000000000..1686894210 --- /dev/null +++ b/analysis/examples/larger-project/src/DeadExn.resi @@ -0,0 +1,2 @@ +// empty +exception Etoplevel diff --git a/analysis/examples/larger-project/src/DeadRT.js b/analysis/examples/larger-project/src/DeadRT.js new file mode 100644 index 0000000000..028c363b5a --- /dev/null +++ b/analysis/examples/larger-project/src/DeadRT.js @@ -0,0 +1,9 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +console.log(/* Kaboom */0); + +export { + +} +/* Not a pure module */ diff --git a/analysis/examples/larger-project/src/DeadRT.res b/analysis/examples/larger-project/src/DeadRT.res new file mode 100644 index 0000000000..1ebbc4c32b --- /dev/null +++ b/analysis/examples/larger-project/src/DeadRT.res @@ -0,0 +1,11 @@ +type moduleAccessPath = + | Root(string) + | Kaboom + +let rec emitModuleAccessPath = moduleAccessPath => + switch moduleAccessPath { + | Root(s) => s + | Kaboom => "" + } + +let () = Js.log(Kaboom) diff --git a/analysis/examples/larger-project/src/DeadRT.resi b/analysis/examples/larger-project/src/DeadRT.resi new file mode 100644 index 0000000000..123cd38f6f --- /dev/null +++ b/analysis/examples/larger-project/src/DeadRT.resi @@ -0,0 +1,3 @@ +type moduleAccessPath = + | Root(string) + | Kaboom diff --git a/analysis/examples/larger-project/src/DeadTest.js b/analysis/examples/larger-project/src/DeadTest.js new file mode 100644 index 0000000000..d856702bfe --- /dev/null +++ b/analysis/examples/larger-project/src/DeadTest.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/analysis/examples/larger-project/src/DeadTest.res b/analysis/examples/larger-project/src/DeadTest.res new file mode 100644 index 0000000000..e69de29bb2 diff --git a/analysis/examples/larger-project/src/DeadTestBlacklist.js b/analysis/examples/larger-project/src/DeadTestBlacklist.js new file mode 100644 index 0000000000..9a29139bd4 --- /dev/null +++ b/analysis/examples/larger-project/src/DeadTestBlacklist.js @@ -0,0 +1,10 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +var x = 34; + +export { + x , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/DeadTestBlacklist.res b/analysis/examples/larger-project/src/DeadTestBlacklist.res new file mode 100644 index 0000000000..5681c08c62 --- /dev/null +++ b/analysis/examples/larger-project/src/DeadTestBlacklist.res @@ -0,0 +1 @@ +let x = 34 diff --git a/analysis/examples/larger-project/src/DeadTestWithInterface.js b/analysis/examples/larger-project/src/DeadTestWithInterface.js new file mode 100644 index 0000000000..d856702bfe --- /dev/null +++ b/analysis/examples/larger-project/src/DeadTestWithInterface.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/analysis/examples/larger-project/src/DeadTestWithInterface.res b/analysis/examples/larger-project/src/DeadTestWithInterface.res new file mode 100644 index 0000000000..4d50cd03fc --- /dev/null +++ b/analysis/examples/larger-project/src/DeadTestWithInterface.res @@ -0,0 +1,5 @@ +module Ext_buffer: { + let x: int +} = { + let x = 42 +} diff --git a/analysis/examples/larger-project/src/DeadTestWithInterface.resi b/analysis/examples/larger-project/src/DeadTestWithInterface.resi new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/analysis/examples/larger-project/src/DeadTestWithInterface.resi @@ -0,0 +1 @@ + diff --git a/analysis/examples/larger-project/src/DeadTypeTest.js b/analysis/examples/larger-project/src/DeadTypeTest.js new file mode 100644 index 0000000000..9740261e39 --- /dev/null +++ b/analysis/examples/larger-project/src/DeadTypeTest.js @@ -0,0 +1,10 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +var a = /* A */0; + +export { + a , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/DeadTypeTest.res b/analysis/examples/larger-project/src/DeadTypeTest.res new file mode 100644 index 0000000000..6b70da5546 --- /dev/null +++ b/analysis/examples/larger-project/src/DeadTypeTest.res @@ -0,0 +1,16 @@ +type t = + | A + | B +let a = A + +type deadType = + | OnlyInImplementation + | OnlyInInterface + | InBoth + | InNeither + +let _ = OnlyInImplementation +let _ = InBoth + +@live +type record = {x: int, y: string, z: float} diff --git a/analysis/examples/larger-project/src/DeadTypeTest.resi b/analysis/examples/larger-project/src/DeadTypeTest.resi new file mode 100644 index 0000000000..317bc02c14 --- /dev/null +++ b/analysis/examples/larger-project/src/DeadTypeTest.resi @@ -0,0 +1,10 @@ +type t = + | A + | B +let a: t + +type deadType = + | OnlyInImplementation + | OnlyInInterface + | InBoth + | InNeither diff --git a/analysis/examples/larger-project/src/DeadValueTest.js b/analysis/examples/larger-project/src/DeadValueTest.js new file mode 100644 index 0000000000..2b37b2ec1b --- /dev/null +++ b/analysis/examples/larger-project/src/DeadValueTest.js @@ -0,0 +1,13 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +var valueAlive = 1; + +var valueDead = 2; + +export { + valueAlive , + valueDead , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/DeadValueTest.res b/analysis/examples/larger-project/src/DeadValueTest.res new file mode 100644 index 0000000000..a3fd03b6fc --- /dev/null +++ b/analysis/examples/larger-project/src/DeadValueTest.res @@ -0,0 +1,21 @@ +let valueAlive = 1 +let valueDead = 2 + +let valueOnlyInImplementation = 3 + +@raises(Failure) +let rec subList = (b, e, l) => + switch l { + | list{} => failwith("subList") + | list{h, ...t} => + let tail = if e == 0 { + list{} + } else { + subList(b - 1, e - 1, t) + } + if b > 0 { + tail + } else { + list{h, ...tail} + } + } diff --git a/analysis/examples/larger-project/src/DeadValueTest.resi b/analysis/examples/larger-project/src/DeadValueTest.resi new file mode 100644 index 0000000000..4f6bb0cc2f --- /dev/null +++ b/analysis/examples/larger-project/src/DeadValueTest.resi @@ -0,0 +1,2 @@ +let valueAlive: int +let valueDead: int diff --git a/analysis/examples/larger-project/src/Docstrings.js b/analysis/examples/larger-project/src/Docstrings.js new file mode 100644 index 0000000000..e06b04eb77 --- /dev/null +++ b/analysis/examples/larger-project/src/Docstrings.js @@ -0,0 +1,100 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function signMessage(message, key) { + return message + String(key); +} + +function one(a) { + return a + 0 | 0; +} + +function two(a, b) { + return (a + b | 0) + 0 | 0; +} + +function tree(a, b, c) { + return ((a + b | 0) + c | 0) + 0 | 0; +} + +function oneU(a) { + return a + 0 | 0; +} + +function twoU(a, b) { + return (a + b | 0) + 0 | 0; +} + +function treeU(a, b, c) { + return ((a + b | 0) + c | 0) + 0 | 0; +} + +function useParam(param) { + return param + 34 | 0; +} + +function useParamU(param) { + return param + 34 | 0; +} + +function unnamed1(param) { + return 34; +} + +function unnamed1U(param) { + return 34; +} + +function unnamed2(param, param$1) { + return 34; +} + +function unnamed2U(param, param$1) { + return 34; +} + +function grouped(x, y, a, b, c, z) { + return ((((x + y | 0) + a | 0) + b | 0) + c | 0) + z | 0; +} + +function unitArgWithoutConversion(param) { + return "abc"; +} + +function unitArgWithoutConversionU() { + return "abc"; +} + +function unitArgWithConversion(param) { + return /* A */0; +} + +function unitArgWithConversionU() { + return /* A */0; +} + +var flat = 34; + +export { + flat , + signMessage , + one , + two , + tree , + oneU , + twoU , + treeU , + useParam , + useParamU , + unnamed1 , + unnamed1U , + unnamed2 , + unnamed2U , + grouped , + unitArgWithoutConversion , + unitArgWithoutConversionU , + unitArgWithConversion , + unitArgWithConversionU , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/Docstrings.res b/analysis/examples/larger-project/src/Docstrings.res new file mode 100644 index 0000000000..ca3d7ee035 --- /dev/null +++ b/analysis/examples/larger-project/src/Docstrings.res @@ -0,0 +1,67 @@ +@ocaml.doc(" hello ") @genType +let flat = 34 + +@ocaml.doc(" + * Sign a message with a key. + * + * @param message - A message to be signed + * @param key - The key with which to sign the message + * @returns A signed message + ") +@genType +let signMessage = (. message, key) => message ++ string_of_int(key) + +@genType +let one = a => a + 0 + +@genType +let two = (a, b) => a + b + 0 + +@genType +let tree = (a, b, c) => a + b + c + 0 + +@genType +let oneU = (. a) => a + 0 + +@genType +let twoU = (. a, b) => a + b + 0 + +@genType +let treeU = (. a, b, c) => a + b + c + 0 + +@genType +let useParam = param => param + 34 + +@genType +let useParamU = (. param) => param + 34 + +@genType +let unnamed1 = (_: int) => 34 + +@genType +let unnamed1U = (. _: int) => 34 + +@genType +let unnamed2 = (_: int, _: int) => 34 + +@genType +let unnamed2U = (. _: int, _: int) => 34 + +@genType +let grouped = (~x, ~y, a, b, c, ~z) => x + y + a + b + c + z + +@genType +let unitArgWithoutConversion = () => "abc" + +@genType +let unitArgWithoutConversionU = (. ()) => "abc" + +type t = + | A + | B + +@genType +let unitArgWithConversion = () => A + +@genType +let unitArgWithConversionU = (. ()) => A diff --git a/analysis/examples/larger-project/src/DynamicallyLoadedComponent.js b/analysis/examples/larger-project/src/DynamicallyLoadedComponent.js new file mode 100644 index 0000000000..984fa357b1 --- /dev/null +++ b/analysis/examples/larger-project/src/DynamicallyLoadedComponent.js @@ -0,0 +1,14 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function DynamicallyLoadedComponent(Props) { + return Props.s; +} + +var make = DynamicallyLoadedComponent; + +export { + make , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/DynamicallyLoadedComponent.res b/analysis/examples/larger-project/src/DynamicallyLoadedComponent.res new file mode 100644 index 0000000000..b7b93b52c1 --- /dev/null +++ b/analysis/examples/larger-project/src/DynamicallyLoadedComponent.res @@ -0,0 +1,2 @@ +@react.component +let make = (~s) => React.string(s) diff --git a/analysis/examples/larger-project/src/EmptyArray.js b/analysis/examples/larger-project/src/EmptyArray.js new file mode 100644 index 0000000000..6e55be63af --- /dev/null +++ b/analysis/examples/larger-project/src/EmptyArray.js @@ -0,0 +1,19 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as React from "react"; + +function EmptyArray$Z(Props) { + return React.createElement("br", undefined); +} + +var Z = { + make: EmptyArray$Z +}; + +React.createElement(EmptyArray$Z, {}); + +export { + Z , + +} +/* Not a pure module */ diff --git a/analysis/examples/larger-project/src/EmptyArray.res b/analysis/examples/larger-project/src/EmptyArray.res new file mode 100644 index 0000000000..9c44bd9a7b --- /dev/null +++ b/analysis/examples/larger-project/src/EmptyArray.res @@ -0,0 +1,10 @@ +// @@config({flags : ["-dsource"]}); + +module Z = { + @react.component + let make = () => { +
+ } +} + +let _ = diff --git a/analysis/examples/larger-project/src/ErrorHandler.js b/analysis/examples/larger-project/src/ErrorHandler.js new file mode 100644 index 0000000000..b79220461e --- /dev/null +++ b/analysis/examples/larger-project/src/ErrorHandler.js @@ -0,0 +1,21 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Curry from "rescript/lib/es6/curry.js"; + +function Make($$Error) { + var notify = function (x) { + return Curry._1($$Error.notification, x); + }; + return { + notify: notify + }; +} + +var x = 42; + +export { + Make , + x , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/ErrorHandler.res b/analysis/examples/larger-project/src/ErrorHandler.res new file mode 100644 index 0000000000..557272ca13 --- /dev/null +++ b/analysis/examples/larger-project/src/ErrorHandler.res @@ -0,0 +1,12 @@ +module type Error = { + type t + let notification: t => (string, string) +} + +module Make = (Error: Error) => { + let notify = x => Error.notification(x) +} + +// This is ignored as there's an interface file +@genType +let x = 42 diff --git a/analysis/examples/larger-project/src/ErrorHandler.resi b/analysis/examples/larger-project/src/ErrorHandler.resi new file mode 100644 index 0000000000..fac11f7511 --- /dev/null +++ b/analysis/examples/larger-project/src/ErrorHandler.resi @@ -0,0 +1,10 @@ +module type Error = { + type t + let notification: t => (string, string) +} +module Make: (Error: Error) => +{ + let notify: Error.t => (string, string) +} + +let x: int diff --git a/analysis/examples/larger-project/src/EverythingLiveHere.js b/analysis/examples/larger-project/src/EverythingLiveHere.js new file mode 100644 index 0000000000..864f5020ec --- /dev/null +++ b/analysis/examples/larger-project/src/EverythingLiveHere.js @@ -0,0 +1,16 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +var x = 1; + +var y = 3; + +var z = 4; + +export { + x , + y , + z , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/EverythingLiveHere.res b/analysis/examples/larger-project/src/EverythingLiveHere.res new file mode 100644 index 0000000000..86ff46d5c9 --- /dev/null +++ b/analysis/examples/larger-project/src/EverythingLiveHere.res @@ -0,0 +1,5 @@ +let x = 1 + +let y = 3 + +let z = 4 diff --git a/analysis/examples/larger-project/src/FC.js b/analysis/examples/larger-project/src/FC.js new file mode 100644 index 0000000000..1beb8f4437 --- /dev/null +++ b/analysis/examples/larger-project/src/FC.js @@ -0,0 +1,14 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function foo(impl) { + return impl.make; +} + +console.log(foo); + +export { + foo , + +} +/* Not a pure module */ diff --git a/analysis/examples/larger-project/src/FC.res b/analysis/examples/larger-project/src/FC.res new file mode 100644 index 0000000000..6a55ba0a20 --- /dev/null +++ b/analysis/examples/larger-project/src/FC.res @@ -0,0 +1,11 @@ +module type ReplacebleComponent = { + @react.component + let make: unit => React.element +} + +let foo = (~impl: module(ReplacebleComponent)) => { + let module(X) = impl + X.make +} + +Js.log(foo) diff --git a/analysis/examples/larger-project/src/FirstClassModules.js b/analysis/examples/larger-project/src/FirstClassModules.js new file mode 100644 index 0000000000..d83705e55a --- /dev/null +++ b/analysis/examples/larger-project/src/FirstClassModules.js @@ -0,0 +1,69 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +var y = "abc"; + +var EmptyInnerModule = {}; + +var InnerModule2 = { + k: 4242 +}; + +function k3(x) { + return x + 1 | 0; +} + +var InnerModule3 = { + k3: k3 +}; + +var Z = { + u: [ + 0, + 0 + ] +}; + +var M = { + y: y, + EmptyInnerModule: EmptyInnerModule, + InnerModule2: InnerModule2, + InnerModule3: InnerModule3, + Z: Z, + x: 42 +}; + +var firstClassModule = { + x: 42, + EmptyInnerModule: EmptyInnerModule, + InnerModule2: InnerModule2, + InnerModule3: InnerModule3, + Z: Z, + y: y +}; + +function testConvert(m) { + return m; +} + +function SomeFunctor(X) { + return { + ww: X.y + }; +} + +function someFunctorAsFunction(x) { + return { + ww: x.y + }; +} + +export { + M , + firstClassModule , + testConvert , + SomeFunctor , + someFunctorAsFunction , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/FirstClassModules.res b/analysis/examples/larger-project/src/FirstClassModules.res new file mode 100644 index 0000000000..674d243e3a --- /dev/null +++ b/analysis/examples/larger-project/src/FirstClassModules.res @@ -0,0 +1,65 @@ +module type MT = { + let x: int + type t = int + @module("foo") external f: int => int = "f" + module type MT2 = { + type tt = string + } + module EmptyInnerModule: {} + module InnerModule2: { + let k: t + } + module InnerModule3: { + type inner = int + let k3: inner => inner + } + module type TT = { + let u: (int, int) + } + module Z: TT + let y: string +} +module M = { + let y = "abc" + module type MT2 = { + type tt = string + } + module EmptyInnerModule = {} + module InnerModule2 = { + let k = 4242 + } + module InnerModule3 = { + type inner = int + let k3 = x => x + 1 + } + + module type TT = { + let u: (int, int) + } + module Z = { + let u = (0, 0) + } + type t = int + @module("foo") external f: int => int = "f" + let x = 42 +} + +@genType +type firstClassModule = module(MT) + +@genType +let firstClassModule: firstClassModule = module(M) + +@genType +let testConvert = (m: module(MT)) => m + +module type ResT = { + let ww: string +} + +module SomeFunctor = (X: MT): ResT => { + let ww = X.y +} + +@genType +let someFunctorAsFunction = (x: module(MT)): module(ResT) => module(SomeFunctor(unpack(x))) diff --git a/analysis/examples/larger-project/src/FirstClassModulesInterface.js b/analysis/examples/larger-project/src/FirstClassModulesInterface.js new file mode 100644 index 0000000000..56783f6a44 --- /dev/null +++ b/analysis/examples/larger-project/src/FirstClassModulesInterface.js @@ -0,0 +1,13 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +var r = { + x: 3, + y: "hello" +}; + +export { + r , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/FirstClassModulesInterface.res b/analysis/examples/larger-project/src/FirstClassModulesInterface.res new file mode 100644 index 0000000000..9dd75a90b8 --- /dev/null +++ b/analysis/examples/larger-project/src/FirstClassModulesInterface.res @@ -0,0 +1,12 @@ +type record = { + x: int, + y: string, +} + +let r = {x: 3, y: "hello"} + +module type MT = { + let x: int +} + +type firstClassModule = module(MT) diff --git a/analysis/examples/larger-project/src/FirstClassModulesInterface.resi b/analysis/examples/larger-project/src/FirstClassModulesInterface.resi new file mode 100644 index 0000000000..658663cc45 --- /dev/null +++ b/analysis/examples/larger-project/src/FirstClassModulesInterface.resi @@ -0,0 +1,15 @@ +@genType +type record = { + x: int, + y: string, +} + +let r: record + +@genType +module type MT = { + let x: int +} + +@genType +type firstClassModule = module(MT) diff --git a/analysis/examples/larger-project/src/Hooks.js b/analysis/examples/larger-project/src/Hooks.js new file mode 100644 index 0000000000..8b249e521d --- /dev/null +++ b/analysis/examples/larger-project/src/Hooks.js @@ -0,0 +1,188 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Curry from "rescript/lib/es6/curry.js"; +import * as React from "react"; +import * as ImportHooks from "./ImportHooks.js"; +import * as ImportHookDefault from "./ImportHookDefault.js"; + +function Hooks(Props) { + var vehicle = Props.vehicle; + var match = React.useState(function () { + return 0; + }); + var setCount = match[1]; + var count = match[0]; + return React.createElement("div", undefined, React.createElement("p", undefined, "Hooks example " + (vehicle.name + (" clicked " + (String(count) + " times")))), React.createElement("button", { + onClick: (function (param) { + return Curry._1(setCount, (function (param) { + return count + 1 | 0; + })); + }) + }, "Click me"), React.createElement(ImportHooks.make, { + person: { + name: "Mary", + age: 71 + }, + children: null, + renderMe: (function (x) { + return x.randomString; + }) + }, "child1", "child2"), React.createElement(ImportHookDefault.make, { + person: { + name: "DefaultImport", + age: 42 + }, + children: null, + renderMe: (function (x) { + return x.randomString; + }) + }, "child1", "child2")); +} + +function Hooks$anotherComponent(Props) { + var vehicle = Props.vehicle; + var callback = Props.callback; + Curry._1(callback, undefined); + return React.createElement("div", undefined, "Another Hook " + vehicle.name); +} + +function Hooks$Inner(Props) { + var vehicle = Props.vehicle; + return React.createElement("div", undefined, "Another Hook " + vehicle.name); +} + +function Hooks$Inner$anotherComponent(Props) { + var vehicle = Props.vehicle; + return React.createElement("div", undefined, "Another Hook " + vehicle.name); +} + +function Hooks$Inner$Inner2(Props) { + var vehicle = Props.vehicle; + return React.createElement("div", undefined, "Another Hook " + vehicle.name); +} + +function Hooks$Inner$Inner2$anotherComponent(Props) { + var vehicle = Props.vehicle; + return React.createElement("div", undefined, "Another Hook " + vehicle.name); +} + +var Inner2 = { + make: Hooks$Inner$Inner2, + anotherComponent: Hooks$Inner$Inner2$anotherComponent +}; + +var Inner = { + make: Hooks$Inner, + anotherComponent: Hooks$Inner$anotherComponent, + Inner2: Inner2 +}; + +function Hooks$NoProps(Props) { + return React.createElement("div", undefined, null); +} + +var NoProps = { + make: Hooks$NoProps +}; + +function functionWithRenamedArgs(_to, _Type, cb) { + Curry._1(cb, _to); + return _to.name + _Type.name; +} + +function Hooks$componentWithRenamedArgs(Props) { + var _to = Props.to; + var _Type = Props.Type; + var cb = Props.cb; + Curry._1(cb, _to); + return _to.name + _Type.name; +} + +function Hooks$makeWithRef(Props) { + var vehicle = Props.vehicle; + return function (ref) { + if (ref == null) { + return null; + } else { + return React.createElement("button", { + ref: ref + }, vehicle.name); + } + }; +} + +var testForwardRef = React.forwardRef(function (param, param$1) { + return Hooks$makeWithRef(param)(param$1); + }); + +var input = React.forwardRef(function (Props, param) { + var partial_arg = Props.r; + return React.createElement("div", { + ref: param + }, partial_arg.x); + }); + +function Hooks$polymorphicComponent(Props) { + var param = Props.p; + return param[0].name; +} + +function Hooks$functionReturningReactElement(Props) { + return Props.name; +} + +function Hooks$RenderPropRequiresConversion(Props) { + var renderVehicle = Props.renderVehicle; + return Curry._1(renderVehicle, { + vehicle: { + name: "Car" + }, + number: 42 + }); +} + +var RenderPropRequiresConversion = { + make: Hooks$RenderPropRequiresConversion +}; + +function Hooks$aComponentWithChildren(Props) { + var vehicle = Props.vehicle; + var children = Props.children; + return React.createElement("div", undefined, "Another Hook " + vehicle.name, React.createElement("div", undefined, children)); +} + +var make = Hooks; + +var $$default = Hooks; + +var anotherComponent = Hooks$anotherComponent; + +var componentWithRenamedArgs = Hooks$componentWithRenamedArgs; + +var makeWithRef = Hooks$makeWithRef; + +var polymorphicComponent = Hooks$polymorphicComponent; + +var functionReturningReactElement = Hooks$functionReturningReactElement; + +var aComponentWithChildren = Hooks$aComponentWithChildren; + +export { + make , + $$default , + $$default as default, + anotherComponent , + Inner , + NoProps , + functionWithRenamedArgs , + componentWithRenamedArgs , + makeWithRef , + testForwardRef , + input , + polymorphicComponent , + functionReturningReactElement , + RenderPropRequiresConversion , + aComponentWithChildren , + +} +/* testForwardRef Not a pure module */ diff --git a/analysis/examples/larger-project/src/Hooks.res b/analysis/examples/larger-project/src/Hooks.res new file mode 100644 index 0000000000..f35c242879 --- /dev/null +++ b/analysis/examples/larger-project/src/Hooks.res @@ -0,0 +1,115 @@ +type vehicle = {name: string} + +@react.component +let make = (~vehicle) => { + let (count, setCount) = React.useState(() => 0) + +
+

+ {React.string( + "Hooks example " ++ (vehicle.name ++ (" clicked " ++ (string_of_int(count) ++ " times"))), + )} +

+ + React.string(x["randomString"])}> + {React.string("child1")} {React.string("child2")} + + React.string(x["randomString"])}> + {React.string("child1")} {React.string("child2")} + +
+} + +@genType +let default = make + +@genType @react.component +let anotherComponent = (~vehicle, ~callback: unit => unit) => { + callback() +
{React.string("Another Hook " ++ vehicle.name)}
+} + +module Inner = { + @genType @react.component + let make = (~vehicle) =>
{React.string("Another Hook " ++ vehicle.name)}
+ + @genType @react.component + let anotherComponent = (~vehicle) =>
{React.string("Another Hook " ++ vehicle.name)}
+ + module Inner2 = { + @genType @react.component + let make = (~vehicle) =>
{React.string("Another Hook " ++ vehicle.name)}
+ + @genType @react.component + let anotherComponent = (~vehicle) => +
{React.string("Another Hook " ++ vehicle.name)}
+ } +} + +module NoProps = { + @genType @react.component + let make = () =>
React.null
+} + +type cb = (~_to: vehicle) => unit + +@genType +let functionWithRenamedArgs = (~_to, ~_Type, ~cb: cb) => { + cb(~_to) + _to.name ++ _Type.name +} + +@genType @react.component +let componentWithRenamedArgs = (~_to, ~_Type, ~cb: cb) => { + cb(~_to) + React.string(_to.name ++ _Type.name) +} + +@genType @react.component +let makeWithRef = (~vehicle) => { + let _ = 34 + ref => + switch ref->Js.Nullable.toOption { + | Some(ref) => + | None => React.null + } +} + +@genType +let testForwardRef = React.forwardRef(makeWithRef) + +type r = {x: string} + +@genType @react.component +let input = React.forwardRef((~r, (), ref) =>
{React.string(r.x)}
) + +@genType +type callback<'input, 'output> = React.callback<'input, 'output> + +@genType +type testReactContext = React.Context.t + +@genType +type testReactRef = React.Ref.t + +@genType +type testDomRef = ReactDOM.domRef + +@genType @react.component +let polymorphicComponent = (~p as (x, _)) => React.string(x.name) + +@genType @react.component +let functionReturningReactElement = (~name) => React.string(name) + +module RenderPropRequiresConversion = { + @genType @react.component + let make = (~renderVehicle: {"vehicle": vehicle, "number": int} => React.element) => { + let car = {name: "Car"} + renderVehicle({"vehicle": car, "number": 42}) + } +} + +@genType @react.component +let aComponentWithChildren = (~vehicle, ~children) => +
{React.string("Another Hook " ++ vehicle.name)}
children
diff --git a/analysis/examples/larger-project/src/IgnoreInterface.js b/analysis/examples/larger-project/src/IgnoreInterface.js new file mode 100644 index 0000000000..d856702bfe --- /dev/null +++ b/analysis/examples/larger-project/src/IgnoreInterface.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/analysis/examples/larger-project/src/IgnoreInterface.res b/analysis/examples/larger-project/src/IgnoreInterface.res new file mode 100644 index 0000000000..d381c3d037 --- /dev/null +++ b/analysis/examples/larger-project/src/IgnoreInterface.res @@ -0,0 +1,2 @@ +@gentype +type t = int diff --git a/analysis/examples/larger-project/src/IgnoreInterface.resi b/analysis/examples/larger-project/src/IgnoreInterface.resi new file mode 100644 index 0000000000..709cbb9642 --- /dev/null +++ b/analysis/examples/larger-project/src/IgnoreInterface.resi @@ -0,0 +1,5 @@ +// Use the annotations, and definitions, from the .re file +@@genType.ignoreInterface + +@genType +type t diff --git a/analysis/examples/larger-project/src/ImmutableArray.js b/analysis/examples/larger-project/src/ImmutableArray.js new file mode 100644 index 0000000000..d856702bfe --- /dev/null +++ b/analysis/examples/larger-project/src/ImmutableArray.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/analysis/examples/larger-project/src/ImmutableArray.res b/analysis/examples/larger-project/src/ImmutableArray.res new file mode 100644 index 0000000000..e69de29bb2 diff --git a/analysis/examples/larger-project/src/ImmutableArray.resi b/analysis/examples/larger-project/src/ImmutableArray.resi new file mode 100644 index 0000000000..e69de29bb2 diff --git a/analysis/examples/larger-project/src/ImportHookDefault.js b/analysis/examples/larger-project/src/ImportHookDefault.js new file mode 100644 index 0000000000..119015eb5f --- /dev/null +++ b/analysis/examples/larger-project/src/ImportHookDefault.js @@ -0,0 +1,15 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import ImportHookDefaultGen from "./ImportHookDefault.gen"; +import * as ImportHookDefaultGen$1 from "./ImportHookDefault.gen"; + +var make = ImportHookDefaultGen$1.make; + +var make2 = ImportHookDefaultGen; + +export { + make , + make2 , + +} +/* make Not a pure module */ diff --git a/analysis/examples/larger-project/src/ImportHookDefault.res b/analysis/examples/larger-project/src/ImportHookDefault.res new file mode 100644 index 0000000000..61086d6eae --- /dev/null +++ b/analysis/examples/larger-project/src/ImportHookDefault.res @@ -0,0 +1,18 @@ +type person = { + name: string, + age: int, +} + +@genType.import(("./hookExample", "default")) @react.component +external make: ( + ~person: person, + ~children: React.element, + ~renderMe: ImportHooks.renderMe, +) => React.element = "make" + +@genType.import("./hookExample") @react.component +external make2: ( + ~person: person, + ~children: React.element, + ~renderMe: ImportHooks.renderMe, +) => React.element = "default" diff --git a/analysis/examples/larger-project/src/ImportHooks.js b/analysis/examples/larger-project/src/ImportHooks.js new file mode 100644 index 0000000000..2296ade782 --- /dev/null +++ b/analysis/examples/larger-project/src/ImportHooks.js @@ -0,0 +1,16 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as ImportHooksGen from "./ImportHooks.gen"; + +var make = ImportHooksGen.makeRenamed; + +function foo(prim) { + return ImportHooksGen.foo(prim); +} + +export { + make , + foo , + +} +/* make Not a pure module */ diff --git a/analysis/examples/larger-project/src/ImportHooks.res b/analysis/examples/larger-project/src/ImportHooks.res new file mode 100644 index 0000000000..85bfe4d18d --- /dev/null +++ b/analysis/examples/larger-project/src/ImportHooks.res @@ -0,0 +1,21 @@ +@genType +type person = { + name: string, + age: int, +} + +@genType +type renderMe<'a> = React.component<{ + "randomString": string, + "poly": 'a, +}> + +@genType.import("./hookExample") @react.component +external make: ( + ~person: person, + ~children: React.element, + ~renderMe: renderMe<'a>, +) => React.element = "makeRenamed" + +@genType.import("./hookExample") +external foo: (~person: person) => string = "foo" diff --git a/analysis/examples/larger-project/src/ImportIndex.js b/analysis/examples/larger-project/src/ImportIndex.js new file mode 100644 index 0000000000..d817c1940a --- /dev/null +++ b/analysis/examples/larger-project/src/ImportIndex.js @@ -0,0 +1,11 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import ImportIndexGen from "./ImportIndex.gen"; + +var make = ImportIndexGen; + +export { + make , + +} +/* make Not a pure module */ diff --git a/analysis/examples/larger-project/src/ImportIndex.res b/analysis/examples/larger-project/src/ImportIndex.res new file mode 100644 index 0000000000..61f8998a55 --- /dev/null +++ b/analysis/examples/larger-project/src/ImportIndex.res @@ -0,0 +1,3 @@ +// TODO: rename metodd back once remmt bug is fixed +@genType.import("./") @react.component +external make: (~method: @string [#push | #replace]=?) => React.element = "default" diff --git a/analysis/examples/larger-project/src/ImportJsValue.js b/analysis/examples/larger-project/src/ImportJsValue.js new file mode 100644 index 0000000000..b5447377e9 --- /dev/null +++ b/analysis/examples/larger-project/src/ImportJsValue.js @@ -0,0 +1,81 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import ImportJsValueGen from "./ImportJsValue.gen"; +import * as ImportJsValueGen$1 from "./ImportJsValue.gen"; + +function round(prim) { + return ImportJsValueGen$1.round(prim); +} + +function area(prim) { + return ImportJsValueGen$1.area(prim); +} + +function returnMixedArray(prim) { + return ImportJsValueGen$1.returnMixedArray(); +} + +var roundedNumber = ImportJsValueGen$1.round(1.8); + +var areaValue = ImportJsValueGen$1.area({ + x: 3, + y: undefined + }); + +function getAbs(x) { + return x.getAbs(); +} + +var AbsoluteValue = { + getAbs: getAbs +}; + +function useGetProp(x) { + return x.getProp() + 1 | 0; +} + +function useGetAbs(x) { + return x.getAbs() + 1 | 0; +} + +function useColor(prim) { + return ImportJsValueGen$1.useColor(prim); +} + +function higherOrder(prim) { + return ImportJsValueGen$1.higherOrder(prim); +} + +var returnedFromHigherOrder = ImportJsValueGen$1.higherOrder(function (prim0, prim1) { + return prim0 + prim1 | 0; + }); + +function convertVariant(prim) { + return ImportJsValueGen$1.convertVariant(prim); +} + +function polymorphic(prim) { + return ImportJsValueGen$1.polymorphic(prim); +} + +var $$default = ImportJsValueGen; + +export { + round , + area , + returnMixedArray , + roundedNumber , + areaValue , + AbsoluteValue , + useGetProp , + useGetAbs , + useColor , + higherOrder , + returnedFromHigherOrder , + convertVariant , + polymorphic , + $$default , + $$default as default, + +} +/* roundedNumber Not a pure module */ diff --git a/analysis/examples/larger-project/src/ImportJsValue.res b/analysis/examples/larger-project/src/ImportJsValue.res new file mode 100644 index 0000000000..7728ca527c --- /dev/null +++ b/analysis/examples/larger-project/src/ImportJsValue.res @@ -0,0 +1,84 @@ +@ocaml.doc(" + * Wrap JS values to be used from Reason + ") +@genType.import("./MyMath") +external /* This is the module to import from. */ +/* Name and type of the JS value to bind to. */ +round: float => float = "round" + +@genType +type point = { + x: int, + y: option, +} + +@genType.import("./MyMath") +external /* This is the module to import from. */ +/* Name and type of the JS value to bind to. */ +area: point => int = "area" + +@genType.import("./MyMath") +type numberOrString + +@genType.import("./MyMath") +external returnMixedArray: unit => array = "returnMixedArray" + +@genType +let roundedNumber = round(1.8) + +@genType +let areaValue = area({x: 3, y: None}) + +module AbsoluteValue = { + @genType.import(("./MyMath", "AbsoluteValue")) + type t = {"getAbs": (. unit) => int} + + /* This is untyped */ + @send external getProp: t => int = "getProp" + + /* This is also untyped, as we "trust" the type declaration in absoluteVaue */ + let getAbs = (x: t) => { + let getAbs = x["getAbs"] + getAbs(.) + } +} + +@genType +let useGetProp = (x: AbsoluteValue.t) => x->AbsoluteValue.getProp + 1 + +@genType +let useGetAbs = (x: AbsoluteValue.t) => x->AbsoluteValue.getAbs + 1 + +@genType.import("./MyMath") +type stringFunction + +@genType +type color = [#tomato | #gray] + +@genType.import("./MyMath") external useColor: color => int = "useColor" + +@genType.import("./MyMath") +external higherOrder: ((int, int) => int) => int = "higherOrder" + +@genType +let returnedFromHigherOrder = higherOrder(\"+") + +type variant = + | I(int) + | S(string) + +@genType.import("./MyMath") +external convertVariant: variant => variant = "convertVariant" + +@genType.import("./MyMath") external polymorphic: 'a => 'a = "polymorphic" + +@genType.import("./MyMath") external default: int = "default" + +@genType.import(("./MyMath", "num")) +type num + +@genType.import(("./MyMath", "num")) +type myNum + +@genType.import("./MyMath") +type polyType<'a> diff --git a/analysis/examples/larger-project/src/ImportMyBanner.js b/analysis/examples/larger-project/src/ImportMyBanner.js new file mode 100644 index 0000000000..ffc3d6ed53 --- /dev/null +++ b/analysis/examples/larger-project/src/ImportMyBanner.js @@ -0,0 +1,14 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Caml_option from "rescript/lib/es6/caml_option.js"; +import * as ImportMyBannerGen from "./ImportMyBanner.gen"; + +function make(prim0, prim1, prim2) { + return ImportMyBannerGen.make(prim0, prim1 !== undefined ? Caml_option.valFromOption(prim1) : undefined, prim2); +} + +export { + make , + +} +/* ./ImportMyBanner.gen Not a pure module */ diff --git a/analysis/examples/larger-project/src/ImportMyBanner.res b/analysis/examples/larger-project/src/ImportMyBanner.res new file mode 100644 index 0000000000..9b26fa2366 --- /dev/null +++ b/analysis/examples/larger-project/src/ImportMyBanner.res @@ -0,0 +1,12 @@ +@ocaml.doc(" + * Wrap component MyBanner to be used from Reason. + ") +@genType +type message = {text: string} + +@genType.import("./MyBanner") +external /* Module with the JS component to be wrapped. */ +/* The make function will be automatically generated from the types below. */ +make: (~show: bool, ~message: option=?, 'a) => React.element = "make" + +let make = make diff --git a/analysis/examples/larger-project/src/JSResource.js b/analysis/examples/larger-project/src/JSResource.js new file mode 100644 index 0000000000..d856702bfe --- /dev/null +++ b/analysis/examples/larger-project/src/JSResource.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/analysis/examples/larger-project/src/JSResource.res b/analysis/examples/larger-project/src/JSResource.res new file mode 100644 index 0000000000..432c4a4669 --- /dev/null +++ b/analysis/examples/larger-project/src/JSResource.res @@ -0,0 +1,3 @@ +type t<'a> + +@module external jSResource: string => t<'a> = "JSResource" diff --git a/analysis/examples/larger-project/src/LetPrivate.js b/analysis/examples/larger-project/src/LetPrivate.js new file mode 100644 index 0000000000..25dbf8d5bb --- /dev/null +++ b/analysis/examples/larger-project/src/LetPrivate.js @@ -0,0 +1,10 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +var y = 34; + +export { + y , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/LetPrivate.res b/analysis/examples/larger-project/src/LetPrivate.res new file mode 100644 index 0000000000..758270659a --- /dev/null +++ b/analysis/examples/larger-project/src/LetPrivate.res @@ -0,0 +1,7 @@ +%%private( + @genType + let x = 34 +) + +@genType +let y = x diff --git a/analysis/examples/larger-project/src/ModuleAliases.js b/analysis/examples/larger-project/src/ModuleAliases.js new file mode 100644 index 0000000000..bbe92275ae --- /dev/null +++ b/analysis/examples/larger-project/src/ModuleAliases.js @@ -0,0 +1,48 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +var Inner = {}; + +var Outer = { + Inner: Inner +}; + +var InnerNested = {}; + +var Inner2 = { + InnerNested: InnerNested, + OuterInnerAlias2: undefined +}; + +var Outer2 = { + OuterInnerAlias: undefined, + Inner2: Inner2 +}; + +function testNested(x) { + return x; +} + +function testInner(x) { + return x; +} + +function testInner2(x) { + return x; +} + +var Outer2Alias; + +var InnerNestedAlias; + +export { + Outer , + Outer2 , + Outer2Alias , + InnerNestedAlias , + testNested , + testInner , + testInner2 , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/ModuleAliases.res b/analysis/examples/larger-project/src/ModuleAliases.res new file mode 100644 index 0000000000..93c612acb0 --- /dev/null +++ b/analysis/examples/larger-project/src/ModuleAliases.res @@ -0,0 +1,28 @@ +module Outer = { + module Inner = { + type innerT = {inner: string} + } +} + +module Outer2 = { + module OuterInnerAlias = Outer.Inner + module Inner2 = { + module InnerNested = { + type t = {nested: int} + } + module OuterInnerAlias2 = OuterInnerAlias + } +} + +module Outer2Alias = Outer2 + +module InnerNestedAlias = Outer2.Inner2.InnerNested + +@genType +let testNested = (x: InnerNestedAlias.t) => x + +@genType +let testInner = (x: Outer2Alias.OuterInnerAlias.innerT) => x + +@genType +let testInner2 = (x: Outer2Alias.Inner2.OuterInnerAlias2.innerT) => x diff --git a/analysis/examples/larger-project/src/ModuleAliases2.js b/analysis/examples/larger-project/src/ModuleAliases2.js new file mode 100644 index 0000000000..59a7eb6489 --- /dev/null +++ b/analysis/examples/larger-project/src/ModuleAliases2.js @@ -0,0 +1,23 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +var Inner = {}; + +var Outer = { + Inner: Inner +}; + +var OuterAlias; + +var InnerAlias; + +var q = 42; + +export { + Outer , + OuterAlias , + InnerAlias , + q , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/ModuleAliases2.res b/analysis/examples/larger-project/src/ModuleAliases2.res new file mode 100644 index 0000000000..b0ce0265c6 --- /dev/null +++ b/analysis/examples/larger-project/src/ModuleAliases2.res @@ -0,0 +1,21 @@ +@genType +type record = { + x: int, + y: string, +} + +module Outer = { + @genType + type outer = {outer: string} + + module Inner = { + @genType + type inner = {inner: string} + } +} + +module OuterAlias = Outer + +module InnerAlias = OuterAlias.Inner + +let q = 42 diff --git a/analysis/examples/larger-project/src/ModuleExceptionBug.js b/analysis/examples/larger-project/src/ModuleExceptionBug.js new file mode 100644 index 0000000000..6679d3d6f6 --- /dev/null +++ b/analysis/examples/larger-project/src/ModuleExceptionBug.js @@ -0,0 +1,25 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Caml_exceptions from "rescript/lib/es6/caml_exceptions.js"; + +function customDouble(foo) { + return (foo << 1); +} + +var Dep = { + customDouble: customDouble +}; + +var MyOtherException = /* @__PURE__ */Caml_exceptions.create("ModuleExceptionBug.MyOtherException"); + +console.log(34); + +var ddjdj = 34; + +export { + Dep , + MyOtherException , + ddjdj , + +} +/* Not a pure module */ diff --git a/analysis/examples/larger-project/src/ModuleExceptionBug.res b/analysis/examples/larger-project/src/ModuleExceptionBug.res new file mode 100644 index 0000000000..f9b36ce235 --- /dev/null +++ b/analysis/examples/larger-project/src/ModuleExceptionBug.res @@ -0,0 +1,8 @@ +module Dep = { + let customDouble = foo => foo * 2 +} + +exception MyOtherException + +let ddjdj = 34 +Js.log(ddjdj) diff --git a/analysis/examples/larger-project/src/NestedModules.js b/analysis/examples/larger-project/src/NestedModules.js new file mode 100644 index 0000000000..fd32bddea7 --- /dev/null +++ b/analysis/examples/larger-project/src/NestedModules.js @@ -0,0 +1,43 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function nested3Function(x) { + return x; +} + +var Nested3 = { + x: 0, + y: 1, + z: 2, + w: 3, + nested3Value: "nested3Value", + nested3Function: nested3Function +}; + +function nested2Function(x) { + return x; +} + +var Nested2 = { + x: 0, + nested2Value: 1, + y: 2, + Nested3: Nested3, + nested2Function: nested2Function +}; + +var Universe = { + theAnswer: 42, + notExported: 33, + Nested2: Nested2, + someString: "some exported string" +}; + +var notNested = 1; + +export { + notNested , + Universe , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/NestedModules.res b/analysis/examples/larger-project/src/NestedModules.res new file mode 100644 index 0000000000..f2317d1945 --- /dev/null +++ b/analysis/examples/larger-project/src/NestedModules.res @@ -0,0 +1,51 @@ +@genType +let notNested = 1 + +module Universe = { + @genType + let theAnswer = 42 + + let notExported = 33 + + @genType + type nestedType = array + + module Nested2 = { + let x = 0 + + @genType + let nested2Value = 1 + + let y = 2 + + @genType + type nested2Type = array> + + module Nested3 = { + let x = 0 + let y = 1 + let z = 2 + let w = 3 + + @genType + type nested3Type = array>> + + @genType + let nested3Value = "nested3Value" + + @genType + let nested3Function = (x: nested2Type) => x + } + + @genType + let nested2Function = (x: Nested3.nested3Type) => x + } + + @genType + type variant = + | A + | B(string) + + @genType + let someString = "some exported string" +} diff --git a/analysis/examples/larger-project/src/NestedModulesInSignature.js b/analysis/examples/larger-project/src/NestedModulesInSignature.js new file mode 100644 index 0000000000..1019513009 --- /dev/null +++ b/analysis/examples/larger-project/src/NestedModulesInSignature.js @@ -0,0 +1,12 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +var Universe = { + theAnswer: 42 +}; + +export { + Universe , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/NestedModulesInSignature.res b/analysis/examples/larger-project/src/NestedModulesInSignature.res new file mode 100644 index 0000000000..85f454db98 --- /dev/null +++ b/analysis/examples/larger-project/src/NestedModulesInSignature.res @@ -0,0 +1,3 @@ +module Universe = { + let theAnswer = 42 +} diff --git a/analysis/examples/larger-project/src/NestedModulesInSignature.resi b/analysis/examples/larger-project/src/NestedModulesInSignature.resi new file mode 100644 index 0000000000..482b8ca52a --- /dev/null +++ b/analysis/examples/larger-project/src/NestedModulesInSignature.resi @@ -0,0 +1,4 @@ +module Universe: { + @genType + let theAnswer: int +} diff --git a/analysis/examples/larger-project/src/Newsyntax.js b/analysis/examples/larger-project/src/Newsyntax.js new file mode 100644 index 0000000000..8a024f19da --- /dev/null +++ b/analysis/examples/larger-project/src/Newsyntax.js @@ -0,0 +1,13 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +var x = 34; + +var y = 11; + +export { + x , + y , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/Newsyntax.res b/analysis/examples/larger-project/src/Newsyntax.res new file mode 100644 index 0000000000..45f118b404 --- /dev/null +++ b/analysis/examples/larger-project/src/Newsyntax.res @@ -0,0 +1,12 @@ +let x = 34 + +let y = 11 + +type record = { + xxx: int, + yyy: int, +} + +type variant = A | B(int) | C + +type record2 = {xx: int, yy: int} diff --git a/analysis/examples/larger-project/src/Newton.js b/analysis/examples/larger-project/src/Newton.js new file mode 100644 index 0000000000..5f603b0e87 --- /dev/null +++ b/analysis/examples/larger-project/src/Newton.js @@ -0,0 +1,65 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Curry from "rescript/lib/es6/curry.js"; + +function $neg(prim0, prim1) { + return prim0 - prim1; +} + +function $plus(prim0, prim1) { + return prim0 + prim1; +} + +function $star(prim0, prim1) { + return prim0 * prim1; +} + +function $slash(prim0, prim1) { + return prim0 / prim1; +} + +function newton(f, fPrimed, initial, threshold) { + var current = { + contents: initial + }; + var iterateMore = function (previous, next) { + var delta = next >= previous ? next - previous : previous - next; + current.contents = next; + return delta >= threshold; + }; + var _param; + while(true) { + var previous = current.contents; + var next = previous - Curry._1(f, previous) / Curry._1(fPrimed, previous); + if (!iterateMore(previous, next)) { + return current.contents; + } + _param = undefined; + continue ; + }; +} + +function f(x) { + return x * x * x - 2.0 * x * x - 11.0 * x + 12.0; +} + +function fPrimed(x) { + return 3.0 * x * x - 4.0 * x - 11.0; +} + +var result = newton(f, fPrimed, 5.0, 0.0003); + +console.log(result, f(result)); + +export { + $neg , + $plus , + $star , + $slash , + newton , + f , + fPrimed , + result , + +} +/* result Not a pure module */ diff --git a/analysis/examples/larger-project/src/Newton.res b/analysis/examples/larger-project/src/Newton.res new file mode 100644 index 0000000000..4601b2bc46 --- /dev/null +++ b/analysis/examples/larger-project/src/Newton.res @@ -0,0 +1,32 @@ +let \"-" = \"-." +let \"+" = \"+." +let \"*" = \"*." +let \"/" = \"/." + +let newton = (~f, ~fPrimed, ~initial, ~threshold) => { + let current = ref(initial) + let iterateMore = (previous, next) => { + let delta = next >= previous ? next - previous : previous - next + current := next + !(delta < threshold) + } + + @progress(iterateMore) + let rec loop = () => { + let previous = current.contents + let next = previous - f(previous) / fPrimed(previous) + if iterateMore(previous, next) { + loop() + } else { + current.contents + } + } + loop() +} +let f = x => x * x * x - 2.0 * x * x - 11.0 * x + 12.0 + +let fPrimed = x => 3.0 * x * x - 4.0 * x - 11.0 + +let result = newton(~f, ~fPrimed, ~initial=5.0, ~threshold=0.0003) + +Js.log2(result, f(result)) diff --git a/analysis/examples/larger-project/src/Opaque.js b/analysis/examples/larger-project/src/Opaque.js new file mode 100644 index 0000000000..17f41cac2e --- /dev/null +++ b/analysis/examples/larger-project/src/Opaque.js @@ -0,0 +1,17 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function noConversion(x) { + return x; +} + +function testConvertNestedRecordFromOtherFile(x) { + return x; +} + +export { + noConversion , + testConvertNestedRecordFromOtherFile , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/Opaque.res b/analysis/examples/larger-project/src/Opaque.res new file mode 100644 index 0000000000..e6772142aa --- /dev/null +++ b/analysis/examples/larger-project/src/Opaque.res @@ -0,0 +1,11 @@ +@genType.opaque +type opaqueFromRecords = A(Records.coord) + +@genType +let noConversion = (x: opaqueFromRecords) => x + +@genType +type pair = (opaqueFromRecords, opaqueFromRecords) + +@genType +let testConvertNestedRecordFromOtherFile = (x: Records.business) => x diff --git a/analysis/examples/larger-project/src/OptArg.js b/analysis/examples/larger-project/src/OptArg.js new file mode 100644 index 0000000000..1900ecd3c0 --- /dev/null +++ b/analysis/examples/larger-project/src/OptArg.js @@ -0,0 +1,60 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function foo(xOpt, yOpt, zOpt, w) { + var x = xOpt !== undefined ? xOpt : 1; + var y = yOpt !== undefined ? yOpt : 2; + var z = zOpt !== undefined ? zOpt : 3; + return ((x + y | 0) + z | 0) + w | 0; +} + +function bar(x, y, z, w) { + return y + w | 0; +} + +console.log(foo(3, undefined, undefined, 4)); + +console.log(7); + +function threeArgs(aOpt, bOpt, cOpt, d) { + var a = aOpt !== undefined ? aOpt : 1; + var b = bOpt !== undefined ? bOpt : 2; + var c = cOpt !== undefined ? cOpt : 3; + return ((a + b | 0) + c | 0) + d | 0; +} + +console.log(threeArgs(4, undefined, 7, 1)); + +console.log(threeArgs(4, undefined, undefined, 1)); + +function twoArgs(aOpt, bOpt, c) { + var a = aOpt !== undefined ? aOpt : 1; + var b = bOpt !== undefined ? bOpt : 2; + return (a + b | 0) + c | 0; +} + +console.log(twoArgs(undefined, undefined, 1)); + +var a = 3; + +console.log(a + 44 | 0); + +function wrapfourArgs(a, b, c, n) { + var dOpt; + var a$1 = a !== undefined ? a : 1; + var b$1 = b !== undefined ? b : 2; + var c$1 = c !== undefined ? c : 3; + var d = dOpt !== undefined ? dOpt : 4; + return (((a$1 + b$1 | 0) + c$1 | 0) + d | 0) + n | 0; +} + +console.log(wrapfourArgs(3, undefined, 44, 44)); + +console.log(wrapfourArgs(undefined, 4, 44, 44)); + +export { + foo , + bar , + +} +/* Not a pure module */ diff --git a/analysis/examples/larger-project/src/OptArg.res b/analysis/examples/larger-project/src/OptArg.res new file mode 100644 index 0000000000..a38e8bfc42 --- /dev/null +++ b/analysis/examples/larger-project/src/OptArg.res @@ -0,0 +1,29 @@ +let foo = (~x=1, ~y=2, ~z=3, w) => x + y + z + w + +let bar = (~x=?, ~y, ~z=?, w) => y + w + +Js.log(foo(~x=3, 4)) + +Js.log(bar(~y=3, 4)) + +let threeArgs = (~a=1, ~b=2, ~c=3, d) => a + b + c + d + +Js.log(threeArgs(~a=4, ~c=7, 1)) +Js.log(threeArgs(~a=4, 1)) + +let twoArgs = (~a=1, ~b=2, c) => a + b + c + +Js.log(1 |> twoArgs) + +let oneArg = (~a=1, ~z, b) => a + b + +let wrapOneArg = (~a=?, n) => oneArg(~a?, ~z=33, n) + +Js.log(wrapOneArg(~a=3, 44)) + +let fourArgs = (~a=1, ~b=2, ~c=3, ~d=4, n) => a + b + c + d + n + +let wrapfourArgs = (~a=?, ~b=?, ~c=?, n) => fourArgs(~a?, ~b?, ~c?, n) + +Js.log(wrapfourArgs(~a=3, ~c=44, 44)) +Js.log(wrapfourArgs(~b=4, ~c=44, 44)) diff --git a/analysis/examples/larger-project/src/OptArg.resi b/analysis/examples/larger-project/src/OptArg.resi new file mode 100644 index 0000000000..8145a51165 --- /dev/null +++ b/analysis/examples/larger-project/src/OptArg.resi @@ -0,0 +1,2 @@ +let foo: (~x: int=?, ~y: int=?, ~z: int=?, int) => int +let bar: (~x: 'a=?, ~y: int, ~z: 'b=?, int) => int diff --git a/analysis/examples/larger-project/src/P.js b/analysis/examples/larger-project/src/P.js new file mode 100644 index 0000000000..4a5fd32836 --- /dev/null +++ b/analysis/examples/larger-project/src/P.js @@ -0,0 +1,114 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Caml_exceptions from "rescript/lib/es6/caml_exceptions.js"; + +var Sys_error = /* @__PURE__ */Caml_exceptions.create("P.Sys_error"); + +function input(param) { + throw { + RE_EXN_ID: "Assert_failure", + _1: [ + "P.res", + 2, + 17 + ], + Error: new Error() + }; +} + +function output(param) { + throw { + RE_EXN_ID: "Assert_failure", + _1: [ + "P.res", + 3, + 18 + ], + Error: new Error() + }; +} + +function open_temp_file(param) { + throw { + RE_EXN_ID: "Assert_failure", + _1: [ + "P.res", + 4, + 26 + ], + Error: new Error() + }; +} + +function close_out(param) { + throw { + RE_EXN_ID: "Assert_failure", + _1: [ + "P.res", + 5, + 21 + ], + Error: new Error() + }; +} + +function output_char(param) { + throw { + RE_EXN_ID: "Assert_failure", + _1: [ + "P.res", + 6, + 23 + ], + Error: new Error() + }; +} + +function really_input(param) { + throw { + RE_EXN_ID: "Assert_failure", + _1: [ + "P.res", + 7, + 24 + ], + Error: new Error() + }; +} + +function pp_get_formatter_tag_functions(param) { + throw { + RE_EXN_ID: "Assert_failure", + _1: [ + "P.res", + 8, + 42 + ], + Error: new Error() + }; +} + +throw { + RE_EXN_ID: "Assert_failure", + _1: [ + "P.res", + 11, + 13 + ], + Error: new Error() + }; + +export { + Sys_error , + input , + output , + open_temp_file , + close_out , + output_char , + really_input , + pp_get_formatter_tag_functions , + stderr , + print_char , + +} +/* stderr Not a pure module */ diff --git a/analysis/examples/larger-project/src/P.res b/analysis/examples/larger-project/src/P.res new file mode 100644 index 0000000000..3c69ae7816 --- /dev/null +++ b/analysis/examples/larger-project/src/P.res @@ -0,0 +1,14 @@ +exception Sys_error(string) +let input = _ => assert false +let output = _ => assert false +let open_temp_file = _ => assert false +let close_out = _ => assert false +let output_char = _ => assert false +let really_input = _ => assert false +let pp_get_formatter_tag_functions = _ => assert false +type ttt = Open_text +type out_channel +let stderr = assert false +let print_char = _ => assert false + +type nativeint \ No newline at end of file diff --git a/analysis/examples/larger-project/src/Records.js b/analysis/examples/larger-project/src/Records.js new file mode 100644 index 0000000000..016884c0e2 --- /dev/null +++ b/analysis/examples/larger-project/src/Records.js @@ -0,0 +1,170 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Belt_List from "rescript/lib/es6/belt_List.js"; +import * as Belt_Array from "rescript/lib/es6/belt_Array.js"; +import * as Pervasives from "rescript/lib/es6/pervasives.js"; +import * as Belt_Option from "rescript/lib/es6/belt_Option.js"; +import * as Caml_option from "rescript/lib/es6/caml_option.js"; + +function computeArea(param) { + return Math.imul(Math.imul(param.x, param.y), Belt_Option.mapWithDefault(param.z, 1, (function (n) { + return n; + }))); +} + +function coord2d(x, y) { + return { + x: x, + y: y, + z: undefined + }; +} + +var getOpt = Belt_Option.mapWithDefault; + +function findAddress(business) { + return Belt_Option.mapWithDefault(business.address, /* [] */0, (function (a) { + return { + hd: a, + tl: /* [] */0 + }; + })); +} + +function findAllAddresses(businesses) { + return Belt_List.toArray(Belt_List.flatten(Belt_List.fromArray(Belt_Array.map(businesses, (function (business) { + return Pervasives.$at(Belt_Option.mapWithDefault(business.address, /* [] */0, (function (a) { + return { + hd: a, + tl: /* [] */0 + }; + })), Belt_Option.mapWithDefault(business.owner, /* [] */0, (function (p) { + return Belt_Option.mapWithDefault(p.address, /* [] */0, (function (a) { + return { + hd: a, + tl: /* [] */0 + }; + })); + }))); + }))))); +} + +function getPayload(param) { + return param.payload; +} + +function getPayloadRecord(param) { + return param.payload; +} + +var recordValue = { + v: 1, + w: 1 +}; + +var payloadValue = { + num: 1, + payload: recordValue +}; + +function getPayloadRecordPlusOne(param) { + var payload = param.payload; + return { + v: payload.v + 1 | 0, + w: payload.w + }; +} + +function findAddress2(business) { + return Belt_Option.mapWithDefault(Caml_option.nullable_to_opt(business.address2), /* [] */0, (function (a) { + return { + hd: a, + tl: /* [] */0 + }; + })); +} + +var someBusiness2_owner = null; + +var someBusiness2_address2 = null; + +var someBusiness2 = { + name: "SomeBusiness", + owner: someBusiness2_owner, + address2: someBusiness2_address2 +}; + +function computeArea3(o) { + return Math.imul(Math.imul(o.x, o.y), Belt_Option.mapWithDefault(Caml_option.nullable_to_opt(o.z), 1, (function (n) { + return n; + }))); +} + +function computeArea4(o) { + return Math.imul(Math.imul(o.x, o.y), Belt_Option.mapWithDefault(o.z, 1, (function (n) { + return n; + }))); +} + +function testMyRec(x) { + return x.type_; +} + +function testMyRec2(x) { + return x; +} + +function testMyObj(x) { + return x.type_; +} + +function testMyObj2(x) { + return x; +} + +function testMyRecBsAs(x) { + return x.type; +} + +function testMyRecBsAs2(x) { + return x; +} + +var origin = { + x: 0, + y: 0, + z: 0 +}; + +var someBusiness = { + name: "SomeBusiness", + owner: undefined, + address: undefined +}; + +export { + origin , + computeArea , + coord2d , + getOpt , + findAddress , + someBusiness , + findAllAddresses , + getPayload , + getPayloadRecord , + recordValue , + payloadValue , + getPayloadRecordPlusOne , + findAddress2 , + someBusiness2 , + computeArea3 , + computeArea4 , + testMyRec , + testMyRec2 , + testMyObj , + testMyObj2 , + testMyRecBsAs , + testMyRecBsAs2 , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/Records.res b/analysis/examples/larger-project/src/Records.res new file mode 100644 index 0000000000..e82745e485 --- /dev/null +++ b/analysis/examples/larger-project/src/Records.res @@ -0,0 +1,148 @@ +open Belt + +@genType +type coord = { + x: int, + y: int, + z: option, +} + +@genType +let origin = {x: 0, y: 0, z: Some(0)} + +@genType +let computeArea = ({x, y, z}) => { + open Option + x * y * z->mapWithDefault(1, n => n) +} + +@genType +let coord2d = (x, y) => {x: x, y: y, z: None} + +@genType +type person = { + name: string, + age: int, + address: option, +} + +@genType +type business = { + name: string, + owner: option, + address: option, +} + +let getOpt = (opt, default, foo) => opt->Option.mapWithDefault(default, foo) + +@genType +let findAddress = (business: business): list => + business.address->getOpt(list{}, a => list{a}) + +@genType +let someBusiness = {name: "SomeBusiness", owner: None, address: None} + +@genType +let findAllAddresses = (businesses: array): array => + businesses + ->Array.map(business => + \"@"( + business.address->getOpt(list{}, a => list{a}), + business.owner->getOpt(list{}, p => p.address->getOpt(list{}, a => list{a})), + ) + ) + ->List.fromArray + ->List.flatten + ->List.toArray + +@genType +type payload<'a> = { + num: int, + payload: 'a, +} + +@genType +let getPayload = ({payload}) => payload + +@genType +type record = { + v: int, + w: int, +} + +@genType +let getPayloadRecord = ({payload}): record => payload + +@genType +let recordValue = {v: 1, w: 1} + +@genType +let payloadValue = {num: 1, payload: recordValue} + +@genType +let getPayloadRecordPlusOne = ({payload}): record => { + ...payload, + v: payload.v + 1, +} + +@genType +type business2 = { + name: string, + owner: Js.Nullable.t, + address2: Js.Nullable.t, +} + +@genType +let findAddress2 = (business: business2): list => + business.address2->Js.Nullable.toOption->getOpt(list{}, a => list{a}) + +@genType +let someBusiness2 = { + name: "SomeBusiness", + owner: Js.Nullable.null, + address2: Js.Nullable.null, +} + +@genType +let computeArea3 = (o: {"x": int, "y": int, "z": Js.Nullable.t}) => + o["x"] * o["y"] * o["z"]->Js.Nullable.toOption->Option.mapWithDefault(1, n => n) + +@genType +let computeArea4 = (o: {"x": int, "y": int, "z": option}) => + o["x"] * o["y"] * o["z"]->Option.mapWithDefault(1, n => n) + +@genType +type mix = {"a": int, "b": int, "c": option<{"name": string, "surname": string}>} + +@genType +type myRec = { + @genType.as("type") + type_: string, +} + +@genType +type myObj = {"type_": string} + +@genType +let testMyRec = (x: myRec) => x.type_ + +@genType +let testMyRec2 = (x: myRec) => x + +@genType +let testMyObj = (x: myObj) => x["type_"] + +@genType +let testMyObj2 = (x: myObj) => x + +@genType +type myRecBsAs = { + @as("type") + type_: string, +} + +@genType +let testMyRecBsAs = (x: myRecBsAs) => x.type_ + +@genType +let testMyRecBsAs2 = (x: myRecBsAs) => x diff --git a/analysis/examples/larger-project/src/References.js b/analysis/examples/larger-project/src/References.js new file mode 100644 index 0000000000..41dbd5947a --- /dev/null +++ b/analysis/examples/larger-project/src/References.js @@ -0,0 +1,60 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function create(x) { + return { + contents: x + }; +} + +function access(r) { + return r.contents + 1 | 0; +} + +function update(r) { + r.contents = r.contents + 1 | 0; + +} + +function get(r) { + return r.contents; +} + +function make(prim) { + return { + contents: prim + }; +} + +function set(r, v) { + r.contents = v; + +} + +var R = { + get: get, + make: make, + set: set +}; + +function destroysRefIdentity(x) { + return x; +} + +function preserveRefIdentity(x) { + return x; +} + +export { + create , + access , + update , + R , + get , + make , + set , + destroysRefIdentity , + preserveRefIdentity , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/References.res b/analysis/examples/larger-project/src/References.res new file mode 100644 index 0000000000..fa4ae2bfc9 --- /dev/null +++ b/analysis/examples/larger-project/src/References.res @@ -0,0 +1,47 @@ +// Test pervasive references + +@genType +let create = (x: int) => ref(x) + +@genType +let access = r => r.contents + 1 + +@genType +let update = r => r.contents = r.contents + 1 + +// Abstract version of references: works when conversion is required. + +module R: { + @genType + type t<'a> + let get: t<'a> => 'a + let make: 'a => t<'a> + let set: (t<'a>, 'a) => unit +} = { + type t<'a> = ref<'a> + let get = r => r.contents + let make = ref + let set = (r, v) => r.contents = v +} + +@genType +type t<'a> = R.t<'a> + +@genType +let get = R.get + +@gentype +let make = R.make + +@genType +let set = R.set + +type requiresConversion = {x: int} + +// Careful: conversion makes a copy and destroys the reference identity. +@genType +let destroysRefIdentity = (x: ref) => x + +// Using abstract references preserves the identity. +@genType +let preserveRefIdentity = (x: R.t) => x diff --git a/analysis/examples/larger-project/src/RepeatedLabel.js b/analysis/examples/larger-project/src/RepeatedLabel.js new file mode 100644 index 0000000000..fba30a9dd2 --- /dev/null +++ b/analysis/examples/larger-project/src/RepeatedLabel.js @@ -0,0 +1,17 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function userData(param) { + return { + a: param.a, + b: param.b + }; +} + +console.log(userData); + +export { + userData , + +} +/* Not a pure module */ diff --git a/analysis/examples/larger-project/src/RepeatedLabel.res b/analysis/examples/larger-project/src/RepeatedLabel.res new file mode 100644 index 0000000000..64fda72797 --- /dev/null +++ b/analysis/examples/larger-project/src/RepeatedLabel.res @@ -0,0 +1,14 @@ +type userData = { + a: bool, + b: int, +} + +type tabState = { + a: bool, + b: int, + f: string, +} + +let userData = ({a, b}): userData => {a: a, b: b} + +Js.log(userData) diff --git a/analysis/examples/larger-project/src/RequireCond.js b/analysis/examples/larger-project/src/RequireCond.js new file mode 100644 index 0000000000..d856702bfe --- /dev/null +++ b/analysis/examples/larger-project/src/RequireCond.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/analysis/examples/larger-project/src/RequireCond.res b/analysis/examples/larger-project/src/RequireCond.res new file mode 100644 index 0000000000..b7fdd67a36 --- /dev/null +++ b/analysis/examples/larger-project/src/RequireCond.res @@ -0,0 +1,19 @@ +@module +@deprecated( + "Please use this syntax to guarantee safe usage: [%requireCond(`gk, \"gk_name\", ConditionalModule)]" +) +external make: ( + @string [@as("qe.bool") #qeBool | @as("gk") #gk], + string, + string, +) => Js.Nullable.t<'a> = "requireCond" + +@module +@deprecated( + "Please use this syntax to guarantee safe usage: [%requireCond(`gk, \"gk_name\", {\"true\": ModuleA, \"false\": ModuleB})]" +) +external either: ( + @string [@as("qe.bool") #qeBool | @as("gk") #gk], + string, + {"true": string, "false": string}, +) => 'b = "requireCond" diff --git a/analysis/examples/larger-project/src/Shadow.js b/analysis/examples/larger-project/src/Shadow.js new file mode 100644 index 0000000000..3d1c79858c --- /dev/null +++ b/analysis/examples/larger-project/src/Shadow.js @@ -0,0 +1,21 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function test(param) { + return "a"; +} + +function test$1(param) { + return "a"; +} + +var M = { + test: test$1 +}; + +export { + test , + M , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/Shadow.res b/analysis/examples/larger-project/src/Shadow.res new file mode 100644 index 0000000000..7e6c5542a1 --- /dev/null +++ b/analysis/examples/larger-project/src/Shadow.res @@ -0,0 +1,12 @@ +@genType +let test = () => 3 + +@genType +let test = () => "a" + +module M = { + @genType + let test = () => 3 + + let test = () => "a" +} diff --git a/analysis/examples/larger-project/src/TestDeadExn.js b/analysis/examples/larger-project/src/TestDeadExn.js new file mode 100644 index 0000000000..5d949f4d8f --- /dev/null +++ b/analysis/examples/larger-project/src/TestDeadExn.js @@ -0,0 +1,12 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as DeadExn from "./DeadExn.js"; + +console.log({ + RE_EXN_ID: DeadExn.Etoplevel + }); + +export { + +} +/* Not a pure module */ diff --git a/analysis/examples/larger-project/src/TestDeadExn.res b/analysis/examples/larger-project/src/TestDeadExn.res new file mode 100644 index 0000000000..b1569a222c --- /dev/null +++ b/analysis/examples/larger-project/src/TestDeadExn.res @@ -0,0 +1 @@ +Js.log(DeadExn.Etoplevel) diff --git a/analysis/examples/larger-project/src/TestEmitInnerModules.js b/analysis/examples/larger-project/src/TestEmitInnerModules.js new file mode 100644 index 0000000000..3d1c412ec0 --- /dev/null +++ b/analysis/examples/larger-project/src/TestEmitInnerModules.js @@ -0,0 +1,26 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +var Inner = { + x: 34, + y: "hello" +}; + +var Inner$1 = { + y: 44 +}; + +var Medium = { + Inner: Inner$1 +}; + +var Outer = { + Medium: Medium +}; + +export { + Inner , + Outer , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/TestEmitInnerModules.res b/analysis/examples/larger-project/src/TestEmitInnerModules.res new file mode 100644 index 0000000000..eed5c4fe23 --- /dev/null +++ b/analysis/examples/larger-project/src/TestEmitInnerModules.res @@ -0,0 +1,15 @@ +module Inner = { + @genType + let x = 34 + @genType + let y = "hello" +} + +module Outer = { + module Medium = { + module Inner = { + @genType + let y = 44 + } + } +} diff --git a/analysis/examples/larger-project/src/TestFirstClassModules.js b/analysis/examples/larger-project/src/TestFirstClassModules.js new file mode 100644 index 0000000000..d09433ad8c --- /dev/null +++ b/analysis/examples/larger-project/src/TestFirstClassModules.js @@ -0,0 +1,27 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function convert(x) { + return x; +} + +function convertInterface(x) { + return x; +} + +function convertRecord(x) { + return x; +} + +function convertFirstClassModuleWithTypeEquations(x) { + return x; +} + +export { + convert , + convertInterface , + convertRecord , + convertFirstClassModuleWithTypeEquations , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/TestFirstClassModules.res b/analysis/examples/larger-project/src/TestFirstClassModules.res new file mode 100644 index 0000000000..a799e858ed --- /dev/null +++ b/analysis/examples/larger-project/src/TestFirstClassModules.res @@ -0,0 +1,30 @@ +@genType +let convert = (x: FirstClassModules.firstClassModule) => x + +@genType +let convertInterface = (x: FirstClassModulesInterface.firstClassModule) => x + +@genType +let convertRecord = (x: FirstClassModulesInterface.record) => x + +module type MT = { + type outer + let out: outer => outer + + module Inner: { + type inner + let inn: inner => inner + } +} + +@genType +type firstClassModuleWithTypeEquations<'i, 'o> = module(MT with + type Inner.inner = 'i + and type outer = 'o +) + +@genType +let convertFirstClassModuleWithTypeEquations = ( + type o i, + x: module(MT with type Inner.inner = i and type outer = o), +) => x diff --git a/analysis/examples/larger-project/src/TestImmutableArray.js b/analysis/examples/larger-project/src/TestImmutableArray.js new file mode 100644 index 0000000000..1054678078 --- /dev/null +++ b/analysis/examples/larger-project/src/TestImmutableArray.js @@ -0,0 +1,24 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Belt_Array from "rescript/lib/es6/belt_Array.js"; +import * as Caml_array from "rescript/lib/es6/caml_array.js"; + +function testImmutableArrayGet(arr) { + return Caml_array.get(arr, 3); +} + +function testBeltArrayGet(arr) { + return Belt_Array.get(arr, 3); +} + +function testBeltArraySet(arr) { + return Belt_Array.set(arr, 3, 4); +} + +export { + testImmutableArrayGet , + testBeltArrayGet , + testBeltArraySet , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/TestImmutableArray.res b/analysis/examples/larger-project/src/TestImmutableArray.res new file mode 100644 index 0000000000..d4b49b7a2d --- /dev/null +++ b/analysis/examples/larger-project/src/TestImmutableArray.res @@ -0,0 +1,20 @@ +@genType +let testImmutableArrayGet = arr => { + open ImmutableArray + arr[3] +} + +/* + type error + let testImmutableArraySet = arr => ImmutableArray.(arr[3] = 4); + */ + +let testBeltArrayGet = arr => { + open Belt + arr[3] +} + +let testBeltArraySet = arr => { + open Belt + arr[3] = 4 +} diff --git a/analysis/examples/larger-project/src/TestImport.js b/analysis/examples/larger-project/src/TestImport.js new file mode 100644 index 0000000000..f38c53dbf6 --- /dev/null +++ b/analysis/examples/larger-project/src/TestImport.js @@ -0,0 +1,29 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Caml_option from "rescript/lib/es6/caml_option.js"; +import * as TestImportGen from "./TestImport.gen"; + +var innerStuffContents = TestImportGen.innerStuffContents; + +var innerStuffContentsAsEmptyObject = TestImportGen.innerStuffContentsAsEmptyObject; + +var valueStartingWithUpperCaseLetter = TestImportGen.valueStartingWithUpperCaseLetter; + +var defaultValue = TestImportGen.defaultValue; + +function make(prim0, prim1, prim2) { + return TestImportGen.make(prim0, prim1 !== undefined ? Caml_option.valFromOption(prim1) : undefined, prim2); +} + +var defaultValue2 = TestImportGen.defaultValue2; + +export { + innerStuffContentsAsEmptyObject , + innerStuffContents , + valueStartingWithUpperCaseLetter , + defaultValue , + make , + defaultValue2 , + +} +/* innerStuffContents Not a pure module */ diff --git a/analysis/examples/larger-project/src/TestImport.res b/analysis/examples/larger-project/src/TestImport.res new file mode 100644 index 0000000000..41d3371654 --- /dev/null +++ b/analysis/examples/larger-project/src/TestImport.res @@ -0,0 +1,30 @@ +@genType.import(( + "./exportNestedValues", + "TopLevelClass.MiddleLevelElements.stuff.InnerStuff.innerStuffContents", +)) +external innerStuffContents: {"x": int} = "innerStuffContents" + +@genType.import(( + "./exportNestedValues", + "TopLevelClass.MiddleLevelElements.stuff.InnerStuff.innerStuffContents", +)) +external innerStuffContentsAsEmptyObject: {.} = "innerStuffContentsAsEmptyObject" + +let innerStuffContents = innerStuffContents + +@genType.import(("./exportNestedValues", "ValueStartingWithUpperCaseLetter")) +external valueStartingWithUpperCaseLetter: string = "valueStartingWithUpperCaseLetter" + +@genType.import(("./exportNestedValues", "default")) +external defaultValue: int = "defaultValue" + +@genType +type message = {text: string} + +@genType.import(("./MyBanner", "TopLevelClass.MiddleLevelElements.MyBannerInternal")) +external make: (~show: bool, ~message: option=?, 'a) => React.element = "make" + +let make = make + +@genType.import(("./exportNestedValues", "default")) +external defaultValue2: int = "defaultValue2" diff --git a/analysis/examples/larger-project/src/TestModuleAliases.js b/analysis/examples/larger-project/src/TestModuleAliases.js new file mode 100644 index 0000000000..50564c7a04 --- /dev/null +++ b/analysis/examples/larger-project/src/TestModuleAliases.js @@ -0,0 +1,45 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function testInner1(x) { + return x; +} + +function testInner1Expanded(x) { + return x; +} + +function testInner2(x) { + return x; +} + +function testInner2Expanded(x) { + return x; +} + +var OtherFile; + +var OtherFileAlias; + +var OuterAlias; + +var OtherFile1; + +var Outer2; + +var Inner2; + +export { + OtherFile , + OtherFileAlias , + OuterAlias , + OtherFile1 , + Outer2 , + Inner2 , + testInner1 , + testInner1Expanded , + testInner2 , + testInner2Expanded , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/TestModuleAliases.res b/analysis/examples/larger-project/src/TestModuleAliases.res new file mode 100644 index 0000000000..fff070c4b7 --- /dev/null +++ b/analysis/examples/larger-project/src/TestModuleAliases.res @@ -0,0 +1,41 @@ +module OtherFile = ModuleAliases2 +module OtherFileAlias = OtherFile + +@genType +type record = OtherFile.record + +@genType +type record2 = OtherFileAlias.record + +module OuterAlias = OtherFile.Outer + +@genType +type outer = OtherFileAlias.Outer.outer + +@genType +type outer2 = OuterAlias.outer + +module OtherFile1 = OtherFile +module Outer2 = OtherFile1.Outer +module Inner2 = Outer2.Inner + +@genType +type my2 = Inner2.inner + +@genType +type inner1 = OtherFile.InnerAlias.inner + +@genType +type inner2 = OtherFile.Outer.Inner.inner + +@genType +let testInner1 = (x: inner1) => x + +@genType +let testInner1Expanded = (x: OtherFile.InnerAlias.inner) => x + +@genType +let testInner2 = (x: inner2) => x + +@genType +let testInner2Expanded = (x: OtherFile.Outer.Inner.inner) => x diff --git a/analysis/examples/larger-project/src/TestOptArg.js b/analysis/examples/larger-project/src/TestOptArg.js new file mode 100644 index 0000000000..2369ece082 --- /dev/null +++ b/analysis/examples/larger-project/src/TestOptArg.js @@ -0,0 +1,44 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as OptArg from "./OptArg.js"; + +console.log(OptArg.bar(undefined, 3, 3, 4)); + +function foo(xOpt, y) { + var x = xOpt !== undefined ? xOpt : 3; + return x + y | 0; +} + +function bar(param) { + var x = 12; + return x + 3 | 0; +} + +console.log(bar); + +function notSuppressesOptArgs(xOpt, yOpt, zOpt, w) { + var x = xOpt !== undefined ? xOpt : 1; + var y = yOpt !== undefined ? yOpt : 2; + var z = zOpt !== undefined ? zOpt : 3; + return ((x + y | 0) + z | 0) + w | 0; +} + +notSuppressesOptArgs(undefined, undefined, undefined, 3); + +function liveSuppressesOptArgs(xOpt, yOpt, zOpt, w) { + var x = xOpt !== undefined ? xOpt : 1; + var y = yOpt !== undefined ? yOpt : 2; + var z = zOpt !== undefined ? zOpt : 3; + return ((x + y | 0) + z | 0) + w | 0; +} + +liveSuppressesOptArgs(3, undefined, undefined, 3); + +export { + foo , + bar , + notSuppressesOptArgs , + liveSuppressesOptArgs , + +} +/* Not a pure module */ diff --git a/analysis/examples/larger-project/src/TestOptArg.res b/analysis/examples/larger-project/src/TestOptArg.res new file mode 100644 index 0000000000..ef38c7c7ec --- /dev/null +++ b/analysis/examples/larger-project/src/TestOptArg.res @@ -0,0 +1,16 @@ +Js.log(OptArg.bar(~z=3, ~y=3, 4)) + +let foo = (~x=3, y) => x + y + +let bar = () => foo(~x=12, 3) + +Js.log(bar) + +let notSuppressesOptArgs = (~x=1, ~y=2, ~z=3, w) => x + y + z + w + +let _ = notSuppressesOptArgs(3) + +@live +let liveSuppressesOptArgs = (~x=1, ~y=2, ~z=3, w) => x + y + z + w + +let _ = liveSuppressesOptArgs(~x=3, 3) diff --git a/analysis/examples/larger-project/src/TestPromise.js b/analysis/examples/larger-project/src/TestPromise.js new file mode 100644 index 0000000000..0289ad50c0 --- /dev/null +++ b/analysis/examples/larger-project/src/TestPromise.js @@ -0,0 +1,16 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function convert(param) { + return param.then(function (param) { + return Promise.resolve({ + result: param.s + }); + }); +} + +export { + convert , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/TestPromise.res b/analysis/examples/larger-project/src/TestPromise.res new file mode 100644 index 0000000000..acf835948e --- /dev/null +++ b/analysis/examples/larger-project/src/TestPromise.res @@ -0,0 +1,14 @@ +@genType +type promise<'a> = Js.Promise.t<'a> + +@genType +type fromPayload = { + x: int, + s: string, +} + +@genType +type toPayload = {result: string} + +@genType +let convert = Js.Promise.then_(({s}) => Js.Promise.resolve({result: s})) diff --git a/analysis/examples/larger-project/src/ToSuppress.js b/analysis/examples/larger-project/src/ToSuppress.js new file mode 100644 index 0000000000..b16279a286 --- /dev/null +++ b/analysis/examples/larger-project/src/ToSuppress.js @@ -0,0 +1,10 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +var toSuppress = 0; + +export { + toSuppress , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/ToSuppress.res b/analysis/examples/larger-project/src/ToSuppress.res new file mode 100644 index 0000000000..e21f46451b --- /dev/null +++ b/analysis/examples/larger-project/src/ToSuppress.res @@ -0,0 +1 @@ +let toSuppress = 0 diff --git a/analysis/examples/larger-project/src/TransitiveType1.js b/analysis/examples/larger-project/src/TransitiveType1.js new file mode 100644 index 0000000000..fb6d4e9f36 --- /dev/null +++ b/analysis/examples/larger-project/src/TransitiveType1.js @@ -0,0 +1,17 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function convert(x) { + return x; +} + +function convertAlias(x) { + return x; +} + +export { + convert , + convertAlias , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/TransitiveType1.res b/analysis/examples/larger-project/src/TransitiveType1.res new file mode 100644 index 0000000000..3d16c5e3b9 --- /dev/null +++ b/analysis/examples/larger-project/src/TransitiveType1.res @@ -0,0 +1,5 @@ +@genType +let convert = (x: TransitiveType2.t2) => x + +@genType +let convertAlias = (x: TransitiveType2.t2Alias) => x diff --git a/analysis/examples/larger-project/src/TransitiveType2.js b/analysis/examples/larger-project/src/TransitiveType2.js new file mode 100644 index 0000000000..e0bcc1c485 --- /dev/null +++ b/analysis/examples/larger-project/src/TransitiveType2.js @@ -0,0 +1,12 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function convertT2(x) { + return x; +} + +export { + convertT2 , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/TransitiveType2.res b/analysis/examples/larger-project/src/TransitiveType2.res new file mode 100644 index 0000000000..a0adb89742 --- /dev/null +++ b/analysis/examples/larger-project/src/TransitiveType2.res @@ -0,0 +1,7 @@ +@genType +type t2 = option + +@genType +type t2Alias = t2 + +let convertT2 = (x: t2) => x diff --git a/analysis/examples/larger-project/src/TransitiveType3.js b/analysis/examples/larger-project/src/TransitiveType3.js new file mode 100644 index 0000000000..c28c6fa11b --- /dev/null +++ b/analysis/examples/larger-project/src/TransitiveType3.js @@ -0,0 +1,12 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function convertT3(x) { + return x; +} + +export { + convertT3 , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/TransitiveType3.res b/analysis/examples/larger-project/src/TransitiveType3.res new file mode 100644 index 0000000000..0e561b0cbb --- /dev/null +++ b/analysis/examples/larger-project/src/TransitiveType3.res @@ -0,0 +1,8 @@ +@genType +type t3 = { + i: int, + s: string, +} + +@genType +let convertT3 = (x: t3) => x diff --git a/analysis/examples/larger-project/src/Tuples.js b/analysis/examples/larger-project/src/Tuples.js new file mode 100644 index 0000000000..3e1475545e --- /dev/null +++ b/analysis/examples/larger-project/src/Tuples.js @@ -0,0 +1,73 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Belt_Option from "rescript/lib/es6/belt_Option.js"; + +function testTuple(param) { + return param[0] + param[1] | 0; +} + +function computeArea(param) { + return Math.imul(Math.imul(param[0], param[1]), Belt_Option.mapWithDefault(param[2], 1, (function (n) { + return n; + }))); +} + +function computeAreaWithIdent(param) { + return Math.imul(Math.imul(param[0], param[1]), Belt_Option.mapWithDefault(param[2], 1, (function (n) { + return n; + }))); +} + +function computeAreaNoConverters(param) { + return Math.imul(param[0], param[1]); +} + +function coord2d(x, y) { + return [ + x, + y, + undefined + ]; +} + +function getFirstName(param) { + return param[0].name; +} + +function marry(first, second) { + return [ + first, + second + ]; +} + +function changeSecondAge(param) { + var second = param[1]; + return [ + param[0], + { + name: second.name, + age: second.age + 1 | 0 + } + ]; +} + +var origin = [ + 0, + 0, + 0 +]; + +export { + testTuple , + origin , + computeArea , + computeAreaWithIdent , + computeAreaNoConverters , + coord2d , + getFirstName , + marry , + changeSecondAge , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/Tuples.res b/analysis/examples/larger-project/src/Tuples.res new file mode 100644 index 0000000000..e38ce79a85 --- /dev/null +++ b/analysis/examples/larger-project/src/Tuples.res @@ -0,0 +1,49 @@ +open Belt + +@genType +let testTuple = ((a, b)) => a + b + +@genType +type coord = (int, int, option) + +@genType +let origin = (0, 0, Some(0)) + +@genType +let computeArea = ((x, y, z)) => { + open Option + x * y * z->mapWithDefault(1, n => n) +} + +@genType +let computeAreaWithIdent = ((x, y, z): coord) => { + open Option + x * y * z->mapWithDefault(1, n => n) +} + +@genType +let computeAreaNoConverters = ((x: int, y: int)) => x * y + +@genType +let coord2d = (x, y) => (x, y, None) + +@genType +type coord2 = (int, int, Js.Nullable.t) + +@genType +type person = { + name: string, + age: int, +} + +@genType +type couple = (person, person) + +@genType +let getFirstName = ((first, _second): couple) => first.name + +@genType +let marry = (first, second): couple => (first, second) + +@genType +let changeSecondAge = ((first, second): couple): couple => (first, {...second, age: second.age + 1}) diff --git a/analysis/examples/larger-project/src/TypeParams1.js b/analysis/examples/larger-project/src/TypeParams1.js new file mode 100644 index 0000000000..32eae0619e --- /dev/null +++ b/analysis/examples/larger-project/src/TypeParams1.js @@ -0,0 +1,10 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +var exportSomething = 10; + +export { + exportSomething , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/TypeParams1.res b/analysis/examples/larger-project/src/TypeParams1.res new file mode 100644 index 0000000000..2e51defff8 --- /dev/null +++ b/analysis/examples/larger-project/src/TypeParams1.res @@ -0,0 +1,4 @@ +@gentype +type ocaml_array<'a> = array<'a> + +let exportSomething = 10 diff --git a/analysis/examples/larger-project/src/TypeParams2.js b/analysis/examples/larger-project/src/TypeParams2.js new file mode 100644 index 0000000000..32eae0619e --- /dev/null +++ b/analysis/examples/larger-project/src/TypeParams2.js @@ -0,0 +1,10 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +var exportSomething = 10; + +export { + exportSomething , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/TypeParams2.res b/analysis/examples/larger-project/src/TypeParams2.res new file mode 100644 index 0000000000..f6a2ec0b0c --- /dev/null +++ b/analysis/examples/larger-project/src/TypeParams2.res @@ -0,0 +1,10 @@ +@genType +type item = {id: int} + +@genType +type items = TypeParams1.ocaml_array + +@genType +type items2 = array + +let exportSomething = 10 diff --git a/analysis/examples/larger-project/src/TypeParams3.js b/analysis/examples/larger-project/src/TypeParams3.js new file mode 100644 index 0000000000..5cca982d84 --- /dev/null +++ b/analysis/examples/larger-project/src/TypeParams3.js @@ -0,0 +1,17 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function test(x) { + return x; +} + +function test2(x) { + return x; +} + +export { + test , + test2 , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/TypeParams3.res b/analysis/examples/larger-project/src/TypeParams3.res new file mode 100644 index 0000000000..6fd0044688 --- /dev/null +++ b/analysis/examples/larger-project/src/TypeParams3.res @@ -0,0 +1,5 @@ +@genType +let test = (x: TypeParams2.items) => x + +@genType +let test2 = (x: TypeParams2.items2) => x diff --git a/analysis/examples/larger-project/src/Types.js b/analysis/examples/larger-project/src/Types.js new file mode 100644 index 0000000000..5931d70cbb --- /dev/null +++ b/analysis/examples/larger-project/src/Types.js @@ -0,0 +1,109 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as List from "rescript/lib/es6/list.js"; +import * as Curry from "rescript/lib/es6/curry.js"; +import * as Belt_Option from "rescript/lib/es6/belt_Option.js"; + +function swap(tree) { + return { + label: tree.label, + left: Belt_Option.map(tree.right, swap), + right: Belt_Option.map(tree.left, swap) + }; +} + +function selfRecursiveConverter(param) { + return param.self; +} + +function mutuallyRecursiveConverter(param) { + return param.b; +} + +function testFunctionOnOptionsAsArgument(a, foo) { + return Curry._1(foo, a); +} + +function jsonStringify(prim) { + return JSON.stringify(prim); +} + +function testConvertNull(x) { + return x; +} + +var testMarshalFields = { + rec: "rec", + _switch: "_switch", + switch: "switch", + __: "__", + _: "_", + foo: "foo", + _foo: "_foo", + Uppercase: "Uppercase", + _Uppercase: "_Uppercase" +}; + +function setMatch(x) { + x.match = 34; + +} + +function testInstantiateTypeParameter(x) { + return x; +} + +var currentTime = new Date(); + +var optFunction = (function (param) { + return 3; + }); + +var ObjectId = {}; + +var someIntList = { + hd: 1, + tl: { + hd: 2, + tl: { + hd: 3, + tl: /* [] */0 + } + } +}; + +var map = List.map; + +var stringT = "a"; + +var jsStringT = "a"; + +var jsString2T = "a"; + +var i64Const = [ + 0, + 34 +]; + +export { + someIntList , + map , + swap , + selfRecursiveConverter , + mutuallyRecursiveConverter , + testFunctionOnOptionsAsArgument , + stringT , + jsStringT , + jsString2T , + jsonStringify , + testConvertNull , + testMarshalFields , + setMatch , + testInstantiateTypeParameter , + currentTime , + i64Const , + optFunction , + ObjectId , + +} +/* currentTime Not a pure module */ diff --git a/analysis/examples/larger-project/src/Types.res b/analysis/examples/larger-project/src/Types.res new file mode 100644 index 0000000000..ee398c1fff --- /dev/null +++ b/analysis/examples/larger-project/src/Types.res @@ -0,0 +1,167 @@ +@genType +type t = int + +@genType +let someIntList = list{1, 2, 3} + +@genType +let map = List.map + +@genType +type typeWithVars<'x, 'y, 'z> = + | A('x, 'y) + | B('z) + +@genType +type rec tree = {"label": string, "left": option, "right": option} + +/* + * A tree is a recursive type which does not require any conversion (JS object). + * All is well. + */ +@genType +let rec swap = (tree: tree): tree => + { + "label": tree["label"], + "left": tree["right"]->Belt.Option.map(swap), + "right": tree["left"]->Belt.Option.map(swap), + } + +@genType +type rec selfRecursive = {self: selfRecursive} + +@genType +type rec mutuallyRecursiveA = {b: mutuallyRecursiveB} +and mutuallyRecursiveB = {a: mutuallyRecursiveA} + +/* + * This is a recursive type which requires conversion (a record). + * Only a shallow conversion of the top-level element is performed. + */ +@genType +let selfRecursiveConverter = ({self}) => self + +/* + * This is a mutually recursive type which requires conversion (a record). + * Only a shallow conversion of the two top-level elements is performed. + */ +@genType +let mutuallyRecursiveConverter = ({b}) => b + +@genType +let testFunctionOnOptionsAsArgument = (a: option<'a>, foo) => foo(a) + +@genType.opaque +type opaqueVariant = + | A + | B + +@genType +let stringT: String.t = "a" + +@genType +let jsStringT: Js.String.t = "a" + +@genType +let jsString2T: Js.String2.t = "a" + +@genType +type twice<'a> = ('a, 'a) + +@gentype +type genTypeMispelled = int + +@genType +type dictString = Js.Dict.t + +@genType +let jsonStringify = Js.Json.stringify + +@genType +type nullOrString = Js.Null.t + +@genType +type nullOrString2 = Js.null + +type record = { + i: int, + s: string, +} + +@genType +let testConvertNull = (x: Js.Null.t) => x + +@genType +type decorator<'a, 'b> = 'a => 'b constraint 'a = int constraint 'b = _ => _ + +/* Bucklescript's marshaling rules. */ +@genType +type marshalFields = { + "_rec": string, + "_switch": string, + "switch": string, + "__": string, + "___": string, + "foo__": string, + "_foo__": string, + "_Uppercase": string, + "_Uppercase__": string, +} + +@genType +let testMarshalFields: marshalFields = { + "_rec": "rec", + "_switch" /* reason keywords are not recognized */: "_switch", + "switch": "switch", + "__": "__", + "___": "_", + "foo__": "foo", + "_foo__": "_foo", + "_Uppercase": "Uppercase", + "_Uppercase__": "_Uppercase", +} + +@genType +type marshalMutableField = {@set "_match": int} + +@genType +let setMatch = (x: marshalMutableField) => x["_match"] = 34 + +type ocaml_array<'a> = array<'a> + +// This should be considered annotated automatically. +type someRecord = {id: int} + +type instantiateTypeParameter = ocaml_array + +@genType +let testInstantiateTypeParameter = (x: instantiateTypeParameter) => x + +@genType @genType.as("Vector") +type vector<'a> = ('a, 'a) + +@genType +type date = Js.Date.t + +@genType +let currentTime = Js.Date.make() + +@genType +type i64A = Int64.t + +@genType +type i64B = int64 + +@genType +let i64Const: i64B = 34L + +@genType +let optFunction = Some(() => 3) + +module ObjectId: { + @genType + type t = int +} = { + type t = int + let x = 1 +} diff --git a/analysis/examples/larger-project/src/Unboxed.js b/analysis/examples/larger-project/src/Unboxed.js new file mode 100644 index 0000000000..ff72d52a52 --- /dev/null +++ b/analysis/examples/larger-project/src/Unboxed.js @@ -0,0 +1,17 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function testV1(x) { + return x; +} + +function r2Test(x) { + return x; +} + +export { + testV1 , + r2Test , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/Unboxed.res b/analysis/examples/larger-project/src/Unboxed.res new file mode 100644 index 0000000000..fdc9c03bfb --- /dev/null +++ b/analysis/examples/larger-project/src/Unboxed.res @@ -0,0 +1,17 @@ +@genType @ocaml.unboxed +type v1 = A(int) + +@genType @unboxed +type v2 = A(int) + +@genType +let testV1 = (x: v1) => x + +@genType @unboxed +type r1 = {x: int} + +@genType @ocaml.unboxed +type r2 = B({g: string}) + +@genType +let r2Test = (x: r2) => x diff --git a/analysis/examples/larger-project/src/Uncurried.js b/analysis/examples/larger-project/src/Uncurried.js new file mode 100644 index 0000000000..1ab5858635 --- /dev/null +++ b/analysis/examples/larger-project/src/Uncurried.js @@ -0,0 +1,80 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Curry from "rescript/lib/es6/curry.js"; + +function uncurried0() { + return ""; +} + +function uncurried1(x) { + return String(x); +} + +function uncurried2(x, y) { + return String(x) + y; +} + +function uncurried3(x, y, z) { + return String(x) + (y + String(z)); +} + +function curried3(x, y, z) { + return String(x) + (y + String(z)); +} + +function callback(cb) { + return String(Curry._1(cb, undefined)); +} + +function callback2(auth) { + return Curry._1(auth.login, undefined); +} + +function callback2U(auth) { + return auth.loginU(); +} + +function sumU(n, m) { + console.log("sumU 2nd arg", m, "result", n + m | 0); + +} + +function sumU2(n) { + return function (m) { + console.log("sumU2 2nd arg", m, "result", n + m | 0); + + }; +} + +function sumCurried(n) { + console.log("sumCurried 1st arg", n); + return function (m) { + console.log("sumCurried 2nd arg", m, "result", n + m | 0); + + }; +} + +function sumLblCurried(s, n) { + console.log(s, "sumLblCurried 1st arg", n); + return function (m) { + console.log("sumLblCurried 2nd arg", m, "result", n + m | 0); + + }; +} + +export { + uncurried0 , + uncurried1 , + uncurried2 , + uncurried3 , + curried3 , + callback , + callback2 , + callback2U , + sumU , + sumU2 , + sumCurried , + sumLblCurried , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/Uncurried.res b/analysis/examples/larger-project/src/Uncurried.res new file mode 100644 index 0000000000..641a8b6f6a --- /dev/null +++ b/analysis/examples/larger-project/src/Uncurried.res @@ -0,0 +1,56 @@ +@genType +type u0 = (. unit) => string + +@genType +type u1 = (. int) => string + +@genType +type u2 = (. int, string) => string + +@genType +type u3 = (. int, string, int) => string + +@genType +let uncurried0 = (. ()) => "" + +@genType +let uncurried1 = (. x) => x |> string_of_int + +@genType +let uncurried2 = (. x, y) => (x |> string_of_int) ++ y + +@genType +let uncurried3 = (. x, y, z) => (x |> string_of_int) ++ (y ++ (z |> string_of_int)) + +@genType +let curried3 = (x, y, z) => (x |> string_of_int) ++ (y ++ (z |> string_of_int)) + +@genType +let callback = cb => cb() |> string_of_int + +type auth = {login: unit => string} +type authU = {loginU: (. unit) => string} + +@genType +let callback2 = auth => auth.login() + +@genType +let callback2U = auth => auth.loginU(.) + +@genType +let sumU = (. n, m) => Js.log4("sumU 2nd arg", m, "result", n + m) + +@genType +let sumU2 = (. n, . m) => Js.log4("sumU2 2nd arg", m, "result", n + m) + +@genType +let sumCurried = n => { + Js.log2("sumCurried 1st arg", n) + m => Js.log4("sumCurried 2nd arg", m, "result", n + m) +} + +@genType +let sumLblCurried = (s: string, ~n) => { + Js.log3(s, "sumLblCurried 1st arg", n) + (~m) => Js.log4("sumLblCurried 2nd arg", m, "result", n + m) +} diff --git a/analysis/examples/larger-project/src/Unison.js b/analysis/examples/larger-project/src/Unison.js new file mode 100644 index 0000000000..1be71e8162 --- /dev/null +++ b/analysis/examples/larger-project/src/Unison.js @@ -0,0 +1,76 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function group(breakOpt, doc) { + var $$break = breakOpt !== undefined ? breakOpt : /* IfNeed */0; + return { + break: $$break, + doc: doc + }; +} + +function fits(_w, _stack) { + while(true) { + var stack = _stack; + var w = _w; + if (w < 0) { + return false; + } + if (!stack) { + return true; + } + _stack = stack._1; + _w = w - stack._0.doc.length | 0; + continue ; + }; +} + +function toString(width, stack) { + if (!stack) { + return ""; + } + var stack$1 = stack._1; + var match = stack._0; + var doc = match.doc; + switch (match.break) { + case /* IfNeed */0 : + return ( + fits(width, stack$1) ? "fits " : "no " + ) + toString(width - 1 | 0, stack$1); + case /* Never */1 : + return "never " + (doc + toString(width - 1 | 0, stack$1)); + case /* Always */2 : + return "always " + (doc + toString(width - 1 | 0, stack$1)); + + } +} + +toString(80, /* Empty */0); + +var $$break = /* Never */1; + +toString(80, /* Cons */{ + _0: { + break: $$break, + doc: "abc" + }, + _1: /* Empty */0 + }); + +var $$break$1 = /* Always */2; + +toString(80, /* Cons */{ + _0: { + break: $$break$1, + doc: "d" + }, + _1: /* Empty */0 + }); + +export { + group , + fits , + toString , + +} +/* Not a pure module */ diff --git a/analysis/examples/larger-project/src/Unison.res b/analysis/examples/larger-project/src/Unison.res new file mode 100644 index 0000000000..cfef1fa1d3 --- /dev/null +++ b/analysis/examples/larger-project/src/Unison.res @@ -0,0 +1,39 @@ +// Exmple of several DCE checks operating in unison + +type break = + | IfNeed + | Never + | Always + +type t = { + break: break, + doc: string, +} + +type rec stack = + | Empty + | Cons(t, stack) + +let group = (~break=IfNeed, doc) => {break: break, doc: doc} + +let rec fits = (w, stack) => + switch stack { + | _ if w < 0 => false + | Empty => true + | Cons({doc}, stack) => fits(w - String.length(doc), stack) + } + +let rec toString = (~width, stack) => + switch stack { + | Cons({break, doc}, stack) => + switch break { + | IfNeed => (fits(width, stack) ? "fits " : "no ") ++ (stack |> toString(~width=width - 1)) + | Never => "never " ++ (doc ++ (stack |> toString(~width=width - 1))) + | Always => "always " ++ (doc ++ (stack |> toString(~width=width - 1))) + } + | Empty => "" + } + +toString(~width=80, Empty) +toString(~width=80, Cons(group(~break=Never, "abc"), Empty)) +toString(~width=80, Cons(group(~break=Always, "d"), Empty)) diff --git a/analysis/examples/larger-project/src/UseImportJsValue.js b/analysis/examples/larger-project/src/UseImportJsValue.js new file mode 100644 index 0000000000..45a04b55f1 --- /dev/null +++ b/analysis/examples/larger-project/src/UseImportJsValue.js @@ -0,0 +1,17 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function useGetProp(x) { + return x.getProp() + 1 | 0; +} + +function useTypeImportedInOtherModule(x) { + return x; +} + +export { + useGetProp , + useTypeImportedInOtherModule , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/UseImportJsValue.res b/analysis/examples/larger-project/src/UseImportJsValue.res new file mode 100644 index 0000000000..08d9aee52a --- /dev/null +++ b/analysis/examples/larger-project/src/UseImportJsValue.res @@ -0,0 +1,5 @@ +@genType +let useGetProp = (x: ImportJsValue.AbsoluteValue.t) => x->ImportJsValue.AbsoluteValue.getProp + 1 + +@genType +let useTypeImportedInOtherModule = (x: ImportJsValue.stringFunction) => x diff --git a/analysis/examples/larger-project/src/Variants.js b/analysis/examples/larger-project/src/Variants.js new file mode 100644 index 0000000000..925f338310 --- /dev/null +++ b/analysis/examples/larger-project/src/Variants.js @@ -0,0 +1,107 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function isWeekend(x) { + if (x === "sunday") { + return true; + } else { + return x === "saturday"; + } +} + +function onlySunday(param) { + +} + +function swap(x) { + if (x === "sunday") { + return "saturday"; + } else { + return "sunday"; + } +} + +function testConvert(x) { + return x; +} + +function testConvert2(x) { + return x; +} + +function testConvert3(x) { + return x; +} + +function testConvert2to3(x) { + return x; +} + +function id1(x) { + return x; +} + +function id2(x) { + return x; +} + +function polyWithOpt(foo) { + if (foo === "bar") { + return ; + } else if (foo !== "baz") { + return { + NAME: "One", + VAL: foo + }; + } else { + return { + NAME: "Two", + VAL: 1 + }; + } +} + +function restResult1(x) { + return x; +} + +function restResult2(x) { + return x; +} + +function restResult3(x) { + return x; +} + +var monday = "monday"; + +var saturday = "saturday"; + +var sunday = "sunday"; + +var fortytwoOK = "fortytwo"; + +var fortytwoBAD = "fortytwo"; + +export { + isWeekend , + monday , + saturday , + sunday , + onlySunday , + swap , + testConvert , + fortytwoOK , + fortytwoBAD , + testConvert2 , + testConvert3 , + testConvert2to3 , + id1 , + id2 , + polyWithOpt , + restResult1 , + restResult2 , + restResult3 , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/Variants.res b/analysis/examples/larger-project/src/Variants.res new file mode 100644 index 0000000000..247a883a6b --- /dev/null +++ b/analysis/examples/larger-project/src/Variants.res @@ -0,0 +1,118 @@ +@genType +type weekday = [ + | #monday + | #tuesday + | #wednesday + | #thursday + | #friday + | #saturday + | #sunday +] + +@genType +let isWeekend = (x: weekday) => + switch x { + | #saturday + | #sunday => true + | _ => false + } + +@genType +let monday = #monday +@genType +let saturday = #saturday +@genType +let sunday = #sunday + +@genType +let onlySunday = (_: [#sunday]) => () + +@genType +let swap = x => + switch x { + | #sunday => #saturday + | #saturday => #sunday + } + +@genType +type testGenTypeAs = [ + | @genType.as("type") #type_ + | @genType.as("module") #module_ + | @genType.as("42") #fortytwo +] + +@genType +let testConvert = (x: testGenTypeAs) => x + +@genType +let fortytwoOK: testGenTypeAs = #fortytwo + +/* Exporting this is BAD: type inference means it's not mapped to "42" */ +@genType +let fortytwoBAD = #fortytwo + +@genType +type testGenTypeAs2 = [ + | @genType.as("type") #type_ + | @genType.as("module") #module_ + | @genType.as("42") #fortytwo +] + +/* Since testGenTypeAs2 is the same type as testGenTypeAs1, + share the conversion map. */ +@genType +let testConvert2 = (x: testGenTypeAs2) => x + +@genType +type testGenTypeAs3 = [ + | @genType.as("type") #type_ + | @genType.as("module") #module_ + | @genType.as("THIS IS DIFFERENT") #fortytwo +] + +/* Since testGenTypeAs3 has a different representation: + use a new conversion map. */ +@genType +let testConvert3 = (x: testGenTypeAs3) => x + +/* This converts between testGenTypeAs2 and testGenTypeAs3 */ +@genType +let testConvert2to3 = (x: testGenTypeAs2): testGenTypeAs3 => x + +@genType +type x1 = [#x | @genType.as("same") #x1] + +@genType +type x2 = [#x | @genType.as("same") #x2] + +@genType +let id1 = (x: x1) => x + +@genType +let id2 = (x: x2) => x + +@genType @genType.as("type") +type type_ = | @genType.as("type") Type + +@genType +let polyWithOpt = foo => foo === "bar" ? None : foo !== "baz" ? Some(#One(foo)) : Some(#Two(1)) + +@genType +type result1<'a, 'b> = + | Ok('a) + | Error('b) + +@genType +type result2<'a, 'b> = result<'a, 'b> + +@genType +type result3<'a, 'b> = Belt.Result.t<'a, 'b> + +@genType +let restResult1 = (x: result1) => x + +@genType +let restResult2 = (x: result2) => x + +@genType +let restResult3 = (x: result3) => x diff --git a/analysis/examples/larger-project/src/VariantsWithPayload.js b/analysis/examples/larger-project/src/VariantsWithPayload.js new file mode 100644 index 0000000000..a04a25a65a --- /dev/null +++ b/analysis/examples/larger-project/src/VariantsWithPayload.js @@ -0,0 +1,99 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function testWithPayload(x) { + return x; +} + +function printVariantWithPayload(x) { + if (typeof x !== "object") { + if (x === "a") { + console.log("printVariantWithPayload: a"); + } else if (x === "b") { + console.log("printVariantWithPayload: b"); + } else if (x === "Half") { + console.log("printVariantWithPayload: Half"); + } else if (x === "True") { + console.log("printVariantWithPayload: True"); + } else { + console.log("printVariantWithPayload: Twenty"); + } + return ; + } + var payload = x.VAL; + console.log("printVariantWithPayload x:", payload.x, "y:", payload.y); + +} + +function testManyPayloads(x) { + return x; +} + +function printManyPayloads(x) { + var variant = x.NAME; + if (variant === "two") { + var match = x.VAL; + console.log("printManyPayloads two:", match[0], match[1]); + return ; + } + if (variant === "three") { + var payload = x.VAL; + console.log("printManyPayloads x:", payload.x, "y:", payload.y); + return ; + } + console.log("printManyPayloads one:", x.VAL); + +} + +function testSimpleVariant(x) { + return x; +} + +function testVariantWithPayloads(x) { + return x; +} + +function printVariantWithPayloads(x) { + if (typeof x === "number") { + console.log("printVariantWithPayloads", "A"); + return ; + } + switch (x.TAG | 0) { + case /* B */0 : + console.log("printVariantWithPayloads", "B(" + (String(x._0) + ")")); + return ; + case /* C */1 : + console.log("printVariantWithPayloads", "C(" + (String(x._0) + (", " + (String(x._1) + ")")))); + return ; + case /* D */2 : + var match = x._0; + console.log("printVariantWithPayloads", "D((" + (String(match[0]) + (", " + (String(match[1]) + "))")))); + return ; + case /* E */3 : + console.log("printVariantWithPayloads", "E(" + (String(x._0) + (", " + (x._1 + (", " + (String(x._2) + ")")))))); + return ; + + } +} + +function testVariant1Int(x) { + return x; +} + +function testVariant1Object(x) { + return x; +} + +export { + testWithPayload , + printVariantWithPayload , + testManyPayloads , + printManyPayloads , + testSimpleVariant , + testVariantWithPayloads , + printVariantWithPayloads , + testVariant1Int , + testVariant1Object , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/VariantsWithPayload.res b/analysis/examples/larger-project/src/VariantsWithPayload.res new file mode 100644 index 0000000000..2252fa3da5 --- /dev/null +++ b/analysis/examples/larger-project/src/VariantsWithPayload.res @@ -0,0 +1,99 @@ +type payload = { + x: int, + y: option, +} + +type withPayload = [ + | #a + | @genType.as("bRenamed") #b + | @genType.as(true) #True + | @genType.as(20) #Twenty + | @genType.as(0.5) #Half + | #c(payload) +] + +@genType +let testWithPayload = (x: withPayload) => x + +@genType +let printVariantWithPayload = (x: withPayload) => + switch x { + | #a => Js.log("printVariantWithPayload: a") + | #b => Js.log("printVariantWithPayload: b") + | #True => Js.log("printVariantWithPayload: True") + | #Twenty => Js.log("printVariantWithPayload: Twenty") + | #Half => Js.log("printVariantWithPayload: Half") + | #c(payload) => Js.log4("printVariantWithPayload x:", payload.x, "y:", payload.y) + } + +@genType +type manyPayloads = [ + | @genType.as("oneRenamed") #one(int) + | @genType.as(2) #two(string, string) + | #three(payload) +] + +@genType +let testManyPayloads = (x: manyPayloads) => x + +@genType +let printManyPayloads = (x: manyPayloads) => + switch x { + | #one(n) => Js.log2("printManyPayloads one:", n) + | #two(s1, s2) => Js.log3("printManyPayloads two:", s1, s2) + | #three(payload) => Js.log4("printManyPayloads x:", payload.x, "y:", payload.y) + } + +@genType +type simpleVariant = + | A + | B + | C + +@genType +let testSimpleVariant = (x: simpleVariant) => x + +@genType +type variantWithPayloads = + | @genType.as("ARenamed") A + | B(int) + | C(int, int) + | D((int, int)) + | E(int, string, int) + +@genType +let testVariantWithPayloads = (x: variantWithPayloads) => x + +@genType +let printVariantWithPayloads = x => + switch x { + | A => Js.log2("printVariantWithPayloads", "A") + | B(x) => Js.log2("printVariantWithPayloads", "B(" ++ (string_of_int(x) ++ ")")) + | C(x, y) => + Js.log2( + "printVariantWithPayloads", + "C(" ++ (string_of_int(x) ++ (", " ++ (string_of_int(y) ++ ")"))), + ) + | D((x, y)) => + Js.log2( + "printVariantWithPayloads", + "D((" ++ (string_of_int(x) ++ (", " ++ (string_of_int(y) ++ "))"))), + ) + | E(x, s, y) => + Js.log2( + "printVariantWithPayloads", + "E(" ++ (string_of_int(x) ++ (", " ++ (s ++ (", " ++ (string_of_int(y) ++ ")"))))), + ) + } + +@genType +type variant1Int = R(int) + +@genType +let testVariant1Int = (x: variant1Int) => x + +@genType +type variant1Object = R(payload) + +@genType +let testVariant1Object = (x: variant1Object) => x diff --git a/analysis/examples/larger-project/src/arg_helper.js b/analysis/examples/larger-project/src/arg_helper.js new file mode 100644 index 0000000000..41b8395517 --- /dev/null +++ b/analysis/examples/larger-project/src/arg_helper.js @@ -0,0 +1,229 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as List from "rescript/lib/es6/list.js"; +import * as Curry from "rescript/lib/es6/curry.js"; +import * as Printf from "./printf.js"; +import * as $$String from "rescript/lib/es6/string.js"; +import * as Printexc from "rescript/lib/es6/printexc.js"; +import * as Pervasives from "rescript/lib/es6/pervasives.js"; +import * as Caml_option from "rescript/lib/es6/caml_option.js"; +import * as Caml_exceptions from "rescript/lib/es6/caml_exceptions.js"; +import * as Caml_js_exceptions from "rescript/lib/es6/caml_js_exceptions.js"; + +function fatal(err) { + console.error(err); + return Pervasives.exit(2); +} + +function Make(S) { + var $$default = function (v) { + return { + base_default: v, + base_override: S.Key.$$Map.empty, + user_default: undefined, + user_override: S.Key.$$Map.empty + }; + }; + var set_base_default = function (value, t) { + return { + base_default: value, + base_override: t.base_override, + user_default: t.user_default, + user_override: t.user_override + }; + }; + var add_base_override = function (key, value, t) { + return { + base_default: t.base_default, + base_override: Curry._3(S.Key.$$Map.add, key, value, t.base_override), + user_default: t.user_default, + user_override: t.user_override + }; + }; + var reset_base_overrides = function (t) { + return { + base_default: t.base_default, + base_override: S.Key.$$Map.empty, + user_default: t.user_default, + user_override: t.user_override + }; + }; + var set_user_default = function (value, t) { + return { + base_default: t.base_default, + base_override: t.base_override, + user_default: Caml_option.some(value), + user_override: t.user_override + }; + }; + var add_user_override = function (key, value, t) { + return { + base_default: t.base_default, + base_override: t.base_override, + user_default: t.user_default, + user_override: Curry._3(S.Key.$$Map.add, key, value, t.user_override) + }; + }; + var Parse_failure = /* @__PURE__ */Caml_exceptions.create("Arg_helper.Make(S).Parse_failure"); + var parse_exn = function (str, update) { + var values = List.filter(function (param) { + return "" !== param; + })($$String.split_on_char(/* ',' */44, str)); + var parsed = List.fold_left((function (acc, value) { + var equals; + try { + equals = $$String.index(value, /* '=' */61); + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === "Not_found") { + var exit = 0; + var value$1; + try { + value$1 = Curry._1(S.Value.of_string, value); + exit = 2; + } + catch (raw_exn$1){ + var exn$1 = Caml_js_exceptions.internalToOCamlException(raw_exn$1); + throw { + RE_EXN_ID: Parse_failure, + _1: exn$1, + Error: new Error() + }; + } + if (exit === 2) { + return set_user_default(value$1, acc); + } + + } else { + throw exn; + } + } + var length = value.length; + if (!(equals >= 0 && equals < length)) { + throw { + RE_EXN_ID: "Assert_failure", + _1: [ + "arg_helper.res", + 84, + 8 + ], + Error: new Error() + }; + } + if (equals === 0) { + throw { + RE_EXN_ID: Parse_failure, + _1: { + RE_EXN_ID: "Failure", + _1: "Missing key in argument specification" + }, + Error: new Error() + }; + } + var key = $$String.sub(value, 0, equals); + var key$1; + try { + key$1 = Curry._1(S.Key.of_string, key); + } + catch (raw_exn$2){ + var exn$2 = Caml_js_exceptions.internalToOCamlException(raw_exn$2); + throw { + RE_EXN_ID: Parse_failure, + _1: exn$2, + Error: new Error() + }; + } + var value$2 = $$String.sub(value, equals + 1 | 0, (length - equals | 0) - 1 | 0); + var value$3; + try { + value$3 = Curry._1(S.Value.of_string, value$2); + } + catch (raw_exn$3){ + var exn$3 = Caml_js_exceptions.internalToOCamlException(raw_exn$3); + throw { + RE_EXN_ID: Parse_failure, + _1: exn$3, + Error: new Error() + }; + } + return add_user_override(key$1, value$3, acc); + }), update.contents, values); + update.contents = parsed; + + }; + var parse = function (str, help_text, update) { + try { + parse_exn(str, update); + return ; + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === Parse_failure) { + return fatal(Curry._2(Printf.sprintf("%s: %s"), Printexc.to_string(exn._1), help_text)); + } + throw exn; + } + }; + var parse_no_error = function (str, update) { + try { + parse_exn(str, update); + return /* Ok */0; + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === Parse_failure) { + return /* Parse_failed */{ + _0: exn._1 + }; + } + throw exn; + } + }; + var get = function (key, parsed) { + try { + return Curry._2(S.Key.$$Map.find, key, parsed.user_override); + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === "Not_found") { + var value = parsed.user_default; + if (value !== undefined) { + return Caml_option.valFromOption(value); + } + try { + return Curry._2(S.Key.$$Map.find, key, parsed.base_override); + } + catch (raw_exn$1){ + var exn$1 = Caml_js_exceptions.internalToOCamlException(raw_exn$1); + if (exn$1.RE_EXN_ID === "Not_found") { + return parsed.base_default; + } + throw exn$1; + } + } else { + throw exn; + } + } + }; + return { + $$default: $$default, + set_base_default: set_base_default, + add_base_override: add_base_override, + reset_base_overrides: reset_base_overrides, + set_user_default: set_user_default, + add_user_override: add_user_override, + Parse_failure: Parse_failure, + parse_exn: parse_exn, + parse: parse, + parse_no_error: parse_no_error, + get: get + }; +} + +export { + fatal , + Make , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/arg_helper.res b/analysis/examples/larger-project/src/arg_helper.res new file mode 100644 index 0000000000..898906c6d4 --- /dev/null +++ b/analysis/examples/larger-project/src/arg_helper.res @@ -0,0 +1,142 @@ +/* ************************************************************************ */ +/* */ +/* OCaml */ +/* */ +/* Pierre Chambart, OCamlPro */ +/* Mark Shinwell and Leo White, Jane Street Europe */ +/* */ +/* Copyright 2015--2016 OCamlPro SAS */ +/* Copyright 2015--2016 Jane Street Group LLC */ +/* */ +/* All rights reserved. This file is distributed under the terms of */ +/* the GNU Lesser General Public License version 2.1, with the */ +/* special exception on linking described in the file LICENSE. */ +/* */ +/* ************************************************************************ */ + +@raises(exit) +let fatal = err => { + prerr_endline(err) + exit(2) +} + +module Make = ( + S: { + module Key: { + type t + let of_string: string => t + module Map: Map.S with type key = t + } + + module Value: { + type t + let of_string: string => t + } + }, +) => { + type parsed = { + base_default: S.Value.t, + base_override: S.Key.Map.t, + user_default: option, + user_override: S.Key.Map.t, + } + + let default = v => { + base_default: v, + base_override: S.Key.Map.empty, + user_default: None, + user_override: S.Key.Map.empty, + } + + let set_base_default = (value, t) => {...t, base_default: value} + + let add_base_override = (key, value, t) => { + ...t, + base_override: S.Key.Map.add(key, value, t.base_override), + } + + let reset_base_overrides = t => {...t, base_override: S.Key.Map.empty} + + let set_user_default = (value, t) => {...t, user_default: Some(value)} + + let add_user_override = (key, value, t) => { + ...t, + user_override: S.Key.Map.add(key, value, t.user_override), + } + + exception Parse_failure(exn) + + @raises([Invalid_argument, Parse_failure]) + let parse_exn = (str, ~update) => { + /* Is the removal of empty chunks really relevant here? */ + /* (It has been added to mimic the old Misc.String.split.) */ + let values = String.split_on_char(',', str) |> List.filter(\"<>"("")) + let parsed = List.fold_left((acc, value) => + switch String.index(value, '=') { + | exception Not_found => + switch S.Value.of_string(value) { + | value => set_user_default(value, acc) + | exception exn => raise(Parse_failure(exn)) + } + | equals => + let key_value_pair = value + let length = String.length(key_value_pair) + assert (equals >= 0 && equals < length) + if equals == 0 { + raise(Parse_failure(Failure("Missing key in argument specification"))) + } + let key = { + let key = String.sub(key_value_pair, 0, equals) + try S.Key.of_string(key) catch { + | exn => raise(Parse_failure(exn)) + } + } + + let value = { + let value = String.sub(key_value_pair, equals + 1, length - equals - 1) + + try S.Value.of_string(value) catch { + | exn => raise(Parse_failure(exn)) + } + } + + add_user_override(key, value, acc) + } + , update.contents, values) + + update := parsed + } + + @raises([Invalid_argument, exit]) + let parse = (str, help_text, update) => + switch parse_exn(str, ~update) { + | () => () + | exception Parse_failure(exn) => + fatal(Printf.sprintf("%s: %s", Printexc.to_string(exn), help_text)) + } + + type parse_result = + | Ok + | Parse_failed(exn) + + @raises(Invalid_argument) + let parse_no_error = (str, update) => + switch parse_exn(str, ~update) { + | () => Ok + | exception Parse_failure(exn) => Parse_failed(exn) + } + + let get = (~key, parsed) => + switch S.Key.Map.find(key, parsed.user_override) { + | value => value + | exception Not_found => + switch parsed.user_default { + | Some(value) => value + | None => + switch S.Key.Map.find(key, parsed.base_override) { + | value => value + | exception Not_found => parsed.base_default + } + } + } +} diff --git a/analysis/examples/larger-project/src/ast_helper.js b/analysis/examples/larger-project/src/ast_helper.js new file mode 100644 index 0000000000..a74aa6d850 --- /dev/null +++ b/analysis/examples/larger-project/src/ast_helper.js @@ -0,0 +1,53 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as $$Location from "./location.js"; +import * as Syntaxerr from "./syntaxerr.js"; + +throw { + RE_EXN_ID: "Assert_failure", + _1: [ + "ast_helper.res", + 23, + 21 + ], + Error: new Error() + }; + +export { + docstring_body , + docstring_loc , + text_attr , + empty_docs , + add_docs_attrs , + add_text_attrs , + empty_info , + add_info_attrs , + default_loc , + with_default_loc , + Const , + Typ , + Pat , + Exp , + Mty , + Mod , + Sig , + Str , + Cl , + Cty , + Ctf , + Cf , + Val , + Md , + Mtd , + Mb , + Opn , + Incl , + Vb , + Ci , + Type , + Te , + Csig , + Cstr , + +} +/* docstring_body Not a pure module */ diff --git a/analysis/examples/larger-project/src/ast_helper.res b/analysis/examples/larger-project/src/ast_helper.res new file mode 100644 index 0000000000..fa5c7cb594 --- /dev/null +++ b/analysis/examples/larger-project/src/ast_helper.res @@ -0,0 +1,628 @@ +@@ocaml.text( + /* ************************************************************************ */ + /* */ + /* OCaml */ + /* */ + /* Alain Frisch, LexiFi */ + /* */ + /* Copyright 2012 Institut National de Recherche en Informatique et */ + /* en Automatique. */ + /* */ + /* All rights reserved. This file is distributed under the terms of */ + /* the GNU Lesser General Public License version 2.1, with the */ + /* special exception on linking described in the file LICENSE. */ + /* */ + /* ************************************************************************ */ + + " Helpers to produce Parsetree fragments " +) + +open Asttypes +open Parsetree +open Docstrings +let docstring_body = assert false +let docstring_loc = assert false +let text_attr = assert false +let empty_docs = assert false +let add_docs_attrs = assert false +let add_text_attrs = assert false +let empty_info = assert false +let add_info_attrs = assert false + +type lid = loc +type str = loc +type loc = Location.t +type attrs = list + +let default_loc = ref(Location.none) + +@raises(genericException) +let with_default_loc = (l, f) => { + let old = default_loc.contents + default_loc := l + try { + let r = f() + default_loc := old + r + } catch { + | exn => + default_loc := old + raise(exn) + } +} + +module Const = { + let integer = (~suffix=?, i) => Pconst_integer(i, suffix) + let int = (~suffix=?, i) => integer(~suffix?, string_of_int(i)) + let int32 = (~suffix='l', i) => integer(~suffix, Int32.to_string(i)) + let int64 = (~suffix='L', i) => integer(~suffix, Int64.to_string(i)) + let nativeint = (~suffix='n', i) => integer(~suffix, Nativeint.to_string(i)) + let float = (~suffix=?, f) => Pconst_float(f, suffix) + let char = c => Pconst_char(c) + let string = (~quotation_delimiter=?, s) => Pconst_string(s, quotation_delimiter) +} + +module Typ = { + let mk = (~loc=default_loc.contents, ~attrs=list{}, d) => { + ptyp_desc: d, + ptyp_loc: loc, + ptyp_attributes: attrs, + } + let attr = (d, a) => {...d, ptyp_attributes: \"@"(d.ptyp_attributes, list{a})} + + let any = (~loc=?, ~attrs=?, ()) => mk(~loc?, ~attrs?, Ptyp_any) + let var = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Ptyp_var(a)) + let arrow = (~loc=?, ~attrs=?, a, b, c) => mk(~loc?, ~attrs?, Ptyp_arrow(a, b, c)) + let tuple = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Ptyp_tuple(a)) + let constr = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Ptyp_constr(a, b)) + let object_ = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Ptyp_object(a, b)) + let class_ = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Ptyp_class(a, b)) + let alias = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Ptyp_alias(a, b)) + let variant = (~loc=?, ~attrs=?, a, b, c) => mk(~loc?, ~attrs?, Ptyp_variant(a, b, c)) + let poly = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Ptyp_poly(a, b)) + let package = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Ptyp_package(a, b)) + let extension = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Ptyp_extension(a)) + + let force_poly = t => + switch t.ptyp_desc { + | Ptyp_poly(_) => t + | _ => poly(~loc=t.ptyp_loc, list{}, t) + } /* -> ghost? */ + + @raises(Error) + let varify_constructors = (var_names, t) => { + @raises(Error) + let check_variable = (vl, loc, v) => + if List.mem(v, vl) { + raise({ + open Syntaxerr + Error(Variable_in_scope(loc, v)) + }) + } + let var_names = List.map(v => v.txt, var_names) + + @raises(Error) + let rec loop = t => { + let desc = switch t.ptyp_desc { + | Ptyp_any => Ptyp_any + | Ptyp_var(x) => + check_variable(var_names, t.ptyp_loc, x) + Ptyp_var(x) + | Ptyp_arrow(label, core_type, core_type') => + Ptyp_arrow(label, loop(core_type), loop(core_type')) + | Ptyp_tuple(lst) => Ptyp_tuple(List.map(loop, lst)) + | Ptyp_constr({txt: Longident.Lident(s)}, list{}) if List.mem(s, var_names) => Ptyp_var(s) + | Ptyp_constr(longident, lst) => Ptyp_constr(longident, List.map(loop, lst)) + | Ptyp_object(lst, o) => Ptyp_object(List.map(loop_object_field, lst), o) + | Ptyp_class(longident, lst) => Ptyp_class(longident, List.map(loop, lst)) + | Ptyp_alias(core_type, string) => + check_variable(var_names, t.ptyp_loc, string) + Ptyp_alias(loop(core_type), string) + | Ptyp_variant(row_field_list, flag, lbl_lst_option) => + Ptyp_variant(List.map(loop_row_field, row_field_list), flag, lbl_lst_option) + | Ptyp_poly(string_lst, core_type) => + List.iter(v => check_variable(var_names, t.ptyp_loc, v.txt), string_lst) + Ptyp_poly(string_lst, loop(core_type)) + | Ptyp_package(longident, lst) => + Ptyp_package(longident, List.map(((n, typ)) => (n, loop(typ)), lst)) + | Ptyp_extension(s, arg) => Ptyp_extension(s, arg) + } + + {...t, ptyp_desc: desc} + } + @raises(Error) + and loop_row_field = x => + switch x { + | Rtag(label, attrs, flag, lst) => Rtag(label, attrs, flag, List.map(loop, lst)) + | Rinherit(t) => Rinherit(loop(t)) + } + @raises(Error) + and loop_object_field = x => + switch x { + | Otag(label, attrs, t) => Otag(label, attrs, loop(t)) + | Oinherit(t) => Oinherit(loop(t)) + } + + loop(t) + } +} + +module Pat = { + let mk = (~loc=default_loc.contents, ~attrs=list{}, d) => { + ppat_desc: d, + ppat_loc: loc, + ppat_attributes: attrs, + } + let attr = (d, a) => {...d, ppat_attributes: \"@"(d.ppat_attributes, list{a})} + + let any = (~loc=?, ~attrs=?, ()) => mk(~loc?, ~attrs?, Ppat_any) + let var = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Ppat_var(a)) + let alias = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Ppat_alias(a, b)) + let constant = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Ppat_constant(a)) + let interval = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Ppat_interval(a, b)) + let tuple = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Ppat_tuple(a)) + let construct = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Ppat_construct(a, b)) + let variant = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Ppat_variant(a, b)) + let record = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Ppat_record(a, b)) + let array = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Ppat_array(a)) + let or_ = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Ppat_or(a, b)) + let constraint_ = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Ppat_constraint(a, b)) + let type_ = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Ppat_type(a)) + let lazy_ = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Ppat_lazy(a)) + let unpack = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Ppat_unpack(a)) + let open_ = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Ppat_open(a, b)) + let exception_ = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Ppat_exception(a)) + let extension = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Ppat_extension(a)) +} + +module Exp = { + let mk = (~loc=default_loc.contents, ~attrs=list{}, d) => { + pexp_desc: d, + pexp_loc: loc, + pexp_attributes: attrs, + } + let attr = (d, a) => {...d, pexp_attributes: \"@"(d.pexp_attributes, list{a})} + + let ident = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pexp_ident(a)) + let constant = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pexp_constant(a)) + let let_ = (~loc=?, ~attrs=?, a, b, c) => mk(~loc?, ~attrs?, Pexp_let(a, b, c)) + let fun_ = (~loc=?, ~attrs=?, a, b, c, d) => mk(~loc?, ~attrs?, Pexp_fun(a, b, c, d)) + let function_ = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pexp_function(a)) + let apply = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Pexp_apply(a, b)) + let match_ = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Pexp_match(a, b)) + let try_ = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Pexp_try(a, b)) + let tuple = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pexp_tuple(a)) + let construct = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Pexp_construct(a, b)) + let variant = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Pexp_variant(a, b)) + let record = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Pexp_record(a, b)) + let field = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Pexp_field(a, b)) + let setfield = (~loc=?, ~attrs=?, a, b, c) => mk(~loc?, ~attrs?, Pexp_setfield(a, b, c)) + let array = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pexp_array(a)) + let ifthenelse = (~loc=?, ~attrs=?, a, b, c) => mk(~loc?, ~attrs?, Pexp_ifthenelse(a, b, c)) + let sequence = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Pexp_sequence(a, b)) + let while_ = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Pexp_while(a, b)) + let for_ = (~loc=?, ~attrs=?, a, b, c, d, e) => mk(~loc?, ~attrs?, Pexp_for(a, b, c, d, e)) + let constraint_ = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Pexp_constraint(a, b)) + let coerce = (~loc=?, ~attrs=?, a, b, c) => mk(~loc?, ~attrs?, Pexp_coerce(a, b, c)) + let send = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Pexp_send(a, b)) + let new_ = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pexp_new(a)) + let setinstvar = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Pexp_setinstvar(a, b)) + let override = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pexp_override(a)) + let letmodule = (~loc=?, ~attrs=?, a, b, c) => mk(~loc?, ~attrs?, Pexp_letmodule(a, b, c)) + let letexception = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Pexp_letexception(a, b)) + let assert_ = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pexp_assert(a)) + let lazy_ = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pexp_lazy(a)) + let poly = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Pexp_poly(a, b)) + let object_ = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pexp_object(a)) + let newtype = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Pexp_newtype(a, b)) + let pack = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pexp_pack(a)) + let open_ = (~loc=?, ~attrs=?, a, b, c) => mk(~loc?, ~attrs?, Pexp_open(a, b, c)) + let extension = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pexp_extension(a)) + let unreachable = (~loc=?, ~attrs=?, ()) => mk(~loc?, ~attrs?, Pexp_unreachable) + + let case = (lhs, ~guard=?, rhs) => { + pc_lhs: lhs, + pc_guard: guard, + pc_rhs: rhs, + } +} + +module Mty = { + let mk = (~loc=default_loc.contents, ~attrs=list{}, d) => { + pmty_desc: d, + pmty_loc: loc, + pmty_attributes: attrs, + } + let attr = (d, a) => {...d, pmty_attributes: \"@"(d.pmty_attributes, list{a})} + + let ident = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pmty_ident(a)) + let alias = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pmty_alias(a)) + let signature = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pmty_signature(a)) + let functor_ = (~loc=?, ~attrs=?, a, b, c) => mk(~loc?, ~attrs?, Pmty_functor(a, b, c)) + let with_ = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Pmty_with(a, b)) + let typeof_ = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pmty_typeof(a)) + let extension = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pmty_extension(a)) +} + +module Mod = { + let mk = (~loc=default_loc.contents, ~attrs=list{}, d) => { + pmod_desc: d, + pmod_loc: loc, + pmod_attributes: attrs, + } + let attr = (d, a) => {...d, pmod_attributes: \"@"(d.pmod_attributes, list{a})} + + let ident = (~loc=?, ~attrs=?, x) => mk(~loc?, ~attrs?, Pmod_ident(x)) + let structure = (~loc=?, ~attrs=?, x) => mk(~loc?, ~attrs?, Pmod_structure(x)) + let functor_ = (~loc=?, ~attrs=?, arg, arg_ty, body) => + mk(~loc?, ~attrs?, Pmod_functor(arg, arg_ty, body)) + let apply = (~loc=?, ~attrs=?, m1, m2) => mk(~loc?, ~attrs?, Pmod_apply(m1, m2)) + let constraint_ = (~loc=?, ~attrs=?, m, mty) => mk(~loc?, ~attrs?, Pmod_constraint(m, mty)) + let unpack = (~loc=?, ~attrs=?, e) => mk(~loc?, ~attrs?, Pmod_unpack(e)) + let extension = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pmod_extension(a)) +} + +module Sig = { + let mk = (~loc=default_loc.contents, d) => {psig_desc: d, psig_loc: loc} + + let value = (~loc=?, a) => mk(~loc?, Psig_value(a)) + let type_ = (~loc=?, rec_flag, a) => mk(~loc?, Psig_type(rec_flag, a)) + let type_extension = (~loc=?, a) => mk(~loc?, Psig_typext(a)) + let exception_ = (~loc=?, a) => mk(~loc?, Psig_exception(a)) + let module_ = (~loc=?, a) => mk(~loc?, Psig_module(a)) + let rec_module = (~loc=?, a) => mk(~loc?, Psig_recmodule(a)) + let modtype = (~loc=?, a) => mk(~loc?, Psig_modtype(a)) + let open_ = (~loc=?, a) => mk(~loc?, Psig_open(a)) + let include_ = (~loc=?, a) => mk(~loc?, Psig_include(a)) + let class_ = (~loc=?, a) => mk(~loc?, Psig_class(a)) + let class_type = (~loc=?, a) => mk(~loc?, Psig_class_type(a)) + let extension = (~loc=?, ~attrs=list{}, a) => mk(~loc?, Psig_extension(a, attrs)) + let attribute = (~loc=?, a) => mk(~loc?, Psig_attribute(a)) + let text = txt => { + let f_txt = List.filter(ds => docstring_body(ds) != "", txt) + List.map(ds => attribute(~loc=docstring_loc(ds), text_attr(ds)), f_txt) + } +} + +module Str = { + let mk = (~loc=default_loc.contents, d) => {pstr_desc: d, pstr_loc: loc} + + let eval = (~loc=?, ~attrs=list{}, a) => mk(~loc?, Pstr_eval(a, attrs)) + let value = (~loc=?, a, b) => mk(~loc?, Pstr_value(a, b)) + let primitive = (~loc=?, a) => mk(~loc?, Pstr_primitive(a)) + let type_ = (~loc=?, rec_flag, a) => mk(~loc?, Pstr_type(rec_flag, a)) + let type_extension = (~loc=?, a) => mk(~loc?, Pstr_typext(a)) + let exception_ = (~loc=?, a) => mk(~loc?, Pstr_exception(a)) + let module_ = (~loc=?, a) => mk(~loc?, Pstr_module(a)) + let rec_module = (~loc=?, a) => mk(~loc?, Pstr_recmodule(a)) + let modtype = (~loc=?, a) => mk(~loc?, Pstr_modtype(a)) + let open_ = (~loc=?, a) => mk(~loc?, Pstr_open(a)) + let class_ = (~loc=?, a) => mk(~loc?, Pstr_class(a)) + let class_type = (~loc=?, a) => mk(~loc?, Pstr_class_type(a)) + let include_ = (~loc=?, a) => mk(~loc?, Pstr_include(a)) + let extension = (~loc=?, ~attrs=list{}, a) => mk(~loc?, Pstr_extension(a, attrs)) + let attribute = (~loc=?, a) => mk(~loc?, Pstr_attribute(a)) + let text = txt => { + let f_txt = List.filter(ds => docstring_body(ds) != "", txt) + List.map(ds => attribute(~loc=docstring_loc(ds), text_attr(ds)), f_txt) + } +} + +module Cl = { + let mk = (~loc=default_loc.contents, ~attrs=list{}, d) => { + pcl_desc: d, + pcl_loc: loc, + pcl_attributes: attrs, + } + let attr = (d, a) => {...d, pcl_attributes: \"@"(d.pcl_attributes, list{a})} + + let constr = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Pcl_constr(a, b)) + let structure = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pcl_structure(a)) + let fun_ = (~loc=?, ~attrs=?, a, b, c, d) => mk(~loc?, ~attrs?, Pcl_fun(a, b, c, d)) + let apply = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Pcl_apply(a, b)) + let let_ = (~loc=?, ~attrs=?, a, b, c) => mk(~loc?, ~attrs?, Pcl_let(a, b, c)) + let constraint_ = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Pcl_constraint(a, b)) + let extension = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pcl_extension(a)) + let open_ = (~loc=?, ~attrs=?, a, b, c) => mk(~loc?, ~attrs?, Pcl_open(a, b, c)) +} + +module Cty = { + let mk = (~loc=default_loc.contents, ~attrs=list{}, d) => { + pcty_desc: d, + pcty_loc: loc, + pcty_attributes: attrs, + } + let attr = (d, a) => {...d, pcty_attributes: \"@"(d.pcty_attributes, list{a})} + + let constr = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Pcty_constr(a, b)) + let signature = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pcty_signature(a)) + let arrow = (~loc=?, ~attrs=?, a, b, c) => mk(~loc?, ~attrs?, Pcty_arrow(a, b, c)) + let extension = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pcty_extension(a)) + let open_ = (~loc=?, ~attrs=?, a, b, c) => mk(~loc?, ~attrs?, Pcty_open(a, b, c)) +} + +module Ctf = { + let mk = (~loc=default_loc.contents, ~attrs=list{}, ~docs=empty_docs, d) => { + pctf_desc: d, + pctf_loc: loc, + pctf_attributes: add_docs_attrs(docs, attrs), + } + + let inherit_ = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pctf_inherit(a)) + let val_ = (~loc=?, ~attrs=?, a, b, c, d) => mk(~loc?, ~attrs?, Pctf_val(a, b, c, d)) + let method_ = (~loc=?, ~attrs=?, a, b, c, d) => mk(~loc?, ~attrs?, Pctf_method(a, b, c, d)) + let constraint_ = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Pctf_constraint(a, b)) + let extension = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pctf_extension(a)) + let attribute = (~loc=?, a) => mk(~loc?, Pctf_attribute(a)) + let text = txt => { + let f_txt = List.filter(ds => docstring_body(ds) != "", txt) + List.map(ds => attribute(~loc=docstring_loc(ds), text_attr(ds)), f_txt) + } + + let attr = (d, a) => {...d, pctf_attributes: \"@"(d.pctf_attributes, list{a})} +} + +module Cf = { + let mk = (~loc=default_loc.contents, ~attrs=list{}, ~docs=empty_docs, d) => { + pcf_desc: d, + pcf_loc: loc, + pcf_attributes: add_docs_attrs(docs, attrs), + } + + let inherit_ = (~loc=?, ~attrs=?, a, b, c) => mk(~loc?, ~attrs?, Pcf_inherit(a, b, c)) + let val_ = (~loc=?, ~attrs=?, a, b, c) => mk(~loc?, ~attrs?, Pcf_val(a, b, c)) + let method_ = (~loc=?, ~attrs=?, a, b, c) => mk(~loc?, ~attrs?, Pcf_method(a, b, c)) + let constraint_ = (~loc=?, ~attrs=?, a, b) => mk(~loc?, ~attrs?, Pcf_constraint(a, b)) + let initializer_ = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pcf_initializer(a)) + let extension = (~loc=?, ~attrs=?, a) => mk(~loc?, ~attrs?, Pcf_extension(a)) + let attribute = (~loc=?, a) => mk(~loc?, Pcf_attribute(a)) + let text = txt => { + let f_txt = List.filter(ds => docstring_body(ds) != "", txt) + List.map(ds => attribute(~loc=docstring_loc(ds), text_attr(ds)), f_txt) + } + + let virtual_ = ct => Cfk_virtual(ct) + let concrete = (o, e) => Cfk_concrete(o, e) + + let attr = (d, a) => {...d, pcf_attributes: \"@"(d.pcf_attributes, list{a})} +} + +module Val = { + let mk = ( + ~loc=default_loc.contents, + ~attrs=list{}, + ~docs=empty_docs, + ~prim=list{}, + name, + typ, + ) => { + pval_name: name, + pval_type: typ, + pval_attributes: add_docs_attrs(docs, attrs), + pval_loc: loc, + pval_prim: prim, + } +} + +module Md = { + let mk = ( + ~loc=default_loc.contents, + ~attrs=list{}, + ~docs=empty_docs, + ~text=list{}, + name, + typ, + ) => { + pmd_name: name, + pmd_type: typ, + pmd_attributes: add_text_attrs(text, add_docs_attrs(docs, attrs)), + pmd_loc: loc, + } +} + +module Mtd = { + let mk = ( + ~loc=default_loc.contents, + ~attrs=list{}, + ~docs=empty_docs, + ~text=list{}, + ~typ=?, + name, + ) => { + pmtd_name: name, + pmtd_type: typ, + pmtd_attributes: add_text_attrs(text, add_docs_attrs(docs, attrs)), + pmtd_loc: loc, + } +} + +module Mb = { + let mk = ( + ~loc=default_loc.contents, + ~attrs=list{}, + ~docs=empty_docs, + ~text=list{}, + name, + expr, + ) => { + pmb_name: name, + pmb_expr: expr, + pmb_attributes: add_text_attrs(text, add_docs_attrs(docs, attrs)), + pmb_loc: loc, + } +} + +module Opn = { + let mk = (~loc=default_loc.contents, ~attrs=list{}, ~docs=empty_docs, ~override=Fresh, lid) => { + popen_lid: lid, + popen_override: override, + popen_loc: loc, + popen_attributes: add_docs_attrs(docs, attrs), + } +} + +module Incl = { + let mk = (~loc=default_loc.contents, ~attrs=list{}, ~docs=empty_docs, mexpr) => { + pincl_mod: mexpr, + pincl_loc: loc, + pincl_attributes: add_docs_attrs(docs, attrs), + } +} + +module Vb = { + let mk = ( + ~loc=default_loc.contents, + ~attrs=list{}, + ~docs=empty_docs, + ~text=list{}, + pat, + expr, + ) => { + pvb_pat: pat, + pvb_expr: expr, + pvb_attributes: add_text_attrs(text, add_docs_attrs(docs, attrs)), + pvb_loc: loc, + } +} + +module Ci = { + let mk = ( + ~loc=default_loc.contents, + ~attrs=list{}, + ~docs=empty_docs, + ~text=list{}, + ~virt=Concrete, + ~params=list{}, + name, + expr, + ) => { + pci_virt: virt, + pci_params: params, + pci_name: name, + pci_expr: expr, + pci_attributes: add_text_attrs(text, add_docs_attrs(docs, attrs)), + pci_loc: loc, + } +} + +module Type = { + let mk = ( + ~loc=default_loc.contents, + ~attrs=list{}, + ~docs=empty_docs, + ~text=list{}, + ~params=list{}, + ~cstrs=list{}, + ~kind=Ptype_abstract, + ~priv=Public, + ~manifest=?, + name, + ) => { + ptype_name: name, + ptype_params: params, + ptype_cstrs: cstrs, + ptype_kind: kind, + ptype_private: priv, + ptype_manifest: manifest, + ptype_attributes: add_text_attrs(text, add_docs_attrs(docs, attrs)), + ptype_loc: loc, + } + + let constructor = ( + ~loc=default_loc.contents, + ~attrs=list{}, + ~info=empty_info, + ~args=Pcstr_tuple(list{}), + ~res=?, + name, + ) => { + pcd_name: name, + pcd_args: args, + pcd_res: res, + pcd_loc: loc, + pcd_attributes: add_info_attrs(info, attrs), + } + + let field = ( + ~loc=default_loc.contents, + ~attrs=list{}, + ~info=empty_info, + ~mut=Immutable, + name, + typ, + ) => { + pld_name: name, + pld_mutable: mut, + pld_type: typ, + pld_loc: loc, + pld_attributes: add_info_attrs(info, attrs), + } +} + +@ocaml.doc(" Type extensions ") +module Te = { + let mk = (~attrs=list{}, ~docs=empty_docs, ~params=list{}, ~priv=Public, path, constructors) => { + ptyext_path: path, + ptyext_params: params, + ptyext_constructors: constructors, + ptyext_private: priv, + ptyext_attributes: add_docs_attrs(docs, attrs), + } + + let constructor = ( + ~loc=default_loc.contents, + ~attrs=list{}, + ~docs=empty_docs, + ~info=empty_info, + name, + kind, + ) => { + pext_name: name, + pext_kind: kind, + pext_loc: loc, + pext_attributes: add_docs_attrs(docs, add_info_attrs(info, attrs)), + } + + let decl = ( + ~loc=default_loc.contents, + ~attrs=list{}, + ~docs=empty_docs, + ~info=empty_info, + ~args=Pcstr_tuple(list{}), + ~res=?, + name, + ) => { + pext_name: name, + pext_kind: Pext_decl(args, res), + pext_loc: loc, + pext_attributes: add_docs_attrs(docs, add_info_attrs(info, attrs)), + } + + let rebind = ( + ~loc=default_loc.contents, + ~attrs=list{}, + ~docs=empty_docs, + ~info=empty_info, + name, + lid, + ) => { + pext_name: name, + pext_kind: Pext_rebind(lid), + pext_loc: loc, + pext_attributes: add_docs_attrs(docs, add_info_attrs(info, attrs)), + } +} + +module Csig = { + let mk = (self, fields) => { + pcsig_self: self, + pcsig_fields: fields, + } +} + +module Cstr = { + let mk = (self, fields) => { + pcstr_self: self, + pcstr_fields: fields, + } +} diff --git a/analysis/examples/larger-project/src/asttypes.js b/analysis/examples/larger-project/src/asttypes.js new file mode 100644 index 0000000000..d856702bfe --- /dev/null +++ b/analysis/examples/larger-project/src/asttypes.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/analysis/examples/larger-project/src/asttypes.res b/analysis/examples/larger-project/src/asttypes.res new file mode 100644 index 0000000000..b21e2b722b --- /dev/null +++ b/analysis/examples/larger-project/src/asttypes.res @@ -0,0 +1,62 @@ +open P + +@@ocaml.text( + /* ************************************************************************ */ + /* */ + /* OCaml */ + /* */ + /* Xavier Leroy, projet Cristal, INRIA Rocquencourt */ + /* */ + /* Copyright 1996 Institut National de Recherche en Informatique et */ + /* en Automatique. */ + /* */ + /* All rights reserved. This file is distributed under the terms of */ + /* the GNU Lesser General Public License version 2.1, with the */ + /* special exception on linking described in the file LICENSE. */ + /* */ + /* ************************************************************************ */ + + " Auxiliary AST types used by parsetree and typedtree. " +) + +type constant = + | Const_int(int) + | Const_char(char) + | Const_string(string, option) + | Const_float(string) + | Const_int32(int32) + | Const_int64(int64) + | Const_nativeint(nativeint) + +type rec_flag = Nonrecursive | Recursive + +type direction_flag = Upto | Downto + +/* Order matters, used in polymorphic comparison */ +type private_flag = Private | Public + +type mutable_flag = Immutable | Mutable + +type virtual_flag = Virtual | Concrete + +type override_flag = Override | Fresh + +type closed_flag = Closed | Open + +type label = string + +type arg_label = + | Nolabel + | Labelled(string) /* label:T -> ... */ + | Optional(string) /* ?label:T -> ... */ + +type loc<'a> = Location.loc<'a> = { + txt: 'a, + loc: Location.t, +} + +type variance = + | Covariant + | Contravariant + | Invariant + diff --git a/analysis/examples/larger-project/src/clflags.js b/analysis/examples/larger-project/src/clflags.js new file mode 100644 index 0000000000..9b31202039 --- /dev/null +++ b/analysis/examples/larger-project/src/clflags.js @@ -0,0 +1,873 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Arg from "rescript/lib/es6/arg.js"; +import * as Sys from "rescript/lib/es6/sys.js"; +import * as List from "rescript/lib/es6/list.js"; +import * as Misc from "./misc.js"; +import * as Curry from "rescript/lib/es6/curry.js"; +import * as Config from "./config.js"; +import * as Printf from "./printf.js"; +import * as Filename from "rescript/lib/es6/filename.js"; +import * as Pervasives from "rescript/lib/es6/pervasives.js"; +import * as Caml_js_exceptions from "rescript/lib/es6/caml_js_exceptions.js"; + +var Int_arg_helper = {}; + +var Float_arg_helper = {}; + +var objfiles = { + contents: /* [] */0 +}; + +var ccobjs = { + contents: /* [] */0 +}; + +var dllibs = { + contents: /* [] */0 +}; + +var compile_only = { + contents: false +}; + +var output_name = { + contents: undefined +}; + +var include_dirs = { + contents: /* [] */0 +}; + +var no_std_include = { + contents: false +}; + +var print_types = { + contents: false +}; + +var make_archive = { + contents: false +}; + +var debug = { + contents: false +}; + +var fast = { + contents: false +}; + +var use_linscan = { + contents: false +}; + +var link_everything = { + contents: false +}; + +var custom_runtime = { + contents: false +}; + +var no_check_prims = { + contents: false +}; + +var bytecode_compatible_32 = { + contents: false +}; + +var output_c_object = { + contents: false +}; + +var output_complete_object = { + contents: false +}; + +var all_ccopts = { + contents: /* [] */0 +}; + +var classic = { + contents: false +}; + +var nopervasives = { + contents: false +}; + +var preprocessor = { + contents: undefined +}; + +var all_ppx = { + contents: /* [] */0 +}; + +var annotations = { + contents: false +}; + +var binary_annotations = { + contents: false +}; + +var use_threads = { + contents: false +}; + +var use_vmthreads = { + contents: false +}; + +var noassert = { + contents: false +}; + +var verbose = { + contents: false +}; + +var noversion = { + contents: false +}; + +var noprompt = { + contents: false +}; + +var nopromptcont = { + contents: false +}; + +var init_file = { + contents: undefined +}; + +var noinit = { + contents: false +}; + +var open_modules = { + contents: /* [] */0 +}; + +var use_prims = { + contents: "" +}; + +var use_runtime = { + contents: "" +}; + +var principal = { + contents: false +}; + +var real_paths = { + contents: true +}; + +var recursive_types = { + contents: false +}; + +var strict_sequence = { + contents: false +}; + +var strict_formats = { + contents: false +}; + +var applicative_functors = { + contents: true +}; + +var make_runtime = { + contents: false +}; + +var gprofile = { + contents: false +}; + +var c_compiler = { + contents: undefined +}; + +var no_auto_link = { + contents: false +}; + +var dllpaths = { + contents: /* [] */0 +}; + +var make_package = { + contents: false +}; + +var for_package = { + contents: undefined +}; + +var error_size = { + contents: 500 +}; + +var float_const_prop = { + contents: true +}; + +var transparent_modules = { + contents: false +}; + +var dump_source = { + contents: false +}; + +var dump_parsetree = { + contents: false +}; + +var dump_typedtree = { + contents: false +}; + +var dump_rawlambda = { + contents: false +}; + +var dump_lambda = { + contents: false +}; + +var dump_rawclambda = { + contents: false +}; + +var dump_clambda = { + contents: false +}; + +var dump_rawflambda = { + contents: false +}; + +var dump_flambda = { + contents: false +}; + +var dump_flambda_let = { + contents: undefined +}; + +var dump_flambda_verbose = { + contents: false +}; + +var dump_instr = { + contents: false +}; + +var keep_asm_file = { + contents: false +}; + +var optimize_for_speed = { + contents: true +}; + +var opaque = { + contents: false +}; + +var dump_cmm = { + contents: false +}; + +var dump_selection = { + contents: false +}; + +var dump_cse = { + contents: false +}; + +var dump_live = { + contents: false +}; + +var dump_avail = { + contents: false +}; + +var dump_spill = { + contents: false +}; + +var dump_split = { + contents: false +}; + +var dump_interf = { + contents: false +}; + +var dump_prefer = { + contents: false +}; + +var dump_regalloc = { + contents: false +}; + +var dump_reload = { + contents: false +}; + +var dump_scheduling = { + contents: false +}; + +var dump_linear = { + contents: false +}; + +var dump_interval = { + contents: false +}; + +var keep_startup_file = { + contents: false +}; + +var dump_combine = { + contents: false +}; + +var debug_runavail = { + contents: false +}; + +var native_code = { + contents: false +}; + +var force_slash = { + contents: false +}; + +var clambda_checks = { + contents: false +}; + +var flambda_invariant_checks = { + contents: true +}; + +var dont_write_files = { + contents: false +}; + +function std_include_flag(prefix) { + if (no_std_include.contents) { + return ""; + } else { + return prefix + Curry._1(Filename.quote, Config.standard_library); + } +} + +function std_include_dir(param) { + if (no_std_include.contents) { + return /* [] */0; + } else { + return { + hd: Config.standard_library, + tl: /* [] */0 + }; + } +} + +var shared = { + contents: false +}; + +var dlcode = { + contents: true +}; + +var tmp = Config.architecture === "amd64" ? true : false; + +var pic_code = { + contents: tmp +}; + +var runtime_variant = { + contents: "" +}; + +var keep_docs = { + contents: false +}; + +var keep_locs = { + contents: true +}; + +var unsafe_string = { + contents: false +}; + +var classic_inlining = { + contents: false +}; + +var inlining_report = { + contents: false +}; + +var afl_instrument = { + contents: false +}; + +var afl_inst_ratio = { + contents: 100 +}; + +var simplify_rounds = { + contents: undefined +}; + +var default_simplify_rounds = { + contents: 1 +}; + +function rounds(param) { + var r = simplify_rounds.contents; + if (r !== undefined) { + return r; + } else { + return default_simplify_rounds.contents; + } +} + +var default_inline_threshold = 10 / 8; + +var default_inline_toplevel_threshold = 16 * default_inline_threshold | 0; + +var unbox_specialised_args = { + contents: true +}; + +var unbox_free_vars_of_closures = { + contents: true +}; + +var unbox_closures = { + contents: false +}; + +var unbox_closures_factor = { + contents: 10 +}; + +var remove_unused_arguments = { + contents: false +}; + +var classic_arguments_inline_threshold = 10 / 8; + +var classic_arguments_inline_toplevel_threshold = 1; + +var classic_arguments = { + inline_call_cost: undefined, + inline_alloc_cost: undefined, + inline_prim_cost: undefined, + inline_branch_cost: undefined, + inline_indirect_cost: undefined, + inline_lifting_benefit: undefined, + inline_branch_factor: undefined, + inline_max_depth: undefined, + inline_max_unroll: undefined, + inline_threshold: classic_arguments_inline_threshold, + inline_toplevel_threshold: classic_arguments_inline_toplevel_threshold +}; + +var o2_arguments_inline_call_cost = 10; + +var o2_arguments_inline_alloc_cost = 14; + +var o2_arguments_inline_prim_cost = 6; + +var o2_arguments_inline_branch_cost = 10; + +var o2_arguments_inline_indirect_cost = 8; + +var o2_arguments_inline_max_depth = 2; + +var o2_arguments_inline_threshold = 25; + +var o2_arguments_inline_toplevel_threshold = 400; + +var o2_arguments = { + inline_call_cost: o2_arguments_inline_call_cost, + inline_alloc_cost: o2_arguments_inline_alloc_cost, + inline_prim_cost: o2_arguments_inline_prim_cost, + inline_branch_cost: o2_arguments_inline_branch_cost, + inline_indirect_cost: o2_arguments_inline_indirect_cost, + inline_lifting_benefit: undefined, + inline_branch_factor: undefined, + inline_max_depth: o2_arguments_inline_max_depth, + inline_max_unroll: undefined, + inline_threshold: o2_arguments_inline_threshold, + inline_toplevel_threshold: o2_arguments_inline_toplevel_threshold +}; + +var o3_arguments_inline_call_cost = 15; + +var o3_arguments_inline_alloc_cost = 21; + +var o3_arguments_inline_prim_cost = 9; + +var o3_arguments_inline_branch_cost = 15; + +var o3_arguments_inline_indirect_cost = 12; + +var o3_arguments_inline_branch_factor = 0; + +var o3_arguments_inline_max_depth = 3; + +var o3_arguments_inline_max_unroll = 1; + +var o3_arguments_inline_threshold = 50; + +var o3_arguments_inline_toplevel_threshold = 800; + +var o3_arguments = { + inline_call_cost: o3_arguments_inline_call_cost, + inline_alloc_cost: o3_arguments_inline_alloc_cost, + inline_prim_cost: o3_arguments_inline_prim_cost, + inline_branch_cost: o3_arguments_inline_branch_cost, + inline_indirect_cost: o3_arguments_inline_indirect_cost, + inline_lifting_benefit: undefined, + inline_branch_factor: o3_arguments_inline_branch_factor, + inline_max_depth: o3_arguments_inline_max_depth, + inline_max_unroll: o3_arguments_inline_max_unroll, + inline_threshold: o3_arguments_inline_threshold, + inline_toplevel_threshold: o3_arguments_inline_toplevel_threshold +}; + +var all_passes = { + contents: /* [] */0 +}; + +var dumped_passes_list = { + contents: /* [] */0 +}; + +function dumped_pass(s) { + if (!List.mem(s, all_passes.contents)) { + throw { + RE_EXN_ID: "Assert_failure", + _1: [ + "clflags.res", + 276, + 2 + ], + Error: new Error() + }; + } + return List.mem(s, dumped_passes_list.contents); +} + +function set_dumped_pass(s, enabled) { + if (!List.mem(s, all_passes.contents)) { + return ; + } + var passes_without_s = List.filter(function (param) { + return s !== param; + })(dumped_passes_list.contents); + var dumped_passes = enabled ? ({ + hd: s, + tl: passes_without_s + }) : passes_without_s; + dumped_passes_list.contents = dumped_passes; + +} + +function parse_color_setting(x) { + switch (x) { + case "always" : + return /* Always */1; + case "auto" : + return /* Auto */0; + case "never" : + return /* Never */2; + default: + return ; + } +} + +var color = { + contents: undefined +}; + +var unboxed_types = { + contents: false +}; + +var arg_spec = { + contents: /* [] */0 +}; + +var arg_names = { + contents: Misc.StringMap.empty +}; + +function reset_arguments(param) { + arg_spec.contents = /* [] */0; + arg_names.contents = Misc.StringMap.empty; + +} + +function add_arguments(loc, args) { + return List.iter((function (x) { + var arg_name = x[0]; + try { + var loc2 = Curry._2(Misc.StringMap.find, arg_name, arg_names.contents); + Curry._1(Printf.eprintf("Warning: plugin argument %s is already defined:\n"), arg_name); + Curry._1(Printf.eprintf(" First definition: %s\n"), loc2); + return Curry._1(Printf.eprintf(" New definition: %s\n"), loc); + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === "Not_found") { + arg_spec.contents = Pervasives.$at(arg_spec.contents, { + hd: x, + tl: /* [] */0 + }); + arg_names.contents = Curry._3(Misc.StringMap.add, arg_name, loc, arg_names.contents); + return ; + } + throw exn; + } + }), args); +} + +function print_arguments(usage) { + return Arg.usage(arg_spec.contents, usage); +} + +function parse_arguments(f, msg) { + try { + var argv = { + contents: Sys.argv + }; + var current = { + contents: Arg.current.contents + }; + return Arg.parse_and_expand_argv_dynamic(current, argv, arg_spec, f, msg); + } + catch (raw_msg){ + var msg$1 = Caml_js_exceptions.internalToOCamlException(raw_msg); + if (msg$1.RE_EXN_ID === Arg.Bad) { + Curry._1(Printf.eprintf("%s"), msg$1._1); + return Pervasives.exit(2); + } + if (msg$1.RE_EXN_ID === Arg.Help) { + Curry._1(Printf.printf("%s"), msg$1._1); + return Pervasives.exit(0); + } + throw msg$1; + } +} + +var inline_toplevel_multiplier = 16; + +var default_inline_call_cost = 5; + +var default_inline_alloc_cost = 7; + +var default_inline_prim_cost = 3; + +var default_inline_branch_cost = 5; + +var default_inline_indirect_cost = 4; + +var default_inline_branch_factor = 0.1; + +var default_inline_lifting_benefit = 1300; + +var default_inline_max_unroll = 0; + +var default_inline_max_depth = 1; + +var default_unbox_closures_factor = 10; + +var o1_arguments = { + inline_call_cost: undefined, + inline_alloc_cost: undefined, + inline_prim_cost: undefined, + inline_branch_cost: undefined, + inline_indirect_cost: undefined, + inline_lifting_benefit: undefined, + inline_branch_factor: undefined, + inline_max_depth: undefined, + inline_max_unroll: undefined, + inline_threshold: undefined, + inline_toplevel_threshold: undefined +}; + +export { + Int_arg_helper , + Float_arg_helper , + objfiles , + ccobjs , + dllibs , + compile_only , + output_name , + include_dirs , + no_std_include , + print_types , + make_archive , + debug , + fast , + use_linscan , + link_everything , + custom_runtime , + no_check_prims , + bytecode_compatible_32 , + output_c_object , + output_complete_object , + all_ccopts , + classic , + nopervasives , + preprocessor , + all_ppx , + annotations , + binary_annotations , + use_threads , + use_vmthreads , + noassert , + verbose , + noversion , + noprompt , + nopromptcont , + init_file , + noinit , + open_modules , + use_prims , + use_runtime , + principal , + real_paths , + recursive_types , + strict_sequence , + strict_formats , + applicative_functors , + make_runtime , + gprofile , + c_compiler , + no_auto_link , + dllpaths , + make_package , + for_package , + error_size , + float_const_prop , + transparent_modules , + dump_source , + dump_parsetree , + dump_typedtree , + dump_rawlambda , + dump_lambda , + dump_rawclambda , + dump_clambda , + dump_rawflambda , + dump_flambda , + dump_flambda_let , + dump_flambda_verbose , + dump_instr , + keep_asm_file , + optimize_for_speed , + opaque , + dump_cmm , + dump_selection , + dump_cse , + dump_live , + dump_avail , + dump_spill , + dump_split , + dump_interf , + dump_prefer , + dump_regalloc , + dump_reload , + dump_scheduling , + dump_linear , + dump_interval , + keep_startup_file , + dump_combine , + debug_runavail , + native_code , + force_slash , + clambda_checks , + flambda_invariant_checks , + dont_write_files , + std_include_flag , + std_include_dir , + shared , + dlcode , + pic_code , + runtime_variant , + keep_docs , + keep_locs , + unsafe_string , + classic_inlining , + inlining_report , + afl_instrument , + afl_inst_ratio , + simplify_rounds , + default_simplify_rounds , + rounds , + default_inline_threshold , + inline_toplevel_multiplier , + default_inline_toplevel_threshold , + default_inline_call_cost , + default_inline_alloc_cost , + default_inline_prim_cost , + default_inline_branch_cost , + default_inline_indirect_cost , + default_inline_branch_factor , + default_inline_lifting_benefit , + default_inline_max_unroll , + default_inline_max_depth , + unbox_specialised_args , + unbox_free_vars_of_closures , + unbox_closures , + default_unbox_closures_factor , + unbox_closures_factor , + remove_unused_arguments , + o1_arguments , + classic_arguments , + o2_arguments , + o3_arguments , + all_passes , + dumped_passes_list , + dumped_pass , + set_dumped_pass , + parse_color_setting , + color , + unboxed_types , + arg_spec , + arg_names , + reset_arguments , + add_arguments , + print_arguments , + parse_arguments , + +} +/* pic_code Not a pure module */ diff --git a/analysis/examples/larger-project/src/clflags.res b/analysis/examples/larger-project/src/clflags.res new file mode 100644 index 0000000000..106c215628 --- /dev/null +++ b/analysis/examples/larger-project/src/clflags.res @@ -0,0 +1,346 @@ +/* ************************************************************************ */ +/* */ +/* OCaml */ +/* */ +/* Xavier Leroy, projet Cristal, INRIA Rocquencourt */ +/* */ +/* Copyright 1996 Institut National de Recherche en Informatique et */ +/* en Automatique. */ +/* */ +/* All rights reserved. This file is distributed under the terms of */ +/* the GNU Lesser General Public License version 2.1, with the */ +/* special exception on linking described in the file LICENSE. */ +/* */ +/* ************************************************************************ */ + +/* Command-line parameters */ + +module Int_arg_helper = {} +module Float_arg_helper = { + +} + +let objfiles = ref((list{}: list)) /* .cmo and .cma files */ +and ccobjs = ref((list{}: list)) /* .o, .a, .so and -cclib -lxxx */ +and dllibs = ref((list{}: list)) /* .so and -dllib -lxxx */ + +let compile_only = ref(false) /* -c */ +and output_name = ref((None: option)) /* -o */ +and include_dirs = ref((list{}: list)) /* -I */ +and no_std_include = ref(false) /* -nostdlib */ +and print_types = ref(false) /* -i */ +and make_archive = ref(false) /* -a */ +and debug = ref(false) /* -g */ +and fast = ref(false) /* -unsafe */ +and use_linscan = ref(false) /* -linscan */ +and link_everything = ref(false) /* -linkall */ +and custom_runtime = ref(false) /* -custom */ +and no_check_prims = ref(false) /* -no-check-prims */ +and bytecode_compatible_32 = ref(false) /* -compat-32 */ +and output_c_object = ref(false) /* -output-obj */ +and output_complete_object = ref(false) /* -output-complete-obj */ +and all_ccopts = ref((list{}: list)) /* -ccopt */ +and classic = ref(false) /* -nolabels */ +and nopervasives = ref(false) /* -nopervasives */ +and preprocessor = ref((None: option)) /* -pp */ +and all_ppx = ref((list{}: list)) /* -ppx */ +let annotations = ref(false) /* -annot */ +let binary_annotations = ref(false) /* -annot */ +and use_threads = ref(false) /* -thread */ +and use_vmthreads = ref(false) /* -vmthread */ +and noassert = ref(false) /* -noassert */ +and verbose = ref(false) /* -verbose */ +and noversion = ref(false) /* -no-version */ +and noprompt = ref(false) /* -noprompt */ +and nopromptcont = ref(false) /* -nopromptcont */ +and init_file = ref((None: option)) /* -init */ +and noinit = ref(false) /* -noinit */ +and open_modules: ref> = ref(list{}) /* -open */ +and use_prims = ref("") /* -use-prims ... */ +and use_runtime = ref("") /* -use-runtime ... */ +and principal = ref(false) /* -principal */ +and real_paths = ref(true) /* -short-paths */ +and recursive_types = ref(false) /* -rectypes */ +and strict_sequence = ref(false) /* -strict-sequence */ +and strict_formats = ref(false) /* -strict-formats */ +and applicative_functors = ref(true) /* -no-app-funct */ +and make_runtime = ref(false) /* -make-runtime */ +and gprofile = ref(false) /* -p */ +and c_compiler = ref((None: option)) /* -cc */ +and no_auto_link = ref(false) /* -noautolink */ +and dllpaths = ref((list{}: list)) /* -dllpath */ +and make_package = ref(false) /* -pack */ +and for_package = ref((None: option)) /* -for-pack */ +and error_size = ref(500) /* -error-size */ +and float_const_prop = ref(true) /* -no-float-const-prop */ +and transparent_modules = ref(false) /* -trans-mod */ +let dump_source = ref(false) /* -dsource */ +let dump_parsetree = ref(false) /* -dparsetree */ +and dump_typedtree = ref(false) /* -dtypedtree */ +and dump_rawlambda = ref(false) /* -drawlambda */ +and dump_lambda = ref(false) /* -dlambda */ +and dump_rawclambda = ref(false) /* -drawclambda */ +and dump_clambda = ref(false) /* -dclambda */ +and dump_rawflambda = ref(false) /* -drawflambda */ +and dump_flambda = ref(false) /* -dflambda */ +and dump_flambda_let = ref((None: option)) /* -dflambda-let=... */ +and dump_flambda_verbose = ref(false) /* -dflambda-verbose */ +and dump_instr = ref(false) /* -dinstr */ + +let keep_asm_file = ref(false) /* -S */ +let optimize_for_speed = ref(true) /* -compact */ +and opaque = ref(false) /* -opaque */ + +and dump_cmm = ref(false) /* -dcmm */ +let dump_selection = ref(false) /* -dsel */ +let dump_cse = ref(false) /* -dcse */ +let dump_live = ref(false) /* -dlive */ +let dump_avail = ref(false) /* -davail */ +let dump_spill = ref(false) /* -dspill */ +let dump_split = ref(false) /* -dsplit */ +let dump_interf = ref(false) /* -dinterf */ +let dump_prefer = ref(false) /* -dprefer */ +let dump_regalloc = ref(false) /* -dalloc */ +let dump_reload = ref(false) /* -dreload */ +let dump_scheduling = ref(false) /* -dscheduling */ +let dump_linear = ref(false) /* -dlinear */ +let dump_interval = ref(false) /* -dinterval */ +let keep_startup_file = ref(false) /* -dstartup */ +let dump_combine = ref(false) /* -dcombine */ + +let debug_runavail = ref(false) /* -drunavail */ + +let native_code = ref(false) /* set to true under ocamlopt */ + +let force_slash = ref(false) /* for ocamldep */ +let clambda_checks = ref(false) /* -clambda-checks */ + +let flambda_invariant_checks = ref(true) /* -flambda-invariants */ + +let dont_write_files = ref(false) /* set to true under ocamldoc */ + +let std_include_flag = prefix => + if no_std_include.contents { + "" + } else { + prefix ++ Filename.quote(Config.standard_library) + } + +let std_include_dir = () => + if no_std_include.contents { + list{} + } else { + list{Config.standard_library} + } + +let shared = ref(false) /* -shared */ +let dlcode = ref(true) /* not -nodynlink */ + +let pic_code = ref( + switch Config.architecture { + /* -fPIC */ + | "amd64" => true + | _ => false + }, +) + +let runtime_variant = ref("") /* -runtime-variant */ + +let keep_docs = ref(false) /* -keep-docs */ +let keep_locs = ref(true) /* -keep-locs */ +let unsafe_string = if Config.safe_string { + ref(false) +} else { + ref(!Config.default_safe_string) +} +/* -safe-string / -unsafe-string */ + +let classic_inlining = ref(false) /* -Oclassic */ +let inlining_report = ref(false) /* -inlining-report */ + +let afl_instrument = ref(Config.afl_instrument) /* -afl-instrument */ +let afl_inst_ratio = ref(100) /* -afl-inst-ratio */ + +let simplify_rounds = ref(None) /* -rounds */ +let default_simplify_rounds = ref(1) /* -rounds */ +let rounds = () => + switch simplify_rounds.contents { + | None => default_simplify_rounds.contents + | Some(r) => r + } + +let default_inline_threshold = if Config.flambda { + 10. +} else { + 10. /. 8. +} +let inline_toplevel_multiplier = 16 +let default_inline_toplevel_threshold = int_of_float( + float(inline_toplevel_multiplier) *. default_inline_threshold, +) +let default_inline_call_cost = 5 +let default_inline_alloc_cost = 7 +let default_inline_prim_cost = 3 +let default_inline_branch_cost = 5 +let default_inline_indirect_cost = 4 +let default_inline_branch_factor = 0.1 +let default_inline_lifting_benefit = 1300 +let default_inline_max_unroll = 0 +let default_inline_max_depth = 1 + +let unbox_specialised_args = ref(true) /* -no-unbox-specialised-args */ +let unbox_free_vars_of_closures = ref(true) +let unbox_closures = ref(false) /* -unbox-closures */ +let default_unbox_closures_factor = 10 +let unbox_closures_factor = ref(default_unbox_closures_factor) /* -unbox-closures-factor */ +let remove_unused_arguments = ref(false) /* -remove-unused-arguments */ + +type inlining_arguments = { + inline_call_cost: option, + inline_alloc_cost: option, + inline_prim_cost: option, + inline_branch_cost: option, + inline_indirect_cost: option, + inline_lifting_benefit: option, + inline_branch_factor: option, + inline_max_depth: option, + inline_max_unroll: option, + inline_threshold: option, + inline_toplevel_threshold: option, +} + +/* o1 is the default */ +let o1_arguments = { + inline_call_cost: None, + inline_alloc_cost: None, + inline_prim_cost: None, + inline_branch_cost: None, + inline_indirect_cost: None, + inline_lifting_benefit: None, + inline_branch_factor: None, + inline_max_depth: None, + inline_max_unroll: None, + inline_threshold: None, + inline_toplevel_threshold: None, +} + +let classic_arguments = { + inline_call_cost: None, + inline_alloc_cost: None, + inline_prim_cost: None, + inline_branch_cost: None, + inline_indirect_cost: None, + inline_lifting_benefit: None, + inline_branch_factor: None, + inline_max_depth: None, + inline_max_unroll: None, + /* [inline_threshold] matches the current compiler's default. + Note that this particular fraction can be expressed exactly in + floating point. */ + inline_threshold: Some(10. /. 8.), + /* [inline_toplevel_threshold] is not used in classic mode. */ + inline_toplevel_threshold: Some(1), +} + +let o2_arguments = { + inline_call_cost: Some(2 * default_inline_call_cost), + inline_alloc_cost: Some(2 * default_inline_alloc_cost), + inline_prim_cost: Some(2 * default_inline_prim_cost), + inline_branch_cost: Some(2 * default_inline_branch_cost), + inline_indirect_cost: Some(2 * default_inline_indirect_cost), + inline_lifting_benefit: None, + inline_branch_factor: None, + inline_max_depth: Some(2), + inline_max_unroll: None, + inline_threshold: Some(25.), + inline_toplevel_threshold: Some(25 * inline_toplevel_multiplier), +} + +let o3_arguments = { + inline_call_cost: Some(3 * default_inline_call_cost), + inline_alloc_cost: Some(3 * default_inline_alloc_cost), + inline_prim_cost: Some(3 * default_inline_prim_cost), + inline_branch_cost: Some(3 * default_inline_branch_cost), + inline_indirect_cost: Some(3 * default_inline_indirect_cost), + inline_lifting_benefit: None, + inline_branch_factor: Some(0.), + inline_max_depth: Some(3), + inline_max_unroll: Some(1), + inline_threshold: Some(50.), + inline_toplevel_threshold: Some(50 * inline_toplevel_multiplier), +} + +let all_passes: ref> = ref(list{}) +let dumped_passes_list = ref(list{}) +let dumped_pass = s => { + assert List.mem(s, all_passes.contents) + List.mem(s, dumped_passes_list.contents) +} + +let set_dumped_pass = (s, enabled) => + if List.mem(s, all_passes.contents) { + let passes_without_s = List.filter(\"<>"(s), dumped_passes_list.contents) + let dumped_passes = if enabled { + list{s, ...passes_without_s} + } else { + passes_without_s + } + + dumped_passes_list := dumped_passes + } + +let parse_color_setting = x => + switch x { + | "auto" => Some(Misc.Color.Auto) + | "always" => Some(Misc.Color.Always) + | "never" => Some(Misc.Color.Never) + | _ => None + } +let color: ref> = ref(None) /* -color */ + +let unboxed_types = ref(false) + +let arg_spec = ref(list{}) +let arg_names : ref> = ref(Misc.StringMap.empty) + +let reset_arguments = () => { + arg_spec := list{} + arg_names := Misc.StringMap.empty +} + +let add_arguments = (loc, args) => List.iter(x => + switch x { + | (arg_name, _, _) as arg => + try { + let loc2 = Misc.StringMap.find(arg_name, arg_names.contents) + Printf.eprintf("Warning: plugin argument %s is already defined:\n", arg_name) + Printf.eprintf(" First definition: %s\n", loc2) + Printf.eprintf(" New definition: %s\n", loc) + } catch { + | Not_found => + arg_spec := \"@"(arg_spec.contents, list{arg}) + arg_names := Misc.StringMap.add(arg_name, loc, arg_names.contents) + } + } + , args) + +let print_arguments = usage => Arg.usage(arg_spec.contents, usage) + +/* This function is almost the same as [Arg.parse_expand], except + that [Arg.parse_expand] could not be used because it does not take a + reference for [arg_spec].*/ +@raises(exit) +let parse_arguments = (f, msg) => + try { + let argv = ref(Sys.argv) + let current = ref(Arg.current.contents) + Arg.parse_and_expand_argv_dynamic(current, argv, arg_spec, f, msg) + } catch { + | Arg.Bad(msg) => + Printf.eprintf("%s", msg) + exit(2) + | Arg.Help(msg) => + Printf.printf("%s", msg) + exit(0) + } + diff --git a/analysis/examples/larger-project/src/config.js b/analysis/examples/larger-project/src/config.js new file mode 100644 index 0000000000..50ce03020e --- /dev/null +++ b/analysis/examples/larger-project/src/config.js @@ -0,0 +1,362 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Sys from "rescript/lib/es6/sys.js"; +import * as Curry from "rescript/lib/es6/curry.js"; +import * as Printf from "./printf.js"; +import * as $$String from "rescript/lib/es6/string.js"; +import * as Caml_sys from "rescript/lib/es6/caml_sys.js"; +import * as Caml_string from "rescript/lib/es6/caml_string.js"; +import * as Caml_js_exceptions from "rescript/lib/es6/caml_js_exceptions.js"; + +var standard_library_default = "/usr/local/lib/ocaml"; + +var standard_library; + +try { + standard_library = Caml_sys.caml_sys_getenv("OCAMLLIB"); +} +catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === "Not_found") { + try { + standard_library = Caml_sys.caml_sys_getenv("CAMLLIB"); + } + catch (raw_exn$1){ + var exn$1 = Caml_js_exceptions.internalToOCamlException(raw_exn$1); + if (exn$1.RE_EXN_ID === "Not_found") { + standard_library = standard_library_default; + } else { + throw exn$1; + } + } + } else { + throw exn; + } +} + +var standard_runtime = "/usr/local/bin/ocamlrun"; + +var ccomp_type = "cc"; + +var c_compiler = "gcc"; + +var ocamlc_cflags = "-O2 -fno-strict-aliasing -fwrapv "; + +var ocamlc_cppflags = "-D_FILE_OFFSET_BITS=64 -D_REENTRANT"; + +var ocamlopt_cflags = "-O2 -fno-strict-aliasing -fwrapv"; + +var ocamlopt_cppflags = "-D_FILE_OFFSET_BITS=64 -D_REENTRANT"; + +var bytecomp_c_libraries = "-lpthread "; + +var bytecomp_c_compiler = "gcc -O2 -fno-strict-aliasing -fwrapv -D_FILE_OFFSET_BITS=64 -D_REENTRANT"; + +var native_c_compiler = "gcc -O2 -fno-strict-aliasing -fwrapv -D_FILE_OFFSET_BITS=64 -D_REENTRANT"; + +var native_c_libraries = ""; + +var native_pack_linker = "ld -r -arch x86_64 -o "; + +var ranlib = "ranlib"; + +var cc_profile = "-pg"; + +var match; + +if (Sys.os_type === "Win32") { + try { + var flexlink = Caml_sys.caml_sys_getenv("OCAML_FLEXLINK"); + var f = function (i) { + var c = Caml_string.get(flexlink, i); + if (c === /* '/' */47) { + return /* '\\' */92; + } else { + return c; + } + }; + var flexlink$1 = $$String.init(flexlink.length, f) + " "; + match = [ + flexlink$1, + flexlink$1 + " -exe", + flexlink$1 + " -maindll" + ]; + } + catch (raw_exn$2){ + var exn$2 = Caml_js_exceptions.internalToOCamlException(raw_exn$2); + if (exn$2.RE_EXN_ID === "Not_found") { + match = [ + "gcc -shared -flat_namespace -undefined suppress -Wl,-no_compact_unwind", + "gcc -O2 -fno-strict-aliasing -fwrapv -Wall -Werror -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DCAML_NAME_SPACE -Wl,-no_compact_unwind", + "gcc -shared -flat_namespace -undefined suppress -Wl,-no_compact_unwind" + ]; + } else { + throw exn$2; + } + } +} else { + match = [ + "gcc -shared -flat_namespace -undefined suppress -Wl,-no_compact_unwind", + "gcc -O2 -fno-strict-aliasing -fwrapv -Wall -Werror -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DCAML_NAME_SPACE -Wl,-no_compact_unwind", + "gcc -shared -flat_namespace -undefined suppress -Wl,-no_compact_unwind" + ]; +} + +var exec_magic_number = "Caml1999X011"; + +var cmi_magic_number = "Caml1999I022"; + +var cmo_magic_number = "Caml1999O022"; + +var cma_magic_number = "Caml1999A022"; + +var cmx_magic_number = "Caml1999Y022"; + +var cmxa_magic_number = "Caml1999Z022"; + +var ast_impl_magic_number = "Caml1999M022"; + +var ast_intf_magic_number = "Caml1999N022"; + +var cmxs_magic_number = "Caml1999D022"; + +var cmt_magic_number = "Caml1999T022"; + +var load_path = { + contents: /* [] */0 +}; + +var interface_suffix = { + contents: ".mli" +}; + +var architecture = "amd64"; + +var model = "default"; + +var system = "macosx"; + +var asm = "clang -arch x86_64 -Wno-trigraphs -c"; + +var ext_exe = ""; + +var ext_obj = ".o"; + +var ext_asm = ".s"; + +var ext_lib = ".a"; + +var ext_dll = ".so"; + +var host = "x86_64-apple-darwin21.4.0"; + +var target = "x86_64-apple-darwin21.4.0"; + +var default_executable_name; + +switch (Sys.os_type) { + case "Unix" : + default_executable_name = "a.out"; + break; + case "Cygwin" : + case "Win32" : + default_executable_name = "camlprog.exe"; + break; + default: + default_executable_name = "camlprog"; +} + +function print_config(oc) { + var p = function (name, valu) { + return Curry._3(Printf.fprintf(oc), "%s: %s\n", name, valu); + }; + var p_int = function (name, valu) { + return Curry._3(Printf.fprintf(oc), "%s: %d\n", name, valu); + }; + var p_bool = function (name, valu) { + return Curry._3(Printf.fprintf(oc), "%s: %B\n", name, valu); + }; + p("version", Sys.ocaml_version); + p("standard_library_default", standard_library_default); + p("standard_library", standard_library); + p("standard_runtime", standard_runtime); + p("ccomp_type", ccomp_type); + p("c_compiler", c_compiler); + p("ocamlc_cflags", ocamlc_cflags); + p("ocamlc_cppflags", ocamlc_cppflags); + p("ocamlopt_cflags", ocamlopt_cflags); + p("ocamlopt_cppflags", ocamlopt_cppflags); + p("bytecomp_c_compiler", bytecomp_c_compiler); + p("native_c_compiler", native_c_compiler); + p("bytecomp_c_libraries", bytecomp_c_libraries); + p("native_c_libraries", native_c_libraries); + p("native_pack_linker", native_pack_linker); + p("ranlib", ranlib); + p("cc_profile", cc_profile); + p("architecture", architecture); + p("model", model); + p_int("int_size", Sys.int_size); + p_int("word_size", Sys.word_size); + p("system", system); + p("asm", asm); + p_bool("asm_cfi_supported", true); + p_bool("with_frame_pointers", false); + p("ext_exe", ext_exe); + p("ext_obj", ext_obj); + p("ext_asm", ext_asm); + p("ext_lib", ext_lib); + p("ext_dll", ext_dll); + p("os_type", Sys.os_type); + p("default_executable_name", default_executable_name); + p_bool("systhread_supported", true); + p("host", host); + p("target", target); + p_bool("profiling", true); + p_bool("flambda", false); + p_bool("spacetime", false); + p_bool("safe_string", false); + p_bool("default_safe_string", true); + p_bool("flat_float_array", true); + p_bool("afl_instrument", false); + p_bool("windows_unicode", false); + p("exec_magic_number", exec_magic_number); + p("cmi_magic_number", cmi_magic_number); + p("cmo_magic_number", cmo_magic_number); + p("cma_magic_number", cma_magic_number); + p("cmx_magic_number", cmx_magic_number); + p("cmxa_magic_number", cmxa_magic_number); + p("ast_impl_magic_number", ast_impl_magic_number); + p("ast_intf_magic_number", ast_intf_magic_number); + p("cmxs_magic_number", cmxs_magic_number); + return p("cmt_magic_number", cmt_magic_number); +} + +var version = Sys.ocaml_version; + +var c_output_obj = "-o "; + +var ar = "ar"; + +var mkdll = match[0]; + +var mkexe = match[1]; + +var mkmaindll = match[2]; + +var profiling = true; + +var flambda = false; + +var safe_string = false; + +var default_safe_string = true; + +var windows_unicode = false; + +var flat_float_array = true; + +var afl_instrument = false; + +var max_tag = 245; + +var lazy_tag = 246; + +var max_young_wosize = 256; + +var stack_threshold = 256; + +var stack_safety_margin = 60; + +var asm_cfi_supported = true; + +var with_frame_pointers = false; + +var spacetime = false; + +var enable_call_counts = true; + +var libunwind_available = false; + +var libunwind_link_flags = ""; + +var profinfo = false; + +var profinfo_width = 0; + +var systhread_supported = true; + +var flexdll_dirs = /* [] */0; + +export { + version , + standard_library_default , + standard_library , + standard_runtime , + ccomp_type , + c_compiler , + c_output_obj , + ocamlc_cflags , + ocamlc_cppflags , + ocamlopt_cflags , + ocamlopt_cppflags , + bytecomp_c_libraries , + bytecomp_c_compiler , + native_c_compiler , + native_c_libraries , + native_pack_linker , + ranlib , + ar , + cc_profile , + mkdll , + mkexe , + mkmaindll , + profiling , + flambda , + safe_string , + default_safe_string , + windows_unicode , + flat_float_array , + afl_instrument , + exec_magic_number , + cmi_magic_number , + cmo_magic_number , + cma_magic_number , + cmx_magic_number , + cmxa_magic_number , + ast_impl_magic_number , + ast_intf_magic_number , + cmxs_magic_number , + cmt_magic_number , + load_path , + interface_suffix , + max_tag , + lazy_tag , + max_young_wosize , + stack_threshold , + stack_safety_margin , + architecture , + model , + system , + asm , + asm_cfi_supported , + with_frame_pointers , + spacetime , + enable_call_counts , + libunwind_available , + libunwind_link_flags , + profinfo , + profinfo_width , + ext_exe , + ext_obj , + ext_asm , + ext_lib , + ext_dll , + host , + target , + default_executable_name , + systhread_supported , + flexdll_dirs , + print_config , + +} +/* standard_library Not a pure module */ diff --git a/analysis/examples/larger-project/src/config.res b/analysis/examples/larger-project/src/config.res new file mode 100644 index 0000000000..c856664d12 --- /dev/null +++ b/analysis/examples/larger-project/src/config.res @@ -0,0 +1,222 @@ +/* ************************************************************************ */ +/* */ +/* OCaml */ +/* */ +/* Xavier Leroy, projet Cristal, INRIA Rocquencourt */ +/* */ +/* Copyright 1996 Institut National de Recherche en Informatique et */ +/* en Automatique. */ +/* */ +/* All rights reserved. This file is distributed under the terms of */ +/* the GNU Lesser General Public License version 2.1, with the */ +/* special exception on linking described in the file LICENSE. */ +/* */ +/* ************************************************************************ */ + +/* The main OCaml version string has moved to ../VERSION */ +let version = Sys.ocaml_version + +let standard_library_default = "/usr/local/lib/ocaml" + +let standard_library = try Sys.getenv("OCAMLLIB") catch { +| Not_found => + try Sys.getenv("CAMLLIB") catch { + | Not_found => standard_library_default + } +} + +let standard_runtime = "/usr/local/bin/ocamlrun" +let ccomp_type = "cc" +let c_compiler = "gcc" +let c_output_obj = "-o " +let ocamlc_cflags = "-O2 -fno-strict-aliasing -fwrapv " +let ocamlc_cppflags = "-D_FILE_OFFSET_BITS=64 -D_REENTRANT" +let ocamlopt_cflags = "-O2 -fno-strict-aliasing -fwrapv" +let ocamlopt_cppflags = "-D_FILE_OFFSET_BITS=64 -D_REENTRANT" +let bytecomp_c_libraries = "-lpthread " +/* bytecomp_c_compiler and native_c_compiler have been supported for a + long time and are retained for backwards compatibility. + For programs that don't need compatibility with older OCaml releases + the recommended approach is to use the constituent variables + c_compiler, ocamlc_cflags, ocamlc_cppflags etc., directly. +*/ +let bytecomp_c_compiler = c_compiler ++ (" " ++ (ocamlc_cflags ++ (" " ++ ocamlc_cppflags))) +let native_c_compiler = c_compiler ++ (" " ++ (ocamlopt_cflags ++ (" " ++ ocamlopt_cppflags))) +let native_c_libraries = "" +let native_pack_linker = "ld -r -arch x86_64 -o\ " +let ranlib = "ranlib" +let ar = "ar" +let cc_profile = "-pg" +let (mkdll, mkexe, mkmaindll) = /* @@DRA Cygwin - but only if shared libraries are enabled, which we + should be able to detect? */ +if Sys.os_type == "Win32" { + try { + @raises(Invalid_argument) + let flexlink = { + let flexlink = Sys.getenv("OCAML_FLEXLINK") + + @raises(Invalid_argument) + let f = i => { + let c = String.get(flexlink, i) + if c == '/' { + '\\' + } else { + c + } + } + String.init(String.length(flexlink), f) ++ " " + } + (flexlink, flexlink ++ " -exe", flexlink ++ " -maindll") + } catch { + | Not_found => ( + "gcc -shared -flat_namespace -undefined suppress -Wl,-no_compact_unwind", + "gcc -O2 -fno-strict-aliasing -fwrapv -Wall -Werror -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DCAML_NAME_SPACE -Wl,-no_compact_unwind", + "gcc -shared -flat_namespace -undefined suppress -Wl,-no_compact_unwind", + ) + } +} else { + ( + "gcc -shared -flat_namespace -undefined suppress -Wl,-no_compact_unwind", + "gcc -O2 -fno-strict-aliasing -fwrapv -Wall -Werror -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DCAML_NAME_SPACE -Wl,-no_compact_unwind", + "gcc -shared -flat_namespace -undefined suppress -Wl,-no_compact_unwind", + ) +} + +let profiling = true +let flambda = false +let safe_string = false +let default_safe_string = true +let windows_unicode = 0 !== 0 + +let flat_float_array = true + +let afl_instrument = false + +let exec_magic_number = "Caml1999X011" +and cmi_magic_number = "Caml1999I022" +and cmo_magic_number = "Caml1999O022" +and cma_magic_number = "Caml1999A022" +and cmx_magic_number = if flambda { + "Caml1999y022" +} else { + "Caml1999Y022" +} +and cmxa_magic_number = if flambda { + "Caml1999z022" +} else { + "Caml1999Z022" +} +and ast_impl_magic_number = "Caml1999M022" +and ast_intf_magic_number = "Caml1999N022" +and cmxs_magic_number = "Caml1999D022" +/* cmxs_magic_number is duplicated in otherlibs/dynlink/natdynlink.ml */ +and cmt_magic_number = "Caml1999T022" + +let load_path = ref((list{}: list)) + +let interface_suffix = ref(".mli") + +let max_tag = 245 +/* This is normally the same as in obj.ml, but we have to define it + separately because it can differ when we're in the middle of a + bootstrapping phase. */ +let lazy_tag = 246 + +let max_young_wosize = 256 +let stack_threshold = 256 /* see byterun/config.h */ +let stack_safety_margin = 60 + +let architecture = "amd64" +let model = "default" +let system = "macosx" + +let asm = "clang -arch x86_64 -Wno-trigraphs -c" +let asm_cfi_supported = true +let with_frame_pointers = false +let spacetime = false +let enable_call_counts = true +let libunwind_available = false +let libunwind_link_flags = "" +let profinfo = false +let profinfo_width = 0 + +let ext_exe = "" +let ext_obj = ".o" +let ext_asm = ".s" +let ext_lib = ".a" +let ext_dll = ".so" + +let host = "x86_64-apple-darwin21.4.0" +let target = "x86_64-apple-darwin21.4.0" + +let default_executable_name = switch Sys.os_type { +| "Unix" => "a.out" +| "Win32" | "Cygwin" => "camlprog.exe" +| _ => "camlprog" +} + +let systhread_supported = true + +let flexdll_dirs = list{} + +let print_config = oc => { + let p = (name, valu) => Printf.fprintf(oc, "%s: %s\n", name, valu) + let p_int = (name, valu) => Printf.fprintf(oc, "%s: %d\n", name, valu) + let p_bool = (name, valu) => Printf.fprintf(oc, "%s: %B\n", name, valu) + p("version", version) + p("standard_library_default", standard_library_default) + p("standard_library", standard_library) + p("standard_runtime", standard_runtime) + p("ccomp_type", ccomp_type) + p("c_compiler", c_compiler) + p("ocamlc_cflags", ocamlc_cflags) + p("ocamlc_cppflags", ocamlc_cppflags) + p("ocamlopt_cflags", ocamlopt_cflags) + p("ocamlopt_cppflags", ocamlopt_cppflags) + p("bytecomp_c_compiler", bytecomp_c_compiler) + p("native_c_compiler", native_c_compiler) + p("bytecomp_c_libraries", bytecomp_c_libraries) + p("native_c_libraries", native_c_libraries) + p("native_pack_linker", native_pack_linker) + p("ranlib", ranlib) + p("cc_profile", cc_profile) + p("architecture", architecture) + p("model", model) + p_int("int_size", Sys.int_size) + p_int("word_size", Sys.word_size) + p("system", system) + p("asm", asm) + p_bool("asm_cfi_supported", asm_cfi_supported) + p_bool("with_frame_pointers", with_frame_pointers) + p("ext_exe", ext_exe) + p("ext_obj", ext_obj) + p("ext_asm", ext_asm) + p("ext_lib", ext_lib) + p("ext_dll", ext_dll) + p("os_type", Sys.os_type) + p("default_executable_name", default_executable_name) + p_bool("systhread_supported", systhread_supported) + p("host", host) + p("target", target) + p_bool("profiling", profiling) + p_bool("flambda", flambda) + p_bool("spacetime", spacetime) + p_bool("safe_string", safe_string) + p_bool("default_safe_string", default_safe_string) + p_bool("flat_float_array", flat_float_array) + p_bool("afl_instrument", afl_instrument) + p_bool("windows_unicode", windows_unicode) + + /* print the magic number */ + p("exec_magic_number", exec_magic_number) + p("cmi_magic_number", cmi_magic_number) + p("cmo_magic_number", cmo_magic_number) + p("cma_magic_number", cma_magic_number) + p("cmx_magic_number", cmx_magic_number) + p("cmxa_magic_number", cmxa_magic_number) + p("ast_impl_magic_number", ast_impl_magic_number) + p("ast_intf_magic_number", ast_intf_magic_number) + p("cmxs_magic_number", cmxs_magic_number) + p("cmt_magic_number", cmt_magic_number) + +} diff --git a/analysis/examples/larger-project/src/exception/Arr.js b/analysis/examples/larger-project/src/exception/Arr.js new file mode 100644 index 0000000000..ec423e8722 --- /dev/null +++ b/analysis/examples/larger-project/src/exception/Arr.js @@ -0,0 +1,24 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Belt_Array from "rescript/lib/es6/belt_Array.js"; + +function ff(a) { + Belt_Array.get(a, 3); + return 11; +} + +var MM = { + ff: ff +}; + +var B; + +var $$Array; + +export { + B , + $$Array , + MM , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/exception/Arr.res b/analysis/examples/larger-project/src/exception/Arr.res new file mode 100644 index 0000000000..320a7c85d2 --- /dev/null +++ b/analysis/examples/larger-project/src/exception/Arr.res @@ -0,0 +1,9 @@ +module B = Belt +module Array = B.Array + +module MM = { + let ff = a => + switch a[3] { + | _ => 11 + } +} diff --git a/analysis/examples/larger-project/src/exception/BeltTest.js b/analysis/examples/larger-project/src/exception/BeltTest.js new file mode 100644 index 0000000000..693b400d47 --- /dev/null +++ b/analysis/examples/larger-project/src/exception/BeltTest.js @@ -0,0 +1,41 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Belt_Map from "rescript/lib/es6/belt_Map.js"; +import * as Belt_List from "rescript/lib/es6/belt_List.js"; +import * as Belt_MapInt from "rescript/lib/es6/belt_MapInt.js"; +import * as Belt_MapString from "rescript/lib/es6/belt_MapString.js"; + +var lstHead1 = Belt_List.headExn; + +var lstHead2 = Belt_List.headExn; + +var mapGetExn1 = Belt_MapInt.getExn; + +var mapGetExn2 = Belt_MapInt.getExn; + +var mapGetExn3 = Belt_MapInt.getExn; + +var mapGetExn4 = Belt_MapString.getExn; + +var mapGetExn5 = Belt_MapString.getExn; + +var mapGetExn6 = Belt_MapString.getExn; + +var mapGetExn7 = Belt_Map.getExn; + +var mapGetExn8 = Belt_Map.getExn; + +export { + lstHead1 , + lstHead2 , + mapGetExn1 , + mapGetExn2 , + mapGetExn3 , + mapGetExn4 , + mapGetExn5 , + mapGetExn6 , + mapGetExn7 , + mapGetExn8 , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/exception/BeltTest.res b/analysis/examples/larger-project/src/exception/BeltTest.res new file mode 100644 index 0000000000..4205f3e0b7 --- /dev/null +++ b/analysis/examples/larger-project/src/exception/BeltTest.res @@ -0,0 +1,31 @@ +open Belt.List + +@raises(Not_found) +let lstHead1 = l => l->Belt.List.headExn + +@raises(Not_found) +let lstHead2 = l => l->Belt_List.headExn + +@raises(Not_found) +let mapGetExn1 = (s, k) => s->Belt.Map.Int.getExn(k) + +@raises(Not_found) +let mapGetExn2 = (s, k) => s->Belt_Map.Int.getExn(k) + +@raises(Not_found) +let mapGetExn3 = (s, k) => s->Belt_MapInt.getExn(k) + +@raises(Not_found) +let mapGetExn4 = (s, k) => s->Belt.Map.String.getExn(k) + +@raises(Not_found) +let mapGetExn5 = (s, k) => s->Belt_Map.String.getExn(k) + +@raises(Not_found) +let mapGetExn6 = (s, k) => s->Belt_MapString.getExn(k) + +@raises(Not_found) +let mapGetExn7 = (s, k) => s->Belt.Map.getExn(k) + +@raises(Not_found) +let mapGetExn8 = (s, k) => s->Belt_Map.getExn(k) diff --git a/analysis/examples/larger-project/src/exception/BsJson.js b/analysis/examples/larger-project/src/exception/BsJson.js new file mode 100644 index 0000000000..65921ddc65 --- /dev/null +++ b/analysis/examples/larger-project/src/exception/BsJson.js @@ -0,0 +1,14 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Json_decode from "@glennsl/bs-json/src/Json_decode.js"; + +var testBsJson = Json_decode.string; + +var testBsJson2 = Json_decode.string; + +export { + testBsJson , + testBsJson2 , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/exception/BsJson.res b/analysis/examples/larger-project/src/exception/BsJson.res new file mode 100644 index 0000000000..ad892c8e7b --- /dev/null +++ b/analysis/examples/larger-project/src/exception/BsJson.res @@ -0,0 +1,5 @@ +@raise(DecodeError) +let testBsJson = x => Json_decode.string(x) + +@raise(DecodeError) +let testBsJson2 = x => Json.Decode.string(x) diff --git a/analysis/examples/larger-project/src/exception/Exn.js b/analysis/examples/larger-project/src/exception/Exn.js new file mode 100644 index 0000000000..d856702bfe --- /dev/null +++ b/analysis/examples/larger-project/src/exception/Exn.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/analysis/examples/larger-project/src/exception/Exn.res b/analysis/examples/larger-project/src/exception/Exn.res new file mode 100644 index 0000000000..e69de29bb2 diff --git a/analysis/examples/larger-project/src/exception/ExnA.js b/analysis/examples/larger-project/src/exception/ExnA.js new file mode 100644 index 0000000000..d856702bfe --- /dev/null +++ b/analysis/examples/larger-project/src/exception/ExnA.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/analysis/examples/larger-project/src/exception/ExnA.res b/analysis/examples/larger-project/src/exception/ExnA.res new file mode 100644 index 0000000000..e69de29bb2 diff --git a/analysis/examples/larger-project/src/exception/ExnB.js b/analysis/examples/larger-project/src/exception/ExnB.js new file mode 100644 index 0000000000..4967199b18 --- /dev/null +++ b/analysis/examples/larger-project/src/exception/ExnB.js @@ -0,0 +1,15 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function foo(param) { + throw { + RE_EXN_ID: "Not_found", + Error: new Error() + }; +} + +export { + foo , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/exception/ExnB.res b/analysis/examples/larger-project/src/exception/ExnB.res new file mode 100644 index 0000000000..2a50ef4652 --- /dev/null +++ b/analysis/examples/larger-project/src/exception/ExnB.res @@ -0,0 +1,2 @@ +@raises(Not_found) +let foo = () => raise(Not_found) diff --git a/analysis/examples/larger-project/src/exception/ExportWithRename.js b/analysis/examples/larger-project/src/exception/ExportWithRename.js new file mode 100644 index 0000000000..dbbd1bbf92 --- /dev/null +++ b/analysis/examples/larger-project/src/exception/ExportWithRename.js @@ -0,0 +1,14 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function ExportWithRename(Props) { + return Props.s; +} + +var make = ExportWithRename; + +export { + make , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/exception/ExportWithRename.res b/analysis/examples/larger-project/src/exception/ExportWithRename.res new file mode 100644 index 0000000000..b8b4865b2a --- /dev/null +++ b/analysis/examples/larger-project/src/exception/ExportWithRename.res @@ -0,0 +1,2 @@ +@genType("ExportWithRename") @react.component +let make = (~s) => React.string(s) diff --git a/analysis/examples/larger-project/src/exception/InnerModules.js b/analysis/examples/larger-project/src/exception/InnerModules.js new file mode 100644 index 0000000000..9ddf89f8ab --- /dev/null +++ b/analysis/examples/larger-project/src/exception/InnerModules.js @@ -0,0 +1,40 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Pervasives from "rescript/lib/es6/pervasives.js"; + +var wrapExitTop = Pervasives.exit; + +var wrapExitM1 = Pervasives.exit; + +var callLocally = Pervasives.exit; + +var callTop = Pervasives.exit; + +var wrapExitM2 = Pervasives.exit; + +var callM1 = Pervasives.exit; + +var callTop$1 = Pervasives.exit; + +var M2 = { + wrapExitM2: wrapExitM2, + callM1: callM1, + callTop: callTop$1 +}; + +var M1 = { + wrapExitM1: wrapExitM1, + callLocally: callLocally, + callTop: callTop, + M2: M2 +}; + +var callM1$1 = Pervasives.exit; + +export { + wrapExitTop , + M1 , + callM1$1 as callM1, + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/exception/InnerModules.res b/analysis/examples/larger-project/src/exception/InnerModules.res new file mode 100644 index 0000000000..7c7f9dc1a0 --- /dev/null +++ b/analysis/examples/larger-project/src/exception/InnerModules.res @@ -0,0 +1,27 @@ +@raises(exit) +let wrapExitTop = x => exit(x) + +module M1 = { + @raises(exit) + let wrapExitM1 = x => exit(x) + + @raises(exit) + let callLocally = x => wrapExitM1(x) + + @raises(exit) + let callTop = x => wrapExitTop(x) + + module M2 = { + @raises(exit) + let wrapExitM2 = x => exit(x) + + @raises(exit) + let callM1 = x => wrapExitM1(x) + + @raises(exit) + let callTop = x => wrapExitTop(x) + } +} + +@raises(exit) +let callM1 = x => M1.wrapExitM1(x) diff --git a/analysis/examples/larger-project/src/exception/TestInnerModules.js b/analysis/examples/larger-project/src/exception/TestInnerModules.js new file mode 100644 index 0000000000..0d15a24c7f --- /dev/null +++ b/analysis/examples/larger-project/src/exception/TestInnerModules.js @@ -0,0 +1,22 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Curry from "rescript/lib/es6/curry.js"; +import * as InnerModules from "./InnerModules.js"; + +var testTop = InnerModules.wrapExitTop; + +function testM1(x) { + return InnerModules.M1.wrapExitM1(x); +} + +function testM2(x) { + return Curry._1(InnerModules.M1.M2.wrapExitM2, x); +} + +export { + testTop , + testM1 , + testM2 , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/exception/TestInnerModules.res b/analysis/examples/larger-project/src/exception/TestInnerModules.res new file mode 100644 index 0000000000..6b1e88516b --- /dev/null +++ b/analysis/examples/larger-project/src/exception/TestInnerModules.res @@ -0,0 +1,8 @@ +@raises(exit) +let testTop = x => InnerModules.wrapExitTop(x) + +@raises(exit) +let testM1 = x => InnerModules.M1.wrapExitM1(x) + +@raises(exit) +let testM2 = x => InnerModules.M1.M2.wrapExitM2(x) diff --git a/analysis/examples/larger-project/src/exception/TestYojson.js b/analysis/examples/larger-project/src/exception/TestYojson.js new file mode 100644 index 0000000000..e7efc9a066 --- /dev/null +++ b/analysis/examples/larger-project/src/exception/TestYojson.js @@ -0,0 +1,46 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Curry from "rescript/lib/es6/curry.js"; +import * as Yojson from "./Yojson.js"; +import * as Caml_obj from "rescript/lib/es6/caml_obj.js"; +import * as Caml_js_exceptions from "rescript/lib/es6/caml_js_exceptions.js"; + +function foo(x) { + return Yojson.Basic.from_string(x); +} + +function bar(str, json) { + try { + return Curry._2(Yojson.Basic.Util.member, str, json); + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === Yojson.Basic.Util.Type_error) { + if (exn._1 === "a") { + if (Caml_obj.caml_equal(exn._2, json)) { + return json; + } + throw exn; + } + throw exn; + } + throw exn; + } +} + +function toString(x) { + return Curry._1(Yojson.Basic.Util.to_string, x); +} + +function toInt(x) { + return Curry._1(Yojson.Basic.Util.to_int, x); +} + +export { + foo , + bar , + toString , + toInt , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/exception/TestYojson.res b/analysis/examples/larger-project/src/exception/TestYojson.res new file mode 100644 index 0000000000..2614fd1f53 --- /dev/null +++ b/analysis/examples/larger-project/src/exception/TestYojson.res @@ -0,0 +1,17 @@ +@raises(Yojson.Json_error) +let foo = x => Yojson.Basic.from_string(x) + +let bar = (str, json) => + switch { + open Yojson.Basic.Util + json |> member(str) + } { + | j => j + | exception Yojson.Basic.Util.Type_error("a", d) if d == json => json + } + +@raises(Yojson.Basic.Util.Type_error) +let toString = x => Yojson.Basic.Util.to_string(x) + +@raises(Yojson.Basic.Util.Type_error) +let toInt = x => Yojson.Basic.Util.to_int(x) diff --git a/analysis/examples/larger-project/src/exception/Yojson.js b/analysis/examples/larger-project/src/exception/Yojson.js new file mode 100644 index 0000000000..ce892f7943 --- /dev/null +++ b/analysis/examples/larger-project/src/exception/Yojson.js @@ -0,0 +1,51 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Caml_exceptions from "rescript/lib/es6/caml_exceptions.js"; + +var Json_error = /* @__PURE__ */Caml_exceptions.create("Yojson.Json_error"); + +function from_string(param) { + throw { + RE_EXN_ID: Json_error, + _1: "Basic.from_string", + Error: new Error() + }; +} + +var Type_error = /* @__PURE__ */Caml_exceptions.create("Yojson.Basic.Util.Type_error"); + +function member(_s, j) { + throw { + RE_EXN_ID: Type_error, + _1: "Basic.Util.member", + _2: j, + Error: new Error() + }; +} + +function to_int(param) { + return 34; +} + +function to_string(param) { + return ""; +} + +var Util = { + Type_error: Type_error, + member: member, + to_int: to_int, + to_string: to_string +}; + +var Basic = { + from_string: from_string, + Util: Util +}; + +export { + Json_error , + Basic , + +} +/* No side effect */ diff --git a/analysis/examples/larger-project/src/exception/Yojson.res b/analysis/examples/larger-project/src/exception/Yojson.res new file mode 100644 index 0000000000..40758bda19 --- /dev/null +++ b/analysis/examples/larger-project/src/exception/Yojson.res @@ -0,0 +1,19 @@ +exception Json_error(string) + +module Basic = { + type t + + @raises(Json_error) + let from_string: string => t = _ => raise(Json_error("Basic.from_string")) + + module Util = { + exception Type_error(string, t) + + @raises(Type_error) + let member: (string, t) => t = (_s, j) => raise(Type_error("Basic.Util.member", j)) + + let to_int: t => int = _ => 34 + + let to_string: t => string = _ => "" + } +} diff --git a/analysis/examples/larger-project/src/format.js b/analysis/examples/larger-project/src/format.js new file mode 100644 index 0000000000..2a8e65c13e --- /dev/null +++ b/analysis/examples/larger-project/src/format.js @@ -0,0 +1,29 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +throw { + RE_EXN_ID: "Assert_failure", + _1: [ + "format.res", + 3, + 20 + ], + Error: new Error() + }; + +export { + std_formatter , + err_formatter , + str_formatter , + fprintf , + sprintf , + kasprintf , + asprintf , + kfprintf , + set_mark_tags , + formatter_of_buffer , + pp_print_flush , + pp_print_as , + +} +/* std_formatter Not a pure module */ diff --git a/analysis/examples/larger-project/src/format.res b/analysis/examples/larger-project/src/format.res new file mode 100644 index 0000000000..007ed334ce --- /dev/null +++ b/analysis/examples/larger-project/src/format.res @@ -0,0 +1,23 @@ +type formatter + +let std_formatter = assert false +let err_formatter = assert false +let str_formatter = assert false + +let fprintf = _ => assert false + +let sprintf = _ => assert false + +let kasprintf = _ => assert false + +let asprintf = _ => assert false + +let kfprintf = _ => assert false + +let set_mark_tags = _ => assert false + +let formatter_of_buffer = _ => assert false + +let pp_print_flush = _ => assert false + +let pp_print_as = _ => assert false \ No newline at end of file diff --git a/analysis/examples/larger-project/src/identifiable.js b/analysis/examples/larger-project/src/identifiable.js new file mode 100644 index 0000000000..0e5002b547 --- /dev/null +++ b/analysis/examples/larger-project/src/identifiable.js @@ -0,0 +1,1312 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as $$Map from "rescript/lib/es6/map.js"; +import * as $$Set from "rescript/lib/es6/set.js"; +import * as List from "rescript/lib/es6/list.js"; +import * as Misc from "./misc.js"; +import * as Curry from "rescript/lib/es6/curry.js"; +import * as Format from "./format.js"; +import * as Printf from "./printf.js"; +import * as Hashtbl from "rescript/lib/es6/hashtbl.js"; +import * as Caml_option from "rescript/lib/es6/caml_option.js"; +import * as Caml_js_exceptions from "rescript/lib/es6/caml_js_exceptions.js"; + +function Pair(A, B) { + var compare = function (param, param$1) { + var c = Curry._2(A.compare, param[0], param$1[0]); + if (c !== 0) { + return c; + } else { + return Curry._2(B.compare, param[1], param$1[1]); + } + }; + var output = function (oc, param) { + return Curry._5(Printf.fprintf(oc), " (%a, %a)", A.output, param[0], B.output, param[1]); + }; + var hash = function (param) { + return Hashtbl.hash([ + Curry._1(A.hash, param[0]), + Curry._1(B.hash, param[1]) + ]); + }; + var equal = function (param, param$1) { + if (Curry._2(A.equal, param[0], param$1[0])) { + return Curry._2(B.equal, param[1], param$1[1]); + } else { + return false; + } + }; + var print = function (ppf, param) { + return Curry._5(Format.fprintf(ppf), " (%a, @ %a)", A.print, param[0], B.print, param[1]); + }; + return { + equal: equal, + hash: hash, + compare: compare, + output: output, + print: print + }; +} + +function Make_map(T) { + var include = $$Map.Make({ + compare: T.compare + }); + var empty = include.empty; + var add = include.add; + var merge = include.merge; + var union = include.union; + var iter = include.iter; + var fold = include.fold; + var bindings = include.bindings; + var find = include.find; + var filter_map = function (t, f) { + return Curry._3(fold, (function (id, v, map) { + var r = Curry._2(f, id, v); + if (r !== undefined) { + return Curry._3(add, id, Caml_option.valFromOption(r), map); + } else { + return map; + } + }), t, empty); + }; + var of_list = function (l) { + return List.fold_left((function (map, param) { + return Curry._3(add, param[0], param[1], map); + }), empty, l); + }; + var disjoint_union = function (eq, print, m1, m2) { + return Curry._3(union, (function (id, v1, v2) { + var ok = eq !== undefined ? Curry._2(eq, v1, v2) : false; + if (ok) { + return Caml_option.some(v1); + } + var tmp; + if (print !== undefined) { + var print$1 = Caml_option.valFromOption(print); + tmp = Curry._6(Format.asprintf("Map.disjoint_union %a => %a <> %a"), T.print, id, print$1, v1, print$1, v2); + } else { + tmp = Curry._2(Format.asprintf("Map.disjoint_union %a"), T.print, id); + } + return Misc.fatal_error(tmp); + }), m1, m2); + }; + var union_right = function (m1, m2) { + return Curry._3(merge, (function (_id, x, y) { + if (x !== undefined) { + if (y !== undefined) { + return Caml_option.some(Caml_option.valFromOption(y)); + } else { + return Caml_option.some(Caml_option.valFromOption(x)); + } + } else if (y !== undefined) { + return Caml_option.some(Caml_option.valFromOption(y)); + } else { + return ; + } + }), m1, m2); + }; + var union_left = function (m1, m2) { + return union_right(m2, m1); + }; + var union_merge = function (f, m1, m2) { + var aux = function (param, m1, m2) { + if (m1 !== undefined) { + if (m2 !== undefined) { + return Caml_option.some(Curry._2(f, Caml_option.valFromOption(m1), Caml_option.valFromOption(m2))); + } else { + return m1; + } + } else { + return m2; + } + }; + return Curry._3(merge, aux, m1, m2); + }; + var rename = function (m, v) { + try { + return Curry._2(find, v, m); + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === "Not_found") { + return v; + } + throw exn; + } + }; + var map_keys = function (f, m) { + return of_list(List.map((function (param) { + return [ + Curry._1(f, param[0]), + param[1] + ]; + }), Curry._1(bindings, m))); + }; + var print = function (f, ppf, s) { + var elts = function (ppf, s) { + return Curry._2(iter, (function (id, v) { + return Curry._5(Format.fprintf(ppf), "@ (@[%a@ %a@])", T.print, id, f, v); + }), s); + }; + return Curry._3(Format.fprintf(ppf), "@[<1>{@[%a@ @]}@]", elts, s); + }; + var T_set = $$Set.Make({ + compare: T.compare + }); + var keys = function (map) { + return Curry._3(fold, (function (k, param, set) { + return Curry._2(T_set.add, k, set); + }), map, T_set.empty); + }; + var data = function (t) { + return List.map((function (prim) { + return prim[1]; + }), Curry._1(bindings, t)); + }; + var of_set = function (f, set) { + return Curry._3(T_set.fold, (function (e, map) { + return Curry._3(add, e, Curry._1(f, e), map); + }), set, empty); + }; + var transpose_keys_and_data = function (map) { + return Curry._3(fold, (function (k, v, m) { + return Curry._3(add, v, k, m); + }), map, empty); + }; + var transpose_keys_and_data_set = function (map) { + return Curry._3(fold, (function (k, v, m) { + var set; + var exit = 0; + var set$1; + try { + set$1 = Curry._2(find, v, m); + exit = 1; + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === "Not_found") { + set = Curry._1(T_set.singleton, k); + } else { + throw exn; + } + } + if (exit === 1) { + set = Curry._2(T_set.add, k, set$1); + } + return Curry._3(add, v, set, m); + }), map, empty); + }; + return { + empty: empty, + is_empty: include.is_empty, + mem: include.mem, + add: add, + update: include.update, + singleton: include.singleton, + remove: include.remove, + merge: merge, + union: union, + compare: include.compare, + equal: include.equal, + iter: iter, + fold: fold, + for_all: include.for_all, + exists: include.exists, + filter: include.filter, + partition: include.partition, + cardinal: include.cardinal, + bindings: bindings, + min_binding: include.min_binding, + min_binding_opt: include.min_binding_opt, + max_binding: include.max_binding, + max_binding_opt: include.max_binding_opt, + choose: include.choose, + choose_opt: include.choose_opt, + split: include.split, + find: find, + find_opt: include.find_opt, + find_first: include.find_first, + find_first_opt: include.find_first_opt, + find_last: include.find_last, + find_last_opt: include.find_last_opt, + map: include.map, + mapi: include.mapi, + filter_map: filter_map, + of_list: of_list, + disjoint_union: disjoint_union, + union_right: union_right, + union_left: union_left, + union_merge: union_merge, + rename: rename, + map_keys: map_keys, + print: print, + T_set: T_set, + keys: keys, + data: data, + of_set: of_set, + transpose_keys_and_data: transpose_keys_and_data, + transpose_keys_and_data_set: transpose_keys_and_data_set + }; +} + +function Make_set(T) { + var include = $$Set.Make({ + compare: T.compare + }); + var empty = include.empty; + var add = include.add; + var singleton = include.singleton; + var iter = include.iter; + var elements = include.elements; + var output = function (oc, s) { + Curry._1(Printf.fprintf(oc), " ( "); + Curry._2(iter, (function (v) { + return Curry._3(Printf.fprintf(oc), "%a ", T.output, v); + }), s); + return Curry._1(Printf.fprintf(oc), ")"); + }; + var print = function (ppf, s) { + var elts = function (ppf, s) { + return Curry._2(iter, (function (e) { + return Curry._3(Format.fprintf(ppf), "@ %a", T.print, e); + }), s); + }; + return Curry._3(Format.fprintf(ppf), "@[<1>{@[%a@ @]}@]", elts, s); + }; + var to_string = function (s) { + return Curry._2(Format.asprintf("%a"), print, s); + }; + var of_list = function (l) { + if (!l) { + return empty; + } + var q = l.tl; + var t = l.hd; + if (q) { + return List.fold_left((function (acc, e) { + return Curry._2(add, e, acc); + }), Curry._1(singleton, t), q); + } else { + return Curry._1(singleton, t); + } + }; + var map = function (f, s) { + return of_list(List.map(f, Curry._1(elements, s))); + }; + return { + empty: empty, + is_empty: include.is_empty, + mem: include.mem, + add: add, + singleton: singleton, + remove: include.remove, + union: include.union, + inter: include.inter, + diff: include.diff, + compare: include.compare, + equal: include.equal, + subset: include.subset, + iter: iter, + fold: include.fold, + for_all: include.for_all, + exists: include.exists, + filter: include.filter, + partition: include.partition, + cardinal: include.cardinal, + elements: elements, + min_elt: include.min_elt, + min_elt_opt: include.min_elt_opt, + max_elt: include.max_elt, + max_elt_opt: include.max_elt_opt, + choose: include.choose, + choose_opt: include.choose_opt, + split: include.split, + find: include.find, + find_opt: include.find_opt, + find_first: include.find_first, + find_first_opt: include.find_first_opt, + find_last: include.find_last, + find_last_opt: include.find_last_opt, + output: output, + print: print, + to_string: to_string, + of_list: of_list, + map: map + }; +} + +function Make_tbl(T) { + var include = Hashtbl.Make(T); + var create = include.create; + var add = include.add; + var find = include.find; + var fold = include.fold; + var include$1 = $$Map.Make({ + compare: T.compare + }); + var empty = include$1.empty; + var add$1 = include$1.add; + var merge = include$1.merge; + var union = include$1.union; + var iter = include$1.iter; + var fold$1 = include$1.fold; + var cardinal = include$1.cardinal; + var bindings = include$1.bindings; + var find$1 = include$1.find; + var map = include$1.map; + var filter_map = function (t, f) { + return Curry._3(fold$1, (function (id, v, map) { + var r = Curry._2(f, id, v); + if (r !== undefined) { + return Curry._3(add$1, id, Caml_option.valFromOption(r), map); + } else { + return map; + } + }), t, empty); + }; + var of_list = function (l) { + return List.fold_left((function (map, param) { + return Curry._3(add$1, param[0], param[1], map); + }), empty, l); + }; + var disjoint_union = function (eq, print, m1, m2) { + return Curry._3(union, (function (id, v1, v2) { + var ok = eq !== undefined ? Curry._2(eq, v1, v2) : false; + if (ok) { + return Caml_option.some(v1); + } + var tmp; + if (print !== undefined) { + var print$1 = Caml_option.valFromOption(print); + tmp = Curry._6(Format.asprintf("Map.disjoint_union %a => %a <> %a"), T.print, id, print$1, v1, print$1, v2); + } else { + tmp = Curry._2(Format.asprintf("Map.disjoint_union %a"), T.print, id); + } + return Misc.fatal_error(tmp); + }), m1, m2); + }; + var union_right = function (m1, m2) { + return Curry._3(merge, (function (_id, x, y) { + if (x !== undefined) { + if (y !== undefined) { + return Caml_option.some(Caml_option.valFromOption(y)); + } else { + return Caml_option.some(Caml_option.valFromOption(x)); + } + } else if (y !== undefined) { + return Caml_option.some(Caml_option.valFromOption(y)); + } else { + return ; + } + }), m1, m2); + }; + var union_left = function (m1, m2) { + return union_right(m2, m1); + }; + var union_merge = function (f, m1, m2) { + var aux = function (param, m1, m2) { + if (m1 !== undefined) { + if (m2 !== undefined) { + return Caml_option.some(Curry._2(f, Caml_option.valFromOption(m1), Caml_option.valFromOption(m2))); + } else { + return m1; + } + } else { + return m2; + } + }; + return Curry._3(merge, aux, m1, m2); + }; + var rename = function (m, v) { + try { + return Curry._2(find$1, v, m); + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === "Not_found") { + return v; + } + throw exn; + } + }; + var map_keys = function (f, m) { + return of_list(List.map((function (param) { + return [ + Curry._1(f, param[0]), + param[1] + ]; + }), Curry._1(bindings, m))); + }; + var print = function (f, ppf, s) { + var elts = function (ppf, s) { + return Curry._2(iter, (function (id, v) { + return Curry._5(Format.fprintf(ppf), "@ (@[%a@ %a@])", T.print, id, f, v); + }), s); + }; + return Curry._3(Format.fprintf(ppf), "@[<1>{@[%a@ @]}@]", elts, s); + }; + var T_set = $$Set.Make({ + compare: T.compare + }); + var keys = function (map) { + return Curry._3(fold$1, (function (k, param, set) { + return Curry._2(T_set.add, k, set); + }), map, T_set.empty); + }; + var data = function (t) { + return List.map((function (prim) { + return prim[1]; + }), Curry._1(bindings, t)); + }; + var of_set = function (f, set) { + return Curry._3(T_set.fold, (function (e, map) { + return Curry._3(add$1, e, Curry._1(f, e), map); + }), set, empty); + }; + var transpose_keys_and_data = function (map) { + return Curry._3(fold$1, (function (k, v, m) { + return Curry._3(add$1, v, k, m); + }), map, empty); + }; + var transpose_keys_and_data_set = function (map) { + return Curry._3(fold$1, (function (k, v, m) { + var set; + var exit = 0; + var set$1; + try { + set$1 = Curry._2(find$1, v, m); + exit = 1; + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === "Not_found") { + set = Curry._1(T_set.singleton, k); + } else { + throw exn; + } + } + if (exit === 1) { + set = Curry._2(T_set.add, k, set$1); + } + return Curry._3(add$1, v, set, m); + }), map, empty); + }; + var T_map_is_empty = include$1.is_empty; + var T_map_mem = include$1.mem; + var T_map_update = include$1.update; + var T_map_singleton = include$1.singleton; + var T_map_remove = include$1.remove; + var T_map_compare = include$1.compare; + var T_map_equal = include$1.equal; + var T_map_for_all = include$1.for_all; + var T_map_exists = include$1.exists; + var T_map_filter = include$1.filter; + var T_map_partition = include$1.partition; + var T_map_min_binding = include$1.min_binding; + var T_map_min_binding_opt = include$1.min_binding_opt; + var T_map_max_binding = include$1.max_binding; + var T_map_max_binding_opt = include$1.max_binding_opt; + var T_map_choose = include$1.choose; + var T_map_choose_opt = include$1.choose_opt; + var T_map_split = include$1.split; + var T_map_find_opt = include$1.find_opt; + var T_map_find_first = include$1.find_first; + var T_map_find_first_opt = include$1.find_first_opt; + var T_map_find_last = include$1.find_last; + var T_map_find_last_opt = include$1.find_last_opt; + var T_map_mapi = include$1.mapi; + var T_map = { + empty: empty, + is_empty: T_map_is_empty, + mem: T_map_mem, + add: add$1, + update: T_map_update, + singleton: T_map_singleton, + remove: T_map_remove, + merge: merge, + union: union, + compare: T_map_compare, + equal: T_map_equal, + iter: iter, + fold: fold$1, + for_all: T_map_for_all, + exists: T_map_exists, + filter: T_map_filter, + partition: T_map_partition, + cardinal: cardinal, + bindings: bindings, + min_binding: T_map_min_binding, + min_binding_opt: T_map_min_binding_opt, + max_binding: T_map_max_binding, + max_binding_opt: T_map_max_binding_opt, + choose: T_map_choose, + choose_opt: T_map_choose_opt, + split: T_map_split, + find: find$1, + find_opt: T_map_find_opt, + find_first: T_map_find_first, + find_first_opt: T_map_find_first_opt, + find_last: T_map_find_last, + find_last_opt: T_map_find_last_opt, + map: map, + mapi: T_map_mapi, + filter_map: filter_map, + of_list: of_list, + disjoint_union: disjoint_union, + union_right: union_right, + union_left: union_left, + union_merge: union_merge, + rename: rename, + map_keys: map_keys, + print: print, + T_set: T_set, + keys: keys, + data: data, + of_set: of_set, + transpose_keys_and_data: transpose_keys_and_data, + transpose_keys_and_data_set: transpose_keys_and_data_set + }; + var to_list = function (t) { + return Curry._3(fold, (function (key, datum, elts) { + return { + hd: [ + key, + datum + ], + tl: elts + }; + }), t, /* [] */0); + }; + var of_list$1 = function (elts) { + var t = Curry._1(create, 42); + List.iter((function (param) { + return Curry._3(add, t, param[0], param[1]); + }), elts); + return t; + }; + var to_map = function (v) { + return Curry._3(fold, add$1, v, empty); + }; + var of_map = function (m) { + var t = Curry._1(create, Curry._1(cardinal, m)); + Curry._2(iter, (function (k, v) { + return Curry._3(add, t, k, v); + }), m); + return t; + }; + var memoize = function (t, f, key) { + try { + return Curry._2(find, t, key); + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === "Not_found") { + var r = Curry._1(f, key); + Curry._3(add, t, key, r); + return r; + } + throw exn; + } + }; + var map$1 = function (t, f) { + return of_map(Curry._2(map, f, Curry._3(fold, add$1, t, empty))); + }; + return { + create: create, + clear: include.clear, + reset: include.reset, + copy: include.copy, + add: add, + remove: include.remove, + find: find, + find_opt: include.find_opt, + find_all: include.find_all, + replace: include.replace, + mem: include.mem, + iter: include.iter, + filter_map_inplace: include.filter_map_inplace, + fold: fold, + length: include.length, + stats: include.stats, + T_map: T_map, + to_list: to_list, + of_list: of_list$1, + to_map: to_map, + of_map: of_map, + memoize: memoize, + map: map$1 + }; +} + +function Make(T) { + var include = $$Set.Make({ + compare: T.compare + }); + var empty = include.empty; + var add = include.add; + var singleton = include.singleton; + var iter = include.iter; + var elements = include.elements; + var output = function (oc, s) { + Curry._1(Printf.fprintf(oc), " ( "); + Curry._2(iter, (function (v) { + return Curry._3(Printf.fprintf(oc), "%a ", T.output, v); + }), s); + return Curry._1(Printf.fprintf(oc), ")"); + }; + var print = function (ppf, s) { + var elts = function (ppf, s) { + return Curry._2(iter, (function (e) { + return Curry._3(Format.fprintf(ppf), "@ %a", T.print, e); + }), s); + }; + return Curry._3(Format.fprintf(ppf), "@[<1>{@[%a@ @]}@]", elts, s); + }; + var to_string = function (s) { + return Curry._2(Format.asprintf("%a"), print, s); + }; + var of_list = function (l) { + if (!l) { + return empty; + } + var q = l.tl; + var t = l.hd; + if (q) { + return List.fold_left((function (acc, e) { + return Curry._2(add, e, acc); + }), Curry._1(singleton, t), q); + } else { + return Curry._1(singleton, t); + } + }; + var map = function (f, s) { + return of_list(List.map(f, Curry._1(elements, s))); + }; + var Set_is_empty = include.is_empty; + var Set_mem = include.mem; + var Set_remove = include.remove; + var Set_union = include.union; + var Set_inter = include.inter; + var Set_diff = include.diff; + var Set_compare = include.compare; + var Set_equal = include.equal; + var Set_subset = include.subset; + var Set_fold = include.fold; + var Set_for_all = include.for_all; + var Set_exists = include.exists; + var Set_filter = include.filter; + var Set_partition = include.partition; + var Set_cardinal = include.cardinal; + var Set_min_elt = include.min_elt; + var Set_min_elt_opt = include.min_elt_opt; + var Set_max_elt = include.max_elt; + var Set_max_elt_opt = include.max_elt_opt; + var Set_choose = include.choose; + var Set_choose_opt = include.choose_opt; + var Set_split = include.split; + var Set_find = include.find; + var Set_find_opt = include.find_opt; + var Set_find_first = include.find_first; + var Set_find_first_opt = include.find_first_opt; + var Set_find_last = include.find_last; + var Set_find_last_opt = include.find_last_opt; + var $$Set$1 = { + empty: empty, + is_empty: Set_is_empty, + mem: Set_mem, + add: add, + singleton: singleton, + remove: Set_remove, + union: Set_union, + inter: Set_inter, + diff: Set_diff, + compare: Set_compare, + equal: Set_equal, + subset: Set_subset, + iter: iter, + fold: Set_fold, + for_all: Set_for_all, + exists: Set_exists, + filter: Set_filter, + partition: Set_partition, + cardinal: Set_cardinal, + elements: elements, + min_elt: Set_min_elt, + min_elt_opt: Set_min_elt_opt, + max_elt: Set_max_elt, + max_elt_opt: Set_max_elt_opt, + choose: Set_choose, + choose_opt: Set_choose_opt, + split: Set_split, + find: Set_find, + find_opt: Set_find_opt, + find_first: Set_find_first, + find_first_opt: Set_find_first_opt, + find_last: Set_find_last, + find_last_opt: Set_find_last_opt, + output: output, + print: print, + to_string: to_string, + of_list: of_list, + map: map + }; + var include$1 = $$Map.Make({ + compare: T.compare + }); + var empty$1 = include$1.empty; + var add$1 = include$1.add; + var merge = include$1.merge; + var union = include$1.union; + var iter$1 = include$1.iter; + var fold = include$1.fold; + var bindings = include$1.bindings; + var find = include$1.find; + var filter_map = function (t, f) { + return Curry._3(fold, (function (id, v, map) { + var r = Curry._2(f, id, v); + if (r !== undefined) { + return Curry._3(add$1, id, Caml_option.valFromOption(r), map); + } else { + return map; + } + }), t, empty$1); + }; + var of_list$1 = function (l) { + return List.fold_left((function (map, param) { + return Curry._3(add$1, param[0], param[1], map); + }), empty$1, l); + }; + var disjoint_union = function (eq, print, m1, m2) { + return Curry._3(union, (function (id, v1, v2) { + var ok = eq !== undefined ? Curry._2(eq, v1, v2) : false; + if (ok) { + return Caml_option.some(v1); + } + var tmp; + if (print !== undefined) { + var print$1 = Caml_option.valFromOption(print); + tmp = Curry._6(Format.asprintf("Map.disjoint_union %a => %a <> %a"), T.print, id, print$1, v1, print$1, v2); + } else { + tmp = Curry._2(Format.asprintf("Map.disjoint_union %a"), T.print, id); + } + return Misc.fatal_error(tmp); + }), m1, m2); + }; + var union_right = function (m1, m2) { + return Curry._3(merge, (function (_id, x, y) { + if (x !== undefined) { + if (y !== undefined) { + return Caml_option.some(Caml_option.valFromOption(y)); + } else { + return Caml_option.some(Caml_option.valFromOption(x)); + } + } else if (y !== undefined) { + return Caml_option.some(Caml_option.valFromOption(y)); + } else { + return ; + } + }), m1, m2); + }; + var union_left = function (m1, m2) { + return union_right(m2, m1); + }; + var union_merge = function (f, m1, m2) { + var aux = function (param, m1, m2) { + if (m1 !== undefined) { + if (m2 !== undefined) { + return Caml_option.some(Curry._2(f, Caml_option.valFromOption(m1), Caml_option.valFromOption(m2))); + } else { + return m1; + } + } else { + return m2; + } + }; + return Curry._3(merge, aux, m1, m2); + }; + var rename = function (m, v) { + try { + return Curry._2(find, v, m); + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === "Not_found") { + return v; + } + throw exn; + } + }; + var map_keys = function (f, m) { + return of_list$1(List.map((function (param) { + return [ + Curry._1(f, param[0]), + param[1] + ]; + }), Curry._1(bindings, m))); + }; + var print$1 = function (f, ppf, s) { + var elts = function (ppf, s) { + return Curry._2(iter$1, (function (id, v) { + return Curry._5(Format.fprintf(ppf), "@ (@[%a@ %a@])", T.print, id, f, v); + }), s); + }; + return Curry._3(Format.fprintf(ppf), "@[<1>{@[%a@ @]}@]", elts, s); + }; + var T_set = $$Set.Make({ + compare: T.compare + }); + var keys = function (map) { + return Curry._3(fold, (function (k, param, set) { + return Curry._2(T_set.add, k, set); + }), map, T_set.empty); + }; + var data = function (t) { + return List.map((function (prim) { + return prim[1]; + }), Curry._1(bindings, t)); + }; + var of_set = function (f, set) { + return Curry._3(T_set.fold, (function (e, map) { + return Curry._3(add$1, e, Curry._1(f, e), map); + }), set, empty$1); + }; + var transpose_keys_and_data = function (map) { + return Curry._3(fold, (function (k, v, m) { + return Curry._3(add$1, v, k, m); + }), map, empty$1); + }; + var transpose_keys_and_data_set = function (map) { + return Curry._3(fold, (function (k, v, m) { + var set; + var exit = 0; + var set$1; + try { + set$1 = Curry._2(find, v, m); + exit = 1; + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === "Not_found") { + set = Curry._1(T_set.singleton, k); + } else { + throw exn; + } + } + if (exit === 1) { + set = Curry._2(T_set.add, k, set$1); + } + return Curry._3(add$1, v, set, m); + }), map, empty$1); + }; + var Map_is_empty = include$1.is_empty; + var Map_mem = include$1.mem; + var Map_update = include$1.update; + var Map_singleton = include$1.singleton; + var Map_remove = include$1.remove; + var Map_compare = include$1.compare; + var Map_equal = include$1.equal; + var Map_for_all = include$1.for_all; + var Map_exists = include$1.exists; + var Map_filter = include$1.filter; + var Map_partition = include$1.partition; + var Map_cardinal = include$1.cardinal; + var Map_min_binding = include$1.min_binding; + var Map_min_binding_opt = include$1.min_binding_opt; + var Map_max_binding = include$1.max_binding; + var Map_max_binding_opt = include$1.max_binding_opt; + var Map_choose = include$1.choose; + var Map_choose_opt = include$1.choose_opt; + var Map_split = include$1.split; + var Map_find_opt = include$1.find_opt; + var Map_find_first = include$1.find_first; + var Map_find_first_opt = include$1.find_first_opt; + var Map_find_last = include$1.find_last; + var Map_find_last_opt = include$1.find_last_opt; + var Map_map = include$1.map; + var Map_mapi = include$1.mapi; + var $$Map$1 = { + empty: empty$1, + is_empty: Map_is_empty, + mem: Map_mem, + add: add$1, + update: Map_update, + singleton: Map_singleton, + remove: Map_remove, + merge: merge, + union: union, + compare: Map_compare, + equal: Map_equal, + iter: iter$1, + fold: fold, + for_all: Map_for_all, + exists: Map_exists, + filter: Map_filter, + partition: Map_partition, + cardinal: Map_cardinal, + bindings: bindings, + min_binding: Map_min_binding, + min_binding_opt: Map_min_binding_opt, + max_binding: Map_max_binding, + max_binding_opt: Map_max_binding_opt, + choose: Map_choose, + choose_opt: Map_choose_opt, + split: Map_split, + find: find, + find_opt: Map_find_opt, + find_first: Map_find_first, + find_first_opt: Map_find_first_opt, + find_last: Map_find_last, + find_last_opt: Map_find_last_opt, + map: Map_map, + mapi: Map_mapi, + filter_map: filter_map, + of_list: of_list$1, + disjoint_union: disjoint_union, + union_right: union_right, + union_left: union_left, + union_merge: union_merge, + rename: rename, + map_keys: map_keys, + print: print$1, + T_set: T_set, + keys: keys, + data: data, + of_set: of_set, + transpose_keys_and_data: transpose_keys_and_data, + transpose_keys_and_data_set: transpose_keys_and_data_set + }; + var include$2 = Hashtbl.Make(T); + var create = include$2.create; + var add$2 = include$2.add; + var find$1 = include$2.find; + var fold$1 = include$2.fold; + var include$3 = $$Map.Make({ + compare: T.compare + }); + var empty$2 = include$3.empty; + var add$3 = include$3.add; + var merge$1 = include$3.merge; + var union$1 = include$3.union; + var iter$2 = include$3.iter; + var fold$2 = include$3.fold; + var cardinal = include$3.cardinal; + var bindings$1 = include$3.bindings; + var find$2 = include$3.find; + var map$1 = include$3.map; + var filter_map$1 = function (t, f) { + return Curry._3(fold$2, (function (id, v, map) { + var r = Curry._2(f, id, v); + if (r !== undefined) { + return Curry._3(add$3, id, Caml_option.valFromOption(r), map); + } else { + return map; + } + }), t, empty$2); + }; + var of_list$2 = function (l) { + return List.fold_left((function (map, param) { + return Curry._3(add$3, param[0], param[1], map); + }), empty$2, l); + }; + var disjoint_union$1 = function (eq, print, m1, m2) { + return Curry._3(union$1, (function (id, v1, v2) { + var ok = eq !== undefined ? Curry._2(eq, v1, v2) : false; + if (ok) { + return Caml_option.some(v1); + } + var tmp; + if (print !== undefined) { + var print$1 = Caml_option.valFromOption(print); + tmp = Curry._6(Format.asprintf("Map.disjoint_union %a => %a <> %a"), T.print, id, print$1, v1, print$1, v2); + } else { + tmp = Curry._2(Format.asprintf("Map.disjoint_union %a"), T.print, id); + } + return Misc.fatal_error(tmp); + }), m1, m2); + }; + var union_right$1 = function (m1, m2) { + return Curry._3(merge$1, (function (_id, x, y) { + if (x !== undefined) { + if (y !== undefined) { + return Caml_option.some(Caml_option.valFromOption(y)); + } else { + return Caml_option.some(Caml_option.valFromOption(x)); + } + } else if (y !== undefined) { + return Caml_option.some(Caml_option.valFromOption(y)); + } else { + return ; + } + }), m1, m2); + }; + var union_left$1 = function (m1, m2) { + return union_right$1(m2, m1); + }; + var union_merge$1 = function (f, m1, m2) { + var aux = function (param, m1, m2) { + if (m1 !== undefined) { + if (m2 !== undefined) { + return Caml_option.some(Curry._2(f, Caml_option.valFromOption(m1), Caml_option.valFromOption(m2))); + } else { + return m1; + } + } else { + return m2; + } + }; + return Curry._3(merge$1, aux, m1, m2); + }; + var rename$1 = function (m, v) { + try { + return Curry._2(find$2, v, m); + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === "Not_found") { + return v; + } + throw exn; + } + }; + var map_keys$1 = function (f, m) { + return of_list$2(List.map((function (param) { + return [ + Curry._1(f, param[0]), + param[1] + ]; + }), Curry._1(bindings$1, m))); + }; + var print$2 = function (f, ppf, s) { + var elts = function (ppf, s) { + return Curry._2(iter$2, (function (id, v) { + return Curry._5(Format.fprintf(ppf), "@ (@[%a@ %a@])", T.print, id, f, v); + }), s); + }; + return Curry._3(Format.fprintf(ppf), "@[<1>{@[%a@ @]}@]", elts, s); + }; + var T_set$1 = $$Set.Make({ + compare: T.compare + }); + var keys$1 = function (map) { + return Curry._3(fold$2, (function (k, param, set) { + return Curry._2(T_set$1.add, k, set); + }), map, T_set$1.empty); + }; + var data$1 = function (t) { + return List.map((function (prim) { + return prim[1]; + }), Curry._1(bindings$1, t)); + }; + var of_set$1 = function (f, set) { + return Curry._3(T_set$1.fold, (function (e, map) { + return Curry._3(add$3, e, Curry._1(f, e), map); + }), set, empty$2); + }; + var transpose_keys_and_data$1 = function (map) { + return Curry._3(fold$2, (function (k, v, m) { + return Curry._3(add$3, v, k, m); + }), map, empty$2); + }; + var transpose_keys_and_data_set$1 = function (map) { + return Curry._3(fold$2, (function (k, v, m) { + var set; + var exit = 0; + var set$1; + try { + set$1 = Curry._2(find$2, v, m); + exit = 1; + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === "Not_found") { + set = Curry._1(T_set$1.singleton, k); + } else { + throw exn; + } + } + if (exit === 1) { + set = Curry._2(T_set$1.add, k, set$1); + } + return Curry._3(add$3, v, set, m); + }), map, empty$2); + }; + var T_map_is_empty = include$3.is_empty; + var T_map_mem = include$3.mem; + var T_map_update = include$3.update; + var T_map_singleton = include$3.singleton; + var T_map_remove = include$3.remove; + var T_map_compare = include$3.compare; + var T_map_equal = include$3.equal; + var T_map_for_all = include$3.for_all; + var T_map_exists = include$3.exists; + var T_map_filter = include$3.filter; + var T_map_partition = include$3.partition; + var T_map_min_binding = include$3.min_binding; + var T_map_min_binding_opt = include$3.min_binding_opt; + var T_map_max_binding = include$3.max_binding; + var T_map_max_binding_opt = include$3.max_binding_opt; + var T_map_choose = include$3.choose; + var T_map_choose_opt = include$3.choose_opt; + var T_map_split = include$3.split; + var T_map_find_opt = include$3.find_opt; + var T_map_find_first = include$3.find_first; + var T_map_find_first_opt = include$3.find_first_opt; + var T_map_find_last = include$3.find_last; + var T_map_find_last_opt = include$3.find_last_opt; + var T_map_mapi = include$3.mapi; + var T_map = { + empty: empty$2, + is_empty: T_map_is_empty, + mem: T_map_mem, + add: add$3, + update: T_map_update, + singleton: T_map_singleton, + remove: T_map_remove, + merge: merge$1, + union: union$1, + compare: T_map_compare, + equal: T_map_equal, + iter: iter$2, + fold: fold$2, + for_all: T_map_for_all, + exists: T_map_exists, + filter: T_map_filter, + partition: T_map_partition, + cardinal: cardinal, + bindings: bindings$1, + min_binding: T_map_min_binding, + min_binding_opt: T_map_min_binding_opt, + max_binding: T_map_max_binding, + max_binding_opt: T_map_max_binding_opt, + choose: T_map_choose, + choose_opt: T_map_choose_opt, + split: T_map_split, + find: find$2, + find_opt: T_map_find_opt, + find_first: T_map_find_first, + find_first_opt: T_map_find_first_opt, + find_last: T_map_find_last, + find_last_opt: T_map_find_last_opt, + map: map$1, + mapi: T_map_mapi, + filter_map: filter_map$1, + of_list: of_list$2, + disjoint_union: disjoint_union$1, + union_right: union_right$1, + union_left: union_left$1, + union_merge: union_merge$1, + rename: rename$1, + map_keys: map_keys$1, + print: print$2, + T_set: T_set$1, + keys: keys$1, + data: data$1, + of_set: of_set$1, + transpose_keys_and_data: transpose_keys_and_data$1, + transpose_keys_and_data_set: transpose_keys_and_data_set$1 + }; + var to_list = function (t) { + return Curry._3(fold$1, (function (key, datum, elts) { + return { + hd: [ + key, + datum + ], + tl: elts + }; + }), t, /* [] */0); + }; + var of_list$3 = function (elts) { + var t = Curry._1(create, 42); + List.iter((function (param) { + return Curry._3(add$2, t, param[0], param[1]); + }), elts); + return t; + }; + var to_map = function (v) { + return Curry._3(fold$1, add$3, v, empty$2); + }; + var of_map = function (m) { + var t = Curry._1(create, Curry._1(cardinal, m)); + Curry._2(iter$2, (function (k, v) { + return Curry._3(add$2, t, k, v); + }), m); + return t; + }; + var memoize = function (t, f, key) { + try { + return Curry._2(find$1, t, key); + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === "Not_found") { + var r = Curry._1(f, key); + Curry._3(add$2, t, key, r); + return r; + } + throw exn; + } + }; + var map$2 = function (t, f) { + return of_map(Curry._2(map$1, f, Curry._3(fold$1, add$3, t, empty$2))); + }; + var Tbl_clear = include$2.clear; + var Tbl_reset = include$2.reset; + var Tbl_copy = include$2.copy; + var Tbl_remove = include$2.remove; + var Tbl_find_opt = include$2.find_opt; + var Tbl_find_all = include$2.find_all; + var Tbl_replace = include$2.replace; + var Tbl_mem = include$2.mem; + var Tbl_iter = include$2.iter; + var Tbl_filter_map_inplace = include$2.filter_map_inplace; + var Tbl_length = include$2.length; + var Tbl_stats = include$2.stats; + var Tbl = { + create: create, + clear: Tbl_clear, + reset: Tbl_reset, + copy: Tbl_copy, + add: add$2, + remove: Tbl_remove, + find: find$1, + find_opt: Tbl_find_opt, + find_all: Tbl_find_all, + replace: Tbl_replace, + mem: Tbl_mem, + iter: Tbl_iter, + filter_map_inplace: Tbl_filter_map_inplace, + fold: fold$1, + length: Tbl_length, + stats: Tbl_stats, + T_map: T_map, + to_list: to_list, + of_list: of_list$3, + to_map: to_map, + of_map: of_map, + memoize: memoize, + map: map$2 + }; + return { + T: T, + equal: T.equal, + hash: T.hash, + compare: T.compare, + output: T.output, + print: T.print, + $$Set: $$Set$1, + $$Map: $$Map$1, + Tbl: Tbl + }; +} + +export { + Pair , + Make_map , + Make_set , + Make_tbl , + Make , + +} +/* Misc Not a pure module */ diff --git a/analysis/examples/larger-project/src/location.js b/analysis/examples/larger-project/src/location.js new file mode 100644 index 0000000000..4580019a27 --- /dev/null +++ b/analysis/examples/larger-project/src/location.js @@ -0,0 +1,369 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as P from "./P.js"; +import * as Misc from "./misc.js"; +import * as Curry from "rescript/lib/es6/curry.js"; +import * as $$Buffer from "rescript/lib/es6/buffer.js"; +import * as Format from "./format.js"; +import * as Parsing from "rescript/lib/es6/parsing.js"; +import * as Caml_sys from "rescript/lib/es6/caml_sys.js"; +import * as Filename from "rescript/lib/es6/filename.js"; +import * as Printexc from "rescript/lib/es6/printexc.js"; +import * as Warnings from "./warnings.js"; +import * as Pervasives from "rescript/lib/es6/pervasives.js"; +import * as Caml_option from "rescript/lib/es6/caml_option.js"; +import * as Caml_exceptions from "rescript/lib/es6/caml_exceptions.js"; + +var absname = { + contents: false +}; + +function in_file(name) { + var loc = { + pos_fname: name, + pos_lnum: 1, + pos_bol: 0, + pos_cnum: -1 + }; + return { + loc_start: loc, + loc_end: loc, + loc_ghost: true + }; +} + +var none = in_file("_none_"); + +function curr(lexbuf) { + return { + loc_start: lexbuf.lex_start_p, + loc_end: lexbuf.lex_curr_p, + loc_ghost: false + }; +} + +function init(lexbuf, fname) { + lexbuf.lex_curr_p = { + pos_fname: fname, + pos_lnum: 1, + pos_bol: 0, + pos_cnum: 0 + }; + +} + +function symbol_rloc(param) { + return { + loc_start: Parsing.symbol_start_pos(undefined), + loc_end: Parsing.symbol_end_pos(undefined), + loc_ghost: false + }; +} + +function symbol_gloc(param) { + return { + loc_start: Parsing.symbol_start_pos(undefined), + loc_end: Parsing.symbol_end_pos(undefined), + loc_ghost: true + }; +} + +function rhs_loc(n) { + return { + loc_start: Parsing.rhs_start_pos(n), + loc_end: Parsing.rhs_end_pos(n), + loc_ghost: false + }; +} + +var input_name = { + contents: "_none_" +}; + +var input_lexbuf = { + contents: undefined +}; + +function set_input_name(name) { + if (name !== "") { + input_name.contents = name; + return ; + } + +} + +var num_loc_lines = { + contents: 0 +}; + +function absolute_path(s) { + var s$1 = Curry._1(Filename.is_relative, s) ? Filename.concat(Caml_sys.caml_sys_getcwd(undefined), s) : s; + var aux = function (_s) { + while(true) { + var s = _s; + var base = Curry._1(Filename.basename, s); + var dir = Curry._1(Filename.dirname, s); + if (dir === s) { + return dir; + } + if (base !== Filename.current_dir_name) { + if (base === Filename.parent_dir_name) { + return Curry._1(Filename.dirname, aux(dir)); + } else { + return Filename.concat(aux(dir), base); + } + } + _s = dir; + continue ; + }; + }; + return aux(s$1); +} + +function show_filename(file) { + var file$1 = file === "_none_" ? input_name.contents : file; + if (absname.contents) { + return absolute_path(file$1); + } else { + return file$1; + } +} + +function print_filename(ppf, file) { + return Curry._2(Format.fprintf(ppf), "%s", show_filename(file)); +} + +function reset(param) { + num_loc_lines.contents = 0; + +} + +function get_pos_info(pos) { + return [ + pos.pos_fname, + pos.pos_lnum, + pos.pos_cnum - pos.pos_bol | 0 + ]; +} + +var error_prefix = "Error"; + +function print_compact(ppf, loc) { + var match = get_pos_info(loc.loc_start); + var startchar = match[2]; + var endchar = (loc.loc_end.pos_cnum - loc.loc_start.pos_cnum | 0) + startchar | 0; + Curry._4(Format.fprintf(ppf), "%a:%i", print_filename, match[0], match[1]); + if (startchar >= 0) { + return Curry._3(Format.fprintf(ppf), ",%i--%i", startchar, endchar); + } + +} + +function echo_eof(param) { + Pervasives.print_newline(undefined); + num_loc_lines.contents = num_loc_lines.contents + 1 | 0; + +} + +function mkloc(txt, loc) { + return { + txt: txt, + loc: loc + }; +} + +function mknoloc(txt) { + return { + txt: txt, + loc: none + }; +} + +function pp_ksprintf(before, k, fmt) { + var buf = $$Buffer.create(64); + var ppf = Format.formatter_of_buffer(buf); + Misc.Color.set_color_tag_handling(ppf); + if (before !== undefined) { + Curry._1(before, ppf); + } + return Curry._2(Format.kfprintf(function (param) { + Curry._1(Format.pp_print_flush(ppf), undefined); + return Curry._1(k, $$Buffer.contents(buf)); + }), ppf, fmt); +} + +function print_phanton_error_prefix(ppf) { + return Curry._2(Format.pp_print_as(ppf), error_prefix.length + 2 | 0, ""); +} + +function errorf(locOpt, subOpt, if_highlightOpt, fmt) { + var loc = locOpt !== undefined ? locOpt : none; + var sub = subOpt !== undefined ? subOpt : /* [] */0; + var if_highlight = if_highlightOpt !== undefined ? if_highlightOpt : ""; + return pp_ksprintf(print_phanton_error_prefix, (function (msg) { + return { + loc: loc, + msg: msg, + sub: sub, + if_highlight: if_highlight + }; + }), fmt); +} + +function error(locOpt, subOpt, if_highlightOpt, msg) { + var loc = locOpt !== undefined ? locOpt : none; + var sub = subOpt !== undefined ? subOpt : /* [] */0; + var if_highlight = if_highlightOpt !== undefined ? if_highlightOpt : ""; + return { + loc: loc, + msg: msg, + sub: sub, + if_highlight: if_highlight + }; +} + +var error_of_exn = { + contents: /* [] */0 +}; + +function register_error_of_exn(f) { + error_of_exn.contents = { + hd: f, + tl: error_of_exn.contents + }; + +} + +function error_of_exn$1(exn) { + if (exn.RE_EXN_ID === Warnings.Errors) { + return "Already_displayed"; + } + var _x = error_of_exn.contents; + while(true) { + var x = _x; + if (!x) { + return ; + } + var error = Curry._1(x.hd, exn); + if (error !== undefined) { + return { + NAME: "Ok", + VAL: Caml_option.valFromOption(error) + }; + } + _x = x.tl; + continue ; + }; +} + +function error_of_printer(loc, print, x) { + return Curry._2(errorf(loc, undefined, undefined, "%a@?"), print, x); +} + +function error_of_printer_file(print, x) { + return error_of_printer(in_file(input_name.contents), print, x); +} + +register_error_of_exn(function (x) { + if (x.RE_EXN_ID === P.Sys_error) { + return Curry._1(errorf(in_file(input_name.contents), undefined, undefined, "I/O error: %s"), x._1); + } + if (x.RE_EXN_ID !== Misc.HookExnWrapper) { + return ; + } + var e = x.error; + var match = error_of_exn$1(e); + var sub = match !== undefined && typeof match === "object" ? match.VAL : error(undefined, undefined, undefined, Printexc.to_string(e)); + return Curry._1(errorf(in_file(x.hook_info.sourcefile), { + hd: sub, + tl: /* [] */0 + }, undefined, "In hook %S:"), x.hook_name); + }); + +var $$Error = /* @__PURE__ */Caml_exceptions.create("Location.Error"); + +register_error_of_exn(function (x) { + if (x.RE_EXN_ID === $$Error) { + return x._1; + } + + }); + +function raise_errorf(locOpt, subOpt, if_highlightOpt) { + var loc = locOpt !== undefined ? locOpt : none; + var sub = subOpt !== undefined ? subOpt : /* [] */0; + var if_highlight = if_highlightOpt !== undefined ? if_highlightOpt : ""; + var partial_arg = print_phanton_error_prefix; + return function (param) { + return pp_ksprintf(partial_arg, (function (msg) { + throw { + RE_EXN_ID: $$Error, + _1: { + loc: loc, + msg: msg, + sub: sub, + if_highlight: if_highlight + }, + Error: new Error() + }; + }), param); + }; +} + +var msg_file = "File \""; + +var msg_line = "\", line "; + +var msg_chars = ", characters "; + +var msg_to = "-"; + +var msg_colon = ":"; + +var warning_prefix = "Warning"; + +var Already_displayed_error = Warnings.Errors; + +export { + absname , + in_file , + none , + curr , + init , + symbol_rloc , + symbol_gloc , + rhs_loc , + input_name , + input_lexbuf , + set_input_name , + num_loc_lines , + absolute_path , + show_filename , + print_filename , + reset , + msg_file , + msg_line , + msg_chars , + msg_to , + msg_colon , + get_pos_info , + error_prefix , + warning_prefix , + print_compact , + echo_eof , + mkloc , + mknoloc , + pp_ksprintf , + print_phanton_error_prefix , + errorf , + error , + register_error_of_exn , + Already_displayed_error , + error_of_exn$1 as error_of_exn, + error_of_printer , + error_of_printer_file , + $$Error , + raise_errorf , + +} +/* none Not a pure module */ diff --git a/analysis/examples/larger-project/src/location.res b/analysis/examples/larger-project/src/location.res new file mode 100644 index 0000000000..332f0c40d6 --- /dev/null +++ b/analysis/examples/larger-project/src/location.res @@ -0,0 +1,261 @@ +/* ************************************************************************ */ +/* */ +/* OCaml */ +/* */ +/* Xavier Leroy, projet Cristal, INRIA Rocquencourt */ +/* */ +/* Copyright 1996 Institut National de Recherche en Informatique et */ +/* en Automatique. */ +/* */ +/* All rights reserved. This file is distributed under the terms of */ +/* the GNU Lesser General Public License version 2.1, with the */ +/* special exception on linking described in the file LICENSE. */ +/* */ +/* ************************************************************************ */ + +open P + +open Lexing + +let absname = ref(false) +/* This reference should be in Clflags, but it would create an additional + dependency and make bootstrapping Camlp4 more difficult. */ + +type t = Warnings.loc = {loc_start: position, loc_end: position, loc_ghost: bool} + +let in_file = name => { + let loc = { + pos_fname: name, + pos_lnum: 1, + pos_bol: 0, + pos_cnum: -1, + } + {loc_start: loc, loc_end: loc, loc_ghost: true} +} + +let none = in_file("_none_") + +let curr = lexbuf => { + loc_start: lexbuf.lex_start_p, + loc_end: lexbuf.lex_curr_p, + loc_ghost: false, +} + +let init = (lexbuf, fname) => + lexbuf.lex_curr_p = { + pos_fname: fname, + pos_lnum: 1, + pos_bol: 0, + pos_cnum: 0, + } + +let symbol_rloc = () => { + loc_start: Parsing.symbol_start_pos(), + loc_end: Parsing.symbol_end_pos(), + loc_ghost: false, +} + +let symbol_gloc = () => { + loc_start: Parsing.symbol_start_pos(), + loc_end: Parsing.symbol_end_pos(), + loc_ghost: true, +} + +let rhs_loc = n => { + loc_start: Parsing.rhs_start_pos(n), + loc_end: Parsing.rhs_end_pos(n), + loc_ghost: false, +} + +let input_name = ref("_none_") +let input_lexbuf = ref((None: option)) +let set_input_name = name => + if name != "" { + input_name := name + } +/* Terminal info */ + +let num_loc_lines = ref(0) /* number of lines already printed after input */ + +/* Print the location in some way or another */ + +open Format + +let absolute_path = s => { + /* This function could go into Filename */ + open Filename + let s = if is_relative(s) { + concat(Sys.getcwd(), s) + } else { + s + } + /* Now simplify . and .. components */ + let rec aux = s => { + let base = basename(s) + let dir = dirname(s) + if dir == s { + dir + } else if base == current_dir_name { + aux(dir) + } else if base == parent_dir_name { + dirname(aux(dir)) + } else { + concat(aux(dir), base) + } + } + + aux(s) +} + +let show_filename = file => { + let file = if file == "_none_" { + input_name.contents + } else { + file + } + if absname.contents { + absolute_path(file) + } else { + file + } +} + +let print_filename = (ppf, file) => Format.fprintf(ppf, "%s", show_filename(file)) + +let reset = () => num_loc_lines := 0 + +let (msg_file, msg_line, msg_chars, msg_to, msg_colon) = ( + "File \"", + "\", line ", + ", characters ", + "-", + ":", +) + +/* return file, line, char from the given position */ +let get_pos_info = pos => (pos.pos_fname, pos.pos_lnum, pos.pos_cnum - pos.pos_bol) + +let error_prefix = "Error" +let warning_prefix = "Warning" + +let print_compact = (ppf, loc) => { + let (file, line, startchar) = get_pos_info(loc.loc_start) + let endchar = loc.loc_end.pos_cnum - loc.loc_start.pos_cnum + startchar + fprintf(ppf, "%a:%i", print_filename, file, line) + if startchar >= 0 { + fprintf(ppf, ",%i--%i", startchar, endchar) + } +} + +let echo_eof = () => { + print_newline() + incr(num_loc_lines) +} + +type loc<'a> = { + txt: 'a, + loc: t, +} + +let mkloc = (txt, loc) => {txt: txt, loc: loc} +let mknoloc = txt => mkloc(txt, none) + +type rec error = { + loc: t, + msg: string, + sub: list, + if_highlight: string /* alternative message if locations are highlighted */, +} + +let pp_ksprintf = (~before=?, k, fmt) => { + let buf = Buffer.create(64) + let ppf = Format.formatter_of_buffer(buf) + Misc.Color.set_color_tag_handling(ppf) + switch before { + | None => () + | Some(f) => f(ppf) + } + kfprintf(_ => { + pp_print_flush(ppf, ()) + let msg = Buffer.contents(buf) + k(msg) + }, ppf, fmt) +} + +/* Shift the formatter's offset by the length of the error prefix, which + is always added by the compiler after the message has been formatted */ +let print_phanton_error_prefix = ppf => + Format.pp_print_as(ppf, String.length(error_prefix) + 2 /* ": " */, "") + +let errorf = (~loc=none, ~sub=list{}, ~if_highlight="", fmt) => + pp_ksprintf( + ~before=print_phanton_error_prefix, + msg => {loc: loc, msg: msg, sub: sub, if_highlight: if_highlight}, + fmt, + ) + +let error = (~loc=none, ~sub=list{}, ~if_highlight="", msg) => { + loc: loc, + msg: msg, + sub: sub, + if_highlight: if_highlight, +} + +let error_of_exn: ref option>> = ref(list{}) + +let register_error_of_exn = f => error_of_exn := list{f, ...error_of_exn.contents} + +exception Already_displayed_error = Warnings.Errors + +let error_of_exn = exn => + switch exn { + | Already_displayed_error => Some(#Already_displayed) + | _ => + let rec loop = x => + switch x { + | list{} => None + | list{f, ...rest} => + switch f(exn) { + | Some(error) => Some(#Ok(error)) + | None => loop(rest) + } + } + + loop(error_of_exn.contents) + } + +let error_of_printer = (loc, print, x) => errorf(~loc, "%a@?", print, x) + +let error_of_printer_file = (print, x) => error_of_printer(in_file(input_name.contents), print, x) + +let () = register_error_of_exn(x => + switch x { + | Sys_error(msg) => Some(errorf(~loc=in_file(input_name.contents), "I/O error: %s", msg)) + + | Misc.HookExnWrapper({error: e, hook_name, hook_info: {Misc.sourcefile: sourcefile}}) => + let sub = switch error_of_exn(e) { + | None | Some(#Already_displayed) => error(Printexc.to_string(e)) + | Some(#Ok(err)) => err + } + + Some(errorf(~loc=in_file(sourcefile), "In hook %S:", hook_name, ~sub=list{sub})) + | _ => None + } +) + +external reraise: exn => 'a = "%reraise" + +exception Error(error) + +let () = register_error_of_exn(x => + switch x { + | Error(e) => Some(e) + | _ => None + } +) + +@raises(Error) +let raise_errorf = (~loc=none, ~sub=list{}, ~if_highlight="") => + pp_ksprintf(~before=print_phanton_error_prefix, msg => + raise(Error({loc: loc, msg: msg, sub: sub, if_highlight: if_highlight})) + ) diff --git a/analysis/examples/larger-project/src/longident.js b/analysis/examples/larger-project/src/longident.js new file mode 100644 index 0000000000..b9686fbe86 --- /dev/null +++ b/analysis/examples/larger-project/src/longident.js @@ -0,0 +1,105 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as List from "rescript/lib/es6/list.js"; +import * as Misc from "./misc.js"; +import * as $$String from "rescript/lib/es6/string.js"; +import * as Caml_js_exceptions from "rescript/lib/es6/caml_js_exceptions.js"; + +function flat(_accu, _x) { + while(true) { + var x = _x; + var accu = _accu; + switch (x.TAG | 0) { + case /* Lident */0 : + return { + hd: x._0, + tl: accu + }; + case /* Ldot */1 : + _x = x._0; + _accu = { + hd: x._1, + tl: accu + }; + continue ; + case /* Lapply */2 : + return Misc.fatal_error("Longident.flat"); + + } + }; +} + +function flatten(lid) { + return flat(/* [] */0, lid); +} + +function last(x) { + switch (x.TAG | 0) { + case /* Lident */0 : + return x._0; + case /* Ldot */1 : + return x._1; + case /* Lapply */2 : + return Misc.fatal_error("Longident.last"); + + } +} + +function split_at_dots(s, pos) { + try { + var dot = $$String.index_from(s, pos, /* '.' */46); + return { + hd: $$String.sub(s, pos, dot - pos | 0), + tl: split_at_dots(s, dot + 1 | 0) + }; + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === "Not_found") { + return { + hd: $$String.sub(s, pos, s.length - pos | 0), + tl: /* [] */0 + }; + } + throw exn; + } +} + +function unflatten(l) { + if (l) { + return List.fold_left((function (p, s) { + return { + TAG: /* Ldot */1, + _0: p, + _1: s + }; + }), { + TAG: /* Lident */0, + _0: l.hd + }, l.tl); + } + +} + +function parse(s) { + var v = unflatten(split_at_dots(s, 0)); + if (v !== undefined) { + return v; + } else { + return { + TAG: /* Lident */0, + _0: "" + }; + } +} + +export { + flat , + flatten , + last , + split_at_dots , + unflatten , + parse , + +} +/* Misc Not a pure module */ diff --git a/analysis/examples/larger-project/src/longident.res b/analysis/examples/larger-project/src/longident.res new file mode 100644 index 0000000000..5c5ceedf1f --- /dev/null +++ b/analysis/examples/larger-project/src/longident.res @@ -0,0 +1,60 @@ +/* ************************************************************************ */ +/* */ +/* OCaml */ +/* */ +/* Xavier Leroy, projet Cristal, INRIA Rocquencourt */ +/* */ +/* Copyright 1996 Institut National de Recherche en Informatique et */ +/* en Automatique. */ +/* */ +/* All rights reserved. This file is distributed under the terms of */ +/* the GNU Lesser General Public License version 2.1, with the */ +/* special exception on linking described in the file LICENSE. */ +/* */ +/* ************************************************************************ */ + +type rec t = + | Lident(string) + | Ldot(t, string) + | Lapply(t, t) + +let rec flat = (accu, x) => + switch x { + | Lident(s) => list{s, ...accu} + | Ldot(lid, s) => flat(list{s, ...accu}, lid) + | Lapply(_, _) => Misc.fatal_error("Longident.flat") + } + +let flatten = lid => flat(list{}, lid) + +let last = x => + switch x { + | Lident(s) => s + | Ldot(_, s) => s + | Lapply(_, _) => Misc.fatal_error("Longident.last") + } + +@raises(Invalid_argument) +let rec split_at_dots = (s, pos) => + try { + let dot = String.index_from(s, pos, '.') + list{String.sub(s, pos, dot - pos), ...split_at_dots(s, dot + 1)} + } catch { + | Not_found => list{String.sub(s, pos, String.length(s) - pos)} + } + +let unflatten = l => + switch l { + | list{} => None + | list{hd, ...tl} => Some(List.fold_left((p, s) => Ldot(p, s), Lident(hd), tl)) + } + +@raises(Invalid_argument) +let parse = s => + switch unflatten(split_at_dots(s, 0)) { + | None => Lident("") /* should not happen, but don't put assert false + so as not to crash the toplevel (see Genprintval) */ + + | Some(v) => v + } + diff --git a/analysis/examples/larger-project/src/loop.js b/analysis/examples/larger-project/src/loop.js new file mode 100644 index 0000000000..d856702bfe --- /dev/null +++ b/analysis/examples/larger-project/src/loop.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/analysis/examples/larger-project/src/loop.res b/analysis/examples/larger-project/src/loop.res new file mode 100644 index 0000000000..10417269ac --- /dev/null +++ b/analysis/examples/larger-project/src/loop.res @@ -0,0 +1,4 @@ +// let foo = x => +// switch x { +// | `${ + diff --git a/analysis/examples/larger-project/src/misc.js b/analysis/examples/larger-project/src/misc.js new file mode 100644 index 0000000000..ca5c79b601 --- /dev/null +++ b/analysis/examples/larger-project/src/misc.js @@ -0,0 +1,1450 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as P from "./P.js"; +import * as $$Map from "rescript/lib/es6/map.js"; +import * as $$Set from "rescript/lib/es6/set.js"; +import * as Sys from "rescript/lib/es6/sys.js"; +import * as Caml from "rescript/lib/es6/caml.js"; +import * as List from "rescript/lib/es6/list.js"; +import * as $$Array from "rescript/lib/es6/array.js"; +import * as Bytes from "rescript/lib/es6/bytes.js"; +import * as Curry from "rescript/lib/es6/curry.js"; +import * as $$Buffer from "rescript/lib/es6/buffer.js"; +import * as Format from "./format.js"; +import * as $$String from "rescript/lib/es6/string.js"; +import * as Hashtbl from "rescript/lib/es6/hashtbl.js"; +import * as Caml_obj from "rescript/lib/es6/caml_obj.js"; +import * as Caml_sys from "rescript/lib/es6/caml_sys.js"; +import * as Filename from "rescript/lib/es6/filename.js"; +import * as Caml_array from "rescript/lib/es6/caml_array.js"; +import * as Caml_bytes from "rescript/lib/es6/caml_bytes.js"; +import * as Caml_int32 from "rescript/lib/es6/caml_int32.js"; +import * as Caml_int64 from "rescript/lib/es6/caml_int64.js"; +import * as Pervasives from "rescript/lib/es6/pervasives.js"; +import * as Caml_format from "rescript/lib/es6/caml_format.js"; +import * as Caml_option from "rescript/lib/es6/caml_option.js"; +import * as Caml_string from "rescript/lib/es6/caml_string.js"; +import * as Caml_exceptions from "rescript/lib/es6/caml_exceptions.js"; +import * as Caml_js_exceptions from "rescript/lib/es6/caml_js_exceptions.js"; +import * as Caml_external_polyfill from "rescript/lib/es6/caml_external_polyfill.js"; + +var Fatal_error = /* @__PURE__ */Caml_exceptions.create("Misc.Fatal_error"); + +function fatal_error(msg) { + Pervasives.print_string(">> Fatal error: "); + console.error(msg); + throw { + RE_EXN_ID: Fatal_error, + Error: new Error() + }; +} + +function fatal_errorf(fmt) { + return Curry._1(Format.kasprintf(fatal_error), fmt); +} + +function try_finally(work, cleanup) { + var result; + try { + result = Curry._1(work, undefined); + } + catch (e){ + Curry._1(cleanup, undefined); + throw e; + } + Curry._1(cleanup, undefined); + return result; +} + +function set_refs(l) { + return List.iter((function (param) { + param._0.contents = param._1; + + }), l); +} + +function protect_refs(refs, f) { + var backup = List.map((function (param) { + var r = param._0; + return /* R */{ + _0: r, + _1: r.contents + }; + }), refs); + set_refs(refs); + var x; + try { + x = Curry._1(f, undefined); + } + catch (e){ + set_refs(backup); + throw e; + } + set_refs(backup); + return x; +} + +function map_end(f, l1, l2) { + if (l1) { + return { + hd: Curry._1(f, l1.hd), + tl: map_end(f, l1.tl, l2) + }; + } else { + return l2; + } +} + +function map_left_right(f, x) { + if (!x) { + return /* [] */0; + } + var res = Curry._1(f, x.hd); + return { + hd: res, + tl: map_left_right(f, x.tl) + }; +} + +function for_all2(pred, _l1, _l2) { + while(true) { + var l2 = _l2; + var l1 = _l1; + if (!l1) { + if (l2) { + return false; + } else { + return true; + } + } + if (!l2) { + return false; + } + if (!Curry._2(pred, l1.hd, l2.hd)) { + return false; + } + _l2 = l2.tl; + _l1 = l1.tl; + continue ; + }; +} + +function replicate_list(elem, n) { + if (n <= 0) { + return /* [] */0; + } else { + return { + hd: elem, + tl: replicate_list(elem, n - 1 | 0) + }; + } +} + +function list_remove(x, y) { + throw { + RE_EXN_ID: "Assert_failure", + _1: [ + "misc.res", + 94, + 32 + ], + Error: new Error() + }; +} + +function split_last(x) { + if (x) { + var tl = x.tl; + var x$1 = x.hd; + if (!tl) { + return [ + /* [] */0, + x$1 + ]; + } + var match = split_last(tl); + return [ + { + hd: x$1, + tl: match[0] + }, + match[1] + ]; + } + throw { + RE_EXN_ID: "Assert_failure", + _1: [ + "misc.res", + 98, + 14 + ], + Error: new Error() + }; +} + +function compare(cmp, _l1, _l2) { + while(true) { + var l2 = _l2; + var l1 = _l1; + if (!l1) { + if (l2) { + return -1; + } else { + return 0; + } + } + if (!l2) { + return 1; + } + var c = Curry._2(cmp, l1.hd, l2.hd); + if (c !== 0) { + return c; + } + _l2 = l2.tl; + _l1 = l1.tl; + continue ; + }; +} + +function equal(eq, _l1, _l2) { + while(true) { + var l2 = _l2; + var l1 = _l1; + if (!l1) { + if (l2) { + return false; + } else { + return true; + } + } + if (!l2) { + return false; + } + if (!Curry._2(eq, l1.hd, l2.hd)) { + return false; + } + _l2 = l2.tl; + _l1 = l1.tl; + continue ; + }; +} + +function filter_map(f, l) { + var _acc = /* [] */0; + var _l = l; + while(true) { + var l$1 = _l; + var acc = _acc; + if (!l$1) { + return List.rev(acc); + } + var t = l$1.tl; + var v = Curry._1(f, l$1.hd); + if (v !== undefined) { + _l = t; + _acc = { + hd: Caml_option.valFromOption(v), + tl: acc + }; + continue ; + } + _l = t; + continue ; + }; +} + +function map2_prefix(f, l1, l2) { + var _acc = /* [] */0; + var _l1 = l1; + var _l2 = l2; + while(true) { + var l2$1 = _l2; + var l1$1 = _l1; + var acc = _acc; + if (!l1$1) { + return [ + List.rev(acc), + l2$1 + ]; + } + if (l2$1) { + var h = Curry._2(f, l1$1.hd, l2$1.hd); + _l2 = l2$1.tl; + _l1 = l1$1.tl; + _acc = { + hd: h, + tl: acc + }; + continue ; + } + throw { + RE_EXN_ID: "Invalid_argument", + _1: "map2_prefix", + Error: new Error() + }; + }; +} + +function some_if_all_elements_are_some(l) { + var _acc = /* [] */0; + var _l = l; + while(true) { + var l$1 = _l; + var acc = _acc; + if (!l$1) { + return List.rev(acc); + } + var h = l$1.hd; + if (h === undefined) { + return ; + } + _l = l$1.tl; + _acc = { + hd: Caml_option.valFromOption(h), + tl: acc + }; + continue ; + }; +} + +function split_at(n, l) { + var _n = n; + var _acc = /* [] */0; + var _l = l; + while(true) { + var l$1 = _l; + var acc = _acc; + var n$1 = _n; + if (n$1 === 0) { + return [ + List.rev(acc), + l$1 + ]; + } + if (l$1) { + _l = l$1.tl; + _acc = { + hd: l$1.hd, + tl: acc + }; + _n = n$1 - 1 | 0; + continue ; + } + throw { + RE_EXN_ID: "Invalid_argument", + _1: "split_at", + Error: new Error() + }; + }; +} + +var List$1 = { + compare: compare, + equal: equal, + filter_map: filter_map, + map2_prefix: map2_prefix, + some_if_all_elements_are_some: some_if_all_elements_are_some, + split_at: split_at +}; + +function equal$1(eq, o1, o2) { + if (o1 !== undefined) { + if (o2 !== undefined) { + return Curry._2(eq, Caml_option.valFromOption(o1), Caml_option.valFromOption(o2)); + } else { + return false; + } + } else { + return o2 === undefined; + } +} + +function iter(f, x) { + if (x !== undefined) { + return Curry._1(f, Caml_option.valFromOption(x)); + } + +} + +function map(f, x) { + if (x !== undefined) { + return Caml_option.some(Curry._1(f, Caml_option.valFromOption(x))); + } + +} + +function fold(f, a, b) { + if (a !== undefined) { + return Curry._2(f, Caml_option.valFromOption(a), b); + } else { + return b; + } +} + +function value_default(f, $$default, a) { + if (a !== undefined) { + return Curry._1(f, Caml_option.valFromOption(a)); + } else { + return $$default; + } +} + +var $$Option = { + equal: equal$1, + iter: iter, + map: map, + fold: fold, + value_default: value_default +}; + +function exists2(p, a1, a2) { + var n = a1.length; + if (a2.length !== n) { + Pervasives.invalid_arg("Misc.Stdlib.Array.exists2"); + } + var _i = 0; + while(true) { + var i = _i; + if (i === n) { + return false; + } + if (Curry._2(p, a1[i], a2[i])) { + return true; + } + _i = i + 1 | 0; + continue ; + }; +} + +var $$Array$1 = { + exists2: exists2 +}; + +var Stdlib = { + List: List$1, + $$Option: $$Option, + $$Array: $$Array$1 +}; + +function find_in_path(path, name) { + if (Curry._1(Filename.is_implicit, name)) { + var _x = path; + while(true) { + var x = _x; + if (x) { + var fullname = Filename.concat(x.hd, name); + if (Caml_external_polyfill.resolve("caml_sys_file_exists")(fullname)) { + return fullname; + } + _x = x.tl; + continue ; + } + throw { + RE_EXN_ID: "Not_found", + Error: new Error() + }; + }; + } + if (Caml_external_polyfill.resolve("caml_sys_file_exists")(name)) { + return name; + } + throw { + RE_EXN_ID: "Not_found", + Error: new Error() + }; +} + +function find_in_path_rel(path, name) { + var simplify = function (_s) { + while(true) { + var s = _s; + var base = Curry._1(Filename.basename, s); + var dir = Curry._1(Filename.dirname, s); + if (dir === s) { + return dir; + } + if (base !== Filename.current_dir_name) { + return Filename.concat(simplify(dir), base); + } + _s = dir; + continue ; + }; + }; + var _x = path; + while(true) { + var x = _x; + if (x) { + var fullname = simplify(Filename.concat(x.hd, name)); + if (Caml_external_polyfill.resolve("caml_sys_file_exists")(fullname)) { + return fullname; + } + _x = x.tl; + continue ; + } + throw { + RE_EXN_ID: "Not_found", + Error: new Error() + }; + }; +} + +function find_in_path_uncap(path, name) { + var uname = $$String.uncapitalize_ascii(name); + var _x = path; + while(true) { + var x = _x; + if (x) { + var dir = x.hd; + var fullname = Filename.concat(dir, name); + var ufullname = Filename.concat(dir, uname); + if (Caml_external_polyfill.resolve("caml_sys_file_exists")(ufullname)) { + return ufullname; + } + if (Caml_external_polyfill.resolve("caml_sys_file_exists")(fullname)) { + return fullname; + } + _x = x.tl; + continue ; + } + throw { + RE_EXN_ID: "Not_found", + Error: new Error() + }; + }; +} + +function remove_file(filename) { + try { + if (Caml_external_polyfill.resolve("caml_sys_file_exists")(filename)) { + return Caml_external_polyfill.resolve("caml_sys_remove")(filename); + } else { + return ; + } + } + catch (raw__msg){ + var _msg = Caml_js_exceptions.internalToOCamlException(raw__msg); + if (_msg.RE_EXN_ID === P.Sys_error) { + return ; + } + throw _msg; + } +} + +function expand_directory(alt, s) { + if (s.length !== 0 && Caml_string.get(s, 0) === /* '+' */43) { + return Filename.concat(alt, $$String.sub(s, 1, s.length - 1 | 0)); + } else { + return s; + } +} + +function create_hashtable(size, init) { + var tbl = Hashtbl.create(undefined, size); + List.iter((function (param) { + return Hashtbl.add(tbl, param[0], param[1]); + }), init); + return tbl; +} + +function copy_file(ic, oc) { + var buff = Caml_bytes.caml_create_bytes(4096); + var _param; + while(true) { + var n = Curry._3(P.input(ic), buff, 0, 4096); + if (n === 0) { + return ; + } + Curry._3(P.output(oc), buff, 0, n); + _param = undefined; + continue ; + }; +} + +function copy_file_chunk(ic, oc, len) { + var buff = Caml_bytes.caml_create_bytes(4096); + var _n = len; + while(true) { + var n = _n; + if (n <= 0) { + return ; + } + var r = Curry._3(P.input(ic), buff, 0, n < 4096 ? n : 4096); + if (r === 0) { + throw { + RE_EXN_ID: "End_of_file", + Error: new Error() + }; + } + Curry._3(P.output(oc), buff, 0, r); + _n = n - r | 0; + continue ; + }; +} + +function string_of_file(ic) { + var b = $$Buffer.create(65536); + var buff = Caml_bytes.caml_create_bytes(4096); + var _param; + while(true) { + var n = Curry._3(P.input(ic), buff, 0, 4096); + if (n === 0) { + return $$Buffer.contents(b); + } + $$Buffer.add_subbytes(b, buff, 0, n); + _param = undefined; + continue ; + }; +} + +function output_to_file_via_temporary(modeOpt, filename, fn) { + var mode = modeOpt !== undefined ? modeOpt : ({ + hd: /* Open_text */0, + tl: /* [] */0 + }); + var match = Curry._4(P.open_temp_file(Curry._1(Filename.basename, filename)), mode, 438, Curry._1(Filename.dirname, filename), ".tmp"); + var oc = match[1]; + var temp_filename = match[0]; + var res; + try { + res = Curry._2(fn, temp_filename, oc); + } + catch (exn){ + P.close_out(oc); + remove_file(temp_filename); + throw exn; + } + P.close_out(oc); + try { + Caml_external_polyfill.resolve("caml_sys_rename")(temp_filename, filename); + return res; + } + catch (exn$1){ + remove_file(temp_filename); + throw exn$1; + } +} + +function log2(n) { + if (n <= 1) { + return 0; + } else { + return 1 + log2((n >> 1)) | 0; + } +} + +function align(n, a) { + if (n >= 0) { + return (n + a | 0) - 1 & (-a | 0); + } else { + return n & (-a | 0); + } +} + +function no_overflow_add(a, b) { + return (a ^ b | a ^ Pervasives.lnot(a + b | 0)) < 0; +} + +function no_overflow_sub(a, b) { + return (a ^ Pervasives.lnot(b) | b ^ (a - b | 0)) < 0; +} + +function no_overflow_mul(a, b) { + if (b !== 0) { + return Caml_int32.div(Math.imul(a, b), b) === a; + } else { + return false; + } +} + +function no_overflow_lsl(a, k) { + if (0 <= k && k < Sys.word_size && (Pervasives.min_int >> k) <= a) { + return a <= (Pervasives.max_int >> k); + } else { + return false; + } +} + +function cvt_int_aux(str, neg, of_string) { + if (str.length === 0 || Caml_string.get(str, 0) === /* '-' */45) { + return Curry._1(of_string, str); + } else { + return Curry._1(neg, Curry._1(of_string, "-" + str)); + } +} + +function $$int(s) { + return cvt_int_aux(s, (function (prim) { + return -prim | 0; + }), Caml_format.caml_int_of_string); +} + +function int32(s) { + return cvt_int_aux(s, (function (prim) { + return -prim | 0; + }), Caml_format.caml_int32_of_string); +} + +function int64(s) { + return cvt_int_aux(s, Caml_int64.neg, Caml_format.caml_int64_of_string); +} + +function nativeint(s) { + return cvt_int_aux(s, (function (prim) { + return -prim | 0; + }), Caml_format.caml_nativeint_of_string); +} + +var Int_literal_converter = { + cvt_int_aux: cvt_int_aux, + $$int: $$int, + int32: int32, + int64: int64, + nativeint: nativeint +}; + +function chop_extensions(file) { + var dirname = Curry._1(Filename.dirname, file); + var basename = Curry._1(Filename.basename, file); + try { + var pos = $$String.index(basename, /* '.' */46); + var basename$1 = $$String.sub(basename, 0, pos); + if (Curry._1(Filename.is_implicit, file) && dirname === Filename.current_dir_name) { + return basename$1; + } else { + return Filename.concat(dirname, basename$1); + } + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === "Not_found") { + return file; + } + throw exn; + } +} + +function search_substring(pat, str, start) { + var _i = start; + var _j = 0; + while(true) { + var j = _j; + var i = _i; + if (j >= pat.length) { + return i; + } + if ((i + j | 0) >= str.length) { + throw { + RE_EXN_ID: "Not_found", + Error: new Error() + }; + } + if (Caml_string.get(str, i + j | 0) === Caml_string.get(pat, j)) { + _j = j + 1 | 0; + continue ; + } + _j = 0; + _i = i + 1 | 0; + continue ; + }; +} + +function replace_substring(before, after, str) { + var search = function (_acc, _curr) { + while(true) { + var curr = _curr; + var acc = _acc; + var next; + try { + next = search_substring(before, str, curr); + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === "Not_found") { + var suffix = $$String.sub(str, curr, str.length - curr | 0); + return List.rev({ + hd: suffix, + tl: acc + }); + } + throw exn; + } + var prefix = $$String.sub(str, curr, next - curr | 0); + _curr = next + before.length | 0; + _acc = { + hd: prefix, + tl: acc + }; + continue ; + }; + }; + return $$String.concat(after, search(/* [] */0, 0)); +} + +function rev_split_words(s) { + var split1 = function (res, _i) { + while(true) { + var i = _i; + if (i >= s.length) { + return res; + } + var match = Caml_string.get(s, i); + if (match > 13 || match < 9) { + if (match !== 32) { + return split2(res, i, i + 1 | 0); + } + _i = i + 1 | 0; + continue ; + } + if (match === 12 || match === 11) { + return split2(res, i, i + 1 | 0); + } + _i = i + 1 | 0; + continue ; + }; + }; + var split2 = function (res, i, _j) { + while(true) { + var j = _j; + if (j >= s.length) { + return { + hd: $$String.sub(s, i, j - i | 0), + tl: res + }; + } + var match = Caml_string.get(s, j); + if (match > 13 || match < 9) { + if (match !== 32) { + _j = j + 1 | 0; + continue ; + } + + } else if (match === 12 || match === 11) { + _j = j + 1 | 0; + continue ; + } + return split1({ + hd: $$String.sub(s, i, j - i | 0), + tl: res + }, j + 1 | 0); + }; + }; + return split1(/* [] */0, 0); +} + +function get_ref(r) { + var v = r.contents; + r.contents = /* [] */0; + return v; +} + +function fst3(param) { + return param[0]; +} + +function snd3(param) { + return param[1]; +} + +function thd3(param) { + return param[2]; +} + +function fst4(param) { + return param[0]; +} + +function snd4(param) { + return param[1]; +} + +function thd4(param) { + return param[2]; +} + +function for4(param) { + return param[3]; +} + +function create(str_size) { + var tbl_size = Caml_int32.div(str_size, Sys.max_string_length) + 1 | 0; + var tbl = Caml_array.make(tbl_size, Bytes.empty); + for(var i = 0 ,i_finish = tbl_size - 2 | 0; i <= i_finish; ++i){ + Caml_array.set(tbl, i, Caml_bytes.caml_create_bytes(Sys.max_string_length)); + } + Caml_array.set(tbl, tbl_size - 1 | 0, Caml_bytes.caml_create_bytes(Caml_int32.mod_(str_size, Sys.max_string_length))); + return tbl; +} + +function length(tbl) { + var tbl_size = tbl.length; + return Math.imul(Sys.max_string_length, tbl_size - 1 | 0) + Caml_array.get(tbl, tbl_size - 1 | 0).length | 0; +} + +function get(tbl, ind) { + return Caml_bytes.get(Caml_array.get(tbl, Caml_int32.div(ind, Sys.max_string_length)), Caml_int32.mod_(ind, Sys.max_string_length)); +} + +function set(tbl, ind, c) { + return Caml_bytes.set(Caml_array.get(tbl, Caml_int32.div(ind, Sys.max_string_length)), Caml_int32.mod_(ind, Sys.max_string_length), c); +} + +function blit(src, srcoff, dst, dstoff, len) { + for(var i = 0; i < len; ++i){ + set(dst, dstoff + i | 0, get(src, srcoff + i | 0)); + } + +} + +function output(oc, tbl, pos, len) { + for(var i = pos ,i_finish = pos + len | 0; i < i_finish; ++i){ + Curry._1(P.output_char(oc), get(tbl, i)); + } + +} + +function unsafe_blit_to_bytes(src, srcoff, dst, dstoff, len) { + for(var i = 0; i < len; ++i){ + dst[dstoff + i | 0] = get(src, srcoff + i | 0); + } + +} + +function input_bytes(ic, len) { + var tbl = create(len); + $$Array.iter((function (str) { + return Curry._3(P.really_input(ic), str, 0, str.length); + }), tbl); + return tbl; +} + +var LongString = { + create: create, + length: length, + get: get, + set: set, + blit: blit, + output: output, + unsafe_blit_to_bytes: unsafe_blit_to_bytes, + input_bytes: input_bytes +}; + +function edit_distance(a, b, cutoff) { + var la = a.length; + var lb = b.length; + var cutoff$1 = Caml.caml_int_min(la > lb ? la : lb, cutoff); + if (Pervasives.abs(la - lb | 0) > cutoff$1) { + return ; + } + var m = $$Array.make_matrix(la + 1 | 0, lb + 1 | 0, cutoff$1 + 1 | 0); + Caml_array.set(Caml_array.get(m, 0), 0, 0); + for(var i = 1; i <= la; ++i){ + Caml_array.set(Caml_array.get(m, i), 0, i); + } + for(var j = 1; j <= lb; ++j){ + Caml_array.set(Caml_array.get(m, 0), j, j); + } + for(var i$1 = 1; i$1 <= la; ++i$1){ + for(var j$1 = Caml.caml_int_max(1, (i$1 - cutoff$1 | 0) - 1 | 0) ,j_finish = Caml.caml_int_min(lb, (i$1 + cutoff$1 | 0) + 1 | 0); j$1 <= j_finish; ++j$1){ + var cost = Caml_string.get(a, i$1 - 1 | 0) === Caml_string.get(b, j$1 - 1 | 0) ? 0 : 1; + var best = Caml.caml_int_min(1 + Caml.caml_int_min(Caml_array.get(Caml_array.get(m, i$1 - 1 | 0), j$1), Caml_array.get(Caml_array.get(m, i$1), j$1 - 1 | 0)) | 0, Caml_array.get(Caml_array.get(m, i$1 - 1 | 0), j$1 - 1 | 0) + cost | 0); + var best$1 = i$1 > 1 && j$1 > 1 && Caml_string.get(a, i$1 - 1 | 0) === Caml_string.get(b, j$1 - 2 | 0) && Caml_string.get(a, i$1 - 2 | 0) === Caml_string.get(b, j$1 - 1 | 0) ? Caml.caml_int_min(best, Caml_array.get(Caml_array.get(m, i$1 - 2 | 0), j$1 - 2 | 0) + cost | 0) : best; + Caml_array.set(Caml_array.get(m, i$1), j$1, best$1); + } + } + var result = Caml_array.get(Caml_array.get(m, la), lb); + if (result > cutoff$1) { + return ; + } else { + return result; + } +} + +function spellcheck(env, name) { + var match = name.length; + var cutoff = match > 4 || match < 1 ? ( + match === 6 || match === 5 ? 2 : 3 + ) : ( + match >= 3 ? 1 : 0 + ); + return List.fold_left((function (param, param$1) { + var dist = edit_distance(name, param$1, cutoff); + if (dist === undefined) { + return param; + } + var best_dist = param[1]; + if (dist < best_dist) { + return [ + { + hd: param$1, + tl: /* [] */0 + }, + dist + ]; + } else if (dist === best_dist) { + return [ + { + hd: param$1, + tl: param[0] + }, + dist + ]; + } else { + return param; + } + }), [ + /* [] */0, + Pervasives.max_int + ], env)[0]; +} + +function did_you_mean(ppf, get_choices) { + Curry._1(Format.fprintf(ppf), "@?"); + var choices = Curry._1(get_choices, undefined); + if (!choices) { + return ; + } + var match = split_last(choices); + var rest = match[0]; + return Curry._4(Format.fprintf(ppf), "@\nHint: Did you mean %s%s%s?@?", $$String.concat(", ", rest), rest === /* [] */0 ? "" : " or ", match[1]); +} + +function cut_at(s, c) { + var pos = $$String.index(s, c); + return [ + $$String.sub(s, 0, pos), + $$String.sub(s, pos + 1 | 0, (s.length - pos | 0) - 1 | 0) + ]; +} + +var compare$1 = Caml_obj.caml_compare; + +var StringSet = $$Set.Make({ + compare: compare$1 + }); + +var compare$2 = Caml_obj.caml_compare; + +var StringMap = $$Map.Make({ + compare: compare$2 + }); + +function ansi_of_color(x) { + switch (x) { + case /* Black */0 : + return "0"; + case /* Red */1 : + return "1"; + case /* Green */2 : + return "2"; + case /* Yellow */3 : + return "3"; + case /* Blue */4 : + return "4"; + case /* Magenta */5 : + return "5"; + case /* Cyan */6 : + return "6"; + case /* White */7 : + return "7"; + + } +} + +function code_of_style(x) { + if (typeof x === "number") { + if (x === /* Bold */0) { + return "1"; + } else { + return "0"; + } + } else if (x.TAG === /* FG */0) { + return "3" + ansi_of_color(x._0); + } else { + return "4" + ansi_of_color(x._0); + } +} + +function ansi_of_style_l(l) { + var s = l ? ( + l.tl ? $$String.concat(";", List.map(code_of_style, l)) : code_of_style(l.hd) + ) : "0"; + return "\x11[" + (s + "m"); +} + +var default_styles = { + error: { + hd: /* Bold */0, + tl: { + hd: { + TAG: /* FG */0, + _0: /* Red */1 + }, + tl: /* [] */0 + } + }, + warning: { + hd: /* Bold */0, + tl: { + hd: { + TAG: /* FG */0, + _0: /* Magenta */5 + }, + tl: /* [] */0 + } + }, + loc: { + hd: /* Bold */0, + tl: /* [] */0 + } +}; + +var cur_styles = { + contents: default_styles +}; + +function get_styles(param) { + return cur_styles.contents; +} + +function set_styles(s) { + cur_styles.contents = s; + +} + +function style_of_tag(s) { + switch (s) { + case "error" : + return cur_styles.contents.error; + case "loc" : + return cur_styles.contents.loc; + case "warning" : + return cur_styles.contents.warning; + default: + throw { + RE_EXN_ID: "Not_found", + Error: new Error() + }; + } +} + +var color_enabled = { + contents: true +}; + +function mark_open_tag(or_else, s) { + try { + var style = style_of_tag(s); + if (color_enabled.contents) { + return ansi_of_style_l(style); + } else { + return ""; + } + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === "Not_found") { + return Curry._1(or_else, s); + } + throw exn; + } +} + +function mark_close_tag(or_else, s) { + try { + style_of_tag(s); + if (color_enabled.contents) { + return ansi_of_style_l({ + hd: /* Reset */1, + tl: /* [] */0 + }); + } else { + return ""; + } + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === "Not_found") { + return Curry._1(or_else, s); + } + throw exn; + } +} + +function set_color_tag_handling(ppf) { + throw { + RE_EXN_ID: "Assert_failure", + _1: [ + "misc.res", + 866, + 4 + ], + Error: new Error() + }; +} + +function should_enable_color(param) { + var term; + try { + term = Caml_sys.caml_sys_getenv("TERM"); + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === "Not_found") { + term = ""; + } else { + throw exn; + } + } + if (term !== "dumb" && term !== "") { + return Caml_external_polyfill.resolve("caml_sys_isatty")(P.stderr); + } else { + return false; + } +} + +var first = { + contents: true +}; + +var formatter_l_1 = { + hd: Format.err_formatter, + tl: { + hd: Format.str_formatter, + tl: /* [] */0 + } +}; + +var formatter_l = { + hd: Format.std_formatter, + tl: formatter_l_1 +}; + +function setup(o) { + if (first.contents) { + first.contents = false; + Format.set_mark_tags(true); + List.iter(set_color_tag_handling, formatter_l); + var tmp; + if (o !== undefined) { + switch (o) { + case /* Auto */0 : + tmp = should_enable_color(undefined); + break; + case /* Always */1 : + tmp = true; + break; + case /* Never */2 : + tmp = false; + break; + + } + } else { + tmp = should_enable_color(undefined); + } + color_enabled.contents = tmp; + } + +} + +var Color = { + ansi_of_color: ansi_of_color, + code_of_style: code_of_style, + ansi_of_style_l: ansi_of_style_l, + default_styles: default_styles, + cur_styles: cur_styles, + get_styles: get_styles, + set_styles: set_styles, + style_of_tag: style_of_tag, + color_enabled: color_enabled, + mark_open_tag: mark_open_tag, + mark_close_tag: mark_close_tag, + set_color_tag_handling: set_color_tag_handling, + should_enable_color: should_enable_color, + setup: setup +}; + +function normalise_eol(s) { + var b = $$Buffer.create(80); + for(var i = 0 ,i_finish = s.length; i < i_finish; ++i){ + if (Caml_string.get(s, i) !== /* '\r' */13) { + $$Buffer.add_char(b, Caml_string.get(s, i)); + } + + } + return $$Buffer.contents(b); +} + +function delete_eol_spaces(src) { + var len_src = src.length; + var dst = Caml_bytes.caml_create_bytes(len_src); + var loop = function (_i_src, _i_dst) { + while(true) { + var i_dst = _i_dst; + var i_src = _i_src; + if (i_src === len_src) { + return i_dst; + } + var c = Caml_string.get(src, i_src); + if (c === 9) { + return loop_spaces(1, i_src + 1 | 0, i_dst); + } + if (c === 32) { + return loop_spaces(1, i_src + 1 | 0, i_dst); + } + Caml_bytes.set(dst, i_dst, c); + _i_dst = i_dst + 1 | 0; + _i_src = i_src + 1 | 0; + continue ; + }; + }; + var loop_spaces = function (_spaces, _i_src, i_dst) { + while(true) { + var i_src = _i_src; + var spaces = _spaces; + if (i_src === len_src) { + return i_dst; + } + var match = Caml_string.get(src, i_src); + if (match === 10 || match === 9) { + if (match >= 10) { + Caml_bytes.set(dst, i_dst, /* '\n' */10); + return loop(i_src + 1 | 0, i_dst + 1 | 0); + } + + } else if (match !== 32) { + for(var n = 0; n <= spaces; ++n){ + Caml_bytes.set(dst, i_dst + n | 0, Caml_string.get(src, (i_src - spaces | 0) + n | 0)); + } + return loop(i_src + 1 | 0, (i_dst + spaces | 0) + 1 | 0); + } + _i_src = i_src + 1 | 0; + _spaces = spaces + 1 | 0; + continue ; + }; + }; + var stop = loop(0, 0); + return Bytes.sub_string(dst, 0, stop); +} + +var HookExnWrapper = /* @__PURE__ */Caml_exceptions.create("Misc.HookExnWrapper"); + +var HookExn = /* @__PURE__ */Caml_exceptions.create("Misc.HookExn"); + +function raise_direct_hook_exn(e) { + throw { + RE_EXN_ID: HookExn, + _1: e, + Error: new Error() + }; +} + +function fold_hooks(list, hook_info, ast) { + return List.fold_left((function (ast, param) { + try { + return Curry._2(param[1], hook_info, ast); + } + catch (raw_e){ + var e = Caml_js_exceptions.internalToOCamlException(raw_e); + if (e.RE_EXN_ID === HookExn) { + throw e._1; + } + throw { + RE_EXN_ID: HookExnWrapper, + error: e, + hook_name: param[0], + hook_info: hook_info, + Error: new Error() + }; + } + }), ast, List.sort(Caml_obj.caml_compare, list)); +} + +function MakeHooks(M) { + var hooks = { + contents: /* [] */0 + }; + var add_hook = function (name, f) { + hooks.contents = { + hd: [ + name, + f + ], + tl: hooks.contents + }; + + }; + var apply_hooks = function (sourcefile, intf) { + return fold_hooks(hooks.contents, sourcefile, intf); + }; + return { + add_hook: add_hook, + apply_hooks: apply_hooks + }; +} + +var may = iter; + +var may_map = map; + +export { + Fatal_error , + fatal_error , + fatal_errorf , + try_finally , + protect_refs , + map_end , + map_left_right , + for_all2 , + replicate_list , + list_remove , + split_last , + Stdlib , + may , + may_map , + find_in_path , + find_in_path_rel , + find_in_path_uncap , + remove_file , + expand_directory , + create_hashtable , + copy_file , + copy_file_chunk , + string_of_file , + output_to_file_via_temporary , + log2 , + align , + no_overflow_add , + no_overflow_sub , + no_overflow_mul , + no_overflow_lsl , + Int_literal_converter , + chop_extensions , + search_substring , + replace_substring , + rev_split_words , + get_ref , + fst3 , + snd3 , + thd3 , + fst4 , + snd4 , + thd4 , + for4 , + LongString , + edit_distance , + spellcheck , + did_you_mean , + cut_at , + StringSet , + StringMap , + Color , + normalise_eol , + delete_eol_spaces , + HookExnWrapper , + HookExn , + raise_direct_hook_exn , + fold_hooks , + MakeHooks , + +} +/* StringSet Not a pure module */ diff --git a/analysis/examples/larger-project/src/misc.res b/analysis/examples/larger-project/src/misc.res new file mode 100644 index 0000000000..ff95a24c65 --- /dev/null +++ b/analysis/examples/larger-project/src/misc.res @@ -0,0 +1,994 @@ +/* ************************************************************************ */ +/* */ +/* OCaml */ +/* */ +/* Xavier Leroy, projet Cristal, INRIA Rocquencourt */ +/* */ +/* Copyright 1996 Institut National de Recherche en Informatique et */ +/* en Automatique. */ +/* */ +/* All rights reserved. This file is distributed under the terms of */ +/* the GNU Lesser General Public License version 2.1, with the */ +/* special exception on linking described in the file LICENSE. */ +/* */ +/* ************************************************************************ */ + +/* Errors */ + +open P + +exception Fatal_error + +@raises(Fatal_error) +let fatal_error = msg => { + print_string(">> Fatal error: ") + prerr_endline(msg) + raise(Fatal_error) +} + +@raises(Fatal_error) +let fatal_errorf = fmt => Format.kasprintf(fatal_error, fmt) + +/* Exceptions */ + +@raises(genericException) +let try_finally = (work, cleanup) => { + let result = try work() catch { + | e => + cleanup() + raise(e) + } + cleanup() + result +} + +type rec ref_and_value = R(ref<'a>, 'a): ref_and_value + +@raises(genericException) +let protect_refs = { + let set_refs = l => List.iter((R(r, v)) => r := v, l) + (refs, f) => { + let backup = List.map((R(r, _)) => R(r, r.contents), refs) + set_refs(refs) + switch f() { + | x => + set_refs(backup) + x + | exception e => + set_refs(backup) + raise(e) + } + } +} + +/* List functions */ + +let rec map_end = (f, l1, l2) => + switch l1 { + | list{} => l2 + | list{hd, ...tl} => list{f(hd), ...map_end(f, tl, l2)} + } + +let rec map_left_right = (f, x) => + switch x { + | list{} => list{} + | list{hd, ...tl} => + let res = f(hd) + list{res, ...map_left_right(f, tl)} + } + +let rec for_all2 = (pred, l1, l2) => + switch (l1, l2) { + | (list{}, list{}) => true + | (list{hd1, ...tl1}, list{hd2, ...tl2}) => pred(hd1, hd2) && for_all2(pred, tl1, tl2) + | (_, _) => false + } + +let rec replicate_list = (elem, n) => + if n <= 0 { + list{} + } else { + list{elem, ...replicate_list(elem, n - 1)} + } + +let rec list_remove = (x, y) => assert false + +let rec split_last = x => + switch x { + | list{} => assert false + | list{x} => (list{}, x) + | list{hd, ...tl} => + let (lst, last) = split_last(tl) + (list{hd, ...lst}, last) + } + +module Stdlib = { + module List = { + type t<'a> = list<'a> + + let rec compare = (cmp, l1, l2) => + switch (l1, l2) { + | (list{}, list{}) => 0 + | (list{}, list{_, ..._}) => -1 + | (list{_, ..._}, list{}) => 1 + | (list{h1, ...t1}, list{h2, ...t2}) => + let c = cmp(h1, h2) + if c != 0 { + c + } else { + compare(cmp, t1, t2) + } + } + + let rec equal = (eq, l1, l2) => + switch (l1, l2) { + | (list{}, list{}) => true + | (list{hd1, ...tl1}, list{hd2, ...tl2}) => eq(hd1, hd2) && equal(eq, tl1, tl2) + | (_, _) => false + } + + @raises(Invalid_argument) + let filter_map = (f, l) => { + @raises(Invalid_argument) + let rec aux = (acc, l) => + switch l { + | list{} => List.rev(acc) + | list{h, ...t} => + switch f(h) { + | None => aux(acc, t) + | Some(v) => aux(list{v, ...acc}, t) + } + } + + aux(list{}, l) + } + + @raises(Invalid_argument) + let map2_prefix = (f, l1, l2) => { + @raises(Invalid_argument) + let rec aux = (acc, l1, l2) => + switch (l1, l2) { + | (list{}, _) => (List.rev(acc), l2) + | (list{_, ..._}, list{}) => raise(Invalid_argument("map2_prefix")) + | (list{h1, ...t1}, list{h2, ...t2}) => + let h = f(h1, h2) + aux(list{h, ...acc}, t1, t2) + } + + aux(list{}, l1, l2) + } + + @raises(Invalid_argument) + let some_if_all_elements_are_some = l => { + @raises(Invalid_argument) + let rec aux = (acc, l) => + switch l { + | list{} => Some(List.rev(acc)) + | list{None, ..._} => None + | list{Some(h), ...t} => aux(list{h, ...acc}, t) + } + + aux(list{}, l) + } + + @raises(Invalid_argument) + let split_at = (n, l) => { + @raises(Invalid_argument) + let rec aux = (n, acc, l) => + if n == 0 { + (List.rev(acc), l) + } else { + switch l { + | list{} => raise(Invalid_argument("split_at")) + | list{t, ...q} => aux(n - 1, list{t, ...acc}, q) + } + } + + aux(n, list{}, l) + } + } + + module Option = { + type t<'a> = option<'a> + + let equal = (eq, o1, o2) => + switch (o1, o2) { + | (None, None) => true + | (Some(e1), Some(e2)) => eq(e1, e2) + | (_, _) => false + } + + let iter = (f, x) => + switch x { + | Some(x) => f(x) + | None => () + } + + let map = (f, x) => + switch x { + | Some(x) => Some(f(x)) + | None => None + } + + let fold = (f, a, b) => + switch a { + | None => b + | Some(a) => f(a, b) + } + + let value_default = (f, ~default, a) => + switch a { + | None => default + | Some(a) => f(a) + } + } + + module Array = { + @raises(Invalid_argument) + let exists2 = (p, a1, a2) => { + let n = Array.length(a1) + if Array.length(a2) != n { + invalid_arg("Misc.Stdlib.Array.exists2") + } + let rec loop = i => + if i == n { + false + } else if p(Array.unsafe_get(a1, i), Array.unsafe_get(a2, i)) { + true + } else { + loop(succ(i)) + } + loop(0) + } + } +} + +let may = Stdlib.Option.iter +let may_map = Stdlib.Option.map + +/* File functions */ + +@raises(Not_found) +let find_in_path = (path, name) => + if !Filename.is_implicit(name) { + if Sys.file_exists(name) { + name + } else { + raise(Not_found) + } + } else { + @raises(Not_found) + let rec try_dir = x => + switch x { + | list{} => raise(Not_found) + | list{dir, ...rem} => + let fullname = Filename.concat(dir, name) + if Sys.file_exists(fullname) { + fullname + } else { + try_dir(rem) + } + } + try_dir(path) + } + +@raises(Not_found) +let find_in_path_rel = (path, name) => { + let rec simplify = s => { + open Filename + let base = basename(s) + let dir = dirname(s) + if dir == s { + dir + } else if base == current_dir_name { + simplify(dir) + } else { + concat(simplify(dir), base) + } + } + + @raises(Not_found) + let rec try_dir = x => + switch x { + | list{} => raise(Not_found) + | list{dir, ...rem} => + let fullname = simplify(Filename.concat(dir, name)) + if Sys.file_exists(fullname) { + fullname + } else { + try_dir(rem) + } + } + try_dir(path) +} + +@raises(Not_found) +let find_in_path_uncap = (path, name) => { + let uname = String.uncapitalize_ascii(name) + + @raises(Not_found) + let rec try_dir = x => + switch x { + | list{} => raise(Not_found) + | list{dir, ...rem} => + let fullname = Filename.concat(dir, name) + and ufullname = Filename.concat(dir, uname) + if Sys.file_exists(ufullname) { + ufullname + } else if Sys.file_exists(fullname) { + fullname + } else { + try_dir(rem) + } + } + try_dir(path) +} + + +let remove_file = filename => + try if Sys.file_exists(filename) { + Sys.remove(filename) + } catch { + | Sys_error(_msg) => () + } + +/* Expand a -I option: if it starts with +, make it relative to the standard + library directory */ + +@raises(Invalid_argument) +let expand_directory = (alt, s) => + if String.length(s) > 0 && String.get(s, 0) == '+' { + Filename.concat(alt, String.sub(s, 1, String.length(s) - 1)) + } else { + s + } + +/* Hashtable functions */ + +let create_hashtable = (size, init) => { + let tbl = Hashtbl.create(size) + List.iter(((key, data)) => Hashtbl.add(tbl, key, data), init) + tbl +} + +/* File copy */ + +@raises(Invalid_argument) +let copy_file = (ic, oc) => { + let buff = Bytes.create(0x1000) + + @raises(Invalid_argument) + let rec copy = () => { + let n = input(ic, buff, 0, 0x1000) + if n == 0 { + () + } else { + output(oc, buff, 0, n) + copy() + } + } + copy() +} + +@raises(Invalid_argument) +let copy_file_chunk = (ic, oc, len) => { + let buff = Bytes.create(0x1000) + + @raises([End_of_file, Invalid_argument]) + let rec copy = n => + if n <= 0 { + () + } else { + let r = input(ic, buff, 0, min(n, 0x1000)) + if r == 0 { + raise(End_of_file) + } else { + output(oc, buff, 0, r) + copy(n - r) + } + } + copy(len) +} + +@raises(Invalid_argument) +let string_of_file = ic => { + let b = Buffer.create(0x10000) + let buff = Bytes.create(0x1000) + + @raises(Invalid_argument) + let rec copy = () => { + let n = input(ic, buff, 0, 0x1000) + if n == 0 { + Buffer.contents(b) + } else { + Buffer.add_subbytes(b, buff, 0, n) + copy() + } + } + copy() +} + +@raises([Sys_error, genericException]) +let output_to_file_via_temporary = (~mode=list{Open_text}, filename, fn) => { + let (temp_filename, oc) = open_temp_file( + ~mode, + ~perms=0o666, + ~temp_dir=Filename.dirname(filename), + Filename.basename(filename), + ".tmp", + ) + /* The 0o666 permissions will be modified by the umask. It's just + like what [open_out] and [open_out_bin] do. + With temp_dir = dirname filename, we ensure that the returned + temp file is in the same directory as filename itself, making + it safe to rename temp_filename to filename later. + With prefix = basename filename, we are almost certain that + the first generated name will be unique. A fixed prefix + would work too but might generate more collisions if many + files are being produced simultaneously in the same directory. */ + switch fn(temp_filename, oc) { + | res => + close_out(oc) + try { + Sys.rename(temp_filename, filename) + res + } catch { + | exn => + remove_file(temp_filename) + raise(exn) + } + | exception exn => + close_out(oc) + remove_file(temp_filename) + raise(exn) + } +} + +/* Integer operations */ + +let rec log2 = n => + if n <= 1 { + 0 + } else { + 1 + log2(asr(n, 1)) + } + +let align = (n, a) => + if n >= 0 { + land(n + a - 1, -a) + } else { + land(n, -a) + } + +let no_overflow_add = (a, b) => lor(lxor(a, b), lxor(a, lnot(a + b))) < 0 + +let no_overflow_sub = (a, b) => lor(lxor(a, lnot(b)), lxor(b, a - b)) < 0 + +@raises(Division_by_zero) +let no_overflow_mul = (a, b) => b != 0 && a * b / b == a + +let no_overflow_lsl = (a, k) => + 0 <= k && (k < Sys.word_size && (asr(min_int, k) <= a && a <= asr(max_int, k))) + +module Int_literal_converter = { + /* To convert integer literals, allowing max_int + 1 (PR#4210) */ + @raises(Invalid_argument) + let cvt_int_aux = (str, neg, of_string) => + if String.length(str) == 0 || String.get(str, 0) == '-' { + of_string(str) + } else { + neg(of_string("-" ++ str)) + } + @raises([Failure, Invalid_argument]) + let int = s => cvt_int_aux(s, \"~-", int_of_string) + @raises(Invalid_argument) + let int32 = s => cvt_int_aux(s, Int32.neg, Int32.of_string) + @raises(Invalid_argument) + let int64 = s => cvt_int_aux(s, Int64.neg, Int64.of_string) + @raises(Invalid_argument) + let nativeint = s => cvt_int_aux(s, Nativeint.neg, Nativeint.of_string) +} + +/* String operations */ + +@raises(Invalid_argument) +let chop_extensions = file => { + let dirname = Filename.dirname(file) and basename = Filename.basename(file) + try { + let pos = String.index(basename, '.') + let basename = String.sub(basename, 0, pos) + if Filename.is_implicit(file) && dirname == Filename.current_dir_name { + basename + } else { + Filename.concat(dirname, basename) + } + } catch { + | Not_found => file + } +} + +@raises(Invalid_argument) +let search_substring = (pat, str, start) => { + @raises([Invalid_argument, Not_found]) + let rec search = (i, j) => + if j >= String.length(pat) { + i + } else if i + j >= String.length(str) { + raise(Not_found) + } else if String.get(str, i + j) == String.get(pat, j) { + search(i, j + 1) + } else { + search(i + 1, 0) + } + search(start, 0) +} + +@raises(Invalid_argument) +let replace_substring = (~before, ~after, str) => { + @raises(Invalid_argument) + let rec search = (acc, curr) => + switch search_substring(before, str, curr) { + | next => + let prefix = String.sub(str, curr, next - curr) + search(list{prefix, ...acc}, next + String.length(before)) + | exception Not_found => + let suffix = String.sub(str, curr, String.length(str) - curr) + List.rev(list{suffix, ...acc}) + } + String.concat(after, search(list{}, 0)) +} + +@raises(Invalid_argument) +let rev_split_words = s => { + @raises(Invalid_argument) + let rec split1 = (res, i) => + if i >= String.length(s) { + res + } else { + switch String.get(s, i) { + | ' ' | '\t' | '\r' | '\n' => split1(res, i + 1) + | _ => split2(res, i, i + 1) + } + } + @raises(Invalid_argument) + and split2 = (res, i, j) => + if j >= String.length(s) { + list{String.sub(s, i, j - i), ...res} + } else { + switch String.get(s, j) { + | ' ' | '\t' | '\r' | '\n' => split1(list{String.sub(s, i, j - i), ...res}, j + 1) + | _ => split2(res, i, j + 1) + } + } + split1(list{}, 0) +} + +let get_ref = r => { + let v = r.contents + r := list{} + v +} + +let fst3 = ((x, _, _)) => x +let snd3 = ((_, x, _)) => x +let thd3 = ((_, _, x)) => x + +let fst4 = ((x, _, _, _)) => x +let snd4 = ((_, x, _, _)) => x +let thd4 = ((_, _, x, _)) => x +let for4 = ((_, _, _, x)) => x + +module LongString = { + type t = array + + @raises([Division_by_zero, Invalid_argument]) + let create = str_size => { + let tbl_size = str_size / Sys.max_string_length + 1 + let tbl = Array.make(tbl_size, Bytes.empty) + for i in 0 to tbl_size - 2 { + tbl[i] = Bytes.create(Sys.max_string_length) + } + tbl[tbl_size - 1] = Bytes.create(mod(str_size, Sys.max_string_length)) + tbl + } + + @raises(Invalid_argument) + let length = tbl => { + let tbl_size = Array.length(tbl) + Sys.max_string_length * (tbl_size - 1) + Bytes.length(tbl[tbl_size - 1]) + } + + @raises([Division_by_zero, Invalid_argument]) + let get = (tbl, ind) => + Bytes.get(tbl[ind / Sys.max_string_length], mod(ind, Sys.max_string_length)) + + @raises([Division_by_zero, Invalid_argument]) + let set = (tbl, ind, c) => + Bytes.set(tbl[ind / Sys.max_string_length], mod(ind, Sys.max_string_length), c) + + @raises([Division_by_zero, Invalid_argument]) + let blit = (src, srcoff, dst, dstoff, len) => + for i in 0 to len - 1 { + set(dst, dstoff + i, get(src, srcoff + i)) + } + + @raises([Division_by_zero, Invalid_argument]) + let output = (oc, tbl, pos, len) => + for i in pos to pos + len - 1 { + output_char(oc, get(tbl, i)) + } + + @raises([Division_by_zero, Invalid_argument]) + let unsafe_blit_to_bytes = (src, srcoff, dst, dstoff, len) => + for i in 0 to len - 1 { + Bytes.unsafe_set(dst, dstoff + i, get(src, srcoff + i)) + } + + @raises([Division_by_zero, End_of_file, Invalid_argument]) + let input_bytes = (ic, len) => { + let tbl = create(len) + Array.iter(str => really_input(ic, str, 0, Bytes.length(str)), tbl) + tbl + } +} + +@raises(Invalid_argument) +let edit_distance = (a, b, cutoff) => { + let (la, lb) = (String.length(a), String.length(b)) + let cutoff = /* using max_int for cutoff would cause overflows in (i + cutoff + 1); + we bring it back to the (max la lb) worstcase */ + min(max(la, lb), cutoff) + if abs(la - lb) > cutoff { + None + } else { + /* initialize with 'cutoff + 1' so that not-yet-written-to cases have + the worst possible cost; this is useful when computing the cost of + a case just at the boundary of the cutoff diagonal. */ + let m = Array.make_matrix(la + 1, lb + 1, cutoff + 1) + m[0][0] = 0 + for i in 1 to la { + m[i][0] = i + } + for j in 1 to lb { + m[0][j] = j + } + for i in 1 to la { + for j in max(1, i - cutoff - 1) to min(lb, i + cutoff + 1) { + let cost = if String.get(a, i - 1) == String.get(b, j - 1) { + 0 + } else { + 1 + } + let best = /* insert, delete or substitute */ + min(1 + min(m[i - 1][j], m[i][j - 1]), m[i - 1][j - 1] + cost) + + let best = /* swap two adjacent letters; we use "cost" again in case of + a swap between two identical letters; this is slightly + redundant as this is a double-substitution case, but it + was done this way in most online implementations and + imitation has its virtues */ + if ( + !( + i > 1 && + (j > 1 && + (String.get(a, i - 1) == String.get(b, j - 2) && + String.get(a, i - 2) == String.get(b, j - 1))) + ) + ) { + best + } else { + min(best, m[i - 2][j - 2] + cost) + } + + m[i][j] = best + } + } + let result = m[la][lb] + if result > cutoff { + None + } else { + Some(result) + } + } +} + +@raises(Invalid_argument) +let spellcheck = (env, name) => { + let cutoff = switch String.length(name) { + | 1 | 2 => 0 + | 3 | 4 => 1 + | 5 | 6 => 2 + | _ => 3 + } + + @raises(Invalid_argument) + let compare = (target, acc, head) => + switch edit_distance(target, head, cutoff) { + | None => acc + | Some(dist) => + let (best_choice, best_dist) = acc + if dist < best_dist { + (list{head}, dist) + } else if dist == best_dist { + (list{head, ...best_choice}, dist) + } else { + acc + } + } + + fst(List.fold_left(compare(name), (list{}, max_int), env)) +} + +let did_you_mean = (ppf, get_choices) => { + /* flush now to get the error report early, in the (unheard of) case + where the search in the get_choices function would take a bit of + time; in the worst case, the user has seen the error, she can + interrupt the process before the spell-checking terminates. */ + Format.fprintf(ppf, "@?") + switch get_choices() { + | list{} => () + | choices => + let (rest, last) = split_last(choices) + Format.fprintf( + ppf, + "@\nHint: Did you mean %s%s%s?@?", + String.concat(", ", rest), + if rest == list{} { + "" + } else { + " or " + }, + last, + ) + } +} + +@raises([Invalid_argument, Not_found]) +let cut_at = (s, c) => { + let pos = String.index(s, c) + (String.sub(s, 0, pos), String.sub(s, pos + 1, String.length(s) - pos - 1)) +} + +module StringSet = Set.Make({ + type t = string + let compare = compare +}) +module StringMap = Map.Make({ + type t = string + let compare = compare +}) + +/* Color handling */ +module Color = { + /* use ANSI color codes, see https://en.wikipedia.org/wiki/ANSI_escape_code */ + type color = + | Black + | Red + | Green + | Yellow + | Blue + | Magenta + | Cyan + | White + + type style = + | FG(color) /* foreground */ + | BG(color) /* background */ + | Bold + | Reset + + let ansi_of_color = x => + switch x { + | Black => "0" + | Red => "1" + | Green => "2" + | Yellow => "3" + | Blue => "4" + | Magenta => "5" + | Cyan => "6" + | White => "7" + } + + let code_of_style = x => + switch x { + | FG(c) => "3" ++ ansi_of_color(c) + | BG(c) => "4" ++ ansi_of_color(c) + | Bold => "1" + | Reset => "0" + } + + let ansi_of_style_l = l => { + let s = switch l { + | list{} => code_of_style(Reset) + | list{s} => code_of_style(s) + | _ => String.concat(";", List.map(code_of_style, l)) + } + + "\x1b[" ++ (s ++ "m") + } + + type styles = { + error: list