├── .gitignore ├── .tidyrc.json ├── LICENSE ├── README.md ├── bin └── print-module-types.js ├── flake.lock ├── flake.nix ├── package.json ├── packages.dhall ├── spago.dhall ├── src ├── Bin │ └── PrintModuleTypes.purs ├── Effect │ └── Uncurried │ │ ├── Methods.js │ │ ├── Methods.purs │ │ └── Metohds.js ├── ReadDTS.purs ├── ReadDTS │ ├── AST.purs │ ├── AST │ │ └── Printer.purs │ ├── Specialization.purs │ ├── Specialization │ │ └── Pretty.purs │ ├── TypeScript.js │ ├── TypeScript.purs │ └── TypeScript.ts ├── TS │ └── Codegen │ │ ├── PS.purs │ │ └── PS │ │ ├── ModulePath.purs │ │ └── Types.purs └── TypeScript │ ├── Class │ └── Compiler │ │ └── Program.purs │ ├── Compiler │ ├── Checker.js │ ├── Checker.purs │ ├── Checker.ts │ ├── Checker │ │ ├── Internal.js │ │ ├── Internal.purs │ │ └── Internal.ts │ ├── Debug.js │ ├── Debug.purs │ ├── Debug.ts │ ├── Factory │ │ ├── NodeTests.js │ │ ├── NodeTests.purs │ │ └── NodeTests.ts │ ├── Parser.js │ ├── Parser.purs │ ├── Parser.ts │ ├── Program.js │ ├── Program.purs │ ├── Program.ts │ ├── Types.js │ ├── Types.purs │ ├── Types.ts │ ├── Types │ │ ├── Diagnostics.js │ │ ├── Diagnostics.purs │ │ ├── Nodes.js │ │ ├── Nodes.purs │ │ ├── Nodes.ts │ │ ├── Signature.js │ │ ├── Signature.purs │ │ ├── Signature.ts │ │ ├── Symbol.js │ │ ├── Symbol.purs │ │ ├── Symbol.ts │ │ ├── Typs.js │ │ ├── Typs.purs │ │ ├── Typs.ts │ │ └── Typs │ │ │ ├── Internal.js │ │ │ ├── Internal.purs │ │ │ └── Internal.ts │ ├── UtilitiesPublic.js │ ├── UtilitiesPublic.purs │ └── UtilitiesPublic.ts │ └── Testing │ ├── BoundedCompilerHost.js │ ├── BoundedCompilerHost.purs │ ├── BoundedCompilerHost.ts │ ├── DefaultLib.purs │ ├── InMemory.purs │ ├── InSubdir.purs │ └── Types.purs └── test ├── Codegen.purs ├── Compile.purs ├── Golden ├── ThreeJs.purs └── ts │ └── three │ ├── cameras │ └── Camera.d.ts │ ├── constants.d.ts │ ├── core │ ├── BufferAttribute.d.ts │ ├── BufferGeometry.d.ts │ ├── EventDispatcher.d.ts │ ├── InterleavedBuffer.d.ts │ ├── InterleavedBufferAttribute.d.ts │ └── Object3D.d.ts │ ├── math │ ├── Box2.d.ts │ ├── Box3.d.ts │ ├── Color.d.ts │ ├── Cylindrical.d.ts │ ├── Euler.d.ts │ ├── Frustum.d.ts │ ├── Interpolant.d.ts │ ├── Line3.d.ts │ ├── MathUtils.d.ts │ ├── Matrix3.d.ts │ ├── Matrix4.d.ts │ ├── Plane.d.ts │ ├── Quaternion.d.ts │ ├── Ray.d.ts │ ├── Sphere.d.ts │ ├── Spherical.d.ts │ ├── SphericalHarmonics3.d.ts │ ├── Triangle.d.ts │ ├── Vector2.d.ts │ ├── Vector3.d.ts │ ├── Vector4.d.ts │ └── interpolants │ │ ├── CubicInterpolant.d.ts │ │ ├── DiscreteInterpolant.d.ts │ │ ├── LinearInterpolant.d.ts │ │ └── QuaternionLinearInterpolant.d.ts │ ├── objects │ └── Sprite.d.ts │ └── utils.d.ts ├── Main.purs ├── MultiModule.purs ├── NonRecType.purs └── RecType.purs /.gitignore: -------------------------------------------------------------------------------- 1 | .psci_modules 2 | node_modules 3 | .psci 4 | 5 | /.pulp-cache/ 6 | /output/ 7 | /generated-docs/ 8 | /.psc-package/ 9 | /.psc* 10 | /.purs* 11 | /.psa* 12 | /.spago 13 | 14 | package-lock.json 15 | *.js.map 16 | -------------------------------------------------------------------------------- /.tidyrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "importWrap": "source", 3 | "indent": 2, 4 | "operatorsFile": null, 5 | "ribbon": 1, 6 | "typeArrowPlacement": "first", 7 | "unicode": "never", 8 | "width": null 9 | } 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2019, doolse, Kamirus, Tomasz Rybarczyk (aka paluh) 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # purescript-read-dts 2 | 3 | ## Status 4 | 5 | _Major rewrite_. I want to put here some stubs for the notes: 6 | 7 | * Explain `TypeScript` package structure: 8 | 9 | - it tries to follow original `typescript/typescript` project structure. 10 | 11 | - `Internal` modules are modules which expose typescript implementation internals which seems to be really useful. 12 | 13 | - `Contrib` subpackage contains additions - for clarity 14 | 15 | - Bindings to `is*` are usually renamed to `as*` functions which return `Maybe t` where `t` is narrowed type 16 | 17 | - `Node r` - provide info about interfaces access model. 18 | 19 | - Add info about immutability of the Program from the checker and the decision behind "pure" bindings. 20 | 21 | [A Program is an immutable collection of 'SourceFile's and a 'CompilerOptions']("https://github.com/microsoft/TypeScript/blob/v4.5.2/src/compiler/program.ts#L842") 22 | 23 | 24 | ## Old docs for reference during rewrite: 25 | 26 | --- 27 | 28 | Provide a way to work with TypeScript [types declarations](https://stackoverflow.com/questions/21247278/about-d-ts-in-typescript). 29 | 30 | ### Status 31 | 32 | Currently we are in a somewhat inconsistent state. On the one hand this codebase is very rough in a many places and it is developed thanks to the live experimentation and direct source browsing of the typescript compiler. On the other hand we successfully test and use it against quite a large codegen projects. 33 | 34 | As a main battlefield we have choosen `purescript-react-basic-mui` so please check this project for an extended example. 35 | 36 | API of this library consists of three layers. 37 | 38 | * We have semivisitor API build upon TypeScript compiler API and provided by `ReadDTS.ts`and `ReadDTS.purs`. 39 | 40 | * We have an opinionated minimal AST which represents TypeScript types declarations. You can find it in `ReadDTS/AST.purs`. Initially this AST contains unresolved refreneces to other types which are filled during unfolding done by effectfull `AST.coalgebra`. 41 | 42 | * Finally we have `ReadDTS/Instantiation.purs` module (it [should be renamed to](/purescript-codegen/purescript-read-dts/issues/7) `Specialization.purs`) which provides an AST for an instantiated type from a given type declaration. 43 | 44 | This is directed and acyclical dependency graph of modules so you can use any previous layer without bothering about the next step ASTs design. 45 | 46 | Please, consider [Test.ReadDTS.Instantiation]( 47 | https://github.com/purescript-codegen/purescript-read-dts/blob/master/test/ReadDTS/Instantiation.purs) as a form of a short guide for the top layer of this lib. 48 | 49 | ### Testing 50 | 51 | Currently we are runnig only `test/ReadDTS/Instantiation.purs` as a part of main suite. 52 | 53 | ``` 54 | $ spago test 55 | ``` 56 | 57 | ### Credits 58 | 59 | * This library has started as an attempt to fix some bugs in `purescript-readts`. It has diverged into a separate lib and till its full maturation we want to keep it separate and not propose any merges. 60 | 61 | * Initial developement was funded by lambdaterms.com 62 | 63 | ### Useful links 64 | * [Typescript compiler API - using the type checker](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API#using-the-type-checker) 65 | * [purescript-tsd-gen](https://github.com/minoki/purescript-tsd-gen) - Generate DTS from purescript, the reverse of this repository. 66 | * Generate json-schema from your Typescript sources: [typescript-json-schema](https://github.com/YousefED/typescript-json-schema). This is useful to see how the typescript compiler works and which information can be extracted from it. 67 | -------------------------------------------------------------------------------- /bin/print-module-types.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import { main } from '../output/Bin.PrintModuleTypes/index.js'; 4 | 5 | main(); 6 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "easyPSSrc": { 4 | "flake": false, 5 | "locked": { 6 | "lastModified": 1671011575, 7 | "narHash": "sha256-tESal32bcqqdZO+aKnBzc1GoL2mtnaDtj2y7ociCRGA=", 8 | "owner": "justinwoo", 9 | "repo": "easy-purescript-nix", 10 | "rev": "11d3bd58ce6e32703bf69cec04dc7c38eabe14ba", 11 | "type": "github" 12 | }, 13 | "original": { 14 | "owner": "justinwoo", 15 | "repo": "easy-purescript-nix", 16 | "type": "github" 17 | } 18 | }, 19 | "flake-utils": { 20 | "locked": { 21 | "lastModified": 1644229661, 22 | "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=", 23 | "owner": "numtide", 24 | "repo": "flake-utils", 25 | "rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797", 26 | "type": "github" 27 | }, 28 | "original": { 29 | "owner": "numtide", 30 | "repo": "flake-utils", 31 | "type": "github" 32 | } 33 | }, 34 | "flakeUtils": { 35 | "inputs": { 36 | "flake-utils": "flake-utils" 37 | }, 38 | "locked": { 39 | "lastModified": 1657226504, 40 | "narHash": "sha256-GIYNjuq4mJlFgqKsZ+YrgzWm0IpA4axA3MCrdKYj7gs=", 41 | "owner": "gytis-ivaskevicius", 42 | "repo": "flake-utils-plus", 43 | "rev": "2bf0f91643c2e5ae38c1b26893ac2927ac9bd82a", 44 | "type": "github" 45 | }, 46 | "original": { 47 | "owner": "gytis-ivaskevicius", 48 | "repo": "flake-utils-plus", 49 | "type": "github" 50 | } 51 | }, 52 | "nixpkgs": { 53 | "locked": { 54 | "lastModified": 1669809720, 55 | "narHash": "sha256-RMT77f6CPOYtLLQ2esj+EJ1BPVWxf4RDidjrSvA5OhI=", 56 | "owner": "nixos", 57 | "repo": "nixpkgs", 58 | "rev": "227de2b3bbec142f912c09d5e8a1b4e778aa54fb", 59 | "type": "github" 60 | }, 61 | "original": { 62 | "owner": "nixos", 63 | "ref": "nixpkgs-unstable", 64 | "repo": "nixpkgs", 65 | "type": "github" 66 | } 67 | }, 68 | "root": { 69 | "inputs": { 70 | "easyPSSrc": "easyPSSrc", 71 | "flakeUtils": "flakeUtils", 72 | "nixpkgs": "nixpkgs" 73 | } 74 | } 75 | }, 76 | "root": "root", 77 | "version": 7 78 | } 79 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs = { 3 | nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; 4 | flakeUtils.url = "github:gytis-ivaskevicius/flake-utils-plus"; 5 | easyPSSrc = { 6 | flake = false; 7 | url = "github:justinwoo/easy-purescript-nix"; 8 | }; 9 | }; 10 | outputs = { self, nixpkgs, flakeUtils, easyPSSrc }: 11 | flakeUtils.lib.eachSystem ["x86_64-linux"] (system: 12 | let 13 | pkgs = nixpkgs.legacyPackages.${system}; 14 | easyPS = pkgs.callPackage easyPSSrc { inherit pkgs; }; 15 | nodejs-16 = pkgs.writeShellScriptBin "nodejs-16" '' 16 | ${ pkgs.nodejs-16_x.out}/bin/node $@ 17 | ''; 18 | in { 19 | devShell = pkgs.mkShell { 20 | buildInputs = [ 21 | 22 | # Please update spago and purescript in `package.json` `scripts` section 23 | easyPS."purs-0_15_7" 24 | easyPS.purescript-language-server 25 | easyPS.pscid 26 | easyPS.purs-tidy 27 | easyPS.pulp 28 | easyPS.spago 29 | 30 | pkgs.jq 31 | pkgs.docker 32 | pkgs.nodePackages.bower 33 | pkgs.nodePackages.jshint 34 | # pkgs.nodePackages.yarn 35 | # pkgs.nodePackages.nodemon 36 | # pkgs.nodePackages.webpack 37 | # pkgs.nodePackages.webpack-cli 38 | # pkgs.nodePackages.webpack-dev-server 39 | pkgs.dhall 40 | pkgs.nodejs-18_x 41 | nodejs-16 42 | pkgs.pkgconfig 43 | pkgs.postgresql 44 | pkgs.python27 45 | pkgs.python37 46 | pkgs.unzip 47 | pkgs.nixpacks 48 | ]; 49 | shellHook = '' 50 | npm install 51 | NODE_OPTIONS=--experimental-fetch --trace-warnings 52 | export PATH=$PATH:./node_modules/.bin/:./bin 53 | export PS1="\n\[\033[1;32m\][nix develop:\w]\$\[\033[0m\] "; 54 | ''; 55 | }; 56 | } 57 | ); 58 | } 59 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "purescript-read-dts", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "type": "module", 7 | "directories": { 8 | "test": "test" 9 | }, 10 | "bin": { 11 | "print-module-types": "bin/print-module-types.js" 12 | }, 13 | "scripts": { 14 | "build": "tsc && spago build", 15 | "format": "purs-tidy format-in-place src test", 16 | "test": "npm run-script build && spago test", 17 | "run": "npm run-script build && spago run" 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/lambdaterms/purescript-read-dts.git" 22 | }, 23 | "author": "", 24 | "license": "ISC", 25 | "bugs": { 26 | "url": "https://github.com/lambdaterms/purescript-read-dts/issues" 27 | }, 28 | "homepage": "https://github.com/lambdaterms/purescript-read-dts#readme", 29 | "dependencies": { 30 | "@react-three/drei": "^9.68.3", 31 | "@react-three/fiber": "^8.13.0", 32 | "@types/react": "^18.2.6", 33 | "@types/react-dom": "^18.2.4", 34 | "@types/three": "^0.150.2", 35 | "esbuild": "^0.17.19", 36 | "react-bootstrap": "^2.7.0", 37 | "ts-node": "^10.9.1", 38 | "typescript-compiler": "^1.4.1-2", 39 | "typescript-language-server": "^2.2.0" 40 | }, 41 | "devDependencies": { 42 | "@types/node": "^18.11.17", 43 | "typescript": "^4.9.4" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages.dhall: -------------------------------------------------------------------------------- 1 | let mkPackage = 2 | https://raw.githubusercontent.com/purescript/package-sets/psc-0.13.0-20190626/src/mkPackage.dhall 3 | sha256:0b197efa1d397ace6eb46b243ff2d73a3da5638d8d0ac8473e8e4a8fc528cf57 4 | 5 | let upstream = 6 | https://github.com/purescript/package-sets/releases/download/psc-0.15.4-20221201/packages.dhall 7 | sha256:d1a68fa15709eaa686515eb5b9950d82c743f7bf73e3d87a4abe9e1be6fda571 8 | 9 | in upstream 10 | with errors = ../purescript-errors/spago.dhall as Location 11 | -- mkPackage 12 | -- [ "prelude", "either", "maybe", "transformers", "control", "effect" ] 13 | -- "https://github.com/passy/purescript-errors.git" 14 | -- "v4.1.0" 15 | with dodo-printer = 16 | mkPackage 17 | [ "ansi", "foldable-traversable", "lists", "maybe", "strings" ] 18 | "https://github.com/natefaubion/purescript-dodo-printer.git" 19 | "v2.1.0" 20 | with js-object = ../js-object/spago.dhall as Location 21 | with js-unsafe-stringify = 22 | mkPackage 23 | ([] : List Text) 24 | "https://github.com/paluh/purescript-js-unsafe-stringify" 25 | "v0.2.1" 26 | with language-cst-parser = 27 | mkPackage 28 | [ "arrays" 29 | , "const" 30 | , "effect" 31 | , "either" 32 | , "foldable-traversable" 33 | , "free" 34 | , "functors" 35 | , "maybe" 36 | , "numbers" 37 | , "ordered-collections" 38 | , "strings" 39 | , "transformers" 40 | , "tuples" 41 | , "typelevel-prelude" 42 | ] 43 | "https://github.com/natefaubion/purescript-language-cst-parser.git" 44 | "v0.9.1" 45 | with matryoshka = 46 | mkPackage 47 | [ "fixed-points", "free", "prelude", "profunctor", "transformers" ] 48 | "https://github.com/slamdata/purescript-matryoshka.git" 49 | "v1.0.0" 50 | with pprint = 51 | mkPackage 52 | [ "arrays", "strings", "unfoldable" ] 53 | "https://github.com/paf31/purescript-pprint.git" 54 | "v5.0.0" 55 | with tidy-codegen = 56 | mkPackage 57 | [ "aff" 58 | , "ansi" 59 | , "arrays" 60 | , "avar" 61 | , "bifunctors" 62 | , "console" 63 | , "control" 64 | , "dodo-printer" 65 | , "effect" 66 | , "either" 67 | , "enums" 68 | , "exceptions" 69 | , "filterable" 70 | , "foldable-traversable" 71 | , "free" 72 | , "identity" 73 | , "integers" 74 | , "language-cst-parser" 75 | , "lazy" 76 | , "lists" 77 | , "maybe" 78 | , "newtype" 79 | , "node-buffer" 80 | , "node-child-process" 81 | , "node-fs-aff" 82 | , "node-path" 83 | , "node-process" 84 | , "node-streams" 85 | , "ordered-collections" 86 | , "parallel" 87 | , "partial" 88 | , "posix-types" 89 | , "prelude" 90 | , "record" 91 | , "safe-coerce" 92 | , "st" 93 | , "strings" 94 | , "tidy" 95 | , "transformers" 96 | , "tuples" 97 | , "type-equality" 98 | , "unicode" 99 | ] 100 | "https://github.com/natefaubion/purescript-tidy-codegen.git" 101 | "v2.0.0" 102 | with tidy = 103 | mkPackage 104 | [ "arrays" 105 | , "dodo-printer" 106 | , "foldable-traversable" 107 | , "lists" 108 | , "maybe" 109 | , "ordered-collections" 110 | , "partial" 111 | , "prelude" 112 | , "language-cst-parser" 113 | , "strings" 114 | , "tuples" 115 | ] 116 | "https://github.com/natefaubion/purescript-tidy.git" 117 | "v0.7.0" 118 | -------------------------------------------------------------------------------- /spago.dhall: -------------------------------------------------------------------------------- 1 | {- 2 | Welcome to a Spago project! 3 | You can edit this file as you like. 4 | -} 5 | { name = "my-project" 6 | , dependencies = 7 | [ "aff" 8 | , "arrays" 9 | , "bifunctors" 10 | , "console" 11 | , "control" 12 | , "debug" 13 | , "effect" 14 | , "either" 15 | , "errors" 16 | , "exceptions" 17 | , "filterable" 18 | , "fixed-points" 19 | , "foldable-traversable" 20 | , "foreign" 21 | , "foreign-object" 22 | , "free" 23 | , "functions" 24 | , "identity" 25 | , "integers" 26 | , "js-object" 27 | , "language-cst-parser" 28 | , "lists" 29 | , "matryoshka" 30 | , "maybe" 31 | , "monad-loops" 32 | , "newtype" 33 | , "node-buffer" 34 | , "node-fs" 35 | , "node-path" 36 | , "nullable" 37 | , "optparse" 38 | , "ordered-collections" 39 | , "partial" 40 | , "pprint" 41 | , "prelude" 42 | , "prettier-printer" 43 | , "profunctor" 44 | , "profunctor-lenses" 45 | , "psci-support" 46 | , "record" 47 | , "refs" 48 | , "safe-coerce" 49 | , "strings" 50 | , "strings-extra" 51 | , "test-unit" 52 | , "tidy-codegen" 53 | , "transformers" 54 | , "tuples" 55 | , "typelevel-prelude" 56 | , "undefined-is-not-a-problem" 57 | , "unsafe-coerce" 58 | , "unsafe-reference" 59 | ] 60 | , packages = ./packages.dhall 61 | , sources = [ "src/**/*.purs", "test/**/*.purs" ] 62 | } 63 | -------------------------------------------------------------------------------- /src/Effect/Uncurried/Methods.js: -------------------------------------------------------------------------------- 1 | export const unsafeRunEffectMth1 = function unsafeRunEffectMth1(mth, obj, arg1) { 2 | return obj[mth](arg1); 3 | } 4 | 5 | export const unsafeRunEffectMth2 = function unsafeRunEffectMth2(mth, obj, arg1, arg2) { 6 | return obj[mth](arg1, arg2); 7 | } 8 | 9 | export const unsafeRunEffectMth3 = function unsafeRunEffectMth3(mth, obj, arg1, arg2, arg3) { 10 | return obj[mth](arg1, arg2, arg3); 11 | } 12 | 13 | export unsafeRunEffectMth4 = function unsafeRunEffectMth4(mth, obj, arg1, arg2, arg3, arg4) { 14 | return obj[mth](arg1, arg2, arg3, arg4); 15 | } 16 | 17 | export unsafeRunEffectMth5 = function unsafeRunEffectMth5(mth, obj, arg1, arg2, arg3, arg4, arg5) { 18 | return obj[mth](arg1, arg2, arg3, arg4, arg5); 19 | } 20 | return obj[mth](arg1, arg2, arg3, arg4, arg5); 21 | } 22 | 23 | export unsafeRunEffectMth6 = function unsafeRunEffectMth6(mth, obj, arg1, arg2, arg3, arg4, arg5, arg6) { 24 | return obj[mth](arg1, arg2, arg3, arg4, arg5, arg6); 25 | } 26 | 27 | export unsafeRunEffectMth7 = function unsafeRunEffectMth7(mth, obj, arg1, arg2, arg3, arg4, arg5, arg6, arg7) { 28 | return obj[mth](arg1, arg2, arg3, arg4, arg5, arg6, arg7); 29 | } 30 | -------------------------------------------------------------------------------- /src/Effect/Uncurried/Methods.purs: -------------------------------------------------------------------------------- 1 | module Effect.Uncurried.Methods where 2 | 3 | import Data.Symbol (class IsSymbol, reflectSymbol) 4 | import Effect (Effect) 5 | import Effect.Aff.Compat (EffectFn3) 6 | import Effect.Uncurried (EffectFn4, EffectFn5, EffectFn6, EffectFn7, EffectFn8, EffectFn9, runEffectFn3, runEffectFn4, runEffectFn5, runEffectFn6, runEffectFn7, runEffectFn8, runEffectFn9) 7 | import Prim.Row as Row 8 | import Type.Prelude (Proxy) 9 | 10 | foreign import data EffectMth1 :: Type -> Type -> Type 11 | 12 | foreign import unsafeRunEffectMth1 :: forall a1 b obj. EffectFn3 String obj a1 b 13 | 14 | runEffectMth1 :: forall a1 b mth_ mth obj s. IsSymbol s => Row.Cons s (EffectMth1 a1 b) mth_ mth => Proxy s -> obj mth -> a1 -> Effect b 15 | runEffectMth1 m = do 16 | let 17 | m' = reflectSymbol m 18 | runEffectFn3 unsafeRunEffectMth1 m' 19 | 20 | foreign import data EffectMth2 :: Type -> Type -> Type -> Type 21 | 22 | foreign import unsafeRunEffectMth2 :: forall a1 a2 b obj. EffectFn4 String obj a1 a2 b 23 | 24 | runEffectMth2 :: forall a1 a2 b mth_ mth obj s. IsSymbol s => Row.Cons s (EffectMth2 a1 a2 b) mth_ mth => Proxy s -> obj mth -> a1 -> a2 -> Effect b 25 | runEffectMth2 m = do 26 | let 27 | m' = reflectSymbol m 28 | runEffectFn4 unsafeRunEffectMth2 m' 29 | 30 | foreign import data EffectMth3 :: Type -> Type -> Type -> Type -> Type 31 | 32 | foreign import unsafeRunEffectMth3 :: forall a1 a2 a3 b obj. EffectFn5 String obj a1 a2 a3 b 33 | 34 | runEffectMth3 :: forall a1 a2 a3 b mth_ mth obj s. IsSymbol s => Row.Cons s (EffectMth3 a1 a2 a3 b) mth_ mth => Proxy s -> obj mth -> a1 -> a2 -> a3 -> Effect b 35 | runEffectMth3 m = do 36 | let 37 | m' = reflectSymbol m 38 | runEffectFn5 unsafeRunEffectMth3 m' 39 | 40 | foreign import data EffectMth4 :: Type -> Type -> Type -> Type -> Type -> Type 41 | 42 | foreign import unsafeRunEffectMth4 :: forall a1 a2 a3 a4 b obj. EffectFn6 String obj a1 a2 a3 a4 b 43 | 44 | runEffectMth4 :: forall a1 a2 a3 a4 b mth_ mth obj s. IsSymbol s => Row.Cons s (EffectMth4 a1 a2 a3 a4 b) mth_ mth => Proxy s -> obj mth -> a1 -> a2 -> a3 -> a4 -> Effect b 45 | runEffectMth4 m = do 46 | let 47 | m' = reflectSymbol m 48 | runEffectFn6 unsafeRunEffectMth4 m' 49 | 50 | foreign import data EffectMth5 :: Type -> Type -> Type -> Type -> Type -> Type -> Type 51 | 52 | foreign import unsafeRunEffectMth5 :: forall a1 a2 a3 a4 a5 b obj. EffectFn7 String obj a1 a2 a3 a4 a5 b 53 | 54 | runEffectMth5 :: forall a1 a2 a3 a4 a5 b mth_ mth obj s. IsSymbol s => Row.Cons s (EffectMth5 a1 a2 a3 a4 a5 b) mth_ mth => Proxy s -> obj mth -> a1 -> a2 -> a3 -> a4 -> a5 -> Effect b 55 | runEffectMth5 m = do 56 | let 57 | m' = reflectSymbol m 58 | runEffectFn7 unsafeRunEffectMth5 m' 59 | 60 | foreign import data EffectMth6 :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type 61 | 62 | foreign import unsafeRunEffectMth6 :: forall a1 a2 a3 a4 a5 a6 b obj. EffectFn8 String obj a1 a2 a3 a4 a5 a6 b 63 | 64 | runEffectMth6 :: forall a1 a2 a3 a4 a5 a6 b mth_ mth obj s. IsSymbol s => Row.Cons s (EffectMth6 a1 a2 a3 a4 a5 a6 b) mth_ mth => Proxy s -> obj mth -> a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> Effect b 65 | runEffectMth6 m = do 66 | let 67 | m' = reflectSymbol m 68 | runEffectFn8 unsafeRunEffectMth6 m' 69 | 70 | 71 | foreign import data EffectMth7 :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type 72 | 73 | foreign import unsafeRunEffectMth7 :: forall a1 a2 a3 a4 a5 a6 a7 b obj. EffectFn9 String obj a1 a2 a3 a4 a5 a6 a7 b 74 | 75 | runEffectMth7 :: forall a1 a2 a3 a4 a5 a6 a7 b mth_ mth obj s. IsSymbol s => Row.Cons s (EffectMth7 a1 a2 a3 a4 a5 a6 a7 b) mth_ mth => Proxy s -> obj mth -> a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> Effect b 76 | runEffectMth7 m = do 77 | let 78 | m' = reflectSymbol m 79 | runEffectFn9 unsafeRunEffectMth7 m' 80 | -------------------------------------------------------------------------------- /src/Effect/Uncurried/Metohds.js: -------------------------------------------------------------------------------- 1 | exports. 2 | -------------------------------------------------------------------------------- /src/ReadDTS/AST/Printer.purs: -------------------------------------------------------------------------------- 1 | module ReadDTS.AST.Printer where 2 | 3 | -- Quick and really dirty (sorry about that) printer for the AST. 4 | 5 | import Prelude 6 | 7 | import Data.Array (fromFoldable, uncons) as Array 8 | import Data.Foldable (foldMap, foldl, intercalate) 9 | import Data.List (List(..)) as List 10 | import Data.Maybe (Maybe(..)) 11 | import Data.Newtype (unwrap) 12 | import Matryoshka (Algebra, cata) 13 | import ReadDTS (fqnToString) 14 | import ReadDTS.AST (TsType(..)) 15 | import Text.Pretty (Columns(..), Doc, Stack(..), beside, empty, hcat, render, text, width) 16 | import TypeScript.Compiler.Types (FullyQualifiedName) 17 | 18 | joinWithDoc :: Doc -> Array Doc -> Maybe Int -> Doc 19 | joinWithDoc sep elems (Just w) = case Array.uncons elems of 20 | Nothing -> empty 0 0 21 | Just { head, tail } -> doc 22 | where 23 | step { row, rows } curr = 24 | if width row + width sep + width curr > w then { row: curr, rows: List.Cons row rows } 25 | else { row: row `beside` sep `beside` curr, rows } 26 | { row, rows } = foldl step { row: head, rows: List.Nil } tail 27 | doc = unwrap $ foldl (\rows curr -> rows <> Stack (sep `beside` curr)) (Stack row) $ rows 28 | 29 | joinWithDoc sep elems Nothing = 30 | unwrap $ intercalate (Columns sep) (map Columns elems) 31 | 32 | pprintProps name props = objDoc 33 | where 34 | sep = text ": " 35 | sepOpt = text "?: " 36 | step ({ name: n, type: t, optional }) = 37 | Stack $ hcat [ text n, (if optional then sepOpt else sep), t ] 38 | nameCol = Columns $ name -- $ "<" <> fqn <> ">: " 39 | propsCol = 40 | Columns 41 | <<< unwrap 42 | <<< foldMap step 43 | $ props 44 | objDoc = unwrap (nameCol <> Columns (text " ") <> propsCol) 45 | 46 | pprint = render <<< cata alg 47 | where 48 | alg :: Algebra (TsType FullyQualifiedName) Doc 49 | alg TsAny = text "any" 50 | alg (TsApplication fqn arr) = hcat $ [ text $ fqnToString fqn, text "<" ] <> Array.fromFoldable arr <> [ text ">" ] 51 | alg (TsArray t) = hcat [ text "[", t, text "]" ] 52 | alg TsBoolean = text "boolean" 53 | 54 | -- | FIXME: Print constructors 55 | alg (TsClass { bases, constructors, props }) = case bases of 56 | [] -> pprintProps (text "class") props 57 | _ -> do 58 | let 59 | header = hcat $ [ text "class(" ] <> bases <> [ text ")" ] 60 | pprintProps header props 61 | 62 | alg (TsInterface { bases, props }) = case bases of 63 | [] -> pprintProps (text "interface") props 64 | _ -> do 65 | let 66 | header = hcat $ [ text "interface(" ] <> bases <> [ text ")" ] 67 | pprintProps header props 68 | alg (TsFunction parameters returnType) = do 69 | let 70 | arg { name, type: t } = joinWithDoc (text ":") [ text name, t ] (Just 80) 71 | hcat 72 | [ text "function " 73 | , text "(" 74 | , joinWithDoc (text ", ") (map arg parameters) (Just 30) 75 | , text "): " 76 | , returnType 77 | ] 78 | alg (TsIntersection arr) = joinWithDoc (text " & ") arr (Just 80) 79 | alg TsNull = text "null" 80 | alg TsNumber = text "number" 81 | -- FIXME 82 | alg (TsObject props) = pprintProps (text "object") props 83 | -- | length props == 0 = text "{}" 84 | alg TsString = text "string" 85 | alg (TsTuple ts) = 86 | hcat [ text "(", joinWithDoc (text ", ") ts (Just 80), text ")" ] 87 | alg (TsBooleanLiteral b) = text $ "@" <> show b 88 | alg (TsStringLiteral s) = text $ "@" <> show s 89 | alg (TsNumberLiteral n) = text $ "@" <> show n 90 | alg TsUndefined = text "undefined" 91 | alg (TsUnion ts) = joinWithDoc (text " | ") ts (Just 80) 92 | alg (TsMerge ts) = joinWithDoc (text " `merge` ") ts (Just 80) 93 | alg (TsUnknown _) = text "unknown " 94 | alg (TsParametric body params) = text "pprint.FIXME: parametric" 95 | alg (TsParameter _) = text "FIXME: param" 96 | alg (TsTypeRef fqn) = text (fqnToString fqn) 97 | 98 | -- pprintTypeName :: TsType String -> String 99 | -- pprintTypeName TsAny = "any" 100 | -- pprintTypeName (TsArray t) = "[ " <> t <> "]" 101 | -- pprintTypeName (TsBoolean) = "boolean" 102 | -- pprintTypeName (TsFunction r) = "function" 103 | -- pprintTypeName (TsIntersection t1 t2) = "intersection: " <> t1 <> " & " <> t2 104 | -- pprintTypeName TsNull = "null" 105 | -- pprintTypeName Number = "number" 106 | -- pprintTypeName (NumberLiteral n) = "@" <> show n 107 | -- pprintTypeName (Object _ ms) | length ms == 0 = "{}" 108 | -- pprintTypeName (Object fqn _) = "<" <> fqn <> ">" 109 | -- pprintTypeName String = "string" 110 | -- pprintTypeName (Union ts) = String.joinWith " | " ts 111 | -- pprintTypeName (Tuple ts) = "(" <> String.joinWith ", " ts <> ")" 112 | -- pprintTypeName (BooleanLiteral b) = "@" <> show b 113 | -- pprintTypeName (StringLiteral s) = "@" <> s 114 | -- pprintTypeName Undefined = "undefined" 115 | -- pprintTypeName (Unknown s) = "unkown:" <> s 116 | -- pprintTypeName Void = "void" 117 | -------------------------------------------------------------------------------- /src/ReadDTS/Specialization/Pretty.purs: -------------------------------------------------------------------------------- 1 | module ReadDTS.Instantiation.Pretty where 2 | 3 | -- import Prelude 4 | -- 5 | -- import Data.Array (uncons) as Array 6 | -- import Data.Foldable (foldMap, foldl, intercalate, length) 7 | -- import Data.List (List(..)) as List 8 | -- import Data.Map (toUnfoldable) as Map 9 | -- import Data.Maybe (Maybe(..)) 10 | -- import Data.Newtype (unwrap) 11 | -- import Data.String (joinWith) as String 12 | -- import Data.Tuple (Tuple(..)) as Tuple 13 | -- import Matryoshka (Algebra, cata) 14 | -- import ReadDTS.Instantiation (Type, TypeF(..)) 15 | -- import Text.Pretty (Columns(..), Doc, Stack(..), beside, empty, hcat, render, text, width) 16 | -- 17 | -- joinWithDoc ∷ Doc → Array Doc → Maybe Int → Doc 18 | -- joinWithDoc sep elems (Just w) = case Array.uncons elems of 19 | -- Nothing → empty 0 0 20 | -- Just { head, tail } → doc 21 | -- where 22 | -- step { row, rows } curr = if width row + width sep + width curr > w 23 | -- then { row: curr, rows: List.Cons row rows } 24 | -- else { row: row `beside` sep `beside` curr, rows } 25 | -- { row, rows } = foldl step { row: head, rows: List.Nil } tail 26 | -- doc = unwrap $ foldl (\rows curr → rows <> Stack (sep `beside` curr)) (Stack row) $ rows 27 | -- 28 | -- joinWithDoc sep elems Nothing = 29 | -- unwrap $ intercalate (Columns sep) (map Columns elems) 30 | -- 31 | -- pprint ∷ Type → String 32 | -- pprint = render <<< cata alg 33 | -- where 34 | -- alg ∷ Algebra TypeF Doc 35 | -- alg Any = text "any" 36 | -- alg (Array t) = hcat [ text "[", t, text "]" ] 37 | -- alg Boolean = text "boolean" 38 | -- alg (Function { parameters, returnType }) = hcat 39 | -- [ text "function " 40 | -- , joinWithDoc (text ", ") (map (text <<< _.name) parameters) (Just 80) 41 | -- , text ") : " 42 | -- , returnType 43 | -- ] 44 | -- alg (Intersection t1 t2) = hcat [ t1, text " & ", t2 ] 45 | -- alg (Module m) = hcat $ [ text "Module", text m.fullyQualifiedName ] <> m.types 46 | -- alg Null = text "null" 47 | -- alg Number = text "number" 48 | -- alg (Object _ props) | length props == 0 = text "{}" 49 | -- alg (Object fqn props) = objDoc 50 | -- where 51 | -- sep = text ": " 52 | -- sepOpt = text "?: " 53 | -- step (Tuple.Tuple n { type: t, optional }) = 54 | -- Stack $ hcat [ text n, (if optional then sepOpt else sep), t ] 55 | -- nameCol = Columns $ text $ "<" <> fqn <> ">: " 56 | -- propsCol 57 | -- = Columns 58 | -- <<< unwrap 59 | -- <<< foldMap step 60 | -- $ (Map.toUnfoldable props ∷ Array _) 61 | -- objDoc = unwrap $ nameCol <> propsCol 62 | -- alg String = text "string" 63 | -- alg (Tuple ts) = 64 | -- hcat [ text "(", joinWithDoc (text ", ") ts (Just 80), text ")" ] 65 | -- alg (BooleanLiteral b) = text $ "@" <> show b 66 | -- alg (StringLiteral s) = text $ "@" <> show s 67 | -- alg (NumberLiteral n) = text $ "@" <> show n 68 | -- alg Undefined = text "undefined" 69 | -- alg (Union ts) = joinWithDoc (text " | ") ts (Just 80) 70 | -- alg (Unknown s) = text $ "unknown: " <> s <> "" 71 | -- alg Void = text "void" 72 | -- 73 | -- pprintTypeName ∷ TypeF String → String 74 | -- pprintTypeName Any = "any" 75 | -- pprintTypeName (Array t) = "[ " <> t <> "]" 76 | -- pprintTypeName (Boolean) = "boolean" 77 | -- pprintTypeName (Function r) = "function" 78 | -- pprintTypeName (Intersection t1 t2) = "intersection: " <> t1 <> " & " <> t2 79 | -- pprintTypeName (Module m) = "module" <> m.fullyQualifiedName 80 | -- pprintTypeName Null = "null" 81 | -- pprintTypeName Number = "number" 82 | -- pprintTypeName (NumberLiteral n) = "@" <> show n 83 | -- pprintTypeName (Object _ ms) | length ms == 0 = "{}" 84 | -- pprintTypeName (Object fqn _) = "<" <> fqn <> ">" 85 | -- pprintTypeName String = "string" 86 | -- pprintTypeName (Union ts) = String.joinWith " | " ts 87 | -- pprintTypeName (Tuple ts) = "(" <> String.joinWith ", " ts <> ")" 88 | -- pprintTypeName (BooleanLiteral b) = "@" <> show b 89 | -- pprintTypeName (StringLiteral s) = "@" <> s 90 | -- pprintTypeName Undefined = "undefined" 91 | -- pprintTypeName (Unknown s) = "unkown:" <> s 92 | -- pprintTypeName Void = "void" 93 | -- 94 | -------------------------------------------------------------------------------- /src/ReadDTS/TypeScript.js: -------------------------------------------------------------------------------- 1 | import ts from "typescript"; 2 | export function isNodeExportedImpl(checker, node) { 3 | let sym = checker.getSymbolAtLocation(node); 4 | return (sym ? ((sym.valueDeclaration && ts.getCombinedModifierFlags(sym.valueDeclaration) & ts.ModifierFlags.Export) !== 0) : false || 5 | (!!node.parent && node.parent.kind === ts.SyntaxKind.SourceFile && node.kind !== ts.SyntaxKind.EndOfFileToken)); 6 | } 7 | ; 8 | export const toDeclarationStatementImpl = (n) => { 9 | return n; 10 | }; 11 | //# sourceMappingURL=TypeScript.js.map -------------------------------------------------------------------------------- /src/ReadDTS/TypeScript.purs: -------------------------------------------------------------------------------- 1 | module ReadDTS.TypeScript where 2 | 3 | import Prelude 4 | 5 | import Control.Alt ((<|>)) 6 | import Data.Function.Uncurried (Fn2, runFn2) 7 | import Data.Maybe (Maybe, fromJust) 8 | import Data.Undefined.NoProblem (toMaybe) as NoProblem 9 | import Debug (traceM) 10 | import Partial.Unsafe (unsafePartial) 11 | import Prim.Row (class Cons, class Union) as Row 12 | import TypeScript.Compiler.Checker (getFullyQualifiedName, getSymbolAtLocation) 13 | import TypeScript.Compiler.Factory.NodeTests (asClassDeclaration, asFunctionDeclaration, asInterfaceDeclaration, asTypeAliasDeclaration) 14 | import TypeScript.Compiler.Factory.NodeTests as Nodes 15 | import TypeScript.Compiler.Types (FullyQualifiedName, Node, TypeChecker) 16 | import TypeScript.Compiler.Types.Nodes (DeclarationStatement, interface) as Nodes 17 | import TypeScript.Compiler.Types.Symbol (getName) as Symbol 18 | import TypeScript.Debug (formatTypeFlags') 19 | 20 | isNodeExported :: forall l k. TypeChecker -> Node l k -> Boolean 21 | isNodeExported = runFn2 isNodeExportedImpl 22 | 23 | foreign import isNodeExportedImpl :: forall l k. Fn2 TypeChecker (Node l k) Boolean 24 | 25 | toDeclarationStatement 26 | :: forall i tag tagRow tagRow_ 27 | . Row.Cons tag Void () tagRow 28 | => Row.Union 29 | tagRow 30 | tagRow_ 31 | ( "ClassDeclaration" :: Void 32 | , "ClassLikeDeclaration" :: Void 33 | , "FunctionDeclaration" :: Void 34 | , "InterfaceDeclaration" :: Void 35 | , "TypeAliasDeclaration" :: Void 36 | ) 37 | => Node tag i 38 | -> Nodes.DeclarationStatement 39 | toDeclarationStatement = toDeclarationStatementImpl 40 | 41 | -- | FIXME: don't export 42 | foreign import toDeclarationStatementImpl :: forall l r. Node l r -> Nodes.DeclarationStatement 43 | 44 | 45 | -- These are all declaration statements but `VariableStatement`/`VariableDeclaration` is something else... 46 | -- export interface ExportAssignment extends DeclarationStatement, JSDocContainer { 47 | -- export interface FunctionDeclaration extends FunctionLikeDeclarationBase, DeclarationStatement, LocalsContainer { 48 | -- export interface MissingDeclaration extends DeclarationStatement { 49 | -- export interface ClassDeclaration extends ClassLikeDeclarationBase, DeclarationStatement { 50 | -- export interface InterfaceDeclaration extends DeclarationStatement, JSDocContainer { 51 | -- export interface TypeAliasDeclaration extends DeclarationStatement, JSDocContainer, LocalsContainer { 52 | -- export interface EnumDeclaration extends DeclarationStatement, JSDocContainer { 53 | -- export interface ModuleDeclaration extends DeclarationStatement, JSDocContainer, LocalsContainer { 54 | -- export interface ImportEqualsDeclaration extends DeclarationStatement, JSDocContainer { 55 | -- export interface NamespaceExportDeclaration extends DeclarationStatement, JSDocContainer { 56 | -- export interface ExportDeclaration extends DeclarationStatement, JSDocContainer { 57 | -- export interface ExportAssignment extends DeclarationStatement, JSDocContainer { 58 | 59 | asDeclarationStatement :: forall l r. Node l r -> Maybe Nodes.DeclarationStatement 60 | asDeclarationStatement node = 61 | (toDeclarationStatement <$> asTypeAliasDeclaration node) 62 | <|> (toDeclarationStatement <$> asInterfaceDeclaration node) 63 | <|> (toDeclarationStatement <$> asClassDeclaration node) 64 | <|> (toDeclarationStatement <$> asFunctionDeclaration node) 65 | 66 | getDeclarationStatementFqn :: TypeChecker -> Nodes.DeclarationStatement -> Maybe FullyQualifiedName 67 | getDeclarationStatementFqn checker node = do 68 | symbol <- 69 | (getSymbolAtLocation checker <<< _.name <<< Nodes.interface =<< asTypeAliasDeclaration node) 70 | <|> (getSymbolAtLocation checker =<< asInterfaceDeclaration node) 71 | <|> (getSymbolAtLocation checker <<< _.name <<< Nodes.interface =<< asInterfaceDeclaration node) 72 | <|> (getSymbolAtLocation checker =<< asClassDeclaration node) 73 | <|> (getSymbolAtLocation checker =<< NoProblem.toMaybe <<< _.name <<< Nodes.interface =<< asClassDeclaration node) 74 | <|> (getSymbolAtLocation checker =<< asFunctionDeclaration node) 75 | -- FIXME: debugging 76 | <|> (getSymbolAtLocation checker node) 77 | pure $ getFullyQualifiedName checker symbol 78 | 79 | -------------------------------------------------------------------------------- /src/ReadDTS/TypeScript.ts: -------------------------------------------------------------------------------- 1 | import ts from "typescript"; 2 | 3 | export function isNodeExportedImpl(checker:ts.TypeChecker, node: ts.Node): boolean { 4 | let sym = checker.getSymbolAtLocation(node); 5 | return ( 6 | sym? ((sym.valueDeclaration && ts.getCombinedModifierFlags(sym.valueDeclaration) & ts.ModifierFlags.Export) !== 0):false || 7 | (!!node.parent && node.parent.kind === ts.SyntaxKind.SourceFile && node.kind !== ts.SyntaxKind.EndOfFileToken) 8 | ) 9 | }; 10 | 11 | export const toDeclarationStatementImpl = (n: ts.ClassDeclaration | ts.InterfaceDeclaration | ts.TypeAliasDeclaration): ts.DeclarationStatement => { 12 | return n; 13 | } 14 | -------------------------------------------------------------------------------- /src/TS/Codegen/PS.purs: -------------------------------------------------------------------------------- 1 | module TS.Codegen.PS where 2 | 3 | import Prelude 4 | 5 | import Control.Alt (alt, (<|>)) 6 | import Control.Apply (lift2) 7 | import Control.Lazy (defer) 8 | import Control.Monad.Error.Class (class MonadThrow, class MonadError, catchError, throwError) 9 | import Control.Monad.Free (Free, runFree) 10 | import Control.Monad.Reader (ReaderT(..), ask, mapReader, withReader) 11 | import Control.Monad.Reader.Trans (mapReaderT, withReaderT) 12 | import Control.Monad.State (StateT(..), State, gets, modify_, put, runStateT, state) 13 | import Control.Monad.Trans.Class (class MonadTrans, lift) 14 | import Control.Monad.Reader.Class (class MonadAsk, class MonadReader, ask, asks, local) 15 | import Data.Foldable (for_) 16 | import Data.Functor.Mu (Mu) 17 | import Data.Identity (Identity(..)) 18 | import Data.List (List(..)) as List 19 | import Data.Map (Map) 20 | import Data.Map (empty, fromFoldable, insert, lookup) as Map 21 | import Data.Maybe (Maybe(..)) 22 | import Data.Newtype (class Newtype) 23 | import Data.Set (empty) as Set 24 | import Data.Tuple.Nested ((/\)) 25 | import Partial.Unsafe (unsafePartial) 26 | import PureScript.CST.Types as CST 27 | import ReadDTS.AST (TsType, TypeRepr(..), RootDeclarations) as TS 28 | import ReadDTS.AST (TypeRepr(..)) 29 | import Safe.Coerce (coerce) as Safe 30 | import TS.Codegen.PS.ModulePath (ModulePath(..)) 31 | import TS.Codegen.PS.Types (Fqn(..)) 32 | import Tidy.Codegen (typeApp, typeCtor, typeVar) as TC 33 | import Tidy.Codegen.Class (class ToName) as TC 34 | import Tidy.Codegen.Monad (Codegen, CodegenState, CodegenT(..)) as TC 35 | import Tidy.Codegen.Monad (CodegenState, Codegen) 36 | import TypeScript.Compiler.Types (FullyQualifiedName(..)) 37 | import TypeScript.Compiler.Types (FullyQualifiedName(..)) as TS 38 | import TypeScript.Compiler.Types (Program) as TSC 39 | 40 | type Modules e = Map ModulePath (TC.CodegenState e) 41 | 42 | type PackageCodegenState e = 43 | { modules :: Modules e 44 | , types :: Map TS.FullyQualifiedName Fqn 45 | } 46 | 47 | -- | Let's start simple: 48 | -- | * basic composition of codegen handlers 49 | -- | * some ts -> ps mapping is probably not best and flexible approach... 50 | newtype TypeReprCodegen e m = TypeReprCodegen (TS.FullyQualifiedName -> TS.TypeRepr -> PackageCodegenT e m (Maybe Fqn)) 51 | 52 | derive instance Newtype (TypeReprCodegen e m) _ 53 | instance Monad m => Semigroup (TypeReprCodegen e m) where 54 | append (TypeReprCodegen c1) (TypeReprCodegen c2) = TypeReprCodegen \tsFqn repr -> 55 | c1 tsFqn repr >>= case _ of 56 | Just psFqn -> pure $ Just psFqn 57 | Nothing -> c2 tsFqn repr 58 | 59 | instance Monad m => Monoid (TypeReprCodegen e m) where 60 | mempty = TypeReprCodegen $ const $ const $ pure Nothing 61 | 62 | newtype PackageCodegenT e m a = PackageCodegenT (ReaderT TS.RootDeclarations (StateT (PackageCodegenState e) m) a) 63 | 64 | derive newtype instance Functor m => Functor (PackageCodegenT e m) 65 | derive newtype instance Monad m => Apply (PackageCodegenT e m) 66 | derive newtype instance Monad m => Applicative (PackageCodegenT e m) 67 | derive newtype instance Monad m => Bind (PackageCodegenT e m) 68 | derive newtype instance Monad m => Monad (PackageCodegenT e m) 69 | derive newtype instance Monad m => MonadReader TS.RootDeclarations (PackageCodegenT e m) 70 | derive newtype instance Monad m => MonadAsk TS.RootDeclarations (PackageCodegenT e m) 71 | instance MonadTrans (PackageCodegenT e) where 72 | lift m = PackageCodegenT $ lift $ lift $ m 73 | 74 | instance MonadThrow e m => MonadThrow e (PackageCodegenT s m) where 75 | throwError e = lift (throwError e) 76 | 77 | instance MonadError e m => MonadError e (PackageCodegenT e m) where 78 | catchError (PackageCodegenT m) h = PackageCodegenT $ 79 | catchError m (\e -> case h e of PackageCodegenT s -> s) 80 | 81 | type PackageCodegen e = PackageCodegenT e (Free Identity) 82 | 83 | emptyModuleCodegenState :: forall e. TC.CodegenState e 84 | emptyModuleCodegenState = 85 | { exports: Set.empty 86 | , importsOpen: Set.empty 87 | , importsFrom: Map.empty 88 | , importsQualified: Map.empty 89 | , declarations: List.Nil 90 | } 91 | 92 | 93 | withModule :: forall a e. ModulePath -> TC.Codegen e a -> PackageCodegen e a 94 | withModule mp (TC.CodegenT c) = PackageCodegenT $ state \st@{ modules } -> do 95 | let 96 | cs = case Map.lookup mp modules of 97 | Just s -> s 98 | Nothing -> emptyModuleCodegenState 99 | a /\ cs' = runFree Safe.coerce <<< runStateT c $ cs 100 | modules' = Map.insert mp cs' modules 101 | a /\ st { modules = modules' } 102 | 103 | eff :: forall e. CST.Type e -> CST.Type e 104 | eff a = unsafePartial $ TC.typeApp (TC.typeCtor "Effect.Effect") [ a ] 105 | 106 | eff' :: forall e n. TC.ToName n CST.Ident => n -> CST.Type e 107 | eff' a = eff (TC.typeVar a) 108 | 109 | lookupPSType :: forall e m. Monad m => TS.FullyQualifiedName -> PackageCodegenT e m (Maybe Fqn) 110 | lookupPSType tsFqn = PackageCodegenT $ gets (_.types >>> Map.lookup tsFqn) 111 | 112 | lookupTsDecl :: forall e m. Monad m => TS.FullyQualifiedName -> PackageCodegenT e m (Maybe TS.TypeRepr) 113 | lookupTsDecl tsFqn = PackageCodegenT $ asks (Map.lookup tsFqn) 114 | 115 | codegen :: forall e m. MonadError String m => Monad m => Array TS.FullyQualifiedName -> TypeReprCodegen e m -> PackageCodegenT e m Unit 116 | codegen genNames (TypeReprCodegen typeReprCodegen) = do 117 | for_ genNames \fqn -> do 118 | asks (Map.lookup fqn) >>= case _ of 119 | Just t -> void $ typeReprCodegen fqn t 120 | Nothing -> throwError $ "Missing FQN:" <> show fqn 121 | 122 | -- type Prop t = 123 | -- { name :: String 124 | -- , type :: t 125 | -- , optional :: Boolean 126 | -- } 127 | 128 | -- tsClass fqn { bases, constructors, props } = do 129 | -- withModule (ModulePath "Types.purs") \tps -> do 130 | -- for props case _ of 131 | -- TsFunction args ret -> do 132 | -- 133 | -- _ -> traceM $ "Skipping non method during codegen of " <> show fqn 134 | -- 135 | -- -- type Opts = 136 | -- -- { foreignDeclarationModule :: Maybe 137 | -- -- , classModule :: Nothing 138 | -- -- } 139 | -- 140 | -- -- tsClass :: TS.FullyQualifiedName -> _ -> _ 141 | -- -- tsClass = unsafePartial $ codegenModule "Data.Maybe" do 142 | -- -- 143 | -- -- tsClass :: Module Void 144 | -- -- tsClass = unsafePartial $ codegenModule "Data.Maybe" do 145 | -- -- importOpen "Prelude" 146 | -- -- tell 147 | -- -- [ declData "Maybe" [ typeVar "a" ] 148 | -- -- [ dataCtor "Nothing" [] 149 | -- -- , dataCtor "Just" [ typeVar "a" ] 150 | -- -- ] 151 | -- -- 152 | -- -- , declDerive Nothing [] 153 | -- -- (typeApp "Functor" [ typeCtor "Maybe" ]) 154 | -- -- 155 | -- -- , declSignature "maybe" do 156 | -- -- typeForall [ typeVar "a", typeVar "b" ] do 157 | -- -- typeArrow 158 | -- -- [ typeVar "b" 159 | -- -- , typeArrow [ typeVar "a" ] (typeVar "b") 160 | -- -- , typeApp (typeCtor "Maybe") [ typeVar "a" ] 161 | -- -- ] 162 | -- -- (typeVar "b") 163 | -- -- , declValue "maybe" [ binderVar "nothing", binderVar "just" ] do 164 | -- -- exprCase [ exprSection ] 165 | -- -- [ caseBranch [ binderCtor "Just" [ bindarVar "a" ] ] do 166 | -- -- exprApp (exprIdent "just") [ exprIdent "a" ] 167 | -- -- , caseBranch [ binderCtor "Nothing" [] ] do 168 | -- -- exprIdent "nothing" 169 | -- -- ] 170 | -- -- ] 171 | -------------------------------------------------------------------------------- /src/TS/Codegen/PS/ModulePath.purs: -------------------------------------------------------------------------------- 1 | module TS.Codegen.PS.ModulePath where 2 | 3 | import Prelude 4 | 5 | import Data.Foldable (intercalate) 6 | import Data.Generic.Rep (class Generic) 7 | import Data.List (List(..), fromFoldable, singleton) as List 8 | import Data.List (List) 9 | import Data.Newtype (class Newtype) 10 | import Data.Show.Generic (genericShow) 11 | import Data.String (Pattern(..), split) as String 12 | import Data.String.Extra (upperCaseFirst) 13 | import Node.Path (FilePath) 14 | import Node.Path (sep) as Path 15 | import PureScript.CST.Types (ModuleName(..)) 16 | 17 | newtype ModulePath = ModulePath (List String) 18 | 19 | derive instance Newtype ModulePath _ 20 | derive newtype instance Eq ModulePath 21 | derive newtype instance Ord ModulePath 22 | derive instance Generic ModulePath _ 23 | instance Show ModulePath where 24 | show = genericShow 25 | 26 | consDir :: String -> ModulePath -> ModulePath 27 | consDir n (ModulePath mp) = ModulePath $ List.Cons n mp 28 | 29 | segments :: ModulePath -> List String 30 | segments (ModulePath p) = p 31 | 32 | empty :: ModulePath 33 | empty = ModulePath mempty 34 | 35 | fromString :: String -> ModulePath 36 | fromString = ModulePath <<< List.singleton 37 | 38 | toModuleName :: ModulePath -> ModuleName 39 | toModuleName (ModulePath mp) = ModuleName $ intercalate "." mp 40 | 41 | fromPath :: FilePath -> ModulePath 42 | fromPath = ModulePath <<< List.fromFoldable <<< map upperCaseFirst <<< String.split (String.Pattern Path.sep) 43 | -------------------------------------------------------------------------------- /src/TS/Codegen/PS/Types.purs: -------------------------------------------------------------------------------- 1 | module TS.Codegen.PS.Types where 2 | 3 | import Prelude 4 | 5 | import Data.Array.NonEmpty (toArray) as NonEmtpy 6 | import Data.Generic.Rep (class Generic) 7 | import Data.Maybe (Maybe(..)) 8 | import Data.Show.Generic (genericShow) 9 | import Data.String.Regex (match) as Regex 10 | import Data.String.Regex.Unsafe (unsafeRegex) 11 | import Debug (traceM) 12 | import TS.Codegen.PS.ModulePath (ModulePath) 13 | import TS.Codegen.PS.ModulePath (fromPath) as ModulePath 14 | import Tidy.Codegen.Types (SymbolName(..)) 15 | import TypeScript.Compiler.Types (FullyQualifiedName(..)) 16 | 17 | data Fqn = Fqn ModulePath SymbolName 18 | 19 | derive instance Eq Fqn 20 | derive instance Ord Fqn 21 | derive instance Generic Fqn _ 22 | instance Show Fqn where 23 | show (Fqn mp (SymbolName n)) = "(Fqn " <> show mp <> " (SymbolName " <> n <> "))" 24 | 25 | -- | Ts compiler gives quite limited access to the fqn structure. 26 | -- | https://stackoverflow.com/questions/67702391/typescript-compiler-api-how-to-get-fully-qualified-name-of-type-without-absolut#comment119681802_67702391 27 | -- | Let's use what we have at the moment. 28 | fromTsFqn :: FullyQualifiedName -> Maybe Fqn 29 | fromTsFqn (FullyQualifiedName s) = do 30 | let 31 | regex = unsafeRegex """^"(.*)"\.(.*)$""" mempty 32 | 33 | matches <- Regex.match regex s 34 | case NonEmtpy.toArray matches of 35 | [ Just _, Just path, Just symbol ] -> do 36 | pure $ Fqn (ModulePath.fromPath path) (SymbolName symbol) 37 | r -> do 38 | traceM r 39 | Nothing 40 | -------------------------------------------------------------------------------- /src/TypeScript/Class/Compiler/Program.purs: -------------------------------------------------------------------------------- 1 | module TypeScript.Class.Compiler.Program where 2 | 3 | import Prelude 4 | 5 | import Data.Maybe (Maybe) 6 | import Effect.Class (class MonadEffect, liftEffect) 7 | import TypeScript.Compiler.Program (createCompilerHost, createProgram) as Program 8 | import TypeScript.Compiler.Types (CompilerHost, CompilerOptions, Program) 9 | 10 | createCompilerHost :: forall m. MonadEffect m => CompilerOptions -> m CompilerHost 11 | createCompilerHost = liftEffect <<< Program.createCompilerHost 12 | 13 | createProgram :: forall m. MonadEffect m => Array String -> CompilerOptions -> Maybe CompilerHost -> m Program 14 | createProgram rootNames opts = liftEffect <<< Program.createProgram rootNames opts 15 | 16 | -- emit :: forall m. MonadEffect m => Program -> m Unit 17 | -- emit 18 | -- 19 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Checker.js: -------------------------------------------------------------------------------- 1 | export const typeToStringImpl = (checker, type) => checker.typeToString(type); 2 | export const getSymbolAtLocationImpl = (checker, node) => checker.getSymbolAtLocation(node) || null; 3 | export const getTypeAtLocationImpl = (checker, node) => checker.getTypeAtLocation(node) || null; 4 | export const getTypeOfSymbolAtLocationImpl = (checker, symbol, node) => checker.getTypeOfSymbolAtLocation(symbol, node); 5 | export const getFullyQualifiedNameImpl = (checker, symbol) => checker.getFullyQualifiedName(symbol); 6 | export const getTypeArgumentsImpl = (checker, type) => checker.getTypeArguments(type); 7 | export const getSignaturesOfTypeImpl = (checker, type, kind) => checker.getSignaturesOfType(type, kind); 8 | export const getExportSymbolOfSymbolImpl = (checker, symbol) => checker.getExportSymbolOfSymbol(symbol); 9 | export const getExportsOfModuleImpl = (checker, symbol) => checker.getExportsOfModule(symbol); 10 | export const getExportsAndPropertiesOfModuleImpl = (checker, symbol) => checker.getExportsAndPropertiesOfModule(symbol); 11 | 12 | // export const getPropertiesOfTypeImpl = (checker, type) => checker.getPropertiesOfType(type); 13 | //# sourceMappingURL=Checker.js.map 14 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Checker.purs: -------------------------------------------------------------------------------- 1 | module TypeScript.Compiler.Checker where 2 | 3 | import Prelude 4 | 5 | import Data.Function.Uncurried (Fn2, Fn3, runFn2, runFn3) 6 | import Data.Maybe (Maybe) 7 | import Data.Nullable (Nullable, toMaybe) 8 | import TypeScript.Compiler.Types (FullyQualifiedName(..), Node, Signature, SignatureKind, Symbol_, Typ, TypeChecker) 9 | import TypeScript.Compiler.Types.Typs (TypeReference) 10 | 11 | typeToString :: forall r. TypeChecker -> Typ r -> String 12 | typeToString = runFn2 typeToStringImpl 13 | 14 | foreign import typeToStringImpl :: forall r. Fn2 TypeChecker (Typ r) String 15 | 16 | foreign import data ModuleSymbol :: Type 17 | 18 | foreign import getExportsOfModuleImpl :: Fn2 TypeChecker Symbol_ (Array Symbol_) 19 | 20 | getExportsOfModule :: TypeChecker -> Symbol_ -> Array Symbol_ 21 | getExportsOfModule c = runFn2 getExportsOfModuleImpl c 22 | 23 | foreign import getExportsAndPropertiesOfModuleImpl :: Fn2 TypeChecker Symbol_ (Array Symbol_) 24 | 25 | getExportsAndPropertiesOfModule :: TypeChecker -> Symbol_ -> Array Symbol_ 26 | getExportsAndPropertiesOfModule c = runFn2 getExportsAndPropertiesOfModuleImpl c 27 | 28 | getSymbolAtLocation :: forall l r. TypeChecker -> Node l r -> Maybe Symbol_ 29 | getSymbolAtLocation c = toMaybe <<< runFn2 getSymbolAtLocationImpl c 30 | 31 | foreign import getSymbolAtLocationImpl :: forall l r. Fn2 TypeChecker (Node l r) (Nullable Symbol_) 32 | 33 | getTypeAtLocation :: forall l r. TypeChecker -> Node l r -> Maybe (Typ ()) 34 | getTypeAtLocation c = toMaybe <<< runFn2 getTypeAtLocationImpl c 35 | 36 | foreign import getTypeAtLocationImpl :: forall l r. Fn2 TypeChecker (Node l r) (Nullable (Typ ())) 37 | 38 | getTypeOfSymbolAtLocation :: forall l r. TypeChecker -> Symbol_ -> Node l r -> Maybe (Typ ()) 39 | getTypeOfSymbolAtLocation c s = toMaybe <<< runFn3 getTypeOfSymbolAtLocationImpl c s 40 | 41 | foreign import getTypeOfSymbolAtLocationImpl :: forall l r. Fn3 TypeChecker Symbol_ (Node l r) (Nullable (Typ ())) 42 | 43 | getFullyQualifiedName :: TypeChecker -> Symbol_ -> FullyQualifiedName 44 | getFullyQualifiedName c = FullyQualifiedName <<< runFn2 getFullyQualifiedNameImpl c 45 | 46 | foreign import getFullyQualifiedNameImpl :: Fn2 TypeChecker Symbol_ String 47 | 48 | getExportedFullyQualifiedName :: TypeChecker -> Symbol_ -> FullyQualifiedName 49 | getExportedFullyQualifiedName c s = do 50 | let 51 | s' = getExportSymbolOfSymbol c s 52 | getFullyQualifiedName c s' 53 | 54 | -- You should rather use getExportedSymbol' because the original API is non obvious: 55 | -- 56 | -- Original docs: 57 | -- 58 | -- If a symbol is a local symbol with an associated exported symbol, returns the exported symbol. 59 | -- Otherwise returns its input. 60 | -- For example, at `export type T = number;`: 61 | -- - `getSymbolAtLocation` at the location `T` will return the exported symbol for `T`. 62 | -- - But the result of `getSymbolsInScope` will contain the *local* symbol for `T`, not the exported symbol. 63 | -- - Calling `getExportSymbolOfSymbol` on that local symbol will return the exported symbol. 64 | getExportSymbolOfSymbol :: TypeChecker -> Symbol_ -> Symbol_ 65 | getExportSymbolOfSymbol c = runFn2 getExportSymbolOfSymbolImpl c 66 | 67 | foreign import getExportSymbolOfSymbolImpl :: Fn2 TypeChecker Symbol_ Symbol_ 68 | 69 | getTypeArguments :: TypeChecker -> TypeReference -> Array (Typ ()) 70 | getTypeArguments = runFn2 getTypeArgumentsImpl 71 | 72 | foreign import getTypeArgumentsImpl :: Fn2 TypeChecker TypeReference (Array (Typ ())) 73 | 74 | getSignaturesOfType :: forall i. TypeChecker -> Typ i -> SignatureKind -> Array Signature 75 | getSignaturesOfType = runFn3 getSignaturesOfTypeImpl 76 | 77 | foreign import getSignaturesOfTypeImpl :: forall i. Fn3 TypeChecker (Typ i) SignatureKind (Array Signature) 78 | 79 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Checker.ts: -------------------------------------------------------------------------------- 1 | import ts from "typescript"; 2 | 3 | export const getExportsOfModule = (checker: ts.TypeChecker, moduleSymbol: ts.Symbol): ts.Symbol[] => { 4 | return checker.getExportsOfModule(moduleSymbol); 5 | } 6 | 7 | export const typeToStringImpl = (checker: ts.TypeChecker, type: ts.Type): string => checker.typeToString(type) 8 | 9 | export const getSymbolAtLocationImpl = (checker: ts.TypeChecker, node: ts.Node): ts.Symbol | null => checker.getSymbolAtLocation(node) || null; 10 | 11 | export const getTypeAtLocationImpl = (checker: ts.TypeChecker, node: ts.Node): ts.Type | null => checker.getTypeAtLocation(node) || null; 12 | 13 | export const getTypeOfSymbolAtLocationImpl = (checker: ts.TypeChecker, symbol: ts.Symbol, node: ts.Node): ts.Type | null => checker.getTypeOfSymbolAtLocation(symbol, node); 14 | 15 | export const getFullyQualifiedNameImpl = (checker: ts.TypeChecker, symbol: ts.Symbol): string => checker.getFullyQualifiedName(symbol); 16 | 17 | export const getTypeArgumentsImpl = (checker: ts.TypeChecker, type: ts.TypeReference): readonly ts.Type[] => checker.getTypeArguments(type); 18 | 19 | export const getSignaturesOfTypeImpl = (checker: ts.TypeChecker, type: ts.Type, kind: ts.SignatureKind): readonly ts.Signature[] => checker.getSignaturesOfType(type, kind); 20 | 21 | export const getExportSymbolOfSymbolImpl = (checker: ts.TypeChecker, symbol: ts.Symbol): ts.Symbol => checker.getExportSymbolOfSymbol(symbol); 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Checker/Internal.js: -------------------------------------------------------------------------------- 1 | ; 2 | export const getElementTypeOfArrayTypeImpl = (checker, type) => checker.getElementTypeOfArrayType(type) || null; 3 | export const isAnyTypeImpl = (checker, type) => checker.getAnyType() == type; 4 | export const isArrayTypeImpl = (checker, type) => checker.isArrayType(type); 5 | export const isBooleanTypeImpl = (checker, type) => checker.getBooleanType() == type; 6 | export const isNullTypeImpl = (checker, type) => checker.getNullType() == type; 7 | export const isNumberTypeImpl = (checker, type) => checker.getNumberType() == type; 8 | export const isReadonlyArrayTypeImpl = (checker, type) => checker.isReadonlyArrayType(type); 9 | export const isStringTypeImpl = (checker, type) => checker.getStringType() == type; 10 | export const isTupleTypeImpl = (checker, type) => checker.isTupleType(type); 11 | export const isUndefinedTypeImpl = (checker, type) => checker.getUndefinedType() == type; 12 | export const getTypeOfPropertyOfTypeImpl = (checker, type, propertyName) => checker.getTypeOfPropertyOfType(type, propertyName) || null; 13 | //# sourceMappingURL=Internal.js.map -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Checker/Internal.purs: -------------------------------------------------------------------------------- 1 | module TypeScript.Compiler.Checker.Internal where 2 | 3 | import Prelude 4 | 5 | import Data.Function.Uncurried (Fn2, Fn3, runFn2, runFn3) 6 | import Data.Maybe (Maybe) 7 | import Data.Nullable (Nullable, toMaybe) 8 | import TypeScript.Compiler.Types (Typ, TypeChecker) 9 | 10 | isAnyType ∷ forall i. TypeChecker -> Typ i -> Boolean 11 | isAnyType = runFn2 isAnyTypeImpl 12 | 13 | foreign import isAnyTypeImpl :: forall i. Fn2 TypeChecker (Typ i) Boolean 14 | 15 | isArrayType ∷ forall i. TypeChecker -> Typ i -> Boolean 16 | isArrayType = runFn2 isArrayTypeImpl 17 | 18 | foreign import isArrayTypeImpl :: forall i. Fn2 TypeChecker (Typ i) Boolean 19 | 20 | -- | We need to expose some extra (internal!) pieces of the type checker 21 | -- | to easily process some builtin types etc. 22 | getElementTypeOfArrayType ∷ forall i. TypeChecker -> Typ i -> Maybe (Typ ()) 23 | getElementTypeOfArrayType c = toMaybe <<< runFn2 getElementTypeOfArrayTypeImpl c 24 | 25 | foreign import getElementTypeOfArrayTypeImpl :: forall i. Fn2 TypeChecker (Typ i) (Nullable (Typ ())) 26 | 27 | isBooleanType :: TypeChecker -> Typ () -> Boolean 28 | isBooleanType = runFn2 isBooleanTypeImpl 29 | 30 | foreign import isBooleanTypeImpl :: Fn2 TypeChecker (Typ ()) Boolean 31 | 32 | -- | For these singletons we can enforce base `Typ ()` restriction. 33 | isNullType :: forall i. TypeChecker -> Typ i -> Boolean 34 | isNullType = runFn2 isNullTypeImpl 35 | 36 | foreign import isNullTypeImpl :: forall i. Fn2 TypeChecker (Typ i) Boolean 37 | 38 | isNumberType :: TypeChecker -> Typ () -> Boolean 39 | isNumberType = runFn2 isNumberTypeImpl 40 | 41 | foreign import isNumberTypeImpl :: forall i. Fn2 TypeChecker (Typ i) Boolean 42 | 43 | isStringType :: TypeChecker -> Typ () -> Boolean 44 | isStringType = runFn2 isStringTypeImpl 45 | 46 | foreign import isStringTypeImpl :: forall i. Fn2 TypeChecker (Typ i) Boolean 47 | 48 | isTupleType ∷ forall i. TypeChecker -> Typ i -> Boolean 49 | isTupleType = runFn2 isTupleTypeImpl 50 | 51 | foreign import isTupleTypeImpl :: forall i. Fn2 TypeChecker (Typ i) Boolean 52 | 53 | isReadonlyArrayType ∷ forall i. TypeChecker -> (Typ i) -> Boolean 54 | isReadonlyArrayType = runFn2 isReadonlyArrayTypeImpl 55 | 56 | foreign import isReadonlyArrayTypeImpl :: forall i. Fn2 TypeChecker (Typ i) Boolean 57 | 58 | isUndefinedType :: forall i. TypeChecker -> Typ i -> Boolean 59 | isUndefinedType = runFn2 isUndefinedTypeImpl 60 | 61 | foreign import isUndefinedTypeImpl :: forall i. Fn2 TypeChecker (Typ i) Boolean 62 | 63 | type PropertyName = String 64 | 65 | getTypeOfPropertyOfType ∷ forall i. TypeChecker → (Typ i) → PropertyName → (Maybe (Typ ())) 66 | getTypeOfPropertyOfType c r = toMaybe <<< runFn3 getTypeOfPropertyOfTypeImpl c r 67 | 68 | foreign import getTypeOfPropertyOfTypeImpl :: forall i. Fn3 TypeChecker (Typ i) PropertyName (Nullable (Typ ())) 69 | 70 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Checker/Internal.ts: -------------------------------------------------------------------------------- 1 | import * as ts from "typescript"; 2 | 3 | export interface TypeChecker extends ts.TypeChecker { 4 | // I've additionally restricted some signatures. 5 | getElementTypeOfArrayType: (type: ts.Type) => ts.Type | undefined; 6 | isArrayType: (type: ts.Type) => boolean; 7 | isTupleType: (type: ts.Type) => boolean; 8 | isReadonlyArrayType: (type: ts.Type) => boolean; 9 | getTypeOfPropertyOfType: (type: ts.Type, propertyName: string) => ts.Type | undefined; 10 | 11 | getAnyType: () => ts.Type; 12 | getBooleanType: () => ts.Type; 13 | getNumberType: () => ts.Type; 14 | getNullType: () => ts.Type; 15 | getStringType: () => ts.Type; 16 | getUndefinedType: () => ts.Type; 17 | 18 | // Some other possible helpers 19 | // isTupleLikeType: (type: ts.Type) => boolean; 20 | // isArrayLikeType: (type: ts.Type) => boolean; 21 | // isEmptyArrayLiteralType: (type: ts.Type) => boolean; 22 | // isArrayOrTupleLikeType: (type: ts.Type) => boolean; 23 | // isNeitherUnitTypeNorNever: (type: ts.Type) => boolean; 24 | // isUnitType: (type: ts.Type) => boolean; 25 | // isLiteralType: (type: ts.Type) => boolean; 26 | }; 27 | 28 | export const getElementTypeOfArrayTypeImpl = (checker: TypeChecker, type: ts.Type): ts.Type | null => checker.getElementTypeOfArrayType(type) || null; 29 | 30 | export const isAnyTypeImpl = (checker: TypeChecker, type: ts.Type): boolean => checker.getAnyType() == type; 31 | 32 | export const isArrayTypeImpl = (checker: TypeChecker, type: ts.Type): boolean => checker.isArrayType(type); 33 | 34 | export const isBooleanTypeImpl = (checker: TypeChecker, type: ts.Type): boolean => checker.getBooleanType() == type; 35 | 36 | export const isNullTypeImpl = (checker: TypeChecker, type: ts.Type): boolean => checker.getNullType() == type; 37 | 38 | export const isNumberTypeImpl = (checker: TypeChecker, type: ts.Type): boolean => checker.getNumberType() == type; 39 | 40 | export const isReadonlyArrayTypeImpl = (checker: TypeChecker, type: ts.Type): boolean => checker.isReadonlyArrayType(type); 41 | 42 | export const isStringTypeImpl = (checker: TypeChecker, type: ts.Type): boolean => checker.getStringType() == type; 43 | 44 | export const isTupleTypeImpl = (checker: TypeChecker, type: ts.Type): boolean => checker.isTupleType(type); 45 | 46 | export const isUndefinedTypeImpl = (checker: TypeChecker, type: ts.Type): boolean => checker.getUndefinedType() == type; 47 | 48 | export const getTypeOfPropertyOfTypeImpl = (checker: TypeChecker, type: ts.Type, propertyName: string): ts.Type | null => checker.getTypeOfPropertyOfType(type, propertyName) || null; 49 | 50 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Debug.js: -------------------------------------------------------------------------------- 1 | import ts from "typescript"; 2 | var TsDebug = ts.Debug; 3 | export const formatSyntaxKind = (kind) => TsDebug.formatSyntaxKind(kind); 4 | export const formatNodeFlags = (flags) => TsDebug.formatNodeFlags(flags); 5 | export const formatModifierFlags = (flags) => TsDebug.formatModifierFlags(flags); 6 | export const formatEmitFlags = (flags) => TsDebug.formatEmitFlags(flags); 7 | export const formatSymbolFlags = (flags) => TsDebug.formatSymbolFlags(flags); 8 | export const formatTypeFlags = (flags) => TsDebug.formatTypeFlags(flags); 9 | // export const formatTransformFlags = (flags: ts.TransformFlags) => TsDebug.formatTransformFlags(flags); 10 | // export const formatSignatureFlags = (flags: ts.SignatureFlags) => TsDebug.formatSignatureFlags(flags); 11 | export const formatObjectFlags = (flags) => TsDebug.formatObjectFlags(flags); 12 | export const formatFlowFlags = (flags) => TsDebug.formatFlowFlags(flags); 13 | //# sourceMappingURL=Debug.js.map -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Debug.purs: -------------------------------------------------------------------------------- 1 | module TypeScript.Debug where 2 | 3 | import Prelude 4 | 5 | import TypeScript.Compiler.Types (Node, Symbol_, Typ, TypeFlags) 6 | import TypeScript.Compiler.Types.Nodes (NodeFlags, SyntaxKind) 7 | import TypeScript.Compiler.Types.Nodes (interface) as Nodes 8 | import TypeScript.Compiler.Types.Symbol (SymbolFlags) 9 | import TypeScript.Compiler.Types.Symbol (getFlags) as Symbol 10 | import TypeScript.Compiler.Types.Typs (ObjectFlags) 11 | import TypeScript.Compiler.Types.Typs (interface) as Typs 12 | 13 | -- | This module exposes internal Debug namespace. Please 14 | -- | be aware that like any other `internal` modules we are not able 15 | -- | to typecheck on the ts side correctness of the exposed interface. 16 | -- | We just hardcode and enforce the type. 17 | -- | In other words we *should* provide test coverage for this module ;-) 18 | 19 | foreign import formatSyntaxKind :: SyntaxKind -> String 20 | foreign import formatNodeFlags :: NodeFlags -> String 21 | foreign import formatSymbolFlags :: SymbolFlags -> String 22 | foreign import formatTypeFlags :: TypeFlags -> String 23 | foreign import formatObjectFlags :: ObjectFlags -> String 24 | 25 | formatTypeFlags' :: forall i. Typ i -> String 26 | formatTypeFlags' = formatTypeFlags <<< _.flags <<< Typs.interface 27 | 28 | formatNodeFlags' :: forall l i. Node l i -> String 29 | formatNodeFlags' = formatNodeFlags <<< _.nodeFlags <<< Nodes.interface 30 | 31 | formatSymbolFlags' :: Symbol_ -> String 32 | formatSymbolFlags' = formatSymbolFlags <<< Symbol.getFlags 33 | 34 | -- We don't expose `EmitNode` at the moment 35 | -- foreign import formatEmitFlags :: EmitFlags -> String 36 | -- We don't expose `FlowNode` at the moment 37 | -- foreign import formatFlowFlags :: FlowFlags -> String 38 | -- These flags printers are possibly there but flags types 39 | -- are not exposed by ts. 40 | -- foreign import formatModifierFlags :: ModifierFlags -> String 41 | -- foreign import :: formatTransformFlags :: TransformFlags -> String 42 | -- foreign import :: formatSignatureFlags :: SignatureFlags -> String 43 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Debug.ts: -------------------------------------------------------------------------------- 1 | import ts from "typescript"; 2 | 3 | // This is internal API `compiler/debug.ts` 4 | type Debug = { 5 | formatSyntaxKind: (kind: ts.SyntaxKind | undefined) => string, 6 | formatNodeFlags: (flags: ts.NodeFlags | undefined) => string, 7 | // `ModifierFlags` type is exposed but its field in the `Node` is `internal`. 8 | formatModifierFlags: (flags: ts.ModifierFlags | undefined) => string, 9 | formatEmitFlags: (flags: ts.EmitFlags | undefined) => string, 10 | formatSymbolFlags: (flags: ts.SymbolFlags | undefined) => string, 11 | formatTypeFlags: (flags: ts.TypeFlags | undefined) => string, 12 | formatObjectFlags: (flags: ts.ObjectFlags | undefined) => string, 13 | formatFlowFlags: (flags: ts.FlowFlags | undefined) => string, 14 | 15 | // These flags types are not exposed: 16 | // formatTransformFlags: (flags: ts.TransformFlags | undefined) => string, 17 | // formatSignatureFlags: (flags: ts.SignatureFlags | undefined) => string, 18 | } 19 | 20 | var TsDebug = (<{ Debug: Debug }>(ts)).Debug; 21 | 22 | export const formatSyntaxKind = (kind: ts.SyntaxKind) => TsDebug.formatSyntaxKind(kind); 23 | export const formatNodeFlags = (flags: ts.NodeFlags) => TsDebug.formatNodeFlags(flags); 24 | export const formatModifierFlags = (flags: ts.ModifierFlags) => TsDebug.formatModifierFlags(flags); 25 | export const formatEmitFlags = (flags: ts.EmitFlags) => TsDebug.formatEmitFlags(flags); 26 | export const formatSymbolFlags = (flags: ts.SymbolFlags) => TsDebug.formatSymbolFlags(flags); 27 | export const formatTypeFlags = (flags: ts.TypeFlags) => TsDebug.formatTypeFlags(flags); 28 | // export const formatTransformFlags = (flags: ts.TransformFlags) => TsDebug.formatTransformFlags(flags); 29 | // export const formatSignatureFlags = (flags: ts.SignatureFlags) => TsDebug.formatSignatureFlags(flags); 30 | export const formatObjectFlags = (flags: ts.ObjectFlags) => TsDebug.formatObjectFlags(flags); 31 | export const formatFlowFlags = (flags: ts.FlowFlags) => TsDebug.formatFlowFlags(flags); 32 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Parser.js: -------------------------------------------------------------------------------- 1 | import ts from "typescript"; 2 | export const createSourceFileImpl = ts.createSourceFile; 3 | //# sourceMappingURL=Parser.js.map -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Parser.purs: -------------------------------------------------------------------------------- 1 | module TypeScript.Compiler.Parser where 2 | 3 | import Effect (Effect) 4 | import Effect.Uncurried (EffectFn4, runEffectFn4) 5 | import TypeScript.Compiler.Types (ScriptTarget) 6 | import TypeScript.Compiler.Types.Nodes (SourceFile) 7 | 8 | type FileName = String 9 | newtype SourceCode = SourceCode String 10 | type SetParentNode = Boolean 11 | 12 | -- export function createSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, setParentNodes = false, scriptKind?: ScriptKind): SourceFile ∷ 13 | createSourceFile :: FileName -> SourceCode -> ScriptTarget -> SetParentNode -> Effect SourceFile 14 | createSourceFile = runEffectFn4 createSourceFileImpl 15 | 16 | foreign import createSourceFileImpl :: EffectFn4 FileName SourceCode ScriptTarget SetParentNode SourceFile 17 | 18 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Parser.ts: -------------------------------------------------------------------------------- 1 | import ts from "typescript"; 2 | 3 | export const createSourceFileImpl = ts.createSourceFile 4 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Program.js: -------------------------------------------------------------------------------- 1 | import ts from "typescript"; 2 | export function createCompilerHostImpl(options) { 3 | return ts.createCompilerHost(options, true); 4 | } 5 | export function createProgramImpl(rootNames, options, host) { 6 | return ts.createProgram(rootNames, options, host); 7 | } 8 | export function getTypeChecker(program) { 9 | return program.getTypeChecker(); 10 | } 11 | export function getRootFileNames(program) { 12 | return program.getRootFileNames(); 13 | } 14 | export function emit(program) { 15 | return program.emit(); 16 | } 17 | export function getSourceFiles(program) { 18 | return program.getSourceFiles(); 19 | } 20 | export function getFileName(sourceFile) { 21 | return sourceFile.fileName; 22 | } 23 | export function getPreEmitDiagnostics(program) { 24 | return ts.getPreEmitDiagnostics(program); 25 | } 26 | export function emitResultDiagnostics(emitResult) { 27 | return emitResult.diagnostics; 28 | } 29 | //# sourceMappingURL=Program.js.map -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Program.purs: -------------------------------------------------------------------------------- 1 | module TypeScript.Compiler.Program where 2 | 3 | import TypeScript.Compiler.Types 4 | 5 | import Data.Maybe (Maybe) 6 | import Data.Nullable (Nullable, toNullable) 7 | import Effect (Effect) 8 | import Effect.Uncurried (EffectFn1, EffectFn3, runEffectFn1, runEffectFn3) 9 | import TypeScript.Compiler.Parser (FileName) 10 | import TypeScript.Compiler.Types.Diagnostics (Diagnostic) 11 | import TypeScript.Compiler.Types.Nodes (SourceFile) 12 | 13 | createCompilerHost :: CompilerOptions -> Effect CompilerHost 14 | createCompilerHost = runEffectFn1 createCompilerHostImpl 15 | 16 | foreign import createCompilerHostImpl :: EffectFn1 CompilerOptions CompilerHost 17 | 18 | type RootNames = Array String 19 | 20 | createProgram :: Array String -> CompilerOptions -> Maybe CompilerHost -> Effect Program 21 | createProgram rootNames opts host = runEffectFn3 createProgramImpl rootNames opts (toNullable host) 22 | 23 | foreign import createProgramImpl :: EffectFn3 (Array String) CompilerOptions (Nullable CompilerHost) Program 24 | 25 | foreign import getTypeChecker :: Program -> TypeChecker 26 | 27 | foreign import getRootFileNames :: Program -> Array FileName 28 | 29 | foreign import getSourceFiles :: Program -> Array SourceFile 30 | 31 | foreign import getFileName :: SourceFile -> String 32 | 33 | foreign import emit :: Program -> Effect EmitResult 34 | 35 | foreign import emitResultDiagnostics :: EmitResult -> Array Diagnostic 36 | 37 | foreign import getPreEmitDiagnostics :: Program -> Array Diagnostic 38 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Program.ts: -------------------------------------------------------------------------------- 1 | import ts from "typescript"; 2 | 3 | export function createCompilerHostImpl(options: ts.CompilerOptions) : ts.CompilerHost { 4 | return ts.createCompilerHost(options, true); 5 | } 6 | 7 | export function createProgramImpl(rootNames: ReadonlyArray, options: ts.CompilerOptions, host?: ts.CompilerHost) : ts.Program { 8 | return ts.createProgram(rootNames, options, host); 9 | } 10 | 11 | export function getTypeChecker(program: ts.Program) : ts.TypeChecker { 12 | return program.getTypeChecker(); 13 | } 14 | 15 | export function getRootFileNames(program: ts.Program) : ReadonlyArray { 16 | return program.getRootFileNames(); 17 | } 18 | 19 | export function emit(program: ts.Program) : ts.EmitResult { 20 | return program.emit(); 21 | } 22 | 23 | export function getSourceFiles(program: ts.Program) : ReadonlyArray { 24 | return program.getSourceFiles(); 25 | } 26 | 27 | export function getFileName(sourceFile: ts.SourceFile) : string { 28 | return sourceFile.fileName; 29 | } 30 | 31 | export function getPreEmitDiagnostics(program: ts.Program) : ReadonlyArray { 32 | return ts.getPreEmitDiagnostics(program); 33 | } 34 | 35 | export function emitResultDiagnostics(emitResult: ts.EmitResult) : ReadonlyArray { 36 | return emitResult.diagnostics; 37 | } 38 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Types.js: -------------------------------------------------------------------------------- 1 | import ts from "typescript"; 2 | export const scriptTarget = ts.ScriptTarget; 3 | export const moduleKind = ts.ModuleKind; 4 | export const moduleResolutionKind = ts.ModuleResolutionKind; 5 | export const call = ts.SignatureKind.Call; 6 | export const construct = ts.SignatureKind.Construct; 7 | //# sourceMappingURL=Types.js.map 8 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Types.purs: -------------------------------------------------------------------------------- 1 | module TypeScript.Compiler.Types where 2 | 3 | import Data.Newtype (class Newtype) 4 | import Data.Undefined.NoProblem (Opt) 5 | import Prelude (class Eq, class Ord, class Show) 6 | 7 | foreign import data Program :: Type 8 | 9 | -- | You can find partial translation (with `this` binding) into just 10 | -- | record of this opaque type in the `ReadDTS.TypeScript.Testing` module. 11 | -- | Should we just move that API here? 12 | foreign import data CompilerHost :: Type 13 | 14 | foreign import data TypeChecker :: Type 15 | 16 | foreign import data ScriptTarget :: Type 17 | 18 | foreign import scriptTarget :: 19 | { "ES3" :: ScriptTarget 20 | , "ES5" :: ScriptTarget 21 | , "ES2015" :: ScriptTarget 22 | , "ES2016" :: ScriptTarget 23 | , "ES2017" :: ScriptTarget 24 | , "ES2018" :: ScriptTarget 25 | , "ES2019" :: ScriptTarget 26 | , "ES2020" :: ScriptTarget 27 | , "ESNext" :: ScriptTarget 28 | , "JSON" :: ScriptTarget 29 | , "Latest" :: ScriptTarget 30 | } 31 | 32 | foreign import data ModuleKind :: Type 33 | 34 | foreign import moduleKind :: 35 | { "None" :: ModuleKind 36 | , "CommonJS" :: ModuleKind 37 | , "AMD" :: ModuleKind 38 | , "UMD" :: ModuleKind 39 | , "System" :: ModuleKind 40 | , "ES2015" :: ModuleKind 41 | , "ESNext" :: ModuleKind 42 | } 43 | 44 | foreign import data ModuleResolutionKind :: Type 45 | 46 | foreign import moduleResolutionKind :: 47 | { "Classic" :: ModuleResolutionKind 48 | , "Node10" :: ModuleResolutionKind 49 | , "Node16" :: ModuleResolutionKind 50 | , "NodeNext" :: ModuleResolutionKind 51 | , "Bundler" :: ModuleResolutionKind 52 | } 53 | 54 | type CompilerOptions = 55 | { "module" :: Opt ModuleKind 56 | , moduleResolution :: Opt ModuleResolutionKind 57 | , noEmitOnError :: Opt Boolean 58 | , noImplicitAny :: Opt Boolean 59 | , allowSyntheticDefaultImports :: Opt Boolean 60 | , rootDirs :: Array String 61 | , strictNullChecks :: Boolean 62 | , target :: Opt ScriptTarget 63 | } 64 | 65 | -- | Opaque type for string like identifiers nodes. 66 | foreign import data Identifier :: Type 67 | 68 | foreign import data PropertyName :: Type 69 | 70 | foreign import data TypeReference :: Type 71 | 72 | -- | `Node` carries information about possible accessors in the row. 73 | -- | You can use it by casting done through `Types.Nodes.interface`. 74 | -- | 75 | -- | Few notes: 76 | -- | 77 | -- | * We treat `Node` values as immutable in this TS compiler binding. 78 | -- | * We need this opaque type around possible records because 79 | -- | we don't want to expose its internal `kind` field which 80 | -- | is used for casting and we don't want to expose private fields etc. 81 | -- | * We need this opaque type because we should disallow 82 | -- | creation of nodes which are partial (i.e. missing `kind` field) 83 | -- | or inconsistent (when `kind` field is incosistent with the 84 | -- | actual shape of the node record). 85 | -- | * Nodes don't have methods. If they have we will not 86 | -- | expose them - methods should be bounded to the "this" object 87 | -- | before we can expose them to the PS. 88 | -- | * We use `Symbol` tag to distinguish between different types 89 | -- | of nodes (with the same exposed public props). They in some 90 | -- | sens represent all the private stuff. 91 | -- | 92 | -- | For a list of `Nodes` and specific fields methods 93 | -- | please check `Compiler.Types.Nodes` and `Compiler.Factory.NodeTests`. 94 | foreign import data Node :: Symbol -> Row Type -> Type 95 | 96 | -- | FIXME: we should add symbol tag similar to the one above 97 | -- | as well here. 98 | -- | 99 | -- | FIXME: Rename to `Type_` so it is consistent with `Symbol_`. 100 | -- | The interface in the `compiler/types.ts` is called 101 | -- | `Type`. I've found that this makes some PS errors 102 | -- | hard to read. `Type` collide with PS builtin type name. 103 | foreign import data Typ :: Row Type -> Type 104 | foreign import data TypeFlags :: Type 105 | foreign import data Symbol_ :: Type 106 | 107 | -- Used by `Checker.getExportsOfModule` 108 | newtype ModuleSymbol = ModuleSymbol Symbol_ 109 | 110 | 111 | newtype FullyQualifiedName = FullyQualifiedName String 112 | 113 | derive instance Newtype FullyQualifiedName _ 114 | derive instance Eq FullyQualifiedName 115 | derive instance Ord FullyQualifiedName 116 | derive newtype instance Show FullyQualifiedName 117 | 118 | foreign import data Signature :: Type 119 | 120 | foreign import data SignatureKind :: Type 121 | 122 | foreign import call :: SignatureKind 123 | 124 | foreign import construct :: SignatureKind 125 | 126 | foreign import data EmitResult :: Type 127 | 128 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Types.ts: -------------------------------------------------------------------------------- 1 | import ts from "typescript"; 2 | 3 | export const scriptTarget = ts.ScriptTarget; 4 | 5 | export const moduleKind = ts.ModuleKind; 6 | 7 | export const moduleResolutionKind = ts.ModuleResolutionKind; 8 | 9 | export const call = ts.SignatureKind.Call; 10 | 11 | export const construct = ts.SignatureKind.Construct; 12 | 13 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Types/Diagnostics.js: -------------------------------------------------------------------------------- 1 | 2 | export const diagnosticCategory = ts.DiagnosticCategory; 3 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Types/Diagnostics.purs: -------------------------------------------------------------------------------- 1 | module TypeScript.Compiler.Types.Diagnostics where 2 | 3 | import Prelude 4 | 5 | import Data.Newtype (class Newtype) 6 | import Data.Undefined.NoProblem (Opt) 7 | import JS.Object.Immutable (Immutable) 8 | import JS.Variant.Untagged (Untagged, StringRow) 9 | import Type.Row (type (+)) 10 | import TypeScript.Compiler.Types.Nodes (SourceFile) 11 | import Unsafe.Reference (unsafeRefEq) 12 | 13 | foreign import data EmitResult :: Type 14 | 15 | foreign import data DiagnosticCategory :: Type 16 | 17 | instance Eq DiagnosticCategory where 18 | eq = unsafeRefEq 19 | 20 | foreign import diagnosticCategory :: Immutable 21 | ( "Warning" :: DiagnosticCategory 22 | , "Error" :: DiagnosticCategory 23 | , "Suggestion" :: DiagnosticCategory 24 | , "Message" :: DiagnosticCategory 25 | ) 26 | 27 | newtype DiagnosticMessageChain = DiagnosticMessageChain 28 | ( Immutable 29 | ( messageText :: String 30 | , category :: DiagnosticCategory 31 | , code :: Int 32 | , next :: Opt (Array DiagnosticMessageChain) 33 | ) 34 | ) 35 | derive instance Newtype DiagnosticMessageChain _ 36 | 37 | type MessageText = Untagged (StringRow + (diagnosticMessageChain :: DiagnosticMessageChain)) 38 | 39 | 40 | -- export interface Diagnostic extends DiagnosticRelatedInformation { 41 | -- /** May store more in future. For now, this will simply be `true` to indicate when a diagnostic is an unused-identifier diagnostic. */ 42 | -- reportsUnnecessary?: {}; 43 | -- 44 | -- reportsDeprecated?: {} 45 | -- source?: string; 46 | -- relatedInformation?: DiagnosticRelatedInformation[]; 47 | -- /** @internal */ skippedOn?: keyof CompilerOptions; 48 | -- } 49 | -- 50 | -- export interface DiagnosticRelatedInformation { 51 | -- category: DiagnosticCategory; 52 | -- code: number; 53 | -- file: SourceFile | undefined; 54 | -- start: number | undefined; 55 | -- length: number | undefined; 56 | -- messageText: string | DiagnosticMessageChain; 57 | -- } 58 | 59 | type DiagnosticRelatedInformationRow = 60 | ( category :: DiagnosticCategory 61 | , code :: Int 62 | , file :: Opt SourceFile 63 | , start :: Opt Int 64 | , length :: Opt Int 65 | , messageText :: MessageText 66 | ) 67 | 68 | newtype DiagnosticRelatedInformation = 69 | DiagnosticRelatedInformation (Immutable DiagnosticRelatedInformationRow) 70 | derive instance Newtype DiagnosticRelatedInformation _ 71 | 72 | newtype Diagnostic = Diagnostic 73 | ( Immutable 74 | ( source :: Opt String 75 | , relatedInformation :: Opt (Array DiagnosticRelatedInformation) 76 | | DiagnosticRelatedInformationRow 77 | ) 78 | ) 79 | derive instance Newtype Diagnostic _ 80 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Types/Nodes.js: -------------------------------------------------------------------------------- 1 | export const getChildren = (node) => node.getChildren(); 2 | //# sourceMappingURL=Nodes.js.map -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Types/Nodes.ts: -------------------------------------------------------------------------------- 1 | import ts from "typescript"; 2 | 3 | export const getChildren = (node: ts.Node): ts.Node[] => node.getChildren(); 4 | 5 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Types/Signature.js: -------------------------------------------------------------------------------- 1 | export function getDeclaration(s) { 2 | return s.getDeclaration() || null; 3 | } 4 | export function getTypeParameters(s) { 5 | return s.getTypeParameters() || []; 6 | } 7 | export function getParameters(s) { 8 | return s.getParameters(); 9 | } 10 | export function getReturnType(s) { 11 | return s.getReturnType(); 12 | } 13 | // export function getDocumentationComment(): SymbolDisplayPart[] { 14 | // return this.documentationComment || (this.documentationComment = getDocumentationComment(singleElementArray(this.declaration), this.checker)); 15 | // } 16 | //# sourceMappingURL=Signature.js.map -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Types/Signature.purs: -------------------------------------------------------------------------------- 1 | module TypeScript.Compier.Types where 2 | 3 | import TypeScript.Compiler.Types (Signature, Symbol_, Typ) 4 | import TypeScript.Compiler.Types.Nodes (SignatureDeclaration) as Nodes 5 | import TypeScript.Compiler.Types.Typs (TypeParameter) as Typs 6 | 7 | foreign import getDeclaration :: Signature -> Nodes.SignatureDeclaration 8 | 9 | foreign import getTypeParameters :: Signature -> Array Typs.TypeParameter 10 | 11 | foreign import getParameters :: Signature -> Array Symbol_ 12 | 13 | foreign import getReturnType :: Signature -> Typ () 14 | 15 | -- foreign import getDocumentationComment :: Signature -> --(): SymbolDisplayPart[] { 16 | 17 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Types/Signature.ts: -------------------------------------------------------------------------------- 1 | import ts from "typescript"; 2 | 3 | export function getDeclaration(s: ts.Signature): ts.SignatureDeclaration { 4 | return s.getDeclaration() || null; 5 | } 6 | export function getTypeParameters(s: ts.Signature): ts.TypeParameter[] { 7 | return s.getTypeParameters() || []; 8 | } 9 | 10 | export function getParameters(s: ts.Signature): ts.Symbol[] { 11 | return s.getParameters(); 12 | } 13 | 14 | export function getReturnType(s: ts.Signature): ts.Type { 15 | return s.getReturnType(); 16 | } 17 | 18 | // export function getDocumentationComment(): SymbolDisplayPart[] { 19 | // return this.documentationComment || (this.documentationComment = getDocumentationComment(singleElementArray(this.declaration), this.checker)); 20 | // } 21 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Types/Symbol.js: -------------------------------------------------------------------------------- 1 | import ts from "typescript"; 2 | // src/compiller/types.ts: 3 | // export interface Symbol { 4 | // flags: SymbolFlags; // Symbol flags 5 | // escapedName: __String; // Name of symbol 6 | // declarations?: Declaration[]; // Declarations associated with this symbol 7 | // valueDeclaration?: Declaration; // First value declaration of the symbol 8 | // members?: SymbolTable; // Class, interface or object literal instance members 9 | // exports?: SymbolTable; // Module exports 10 | // globalExports?: SymbolTable; // Conditional global UMD exports 11 | export const symbolFlags = ts.SymbolFlags; 12 | export const getFlagsImpl = (s) => s.getFlags(); 13 | export const getNameImpl = (s) => s.getName(); 14 | export const getDeclarationsImpl = (s) => s.getDeclarations() || []; 15 | export const getExportsImpl = (s) => s.exports || []; 16 | //# sourceMappingURL=Symbol.js.map 17 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Types/Symbol.purs: -------------------------------------------------------------------------------- 1 | module TypeScript.Compiler.Types.Symbol where 2 | 3 | import Prelude 4 | 5 | import Data.Function.Uncurried (Fn1, runFn1) 6 | import Data.Int.Bits ((.&.)) 7 | import Prim.Row (class Cons) as Row 8 | import Record (get) as Record 9 | import Type.Prelude (class IsSymbol, Proxy) 10 | import TypeScript.Compiler.Types (Symbol_) 11 | import TypeScript.Compiler.Types.Nodes as Nodes 12 | 13 | type SymbolFlags = Int 14 | 15 | type SymbolFlagsRow = ("Optional" :: SymbolFlags, "ModuleMember" :: SymbolFlags) 16 | 17 | foreign import symbolFlags :: { | SymbolFlagsRow } 18 | 19 | interface 20 | :: Symbol_ 21 | -> { flags :: SymbolFlags 22 | , name :: String 23 | , declarations :: Array Nodes.Declaration 24 | } 25 | interface s = 26 | { flags: getFlags s 27 | , name: getName s 28 | , declarations: getDeclarations s 29 | } 30 | 31 | getFlags :: Symbol_ -> SymbolFlags 32 | getFlags = runFn1 getFlagsImpl 33 | 34 | foreign import getFlagsImpl :: Fn1 Symbol_ Int 35 | 36 | getName :: Symbol_ -> String 37 | getName = runFn1 getNameImpl 38 | 39 | foreign import getNameImpl :: Fn1 Symbol_ String 40 | 41 | getDeclarations :: Symbol_ -> Array Nodes.Declaration 42 | getDeclarations = runFn1 getDeclarationsImpl 43 | 44 | foreign import getDeclarationsImpl :: Fn1 Symbol_ (Array Nodes.Declaration) 45 | 46 | checkFlag 47 | :: forall s symbolFlags_ 48 | . IsSymbol s 49 | => Row.Cons s SymbolFlags symbolFlags_ SymbolFlagsRow 50 | => Symbol_ 51 | -> Proxy s 52 | -> Boolean 53 | checkFlag s n = Record.get n symbolFlags .&. getFlags s /= 0 54 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Types/Symbol.ts: -------------------------------------------------------------------------------- 1 | import ts from "typescript"; 2 | 3 | export const symbolFlags = ts.SymbolFlags; 4 | 5 | export const getFlagsImpl = (s: ts.Symbol): ts.SymbolFlags => s.getFlags() 6 | 7 | export const getNameImpl = (s: ts.Symbol): string => s.getName() 8 | 9 | export const getDeclarationsImpl = (s: ts.Symbol): ts.Declaration[] | null => s.getDeclarations() || []; 10 | 11 | export const getExportsImpl = (s: ts.Symbol): never[] | ts.SymbolTable => s.exports || []; 12 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Types/Typs.js: -------------------------------------------------------------------------------- 1 | import ts from "typescript"; 2 | export const asNumberLiteralTypeImpl = (t) => t.isNumberLiteral() ? t : null; 3 | export const asIntersectionTypeImpl = (t) => t.isIntersection() ? t : null; 4 | export const asObjectTypeImpl = (t) => { 5 | let Nullable = ts.TypeFlags.Undefined | ts.TypeFlags.Null; 6 | let ObjectFlagsType = ts.TypeFlags.Any | Nullable | ts.TypeFlags.Never | ts.TypeFlags.Object | ts.TypeFlags.Union | ts.TypeFlags.Intersection; 7 | if (t.flags & ObjectFlagsType) 8 | return t; 9 | return null; 10 | }; 11 | export const asStringLiteralTypeImpl = (t) => t.isStringLiteral() ? t : null; 12 | export const asUnionTypeImpl = (t) => t.isUnion() ? t : null; 13 | export const asTypeParameterImpl = (t) => t.isTypeParameter() ? t : null; 14 | export const asTypeReferenceImpl = (t) => { 15 | // There is no sens at the moment to expose ObjectType casting I think to the PS side... 16 | let s = asObjectTypeImpl(t); 17 | if (s && s.objectFlags & ts.ObjectFlags.Reference) 18 | return s; 19 | return null; 20 | }; 21 | export const getCallSignatures = (t) => t.getCallSignatures(); 22 | export const getConstructSignatures = (t) => t.getConstructSignatures(); 23 | export const getPropertiesImpl = (t) => t.getProperties(); 24 | export const getApparentPropertiesImpl = (t) => t.getApparentProperties(); 25 | export const asInterfaceTypeImpl = (t) => { 26 | if (t.objectFlags & ts.ObjectFlags.Interface) { 27 | return t; 28 | } 29 | return null; 30 | }; 31 | export const asClassTypeImpl = (t) => { 32 | if (t.objectFlags & ts.ObjectFlags.Class) { 33 | return t; 34 | } 35 | return null; 36 | }; 37 | export const getSymbolImpl = (t) => t.getSymbol() || null; 38 | export const getDefaultImpl = (t) => t.getDefault() || null; 39 | export const getBaseTypesImpl = (t) => t.getBaseTypes() || []; 40 | //# sourceMappingURL=Typs.js.map -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Types/Typs.purs: -------------------------------------------------------------------------------- 1 | module TypeScript.Compiler.Types.Typs where 2 | 3 | import Prelude 4 | 5 | import Control.Alternative (guard) as Alternative 6 | import Data.Function.Uncurried (Fn1, runFn1) 7 | import Data.Maybe (Maybe) 8 | import Data.Nullable (Nullable, toMaybe) 9 | import Data.Undefined.NoProblem (Opt) 10 | import Type.Row (type (+)) 11 | import TypeScript.Compiler.Types (Signature, Symbol_, Typ, TypeFlags) 12 | import Unsafe.Coerce (unsafeCoerce) 13 | import Unsafe.Reference (unsafeRefEq) 14 | 15 | type TypRow r = 16 | ( aliasSymbol :: Opt Symbol_ 17 | , aliasTypeArguments :: Opt (Array (Typ ())) 18 | , flags :: TypeFlags 19 | , symbol :: Symbol_ 20 | | r 21 | ) 22 | 23 | interface :: forall i. Typ i -> { | TypRow + i } 24 | interface = unsafeCoerce 25 | 26 | forget :: forall i. Typ i -> Typ () 27 | forget = unsafeCoerce 28 | 29 | type BooleanLiteralType = Typ (value :: Boolean) 30 | 31 | type GenericTypeRow r = InterfaceTypeRow r 32 | 33 | asClassType :: forall r. Typ r -> Maybe InterfaceType 34 | asClassType = toMaybe <<< runFn1 asClassTypeImpl 35 | 36 | foreign import asClassTypeImpl :: forall r. Fn1 (Typ r) (Nullable InterfaceType) 37 | 38 | type IntersectionType = Typ (types :: Array (Typ ())) 39 | 40 | asIntersectionType :: forall r. Typ r -> Maybe IntersectionType 41 | asIntersectionType = toMaybe <<< runFn1 asIntersectionTypeImpl 42 | 43 | foreign import asIntersectionTypeImpl :: forall r. Fn1 (Typ r) (Nullable IntersectionType) 44 | 45 | -- | Interface or Class 46 | type InterfaceTypeRow r 47 | = ObjectTypeRow 48 | + 49 | ( typeParameters :: Opt (Array TypeParameter) 50 | , outerTypeParameters :: Opt (Array TypeParameter) 51 | , localTypeParameters :: Opt (Array TypeParameter) 52 | , thisType :: Opt TypeParameter 53 | | r 54 | ) 55 | 56 | type InterfaceType = Typ (InterfaceTypeRow ()) 57 | 58 | asInterfaceType :: forall r. Typ r -> Maybe InterfaceType 59 | asInterfaceType = toMaybe <<< runFn1 asInterfaceTypeImpl 60 | 61 | foreign import asInterfaceTypeImpl :: forall r. Fn1 (Typ r) (Nullable InterfaceType) 62 | 63 | type NumberLiteralType = Typ (value :: Number) 64 | 65 | asNumberLiteralType :: forall r. Typ r -> Maybe NumberLiteralType 66 | asNumberLiteralType = toMaybe <<< runFn1 asNumberLiteralTypeImpl 67 | 68 | foreign import asNumberLiteralTypeImpl :: forall r. Fn1 (Typ r) (Nullable NumberLiteralType) 69 | 70 | foreign import data ObjectFlags :: Type 71 | 72 | type ObjectTypeRow r = (objectFlags :: ObjectFlags, properties :: Array Symbol | r) 73 | 74 | -- | `ObjectType` has a broad scope in the ts terms 75 | type ObjectType = Typ (ObjectTypeRow + ()) 76 | 77 | asObjectType :: forall r. Typ r -> Maybe ObjectType 78 | asObjectType = toMaybe <<< runFn1 asObjectTypeImpl 79 | 80 | foreign import asObjectTypeImpl :: forall r. Fn1 (Typ r) (Nullable ObjectType) 81 | 82 | foreign import getCallSignatures :: forall r. Typ r -> Array Signature 83 | 84 | foreign import getConstructSignatures :: forall i. Typ i -> (Array Signature) 85 | 86 | type StringLiteralType = Typ (value :: String) 87 | 88 | asStringLiteralType :: forall r. Typ r -> Maybe StringLiteralType 89 | asStringLiteralType = toMaybe <<< runFn1 asStringLiteralTypeImpl 90 | 91 | foreign import asStringLiteralTypeImpl :: forall r. Fn1 (Typ r) (Nullable StringLiteralType) 92 | 93 | type TypeParameter = Typ () 94 | 95 | type TypeReference = Typ 96 | ( target :: Typ (GenericTypeRow ()) 97 | , typeArguments :: Opt (Array (Typ ())) 98 | ) 99 | 100 | asTypeReference :: forall r. Typ r -> Maybe TypeReference 101 | asTypeReference = toMaybe <<< runFn1 asTypeReferenceImpl 102 | 103 | asNonCyclicTypeReference :: forall r. Typ r -> Maybe TypeReference 104 | asNonCyclicTypeReference t = do 105 | ref <- asTypeReference t 106 | let 107 | { target: t' } = interface ref 108 | Alternative.guard (not $ unsafeRefEq (forget t') (forget t)) *> pure ref 109 | 110 | foreign import asTypeReferenceImpl :: forall r. Fn1 (Typ r) (Nullable TypeReference) 111 | 112 | type UnionType = Typ (types :: Array (Typ ())) 113 | 114 | asUnionType :: forall r. Typ r -> Maybe UnionType 115 | asUnionType = toMaybe <<< runFn1 asUnionTypeImpl 116 | 117 | foreign import asUnionTypeImpl :: forall r. Fn1 (Typ r) (Nullable UnionType) 118 | 119 | asTypeParameter :: forall r. Typ r -> Maybe TypeParameter 120 | asTypeParameter = toMaybe <<< runFn1 asTypeParameterImpl 121 | 122 | foreign import asTypeParameterImpl :: forall r. Fn1 (Typ r) (Nullable TypeParameter) 123 | 124 | getProperties :: forall r. Typ r -> Array Symbol_ 125 | getProperties = runFn1 getPropertiesImpl 126 | 127 | foreign import getPropertiesImpl :: forall i. Fn1 (Typ i) (Array Symbol_) 128 | 129 | getApparentProperties :: forall r. Typ r -> Array Symbol_ 130 | getApparentProperties = runFn1 getApparentPropertiesImpl 131 | 132 | foreign import getApparentPropertiesImpl :: forall i. Fn1 (Typ i) (Array Symbol_) 133 | 134 | getSymbol :: forall i. Typ i -> Maybe Symbol_ 135 | getSymbol = toMaybe <<< runFn1 getSymbolImpl 136 | 137 | foreign import getSymbolImpl :: forall i. Fn1 (Typ i) (Nullable Symbol_) 138 | 139 | -- | Dafault type for type parameter 140 | getDefault :: forall i. Typ i -> Maybe (Typ ()) 141 | getDefault = toMaybe <<< runFn1 getDefaultImpl 142 | 143 | foreign import getDefaultImpl :: forall i. Fn1 (Typ i) (Nullable (Typ ())) 144 | 145 | -- | FIXME: result should be more specific (Array `ts.BaseType`) 146 | getBaseTypes :: forall i. Typ i -> Array (Typ ()) 147 | getBaseTypes = runFn1 getBaseTypesImpl 148 | 149 | foreign import getBaseTypesImpl :: forall i. Fn1 (Typ i) (Array (Typ ())) 150 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Types/Typs.ts: -------------------------------------------------------------------------------- 1 | import ts from "typescript"; 2 | 3 | export const asNumberLiteralTypeImpl = (t: ts.Type): ts.NumberLiteralType | null => t.isNumberLiteral()?t:null; 4 | 5 | export const asIntersectionTypeImpl = (t: ts.Type): ts.IntersectionType | null => t.isIntersection()?t:null; 6 | 7 | export interface PlainObjectType extends ts.Type { 8 | objectFlags: ts.ObjectFlags; 9 | members?: ts.SymbolTable; // Properties by name 10 | properties?: ts.Symbol[]; // Properties 11 | } 12 | 13 | export const asObjectTypeImpl = (t: ts.Type): ts.ObjectType | null => { 14 | let Nullable = ts.TypeFlags.Undefined | ts.TypeFlags.Null; 15 | let ObjectFlagsType = ts.TypeFlags.Any | Nullable | ts.TypeFlags.Never | ts.TypeFlags.Object | ts.TypeFlags.Union | ts.TypeFlags.Intersection; 16 | 17 | if (t.flags & ObjectFlagsType) 18 | return t; 19 | return null; 20 | } 21 | 22 | export const asStringLiteralTypeImpl = (t: ts.Type): ts.StringLiteralType | null => t.isStringLiteral()?t:null; 23 | 24 | export const asUnionTypeImpl = (t: ts.Type): ts.UnionType | null => t.isUnion()?t:null; 25 | 26 | export const asTypeParameterImpl = (t: ts.Type): ts.TypeParameter | null => t.isTypeParameter()?t:null; 27 | 28 | export const asTypeReferenceImpl = (t: ts.Type): ts.TypeReference | null => { 29 | // There is no sens at the moment to expose ObjectType casting I think to the PS side... 30 | let s = asObjectTypeImpl(t); 31 | if(s && s.objectFlags & ts.ObjectFlags.Reference) 32 | return s; 33 | 34 | return null; 35 | } 36 | 37 | export const getCallSignatures = (t: ts.Type): readonly ts.Signature[] => t.getCallSignatures(); 38 | 39 | export const getConstructSignatures = (t: ts.Type): readonly ts.Signature[] => t.getConstructSignatures(); 40 | 41 | export const getPropertiesImpl = (t: ts.Type): ts.Symbol[] => t.getProperties(); 42 | 43 | export const getApparentPropertiesImpl = (t: ts.Type): ts.Symbol [] => t.getApparentProperties(); 44 | 45 | export const asInterfaceTypeImpl = (t: ts.ObjectType): ts.InterfaceType | null => { 46 | if(t.objectFlags & ts.ObjectFlags.Interface) { 47 | return t; 48 | } 49 | return null; 50 | } 51 | 52 | export const asClassTypeImpl = (t: ts.ObjectType): ts.InterfaceType | null => { 53 | if(t.objectFlags & ts.ObjectFlags.Class) { 54 | return t; 55 | } 56 | return null; 57 | } 58 | 59 | export const getSymbolImpl = (t: ts.Type): ts.Symbol | null => t.getSymbol() || null; 60 | 61 | export const getDefaultImpl = (t: ts.Type): ts.Type | null => t.getDefault() || null; 62 | 63 | export const getBaseTypesImpl = (t: ts.Type): ts.BaseType[] => t.getBaseTypes() || []; 64 | 65 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Types/Typs/Internal.js: -------------------------------------------------------------------------------- 1 | import ts from "typescript"; 2 | export const asIntrinsicTypeImpl = (t) => { 3 | const isIntrinsicType = (t) => { 4 | // We use this hacky way to detect intrinsic type because 5 | // we want to avoid copying of the `Intrinsic` 6 | // `TypeFlags.Intrinsic` union which can change over time. 7 | return t.intrinsicName !== undefined; 8 | }; 9 | return isIntrinsicType(t) ? t : null; 10 | }; 11 | export const reflectBooleanLiteralTypeImpl = (t) => { 12 | const isBooleanLiteral = (t) => { 13 | return !!(t.flags & ts.TypeFlags.BooleanLiteral); 14 | }; 15 | return isBooleanLiteral(t) ? t.intrinsicName == "true" : null; 16 | }; 17 | //# sourceMappingURL=Internal.js.map -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Types/Typs/Internal.purs: -------------------------------------------------------------------------------- 1 | module TypeScript.Compiler.Types.Typs.Internal where 2 | 3 | import Prelude 4 | 5 | import Data.Function.Uncurried (Fn1, runFn1) 6 | import Data.Maybe (Maybe) 7 | import Data.Nullable (Nullable, toMaybe) 8 | import TypeScript.Compiler.Types (Typ) 9 | 10 | -- | This type is not exposed by tsc 11 | -- | but useful for debugging... 12 | type IntrinsicType = Typ (intrinsicName :: String) 13 | 14 | asIntrinsicType :: forall r. Typ r -> Maybe IntrinsicType 15 | asIntrinsicType = toMaybe <<< runFn1 asIntrinsicTypeImpl 16 | 17 | foreign import asIntrinsicTypeImpl :: forall r. Fn1 (Typ r) (Nullable IntrinsicType) 18 | 19 | reflectBooleanLiteralType :: forall r. Typ r -> Maybe Boolean 20 | reflectBooleanLiteralType = toMaybe <<< runFn1 reflectBooleanLiteralTypeImpl 21 | 22 | foreign import reflectBooleanLiteralTypeImpl :: forall r. Fn1 (Typ r) (Nullable Boolean) 23 | 24 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/Types/Typs/Internal.ts: -------------------------------------------------------------------------------- 1 | import ts from "typescript"; 2 | 3 | /* Caution: @internal .... */ 4 | export interface IntrinsicType extends ts.Type { 5 | intrinsicName: string; // Name of intrinsic type 6 | // objectFlags: ObjectFlags; 7 | } 8 | 9 | export const asIntrinsicTypeImpl = (t: ts.Type): IntrinsicType | null => { 10 | const isIntrinsicType = (t: ts.Type): t is IntrinsicType => { 11 | // We use this hacky way to detect intrinsic type because 12 | // we want to avoid copying of the `Intrinsic` 13 | // `TypeFlags.Intrinsic` union which can change over time. 14 | return (t as IntrinsicType).intrinsicName !== undefined; 15 | } 16 | return isIntrinsicType(t)?t:null; 17 | } 18 | 19 | export const reflectBooleanLiteralTypeImpl = (t: ts.Type): boolean | null => { 20 | const isBooleanLiteral = (t: ts.Type): t is IntrinsicType => { 21 | return !!(t.flags & ts.TypeFlags.BooleanLiteral); 22 | } 23 | return isBooleanLiteral(t)?t.intrinsicName == "true":null; 24 | } 25 | 26 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/UtilitiesPublic.js: -------------------------------------------------------------------------------- 1 | import ts from "typescript"; 2 | export const unsafeIdTextImpl = (identifierOrPrivateName) => ts.idText(identifierOrPrivateName); 3 | //# sourceMappingURL=UtilitiesPublic.js.map -------------------------------------------------------------------------------- /src/TypeScript/Compiler/UtilitiesPublic.purs: -------------------------------------------------------------------------------- 1 | module TypeScript.Compiler.UtilitiesPublic where 2 | 3 | import Prelude 4 | 5 | import Data.Function.Uncurried (Fn1, runFn1) 6 | import Prim.Row (class Cons, class Union) as Row 7 | import TypeScript.Compiler.Types (Node) 8 | 9 | idText :: 10 | forall i tag tagRow tagRow_. 11 | Row.Cons tag Void () tagRow => 12 | Row.Union tagRow tagRow_ ("Identifier" :: Void, "PrivateIdentifier" :: Void) => 13 | Node tag i -> 14 | String 15 | idText = runFn1 unsafeIdTextImpl 16 | 17 | 18 | foreign import unsafeIdTextImpl :: forall tag i. Fn1 (Node tag i) String 19 | 20 | -------------------------------------------------------------------------------- /src/TypeScript/Compiler/UtilitiesPublic.ts: -------------------------------------------------------------------------------- 1 | import ts from "typescript"; 2 | 3 | export const unsafeIdTextImpl = (identifierOrPrivateName: ts.Identifier | ts.PrivateIdentifier): string => ts.idText(identifierOrPrivateName); 4 | 5 | -------------------------------------------------------------------------------- /src/TypeScript/Testing/BoundedCompilerHost.js: -------------------------------------------------------------------------------- 1 | export const fromCompilerHost = (host) => { 2 | return { 3 | fileExists: host.fileExists.bind(host), 4 | directoryExists: host.directoryExists && host.directoryExists.bind(host), 5 | getCurrentDirectory: host.getCurrentDirectory && host.getCurrentDirectory.bind(host), 6 | getDirectories: host.getDirectories && host.getDirectories.bind(host), 7 | getCanonicalFileName: host.getCanonicalFileName.bind(host), 8 | getNewLine: host.getNewLine.bind(host), 9 | getDefaultLibFileName: host.getDefaultLibFileName.bind(host), 10 | getSourceFile: host.getSourceFile.bind(host), 11 | readFile: host.readFile.bind(host), 12 | useCaseSensitiveFileNames: host.useCaseSensitiveFileNames.bind(host), 13 | writeFile: host.writeFile.bind(host), 14 | }; 15 | }; 16 | //# sourceMappingURL=BoundedCompilerHost.js.map -------------------------------------------------------------------------------- /src/TypeScript/Testing/BoundedCompilerHost.purs: -------------------------------------------------------------------------------- 1 | module TypeScript.Testing.BoundedCompilerHost where 2 | 3 | import Prelude 4 | 5 | import Data.Undefined.NoProblem (Opt) 6 | import Effect (Effect) 7 | import Effect.Uncurried (EffectFn1, EffectFn2, EffectFn3, mkEffectFn1, runEffectFn1, runEffectFn2, mkEffectFn2, mkEffectFn3, runEffectFn3) 8 | import Node.Path (FilePath) 9 | import TypeScript.Compiler.Parser (SourceCode) 10 | import TypeScript.Compiler.Types (CompilerHost, CompilerOptions, ScriptTarget) 11 | import TypeScript.Compiler.Types.Nodes (SourceFile) 12 | import Unsafe.Coerce (unsafeCoerce) 13 | 14 | type DirName = String 15 | type WriteByteOrderMark = Boolean 16 | 17 | type WriteFileCallback = EffectFn3 FilePath SourceCode WriteByteOrderMark Unit 18 | 19 | -- | Record of compiler host proper functions - methods bounded to `this` compiler host instance 20 | type BoundedCompilerHost = 21 | { directoryExists :: Opt (EffectFn1 DirName Boolean) 22 | , fileExists :: EffectFn1 FilePath Boolean 23 | , getCanonicalFileName :: EffectFn1 FilePath FilePath 24 | , getCurrentDirectory :: Opt (Effect String) 25 | , getDefaultLibFileName :: EffectFn1 CompilerOptions FilePath 26 | , getDirectories :: Opt (EffectFn1 String (Array String)) 27 | , getNewLine :: Effect String 28 | , getSourceFile :: EffectFn2 FilePath ScriptTarget (Opt SourceFile) 29 | , readFile :: EffectFn1 FilePath (Opt SourceCode) 30 | , useCaseSensitiveFileNames :: Effect Boolean 31 | , writeFile :: WriteFileCallback 32 | } 33 | 34 | foreign import fromCompilerHost :: CompilerHost -> BoundedCompilerHost 35 | 36 | toCompilerHost :: BoundedCompilerHost -> CompilerHost 37 | toCompilerHost = unsafeCoerce 38 | 39 | -- newtype BoundedCompilerHost' = BoundedCompilerHost' BoundedCompilerHost 40 | -- 41 | -- appendEffectFn1With :: forall a b. (b -> b -> b) -> EffectFn1 a b -> EffectFn1 a b -> EffectFn1 a b 42 | -- appendEffectFn1With f f1 f2 = mkEffectFn1 \a -> f <$> (runEffectFn1 f1 a) <*> (runEffectFn1 f2 a) 43 | -- 44 | -- appendEffectFn1 :: forall a b. Semigroup b => EffectFn1 a b -> EffectFn1 a b -> EffectFn1 a b 45 | -- appendEffectFn1 = appendEffectFn1With (<>) 46 | -- 47 | -- appendEffectFn2With :: forall a b c. (c -> c -> c) -> EffectFn2 a b c -> EffectFn2 a b c -> EffectFn2 a b c 48 | -- appendEffectFn2With f f1 f2 = mkEffectFn2 \a b -> f <$> (runEffectFn2 f1 a b) <*> (runEffectFn2 f2 a b) 49 | -- 50 | -- appendEffectFn2 :: forall a b c. Semigroup c => EffectFn2 a b c -> EffectFn2 a b c -> EffectFn2 a b c 51 | -- appendEffectFn2 = appendEffectFn2With (<>) 52 | -- 53 | -- instance Semigroup BoundedCompilerHost' where 54 | -- append (BoundedCompilerHost' a) (BoundedCompilerHost' b) = do 55 | -- let 56 | -- directoryExists = appendEffectFn1With (||) a.directoryExists b.directoryExists 57 | -- fileExists = appendEffectFn1With (||) a.fileExists b.fileExists 58 | 59 | -- let 60 | -- directoryExists = a.directoryExists <> b.directoryExists 61 | -- BoundedCompilerHost' 62 | -- { directoryExists: a.directoryExists <> b.directoryExists 63 | -- , fileExists: a.fileExists <> b.fileExists 64 | -- , getCanonicalFileName: a.getCanonicalFileName <> b.getCanonicalFileName 65 | -- , getCurrentDirectory: a.getCurrentDirectory <> b.getCurrentDirectory 66 | -- , getDefaultLibFileName: a.getDefaultLibFileName <> b.getDefaultLibFileName 67 | -- , getDirectories: a.getDirectories <> b.getDirectories 68 | -- , getNewLine: a.getNewLine <> b.getNewLine 69 | -- , getSourceFile: a.getSourceFile <> b.getSourceFile 70 | -- , readFile: a.readFile <> b.readFile 71 | -- , useCaseSensitiveFileNames: a.useCaseSensitiveFileNames <> b.useCaseSensitiveFileNames 72 | -- , writeFile: a.writeFile <> b.writeFile 73 | -- } 74 | -- 75 | -------------------------------------------------------------------------------- /src/TypeScript/Testing/BoundedCompilerHost.ts: -------------------------------------------------------------------------------- 1 | import * as ts from "typescript"; 2 | 3 | export const fromCompilerHost = (host: ts.CompilerHost) => { 4 | return { 5 | fileExists: host.fileExists.bind(host), 6 | directoryExists: host.directoryExists && host.directoryExists.bind(host), 7 | getCurrentDirectory: host.getCurrentDirectory && host.getCurrentDirectory.bind(host), 8 | getDirectories: host.getDirectories && host.getDirectories.bind(host), 9 | getCanonicalFileName: host.getCanonicalFileName.bind(host), 10 | getNewLine: host.getNewLine.bind(host), 11 | getDefaultLibFileName: host.getDefaultLibFileName.bind(host), 12 | getSourceFile: host.getSourceFile.bind(host), 13 | readFile: host.readFile.bind(host), 14 | useCaseSensitiveFileNames: host.useCaseSensitiveFileNames.bind(host), 15 | writeFile: host.writeFile.bind(host), 16 | }; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /src/TypeScript/Testing/DefaultLib.purs: -------------------------------------------------------------------------------- 1 | module TypeScript.Testing.DefaultLib where 2 | 3 | import Prelude 4 | 5 | import Data.Maybe (Maybe(..), fromMaybe) 6 | import Effect (Effect) 7 | import Effect.Exception (throw) 8 | import Node.Buffer (toString) as Buffer 9 | import Node.Encoding (Encoding(..)) 10 | import Node.FS.Sync (exists, readFile) 11 | import Node.Path (FilePath) 12 | import TypeScript.Compiler.Parser (SourceCode(..), createSourceFile) 13 | import TypeScript.Compiler.Types (scriptTarget) 14 | import TypeScript.Compiler.Types.Nodes (SourceFile) as Nodes 15 | import TypeScript.Testing.Types (InMemoryFile(..), mkInMemoryFile) 16 | 17 | defaultLibPath :: FilePath 18 | defaultLibPath = "node_modules/typescript/lib/lib.es5.d.ts" 19 | 20 | defaultLibSrc :: Maybe FilePath -> Effect InMemoryFile 21 | defaultLibSrc path = do 22 | let 23 | path' = fromMaybe defaultLibPath path 24 | 25 | exists path' >>= 26 | if _ then do 27 | b <- readFile path' 28 | mkInMemoryFile path' <<< SourceCode <$> Buffer.toString UTF8 b 29 | else 30 | throw 31 | $ "InSubdir.compilerHost: Unable to find default `CompilerHost` library file:" 32 | <> path' 33 | 34 | load 35 | :: Maybe FilePath 36 | -> Effect 37 | { inMemoryFile :: InMemoryFile 38 | , sourceFile :: Nodes.SourceFile 39 | } 40 | load path = do 41 | let 42 | path' = fromMaybe defaultLibPath path 43 | 44 | i@(InMemoryFile { source }) <- defaultLibSrc (Just path') 45 | sourceFile <- createSourceFile path' source scriptTarget."ES5" true 46 | pure { inMemoryFile: i, sourceFile } 47 | -------------------------------------------------------------------------------- /src/TypeScript/Testing/InMemory.purs: -------------------------------------------------------------------------------- 1 | module TypeScript.Testing.InMemory where 2 | 3 | import Prelude 4 | 5 | import Data.Array (any, cons) as Array 6 | import Data.Array (find) 7 | import Data.Maybe (Maybe(..), fromMaybe) 8 | import Data.Traversable (for) 9 | import Data.Undefined.NoProblem (opt, undefined) 10 | import Data.Undefined.NoProblem as NoProblem 11 | import Effect (Effect) 12 | import Effect.Uncurried (EffectFn1, mkEffectFn1, mkEffectFn2, mkEffectFn3, runEffectFn1, runEffectFn2) 13 | import Node.Path (FilePath) 14 | import TypeScript.Compiler.Parser (createSourceFile) 15 | import TypeScript.Compiler.Types (CompilerHost, scriptTarget) 16 | import TypeScript.Testing.BoundedCompilerHost (BoundedCompilerHost) 17 | import TypeScript.Testing.BoundedCompilerHost (toCompilerHost) as BoundedCompilerHost 18 | import TypeScript.Testing.DefaultLib (load) as DefaultLib 19 | import TypeScript.Testing.Types (InMemoryFile(..)) 20 | 21 | type Opts r = 22 | { files :: Array InMemoryFile 23 | , defaultLib :: Maybe FilePath 24 | -- You can provide a fallback compiler host to handle files that are not in memory. 25 | -- It is a bit speculative if the fallback wokrs as expected. 26 | , subhost :: Maybe BoundedCompilerHost 27 | | r 28 | } 29 | 30 | compilerHost :: forall r. Opts r -> Effect CompilerHost 31 | compilerHost opts = BoundedCompilerHost.toCompilerHost <$> boundedCompilerHost opts 32 | 33 | boundedCompilerHost :: forall r. Opts r -> Effect BoundedCompilerHost 34 | boundedCompilerHost opts = do 35 | let 36 | { defaultLib, files } = opts 37 | defaultLibFile = fromMaybe "node_modules/typescript/lib/lib.es5.d.ts" defaultLib 38 | 39 | sourceFiles <- for files \(InMemoryFile { path, source }) -> do 40 | file <- createSourceFile path source scriptTarget."ES5" true 41 | pure { path, source, file } 42 | 43 | defaultLib <- DefaultLib.load defaultLib 44 | 45 | let 46 | sourceFiles' = do 47 | let 48 | InMemoryFile { path, source } = defaultLib.inMemoryFile 49 | Array.cons 50 | { path 51 | , file: defaultLib.sourceFile 52 | , source 53 | } 54 | sourceFiles 55 | let 56 | inMemoryHost = 57 | { fileExists: mkEffectFn1 \p -> do 58 | pure (Array.any (eq p <<< _.path) sourceFiles') 59 | , directoryExists: opt $ mkEffectFn1 \d -> do 60 | pure (d == "") 61 | , getCurrentDirectory: NoProblem.undefined -- opt $ pure "" 62 | , getDirectories: NoProblem.undefined -- opt $ mkEffectFn1 $ const (pure [ "" ]) 63 | , getCanonicalFileName: mkEffectFn1 pure 64 | , getNewLine: pure "\n" 65 | , getDefaultLibFileName: mkEffectFn1 (const $ pure defaultLibFile) 66 | , getSourceFile: mkEffectFn2 \fileName _ -> do 67 | case find (eq fileName <<< _.path) sourceFiles' of 68 | Just { file } -> pure $ opt file 69 | Nothing -> pure undefined 70 | , readFile: mkEffectFn1 \fileName -> do 71 | case find (eq fileName <<< _.path) sourceFiles' of 72 | Just { source } -> pure $ opt source 73 | Nothing -> pure undefined 74 | , useCaseSensitiveFileNames: pure true 75 | , writeFile: mkEffectFn3 (\_ _ _ -> pure unit) 76 | } 77 | host :: BoundedCompilerHost 78 | host = case opts.subhost of 79 | Nothing -> inMemoryHost 80 | Just subhost -> 81 | { fileExists: mkEffectFn1 \p -> do 82 | (||) <$> runEffectFn1 subhost.fileExists p <*> runEffectFn1 inMemoryHost.fileExists p 83 | , directoryExists: opt $ mkEffectFn1 \d -> do 84 | (||) <$> runOptEffectFn1 subhost.directoryExists false d <*> runOptEffectFn1 inMemoryHost.directoryExists false d 85 | , getCanonicalFileName: subhost.getCanonicalFileName 86 | , getDefaultLibFileName: subhost.getDefaultLibFileName 87 | , getNewLine: subhost.getNewLine 88 | , useCaseSensitiveFileNames: subhost.useCaseSensitiveFileNames 89 | , writeFile: subhost.writeFile 90 | , getCurrentDirectory: subhost.getCurrentDirectory 91 | , getDirectories: subhost.getDirectories 92 | , getSourceFile: mkEffectFn2 \p x -> do 93 | runEffectFn2 subhost.getSourceFile p x >>= NoProblem.toMaybe >>> case _ of 94 | Just sourceFile -> pure $ opt sourceFile 95 | Nothing -> runEffectFn2 inMemoryHost.getSourceFile p x 96 | , readFile: mkEffectFn1 \p -> do 97 | runEffectFn1 subhost.readFile p >>= NoProblem.toMaybe >>> case _ of 98 | Just source -> pure $ opt source 99 | Nothing -> runEffectFn1 inMemoryHost.readFile p 100 | } 101 | 102 | pure host 103 | 104 | runOptEffectFn1 :: forall i o. NoProblem.Opt (EffectFn1 i o) -> o -> i -> Effect o 105 | runOptEffectFn1 optFnEff1 def = NoProblem.pseudoMap runEffectFn1 optFnEff1 NoProblem.! (const $ pure def) 106 | 107 | 108 | -------------------------------------------------------------------------------- /src/TypeScript/Testing/InSubdir.purs: -------------------------------------------------------------------------------- 1 | module TypeScript.Testing.Subdir where 2 | 3 | import Prelude 4 | 5 | import Control.Monad.Error.Class (catchError) 6 | import Data.Maybe (Maybe(..)) 7 | import Data.Undefined.NoProblem (opt) 8 | import Data.Undefined.NoProblem (toMaybe) as NoProblem 9 | import Effect (Effect) 10 | import Effect.Uncurried (mkEffectFn1, mkEffectFn2, runEffectFn1, runEffectFn2) 11 | import Node.Buffer (toString) as Buffer 12 | import Node.Encoding (Encoding(..)) 13 | import Node.FS.Stats (isDirectory) 14 | import Node.FS.Sync (exists, readFile, stat) 15 | import TypeScript.Compiler.Parser (SourceCode(..), createSourceFile) 16 | import TypeScript.Compiler.Types (CompilerHost, scriptTarget) 17 | import TypeScript.Testing.BoundedCompilerHost (BoundedCompilerHost) 18 | import TypeScript.Testing.BoundedCompilerHost (toCompilerHost) as BoundedCompilerHost 19 | import TypeScript.Testing.InMemory (Opts, boundedCompilerHost) as InMemory 20 | 21 | newtype DirName = DirName String 22 | 23 | type Opts r = InMemory.Opts (dir :: DirName | r) 24 | 25 | compilerHost :: forall r. Opts r -> Effect CompilerHost 26 | compilerHost opts = BoundedCompilerHost.toCompilerHost <$> boundedCompilerHost opts 27 | 28 | -- TODO: 29 | -- This implementation was provided before we had the ability to 30 | -- provide a subhost to the InMemory implementation. 31 | -- We should check if we can simplify this implementation. 32 | boundedCompilerHost :: forall r. Opts r -> Effect BoundedCompilerHost 33 | boundedCompilerHost opts@{ dir: DirName dirName } = do 34 | let 35 | fullPath p = dirName <> "/" <> p 36 | host <- InMemory.boundedCompilerHost opts 37 | let 38 | readSource p = do 39 | e <- exists p 40 | if e then do 41 | b <- readFile p 42 | source <- Buffer.toString UTF8 b 43 | pure $ Just (SourceCode source) 44 | else do 45 | pure Nothing 46 | 47 | host' :: BoundedCompilerHost 48 | host' = host 49 | { fileExists = mkEffectFn1 \p -> do 50 | (||) <$> exists (fullPath p) <*> runEffectFn1 host.fileExists p 51 | , directoryExists = opt $ mkEffectFn1 \d -> do 52 | res <- (isDirectory <$> stat (fullPath d)) `catchError` \_ -> pure false 53 | case res, NoProblem.toMaybe host.directoryExists of 54 | true, _ -> pure true 55 | _, Just fallback -> runEffectFn1 fallback d 56 | _, Nothing -> pure false 57 | 58 | -- , getCurrentDirectory = opt $ pure dirName 59 | -- , getDirectories = opt $ mkEffectFn1 $ const (pure [ dirName ]) 60 | , getSourceFile = mkEffectFn2 \p x -> do 61 | let 62 | p' = fullPath p 63 | readSource p' >>= case _ of 64 | Just source -> do 65 | sf <- createSourceFile p source scriptTarget."ES5" true 66 | pure $ opt sf 67 | Nothing -> do 68 | runEffectFn2 host.getSourceFile p x 69 | , readFile = mkEffectFn1 \p -> do 70 | readSource (fullPath p) >>= case _ of 71 | Just source -> pure $ opt source 72 | Nothing -> runEffectFn1 host.readFile p 73 | } 74 | pure host' 75 | -------------------------------------------------------------------------------- /src/TypeScript/Testing/Types.purs: -------------------------------------------------------------------------------- 1 | module TypeScript.Testing.Types where 2 | 3 | import Data.Newtype (class Newtype) 4 | import Node.Path (FilePath) 5 | import TypeScript.Compiler.Parser (SourceCode) 6 | 7 | newtype InMemoryFile = InMemoryFile { path :: FilePath, source :: SourceCode } 8 | 9 | derive instance Newtype InMemoryFile _ 10 | 11 | mkInMemoryFile :: FilePath -> SourceCode -> InMemoryFile 12 | mkInMemoryFile name source = InMemoryFile 13 | { path: name 14 | , source: source 15 | } 16 | -------------------------------------------------------------------------------- /test/Codegen.purs: -------------------------------------------------------------------------------- 1 | module Test.Codegen where 2 | 3 | import Prelude 4 | 5 | import Data.Maybe (Maybe(..)) 6 | import TS.Codegen.PS.ModulePath (consDir) 7 | import TS.Codegen.PS.ModulePath (empty) as ModulePath 8 | import TS.Codegen.PS.Types (Fqn(..), fromTsFqn) 9 | import Test.Unit (TestSuite) 10 | import Test.Unit (suite, test) as Test 11 | import Test.Unit.Assert (shouldEqual) 12 | import Tidy.Codegen.Types (SymbolName(..)) 13 | import TypeScript.Compiler.Types (FullyQualifiedName(..)) 14 | 15 | suite :: TestSuite 16 | suite = Test.suite "Codegen" do 17 | Test.test "TS fqn conversion" do 18 | let 19 | tsFqn = FullyQualifiedName """"three/math/Matrix4".Matrix4""" 20 | expected = Just $ Fqn 21 | (consDir "Three" $ consDir "Math" $ consDir "Matrix4" ModulePath.empty) 22 | (SymbolName "Matrix4") 23 | 24 | fromTsFqn tsFqn `shouldEqual` expected 25 | -------------------------------------------------------------------------------- /test/Compile.purs: -------------------------------------------------------------------------------- 1 | module Test.Compile where 2 | 3 | import Prelude 4 | 5 | import Data.List (filter, head) as List 6 | import Data.Map (Map) 7 | import Data.Map (toUnfoldableUnordered) as Map 8 | import Data.Maybe (Maybe(..)) 9 | import Data.String (joinWith) as String 10 | import Data.Tuple (fst, snd) 11 | import Data.Tuple.Nested (type (/\)) 12 | import Data.Undefined.NoProblem (Opt, opt, (!)) 13 | import Data.Undefined.NoProblem.Closed (class Coerce, coerce) as Closed 14 | import Data.Undefined.NoProblem.Closed (coerce) as NoProblem 15 | import Effect (Effect) 16 | import Effect.Aff (Aff) 17 | import Effect.Class (liftEffect) 18 | import Node.Path (FilePath) 19 | import ReadDTS (Params, Declarations, readRootDeclarations) 20 | import TypeScript.Class.Compiler.Program as Program 21 | import TypeScript.Compiler.Parser (SourceCode(..)) 22 | import TypeScript.Compiler.Program (createProgram) 23 | import TypeScript.Compiler.Types (CompilerOptions, FullyQualifiedName(..), ModuleResolutionKind, Program, Typ, moduleKind, scriptTarget) 24 | import TypeScript.Compiler.Types.Nodes as Nodes 25 | import TypeScript.Testing.InMemory (compilerHost) as InMemory 26 | import TypeScript.Testing.Types (InMemoryFile, mkInMemoryFile) 27 | 28 | type SourceLine = String 29 | 30 | mkFile' :: FilePath -> Array SourceLine -> InMemoryFile 31 | mkFile' name = mkInMemoryFile name <<< SourceCode <<< String.joinWith "\n" 32 | 33 | newtype TypeName = TypeName String 34 | 35 | type CompileOpts = 36 | { allowSyntheticDefaultImports :: Opt Boolean 37 | , roots :: Array FilePath 38 | , modules :: Array InMemoryFile 39 | , moduleResolution :: Opt ModuleResolutionKind 40 | , strictNullChecks :: Opt Boolean 41 | } 42 | 43 | compile 44 | :: forall opts 45 | . Closed.Coerce opts CompileOpts 46 | => opts 47 | -> Effect Program 48 | compile opts = do 49 | let 50 | opts' = Closed.coerce opts :: CompileOpts 51 | 52 | compilerOpts :: CompilerOptions 53 | compilerOpts = NoProblem.coerce 54 | { module: moduleKind."ES2015" 55 | , moduleResolution: opts'.moduleResolution 56 | , rootDirs: ["./src"] 57 | , target: scriptTarget."ES5" 58 | , strictNullChecks: opts'.strictNullChecks ! false 59 | , allowSyntheticDefaultImports: opt true 60 | } 61 | 62 | host <- liftEffect $ InMemory.compilerHost 63 | { files: opts'.modules 64 | , defaultLib: Nothing 65 | , subhost: Nothing 66 | } 67 | 68 | -- Experimenting with default compiler host now 69 | -- host <- liftEffect $ Program.createCompilerHost compilerOpts 70 | createProgram opts'.roots compilerOpts (Just host) 71 | 72 | newtype StrictNullChecks = StrictNullChecks Boolean 73 | 74 | -- | Compile source code and extract particular type information. 75 | compileType 76 | :: TypeName 77 | -> SourceCode 78 | -> Aff 79 | { program :: Program 80 | , type :: Maybe 81 | { typ :: Typ () 82 | , params :: Maybe (Params (Typ ())) 83 | } 84 | , decls :: Declarations 85 | } 86 | compileType (TypeName name) source = do 87 | let 88 | rootName = "Root.ts" 89 | fqn = FullyQualifiedName $ "\"Root\"." <> name 90 | 91 | getType 92 | :: forall t 93 | . Map FullyQualifiedName t 94 | -> Maybe (FullyQualifiedName /\ t) 95 | getType = List.head 96 | <<< List.filter (eq fqn <<< fst) 97 | <<< Map.toUnfoldableUnordered 98 | 99 | rootFile = mkInMemoryFile rootName source 100 | program <- liftEffect $ compile 101 | { roots: [ rootName ] 102 | , modules: [ rootFile ] 103 | , strictNullChecks: false 104 | } 105 | let 106 | decls = readRootDeclarations program 107 | pure { type: snd <$> getType decls, program, decls } 108 | -------------------------------------------------------------------------------- /test/Golden/ThreeJs.purs: -------------------------------------------------------------------------------- 1 | module Test.Golden.ThreeJs where 2 | 3 | -- | Testing version: "@types/three": "^0.137.0" 4 | -- | 5 | -- | Currenly testing a subset of three.js modules. 6 | -- | 7 | -- | These files were drastically simplified to cut out 8 | -- | inclusion of additional ts modules: 9 | -- | 10 | -- | * `core/Object3D.d.ts` 11 | -- | * `objects/Sprite.d.ts` 12 | 13 | import Prelude 14 | 15 | import Data.Either (Either(..)) 16 | import Data.Foldable (for_) 17 | import Data.Map as Map 18 | import Data.Maybe (Maybe(..)) 19 | import Data.Tuple.Nested ((/\)) 20 | import Data.Undefined.NoProblem (opt) 21 | import Debug (traceM) 22 | import Effect (Effect) 23 | import Effect.Class (liftEffect) 24 | import Effect.Class.Console (log) 25 | import Node.Path (FilePath) 26 | import ReadDTS.AST (TypeRepr(..)) 27 | import ReadDTS.AST (types) as ReadDTS.AST 28 | import ReadDTS.AST.Printer (pprint) 29 | import Test.Unit (TestSuite, failure) 30 | import Test.Unit (suite, test) as Test 31 | import Test.Unit.Assert (shouldEqual) 32 | import Test.Unit.Console (print) 33 | import TypeScript.Compiler.Program (createProgram) 34 | import TypeScript.Compiler.Types (CompilerOptions, FullyQualifiedName(..), Program, moduleKind, moduleResolutionKind, scriptTarget) 35 | import TypeScript.Testing.Subdir (DirName(..)) 36 | import TypeScript.Testing.Subdir (compilerHost) as InSubdir 37 | import TypeScript.Testing.Types (InMemoryFile) 38 | 39 | type CompileOpts = 40 | { roots :: Array FilePath 41 | , modules :: Array InMemoryFile 42 | , dir :: DirName 43 | } 44 | 45 | compile 46 | :: CompileOpts 47 | -> Effect Program 48 | compile opts = do 49 | let 50 | -- compilerOpts :: CompilerOptions 51 | compilerOpts = 52 | { module: opt moduleKind."ES2015" 53 | , moduleResolution: opt moduleResolutionKind."Bundler" 54 | , noEmitOnError: opt true 55 | , noImplicitAny: opt true 56 | , rootDirs: ["."] 57 | , target: opt scriptTarget."ES5" 58 | , strictNullChecks: false 59 | , allowSyntheticDefaultImports: opt true 60 | } 61 | 62 | -- | We have to load es library because without it we are not 63 | -- | able to handle even `Array` type. 64 | host <- liftEffect $ InSubdir.compilerHost 65 | { files: opts.modules 66 | , defaultLib: Nothing 67 | , dir: opts.dir 68 | , subhost: Nothing 69 | } 70 | createProgram opts.roots compilerOpts (Just host) 71 | 72 | suite :: TestSuite 73 | suite = Test.suite "Golden.ThreeJs" do 74 | -- Test.test "read modules of old three.js" do 75 | -- program <- liftEffect $ compile 76 | -- { dir: DirName "test/Golden/ts" 77 | -- , roots: 78 | -- [ "three/math/Matrix3.d.ts" 79 | -- , "three/math/Vector3.d.ts" 80 | -- ] 81 | -- , modules: [] 82 | -- } 83 | 84 | -- case ReadDTS.AST.types program of 85 | -- Right types -> do 86 | -- traceM $ "Successfully read types:" 87 | -- -- traceM $ types -- Object.fromFoldable types 88 | -- for_ types \(TypeRepr t) -> do 89 | -- --log $ show fqn 90 | -- log $ pprint t 91 | -- Left err -> failure $ "FAILURE: " <> show err 92 | 93 | Test.test "read mesh module" do 94 | program <- liftEffect $ compile 95 | { dir: DirName "test/Golden/ts/three@0.152/src" 96 | , roots: 97 | [ "materials/MeshBasicMaterial.d.ts" 98 | -- , "three@0.156/math/Vector3.d.ts" 99 | ] 100 | , modules: [] 101 | } 102 | 103 | case ReadDTS.AST.types program of 104 | Right types -> do 105 | traceM $ "Successfully read types:" 106 | -- traceM $ types -- Object.fromFoldable types 107 | -- for_ types \(TypeRepr t) -> do 108 | -- --log $ show fqn 109 | -- log $ pprint t 110 | log $ show $ Map.keys types 111 | -- (FullyQualifiedName "MeshBasicMaterialParameters" `Map.lookup` types) `shouldEqual` Nothing 112 | for_ (Map.lookup (FullyQualifiedName "\"materials/MeshBasicMaterial\".MeshBasicMaterialParameters") types) \(TypeRepr t) -> do 113 | log $ pprint t 114 | for_ (Map.lookup (FullyQualifiedName "\"materials/MeshBasicMaterial\".MeshBasicMaterial") types) \(TypeRepr t) -> do 115 | log $ pprint t 116 | Left err -> failure $ "FAILURE: " <> show err 117 | 118 | -------------------------------------------------------------------------------- /test/Golden/ts/three/cameras/Camera.d.ts: -------------------------------------------------------------------------------- 1 | import { Matrix4 } from './../math/Matrix4'; 2 | import { Vector3 } from './../math/Vector3'; 3 | import { Object3D } from './../core/Object3D'; 4 | 5 | // Cameras //////////////////////////////////////////////////////////////////////////////////////// 6 | 7 | /** 8 | * Abstract base class for cameras. This class should always be inherited when you build a new camera. 9 | */ 10 | export class Camera extends Object3D { 11 | /** 12 | * This constructor sets following properties to the correct type: matrixWorldInverse, projectionMatrix and projectionMatrixInverse. 13 | */ 14 | constructor(); 15 | 16 | /** 17 | * This is the inverse of matrixWorld. MatrixWorld contains the Matrix which has the world transform of the Camera. 18 | * @default new THREE.Matrix4() 19 | */ 20 | matrixWorldInverse: Matrix4; 21 | 22 | /** 23 | * This is the matrix which contains the projection. 24 | * @default new THREE.Matrix4() 25 | */ 26 | projectionMatrix: Matrix4; 27 | 28 | /** 29 | * This is the inverse of projectionMatrix. 30 | * @default new THREE.Matrix4() 31 | */ 32 | projectionMatrixInverse: Matrix4; 33 | 34 | readonly isCamera: true; 35 | 36 | getWorldDirection(target: Vector3): Vector3; 37 | 38 | updateMatrixWorld(force?: boolean): void; 39 | } 40 | -------------------------------------------------------------------------------- /test/Golden/ts/three/core/BufferAttribute.d.ts: -------------------------------------------------------------------------------- 1 | import { Usage } from '../constants'; 2 | import { Matrix3 } from './../math/Matrix3'; 3 | import { Matrix4 } from './../math/Matrix4'; 4 | 5 | /** 6 | * see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js|src/core/BufferAttribute.js} 7 | */ 8 | export class BufferAttribute { 9 | constructor(array: ArrayLike, itemSize: number, normalized?: boolean); // array parameter should be TypedArray. 10 | 11 | /** 12 | * @default '' 13 | */ 14 | name: string; 15 | array: ArrayLike; 16 | itemSize: number; 17 | 18 | /** 19 | * @default THREE.StaticDrawUsage 20 | */ 21 | usage: Usage; 22 | 23 | /** 24 | * @default { offset: number; count: number } 25 | */ 26 | updateRange: { offset: number; count: number }; 27 | 28 | /** 29 | * @default 0 30 | */ 31 | version: number; 32 | 33 | /** 34 | * @default false 35 | */ 36 | normalized: boolean; 37 | 38 | /** 39 | * @default 0 40 | */ 41 | count: number; 42 | 43 | set needsUpdate(value: boolean); 44 | 45 | readonly isBufferAttribute: true; 46 | 47 | onUploadCallback: () => void; 48 | onUpload(callback: () => void): this; 49 | setUsage(usage: Usage): this; 50 | clone(): this; 51 | copy(source: BufferAttribute): this; 52 | copyAt(index1: number, attribute: BufferAttribute, index2: number): this; 53 | copyArray(array: ArrayLike): this; 54 | copyColorsArray(colors: Array<{ r: number; g: number; b: number }>): this; 55 | copyVector2sArray(vectors: Array<{ x: number; y: number }>): this; 56 | copyVector3sArray(vectors: Array<{ x: number; y: number; z: number }>): this; 57 | copyVector4sArray(vectors: Array<{ x: number; y: number; z: number; w: number }>): this; 58 | applyMatrix3(m: Matrix3): this; 59 | applyMatrix4(m: Matrix4): this; 60 | applyNormalMatrix(m: Matrix3): this; 61 | transformDirection(m: Matrix4): this; 62 | set(value: ArrayLike | ArrayBufferView, offset?: number): this; 63 | getX(index: number): number; 64 | setX(index: number, x: number): this; 65 | getY(index: number): number; 66 | setY(index: number, y: number): this; 67 | getZ(index: number): number; 68 | setZ(index: number, z: number): this; 69 | getW(index: number): number; 70 | setW(index: number, z: number): this; 71 | setXY(index: number, x: number, y: number): this; 72 | setXYZ(index: number, x: number, y: number, z: number): this; 73 | setXYZW(index: number, x: number, y: number, z: number, w: number): this; 74 | toJSON(): { 75 | itemSize: number; 76 | type: string; 77 | array: number[]; 78 | normalized: boolean; 79 | }; 80 | } 81 | 82 | /** 83 | * @deprecated THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead. 84 | */ 85 | export class Int8Attribute extends BufferAttribute { 86 | constructor(array: any, itemSize: number); 87 | } 88 | 89 | /** 90 | * @deprecated THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead. 91 | */ 92 | export class Uint8Attribute extends BufferAttribute { 93 | constructor(array: any, itemSize: number); 94 | } 95 | 96 | /** 97 | * @deprecated THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead. 98 | */ 99 | export class Uint8ClampedAttribute extends BufferAttribute { 100 | constructor(array: any, itemSize: number); 101 | } 102 | 103 | /** 104 | * @deprecated THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead. 105 | */ 106 | export class Int16Attribute extends BufferAttribute { 107 | constructor(array: any, itemSize: number); 108 | } 109 | 110 | /** 111 | * @deprecated THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead. 112 | */ 113 | export class Uint16Attribute extends BufferAttribute { 114 | constructor(array: any, itemSize: number); 115 | } 116 | 117 | /** 118 | * @deprecated THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead. 119 | */ 120 | export class Int32Attribute extends BufferAttribute { 121 | constructor(array: any, itemSize: number); 122 | } 123 | 124 | /** 125 | * @deprecated THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead. 126 | */ 127 | export class Uint32Attribute extends BufferAttribute { 128 | constructor(array: any, itemSize: number); 129 | } 130 | 131 | /** 132 | * @deprecated THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead. 133 | */ 134 | export class Float32Attribute extends BufferAttribute { 135 | constructor(array: any, itemSize: number); 136 | } 137 | 138 | /** 139 | * @deprecated THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead. 140 | */ 141 | export class Float64Attribute extends BufferAttribute { 142 | constructor(array: any, itemSize: number); 143 | } 144 | 145 | export class Int8BufferAttribute extends BufferAttribute { 146 | constructor( 147 | array: Iterable | ArrayLike | ArrayBuffer | number, 148 | itemSize: number, 149 | normalized?: boolean, 150 | ); 151 | } 152 | 153 | export class Uint8BufferAttribute extends BufferAttribute { 154 | constructor( 155 | array: Iterable | ArrayLike | ArrayBuffer | number, 156 | itemSize: number, 157 | normalized?: boolean, 158 | ); 159 | } 160 | 161 | export class Uint8ClampedBufferAttribute extends BufferAttribute { 162 | constructor( 163 | array: Iterable | ArrayLike | ArrayBuffer | number, 164 | itemSize: number, 165 | normalized?: boolean, 166 | ); 167 | } 168 | 169 | export class Int16BufferAttribute extends BufferAttribute { 170 | constructor( 171 | array: Iterable | ArrayLike | ArrayBuffer | number, 172 | itemSize: number, 173 | normalized?: boolean, 174 | ); 175 | } 176 | 177 | export class Uint16BufferAttribute extends BufferAttribute { 178 | constructor( 179 | array: Iterable | ArrayLike | ArrayBuffer | number, 180 | itemSize: number, 181 | normalized?: boolean, 182 | ); 183 | } 184 | 185 | export class Int32BufferAttribute extends BufferAttribute { 186 | constructor( 187 | array: Iterable | ArrayLike | ArrayBuffer | number, 188 | itemSize: number, 189 | normalized?: boolean, 190 | ); 191 | } 192 | 193 | export class Uint32BufferAttribute extends BufferAttribute { 194 | constructor( 195 | array: Iterable | ArrayLike | ArrayBuffer | number, 196 | itemSize: number, 197 | normalized?: boolean, 198 | ); 199 | } 200 | 201 | export class Float16BufferAttribute extends BufferAttribute { 202 | constructor( 203 | array: Iterable | ArrayLike | ArrayBuffer | number, 204 | itemSize: number, 205 | normalized?: boolean, 206 | ); 207 | } 208 | 209 | export class Float32BufferAttribute extends BufferAttribute { 210 | constructor( 211 | array: Iterable | ArrayLike | ArrayBuffer | number, 212 | itemSize: number, 213 | normalized?: boolean, 214 | ); 215 | } 216 | 217 | export class Float64BufferAttribute extends BufferAttribute { 218 | constructor( 219 | array: Iterable | ArrayLike | ArrayBuffer | number, 220 | itemSize: number, 221 | normalized?: boolean, 222 | ); 223 | } 224 | -------------------------------------------------------------------------------- /test/Golden/ts/three/core/BufferGeometry.d.ts: -------------------------------------------------------------------------------- 1 | import { BufferAttribute } from './BufferAttribute'; 2 | import { Box3 } from './../math/Box3'; 3 | import { Sphere } from './../math/Sphere'; 4 | import { Matrix4 } from './../math/Matrix4'; 5 | import { Quaternion } from './../math/Quaternion'; 6 | import { Vector2 } from './../math/Vector2'; 7 | import { Vector3 } from './../math/Vector3'; 8 | import { EventDispatcher } from './EventDispatcher'; 9 | import { InterleavedBufferAttribute } from './InterleavedBufferAttribute'; 10 | import { BuiltinShaderAttributeName } from '../constants'; 11 | 12 | /** 13 | * This is a superefficent class for geometries because it saves all data in buffers. 14 | * It reduces memory costs and cpu cycles. But it is not as easy to work with because of all the necessary buffer calculations. 15 | * It is mainly interesting when working with static objects. 16 | * 17 | * see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferGeometry.js|src/core/BufferGeometry.js} 18 | */ 19 | export class BufferGeometry extends EventDispatcher { 20 | /** 21 | * This creates a new BufferGeometry. It also sets several properties to an default value. 22 | */ 23 | constructor(); 24 | 25 | static MaxIndex: number; 26 | 27 | /** 28 | * Unique number of this buffergeometry instance 29 | */ 30 | id: number; 31 | uuid: string; 32 | 33 | /** 34 | * @default '' 35 | */ 36 | name: string; 37 | 38 | /** 39 | * @default 'BufferGeometry' 40 | */ 41 | type: string; 42 | 43 | /** 44 | * @default null 45 | */ 46 | index: BufferAttribute | null; 47 | 48 | /** 49 | * @default {} 50 | */ 51 | attributes: { 52 | [name: string]: BufferAttribute | InterleavedBufferAttribute; 53 | }; 54 | 55 | /** 56 | * @default {} 57 | */ 58 | morphAttributes: { 59 | [name: string]: Array; 60 | }; 61 | 62 | /** 63 | * @default false 64 | */ 65 | morphTargetsRelative: boolean; 66 | 67 | /** 68 | * @default [] 69 | */ 70 | groups: Array<{ start: number; count: number; materialIndex?: number | undefined }>; 71 | 72 | /** 73 | * @default null 74 | */ 75 | boundingBox: Box3 | null; 76 | 77 | /** 78 | * @default null 79 | */ 80 | boundingSphere: Sphere | null; 81 | 82 | /** 83 | * @default { start: 0, count: Infinity } 84 | */ 85 | drawRange: { start: number; count: number }; 86 | 87 | /** 88 | * @default {} 89 | */ 90 | userData: { [key: string]: any }; 91 | readonly isBufferGeometry: true; 92 | 93 | getIndex(): BufferAttribute | null; 94 | setIndex(index: BufferAttribute | number[] | null): BufferGeometry; 95 | 96 | setAttribute( 97 | name: BuiltinShaderAttributeName | (string & {}), 98 | attribute: BufferAttribute | InterleavedBufferAttribute, 99 | ): BufferGeometry; 100 | getAttribute(name: BuiltinShaderAttributeName | (string & {})): BufferAttribute | InterleavedBufferAttribute; 101 | deleteAttribute(name: BuiltinShaderAttributeName | (string & {})): BufferGeometry; 102 | hasAttribute(name: BuiltinShaderAttributeName | (string & {})): boolean; 103 | 104 | addGroup(start: number, count: number, materialIndex?: number): void; 105 | clearGroups(): void; 106 | 107 | setDrawRange(start: number, count: number): void; 108 | 109 | /** 110 | * Bakes matrix transform directly into vertex coordinates. 111 | */ 112 | applyMatrix4(matrix: Matrix4): BufferGeometry; 113 | applyQuaternion(q: Quaternion): BufferGeometry; 114 | 115 | rotateX(angle: number): BufferGeometry; 116 | rotateY(angle: number): BufferGeometry; 117 | rotateZ(angle: number): BufferGeometry; 118 | translate(x: number, y: number, z: number): BufferGeometry; 119 | scale(x: number, y: number, z: number): BufferGeometry; 120 | lookAt(v: Vector3): void; 121 | 122 | center(): BufferGeometry; 123 | 124 | setFromPoints(points: Vector3[] | Vector2[]): BufferGeometry; 125 | 126 | /** 127 | * Computes bounding box of the geometry, updating Geometry.boundingBox attribute. 128 | * Bounding boxes aren't computed by default. They need to be explicitly computed, otherwise they are null. 129 | */ 130 | computeBoundingBox(): void; 131 | 132 | /** 133 | * Computes bounding sphere of the geometry, updating Geometry.boundingSphere attribute. 134 | * Bounding spheres aren't' computed by default. They need to be explicitly computed, otherwise they are null. 135 | */ 136 | computeBoundingSphere(): void; 137 | 138 | /** 139 | * Computes and adds tangent attribute to this geometry. 140 | */ 141 | computeTangents(): void; 142 | 143 | /** 144 | * Computes vertex normals by averaging face normals. 145 | */ 146 | computeVertexNormals(): void; 147 | 148 | merge(geometry: BufferGeometry, offset?: number): BufferGeometry; 149 | normalizeNormals(): void; 150 | 151 | toNonIndexed(): BufferGeometry; 152 | 153 | toJSON(): any; 154 | clone(): BufferGeometry; 155 | copy(source: BufferGeometry): this; 156 | 157 | /** 158 | * Disposes the object from memory. 159 | * You need to call this when you want the bufferGeometry removed while the application is running. 160 | */ 161 | dispose(): void; 162 | 163 | /** 164 | * @deprecated Use {@link BufferGeometry#groups .groups} instead. 165 | */ 166 | drawcalls: any; 167 | 168 | /** 169 | * @deprecated Use {@link BufferGeometry#groups .groups} instead. 170 | */ 171 | offsets: any; 172 | 173 | /** 174 | * @deprecated Use {@link BufferGeometry#setIndex .setIndex()} instead. 175 | */ 176 | addIndex(index: any): void; 177 | 178 | /** 179 | * @deprecated Use {@link BufferGeometry#addGroup .addGroup()} instead. 180 | */ 181 | addDrawCall(start: any, count: any, indexOffset?: any): void; 182 | 183 | /** 184 | * @deprecated Use {@link BufferGeometry#clearGroups .clearGroups()} instead. 185 | */ 186 | clearDrawCalls(): void; 187 | 188 | /** 189 | * @deprecated Use {@link BufferGeometry#setAttribute .setAttribute()} instead. 190 | */ 191 | addAttribute(name: string, attribute: BufferAttribute | InterleavedBufferAttribute): BufferGeometry; 192 | addAttribute(name: any, array: any, itemSize: any): any; 193 | 194 | /** 195 | * @deprecated Use {@link BufferGeometry#deleteAttribute .deleteAttribute()} instead. 196 | */ 197 | removeAttribute(name: string): BufferGeometry; 198 | } 199 | -------------------------------------------------------------------------------- /test/Golden/ts/three/core/EventDispatcher.d.ts: -------------------------------------------------------------------------------- 1 | export interface BaseEvent { 2 | type: string; 3 | } 4 | 5 | /** 6 | * Event object. 7 | */ 8 | export interface Event extends BaseEvent { 9 | target?: any; 10 | [attachment: string]: any; 11 | } 12 | export type EventListener = (event: E & { type: T } & { target: U }) => void; 13 | 14 | /** 15 | * JavaScript events for custom objects 16 | * 17 | * @source src/core/EventDispatcher.js 18 | */ 19 | export class EventDispatcher { 20 | /** 21 | * Creates eventDispatcher object. It needs to be call with '.call' to add the functionality to an object. 22 | */ 23 | constructor(); 24 | 25 | /** 26 | * Adds a listener to an event type. 27 | * @param type The type of event to listen to. 28 | * @param listener The function that gets called when the event is fired. 29 | */ 30 | addEventListener(type: T, listener: EventListener): void; 31 | 32 | /** 33 | * Checks if listener is added to an event type. 34 | * @param type The type of event to listen to. 35 | * @param listener The function that gets called when the event is fired. 36 | */ 37 | hasEventListener(type: T, listener: EventListener): boolean; 38 | 39 | /** 40 | * Removes a listener from an event type. 41 | * @param type The type of the listener that gets removed. 42 | * @param listener The listener function that gets removed. 43 | */ 44 | removeEventListener(type: T, listener: EventListener): void; 45 | 46 | /** 47 | * Fire an event type. 48 | * @param type The type of event that gets fired. 49 | */ 50 | dispatchEvent(event: E): void; 51 | } 52 | -------------------------------------------------------------------------------- /test/Golden/ts/three/core/InterleavedBuffer.d.ts: -------------------------------------------------------------------------------- 1 | import { InterleavedBufferAttribute } from './InterleavedBufferAttribute'; 2 | import { Usage } from '../constants'; 3 | 4 | /** 5 | * see {@link https://github.com/mrdoob/three.js/blob/master/src/core/InterleavedBuffer.js|src/core/InterleavedBuffer.js} 6 | */ 7 | export class InterleavedBuffer { 8 | constructor(array: ArrayLike, stride: number); 9 | 10 | array: ArrayLike; 11 | stride: number; 12 | 13 | /** 14 | * @default THREE.StaticDrawUsage 15 | */ 16 | usage: Usage; 17 | 18 | /** 19 | * @default { offset: number; count: number } 20 | */ 21 | updateRange: { offset: number; count: number }; 22 | 23 | /** 24 | * @default 0 25 | */ 26 | version: number; 27 | 28 | length: number; 29 | 30 | /** 31 | * @default 0 32 | */ 33 | count: number; 34 | needsUpdate: boolean; 35 | uuid: string; 36 | 37 | setUsage(usage: Usage): InterleavedBuffer; 38 | clone(data: object): InterleavedBuffer; 39 | copy(source: InterleavedBuffer): this; 40 | copyAt(index1: number, attribute: InterleavedBufferAttribute, index2: number): InterleavedBuffer; 41 | set(value: ArrayLike, index: number): InterleavedBuffer; 42 | toJSON(data: object): { 43 | uuid: string; 44 | buffer: string; 45 | type: string; 46 | stride: number; 47 | }; 48 | } 49 | -------------------------------------------------------------------------------- /test/Golden/ts/three/core/InterleavedBufferAttribute.d.ts: -------------------------------------------------------------------------------- 1 | import { BufferAttribute } from './BufferAttribute'; 2 | import { InterleavedBuffer } from './InterleavedBuffer'; 3 | import { Matrix4 } from './../math/Matrix4'; 4 | import { Matrix } from './../math/Matrix3'; 5 | /** 6 | * see {@link https://github.com/mrdoob/three.js/blob/master/src/core/InterleavedBufferAttribute.js|src/core/InterleavedBufferAttribute.js} 7 | */ 8 | export class InterleavedBufferAttribute { 9 | constructor(interleavedBuffer: InterleavedBuffer, itemSize: number, offset: number, normalized?: boolean); 10 | 11 | /** 12 | * @default '' 13 | */ 14 | name: string; 15 | data: InterleavedBuffer; 16 | itemSize: number; 17 | offset: number; 18 | 19 | /** 20 | * @default false 21 | */ 22 | normalized: boolean; 23 | 24 | get count(): number; 25 | get array(): ArrayLike; 26 | set needsUpdate(value: boolean); 27 | 28 | readonly isInterleavedBufferAttribute: true; 29 | 30 | applyMatrix4(m: Matrix4): this; 31 | clone(data?: object): BufferAttribute; 32 | getX(index: number): number; 33 | setX(index: number, x: number): this; 34 | getY(index: number): number; 35 | setY(index: number, y: number): this; 36 | getZ(index: number): number; 37 | setZ(index: number, z: number): this; 38 | getW(index: number): number; 39 | setW(index: number, z: number): this; 40 | setXY(index: number, x: number, y: number): this; 41 | setXYZ(index: number, x: number, y: number, z: number): this; 42 | setXYZW(index: number, x: number, y: number, z: number, w: number): this; 43 | toJSON(data?: object): { 44 | isInterleavedBufferAttribute: true; 45 | itemSize: number; 46 | data: string; 47 | offset: number; 48 | normalized: boolean; 49 | }; 50 | applyNormalMatrix(matrix: Matrix): this; 51 | transformDirection(matrix: Matrix): this; 52 | } 53 | -------------------------------------------------------------------------------- /test/Golden/ts/three/core/Object3D.d.ts: -------------------------------------------------------------------------------- 1 | export class Object3D { 2 | constructor(); 3 | } 4 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/Box2.d.ts: -------------------------------------------------------------------------------- 1 | import { Vector2 } from './Vector2'; 2 | 3 | // Math ////////////////////////////////////////////////////////////////////////////////// 4 | 5 | export class Box2 { 6 | constructor(min?: Vector2, max?: Vector2); 7 | 8 | /** 9 | * @default new THREE.Vector2( + Infinity, + Infinity ) 10 | */ 11 | min: Vector2; 12 | 13 | /** 14 | * @default new THREE.Vector2( - Infinity, - Infinity ) 15 | */ 16 | max: Vector2; 17 | 18 | set(min: Vector2, max: Vector2): Box2; 19 | setFromPoints(points: Vector2[]): Box2; 20 | setFromCenterAndSize(center: Vector2, size: Vector2): Box2; 21 | clone(): this; 22 | copy(box: Box2): this; 23 | makeEmpty(): Box2; 24 | isEmpty(): boolean; 25 | getCenter(target: Vector2): Vector2; 26 | getSize(target: Vector2): Vector2; 27 | expandByPoint(point: Vector2): Box2; 28 | expandByVector(vector: Vector2): Box2; 29 | expandByScalar(scalar: number): Box2; 30 | containsPoint(point: Vector2): boolean; 31 | containsBox(box: Box2): boolean; 32 | getParameter(point: Vector2, target: Vector2): Vector2; 33 | intersectsBox(box: Box2): boolean; 34 | clampPoint(point: Vector2, target: Vector2): Vector2; 35 | distanceToPoint(point: Vector2): number; 36 | intersect(box: Box2): Box2; 37 | union(box: Box2): Box2; 38 | translate(offset: Vector2): Box2; 39 | equals(box: Box2): boolean; 40 | /** 41 | * @deprecated Use {@link Box2#isEmpty .isEmpty()} instead. 42 | */ 43 | empty(): any; 44 | /** 45 | * @deprecated Use {@link Box2#intersectsBox .intersectsBox()} instead. 46 | */ 47 | isIntersectionBox(b: any): any; 48 | } 49 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/Box3.d.ts: -------------------------------------------------------------------------------- 1 | import { BufferAttribute } from './../core/BufferAttribute'; 2 | import { Vector3 } from './Vector3'; 3 | import { Object3D } from './../core/Object3D'; 4 | import { Sphere } from './Sphere'; 5 | import { Plane } from './Plane'; 6 | import { Matrix4 } from './Matrix4'; 7 | import { Triangle } from './Triangle'; 8 | 9 | export class Box3 { 10 | constructor(min?: Vector3, max?: Vector3); 11 | 12 | /** 13 | * @default new THREE.Vector3( + Infinity, + Infinity, + Infinity ) 14 | */ 15 | min: Vector3; 16 | 17 | /** 18 | * @default new THREE.Vector3( - Infinity, - Infinity, - Infinity ) 19 | */ 20 | max: Vector3; 21 | readonly isBox3: true; 22 | 23 | set(min: Vector3, max: Vector3): this; 24 | setFromArray(array: ArrayLike): this; 25 | setFromBufferAttribute(bufferAttribute: BufferAttribute): this; 26 | setFromPoints(points: Vector3[]): this; 27 | setFromCenterAndSize(center: Vector3, size: Vector3): this; 28 | setFromObject(object: Object3D, precise?: boolean): this; 29 | clone(): this; 30 | copy(box: Box3): this; 31 | makeEmpty(): this; 32 | isEmpty(): boolean; 33 | getCenter(target: Vector3): Vector3; 34 | getSize(target: Vector3): Vector3; 35 | expandByPoint(point: Vector3): this; 36 | expandByVector(vector: Vector3): this; 37 | expandByScalar(scalar: number): this; 38 | expandByObject(object: Object3D, precise?: boolean): this; 39 | containsPoint(point: Vector3): boolean; 40 | containsBox(box: Box3): boolean; 41 | getParameter(point: Vector3, target: Vector3): Vector3; 42 | intersectsBox(box: Box3): boolean; 43 | intersectsSphere(sphere: Sphere): boolean; 44 | intersectsPlane(plane: Plane): boolean; 45 | intersectsTriangle(triangle: Triangle): boolean; 46 | clampPoint(point: Vector3, target: Vector3): Vector3; 47 | distanceToPoint(point: Vector3): number; 48 | getBoundingSphere(target: Sphere): Sphere; 49 | intersect(box: Box3): this; 50 | union(box: Box3): this; 51 | applyMatrix4(matrix: Matrix4): this; 52 | translate(offset: Vector3): this; 53 | equals(box: Box3): boolean; 54 | /** 55 | * @deprecated Use {@link Box3#isEmpty .isEmpty()} instead. 56 | */ 57 | empty(): any; 58 | /** 59 | * @deprecated Use {@link Box3#intersectsBox .intersectsBox()} instead. 60 | */ 61 | isIntersectionBox(b: any): any; 62 | /** 63 | * @deprecated Use {@link Box3#intersectsSphere .intersectsSphere()} instead. 64 | */ 65 | isIntersectionSphere(s: any): any; 66 | } 67 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/Color.d.ts: -------------------------------------------------------------------------------- 1 | import { ColorRepresentation } from '../utils'; 2 | import { BufferAttribute } from './../core/BufferAttribute'; 3 | 4 | export interface HSL { 5 | h: number; 6 | s: number; 7 | l: number; 8 | } 9 | 10 | export function SRGBToLinear(c: number): number; 11 | 12 | /** 13 | * Represents a color. See also {@link ColorUtils}. 14 | * 15 | * see {@link https://github.com/mrdoob/three.js/blob/master/src/math/Color.js|src/math/Color.js} 16 | * 17 | * @example 18 | * const color = new THREE.Color( 0xff0000 ); 19 | */ 20 | export class Color { 21 | constructor(color?: ColorRepresentation); 22 | constructor(r: number, g: number, b: number); 23 | 24 | readonly isColor: true; 25 | 26 | /** 27 | * Red channel value between 0 and 1. Default is 1. 28 | * @default 1 29 | */ 30 | r: number; 31 | 32 | /** 33 | * Green channel value between 0 and 1. Default is 1. 34 | * @default 1 35 | */ 36 | g: number; 37 | 38 | /** 39 | * Blue channel value between 0 and 1. Default is 1. 40 | * @default 1 41 | */ 42 | b: number; 43 | 44 | set(color: ColorRepresentation): Color; 45 | setScalar(scalar: number): Color; 46 | setHex(hex: number): Color; 47 | 48 | /** 49 | * Sets this color from RGB values. 50 | * @param r Red channel value between 0 and 1. 51 | * @param g Green channel value between 0 and 1. 52 | * @param b Blue channel value between 0 and 1. 53 | */ 54 | setRGB(r: number, g: number, b: number): Color; 55 | 56 | /** 57 | * Sets this color from HSL values. 58 | * Based on MochiKit implementation by Bob Ippolito. 59 | * 60 | * @param h Hue channel value between 0 and 1. 61 | * @param s Saturation value channel between 0 and 1. 62 | * @param l Value channel value between 0 and 1. 63 | */ 64 | setHSL(h: number, s: number, l: number): Color; 65 | 66 | /** 67 | * Sets this color from a CSS context style string. 68 | * @param contextStyle Color in CSS context style format. 69 | */ 70 | setStyle(style: string): Color; 71 | 72 | /** 73 | * Sets this color from a color name. 74 | * Faster than {@link Color#setStyle .setStyle()} method if you don't need the other CSS-style formats. 75 | * @param style Color name in X11 format. 76 | */ 77 | setColorName(style: string): Color; 78 | 79 | /** 80 | * Clones this color. 81 | */ 82 | clone(): this; 83 | 84 | /** 85 | * Copies given color. 86 | * @param color Color to copy. 87 | */ 88 | copy(color: Color): this; 89 | 90 | /** 91 | * Copies given color making conversion from sRGB to linear space. 92 | * @param color Color to copy. 93 | */ 94 | copySRGBToLinear(color: Color): Color; 95 | 96 | /** 97 | * Copies given color making conversion from linear to sRGB space. 98 | * @param color Color to copy. 99 | */ 100 | copyLinearToSRGB(color: Color): Color; 101 | 102 | /** 103 | * Converts this color from sRGB to linear space. 104 | */ 105 | convertSRGBToLinear(): Color; 106 | 107 | /** 108 | * Converts this color from linear to sRGB space. 109 | */ 110 | convertLinearToSRGB(): Color; 111 | 112 | /** 113 | * Returns the hexadecimal value of this color. 114 | */ 115 | getHex(): number; 116 | 117 | /** 118 | * Returns the string formated hexadecimal value of this color. 119 | */ 120 | getHexString(): string; 121 | 122 | getHSL(target: HSL): HSL; 123 | 124 | /** 125 | * Returns the value of this color in CSS context style. 126 | * Example: rgb(r, g, b) 127 | */ 128 | getStyle(): string; 129 | 130 | offsetHSL(h: number, s: number, l: number): this; 131 | 132 | add(color: Color): this; 133 | addColors(color1: Color, color2: Color): this; 134 | addScalar(s: number): this; 135 | sub(color: Color): this; 136 | multiply(color: Color): this; 137 | multiplyScalar(s: number): this; 138 | lerp(color: Color, alpha: number): this; 139 | lerpColors(color1: Color, color2: Color, alpha: number): this; 140 | lerpHSL(color: Color, alpha: number): this; 141 | equals(color: Color): boolean; 142 | 143 | /** 144 | * Sets this color's red, green and blue value from the provided array or array-like. 145 | * @param array the source array or array-like. 146 | * @param offset (optional) offset into the array-like. Default is 0. 147 | */ 148 | fromArray(array: number[] | ArrayLike, offset?: number): this; 149 | 150 | /** 151 | * Returns an array [red, green, blue], or copies red, green and blue into the provided array. 152 | * @param array (optional) array to store the color to. If this is not provided, a new array will be created. 153 | * @param offset (optional) optional offset into the array. 154 | * @return The created or provided array. 155 | */ 156 | toArray(array?: number[], offset?: number): number[]; 157 | 158 | /** 159 | * Copies red, green and blue into the provided array-like. 160 | * @param array array-like to store the color to. 161 | * @param offset (optional) optional offset into the array-like. 162 | * @return The provided array-like. 163 | */ 164 | toArray(xyz: ArrayLike, offset?: number): ArrayLike; 165 | 166 | fromBufferAttribute(attribute: BufferAttribute, index: number): this; 167 | 168 | /** 169 | * List of X11 color names. 170 | */ 171 | static NAMES: Record; 172 | } 173 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/Cylindrical.d.ts: -------------------------------------------------------------------------------- 1 | import { Vector3 } from './Vector3'; 2 | 3 | export class Cylindrical { 4 | constructor(radius?: number, theta?: number, y?: number); 5 | 6 | /** 7 | * @default 1 8 | */ 9 | radius: number; 10 | 11 | /** 12 | * @default 0 13 | */ 14 | theta: number; 15 | 16 | /** 17 | * @default 0 18 | */ 19 | y: number; 20 | 21 | clone(): this; 22 | copy(other: Cylindrical): this; 23 | set(radius: number, theta: number, y: number): this; 24 | setFromVector3(vec3: Vector3): this; 25 | setFromCartesianCoords(x: number, y: number, z: number): this; 26 | } 27 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/Euler.d.ts: -------------------------------------------------------------------------------- 1 | import { Matrix4 } from './Matrix4'; 2 | import { Quaternion } from './Quaternion'; 3 | import { Vector3 } from './Vector3'; 4 | 5 | export class Euler { 6 | constructor(x?: number, y?: number, z?: number, order?: string); 7 | 8 | /** 9 | * @default 0 10 | */ 11 | x: number; 12 | 13 | /** 14 | * @default 0 15 | */ 16 | y: number; 17 | 18 | /** 19 | * @default 0 20 | */ 21 | z: number; 22 | 23 | /** 24 | * @default THREE.Euler.DefaultOrder 25 | */ 26 | order: string; 27 | readonly isEuler: true; 28 | 29 | _onChangeCallback: () => void; 30 | 31 | set(x: number, y: number, z: number, order?: string): Euler; 32 | clone(): this; 33 | copy(euler: Euler): this; 34 | setFromRotationMatrix(m: Matrix4, order?: string, update?: boolean): Euler; 35 | setFromQuaternion(q: Quaternion, order?: string, update?: boolean): Euler; 36 | setFromVector3(v: Vector3, order?: string): Euler; 37 | reorder(newOrder: string): Euler; 38 | equals(euler: Euler): boolean; 39 | fromArray(xyzo: any[]): Euler; 40 | toArray(array?: number[], offset?: number): number[]; 41 | toVector3(optionalResult?: Vector3): Vector3; 42 | _onChange(callback: () => void): this; 43 | 44 | static RotationOrders: string[]; 45 | static DefaultOrder: string; 46 | } 47 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/Frustum.d.ts: -------------------------------------------------------------------------------- 1 | import { Plane } from './Plane'; 2 | import { Matrix4 } from './Matrix4'; 3 | import { Object3D } from './../core/Object3D'; 4 | import { Sprite } from './../objects/Sprite'; 5 | import { Sphere } from './Sphere'; 6 | import { Box3 } from './Box3'; 7 | import { Vector3 } from './Vector3'; 8 | 9 | /** 10 | * Frustums are used to determine what is inside the camera's field of view. They help speed up the rendering process. 11 | */ 12 | export class Frustum { 13 | constructor(p0?: Plane, p1?: Plane, p2?: Plane, p3?: Plane, p4?: Plane, p5?: Plane); 14 | 15 | /** 16 | * Array of 6 vectors. 17 | */ 18 | planes: Plane[]; 19 | 20 | set(p0: Plane, p1: Plane, p2: Plane, p3: Plane, p4: Plane, p5: Plane): Frustum; 21 | clone(): this; 22 | copy(frustum: Frustum): this; 23 | setFromProjectionMatrix(m: Matrix4): this; 24 | intersectsObject(object: Object3D): boolean; 25 | intersectsSprite(sprite: Sprite): boolean; 26 | intersectsSphere(sphere: Sphere): boolean; 27 | intersectsBox(box: Box3): boolean; 28 | containsPoint(point: Vector3): boolean; 29 | } 30 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/Interpolant.d.ts: -------------------------------------------------------------------------------- 1 | export abstract class Interpolant { 2 | constructor(parameterPositions: any, sampleValues: any, sampleSize: number, resultBuffer?: any); 3 | 4 | parameterPositions: any; 5 | sampleValues: any; 6 | valueSize: number; 7 | resultBuffer: any; 8 | 9 | evaluate(time: number): any; 10 | } 11 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/Line3.d.ts: -------------------------------------------------------------------------------- 1 | import { Vector3 } from './Vector3'; 2 | import { Matrix4 } from './Matrix4'; 3 | 4 | export class Line3 { 5 | constructor(start?: Vector3, end?: Vector3); 6 | 7 | /** 8 | * @default new THREE.Vector3() 9 | */ 10 | start: Vector3; 11 | 12 | /** 13 | * @default new THREE.Vector3() 14 | */ 15 | end: Vector3; 16 | 17 | set(start?: Vector3, end?: Vector3): Line3; 18 | clone(): this; 19 | copy(line: Line3): this; 20 | getCenter(target: Vector3): Vector3; 21 | delta(target: Vector3): Vector3; 22 | distanceSq(): number; 23 | distance(): number; 24 | at(t: number, target: Vector3): Vector3; 25 | closestPointToPointParameter(point: Vector3, clampToLine?: boolean): number; 26 | closestPointToPoint(point: Vector3, clampToLine: boolean, target: Vector3): Vector3; 27 | applyMatrix4(matrix: Matrix4): Line3; 28 | equals(line: Line3): boolean; 29 | } 30 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/MathUtils.d.ts: -------------------------------------------------------------------------------- 1 | import { Quaternion } from './Quaternion'; 2 | 3 | /** 4 | * @see {@link https://github.com/mrdoob/three.js/blob/master/src/math/MathUtils.js|src/math/MathUtils.js} 5 | */ 6 | 7 | export const DEG2RAD: number; 8 | export const RAD2DEG: number; 9 | 10 | export function generateUUID(): string; 11 | 12 | /** 13 | * Clamps the x to be between a and b. 14 | * 15 | * @param value Value to be clamped. 16 | * @param min Minimum value 17 | * @param max Maximum value. 18 | */ 19 | export function clamp(value: number, min: number, max: number): number; 20 | export function euclideanModulo(n: number, m: number): number; 21 | 22 | /** 23 | * Linear mapping of x from range [a1, a2] to range [b1, b2]. 24 | * 25 | * @param x Value to be mapped. 26 | * @param a1 Minimum value for range A. 27 | * @param a2 Maximum value for range A. 28 | * @param b1 Minimum value for range B. 29 | * @param b2 Maximum value for range B. 30 | */ 31 | export function mapLinear(x: number, a1: number, a2: number, b1: number, b2: number): number; 32 | 33 | export function smoothstep(x: number, min: number, max: number): number; 34 | 35 | export function smootherstep(x: number, min: number, max: number): number; 36 | 37 | /** 38 | * Random float from 0 to 1 with 16 bits of randomness. 39 | * Standard Math.random() creates repetitive patterns when applied over larger space. 40 | * 41 | * @deprecated Use {@link Math#random Math.random()} 42 | */ 43 | export function random16(): number; 44 | 45 | /** 46 | * Random integer from low to high interval. 47 | */ 48 | export function randInt(low: number, high: number): number; 49 | 50 | /** 51 | * Random float from low to high interval. 52 | */ 53 | export function randFloat(low: number, high: number): number; 54 | 55 | /** 56 | * Random float from - range / 2 to range / 2 interval. 57 | */ 58 | export function randFloatSpread(range: number): number; 59 | 60 | /** 61 | * Deterministic pseudo-random float in the interval [ 0, 1 ]. 62 | */ 63 | export function seededRandom(seed?: number): number; 64 | 65 | export function degToRad(degrees: number): number; 66 | 67 | export function radToDeg(radians: number): number; 68 | 69 | export function isPowerOfTwo(value: number): boolean; 70 | 71 | export function inverseLerp(x: number, y: number, t: number): number; 72 | 73 | /** 74 | * Returns a value linearly interpolated from two known points based 75 | * on the given interval - t = 0 will return x and t = 1 will return y. 76 | * 77 | * @param x Start point. 78 | * @param y End point. 79 | * @param t interpolation factor in the closed interval [0, 1] 80 | */ 81 | export function lerp(x: number, y: number, t: number): number; 82 | 83 | /** 84 | * Smoothly interpolate a number from x toward y in a spring-like 85 | * manner using the dt to maintain frame rate independent movement. 86 | * 87 | * @param x Current point. 88 | * @param y Target point. 89 | * @param lambda A higher lambda value will make the movement more sudden, and a lower value will make the movement more gradual. 90 | * @param dt Delta time in seconds. 91 | */ 92 | export function damp(x: number, y: number, lambda: number, dt: number): number; 93 | 94 | /** 95 | * Returns a value that alternates between 0 and length. 96 | * 97 | * @param x The value to pingpong. 98 | * @param length The positive value the export function will pingpong to. Default is 1. 99 | */ 100 | export function pingpong(x: number, length?: number): number; 101 | 102 | /** 103 | * @deprecated Use {@link Math#floorPowerOfTwo .floorPowerOfTwo()} 104 | */ 105 | export function nearestPowerOfTwo(value: number): number; 106 | 107 | /** 108 | * @deprecated Use {@link Math#ceilPowerOfTwo .ceilPowerOfTwo()} 109 | */ 110 | export function nextPowerOfTwo(value: number): number; 111 | 112 | export function floorPowerOfTwo(value: number): number; 113 | 114 | export function ceilPowerOfTwo(value: number): number; 115 | 116 | export function setQuaternionFromProperEuler(q: Quaternion, a: number, b: number, c: number, order: string): void; 117 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/Matrix3.d.ts: -------------------------------------------------------------------------------- 1 | import { Matrix4 } from './Matrix4'; 2 | import { Vector3 } from './Vector3'; 3 | 4 | export type Matrix3Tuple = [number, number, number, number, number, number, number, number, number]; 5 | 6 | /** 7 | * ( interface Matrix ) 8 | */ 9 | export interface Matrix { 10 | /** 11 | * Array with matrix values. 12 | */ 13 | elements: number[]; 14 | 15 | /** 16 | * identity():T; 17 | */ 18 | identity(): Matrix; 19 | 20 | /** 21 | * copy(m:T):T; 22 | */ 23 | copy(m: this): this; 24 | 25 | /** 26 | * multiplyScalar(s:number):T; 27 | */ 28 | multiplyScalar(s: number): Matrix; 29 | 30 | determinant(): number; 31 | 32 | /** 33 | * transpose():T; 34 | */ 35 | transpose(): Matrix; 36 | 37 | /** 38 | * invert():T; 39 | */ 40 | invert(): Matrix; 41 | 42 | /** 43 | * clone():T; 44 | */ 45 | clone(): Matrix; 46 | } 47 | 48 | /** 49 | * ( class Matrix3 implements Matrix ) 50 | */ 51 | export class Matrix3 implements Matrix { 52 | /** 53 | * Creates an identity matrix. 54 | */ 55 | constructor(); 56 | 57 | /** 58 | * Array with matrix values. 59 | * @default [1, 0, 0, 0, 1, 0, 0, 0, 1] 60 | */ 61 | elements: number[]; 62 | 63 | set( 64 | n11: number, 65 | n12: number, 66 | n13: number, 67 | n21: number, 68 | n22: number, 69 | n23: number, 70 | n31: number, 71 | n32: number, 72 | n33: number, 73 | ): Matrix3; 74 | identity(): Matrix3; 75 | clone(): this; 76 | copy(m: Matrix3): this; 77 | extractBasis(xAxis: Vector3, yAxis: Vector3, zAxis: Vector3): Matrix3; 78 | setFromMatrix4(m: Matrix4): Matrix3; 79 | multiplyScalar(s: number): Matrix3; 80 | determinant(): number; 81 | 82 | /** 83 | * Inverts this matrix in place. 84 | */ 85 | invert(): Matrix3; 86 | 87 | /** 88 | * Transposes this matrix in place. 89 | */ 90 | transpose(): Matrix3; 91 | getNormalMatrix(matrix4: Matrix4): Matrix3; 92 | 93 | /** 94 | * Transposes this matrix into the supplied array r, and returns itself. 95 | */ 96 | transposeIntoArray(r: number[]): Matrix3; 97 | 98 | setUvTransform(tx: number, ty: number, sx: number, sy: number, rotation: number, cx: number, cy: number): Matrix3; 99 | 100 | scale(sx: number, sy: number): Matrix3; 101 | 102 | rotate(theta: number): Matrix3; 103 | 104 | translate(tx: number, ty: number): Matrix3; 105 | 106 | equals(matrix: Matrix3): boolean; 107 | 108 | /** 109 | * Sets the values of this matrix from the provided array or array-like. 110 | * @param array the source array or array-like. 111 | * @param offset (optional) offset into the array-like. Default is 0. 112 | */ 113 | fromArray(array: number[] | ArrayLike, offset?: number): Matrix3; 114 | 115 | /** 116 | * Returns an array with the values of this matrix, or copies them into the provided array. 117 | * @param array (optional) array to store the matrix to. If this is not provided, a new array will be created. 118 | * @param offset (optional) optional offset into the array. 119 | * @return The created or provided array. 120 | */ 121 | toArray(array?: number[], offset?: number): number[]; 122 | toArray(array?: Matrix3Tuple, offset?: 0): Matrix3Tuple; 123 | 124 | /** 125 | * Copies he values of this matrix into the provided array-like. 126 | * @param array array-like to store the matrix to. 127 | * @param offset (optional) optional offset into the array-like. 128 | * @return The provided array-like. 129 | */ 130 | toArray(array?: ArrayLike, offset?: number): ArrayLike; 131 | 132 | /** 133 | * Multiplies this matrix by m. 134 | */ 135 | multiply(m: Matrix3): Matrix3; 136 | 137 | premultiply(m: Matrix3): Matrix3; 138 | 139 | /** 140 | * Sets this matrix to a x b. 141 | */ 142 | multiplyMatrices(a: Matrix3, b: Matrix3): Matrix3; 143 | 144 | /** 145 | * @deprecated Use {@link Vector3.applyMatrix3 vector.applyMatrix3( matrix )} instead. 146 | */ 147 | multiplyVector3(vector: Vector3): any; 148 | 149 | /** 150 | * @deprecated This method has been removed completely. 151 | */ 152 | multiplyVector3Array(a: any): any; 153 | 154 | /** 155 | * @deprecated Use {@link Matrix3#invert .invert()} instead. 156 | */ 157 | getInverse(matrix: Matrix4, throwOnDegenerate?: boolean): Matrix3; 158 | getInverse(matrix: Matrix): Matrix; 159 | 160 | /** 161 | * @deprecated Use {@link Matrix3#toArray .toArray()} instead. 162 | */ 163 | flattenToArrayOffset(array: number[], offset: number): number[]; 164 | } 165 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/Plane.d.ts: -------------------------------------------------------------------------------- 1 | import { Vector3 } from './Vector3'; 2 | import { Sphere } from './Sphere'; 3 | import { Line3 } from './Line3'; 4 | import { Box3 } from './Box3'; 5 | import { Matrix4 } from './Matrix4'; 6 | import { Matrix3 } from './Matrix3'; 7 | 8 | export class Plane { 9 | constructor(normal?: Vector3, constant?: number); 10 | 11 | /** 12 | * @default new THREE.Vector3( 1, 0, 0 ) 13 | */ 14 | normal: Vector3; 15 | 16 | /** 17 | * @default 0 18 | */ 19 | constant: number; 20 | 21 | readonly isPlane: true; 22 | 23 | set(normal: Vector3, constant: number): Plane; 24 | setComponents(x: number, y: number, z: number, w: number): Plane; 25 | setFromNormalAndCoplanarPoint(normal: Vector3, point: Vector3): Plane; 26 | setFromCoplanarPoints(a: Vector3, b: Vector3, c: Vector3): Plane; 27 | clone(): this; 28 | copy(plane: Plane): this; 29 | normalize(): Plane; 30 | negate(): Plane; 31 | distanceToPoint(point: Vector3): number; 32 | distanceToSphere(sphere: Sphere): number; 33 | projectPoint(point: Vector3, target: Vector3): Vector3; 34 | orthoPoint(point: Vector3, target: Vector3): Vector3; 35 | intersectLine(line: Line3, target: Vector3): Vector3 | null; 36 | intersectsLine(line: Line3): boolean; 37 | intersectsBox(box: Box3): boolean; 38 | intersectsSphere(sphere: Sphere): boolean; 39 | coplanarPoint(target: Vector3): Vector3; 40 | applyMatrix4(matrix: Matrix4, optionalNormalMatrix?: Matrix3): Plane; 41 | translate(offset: Vector3): Plane; 42 | equals(plane: Plane): boolean; 43 | 44 | /** 45 | * @deprecated Use {@link Plane#intersectsLine .intersectsLine()} instead. 46 | */ 47 | isIntersectionLine(l: any): any; 48 | } 49 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/Quaternion.d.ts: -------------------------------------------------------------------------------- 1 | import { Euler } from './Euler'; 2 | import { Vector3 } from './Vector3'; 3 | import { Matrix4 } from './Matrix4'; 4 | 5 | /** 6 | * Implementation of a quaternion. This is used for rotating things without incurring in the dreaded gimbal lock issue, amongst other advantages. 7 | * 8 | * @example 9 | * const quaternion = new THREE.Quaternion(); 10 | * quaternion.setFromAxisAngle( new THREE.Vector3( 0, 1, 0 ), Math.PI / 2 ); 11 | * const vector = new THREE.Vector3( 1, 0, 0 ); 12 | * vector.applyQuaternion( quaternion ); 13 | */ 14 | export class Quaternion { 15 | /** 16 | * @param x x coordinate 17 | * @param y y coordinate 18 | * @param z z coordinate 19 | * @param w w coordinate 20 | */ 21 | constructor(x?: number, y?: number, z?: number, w?: number); 22 | 23 | /** 24 | * @default 0 25 | */ 26 | x: number; 27 | 28 | /** 29 | * @default 0 30 | */ 31 | y: number; 32 | 33 | /** 34 | * @default 0 35 | */ 36 | z: number; 37 | 38 | /** 39 | * @default 1 40 | */ 41 | w: number; 42 | readonly isQuaternion: true; 43 | 44 | /** 45 | * Sets values of this quaternion. 46 | */ 47 | set(x: number, y: number, z: number, w: number): Quaternion; 48 | 49 | /** 50 | * Clones this quaternion. 51 | */ 52 | clone(): this; 53 | 54 | /** 55 | * Copies values of q to this quaternion. 56 | */ 57 | copy(q: Quaternion): this; 58 | 59 | /** 60 | * Sets this quaternion from rotation specified by Euler angles. 61 | */ 62 | setFromEuler(euler: Euler, update?: boolean): Quaternion; 63 | 64 | /** 65 | * Sets this quaternion from rotation specified by axis and angle. 66 | * Adapted from http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm. 67 | * Axis have to be normalized, angle is in radians. 68 | */ 69 | setFromAxisAngle(axis: Vector3, angle: number): Quaternion; 70 | 71 | /** 72 | * Sets this quaternion from rotation component of m. Adapted from http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm. 73 | */ 74 | setFromRotationMatrix(m: Matrix4): Quaternion; 75 | setFromUnitVectors(vFrom: Vector3, vTo: Vector3): Quaternion; 76 | angleTo(q: Quaternion): number; 77 | rotateTowards(q: Quaternion, step: number): Quaternion; 78 | 79 | identity(): Quaternion; 80 | 81 | /** 82 | * Inverts this quaternion. 83 | */ 84 | invert(): Quaternion; 85 | 86 | conjugate(): Quaternion; 87 | dot(v: Quaternion): number; 88 | lengthSq(): number; 89 | 90 | /** 91 | * Computes length of this quaternion. 92 | */ 93 | length(): number; 94 | 95 | /** 96 | * Normalizes this quaternion. 97 | */ 98 | normalize(): Quaternion; 99 | 100 | /** 101 | * Multiplies this quaternion by b. 102 | */ 103 | multiply(q: Quaternion): Quaternion; 104 | premultiply(q: Quaternion): Quaternion; 105 | 106 | /** 107 | * Sets this quaternion to a x b 108 | * Adapted from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm. 109 | */ 110 | multiplyQuaternions(a: Quaternion, b: Quaternion): Quaternion; 111 | 112 | slerp(qb: Quaternion, t: number): Quaternion; 113 | slerpQuaternions(qa: Quaternion, qb: Quaternion, t: number): Quaternion; 114 | equals(v: Quaternion): boolean; 115 | 116 | /** 117 | * Sets this quaternion's x, y, z and w value from the provided array or array-like. 118 | * @param array the source array or array-like. 119 | * @param offset (optional) offset into the array. Default is 0. 120 | */ 121 | fromArray(array: number[] | ArrayLike, offset?: number): this; 122 | 123 | /** 124 | * Returns an array [x, y, z, w], or copies x, y, z and w into the provided array. 125 | * @param array (optional) array to store the quaternion to. If this is not provided, a new array will be created. 126 | * @param offset (optional) optional offset into the array. 127 | * @return The created or provided array. 128 | */ 129 | toArray(array?: number[], offset?: number): number[]; 130 | 131 | /** 132 | * Copies x, y, z and w into the provided array-like. 133 | * @param array array-like to store the quaternion to. 134 | * @param offset (optional) optional offset into the array. 135 | * @return The provided array-like. 136 | */ 137 | toArray(array: ArrayLike, offset?: number): ArrayLike; 138 | 139 | _onChange(callback: () => void): Quaternion; 140 | _onChangeCallback: () => void; 141 | 142 | static slerpFlat( 143 | dst: number[], 144 | dstOffset: number, 145 | src0: number[], 146 | srcOffset: number, 147 | src1: number[], 148 | stcOffset1: number, 149 | t: number, 150 | ): Quaternion; 151 | 152 | static multiplyQuaternionsFlat( 153 | dst: number[], 154 | dstOffset: number, 155 | src0: number[], 156 | srcOffset: number, 157 | src1: number[], 158 | stcOffset1: number, 159 | ): number[]; 160 | 161 | /** 162 | * @deprecated Use qm.slerpQuaternions( qa, qb, t ) instead.. 163 | */ 164 | static slerp(qa: Quaternion, qb: Quaternion, qm: Quaternion, t: number): number; 165 | 166 | /** 167 | * @deprecated Use {@link Vector#applyQuaternion vector.applyQuaternion( quaternion )} instead. 168 | */ 169 | multiplyVector3(v: any): any; 170 | 171 | /** 172 | * @deprecated Use {@link Quaternion#invert .invert()} instead. 173 | */ 174 | inverse(): Quaternion; 175 | 176 | random(): Quaternion; 177 | } 178 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/Ray.d.ts: -------------------------------------------------------------------------------- 1 | import { Vector3 } from './Vector3'; 2 | import { Sphere } from './Sphere'; 3 | import { Plane } from './Plane'; 4 | import { Box3 } from './Box3'; 5 | import { Matrix4 } from './Matrix4'; 6 | 7 | export class Ray { 8 | constructor(origin?: Vector3, direction?: Vector3); 9 | 10 | /** 11 | * @default new THREE.Vector3() 12 | */ 13 | origin: Vector3; 14 | 15 | /** 16 | * @default new THREE.Vector3( 0, 0, - 1 ) 17 | */ 18 | direction: Vector3; 19 | 20 | set(origin: Vector3, direction: Vector3): Ray; 21 | clone(): this; 22 | copy(ray: Ray): this; 23 | at(t: number, target: Vector3): Vector3; 24 | lookAt(v: Vector3): Ray; 25 | recast(t: number): Ray; 26 | closestPointToPoint(point: Vector3, target: Vector3): Vector3; 27 | distanceToPoint(point: Vector3): number; 28 | distanceSqToPoint(point: Vector3): number; 29 | distanceSqToSegment( 30 | v0: Vector3, 31 | v1: Vector3, 32 | optionalPointOnRay?: Vector3, 33 | optionalPointOnSegment?: Vector3, 34 | ): number; 35 | intersectSphere(sphere: Sphere, target: Vector3): Vector3 | null; 36 | intersectsSphere(sphere: Sphere): boolean; 37 | distanceToPlane(plane: Plane): number; 38 | intersectPlane(plane: Plane, target: Vector3): Vector3 | null; 39 | intersectsPlane(plane: Plane): boolean; 40 | intersectBox(box: Box3, target: Vector3): Vector3 | null; 41 | intersectsBox(box: Box3): boolean; 42 | intersectTriangle(a: Vector3, b: Vector3, c: Vector3, backfaceCulling: boolean, target: Vector3): Vector3 | null; 43 | applyMatrix4(matrix4: Matrix4): Ray; 44 | equals(ray: Ray): boolean; 45 | 46 | /** 47 | * @deprecated Use {@link Ray#intersectsBox .intersectsBox()} instead. 48 | */ 49 | isIntersectionBox(b: any): any; 50 | 51 | /** 52 | * @deprecated Use {@link Ray#intersectsPlane .intersectsPlane()} instead. 53 | */ 54 | isIntersectionPlane(p: any): any; 55 | 56 | /** 57 | * @deprecated Use {@link Ray#intersectsSphere .intersectsSphere()} instead. 58 | */ 59 | isIntersectionSphere(s: any): any; 60 | } 61 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/Sphere.d.ts: -------------------------------------------------------------------------------- 1 | import { Vector3 } from './Vector3'; 2 | import { Box3 } from './Box3'; 3 | import { Plane } from './Plane'; 4 | import { Matrix4 } from './Matrix4'; 5 | 6 | export class Sphere { 7 | constructor(center?: Vector3, radius?: number); 8 | 9 | /** 10 | * @default new Vector3() 11 | */ 12 | center: Vector3; 13 | 14 | /** 15 | * @default 1 16 | */ 17 | radius: number; 18 | 19 | set(center: Vector3, radius: number): Sphere; 20 | setFromPoints(points: Vector3[], optionalCenter?: Vector3): Sphere; 21 | clone(): this; 22 | copy(sphere: Sphere): this; 23 | expandByPoint(point: Vector3): this; 24 | isEmpty(): boolean; 25 | makeEmpty(): this; 26 | containsPoint(point: Vector3): boolean; 27 | distanceToPoint(point: Vector3): number; 28 | intersectsSphere(sphere: Sphere): boolean; 29 | intersectsBox(box: Box3): boolean; 30 | intersectsPlane(plane: Plane): boolean; 31 | clampPoint(point: Vector3, target: Vector3): Vector3; 32 | getBoundingBox(target: Box3): Box3; 33 | applyMatrix4(matrix: Matrix4): Sphere; 34 | translate(offset: Vector3): Sphere; 35 | equals(sphere: Sphere): boolean; 36 | union(sphere: Sphere): this; 37 | 38 | /** 39 | * @deprecated Use {@link Sphere#isEmpty .isEmpty()} instead. 40 | */ 41 | empty(): any; 42 | } 43 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/Spherical.d.ts: -------------------------------------------------------------------------------- 1 | import { Vector3 } from './Vector3'; 2 | 3 | export class Spherical { 4 | constructor(radius?: number, phi?: number, theta?: number); 5 | 6 | /** 7 | * @default 1 8 | */ 9 | radius: number; 10 | 11 | /** 12 | * @default 0 13 | */ 14 | phi: number; 15 | 16 | /** 17 | * @default 0 18 | */ 19 | theta: number; 20 | 21 | set(radius: number, phi: number, theta: number): this; 22 | clone(): this; 23 | copy(other: Spherical): this; 24 | makeSafe(): this; 25 | setFromVector3(v: Vector3): this; 26 | setFromCartesianCoords(x: number, y: number, z: number): this; 27 | } 28 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/SphericalHarmonics3.d.ts: -------------------------------------------------------------------------------- 1 | import { Vector3 } from './Vector3'; 2 | 3 | export class SphericalHarmonics3 { 4 | constructor(); 5 | 6 | /** 7 | * @default [new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), 8 | * new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3()] 9 | */ 10 | coefficients: Vector3[]; 11 | readonly isSphericalHarmonics3: true; 12 | 13 | set(coefficients: Vector3[]): SphericalHarmonics3; 14 | zero(): SphericalHarmonics3; 15 | add(sh: SphericalHarmonics3): SphericalHarmonics3; 16 | addScaledSH(sh: SphericalHarmonics3, s: number): SphericalHarmonics3; 17 | scale(s: number): SphericalHarmonics3; 18 | lerp(sh: SphericalHarmonics3, alpha: number): SphericalHarmonics3; 19 | equals(sh: SphericalHarmonics3): boolean; 20 | copy(sh: SphericalHarmonics3): SphericalHarmonics3; 21 | clone(): this; 22 | 23 | /** 24 | * Sets the values of this spherical harmonics from the provided array or array-like. 25 | * @param array the source array or array-like. 26 | * @param offset (optional) offset into the array. Default is 0. 27 | */ 28 | fromArray(array: number[] | ArrayLike, offset?: number): this; 29 | 30 | /** 31 | * Returns an array with the values of this spherical harmonics, or copies them into the provided array. 32 | * @param array (optional) array to store the spherical harmonics to. If this is not provided, a new array will be created. 33 | * @param offset (optional) optional offset into the array. 34 | * @return The created or provided array. 35 | */ 36 | toArray(array?: number[], offset?: number): number[]; 37 | 38 | /** 39 | * Returns an array with the values of this spherical harmonics, or copies them into the provided array-like. 40 | * @param array array-like to store the spherical harmonics to. 41 | * @param offset (optional) optional offset into the array-like. 42 | * @return The provided array-like. 43 | */ 44 | toArray(array: ArrayLike, offset?: number): ArrayLike; 45 | 46 | getAt(normal: Vector3, target: Vector3): Vector3; 47 | getIrradianceAt(normal: Vector3, target: Vector3): Vector3; 48 | 49 | static getBasisAt(normal: Vector3, shBasis: number[]): void; 50 | } 51 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/Triangle.d.ts: -------------------------------------------------------------------------------- 1 | import { Vector2 } from './Vector2'; 2 | import { Vector3 } from './Vector3'; 3 | import { Plane } from './Plane'; 4 | import { Box3 } from './Box3'; 5 | 6 | import { InterleavedBufferAttribute } from '../core/InterleavedBufferAttribute'; 7 | import { BufferAttribute } from '../core/BufferAttribute'; 8 | 9 | export class Triangle { 10 | constructor(a?: Vector3, b?: Vector3, c?: Vector3); 11 | 12 | /** 13 | * @default new THREE.Vector3() 14 | */ 15 | a: Vector3; 16 | 17 | /** 18 | * @default new THREE.Vector3() 19 | */ 20 | b: Vector3; 21 | 22 | /** 23 | * @default new THREE.Vector3() 24 | */ 25 | c: Vector3; 26 | 27 | set(a: Vector3, b: Vector3, c: Vector3): Triangle; 28 | setFromPointsAndIndices(points: Vector3[], i0: number, i1: number, i2: number): this; 29 | setFromAttributeAndIndices( 30 | attribute: BufferAttribute | InterleavedBufferAttribute, 31 | i0: number, 32 | i1: number, 33 | i2: number, 34 | ): this; 35 | clone(): this; 36 | copy(triangle: Triangle): this; 37 | getArea(): number; 38 | getMidpoint(target: Vector3): Vector3; 39 | getNormal(target: Vector3): Vector3; 40 | getPlane(target: Plane): Plane; 41 | getBarycoord(point: Vector3, target: Vector3): Vector3; 42 | getUV(point: Vector3, uv1: Vector2, uv2: Vector2, uv3: Vector2, target: Vector2): Vector2; 43 | containsPoint(point: Vector3): boolean; 44 | intersectsBox(box: Box3): boolean; 45 | isFrontFacing(direction: Vector3): boolean; 46 | closestPointToPoint(point: Vector3, target: Vector3): Vector3; 47 | equals(triangle: Triangle): boolean; 48 | 49 | static getNormal(a: Vector3, b: Vector3, c: Vector3, target: Vector3): Vector3; 50 | static getBarycoord(point: Vector3, a: Vector3, b: Vector3, c: Vector3, target: Vector3): Vector3; 51 | static containsPoint(point: Vector3, a: Vector3, b: Vector3, c: Vector3): boolean; 52 | static getUV( 53 | point: Vector3, 54 | p1: Vector3, 55 | p2: Vector3, 56 | p3: Vector3, 57 | uv1: Vector2, 58 | uv2: Vector2, 59 | uv3: Vector2, 60 | target: Vector2, 61 | ): Vector2; 62 | static isFrontFacing(a: Vector3, b: Vector3, c: Vector3, direction: Vector3): boolean; 63 | } 64 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/Vector3.d.ts: -------------------------------------------------------------------------------- 1 | import { Euler } from './Euler'; 2 | import { Matrix3 } from './Matrix3'; 3 | import { Matrix4 } from './Matrix4'; 4 | import { Quaternion } from './Quaternion'; 5 | import { Camera } from './../cameras/Camera'; 6 | import { Spherical } from './Spherical'; 7 | import { Cylindrical } from './Cylindrical'; 8 | import { BufferAttribute } from './../core/BufferAttribute'; 9 | import { InterleavedBufferAttribute } from './../core/InterleavedBufferAttribute'; 10 | import { Vector } from './Vector2'; 11 | 12 | export type Vector3Tuple = [number, number, number]; 13 | 14 | /** 15 | * 3D vector. ( class Vector3 implements Vector ) 16 | * 17 | * see {@link https://github.com/mrdoob/three.js/blob/master/src/math/Vector3.js} 18 | * 19 | * @example 20 | * const a = new THREE.Vector3( 1, 0, 0 ); 21 | * const b = new THREE.Vector3( 0, 1, 0 ); 22 | * const c = new THREE.Vector3(); 23 | * c.crossVectors( a, b ); 24 | */ 25 | export class Vector3 implements Vector { 26 | constructor(x?: number, y?: number, z?: number); 27 | 28 | /** 29 | * @default 0 30 | */ 31 | x: number; 32 | 33 | /** 34 | * @default 0 35 | */ 36 | y: number; 37 | 38 | /** 39 | * @default 0 40 | */ 41 | z: number; 42 | readonly isVector3: true; 43 | 44 | /** 45 | * Sets value of this vector. 46 | */ 47 | set(x: number, y: number, z: number): this; 48 | 49 | /** 50 | * Sets all values of this vector. 51 | */ 52 | setScalar(scalar: number): this; 53 | 54 | /** 55 | * Sets x value of this vector. 56 | */ 57 | setX(x: number): Vector3; 58 | 59 | /** 60 | * Sets y value of this vector. 61 | */ 62 | setY(y: number): Vector3; 63 | 64 | /** 65 | * Sets z value of this vector. 66 | */ 67 | setZ(z: number): Vector3; 68 | 69 | setComponent(index: number, value: number): this; 70 | 71 | getComponent(index: number): number; 72 | 73 | /** 74 | * Clones this vector. 75 | */ 76 | clone(): this; 77 | 78 | /** 79 | * Copies value of v to this vector. 80 | */ 81 | copy(v: Vector3): this; 82 | 83 | /** 84 | * Adds v to this vector. 85 | */ 86 | add(v: Vector3): this; 87 | 88 | addScalar(s: number): this; 89 | 90 | addScaledVector(v: Vector3, s: number): this; 91 | 92 | /** 93 | * Sets this vector to a + b. 94 | */ 95 | addVectors(a: Vector3, b: Vector3): this; 96 | 97 | /** 98 | * Subtracts v from this vector. 99 | */ 100 | sub(a: Vector3): this; 101 | 102 | subScalar(s: number): this; 103 | 104 | /** 105 | * Sets this vector to a - b. 106 | */ 107 | subVectors(a: Vector3, b: Vector3): this; 108 | 109 | multiply(v: Vector3): this; 110 | 111 | /** 112 | * Multiplies this vector by scalar s. 113 | */ 114 | multiplyScalar(s: number): this; 115 | 116 | multiplyVectors(a: Vector3, b: Vector3): this; 117 | 118 | applyEuler(euler: Euler): this; 119 | 120 | applyAxisAngle(axis: Vector3, angle: number): this; 121 | 122 | applyMatrix3(m: Matrix3): this; 123 | 124 | applyNormalMatrix(m: Matrix3): this; 125 | 126 | applyMatrix4(m: Matrix4): this; 127 | 128 | applyQuaternion(q: Quaternion): this; 129 | 130 | project(camera: Camera): this; 131 | 132 | unproject(camera: Camera): this; 133 | 134 | transformDirection(m: Matrix4): this; 135 | 136 | divide(v: Vector3): this; 137 | 138 | /** 139 | * Divides this vector by scalar s. 140 | * Set vector to ( 0, 0, 0 ) if s == 0. 141 | */ 142 | divideScalar(s: number): this; 143 | 144 | min(v: Vector3): this; 145 | 146 | max(v: Vector3): this; 147 | 148 | clamp(min: Vector3, max: Vector3): this; 149 | 150 | clampScalar(min: number, max: number): this; 151 | 152 | clampLength(min: number, max: number): this; 153 | 154 | floor(): this; 155 | 156 | ceil(): this; 157 | 158 | round(): this; 159 | 160 | roundToZero(): this; 161 | 162 | /** 163 | * Inverts this vector. 164 | */ 165 | negate(): this; 166 | 167 | /** 168 | * Computes dot product of this vector and v. 169 | */ 170 | dot(v: Vector3): number; 171 | 172 | /** 173 | * Computes squared length of this vector. 174 | */ 175 | lengthSq(): number; 176 | 177 | /** 178 | * Computes length of this vector. 179 | */ 180 | length(): number; 181 | 182 | /** 183 | * Computes Manhattan length of this vector. 184 | * http://en.wikipedia.org/wiki/Taxicab_geometry 185 | * 186 | * @deprecated Use {@link Vector3#manhattanLength .manhattanLength()} instead. 187 | */ 188 | lengthManhattan(): number; 189 | 190 | /** 191 | * Computes the Manhattan length of this vector. 192 | * 193 | * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} 194 | */ 195 | manhattanLength(): number; 196 | 197 | /** 198 | * Computes the Manhattan length (distance) from this vector to the given vector v 199 | * 200 | * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} 201 | */ 202 | manhattanDistanceTo(v: Vector3): number; 203 | 204 | /** 205 | * Normalizes this vector. 206 | */ 207 | normalize(): this; 208 | 209 | /** 210 | * Normalizes this vector and multiplies it by l. 211 | */ 212 | setLength(l: number): this; 213 | lerp(v: Vector3, alpha: number): this; 214 | 215 | lerpVectors(v1: Vector3, v2: Vector3, alpha: number): this; 216 | 217 | /** 218 | * Sets this vector to cross product of itself and v. 219 | */ 220 | cross(a: Vector3): this; 221 | 222 | /** 223 | * Sets this vector to cross product of a and b. 224 | */ 225 | crossVectors(a: Vector3, b: Vector3): this; 226 | projectOnVector(v: Vector3): this; 227 | projectOnPlane(planeNormal: Vector3): this; 228 | reflect(vector: Vector3): this; 229 | angleTo(v: Vector3): number; 230 | 231 | /** 232 | * Computes distance of this vector to v. 233 | */ 234 | distanceTo(v: Vector3): number; 235 | 236 | /** 237 | * Computes squared distance of this vector to v. 238 | */ 239 | distanceToSquared(v: Vector3): number; 240 | 241 | /** 242 | * @deprecated Use {@link Vector3#manhattanDistanceTo .manhattanDistanceTo()} instead. 243 | */ 244 | distanceToManhattan(v: Vector3): number; 245 | 246 | setFromSpherical(s: Spherical): this; 247 | setFromSphericalCoords(r: number, phi: number, theta: number): this; 248 | setFromCylindrical(s: Cylindrical): this; 249 | setFromCylindricalCoords(radius: number, theta: number, y: number): this; 250 | setFromMatrixPosition(m: Matrix4): this; 251 | setFromMatrixScale(m: Matrix4): this; 252 | setFromMatrixColumn(matrix: Matrix4, index: number): this; 253 | setFromMatrix3Column(matrix: Matrix3, index: number): this; 254 | 255 | /** 256 | * Checks for strict equality of this vector and v. 257 | */ 258 | equals(v: Vector3): boolean; 259 | 260 | /** 261 | * Sets this vector's x, y and z value from the provided array or array-like. 262 | * @param array the source array or array-like. 263 | * @param offset (optional) offset into the array. Default is 0. 264 | */ 265 | fromArray(array: number[] | ArrayLike, offset?: number): this; 266 | 267 | /** 268 | * Returns an array [x, y, z], or copies x, y and z into the provided array. 269 | * @param array (optional) array to store the vector to. If this is not provided, a new array will be created. 270 | * @param offset (optional) optional offset into the array. 271 | * @return The created or provided array. 272 | */ 273 | toArray(array?: number[], offset?: number): number[]; 274 | toArray(array?: Vector3Tuple, offset?: 0): Vector3Tuple; 275 | 276 | /** 277 | * Copies x, y and z into the provided array-like. 278 | * @param array array-like to store the vector to. 279 | * @param offset (optional) optional offset into the array-like. 280 | * @return The provided array-like. 281 | */ 282 | toArray(array: ArrayLike, offset?: number): ArrayLike; 283 | 284 | fromBufferAttribute(attribute: BufferAttribute | InterleavedBufferAttribute, index: number): this; 285 | 286 | /** 287 | * Sets this vector's x, y and z from Math.random 288 | */ 289 | random(): this; 290 | 291 | randomDirection(): this; 292 | } 293 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/Vector4.d.ts: -------------------------------------------------------------------------------- 1 | import { Matrix4 } from './Matrix4'; 2 | import { Quaternion } from './Quaternion'; 3 | import { BufferAttribute } from './../core/BufferAttribute'; 4 | import { Vector } from './Vector2'; 5 | 6 | export type Vector4Tuple = [number, number, number, number]; 7 | 8 | /** 9 | * 4D vector. 10 | * 11 | * ( class Vector4 implements Vector ) 12 | */ 13 | export class Vector4 implements Vector { 14 | constructor(x?: number, y?: number, z?: number, w?: number); 15 | 16 | /** 17 | * @default 0 18 | */ 19 | x: number; 20 | 21 | /** 22 | * @default 0 23 | */ 24 | y: number; 25 | 26 | /** 27 | * @default 0 28 | */ 29 | z: number; 30 | 31 | /** 32 | * @default 0 33 | */ 34 | w: number; 35 | 36 | width: number; 37 | height: number; 38 | readonly isVector4: true; 39 | 40 | /** 41 | * Sets value of this vector. 42 | */ 43 | set(x: number, y: number, z: number, w: number): this; 44 | 45 | /** 46 | * Sets all values of this vector. 47 | */ 48 | setScalar(scalar: number): this; 49 | 50 | /** 51 | * Sets X component of this vector. 52 | */ 53 | setX(x: number): this; 54 | 55 | /** 56 | * Sets Y component of this vector. 57 | */ 58 | setY(y: number): this; 59 | 60 | /** 61 | * Sets Z component of this vector. 62 | */ 63 | setZ(z: number): this; 64 | 65 | /** 66 | * Sets w component of this vector. 67 | */ 68 | setW(w: number): this; 69 | 70 | setComponent(index: number, value: number): this; 71 | 72 | getComponent(index: number): number; 73 | 74 | /** 75 | * Clones this vector. 76 | */ 77 | clone(): this; 78 | 79 | /** 80 | * Copies value of v to this vector. 81 | */ 82 | copy(v: Vector4): this; 83 | 84 | /** 85 | * Adds v to this vector. 86 | */ 87 | add(v: Vector4): this; 88 | 89 | addScalar(scalar: number): this; 90 | 91 | /** 92 | * Sets this vector to a + b. 93 | */ 94 | addVectors(a: Vector4, b: Vector4): this; 95 | 96 | addScaledVector(v: Vector4, s: number): this; 97 | /** 98 | * Subtracts v from this vector. 99 | */ 100 | sub(v: Vector4): this; 101 | 102 | subScalar(s: number): this; 103 | 104 | /** 105 | * Sets this vector to a - b. 106 | */ 107 | subVectors(a: Vector4, b: Vector4): this; 108 | 109 | multiply(v: Vector4): this; 110 | 111 | /** 112 | * Multiplies this vector by scalar s. 113 | */ 114 | multiplyScalar(s: number): this; 115 | 116 | applyMatrix4(m: Matrix4): this; 117 | 118 | /** 119 | * Divides this vector by scalar s. 120 | * Set vector to ( 0, 0, 0 ) if s == 0. 121 | */ 122 | divideScalar(s: number): this; 123 | 124 | /** 125 | * http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm 126 | * @param q is assumed to be normalized 127 | */ 128 | setAxisAngleFromQuaternion(q: Quaternion): this; 129 | 130 | /** 131 | * http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm 132 | * @param m assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) 133 | */ 134 | setAxisAngleFromRotationMatrix(m: Matrix4): this; 135 | 136 | min(v: Vector4): this; 137 | max(v: Vector4): this; 138 | clamp(min: Vector4, max: Vector4): this; 139 | clampScalar(min: number, max: number): this; 140 | floor(): this; 141 | ceil(): this; 142 | round(): this; 143 | roundToZero(): this; 144 | 145 | /** 146 | * Inverts this vector. 147 | */ 148 | negate(): this; 149 | 150 | /** 151 | * Computes dot product of this vector and v. 152 | */ 153 | dot(v: Vector4): number; 154 | 155 | /** 156 | * Computes squared length of this vector. 157 | */ 158 | lengthSq(): number; 159 | 160 | /** 161 | * Computes length of this vector. 162 | */ 163 | length(): number; 164 | 165 | /** 166 | * Computes the Manhattan length of this vector. 167 | * 168 | * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} 169 | */ 170 | manhattanLength(): number; 171 | 172 | /** 173 | * Normalizes this vector. 174 | */ 175 | normalize(): this; 176 | /** 177 | * Normalizes this vector and multiplies it by l. 178 | */ 179 | setLength(length: number): this; 180 | 181 | /** 182 | * Linearly interpolate between this vector and v with alpha factor. 183 | */ 184 | lerp(v: Vector4, alpha: number): this; 185 | 186 | lerpVectors(v1: Vector4, v2: Vector4, alpha: number): this; 187 | 188 | /** 189 | * Checks for strict equality of this vector and v. 190 | */ 191 | equals(v: Vector4): boolean; 192 | 193 | /** 194 | * Sets this vector's x, y, z and w value from the provided array or array-like. 195 | * @param array the source array or array-like. 196 | * @param offset (optional) offset into the array. Default is 0. 197 | */ 198 | fromArray(array: number[] | ArrayLike, offset?: number): this; 199 | 200 | /** 201 | * Returns an array [x, y, z, w], or copies x, y, z and w into the provided array. 202 | * @param array (optional) array to store the vector to. If this is not provided, a new array will be created. 203 | * @param offset (optional) optional offset into the array. 204 | * @return The created or provided array. 205 | */ 206 | toArray(array?: number[], offset?: number): number[]; 207 | toArray(array?: Vector4Tuple, offset?: 0): Vector4Tuple; 208 | 209 | /** 210 | * Copies x, y, z and w into the provided array-like. 211 | * @param array array-like to store the vector to. 212 | * @param offset (optional) optional offset into the array-like. 213 | * @return The provided array-like. 214 | */ 215 | toArray(array: ArrayLike, offset?: number): ArrayLike; 216 | 217 | fromBufferAttribute(attribute: BufferAttribute, index: number): this; 218 | 219 | /** 220 | * Sets this vector's x, y, z and w from Math.random 221 | */ 222 | random(): this; 223 | } 224 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/interpolants/CubicInterpolant.d.ts: -------------------------------------------------------------------------------- 1 | import { Interpolant } from '../Interpolant'; 2 | 3 | export class CubicInterpolant extends Interpolant { 4 | constructor(parameterPositions: any, samplesValues: any, sampleSize: number, resultBuffer?: any); 5 | 6 | interpolate_(i1: number, t0: number, t: number, t1: number): any; 7 | } 8 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/interpolants/DiscreteInterpolant.d.ts: -------------------------------------------------------------------------------- 1 | import { Interpolant } from '../Interpolant'; 2 | 3 | export class DiscreteInterpolant extends Interpolant { 4 | constructor(parameterPositions: any, samplesValues: any, sampleSize: number, resultBuffer?: any); 5 | 6 | interpolate_(i1: number, t0: number, t: number, t1: number): any; 7 | } 8 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/interpolants/LinearInterpolant.d.ts: -------------------------------------------------------------------------------- 1 | import { Interpolant } from '../Interpolant'; 2 | 3 | export class LinearInterpolant extends Interpolant { 4 | constructor(parameterPositions: any, samplesValues: any, sampleSize: number, resultBuffer?: any); 5 | 6 | interpolate_(i1: number, t0: number, t: number, t1: number): any; 7 | } 8 | -------------------------------------------------------------------------------- /test/Golden/ts/three/math/interpolants/QuaternionLinearInterpolant.d.ts: -------------------------------------------------------------------------------- 1 | import { Interpolant } from '../Interpolant'; 2 | 3 | export class QuaternionLinearInterpolant extends Interpolant { 4 | constructor(parameterPositions: any, samplesValues: any, sampleSize: number, resultBuffer?: any); 5 | 6 | interpolate_(i1: number, t0: number, t: number, t1: number): any; 7 | } 8 | -------------------------------------------------------------------------------- /test/Golden/ts/three/objects/Sprite.d.ts: -------------------------------------------------------------------------------- 1 | // import { Vector2 } from './../math/Vector2'; 2 | // import { Raycaster } from './../core/Raycaster'; 3 | import { Object3D } from './../core/Object3D'; 4 | // import { Intersection } from '../core/Raycaster'; 5 | // import { SpriteMaterial } from '../materials/Materials'; 6 | // import { BufferGeometry } from '../core/BufferGeometry'; 7 | 8 | export class Sprite extends Object3D { 9 | // constructor(material?: SpriteMaterial); 10 | // 11 | // type: 'Sprite'; 12 | // readonly isSprite: true; 13 | // 14 | // geometry: BufferGeometry; 15 | // material: SpriteMaterial; 16 | // center: Vector2; 17 | // 18 | // raycast(raycaster: Raycaster, intersects: Intersection[]): void; 19 | // copy(source: this): this; 20 | } 21 | -------------------------------------------------------------------------------- /test/Golden/ts/three/utils.d.ts: -------------------------------------------------------------------------------- 1 | import { Color } from './math/Color'; 2 | 3 | export type ColorRepresentation = Color | string | number; 4 | -------------------------------------------------------------------------------- /test/Main.purs: -------------------------------------------------------------------------------- 1 | module Test.Main where 2 | 3 | import Prelude 4 | 5 | import Effect (Effect) 6 | import Test.Codegen (suite) as Test.Codegen 7 | import Test.Golden.ThreeJs (suite) as Test.Golden.ThreeJs 8 | import Test.Golden.ReactBootstrap (suite) as Test.Golden.ReactBootstrap 9 | import Test.MultiModule (suite) as Test.MultiModule 10 | import Test.NonRecType (suite) as Test.NonRecType 11 | import Test.RecType (suite) as Test.RecType 12 | import Test.Unit.Main (runTest) 13 | 14 | main :: Effect Unit 15 | main = runTest do 16 | Test.NonRecType.suite 17 | -- Test.RecType.suite 18 | -- Test.MultiModule.suite 19 | -- Test.Codegen.suite 20 | 21 | -- Test.Golden.ThreeJs.suite 22 | -- Test.Golden.ReactBootstrap.suite 23 | 24 | -------------------------------------------------------------------------------- /test/MultiModule.purs: -------------------------------------------------------------------------------- 1 | module Test.MultiModule where 2 | 3 | import Prelude 4 | 5 | import Data.Array (cons, singleton) as Array 6 | import Data.Either (Either(..)) 7 | import Data.Foldable (length) 8 | import Data.Functor.Mu (roll) 9 | import Data.Lens (_1, over) 10 | import Data.Map (empty, fromFoldable) as Map 11 | import Data.String (Pattern(..), Replacement(..), joinWith, replace) as String 12 | import Debug (traceM) 13 | import Effect.Aff (Aff) 14 | import Effect.Class (liftEffect) 15 | import Foreign.Object (fromHomogeneous, toUnfoldable) as Object 16 | import ReadDTS.AST (RootDeclarations, TypeRepr(..)) 17 | import ReadDTS.AST (TsType(..)) as AST 18 | import ReadDTS.AST (types) as ReadDTS.AST 19 | import Test.Compile (compile) 20 | import Test.Unit (TestSuite, failure) 21 | import Test.Unit (suite, test) as Test 22 | import Test.Unit.Assert (shouldEqual) 23 | import TypeScript.Compiler.Parser (SourceCode(..)) 24 | import TypeScript.Compiler.Program (getPreEmitDiagnostics) 25 | import TypeScript.Compiler.Types (FullyQualifiedName(..)) 26 | import TypeScript.Compiler.Types.Diagnostics (Diagnostic(..)) 27 | import TypeScript.Testing.Types (mkInMemoryFile) 28 | 29 | testOnTypes 30 | :: { modules :: 31 | Array 32 | { path :: String 33 | , source :: String 34 | } 35 | , roots :: Array String 36 | } 37 | -> ({ types :: RootDeclarations, diagnostics :: Array Diagnostic } -> Aff Unit) 38 | -> TestSuite 39 | testOnTypes opts test = do 40 | let 41 | labelStep ({ path, source: source }) = "/* " 42 | <> path 43 | <> " */" 44 | <> String.replace (String.Pattern "\n") (String.Replacement ";") source 45 | 46 | label = String.joinWith ";" $ map labelStep opts.modules 47 | 48 | toFile { path, source } = mkInMemoryFile path (SourceCode source) 49 | opts' = opts 50 | { modules = map toFile opts.modules 51 | , roots = opts.roots 52 | } 53 | 54 | Test.test label $ do 55 | program <- liftEffect $ compile opts' 56 | let 57 | diagnostics = getPreEmitDiagnostics program 58 | 59 | case ReadDTS.AST.types program of 60 | Right types -> test { types, diagnostics } 61 | Left err -> failure $ "FAILURE: " <> show err 62 | 63 | testFromRootTypes rootSource modules test = do 64 | let 65 | root = { source: rootSource, path: "Root.ts" } 66 | testOnTypes { roots: [ "Root.ts" ], modules: Array.cons root modules } test 67 | 68 | -- We need this polymorphic 69 | fromHomogeneous = (Map.fromFoldable :: Array _ -> _) 70 | <<< map (over _1 FullyQualifiedName) 71 | <<< Object.toUnfoldable 72 | <<< Object.fromHomogeneous 73 | 74 | suite :: TestSuite 75 | suite = Test.suite "Cross module definitions" do 76 | let 77 | mkModule path source = { path, source } 78 | do 79 | let 80 | modules = Array.singleton $ mkModule 81 | "A.ts" 82 | "export type A = { p1: number, p2: string };" 83 | 84 | testFromRootTypes """import { A } from "A"; export type B = { a: A }""" modules \{ types } -> do 85 | length types `shouldEqual` 2 86 | types `flip shouldEqual` fromHomogeneous 87 | { "\"A\".A": TypeRepr $ roll $ AST.TsObject 88 | [ { type: roll AST.TsNumber, name: "p1", optional: false } 89 | , { type: roll AST.TsString, name: "p2", optional: false } 90 | ] 91 | , "\"Root\".B": TypeRepr $ roll $ AST.TsObject $ Array.singleton $ 92 | { type: roll $ AST.TsTypeRef $ FullyQualifiedName "\"A\".A" 93 | , name: "a" 94 | , optional: false 95 | } 96 | } 97 | 98 | do 99 | let 100 | -- Don't ask me why... but there is non standard way to export stuff and react 101 | -- actually uses this approach :-( 102 | -- https://gist.github.com/chrisgervang/59ed046c0a8d7c3a1be1b3416f8f2466 103 | modules = Array.singleton $ mkModule "React.d.ts" $ String.joinWith " " 104 | [ "export = React; " 105 | , "export as namespace React;" 106 | , "declare namespace React {" 107 | , " type Key = string | number;" 108 | , " type Irrelevant = number;" 109 | , "};" 110 | ] 111 | testFromRootTypes """import React from "React"; export type X = { key: React.Key }""" modules \{ types } -> do 112 | length types `shouldEqual` 2 113 | types `flip shouldEqual` fromHomogeneous 114 | { "React.Key": TypeRepr $ roll $ AST.TsUnion [ roll AST.TsString, roll AST.TsNumber ] 115 | , "\"Root\".X": TypeRepr $ roll $ AST.TsObject $ Array.singleton $ 116 | { type: roll $ AST.TsTypeRef $ FullyQualifiedName "React.Key" 117 | , name: "key" 118 | , optional: false 119 | } 120 | } 121 | 122 | -- Value declation / export is not supported yet 123 | -- do 124 | -- testFromRootTypes """export default { prop: "test" }""" [] \{ types } -> do 125 | -- length types `shouldEqual` 1 126 | -- types `flip shouldEqual` fromHomogeneous 127 | -- { "React.Key": TypeRepr $ roll $ AST.TsUnion [ roll AST.TsString, roll AST.TsNumber ] 128 | -- , "\"Root\".X": TypeRepr $ roll $ AST.TsObject $ Array.singleton $ 129 | -- { type: roll $ AST.TsTypeRef $ FullyQualifiedName "React.Key" 130 | -- , name: "key" 131 | -- , optional: false 132 | -- } 133 | -- } 134 | 135 | do 136 | let 137 | -- expected = roll $ AST.TsInterface $ Array.singleton { name: "x", optional: false, type: roll (AST.TsArray $ roll AST.TsNumber) } 138 | source = String.joinWith " " 139 | [ "namespace X {" 140 | , " export interface Y { y: number[] }" 141 | , "}" 142 | , "export class X {" 143 | , " m: X.Y; " 144 | , "}" 145 | ] 146 | 147 | testFromRootTypes source [] \{ types } -> do 148 | types `flip shouldEqual` fromHomogeneous 149 | { "\"Root\".X": TypeRepr $ roll $ AST.TsClass 150 | { bases: [] 151 | , constructors: [[]] 152 | , props: [ { name: "m", optional: false, type: roll $ AST.TsTypeRef $ FullyQualifiedName "X.Y" } ] 153 | } 154 | , "X.Y": TypeRepr $ roll $ AST.TsInterface 155 | { bases: [] 156 | , props: [ { name: "y", optional: false, type: roll $ AST.TsArray $ roll AST.TsNumber } ] 157 | } 158 | } 159 | 160 | -- | FIXME: merging of `class` and `namespace` is not merged automatically. 161 | -- do 162 | -- let 163 | -- -- expected = roll $ AST.TsInterface $ Array.singleton { name: "x", optional: false, type: roll (AST.TsArray $ roll AST.TsNumber) } 164 | -- source = String.joinWith " " 165 | -- [ "export namespace X {" 166 | -- , " export interface Y { y: number[] }" 167 | -- , "}" 168 | -- , "export class X extends X.Y {" 169 | -- , "}" 170 | -- ] 171 | -- testFromRootTypes source [] \types -> do 172 | -- let 173 | -- -- FIXME: 174 | -- expected = fromHomogeneous 175 | -- { "\"Root\".X": TypeRepr $ roll $ AST.TsObject 176 | -- [ { type: roll AST.TsNumber, name: "p1", optional: false } 177 | -- , { type: roll AST.TsString, name: "p2", optional: false } 178 | -- ] 179 | -- , "\"Root\".X.Y": TypeRepr $ roll $ AST.TsObject $ Array.singleton $ 180 | -- { type: roll $ AST.TsTypeRef $ FullyQualifiedName "\"Root\".X.Y" 181 | -- , name: "a" 182 | -- , optional: false 183 | -- } 184 | -- } 185 | -- types `shouldEqual` expected 186 | 187 | -- -- do 188 | -- -- let 189 | -- -- modules = Array.singleton $ mkModule 190 | -- -- "A.ts" 191 | -- -- "export type A = { p1: number, p2: string };" 192 | -- -- testFromRootTypes """import { A } from "A"; export type B = { a: a }""" modules \types -> do 193 | -- -- -- shouldEqual 2 (length types) 194 | -- -- Map.fromFoldable types `shouldEqual` fromHomogeneous 195 | -- -- { "\"A\".A": roll $ AST.TsObject 196 | -- -- [ { type: roll AST.TsNumber, name: "p1", optional: false } 197 | -- -- , { type: roll AST.TsString, name: "p2", optional: false } 198 | -- -- ] 199 | -- -- , "\"Root\".B": roll $ AST.TsObject $ Array.singleton $ 200 | -- -- { type: roll $ AST.TsTypeRef $ FullyQualifiedName "\"A\".A" 201 | -- -- , name: "a" 202 | -- -- , optional: false 203 | -- -- } 204 | -- -- } 205 | -------------------------------------------------------------------------------- /test/NonRecType.purs: -------------------------------------------------------------------------------- 1 | module Test.NonRecType where 2 | 3 | import Prelude 4 | 5 | import Data.Array.NonEmpty (singleton) as Array.NonEmpty 6 | import Data.Bifunctor (bimap) 7 | import Data.Maybe (Maybe(..)) 8 | import Data.Traversable (for) 9 | import Effect.Aff (Aff) 10 | import ReadDTS (Params, readTopLevelType) 11 | import ReadDTS.AST (TsType) 12 | import ReadDTS.AST as AST 13 | import Test.Compile (TypeName(..), compileType) 14 | import Test.Unit (TestSuite, failure) 15 | import Test.Unit (suite, test) as Test 16 | import Test.Unit.Assert (shouldEqual) 17 | import TypeScript.Compiler.Parser (SourceCode(..)) 18 | import TypeScript.Compiler.Program (getTypeChecker) 19 | import TypeScript.Compiler.Types (FullyQualifiedName, Program, Typ) 20 | import TypeScript.Compiler.Types.Nodes as Nodes 21 | 22 | extractTyp 23 | :: TypeName 24 | -> String 25 | -> Aff 26 | ( Maybe 27 | { params :: Maybe (Params (Typ ())) 28 | , program :: Program 29 | , typ :: Typ () 30 | } 31 | ) 32 | extractTyp typeName source = do 33 | r <- compileType typeName (SourceCode source) 34 | case r of 35 | { type: Nothing } -> pure Nothing 36 | { type: Just { typ, params }, program } -> do 37 | pure $ Just { typ, params, program } 38 | 39 | extractType 40 | :: TypeName 41 | -> String 42 | -> Aff 43 | ( Maybe 44 | { program :: Program 45 | , type :: 46 | TsType 47 | { fullyQualifiedName :: FullyQualifiedName 48 | , ref :: Nodes.DeclarationStatement 49 | } 50 | (Typ ()) 51 | } 52 | ) 53 | extractType typeName source = do 54 | t <- extractTyp typeName source 55 | for t \{ typ, program } -> do 56 | let 57 | checker = getTypeChecker program 58 | type' = readTopLevelType checker typ AST.visitor.onType 59 | pure { type: type', program } 60 | 61 | testOnType 62 | :: TypeName 63 | -> String 64 | -> ( { program :: Program 65 | , type :: 66 | TsType 67 | { fullyQualifiedName :: FullyQualifiedName 68 | , ref :: Nodes.DeclarationStatement 69 | } 70 | (Typ ()) 71 | } 72 | -> Aff Unit 73 | ) 74 | -> TestSuite 75 | testOnType typeName source test = Test.test (source <> "; /* non rec version */") do 76 | extractType typeName source >>= case _ of 77 | Nothing -> failure "Unable compile program or find type X" 78 | Just r -> test r 79 | 80 | testTypeShouldEqual :: TypeName -> String -> TsType Unit Unit -> TestSuite 81 | testTypeShouldEqual typeName source expected = testOnType typeName source \{ type: t } -> do 82 | let 83 | type' = bimap (const unit) (const unit) t 84 | type' `shouldEqual` expected 85 | 86 | suite :: TestSuite 87 | suite = Test.suite "Non recursive ts type layer" do 88 | let 89 | testXShouldEqual = testTypeShouldEqual (TypeName "X") 90 | 91 | testXShouldEqual "export function X(nonOpt: number, opt?: string): number { return 0; }" $ 92 | AST.TsFunction 93 | [ { name: "nonOpt", type: unit, optional: false } 94 | , { name: "opt", type: unit, optional: true } 95 | ] 96 | unit 97 | 98 | testXShouldEqual "export type X = Array;" (AST.TsArray unit) 99 | testXShouldEqual "export declare type X = Array;" (AST.TsArray unit) 100 | testXShouldEqual "export type X = boolean" AST.TsBoolean 101 | testXShouldEqual "export type X = true" (AST.TsBooleanLiteral true) 102 | testXShouldEqual "export type X = false" (AST.TsBooleanLiteral false) 103 | testXShouldEqual "export type X = null" AST.TsNull 104 | testXShouldEqual "export type X = number" AST.TsNumber 105 | testXShouldEqual "export type X = 8" (AST.TsNumberLiteral 8.0) 106 | testXShouldEqual "export type X = string" AST.TsString 107 | testXShouldEqual "export type X = \"symbol\"" (AST.TsStringLiteral "symbol") 108 | testXShouldEqual "export type X = [number, string, boolean]" (AST.TsTuple [ unit, unit, unit ]) 109 | testXShouldEqual "export type X = undefined" AST.TsUndefined 110 | testXShouldEqual "export type X = string | number" (AST.TsUnion [ unit, unit ]) 111 | testXShouldEqual "export type X = { x: string } & { y: number }" (AST.TsIntersection [ unit, unit ]) 112 | testXShouldEqual "export type X = {}" (AST.TsObject []) 113 | testXShouldEqual "export interface X{}" (AST.tsInterface [] []) 114 | testXShouldEqual "export interface X{ m: number }" 115 | (AST.tsInterface [] [ { name: "m", optional: false, type: unit } ]) 116 | testXShouldEqual "export interface X{ m?: number }" 117 | (AST.tsInterface [] [ { name: "m", optional: true, type: unit } ]) 118 | testXShouldEqual "export class X{}" (AST.tsClass [] [ [] ] []) 119 | testXShouldEqual "class C

{}; export type X = C" 120 | ( AST.TsApplication 121 | unit 122 | (Array.NonEmpty.singleton unit) 123 | ) 124 | 125 | -- export class Matrix3 implements Matrix { 126 | -- let 127 | -- source = String.joinWith ";\n" 128 | -- [ "export interface Y { elements: number[]; }" 129 | -- , "export class X implements Y { elements: number[]; }" 130 | -- ] 131 | 132 | -- testXShouldEqual source (AST.TsAny) 133 | 134 | -- FIXME: Parametric types are not handled anymore by `readTyp` which is mainly 135 | -- tested here. We should: 136 | -- 137 | -- * improve `unfoldType` so it return `TsUnkown` (or our internal represent 138 | -- tation for unread type). 139 | -- * test this cases using `unfoldType` with `maxDepth` 1 140 | 141 | -- testXShouldEqual "export class X{ }" 142 | -- ( AST.TsParametric 143 | -- unit 144 | -- (Array.NonEmpty.singleton { default: Just unit, name: "param" }) 145 | -- ) 146 | -- testXShouldEqual "export interface X{ }" 147 | -- ( AST.TsParametric 148 | -- unit 149 | -- (Array.NonEmpty.singleton { default: Just unit, name: "param" }) 150 | -- ) 151 | -- testXShouldEqual 152 | -- "export type X = number | param" 153 | -- ( AST.TsParametric 154 | -- unit 155 | -- (Array.NonEmpty.singleton { default: Nothing, name: "param" }) 156 | -- ) 157 | -- testXShouldEqual 158 | -- "export type X = number | param" 159 | -- ( AST.TsParametric 160 | -- unit 161 | -- (Array.NonEmpty.singleton { default: Just unit, name: "param" }) 162 | -- ) 163 | 164 | -- let 165 | -- testOnX = testOnType (TypeName "X") 166 | -- testOnX "export type X = {prop: arg}" \{ program, type: t } -> do 167 | -- let 168 | -- checker = getTypeChecker program 169 | -- readType' s = readType checker s (AllowTypeRef true) AST.visitor.onType 170 | 171 | -- t' :: TsType Unit (TsType Unit (TsType Unit Unit)) 172 | -- t' = 173 | -- bimap 174 | -- (const unit) 175 | -- (bimap (const unit) (bimap (const unit) (const unit))) 176 | -- <<< map (map readType') 177 | -- <<< map readType' 178 | -- $ t 179 | -- body = AST.TsObject $ Array.singleton 180 | -- { name: "prop" 181 | -- , optional: false 182 | -- , type: AST.TsParameter "arg" 183 | -- } 184 | -- params = Array.NonEmpty.singleton { default: Just AST.TsNumber, name: "arg" } 185 | -- expected = AST.TsParametric body params 186 | -- t' `shouldEqual` expected 187 | --------------------------------------------------------------------------------