diff --git a/package-lock.json b/package-lock.json index 1fdc3b499..02b3303d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,12 +33,6 @@ "integrity": "sha512-d2SJJpwkiPudEQ3+9ysANN2Nvz4QJKUPoe/WL5zyQzI0RaEeZWH5K5xjvUIGszTItHQpFPdH+u51f6G/LkS8Cg==", "dev": true }, - "@types/yargs": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-11.1.1.tgz", - "integrity": "sha512-Awgju4dqD8kHXX3jc/B/LaryJC7MsyNfnbN62lIbFzTi0GewH64zrkh4bxo/YTgVEK6r9V3GNecxMhXTJw0+jA==", - "dev": true - }, "ajv": { "version": "5.5.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", @@ -67,7 +61,8 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true }, "ansi-styles": { "version": "2.2.1", @@ -175,11 +170,6 @@ "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", "dev": true }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" - }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -205,42 +195,12 @@ "integrity": "sha512-13YaR6kiz0kBNmIVM87Io8Hp7bWOo4r61vkEANy8iH9R9bc6avud/1FT0SBpqR1RpIQADOh/Q+yHZDA1iL6ysA==", "dev": true }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, "codecov": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.0.2.tgz", @@ -294,16 +254,6 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -313,14 +263,6 @@ "assert-plus": "^1.0.0" } }, - "decamelize": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-2.0.0.tgz", - "integrity": "sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg==", - "requires": { - "xregexp": "4.0.0" - } - }, "deep-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", @@ -385,20 +327,6 @@ "integrity": "sha1-LUH1Y+H+QA7Uli/hpNXGp1Od9/Y=", "dev": true }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, "extend": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", @@ -448,14 +376,6 @@ } } }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -479,16 +399,6 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" - }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -570,21 +480,6 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -597,11 +492,6 @@ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -661,46 +551,12 @@ "verror": "1.10.0" } }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "requires": { - "invert-kv": "^1.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lru-cache": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, "make-error": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz", "integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==", "dev": true }, - "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", - "requires": { - "mimic-fn": "^1.0.0" - } - }, "mime-db": { "version": "1.33.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", @@ -716,11 +572,6 @@ "mime-db": "~1.33.0" } }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" - }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -759,19 +610,6 @@ "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", "dev": true }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, "nyc": { "version": "11.9.0", "resolved": "https://registry.npmjs.org/nyc/-/nyc-11.9.0.tgz", @@ -811,7 +649,6 @@ "version": "0.1.4", "bundled": true, "dev": true, - "optional": true, "requires": { "kind-of": "^3.0.2", "longest": "^1.0.1", @@ -1994,8 +1831,7 @@ "longest": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "loose-envify": { "version": "1.3.1", @@ -3419,64 +3255,18 @@ "wrappy": "1" } }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } - }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "p-limit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.0.0.tgz", - "integrity": "sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==" - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, "path-parse": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", @@ -3495,11 +3285,6 @@ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", @@ -3568,16 +3353,6 @@ "uuid": "^3.1.0" } }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" - }, "resolve": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", @@ -3630,29 +3405,6 @@ "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", "dev": true }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -3692,30 +3444,6 @@ "tweetnacl": "~0.14.0" } }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, "string_decoder": { "version": "1.1.1", "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -3729,15 +3457,11 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, "requires": { "ansi-regex": "^2.0.0" } }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", @@ -3896,12 +3620,6 @@ } } }, - "tslint-override": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/tslint-override/-/tslint-override-0.1.2.tgz", - "integrity": "sha512-6Xc6KF1NtoDDzYr+quZAXnKhtsItjyw+/n2618/kyp7iY8hdAjg2Tb1UlUABbXEVCvAzjVsLsDUyET5fLohUsg==", - "dev": true - }, "tsutils": { "version": "2.28.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", @@ -3928,9 +3646,9 @@ "optional": true }, "typescript": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", - "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==" + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", + "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==" }, "urlgrey": { "version": "0.4.4", @@ -3961,102 +3679,18 @@ "extsprintf": "^1.2.0" } }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "xregexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz", - "integrity": "sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==" - }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", "dev": true }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - }, - "yargs": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.1.tgz", - "integrity": "sha512-B0vRAp1hRX4jgIOWFtjfNjd9OA9RWYZ6tqGA9/I/IrTMsxmKvtWy+ersM+jzpQqbC3YfLzeABPdeTgcJ9eu1qQ==", - "requires": { - "cliui": "^4.0.0", - "decamelize": "^2.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^10.1.0" - } - }, - "yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", - "requires": { - "camelcase": "^4.1.0" - } - }, "yn": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", diff --git a/package.json b/package.json index e23e6cfc9..46ef87d70 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ "coverage": "nyc --source-map=true npm test && nyc report --reporter=text-lcov > coverage.lcov", "coverage-html": "nyc --source-map=true npm test && nyc report --reporter=html", "test-threaded": "npm run pretest && node ./test/threaded_runner.js && npm run posttest", - "clean": "rimraf \"src/**/*.js\" \"src/**/*.js.map\" \"test/**/*.js\" \"test/**/*.js.map\"", + "test-fast": "npm run pretest && node ./test/runner.js --ignoreDiagnostics && npm run posttest", + "clean": "rimraf \"src/**/*.js\" \"src/**/*.js.map\" \"test/**/*.js\" \"test/**/*.js.map\" \"test/compiler/testfiles/*.lua\"", "release-patch": "npm version patch", "release-minor": "npm version minor", "release-major": "npm version major", @@ -47,13 +48,11 @@ "node": ">=8.5.0" }, "dependencies": { - "typescript": "2.9.2", - "yargs": "^12.0.1" + "typescript": "^3.3.1" }, "devDependencies": { "@types/glob": "^5.0.35", "@types/node": "^9.6.23", - "@types/yargs": "^11.1.1", "alsatian": "^2.3.0", "circular-json": "^0.5.5", "codecov": "3.0.2", @@ -64,7 +63,6 @@ "rimraf": "^2.6.3", "threads": "^0.12.0", "ts-node": "^7.0.0", - "tslint": "^5.10.0", - "tslint-override": "^0.1.2" + "tslint": "^5.10.0" } } diff --git a/src/CommandLineParser.ts b/src/CommandLineParser.ts index cf1a349e2..4d631a501 100644 --- a/src/CommandLineParser.ts +++ b/src/CommandLineParser.ts @@ -1,154 +1,284 @@ import * as fs from "fs"; import * as path from "path"; import * as ts from "typescript"; -import * as yargs from "yargs"; -import {CompilerOptions} from "./CompilerOptions"; +import {CompilerOptions, LuaTarget, LuaLibImportKind} from "./CompilerOptions"; + +export type CLIParseResult = ParseResult; + +type ParseResult = + { isValid: true; result: T } + | { isValid: false, errorMessage: string}; interface ParsedCommandLine extends ts.ParsedCommandLine { options: CompilerOptions; } -interface YargsOptions { - [key: string]: yargs.Options; +interface BaseCLIOption { + aliases: string[]; + describe: string; + type: string; } -export const optionDeclarations: YargsOptions = { +interface CLIOption extends BaseCLIOption { + choices: T[]; + default: T; +} + +const optionDeclarations: {[key: string]: CLIOption} = { luaLibImport: { - choices: ["inline", "require", "none"], - default: "inline", + choices: [LuaLibImportKind.Inline, LuaLibImportKind.Require, LuaLibImportKind.Always, LuaLibImportKind.None], + default: LuaLibImportKind.Inline, describe: "Specifies how js standard features missing in lua are imported.", - type: "string", - }, + type: "enum", + } as CLIOption, luaTarget: { - alias: "lt", - choices: ["JIT", "5.3", "5.2", "5.1"], - default: "JIT", + aliases: ["lt"], + choices: [LuaTarget.LuaJIT, LuaTarget.Lua53, LuaTarget.Lua52, LuaTarget.Lua51], + default: LuaTarget.LuaJIT, describe: "Specify Lua target version.", - type: "string", - }, + type: "enum", + } as CLIOption, noHeader: { default: false, describe: "Specify if a header will be added to compiled files.", type: "boolean", - }, + } as CLIOption, noHoisting: { default: false, describe: "Disables hoisting.", type: "boolean", - }, + } as CLIOption, }; -class CLIError extends Error {} +export const { version } = require("../package.json"); + +const helpString = + `Version ${version}\n` + + "Syntax: tstl [options] [files...]\n\n" + + + "Examples: tstl path/to/file.ts [...]\n" + + " tstl -p path/to/tsconfig.json\n\n" + + + "In addition to the options listed below you can also pass options\n" + + "for the typescript compiler (For a list of options use tsc -h).\n" + + "Some tsc options might have no effect."; /** - * Removes defaults from the arguments. - * Returns a tuple where [0] is a copy of the options without defaults and [1] is the extracted defaults. + * Parse the supplied arguments. + * The result will include arguments supplied via CLI and arguments from tsconfig. */ -function getYargOptionsWithoutDefaults(options: YargsOptions): [YargsOptions, yargs.Arguments] { - // options is a deep object, Object.assign or {...options} still keeps the referece - const copy = JSON.parse(JSON.stringify(options)); +export function parseCommandLine(args: string[]): CLIParseResult +{ + let commandLine = ts.parseCommandLine(args); + + // Run diagnostics to check for invalid tsc options + const diagnosticsResult = runTsDiagnostics(commandLine); + if (diagnosticsResult.isValid === false) { + return diagnosticsResult; + } + + // This will add TS and TSTL options from a tsconfig + const configResult = readTsConfig(commandLine); + if (configResult.isValid === true) { + commandLine = configResult.result; + } else { + return { isValid: false, errorMessage: configResult.errorMessage }; + } + + // Run diagnostics to check for invalid tsconfig + const diagnosticsResult2 = runTsDiagnostics(commandLine); + if (diagnosticsResult2.isValid === false) { + return diagnosticsResult2; + } + + // Merge TSTL CLI options in (highest priority) will also set defaults if none specified + const tstlCLIResult = parseTSTLOptions(commandLine, args); + if (tstlCLIResult.isValid === true) { + commandLine = tstlCLIResult.result; + } else { + return { isValid: false, errorMessage: tstlCLIResult.errorMessage }; + } + + if (commandLine.options.project && !commandLine.options.rootDir) { + commandLine.options.rootDir = path.dirname(commandLine.options.project); + } - const optionDefaults: yargs.Arguments = {_: undefined, $0: undefined}; - for (const optionName in copy) { - const section = copy[optionName]; + if (!commandLine.options.rootDir) { + commandLine.options.rootDir = process.cwd(); + } - optionDefaults[optionName] = section.default; - delete section.default; + if (!commandLine.options.outDir) { + commandLine.options.outDir = commandLine.options.rootDir; } - return [copy, optionDefaults]; + return { isValid: true, result: commandLine as ParsedCommandLine }; } -/** - * Pares the supplied arguments. - * The result will include arguments supplied via CLI and arguments from tsconfig. - */ -export function parseCommandLine(args: string[]): ParsedCommandLine { - // Get a copy of the options without defaults to prevent defaults overriding project config - const [tstlOptions, tstlDefaults] = getYargOptionsWithoutDefaults(optionDeclarations); - - const parsedArgs = yargs - .usage( - "Syntax: tstl [options] [files...]\n\n" + - "In addition to the options listed below you can also pass options" + - "for the typescript compiler (For a list of options use tsc -h).\n" + - "Some tsc options might have no effect.") - .example("tstl path/to/file.ts [...]", "Compile files") - .example("tstl -p path/to/tsconfig.json", "Compile project") - .wrap(yargs.terminalWidth()) - .options(tstlOptions) - .fail((msg, err) => { - throw new CLIError(msg); - }) - .parse(args); +export function getHelpString(): string { + let result = helpString + "\n\n"; - let commandLine = ts.parseCommandLine(args); + result += "Options:\n"; + for (const optionName in optionDeclarations) { + const option = optionDeclarations[optionName]; + const aliasStrings = option.aliases + ? option.aliases.map(a => "-" + a) + : []; + + const optionString = aliasStrings.concat(["--" + optionName]).join("|"); + + const parameterDescribe = option.choices + ? option.choices.join("|") + : option.type; + + const spacing = " ".repeat(Math.max(1, 45 - optionString.length - parameterDescribe.length)); + + result += `\n ${optionString} <${parameterDescribe}>${spacing}${option.describe}\n`; + } - // Run diagnostics to check for invalid tsc/tstl options - runDiagnostics(commandLine); + return result; +} - // Add TSTL options from CLI - addTSTLOptions(commandLine, parsedArgs); +function readTsConfig(parsedCommandLine: ts.ParsedCommandLine): CLIParseResult +{ + const options = parsedCommandLine.options; // Load config - if (commandLine.options.project) { - findConfigFile(commandLine); - const configPath = commandLine.options.project; + if (options.project) { + const findProjectPathResult = findConfigFile(options); + if (findProjectPathResult.isValid === true) { + options.project = findProjectPathResult.result; + } else { + return { isValid: false, errorMessage: findProjectPathResult.errorMessage }; + } + + const configPath = options.project; const configContents = fs.readFileSync(configPath).toString(); const configJson = ts.parseConfigFileTextToJson(configPath, configContents); - commandLine = ts.parseJsonConfigFileContent( + const parsedJsonConfig = ts.parseJsonConfigFileContent( configJson.config, ts.sys, path.dirname(configPath), - commandLine.options + options ); - } - // Add TSTL options from tsconfig - addTSTLOptions(commandLine); + for (const key in parsedJsonConfig.raw) { + const option = optionDeclarations[key]; + if (option !== undefined) { + const value = readValue(parsedJsonConfig.raw[key], option.type, key); + if (option.choices) { + if (option.choices.indexOf(value) < 0) { + return { + isValid: false, + errorMessage: `Unknown ${key} value '${value}'.\nAccepted values: ${option.choices}`, + }; + } + } - // Add TSTL defaults last - addTSTLOptions(commandLine, tstlDefaults); + parsedJsonConfig.options[key] = value; + } + } + return { isValid: true, result: parsedJsonConfig }; + } + return { isValid: true, result: parsedCommandLine }; +} - // Run diagnostics again to check for errors in tsconfig - runDiagnostics(commandLine); +function parseTSTLOptions(commandLine: ts.ParsedCommandLine, args: string[]): CLIParseResult { + const result = {}; + for (let i = 0; i < args.length; i++) { + if (args[i].startsWith("--")) { + const argumentName = args[i].substr(2); + const option = optionDeclarations[argumentName]; + if (option) { + const argumentResult = getArgumentValue(argumentName, args[i + 1]); + i++; // Skip the value from being considered as argument name + if (argumentResult.isValid === true) { + result[argumentName] = argumentResult.result; + } else { + return { isValid: false, errorMessage: argumentResult.errorMessage }; + } + } + } else if (args[i].startsWith("-")) { + const argument = args[i].substr(1); + let argumentName: string; + for (const key in optionDeclarations) { + if (optionDeclarations[key].aliases && optionDeclarations[key].aliases.indexOf(argument) >= 0) { + argumentName = key; + break; + } + } - if (commandLine.options.project && !commandLine.options.rootDir) { - commandLine.options.rootDir = path.dirname(commandLine.options.project); + if (argumentName) { + const argumentResult = getArgumentValue(argumentName, args[i + 1]); + i++; // Skip the value from being considered as argument name + if (argumentResult.isValid === true) { + result[argumentName] = argumentResult.result; + } else { + return { isValid: false, errorMessage: argumentResult.errorMessage }; + } + } + } + } + for (const option in result) { + commandLine.options[option] = result[option]; + } + // Add defaults if not set + const defaultOptions = getDefaultOptions(); + for (const option in defaultOptions) { + if (!commandLine.options[option]) { + commandLine.options[option] = defaultOptions[option]; + } } + return { isValid: true, result: commandLine }; +} - if (!commandLine.options.rootDir) { - commandLine.options.rootDir = process.cwd(); +function getArgumentValue(argumentName: string, argument: string): ParseResult +{ + if (argument === undefined) { + return { isValid: false, errorMessage: `Missing value for parameter ${argumentName}`}; } - if (!commandLine.options.outDir) { - commandLine.options.outDir = commandLine.options.rootDir; + const option = optionDeclarations[argumentName]; + const value = readValue(argument, option.type, argumentName); + + if (option.choices) { + if (option.choices.indexOf(value) < 0) { + return { + isValid: false, + errorMessage: `Unknown ${argumentName} value '${value}'. Accepted values are: ${option.choices}`, + }; + } } - return commandLine as ParsedCommandLine; + return { isValid: true, result: value }; } -function addTSTLOptions( - commandLine: ts.ParsedCommandLine, - additionalArgs?: yargs.Arguments, - forceOverride?: boolean -): void -{ - additionalArgs = additionalArgs ? additionalArgs : commandLine.raw; - // Add compiler options that are ignored by TS parsers - if (additionalArgs) { - for (const arg in additionalArgs) { - // dont override, this will prioritize CLI over tsconfig. - if (optionDeclarations[arg] && (!commandLine.options[arg] || forceOverride)) { - commandLine.options[arg] = additionalArgs[arg]; - } +function readValue(valueString: string, valueType: string, parameterName: string): string | boolean { + if (valueType === "boolean") { + return valueString === "true" || valueString === "t" + ? true + : false; + } else if (valueType === "enum") { + return valueString.toLowerCase(); + } else { + return valueString; + } +} + +function getDefaultOptions(): CompilerOptions { + const options: CompilerOptions = {}; + + for (const optionName in optionDeclarations) { + if (optionDeclarations[optionName].default !== undefined) { + options[optionName] = optionDeclarations[optionName].default; } } + + return options; } /** Check the current state of the ParsedCommandLine for errors */ -function runDiagnostics(commandLine: ts.ParsedCommandLine): void { +function runTsDiagnostics(commandLine: ts.ParsedCommandLine): ParseResult { // Remove files that dont exist commandLine.fileNames = commandLine.fileNames.filter(file => fs.existsSync(file) || fs.existsSync(file + ".ts")); @@ -158,7 +288,7 @@ function runDiagnostics(commandLine: ts.ParsedCommandLine): void { const optionNames: string[] = []; for (const key of Object.keys(optionDeclarations)) { optionNames.push(key); - const alias = optionDeclarations[key].alias; + const alias = optionDeclarations[key].aliases; if (alias) { if (typeof alias === "string") { optionNames.push(alias); @@ -168,36 +298,40 @@ function runDiagnostics(commandLine: ts.ParsedCommandLine): void { } } - commandLine.errors.forEach(err => { - let ignore = false; + for (const err of commandLine.errors) { // Ignore errors caused by tstl specific compiler options if (err.code === tsInvalidCompilerOptionErrorCode) { + let ignore = false; for (const optionName of optionNames) { if (err.messageText.toString().indexOf(optionName) !== -1) { ignore = true; + break; } } + if (!ignore) { - throw new CLIError(`error TS${err.code}: ${err.messageText}`); + return { isValid: false, errorMessage: `error TS${err.code}: ${err.messageText}`}; } } - }); + } } + + return { isValid: true, result: true }; } /** Find configFile, function from ts api seems to be broken? */ -export function findConfigFile(commandLine: ts.ParsedCommandLine): void { - if (!commandLine.options.project) { - throw new CLIError(`error no base path provided, could not find config.`); +export function findConfigFile(options: ts.CompilerOptions): ParseResult { + if (!options.project) { + return { isValid: false, errorMessage: `error no base path provided, could not find config.`}; } - let configPath = commandLine.options.project; + let configPath = options.project; // If the project path is wrapped in double quotes, remove them if (/^".*"$/.test(configPath)) { configPath = configPath.substring(1, configPath.length - 1); } /* istanbul ignore if: Testing else part is not really possible via automated tests */ if (!path.isAbsolute(configPath)) { - // TODO check if commandLine.options.project can even contain non absolute paths + // TODO check if options.project can even contain non absolute paths configPath = path.join(process.cwd(), configPath); } if (fs.statSync(configPath).isDirectory()) { @@ -215,5 +349,6 @@ export function findConfigFile(commandLine: ts.ParsedCommandLine): void { } } } - commandLine.options.project = configPath; + + return { isValid: true, result: configPath }; } diff --git a/src/Compiler.ts b/src/Compiler.ts index 9dfeadf30..b23b83683 100644 --- a/src/Compiler.ts +++ b/src/Compiler.ts @@ -2,17 +2,33 @@ import * as fs from "fs"; import * as path from "path"; import * as ts from "typescript"; -import {parseCommandLine} from "./CommandLineParser"; +import * as CommandLineParser from "./CommandLineParser"; import {CompilerOptions, LuaLibImportKind, LuaTarget} from "./CompilerOptions"; import {LuaTranspiler} from "./LuaTranspiler"; export function compile(argv: string[]): void { - const commandLine = parseCommandLine(argv); - /* istanbul ignore if: tested in test/compiler/watchmode.spec with subproccess */ - if (commandLine.options.watch) { - watchWithOptions(commandLine.fileNames, commandLine.options); + const parseResult = CommandLineParser.parseCommandLine(argv); + + if (parseResult.isValid === true) { + + if (parseResult.result.options.help) { + console.log(CommandLineParser.getHelpString()); + return; + } + + if (parseResult.result.options.version) { + console.log(CommandLineParser.version); + return; + } + + /* istanbul ignore if: tested in test/compiler/watchmode.spec with subproccess */ + if (parseResult.result.options.watch) { + watchWithOptions(parseResult.result.fileNames, parseResult.result.options); + } else { + compileFilesWithOptions(parseResult.result.fileNames, parseResult.result.options); + } } else { - compileFilesWithOptions(commandLine.fileNames, commandLine.options); + console.error(`Invalid CLI input: ${parseResult.errorMessage}`); } } @@ -65,19 +81,17 @@ export function compileFilesWithOptions(fileNames: string[], options: CompilerOp transpiler.emitFilesAndReportErrors(); } -const libSource = fs.readFileSync(path.join(path.dirname(require.resolve("typescript")), "lib.es6.d.ts")).toString(); +const libCache: {[key: string]: string} = {}; const defaultCompilerOptions: CompilerOptions = { luaLibImport: LuaLibImportKind.Require, luaTarget: LuaTarget.Lua53, }; -export function transpileString( - str: string, - options: CompilerOptions = defaultCompilerOptions, - ignoreDiagnostics = false -): string { - const compilerHost = { +export function createStringCompilerProgram( + input: string, options: CompilerOptions = defaultCompilerOptions): ts.Program { + + const compilerHost = { directoryExists: () => true, fileExists: (fileName): boolean => true, getCanonicalFileName: fileName => fileName, @@ -86,12 +100,16 @@ export function transpileString( getDirectories: () => [], getNewLine: () => "\n", - getSourceFile: (filename, languageVersion) => { + getSourceFile: (filename: string, languageVersion) => { if (filename === "file.ts") { - return ts.createSourceFile(filename, str, ts.ScriptTarget.Latest, false); + return ts.createSourceFile(filename, input, ts.ScriptTarget.Latest, false); } - if (filename === "lib.es6.d.ts") { - return ts.createSourceFile(filename, libSource, ts.ScriptTarget.Latest, false); + if (filename.indexOf(".d.ts") !== -1) { + if (!libCache[filename]) { + libCache[filename] = + fs.readFileSync(path.join(path.dirname(require.resolve("typescript")), filename)).toString(); + } + return ts.createSourceFile(filename, libCache[filename], ts.ScriptTarget.Latest, false); } return undefined; }, @@ -102,7 +120,15 @@ export function transpileString( // Don't write output writeFile: (name, text, writeByteOrderMark) => undefined, }; - const program = ts.createProgram(["file.ts"], options, compilerHost); + return ts.createProgram(["file.ts"], options, compilerHost); +} + +export function transpileString( + str: string, + options: CompilerOptions = defaultCompilerOptions, + ignoreDiagnostics = false +): string { + const program = createStringCompilerProgram(str, options); if (!ignoreDiagnostics) { const diagnostics = ts.getPreEmitDiagnostics(program); diff --git a/src/LuaTranspiler.ts b/src/LuaTranspiler.ts index bb49ce9dc..a4a4416a2 100644 --- a/src/LuaTranspiler.ts +++ b/src/LuaTranspiler.ts @@ -70,7 +70,9 @@ export class LuaTranspiler { return error; } - this.program.getSourceFiles().forEach(sourceFile => this.emitSourceFile(sourceFile)); + this.program.getSourceFiles().forEach(sourceFile => { + this.emitSourceFile(sourceFile); + }); // Copy lualib to target dir if (this.options.luaLibImport === LuaLibImportKind.Require @@ -117,7 +119,6 @@ export class LuaTranspiler { // Graciously handle transpilation errors console.error("Encountered error parsing file: " + exception.message); console.error(`${sourceFile.fileName} (${1 + pos.line},${pos.character})\n${exception.stack}`); - process.exit(1); } else { throw exception; } diff --git a/src/TSHelper.ts b/src/TSHelper.ts index f4d847e0e..389ccac37 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -62,7 +62,7 @@ export class TSHelper { for (const clause of node.heritageClauses) { if (clause.token === ts.SyntaxKind.ExtendsKeyword) { const superType = checker.getTypeAtLocation(clause.types[0]); - const decorators = this.getCustomDecorators(superType, checker); + const decorators = TSHelper.getCustomDecorators(superType, checker); if (!decorators.has(DecoratorKind.PureAbstract)) { return clause.types[0]; } @@ -73,24 +73,36 @@ export class TSHelper { } public static getExtendedType(node: ts.ClassLikeDeclarationBase, checker: ts.TypeChecker): ts.Type | undefined { - const extendedTypeNode = this.getExtendedTypeNode(node, checker); + const extendedTypeNode = TSHelper.getExtendedTypeNode(node, checker); return extendedTypeNode && checker.getTypeAtLocation(extendedTypeNode); } public static isFileModule(sourceFile: ts.SourceFile): boolean { if (sourceFile) { - // Vanilla ts flags files as external module if they have an import or - // export statement, we only check for export statements - // TODO will break in 3.x - return sourceFile.statements.some( - statement => (ts.getCombinedModifierFlags(statement) & ts.ModifierFlags.Export) !== 0 - || statement.kind === ts.SyntaxKind.ExportAssignment - || statement.kind === ts.SyntaxKind.ExportDeclaration - ); + return sourceFile.statements.some(TSHelper.isStatementExported); } return false; } + public static isStatementExported(statement: ts.Statement): boolean { + if (ts.isExportAssignment(statement) || ts.isExportDeclaration(statement)) { + return true; + } + if (ts.isVariableStatement(statement)) { + return statement.declarationList.declarations.some( + declaration => (ts.getCombinedModifierFlags(declaration) & ts.ModifierFlags.Export) !== 0); + } + return TSHelper.isDeclaration(statement) + && ((ts.getCombinedModifierFlags(statement) & ts.ModifierFlags.Export) !== 0); + } + + public static isDeclaration(node: ts.Node): node is ts.Declaration { + return ts.isEnumDeclaration(node) || ts.isClassDeclaration(node) || ts.isExportDeclaration(node) + || ts.isImportDeclaration(node) || ts.isMethodDeclaration(node) || ts.isModuleDeclaration(node) + || ts.isFunctionDeclaration(node) || ts.isVariableDeclaration(node) || ts.isInterfaceDeclaration(node) + || ts.isTypeAliasDeclaration(node) || ts.isNamespaceExportDeclaration(node); + } + public static isInDestructingAssignment(node: ts.Node): boolean { return node.parent && ((ts.isVariableDeclaration(node.parent) && ts.isArrayBindingPattern(node.parent.name)) || (ts.isBinaryExpression(node.parent) && ts.isArrayLiteralExpression(node.parent.left))); @@ -112,7 +124,7 @@ export class TSHelper { const superTypes = type.getBaseTypes(); if (superTypes) { for (const superType of superTypes) { - if (this.forTypeOrAnySupertype(superType, checker, predicate)) { + if (TSHelper.forTypeOrAnySupertype(superType, checker, predicate)) { return true; } } @@ -128,12 +140,12 @@ export class TSHelper { public static isArrayTypeNode(typeNode: ts.TypeNode): boolean { return typeNode.kind === ts.SyntaxKind.ArrayType || typeNode.kind === ts.SyntaxKind.TupleType || ((typeNode.kind === ts.SyntaxKind.UnionType || typeNode.kind === ts.SyntaxKind.IntersectionType) && - (typeNode as ts.UnionOrIntersectionTypeNode).types.some(this.isArrayTypeNode)); + (typeNode as ts.UnionOrIntersectionTypeNode).types.some(TSHelper.isArrayTypeNode)); } public static isExplicitArrayType(type: ts.Type, checker: ts.TypeChecker): boolean { const typeNode = checker.typeToTypeNode(type, undefined, ts.NodeBuilderFlags.InTypeAlias); - return typeNode && this.isArrayTypeNode(typeNode); + return typeNode && TSHelper.isArrayTypeNode(typeNode); } public static isFunctionType(type: ts.Type, checker: ts.TypeChecker): boolean { @@ -142,13 +154,13 @@ export class TSHelper { } public static isArrayType(type: ts.Type, checker: ts.TypeChecker): boolean { - return this.forTypeOrAnySupertype(type, checker, t => this.isExplicitArrayType(t, checker)); + return TSHelper.forTypeOrAnySupertype(type, checker, t => TSHelper.isExplicitArrayType(t, checker)); } public static isLuaIteratorCall(node: ts.Node, checker: ts.TypeChecker): boolean { if (ts.isCallExpression(node) && node.parent && ts.isForOfStatement(node.parent)) { const type = checker.getTypeAtLocation(node.expression); - return this.getCustomDecorators(type, checker).has(DecoratorKind.LuaIterator); + return TSHelper.getCustomDecorators(type, checker).has(DecoratorKind.LuaIterator); } else { return false; } @@ -158,19 +170,19 @@ export class TSHelper { if (ts.isCallExpression(node)) { const type = checker.getTypeAtLocation(node.expression); - return this.getCustomDecorators(type, checker).has(DecoratorKind.TupleReturn); + return TSHelper.getCustomDecorators(type, checker).has(DecoratorKind.TupleReturn); } else { return false; } } public static isInTupleReturnFunction(node: ts.Node, checker: ts.TypeChecker): boolean { - const declaration = this.findFirstNodeAbove( + const declaration = TSHelper.findFirstNodeAbove( node, (n): n is ts.Node => ts.isFunctionDeclaration(n) || ts.isMethodDeclaration(n) ); if (declaration) { - const decorators = this.getCustomDecorators(checker.getTypeAtLocation(declaration), checker); + const decorators = TSHelper.getCustomDecorators(checker.getTypeAtLocation(declaration), checker); return decorators.has(DecoratorKind.TupleReturn) // Lua iterators are not 'true' tupleReturn functions as they actually return a function && !decorators.has(DecoratorKind.LuaIterator); @@ -180,7 +192,7 @@ export class TSHelper { } public static getContainingFunctionReturnType(node: ts.Node, checker: ts.TypeChecker): ts.Type { - const declaration = this.findFirstNodeAbove(node, ts.isFunctionLike); + const declaration = TSHelper.findFirstNodeAbove(node, ts.isFunctionLike); if (declaration) { const signature = checker.getSignatureFromDeclaration(declaration); return checker.getReturnTypeOfSignature(signature); @@ -213,7 +225,6 @@ export class TSHelper { console.warn(`Encountered unknown decorator ${decStr}.`); } }); - symbol.getJsDocTags().forEach(tag => { if (Decorator.isValid(tag.name)) { const dec = new Decorator(tag.name, tag.text ? tag.text.split(" ") : []); @@ -225,10 +236,10 @@ export class TSHelper { public static getCustomDecorators(type: ts.Type, checker: ts.TypeChecker): Map { const decMap = new Map(); if (type.symbol) { - this.collectCustomDecorators(type.symbol, checker, decMap); + TSHelper.collectCustomDecorators(type.symbol, checker, decMap); } if (type.aliasSymbol) { - this.collectCustomDecorators(type.aliasSymbol, checker, decMap); + TSHelper.collectCustomDecorators(type.aliasSymbol, checker, decMap); } return decMap; } @@ -255,20 +266,20 @@ export class TSHelper { public static typeHasGetAccessor(type: ts.Type, name: ts.__String, checker: ts.TypeChecker): boolean | undefined { if (type.isUnion()) { - if (type.types.some(t => this.typeHasGetAccessor(t, name, checker))) { + if (type.types.some(t => TSHelper.typeHasGetAccessor(t, name, checker))) { // undefined if only a subset of types implements the accessor - return type.types.every(t => this.typeHasGetAccessor(t, name, checker)) ? true : undefined; + return type.types.every(t => TSHelper.typeHasGetAccessor(t, name, checker)) ? true : undefined; } return false; } - return this.forTypeOrAnySupertype(type, checker, t => this.hasExplicitGetAccessor(t, name)); + return TSHelper.forTypeOrAnySupertype(type, checker, t => TSHelper.hasExplicitGetAccessor(t, name)); } public static hasGetAccessor(node: ts.Node, checker: ts.TypeChecker): boolean | undefined { if (ts.isPropertyAccessExpression(node)) { const name = node.name.escapedText; const type = checker.getTypeAtLocation(node.expression); - return this.typeHasGetAccessor(type, name, checker); + return TSHelper.typeHasGetAccessor(type, name, checker); } return false; } @@ -282,20 +293,20 @@ export class TSHelper { public static typeHasSetAccessor(type: ts.Type, name: ts.__String, checker: ts.TypeChecker): boolean | undefined { if (type.isUnion()) { - if (type.types.some(t => this.typeHasSetAccessor(t, name, checker))) { + if (type.types.some(t => TSHelper.typeHasSetAccessor(t, name, checker))) { // undefined if only a subset of types implements the accessor - return type.types.every(t => this.typeHasSetAccessor(t, name, checker)) ? true : undefined; + return type.types.every(t => TSHelper.typeHasSetAccessor(t, name, checker)) ? true : undefined; } return false; } - return this.forTypeOrAnySupertype(type, checker, t => this.hasExplicitSetAccessor(t, name)); + return TSHelper.forTypeOrAnySupertype(type, checker, t => TSHelper.hasExplicitSetAccessor(t, name)); } public static hasSetAccessor(node: ts.Node, checker: ts.TypeChecker): boolean { if (ts.isPropertyAccessExpression(node)) { const name = node.name.escapedText; const type = checker.getTypeAtLocation(node.expression); - return this.typeHasSetAccessor(type, name, checker); + return TSHelper.typeHasSetAccessor(type, name, checker); } return false; } @@ -356,10 +367,10 @@ export class TSHelper { public static isAccessExpressionWithEvaluationEffects(node: ts.Expression, checker: ts.TypeChecker): [boolean, ts.Expression, ts.Expression] { if (ts.isElementAccessExpression(node) && - (this.isExpressionWithEvaluationEffect(node.expression) - || this.isExpressionWithEvaluationEffect(node.argumentExpression))) { + (TSHelper.isExpressionWithEvaluationEffect(node.expression) + || TSHelper.isExpressionWithEvaluationEffect(node.argumentExpression))) { const type = checker.getTypeAtLocation(node.expression); - if (this.isArrayType(type, checker)) { + if (TSHelper.isArrayType(type, checker)) { // Offset arrays by one const oneLit = ts.createNumericLiteral("1"); const exp = ts.createParen(node.argumentExpression); @@ -368,7 +379,7 @@ export class TSHelper { } else { return [true, node.expression, node.argumentExpression]; } - } else if (ts.isPropertyAccessExpression(node) && this.isExpressionWithEvaluationEffect(node.expression)) { + } else if (ts.isPropertyAccessExpression(node) && TSHelper.isExpressionWithEvaluationEffect(node.expression)) { return [true, node.expression, ts.createStringLiteral(node.name.text)]; } return [false, undefined, undefined]; @@ -448,7 +459,7 @@ export class TSHelper { } public static getSignatureDeclarations( - signatures: ts.Signature[], + signatures: ReadonlyArray, checker: ts.TypeChecker ): ts.SignatureDeclaration[] { @@ -456,10 +467,10 @@ export class TSHelper { for (const signature of signatures) { const signatureDeclaration = signature.getDeclaration(); if ((ts.isFunctionExpression(signatureDeclaration) || ts.isArrowFunction(signatureDeclaration)) - && !this.getExplicitThisParameter(signatureDeclaration)) + && !TSHelper.getExplicitThisParameter(signatureDeclaration)) { // Infer type of function expressions/arrow functions - const inferredType = this.inferAssignedType(signatureDeclaration, checker); + const inferredType = TSHelper.inferAssignedType(signatureDeclaration, checker); if (inferredType) { const inferredSignatures = inferredType.getCallSignatures(); if (inferredSignatures.length > 0) { @@ -478,7 +489,7 @@ export class TSHelper { checker: ts.TypeChecker ): ContextType { - const thisParameter = this.getExplicitThisParameter(signatureDeclaration); + const thisParameter = TSHelper.getExplicitThisParameter(signatureDeclaration); if (thisParameter) { // Explicit 'this' return thisParameter.type && thisParameter.type.kind === ts.SyntaxKind.VoidKeyword @@ -497,7 +508,8 @@ export class TSHelper { } if (ts.isBinaryExpression(signatureDeclaration.parent)) { // Function expression: check type being assigned to - return this.getFunctionContextType(checker.getTypeAtLocation(signatureDeclaration.parent.left), checker); + return TSHelper.getFunctionContextType( + checker.getTypeAtLocation(signatureDeclaration.parent.left), checker); } return ContextType.Void; } @@ -523,15 +535,16 @@ export class TSHelper { } if (type.isUnion()) { - return this.reduceContextTypes(type.types.map(t => this.getFunctionContextType(t, checker))); + return TSHelper.reduceContextTypes(type.types.map(t => TSHelper.getFunctionContextType(t, checker))); } const signatures = checker.getSignaturesOfType(type, ts.SignatureKind.Call); if (signatures.length === 0) { return ContextType.None; } - const signatureDeclarations = this.getSignatureDeclarations(signatures, checker); - return this.reduceContextTypes(signatureDeclarations.map(s => this.getDeclarationContextType(s, checker))); + const signatureDeclarations = TSHelper.getSignatureDeclarations(signatures, checker); + return TSHelper.reduceContextTypes( + signatureDeclarations.map(s => TSHelper.getDeclarationContextType(s, checker))); } public static isDefaultArrayPropertyName(methodName: string): boolean { @@ -582,7 +595,7 @@ export class TSHelper { return true; } else if (type.isUnion()) { for (const subType of type.types) { - if (this.isFalsible(subType, strictNullChecks)) { + if (TSHelper.isFalsible(subType, strictNullChecks)) { return true; } } diff --git a/test/src/util.ts b/test/src/util.ts index fe63b218f..ea122719e 100644 --- a/test/src/util.ts +++ b/test/src/util.ts @@ -3,7 +3,7 @@ import * as ts from "typescript"; import { Expect } from "alsatian"; -import { transpileString as compilerTranspileString } from "../../src/Compiler"; +import { transpileString as compilerTranspileString, createStringCompilerProgram } from "../../src/Compiler"; import { CompilerOptions, LuaTarget, LuaLibImportKind } from "../../src/CompilerOptions"; import {lauxlib, lua, lualib, to_jsstring, to_luastring } from "fengari"; @@ -91,8 +91,9 @@ export function transpileAndExecute( ${tsHeader ? tsHeader : ""} function __runTest(): any {${tsStr}}`; + const ignoreDiagnosticsOverride = process.argv[2] === "--ignoreDiagnostics"; const lua = `${luaHeader ? luaHeader : ""} - ${transpileString(wrappedTsString, compilerOptions, false)} + ${transpileString(wrappedTsString, compilerOptions, ignoreDiagnosticsOverride)} return __runTest();`; return executeLua(lua); @@ -118,35 +119,7 @@ export function transpileExecuteAndReturnExport( export function parseTypeScript(typescript: string, target: LuaTarget = LuaTarget.Lua53) : [ts.SourceFile, ts.TypeChecker] { - const compilerHost = { - directoryExists: () => true, - fileExists: (fileName): boolean => true, - getCanonicalFileName: fileName => fileName, - getCurrentDirectory: () => "", - getDefaultLibFileName: () => "lib.es6.d.ts", - getDirectories: () => [], - getNewLine: () => "\n", - - getSourceFile: (filename, languageVersion) => { - if (filename === "file.ts") { - return ts.createSourceFile(filename, typescript, ts.ScriptTarget.Latest, false); - } - if (filename === "lib.es6.d.ts") { - const libPath = path.join(path.dirname(require.resolve("typescript")), "lib.es6.d.ts"); - const libSource = fs.readFileSync(libPath).toString(); - return ts.createSourceFile(filename, libSource, ts.ScriptTarget.Latest, false); - } - return undefined; - }, - - readFile: () => "", - - useCaseSensitiveFileNames: () => false, - // Don't write output - writeFile: (name, text, writeByteOrderMark) => undefined, - }; - - const program = ts.createProgram(["file.ts"], { luaTarget: target }, compilerHost); + const program = createStringCompilerProgram(typescript, { luaTarget: target }); return [program.getSourceFile("file.ts"), program.getTypeChecker()]; } diff --git a/test/unit/cli.spec.ts b/test/unit/cli.spec.ts deleted file mode 100644 index bfbc98dc6..000000000 --- a/test/unit/cli.spec.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { Expect, Test, TestCase } from "alsatian"; - -import { findConfigFile, parseCommandLine } from "../../src/CommandLineParser"; - -export class CLITests { - - @Test("defaultOption") - @TestCase("luaTarget", "JIT") - @TestCase("noHeader", false) - @TestCase("luaLibImport", "inline") - @TestCase("rootDir", process.cwd()) - @TestCase("outDir", process.cwd()) - public defaultOptions(option: any, expected: any): void { - const parsedCommandLine = parseCommandLine([]); - - Expect(expected).toBe(parsedCommandLine.options[option]); - } - - @Test("ValidLuaTarget") - public validLuaTarget(): void { - const parsedCommandLine = parseCommandLine(['--luaTarget', '5.3']); - Expect(parsedCommandLine.options["luaTarget"]).toBe("5.3"); - } - - @Test("InvalidLuaTarget") - public invalidLuaTarget(): void { - // Don't check error message because the yargs library messes the message up. - Expect(() => parseCommandLine(['--luaTarget', '42'])).toThrow(); - } - - @Test("InvalidArgumentTSTL") - public invalidArgument(): void { - // Don't check error message because the yargs library messes the message up. - Expect(() => parseCommandLine(['--invalidTarget', 'test'])).toThrow(); - } - - @Test("outDir") - public outDir(): void { - const parsedCommandLine = parseCommandLine(['--outDir', './test']); - - Expect(parsedCommandLine.options['outDir']).toBe('./test'); - } - - @Test("rootDir") - public rootDir(): void { - const parsedCommandLine = parseCommandLine(['--rootDir', './test']); - - Expect(parsedCommandLine.options['rootDir']).toBe('./test'); - Expect(parsedCommandLine.options['outDir']).toBe('./test'); - } - - @Test("outDirAndRooDir") - public outDirAndRooDir(): void { - const parsedCommandLine = parseCommandLine(['--outDir', './testOut', '--rootDir', './testRoot']); - - Expect(parsedCommandLine.options['outDir']).toBe('./testOut'); - Expect(parsedCommandLine.options['rootDir']).toBe('./testRoot'); - } - - @Test("Find config no path") - public findConfigNoPath(): void { - Expect(() => findConfigFile({options: {}, fileNames: [], errors: []})).toThrow(); - - } - -} diff --git a/test/unit/commandLineParser.spec.ts b/test/unit/commandLineParser.spec.ts new file mode 100644 index 000000000..3b9bceacd --- /dev/null +++ b/test/unit/commandLineParser.spec.ts @@ -0,0 +1,197 @@ +import { Expect, Test, TestCase } from "alsatian"; + +import { findConfigFile, parseCommandLine } from "../../src/CommandLineParser"; +import { LuaTarget, LuaLibImportKind } from "../../src/CompilerOptions"; + +export class CommandLineParserTests +{ + @TestCase([""], LuaLibImportKind.Inline) + @TestCase(["--luaLibImport", "none"], LuaLibImportKind.None) + @TestCase(["--luaLibImport", "always"], LuaLibImportKind.Always) + @TestCase(["--luaLibImport", "inline"], LuaLibImportKind.Inline) + @TestCase(["--luaLibImport", "require"], LuaLibImportKind.Require) + @Test("CLI parser luaLibImportKind") + public cliParserLuaLibImportKind(args: string[], expected: LuaLibImportKind): void { + const result = parseCommandLine(args); + if (result.isValid === true) { + Expect(result.result.options.luaLibImport).toBe(expected); + } else { + Expect(result.isValid).toBeTruthy(); + } + } + + @Test("CLI parser invalid luaLibImportKind") + public cliParserInvalidLuaLibImportKind(): void { + const result = parseCommandLine(["--luaLibImport", "invalid"]); + Expect(result.isValid).toBe(false); + } + + @TestCase([""], LuaTarget.LuaJIT) + @TestCase(["--luaTarget", "5.1"], LuaTarget.Lua51) + @TestCase(["--luaTarget", "5.2"], LuaTarget.Lua52) + @TestCase(["--luaTarget", "jit"], LuaTarget.LuaJIT) + @TestCase(["--luaTarget", "JIT"], LuaTarget.LuaJIT) + @TestCase(["--luaTarget", "5.3"], LuaTarget.Lua53) + @Test("CLI parser luaTarget") + public cliParserLuaTarget(args: string[], expected: LuaTarget): void { + const result = parseCommandLine(args); + if (result.isValid === true) { + Expect(result.result.options.luaTarget).toBe(expected); + } else { + Expect(result.isValid).toBeTruthy(); + } + } + + @TestCase(["-lt", "5.1"], LuaTarget.Lua51) + @TestCase(["-lt", "5.2"], LuaTarget.Lua52) + @TestCase(["-lt", "jit"], LuaTarget.LuaJIT) + @TestCase(["-lt", "JIT"], LuaTarget.LuaJIT) + @TestCase(["-lt", "5.3"], LuaTarget.Lua53) + @Test("CLI parser luaTarget") + public cliParserLuaTargetAlias(args: string[], expected: LuaTarget): void { + const result = parseCommandLine(args); + if (result.isValid === true) { + Expect(result.result.options.luaTarget).toBe(expected); + } else { + Expect(result.isValid).toBeTruthy(); + } + } + + @Test("CLI parser invalid luaTarget") + public cliParserInvalidLuaTarget(): void { + const result = parseCommandLine(["--luatTarget", "invalid"]); + Expect(result.isValid).toBe(false); + } + + @TestCase([""], false) + @TestCase(["--noHeader", "true"], true) + @TestCase(["--noHeader", "false"], false) + @Test("CLI parser noHeader") + public cliParserNoHeader(args: string[], expected: boolean): void { + const result = parseCommandLine(args); + if (result.isValid === true) { + Expect(result.result.options.noHeader).toBe(expected); + } else { + Expect(result.isValid).toBeTruthy(); + } + } + + @TestCase([""], false) + @TestCase(["--project", "tsconfig.json"], true) + @TestCase(["-p", "tsconfig.json"], true) + @Test("CLI parser project") + public cliParserProject(args: string[], expected: boolean): void { + const result = parseCommandLine(args); + if (result.isValid === true) { + Expect(result.result.options.project !== undefined).toBe(expected); + } else { + Expect(result.isValid).toBeTruthy(); + } + } + + @TestCase([""], false) + @TestCase(["--help"], true) + @TestCase(["-h"], true) + @Test("CLI parser project") + public cliParserHelp(args: string[], expected: boolean): void { + const result = parseCommandLine(args); + if (result.isValid === true) { + Expect(result.result.options.help === true).toBe(expected); + } else { + Expect(result.isValid).toBeTruthy(); + } + } + + @TestCase([""], false) + @TestCase(["--version"], true) + @TestCase(["-v"], true) + @Test("CLI parser project") + public cliParserVersion(args: string[], expected: boolean): void { + const result = parseCommandLine(args); + if (result.isValid === true) { + Expect(result.result.options.version === true).toBe(expected); + } else { + Expect(result.isValid).toBeTruthy(); + } + } + + @Test("defaultOption") + @TestCase("luaTarget", LuaTarget.LuaJIT) + @TestCase("noHeader", false) + @TestCase("luaLibImport", "inline") + @TestCase("rootDir", process.cwd()) + @TestCase("outDir", process.cwd()) + public defaultOptions(option: any, expected: any): void { + const parsedCommandLine = parseCommandLine([]); + if (parsedCommandLine.isValid) { + Expect(expected).toBe(parsedCommandLine.result.options[option]); + } else { + Expect(parsedCommandLine.isValid).toBeTruthy(); + } + } + + @Test("ValidLuaTarget") + public validLuaTarget(): void { + const parsedCommandLine = parseCommandLine(['--luaTarget', '5.3']); + if (parsedCommandLine.isValid) { + Expect(parsedCommandLine.result.options["luaTarget"]).toBe("5.3"); + } else { + Expect(parsedCommandLine.isValid).toBeTruthy(); + } + } + + @Test("InvalidLuaTarget") + public invalidLuaTarget(): void { + // Don't check error message because the yargs library messes the message up. + const result = parseCommandLine(['--luaTarget', '42']); + Expect(result.isValid).toBe(false); + } + + @Test("InvalidArgumentTSTL") + public invalidArgument(): void { + // Don't check error message because the yargs library messes the message up. + const result = parseCommandLine(['--invalidTarget', 'test']); + Expect(result.isValid).toBe(false); + } + + @Test("outDir") + public outDir(): void { + const parsedCommandLine = parseCommandLine(['--outDir', './test']); + + if (parsedCommandLine.isValid) { + Expect(parsedCommandLine.result.options['outDir']).toBe('./test'); + } else { + Expect(parsedCommandLine.isValid).toBeTruthy(); + } + } + + @Test("rootDir") + public rootDir(): void { + const parsedCommandLine = parseCommandLine(['--rootDir', './test']); + + if (parsedCommandLine.isValid) { + Expect(parsedCommandLine.result.options['rootDir']).toBe('./test'); + Expect(parsedCommandLine.result.options['outDir']).toBe('./test'); + } else { + Expect(parsedCommandLine.isValid).toBeTruthy(); + } + } + + @Test("outDirAndRooDir") + public outDirAndRooDir(): void { + const parsedCommandLine = parseCommandLine(['--outDir', './testOut', '--rootDir', './testRoot']); + + if (parsedCommandLine.isValid) { + Expect(parsedCommandLine.result.options['outDir']).toBe('./testOut'); + Expect(parsedCommandLine.result.options['rootDir']).toBe('./testRoot'); + } else { + Expect(parsedCommandLine.isValid).toBeTruthy(); + } + } + + @Test("Find config no path") + public findConfigNoPath(): void { + const result = findConfigFile({ options: {}, fileNames: [], errors: [] }); + Expect(result.isValid).toBe(false); + } +} diff --git a/test/unit/compiler/configuration/mixed/index.spec.ts b/test/unit/compiler/configuration/mixed/index.spec.ts index 1268e1ba5..179a8ac77 100644 --- a/test/unit/compiler/configuration/mixed/index.spec.ts +++ b/test/unit/compiler/configuration/mixed/index.spec.ts @@ -4,12 +4,12 @@ import * as path from "path"; import * as ts from "typescript"; import { CompilerOptions, LuaLibImportKind } from "../../../../../src/CompilerOptions"; -import { optionDeclarations, parseCommandLine } from "../../../../../src/CommandLineParser"; - -export class MixedConfigurationTests { +import { parseCommandLine } from "../../../../../src/CommandLineParser"; +export class MixedConfigurationTests +{ @Test("tsconfig.json mixed with cmd line args") - public tsconfigMixedWithCmdLineArgs() { + public tsconfigMixedWithCmdLineArgs(): void { const rootPath = __dirname; const tsConfigPath = path.join(rootPath, "project-tsconfig.json"); const expectedTsConfig = ts.parseJsonConfigFileContent( @@ -26,16 +26,21 @@ export class MixedConfigurationTests { `${path.join(rootPath, "test.ts")}`, ]); - Expect(parsedArgs.options).toEqual({ - ...expectedTsConfig.options, - // Overridden by cmd args (set to "none" in project-tsconfig.json) - luaLibImport: LuaLibImportKind.Inline, - // Only set in tsconfig, TSTL default is "JIT" - luaTarget: "5.1", - // Only present in TSTL dfaults - noHeader: optionDeclarations["noHeader"].default, - project: tsConfigPath, - noHoisting: optionDeclarations["noHoisting"].default, - } as CompilerOptions); + if (parsedArgs.isValid === true) + { + Expect(parsedArgs.result.options).toEqual({ + ...expectedTsConfig.options, + // Overridden by cmd args (set to "none" in project-tsconfig.json) + luaLibImport: LuaLibImportKind.Inline, + // Only set in tsconfig, TSTL default is "JIT" + luaTarget: "5.1", + // Only present in TSTL dfaults + noHeader: false, + project: tsConfigPath, + noHoisting: false, + } as CompilerOptions); + } else { + Expect(parsedArgs.isValid).toBeTruthy(); + } } } diff --git a/test/unit/string.spec.ts b/test/unit/string.spec.ts index 6b838c4ca..b3326ec78 100644 --- a/test/unit/string.spec.ts +++ b/test/unit/string.spec.ts @@ -88,12 +88,11 @@ export class StringTests @Test("string.concatFct") public concatFct(str: string, param: string[]): void { const paramStr = param.map(elem => `"${elem}"`).join(", "); - console.log(`return "${str}".concat(${paramStr})`); - const result = util.transpileAndExecute( - `return "${str}".concat(${paramStr})` - ); - // Assert - Expect(result).toBe(str.concat(...param)); + const result = util.transpileAndExecute( + `return "${str}".concat(${paramStr})` + ); + // Assert + Expect(result).toBe(str.concat(...param)); } @TestCase("hello test", "") @TestCase("hello test", "t") diff --git a/test/unit/tshelper.spec.ts b/test/unit/tshelper.spec.ts index 6a7b76273..408443d8e 100644 --- a/test/unit/tshelper.spec.ts +++ b/test/unit/tshelper.spec.ts @@ -53,7 +53,7 @@ export class TSHelperTests { const a = TestEnum.val1;`; const [sourceFile, typeChecker] = util.parseTypeScript(source); - const identifier = util.findFirstChild(sourceFile, ts.isIdentifier); + const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); const enumType = typeChecker.getTypeAtLocation(identifier); const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); @@ -76,7 +76,7 @@ export class TSHelperTests { const a = TestEnum.val1;`; const [sourceFile, typeChecker] = util.parseTypeScript(source); - const identifier = util.findFirstChild(sourceFile, ts.isIdentifier); + const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); const enumType = typeChecker.getTypeAtLocation(identifier); const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); @@ -99,7 +99,7 @@ export class TSHelperTests { const a = TestEnum.val1;`; const [sourceFile, typeChecker] = util.parseTypeScript(source); - const identifier = util.findFirstChild(sourceFile, ts.isIdentifier); + const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); const enumType = typeChecker.getTypeAtLocation(identifier); const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); @@ -122,7 +122,7 @@ export class TSHelperTests { const a = TestEnum.val1;`; const [sourceFile, typeChecker] = util.parseTypeScript(source); - const identifier = util.findFirstChild(sourceFile, ts.isIdentifier); + const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); const enumType = typeChecker.getTypeAtLocation(identifier); const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); @@ -148,7 +148,7 @@ export class TSHelperTests { const a = TestEnum.val1;`; const [sourceFile, typeChecker] = util.parseTypeScript(source); - const identifier = util.findFirstChild(sourceFile, ts.isIdentifier); + const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); const enumType = typeChecker.getTypeAtLocation(identifier); const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); diff --git a/tslint.json b/tslint.json index 601befe6c..c321344c9 100644 --- a/tslint.json +++ b/tslint.json @@ -1,8 +1,5 @@ { "defaultSeverity": "error", - "extends": [ - "tslint-override" - ], "rules": { "array-type": [true, "array-simple"], "arrow-parens": [true, "ban-single-arg-parens"],