From 68ff7380d2aae287282dd972a1d153cbb4e9ae2a Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Mon, 11 Oct 2021 06:06:14 +0000 Subject: [PATCH 01/60] Update package-lock.json --- package-lock.json | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4f0a55c8ff4..51ef9a6840e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -325,18 +325,18 @@ } }, "@octokit/openapi-types": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.1.0.tgz", - "integrity": "sha512-dWZfYvCCdjZzDYA3lIAMF72Q0jld8xidqCq5Ryw09eBJXZdcM6he0vWBTvw/b5UnGYqexxOyHWgfrsTlUJL3Gw==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz", + "integrity": "sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==", "dev": true }, "@octokit/plugin-paginate-rest": { - "version": "2.16.9", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.9.tgz", - "integrity": "sha512-gfSCMgz5scFKsR0dW4jaYsDJVt/UwCHp4dF7sHlmSekZvwzvLiOAGZ4MQkEsL5DW9hIk2W+UQkYZMTA1b6Wsqw==", + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz", + "integrity": "sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==", "dev": true, "requires": { - "@octokit/types": "^6.33.0" + "@octokit/types": "^6.34.0" } }, "@octokit/plugin-request-log": { @@ -346,12 +346,12 @@ "dev": true }, "@octokit/plugin-rest-endpoint-methods": { - "version": "5.12.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.12.1.tgz", - "integrity": "sha512-0nY3htfl6x9UkPcqv8pm9vOC/bTA7f4IMDWln13neHRdNWQvOQgZ9fRxK7BAc74rye4yVINEFi9Yb9rnGUvosA==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz", + "integrity": "sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA==", "dev": true, "requires": { - "@octokit/types": "^6.33.0", + "@octokit/types": "^6.34.0", "deprecation": "^2.3.1" } }, @@ -393,12 +393,12 @@ } }, "@octokit/types": { - "version": "6.33.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.33.0.tgz", - "integrity": "sha512-0zffZ048M0UhthyPXQHLz4038Ak46nMWZXkzlXvXB/M/L1jYPBceq4iZj4qjKVrvveaJrrgKdJ9+3yUuITfcCw==", + "version": "6.34.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz", + "integrity": "sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==", "dev": true, "requires": { - "@octokit/openapi-types": "^11.1.0" + "@octokit/openapi-types": "^11.2.0" } }, "@types/browserify": { From 44deb844602f3dc635e749dd5198f08a01b50518 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Tue, 12 Oct 2021 02:41:49 +0300 Subject: [PATCH 02/60] fix(45336): add a blank line before the comment expression to avoid disrupting return statement (#46287) --- src/compiler/transformers/es2015.ts | 3 +- ...mplateStringWithCommentsInArrowFunction.js | 27 ++++++++++++++++ ...eStringWithCommentsInArrowFunction.symbols | 24 ++++++++++++++ ...ateStringWithCommentsInArrowFunction.types | 31 +++++++++++++++++++ ...mplateStringWithCommentsInArrowFunction.ts | 14 +++++++++ 5 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/templateStringWithCommentsInArrowFunction.js create mode 100644 tests/baselines/reference/templateStringWithCommentsInArrowFunction.symbols create mode 100644 tests/baselines/reference/templateStringWithCommentsInArrowFunction.types create mode 100644 tests/cases/conformance/es6/templates/templateStringWithCommentsInArrowFunction.ts diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 52963c530ab..07d79f50fe2 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -4147,7 +4147,8 @@ namespace ts { // NoSubstitutionTemplateLiterals are directly emitted via emitLiteral() Debug.assert(node.templateSpans.length !== 0); - return node.head.text.length !== 0 || node.templateSpans[0].literal.text.length === 0; + const span = node.templateSpans[0]; + return node.head.text.length !== 0 || span.literal.text.length === 0 || !!length(getLeadingCommentRangesOfNode(span.expression, currentSourceFile)); } /** diff --git a/tests/baselines/reference/templateStringWithCommentsInArrowFunction.js b/tests/baselines/reference/templateStringWithCommentsInArrowFunction.js new file mode 100644 index 00000000000..df8a47410f5 --- /dev/null +++ b/tests/baselines/reference/templateStringWithCommentsInArrowFunction.js @@ -0,0 +1,27 @@ +//// [templateStringWithCommentsInArrowFunction.ts] +const a = 1; +const f1 = () => + `${ + // a + a + }a`; + +const f2 = () => + `${ + // a + a + }`; + + +//// [templateStringWithCommentsInArrowFunction.js] +var a = 1; +var f1 = function () { + return "" + + // a + a + "a"; +}; +var f2 = function () { + return "" + + // a + a; +}; diff --git a/tests/baselines/reference/templateStringWithCommentsInArrowFunction.symbols b/tests/baselines/reference/templateStringWithCommentsInArrowFunction.symbols new file mode 100644 index 00000000000..1b9b2243459 --- /dev/null +++ b/tests/baselines/reference/templateStringWithCommentsInArrowFunction.symbols @@ -0,0 +1,24 @@ +=== tests/cases/conformance/es6/templates/templateStringWithCommentsInArrowFunction.ts === +const a = 1; +>a : Symbol(a, Decl(templateStringWithCommentsInArrowFunction.ts, 0, 5)) + +const f1 = () => +>f1 : Symbol(f1, Decl(templateStringWithCommentsInArrowFunction.ts, 1, 5)) + + `${ + // a + a +>a : Symbol(a, Decl(templateStringWithCommentsInArrowFunction.ts, 0, 5)) + + }a`; + +const f2 = () => +>f2 : Symbol(f2, Decl(templateStringWithCommentsInArrowFunction.ts, 7, 5)) + + `${ + // a + a +>a : Symbol(a, Decl(templateStringWithCommentsInArrowFunction.ts, 0, 5)) + + }`; + diff --git a/tests/baselines/reference/templateStringWithCommentsInArrowFunction.types b/tests/baselines/reference/templateStringWithCommentsInArrowFunction.types new file mode 100644 index 00000000000..7f2b2198c60 --- /dev/null +++ b/tests/baselines/reference/templateStringWithCommentsInArrowFunction.types @@ -0,0 +1,31 @@ +=== tests/cases/conformance/es6/templates/templateStringWithCommentsInArrowFunction.ts === +const a = 1; +>a : 1 +>1 : 1 + +const f1 = () => +>f1 : () => string +>() => `${ // a a }a` : () => string + + `${ +>`${ // a a }a` : string + + // a + a +>a : 1 + + }a`; + +const f2 = () => +>f2 : () => string +>() => `${ // a a }` : () => string + + `${ +>`${ // a a }` : string + + // a + a +>a : 1 + + }`; + diff --git a/tests/cases/conformance/es6/templates/templateStringWithCommentsInArrowFunction.ts b/tests/cases/conformance/es6/templates/templateStringWithCommentsInArrowFunction.ts new file mode 100644 index 00000000000..c344bea1fb7 --- /dev/null +++ b/tests/cases/conformance/es6/templates/templateStringWithCommentsInArrowFunction.ts @@ -0,0 +1,14 @@ +// @removeComments: false + +const a = 1; +const f1 = () => + `${ + // a + a + }a`; + +const f2 = () => + `${ + // a + a + }`; From 9e2fc16c32e710ff342d1932ef4668bbcfb22d86 Mon Sep 17 00:00:00 2001 From: Yuya Tanaka Date: Wed, 13 Oct 2021 08:07:21 +0900 Subject: [PATCH 03/60] Improve perf of unions with many primitives (#45220) --- src/compiler/checker.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3d54f2e9db5..c11ce26d883 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -22652,8 +22652,9 @@ namespace ts { // constituent types keyed by the literal types of the property by that name in each constituent type. function getKeyPropertyName(unionType: UnionType): __String | undefined { const types = unionType.types; - // We only construct maps for large unions with non-primitive constituents. - if (types.length < 10 || getObjectFlags(unionType) & ObjectFlags.PrimitiveUnion) { + // We only construct maps for unions with many non-primitive constituents. + if (types.length < 10 || getObjectFlags(unionType) & ObjectFlags.PrimitiveUnion || + countWhere(types, t => !!(t.flags & (TypeFlags.Object | TypeFlags.InstantiableNonPrimitive))) < 10) { return undefined; } if (unionType.keyPropertyName === undefined) { From 713afe2227f6cdb0504d9ddb9c8bf52f1a802f80 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 12 Oct 2021 16:23:37 -0700 Subject: [PATCH 04/60] Set import mode on synthetic imports (#46327) --- src/compiler/checker.ts | 3 +- .../reactJsxReactResolvedNodeNext.js | 27 ++++ .../reactJsxReactResolvedNodeNext.symbols | 20 +++ .../reactJsxReactResolvedNodeNext.trace.json | 135 ++++++++++++++++++ .../reactJsxReactResolvedNodeNext.types | 18 +++ .../reactJsxReactResolvedNodeNextEsm.js | 32 +++++ .../reactJsxReactResolvedNodeNextEsm.symbols | 20 +++ ...eactJsxReactResolvedNodeNextEsm.trace.json | 129 +++++++++++++++++ .../reactJsxReactResolvedNodeNextEsm.types | 18 +++ .../reactJsxReactResolvedNodeNext.tsx | 20 +++ .../reactJsxReactResolvedNodeNextEsm.tsx | 28 ++++ 11 files changed, 449 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/reactJsxReactResolvedNodeNext.js create mode 100644 tests/baselines/reference/reactJsxReactResolvedNodeNext.symbols create mode 100644 tests/baselines/reference/reactJsxReactResolvedNodeNext.trace.json create mode 100644 tests/baselines/reference/reactJsxReactResolvedNodeNext.types create mode 100644 tests/baselines/reference/reactJsxReactResolvedNodeNextEsm.js create mode 100644 tests/baselines/reference/reactJsxReactResolvedNodeNextEsm.symbols create mode 100644 tests/baselines/reference/reactJsxReactResolvedNodeNextEsm.trace.json create mode 100644 tests/baselines/reference/reactJsxReactResolvedNodeNextEsm.types create mode 100644 tests/cases/compiler/reactJsxReactResolvedNodeNext.tsx create mode 100644 tests/cases/compiler/reactJsxReactResolvedNodeNextEsm.tsx diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c11ce26d883..c7bd15da0c8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3416,7 +3416,8 @@ namespace ts { findAncestor(location, isExportDeclaration)?.moduleSpecifier || (isModuleDeclaration(location) ? location : location.parent && isModuleDeclaration(location.parent) && location.parent.name === location ? location.parent : undefined)?.name || (isLiteralImportTypeNode(location) ? location : undefined)?.argument.literal; - const resolvedModule = getResolvedModule(currentSourceFile, moduleReference, contextSpecifier && isStringLiteralLike(contextSpecifier) ? getModeForUsageLocation(currentSourceFile, contextSpecifier) : undefined)!; // TODO: GH#18217 + const mode = contextSpecifier && isStringLiteralLike(contextSpecifier) ? getModeForUsageLocation(currentSourceFile, contextSpecifier) : currentSourceFile.impliedNodeFormat; + const resolvedModule = getResolvedModule(currentSourceFile, moduleReference, mode)!; // TODO: GH#18217 const resolutionDiagnostic = resolvedModule && getResolutionDiagnostic(compilerOptions, resolvedModule); const sourceFile = resolvedModule && !resolutionDiagnostic && host.getSourceFile(resolvedModule.resolvedFileName); if (sourceFile) { diff --git a/tests/baselines/reference/reactJsxReactResolvedNodeNext.js b/tests/baselines/reference/reactJsxReactResolvedNodeNext.js new file mode 100644 index 00000000000..600bc4b92da --- /dev/null +++ b/tests/baselines/reference/reactJsxReactResolvedNodeNext.js @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/reactJsxReactResolvedNodeNext.tsx] //// + +//// [file.tsx] +export const a =
; +//// [package.json] +{ + "name": "@types/react", + "version": "0.0.1", + "main": "", + "types": "index.d.ts", +} +//// [index.d.ts] +declare namespace JSX { + interface IntrinsicElements { [x: string]: any; } +} +//// [jsx-runtime.d.ts] +import './'; +//// [jsx-dev-runtime.d.ts] +import './'; + + +//// [file.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.a = void 0; +const jsx_runtime_1 = require("react/jsx-runtime"); +exports.a = (0, jsx_runtime_1.jsx)("div", {}, void 0); diff --git a/tests/baselines/reference/reactJsxReactResolvedNodeNext.symbols b/tests/baselines/reference/reactJsxReactResolvedNodeNext.symbols new file mode 100644 index 00000000000..af564f6bc38 --- /dev/null +++ b/tests/baselines/reference/reactJsxReactResolvedNodeNext.symbols @@ -0,0 +1,20 @@ +=== tests/cases/compiler/file.tsx === +export const a =
; +>a : Symbol(a, Decl(file.tsx, 0, 12)) +>div : Symbol(JSX.IntrinsicElements, Decl(index.d.ts, 0, 23)) +>div : Symbol(JSX.IntrinsicElements, Decl(index.d.ts, 0, 23)) + +=== tests/cases/compiler/node_modules/@types/react/index.d.ts === +declare namespace JSX { +>JSX : Symbol(JSX, Decl(index.d.ts, 0, 0)) + + interface IntrinsicElements { [x: string]: any; } +>IntrinsicElements : Symbol(IntrinsicElements, Decl(index.d.ts, 0, 23)) +>x : Symbol(x, Decl(index.d.ts, 1, 35)) +} +=== tests/cases/compiler/node_modules/@types/react/jsx-runtime.d.ts === +import './'; +No type information for this code.=== tests/cases/compiler/node_modules/@types/react/jsx-dev-runtime.d.ts === +import './'; +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/reactJsxReactResolvedNodeNext.trace.json b/tests/baselines/reference/reactJsxReactResolvedNodeNext.trace.json new file mode 100644 index 00000000000..00597f669b3 --- /dev/null +++ b/tests/baselines/reference/reactJsxReactResolvedNodeNext.trace.json @@ -0,0 +1,135 @@ +[ + "File 'tests/cases/compiler/package.json' does not exist.", + "File 'tests/cases/package.json' does not exist.", + "File 'tests/package.json' does not exist.", + "File 'package.json' does not exist.", + "File '/package.json' does not exist.", + "======== Resolving module 'react/jsx-runtime' from 'tests/cases/compiler/file.tsx'. ========", + "Module resolution kind is not specified, using 'NodeNext'.", + "File 'tests/cases/compiler/package.json' does not exist according to earlier cached lookups.", + "File 'tests/cases/package.json' does not exist according to earlier cached lookups.", + "File 'tests/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "Loading module 'react/jsx-runtime' from 'node_modules' folder, target file type 'TypeScript'.", + "Found 'package.json' at 'tests/cases/compiler/node_modules/@types/react/package.json'.", + "'package.json' does not have a 'typesVersions' field.", + "File 'tests/cases/compiler/node_modules/@types/react/jsx-runtime.d.ts' exist - use it as a name resolution result.", + "Resolving real path for 'tests/cases/compiler/node_modules/@types/react/jsx-runtime.d.ts', result 'tests/cases/compiler/node_modules/@types/react/jsx-runtime.d.ts'.", + "======== Module name 'react/jsx-runtime' was successfully resolved to 'tests/cases/compiler/node_modules/@types/react/jsx-runtime.d.ts' with Package ID '@types/react/jsx-runtime.d.ts@0.0.1'. ========", + "File 'tests/cases/compiler/node_modules/@types/react/package.json' exists according to earlier cached lookups.", + "======== Resolving module './' from 'tests/cases/compiler/node_modules/@types/react/jsx-runtime.d.ts'. ========", + "Module resolution kind is not specified, using 'NodeNext'.", + "Loading module as file / folder, candidate module location 'tests/cases/compiler/node_modules/@types/react/', target file type 'TypeScript'.", + "File 'tests/cases/compiler/node_modules/@types/react/package.json' exists according to earlier cached lookups.", + "'package.json' does not have a 'typings' field.", + "'package.json' has 'types' field 'index.d.ts' that references 'tests/cases/compiler/node_modules/@types/react/index.d.ts'.", + "File 'tests/cases/compiler/node_modules/@types/react/index.d.ts' exist - use it as a name resolution result.", + "======== Module name './' was successfully resolved to 'tests/cases/compiler/node_modules/@types/react/index.d.ts' with Package ID '@types/react/index.d.ts@0.0.1'. ========", + "File 'tests/cases/compiler/node_modules/@types/react/package.json' exists according to earlier cached lookups.", + "======== Resolving module './' from 'tests/cases/compiler/node_modules/@types/react/jsx-runtime.d.ts'. ========", + "Resolution for module './' was found in cache from location 'tests/cases/compiler/node_modules/@types/react'.", + "======== Module name './' was successfully resolved to 'tests/cases/compiler/node_modules/@types/react/index.d.ts' with Package ID '@types/react/index.d.ts@0.0.1'. ========", + "File 'tests/cases/compiler/node_modules/@types/react/package.json' exists according to earlier cached lookups.", + "======== Resolving module './' from 'tests/cases/compiler/node_modules/@types/react/jsx-dev-runtime.d.ts'. ========", + "Resolution for module './' was found in cache from location 'tests/cases/compiler/node_modules/@types/react'.", + "======== Module name './' was successfully resolved to 'tests/cases/compiler/node_modules/@types/react/index.d.ts' with Package ID '@types/react/index.d.ts@0.0.1'. ========", + "File 'package.json' does not exist.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups." +] \ No newline at end of file diff --git a/tests/baselines/reference/reactJsxReactResolvedNodeNext.types b/tests/baselines/reference/reactJsxReactResolvedNodeNext.types new file mode 100644 index 00000000000..882cac56efc --- /dev/null +++ b/tests/baselines/reference/reactJsxReactResolvedNodeNext.types @@ -0,0 +1,18 @@ +=== tests/cases/compiler/file.tsx === +export const a =
; +>a : error +>
: error +>div : any +>div : any + +=== tests/cases/compiler/node_modules/@types/react/index.d.ts === +declare namespace JSX { + interface IntrinsicElements { [x: string]: any; } +>x : string +} +=== tests/cases/compiler/node_modules/@types/react/jsx-runtime.d.ts === +import './'; +No type information for this code.=== tests/cases/compiler/node_modules/@types/react/jsx-dev-runtime.d.ts === +import './'; +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/reactJsxReactResolvedNodeNextEsm.js b/tests/baselines/reference/reactJsxReactResolvedNodeNextEsm.js new file mode 100644 index 00000000000..bb4cddaf74e --- /dev/null +++ b/tests/baselines/reference/reactJsxReactResolvedNodeNextEsm.js @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/reactJsxReactResolvedNodeNextEsm.tsx] //// + +//// [package.json] +{ + "type": "module" +} +//// [file.tsx] +export const a =
; +//// [package.json] +{ + "name": "@types/react", + "version": "0.0.1", + "main": "", + "types": "index.d.ts", + "exports": { + "./*.js": "./*.js", + "./*": "./*.js" + } +} +//// [index.d.ts] +declare namespace JSX { + interface IntrinsicElements { [x: string]: any; } +} +//// [jsx-runtime.d.ts] +import './'; +//// [jsx-dev-runtime.d.ts] +import './'; + + +//// [file.js] +import { jsx as _jsx } from "react/jsx-runtime"; +export const a = _jsx("div", {}, void 0); diff --git a/tests/baselines/reference/reactJsxReactResolvedNodeNextEsm.symbols b/tests/baselines/reference/reactJsxReactResolvedNodeNextEsm.symbols new file mode 100644 index 00000000000..af564f6bc38 --- /dev/null +++ b/tests/baselines/reference/reactJsxReactResolvedNodeNextEsm.symbols @@ -0,0 +1,20 @@ +=== tests/cases/compiler/file.tsx === +export const a =
; +>a : Symbol(a, Decl(file.tsx, 0, 12)) +>div : Symbol(JSX.IntrinsicElements, Decl(index.d.ts, 0, 23)) +>div : Symbol(JSX.IntrinsicElements, Decl(index.d.ts, 0, 23)) + +=== tests/cases/compiler/node_modules/@types/react/index.d.ts === +declare namespace JSX { +>JSX : Symbol(JSX, Decl(index.d.ts, 0, 0)) + + interface IntrinsicElements { [x: string]: any; } +>IntrinsicElements : Symbol(IntrinsicElements, Decl(index.d.ts, 0, 23)) +>x : Symbol(x, Decl(index.d.ts, 1, 35)) +} +=== tests/cases/compiler/node_modules/@types/react/jsx-runtime.d.ts === +import './'; +No type information for this code.=== tests/cases/compiler/node_modules/@types/react/jsx-dev-runtime.d.ts === +import './'; +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/reactJsxReactResolvedNodeNextEsm.trace.json b/tests/baselines/reference/reactJsxReactResolvedNodeNextEsm.trace.json new file mode 100644 index 00000000000..02a5d6a4299 --- /dev/null +++ b/tests/baselines/reference/reactJsxReactResolvedNodeNextEsm.trace.json @@ -0,0 +1,129 @@ +[ + "Found 'package.json' at 'tests/cases/compiler/package.json'.", + "'package.json' does not have a 'typesVersions' field.", + "======== Resolving module 'react/jsx-runtime' from 'tests/cases/compiler/file.tsx'. ========", + "Module resolution kind is not specified, using 'NodeNext'.", + "File 'tests/cases/compiler/package.json' exists according to earlier cached lookups.", + "Loading module 'react/jsx-runtime' from 'node_modules' folder, target file type 'TypeScript'.", + "Found 'package.json' at 'tests/cases/compiler/node_modules/@types/react/package.json'.", + "'package.json' does not have a 'typesVersions' field.", + "File name 'tests/cases/compiler/node_modules/@types/react/jsx-runtime.js' has a '.js' extension - stripping it.", + "File 'tests/cases/compiler/node_modules/@types/react/jsx-runtime.d.ts' exist - use it as a name resolution result.", + "Resolving real path for 'tests/cases/compiler/node_modules/@types/react/jsx-runtime.d.ts', result 'tests/cases/compiler/node_modules/@types/react/jsx-runtime.d.ts'.", + "======== Module name 'react/jsx-runtime' was successfully resolved to 'tests/cases/compiler/node_modules/@types/react/jsx-runtime.d.ts' with Package ID '@types/react/jsx-runtime.d.ts@0.0.1'. ========", + "File 'tests/cases/compiler/node_modules/@types/react/package.json' exists according to earlier cached lookups.", + "======== Resolving module './' from 'tests/cases/compiler/node_modules/@types/react/jsx-runtime.d.ts'. ========", + "Module resolution kind is not specified, using 'NodeNext'.", + "Loading module as file / folder, candidate module location 'tests/cases/compiler/node_modules/@types/react/', target file type 'TypeScript'.", + "File 'tests/cases/compiler/node_modules/@types/react/package.json' exists according to earlier cached lookups.", + "'package.json' does not have a 'typings' field.", + "'package.json' has 'types' field 'index.d.ts' that references 'tests/cases/compiler/node_modules/@types/react/index.d.ts'.", + "File 'tests/cases/compiler/node_modules/@types/react/index.d.ts' exist - use it as a name resolution result.", + "======== Module name './' was successfully resolved to 'tests/cases/compiler/node_modules/@types/react/index.d.ts' with Package ID '@types/react/index.d.ts@0.0.1'. ========", + "File 'tests/cases/compiler/node_modules/@types/react/package.json' exists according to earlier cached lookups.", + "======== Resolving module './' from 'tests/cases/compiler/node_modules/@types/react/jsx-runtime.d.ts'. ========", + "Resolution for module './' was found in cache from location 'tests/cases/compiler/node_modules/@types/react'.", + "======== Module name './' was successfully resolved to 'tests/cases/compiler/node_modules/@types/react/index.d.ts' with Package ID '@types/react/index.d.ts@0.0.1'. ========", + "File 'tests/cases/compiler/node_modules/@types/react/package.json' exists according to earlier cached lookups.", + "======== Resolving module './' from 'tests/cases/compiler/node_modules/@types/react/jsx-dev-runtime.d.ts'. ========", + "Resolution for module './' was found in cache from location 'tests/cases/compiler/node_modules/@types/react'.", + "======== Module name './' was successfully resolved to 'tests/cases/compiler/node_modules/@types/react/index.d.ts' with Package ID '@types/react/index.d.ts@0.0.1'. ========", + "File 'package.json' does not exist.", + "File '/package.json' does not exist.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups.", + "File 'package.json' does not exist according to earlier cached lookups.", + "File '/package.json' does not exist according to earlier cached lookups." +] \ No newline at end of file diff --git a/tests/baselines/reference/reactJsxReactResolvedNodeNextEsm.types b/tests/baselines/reference/reactJsxReactResolvedNodeNextEsm.types new file mode 100644 index 00000000000..882cac56efc --- /dev/null +++ b/tests/baselines/reference/reactJsxReactResolvedNodeNextEsm.types @@ -0,0 +1,18 @@ +=== tests/cases/compiler/file.tsx === +export const a =
; +>a : error +>
: error +>div : any +>div : any + +=== tests/cases/compiler/node_modules/@types/react/index.d.ts === +declare namespace JSX { + interface IntrinsicElements { [x: string]: any; } +>x : string +} +=== tests/cases/compiler/node_modules/@types/react/jsx-runtime.d.ts === +import './'; +No type information for this code.=== tests/cases/compiler/node_modules/@types/react/jsx-dev-runtime.d.ts === +import './'; +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/cases/compiler/reactJsxReactResolvedNodeNext.tsx b/tests/cases/compiler/reactJsxReactResolvedNodeNext.tsx new file mode 100644 index 00000000000..0cc64eda70a --- /dev/null +++ b/tests/cases/compiler/reactJsxReactResolvedNodeNext.tsx @@ -0,0 +1,20 @@ +// @jsx: react-jsx +// @module: nodenext +// @traceResolution: true +// @filename: file.tsx +export const a =
; +// @filename: node_modules/@types/react/package.json +{ + "name": "@types/react", + "version": "0.0.1", + "main": "", + "types": "index.d.ts", +} +// @filename: node_modules/@types/react/index.d.ts +declare namespace JSX { + interface IntrinsicElements { [x: string]: any; } +} +// @filename: node_modules/@types/react/jsx-runtime.d.ts +import './'; +// @filename: node_modules/@types/react/jsx-dev-runtime.d.ts +import './'; diff --git a/tests/cases/compiler/reactJsxReactResolvedNodeNextEsm.tsx b/tests/cases/compiler/reactJsxReactResolvedNodeNextEsm.tsx new file mode 100644 index 00000000000..6d2fc006f15 --- /dev/null +++ b/tests/cases/compiler/reactJsxReactResolvedNodeNextEsm.tsx @@ -0,0 +1,28 @@ +// @jsx: react-jsx +// @module: nodenext +// @traceResolution: true +// @filename: package.json +{ + "type": "module" +} +// @filename: file.tsx +export const a =
; +// @filename: node_modules/@types/react/package.json +{ + "name": "@types/react", + "version": "0.0.1", + "main": "", + "types": "index.d.ts", + "exports": { + "./*.js": "./*.js", + "./*": "./*.js" + } +} +// @filename: node_modules/@types/react/index.d.ts +declare namespace JSX { + interface IntrinsicElements { [x: string]: any; } +} +// @filename: node_modules/@types/react/jsx-runtime.d.ts +import './'; +// @filename: node_modules/@types/react/jsx-dev-runtime.d.ts +import './'; From 315b807489b8ff3a892179488fb0c00398d9b2c3 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Wed, 13 Oct 2021 06:06:54 +0000 Subject: [PATCH 05/60] Update package-lock.json --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 51ef9a6840e..24f7f2f14b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -676,9 +676,9 @@ "dev": true }, "@types/node": { - "version": "16.10.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.3.tgz", - "integrity": "sha512-ho3Ruq+fFnBrZhUYI46n/bV2GjwzSkwuT4dTf0GkuNFmnb8nq4ny2z9JEVemFi6bdEJanHLlYfy9c6FN9B9McQ==", + "version": "16.10.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.4.tgz", + "integrity": "sha512-EITwVTX5B4nDjXjGeQAfXOrm+Jn+qNjDmyDRtWoD+wZsl/RDPRTFRKivs4Mt74iOFlLOrE5+Kf+p5yjyhm3+cA==", "dev": true }, "@types/node-fetch": { From 0d2aeb7c6582810db0396f4dc07dcf0c480568e9 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 13 Oct 2021 07:08:01 -0700 Subject: [PATCH 06/60] Improve checks for infinitely expanding recursive conditional types (#46326) * Improve checks for infinitely expanding recursive conditional types * Accept new baselines * Add regression tests * Remove 'export' modifier * Accept new baselines --- src/compiler/checker.ts | 82 ++++++++-------- ...wnNotAssignableToConcreteObject.errors.txt | 6 +- .../reference/infiniteConstraints.errors.txt | 5 +- .../recursiveConditionalTypes.errors.txt | 37 ++++++- .../reference/recursiveConditionalTypes.js | 46 +++++++++ .../recursiveConditionalTypes.symbols | 97 +++++++++++++++++++ .../reference/recursiveConditionalTypes.types | 49 ++++++++++ .../compiler/recursiveConditionalTypes.ts | 32 ++++++ 8 files changed, 307 insertions(+), 47 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c7bd15da0c8..1edbb1d4a0d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19024,6 +19024,12 @@ namespace ts { } } else if (target.flags & TypeFlags.Conditional) { + // If we reach 10 levels of nesting for the same conditional type, assume it is an infinitely expanding recursive + // conditional type and bail out with a Ternary.Maybe result. + if (isDeeplyNestedType(target, targetStack, targetDepth, 10)) { + resetErrorInfo(saveErrorInfo); + return Ternary.Maybe; + } const c = target as ConditionalType; // Check if the conditional is always true or always false but still deferred for distribution purposes const skipTrue = !isTypeAssignableTo(getPermissiveInstantiation(c.checkType), getPermissiveInstantiation(c.extendsType)); @@ -19123,33 +19129,34 @@ namespace ts { } } else if (source.flags & TypeFlags.Conditional) { + // If we reach 10 levels of nesting for the same conditional type, assume it is an infinitely expanding recursive + // conditional type and bail out with a Ternary.Maybe result. + if (isDeeplyNestedType(source, sourceStack, sourceDepth, 10)) { + resetErrorInfo(saveErrorInfo); + return Ternary.Maybe; + } if (target.flags & TypeFlags.Conditional) { - // If one of the conditionals under comparison seems to be infinitely expanding, stop comparing it - back out, try - // the constraint, and failing that, give up trying to relate the two. This is the only way we can handle recursive conditional - // types, which might expand forever. - if (!isDeeplyNestedType(source, sourceStack, sourceDepth) && !isDeeplyNestedType(target, targetStack, targetDepth)) { - // Two conditional types 'T1 extends U1 ? X1 : Y1' and 'T2 extends U2 ? X2 : Y2' are related if - // one of T1 and T2 is related to the other, U1 and U2 are identical types, X1 is related to X2, - // and Y1 is related to Y2. - const sourceParams = (source as ConditionalType).root.inferTypeParameters; - let sourceExtends = (source as ConditionalType).extendsType; - let mapper: TypeMapper | undefined; - if (sourceParams) { - // If the source has infer type parameters, we instantiate them in the context of the target - const ctx = createInferenceContext(sourceParams, /*signature*/ undefined, InferenceFlags.None, isRelatedToWorker); - inferTypes(ctx.inferences, (target as ConditionalType).extendsType, sourceExtends, InferencePriority.NoConstraints | InferencePriority.AlwaysStrict); - sourceExtends = instantiateType(sourceExtends, ctx.mapper); - mapper = ctx.mapper; + // Two conditional types 'T1 extends U1 ? X1 : Y1' and 'T2 extends U2 ? X2 : Y2' are related if + // one of T1 and T2 is related to the other, U1 and U2 are identical types, X1 is related to X2, + // and Y1 is related to Y2. + const sourceParams = (source as ConditionalType).root.inferTypeParameters; + let sourceExtends = (source as ConditionalType).extendsType; + let mapper: TypeMapper | undefined; + if (sourceParams) { + // If the source has infer type parameters, we instantiate them in the context of the target + const ctx = createInferenceContext(sourceParams, /*signature*/ undefined, InferenceFlags.None, isRelatedToWorker); + inferTypes(ctx.inferences, (target as ConditionalType).extendsType, sourceExtends, InferencePriority.NoConstraints | InferencePriority.AlwaysStrict); + sourceExtends = instantiateType(sourceExtends, ctx.mapper); + mapper = ctx.mapper; + } + if (isTypeIdenticalTo(sourceExtends, (target as ConditionalType).extendsType) && + (isRelatedTo((source as ConditionalType).checkType, (target as ConditionalType).checkType, RecursionFlags.Both) || isRelatedTo((target as ConditionalType).checkType, (source as ConditionalType).checkType, RecursionFlags.Both))) { + if (result = isRelatedTo(instantiateType(getTrueTypeFromConditionalType(source as ConditionalType), mapper), getTrueTypeFromConditionalType(target as ConditionalType), RecursionFlags.Both, reportErrors)) { + result &= isRelatedTo(getFalseTypeFromConditionalType(source as ConditionalType), getFalseTypeFromConditionalType(target as ConditionalType), RecursionFlags.Both, reportErrors); } - if (isTypeIdenticalTo(sourceExtends, (target as ConditionalType).extendsType) && - (isRelatedTo((source as ConditionalType).checkType, (target as ConditionalType).checkType, RecursionFlags.Both) || isRelatedTo((target as ConditionalType).checkType, (source as ConditionalType).checkType, RecursionFlags.Both))) { - if (result = isRelatedTo(instantiateType(getTrueTypeFromConditionalType(source as ConditionalType), mapper), getTrueTypeFromConditionalType(target as ConditionalType), RecursionFlags.Both, reportErrors)) { - result &= isRelatedTo(getFalseTypeFromConditionalType(source as ConditionalType), getFalseTypeFromConditionalType(target as ConditionalType), RecursionFlags.Both, reportErrors); - } - if (result) { - resetErrorInfo(saveErrorInfo); - return result; - } + if (result) { + resetErrorInfo(saveErrorInfo); + return result; } } } @@ -19165,18 +19172,13 @@ namespace ts { } } - - // We'll repeatedly decompose source side conditionals if they're recursive - check if we've already recured on the constraint a lot and, if so, bail - // on the comparison. - if (!isDeeplyNestedType(source, sourceStack, sourceDepth)) { - // conditionals _can_ be related to one another via normal constraint, as, eg, `A extends B ? O : never` should be assignable to `O` - // when `O` is a conditional (`never` is trivially assignable to `O`, as is `O`!). - const defaultConstraint = getDefaultConstraintOfConditionalType(source as ConditionalType); - if (defaultConstraint) { - if (result = isRelatedTo(defaultConstraint, target, RecursionFlags.Source, reportErrors)) { - resetErrorInfo(saveErrorInfo); - return result; - } + // conditionals _can_ be related to one another via normal constraint, as, eg, `A extends B ? O : never` should be assignable to `O` + // when `O` is a conditional (`never` is trivially assignable to `O`, as is `O`!). + const defaultConstraint = getDefaultConstraintOfConditionalType(source as ConditionalType); + if (defaultConstraint) { + if (result = isRelatedTo(defaultConstraint, target, RecursionFlags.Source, reportErrors)) { + resetErrorInfo(saveErrorInfo); + return result; } } } @@ -20322,14 +20324,14 @@ namespace ts { // `type A = null extends T ? [A>] : [T]` // has expanded into `[A>>>>>]` // in such cases we need to terminate the expansion, and we do so here. - function isDeeplyNestedType(type: Type, stack: Type[], depth: number): boolean { - if (depth >= 5) { + function isDeeplyNestedType(type: Type, stack: Type[], depth: number, maxDepth = 5): boolean { + if (depth >= maxDepth) { const identity = getRecursionIdentity(type); let count = 0; for (let i = 0; i < depth; i++) { if (getRecursionIdentity(stack[i]) === identity) { count++; - if (count >= 5) { + if (count >= maxDepth) { return true; } } diff --git a/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.errors.txt b/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.errors.txt index 5d74b6e23b5..2063b58b4e3 100644 --- a/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.errors.txt +++ b/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.errors.txt @@ -8,7 +8,8 @@ tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcre Type 'ReturnType' is not assignable to type 'A'. Type 'unknown' is not assignable to type 'A'. Type 'ReturnType[string]>' is not assignable to type 'A'. - Property 'x' is missing in type '{}' but required in type 'A'. + Type 'unknown' is not assignable to type 'A'. + Property 'x' is missing in type '{}' but required in type 'A'. ==== tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts (1 errors) ==== @@ -36,7 +37,8 @@ tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcre !!! error TS2322: Type 'ReturnType' is not assignable to type 'A'. !!! error TS2322: Type 'unknown' is not assignable to type 'A'. !!! error TS2322: Type 'ReturnType[string]>' is not assignable to type 'A'. -!!! error TS2322: Property 'x' is missing in type '{}' but required in type 'A'. +!!! error TS2322: Type 'unknown' is not assignable to type 'A'. +!!! error TS2322: Property 'x' is missing in type '{}' but required in type 'A'. !!! related TS2728 tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts:1:15: 'x' is declared here. } diff --git a/tests/baselines/reference/infiniteConstraints.errors.txt b/tests/baselines/reference/infiniteConstraints.errors.txt index c3101af493e..0a9cd55b14e 100644 --- a/tests/baselines/reference/infiniteConstraints.errors.txt +++ b/tests/baselines/reference/infiniteConstraints.errors.txt @@ -2,10 +2,9 @@ tests/cases/compiler/infiniteConstraints.ts(4,37): error TS2536: Type '"val"' ca tests/cases/compiler/infiniteConstraints.ts(31,43): error TS2322: Type 'Value<"dup">' is not assignable to type 'never'. tests/cases/compiler/infiniteConstraints.ts(31,63): error TS2322: Type 'Value<"dup">' is not assignable to type 'never'. tests/cases/compiler/infiniteConstraints.ts(36,71): error TS2536: Type '"foo"' cannot be used to index type 'T[keyof T]'. -tests/cases/compiler/infiniteConstraints.ts(48,27): error TS2321: Excessive stack depth comparing types 'Conv, ExactExtract>' and 'unknown[]'. -==== tests/cases/compiler/infiniteConstraints.ts (5 errors) ==== +==== tests/cases/compiler/infiniteConstraints.ts (4 errors) ==== // Both of the following types trigger the recursion limiter in getImmediateBaseConstraint type T1], { val: string }>["val"] }> = B; @@ -64,6 +63,4 @@ tests/cases/compiler/infiniteConstraints.ts(48,27): error TS2321: Excessive stac type Conv = { 0: [T]; 1: Prepend>>;}[U extends T ? 0 : 1]; - ~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2321: Excessive stack depth comparing types 'Conv, ExactExtract>' and 'unknown[]'. \ No newline at end of file diff --git a/tests/baselines/reference/recursiveConditionalTypes.errors.txt b/tests/baselines/reference/recursiveConditionalTypes.errors.txt index 051137b4e16..3706310c559 100644 --- a/tests/baselines/reference/recursiveConditionalTypes.errors.txt +++ b/tests/baselines/reference/recursiveConditionalTypes.errors.txt @@ -23,9 +23,10 @@ tests/cases/compiler/recursiveConditionalTypes.ts(117,9): error TS2345: Argument Type '[string]' is not assignable to type 'Grow1<[number], T>'. Type '[string]' is not assignable to type '[number]'. Type 'string' is not assignable to type 'number'. +tests/cases/compiler/recursiveConditionalTypes.ts(169,5): error TS2322: Type 'number' is not assignable to type 'Enumerate'. -==== tests/cases/compiler/recursiveConditionalTypes.ts (9 errors) ==== +==== tests/cases/compiler/recursiveConditionalTypes.ts (10 errors) ==== // Awaiting promises type __Awaited = @@ -198,4 +199,38 @@ tests/cases/compiler/recursiveConditionalTypes.ts(117,9): error TS2345: Argument type Helper = T extends ParseSuccess ? ParseSuccess : null type TP2 = ParseManyWhitespace2<" foo">; + + // Repro from #46183 + + type NTuple = + Tup['length'] extends N ? Tup : NTuple; + + type Add = + [...NTuple, ...NTuple]['length']; + + let five: Add<2, 3>; + + // Repro from #46316 + + type _PrependNextNum> = A['length'] extends infer T + ? [T, ...A] extends [...infer X] + ? X + : never + : never; + + type _Enumerate, N extends number> = N extends A['length'] + ? A + : _Enumerate<_PrependNextNum, N> & number; + + type Enumerate = number extends N + ? number + : _Enumerate<[], N> extends (infer E)[] + ? E + : never; + + function foo2(value: T): Enumerate { + return value.length; // Error + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'number' is not assignable to type 'Enumerate'. + } \ No newline at end of file diff --git a/tests/baselines/reference/recursiveConditionalTypes.js b/tests/baselines/reference/recursiveConditionalTypes.js index 1b7cf831fac..0c590309550 100644 --- a/tests/baselines/reference/recursiveConditionalTypes.js +++ b/tests/baselines/reference/recursiveConditionalTypes.js @@ -137,6 +137,38 @@ type ParseManyWhitespace2 = type Helper = T extends ParseSuccess ? ParseSuccess : null type TP2 = ParseManyWhitespace2<" foo">; + +// Repro from #46183 + +type NTuple = + Tup['length'] extends N ? Tup : NTuple; + +type Add = + [...NTuple, ...NTuple]['length']; + +let five: Add<2, 3>; + +// Repro from #46316 + +type _PrependNextNum> = A['length'] extends infer T + ? [T, ...A] extends [...infer X] + ? X + : never + : never; + +type _Enumerate, N extends number> = N extends A['length'] + ? A + : _Enumerate<_PrependNextNum, N> & number; + +type Enumerate = number extends N + ? number + : _Enumerate<[], N> extends (infer E)[] + ? E + : never; + +function foo2(value: T): Enumerate { + return value.length; // Error +} //// [recursiveConditionalTypes.js] @@ -169,6 +201,10 @@ function f20(x, y) { function f21(x, y) { f21(y, x); // Error } +let five; +function foo2(value) { + return value.length; // Error +} //// [recursiveConditionalTypes.d.ts] @@ -244,3 +280,13 @@ declare type TP1 = ParseManyWhitespace<" foo">; declare type ParseManyWhitespace2 = S extends ` ${infer R0}` ? Helper> : ParseSuccess; declare type Helper = T extends ParseSuccess ? ParseSuccess : null; declare type TP2 = ParseManyWhitespace2<" foo">; +declare type NTuple = Tup['length'] extends N ? Tup : NTuple; +declare type Add = [ + ...NTuple, + ...NTuple +]['length']; +declare let five: Add<2, 3>; +declare type _PrependNextNum> = A['length'] extends infer T ? [T, ...A] extends [...infer X] ? X : never : never; +declare type _Enumerate, N extends number> = N extends A['length'] ? A : _Enumerate<_PrependNextNum, N> & number; +declare type Enumerate = number extends N ? number : _Enumerate<[], N> extends (infer E)[] ? E : never; +declare function foo2(value: T): Enumerate; diff --git a/tests/baselines/reference/recursiveConditionalTypes.symbols b/tests/baselines/reference/recursiveConditionalTypes.symbols index 492184be494..3c77d93e71f 100644 --- a/tests/baselines/reference/recursiveConditionalTypes.symbols +++ b/tests/baselines/reference/recursiveConditionalTypes.symbols @@ -531,3 +531,100 @@ type TP2 = ParseManyWhitespace2<" foo">; >TP2 : Symbol(TP2, Decl(recursiveConditionalTypes.ts, 135, 73)) >ParseManyWhitespace2 : Symbol(ParseManyWhitespace2, Decl(recursiveConditionalTypes.ts, 128, 39)) +// Repro from #46183 + +type NTuple = +>NTuple : Symbol(NTuple, Decl(recursiveConditionalTypes.ts, 137, 40)) +>N : Symbol(N, Decl(recursiveConditionalTypes.ts, 141, 12)) +>Tup : Symbol(Tup, Decl(recursiveConditionalTypes.ts, 141, 29)) + + Tup['length'] extends N ? Tup : NTuple; +>Tup : Symbol(Tup, Decl(recursiveConditionalTypes.ts, 141, 29)) +>N : Symbol(N, Decl(recursiveConditionalTypes.ts, 141, 12)) +>Tup : Symbol(Tup, Decl(recursiveConditionalTypes.ts, 141, 29)) +>NTuple : Symbol(NTuple, Decl(recursiveConditionalTypes.ts, 137, 40)) +>N : Symbol(N, Decl(recursiveConditionalTypes.ts, 141, 12)) +>Tup : Symbol(Tup, Decl(recursiveConditionalTypes.ts, 141, 29)) + +type Add = +>Add : Symbol(Add, Decl(recursiveConditionalTypes.ts, 142, 65)) +>A : Symbol(A, Decl(recursiveConditionalTypes.ts, 144, 9)) +>B : Symbol(B, Decl(recursiveConditionalTypes.ts, 144, 26)) + + [...NTuple, ...NTuple]['length']; +>NTuple : Symbol(NTuple, Decl(recursiveConditionalTypes.ts, 137, 40)) +>A : Symbol(A, Decl(recursiveConditionalTypes.ts, 144, 9)) +>NTuple : Symbol(NTuple, Decl(recursiveConditionalTypes.ts, 137, 40)) +>B : Symbol(B, Decl(recursiveConditionalTypes.ts, 144, 26)) + +let five: Add<2, 3>; +>five : Symbol(five, Decl(recursiveConditionalTypes.ts, 147, 3)) +>Add : Symbol(Add, Decl(recursiveConditionalTypes.ts, 142, 65)) + +// Repro from #46316 + +type _PrependNextNum> = A['length'] extends infer T +>_PrependNextNum : Symbol(_PrependNextNum, Decl(recursiveConditionalTypes.ts, 147, 20)) +>A : Symbol(A, Decl(recursiveConditionalTypes.ts, 151, 21)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 2 more) +>A : Symbol(A, Decl(recursiveConditionalTypes.ts, 151, 21)) +>T : Symbol(T, Decl(recursiveConditionalTypes.ts, 151, 74)) + + ? [T, ...A] extends [...infer X] +>T : Symbol(T, Decl(recursiveConditionalTypes.ts, 151, 74)) +>A : Symbol(A, Decl(recursiveConditionalTypes.ts, 151, 21)) +>X : Symbol(X, Decl(recursiveConditionalTypes.ts, 152, 33)) + + ? X +>X : Symbol(X, Decl(recursiveConditionalTypes.ts, 152, 33)) + + : never + : never; + +type _Enumerate, N extends number> = N extends A['length'] +>_Enumerate : Symbol(_Enumerate, Decl(recursiveConditionalTypes.ts, 155, 12)) +>A : Symbol(A, Decl(recursiveConditionalTypes.ts, 157, 16)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 2 more) +>N : Symbol(N, Decl(recursiveConditionalTypes.ts, 157, 41)) +>N : Symbol(N, Decl(recursiveConditionalTypes.ts, 157, 41)) +>A : Symbol(A, Decl(recursiveConditionalTypes.ts, 157, 16)) + + ? A +>A : Symbol(A, Decl(recursiveConditionalTypes.ts, 157, 16)) + + : _Enumerate<_PrependNextNum, N> & number; +>_Enumerate : Symbol(_Enumerate, Decl(recursiveConditionalTypes.ts, 155, 12)) +>_PrependNextNum : Symbol(_PrependNextNum, Decl(recursiveConditionalTypes.ts, 147, 20)) +>A : Symbol(A, Decl(recursiveConditionalTypes.ts, 157, 16)) +>N : Symbol(N, Decl(recursiveConditionalTypes.ts, 157, 41)) + +type Enumerate = number extends N +>Enumerate : Symbol(Enumerate, Decl(recursiveConditionalTypes.ts, 159, 49)) +>N : Symbol(N, Decl(recursiveConditionalTypes.ts, 161, 15)) +>N : Symbol(N, Decl(recursiveConditionalTypes.ts, 161, 15)) + + ? number + : _Enumerate<[], N> extends (infer E)[] +>_Enumerate : Symbol(_Enumerate, Decl(recursiveConditionalTypes.ts, 155, 12)) +>N : Symbol(N, Decl(recursiveConditionalTypes.ts, 161, 15)) +>E : Symbol(E, Decl(recursiveConditionalTypes.ts, 163, 38)) + + ? E +>E : Symbol(E, Decl(recursiveConditionalTypes.ts, 163, 38)) + + : never; + +function foo2(value: T): Enumerate { +>foo2 : Symbol(foo2, Decl(recursiveConditionalTypes.ts, 165, 12)) +>T : Symbol(T, Decl(recursiveConditionalTypes.ts, 167, 14)) +>value : Symbol(value, Decl(recursiveConditionalTypes.ts, 167, 35)) +>T : Symbol(T, Decl(recursiveConditionalTypes.ts, 167, 14)) +>Enumerate : Symbol(Enumerate, Decl(recursiveConditionalTypes.ts, 159, 49)) +>T : Symbol(T, Decl(recursiveConditionalTypes.ts, 167, 14)) + + return value.length; // Error +>value.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) +>value : Symbol(value, Decl(recursiveConditionalTypes.ts, 167, 35)) +>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) +} + diff --git a/tests/baselines/reference/recursiveConditionalTypes.types b/tests/baselines/reference/recursiveConditionalTypes.types index 281a5886497..2291ce8b5eb 100644 --- a/tests/baselines/reference/recursiveConditionalTypes.types +++ b/tests/baselines/reference/recursiveConditionalTypes.types @@ -345,3 +345,52 @@ type Helper = T extends ParseSuccess ? ParseSuccess : null type TP2 = ParseManyWhitespace2<" foo">; >TP2 : ParseSuccess<"foo"> +// Repro from #46183 + +type NTuple = +>NTuple : NTuple + + Tup['length'] extends N ? Tup : NTuple; + +type Add = +>Add : Add + + [...NTuple, ...NTuple]['length']; + +let five: Add<2, 3>; +>five : 5 + +// Repro from #46316 + +type _PrependNextNum> = A['length'] extends infer T +>_PrependNextNum : _PrependNextNum + + ? [T, ...A] extends [...infer X] + ? X + : never + : never; + +type _Enumerate, N extends number> = N extends A['length'] +>_Enumerate : _Enumerate + + ? A + : _Enumerate<_PrependNextNum, N> & number; + +type Enumerate = number extends N +>Enumerate : Enumerate + + ? number + : _Enumerate<[], N> extends (infer E)[] + ? E + : never; + +function foo2(value: T): Enumerate { +>foo2 : (value: T) => Enumerate +>value : T + + return value.length; // Error +>value.length : number +>value : T +>length : number +} + diff --git a/tests/cases/compiler/recursiveConditionalTypes.ts b/tests/cases/compiler/recursiveConditionalTypes.ts index d086b37f30c..6810a37ca07 100644 --- a/tests/cases/compiler/recursiveConditionalTypes.ts +++ b/tests/cases/compiler/recursiveConditionalTypes.ts @@ -140,3 +140,35 @@ type ParseManyWhitespace2 = type Helper = T extends ParseSuccess ? ParseSuccess : null type TP2 = ParseManyWhitespace2<" foo">; + +// Repro from #46183 + +type NTuple = + Tup['length'] extends N ? Tup : NTuple; + +type Add = + [...NTuple, ...NTuple]['length']; + +let five: Add<2, 3>; + +// Repro from #46316 + +type _PrependNextNum> = A['length'] extends infer T + ? [T, ...A] extends [...infer X] + ? X + : never + : never; + +type _Enumerate, N extends number> = N extends A['length'] + ? A + : _Enumerate<_PrependNextNum, N> & number; + +type Enumerate = number extends N + ? number + : _Enumerate<[], N> extends (infer E)[] + ? E + : never; + +function foo2(value: T): Enumerate { + return value.length; // Error +} From cd0434aa768da69515eb184c7f333729e663825c Mon Sep 17 00:00:00 2001 From: LowR Date: Thu, 14 Oct 2021 04:03:31 +0900 Subject: [PATCH 07/60] fix(39744): make template literals more spec compliant (#45304) * fix(39744): make template literals more spec compliant * Add evaluation test for template literals * Add test for template literals with source map --- src/compiler/transformers/es2015.ts | 89 ++------ src/testRunner/tsconfig.json | 1 + .../unittests/evaluation/templateLiteral.ts | 40 ++++ .../baselines/reference/APISample_compile.js | 4 +- tests/baselines/reference/APISample_linter.js | 2 +- .../reference/APISample_parseConfig.js | 2 +- .../baselines/reference/APISample_watcher.js | 8 +- .../reference/TemplateExpression1.js | 2 +- tests/baselines/reference/asOperator3.js | 10 +- .../checkJsObjectLiteralIndexSignatures.js | 2 +- .../classAttributeInferenceTemplate.js | 4 +- .../reference/computedPropertyNames10_ES5.js | 2 +- .../reference/computedPropertyNames11_ES5.js | 2 +- .../reference/computedPropertyNames12_ES5.js | 2 +- .../reference/computedPropertyNames13_ES5.js | 2 +- .../reference/computedPropertyNames16_ES5.js | 2 +- .../reference/computedPropertyNames4_ES5.js | 2 +- tests/baselines/reference/constEnumErrors.js | 2 +- .../declarationNoDanglingGenerics.js | 2 +- ...ingInitializerContextualTypeFromContext.js | 2 +- ...ExponentiationOperatorInTempalteString4.js | 34 ++-- ...ExponentiationOperatorInTemplateString1.js | 38 ++-- ...ExponentiationOperatorInTemplateString2.js | 38 ++-- ...ExponentiationOperatorInTemplateString3.js | 38 ++-- ...peratorInTemplateStringWithSyntaxError1.js | 36 ++-- ...peratorInTemplateStringWithSyntaxError2.js | 36 ++-- ...peratorInTemplateStringWithSyntaxError3.js | 36 ++-- ...iationOperatorWithTemplateStringInvalid.js | 24 +-- ...ggedTemplateEscapeSequences(target=es5).js | 2 +- .../jsDeclarationsExportedClassAliases.js | 2 +- .../reference/noImplicitSymbolToString.js | 4 +- .../reference/recursiveTypeReferences1.js | 2 +- ...stringLiteralTypesWithTemplateStrings02.js | 2 +- ...sPlainCharactersThatArePartsOfEscapes02.js | 2 +- ...emplateStringsWithIncompatibleTypedTags.js | 2 +- ...taggedTemplateStringsWithTagsTypedAsAny.js | 2 +- .../taggedTemplateStringsWithTypedTags.js | 2 +- .../reference/templateLiteralTypes1.js | 2 +- .../reference/templateLiteralTypes2.js | 60 +++--- .../reference/templateLiteralTypes3.js | 32 +-- .../reference/templateLiteralsInTypes.js | 2 +- .../reference/templateLiteralsSourceMap.js | 7 + .../templateLiteralsSourceMap.js.map | 3 + .../templateLiteralsSourceMap.sourcemap.txt | 49 +++++ .../templateLiteralsSourceMap.symbols | 4 + .../reference/templateLiteralsSourceMap.types | 8 + .../templateStringBinaryOperations.js | 96 ++++----- .../templateStringBinaryOperationsInvalid.js | 192 +++++++++--------- .../reference/templateStringInArray.js | 2 +- .../templateStringInArrowFunction.js | 2 +- .../templateStringInCallExpression.js | 2 +- .../reference/templateStringInConditional.js | 2 +- .../templateStringInDeleteExpression.js | 2 +- .../reference/templateStringInDivision.js | 2 +- .../templateStringInEqualityChecks.js | 8 +- .../templateStringInFunctionExpression.js | 4 +- .../reference/templateStringInInOperator.js | 2 +- .../templateStringInIndexExpression.js | 2 +- .../reference/templateStringInInstanceOf.js | 2 +- .../reference/templateStringInModulo.js | 2 +- .../templateStringInMultiplication.js | 2 +- .../templateStringInNewExpression.js | 2 +- .../reference/templateStringInNewOperator.js | 2 +- .../templateStringInObjectLiteral.js | 2 +- .../reference/templateStringInParentheses.js | 2 +- .../templateStringInPropertyAssignment.js | 2 +- .../templateStringInSwitchAndCase.js | 6 +- .../templateStringInTaggedTemplate.js | 2 +- .../templateStringInTypeAssertion.js | 2 +- .../reference/templateStringInTypeOf.js | 2 +- .../reference/templateStringInUnaryPlus.js | 2 +- .../reference/templateStringInWhile.js | 4 +- ...gPlainCharactersThatArePartsOfEscapes02.js | 2 +- ...mplateStringWithCommentsInArrowFunction.js | 8 +- .../templateStringWithEmbeddedAddition.js | 2 +- .../templateStringWithEmbeddedArray.js | 2 +- ...templateStringWithEmbeddedArrowFunction.js | 2 +- .../templateStringWithEmbeddedComments.js | 7 +- .../templateStringWithEmbeddedConditional.js | 2 +- .../templateStringWithEmbeddedDivision.js | 2 +- ...ateStringWithEmbeddedFunctionExpression.js | 2 +- .../templateStringWithEmbeddedInOperator.js | 2 +- .../templateStringWithEmbeddedInstanceOf.js | 2 +- .../templateStringWithEmbeddedModulo.js | 2 +- ...emplateStringWithEmbeddedMultiplication.js | 2 +- .../templateStringWithEmbeddedNewOperator.js | 2 +- ...templateStringWithEmbeddedObjectLiteral.js | 2 +- ...emplateStringWithEmbeddedTemplateString.js | 2 +- ...ringWithEmbeddedTypeAssertionOnAddition.js | 2 +- ...emplateStringWithEmbeddedTypeOfOperator.js | 2 +- .../templateStringWithEmbeddedUnaryPlus.js | 2 +- .../templateStringWithEmbeddedYieldKeyword.js | 4 +- .../templateStringWithEmptyLiteralPortions.js | 24 +-- ...ateStringWithOpenCommentInStringPortion.js | 2 +- .../templateStringWithPropertyAccess.js | 2 +- ...tionExpressionsInSubstitutionExpression.js | 2 +- .../truthinessCallExpressionCoercion.js | 2 +- ...ng-setup-correctly-and-reports-no-error.js | 2 +- .../demo/updates-with-circular-reference.js | 2 +- .../reference/typeGuardIntersectionTypes.js | 4 +- ...unicodeExtendedEscapesInTemplates20_ES5.js | 2 +- .../compiler/templateLiteralsSourceMap.ts | 3 + 102 files changed, 575 insertions(+), 522 deletions(-) create mode 100644 src/testRunner/unittests/evaluation/templateLiteral.ts create mode 100644 tests/baselines/reference/templateLiteralsSourceMap.js create mode 100644 tests/baselines/reference/templateLiteralsSourceMap.js.map create mode 100644 tests/baselines/reference/templateLiteralsSourceMap.sourcemap.txt create mode 100644 tests/baselines/reference/templateLiteralsSourceMap.symbols create mode 100644 tests/baselines/reference/templateLiteralsSourceMap.types create mode 100644 tests/cases/compiler/templateLiteralsSourceMap.ts diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 07d79f50fe2..3ad6ce006b0 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -4102,87 +4102,22 @@ namespace ts { * @param node A TemplateExpression node. */ function visitTemplateExpression(node: TemplateExpression): Expression { - const expressions: Expression[] = []; - addTemplateHead(expressions, node); - addTemplateSpans(expressions, node); - - // createAdd will check if each expression binds less closely than binary '+'. - // If it does, it wraps the expression in parentheses. Otherwise, something like - // `abc${ 1 << 2 }` - // becomes - // "abc" + 1 << 2 + "" - // which is really - // ("abc" + 1) << (2 + "") - // rather than - // "abc" + (1 << 2) + "" - const expression = reduceLeft(expressions, factory.createAdd)!; - if (nodeIsSynthesized(expression)) { - setTextRange(expression, node); - } - - return expression; - } - - /** - * Gets a value indicating whether we need to include the head of a TemplateExpression. - * - * @param node A TemplateExpression node. - */ - function shouldAddTemplateHead(node: TemplateExpression) { - // If this expression has an empty head literal and the first template span has a non-empty - // literal, then emitting the empty head literal is not necessary. - // `${ foo } and ${ bar }` - // can be emitted as - // foo + " and " + bar - // This is because it is only required that one of the first two operands in the emit - // output must be a string literal, so that the other operand and all following operands - // are forced into strings. - // - // If the first template span has an empty literal, then the head must still be emitted. - // `${ foo }${ bar }` - // must still be emitted as - // "" + foo + bar - - // There is always atleast one templateSpan in this code path, since - // NoSubstitutionTemplateLiterals are directly emitted via emitLiteral() - Debug.assert(node.templateSpans.length !== 0); - - const span = node.templateSpans[0]; - return node.head.text.length !== 0 || span.literal.text.length === 0 || !!length(getLeadingCommentRangesOfNode(span.expression, currentSourceFile)); - } - - /** - * Adds the head of a TemplateExpression to an array of expressions. - * - * @param expressions An array of expressions. - * @param node A TemplateExpression node. - */ - function addTemplateHead(expressions: Expression[], node: TemplateExpression): void { - if (!shouldAddTemplateHead(node)) { - return; - } - - expressions.push(factory.createStringLiteral(node.head.text)); - } - - /** - * Visits and adds the template spans of a TemplateExpression to an array of expressions. - * - * @param expressions An array of expressions. - * @param node A TemplateExpression node. - */ - function addTemplateSpans(expressions: Expression[], node: TemplateExpression): void { + let expression: Expression = factory.createStringLiteral(node.head.text); for (const span of node.templateSpans) { - expressions.push(visitNode(span.expression, visitor, isExpression)); + const args = [visitNode(span.expression, visitor, isExpression)]; - // Only emit if the literal is non-empty. - // The binary '+' operator is left-associative, so the first string concatenation - // with the head will force the result up to this point to be a string. - // Emitting a '+ ""' has no semantic effect for middles and tails. - if (span.literal.text.length !== 0) { - expressions.push(factory.createStringLiteral(span.literal.text)); + if (span.literal.text.length > 0) { + args.push(factory.createStringLiteral(span.literal.text)); } + + expression = factory.createCallExpression( + factory.createPropertyAccessExpression(expression, "concat"), + /*typeArguments*/ undefined, + args, + ); } + + return setTextRange(expression, node); } /** diff --git a/src/testRunner/tsconfig.json b/src/testRunner/tsconfig.json index 5f9615be944..e617b5adc09 100644 --- a/src/testRunner/tsconfig.json +++ b/src/testRunner/tsconfig.json @@ -100,6 +100,7 @@ "unittests/evaluation/optionalCall.ts", "unittests/evaluation/objectRest.ts", "unittests/evaluation/superInStaticInitializer.ts", + "unittests/evaluation/templateLiteral.ts", "unittests/evaluation/updateExpressionInModule.ts", "unittests/services/cancellableLanguageServiceOperations.ts", "unittests/services/colorization.ts", diff --git a/src/testRunner/unittests/evaluation/templateLiteral.ts b/src/testRunner/unittests/evaluation/templateLiteral.ts new file mode 100644 index 00000000000..2a4e23ee879 --- /dev/null +++ b/src/testRunner/unittests/evaluation/templateLiteral.ts @@ -0,0 +1,40 @@ +describe("unittests:: evaluation:: templateLiteral", () => { + it("toString() over valueOf()", () => { + const result = evaluator.evaluateTypeScript(` + class C { + toString() { + return "toString"; + } + valueOf() { + return "valueOf"; + } + } + + export const output = \`\${new C}\`; + `); + assert.strictEqual(result.output, "toString"); + }); + + it("correct evaluation order", () => { + const result = evaluator.evaluateTypeScript(` + class C { + counter: number; + + constructor() { + this.counter = 0; + } + + get foo() { + this.counter++; + return { + toString: () => this.counter++, + }; + } + } + + const c = new C; + export const output = \`\${c.foo} \${c.foo}\`; + `); + assert.strictEqual(result.output, "1 3"); + }); +}); diff --git a/tests/baselines/reference/APISample_compile.js b/tests/baselines/reference/APISample_compile.js index 673dc047fa1..b19bc06d1e6 100644 --- a/tests/baselines/reference/APISample_compile.js +++ b/tests/baselines/reference/APISample_compile.js @@ -66,10 +66,10 @@ function compile(fileNames, options) { return; } var _a = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start), line = _a.line, character = _a.character; - console.log(diagnostic.file.fileName + " (" + (line + 1) + "," + (character + 1) + "): " + message); + console.log("".concat(diagnostic.file.fileName, " (").concat(line + 1, ",").concat(character + 1, "): ").concat(message)); }); var exitCode = emitResult.emitSkipped ? 1 : 0; - console.log("Process exiting with code '" + exitCode + "'."); + console.log("Process exiting with code '".concat(exitCode, "'.")); process.exit(exitCode); } exports.compile = compile; diff --git a/tests/baselines/reference/APISample_linter.js b/tests/baselines/reference/APISample_linter.js index a51c9cde268..65e03d339e6 100644 --- a/tests/baselines/reference/APISample_linter.js +++ b/tests/baselines/reference/APISample_linter.js @@ -114,7 +114,7 @@ function delint(sourceFile) { } function report(node, message) { var _a = sourceFile.getLineAndCharacterOfPosition(node.getStart()), line = _a.line, character = _a.character; - console.log(sourceFile.fileName + " (" + (line + 1) + "," + (character + 1) + "): " + message); + console.log("".concat(sourceFile.fileName, " (").concat(line + 1, ",").concat(character + 1, "): ").concat(message)); } } exports.delint = delint; diff --git a/tests/baselines/reference/APISample_parseConfig.js b/tests/baselines/reference/APISample_parseConfig.js index ffd27fdbabb..e9dc119417c 100644 --- a/tests/baselines/reference/APISample_parseConfig.js +++ b/tests/baselines/reference/APISample_parseConfig.js @@ -56,7 +56,7 @@ function printError(error) { if (!error) { return; } - console.log((error.file && error.file.fileName) + ": " + error.messageText); + console.log("".concat(error.file && error.file.fileName, ": ").concat(error.messageText)); } function createProgram(rootFiles, compilerOptionsJson) { var _a = ts.parseConfigFileTextToJson("tsconfig.json", compilerOptionsJson), config = _a.config, error = _a.error; diff --git a/tests/baselines/reference/APISample_watcher.js b/tests/baselines/reference/APISample_watcher.js index e93856a3165..8241222971b 100644 --- a/tests/baselines/reference/APISample_watcher.js +++ b/tests/baselines/reference/APISample_watcher.js @@ -166,10 +166,10 @@ function watch(rootFileNames, options) { function emitFile(fileName) { var output = services.getEmitOutput(fileName); if (!output.emitSkipped) { - console.log("Emitting " + fileName); + console.log("Emitting ".concat(fileName)); } else { - console.log("Emitting " + fileName + " failed"); + console.log("Emitting ".concat(fileName, " failed")); logErrors(fileName); } output.outputFiles.forEach(function (o) { @@ -184,10 +184,10 @@ function watch(rootFileNames, options) { var message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"); if (diagnostic.file) { var _a = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start), line = _a.line, character = _a.character; - console.log(" Error " + diagnostic.file.fileName + " (" + (line + 1) + "," + (character + 1) + "): " + message); + console.log(" Error ".concat(diagnostic.file.fileName, " (").concat(line + 1, ",").concat(character + 1, "): ").concat(message)); } else { - console.log(" Error: " + message); + console.log(" Error: ".concat(message)); } }); } diff --git a/tests/baselines/reference/TemplateExpression1.js b/tests/baselines/reference/TemplateExpression1.js index c4437260084..6a0f901f0f9 100644 --- a/tests/baselines/reference/TemplateExpression1.js +++ b/tests/baselines/reference/TemplateExpression1.js @@ -2,4 +2,4 @@ var v = `foo ${ a //// [TemplateExpression1.js] -var v = "foo " + a; +var v = "foo ".concat(a); diff --git a/tests/baselines/reference/asOperator3.js b/tests/baselines/reference/asOperator3.js index 7cbb277bb03..9027237af1d 100644 --- a/tests/baselines/reference/asOperator3.js +++ b/tests/baselines/reference/asOperator3.js @@ -15,11 +15,11 @@ var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cook if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; }; -var a = "" + (123 + 456); -var b = "leading " + (123 + 456); -var c = 123 + 456 + " trailing"; -var d = "Hello " + 123 + " World"; +var a = "".concat(123 + 456); +var b = "leading ".concat(123 + 456); +var c = "".concat(123 + 456, " trailing"); +var d = "Hello ".concat(123, " World"); var e = "Hello"; -var f = 1 + (1 + " end of string"); +var f = 1 + "".concat(1, " end of string"); var g = tag(__makeTemplateObject(["Hello ", " World"], ["Hello ", " World"]), 123); var h = tag(__makeTemplateObject(["Hello"], ["Hello"])); diff --git a/tests/baselines/reference/checkJsObjectLiteralIndexSignatures.js b/tests/baselines/reference/checkJsObjectLiteralIndexSignatures.js index bc9c08b5524..b133c6c6ba5 100644 --- a/tests/baselines/reference/checkJsObjectLiteralIndexSignatures.js +++ b/tests/baselines/reference/checkJsObjectLiteralIndexSignatures.js @@ -16,7 +16,7 @@ stringIndex[s].toFixed(); // @ts-check var _a, _b; var n = Math.random(); -var s = "" + n; +var s = "".concat(n); var numericIndex = (_a = {}, _a[n] = 1, _a); numericIndex[n].toFixed(); var stringIndex = (_b = {}, _b[s] = 1, _b); diff --git a/tests/baselines/reference/classAttributeInferenceTemplate.js b/tests/baselines/reference/classAttributeInferenceTemplate.js index 24a90d0301a..2f5503d7219 100644 --- a/tests/baselines/reference/classAttributeInferenceTemplate.js +++ b/tests/baselines/reference/classAttributeInferenceTemplate.js @@ -19,8 +19,8 @@ var MyClass = /** @class */ (function () { function MyClass() { var variable = 'something'; this.property = "foo"; // Correctly inferred as `string` - this.property2 = "foo-" + variable; // Causes an error - var localProperty = "foo-" + variable; // Correctly inferred as `string` + this.property2 = "foo-".concat(variable); // Causes an error + var localProperty = "foo-".concat(variable); // Correctly inferred as `string` } return MyClass; }()); diff --git a/tests/baselines/reference/computedPropertyNames10_ES5.js b/tests/baselines/reference/computedPropertyNames10_ES5.js index 01e11d237f1..eb277ed2b6b 100644 --- a/tests/baselines/reference/computedPropertyNames10_ES5.js +++ b/tests/baselines/reference/computedPropertyNames10_ES5.js @@ -32,5 +32,5 @@ var v = (_a = {}, _a[a] = function () { }, _a[true] = function () { }, _a["hello bye"] = function () { }, - _a["hello " + a + " bye"] = function () { }, + _a["hello ".concat(a, " bye")] = function () { }, _a); diff --git a/tests/baselines/reference/computedPropertyNames11_ES5.js b/tests/baselines/reference/computedPropertyNames11_ES5.js index 8123ba00c35..47c6cbb3c9f 100644 --- a/tests/baselines/reference/computedPropertyNames11_ES5.js +++ b/tests/baselines/reference/computedPropertyNames11_ES5.js @@ -72,7 +72,7 @@ var v = (_a = {}, enumerable: false, configurable: true }), - Object.defineProperty(_a, "hello " + a + " bye", { + Object.defineProperty(_a, "hello ".concat(a, " bye"), { get: function () { return 0; }, enumerable: false, configurable: true diff --git a/tests/baselines/reference/computedPropertyNames12_ES5.js b/tests/baselines/reference/computedPropertyNames12_ES5.js index 0245bfd3b2a..2050c2c75f1 100644 --- a/tests/baselines/reference/computedPropertyNames12_ES5.js +++ b/tests/baselines/reference/computedPropertyNames12_ES5.js @@ -27,7 +27,7 @@ var C = /** @class */ (function () { this["hello bye"] = 0; } var _a, _b, _c; - _a = n, s + s, _b = s + n, +s, _c = "hello " + a + " bye"; + _a = n, s + s, _b = s + n, +s, _c = "hello ".concat(a, " bye"); C[_c] = 0; return C; }()); diff --git a/tests/baselines/reference/computedPropertyNames13_ES5.js b/tests/baselines/reference/computedPropertyNames13_ES5.js index f22d5550604..b23507e3635 100644 --- a/tests/baselines/reference/computedPropertyNames13_ES5.js +++ b/tests/baselines/reference/computedPropertyNames13_ES5.js @@ -33,6 +33,6 @@ var C = /** @class */ (function () { C.prototype[a] = function () { }; C[true] = function () { }; C.prototype["hello bye"] = function () { }; - C["hello " + a + " bye"] = function () { }; + C["hello ".concat(a, " bye")] = function () { }; return C; }()); diff --git a/tests/baselines/reference/computedPropertyNames16_ES5.js b/tests/baselines/reference/computedPropertyNames16_ES5.js index 1fec4a6f2ea..9d7a21520c3 100644 --- a/tests/baselines/reference/computedPropertyNames16_ES5.js +++ b/tests/baselines/reference/computedPropertyNames16_ES5.js @@ -73,7 +73,7 @@ var C = /** @class */ (function () { enumerable: false, configurable: true }); - Object.defineProperty(C.prototype, "hello " + a + " bye", { + Object.defineProperty(C.prototype, "hello ".concat(a, " bye"), { get: function () { return 0; }, enumerable: false, configurable: true diff --git a/tests/baselines/reference/computedPropertyNames4_ES5.js b/tests/baselines/reference/computedPropertyNames4_ES5.js index 1c966e63bb5..58c7b93660d 100644 --- a/tests/baselines/reference/computedPropertyNames4_ES5.js +++ b/tests/baselines/reference/computedPropertyNames4_ES5.js @@ -32,5 +32,5 @@ var v = (_a = {}, _a[a] = 1, _a[true] = 0, _a["hello bye"] = 0, - _a["hello " + a + " bye"] = 0, + _a["hello ".concat(a, " bye")] = 0, _a); diff --git a/tests/baselines/reference/constEnumErrors.js b/tests/baselines/reference/constEnumErrors.js index 3614059d629..09eee16dcd9 100644 --- a/tests/baselines/reference/constEnumErrors.js +++ b/tests/baselines/reference/constEnumErrors.js @@ -52,7 +52,7 @@ var E; var y0 = E2[1]; var name = "A"; var y1 = E2[name]; -var y2 = E2["" + name]; +var y2 = E2["".concat(name)]; var x = E2; var y = [E2]; function foo(t) { diff --git a/tests/baselines/reference/declarationNoDanglingGenerics.js b/tests/baselines/reference/declarationNoDanglingGenerics.js index 4b97a3abe0b..e758b86a469 100644 --- a/tests/baselines/reference/declarationNoDanglingGenerics.js +++ b/tests/baselines/reference/declarationNoDanglingGenerics.js @@ -54,7 +54,7 @@ exports.CKind = exports.BKind = exports.AKind = void 0; var kindCache = {}; function register(kind) { if (kindCache[kind]) { - throw new Error("Class with kind \"" + kind + "\" is already registered."); + throw new Error("Class with kind \"".concat(kind, "\" is already registered.")); } kindCache[kind] = true; } diff --git a/tests/baselines/reference/destructuringInitializerContextualTypeFromContext.js b/tests/baselines/reference/destructuringInitializerContextualTypeFromContext.js index ad434acada1..fc812b3b67b 100644 --- a/tests/baselines/reference/destructuringInitializerContextualTypeFromContext.js +++ b/tests/baselines/reference/destructuringInitializerContextualTypeFromContext.js @@ -55,7 +55,7 @@ var Parent = function (_a) { }; var Child = function (_a) { var children = _a.children, _b = _a.name, name = _b === void 0 ? "Artemis" : _b, props = __rest(_a, ["children", "name"]); - return "name: " + name + " props: " + JSON.stringify(props); + return "name: ".concat(name, " props: ").concat(JSON.stringify(props)); }; f(function (_a) { var _1 = _a[0], _b = _a[1], _2 = _b === void 0 ? undefined : _b; diff --git a/tests/baselines/reference/emitExponentiationOperatorInTempalteString4.js b/tests/baselines/reference/emitExponentiationOperatorInTempalteString4.js index 379af45e0f7..65c637a58e1 100644 --- a/tests/baselines/reference/emitExponentiationOperatorInTempalteString4.js +++ b/tests/baselines/reference/emitExponentiationOperatorInTempalteString4.js @@ -31,22 +31,22 @@ var t1 = 10; var t2 = 10; var s; // With TemplateTail -Math.pow(t1, -t2) + " world"; -Math.pow((-t1), t2) - t1 + " world"; -Math.pow((-++t1), t2) - t1 + " world"; -Math.pow((-t1++), t2) - t1 + " world"; -Math.pow((~t1), Math.pow(t2, --t1)) + " world"; -typeof (Math.pow(t1, Math.pow(t2, t1))) + " world"; +"".concat(Math.pow(t1, -t2), " world"); +"".concat(Math.pow((-t1), t2) - t1, " world"); +"".concat(Math.pow((-++t1), t2) - t1, " world"); +"".concat(Math.pow((-t1++), t2) - t1, " world"); +"".concat(Math.pow((~t1), Math.pow(t2, --t1)), " world"); +"".concat(typeof (Math.pow(t1, Math.pow(t2, t1))), " world"); // TempateHead & TemplateTail are empt -Math.pow(t1, -t2) + " hello world " + Math.pow(t1, -t2); -Math.pow((-t1), t2) - t1 + " hello world " + (Math.pow((-t1), t2) - t1); -Math.pow((-++t1), t2) - t1 + " hello world " + Math.pow(t1, Math.pow((-++t1), -t1)); -Math.pow((-t1++), t2) - t1 + " hello world " + Math.pow(t2, Math.pow((-t1++), -t1)); -Math.pow((~t1), Math.pow(t2, --t1)) + " hello world " + Math.pow((~t1), Math.pow(t2, --t1)); -typeof (Math.pow(t1, Math.pow(t2, t1))) + " hello world " + typeof (Math.pow(t1, Math.pow(t2, t1))); +"".concat(Math.pow(t1, -t2), " hello world ").concat(Math.pow(t1, -t2)); +"".concat(Math.pow((-t1), t2) - t1, " hello world ").concat(Math.pow((-t1), t2) - t1); +"".concat(Math.pow((-++t1), t2) - t1, " hello world ").concat(Math.pow(t1, Math.pow((-++t1), -t1))); +"".concat(Math.pow((-t1++), t2) - t1, " hello world ").concat(Math.pow(t2, Math.pow((-t1++), -t1))); +"".concat(Math.pow((~t1), Math.pow(t2, --t1)), " hello world ").concat(Math.pow((~t1), Math.pow(t2, --t1))); +"".concat(typeof (Math.pow(t1, Math.pow(t2, t1))), " hello world ").concat(typeof (Math.pow(t1, Math.pow(t2, t1)))); // With templateHead -"hello " + (Math.pow((-t1), t2) - t1); -"hello " + (Math.pow((-++t1), t2) - t1); -"hello " + (Math.pow((-t1++), t2) - t1); -"hello " + Math.pow((~t1), Math.pow(t2, --t1)); -"hello " + typeof (Math.pow(t1, Math.pow(t2, t1))); +"hello ".concat(Math.pow((-t1), t2) - t1); +"hello ".concat(Math.pow((-++t1), t2) - t1); +"hello ".concat(Math.pow((-t1++), t2) - t1); +"hello ".concat(Math.pow((~t1), Math.pow(t2, --t1))); +"hello ".concat(typeof (Math.pow(t1, Math.pow(t2, t1)))); diff --git a/tests/baselines/reference/emitExponentiationOperatorInTemplateString1.js b/tests/baselines/reference/emitExponentiationOperatorInTemplateString1.js index dbfd5987156..3af187a1ea2 100644 --- a/tests/baselines/reference/emitExponentiationOperatorInTemplateString1.js +++ b/tests/baselines/reference/emitExponentiationOperatorInTemplateString1.js @@ -31,22 +31,22 @@ var t1 = 10; var t2 = 10; var s; // TempateHead & TemplateTail are empty -"" + Math.pow(t1, t2); -"" + Math.pow(t1, Math.pow(t2, t1)); -"" + (t1 + Math.pow(t2, t1)); -"" + (Math.pow(t1, t2) + t1); -"" + (t1 + Math.pow(t2, t2) + t1); -"" + typeof (Math.pow(t1, Math.pow(t2, t1))); -"" + (1 + typeof (Math.pow(t1, Math.pow(t2, t1)))); -"" + Math.pow(t1, t2) + Math.pow(t1, t2); -"" + Math.pow(t1, Math.pow(t2, t1)) + Math.pow(t1, Math.pow(t2, t1)); -"" + (t1 + Math.pow(t2, t1)) + (t1 + Math.pow(t2, t1)); -"" + (Math.pow(t1, t2) + t1) + (Math.pow(t1, t2) + t1); -"" + (t1 + Math.pow(t2, t2) + t1) + (t1 + Math.pow(t2, t2) + t1); -"" + typeof (Math.pow(t1, Math.pow(t2, t1))) + typeof (Math.pow(t1, Math.pow(t2, t1))); -Math.pow(t1, t2) + " hello world " + Math.pow(t1, t2); -Math.pow(t1, Math.pow(t2, t1)) + " hello world " + Math.pow(t1, Math.pow(t2, t1)); -t1 + Math.pow(t2, t1) + " hello world " + (t1 + Math.pow(t2, t1)); -Math.pow(t1, t2) + t1 + " hello world " + (Math.pow(t1, t2) + t1); -t1 + Math.pow(t2, t2) + t1 + " hello world " + (t1 + Math.pow(t2, t2) + t1); -typeof (Math.pow(t1, Math.pow(t2, t1))) + " hello world " + typeof (Math.pow(t1, Math.pow(t2, t1))); +"".concat(Math.pow(t1, t2)); +"".concat(Math.pow(t1, Math.pow(t2, t1))); +"".concat(t1 + Math.pow(t2, t1)); +"".concat(Math.pow(t1, t2) + t1); +"".concat(t1 + Math.pow(t2, t2) + t1); +"".concat(typeof (Math.pow(t1, Math.pow(t2, t1)))); +"".concat(1 + typeof (Math.pow(t1, Math.pow(t2, t1)))); +"".concat(Math.pow(t1, t2)).concat(Math.pow(t1, t2)); +"".concat(Math.pow(t1, Math.pow(t2, t1))).concat(Math.pow(t1, Math.pow(t2, t1))); +"".concat(t1 + Math.pow(t2, t1)).concat(t1 + Math.pow(t2, t1)); +"".concat(Math.pow(t1, t2) + t1).concat(Math.pow(t1, t2) + t1); +"".concat(t1 + Math.pow(t2, t2) + t1).concat(t1 + Math.pow(t2, t2) + t1); +"".concat(typeof (Math.pow(t1, Math.pow(t2, t1)))).concat(typeof (Math.pow(t1, Math.pow(t2, t1)))); +"".concat(Math.pow(t1, t2), " hello world ").concat(Math.pow(t1, t2)); +"".concat(Math.pow(t1, Math.pow(t2, t1)), " hello world ").concat(Math.pow(t1, Math.pow(t2, t1))); +"".concat(t1 + Math.pow(t2, t1), " hello world ").concat(t1 + Math.pow(t2, t1)); +"".concat(Math.pow(t1, t2) + t1, " hello world ").concat(Math.pow(t1, t2) + t1); +"".concat(t1 + Math.pow(t2, t2) + t1, " hello world ").concat(t1 + Math.pow(t2, t2) + t1); +"".concat(typeof (Math.pow(t1, Math.pow(t2, t1))), " hello world ").concat(typeof (Math.pow(t1, Math.pow(t2, t1)))); diff --git a/tests/baselines/reference/emitExponentiationOperatorInTemplateString2.js b/tests/baselines/reference/emitExponentiationOperatorInTemplateString2.js index 93604d0e00f..dea48731c6b 100644 --- a/tests/baselines/reference/emitExponentiationOperatorInTemplateString2.js +++ b/tests/baselines/reference/emitExponentiationOperatorInTemplateString2.js @@ -31,22 +31,22 @@ var t1 = 10; var t2 = 10; var s; // With templateHead -"hello " + Math.pow(t1, t2); -"hello " + Math.pow(t1, Math.pow(t2, t1)); -"hello " + (t1 + Math.pow(t2, t1)); -"hello " + (Math.pow(t1, t2) + t1); -"hello " + (t1 + Math.pow(t2, t2) + t1); -"hello " + typeof (Math.pow(t1, Math.pow(t2, t1))); -"hello " + (1 + typeof (Math.pow(t1, Math.pow(t2, t1)))); -"hello " + Math.pow(t1, t2) + Math.pow(t1, t2); -"hello " + Math.pow(t1, Math.pow(t2, t1)) + Math.pow(t1, Math.pow(t2, t1)); -"hello " + (t1 + Math.pow(t2, t1)) + (t1 + Math.pow(t2, t1)); -"hello " + (Math.pow(t1, t2) + t1) + (Math.pow(t1, t2) + t1); -"hello " + (t1 + Math.pow(t2, t2) + t1) + (t1 + Math.pow(t2, t2) + t1); -"hello " + typeof (Math.pow(t1, Math.pow(t2, t1))) + typeof (Math.pow(t1, Math.pow(t2, t1))); -"hello " + Math.pow(t1, t2) + " hello world " + Math.pow(t1, t2); -"hello " + Math.pow(t1, Math.pow(t2, t1)) + " hello world " + Math.pow(t1, Math.pow(t2, t1)); -"hello " + (t1 + Math.pow(t2, t1)) + " hello world " + (t1 + Math.pow(t2, t1)); -"hello " + (Math.pow(t1, t2) + t1) + " hello world " + (Math.pow(t1, t2) + t1); -"hello " + (t1 + Math.pow(t2, t2) + t1) + " hello world " + (t1 + Math.pow(t2, t2) + t1); -"hello " + typeof (Math.pow(t1, Math.pow(t2, t1))) + " hello world " + typeof (Math.pow(t1, Math.pow(t2, t1))); +"hello ".concat(Math.pow(t1, t2)); +"hello ".concat(Math.pow(t1, Math.pow(t2, t1))); +"hello ".concat(t1 + Math.pow(t2, t1)); +"hello ".concat(Math.pow(t1, t2) + t1); +"hello ".concat(t1 + Math.pow(t2, t2) + t1); +"hello ".concat(typeof (Math.pow(t1, Math.pow(t2, t1)))); +"hello ".concat(1 + typeof (Math.pow(t1, Math.pow(t2, t1)))); +"hello ".concat(Math.pow(t1, t2)).concat(Math.pow(t1, t2)); +"hello ".concat(Math.pow(t1, Math.pow(t2, t1))).concat(Math.pow(t1, Math.pow(t2, t1))); +"hello ".concat(t1 + Math.pow(t2, t1)).concat(t1 + Math.pow(t2, t1)); +"hello ".concat(Math.pow(t1, t2) + t1).concat(Math.pow(t1, t2) + t1); +"hello ".concat(t1 + Math.pow(t2, t2) + t1).concat(t1 + Math.pow(t2, t2) + t1); +"hello ".concat(typeof (Math.pow(t1, Math.pow(t2, t1)))).concat(typeof (Math.pow(t1, Math.pow(t2, t1)))); +"hello ".concat(Math.pow(t1, t2), " hello world ").concat(Math.pow(t1, t2)); +"hello ".concat(Math.pow(t1, Math.pow(t2, t1)), " hello world ").concat(Math.pow(t1, Math.pow(t2, t1))); +"hello ".concat(t1 + Math.pow(t2, t1), " hello world ").concat(t1 + Math.pow(t2, t1)); +"hello ".concat(Math.pow(t1, t2) + t1, " hello world ").concat(Math.pow(t1, t2) + t1); +"hello ".concat(t1 + Math.pow(t2, t2) + t1, " hello world ").concat(t1 + Math.pow(t2, t2) + t1); +"hello ".concat(typeof (Math.pow(t1, Math.pow(t2, t1))), " hello world ").concat(typeof (Math.pow(t1, Math.pow(t2, t1)))); diff --git a/tests/baselines/reference/emitExponentiationOperatorInTemplateString3.js b/tests/baselines/reference/emitExponentiationOperatorInTemplateString3.js index 93333a3a8df..ffd4a0bb208 100644 --- a/tests/baselines/reference/emitExponentiationOperatorInTemplateString3.js +++ b/tests/baselines/reference/emitExponentiationOperatorInTemplateString3.js @@ -32,22 +32,22 @@ var t1 = 10; var t2 = 10; var s; // With TemplateTail -Math.pow(t1, t2) + " world"; -Math.pow(t1, Math.pow(t2, t1)) + " world"; -t1 + Math.pow(t2, t1) + " world"; -Math.pow(t1, t2) + t1 + " world"; -t1 + Math.pow(t2, t2) + t1 + " world"; -typeof (Math.pow(t1, Math.pow(t2, t1))) + " world"; -1 + typeof (Math.pow(t1, Math.pow(t2, t1))) + " world"; -"" + Math.pow(t1, t2) + Math.pow(t1, t2) + " world"; -"" + Math.pow(t1, Math.pow(t2, t1)) + Math.pow(t1, Math.pow(t2, t1)) + " world"; -"" + (t1 + Math.pow(t2, t1)) + (t1 + Math.pow(t2, t1)) + " world"; -"" + (Math.pow(t1, t2) + t1) + (Math.pow(t1, t2) + t1) + " world"; -"" + (t1 + Math.pow(t2, t2) + t1) + (t1 + Math.pow(t2, t2) + t1) + " world"; -"" + typeof (Math.pow(t1, Math.pow(t2, t1))) + typeof (Math.pow(t1, Math.pow(t2, t1))) + " world"; -Math.pow(t1, t2) + " hello world " + Math.pow(t1, t2) + " !!"; -Math.pow(t1, Math.pow(t2, t1)) + " hello world " + Math.pow(t1, Math.pow(t2, t1)) + " !!"; -t1 + Math.pow(t2, t1) + " hello world " + (t1 + Math.pow(t2, t1)) + " !!"; -Math.pow(t1, t2) + t1 + " hello world " + (Math.pow(t1, t2) + t1) + " !!"; -t1 + Math.pow(t2, t2) + t1 + " hello world " + (t1 + Math.pow(t2, t2) + t1) + " !!"; -typeof (Math.pow(t1, Math.pow(t2, t1))) + " hello world " + typeof (Math.pow(t1, Math.pow(t2, t1))) + " !!"; +"".concat(Math.pow(t1, t2), " world"); +"".concat(Math.pow(t1, Math.pow(t2, t1)), " world"); +"".concat(t1 + Math.pow(t2, t1), " world"); +"".concat(Math.pow(t1, t2) + t1, " world"); +"".concat(t1 + Math.pow(t2, t2) + t1, " world"); +"".concat(typeof (Math.pow(t1, Math.pow(t2, t1))), " world"); +"".concat(1 + typeof (Math.pow(t1, Math.pow(t2, t1))), " world"); +"".concat(Math.pow(t1, t2)).concat(Math.pow(t1, t2), " world"); +"".concat(Math.pow(t1, Math.pow(t2, t1))).concat(Math.pow(t1, Math.pow(t2, t1)), " world"); +"".concat(t1 + Math.pow(t2, t1)).concat(t1 + Math.pow(t2, t1), " world"); +"".concat(Math.pow(t1, t2) + t1).concat(Math.pow(t1, t2) + t1, " world"); +"".concat(t1 + Math.pow(t2, t2) + t1).concat(t1 + Math.pow(t2, t2) + t1, " world"); +"".concat(typeof (Math.pow(t1, Math.pow(t2, t1)))).concat(typeof (Math.pow(t1, Math.pow(t2, t1))), " world"); +"".concat(Math.pow(t1, t2), " hello world ").concat(Math.pow(t1, t2), " !!"); +"".concat(Math.pow(t1, Math.pow(t2, t1)), " hello world ").concat(Math.pow(t1, Math.pow(t2, t1)), " !!"); +"".concat(t1 + Math.pow(t2, t1), " hello world ").concat(t1 + Math.pow(t2, t1), " !!"); +"".concat(Math.pow(t1, t2) + t1, " hello world ").concat(Math.pow(t1, t2) + t1, " !!"); +"".concat(t1 + Math.pow(t2, t2) + t1, " hello world ").concat(t1 + Math.pow(t2, t2) + t1, " !!"); +"".concat(typeof (Math.pow(t1, Math.pow(t2, t1))), " hello world ").concat(typeof (Math.pow(t1, Math.pow(t2, t1))), " !!"); diff --git a/tests/baselines/reference/exponentiationOperatorInTemplateStringWithSyntaxError1.js b/tests/baselines/reference/exponentiationOperatorInTemplateStringWithSyntaxError1.js index 8a793b4e780..6ba3fdc9ee5 100644 --- a/tests/baselines/reference/exponentiationOperatorInTemplateStringWithSyntaxError1.js +++ b/tests/baselines/reference/exponentiationOperatorInTemplateStringWithSyntaxError1.js @@ -32,21 +32,21 @@ var t2 = 10; var s; // Error: early syntax error using ES7 SimpleUnaryExpression on left-hand side without () // TempateHead & TemplateTail are empty -"" + (1 + Math.pow(typeof t1, Math.pow(t2, t1))); -"" + (Math.pow(-t1, t2) - t1); -"" + (Math.pow(-++t1, t2) - t1); -"" + (Math.pow(-t1++, t2) - t1); -"" + Math.pow(!t1, Math.pow(t2, --t1)); -"" + Math.pow(typeof t1, Math.pow(t2, t1)); -"" + (Math.pow(-t1, t2) - t1) + (Math.pow(-t1, t2) - t1); -"" + (Math.pow(-++t1, t2) - t1) + (Math.pow(-++t1, t2) - t1); -"" + (Math.pow(-t1++, t2) - t1) + (Math.pow(-t1++, t2) - t1); -"" + Math.pow(!t1, Math.pow(t2, --t1)) + Math.pow(!t1, Math.pow(t2, --t1)); -"" + Math.pow(typeof t1, Math.pow(t2, t1)) + Math.pow(typeof t1, Math.pow(t2, t1)); -"" + (1 + Math.pow(typeof t1, Math.pow(t2, t1))) + (1 + Math.pow(typeof t1, Math.pow(t2, t1))); -Math.pow(-t1, t2) - t1 + " hello world " + (Math.pow(-t1, t2) - t1); -Math.pow(-++t1, t2) - t1 + " hello world " + (Math.pow(-++t1, t2) - t1); -Math.pow(-t1++, t2) - t1 + " hello world " + (Math.pow(-t1++, t2) - t1); -Math.pow(!t1, Math.pow(t2, --t1)) + " hello world " + Math.pow(!t1, Math.pow(t2, --t1)); -Math.pow(typeof t1, Math.pow(t2, t1)) + " hello world " + Math.pow(typeof t1, Math.pow(t2, t1)); -1 + Math.pow(typeof t1, Math.pow(t2, t1)) + " hello world " + (1 + Math.pow(typeof t1, Math.pow(t2, t1))); +"".concat(1 + Math.pow(typeof t1, Math.pow(t2, t1))); +"".concat(Math.pow(-t1, t2) - t1); +"".concat(Math.pow(-++t1, t2) - t1); +"".concat(Math.pow(-t1++, t2) - t1); +"".concat(Math.pow(!t1, Math.pow(t2, --t1))); +"".concat(Math.pow(typeof t1, Math.pow(t2, t1))); +"".concat(Math.pow(-t1, t2) - t1).concat(Math.pow(-t1, t2) - t1); +"".concat(Math.pow(-++t1, t2) - t1).concat(Math.pow(-++t1, t2) - t1); +"".concat(Math.pow(-t1++, t2) - t1).concat(Math.pow(-t1++, t2) - t1); +"".concat(Math.pow(!t1, Math.pow(t2, --t1))).concat(Math.pow(!t1, Math.pow(t2, --t1))); +"".concat(Math.pow(typeof t1, Math.pow(t2, t1))).concat(Math.pow(typeof t1, Math.pow(t2, t1))); +"".concat(1 + Math.pow(typeof t1, Math.pow(t2, t1))).concat(1 + Math.pow(typeof t1, Math.pow(t2, t1))); +"".concat(Math.pow(-t1, t2) - t1, " hello world ").concat(Math.pow(-t1, t2) - t1); +"".concat(Math.pow(-++t1, t2) - t1, " hello world ").concat(Math.pow(-++t1, t2) - t1); +"".concat(Math.pow(-t1++, t2) - t1, " hello world ").concat(Math.pow(-t1++, t2) - t1); +"".concat(Math.pow(!t1, Math.pow(t2, --t1)), " hello world ").concat(Math.pow(!t1, Math.pow(t2, --t1))); +"".concat(Math.pow(typeof t1, Math.pow(t2, t1)), " hello world ").concat(Math.pow(typeof t1, Math.pow(t2, t1))); +"".concat(1 + Math.pow(typeof t1, Math.pow(t2, t1)), " hello world ").concat(1 + Math.pow(typeof t1, Math.pow(t2, t1))); diff --git a/tests/baselines/reference/exponentiationOperatorInTemplateStringWithSyntaxError2.js b/tests/baselines/reference/exponentiationOperatorInTemplateStringWithSyntaxError2.js index cf8bcfd698f..478603923f9 100644 --- a/tests/baselines/reference/exponentiationOperatorInTemplateStringWithSyntaxError2.js +++ b/tests/baselines/reference/exponentiationOperatorInTemplateStringWithSyntaxError2.js @@ -33,21 +33,21 @@ var t2 = 10; var s; // Error: early syntax error using ES7 SimpleUnaryExpression on left-hand side without () // With templateHead -"hello " + (Math.pow(-t1, t2) - t1); -"hello " + (Math.pow(-++t1, t2) - t1); -"hello " + (Math.pow(-t1++, t2) - t1); -"hello " + Math.pow(!t1, Math.pow(t2, --t1)); -"hello " + Math.pow(typeof t1, Math.pow(t2, t1)); -"hello " + (1 + Math.pow(typeof t1, Math.pow(t2, t1))); -"hello " + (Math.pow(-t1, t2) - t1) + (Math.pow(-t1, t2) - t1); -"hello " + (Math.pow(-++t1, t2) - t1) + (Math.pow(-++t1, t2) - t1); -"hello " + (Math.pow(-t1++, t2) - t1) + (Math.pow(-t1++, t2) - t1); -"hello " + Math.pow(!t1, Math.pow(t2, --t1)) + Math.pow(!t1, Math.pow(t2, --t1)); -"hello " + Math.pow(typeof t1, Math.pow(t2, t1)) + Math.pow(typeof t1, Math.pow(t2, t1)); -"hello " + (1 + Math.pow(typeof t1, Math.pow(t2, t1))) + (1 + Math.pow(typeof t1, Math.pow(t2, t1))); -"hello " + (Math.pow(-t1, t2) - t1) + " hello world " + (Math.pow(-t1, t2) - t1); -"hello " + (Math.pow(-++t1, t2) - t1) + " hello world " + (Math.pow(-++t1, t2) - t1); -"hello " + (Math.pow(-t1++, t2) - t1) + " hello world " + (Math.pow(-t1++, t2) - t1); -"hello " + Math.pow(!t1, Math.pow(t2, --t1)) + " hello world " + Math.pow(!t1, Math.pow(t2, --t1)); -"hello " + Math.pow(typeof t1, Math.pow(t2, t1)) + " hello world " + Math.pow(typeof t1, Math.pow(t2, t1)); -"hello " + (1 + Math.pow(typeof t1, Math.pow(t2, t1))) + " hello world " + (1 + Math.pow(typeof t1, Math.pow(t2, t1))); +"hello ".concat(Math.pow(-t1, t2) - t1); +"hello ".concat(Math.pow(-++t1, t2) - t1); +"hello ".concat(Math.pow(-t1++, t2) - t1); +"hello ".concat(Math.pow(!t1, Math.pow(t2, --t1))); +"hello ".concat(Math.pow(typeof t1, Math.pow(t2, t1))); +"hello ".concat(1 + Math.pow(typeof t1, Math.pow(t2, t1))); +"hello ".concat(Math.pow(-t1, t2) - t1).concat(Math.pow(-t1, t2) - t1); +"hello ".concat(Math.pow(-++t1, t2) - t1).concat(Math.pow(-++t1, t2) - t1); +"hello ".concat(Math.pow(-t1++, t2) - t1).concat(Math.pow(-t1++, t2) - t1); +"hello ".concat(Math.pow(!t1, Math.pow(t2, --t1))).concat(Math.pow(!t1, Math.pow(t2, --t1))); +"hello ".concat(Math.pow(typeof t1, Math.pow(t2, t1))).concat(Math.pow(typeof t1, Math.pow(t2, t1))); +"hello ".concat(1 + Math.pow(typeof t1, Math.pow(t2, t1))).concat(1 + Math.pow(typeof t1, Math.pow(t2, t1))); +"hello ".concat(Math.pow(-t1, t2) - t1, " hello world ").concat(Math.pow(-t1, t2) - t1); +"hello ".concat(Math.pow(-++t1, t2) - t1, " hello world ").concat(Math.pow(-++t1, t2) - t1); +"hello ".concat(Math.pow(-t1++, t2) - t1, " hello world ").concat(Math.pow(-t1++, t2) - t1); +"hello ".concat(Math.pow(!t1, Math.pow(t2, --t1)), " hello world ").concat(Math.pow(!t1, Math.pow(t2, --t1))); +"hello ".concat(Math.pow(typeof t1, Math.pow(t2, t1)), " hello world ").concat(Math.pow(typeof t1, Math.pow(t2, t1))); +"hello ".concat(1 + Math.pow(typeof t1, Math.pow(t2, t1)), " hello world ").concat(1 + Math.pow(typeof t1, Math.pow(t2, t1))); diff --git a/tests/baselines/reference/exponentiationOperatorInTemplateStringWithSyntaxError3.js b/tests/baselines/reference/exponentiationOperatorInTemplateStringWithSyntaxError3.js index bb203db9144..0324a2124b2 100644 --- a/tests/baselines/reference/exponentiationOperatorInTemplateStringWithSyntaxError3.js +++ b/tests/baselines/reference/exponentiationOperatorInTemplateStringWithSyntaxError3.js @@ -32,21 +32,21 @@ var t2 = 10; var s; // Error: early syntax error using ES7 SimpleUnaryExpression on left-hand side without () // With TemplateTail -Math.pow(-t1, t2) - t1 + " world"; -Math.pow(-++t1, t2) - t1 + " world"; -Math.pow(-t1++, t2) - t1 + " world"; -Math.pow(!t1, Math.pow(t2, --t1)) + " world"; -Math.pow(typeof t1, Math.pow(t2, t1)) + " world"; -1 + Math.pow(typeof t1, Math.pow(t2, t1)) + " world"; -"" + (Math.pow(-t1, t2) - t1) + (Math.pow(-t1, t2) - t1) + " world"; -"" + (Math.pow(-++t1, t2) - t1) + (Math.pow(-++t1, t2) - t1) + " world"; -"" + (Math.pow(-t1++, t2) - t1) + (Math.pow(-t1++, t2) - t1) + " world"; -"" + Math.pow(!t1, Math.pow(t2, --t1)) + Math.pow(!t1, Math.pow(t2, --t1)) + " world"; -"" + Math.pow(typeof t1, Math.pow(t2, t1)) + Math.pow(typeof t1, Math.pow(t2, t1)) + " world"; -"" + (1 + Math.pow(typeof t1, Math.pow(t2, t1))) + (1 + Math.pow(typeof t1, Math.pow(t2, t1))) + " world"; -Math.pow(-t1, t2) - t1 + " hello world " + (Math.pow(-t1, t2) - t1) + " !!"; -Math.pow(-++t1, t2) - t1 + " hello world " + (Math.pow(-++t1, t2) - t1) + " !!"; -Math.pow(-t1++, t2) - t1 + " hello world " + (Math.pow(-t1++, t2) - t1) + " !!"; -Math.pow(!t1, Math.pow(t2, --t1)) + " hello world " + Math.pow(!t1, Math.pow(t2, --t1)) + " !!"; -Math.pow(typeof t1, Math.pow(t2, t1)) + " hello world " + Math.pow(typeof t1, Math.pow(t2, t1)) + " !!"; -1 + Math.pow(typeof t1, Math.pow(t2, t1)) + " hello world " + (1 + Math.pow(typeof t1, Math.pow(t2, t1))) + " !!"; +"".concat(Math.pow(-t1, t2) - t1, " world"); +"".concat(Math.pow(-++t1, t2) - t1, " world"); +"".concat(Math.pow(-t1++, t2) - t1, " world"); +"".concat(Math.pow(!t1, Math.pow(t2, --t1)), " world"); +"".concat(Math.pow(typeof t1, Math.pow(t2, t1)), " world"); +"".concat(1 + Math.pow(typeof t1, Math.pow(t2, t1)), " world"); +"".concat(Math.pow(-t1, t2) - t1).concat(Math.pow(-t1, t2) - t1, " world"); +"".concat(Math.pow(-++t1, t2) - t1).concat(Math.pow(-++t1, t2) - t1, " world"); +"".concat(Math.pow(-t1++, t2) - t1).concat(Math.pow(-t1++, t2) - t1, " world"); +"".concat(Math.pow(!t1, Math.pow(t2, --t1))).concat(Math.pow(!t1, Math.pow(t2, --t1)), " world"); +"".concat(Math.pow(typeof t1, Math.pow(t2, t1))).concat(Math.pow(typeof t1, Math.pow(t2, t1)), " world"); +"".concat(1 + Math.pow(typeof t1, Math.pow(t2, t1))).concat(1 + Math.pow(typeof t1, Math.pow(t2, t1)), " world"); +"".concat(Math.pow(-t1, t2) - t1, " hello world ").concat(Math.pow(-t1, t2) - t1, " !!"); +"".concat(Math.pow(-++t1, t2) - t1, " hello world ").concat(Math.pow(-++t1, t2) - t1, " !!"); +"".concat(Math.pow(-t1++, t2) - t1, " hello world ").concat(Math.pow(-t1++, t2) - t1, " !!"); +"".concat(Math.pow(!t1, Math.pow(t2, --t1)), " hello world ").concat(Math.pow(!t1, Math.pow(t2, --t1)), " !!"); +"".concat(Math.pow(typeof t1, Math.pow(t2, t1)), " hello world ").concat(Math.pow(typeof t1, Math.pow(t2, t1)), " !!"); +"".concat(1 + Math.pow(typeof t1, Math.pow(t2, t1)), " hello world ").concat(1 + Math.pow(typeof t1, Math.pow(t2, t1)), " !!"); diff --git a/tests/baselines/reference/exponentiationOperatorWithTemplateStringInvalid.js b/tests/baselines/reference/exponentiationOperatorWithTemplateStringInvalid.js index 530a106d09d..0bf4330b428 100644 --- a/tests/baselines/reference/exponentiationOperatorWithTemplateStringInvalid.js +++ b/tests/baselines/reference/exponentiationOperatorWithTemplateStringInvalid.js @@ -18,16 +18,16 @@ k **= `2${ 3 }4`; //// [exponentiationOperatorWithTemplateStringInvalid.js] -var a = Math.pow(1, "" + 3); -var b = Math.pow(1, "2" + 3); -var c = Math.pow(1, 3 + "4"); -var d = Math.pow(1, "2" + 3 + "4"); -var e = Math.pow("" + 3, 5); -var f = Math.pow("2" + 3, 5); -var g = Math.pow(3 + "4", 5); -var h = Math.pow("2" + 3 + "4", 5); +var a = Math.pow(1, "".concat(3)); +var b = Math.pow(1, "2".concat(3)); +var c = Math.pow(1, "".concat(3, "4")); +var d = Math.pow(1, "2".concat(3, "4")); +var e = Math.pow("".concat(3), 5); +var f = Math.pow("2".concat(3), 5); +var g = Math.pow("".concat(3, "4"), 5); +var h = Math.pow("2".concat(3, "4"), 5); var k = 10; -k = Math.pow(k, "" + 3); -k = Math.pow(k, "2" + 3); -k = Math.pow(k, "2" + 3 + "4"); -k = Math.pow(k, "2" + 3 + "4"); +k = Math.pow(k, "".concat(3)); +k = Math.pow(k, "2".concat(3)); +k = Math.pow(k, "2".concat(3, "4")); +k = Math.pow(k, "2".concat(3, "4")); diff --git a/tests/baselines/reference/invalidTaggedTemplateEscapeSequences(target=es5).js b/tests/baselines/reference/invalidTaggedTemplateEscapeSequences(target=es5).js index 6e0c375edb2..b980ba0304d 100644 --- a/tests/baselines/reference/invalidTaggedTemplateEscapeSequences(target=es5).js +++ b/tests/baselines/reference/invalidTaggedTemplateEscapeSequences(target=es5).js @@ -40,7 +40,7 @@ function tag(str) { var a = tag(__makeTemplateObject(["123"], ["123"])); var b = tag(__makeTemplateObject(["123 ", ""], ["123 ", ""]), 100); var x = tag(__makeTemplateObject([void 0, void 0, " wonderful ", void 0], ["\\u{hello} ", " \\xtraordinary ", " wonderful ", " \\uworld"]), 100, 200, 300); -var y = "hello} " + 100 + " traordinary " + 200 + " wonderful " + 300 + " world"; // should error with NoSubstitutionTemplate +var y = "hello} ".concat(100, " traordinary ").concat(200, " wonderful ").concat(300, " world"); // should error with NoSubstitutionTemplate var z = tag(__makeTemplateObject([void 0], ["\\u{hello} \\xtraordinary wonderful \\uworld"])); // should work with Tagged NoSubstitutionTemplate var a1 = tag(__makeTemplateObject(["", "\0"], ["", "\\0"]), 100); // \0 var a2 = tag(__makeTemplateObject(["", void 0], ["", "\\00"]), 100); // \\00 diff --git a/tests/baselines/reference/jsDeclarationsExportedClassAliases.js b/tests/baselines/reference/jsDeclarationsExportedClassAliases.js index aaf4bf08165..3a79339339c 100644 --- a/tests/baselines/reference/jsDeclarationsExportedClassAliases.js +++ b/tests/baselines/reference/jsDeclarationsExportedClassAliases.js @@ -38,7 +38,7 @@ var __extends = (this && this.__extends) || (function () { var FancyError = /** @class */ (function (_super) { __extends(FancyError, _super); function FancyError(status) { - return _super.call(this, "error with status " + status) || this; + return _super.call(this, "error with status ".concat(status)) || this; } return FancyError; }(Error)); diff --git a/tests/baselines/reference/noImplicitSymbolToString.js b/tests/baselines/reference/noImplicitSymbolToString.js index 836d5abe8a9..fed276b8a73 100644 --- a/tests/baselines/reference/noImplicitSymbolToString.js +++ b/tests/baselines/reference/noImplicitSymbolToString.js @@ -18,9 +18,9 @@ const templateStrUnion = `union with number ${symbolUnionNumber} and union with // Fix #19666 var symbol; var str = "hello "; -var templateStr = "hello " + symbol; +var templateStr = "hello ".concat(symbol); var appendStr = "hello " + symbol; str += symbol; var symbolUnionNumber; var symbolUnionString; -var templateStrUnion = "union with number " + symbolUnionNumber + " and union with string " + symbolUnionString; +var templateStrUnion = "union with number ".concat(symbolUnionNumber, " and union with string ").concat(symbolUnionString); diff --git a/tests/baselines/reference/recursiveTypeReferences1.js b/tests/baselines/reference/recursiveTypeReferences1.js index 30e09450be4..744c9c57b5c 100644 --- a/tests/baselines/reference/recursiveTypeReferences1.js +++ b/tests/baselines/reference/recursiveTypeReferences1.js @@ -191,7 +191,7 @@ function parse(node, index) { var el = _a[0], children = _a[1]; var idx = __spreadArray(__spreadArray([], index, true), [i + 1], false); return html('li', [ - html('a', { href: "#" + el.id, rel: 'noopener', 'data-index': idx.join('.') }, el.textContent), + html('a', { href: "#".concat(el.id), rel: 'noopener', 'data-index': idx.join('.') }, el.textContent), children.length > 0 ? parse(children, idx) : frag() ]); })); diff --git a/tests/baselines/reference/stringLiteralTypesWithTemplateStrings02.js b/tests/baselines/reference/stringLiteralTypesWithTemplateStrings02.js index 8d675eeb9c4..8a34efbb267 100644 --- a/tests/baselines/reference/stringLiteralTypesWithTemplateStrings02.js +++ b/tests/baselines/reference/stringLiteralTypesWithTemplateStrings02.js @@ -5,7 +5,7 @@ let de_NEWLINE_f: "DE\nF" = `DE${"\n"}F`; //// [stringLiteralTypesWithTemplateStrings02.js] var abc = "AB\nC"; -var de_NEWLINE_f = "DE" + "\n" + "F"; +var de_NEWLINE_f = "DE".concat("\n", "F"); //// [stringLiteralTypesWithTemplateStrings02.d.ts] diff --git a/tests/baselines/reference/taggedTemplateStringsPlainCharactersThatArePartsOfEscapes02.js b/tests/baselines/reference/taggedTemplateStringsPlainCharactersThatArePartsOfEscapes02.js index 159181febc1..124dd7b381b 100644 --- a/tests/baselines/reference/taggedTemplateStringsPlainCharactersThatArePartsOfEscapes02.js +++ b/tests/baselines/reference/taggedTemplateStringsPlainCharactersThatArePartsOfEscapes02.js @@ -2,4 +2,4 @@ `0${ " " }1${ " " }2${ " " }3${ " " }4${ " " }5${ " " }6${ " " }7${ " " }8${ " " }9${ " " }10${ " " }11${ " " }12${ " " }13${ " " }14${ " " }15${ " " }16${ " " }17${ " " }18${ " " }19${ " " }20${ " " }2028${ " " }2029${ " " }0085${ " " }t${ " " }v${ " " }f${ " " }b${ " " }r${ " " }n` //// [taggedTemplateStringsPlainCharactersThatArePartsOfEscapes02.js] -"0" + " " + "1" + " " + "2" + " " + "3" + " " + "4" + " " + "5" + " " + "6" + " " + "7" + " " + "8" + " " + "9" + " " + "10" + " " + "11" + " " + "12" + " " + "13" + " " + "14" + " " + "15" + " " + "16" + " " + "17" + " " + "18" + " " + "19" + " " + "20" + " " + "2028" + " " + "2029" + " " + "0085" + " " + "t" + " " + "v" + " " + "f" + " " + "b" + " " + "r" + " " + "n"; +"0".concat(" ", "1").concat(" ", "2").concat(" ", "3").concat(" ", "4").concat(" ", "5").concat(" ", "6").concat(" ", "7").concat(" ", "8").concat(" ", "9").concat(" ", "10").concat(" ", "11").concat(" ", "12").concat(" ", "13").concat(" ", "14").concat(" ", "15").concat(" ", "16").concat(" ", "17").concat(" ", "18").concat(" ", "19").concat(" ", "20").concat(" ", "2028").concat(" ", "2029").concat(" ", "0085").concat(" ", "t").concat(" ", "v").concat(" ", "f").concat(" ", "b").concat(" ", "r").concat(" ", "n"); diff --git a/tests/baselines/reference/taggedTemplateStringsWithIncompatibleTypedTags.js b/tests/baselines/reference/taggedTemplateStringsWithIncompatibleTypedTags.js index 4e0c70e837a..b90c922e289 100644 --- a/tests/baselines/reference/taggedTemplateStringsWithIncompatibleTypedTags.js +++ b/tests/baselines/reference/taggedTemplateStringsWithIncompatibleTypedTags.js @@ -49,4 +49,4 @@ f(__makeTemplateObject(["abc"], ["abc"]))[0].member(__makeTemplateObject(["abc", f(__makeTemplateObject(["abc", "def", "ghi"], ["abc", "def", "ghi"]), 1, 2)["member"].member(__makeTemplateObject(["abc", "def", "ghi"], ["abc", "def", "ghi"]), 1, 2); f(__makeTemplateObject(["abc", "def", "ghi"], ["abc", "def", "ghi"]), true, true)["member"].member(__makeTemplateObject(["abc", "def", "ghi"], ["abc", "def", "ghi"]), 1, 2); f.thisIsNotATag("abc"); -f.thisIsNotATag("abc" + 1 + "def" + 2 + "ghi"); +f.thisIsNotATag("abc".concat(1, "def").concat(2, "ghi")); diff --git a/tests/baselines/reference/taggedTemplateStringsWithTagsTypedAsAny.js b/tests/baselines/reference/taggedTemplateStringsWithTagsTypedAsAny.js index af9fd2c9d44..b374e406ce2 100644 --- a/tests/baselines/reference/taggedTemplateStringsWithTagsTypedAsAny.js +++ b/tests/baselines/reference/taggedTemplateStringsWithTagsTypedAsAny.js @@ -42,4 +42,4 @@ f(__makeTemplateObject(["abc", "def", "ghi"], ["abc", "def", "ghi"]), 1, 2)["mem f(__makeTemplateObject(["abc"], ["abc"]))["member"].someOtherTag(__makeTemplateObject(["abc", "def", "ghi"], ["abc", "def", "ghi"]), 1, 2); f(__makeTemplateObject(["abc", "def", "ghi"], ["abc", "def", "ghi"]), 1, 2)["member"].someOtherTag(__makeTemplateObject(["abc", "def", "ghi"], ["abc", "def", "ghi"]), 1, 2); f.thisIsNotATag("abc"); -f.thisIsNotATag("abc" + 1 + "def" + 2 + "ghi"); +f.thisIsNotATag("abc".concat(1, "def").concat(2, "ghi")); diff --git a/tests/baselines/reference/taggedTemplateStringsWithTypedTags.js b/tests/baselines/reference/taggedTemplateStringsWithTypedTags.js index c6509f1ca86..af262aa1ac1 100644 --- a/tests/baselines/reference/taggedTemplateStringsWithTypedTags.js +++ b/tests/baselines/reference/taggedTemplateStringsWithTypedTags.js @@ -46,4 +46,4 @@ f(__makeTemplateObject(["abc", "def", "ghi"], ["abc", "def", "ghi"]), 1, 2)["mem f(__makeTemplateObject(["abc"], ["abc"]))[0].member(__makeTemplateObject(["abc", "def", "ghi"], ["abc", "def", "ghi"]), 1, 2); f(__makeTemplateObject(["abc", "def", "ghi"], ["abc", "def", "ghi"]), 1, 2)["member"].member(__makeTemplateObject(["abc", "def", "ghi"], ["abc", "def", "ghi"]), 1, 2); f.thisIsNotATag("abc"); -f.thisIsNotATag("abc" + 1 + "def" + 2 + "ghi"); +f.thisIsNotATag("abc".concat(1, "def").concat(2, "ghi")); diff --git a/tests/baselines/reference/templateLiteralTypes1.js b/tests/baselines/reference/templateLiteralTypes1.js index 5f93208af2f..b8f7d0f4066 100644 --- a/tests/baselines/reference/templateLiteralTypes1.js +++ b/tests/baselines/reference/templateLiteralTypes1.js @@ -240,7 +240,7 @@ let make = getProp2(obj2, 'cars.1.make'); // 'Trabant' //// [templateLiteralTypes1.js] "use strict"; // Template types example from #12754 -var createScopedActionType = function (scope) { return function (type) { return scope + "/" + type; }; }; +var createScopedActionType = function (scope) { return function (type) { return "".concat(scope, "/").concat(type); }; }; var createActionInMyScope = createScopedActionType("MyScope"); // (type: T) => `MyScope/${T}` var MY_ACTION = createActionInMyScope("MY_ACTION"); // 'MyScope/MY_ACTION' // Assignability diff --git a/tests/baselines/reference/templateLiteralTypes2.js b/tests/baselines/reference/templateLiteralTypes2.js index 37c101be269..1b31f3a00ee 100644 --- a/tests/baselines/reference/templateLiteralTypes2.js +++ b/tests/baselines/reference/templateLiteralTypes2.js @@ -122,33 +122,33 @@ C2(`rotate(${interpolatedStyle.rotate}dig)`); //// [templateLiteralTypes2.js] "use strict"; function ft1(s, n, u, t) { - var c1 = "abc" + s; // `abc${string}` - var c2 = "abc" + n; // `abc${number}` - var c3 = "abc" + u; // "abcfoo" | "abcbar" | "abcbaz" - var c4 = "abc" + t; // `abc${T} - var d1 = "abc" + s; - var d2 = "abc" + n; - var d3 = "abc" + u; - var d4 = "abc" + t; + var c1 = "abc".concat(s); // `abc${string}` + var c2 = "abc".concat(n); // `abc${number}` + var c3 = "abc".concat(u); // "abcfoo" | "abcbar" | "abcbaz" + var c4 = "abc".concat(t); // `abc${T} + var d1 = "abc".concat(s); + var d2 = "abc".concat(n); + var d3 = "abc".concat(u); + var d4 = "abc".concat(t); } function ft2(s) { - return "abc" + s; + return "abc".concat(s); } function ft10(s) { - var c1 = "abc" + s; // Widening type `abc${string}` + var c1 = "abc".concat(s); // Widening type `abc${string}` var v1 = c1; // Type string var c2 = c1; // Widening type `abc${string}` var v2 = c2; // Type string - var c3 = "abc" + s; + var c3 = "abc".concat(s); var v3 = c3; // Type `abc${string}` var c4 = c1; // Type `abc${string}` var v4 = c4; // Type `abc${string}` } function ft11(s, cond) { - var c1 = cond ? "foo" + s : "bar" + s; // widening `foo${string}` | widening `bar${string}` + var c1 = cond ? "foo".concat(s) : "bar".concat(s); // widening `foo${string}` | widening `bar${string}` var c2 = c1; // `foo${string}` | `bar${string}` var c3 = cond ? c1 : c2; // `foo${string}` | `bar${string}` - var c4 = cond ? c3 : "baz" + s; // `foo${string}` | `bar${string}` | widening `baz${string}` + var c4 = cond ? c3 : "baz".concat(s); // `foo${string}` | `bar${string}` | widening `baz${string}` var c5 = c4; // `foo${string}` | `bar${string}` | `baz${string}` var v1 = c1; // string var v2 = c2; // `foo${string}` | `bar${string}` @@ -157,22 +157,22 @@ function ft11(s, cond) { var v5 = c5; // `foo${string}` | `bar${string}` | `baz${string}` } function ft12(s) { - var c1 = "foo" + s; + var c1 = "foo".concat(s); var v1 = c1; - var c2 = "foo" + s; + var c2 = "foo".concat(s); var v2 = c2; - var c3 = "foo" + s; + var c3 = "foo".concat(s); var v3 = c3; - var c4 = "foo" + s; + var c4 = "foo".concat(s); var v4 = c4; - var c5 = "foo" + s; + var c5 = "foo".concat(s); var v5 = c5; } function ft13(s, cond) { - var x1 = widening("foo" + s); - var x2 = widening(cond ? 'a' : "foo" + s); - var y1 = nonWidening("foo" + s); - var y2 = nonWidening(cond ? 'a' : "foo" + s); + var x1 = widening("foo".concat(s)); + var x2 = widening(cond ? 'a' : "foo".concat(s)); + var y1 = nonWidening("foo".concat(s)); + var y2 = nonWidening(cond ? 'a' : "foo".concat(s)); } function ft14(t) { var x1 = t; @@ -182,28 +182,28 @@ function ft14(t) { var x6 = t; } function ft20(s) { - var x1 = g1("xyz-" + s); // string - var x2 = g2("xyz-" + s); // `xyz-${string}` + var x1 = g1("xyz-".concat(s)); // string + var x2 = g2("xyz-".concat(s)); // `xyz-${string}` } var t1 = takesLiteral("foo.bar.baz"); // "baz" var id2 = "foo.bar.baz"; var t2 = takesLiteral(id2); // "baz" -var t3 = takesLiteral("foo.bar." + someString); // string -var id4 = "foo.bar." + someString; +var t3 = takesLiteral("foo.bar.".concat(someString)); // string +var id4 = "foo.bar.".concat(someString); var t4 = takesLiteral(id4); // string -var t5 = takesLiteral("foo.bar." + someUnion); // "abc" | "def" | "ghi" +var t5 = takesLiteral("foo.bar.".concat(someUnion)); // "abc" | "def" | "ghi" // Repro from #41732 var pixelValue = 22; var pixelString = "22px"; -var pixelStringWithTemplate = pixelValue + "px"; +var pixelStringWithTemplate = "".concat(pixelValue, "px"); // Repro from #43143 function getCardTitle(title) { - return "test-" + title; + return "test-".concat(title); } // Repro from #43424 var interpolatedStyle = { rotate: 12 }; function C2(transform) { return 12; } -C2("rotate(" + interpolatedStyle.rotate + "dig)"); +C2("rotate(".concat(interpolatedStyle.rotate, "dig)")); //// [templateLiteralTypes2.d.ts] diff --git a/tests/baselines/reference/templateLiteralTypes3.js b/tests/baselines/reference/templateLiteralTypes3.js index 7122f13da6d..fc2df68a400 100644 --- a/tests/baselines/reference/templateLiteralTypes3.js +++ b/tests/baselines/reference/templateLiteralTypes3.js @@ -179,11 +179,11 @@ function f1(s, n, b, t) { var x1 = foo1('hello'); // Error var x2 = foo1('*hello*'); var x3 = foo1('**hello**'); - var x4 = foo1("*" + s + "*"); - var x5 = foo1("*" + n + "*"); - var x6 = foo1("*" + b + "*"); - var x7 = foo1("*" + t + "*"); - var x8 = foo1("**" + s + "**"); + var x4 = foo1("*".concat(s, "*")); + var x5 = foo1("*".concat(n, "*")); + var x6 = foo1("*".concat(b, "*")); + var x7 = foo1("*".concat(t, "*")); + var x8 = foo1("**".concat(s, "**")); } function f2() { var x; @@ -201,27 +201,27 @@ function f3(s, n, b, t) { x = 'hello'; // Error x = '*hello*'; x = '**hello**'; - x = "*" + s + "*"; - x = "*" + n + "*"; - x = "*" + b + "*"; - x = "*" + t + "*"; - x = "**" + s + "**"; + x = "*".concat(s, "*"); + x = "*".concat(n, "*"); + x = "*".concat(b, "*"); + x = "*".concat(t, "*"); + x = "**".concat(s, "**"); } function f4(s, n, b, t) { var x; x = '123'; // Error x = '*123*'; x = '**123**'; // Error - x = "*" + s + "*"; // Error - x = "*" + n + "*"; - x = "*" + b + "*"; // Error - x = "*" + t + "*"; + x = "*".concat(s, "*"); // Error + x = "*".concat(n, "*"); + x = "*".concat(b, "*"); // Error + x = "*".concat(t, "*"); } var value1 = "abc"; -var templated1 = value1 + " abc"; +var templated1 = "".concat(value1, " abc"); // Type '`${string} abc`' is not assignable to type '`${string} ${string}`'. var value2 = "abc"; -var templated2 = value2 + " abc"; +var templated2 = "".concat(value2, " abc"); chain("a"); // Repro from #46125 function ff1(x, y, z) { diff --git a/tests/baselines/reference/templateLiteralsInTypes.js b/tests/baselines/reference/templateLiteralsInTypes.js index d1ff18694fd..462b08811ca 100644 --- a/tests/baselines/reference/templateLiteralsInTypes.js +++ b/tests/baselines/reference/templateLiteralsInTypes.js @@ -6,7 +6,7 @@ f("x").foo; //// [templateLiteralsInTypes.js] "use strict"; -var f = function (hdr, val) { return hdr + ":\t" + val + "\r\n"; }; +var f = function (hdr, val) { return "".concat(hdr, ":\t").concat(val, "\r\n"); }; f("x").foo; diff --git a/tests/baselines/reference/templateLiteralsSourceMap.js b/tests/baselines/reference/templateLiteralsSourceMap.js new file mode 100644 index 00000000000..3af8719c510 --- /dev/null +++ b/tests/baselines/reference/templateLiteralsSourceMap.js @@ -0,0 +1,7 @@ +//// [templateLiteralsSourceMap.ts] +const s = `a${0}b${1}c${2}`; + + +//// [templateLiteralsSourceMap.js] +var s = "a".concat(0, "b").concat(1, "c").concat(2); +//# sourceMappingURL=templateLiteralsSourceMap.js.map \ No newline at end of file diff --git a/tests/baselines/reference/templateLiteralsSourceMap.js.map b/tests/baselines/reference/templateLiteralsSourceMap.js.map new file mode 100644 index 00000000000..aad02400df6 --- /dev/null +++ b/tests/baselines/reference/templateLiteralsSourceMap.js.map @@ -0,0 +1,3 @@ +//// [templateLiteralsSourceMap.js.map] +{"version":3,"file":"templateLiteralsSourceMap.js","sourceRoot":"","sources":["templateLiteralsSourceMap.ts"],"names":[],"mappings":"AAAA,IAAM,CAAC,GAAG,WAAI,CAAC,cAAI,CAAC,cAAI,CAAC,CAAE,CAAC"} +//// https://sokra.github.io/source-map-visualization#base64,dmFyIHMgPSAiYSIuY29uY2F0KDAsICJiIikuY29uY2F0KDEsICJjIikuY29uY2F0KDIpOw0KLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVtcGxhdGVMaXRlcmFsc1NvdXJjZU1hcC5qcy5tYXA=,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVtcGxhdGVMaXRlcmFsc1NvdXJjZU1hcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlbXBsYXRlTGl0ZXJhbHNTb3VyY2VNYXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsSUFBTSxDQUFDLEdBQUcsV0FBSSxDQUFDLGNBQUksQ0FBQyxjQUFJLENBQUMsQ0FBRSxDQUFDIn0=,Y29uc3QgcyA9IGBhJHswfWIkezF9YyR7Mn1gOwo= diff --git a/tests/baselines/reference/templateLiteralsSourceMap.sourcemap.txt b/tests/baselines/reference/templateLiteralsSourceMap.sourcemap.txt new file mode 100644 index 00000000000..fd888d37340 --- /dev/null +++ b/tests/baselines/reference/templateLiteralsSourceMap.sourcemap.txt @@ -0,0 +1,49 @@ +=================================================================== +JsFile: templateLiteralsSourceMap.js +mapUrl: templateLiteralsSourceMap.js.map +sourceRoot: +sources: templateLiteralsSourceMap.ts +=================================================================== +------------------------------------------------------------------- +emittedFile:tests/cases/compiler/templateLiteralsSourceMap.js +sourceFile:templateLiteralsSourceMap.ts +------------------------------------------------------------------- +>>>var s = "a".concat(0, "b").concat(1, "c").concat(2); +1 > +2 >^^^^ +3 > ^ +4 > ^^^ +5 > ^^^^^^^^^^^ +6 > ^ +7 > ^^^^^^^^^^^^^^ +8 > ^ +9 > ^^^^^^^^^^^^^^ +10> ^ +11> ^ +12> ^ +1 > +2 >const +3 > s +4 > = +5 > `a${ +6 > 0 +7 > }b${ +8 > 1 +9 > }c${ +10> 2 +11> }` +12> ; +1 >Emitted(1, 1) Source(1, 1) + SourceIndex(0) +2 >Emitted(1, 5) Source(1, 7) + SourceIndex(0) +3 >Emitted(1, 6) Source(1, 8) + SourceIndex(0) +4 >Emitted(1, 9) Source(1, 11) + SourceIndex(0) +5 >Emitted(1, 20) Source(1, 15) + SourceIndex(0) +6 >Emitted(1, 21) Source(1, 16) + SourceIndex(0) +7 >Emitted(1, 35) Source(1, 20) + SourceIndex(0) +8 >Emitted(1, 36) Source(1, 21) + SourceIndex(0) +9 >Emitted(1, 50) Source(1, 25) + SourceIndex(0) +10>Emitted(1, 51) Source(1, 26) + SourceIndex(0) +11>Emitted(1, 52) Source(1, 28) + SourceIndex(0) +12>Emitted(1, 53) Source(1, 29) + SourceIndex(0) +--- +>>>//# sourceMappingURL=templateLiteralsSourceMap.js.map \ No newline at end of file diff --git a/tests/baselines/reference/templateLiteralsSourceMap.symbols b/tests/baselines/reference/templateLiteralsSourceMap.symbols new file mode 100644 index 00000000000..0c0205fed3a --- /dev/null +++ b/tests/baselines/reference/templateLiteralsSourceMap.symbols @@ -0,0 +1,4 @@ +=== tests/cases/compiler/templateLiteralsSourceMap.ts === +const s = `a${0}b${1}c${2}`; +>s : Symbol(s, Decl(templateLiteralsSourceMap.ts, 0, 5)) + diff --git a/tests/baselines/reference/templateLiteralsSourceMap.types b/tests/baselines/reference/templateLiteralsSourceMap.types new file mode 100644 index 00000000000..4233343cbc8 --- /dev/null +++ b/tests/baselines/reference/templateLiteralsSourceMap.types @@ -0,0 +1,8 @@ +=== tests/cases/compiler/templateLiteralsSourceMap.ts === +const s = `a${0}b${1}c${2}`; +>s : string +>`a${0}b${1}c${2}` : string +>0 : 0 +>1 : 1 +>2 : 2 + diff --git a/tests/baselines/reference/templateStringBinaryOperations.js b/tests/baselines/reference/templateStringBinaryOperations.js index 74093775b98..035f54fead0 100644 --- a/tests/baselines/reference/templateStringBinaryOperations.js +++ b/tests/baselines/reference/templateStringBinaryOperations.js @@ -53,51 +53,51 @@ var l4 = 1 + `2${ 3 & 4 }5` + 6; //// [templateStringBinaryOperations.js] -var a = 1 + ("" + 3); -var b = 1 + ("2" + 3); -var c = 1 + (3 + "4"); -var d = 1 + ("2" + 3 + "4"); -var e = "" + 3 + 5; -var f = "2" + 3 + 5; -var g = 3 + "4" + 5; -var h = "2" + 3 + "4" + 5; -var i = 1 + ("" + 3) + 5; -var j = 1 + ("2" + 3) + 5; -var k = 1 + (3 + "4") + 5; -var l = 1 + ("2" + 3 + "4") + 5; -var a2 = 1 + ("" + (3 - 4)); -var b2 = 1 + ("2" + (3 - 4)); -var c2 = 1 + (3 - 4 + "5"); -var d2 = 1 + ("2" + (3 - 4) + "5"); -var e2 = "" + (3 - 4) + 6; -var f2 = "2" + (3 - 4) + 6; -var g2 = 3 - 4 + "5" + 6; -var h2 = "2" + (3 - 4) + "5" + 6; -var i2 = 1 + ("" + (3 - 4)) + 6; -var j2 = 1 + ("2" + (3 - 4)) + 6; -var k2 = 1 + (3 - 4 + "5") + 6; -var l2 = 1 + ("2" + (3 - 4) + "5") + 6; -var a3 = 1 + ("" + 3 * 4); -var b3 = 1 + ("2" + 3 * 4); -var c3 = 1 + (3 * 4 + "5"); -var d3 = 1 + ("2" + 3 * 4 + "5"); -var e3 = "" + 3 * 4 + 6; -var f3 = "2" + 3 * 4 + 6; -var g3 = 3 * 4 + "5" + 6; -var h3 = "2" + 3 * 4 + "5" + 6; -var i3 = 1 + ("" + 3 * 4) + 6; -var j3 = 1 + ("2" + 3 * 4) + 6; -var k3 = 1 + (3 * 4 + "5") + 6; -var l3 = 1 + ("2" + 3 * 4 + "5") + 6; -var a4 = 1 + ("" + (3 & 4)); -var b4 = 1 + ("2" + (3 & 4)); -var c4 = 1 + ((3 & 4) + "5"); -var d4 = 1 + ("2" + (3 & 4) + "5"); -var e4 = "" + (3 & 4) + 6; -var f4 = "2" + (3 & 4) + 6; -var g4 = (3 & 4) + "5" + 6; -var h4 = "2" + (3 & 4) + "5" + 6; -var i4 = 1 + ("" + (3 & 4)) + 6; -var j4 = 1 + ("2" + (3 & 4)) + 6; -var k4 = 1 + ((3 & 4) + "5") + 6; -var l4 = 1 + ("2" + (3 & 4) + "5") + 6; +var a = 1 + "".concat(3); +var b = 1 + "2".concat(3); +var c = 1 + "".concat(3, "4"); +var d = 1 + "2".concat(3, "4"); +var e = "".concat(3) + 5; +var f = "2".concat(3) + 5; +var g = "".concat(3, "4") + 5; +var h = "2".concat(3, "4") + 5; +var i = 1 + "".concat(3) + 5; +var j = 1 + "2".concat(3) + 5; +var k = 1 + "".concat(3, "4") + 5; +var l = 1 + "2".concat(3, "4") + 5; +var a2 = 1 + "".concat(3 - 4); +var b2 = 1 + "2".concat(3 - 4); +var c2 = 1 + "".concat(3 - 4, "5"); +var d2 = 1 + "2".concat(3 - 4, "5"); +var e2 = "".concat(3 - 4) + 6; +var f2 = "2".concat(3 - 4) + 6; +var g2 = "".concat(3 - 4, "5") + 6; +var h2 = "2".concat(3 - 4, "5") + 6; +var i2 = 1 + "".concat(3 - 4) + 6; +var j2 = 1 + "2".concat(3 - 4) + 6; +var k2 = 1 + "".concat(3 - 4, "5") + 6; +var l2 = 1 + "2".concat(3 - 4, "5") + 6; +var a3 = 1 + "".concat(3 * 4); +var b3 = 1 + "2".concat(3 * 4); +var c3 = 1 + "".concat(3 * 4, "5"); +var d3 = 1 + "2".concat(3 * 4, "5"); +var e3 = "".concat(3 * 4) + 6; +var f3 = "2".concat(3 * 4) + 6; +var g3 = "".concat(3 * 4, "5") + 6; +var h3 = "2".concat(3 * 4, "5") + 6; +var i3 = 1 + "".concat(3 * 4) + 6; +var j3 = 1 + "2".concat(3 * 4) + 6; +var k3 = 1 + "".concat(3 * 4, "5") + 6; +var l3 = 1 + "2".concat(3 * 4, "5") + 6; +var a4 = 1 + "".concat(3 & 4); +var b4 = 1 + "2".concat(3 & 4); +var c4 = 1 + "".concat(3 & 4, "5"); +var d4 = 1 + "2".concat(3 & 4, "5"); +var e4 = "".concat(3 & 4) + 6; +var f4 = "2".concat(3 & 4) + 6; +var g4 = "".concat(3 & 4, "5") + 6; +var h4 = "2".concat(3 & 4, "5") + 6; +var i4 = 1 + "".concat(3 & 4) + 6; +var j4 = 1 + "2".concat(3 & 4) + 6; +var k4 = 1 + "".concat(3 & 4, "5") + 6; +var l4 = 1 + "2".concat(3 & 4, "5") + 6; diff --git a/tests/baselines/reference/templateStringBinaryOperationsInvalid.js b/tests/baselines/reference/templateStringBinaryOperationsInvalid.js index e6c288f1b54..4fbc6c667d7 100644 --- a/tests/baselines/reference/templateStringBinaryOperationsInvalid.js +++ b/tests/baselines/reference/templateStringBinaryOperationsInvalid.js @@ -109,99 +109,99 @@ var hc = `2${ 3 & 4 }5` & 6; //// [templateStringBinaryOperationsInvalid.js] -var a = 1 - ("" + 3); -var b = 1 - ("2" + 3); -var c = 1 - (3 + "4"); -var d = 1 - ("2" + 3 + "4"); -var e = "" + 3 - 5; -var f = "2" + 3 - 5; -var g = 3 + "4" - 5; -var h = "2" + 3 + "4" - 5; -var a2 = 1 * ("" + 3); -var b2 = 1 * ("2" + 3); -var c2 = 1 * (3 + "4"); -var d2 = 1 * ("2" + 3 + "4"); -var e2 = ("" + 3) * 5; -var f2 = ("2" + 3) * 5; -var g2 = (3 + "4") * 5; -var h2 = ("2" + 3 + "4") * 5; -var a3 = 1 & "" + 3; -var b3 = 1 & "2" + 3; -var c3 = 1 & 3 + "4"; -var d3 = 1 & "2" + 3 + "4"; -var e3 = "" + 3 & 5; -var f3 = "2" + 3 & 5; -var g3 = 3 + "4" & 5; -var h3 = "2" + 3 + "4" & 5; -var a4 = 1 - ("" + (3 - 4)); -var b4 = 1 - ("2" + (3 - 4)); -var c4 = 1 - (3 - 4 + "5"); -var d4 = 1 - ("2" + (3 - 4) + "5"); -var e4 = "" + (3 - 4) - 6; -var f4 = "2" + (3 - 4) - 6; -var g4 = 3 - 4 + "5" - 6; -var h4 = "2" + (3 - 4) + "5" - 6; -var a5 = 1 - ("" + 3 * 4); -var b5 = 1 - ("2" + 3 * 4); -var c5 = 1 - (3 * 4 + "5"); -var d5 = 1 - ("2" + 3 * 4 + "5"); -var e5 = "" + 3 * 4 - 6; -var f5 = "2" + 3 * 4 - 6; -var g5 = 3 * 4 + "5" - 6; -var h5 = "2" + 3 * 4 + "5" - 6; -var a6 = 1 - ("" + (3 & 4)); -var b6 = 1 - ("2" + (3 & 4)); -var c6 = 1 - ((3 & 4) + "5"); -var d6 = 1 - ("2" + (3 & 4) + "5"); -var e6 = "" + (3 & 4) - 6; -var f6 = "2" + (3 & 4) - 6; -var g6 = (3 & 4) + "5" - 6; -var h6 = "2" + (3 & 4) + "5" - 6; -var a7 = 1 * ("" + (3 - 4)); -var b7 = 1 * ("2" + (3 - 4)); -var c7 = 1 * (3 - 4 + "5"); -var d7 = 1 * ("2" + (3 - 4) + "5"); -var e7 = ("" + (3 - 4)) * 6; -var f7 = ("2" + (3 - 4)) * 6; -var g7 = (3 - 4 + "5") * 6; -var h7 = ("2" + (3 - 4) + "5") * 6; -var a8 = 1 * ("" + 3 * 4); -var b8 = 1 * ("2" + 3 * 4); -var c8 = 1 * (3 * 4 + "5"); -var d8 = 1 * ("2" + 3 * 4 + "5"); -var e8 = ("" + 3 * 4) * 6; -var f8 = ("2" + 3 * 4) * 6; -var g8 = (3 * 4 + "5") * 6; -var h8 = ("2" + 3 * 4 + "5") * 6; -var a9 = 1 * ("" + (3 & 4)); -var b9 = 1 * ("2" + (3 & 4)); -var c9 = 1 * ((3 & 4) + "5"); -var d9 = 1 * ("2" + (3 & 4) + "5"); -var e9 = ("" + (3 & 4)) * 6; -var f9 = ("2" + (3 & 4)) * 6; -var g9 = ((3 & 4) + "5") * 6; -var h9 = ("2" + (3 & 4) + "5") * 6; -var aa = 1 & "" + (3 - 4); -var ba = 1 & "2" + (3 - 4); -var ca = 1 & 3 - 4 + "5"; -var da = 1 & "2" + (3 - 4) + "5"; -var ea = "" + (3 - 4) & 6; -var fa = "2" + (3 - 4) & 6; -var ga = 3 - 4 + "5" & 6; -var ha = "2" + (3 - 4) + "5" & 6; -var ab = 1 & "" + 3 * 4; -var bb = 1 & "2" + 3 * 4; -var cb = 1 & 3 * 4 + "5"; -var db = 1 & "2" + 3 * 4 + "5"; -var eb = "" + 3 * 4 & 6; -var fb = "2" + 3 * 4 & 6; -var gb = 3 * 4 + "5" & 6; -var hb = "2" + 3 * 4 + "5" & 6; -var ac = 1 & "" + (3 & 4); -var bc = 1 & "2" + (3 & 4); -var cc = 1 & (3 & 4) + "5"; -var dc = 1 & "2" + (3 & 4) + "5"; -var ec = "" + (3 & 4) & 6; -var fc = "2" + (3 & 4) & 6; -var gc = (3 & 4) + "5" & 6; -var hc = "2" + (3 & 4) + "5" & 6; +var a = 1 - "".concat(3); +var b = 1 - "2".concat(3); +var c = 1 - "".concat(3, "4"); +var d = 1 - "2".concat(3, "4"); +var e = "".concat(3) - 5; +var f = "2".concat(3) - 5; +var g = "".concat(3, "4") - 5; +var h = "2".concat(3, "4") - 5; +var a2 = 1 * "".concat(3); +var b2 = 1 * "2".concat(3); +var c2 = 1 * "".concat(3, "4"); +var d2 = 1 * "2".concat(3, "4"); +var e2 = "".concat(3) * 5; +var f2 = "2".concat(3) * 5; +var g2 = "".concat(3, "4") * 5; +var h2 = "2".concat(3, "4") * 5; +var a3 = 1 & "".concat(3); +var b3 = 1 & "2".concat(3); +var c3 = 1 & "".concat(3, "4"); +var d3 = 1 & "2".concat(3, "4"); +var e3 = "".concat(3) & 5; +var f3 = "2".concat(3) & 5; +var g3 = "".concat(3, "4") & 5; +var h3 = "2".concat(3, "4") & 5; +var a4 = 1 - "".concat(3 - 4); +var b4 = 1 - "2".concat(3 - 4); +var c4 = 1 - "".concat(3 - 4, "5"); +var d4 = 1 - "2".concat(3 - 4, "5"); +var e4 = "".concat(3 - 4) - 6; +var f4 = "2".concat(3 - 4) - 6; +var g4 = "".concat(3 - 4, "5") - 6; +var h4 = "2".concat(3 - 4, "5") - 6; +var a5 = 1 - "".concat(3 * 4); +var b5 = 1 - "2".concat(3 * 4); +var c5 = 1 - "".concat(3 * 4, "5"); +var d5 = 1 - "2".concat(3 * 4, "5"); +var e5 = "".concat(3 * 4) - 6; +var f5 = "2".concat(3 * 4) - 6; +var g5 = "".concat(3 * 4, "5") - 6; +var h5 = "2".concat(3 * 4, "5") - 6; +var a6 = 1 - "".concat(3 & 4); +var b6 = 1 - "2".concat(3 & 4); +var c6 = 1 - "".concat(3 & 4, "5"); +var d6 = 1 - "2".concat(3 & 4, "5"); +var e6 = "".concat(3 & 4) - 6; +var f6 = "2".concat(3 & 4) - 6; +var g6 = "".concat(3 & 4, "5") - 6; +var h6 = "2".concat(3 & 4, "5") - 6; +var a7 = 1 * "".concat(3 - 4); +var b7 = 1 * "2".concat(3 - 4); +var c7 = 1 * "".concat(3 - 4, "5"); +var d7 = 1 * "2".concat(3 - 4, "5"); +var e7 = "".concat(3 - 4) * 6; +var f7 = "2".concat(3 - 4) * 6; +var g7 = "".concat(3 - 4, "5") * 6; +var h7 = "2".concat(3 - 4, "5") * 6; +var a8 = 1 * "".concat(3 * 4); +var b8 = 1 * "2".concat(3 * 4); +var c8 = 1 * "".concat(3 * 4, "5"); +var d8 = 1 * "2".concat(3 * 4, "5"); +var e8 = "".concat(3 * 4) * 6; +var f8 = "2".concat(3 * 4) * 6; +var g8 = "".concat(3 * 4, "5") * 6; +var h8 = "2".concat(3 * 4, "5") * 6; +var a9 = 1 * "".concat(3 & 4); +var b9 = 1 * "2".concat(3 & 4); +var c9 = 1 * "".concat(3 & 4, "5"); +var d9 = 1 * "2".concat(3 & 4, "5"); +var e9 = "".concat(3 & 4) * 6; +var f9 = "2".concat(3 & 4) * 6; +var g9 = "".concat(3 & 4, "5") * 6; +var h9 = "2".concat(3 & 4, "5") * 6; +var aa = 1 & "".concat(3 - 4); +var ba = 1 & "2".concat(3 - 4); +var ca = 1 & "".concat(3 - 4, "5"); +var da = 1 & "2".concat(3 - 4, "5"); +var ea = "".concat(3 - 4) & 6; +var fa = "2".concat(3 - 4) & 6; +var ga = "".concat(3 - 4, "5") & 6; +var ha = "2".concat(3 - 4, "5") & 6; +var ab = 1 & "".concat(3 * 4); +var bb = 1 & "2".concat(3 * 4); +var cb = 1 & "".concat(3 * 4, "5"); +var db = 1 & "2".concat(3 * 4, "5"); +var eb = "".concat(3 * 4) & 6; +var fb = "2".concat(3 * 4) & 6; +var gb = "".concat(3 * 4, "5") & 6; +var hb = "2".concat(3 * 4, "5") & 6; +var ac = 1 & "".concat(3 & 4); +var bc = 1 & "2".concat(3 & 4); +var cc = 1 & "".concat(3 & 4, "5"); +var dc = 1 & "2".concat(3 & 4, "5"); +var ec = "".concat(3 & 4) & 6; +var fc = "2".concat(3 & 4) & 6; +var gc = "".concat(3 & 4, "5") & 6; +var hc = "2".concat(3 & 4, "5") & 6; diff --git a/tests/baselines/reference/templateStringInArray.js b/tests/baselines/reference/templateStringInArray.js index 7b387ae8e74..63982c0b064 100644 --- a/tests/baselines/reference/templateStringInArray.js +++ b/tests/baselines/reference/templateStringInArray.js @@ -2,4 +2,4 @@ var x = [1, 2, `abc${ 123 }def`]; //// [templateStringInArray.js] -var x = [1, 2, "abc" + 123 + "def"]; +var x = [1, 2, "abc".concat(123, "def")]; diff --git a/tests/baselines/reference/templateStringInArrowFunction.js b/tests/baselines/reference/templateStringInArrowFunction.js index 3e72edf031f..366f0ba15f7 100644 --- a/tests/baselines/reference/templateStringInArrowFunction.js +++ b/tests/baselines/reference/templateStringInArrowFunction.js @@ -2,4 +2,4 @@ var x = x => `abc${ x }def`; //// [templateStringInArrowFunction.js] -var x = function (x) { return "abc" + x + "def"; }; +var x = function (x) { return "abc".concat(x, "def"); }; diff --git a/tests/baselines/reference/templateStringInCallExpression.js b/tests/baselines/reference/templateStringInCallExpression.js index aa0671a1862..affdad6e9e2 100644 --- a/tests/baselines/reference/templateStringInCallExpression.js +++ b/tests/baselines/reference/templateStringInCallExpression.js @@ -2,4 +2,4 @@ `abc${0}abc`(`hello ${0} world`, ` `, `1${2}3`); //// [templateStringInCallExpression.js] -("abc" + 0 + "abc")("hello " + 0 + " world", " ", "1" + 2 + "3"); +"abc".concat(0, "abc")("hello ".concat(0, " world"), " ", "1".concat(2, "3")); diff --git a/tests/baselines/reference/templateStringInConditional.js b/tests/baselines/reference/templateStringInConditional.js index 8ffcf24e5f4..f6c3d083073 100644 --- a/tests/baselines/reference/templateStringInConditional.js +++ b/tests/baselines/reference/templateStringInConditional.js @@ -2,4 +2,4 @@ var x = `abc${ " " }def` ? `abc${ " " }def` : `abc${ " " }def`; //// [templateStringInConditional.js] -var x = "abc" + " " + "def" ? "abc" + " " + "def" : "abc" + " " + "def"; +var x = "abc".concat(" ", "def") ? "abc".concat(" ", "def") : "abc".concat(" ", "def"); diff --git a/tests/baselines/reference/templateStringInDeleteExpression.js b/tests/baselines/reference/templateStringInDeleteExpression.js index e8da2e2ba32..9159f976b82 100644 --- a/tests/baselines/reference/templateStringInDeleteExpression.js +++ b/tests/baselines/reference/templateStringInDeleteExpression.js @@ -2,4 +2,4 @@ delete `abc${0}abc`; //// [templateStringInDeleteExpression.js] -delete ("abc" + 0 + "abc"); +delete "abc".concat(0, "abc"); diff --git a/tests/baselines/reference/templateStringInDivision.js b/tests/baselines/reference/templateStringInDivision.js index d624d73f6bb..639a78d24ed 100644 --- a/tests/baselines/reference/templateStringInDivision.js +++ b/tests/baselines/reference/templateStringInDivision.js @@ -2,4 +2,4 @@ var x = `abc${ 1 }def` / 1; //// [templateStringInDivision.js] -var x = ("abc" + 1 + "def") / 1; +var x = "abc".concat(1, "def") / 1; diff --git a/tests/baselines/reference/templateStringInEqualityChecks.js b/tests/baselines/reference/templateStringInEqualityChecks.js index f7573f8efd5..ad7774f3813 100644 --- a/tests/baselines/reference/templateStringInEqualityChecks.js +++ b/tests/baselines/reference/templateStringInEqualityChecks.js @@ -5,7 +5,7 @@ var x = `abc${0}abc` === `abc` || "abc0abc" !== `abc${0}abc`; //// [templateStringInEqualityChecks.js] -var x = "abc" + 0 + "abc" === "abc" || - "abc" !== "abc" + 0 + "abc" && - "abc" + 0 + "abc" == "abc0abc" && - "abc0abc" !== "abc" + 0 + "abc"; +var x = "abc".concat(0, "abc") === "abc" || + "abc" !== "abc".concat(0, "abc") && + "abc".concat(0, "abc") == "abc0abc" && + "abc0abc" !== "abc".concat(0, "abc"); diff --git a/tests/baselines/reference/templateStringInFunctionExpression.js b/tests/baselines/reference/templateStringInFunctionExpression.js index 9711b2edc3a..deb6b23cf5e 100644 --- a/tests/baselines/reference/templateStringInFunctionExpression.js +++ b/tests/baselines/reference/templateStringInFunctionExpression.js @@ -6,6 +6,6 @@ var x = function y() { //// [templateStringInFunctionExpression.js] var x = function y() { - "abc" + 0 + "def"; - return "abc" + 0 + "def"; + "abc".concat(0, "def"); + return "abc".concat(0, "def"); }; diff --git a/tests/baselines/reference/templateStringInInOperator.js b/tests/baselines/reference/templateStringInInOperator.js index c496e335dd4..ab2082b9e44 100644 --- a/tests/baselines/reference/templateStringInInOperator.js +++ b/tests/baselines/reference/templateStringInInOperator.js @@ -2,4 +2,4 @@ var x = `${ "hi" }` in { hi: 10, hello: 20}; //// [templateStringInInOperator.js] -var x = "" + "hi" in { hi: 10, hello: 20 }; +var x = "".concat("hi") in { hi: 10, hello: 20 }; diff --git a/tests/baselines/reference/templateStringInIndexExpression.js b/tests/baselines/reference/templateStringInIndexExpression.js index 680cfb49f47..56910937c61 100644 --- a/tests/baselines/reference/templateStringInIndexExpression.js +++ b/tests/baselines/reference/templateStringInIndexExpression.js @@ -2,4 +2,4 @@ `abc${0}abc`[`0`]; //// [templateStringInIndexExpression.js] -("abc" + 0 + "abc")["0"]; +"abc".concat(0, "abc")["0"]; diff --git a/tests/baselines/reference/templateStringInInstanceOf.js b/tests/baselines/reference/templateStringInInstanceOf.js index ccf022cc703..afb7ddfac73 100644 --- a/tests/baselines/reference/templateStringInInstanceOf.js +++ b/tests/baselines/reference/templateStringInInstanceOf.js @@ -2,4 +2,4 @@ var x = `abc${ 0 }def` instanceof String; //// [templateStringInInstanceOf.js] -var x = "abc" + 0 + "def" instanceof String; +var x = "abc".concat(0, "def") instanceof String; diff --git a/tests/baselines/reference/templateStringInModulo.js b/tests/baselines/reference/templateStringInModulo.js index 65d5ec7eaab..59de4441290 100644 --- a/tests/baselines/reference/templateStringInModulo.js +++ b/tests/baselines/reference/templateStringInModulo.js @@ -2,4 +2,4 @@ var x = 1 % `abc${ 1 }def`; //// [templateStringInModulo.js] -var x = 1 % ("abc" + 1 + "def"); +var x = 1 % "abc".concat(1, "def"); diff --git a/tests/baselines/reference/templateStringInMultiplication.js b/tests/baselines/reference/templateStringInMultiplication.js index e48db6e1715..1117d9db8e3 100644 --- a/tests/baselines/reference/templateStringInMultiplication.js +++ b/tests/baselines/reference/templateStringInMultiplication.js @@ -2,4 +2,4 @@ var x = 1 * `abc${ 1 }def`; //// [templateStringInMultiplication.js] -var x = 1 * ("abc" + 1 + "def"); +var x = 1 * "abc".concat(1, "def"); diff --git a/tests/baselines/reference/templateStringInNewExpression.js b/tests/baselines/reference/templateStringInNewExpression.js index 1b1770c6197..bf06bfbcc13 100644 --- a/tests/baselines/reference/templateStringInNewExpression.js +++ b/tests/baselines/reference/templateStringInNewExpression.js @@ -2,4 +2,4 @@ new `abc${0}abc`(`hello ${0} world`, ` `, `1${2}3`); //// [templateStringInNewExpression.js] -new ("abc" + 0 + "abc")("hello " + 0 + " world", " ", "1" + 2 + "3"); +new ("abc".concat(0, "abc"))("hello ".concat(0, " world"), " ", "1".concat(2, "3")); diff --git a/tests/baselines/reference/templateStringInNewOperator.js b/tests/baselines/reference/templateStringInNewOperator.js index 8d76d59f7ee..436d7c0a92b 100644 --- a/tests/baselines/reference/templateStringInNewOperator.js +++ b/tests/baselines/reference/templateStringInNewOperator.js @@ -2,4 +2,4 @@ var x = new `abc${ 1 }def`; //// [templateStringInNewOperator.js] -var x = new ("abc" + 1 + "def"); +var x = new ("abc".concat(1, "def")); diff --git a/tests/baselines/reference/templateStringInObjectLiteral.js b/tests/baselines/reference/templateStringInObjectLiteral.js index e007ff7b7e7..7dc462a4fce 100644 --- a/tests/baselines/reference/templateStringInObjectLiteral.js +++ b/tests/baselines/reference/templateStringInObjectLiteral.js @@ -10,6 +10,6 @@ var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cook return cooked; }; var x = { - a: "abc" + 123 + "def" + a: "abc".concat(123, "def") }(__makeTemplateObject(["b"], ["b"])); 321; diff --git a/tests/baselines/reference/templateStringInParentheses.js b/tests/baselines/reference/templateStringInParentheses.js index 6c5c678bf4e..67199b0616f 100644 --- a/tests/baselines/reference/templateStringInParentheses.js +++ b/tests/baselines/reference/templateStringInParentheses.js @@ -2,4 +2,4 @@ var x = (`abc${0}abc`); //// [templateStringInParentheses.js] -var x = ("abc" + 0 + "abc"); +var x = ("abc".concat(0, "abc")); diff --git a/tests/baselines/reference/templateStringInPropertyAssignment.js b/tests/baselines/reference/templateStringInPropertyAssignment.js index 99fb24712c0..fd8f5586047 100644 --- a/tests/baselines/reference/templateStringInPropertyAssignment.js +++ b/tests/baselines/reference/templateStringInPropertyAssignment.js @@ -5,5 +5,5 @@ var x = { //// [templateStringInPropertyAssignment.js] var x = { - a: "abc" + 123 + "def" + 456 + "ghi" + a: "abc".concat(123, "def").concat(456, "ghi") }; diff --git a/tests/baselines/reference/templateStringInSwitchAndCase.js b/tests/baselines/reference/templateStringInSwitchAndCase.js index 67f182f8012..2bbdc2be007 100644 --- a/tests/baselines/reference/templateStringInSwitchAndCase.js +++ b/tests/baselines/reference/templateStringInSwitchAndCase.js @@ -7,9 +7,9 @@ switch (`abc${0}abc`) { } //// [templateStringInSwitchAndCase.js] -switch ("abc" + 0 + "abc") { +switch ("abc".concat(0, "abc")) { case "abc": case "123": - case "abc" + 0 + "abc": - "def" + 1 + "def"; + case "abc".concat(0, "abc"): + "def".concat(1, "def"); } diff --git a/tests/baselines/reference/templateStringInTaggedTemplate.js b/tests/baselines/reference/templateStringInTaggedTemplate.js index 29b85bf71ea..df0f1dd8954 100644 --- a/tests/baselines/reference/templateStringInTaggedTemplate.js +++ b/tests/baselines/reference/templateStringInTaggedTemplate.js @@ -6,4 +6,4 @@ var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cook if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; }; -("I AM THE " + "TAG" + " " + " PORTION")(__makeTemplateObject(["I ", " THE TEMPLATE PORTION"], ["I ", " THE TEMPLATE PORTION"]), "AM"); +"I AM THE ".concat("".concat("TAG", " "), " PORTION")(__makeTemplateObject(["I ", " THE TEMPLATE PORTION"], ["I ", " THE TEMPLATE PORTION"]), "AM"); diff --git a/tests/baselines/reference/templateStringInTypeAssertion.js b/tests/baselines/reference/templateStringInTypeAssertion.js index 723e688d94b..438aca44293 100644 --- a/tests/baselines/reference/templateStringInTypeAssertion.js +++ b/tests/baselines/reference/templateStringInTypeAssertion.js @@ -2,4 +2,4 @@ var x = `abc${ 123 }def`; //// [templateStringInTypeAssertion.js] -var x = "abc" + 123 + "def"; +var x = "abc".concat(123, "def"); diff --git a/tests/baselines/reference/templateStringInTypeOf.js b/tests/baselines/reference/templateStringInTypeOf.js index 2543091df88..27bdc9090d1 100644 --- a/tests/baselines/reference/templateStringInTypeOf.js +++ b/tests/baselines/reference/templateStringInTypeOf.js @@ -2,4 +2,4 @@ var x = typeof `abc${ 123 }def`; //// [templateStringInTypeOf.js] -var x = typeof ("abc" + 123 + "def"); +var x = typeof "abc".concat(123, "def"); diff --git a/tests/baselines/reference/templateStringInUnaryPlus.js b/tests/baselines/reference/templateStringInUnaryPlus.js index 83f107b3ac2..224c289af40 100644 --- a/tests/baselines/reference/templateStringInUnaryPlus.js +++ b/tests/baselines/reference/templateStringInUnaryPlus.js @@ -2,4 +2,4 @@ var x = +`abc${ 123 }def`; //// [templateStringInUnaryPlus.js] -var x = +("abc" + 123 + "def"); +var x = +"abc".concat(123, "def"); diff --git a/tests/baselines/reference/templateStringInWhile.js b/tests/baselines/reference/templateStringInWhile.js index 31f7dba45d1..ad77fe0aac8 100644 --- a/tests/baselines/reference/templateStringInWhile.js +++ b/tests/baselines/reference/templateStringInWhile.js @@ -4,6 +4,6 @@ while (`abc${0}abc`) { } //// [templateStringInWhile.js] -while ("abc" + 0 + "abc") { - "def" + 1 + "def"; +while ("abc".concat(0, "abc")) { + "def".concat(1, "def"); } diff --git a/tests/baselines/reference/templateStringPlainCharactersThatArePartsOfEscapes02.js b/tests/baselines/reference/templateStringPlainCharactersThatArePartsOfEscapes02.js index cc7b26dec83..0cdbc58c9b3 100644 --- a/tests/baselines/reference/templateStringPlainCharactersThatArePartsOfEscapes02.js +++ b/tests/baselines/reference/templateStringPlainCharactersThatArePartsOfEscapes02.js @@ -2,4 +2,4 @@ `0${ " " }1${ " " }2${ " " }3${ " " }4${ " " }5${ " " }6${ " " }7${ " " }8${ " " }9${ " " }10${ " " }11${ " " }12${ " " }13${ " " }14${ " " }15${ " " }16${ " " }17${ " " }18${ " " }19${ " " }20${ " " }2028${ " " }2029${ " " }0085${ " " }t${ " " }v${ " " }f${ " " }b${ " " }r${ " " }n` //// [templateStringPlainCharactersThatArePartsOfEscapes02.js] -"0" + " " + "1" + " " + "2" + " " + "3" + " " + "4" + " " + "5" + " " + "6" + " " + "7" + " " + "8" + " " + "9" + " " + "10" + " " + "11" + " " + "12" + " " + "13" + " " + "14" + " " + "15" + " " + "16" + " " + "17" + " " + "18" + " " + "19" + " " + "20" + " " + "2028" + " " + "2029" + " " + "0085" + " " + "t" + " " + "v" + " " + "f" + " " + "b" + " " + "r" + " " + "n"; +"0".concat(" ", "1").concat(" ", "2").concat(" ", "3").concat(" ", "4").concat(" ", "5").concat(" ", "6").concat(" ", "7").concat(" ", "8").concat(" ", "9").concat(" ", "10").concat(" ", "11").concat(" ", "12").concat(" ", "13").concat(" ", "14").concat(" ", "15").concat(" ", "16").concat(" ", "17").concat(" ", "18").concat(" ", "19").concat(" ", "20").concat(" ", "2028").concat(" ", "2029").concat(" ", "0085").concat(" ", "t").concat(" ", "v").concat(" ", "f").concat(" ", "b").concat(" ", "r").concat(" ", "n"); diff --git a/tests/baselines/reference/templateStringWithCommentsInArrowFunction.js b/tests/baselines/reference/templateStringWithCommentsInArrowFunction.js index df8a47410f5..b63772c0a68 100644 --- a/tests/baselines/reference/templateStringWithCommentsInArrowFunction.js +++ b/tests/baselines/reference/templateStringWithCommentsInArrowFunction.js @@ -16,12 +16,12 @@ const f2 = () => //// [templateStringWithCommentsInArrowFunction.js] var a = 1; var f1 = function () { - return "" + + return "".concat( // a - a + "a"; + a, "a"); }; var f2 = function () { - return "" + + return "".concat( // a - a; + a); }; diff --git a/tests/baselines/reference/templateStringWithEmbeddedAddition.js b/tests/baselines/reference/templateStringWithEmbeddedAddition.js index 2cf74941600..8f322e1170e 100644 --- a/tests/baselines/reference/templateStringWithEmbeddedAddition.js +++ b/tests/baselines/reference/templateStringWithEmbeddedAddition.js @@ -2,4 +2,4 @@ var x = `abc${ 10 + 10 }def`; //// [templateStringWithEmbeddedAddition.js] -var x = "abc" + (10 + 10) + "def"; +var x = "abc".concat(10 + 10, "def"); diff --git a/tests/baselines/reference/templateStringWithEmbeddedArray.js b/tests/baselines/reference/templateStringWithEmbeddedArray.js index 1fb6512db47..1d1abeebff0 100644 --- a/tests/baselines/reference/templateStringWithEmbeddedArray.js +++ b/tests/baselines/reference/templateStringWithEmbeddedArray.js @@ -2,4 +2,4 @@ var x = `abc${ [1,2,3] }def`; //// [templateStringWithEmbeddedArray.js] -var x = "abc" + [1, 2, 3] + "def"; +var x = "abc".concat([1, 2, 3], "def"); diff --git a/tests/baselines/reference/templateStringWithEmbeddedArrowFunction.js b/tests/baselines/reference/templateStringWithEmbeddedArrowFunction.js index eb2579b0cc3..66fcbd32185 100644 --- a/tests/baselines/reference/templateStringWithEmbeddedArrowFunction.js +++ b/tests/baselines/reference/templateStringWithEmbeddedArrowFunction.js @@ -2,4 +2,4 @@ var x = `abc${ x => x }def`; //// [templateStringWithEmbeddedArrowFunction.js] -var x = "abc" + function (x) { return x; } + "def"; +var x = "abc".concat(function (x) { return x; }, "def"); diff --git a/tests/baselines/reference/templateStringWithEmbeddedComments.js b/tests/baselines/reference/templateStringWithEmbeddedComments.js index 730997e28fb..4778efbf9db 100644 --- a/tests/baselines/reference/templateStringWithEmbeddedComments.js +++ b/tests/baselines/reference/templateStringWithEmbeddedComments.js @@ -13,9 +13,12 @@ middle${ tail`; //// [templateStringWithEmbeddedComments.js] -"head" + 10 + "\nmiddle" + +"head".concat(// single line comment +10, "\nmiddle").concat( /* Multi- * line * comment */ -20 + "\ntail"; +20 +// closing comment +, "\ntail"); diff --git a/tests/baselines/reference/templateStringWithEmbeddedConditional.js b/tests/baselines/reference/templateStringWithEmbeddedConditional.js index 5b03f56a019..d7f35cc7ffe 100644 --- a/tests/baselines/reference/templateStringWithEmbeddedConditional.js +++ b/tests/baselines/reference/templateStringWithEmbeddedConditional.js @@ -2,4 +2,4 @@ var x = `abc${ true ? false : " " }def`; //// [templateStringWithEmbeddedConditional.js] -var x = "abc" + (true ? false : " ") + "def"; +var x = "abc".concat(true ? false : " ", "def"); diff --git a/tests/baselines/reference/templateStringWithEmbeddedDivision.js b/tests/baselines/reference/templateStringWithEmbeddedDivision.js index f9996ae035d..6959e7afe7e 100644 --- a/tests/baselines/reference/templateStringWithEmbeddedDivision.js +++ b/tests/baselines/reference/templateStringWithEmbeddedDivision.js @@ -2,4 +2,4 @@ var x = `abc${ 1 / 1 }def`; //// [templateStringWithEmbeddedDivision.js] -var x = "abc" + 1 / 1 + "def"; +var x = "abc".concat(1 / 1, "def"); diff --git a/tests/baselines/reference/templateStringWithEmbeddedFunctionExpression.js b/tests/baselines/reference/templateStringWithEmbeddedFunctionExpression.js index 88a8349d1a4..2c0b4e45746 100644 --- a/tests/baselines/reference/templateStringWithEmbeddedFunctionExpression.js +++ b/tests/baselines/reference/templateStringWithEmbeddedFunctionExpression.js @@ -2,4 +2,4 @@ var x = `abc${ function y() { return y; } }def`; //// [templateStringWithEmbeddedFunctionExpression.js] -var x = "abc" + function y() { return y; } + "def"; +var x = "abc".concat(function y() { return y; }, "def"); diff --git a/tests/baselines/reference/templateStringWithEmbeddedInOperator.js b/tests/baselines/reference/templateStringWithEmbeddedInOperator.js index 091843ea52e..ab30a23c845 100644 --- a/tests/baselines/reference/templateStringWithEmbeddedInOperator.js +++ b/tests/baselines/reference/templateStringWithEmbeddedInOperator.js @@ -2,4 +2,4 @@ var x = `abc${ "hi" in { hi: 10, hello: 20} }def`; //// [templateStringWithEmbeddedInOperator.js] -var x = "abc" + ("hi" in { hi: 10, hello: 20 }) + "def"; +var x = "abc".concat("hi" in { hi: 10, hello: 20 }, "def"); diff --git a/tests/baselines/reference/templateStringWithEmbeddedInstanceOf.js b/tests/baselines/reference/templateStringWithEmbeddedInstanceOf.js index 009f6bf988d..acb84e4c92b 100644 --- a/tests/baselines/reference/templateStringWithEmbeddedInstanceOf.js +++ b/tests/baselines/reference/templateStringWithEmbeddedInstanceOf.js @@ -2,4 +2,4 @@ var x = `abc${ "hello" instanceof String }def`; //// [templateStringWithEmbeddedInstanceOf.js] -var x = "abc" + ("hello" instanceof String) + "def"; +var x = "abc".concat("hello" instanceof String, "def"); diff --git a/tests/baselines/reference/templateStringWithEmbeddedModulo.js b/tests/baselines/reference/templateStringWithEmbeddedModulo.js index 6fe9be64314..afb9a0716c9 100644 --- a/tests/baselines/reference/templateStringWithEmbeddedModulo.js +++ b/tests/baselines/reference/templateStringWithEmbeddedModulo.js @@ -2,4 +2,4 @@ var x = `abc${ 1 % 1 }def`; //// [templateStringWithEmbeddedModulo.js] -var x = "abc" + 1 % 1 + "def"; +var x = "abc".concat(1 % 1, "def"); diff --git a/tests/baselines/reference/templateStringWithEmbeddedMultiplication.js b/tests/baselines/reference/templateStringWithEmbeddedMultiplication.js index 7ac4b1b534c..27049b5b76d 100644 --- a/tests/baselines/reference/templateStringWithEmbeddedMultiplication.js +++ b/tests/baselines/reference/templateStringWithEmbeddedMultiplication.js @@ -2,4 +2,4 @@ var x = `abc${ 7 * 6 }def`; //// [templateStringWithEmbeddedMultiplication.js] -var x = "abc" + 7 * 6 + "def"; +var x = "abc".concat(7 * 6, "def"); diff --git a/tests/baselines/reference/templateStringWithEmbeddedNewOperator.js b/tests/baselines/reference/templateStringWithEmbeddedNewOperator.js index 480fbe2573d..f6e88cfaf41 100644 --- a/tests/baselines/reference/templateStringWithEmbeddedNewOperator.js +++ b/tests/baselines/reference/templateStringWithEmbeddedNewOperator.js @@ -2,4 +2,4 @@ var x = `abc${ new String("Hi") }def`; //// [templateStringWithEmbeddedNewOperator.js] -var x = "abc" + new String("Hi") + "def"; +var x = "abc".concat(new String("Hi"), "def"); diff --git a/tests/baselines/reference/templateStringWithEmbeddedObjectLiteral.js b/tests/baselines/reference/templateStringWithEmbeddedObjectLiteral.js index 40ecf486245..8fd83d89ad9 100644 --- a/tests/baselines/reference/templateStringWithEmbeddedObjectLiteral.js +++ b/tests/baselines/reference/templateStringWithEmbeddedObjectLiteral.js @@ -2,4 +2,4 @@ var x = `abc${ { x: 10, y: 20 } }def`; //// [templateStringWithEmbeddedObjectLiteral.js] -var x = "abc" + { x: 10, y: 20 } + "def"; +var x = "abc".concat({ x: 10, y: 20 }, "def"); diff --git a/tests/baselines/reference/templateStringWithEmbeddedTemplateString.js b/tests/baselines/reference/templateStringWithEmbeddedTemplateString.js index c0059dbb950..ece7755341f 100644 --- a/tests/baselines/reference/templateStringWithEmbeddedTemplateString.js +++ b/tests/baselines/reference/templateStringWithEmbeddedTemplateString.js @@ -2,4 +2,4 @@ var x = `123${ `456 ${ " | " } 654` }321 123${ `456 ${ " | " } 654` }321`; //// [templateStringWithEmbeddedTemplateString.js] -var x = "123" + "456 " + " | " + " 654" + "321 123" + "456 " + " | " + " 654" + "321"; +var x = "123".concat("456 ".concat(" | ", " 654"), "321 123").concat("456 ".concat(" | ", " 654"), "321"); diff --git a/tests/baselines/reference/templateStringWithEmbeddedTypeAssertionOnAddition.js b/tests/baselines/reference/templateStringWithEmbeddedTypeAssertionOnAddition.js index 89d9ba6940c..3e18c60766a 100644 --- a/tests/baselines/reference/templateStringWithEmbeddedTypeAssertionOnAddition.js +++ b/tests/baselines/reference/templateStringWithEmbeddedTypeAssertionOnAddition.js @@ -2,4 +2,4 @@ var x = `abc${ (10 + 10) }def`; //// [templateStringWithEmbeddedTypeAssertionOnAddition.js] -var x = "abc" + (10 + 10) + "def"; +var x = "abc".concat((10 + 10), "def"); diff --git a/tests/baselines/reference/templateStringWithEmbeddedTypeOfOperator.js b/tests/baselines/reference/templateStringWithEmbeddedTypeOfOperator.js index 10450707b11..544b3245414 100644 --- a/tests/baselines/reference/templateStringWithEmbeddedTypeOfOperator.js +++ b/tests/baselines/reference/templateStringWithEmbeddedTypeOfOperator.js @@ -2,4 +2,4 @@ var x = `abc${ typeof "hi" }def`; //// [templateStringWithEmbeddedTypeOfOperator.js] -var x = "abc" + typeof "hi" + "def"; +var x = "abc".concat(typeof "hi", "def"); diff --git a/tests/baselines/reference/templateStringWithEmbeddedUnaryPlus.js b/tests/baselines/reference/templateStringWithEmbeddedUnaryPlus.js index a4a9c1a8508..7be80f3aed3 100644 --- a/tests/baselines/reference/templateStringWithEmbeddedUnaryPlus.js +++ b/tests/baselines/reference/templateStringWithEmbeddedUnaryPlus.js @@ -2,4 +2,4 @@ var x = `abc${ +Infinity }def`; //// [templateStringWithEmbeddedUnaryPlus.js] -var x = "abc" + +Infinity + "def"; +var x = "abc".concat(+Infinity, "def"); diff --git a/tests/baselines/reference/templateStringWithEmbeddedYieldKeyword.js b/tests/baselines/reference/templateStringWithEmbeddedYieldKeyword.js index 53eb1b5af22..a3a1bdcc504 100644 --- a/tests/baselines/reference/templateStringWithEmbeddedYieldKeyword.js +++ b/tests/baselines/reference/templateStringWithEmbeddedYieldKeyword.js @@ -38,10 +38,10 @@ function gen() { return __generator(this, function (_b) { switch (_b.label) { case 0: - _a = "abc"; + _a = "abc".concat; return [4 /*yield*/, 10]; case 1: - x = _a + (_b.sent()) + "def"; + x = _a.apply("abc", [_b.sent(), "def"]); return [2 /*return*/]; } }); diff --git a/tests/baselines/reference/templateStringWithEmptyLiteralPortions.js b/tests/baselines/reference/templateStringWithEmptyLiteralPortions.js index e7a35d76f45..5703114d2d4 100644 --- a/tests/baselines/reference/templateStringWithEmptyLiteralPortions.js +++ b/tests/baselines/reference/templateStringWithEmptyLiteralPortions.js @@ -28,15 +28,15 @@ var m = `1${ 0 }2${ 0 }3`; //// [templateStringWithEmptyLiteralPortions.js] var a = ""; -var b = "" + 0; -var c = "1" + 0; -var d = 0 + "2"; -var e = "1" + 0 + "2"; -var f = "" + 0 + 0; -var g = "1" + 0 + 0; -var h = 0 + "2" + 0; -var i = "1" + 0 + "2" + 0; -var j = "" + 0 + 0 + "3"; -var k = "1" + 0 + 0 + "3"; -var l = 0 + "2" + 0 + "3"; -var m = "1" + 0 + "2" + 0 + "3"; +var b = "".concat(0); +var c = "1".concat(0); +var d = "".concat(0, "2"); +var e = "1".concat(0, "2"); +var f = "".concat(0).concat(0); +var g = "1".concat(0).concat(0); +var h = "".concat(0, "2").concat(0); +var i = "1".concat(0, "2").concat(0); +var j = "".concat(0).concat(0, "3"); +var k = "1".concat(0).concat(0, "3"); +var l = "".concat(0, "2").concat(0, "3"); +var m = "1".concat(0, "2").concat(0, "3"); diff --git a/tests/baselines/reference/templateStringWithOpenCommentInStringPortion.js b/tests/baselines/reference/templateStringWithOpenCommentInStringPortion.js index 233ab78a195..3469a5db07f 100644 --- a/tests/baselines/reference/templateStringWithOpenCommentInStringPortion.js +++ b/tests/baselines/reference/templateStringWithOpenCommentInStringPortion.js @@ -2,4 +2,4 @@ ` /**head ${ 10 } // still middle ${ 20 } /* still tail ` //// [templateStringWithOpenCommentInStringPortion.js] -" /**head " + 10 + " // still middle " + 20 + " /* still tail "; +" /**head ".concat(10, " // still middle ").concat(20, " /* still tail "); diff --git a/tests/baselines/reference/templateStringWithPropertyAccess.js b/tests/baselines/reference/templateStringWithPropertyAccess.js index 9866b6bd53b..5a43a875311 100644 --- a/tests/baselines/reference/templateStringWithPropertyAccess.js +++ b/tests/baselines/reference/templateStringWithPropertyAccess.js @@ -2,4 +2,4 @@ `abc${0}abc`.indexOf(`abc`); //// [templateStringWithPropertyAccess.js] -("abc" + 0 + "abc").indexOf("abc"); +"abc".concat(0, "abc").indexOf("abc"); diff --git a/tests/baselines/reference/templateStringsWithTypeErrorInFunctionExpressionsInSubstitutionExpression.js b/tests/baselines/reference/templateStringsWithTypeErrorInFunctionExpressionsInSubstitutionExpression.js index f01741ce68d..461648a46c9 100644 --- a/tests/baselines/reference/templateStringsWithTypeErrorInFunctionExpressionsInSubstitutionExpression.js +++ b/tests/baselines/reference/templateStringsWithTypeErrorInFunctionExpressionsInSubstitutionExpression.js @@ -2,4 +2,4 @@ `${function (x: number) { x = "bad"; } }`; //// [templateStringsWithTypeErrorInFunctionExpressionsInSubstitutionExpression.js] -"" + function (x) { x = "bad"; }; +"".concat(function (x) { x = "bad"; }); diff --git a/tests/baselines/reference/truthinessCallExpressionCoercion.js b/tests/baselines/reference/truthinessCallExpressionCoercion.js index 3f43e629671..949b64303fd 100644 --- a/tests/baselines/reference/truthinessCallExpressionCoercion.js +++ b/tests/baselines/reference/truthinessCallExpressionCoercion.js @@ -159,7 +159,7 @@ var Foo = /** @class */ (function () { // Test for GH-35557 where ids were not assigned for a symbol. function A(stats) { if (stats.isDirectory) { // err - console.log("[Directory] " + stats.ctime); + console.log("[Directory] ".concat(stats.ctime)); } } function B(a, b) { diff --git a/tests/baselines/reference/tsbuild/demo/initial-build/in-master-branch-with-everything-setup-correctly-and-reports-no-error.js b/tests/baselines/reference/tsbuild/demo/initial-build/in-master-branch-with-everything-setup-correctly-and-reports-no-error.js index e941596a114..3bfd6267acf 100644 --- a/tests/baselines/reference/tsbuild/demo/initial-build/in-master-branch-with-everything-setup-correctly-and-reports-no-error.js +++ b/tests/baselines/reference/tsbuild/demo/initial-build/in-master-branch-with-everything-setup-correctly-and-reports-no-error.js @@ -196,7 +196,7 @@ function createDog() { return ({ size: "medium", woof: function () { - console.log(this.name + " says \"Woof\"!"); + console.log("".concat(this.name, " says \"Woof\"!")); }, name: (0, utilities_1.makeRandomName)() }); diff --git a/tests/baselines/reference/tsbuild/watchMode/demo/updates-with-circular-reference.js b/tests/baselines/reference/tsbuild/watchMode/demo/updates-with-circular-reference.js index 15a8f8af612..62e75a21495 100644 --- a/tests/baselines/reference/tsbuild/watchMode/demo/updates-with-circular-reference.js +++ b/tests/baselines/reference/tsbuild/watchMode/demo/updates-with-circular-reference.js @@ -434,7 +434,7 @@ function createDog() { return ({ size: "medium", woof: function () { - console.log(this.name + " says \"Woof\"!"); + console.log("".concat(this.name, " says \"Woof\"!")); }, name: (0, utilities_1.makeRandomName)() }); diff --git a/tests/baselines/reference/typeGuardIntersectionTypes.js b/tests/baselines/reference/typeGuardIntersectionTypes.js index 5a7bc055330..fc79e74bea0 100644 --- a/tests/baselines/reference/typeGuardIntersectionTypes.js +++ b/tests/baselines/reference/typeGuardIntersectionTypes.js @@ -149,12 +149,12 @@ function identifyBeast(beast) { log("bird - 2 legs, wings"); } else { - log("unknown - " + beast.legs + " legs, wings"); + log("unknown - ".concat(beast.legs, " legs, wings")); } } // All non-winged beasts with legs else { - log("manbearpig - " + beast.legs + " legs, no wings"); + log("manbearpig - ".concat(beast.legs, " legs, no wings")); } } // All beasts without legs diff --git a/tests/baselines/reference/unicodeExtendedEscapesInTemplates20_ES5.js b/tests/baselines/reference/unicodeExtendedEscapesInTemplates20_ES5.js index 14727c69551..e822de3560c 100644 --- a/tests/baselines/reference/unicodeExtendedEscapesInTemplates20_ES5.js +++ b/tests/baselines/reference/unicodeExtendedEscapesInTemplates20_ES5.js @@ -3,4 +3,4 @@ var x = `\u{48}\u{65}\u{6c}\u{6c}\u{6f}${`\u{20}\u{020}\u{0020}\u{000020}`}\u{77 //// [unicodeExtendedEscapesInTemplates20_ES5.js] -var x = "Hello" + " " + "world"; +var x = "Hello".concat(" ", "world"); diff --git a/tests/cases/compiler/templateLiteralsSourceMap.ts b/tests/cases/compiler/templateLiteralsSourceMap.ts new file mode 100644 index 00000000000..6e56ce184ce --- /dev/null +++ b/tests/cases/compiler/templateLiteralsSourceMap.ts @@ -0,0 +1,3 @@ +// @sourcemap: true + +const s = `a${0}b${1}c${2}`; From ac345849e3c12c8fc9c041c6b26e66852cf6ae38 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 13 Oct 2021 17:04:13 -0700 Subject: [PATCH 08/60] Set impliedNodeFormat on sourceFiles maufactured in watch mode (#46349) --- src/compiler/watchPublic.ts | 3 + src/testRunner/tsconfig.json | 1 + .../unittests/tscWatch/nodeNextWatch.ts | 58 +++++++ .../esm-mode-file-is-edited.js | 147 ++++++++++++++++++ 4 files changed, 209 insertions(+) create mode 100644 src/testRunner/unittests/tscWatch/nodeNextWatch.ts create mode 100644 tests/baselines/reference/tscWatch/nodenext watch emit/esm-mode-file-is-edited.js diff --git a/src/compiler/watchPublic.ts b/src/compiler/watchPublic.ts index 4b1eba91b7c..33220b03d2e 100644 --- a/src/compiler/watchPublic.ts +++ b/src/compiler/watchPublic.ts @@ -560,6 +560,9 @@ namespace ts { sourceFilesCache.set(path, false); } } + if (sourceFile) { + sourceFile.impliedNodeFormat = getImpliedNodeFormatForFile(path, resolutionCache.getModuleResolutionCache().getPackageJsonInfoCache(), compilerHost, compilerHost.getCompilationSettings()); + } return sourceFile; } return hostSourceFile.sourceFile; diff --git a/src/testRunner/tsconfig.json b/src/testRunner/tsconfig.json index e617b5adc09..e85df70861e 100644 --- a/src/testRunner/tsconfig.json +++ b/src/testRunner/tsconfig.json @@ -158,6 +158,7 @@ "unittests/tsc/runWithoutArgs.ts", "unittests/tscWatch/consoleClearing.ts", "unittests/tscWatch/emit.ts", + "unittests/tscWatch/nodeNextWatch.ts", "unittests/tscWatch/emitAndErrorUpdates.ts", "unittests/tscWatch/forceConsistentCasingInFileNames.ts", "unittests/tscWatch/incremental.ts", diff --git a/src/testRunner/unittests/tscWatch/nodeNextWatch.ts b/src/testRunner/unittests/tscWatch/nodeNextWatch.ts new file mode 100644 index 00000000000..a7cb1d4ed94 --- /dev/null +++ b/src/testRunner/unittests/tscWatch/nodeNextWatch.ts @@ -0,0 +1,58 @@ +namespace ts.tscWatch { + describe("unittests:: tsc-watch:: nodeNextWatch:: emit when module emit is specified as nodenext", () => { + verifyTscWatch({ + scenario: "nodenext watch emit", + subScenario: "esm-mode file is edited", + commandLineArgs: ["--w", "--p", "/project/tsconfig.json"], + sys: () => { + const configFile: File = { + path: "/project/tsconfig.json", + content: JSON.stringify({ + compilerOptions: { + strict: true, + target: "es2020", + module: "nodenext", + moduleResolution: "nodenext", + outDir: "../dist" + } + }) + }; + const packageFile: File = { + path: "/project/package.json", + content: JSON.stringify({ + name: "some-proj", + version: "1.0.0", + description: "", + type: "module", + main: "index.js", + }) + }; + const file1: File = { + path: "/project/src/index.ts", + content: Utils.dedent` + import * as Thing from "thing"; + + Thing.fn();` + }; + const declFile: File = { + path: "/project/src/deps.d.ts", + content: `declare module "thing";` + }; + return createWatchedSystem([configFile, file1, declFile, packageFile, { ...libFile, path: "/a/lib/lib.es2020.full.d.ts" }]); + }, + changes: [ + { + caption: "Modify typescript file", + change: sys => sys.modifyFile( + "/project/src/index.ts", + Utils.dedent` + import * as Thing from "thing"; + Thing.fn();`, + {}, + ), + timeouts: runQueuedTimeoutCallbacks, + } + ], + }); + }); +} \ No newline at end of file diff --git a/tests/baselines/reference/tscWatch/nodenext watch emit/esm-mode-file-is-edited.js b/tests/baselines/reference/tscWatch/nodenext watch emit/esm-mode-file-is-edited.js new file mode 100644 index 00000000000..bad3c2f405f --- /dev/null +++ b/tests/baselines/reference/tscWatch/nodenext watch emit/esm-mode-file-is-edited.js @@ -0,0 +1,147 @@ +Input:: +//// [/project/tsconfig.json] +{"compilerOptions":{"strict":true,"target":"es2020","module":"nodenext","moduleResolution":"nodenext","outDir":"../dist"}} + +//// [/project/src/index.ts] +import * as Thing from "thing"; + +Thing.fn(); + +//// [/project/src/deps.d.ts] +declare module "thing"; + +//// [/project/package.json] +{"name":"some-proj","version":"1.0.0","description":"","type":"module","main":"index.js"} + +//// [/a/lib/lib.es2020.full.d.ts] +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } + + +/a/lib/tsc.js --w --p /project/tsconfig.json +Output:: +>> Screen clear +[12:00:21 AM] Starting compilation in watch mode... + +[12:00:27 AM] Found 0 errors. Watching for file changes. + + + +Program root files: ["/project/src/deps.d.ts","/project/src/index.ts"] +Program options: {"strict":true,"target":7,"module":199,"moduleResolution":99,"outDir":"/dist","watch":true,"project":"/project/tsconfig.json","configFilePath":"/project/tsconfig.json"} +Program structureReused: Not +Program files:: +/a/lib/lib.es2020.full.d.ts +/project/src/deps.d.ts +/project/src/index.ts + +Semantic diagnostics in builder refreshed for:: +/a/lib/lib.es2020.full.d.ts +/project/src/deps.d.ts +/project/src/index.ts + +Shape signatures in builder refreshed for:: +/a/lib/lib.es2020.full.d.ts (used version) +/project/src/deps.d.ts (used version) +/project/src/index.ts (used version) + +WatchedFiles:: +/project/tsconfig.json: + {"fileName":"/project/tsconfig.json","pollingInterval":250} +/project/src/deps.d.ts: + {"fileName":"/project/src/deps.d.ts","pollingInterval":250} +/project/src/index.ts: + {"fileName":"/project/src/index.ts","pollingInterval":250} +/a/lib/lib.es2020.full.d.ts: + {"fileName":"/a/lib/lib.es2020.full.d.ts","pollingInterval":250} +/project/src/package.json: + {"fileName":"/project/src/package.json","pollingInterval":250} +/project/package.json: + {"fileName":"/project/package.json","pollingInterval":250} +/a/lib/package.json: + {"fileName":"/a/lib/package.json","pollingInterval":250} +/a/package.json: + {"fileName":"/a/package.json","pollingInterval":250} +/package.json: + {"fileName":"/package.json","pollingInterval":250} + +FsWatches:: + +FsWatchesRecursive:: +/project/node_modules/@types: + {"directoryName":"/project/node_modules/@types","fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} +/project: + {"directoryName":"/project","fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} + +exitCode:: ExitStatus.undefined + +//// [/dist/index.js] +import * as Thing from "thing"; +Thing.fn(); + + + +Change:: Modify typescript file + +Input:: +//// [/project/src/index.ts] +import * as Thing from "thing"; +Thing.fn(); + + +Output:: +>> Screen clear +[12:00:30 AM] File change detected. Starting incremental compilation... + +[12:00:34 AM] Found 0 errors. Watching for file changes. + + + +Program root files: ["/project/src/deps.d.ts","/project/src/index.ts"] +Program options: {"strict":true,"target":7,"module":199,"moduleResolution":99,"outDir":"/dist","watch":true,"project":"/project/tsconfig.json","configFilePath":"/project/tsconfig.json"} +Program structureReused: Completely +Program files:: +/a/lib/lib.es2020.full.d.ts +/project/src/deps.d.ts +/project/src/index.ts + +Semantic diagnostics in builder refreshed for:: +/project/src/index.ts + +Shape signatures in builder refreshed for:: +/project/src/index.ts (computed .d.ts) + +WatchedFiles:: +/project/tsconfig.json: + {"fileName":"/project/tsconfig.json","pollingInterval":250} +/project/src/deps.d.ts: + {"fileName":"/project/src/deps.d.ts","pollingInterval":250} +/project/src/index.ts: + {"fileName":"/project/src/index.ts","pollingInterval":250} +/a/lib/lib.es2020.full.d.ts: + {"fileName":"/a/lib/lib.es2020.full.d.ts","pollingInterval":250} +/project/src/package.json: + {"fileName":"/project/src/package.json","pollingInterval":250} +/project/package.json: + {"fileName":"/project/package.json","pollingInterval":250} + +FsWatches:: + +FsWatchesRecursive:: +/project/node_modules/@types: + {"directoryName":"/project/node_modules/@types","fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} +/project: + {"directoryName":"/project","fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} + +exitCode:: ExitStatus.undefined + +//// [/dist/index.js] file written with same contents From 1c5d4e1740eb14673eb5394cec2163168471d2de Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 13 Oct 2021 17:04:33 -0700 Subject: [PATCH 09/60] Pass symbol under inspection into checkIndexConstraints (#46350) --- src/compiler/checker.ts | 12 ++-- .../mixinOverMappedTypeNoCrash.symbols | 58 +++++++++++++++++++ .../mixinOverMappedTypeNoCrash.types | 41 +++++++++++++ .../compiler/mixinOverMappedTypeNoCrash.ts | 21 +++++++ 4 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 tests/baselines/reference/mixinOverMappedTypeNoCrash.symbols create mode 100644 tests/baselines/reference/mixinOverMappedTypeNoCrash.types create mode 100644 tests/cases/compiler/mixinOverMappedTypeNoCrash.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1edbb1d4a0d..d4588d9551e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -34636,7 +34636,7 @@ namespace ts { forEach(node.members, checkSourceElement); if (produceDiagnostics) { const type = getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node); - checkIndexConstraints(type); + checkIndexConstraints(type, type.symbol); checkTypeForDuplicateIndexSignatures(node); checkObjectTypeForDuplicateDeclarations(node); } @@ -38069,7 +38069,7 @@ namespace ts { } } - function checkIndexConstraints(type: Type, isStaticIndex?: boolean) { + function checkIndexConstraints(type: Type, symbol: Symbol, isStaticIndex?: boolean) { const indexInfos = getIndexInfosOfType(type); if (indexInfos.length === 0) { return; @@ -38079,7 +38079,7 @@ namespace ts { checkIndexConstraintForProperty(type, prop, getLiteralTypeFromProperty(prop, TypeFlags.StringOrNumberLiteralOrUnique, /*includeNonPublic*/ true), getNonMissingTypeOfSymbol(prop)); } } - const typeDeclaration = type.symbol.valueDeclaration; + const typeDeclaration = symbol.valueDeclaration; if (typeDeclaration && isClassLike(typeDeclaration)) { for (const member of typeDeclaration.members) { // Only process instance properties with computed names here. Static properties cannot be in conflict with indexers, @@ -38420,8 +38420,8 @@ namespace ts { } if (produceDiagnostics) { - checkIndexConstraints(type); - checkIndexConstraints(staticType, /*isStaticIndex*/ true); + checkIndexConstraints(type, symbol); + checkIndexConstraints(staticType, symbol, /*isStaticIndex*/ true); checkTypeForDuplicateIndexSignatures(node); checkPropertyInitialization(node); } @@ -38848,7 +38848,7 @@ namespace ts { for (const baseType of getBaseTypes(type)) { checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(baseType, type.thisType), node.name, Diagnostics.Interface_0_incorrectly_extends_interface_1); } - checkIndexConstraints(type); + checkIndexConstraints(type, symbol); } } checkObjectTypeForDuplicateDeclarations(node); diff --git a/tests/baselines/reference/mixinOverMappedTypeNoCrash.symbols b/tests/baselines/reference/mixinOverMappedTypeNoCrash.symbols new file mode 100644 index 00000000000..01fff6cbf4f --- /dev/null +++ b/tests/baselines/reference/mixinOverMappedTypeNoCrash.symbols @@ -0,0 +1,58 @@ +=== tests/cases/compiler/mixinOverMappedTypeNoCrash.ts === +export type ClassInterface = { +>ClassInterface : Symbol(ClassInterface, Decl(mixinOverMappedTypeNoCrash.ts, 0, 0)) +>C : Symbol(C, Decl(mixinOverMappedTypeNoCrash.ts, 0, 27)) + + [key in keyof C]: C[key]; +>key : Symbol(key, Decl(mixinOverMappedTypeNoCrash.ts, 1, 5)) +>C : Symbol(C, Decl(mixinOverMappedTypeNoCrash.ts, 0, 27)) +>C : Symbol(C, Decl(mixinOverMappedTypeNoCrash.ts, 0, 27)) +>key : Symbol(key, Decl(mixinOverMappedTypeNoCrash.ts, 1, 5)) +} + +type InstanceInterface = { +>InstanceInterface : Symbol(InstanceInterface, Decl(mixinOverMappedTypeNoCrash.ts, 2, 1)) +>I : Symbol(I, Decl(mixinOverMappedTypeNoCrash.ts, 4, 23)) + + new(...args: any[]): I +>args : Symbol(args, Decl(mixinOverMappedTypeNoCrash.ts, 5, 8)) +>I : Symbol(I, Decl(mixinOverMappedTypeNoCrash.ts, 4, 23)) + + prototype: I +>prototype : Symbol(prototype, Decl(mixinOverMappedTypeNoCrash.ts, 5, 26)) +>I : Symbol(I, Decl(mixinOverMappedTypeNoCrash.ts, 4, 23)) +} + +type Constructor = ClassInterface & InstanceInterface +>Constructor : Symbol(Constructor, Decl(mixinOverMappedTypeNoCrash.ts, 7, 1)) +>I : Symbol(I, Decl(mixinOverMappedTypeNoCrash.ts, 9, 17)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>C : Symbol(C, Decl(mixinOverMappedTypeNoCrash.ts, 9, 34)) +>ClassInterface : Symbol(ClassInterface, Decl(mixinOverMappedTypeNoCrash.ts, 0, 0)) +>C : Symbol(C, Decl(mixinOverMappedTypeNoCrash.ts, 9, 34)) +>InstanceInterface : Symbol(InstanceInterface, Decl(mixinOverMappedTypeNoCrash.ts, 2, 1)) +>I : Symbol(I, Decl(mixinOverMappedTypeNoCrash.ts, 9, 17)) + +function cloneClass>(OriginalClass: T): T { +>cloneClass : Symbol(cloneClass, Decl(mixinOverMappedTypeNoCrash.ts, 9, 86)) +>T : Symbol(T, Decl(mixinOverMappedTypeNoCrash.ts, 11, 20)) +>Constructor : Symbol(Constructor, Decl(mixinOverMappedTypeNoCrash.ts, 7, 1)) +>OriginalClass : Symbol(OriginalClass, Decl(mixinOverMappedTypeNoCrash.ts, 11, 47)) +>T : Symbol(T, Decl(mixinOverMappedTypeNoCrash.ts, 11, 20)) +>T : Symbol(T, Decl(mixinOverMappedTypeNoCrash.ts, 11, 20)) + + class AnotherOriginalClass extends OriginalClass { +>AnotherOriginalClass : Symbol(AnotherOriginalClass, Decl(mixinOverMappedTypeNoCrash.ts, 11, 69)) +>OriginalClass : Symbol(OriginalClass, Decl(mixinOverMappedTypeNoCrash.ts, 11, 47)) + + constructor(...args: any[]) { +>args : Symbol(args, Decl(mixinOverMappedTypeNoCrash.ts, 13, 20)) + + super(...args) +>super : Symbol(T, Decl(mixinOverMappedTypeNoCrash.ts, 11, 20)) +>args : Symbol(args, Decl(mixinOverMappedTypeNoCrash.ts, 13, 20)) + } + } + return AnotherOriginalClass +>AnotherOriginalClass : Symbol(AnotherOriginalClass, Decl(mixinOverMappedTypeNoCrash.ts, 11, 69)) +} diff --git a/tests/baselines/reference/mixinOverMappedTypeNoCrash.types b/tests/baselines/reference/mixinOverMappedTypeNoCrash.types new file mode 100644 index 00000000000..de9532379b4 --- /dev/null +++ b/tests/baselines/reference/mixinOverMappedTypeNoCrash.types @@ -0,0 +1,41 @@ +=== tests/cases/compiler/mixinOverMappedTypeNoCrash.ts === +export type ClassInterface = { +>ClassInterface : ClassInterface + + [key in keyof C]: C[key]; +} + +type InstanceInterface = { +>InstanceInterface : InstanceInterface + + new(...args: any[]): I +>args : any[] + + prototype: I +>prototype : I +} + +type Constructor = ClassInterface & InstanceInterface +>Constructor : Constructor + +function cloneClass>(OriginalClass: T): T { +>cloneClass : >(OriginalClass: T) => T +>OriginalClass : T + + class AnotherOriginalClass extends OriginalClass { +>AnotherOriginalClass : AnotherOriginalClass +>OriginalClass : {} + + constructor(...args: any[]) { +>args : any[] + + super(...args) +>super(...args) : void +>super : T +>...args : any +>args : any[] + } + } + return AnotherOriginalClass +>AnotherOriginalClass : { new (...args: any[]): AnotherOriginalClass; prototype: cloneClass.AnotherOriginalClass; } & T +} diff --git a/tests/cases/compiler/mixinOverMappedTypeNoCrash.ts b/tests/cases/compiler/mixinOverMappedTypeNoCrash.ts new file mode 100644 index 00000000000..7ca9129a0e6 --- /dev/null +++ b/tests/cases/compiler/mixinOverMappedTypeNoCrash.ts @@ -0,0 +1,21 @@ +// @noEmit: true + +export type ClassInterface = { + [key in keyof C]: C[key]; +} + +type InstanceInterface = { + new(...args: any[]): I + prototype: I +} + +type Constructor = ClassInterface & InstanceInterface + +function cloneClass>(OriginalClass: T): T { + class AnotherOriginalClass extends OriginalClass { + constructor(...args: any[]) { + super(...args) + } + } + return AnotherOriginalClass +} \ No newline at end of file From 3b086e181314b2c5b0381cd469a10027617e9c51 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Thu, 14 Oct 2021 06:07:58 +0000 Subject: [PATCH 10/60] Update package-lock.json --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 24f7f2f14b4..34f74eefbf7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -676,9 +676,9 @@ "dev": true }, "@types/node": { - "version": "16.10.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.4.tgz", - "integrity": "sha512-EITwVTX5B4nDjXjGeQAfXOrm+Jn+qNjDmyDRtWoD+wZsl/RDPRTFRKivs4Mt74iOFlLOrE5+Kf+p5yjyhm3+cA==", + "version": "16.10.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.9.tgz", + "integrity": "sha512-H9ReOt+yqIJPCutkTYjFjlyK6WEMQYT9hLZMlWtOjFQY2ItppsWZ6RJf8Aw+jz5qTYceuHvFgPIaKOHtLAEWBw==", "dev": true }, "@types/node-fetch": { From 5185ef55e3b7de92e5b8710f954506a59bdecb1f Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Thu, 14 Oct 2021 22:25:59 +0530 Subject: [PATCH 11/60] fix(suggestion): Remove 80001 from cjs/cts files. (#46270) * fix(suggestion): Remove 80001 from cjs/cts files. * tests: Cover more cases in a single file. * tests: Cover more cases in a single file. --- src/services/suggestionDiagnostics.ts | 4 ++- ...factorConvertToEs6Module_inCommonJsFile.ts | 31 +++++++++++++++++++ ...efactorConvertToEs6Module_module_node12.ts | 29 +++++++++++++++++ ...actorConvertToEs6Module_module_nodenext.ts | 29 +++++++++++++++++ 4 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_inCommonJsFile.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_module_node12.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_module_nodenext.ts diff --git a/src/services/suggestionDiagnostics.ts b/src/services/suggestionDiagnostics.ts index ebefddfd80d..1ca10245c72 100644 --- a/src/services/suggestionDiagnostics.ts +++ b/src/services/suggestionDiagnostics.ts @@ -6,8 +6,10 @@ namespace ts { program.getSemanticDiagnostics(sourceFile, cancellationToken); const diags: DiagnosticWithLocation[] = []; const checker = program.getTypeChecker(); + const isCommonJSFile = sourceFile.impliedNodeFormat === ModuleKind.CommonJS || fileExtensionIsOneOf(sourceFile.fileName, [Extension.Cts, Extension.Cjs]) ; - if (sourceFile.commonJsModuleIndicator && + if (!isCommonJSFile && + sourceFile.commonJsModuleIndicator && (programContainsEs6Modules(program) || compilerOptionsIndicateEs6Modules(program.getCompilerOptions())) && containsTopLevelCommonjs(sourceFile)) { diags.push(createDiagnosticForNode(getErrorNodeFromCommonJsIndicator(sourceFile.commonJsModuleIndicator), Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module)); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_inCommonJsFile.ts b/tests/cases/fourslash/refactorConvertToEs6Module_inCommonJsFile.ts new file mode 100644 index 00000000000..d56bdc303fb --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_inCommonJsFile.ts @@ -0,0 +1,31 @@ +/// + +// @allowJs: true +// @target: esnext + +// @Filename: /a.cjs +////module.exports = 0; + +// @Filename: /b.cts +////module.exports = 0; + +// @Filename: /c.ts +////module.exports = 0; + +// @Filename: /d.js +////module.exports = 0; + +goTo.file("/a.cjs"); +verify.codeFixAvailable([]); + +goTo.file("/b.cts"); +verify.codeFixAvailable([]); + +goTo.file("/c.ts"); +verify.codeFixAvailable([]); + +goTo.file("/d.js"); +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: 'export default 0;', +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_module_node12.ts b/tests/cases/fourslash/refactorConvertToEs6Module_module_node12.ts new file mode 100644 index 00000000000..a7be99ba157 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_module_node12.ts @@ -0,0 +1,29 @@ +/// + +// @allowJs: true +// @target: esnext +// @module: node12 + +// @Filename: /a.js +////module.exports = 0; + +// @Filename: /b.ts +////module.exports = 0; + +// @Filename: /c.cjs +////module.exports = 0; + +// @Filename: /d.cts +////module.exports = 0; + +goTo.file("/a.js"); +verify.codeFixAvailable([]); + +goTo.file("/b.ts"); +verify.codeFixAvailable([]); + +goTo.file("/c.cjs"); +verify.codeFixAvailable([]); + +goTo.file("/d.cts"); +verify.codeFixAvailable([]); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_module_nodenext.ts b/tests/cases/fourslash/refactorConvertToEs6Module_module_nodenext.ts new file mode 100644 index 00000000000..622c3168b2f --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_module_nodenext.ts @@ -0,0 +1,29 @@ +/// + +// @allowJs: true +// @target: esnext +// @module: nodenext + +// @Filename: /a.js +////module.exports = 0; + +// @Filename: /b.ts +////module.exports = 0; + +// @Filename: /c.cjs +////module.exports = 0; + +// @Filename: /d.cts +////module.exports = 0; + +goTo.file("/a.js"); +verify.codeFixAvailable([]); + +goTo.file("/b.ts"); +verify.codeFixAvailable([]); + +goTo.file("/c.cjs"); +verify.codeFixAvailable([]); + +goTo.file("/d.cts"); +verify.codeFixAvailable([]); \ No newline at end of file From 8718df3dc107204e1eeffb5f1f90849a70d8cecd Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 14 Oct 2021 10:11:44 -0700 Subject: [PATCH 12/60] Fix stack overflow in JSX discriminated union logic (#46354) * Use getContextFreeTypeOfExpression to avoid circularities * Add regression test --- src/compiler/checker.ts | 4 +- .../reference/discriminatedUnionJsxElement.js | 57 ++++++++++++++++ .../discriminatedUnionJsxElement.symbols | 67 +++++++++++++++++++ .../discriminatedUnionJsxElement.types | 57 ++++++++++++++++ .../compiler/discriminatedUnionJsxElement.tsx | 25 +++++++ 5 files changed, 208 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/discriminatedUnionJsxElement.js create mode 100644 tests/baselines/reference/discriminatedUnionJsxElement.symbols create mode 100644 tests/baselines/reference/discriminatedUnionJsxElement.types create mode 100644 tests/cases/compiler/discriminatedUnionJsxElement.tsx diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d4588d9551e..26ba5be32f6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -22691,7 +22691,7 @@ namespace ts { const keyPropertyName = getKeyPropertyName(unionType); const propNode = keyPropertyName && find(node.properties, p => p.symbol && p.kind === SyntaxKind.PropertyAssignment && p.symbol.escapedName === keyPropertyName && isPossiblyDiscriminantValue(p.initializer)); - const propType = propNode && getTypeOfExpression((propNode as PropertyAssignment).initializer); + const propType = propNode && getContextFreeTypeOfExpression((propNode as PropertyAssignment).initializer); return propType && getConstituentTypeForKeyType(unionType, propType); } @@ -26198,7 +26198,7 @@ namespace ts { concatenate( map( filter(node.properties, p => !!p.symbol && p.kind === SyntaxKind.JsxAttribute && isDiscriminantProperty(contextualType, p.symbol.escapedName) && (!p.initializer || isPossiblyDiscriminantValue(p.initializer))), - prop => ([!(prop as JsxAttribute).initializer ? (() => trueType) : (() => checkExpression((prop as JsxAttribute).initializer!)), prop.symbol.escapedName] as [() => Type, __String]) + prop => ([!(prop as JsxAttribute).initializer ? (() => trueType) : (() => getContextFreeTypeOfExpression((prop as JsxAttribute).initializer!)), prop.symbol.escapedName] as [() => Type, __String]) ), map( filter(getPropertiesOfType(contextualType), s => !!(s.flags & SymbolFlags.Optional) && !!node?.symbol?.members && !node.symbol.members.has(s.escapedName) && isDiscriminantProperty(contextualType, s.escapedName)), diff --git a/tests/baselines/reference/discriminatedUnionJsxElement.js b/tests/baselines/reference/discriminatedUnionJsxElement.js new file mode 100644 index 00000000000..ca5b766aac9 --- /dev/null +++ b/tests/baselines/reference/discriminatedUnionJsxElement.js @@ -0,0 +1,57 @@ +//// [discriminatedUnionJsxElement.tsx] +// Repro from #46021 + +interface IData { + menuItemsVariant?: MenuItemVariant; +} + +function Menu(data: IData) { + const listItemVariant = data.menuItemsVariant ?? ListItemVariant.OneLine; + return ; +} + +type IListItemData = { variant: ListItemVariant.Avatar; } | { variant: ListItemVariant.OneLine; }; + +enum ListItemVariant { + OneLine, + Avatar, +} + +function ListItem(_data: IListItemData) { + return null; +} + + +//// [discriminatedUnionJsxElement.jsx] +"use strict"; +// Repro from #46021 +function Menu(data) { + var _a; + var listItemVariant = (_a = data.menuItemsVariant) !== null && _a !== void 0 ? _a : ListItemVariant.OneLine; + return ; +} +var ListItemVariant; +(function (ListItemVariant) { + ListItemVariant[ListItemVariant["OneLine"] = 0] = "OneLine"; + ListItemVariant[ListItemVariant["Avatar"] = 1] = "Avatar"; +})(ListItemVariant || (ListItemVariant = {})); +function ListItem(_data) { + return null; +} + + +//// [discriminatedUnionJsxElement.d.ts] +interface IData { + menuItemsVariant?: MenuItemVariant; +} +declare function Menu(data: IData): any; +declare type IListItemData = { + variant: ListItemVariant.Avatar; +} | { + variant: ListItemVariant.OneLine; +}; +declare enum ListItemVariant { + OneLine = 0, + Avatar = 1 +} +declare function ListItem(_data: IListItemData): null; diff --git a/tests/baselines/reference/discriminatedUnionJsxElement.symbols b/tests/baselines/reference/discriminatedUnionJsxElement.symbols new file mode 100644 index 00000000000..aa884f5a1b0 --- /dev/null +++ b/tests/baselines/reference/discriminatedUnionJsxElement.symbols @@ -0,0 +1,67 @@ +=== tests/cases/compiler/discriminatedUnionJsxElement.tsx === +// Repro from #46021 + +interface IData { +>IData : Symbol(IData, Decl(discriminatedUnionJsxElement.tsx, 0, 0)) +>MenuItemVariant : Symbol(MenuItemVariant, Decl(discriminatedUnionJsxElement.tsx, 2, 16)) +>ListItemVariant : Symbol(ListItemVariant, Decl(discriminatedUnionJsxElement.tsx, 11, 98)) +>ListItemVariant : Symbol(ListItemVariant, Decl(discriminatedUnionJsxElement.tsx, 11, 98)) +>OneLine : Symbol(ListItemVariant.OneLine, Decl(discriminatedUnionJsxElement.tsx, 13, 22)) + + menuItemsVariant?: MenuItemVariant; +>menuItemsVariant : Symbol(IData.menuItemsVariant, Decl(discriminatedUnionJsxElement.tsx, 2, 84)) +>MenuItemVariant : Symbol(MenuItemVariant, Decl(discriminatedUnionJsxElement.tsx, 2, 16)) +} + +function Menu(data: IData) { +>Menu : Symbol(Menu, Decl(discriminatedUnionJsxElement.tsx, 4, 1)) +>MenuItemVariant : Symbol(MenuItemVariant, Decl(discriminatedUnionJsxElement.tsx, 6, 14)) +>ListItemVariant : Symbol(ListItemVariant, Decl(discriminatedUnionJsxElement.tsx, 11, 98)) +>ListItemVariant : Symbol(ListItemVariant, Decl(discriminatedUnionJsxElement.tsx, 11, 98)) +>OneLine : Symbol(ListItemVariant.OneLine, Decl(discriminatedUnionJsxElement.tsx, 13, 22)) +>data : Symbol(data, Decl(discriminatedUnionJsxElement.tsx, 6, 81)) +>IData : Symbol(IData, Decl(discriminatedUnionJsxElement.tsx, 0, 0)) +>MenuItemVariant : Symbol(MenuItemVariant, Decl(discriminatedUnionJsxElement.tsx, 6, 14)) + + const listItemVariant = data.menuItemsVariant ?? ListItemVariant.OneLine; +>listItemVariant : Symbol(listItemVariant, Decl(discriminatedUnionJsxElement.tsx, 7, 9)) +>data.menuItemsVariant : Symbol(IData.menuItemsVariant, Decl(discriminatedUnionJsxElement.tsx, 2, 84)) +>data : Symbol(data, Decl(discriminatedUnionJsxElement.tsx, 6, 81)) +>menuItemsVariant : Symbol(IData.menuItemsVariant, Decl(discriminatedUnionJsxElement.tsx, 2, 84)) +>ListItemVariant.OneLine : Symbol(ListItemVariant.OneLine, Decl(discriminatedUnionJsxElement.tsx, 13, 22)) +>ListItemVariant : Symbol(ListItemVariant, Decl(discriminatedUnionJsxElement.tsx, 11, 98)) +>OneLine : Symbol(ListItemVariant.OneLine, Decl(discriminatedUnionJsxElement.tsx, 13, 22)) + + return ; +>ListItem : Symbol(ListItem, Decl(discriminatedUnionJsxElement.tsx, 16, 1)) +>variant : Symbol(variant, Decl(discriminatedUnionJsxElement.tsx, 8, 20)) +>listItemVariant : Symbol(listItemVariant, Decl(discriminatedUnionJsxElement.tsx, 7, 9)) +} + +type IListItemData = { variant: ListItemVariant.Avatar; } | { variant: ListItemVariant.OneLine; }; +>IListItemData : Symbol(IListItemData, Decl(discriminatedUnionJsxElement.tsx, 9, 1)) +>variant : Symbol(variant, Decl(discriminatedUnionJsxElement.tsx, 11, 22)) +>ListItemVariant : Symbol(ListItemVariant, Decl(discriminatedUnionJsxElement.tsx, 11, 98)) +>Avatar : Symbol(ListItemVariant.Avatar, Decl(discriminatedUnionJsxElement.tsx, 14, 12)) +>variant : Symbol(variant, Decl(discriminatedUnionJsxElement.tsx, 11, 61)) +>ListItemVariant : Symbol(ListItemVariant, Decl(discriminatedUnionJsxElement.tsx, 11, 98)) +>OneLine : Symbol(ListItemVariant.OneLine, Decl(discriminatedUnionJsxElement.tsx, 13, 22)) + +enum ListItemVariant { +>ListItemVariant : Symbol(ListItemVariant, Decl(discriminatedUnionJsxElement.tsx, 11, 98)) + + OneLine, +>OneLine : Symbol(ListItemVariant.OneLine, Decl(discriminatedUnionJsxElement.tsx, 13, 22)) + + Avatar, +>Avatar : Symbol(ListItemVariant.Avatar, Decl(discriminatedUnionJsxElement.tsx, 14, 12)) +} + +function ListItem(_data: IListItemData) { +>ListItem : Symbol(ListItem, Decl(discriminatedUnionJsxElement.tsx, 16, 1)) +>_data : Symbol(_data, Decl(discriminatedUnionJsxElement.tsx, 18, 18)) +>IListItemData : Symbol(IListItemData, Decl(discriminatedUnionJsxElement.tsx, 9, 1)) + + return null; +} + diff --git a/tests/baselines/reference/discriminatedUnionJsxElement.types b/tests/baselines/reference/discriminatedUnionJsxElement.types new file mode 100644 index 00000000000..54ca2b4268f --- /dev/null +++ b/tests/baselines/reference/discriminatedUnionJsxElement.types @@ -0,0 +1,57 @@ +=== tests/cases/compiler/discriminatedUnionJsxElement.tsx === +// Repro from #46021 + +interface IData { +>ListItemVariant : any + + menuItemsVariant?: MenuItemVariant; +>menuItemsVariant : MenuItemVariant | undefined +} + +function Menu(data: IData) { +>Menu : (data: IData) => any +>ListItemVariant : any +>data : IData + + const listItemVariant = data.menuItemsVariant ?? ListItemVariant.OneLine; +>listItemVariant : ListItemVariant.OneLine | NonNullable +>data.menuItemsVariant ?? ListItemVariant.OneLine : ListItemVariant.OneLine | NonNullable +>data.menuItemsVariant : MenuItemVariant | undefined +>data : IData +>menuItemsVariant : MenuItemVariant | undefined +>ListItemVariant.OneLine : ListItemVariant.OneLine +>ListItemVariant : typeof ListItemVariant +>OneLine : ListItemVariant.OneLine + + return ; +> : error +>ListItem : (_data: IListItemData) => null +>variant : ListItemVariant +>listItemVariant : ListItemVariant +} + +type IListItemData = { variant: ListItemVariant.Avatar; } | { variant: ListItemVariant.OneLine; }; +>IListItemData : IListItemData +>variant : ListItemVariant.Avatar +>ListItemVariant : any +>variant : ListItemVariant.OneLine +>ListItemVariant : any + +enum ListItemVariant { +>ListItemVariant : ListItemVariant + + OneLine, +>OneLine : ListItemVariant.OneLine + + Avatar, +>Avatar : ListItemVariant.Avatar +} + +function ListItem(_data: IListItemData) { +>ListItem : (_data: IListItemData) => null +>_data : IListItemData + + return null; +>null : null +} + diff --git a/tests/cases/compiler/discriminatedUnionJsxElement.tsx b/tests/cases/compiler/discriminatedUnionJsxElement.tsx new file mode 100644 index 00000000000..b000c2fb2a0 --- /dev/null +++ b/tests/cases/compiler/discriminatedUnionJsxElement.tsx @@ -0,0 +1,25 @@ +// @strict: true +// @declaration: true +// @jsx: preserve + +// Repro from #46021 + +interface IData { + menuItemsVariant?: MenuItemVariant; +} + +function Menu(data: IData) { + const listItemVariant = data.menuItemsVariant ?? ListItemVariant.OneLine; + return ; +} + +type IListItemData = { variant: ListItemVariant.Avatar; } | { variant: ListItemVariant.OneLine; }; + +enum ListItemVariant { + OneLine, + Avatar, +} + +function ListItem(_data: IListItemData) { + return null; +} From 80e1a2924853f87926fc13d684920813499193e4 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Fri, 15 Oct 2021 00:23:50 +0300 Subject: [PATCH 13/60] fix(46305): omit converting jsx (react-jsx) spread attributes to Object.assign for ES2018 and up (#46317) --- src/compiler/transformers/jsx.ts | 132 +++++++----------- ...ReactEmitSpreadAttribute(target=es2015).js | 56 ++++++++ ...EmitSpreadAttribute(target=es2015).symbols | 99 +++++++++++++ ...ctEmitSpreadAttribute(target=es2015).types | 117 ++++++++++++++++ ...ReactEmitSpreadAttribute(target=es2018).js | 56 ++++++++ ...EmitSpreadAttribute(target=es2018).symbols | 99 +++++++++++++ ...ctEmitSpreadAttribute(target=es2018).types | 117 ++++++++++++++++ ...ReactEmitSpreadAttribute(target=esnext).js | 56 ++++++++ ...EmitSpreadAttribute(target=esnext).symbols | 99 +++++++++++++ ...ctEmitSpreadAttribute(target=esnext).types | 117 ++++++++++++++++ .../jsx/tsxReactEmitSpreadAttribute.ts | 32 +++++ 11 files changed, 898 insertions(+), 82 deletions(-) create mode 100644 tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).js create mode 100644 tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).symbols create mode 100644 tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).types create mode 100644 tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).js create mode 100644 tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).symbols create mode 100644 tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).types create mode 100644 tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).js create mode 100644 tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).symbols create mode 100644 tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).types create mode 100644 tests/cases/conformance/jsx/tsxReactEmitSpreadAttribute.ts diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index ef296d779a9..166a91dfa69 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -200,59 +200,27 @@ namespace ts { } function convertJsxChildrenToChildrenPropObject(children: readonly JsxChild[]) { + const prop = convertJsxChildrenToChildrenPropAssignment(children); + return prop && factory.createObjectLiteralExpression([prop]); + } + + function convertJsxChildrenToChildrenPropAssignment(children: readonly JsxChild[]) { const nonWhitespaceChildren = getSemanticJsxChildren(children); if (length(nonWhitespaceChildren) === 1) { const result = transformJsxChildToExpression(nonWhitespaceChildren[0]); - return result && factory.createObjectLiteralExpression([ - factory.createPropertyAssignment("children", result) - ]); + return result && factory.createPropertyAssignment("children", result); } const result = mapDefined(children, transformJsxChildToExpression); - return !result.length ? undefined : factory.createObjectLiteralExpression([ - factory.createPropertyAssignment("children", factory.createArrayLiteralExpression(result)) - ]); + return length(result) ? factory.createPropertyAssignment("children", factory.createArrayLiteralExpression(result)) : undefined; } function visitJsxOpeningLikeElementJSX(node: JsxOpeningLikeElement, children: readonly JsxChild[] | undefined, isChild: boolean, location: TextRange) { const tagName = getTagName(node); - let objectProperties: Expression; + const childrenProp = children && children.length ? convertJsxChildrenToChildrenPropAssignment(children) : undefined; const keyAttr = find(node.attributes.properties, p => !!p.name && isIdentifier(p.name) && p.name.escapedText === "key") as JsxAttribute | undefined; const attrs = keyAttr ? filter(node.attributes.properties, p => p !== keyAttr) : node.attributes.properties; - - let segments: Expression[] = []; - if (attrs.length) { - // Map spans of JsxAttribute nodes into object literals and spans - // of JsxSpreadAttribute nodes into expressions. - segments = flatten( - spanMap(attrs, isJsxSpreadAttribute, (attrs, isSpread) => isSpread - ? map(attrs, transformJsxSpreadAttributeToExpression) - : factory.createObjectLiteralExpression(map(attrs, transformJsxAttributeToObjectLiteralElement)) - ) - ); - - if (isJsxSpreadAttribute(attrs[0])) { - // We must always emit at least one object literal before a spread - // argument.factory.createObjectLiteral - segments.unshift(factory.createObjectLiteralExpression()); - } - } - if (children && children.length) { - const result = convertJsxChildrenToChildrenPropObject(children); - if (result) { - segments.push(result); - } - } - - if (segments.length === 0) { - objectProperties = factory.createObjectLiteralExpression([]); - // When there are no attributes, React wants {} - } - else { - // Either emit one big object literal (no spread attribs), or - // a call to the __assign helper. - objectProperties = singleOrUndefined(segments) || emitHelpers().createAssignHelper(segments); - } - + const objectProperties = length(attrs) ? transformJsxAttributesToObjectProps(attrs, childrenProp) : + factory.createObjectLiteralExpression(childrenProp ? [childrenProp] : emptyArray); // When there are no attributes, React wants {} return visitJsxOpeningLikeElementOrFragmentJSX(tagName, objectProperties, keyAttr, length(getSemanticJsxChildren(children || emptyArray)), isChild, location); } @@ -285,47 +253,9 @@ namespace ts { function visitJsxOpeningLikeElementCreateElement(node: JsxOpeningLikeElement, children: readonly JsxChild[] | undefined, isChild: boolean, location: TextRange) { const tagName = getTagName(node); - let objectProperties: Expression | undefined; const attrs = node.attributes.properties; - if (attrs.length === 0) { - objectProperties = factory.createNull(); - // When there are no attributes, React wants "null" - } - else { - const target = getEmitScriptTarget(compilerOptions); - if (target && target >= ScriptTarget.ES2018) { - objectProperties = factory.createObjectLiteralExpression( - flatten( - spanMap(attrs, isJsxSpreadAttribute, (attrs, isSpread) => - isSpread ? map(attrs, transformJsxSpreadAttributeToSpreadAssignment) : map(attrs, transformJsxAttributeToObjectLiteralElement) - ) - ) - ); - } - else { - // Map spans of JsxAttribute nodes into object literals and spans - // of JsxSpreadAttribute nodes into expressions. - const segments = flatten( - spanMap(attrs, isJsxSpreadAttribute, (attrs, isSpread) => isSpread - ? map(attrs, transformJsxSpreadAttributeToExpression) - : factory.createObjectLiteralExpression(map(attrs, transformJsxAttributeToObjectLiteralElement)) - ) - ); - - if (isJsxSpreadAttribute(attrs[0])) { - // We must always emit at least one object literal before a spread - // argument.factory.createObjectLiteral - segments.unshift(factory.createObjectLiteralExpression()); - } - - // Either emit one big object literal (no spread attribs), or - // a call to the __assign helper. - objectProperties = singleOrUndefined(segments); - if (!objectProperties) { - objectProperties = emitHelpers().createAssignHelper(segments); - } - } - } + const objectProperties = length(attrs) ? transformJsxAttributesToObjectProps(attrs) : + factory.createNull(); // When there are no attributes, React wants "null" const callee = currentFileState.importSpecifier === undefined ? createJsxFactoryExpression( @@ -392,6 +322,44 @@ namespace ts { return factory.createSpreadAssignment(visitNode(node.expression, visitor, isExpression)); } + function transformJsxAttributesToObjectProps(attrs: readonly(JsxSpreadAttribute | JsxAttribute)[], children?: PropertyAssignment) { + const target = getEmitScriptTarget(compilerOptions); + return target && target >= ScriptTarget.ES2018 ? factory.createObjectLiteralExpression(transformJsxAttributesToProps(attrs, children)) : + transformJsxAttributesToExpression(attrs, children); + } + + function transformJsxAttributesToProps(attrs: readonly(JsxSpreadAttribute | JsxAttribute)[], children?: PropertyAssignment) { + const props = flatten(spanMap(attrs, isJsxSpreadAttribute, (attrs, isSpread) => + map(attrs, attr => isSpread ? transformJsxSpreadAttributeToSpreadAssignment(attr as JsxSpreadAttribute) : transformJsxAttributeToObjectLiteralElement(attr as JsxAttribute)))); + if (children) { + props.push(children); + } + return props; + } + + function transformJsxAttributesToExpression(attrs: readonly(JsxSpreadAttribute | JsxAttribute)[], children?: PropertyAssignment) { + // Map spans of JsxAttribute nodes into object literals and spans + // of JsxSpreadAttribute nodes into expressions. + const expressions = flatten( + spanMap(attrs, isJsxSpreadAttribute, (attrs, isSpread) => isSpread + ? map(attrs, transformJsxSpreadAttributeToExpression) + : factory.createObjectLiteralExpression(map(attrs, transformJsxAttributeToObjectLiteralElement)) + ) + ); + + if (isJsxSpreadAttribute(attrs[0])) { + // We must always emit at least one object literal before a spread + // argument.factory.createObjectLiteral + expressions.unshift(factory.createObjectLiteralExpression()); + } + + if (children) { + expressions.push(factory.createObjectLiteralExpression([children])); + } + + return singleOrUndefined(expressions) || emitHelpers().createAssignHelper(expressions); + } + function transformJsxSpreadAttributeToExpression(node: JsxSpreadAttribute) { return visitNode(node.expression, visitor, isExpression); } diff --git a/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).js b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).js new file mode 100644 index 00000000000..24705934a29 --- /dev/null +++ b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).js @@ -0,0 +1,56 @@ +//// [test.tsx] +/// + +export function T1(a: any) { + return
T1
; +} + +export function T2(a: any, b: any) { + return
T2
; +} + +export function T3(a: any, b: any) { + return
T3
; +} + +export function T4(a: any, b: any) { + return
T4
; +} + +export function T5(a: any, b: any, c: any, d: any) { + return
T5
; +} + +export function T6(a: any, b: any, c: any, d: any) { + return
T6
; +} + +export function T7(a: any, b: any, c: any, d: any) { + return
T7
; +} + + +//// [test.js] +import { jsx as _jsx } from "react/jsx-runtime"; +/// +export function T1(a) { + return _jsx("div", Object.assign({ className: "T1" }, a, { children: "T1" }), void 0); +} +export function T2(a, b) { + return _jsx("div", Object.assign({ className: "T2" }, a, b, { children: "T2" }), void 0); +} +export function T3(a, b) { + return _jsx("div", Object.assign({}, a, { className: "T3" }, b, { children: "T3" }), void 0); +} +export function T4(a, b) { + return _jsx("div", Object.assign({ className: "T4" }, Object.assign(Object.assign({}, a), b), { children: "T4" }), void 0); +} +export function T5(a, b, c, d) { + return _jsx("div", Object.assign({ className: "T5" }, Object.assign(Object.assign(Object.assign({}, a), b), { c, d }), { children: "T5" }), void 0); +} +export function T6(a, b, c, d) { + return _jsx("div", Object.assign({ className: "T6" }, Object.assign(Object.assign(Object.assign({}, a), b), Object.assign(Object.assign({}, c), d)), { children: "T6" }), void 0); +} +export function T7(a, b, c, d) { + return _jsx("div", { children: "T7" }, void 0); +} diff --git a/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).symbols b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).symbols new file mode 100644 index 00000000000..09b030724b8 --- /dev/null +++ b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).symbols @@ -0,0 +1,99 @@ +=== tests/cases/conformance/jsx/test.tsx === +/// + +export function T1(a: any) { +>T1 : Symbol(T1, Decl(test.tsx, 0, 0)) +>a : Symbol(a, Decl(test.tsx, 2, 19)) + + return
T1
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 3, 15)) +>a : Symbol(a, Decl(test.tsx, 2, 19)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T2(a: any, b: any) { +>T2 : Symbol(T2, Decl(test.tsx, 4, 1)) +>a : Symbol(a, Decl(test.tsx, 6, 19)) +>b : Symbol(b, Decl(test.tsx, 6, 26)) + + return
T2
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 7, 15)) +>a : Symbol(a, Decl(test.tsx, 6, 19)) +>b : Symbol(b, Decl(test.tsx, 6, 26)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T3(a: any, b: any) { +>T3 : Symbol(T3, Decl(test.tsx, 8, 1)) +>a : Symbol(a, Decl(test.tsx, 10, 19)) +>b : Symbol(b, Decl(test.tsx, 10, 26)) + + return
T3
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>a : Symbol(a, Decl(test.tsx, 10, 19)) +>className : Symbol(className, Decl(test.tsx, 11, 24)) +>b : Symbol(b, Decl(test.tsx, 10, 26)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T4(a: any, b: any) { +>T4 : Symbol(T4, Decl(test.tsx, 12, 1)) +>a : Symbol(a, Decl(test.tsx, 14, 19)) +>b : Symbol(b, Decl(test.tsx, 14, 26)) + + return
T4
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 15, 15)) +>a : Symbol(a, Decl(test.tsx, 14, 19)) +>b : Symbol(b, Decl(test.tsx, 14, 26)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T5(a: any, b: any, c: any, d: any) { +>T5 : Symbol(T5, Decl(test.tsx, 16, 1)) +>a : Symbol(a, Decl(test.tsx, 18, 19)) +>b : Symbol(b, Decl(test.tsx, 18, 26)) +>c : Symbol(c, Decl(test.tsx, 18, 34)) +>d : Symbol(d, Decl(test.tsx, 18, 42)) + + return
T5
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 19, 15)) +>a : Symbol(a, Decl(test.tsx, 18, 19)) +>b : Symbol(b, Decl(test.tsx, 18, 26)) +>c : Symbol(c, Decl(test.tsx, 19, 56)) +>d : Symbol(d, Decl(test.tsx, 19, 59)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T6(a: any, b: any, c: any, d: any) { +>T6 : Symbol(T6, Decl(test.tsx, 20, 1)) +>a : Symbol(a, Decl(test.tsx, 22, 19)) +>b : Symbol(b, Decl(test.tsx, 22, 26)) +>c : Symbol(c, Decl(test.tsx, 22, 34)) +>d : Symbol(d, Decl(test.tsx, 22, 42)) + + return
T6
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 23, 15)) +>a : Symbol(a, Decl(test.tsx, 22, 19)) +>b : Symbol(b, Decl(test.tsx, 22, 26)) +>c : Symbol(c, Decl(test.tsx, 22, 34)) +>d : Symbol(d, Decl(test.tsx, 22, 42)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T7(a: any, b: any, c: any, d: any) { +>T7 : Symbol(T7, Decl(test.tsx, 24, 1)) +>a : Symbol(a, Decl(test.tsx, 26, 19)) +>b : Symbol(b, Decl(test.tsx, 26, 26)) +>c : Symbol(c, Decl(test.tsx, 26, 34)) +>d : Symbol(d, Decl(test.tsx, 26, 42)) + + return
T7
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + diff --git a/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).types b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).types new file mode 100644 index 00000000000..7fc232939b0 --- /dev/null +++ b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).types @@ -0,0 +1,117 @@ +=== tests/cases/conformance/jsx/test.tsx === +/// + +export function T1(a: any) { +>T1 : (a: any) => JSX.Element +>a : any + + return
T1
; +>
T1
: JSX.Element +>div : any +>className : string +>"T1" : "T1" +>a : any +>div : any +} + +export function T2(a: any, b: any) { +>T2 : (a: any, b: any) => JSX.Element +>a : any +>b : any + + return
T2
; +>
T2
: JSX.Element +>div : any +>className : string +>"T2" : "T2" +>a : any +>b : any +>div : any +} + +export function T3(a: any, b: any) { +>T3 : (a: any, b: any) => JSX.Element +>a : any +>b : any + + return
T3
; +>
T3
: JSX.Element +>div : any +>a : any +>className : string +>"T3" : "T3" +>b : any +>div : any +} + +export function T4(a: any, b: any) { +>T4 : (a: any, b: any) => JSX.Element +>a : any +>b : any + + return
T4
; +>
T4
: JSX.Element +>div : any +>className : string +>"T4" : "T4" +>{ ...a, ...b } : any +>a : any +>b : any +>div : any +} + +export function T5(a: any, b: any, c: any, d: any) { +>T5 : (a: any, b: any, c: any, d: any) => JSX.Element +>a : any +>b : any +>c : any +>d : any + + return
T5
; +>
T5
: JSX.Element +>div : any +>className : string +>"T5" : "T5" +>{ ...a, ...b, ...{ c, d } } : any +>a : any +>b : any +>{ c, d } : { c: any; d: any; } +>c : any +>d : any +>div : any +} + +export function T6(a: any, b: any, c: any, d: any) { +>T6 : (a: any, b: any, c: any, d: any) => JSX.Element +>a : any +>b : any +>c : any +>d : any + + return
T6
; +>
T6
: JSX.Element +>div : any +>className : string +>"T6" : "T6" +>{ ...a, ...b, ...{ ...c, ...d } } : any +>a : any +>b : any +>{ ...c, ...d } : any +>c : any +>d : any +>div : any +} + +export function T7(a: any, b: any, c: any, d: any) { +>T7 : (a: any, b: any, c: any, d: any) => JSX.Element +>a : any +>b : any +>c : any +>d : any + + return
T7
; +>
T7
: JSX.Element +>div : any +>div : any +} + diff --git a/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).js b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).js new file mode 100644 index 00000000000..5e870a365bc --- /dev/null +++ b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).js @@ -0,0 +1,56 @@ +//// [test.tsx] +/// + +export function T1(a: any) { + return
T1
; +} + +export function T2(a: any, b: any) { + return
T2
; +} + +export function T3(a: any, b: any) { + return
T3
; +} + +export function T4(a: any, b: any) { + return
T4
; +} + +export function T5(a: any, b: any, c: any, d: any) { + return
T5
; +} + +export function T6(a: any, b: any, c: any, d: any) { + return
T6
; +} + +export function T7(a: any, b: any, c: any, d: any) { + return
T7
; +} + + +//// [test.js] +import { jsx as _jsx } from "react/jsx-runtime"; +/// +export function T1(a) { + return _jsx("div", { className: "T1", ...a, children: "T1" }, void 0); +} +export function T2(a, b) { + return _jsx("div", { className: "T2", ...a, ...b, children: "T2" }, void 0); +} +export function T3(a, b) { + return _jsx("div", { ...a, className: "T3", ...b, children: "T3" }, void 0); +} +export function T4(a, b) { + return _jsx("div", { className: "T4", ...{ ...a, ...b }, children: "T4" }, void 0); +} +export function T5(a, b, c, d) { + return _jsx("div", { className: "T5", ...{ ...a, ...b, ...{ c, d } }, children: "T5" }, void 0); +} +export function T6(a, b, c, d) { + return _jsx("div", { className: "T6", ...{ ...a, ...b, ...{ ...c, ...d } }, children: "T6" }, void 0); +} +export function T7(a, b, c, d) { + return _jsx("div", { children: "T7" }, void 0); +} diff --git a/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).symbols b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).symbols new file mode 100644 index 00000000000..09b030724b8 --- /dev/null +++ b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).symbols @@ -0,0 +1,99 @@ +=== tests/cases/conformance/jsx/test.tsx === +/// + +export function T1(a: any) { +>T1 : Symbol(T1, Decl(test.tsx, 0, 0)) +>a : Symbol(a, Decl(test.tsx, 2, 19)) + + return
T1
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 3, 15)) +>a : Symbol(a, Decl(test.tsx, 2, 19)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T2(a: any, b: any) { +>T2 : Symbol(T2, Decl(test.tsx, 4, 1)) +>a : Symbol(a, Decl(test.tsx, 6, 19)) +>b : Symbol(b, Decl(test.tsx, 6, 26)) + + return
T2
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 7, 15)) +>a : Symbol(a, Decl(test.tsx, 6, 19)) +>b : Symbol(b, Decl(test.tsx, 6, 26)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T3(a: any, b: any) { +>T3 : Symbol(T3, Decl(test.tsx, 8, 1)) +>a : Symbol(a, Decl(test.tsx, 10, 19)) +>b : Symbol(b, Decl(test.tsx, 10, 26)) + + return
T3
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>a : Symbol(a, Decl(test.tsx, 10, 19)) +>className : Symbol(className, Decl(test.tsx, 11, 24)) +>b : Symbol(b, Decl(test.tsx, 10, 26)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T4(a: any, b: any) { +>T4 : Symbol(T4, Decl(test.tsx, 12, 1)) +>a : Symbol(a, Decl(test.tsx, 14, 19)) +>b : Symbol(b, Decl(test.tsx, 14, 26)) + + return
T4
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 15, 15)) +>a : Symbol(a, Decl(test.tsx, 14, 19)) +>b : Symbol(b, Decl(test.tsx, 14, 26)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T5(a: any, b: any, c: any, d: any) { +>T5 : Symbol(T5, Decl(test.tsx, 16, 1)) +>a : Symbol(a, Decl(test.tsx, 18, 19)) +>b : Symbol(b, Decl(test.tsx, 18, 26)) +>c : Symbol(c, Decl(test.tsx, 18, 34)) +>d : Symbol(d, Decl(test.tsx, 18, 42)) + + return
T5
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 19, 15)) +>a : Symbol(a, Decl(test.tsx, 18, 19)) +>b : Symbol(b, Decl(test.tsx, 18, 26)) +>c : Symbol(c, Decl(test.tsx, 19, 56)) +>d : Symbol(d, Decl(test.tsx, 19, 59)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T6(a: any, b: any, c: any, d: any) { +>T6 : Symbol(T6, Decl(test.tsx, 20, 1)) +>a : Symbol(a, Decl(test.tsx, 22, 19)) +>b : Symbol(b, Decl(test.tsx, 22, 26)) +>c : Symbol(c, Decl(test.tsx, 22, 34)) +>d : Symbol(d, Decl(test.tsx, 22, 42)) + + return
T6
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 23, 15)) +>a : Symbol(a, Decl(test.tsx, 22, 19)) +>b : Symbol(b, Decl(test.tsx, 22, 26)) +>c : Symbol(c, Decl(test.tsx, 22, 34)) +>d : Symbol(d, Decl(test.tsx, 22, 42)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T7(a: any, b: any, c: any, d: any) { +>T7 : Symbol(T7, Decl(test.tsx, 24, 1)) +>a : Symbol(a, Decl(test.tsx, 26, 19)) +>b : Symbol(b, Decl(test.tsx, 26, 26)) +>c : Symbol(c, Decl(test.tsx, 26, 34)) +>d : Symbol(d, Decl(test.tsx, 26, 42)) + + return
T7
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + diff --git a/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).types b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).types new file mode 100644 index 00000000000..7fc232939b0 --- /dev/null +++ b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).types @@ -0,0 +1,117 @@ +=== tests/cases/conformance/jsx/test.tsx === +/// + +export function T1(a: any) { +>T1 : (a: any) => JSX.Element +>a : any + + return
T1
; +>
T1
: JSX.Element +>div : any +>className : string +>"T1" : "T1" +>a : any +>div : any +} + +export function T2(a: any, b: any) { +>T2 : (a: any, b: any) => JSX.Element +>a : any +>b : any + + return
T2
; +>
T2
: JSX.Element +>div : any +>className : string +>"T2" : "T2" +>a : any +>b : any +>div : any +} + +export function T3(a: any, b: any) { +>T3 : (a: any, b: any) => JSX.Element +>a : any +>b : any + + return
T3
; +>
T3
: JSX.Element +>div : any +>a : any +>className : string +>"T3" : "T3" +>b : any +>div : any +} + +export function T4(a: any, b: any) { +>T4 : (a: any, b: any) => JSX.Element +>a : any +>b : any + + return
T4
; +>
T4
: JSX.Element +>div : any +>className : string +>"T4" : "T4" +>{ ...a, ...b } : any +>a : any +>b : any +>div : any +} + +export function T5(a: any, b: any, c: any, d: any) { +>T5 : (a: any, b: any, c: any, d: any) => JSX.Element +>a : any +>b : any +>c : any +>d : any + + return
T5
; +>
T5
: JSX.Element +>div : any +>className : string +>"T5" : "T5" +>{ ...a, ...b, ...{ c, d } } : any +>a : any +>b : any +>{ c, d } : { c: any; d: any; } +>c : any +>d : any +>div : any +} + +export function T6(a: any, b: any, c: any, d: any) { +>T6 : (a: any, b: any, c: any, d: any) => JSX.Element +>a : any +>b : any +>c : any +>d : any + + return
T6
; +>
T6
: JSX.Element +>div : any +>className : string +>"T6" : "T6" +>{ ...a, ...b, ...{ ...c, ...d } } : any +>a : any +>b : any +>{ ...c, ...d } : any +>c : any +>d : any +>div : any +} + +export function T7(a: any, b: any, c: any, d: any) { +>T7 : (a: any, b: any, c: any, d: any) => JSX.Element +>a : any +>b : any +>c : any +>d : any + + return
T7
; +>
T7
: JSX.Element +>div : any +>div : any +} + diff --git a/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).js b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).js new file mode 100644 index 00000000000..5e870a365bc --- /dev/null +++ b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).js @@ -0,0 +1,56 @@ +//// [test.tsx] +/// + +export function T1(a: any) { + return
T1
; +} + +export function T2(a: any, b: any) { + return
T2
; +} + +export function T3(a: any, b: any) { + return
T3
; +} + +export function T4(a: any, b: any) { + return
T4
; +} + +export function T5(a: any, b: any, c: any, d: any) { + return
T5
; +} + +export function T6(a: any, b: any, c: any, d: any) { + return
T6
; +} + +export function T7(a: any, b: any, c: any, d: any) { + return
T7
; +} + + +//// [test.js] +import { jsx as _jsx } from "react/jsx-runtime"; +/// +export function T1(a) { + return _jsx("div", { className: "T1", ...a, children: "T1" }, void 0); +} +export function T2(a, b) { + return _jsx("div", { className: "T2", ...a, ...b, children: "T2" }, void 0); +} +export function T3(a, b) { + return _jsx("div", { ...a, className: "T3", ...b, children: "T3" }, void 0); +} +export function T4(a, b) { + return _jsx("div", { className: "T4", ...{ ...a, ...b }, children: "T4" }, void 0); +} +export function T5(a, b, c, d) { + return _jsx("div", { className: "T5", ...{ ...a, ...b, ...{ c, d } }, children: "T5" }, void 0); +} +export function T6(a, b, c, d) { + return _jsx("div", { className: "T6", ...{ ...a, ...b, ...{ ...c, ...d } }, children: "T6" }, void 0); +} +export function T7(a, b, c, d) { + return _jsx("div", { children: "T7" }, void 0); +} diff --git a/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).symbols b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).symbols new file mode 100644 index 00000000000..09b030724b8 --- /dev/null +++ b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).symbols @@ -0,0 +1,99 @@ +=== tests/cases/conformance/jsx/test.tsx === +/// + +export function T1(a: any) { +>T1 : Symbol(T1, Decl(test.tsx, 0, 0)) +>a : Symbol(a, Decl(test.tsx, 2, 19)) + + return
T1
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 3, 15)) +>a : Symbol(a, Decl(test.tsx, 2, 19)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T2(a: any, b: any) { +>T2 : Symbol(T2, Decl(test.tsx, 4, 1)) +>a : Symbol(a, Decl(test.tsx, 6, 19)) +>b : Symbol(b, Decl(test.tsx, 6, 26)) + + return
T2
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 7, 15)) +>a : Symbol(a, Decl(test.tsx, 6, 19)) +>b : Symbol(b, Decl(test.tsx, 6, 26)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T3(a: any, b: any) { +>T3 : Symbol(T3, Decl(test.tsx, 8, 1)) +>a : Symbol(a, Decl(test.tsx, 10, 19)) +>b : Symbol(b, Decl(test.tsx, 10, 26)) + + return
T3
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>a : Symbol(a, Decl(test.tsx, 10, 19)) +>className : Symbol(className, Decl(test.tsx, 11, 24)) +>b : Symbol(b, Decl(test.tsx, 10, 26)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T4(a: any, b: any) { +>T4 : Symbol(T4, Decl(test.tsx, 12, 1)) +>a : Symbol(a, Decl(test.tsx, 14, 19)) +>b : Symbol(b, Decl(test.tsx, 14, 26)) + + return
T4
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 15, 15)) +>a : Symbol(a, Decl(test.tsx, 14, 19)) +>b : Symbol(b, Decl(test.tsx, 14, 26)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T5(a: any, b: any, c: any, d: any) { +>T5 : Symbol(T5, Decl(test.tsx, 16, 1)) +>a : Symbol(a, Decl(test.tsx, 18, 19)) +>b : Symbol(b, Decl(test.tsx, 18, 26)) +>c : Symbol(c, Decl(test.tsx, 18, 34)) +>d : Symbol(d, Decl(test.tsx, 18, 42)) + + return
T5
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 19, 15)) +>a : Symbol(a, Decl(test.tsx, 18, 19)) +>b : Symbol(b, Decl(test.tsx, 18, 26)) +>c : Symbol(c, Decl(test.tsx, 19, 56)) +>d : Symbol(d, Decl(test.tsx, 19, 59)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T6(a: any, b: any, c: any, d: any) { +>T6 : Symbol(T6, Decl(test.tsx, 20, 1)) +>a : Symbol(a, Decl(test.tsx, 22, 19)) +>b : Symbol(b, Decl(test.tsx, 22, 26)) +>c : Symbol(c, Decl(test.tsx, 22, 34)) +>d : Symbol(d, Decl(test.tsx, 22, 42)) + + return
T6
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 23, 15)) +>a : Symbol(a, Decl(test.tsx, 22, 19)) +>b : Symbol(b, Decl(test.tsx, 22, 26)) +>c : Symbol(c, Decl(test.tsx, 22, 34)) +>d : Symbol(d, Decl(test.tsx, 22, 42)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T7(a: any, b: any, c: any, d: any) { +>T7 : Symbol(T7, Decl(test.tsx, 24, 1)) +>a : Symbol(a, Decl(test.tsx, 26, 19)) +>b : Symbol(b, Decl(test.tsx, 26, 26)) +>c : Symbol(c, Decl(test.tsx, 26, 34)) +>d : Symbol(d, Decl(test.tsx, 26, 42)) + + return
T7
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + diff --git a/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).types b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).types new file mode 100644 index 00000000000..7fc232939b0 --- /dev/null +++ b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).types @@ -0,0 +1,117 @@ +=== tests/cases/conformance/jsx/test.tsx === +/// + +export function T1(a: any) { +>T1 : (a: any) => JSX.Element +>a : any + + return
T1
; +>
T1
: JSX.Element +>div : any +>className : string +>"T1" : "T1" +>a : any +>div : any +} + +export function T2(a: any, b: any) { +>T2 : (a: any, b: any) => JSX.Element +>a : any +>b : any + + return
T2
; +>
T2
: JSX.Element +>div : any +>className : string +>"T2" : "T2" +>a : any +>b : any +>div : any +} + +export function T3(a: any, b: any) { +>T3 : (a: any, b: any) => JSX.Element +>a : any +>b : any + + return
T3
; +>
T3
: JSX.Element +>div : any +>a : any +>className : string +>"T3" : "T3" +>b : any +>div : any +} + +export function T4(a: any, b: any) { +>T4 : (a: any, b: any) => JSX.Element +>a : any +>b : any + + return
T4
; +>
T4
: JSX.Element +>div : any +>className : string +>"T4" : "T4" +>{ ...a, ...b } : any +>a : any +>b : any +>div : any +} + +export function T5(a: any, b: any, c: any, d: any) { +>T5 : (a: any, b: any, c: any, d: any) => JSX.Element +>a : any +>b : any +>c : any +>d : any + + return
T5
; +>
T5
: JSX.Element +>div : any +>className : string +>"T5" : "T5" +>{ ...a, ...b, ...{ c, d } } : any +>a : any +>b : any +>{ c, d } : { c: any; d: any; } +>c : any +>d : any +>div : any +} + +export function T6(a: any, b: any, c: any, d: any) { +>T6 : (a: any, b: any, c: any, d: any) => JSX.Element +>a : any +>b : any +>c : any +>d : any + + return
T6
; +>
T6
: JSX.Element +>div : any +>className : string +>"T6" : "T6" +>{ ...a, ...b, ...{ ...c, ...d } } : any +>a : any +>b : any +>{ ...c, ...d } : any +>c : any +>d : any +>div : any +} + +export function T7(a: any, b: any, c: any, d: any) { +>T7 : (a: any, b: any, c: any, d: any) => JSX.Element +>a : any +>b : any +>c : any +>d : any + + return
T7
; +>
T7
: JSX.Element +>div : any +>div : any +} + diff --git a/tests/cases/conformance/jsx/tsxReactEmitSpreadAttribute.ts b/tests/cases/conformance/jsx/tsxReactEmitSpreadAttribute.ts new file mode 100644 index 00000000000..2ddc20ae39f --- /dev/null +++ b/tests/cases/conformance/jsx/tsxReactEmitSpreadAttribute.ts @@ -0,0 +1,32 @@ +// @jsx: react-jsx +// @target: es2015,es2018,esnext +// @filename: test.tsx +/// + +export function T1(a: any) { + return
T1
; +} + +export function T2(a: any, b: any) { + return
T2
; +} + +export function T3(a: any, b: any) { + return
T3
; +} + +export function T4(a: any, b: any) { + return
T4
; +} + +export function T5(a: any, b: any, c: any, d: any) { + return
T5
; +} + +export function T6(a: any, b: any, c: any, d: any) { + return
T6
; +} + +export function T7(a: any, b: any, c: any, d: any) { + return
T7
; +} From d16d7779a817f1c0b247b19cef10eeab7f031d6f Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 14 Oct 2021 15:22:59 -0700 Subject: [PATCH 14/60] No error for markdown links in @see (#46348) This only shows up in checkJS files, but should still be ignored. --- src/compiler/parser.ts | 5 +++-- tests/baselines/reference/seeTag3.js | 10 ++++++++++ tests/baselines/reference/seeTag3.symbols | 6 ++++++ tests/baselines/reference/seeTag3.types | 6 ++++++ tests/cases/conformance/jsdoc/seeTag3.ts | 7 +++++++ 5 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/seeTag3.js create mode 100644 tests/baselines/reference/seeTag3.symbols create mode 100644 tests/baselines/reference/seeTag3.types create mode 100644 tests/cases/conformance/jsdoc/seeTag3.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 4182d621cfa..6d94ef225b1 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -8256,8 +8256,9 @@ namespace ts { } function parseSeeTag(start: number, tagName: Identifier, indent?: number, indentText?: string): JSDocSeeTag { - const isLink = lookAhead(() => nextTokenJSDoc() === SyntaxKind.AtToken && tokenIsIdentifierOrKeyword(nextTokenJSDoc()) && scanner.getTokenValue() === "link"); - const nameExpression = isLink ? undefined : parseJSDocNameReference(); + const isMarkdownOrJSDocLink = token() === SyntaxKind.OpenBracketToken + || lookAhead(() => nextTokenJSDoc() === SyntaxKind.AtToken && tokenIsIdentifierOrKeyword(nextTokenJSDoc()) && scanner.getTokenValue() === "link"); + const nameExpression = isMarkdownOrJSDocLink ? undefined : parseJSDocNameReference(); const comments = indent !== undefined && indentText !== undefined ? parseTrailingTagComments(start, getNodePos(), indent, indentText) : undefined; return finishNode(factory.createJSDocSeeTag(tagName, nameExpression, comments), start); } diff --git a/tests/baselines/reference/seeTag3.js b/tests/baselines/reference/seeTag3.js new file mode 100644 index 00000000000..7d13f07d667 --- /dev/null +++ b/tests/baselines/reference/seeTag3.js @@ -0,0 +1,10 @@ +//// [seeTag3.js] +/** @see [The typescript web site](https://typescriptlang.org) */ +function theWholeThing() { +} + + +//// [seeTag3.js] +/** @see [The typescript web site](https://typescriptlang.org) */ +function theWholeThing() { +} diff --git a/tests/baselines/reference/seeTag3.symbols b/tests/baselines/reference/seeTag3.symbols new file mode 100644 index 00000000000..2eb5284aaaf --- /dev/null +++ b/tests/baselines/reference/seeTag3.symbols @@ -0,0 +1,6 @@ +=== tests/cases/conformance/jsdoc/seeTag3.js === +/** @see [The typescript web site](https://typescriptlang.org) */ +function theWholeThing() { +>theWholeThing : Symbol(theWholeThing, Decl(seeTag3.js, 0, 0)) +} + diff --git a/tests/baselines/reference/seeTag3.types b/tests/baselines/reference/seeTag3.types new file mode 100644 index 00000000000..6f150952c9e --- /dev/null +++ b/tests/baselines/reference/seeTag3.types @@ -0,0 +1,6 @@ +=== tests/cases/conformance/jsdoc/seeTag3.js === +/** @see [The typescript web site](https://typescriptlang.org) */ +function theWholeThing() { +>theWholeThing : () => void +} + diff --git a/tests/cases/conformance/jsdoc/seeTag3.ts b/tests/cases/conformance/jsdoc/seeTag3.ts new file mode 100644 index 00000000000..abd16226fee --- /dev/null +++ b/tests/cases/conformance/jsdoc/seeTag3.ts @@ -0,0 +1,7 @@ +// @outdir: out/ +// @checkJs: true +// @filename: seeTag3.js + +/** @see [The typescript web site](https://typescriptlang.org) */ +function theWholeThing() { +} From 2c7b13b8306899b3846333670e13fb883b0aad41 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 14 Oct 2021 17:00:55 -0700 Subject: [PATCH 15/60] Fix explainFiles on files under nodenext with types references (#46367) * Fix explainFiles on files under nodenext with types references * Fix explainFiles crash on module nodenext --- src/compiler/program.ts | 2 +- ...sNodeNextWithTypesReference.baseline.jsonc | 37 +++++++++++++++ .../explainFilesNodeNextWithTypesReference.ts | 45 +++++++++++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/explainFilesNodeNextWithTypesReference.baseline.jsonc create mode 100644 tests/cases/fourslash/explainFilesNodeNextWithTypesReference.ts diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 045a31d4576..2db75250cce 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -685,7 +685,7 @@ namespace ts { break; case FileIncludeKind.TypeReferenceDirective: ({ pos, end } = file.typeReferenceDirectives[index]); - packageId = file.resolvedTypeReferenceDirectiveNames?.get(toFileNameLowerCase(file.typeReferenceDirectives[index].fileName), getModeForResolutionAtIndex(file, index))?.packageId; + packageId = file.resolvedTypeReferenceDirectiveNames?.get(toFileNameLowerCase(file.typeReferenceDirectives[index].fileName), file.impliedNodeFormat)?.packageId; break; case FileIncludeKind.LibReferenceDirective: ({ pos, end } = file.libReferenceDirectives[index]); diff --git a/tests/baselines/reference/explainFilesNodeNextWithTypesReference.baseline.jsonc b/tests/baselines/reference/explainFilesNodeNextWithTypesReference.baseline.jsonc new file mode 100644 index 00000000000..535e351c335 --- /dev/null +++ b/tests/baselines/reference/explainFilesNodeNextWithTypesReference.baseline.jsonc @@ -0,0 +1,37 @@ +// === /node_modules/react-hook-form/dist/index.d.ts === +// /// +// export type Foo = React.Whatever; +// export function useForm(): any; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/node_modules/react-hook-form/dist/index.d.ts", + "kind": "string", + "name": "react", + "textSpan": { + "start": 22, + "length": 5 + }, + "displayParts": [ + { + "text": "\"react\"", + "kind": "stringLiteral" + } + ] + }, + "references": [ + { + "textSpan": { + "start": 22, + "length": 5 + }, + "fileName": "/node_modules/react-hook-form/dist/index.d.ts", + "isWriteAccess": false, + "isDefinition": false + } + ] + } +] \ No newline at end of file diff --git a/tests/cases/fourslash/explainFilesNodeNextWithTypesReference.ts b/tests/cases/fourslash/explainFilesNodeNextWithTypesReference.ts new file mode 100644 index 00000000000..8b22bb50044 --- /dev/null +++ b/tests/cases/fourslash/explainFilesNodeNextWithTypesReference.ts @@ -0,0 +1,45 @@ +/// +// @Filename: /node_modules/react-hook-form/package.json +//// { +//// "name": "react-hook-form", +//// "main": "dist/index.cjs.js", +//// "module": "dist/index.esm.js", +//// "types": "dist/index.d.ts", +//// "exports": { +//// "./package.json": "./package.json", +//// ".": { +//// "import": "./dist/index.esm.js", +//// "require": "./dist/index.cjs.js", +//// "types": "./dist/index.d.ts" +//// } +//// } +//// } + +// @Filename: /node_modules/react-hook-form/dist/index.cjs.js +//// module.exports = {}; + +// @Filename: /node_modules/react-hook-form/dist/index.esm.js +//// export function useForm() {} + +// @Filename: /node_modules/react-hook-form/dist/index.d.ts +//// /// +//// export type Foo = React.Whatever; +//// export function useForm(): any; + +// @Filename: /node_modules/react/index.d.ts +//// declare namespace JSX {} +//// declare namespace React { export interface Whatever {} } + +// @Filename: /tsconfig.json +//// { +//// "compilerOptions": { +//// "module": "nodenext", +//// "explainFiles": true +//// } +//// "files": ["./index.ts"] +//// } + +// @Filename: /index.ts +//// import { useForm } from "react-hook-form"; + +verify.baselineFindAllReferences(""); \ No newline at end of file From cf9d38fe521e5df05aaf0eb8cc6fdb8c4e6716e9 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Fri, 15 Oct 2021 06:06:32 +0000 Subject: [PATCH 16/60] Update package-lock.json --- package-lock.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 34f74eefbf7..f39b1c7778f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -676,9 +676,9 @@ "dev": true }, "@types/node": { - "version": "16.10.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.9.tgz", - "integrity": "sha512-H9ReOt+yqIJPCutkTYjFjlyK6WEMQYT9hLZMlWtOjFQY2ItppsWZ6RJf8Aw+jz5qTYceuHvFgPIaKOHtLAEWBw==", + "version": "16.11.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.0.tgz", + "integrity": "sha512-8MLkBIYQMuhRBQzGN9875bYsOhPnf/0rgXGo66S2FemHkhbn9qtsz9ywV1iCG+vbjigE4WUNVvw37Dx+L0qsPg==", "dev": true }, "@types/node-fetch": { @@ -1658,9 +1658,9 @@ } }, "is-core-module": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.7.0.tgz", - "integrity": "sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", "dev": true, "requires": { "has": "^1.0.3" @@ -5730,9 +5730,9 @@ } }, "is-core-module": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.7.0.tgz", - "integrity": "sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", "dev": true, "requires": { "has": "^1.0.3" From b1f39a705e7f053bb4c717688424101c60e5d0bb Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Fri, 15 Oct 2021 09:31:47 -0700 Subject: [PATCH 17/60] Fix React auto-import blocking component imports in --preserve (#46368) --- src/services/codefixes/importFixes.ts | 6 +++- .../fourslash/importNameCodeFix_jsxReact17.ts | 31 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/importNameCodeFix_jsxReact17.ts diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 6fd9b702f04..d910128f6db 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -766,9 +766,13 @@ namespace ts.codefix { return { fixes, symbolName }; } + function jsxModeNeedsExplicitImport(jsx: JsxEmit | undefined) { + return jsx === JsxEmit.React || jsx === JsxEmit.ReactNative; + } + function getSymbolName(sourceFile: SourceFile, checker: TypeChecker, symbolToken: Identifier, compilerOptions: CompilerOptions): string { const parent = symbolToken.parent; - if ((isJsxOpeningLikeElement(parent) || isJsxClosingElement(parent)) && parent.tagName === symbolToken && compilerOptions.jsx !== JsxEmit.ReactJSX && compilerOptions.jsx !== JsxEmit.ReactJSXDev) { + if ((isJsxOpeningLikeElement(parent) || isJsxClosingElement(parent)) && parent.tagName === symbolToken && jsxModeNeedsExplicitImport(compilerOptions.jsx)) { const jsxNamespace = checker.getJsxNamespace(sourceFile); if (isIntrinsicJsxName(symbolToken.text) || !checker.resolveName(jsxNamespace, parent, SymbolFlags.Value, /*excludeGlobals*/ true)) { return jsxNamespace; diff --git a/tests/cases/fourslash/importNameCodeFix_jsxReact17.ts b/tests/cases/fourslash/importNameCodeFix_jsxReact17.ts new file mode 100644 index 00000000000..9fa78d51113 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFix_jsxReact17.ts @@ -0,0 +1,31 @@ +/// + +// @jsx: preserve +// @module: commonjs + +// @Filename: /node_modules/@types/react/index.d.ts +//// declare namespace React { +//// function createElement(): any; +//// } +//// export = React; +//// export as namespace React; +//// +//// declare global { +//// namespace JSX { +//// interface IntrinsicElements {} +//// interface IntrinsicAttributes {} +//// } +//// } + +// @Filename: /component.tsx +//// import "react"; +//// export declare function Component(): any; + +// @Filename: /index.tsx +//// (); + +goTo.marker(""); +verify.importFixAtPosition([`import { Component } from "./component"; + +();`]); + From 7582b1bbaea94eb50a350455abccd96e62241ad9 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Fri, 15 Oct 2021 20:34:57 +0300 Subject: [PATCH 18/60] fix(45799): skip checking arguments used as a key in object literals (#45814) --- src/compiler/checker.ts | 2 +- ...entsReferenceInObjectLiteral_Js.errors.txt | 32 ++++++++++ .../argumentsReferenceInObjectLiteral_Js.js | 51 +++++++++++++++ ...gumentsReferenceInObjectLiteral_Js.symbols | 49 +++++++++++++++ ...argumentsReferenceInObjectLiteral_Js.types | 62 +++++++++++++++++++ .../argumentsReferenceInObjectLiteral_Js.ts | 31 ++++++++++ 6 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/argumentsReferenceInObjectLiteral_Js.errors.txt create mode 100644 tests/baselines/reference/argumentsReferenceInObjectLiteral_Js.js create mode 100644 tests/baselines/reference/argumentsReferenceInObjectLiteral_Js.symbols create mode 100644 tests/baselines/reference/argumentsReferenceInObjectLiteral_Js.types create mode 100644 tests/cases/compiler/argumentsReferenceInObjectLiteral_Js.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 26ba5be32f6..f5aed2e1d5c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12581,7 +12581,7 @@ namespace ts { if (!node) return false; switch (node.kind) { case SyntaxKind.Identifier: - return (node as Identifier).escapedText === argumentsSymbol.escapedName && getResolvedSymbol(node as Identifier) === argumentsSymbol; + return (node as Identifier).escapedText === argumentsSymbol.escapedName && getReferencedValueSymbol(node as Identifier) === argumentsSymbol; case SyntaxKind.PropertyDeclaration: case SyntaxKind.MethodDeclaration: diff --git a/tests/baselines/reference/argumentsReferenceInObjectLiteral_Js.errors.txt b/tests/baselines/reference/argumentsReferenceInObjectLiteral_Js.errors.txt new file mode 100644 index 00000000000..1c26e2e6011 --- /dev/null +++ b/tests/baselines/reference/argumentsReferenceInObjectLiteral_Js.errors.txt @@ -0,0 +1,32 @@ +/a.js(16,9): error TS18004: No value exists in scope for the shorthand property 'arguments'. Either declare one or provide an initializer. + + +==== /a.js (1 errors) ==== + const a = () => { + return { + arguments: [], + }; + }; + + const b = () => { + const c = { + arguments: [], + } + return c; + }; + + const c = () => { + return { + arguments, + ~~~~~~~~~ +!!! error TS18004: No value exists in scope for the shorthand property 'arguments'. Either declare one or provide an initializer. + }; + } + + const d = () => { + const arguments = undefined; + return { + arguments, + }; + } + \ No newline at end of file diff --git a/tests/baselines/reference/argumentsReferenceInObjectLiteral_Js.js b/tests/baselines/reference/argumentsReferenceInObjectLiteral_Js.js new file mode 100644 index 00000000000..39c849a90ec --- /dev/null +++ b/tests/baselines/reference/argumentsReferenceInObjectLiteral_Js.js @@ -0,0 +1,51 @@ +//// [a.js] +const a = () => { + return { + arguments: [], + }; +}; + +const b = () => { + const c = { + arguments: [], + } + return c; +}; + +const c = () => { + return { + arguments, + }; +} + +const d = () => { + const arguments = undefined; + return { + arguments, + }; +} + + +//// [a.js] +const a = () => { + return { + arguments: [], + }; +}; +const b = () => { + const c = { + arguments: [], + }; + return c; +}; +const c = () => { + return { + arguments, + }; +}; +const d = () => { + const arguments = undefined; + return { + arguments, + }; +}; diff --git a/tests/baselines/reference/argumentsReferenceInObjectLiteral_Js.symbols b/tests/baselines/reference/argumentsReferenceInObjectLiteral_Js.symbols new file mode 100644 index 00000000000..e2e56a3cb37 --- /dev/null +++ b/tests/baselines/reference/argumentsReferenceInObjectLiteral_Js.symbols @@ -0,0 +1,49 @@ +=== /a.js === +const a = () => { +>a : Symbol(a, Decl(a.js, 0, 5)) + + return { + arguments: [], +>arguments : Symbol(arguments, Decl(a.js, 1, 12)) + + }; +}; + +const b = () => { +>b : Symbol(b, Decl(a.js, 6, 5)) + + const c = { +>c : Symbol(c, Decl(a.js, 7, 9)) + + arguments: [], +>arguments : Symbol(arguments, Decl(a.js, 7, 15)) + } + return c; +>c : Symbol(c, Decl(a.js, 7, 9)) + +}; + +const c = () => { +>c : Symbol(c, Decl(a.js, 13, 5)) + + return { + arguments, +>arguments : Symbol(arguments, Decl(a.js, 14, 12)) + + }; +} + +const d = () => { +>d : Symbol(d, Decl(a.js, 19, 5)) + + const arguments = undefined; +>arguments : Symbol(arguments, Decl(a.js, 20, 9)) +>undefined : Symbol(undefined) + + return { + arguments, +>arguments : Symbol(arguments, Decl(a.js, 21, 12)) + + }; +} + diff --git a/tests/baselines/reference/argumentsReferenceInObjectLiteral_Js.types b/tests/baselines/reference/argumentsReferenceInObjectLiteral_Js.types new file mode 100644 index 00000000000..8be8786acc8 --- /dev/null +++ b/tests/baselines/reference/argumentsReferenceInObjectLiteral_Js.types @@ -0,0 +1,62 @@ +=== /a.js === +const a = () => { +>a : () => { arguments: any[]; } +>() => { return { arguments: [], };} : () => { arguments: any[]; } + + return { +>{ arguments: [], } : { arguments: undefined[]; } + + arguments: [], +>arguments : undefined[] +>[] : undefined[] + + }; +}; + +const b = () => { +>b : () => { arguments: any[]; } +>() => { const c = { arguments: [], } return c;} : () => { arguments: any[]; } + + const c = { +>c : { arguments: any[]; } +>{ arguments: [], } : { arguments: undefined[]; } + + arguments: [], +>arguments : undefined[] +>[] : undefined[] + } + return c; +>c : { arguments: any[]; } + +}; + +const c = () => { +>c : () => { arguments: any; } +>() => { return { arguments, };} : () => { arguments: any; } + + return { +>{ arguments, } : { arguments: any; } + + arguments, +>arguments : any + + }; +} + +const d = () => { +>d : () => { arguments: any; } +>() => { const arguments = undefined; return { arguments, };} : () => { arguments: any; } + + const arguments = undefined; +>arguments : any +>undefined : undefined + + return { +>{ arguments, } : { arguments: any; } + + arguments, +>arguments : any + + }; +} + diff --git a/tests/cases/compiler/argumentsReferenceInObjectLiteral_Js.ts b/tests/cases/compiler/argumentsReferenceInObjectLiteral_Js.ts new file mode 100644 index 00000000000..92fadcd6001 --- /dev/null +++ b/tests/cases/compiler/argumentsReferenceInObjectLiteral_Js.ts @@ -0,0 +1,31 @@ +// @checkJs: true +// @allowJs: true +// @target: es6 +// @outDir: ./out +// @filename: /a.js + +const a = () => { + return { + arguments: [], + }; +}; + +const b = () => { + const c = { + arguments: [], + } + return c; +}; + +const c = () => { + return { + arguments, + }; +} + +const d = () => { + const arguments = undefined; + return { + arguments, + }; +} From 6a75689a25c414bd68ab727f0f0edd3cd881472c Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 15 Oct 2021 13:26:46 -0700 Subject: [PATCH 19/60] Import assertion: do no parse } if { is not present (#46388) Previously, import assertion parsing would try to parse both { and }, even if both were missing. If both were missing, the error for } could occur past the end of the file, causing an assertion. Fixes #46364 --- src/compiler/parser.ts | 27 +++++++++++-------- .../reference/importAssertion4.errors.txt | 11 ++++++++ tests/baselines/reference/importAssertion4.js | 7 +++++ .../reference/importAssertion4.symbols | 4 +++ .../reference/importAssertion4.types | 4 +++ .../reference/importAssertion5.errors.txt | 12 +++++++++ tests/baselines/reference/importAssertion5.js | 7 +++++ .../reference/importAssertion5.symbols | 4 +++ .../reference/importAssertion5.types | 4 +++ .../importAssertion/importAssertion4.ts | 1 + .../importAssertion/importAssertion5.ts | 1 + 11 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 tests/baselines/reference/importAssertion4.errors.txt create mode 100644 tests/baselines/reference/importAssertion4.js create mode 100644 tests/baselines/reference/importAssertion4.symbols create mode 100644 tests/baselines/reference/importAssertion4.types create mode 100644 tests/baselines/reference/importAssertion5.errors.txt create mode 100644 tests/baselines/reference/importAssertion5.js create mode 100644 tests/baselines/reference/importAssertion5.symbols create mode 100644 tests/baselines/reference/importAssertion5.types create mode 100644 tests/cases/conformance/importAssertion/importAssertion4.ts create mode 100644 tests/cases/conformance/importAssertion/importAssertion5.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 6d94ef225b1..59eaaa2efbb 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -7277,19 +7277,24 @@ namespace ts { const pos = getNodePos(); parseExpected(SyntaxKind.AssertKeyword); const openBracePosition = scanner.getTokenPos(); - parseExpected(SyntaxKind.OpenBraceToken); - const multiLine = scanner.hasPrecedingLineBreak(); - const elements = parseDelimitedList(ParsingContext.AssertEntries, parseAssertEntry, /*considerSemicolonAsDelimiter*/ true); - if (!parseExpected(SyntaxKind.CloseBraceToken)) { - const lastError = lastOrUndefined(parseDiagnostics); - if (lastError && lastError.code === Diagnostics._0_expected.code) { - addRelatedInfo( - lastError, - createDetachedDiagnostic(fileName, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_to_match_the_token_here) - ); + if (parseExpected(SyntaxKind.OpenBraceToken)) { + const multiLine = scanner.hasPrecedingLineBreak(); + const elements = parseDelimitedList(ParsingContext.AssertEntries, parseAssertEntry, /*considerSemicolonAsDelimiter*/ true); + if (!parseExpected(SyntaxKind.CloseBraceToken)) { + const lastError = lastOrUndefined(parseDiagnostics); + if (lastError && lastError.code === Diagnostics._0_expected.code) { + addRelatedInfo( + lastError, + createDetachedDiagnostic(fileName, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_to_match_the_token_here) + ); + } } + return finishNode(factory.createAssertClause(elements, multiLine), pos); + } + else { + const elements = createNodeArray([], getNodePos(), /*end*/ undefined, /*hasTrailingComma*/ false); + return finishNode(factory.createAssertClause(elements, /*multiLine*/ false), pos); } - return finishNode(factory.createAssertClause(elements, multiLine), pos); } function tokenAfterImportDefinitelyProducesImportDeclaration() { diff --git a/tests/baselines/reference/importAssertion4.errors.txt b/tests/baselines/reference/importAssertion4.errors.txt new file mode 100644 index 00000000000..fb1810d26fc --- /dev/null +++ b/tests/baselines/reference/importAssertion4.errors.txt @@ -0,0 +1,11 @@ +tests/cases/conformance/importAssertion/importAssertion4.ts(1,20): error TS2307: Cannot find module './first' or its corresponding type declarations. +tests/cases/conformance/importAssertion/importAssertion4.ts(2,1): error TS1005: '{' expected. + + +==== tests/cases/conformance/importAssertion/importAssertion4.ts (2 errors) ==== + import * as f from "./first" assert + ~~~~~~~~~ +!!! error TS2307: Cannot find module './first' or its corresponding type declarations. + + +!!! error TS1005: '{' expected. \ No newline at end of file diff --git a/tests/baselines/reference/importAssertion4.js b/tests/baselines/reference/importAssertion4.js new file mode 100644 index 00000000000..24bd2f287e0 --- /dev/null +++ b/tests/baselines/reference/importAssertion4.js @@ -0,0 +1,7 @@ +//// [importAssertion4.ts] +import * as f from "./first" assert + + +//// [importAssertion4.js] +"use strict"; +exports.__esModule = true; diff --git a/tests/baselines/reference/importAssertion4.symbols b/tests/baselines/reference/importAssertion4.symbols new file mode 100644 index 00000000000..d904f159021 --- /dev/null +++ b/tests/baselines/reference/importAssertion4.symbols @@ -0,0 +1,4 @@ +=== tests/cases/conformance/importAssertion/importAssertion4.ts === +import * as f from "./first" assert +>f : Symbol(f, Decl(importAssertion4.ts, 0, 6)) + diff --git a/tests/baselines/reference/importAssertion4.types b/tests/baselines/reference/importAssertion4.types new file mode 100644 index 00000000000..6c828613032 --- /dev/null +++ b/tests/baselines/reference/importAssertion4.types @@ -0,0 +1,4 @@ +=== tests/cases/conformance/importAssertion/importAssertion4.ts === +import * as f from "./first" assert +>f : any + diff --git a/tests/baselines/reference/importAssertion5.errors.txt b/tests/baselines/reference/importAssertion5.errors.txt new file mode 100644 index 00000000000..ccc17ec0cad --- /dev/null +++ b/tests/baselines/reference/importAssertion5.errors.txt @@ -0,0 +1,12 @@ +tests/cases/conformance/importAssertion/importAssertion5.ts(1,20): error TS2307: Cannot find module './first' or its corresponding type declarations. +tests/cases/conformance/importAssertion/importAssertion5.ts(2,1): error TS1005: '}' expected. + + +==== tests/cases/conformance/importAssertion/importAssertion5.ts (2 errors) ==== + import * as f from "./first" assert { + ~~~~~~~~~ +!!! error TS2307: Cannot find module './first' or its corresponding type declarations. + + +!!! error TS1005: '}' expected. +!!! related TS1007 tests/cases/conformance/importAssertion/importAssertion5.ts:1:37: The parser expected to find a '}' to match the '{' token here. \ No newline at end of file diff --git a/tests/baselines/reference/importAssertion5.js b/tests/baselines/reference/importAssertion5.js new file mode 100644 index 00000000000..5237c5f2805 --- /dev/null +++ b/tests/baselines/reference/importAssertion5.js @@ -0,0 +1,7 @@ +//// [importAssertion5.ts] +import * as f from "./first" assert { + + +//// [importAssertion5.js] +"use strict"; +exports.__esModule = true; diff --git a/tests/baselines/reference/importAssertion5.symbols b/tests/baselines/reference/importAssertion5.symbols new file mode 100644 index 00000000000..2f3b7f00ad3 --- /dev/null +++ b/tests/baselines/reference/importAssertion5.symbols @@ -0,0 +1,4 @@ +=== tests/cases/conformance/importAssertion/importAssertion5.ts === +import * as f from "./first" assert { +>f : Symbol(f, Decl(importAssertion5.ts, 0, 6)) + diff --git a/tests/baselines/reference/importAssertion5.types b/tests/baselines/reference/importAssertion5.types new file mode 100644 index 00000000000..55c946ea4cc --- /dev/null +++ b/tests/baselines/reference/importAssertion5.types @@ -0,0 +1,4 @@ +=== tests/cases/conformance/importAssertion/importAssertion5.ts === +import * as f from "./first" assert { +>f : any + diff --git a/tests/cases/conformance/importAssertion/importAssertion4.ts b/tests/cases/conformance/importAssertion/importAssertion4.ts new file mode 100644 index 00000000000..242d7dd375a --- /dev/null +++ b/tests/cases/conformance/importAssertion/importAssertion4.ts @@ -0,0 +1 @@ +import * as f from "./first" assert diff --git a/tests/cases/conformance/importAssertion/importAssertion5.ts b/tests/cases/conformance/importAssertion/importAssertion5.ts new file mode 100644 index 00000000000..ef09d84e66c --- /dev/null +++ b/tests/cases/conformance/importAssertion/importAssertion5.ts @@ -0,0 +1 @@ +import * as f from "./first" assert { From dfb40549fc2d9f17cd5baebceaabad27d5b72f69 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Sat, 16 Oct 2021 03:21:14 +0530 Subject: [PATCH 20/60] fix: ES6 Modules => ES Modules in error messages (#46378) * fix: ES6 Modules => ES Modules in error messages * chore: Rename test file names * chore: Rename function names --- src/compiler/diagnosticMessages.json | 4 ++-- ...{convertToEs6Module.ts => convertToEsModule.ts} | 12 ++++++------ src/services/completions.ts | 4 ++-- src/services/refactors/moveToNewFile.ts | 14 +++++++------- src/services/suggestionDiagnostics.ts | 6 +++--- src/services/tsconfig.json | 2 +- src/services/utilities.ts | 4 ++-- ...refactorConvertToEsModule_exportEqualsClass.ts} | 2 +- ...s => refactorConvertToEsModule_export_alias.ts} | 2 +- ...refactorConvertToEsModule_export_dotDefault.ts} | 2 +- ...efactorConvertToEsModule_export_invalidName.ts} | 2 +- ...orConvertToEsModule_export_moduleDotExports.ts} | 2 +- ...Module_export_moduleDotExportsEqualsRequire.ts} | 2 +- ...dule_export_moduleDotExports_changesImports.ts} | 2 +- ...s => refactorConvertToEsModule_export_named.ts} | 4 ++-- ...nvertToEsModule_export_namedClassExpression.ts} | 2 +- ...rtToEsModule_export_namedFunctionExpression.ts} | 2 +- ... => refactorConvertToEsModule_export_object.ts} | 2 +- ...orConvertToEsModule_export_object_shorthand.ts} | 2 +- ...refactorConvertToEsModule_export_referenced.ts} | 2 +- ...orConvertToEsModule_expressionToDeclaration.ts} | 2 +- ...onvertToEsModule_import_arrayBindingPattern.ts} | 2 +- ...orConvertToEsModule_import_es6DefaultImport.ts} | 2 +- ...ConvertToEsModule_import_includeDefaultUses.ts} | 2 +- ...ToEsModule_import_multipleUniqueIdentifiers.ts} | 2 +- ...sModule_import_multipleVariableDeclarations.ts} | 2 +- ...rtToEsModule_import_nameFromModuleSpecifier.ts} | 2 +- ...sModule_import_objectBindingPattern_complex.ts} | 2 +- ...oEsModule_import_objectBindingPattern_plain.ts} | 2 +- ...orConvertToEsModule_import_onlyNamedImports.ts} | 2 +- ...ctorConvertToEsModule_import_propertyAccess.ts} | 2 +- ... refactorConvertToEsModule_import_shadowing.ts} | 2 +- ...refactorConvertToEsModule_import_sideEffect.ts} | 2 +- ...=> refactorConvertToEsModule_inCommonJsFile.ts} | 2 +- ...efactorConvertToEsModule_missingInitializer.ts} | 2 +- ... => refactorConvertToEsModule_module_node12.ts} | 0 ...> refactorConvertToEsModule_module_nodenext.ts} | 0 ... => refactorConvertToEsModule_notAtTopLevel.ts} | 0 ...actorConvertToEsModule_notInCommonjsProject.ts} | 0 ...dule_notInCommonjsProject_yesIfSomeEsModule.ts} | 2 +- ...=> refactorConvertToEsModule_preserveQuotes.ts} | 2 +- ...rtToEsModule_renameWithinTransformedExports.ts} | 2 +- ...vertToEsModule_unexported_uninitialized_var.ts} | 4 ++-- 43 files changed, 57 insertions(+), 57 deletions(-) rename src/services/codefixes/{convertToEs6Module.ts => convertToEsModule.ts} (96%) rename tests/cases/fourslash/{refactorConvertToEs6Module_exportEqualsClass.ts => refactorConvertToEsModule_exportEqualsClass.ts} (87%) rename tests/cases/fourslash/{refactorConvertToEs6Module_export_alias.ts => refactorConvertToEsModule_export_alias.ts} (86%) rename tests/cases/fourslash/{refactorConvertToEs6Module_export_dotDefault.ts => refactorConvertToEsModule_export_dotDefault.ts} (88%) rename tests/cases/fourslash/{refactorConvertToEs6Module_export_invalidName.ts => refactorConvertToEsModule_export_invalidName.ts} (88%) rename tests/cases/fourslash/{refactorConvertToEs6Module_export_moduleDotExports.ts => refactorConvertToEsModule_export_moduleDotExports.ts} (92%) rename tests/cases/fourslash/{refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts => refactorConvertToEsModule_export_moduleDotExportsEqualsRequire.ts} (96%) rename tests/cases/fourslash/{refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts => refactorConvertToEsModule_export_moduleDotExports_changesImports.ts} (86%) rename tests/cases/fourslash/{refactorConvertToEs6Module_export_named.ts => refactorConvertToEsModule_export_named.ts} (88%) rename tests/cases/fourslash/{refactorConvertToEs6Module_export_namedClassExpression.ts => refactorConvertToEsModule_export_namedClassExpression.ts} (86%) rename tests/cases/fourslash/{refactorConvertToEs6Module_export_namedFunctionExpression.ts => refactorConvertToEsModule_export_namedFunctionExpression.ts} (87%) rename tests/cases/fourslash/{refactorConvertToEs6Module_export_object.ts => refactorConvertToEsModule_export_object.ts} (86%) rename tests/cases/fourslash/{refactorConvertToEs6Module_export_object_shorthand.ts => refactorConvertToEsModule_export_object_shorthand.ts} (87%) rename tests/cases/fourslash/{refactorConvertToEs6Module_export_referenced.ts => refactorConvertToEsModule_export_referenced.ts} (91%) rename tests/cases/fourslash/{refactorConvertToEs6Module_expressionToDeclaration.ts => refactorConvertToEsModule_expressionToDeclaration.ts} (90%) rename tests/cases/fourslash/{refactorConvertToEs6Module_import_arrayBindingPattern.ts => refactorConvertToEsModule_import_arrayBindingPattern.ts} (85%) rename tests/cases/fourslash/{refactorConvertToEs6Module_import_es6DefaultImport.ts => refactorConvertToEsModule_import_es6DefaultImport.ts} (86%) rename tests/cases/fourslash/{refactorConvertToEs6Module_import_includeDefaultUses.ts => refactorConvertToEsModule_import_includeDefaultUses.ts} (84%) rename tests/cases/fourslash/{refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts => refactorConvertToEsModule_import_multipleUniqueIdentifiers.ts} (89%) rename tests/cases/fourslash/{refactorConvertToEs6Module_import_multipleVariableDeclarations.ts => refactorConvertToEsModule_import_multipleVariableDeclarations.ts} (88%) rename tests/cases/fourslash/{refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts => refactorConvertToEsModule_import_nameFromModuleSpecifier.ts} (89%) rename tests/cases/fourslash/{refactorConvertToEs6Module_import_objectBindingPattern_complex.ts => refactorConvertToEsModule_import_objectBindingPattern_complex.ts} (85%) rename tests/cases/fourslash/{refactorConvertToEs6Module_import_objectBindingPattern_plain.ts => refactorConvertToEsModule_import_objectBindingPattern_plain.ts} (84%) rename tests/cases/fourslash/{refactorConvertToEs6Module_import_onlyNamedImports.ts => refactorConvertToEsModule_import_onlyNamedImports.ts} (82%) rename tests/cases/fourslash/{refactorConvertToEs6Module_import_propertyAccess.ts => refactorConvertToEsModule_import_propertyAccess.ts} (90%) rename tests/cases/fourslash/{refactorConvertToEs6Module_import_shadowing.ts => refactorConvertToEsModule_import_shadowing.ts} (85%) rename tests/cases/fourslash/{refactorConvertToEs6Module_import_sideEffect.ts => refactorConvertToEsModule_import_sideEffect.ts} (84%) rename tests/cases/fourslash/{refactorConvertToEs6Module_inCommonJsFile.ts => refactorConvertToEsModule_inCommonJsFile.ts} (92%) rename tests/cases/fourslash/{refactorConvertToEs6Module_missingInitializer.ts => refactorConvertToEsModule_missingInitializer.ts} (82%) rename tests/cases/fourslash/{refactorConvertToEs6Module_module_node12.ts => refactorConvertToEsModule_module_node12.ts} (100%) rename tests/cases/fourslash/{refactorConvertToEs6Module_module_nodenext.ts => refactorConvertToEsModule_module_nodenext.ts} (100%) rename tests/cases/fourslash/{refactorConvertToEs6Module_notAtTopLevel.ts => refactorConvertToEsModule_notAtTopLevel.ts} (100%) rename tests/cases/fourslash/{refactorConvertToEs6Module_notInCommonjsProject.ts => refactorConvertToEsModule_notInCommonjsProject.ts} (100%) rename tests/cases/fourslash/{refactorConvertToEs6Module_notInCommonjsProject_yesIfSomeEs6Module.ts => refactorConvertToEsModule_notInCommonjsProject_yesIfSomeEsModule.ts} (83%) rename tests/cases/fourslash/{refactorConvertToEs6Module_preserveQuotes.ts => refactorConvertToEsModule_preserveQuotes.ts} (82%) rename tests/cases/fourslash/{refactorConvertToEs6Module_renameWithinTransformedExports.ts => refactorConvertToEsModule_renameWithinTransformedExports.ts} (94%) rename tests/cases/fourslash/{refactorConvertToEs6Module_unexported_uninitialized_var.ts => refactorConvertToEsModule_unexported_uninitialized_var.ts} (89%) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index e9ae0131b05..d21a923a87b 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -6216,7 +6216,7 @@ "code": 18003 }, - "File is a CommonJS module; it may be converted to an ES6 module.": { + "File is a CommonJS module; it may be converted to an ES module.": { "category": "Suggestion", "code": 80001 }, @@ -6465,7 +6465,7 @@ "category": "Message", "code": 95016 }, - "Convert to ES6 module": { + "Convert to ES module": { "category": "Message", "code": 95017 }, diff --git a/src/services/codefixes/convertToEs6Module.ts b/src/services/codefixes/convertToEsModule.ts similarity index 96% rename from src/services/codefixes/convertToEs6Module.ts rename to src/services/codefixes/convertToEsModule.ts index 94f6dfe2495..e9f29c80de7 100644 --- a/src/services/codefixes/convertToEs6Module.ts +++ b/src/services/codefixes/convertToEsModule.ts @@ -1,11 +1,11 @@ /* @internal */ namespace ts.codefix { registerCodeFix({ - errorCodes: [Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module.code], + errorCodes: [Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES_module.code], getCodeActions(context) { const { sourceFile, program, preferences } = context; const changes = textChanges.ChangeTracker.with(context, changes => { - const moduleExportsChangedToDefault = convertFileToEs6Module(sourceFile, program.getTypeChecker(), changes, getEmitScriptTarget(program.getCompilerOptions()), getQuotePreference(sourceFile, preferences)); + const moduleExportsChangedToDefault = convertFileToEsModule(sourceFile, program.getTypeChecker(), changes, getEmitScriptTarget(program.getCompilerOptions()), getQuotePreference(sourceFile, preferences)); if (moduleExportsChangedToDefault) { for (const importingFile of program.getSourceFiles()) { fixImportOfModuleExports(importingFile, sourceFile, changes, getQuotePreference(importingFile, preferences)); @@ -13,7 +13,7 @@ namespace ts.codefix { } }); // No support for fix-all since this applies to the whole file at once anyway. - return [createCodeFixActionWithoutFixAll("convertToEs6Module", changes, Diagnostics.Convert_to_ES6_module)]; + return [createCodeFixActionWithoutFixAll("convertToEsModule", changes, Diagnostics.Convert_to_ES_module)]; }, }); @@ -39,7 +39,7 @@ namespace ts.codefix { } /** @returns Whether we converted a `module.exports =` to a default export. */ - function convertFileToEs6Module(sourceFile: SourceFile, checker: TypeChecker, changes: textChanges.ChangeTracker, target: ScriptTarget, quotePreference: QuotePreference): ModuleExportsChanged { + function convertFileToEsModule(sourceFile: SourceFile, checker: TypeChecker, changes: textChanges.ChangeTracker, target: ScriptTarget, quotePreference: QuotePreference): ModuleExportsChanged { const identifiers: Identifiers = { original: collectFreeIdentifiers(sourceFile), additional: new Set() }; const exports = collectExportRenames(sourceFile, checker, identifiers); convertExportsAccesses(sourceFile, exports, changes); @@ -210,7 +210,7 @@ namespace ts.codefix { // `const a = require("b").c` --> `import { c as a } from "./b"; return convertedImports([makeSingleImport(name.text, propertyName, moduleSpecifier, quotePreference)]); default: - return Debug.assertNever(name, `Convert to ES6 module got invalid syntax form ${(name as BindingName).kind}`); + return Debug.assertNever(name, `Convert to ES module got invalid syntax form ${(name as BindingName).kind}`); } } @@ -430,7 +430,7 @@ namespace ts.codefix { case SyntaxKind.Identifier: return convertSingleIdentifierImport(name, moduleSpecifier, checker, identifiers, quotePreference); default: - return Debug.assertNever(name, `Convert to ES6 module got invalid name kind ${(name as BindingName).kind}`); + return Debug.assertNever(name, `Convert to ES module got invalid name kind ${(name as BindingName).kind}`); } } diff --git a/src/services/completions.ts b/src/services/completions.ts index e76f60ba507..40053d2e873 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1993,10 +1993,10 @@ namespace ts.Completions { if (isNonContextualObjectLiteral) return false; // If not already a module, must have modules enabled. if (!preferences.includeCompletionsForModuleExports) return false; - // If already using ES6 modules, OK to continue using them. + // If already using ES modules, OK to continue using them. if (sourceFile.externalModuleIndicator || sourceFile.commonJsModuleIndicator) return true; // If module transpilation is enabled or we're targeting es6 or above, or not emitting, OK. - if (compilerOptionsIndicateEs6Modules(program.getCompilerOptions())) return true; + if (compilerOptionsIndicateEsModules(program.getCompilerOptions())) return true; // If some file is using ES6 modules, assume that it's OK to add more. return programContainsModules(program); } diff --git a/src/services/refactors/moveToNewFile.ts b/src/services/refactors/moveToNewFile.ts index 9e204bb383f..271a08b20f4 100644 --- a/src/services/refactors/moveToNewFile.ts +++ b/src/services/refactors/moveToNewFile.ts @@ -138,9 +138,9 @@ namespace ts.refactor { return [...prologueDirectives, ...toMove.all]; } - const useEs6ModuleSyntax = !!oldFile.externalModuleIndicator; + const useEsModuleSyntax = !!oldFile.externalModuleIndicator; const quotePreference = getQuotePreference(oldFile, preferences); - const importsFromNewFile = createOldFileImportsFromNewFile(usage.oldFileImportsFromNewFile, newModuleName, useEs6ModuleSyntax, quotePreference); + const importsFromNewFile = createOldFileImportsFromNewFile(usage.oldFileImportsFromNewFile, newModuleName, useEsModuleSyntax, quotePreference); if (importsFromNewFile) { insertImports(changes, oldFile, importsFromNewFile, /*blankLineBetween*/ true); } @@ -149,8 +149,8 @@ namespace ts.refactor { deleteMovedStatements(oldFile, toMove.ranges, changes); updateImportsInOtherFiles(changes, program, oldFile, usage.movedSymbols, newModuleName); - const imports = getNewFileImportsAndAddExportInOldFile(oldFile, usage.oldImportsNeededByNewFile, usage.newFileImportsFromOldFile, changes, checker, useEs6ModuleSyntax, quotePreference); - const body = addExports(oldFile, toMove.all, usage.oldFileImportsFromNewFile, useEs6ModuleSyntax); + const imports = getNewFileImportsAndAddExportInOldFile(oldFile, usage.oldImportsNeededByNewFile, usage.newFileImportsFromOldFile, changes, checker, useEsModuleSyntax, quotePreference); + const body = addExports(oldFile, toMove.all, usage.oldFileImportsFromNewFile, useEsModuleSyntax); if (imports.length && body.length) { return [ ...prologueDirectives, @@ -429,7 +429,7 @@ namespace ts.refactor { newFileImportsFromOldFile: ReadonlySymbolSet, changes: textChanges.ChangeTracker, checker: TypeChecker, - useEs6ModuleSyntax: boolean, + useEsModuleSyntax: boolean, quotePreference: QuotePreference, ): readonly SupportedImportStatement[] { const copiedOldImports: SupportedImportStatement[] = []; @@ -454,7 +454,7 @@ namespace ts.refactor { const top = getTopLevelDeclarationStatement(decl); if (markSeenTop(top)) { - addExportToChanges(oldFile, top, name, changes, useEs6ModuleSyntax); + addExportToChanges(oldFile, top, name, changes, useEsModuleSyntax); } if (hasSyntacticModifier(decl, ModifierFlags.Default)) { oldFileDefault = name; @@ -465,7 +465,7 @@ namespace ts.refactor { } }); - append(copiedOldImports, makeImportOrRequire(oldFileDefault, oldFileNamedImports, removeFileExtension(getBaseFileName(oldFile.fileName)), useEs6ModuleSyntax, quotePreference)); + append(copiedOldImports, makeImportOrRequire(oldFileDefault, oldFileNamedImports, removeFileExtension(getBaseFileName(oldFile.fileName)), useEsModuleSyntax, quotePreference)); return copiedOldImports; } diff --git a/src/services/suggestionDiagnostics.ts b/src/services/suggestionDiagnostics.ts index 1ca10245c72..314d4d485b8 100644 --- a/src/services/suggestionDiagnostics.ts +++ b/src/services/suggestionDiagnostics.ts @@ -10,9 +10,9 @@ namespace ts { if (!isCommonJSFile && sourceFile.commonJsModuleIndicator && - (programContainsEs6Modules(program) || compilerOptionsIndicateEs6Modules(program.getCompilerOptions())) && + (programContainsEsModules(program) || compilerOptionsIndicateEsModules(program.getCompilerOptions())) && containsTopLevelCommonjs(sourceFile)) { - diags.push(createDiagnosticForNode(getErrorNodeFromCommonJsIndicator(sourceFile.commonJsModuleIndicator), Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module)); + diags.push(createDiagnosticForNode(getErrorNodeFromCommonJsIndicator(sourceFile.commonJsModuleIndicator), Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES_module)); } const isJsFile = isSourceFileJS(sourceFile); @@ -66,7 +66,7 @@ namespace ts { } } - // convertToEs6Module only works on top-level, so don't trigger it if commonjs code only appears in nested scopes. + // convertToEsModule only works on top-level, so don't trigger it if commonjs code only appears in nested scopes. function containsTopLevelCommonjs(sourceFile: SourceFile): boolean { return sourceFile.statements.some(statement => { switch (statement.kind) { diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index 1e0934804ed..d2119947f8f 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -61,7 +61,7 @@ "codefixes/annotateWithTypeFromJSDoc.ts", "codefixes/convertFunctionToEs6Class.ts", "codefixes/convertToAsyncFunction.ts", - "codefixes/convertToEs6Module.ts", + "codefixes/convertToEsModule.ts", "codefixes/correctQualifiedNameToIndexedAccessType.ts", "codefixes/convertToTypeOnlyExport.ts", "codefixes/convertToTypeOnlyImport.ts", diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 965ae736d05..5414814bd2e 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1897,10 +1897,10 @@ namespace ts { export function programContainsModules(program: Program): boolean { return program.getSourceFiles().some(s => !s.isDeclarationFile && !program.isSourceFileFromExternalLibrary(s) && !!(s.externalModuleIndicator || s.commonJsModuleIndicator)); } - export function programContainsEs6Modules(program: Program): boolean { + export function programContainsEsModules(program: Program): boolean { return program.getSourceFiles().some(s => !s.isDeclarationFile && !program.isSourceFileFromExternalLibrary(s) && !!s.externalModuleIndicator); } - export function compilerOptionsIndicateEs6Modules(compilerOptions: CompilerOptions): boolean { + export function compilerOptionsIndicateEsModules(compilerOptions: CompilerOptions): boolean { return !!compilerOptions.module || getEmitScriptTarget(compilerOptions) >= ScriptTarget.ES2015 || !!compilerOptions.noEmit; } diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_exportEqualsClass.ts b/tests/cases/fourslash/refactorConvertToEsModule_exportEqualsClass.ts similarity index 87% rename from tests/cases/fourslash/refactorConvertToEs6Module_exportEqualsClass.ts rename to tests/cases/fourslash/refactorConvertToEsModule_exportEqualsClass.ts index 2abff8c95df..b7613fe01e6 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_exportEqualsClass.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_exportEqualsClass.ts @@ -12,7 +12,7 @@ ////}; verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `import { x } from "./b"; export default class C { diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts b/tests/cases/fourslash/refactorConvertToEsModule_export_alias.ts similarity index 86% rename from tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts rename to tests/cases/fourslash/refactorConvertToEsModule_export_alias.ts index 56fe9d0808c..4df276bb9a3 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_export_alias.ts @@ -9,7 +9,7 @@ ////module.exports = exportsAlias; verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: ` export function f() {} `, diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_dotDefault.ts b/tests/cases/fourslash/refactorConvertToEsModule_export_dotDefault.ts similarity index 88% rename from tests/cases/fourslash/refactorConvertToEs6Module_export_dotDefault.ts rename to tests/cases/fourslash/refactorConvertToEsModule_export_dotDefault.ts index 8bd74041dec..09b5f1fad07 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_dotDefault.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_export_dotDefault.ts @@ -10,7 +10,7 @@ ////exports.default; verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `const _default = 0; export { _default as default }; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_invalidName.ts b/tests/cases/fourslash/refactorConvertToEsModule_export_invalidName.ts similarity index 88% rename from tests/cases/fourslash/refactorConvertToEs6Module_export_invalidName.ts rename to tests/cases/fourslash/refactorConvertToEsModule_export_invalidName.ts index bec40f756ad..be9aff92c53 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_invalidName.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_export_invalidName.ts @@ -10,7 +10,7 @@ ////exports.async = 1; verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `const _class = 0; export { _class as class }; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports.ts b/tests/cases/fourslash/refactorConvertToEsModule_export_moduleDotExports.ts similarity index 92% rename from tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports.ts rename to tests/cases/fourslash/refactorConvertToEsModule_export_moduleDotExports.ts index e88e3e2f173..1a38ba745d5 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_export_moduleDotExports.ts @@ -13,7 +13,7 @@ // See also `refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts` verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `export default function() {} export default function f() {} diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts b/tests/cases/fourslash/refactorConvertToEsModule_export_moduleDotExportsEqualsRequire.ts similarity index 96% rename from tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts rename to tests/cases/fourslash/refactorConvertToEsModule_export_moduleDotExportsEqualsRequire.ts index 8dd77f06e1d..97b559c61d4 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_export_moduleDotExportsEqualsRequire.ts @@ -31,7 +31,7 @@ goTo.file("/z.js"); verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `export * from "./a"; export { default } from "./b"; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts b/tests/cases/fourslash/refactorConvertToEsModule_export_moduleDotExports_changesImports.ts similarity index 86% rename from tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts rename to tests/cases/fourslash/refactorConvertToEsModule_export_moduleDotExports_changesImports.ts index ddc6a77721e..2d598c54d88 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_export_moduleDotExports_changesImports.ts @@ -13,7 +13,7 @@ ////const a = require("./a"); verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: { "/a.js": "export default 0;", "/b.ts": 'import a from "./a";', diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts b/tests/cases/fourslash/refactorConvertToEsModule_export_named.ts similarity index 88% rename from tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts rename to tests/cases/fourslash/refactorConvertToEsModule_export_named.ts index 481281a47a4..d8b0769eeaa 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_export_named.ts @@ -14,11 +14,11 @@ const [r0, r1, r2] = test.ranges(); verify.getSuggestionDiagnostics([ - { message: "File is a CommonJS module; it may be converted to an ES6 module.", code: 80001, range: r0 }, + { message: "File is a CommonJS module; it may be converted to an ES module.", code: 80001, range: r0 }, ]); verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `export function f() {} export class C {} diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_namedClassExpression.ts b/tests/cases/fourslash/refactorConvertToEsModule_export_namedClassExpression.ts similarity index 86% rename from tests/cases/fourslash/refactorConvertToEs6Module_export_namedClassExpression.ts rename to tests/cases/fourslash/refactorConvertToEsModule_export_namedClassExpression.ts index e1cb86e8d68..8847ff61068 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_namedClassExpression.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_export_namedClassExpression.ts @@ -8,7 +8,7 @@ ////exports.D = class D { static instance = new D(); } verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `export const C = class E { static instance = new E(); } export class D { static instance = new D(); }`, diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_namedFunctionExpression.ts b/tests/cases/fourslash/refactorConvertToEsModule_export_namedFunctionExpression.ts similarity index 87% rename from tests/cases/fourslash/refactorConvertToEs6Module_export_namedFunctionExpression.ts rename to tests/cases/fourslash/refactorConvertToEsModule_export_namedFunctionExpression.ts index c4468a1a189..0144912fb56 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_namedFunctionExpression.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_export_namedFunctionExpression.ts @@ -8,7 +8,7 @@ ////exports.h = function h() { h(); } verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `export const f = function g() { g(); } export function h() { h(); }`, diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts b/tests/cases/fourslash/refactorConvertToEsModule_export_object.ts similarity index 86% rename from tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts rename to tests/cases/fourslash/refactorConvertToEsModule_export_object.ts index 664796b1172..20e643a298b 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_export_object.ts @@ -16,7 +16,7 @@ ////const a = require("./a.js"); verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `export const x = 0; export function f() { } diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_object_shorthand.ts b/tests/cases/fourslash/refactorConvertToEsModule_export_object_shorthand.ts similarity index 87% rename from tests/cases/fourslash/refactorConvertToEs6Module_export_object_shorthand.ts rename to tests/cases/fourslash/refactorConvertToEsModule_export_object_shorthand.ts index 62588f6a531..b82f8230d5f 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_object_shorthand.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_export_object_shorthand.ts @@ -10,7 +10,7 @@ ////module.exports = { f }; verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `function f() {} export default { f };`, diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts b/tests/cases/fourslash/refactorConvertToEsModule_export_referenced.ts similarity index 91% rename from tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts rename to tests/cases/fourslash/refactorConvertToEsModule_export_referenced.ts index 7a5b94b0a98..4f16770d989 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_export_referenced.ts @@ -17,7 +17,7 @@ ////} verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `export const x = 0; x; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts b/tests/cases/fourslash/refactorConvertToEsModule_expressionToDeclaration.ts similarity index 90% rename from tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts rename to tests/cases/fourslash/refactorConvertToEsModule_expressionToDeclaration.ts index 73dcff28285..bda1c079b9d 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_expressionToDeclaration.ts @@ -10,7 +10,7 @@ ////exports.C = class C extends D { m() {} } verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `var C = {}; console.log(C); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts b/tests/cases/fourslash/refactorConvertToEsModule_import_arrayBindingPattern.ts similarity index 85% rename from tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts rename to tests/cases/fourslash/refactorConvertToEsModule_import_arrayBindingPattern.ts index f373f00dfe7..2784905fe1e 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_import_arrayBindingPattern.ts @@ -8,7 +8,7 @@ ////x; y; verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `import _x from "x"; const [x, y] = _x; x; y;`, diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_es6DefaultImport.ts b/tests/cases/fourslash/refactorConvertToEsModule_import_es6DefaultImport.ts similarity index 86% rename from tests/cases/fourslash/refactorConvertToEs6Module_import_es6DefaultImport.ts rename to tests/cases/fourslash/refactorConvertToEsModule_import_es6DefaultImport.ts index 9fe26a24010..54d0f4d46cd 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_es6DefaultImport.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_import_es6DefaultImport.ts @@ -10,7 +10,7 @@ ////y(); verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `import x from 'x'; x(); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_includeDefaultUses.ts b/tests/cases/fourslash/refactorConvertToEsModule_import_includeDefaultUses.ts similarity index 84% rename from tests/cases/fourslash/refactorConvertToEs6Module_import_includeDefaultUses.ts rename to tests/cases/fourslash/refactorConvertToEsModule_import_includeDefaultUses.ts index a75854595f3..77f21f10e24 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_includeDefaultUses.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_import_includeDefaultUses.ts @@ -9,7 +9,7 @@ ////x.y; verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `import x, { y } from "x"; x(); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts b/tests/cases/fourslash/refactorConvertToEsModule_import_multipleUniqueIdentifiers.ts similarity index 89% rename from tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts rename to tests/cases/fourslash/refactorConvertToEsModule_import_multipleUniqueIdentifiers.ts index faf8ec5eb69..fcfb23c5ed1 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_import_multipleUniqueIdentifiers.ts @@ -10,7 +10,7 @@ ////x; a; b; c; d; verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `import x from "x"; import _x from "x"; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts b/tests/cases/fourslash/refactorConvertToEsModule_import_multipleVariableDeclarations.ts similarity index 88% rename from tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts rename to tests/cases/fourslash/refactorConvertToEsModule_import_multipleVariableDeclarations.ts index 33f31299f8b..e3695bd59ed 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_import_multipleVariableDeclarations.ts @@ -10,7 +10,7 @@ ////x; y; z; verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `import x from "x"; const y = 0; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts b/tests/cases/fourslash/refactorConvertToEsModule_import_nameFromModuleSpecifier.ts similarity index 89% rename from tests/cases/fourslash/refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts rename to tests/cases/fourslash/refactorConvertToEsModule_import_nameFromModuleSpecifier.ts index 3427e62fb9c..e12264c8667 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_import_nameFromModuleSpecifier.ts @@ -9,7 +9,7 @@ ////const [] = require("1a"); verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `import aB from "a-b"; const [] = aB; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts b/tests/cases/fourslash/refactorConvertToEsModule_import_objectBindingPattern_complex.ts similarity index 85% rename from tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts rename to tests/cases/fourslash/refactorConvertToEsModule_import_objectBindingPattern_complex.ts index 74071ba55fb..320b433df3b 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_import_objectBindingPattern_complex.ts @@ -8,7 +8,7 @@ ////a; b; verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `import x from "x"; const { x: { a, b } } = x; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts b/tests/cases/fourslash/refactorConvertToEsModule_import_objectBindingPattern_plain.ts similarity index 84% rename from tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts rename to tests/cases/fourslash/refactorConvertToEsModule_import_objectBindingPattern_plain.ts index 31b9cb41f62..a26b8e4fc08 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_import_objectBindingPattern_plain.ts @@ -8,7 +8,7 @@ ////x; z; verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `import { x, y as z } from "x"; x; z;`, diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_onlyNamedImports.ts b/tests/cases/fourslash/refactorConvertToEsModule_import_onlyNamedImports.ts similarity index 82% rename from tests/cases/fourslash/refactorConvertToEs6Module_import_onlyNamedImports.ts rename to tests/cases/fourslash/refactorConvertToEsModule_import_onlyNamedImports.ts index 2b40e1ade36..3b8575d6f47 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_onlyNamedImports.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_import_onlyNamedImports.ts @@ -8,7 +8,7 @@ ////x.y; verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `import { y } from "x"; y;`, diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts b/tests/cases/fourslash/refactorConvertToEsModule_import_propertyAccess.ts similarity index 90% rename from tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts rename to tests/cases/fourslash/refactorConvertToEsModule_import_propertyAccess.ts index dea48380597..9ff80563c76 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_import_propertyAccess.ts @@ -12,7 +12,7 @@ ////x; a; b; verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `import x from "x"; import { c as a } from "b"; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_shadowing.ts b/tests/cases/fourslash/refactorConvertToEsModule_import_shadowing.ts similarity index 85% rename from tests/cases/fourslash/refactorConvertToEs6Module_import_shadowing.ts rename to tests/cases/fourslash/refactorConvertToEsModule_import_shadowing.ts index f506f970085..e2becf8b8d0 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_shadowing.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_import_shadowing.ts @@ -9,7 +9,7 @@ ////mod.x(x); verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `import { x as _x } from "mod"; const x = 0; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts b/tests/cases/fourslash/refactorConvertToEsModule_import_sideEffect.ts similarity index 84% rename from tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts rename to tests/cases/fourslash/refactorConvertToEsModule_import_sideEffect.ts index e8023ac414a..d252f28ae9b 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_import_sideEffect.ts @@ -9,6 +9,6 @@ ////require("foo"); verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: 'import "foo";', }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_inCommonJsFile.ts b/tests/cases/fourslash/refactorConvertToEsModule_inCommonJsFile.ts similarity index 92% rename from tests/cases/fourslash/refactorConvertToEs6Module_inCommonJsFile.ts rename to tests/cases/fourslash/refactorConvertToEsModule_inCommonJsFile.ts index d56bdc303fb..bd739e59dca 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_inCommonJsFile.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_inCommonJsFile.ts @@ -26,6 +26,6 @@ verify.codeFixAvailable([]); goTo.file("/d.js"); verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: 'export default 0;', }); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_missingInitializer.ts b/tests/cases/fourslash/refactorConvertToEsModule_missingInitializer.ts similarity index 82% rename from tests/cases/fourslash/refactorConvertToEs6Module_missingInitializer.ts rename to tests/cases/fourslash/refactorConvertToEsModule_missingInitializer.ts index 90a256c2480..b6ee4fda681 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_missingInitializer.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_missingInitializer.ts @@ -8,7 +8,7 @@ ////let x; x; verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `import "m"; let x; x;` diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_module_node12.ts b/tests/cases/fourslash/refactorConvertToEsModule_module_node12.ts similarity index 100% rename from tests/cases/fourslash/refactorConvertToEs6Module_module_node12.ts rename to tests/cases/fourslash/refactorConvertToEsModule_module_node12.ts diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_module_nodenext.ts b/tests/cases/fourslash/refactorConvertToEsModule_module_nodenext.ts similarity index 100% rename from tests/cases/fourslash/refactorConvertToEs6Module_module_nodenext.ts rename to tests/cases/fourslash/refactorConvertToEsModule_module_nodenext.ts diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_notAtTopLevel.ts b/tests/cases/fourslash/refactorConvertToEsModule_notAtTopLevel.ts similarity index 100% rename from tests/cases/fourslash/refactorConvertToEs6Module_notAtTopLevel.ts rename to tests/cases/fourslash/refactorConvertToEsModule_notAtTopLevel.ts diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_notInCommonjsProject.ts b/tests/cases/fourslash/refactorConvertToEsModule_notInCommonjsProject.ts similarity index 100% rename from tests/cases/fourslash/refactorConvertToEs6Module_notInCommonjsProject.ts rename to tests/cases/fourslash/refactorConvertToEsModule_notInCommonjsProject.ts diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_notInCommonjsProject_yesIfSomeEs6Module.ts b/tests/cases/fourslash/refactorConvertToEsModule_notInCommonjsProject_yesIfSomeEsModule.ts similarity index 83% rename from tests/cases/fourslash/refactorConvertToEs6Module_notInCommonjsProject_yesIfSomeEs6Module.ts rename to tests/cases/fourslash/refactorConvertToEsModule_notInCommonjsProject_yesIfSomeEsModule.ts index 491b61a0bc2..5bc9502b0f2 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_notInCommonjsProject_yesIfSomeEs6Module.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_notInCommonjsProject_yesIfSomeEsModule.ts @@ -9,6 +9,6 @@ ////export const y = 0; verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: "export const x = 0;", }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_preserveQuotes.ts b/tests/cases/fourslash/refactorConvertToEsModule_preserveQuotes.ts similarity index 82% rename from tests/cases/fourslash/refactorConvertToEs6Module_preserveQuotes.ts rename to tests/cases/fourslash/refactorConvertToEsModule_preserveQuotes.ts index d8c48d0e971..2ed5c156123 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_preserveQuotes.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_preserveQuotes.ts @@ -7,6 +7,6 @@ ////const a = require('a'); a; verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: "import a from 'a'; a;", }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_renameWithinTransformedExports.ts b/tests/cases/fourslash/refactorConvertToEsModule_renameWithinTransformedExports.ts similarity index 94% rename from tests/cases/fourslash/refactorConvertToEs6Module_renameWithinTransformedExports.ts rename to tests/cases/fourslash/refactorConvertToEsModule_renameWithinTransformedExports.ts index 5908aedd002..528c982292e 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_renameWithinTransformedExports.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_renameWithinTransformedExports.ts @@ -24,7 +24,7 @@ verify.codeFix({ index: 2, - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `import { defer } from "q"; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_unexported_uninitialized_var.ts b/tests/cases/fourslash/refactorConvertToEsModule_unexported_uninitialized_var.ts similarity index 89% rename from tests/cases/fourslash/refactorConvertToEs6Module_unexported_uninitialized_var.ts rename to tests/cases/fourslash/refactorConvertToEsModule_unexported_uninitialized_var.ts index e9cbaafee58..5f7f791e70d 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_unexported_uninitialized_var.ts +++ b/tests/cases/fourslash/refactorConvertToEsModule_unexported_uninitialized_var.ts @@ -10,12 +10,12 @@ ////console.log(privateUnrelated); verify.getSuggestionDiagnostics([{ - message: "File is a CommonJS module; it may be converted to an ES6 module.", + message: "File is a CommonJS module; it may be converted to an ES module.", code: 80001, }]); verify.codeFix({ - description: "Convert to ES6 module", + description: "Convert to ES module", newFileContent: `var privateUnrelated; export function f() {} From 506a95b5a5c992c774eb0c9463ee20dc1f5c8a6c Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Sat, 16 Oct 2021 06:06:14 +0000 Subject: [PATCH 21/60] Update package-lock.json --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f39b1c7778f..e23a451298c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5339,9 +5339,9 @@ "dev": true }, "mocha": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.2.tgz", - "integrity": "sha512-ta3LtJ+63RIBP03VBjMGtSqbe6cWXRejF9SyM9Zyli1CKZJZ+vfCTj3oW24V7wAphMJdpOFLoMI3hjJ1LWbs0w==", + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.3.tgz", + "integrity": "sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw==", "dev": true, "requires": { "@ungap/promise-all-settled": "1.1.2", From 39ff1568e9676d40cf545477e9fd04077eff9b78 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Wed, 22 Sep 2021 16:08:27 -0400 Subject: [PATCH 22/60] Changes to enable the module conversion script * shorthand -> long for `factory` since the typeformer script doesn't know how to handle it. * Use setter to change `ts.sys` (similar to #35399). * Fix `loggedIO` with empty namespaces to indicate dependency (similar to 50603eda). * Move `Map` / `Set` stuff from `core.ts` to `corePublic.ts` since the types are there. --- src/compiler/core.ts | 20 -------------------- src/compiler/corePublic.ts | 28 ++++++++++++++++++++++++++-- src/compiler/sys.ts | 5 +++++ src/compiler/transformer.ts | 2 +- src/loggedIO/loggedIO.ts | 6 +++++- src/tsserver/webServer.ts | 2 +- 6 files changed, 38 insertions(+), 25 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index eb07a11cbac..fab736de008 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1,25 +1,5 @@ /* @internal */ namespace ts { - type GetIteratorCallback = | ReadonlyESMap | undefined>(iterable: I) => Iterator< - I extends ReadonlyESMap ? [K, V] : - I extends ReadonlySet ? T : - I extends readonly (infer T)[] ? T : - I extends undefined ? undefined : - never>; - - function getCollectionImplementation< - K1 extends MatchingKeys any>, - K2 extends MatchingKeys ReturnType<(typeof NativeCollections)[K1]>> - >(name: string, nativeFactory: K1, shimFactory: K2): NonNullable> { - // NOTE: ts.ShimCollections will be defined for typescriptServices.js but not for tsc.js, so we must test for it. - const constructor = NativeCollections[nativeFactory]() ?? ShimCollections?.[shimFactory](getIterator); - if (constructor) return constructor as NonNullable>; - throw new Error(`TypeScript requires an environment that provides a compatible native ${name} implementation.`); - } - - export const Map = getCollectionImplementation("Map", "tryGetNativeMap", "createMapShim"); - export const Set = getCollectionImplementation("Set", "tryGetNativeSet", "createSetShim"); - export function getIterator | ReadonlyESMap | undefined>(iterable: I): Iterator< I extends ReadonlyESMap ? [K, V] : I extends ReadonlySet ? T : diff --git a/src/compiler/corePublic.ts b/src/compiler/corePublic.ts index 58d53aec456..4391aa1b5f2 100644 --- a/src/compiler/corePublic.ts +++ b/src/compiler/corePublic.ts @@ -113,7 +113,7 @@ namespace ts { } /* @internal */ - export namespace NativeCollections { + namespace NativeCollections { declare const Map: MapConstructor | undefined; declare const Set: SetConstructor | undefined; @@ -135,4 +135,28 @@ namespace ts { return typeof Set !== "undefined" && "entries" in Set.prototype && new Set([0]).size === 1 ? Set : undefined; } } -} \ No newline at end of file + + /* @internal */ + export const Map = getCollectionImplementation("Map", "tryGetNativeMap", "createMapShim"); + /* @internal */ + export const Set = getCollectionImplementation("Set", "tryGetNativeSet", "createSetShim"); + + /* @internal */ + type GetIteratorCallback = | ReadonlyESMap | undefined>(iterable: I) => Iterator< + I extends ReadonlyESMap ? [K, V] : + I extends ReadonlySet ? T : + I extends readonly (infer T)[] ? T : + I extends undefined ? undefined : + never>; + + /* @internal */ + function getCollectionImplementation< + K1 extends MatchingKeys any>, + K2 extends MatchingKeys ReturnType<(typeof NativeCollections)[K1]>> + >(name: string, nativeFactory: K1, shimFactory: K2): NonNullable> { + // NOTE: ts.ShimCollections will be defined for typescriptServices.js but not for tsc.js, so we must test for it. + const constructor = NativeCollections[nativeFactory]() ?? ShimCollections?.[shimFactory](getIterator); + if (constructor) return constructor as NonNullable>; + throw new Error(`TypeScript requires an environment that provides a compatible native ${name} implementation.`); + } +} diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 4f853cbb146..a5330d807cd 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -1900,6 +1900,11 @@ namespace ts { return sys!; })(); + /*@internal*/ + export function setSys(s: System) { + sys = s; + } + if (sys && sys.getEnvironmentVariable) { setCustomPollingValues(sys); Debug.setAssertionLevel(/^development$/i.test(sys.getEnvironmentVariable("NODE_ENV")) diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index 12aeca7f67d..7207d8a60d7 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -566,7 +566,7 @@ namespace ts { } export const nullTransformationContext: TransformationContext = { - factory, + factory: factory, // eslint-disable-line object-shorthand getCompilerOptions: () => ({}), getEmitResolver: notImplemented, getEmitHost: notImplemented, diff --git a/src/loggedIO/loggedIO.ts b/src/loggedIO/loggedIO.ts index c572f08fce6..fdd8c91906d 100644 --- a/src/loggedIO/loggedIO.ts +++ b/src/loggedIO/loggedIO.ts @@ -1,4 +1,4 @@ -namespace Playback { +namespace Playback { // eslint-disable-line one-namespace-per-file interface FileInformation { contents?: string; contentsPath?: string; @@ -445,3 +445,7 @@ namespace Playback { return wrapper; } } + +// empty modules for the module migration script +namespace ts.server { } // eslint-disable-line one-namespace-per-file +namespace Harness { } // eslint-disable-line one-namespace-per-file diff --git a/src/tsserver/webServer.ts b/src/tsserver/webServer.ts index dced32152b7..18d9ab4d13e 100644 --- a/src/tsserver/webServer.ts +++ b/src/tsserver/webServer.ts @@ -78,7 +78,7 @@ namespace ts.server { }; // Do this after sys has been set as findArguments is going to work only then const sys = server.createWebSystem(webHost, args, () => findArgument("--executingFilePath") || location + ""); - ts.sys = sys; + setSys(sys); const localeStr = findArgument("--locale"); if (localeStr) { validateLocaleAndSetLanguage(localeStr, sys); From 26aea0df613c61edfbfe7b003ff564bea421d071 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Sun, 17 Oct 2021 06:07:02 +0000 Subject: [PATCH 23/60] Update package-lock.json --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e23a451298c..049d13fa7cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -676,9 +676,9 @@ "dev": true }, "@types/node": { - "version": "16.11.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.0.tgz", - "integrity": "sha512-8MLkBIYQMuhRBQzGN9875bYsOhPnf/0rgXGo66S2FemHkhbn9qtsz9ywV1iCG+vbjigE4WUNVvw37Dx+L0qsPg==", + "version": "16.11.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.1.tgz", + "integrity": "sha512-PYGcJHL9mwl1Ek3PLiYgyEKtwTMmkMw4vbiyz/ps3pfdRYLVv+SN7qHVAImrjdAXxgluDEw6Ph4lyv+m9UpRmA==", "dev": true }, "@types/node-fetch": { From 8d715ff53eb94acad32ab0ee8652569ae434eacd Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 18 Oct 2021 09:00:00 -0700 Subject: [PATCH 24/60] Error on mapped type w/properties (#46346) * Error on mapped types with properties 1. Error on properties of type literals with computed properties whose name is a binary expression with `in`, because that's a good sign of a mapped type. 2. Parse following properties on mapped types, and error on them. 3. Stop checking computed property names in (1) to avoid producing errors based on misinterpreting mapped type syntax as an expression. * add comment in types.ts * Update API again * Check interfaces and classes too * Add missed check in updateMappedTypeNode --- src/compiler/checker.ts | 20 +++- src/compiler/diagnosticMessages.json | 5 +- src/compiler/factory/nodeFactory.ts | 8 +- src/compiler/parser.ts | 6 +- src/compiler/types.ts | 6 +- src/compiler/visitorPublic.ts | 3 +- .../convertLiteralTypeToMappedType.ts | 9 +- .../codefixes/convertToMappedObjectType.ts | 3 +- .../reference/api/tsserverlibrary.d.ts | 10 +- tests/baselines/reference/api/typescript.d.ts | 10 +- .../reference/mappedTypeProperties.errors.txt | 87 +++++++++++++++++ .../reference/mappedTypeProperties.js | 72 ++++++++++++++ .../reference/mappedTypeProperties.symbols | 93 ++++++++++++++++++ .../reference/mappedTypeProperties.types | 95 +++++++++++++++++++ .../reference/smartSelection_complex.baseline | 1 + .../types/mapped/mappedTypeProperties.ts | 42 ++++++++ 16 files changed, 448 insertions(+), 22 deletions(-) create mode 100644 tests/baselines/reference/mappedTypeProperties.errors.txt create mode 100644 tests/baselines/reference/mappedTypeProperties.js create mode 100644 tests/baselines/reference/mappedTypeProperties.symbols create mode 100644 tests/baselines/reference/mappedTypeProperties.types create mode 100644 tests/cases/conformance/types/mapped/mappedTypeProperties.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f5aed2e1d5c..bcf3a78f052 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4973,7 +4973,7 @@ namespace ts { const typeParameterNode = typeParameterToDeclarationWithConstraint(getTypeParameterFromMappedType(type), context, appropriateConstraintTypeNode); const nameTypeNode = type.declaration.nameType ? typeToTypeNodeHelper(getNameTypeFromMappedType(type)!, context) : undefined; const templateTypeNode = typeToTypeNodeHelper(removeMissingType(getTemplateTypeFromMappedType(type), !!(getMappedTypeModifiers(type) & MappedTypeModifiers.IncludeOptional)), context); - const mappedTypeNode = factory.createMappedTypeNode(readonlyToken, typeParameterNode, nameTypeNode, questionToken, templateTypeNode); + const mappedTypeNode = factory.createMappedTypeNode(readonlyToken, typeParameterNode, nameTypeNode, questionToken, templateTypeNode, /*members*/ undefined); context.approximateLength += 10; return setEmitFlags(mappedTypeNode, EmitFlags.SingleLine); } @@ -26811,6 +26811,10 @@ namespace ts { function checkComputedPropertyName(node: ComputedPropertyName): Type { const links = getNodeLinks(node.expression); if (!links.resolvedType) { + if ((isTypeLiteralNode(node.parent.parent) || isClassLike(node.parent.parent) || isInterfaceDeclaration(node.parent.parent)) + && isBinaryExpression(node.expression) && node.expression.operatorToken.kind === SyntaxKind.InKeyword) { + return links.resolvedType = errorType; + } links.resolvedType = checkExpression(node.expression); // The computed property name of a non-static class field within a loop must be stored in a block-scoped binding. // (It needs to be bound at class evaluation time.) @@ -34736,6 +34740,7 @@ namespace ts { } function checkMappedType(node: MappedTypeNode) { + checkGrammarMappedType(node); checkSourceElement(node.typeParameter); checkSourceElement(node.nameType); checkSourceElement(node.type); @@ -34755,6 +34760,12 @@ namespace ts { } } + function checkGrammarMappedType(node: MappedTypeNode) { + if (node.members?.length) { + return grammarErrorOnNode(node.members[0], Diagnostics.A_mapped_type_may_not_declare_properties_or_methods); + } + } + function checkThisType(node: ThisTypeNode) { getTypeFromThisTypeNode(node); } @@ -43417,6 +43428,11 @@ namespace ts { } function checkGrammarProperty(node: PropertyDeclaration | PropertySignature) { + if (isComputedPropertyName(node.name) && isBinaryExpression(node.name.expression) && node.name.expression.operatorToken.kind === SyntaxKind.InKeyword) { + return grammarErrorOnNode( + (node.parent as ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode).members[0], + Diagnostics.A_mapped_type_may_not_declare_properties_or_methods); + } if (isClassLike(node.parent)) { if (isStringLiteral(node.name) && node.name.text === "constructor") { return grammarErrorOnNode(node.name, Diagnostics.Classes_may_not_have_a_field_named_constructor); @@ -43436,7 +43452,7 @@ namespace ts { return grammarErrorOnNode(node.initializer, Diagnostics.An_interface_property_cannot_have_an_initializer); } } - else if (node.parent.kind === SyntaxKind.TypeLiteral) { + else if (isTypeLiteralNode(node.parent)) { if (checkGrammarForInvalidDynamicName(node.name, Diagnostics.A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type)) { return true; } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index d21a923a87b..a40439d012a 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -5993,7 +5993,10 @@ "category": "Error", "code": 7060 }, - + "A mapped type may not declare properties or methods.": { + "category": "Error", + "code": 7061 + }, "You cannot rename this element.": { "category": "Error", diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index b87d54e5dab..963ce75441f 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -2112,25 +2112,27 @@ namespace ts { } // @api - function createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode { + function createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined, members: readonly TypeElement[] | undefined): MappedTypeNode { const node = createBaseNode(SyntaxKind.MappedType); node.readonlyToken = readonlyToken; node.typeParameter = typeParameter; node.nameType = nameType; node.questionToken = questionToken; node.type = type; + node.members = members && createNodeArray(members); node.transformFlags = TransformFlags.ContainsTypeScript; return node; } // @api - function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode { + function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined, members: NodeArray | undefined): MappedTypeNode { return node.readonlyToken !== readonlyToken || node.typeParameter !== typeParameter || node.nameType !== nameType || node.questionToken !== questionToken || node.type !== type - ? update(createMappedTypeNode(readonlyToken, typeParameter, nameType, questionToken, type), node) + || node.members !== members + ? update(createMappedTypeNode(readonlyToken, typeParameter, nameType, questionToken, type, members), node) : node; } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 59eaaa2efbb..1109d36a610 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -212,7 +212,8 @@ namespace ts { visitNode(cbNode, (node as MappedTypeNode).typeParameter) || visitNode(cbNode, (node as MappedTypeNode).nameType) || visitNode(cbNode, (node as MappedTypeNode).questionToken) || - visitNode(cbNode, (node as MappedTypeNode).type); + visitNode(cbNode, (node as MappedTypeNode).type) || + visitNodes(cbNode, cbNodes, (node as MappedTypeNode).members); case SyntaxKind.LiteralType: return visitNode(cbNode, (node as LiteralTypeNode).literal); case SyntaxKind.NamedTupleMember: @@ -3534,8 +3535,9 @@ namespace ts { } const type = parseTypeAnnotation(); parseSemicolon(); + const members = parseList(ParsingContext.TypeMembers, parseTypeMember); parseExpected(SyntaxKind.CloseBraceToken); - return finishNode(factory.createMappedTypeNode(readonlyToken, typeParameter, nameType, questionToken, type), pos); + return finishNode(factory.createMappedTypeNode(readonlyToken, typeParameter, nameType, questionToken, type, members), pos); } function parseTupleElementType() { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index beff69baaa1..a5b143e06f3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1707,6 +1707,8 @@ namespace ts { readonly nameType?: TypeNode; readonly questionToken?: QuestionToken | PlusToken | MinusToken; readonly type?: TypeNode; + /** Used only to produce grammar errors */ + readonly members?: NodeArray; } export interface LiteralTypeNode extends TypeNode { @@ -7212,8 +7214,8 @@ namespace ts { updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode; createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode; updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode; - createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; - updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; + createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined, members: NodeArray | undefined): MappedTypeNode; + updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined, members: NodeArray | undefined): MappedTypeNode; createLiteralTypeNode(literal: LiteralTypeNode["literal"]): LiteralTypeNode; updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralTypeNode["literal"]): LiteralTypeNode; createTemplateLiteralType(head: TemplateHead, templateSpans: readonly TemplateLiteralTypeSpan[]): TemplateLiteralTypeNode; diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index 869d4604bd0..5651ac043d3 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -629,7 +629,8 @@ namespace ts { nodeVisitor(node.typeParameter, visitor, isTypeParameterDeclaration), nodeVisitor(node.nameType, visitor, isTypeNode), nodeVisitor(node.questionToken, tokenVisitor, isQuestionOrPlusOrMinusToken), - nodeVisitor(node.type, visitor, isTypeNode)); + nodeVisitor(node.type, visitor, isTypeNode), + nodesVisitor(node.members, visitor, isTypeElement)); case SyntaxKind.LiteralType: Debug.type(node); diff --git a/src/services/codefixes/convertLiteralTypeToMappedType.ts b/src/services/codefixes/convertLiteralTypeToMappedType.ts index 4801d8e5f29..edcbbe0c0ce 100644 --- a/src/services/codefixes/convertLiteralTypeToMappedType.ts +++ b/src/services/codefixes/convertLiteralTypeToMappedType.ts @@ -47,7 +47,12 @@ namespace ts.codefix { } function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, { container, typeNode, constraint, name }: Info): void { - changes.replaceNode(sourceFile, container, factory.createMappedTypeNode(/*readonlyToken*/ undefined, - factory.createTypeParameterDeclaration(name, factory.createTypeReferenceNode(constraint)), /*nameType*/ undefined, /*questionToken*/ undefined, typeNode)); + changes.replaceNode(sourceFile, container, factory.createMappedTypeNode( + /*readonlyToken*/ undefined, + factory.createTypeParameterDeclaration(name, factory.createTypeReferenceNode(constraint)), + /*nameType*/ undefined, + /*questionToken*/ undefined, + typeNode, + /*members*/ undefined)); } } diff --git a/src/services/codefixes/convertToMappedObjectType.ts b/src/services/codefixes/convertToMappedObjectType.ts index 76da5233a51..dc6c2f5cd50 100644 --- a/src/services/codefixes/convertToMappedObjectType.ts +++ b/src/services/codefixes/convertToMappedObjectType.ts @@ -46,7 +46,8 @@ namespace ts.codefix { mappedTypeParameter, /*nameType*/ undefined, indexSignature.questionToken, - indexSignature.type); + indexSignature.type, + /*members*/ undefined); const intersectionType = factory.createIntersectionTypeNode([ ...getAllSuperTypeNodes(container), mappedIntersectionType, diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 349e025e58e..116be4316f9 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -973,6 +973,8 @@ declare namespace ts { readonly nameType?: TypeNode; readonly questionToken?: QuestionToken | PlusToken | MinusToken; readonly type?: TypeNode; + /** Used only to produce grammar errors */ + readonly members?: NodeArray; } export interface LiteralTypeNode extends TypeNode { readonly kind: SyntaxKind.LiteralType; @@ -3420,8 +3422,8 @@ declare namespace ts { updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode; createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode; updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode; - createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; - updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; + createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined, members: NodeArray | undefined): MappedTypeNode; + updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined, members: NodeArray | undefined): MappedTypeNode; createLiteralTypeNode(literal: LiteralTypeNode["literal"]): LiteralTypeNode; updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralTypeNode["literal"]): LiteralTypeNode; createTemplateLiteralType(head: TemplateHead, templateSpans: readonly TemplateLiteralTypeSpan[]): TemplateLiteralTypeNode; @@ -10779,9 +10781,9 @@ declare namespace ts { /** @deprecated Use `factory.updateIndexedAccessTypeNode` or the factory supplied by your transformation context instead. */ const updateIndexedAccessTypeNode: (node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) => IndexedAccessTypeNode; /** @deprecated Use `factory.createMappedTypeNode` or the factory supplied by your transformation context instead. */ - const createMappedTypeNode: (readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined) => MappedTypeNode; + const createMappedTypeNode: (readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined, members: NodeArray | undefined) => MappedTypeNode; /** @deprecated Use `factory.updateMappedTypeNode` or the factory supplied by your transformation context instead. */ - const updateMappedTypeNode: (node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined) => MappedTypeNode; + const updateMappedTypeNode: (node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined, members: NodeArray | undefined) => MappedTypeNode; /** @deprecated Use `factory.createLiteralTypeNode` or the factory supplied by your transformation context instead. */ const createLiteralTypeNode: (literal: LiteralExpression | BooleanLiteral | PrefixUnaryExpression | NullLiteral) => LiteralTypeNode; /** @deprecated Use `factory.updateLiteralTypeNode` or the factory supplied by your transformation context instead. */ diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 2a2c398553c..56d764c664c 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -973,6 +973,8 @@ declare namespace ts { readonly nameType?: TypeNode; readonly questionToken?: QuestionToken | PlusToken | MinusToken; readonly type?: TypeNode; + /** Used only to produce grammar errors */ + readonly members?: NodeArray; } export interface LiteralTypeNode extends TypeNode { readonly kind: SyntaxKind.LiteralType; @@ -3420,8 +3422,8 @@ declare namespace ts { updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode; createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode; updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode; - createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; - updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; + createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined, members: NodeArray | undefined): MappedTypeNode; + updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined, members: NodeArray | undefined): MappedTypeNode; createLiteralTypeNode(literal: LiteralTypeNode["literal"]): LiteralTypeNode; updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralTypeNode["literal"]): LiteralTypeNode; createTemplateLiteralType(head: TemplateHead, templateSpans: readonly TemplateLiteralTypeSpan[]): TemplateLiteralTypeNode; @@ -6978,9 +6980,9 @@ declare namespace ts { /** @deprecated Use `factory.updateIndexedAccessTypeNode` or the factory supplied by your transformation context instead. */ const updateIndexedAccessTypeNode: (node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) => IndexedAccessTypeNode; /** @deprecated Use `factory.createMappedTypeNode` or the factory supplied by your transformation context instead. */ - const createMappedTypeNode: (readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined) => MappedTypeNode; + const createMappedTypeNode: (readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined, members: NodeArray | undefined) => MappedTypeNode; /** @deprecated Use `factory.updateMappedTypeNode` or the factory supplied by your transformation context instead. */ - const updateMappedTypeNode: (node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined) => MappedTypeNode; + const updateMappedTypeNode: (node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined, members: NodeArray | undefined) => MappedTypeNode; /** @deprecated Use `factory.createLiteralTypeNode` or the factory supplied by your transformation context instead. */ const createLiteralTypeNode: (literal: LiteralExpression | BooleanLiteral | PrefixUnaryExpression | NullLiteral) => LiteralTypeNode; /** @deprecated Use `factory.updateLiteralTypeNode` or the factory supplied by your transformation context instead. */ diff --git a/tests/baselines/reference/mappedTypeProperties.errors.txt b/tests/baselines/reference/mappedTypeProperties.errors.txt new file mode 100644 index 00000000000..9f64d7e8563 --- /dev/null +++ b/tests/baselines/reference/mappedTypeProperties.errors.txt @@ -0,0 +1,87 @@ +tests/cases/conformance/types/mapped/mappedTypeProperties.ts(3,5): error TS7061: A mapped type may not declare properties or methods. +tests/cases/conformance/types/mapped/mappedTypeProperties.ts(9,5): error TS7061: A mapped type may not declare properties or methods. +tests/cases/conformance/types/mapped/mappedTypeProperties.ts(14,5): error TS7061: A mapped type may not declare properties or methods. +tests/cases/conformance/types/mapped/mappedTypeProperties.ts(18,5): error TS7061: A mapped type may not declare properties or methods. +tests/cases/conformance/types/mapped/mappedTypeProperties.ts(23,5): error TS7061: A mapped type may not declare properties or methods. +tests/cases/conformance/types/mapped/mappedTypeProperties.ts(27,5): error TS7061: A mapped type may not declare properties or methods. +tests/cases/conformance/types/mapped/mappedTypeProperties.ts(31,5): error TS7061: A mapped type may not declare properties or methods. +tests/cases/conformance/types/mapped/mappedTypeProperties.ts(34,5): error TS7061: A mapped type may not declare properties or methods. +tests/cases/conformance/types/mapped/mappedTypeProperties.ts(37,5): error TS7061: A mapped type may not declare properties or methods. +tests/cases/conformance/types/mapped/mappedTypeProperties.ts(40,5): error TS1166: A computed property name in a class property declaration must have a simple literal type or a 'unique symbol' type. +tests/cases/conformance/types/mapped/mappedTypeProperties.ts(40,6): error TS2304: Cannot find name 'P'. +tests/cases/conformance/types/mapped/mappedTypeProperties.ts(40,6): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. +tests/cases/conformance/types/mapped/mappedTypeProperties.ts(40,11): error TS2361: The right-hand side of an 'in' expression must not be a primitive. +tests/cases/conformance/types/mapped/mappedTypeProperties.ts(40,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. + + +==== tests/cases/conformance/types/mapped/mappedTypeProperties.ts (14 errors) ==== + export type PlaceType = 'openSky' | 'roofed' | 'garage' + type Before = { + model: 'hour' | 'day'; + ~~~~~ +!!! error TS7061: A mapped type may not declare properties or methods. + [placeType in PlaceType]: void; + } + + type After = { + [placeType in PlaceType]: void; + model: 'hour' | 'day' + ~~~~~ +!!! error TS7061: A mapped type may not declare properties or methods. + } + + type AfterQuestion = { + [placeType in PlaceType]?: void; + model: 'hour' | 'day'; + ~~~~~ +!!! error TS7061: A mapped type may not declare properties or methods. + } + type AfterMethod = { + [placeType in PlaceType]?: void; + model(duration: number): 'hour' | 'day'; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS7061: A mapped type may not declare properties or methods. + } + + type AfterImplicit = { + [placeType in PlaceType] + model: 'hour' | 'day'; + ~~~~~ +!!! error TS7061: A mapped type may not declare properties or methods. + } + type AfterImplicitQ = { + [placeType in PlaceType]? + model: 'hour' | 'day' + ~~~~~ +!!! error TS7061: A mapped type may not declare properties or methods. + } + + interface I { + [P in PlaceType]: any + ~~~~~~~~~~~~~~~~ +!!! error TS7061: A mapped type may not declare properties or methods. + } + class C { + [P in PlaceType]: any + ~~~~~~~~~~~~~~~~ +!!! error TS7061: A mapped type may not declare properties or methods. + } + const D = class { + [P in PlaceType]: any + ~~~~~~~~~~~~~~~~ +!!! error TS7061: A mapped type may not declare properties or methods. + } + const E = class { + [P in 'a' | 'b']: any + ~~~~~~~~~~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must have a simple literal type or a 'unique symbol' type. + ~ +!!! error TS2304: Cannot find name 'P'. + ~~~~~~~~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. + ~~~ +!!! error TS2361: The right-hand side of an 'in' expression must not be a primitive. + ~~~ +!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. + } + \ No newline at end of file diff --git a/tests/baselines/reference/mappedTypeProperties.js b/tests/baselines/reference/mappedTypeProperties.js new file mode 100644 index 00000000000..fce8364b0ce --- /dev/null +++ b/tests/baselines/reference/mappedTypeProperties.js @@ -0,0 +1,72 @@ +//// [mappedTypeProperties.ts] +export type PlaceType = 'openSky' | 'roofed' | 'garage' +type Before = { + model: 'hour' | 'day'; + [placeType in PlaceType]: void; +} + +type After = { + [placeType in PlaceType]: void; + model: 'hour' | 'day' +} + +type AfterQuestion = { + [placeType in PlaceType]?: void; + model: 'hour' | 'day'; +} +type AfterMethod = { + [placeType in PlaceType]?: void; + model(duration: number): 'hour' | 'day'; +} + +type AfterImplicit = { + [placeType in PlaceType] + model: 'hour' | 'day'; +} +type AfterImplicitQ = { + [placeType in PlaceType]? + model: 'hour' | 'day' +} + +interface I { + [P in PlaceType]: any +} +class C { + [P in PlaceType]: any +} +const D = class { + [P in PlaceType]: any +} +const E = class { + [P in 'a' | 'b']: any +} + + +//// [mappedTypeProperties.js] +"use strict"; +var _a, _b; +exports.__esModule = true; +var C = /** @class */ (function () { + function C() { + } + return C; +}()); +P in PlaceType; +var D = (_a = /** @class */ (function () { + function class_1() { + } + return class_1; + }()), + P in PlaceType, + _a); +var E = (_b = /** @class */ (function () { + function class_2() { + } + return class_2; + }()), + P in 'a' | 'b', + _b); + + +//// [mappedTypeProperties.d.ts] +export declare type PlaceType = 'openSky' | 'roofed' | 'garage'; diff --git a/tests/baselines/reference/mappedTypeProperties.symbols b/tests/baselines/reference/mappedTypeProperties.symbols new file mode 100644 index 00000000000..a38d36c2406 --- /dev/null +++ b/tests/baselines/reference/mappedTypeProperties.symbols @@ -0,0 +1,93 @@ +=== tests/cases/conformance/types/mapped/mappedTypeProperties.ts === +export type PlaceType = 'openSky' | 'roofed' | 'garage' +>PlaceType : Symbol(PlaceType, Decl(mappedTypeProperties.ts, 0, 0)) + +type Before = { +>Before : Symbol(Before, Decl(mappedTypeProperties.ts, 0, 55)) + + model: 'hour' | 'day'; +>model : Symbol(model, Decl(mappedTypeProperties.ts, 1, 15)) + + [placeType in PlaceType]: void; +>[placeType in PlaceType] : Symbol([placeType in PlaceType], Decl(mappedTypeProperties.ts, 2, 26)) +} + +type After = { +>After : Symbol(After, Decl(mappedTypeProperties.ts, 4, 1)) + + [placeType in PlaceType]: void; +>placeType : Symbol(placeType, Decl(mappedTypeProperties.ts, 7, 5)) +>PlaceType : Symbol(PlaceType, Decl(mappedTypeProperties.ts, 0, 0)) + + model: 'hour' | 'day' +>model : Symbol(model, Decl(mappedTypeProperties.ts, 7, 35)) +} + +type AfterQuestion = { +>AfterQuestion : Symbol(AfterQuestion, Decl(mappedTypeProperties.ts, 9, 1)) + + [placeType in PlaceType]?: void; +>placeType : Symbol(placeType, Decl(mappedTypeProperties.ts, 12, 5)) +>PlaceType : Symbol(PlaceType, Decl(mappedTypeProperties.ts, 0, 0)) + + model: 'hour' | 'day'; +>model : Symbol(model, Decl(mappedTypeProperties.ts, 12, 36)) +} +type AfterMethod = { +>AfterMethod : Symbol(AfterMethod, Decl(mappedTypeProperties.ts, 14, 1)) + + [placeType in PlaceType]?: void; +>placeType : Symbol(placeType, Decl(mappedTypeProperties.ts, 16, 5)) +>PlaceType : Symbol(PlaceType, Decl(mappedTypeProperties.ts, 0, 0)) + + model(duration: number): 'hour' | 'day'; +>model : Symbol(model, Decl(mappedTypeProperties.ts, 16, 36)) +>duration : Symbol(duration, Decl(mappedTypeProperties.ts, 17, 10)) +} + +type AfterImplicit = { +>AfterImplicit : Symbol(AfterImplicit, Decl(mappedTypeProperties.ts, 18, 1)) + + [placeType in PlaceType] +>placeType : Symbol(placeType, Decl(mappedTypeProperties.ts, 21, 5)) +>PlaceType : Symbol(PlaceType, Decl(mappedTypeProperties.ts, 0, 0)) + + model: 'hour' | 'day'; +>model : Symbol(model, Decl(mappedTypeProperties.ts, 21, 28)) +} +type AfterImplicitQ = { +>AfterImplicitQ : Symbol(AfterImplicitQ, Decl(mappedTypeProperties.ts, 23, 1)) + + [placeType in PlaceType]? +>placeType : Symbol(placeType, Decl(mappedTypeProperties.ts, 25, 5)) +>PlaceType : Symbol(PlaceType, Decl(mappedTypeProperties.ts, 0, 0)) + + model: 'hour' | 'day' +>model : Symbol(model, Decl(mappedTypeProperties.ts, 25, 29)) +} + +interface I { +>I : Symbol(I, Decl(mappedTypeProperties.ts, 27, 1)) + + [P in PlaceType]: any +>[P in PlaceType] : Symbol(I[P in PlaceType], Decl(mappedTypeProperties.ts, 29, 13)) +} +class C { +>C : Symbol(C, Decl(mappedTypeProperties.ts, 31, 1)) + + [P in PlaceType]: any +>[P in PlaceType] : Symbol(C[P in PlaceType], Decl(mappedTypeProperties.ts, 32, 9)) +} +const D = class { +>D : Symbol(D, Decl(mappedTypeProperties.ts, 35, 5)) + + [P in PlaceType]: any +>[P in PlaceType] : Symbol(D[P in PlaceType], Decl(mappedTypeProperties.ts, 35, 17)) +} +const E = class { +>E : Symbol(E, Decl(mappedTypeProperties.ts, 38, 5)) + + [P in 'a' | 'b']: any +>[P in 'a' | 'b'] : Symbol(E[P in 'a' | 'b'], Decl(mappedTypeProperties.ts, 38, 17)) +} + diff --git a/tests/baselines/reference/mappedTypeProperties.types b/tests/baselines/reference/mappedTypeProperties.types new file mode 100644 index 00000000000..bb40340eacb --- /dev/null +++ b/tests/baselines/reference/mappedTypeProperties.types @@ -0,0 +1,95 @@ +=== tests/cases/conformance/types/mapped/mappedTypeProperties.ts === +export type PlaceType = 'openSky' | 'roofed' | 'garage' +>PlaceType : PlaceType + +type Before = { +>Before : Before + + model: 'hour' | 'day'; +>model : "hour" | "day" + + [placeType in PlaceType]: void; +>[placeType in PlaceType] : void +>placeType in PlaceType : boolean +>placeType : any +>PlaceType : any +} + +type After = { +>After : After + + [placeType in PlaceType]: void; + model: 'hour' | 'day' +>model : "hour" | "day" +} + +type AfterQuestion = { +>AfterQuestion : AfterQuestion + + [placeType in PlaceType]?: void; + model: 'hour' | 'day'; +>model : "hour" | "day" +} +type AfterMethod = { +>AfterMethod : AfterMethod + + [placeType in PlaceType]?: void; + model(duration: number): 'hour' | 'day'; +>model : (duration: number) => 'hour' | 'day' +>duration : number +} + +type AfterImplicit = { +>AfterImplicit : AfterImplicit + + [placeType in PlaceType] + model: 'hour' | 'day'; +>model : "hour" | "day" +} +type AfterImplicitQ = { +>AfterImplicitQ : AfterImplicitQ + + [placeType in PlaceType]? + model: 'hour' | 'day' +>model : "hour" | "day" +} + +interface I { + [P in PlaceType]: any +>[P in PlaceType] : any +>P in PlaceType : boolean +>P : any +>PlaceType : any +} +class C { +>C : C + + [P in PlaceType]: any +>[P in PlaceType] : any +>P in PlaceType : boolean +>P : any +>PlaceType : any +} +const D = class { +>D : typeof D +>class { [P in PlaceType]: any} : typeof D + + [P in PlaceType]: any +>[P in PlaceType] : any +>P in PlaceType : boolean +>P : any +>PlaceType : any +} +const E = class { +>E : typeof E +>class { [P in 'a' | 'b']: any} : typeof E + + [P in 'a' | 'b']: any +>[P in 'a' | 'b'] : any +>P in 'a' | 'b' : number +>P in 'a' : boolean +>P : any +>'a' : "a" +>'b' : "b" +} + diff --git a/tests/baselines/reference/smartSelection_complex.baseline b/tests/baselines/reference/smartSelection_complex.baseline index c16b1912ae7..2fc5c68c449 100644 --- a/tests/baselines/reference/smartSelection_complex.baseline +++ b/tests/baselines/reference/smartSelection_complex.baseline @@ -4,6 +4,7 @@ type X = IsExactlyAny

extends true ? T : ({ [K in keyof P]: IsExactlyAn P[K] K extends keyof T ? T[K] : P[K] IsExactlyAny extends true ? K extends keyof T ? T[K] : P[K] : P[K] + IsExactlyAny extends true ? K extends keyof T ? T[K] : P[K] : P[K]; [K in keyof P]: IsExactlyAny extends true ? K extends keyof T ? T[K] : P[K] : P[K]; { [K in keyof P]: IsExactlyAny extends true ? K extends keyof T ? T[K] : P[K] : P[K]; } { [K in keyof P]: IsExactlyAny extends true ? K extends keyof T ? T[K] : P[K] : P[K]; } & Pick> diff --git a/tests/cases/conformance/types/mapped/mappedTypeProperties.ts b/tests/cases/conformance/types/mapped/mappedTypeProperties.ts new file mode 100644 index 00000000000..407e0eaf56d --- /dev/null +++ b/tests/cases/conformance/types/mapped/mappedTypeProperties.ts @@ -0,0 +1,42 @@ +// @declaration: true +export type PlaceType = 'openSky' | 'roofed' | 'garage' +type Before = { + model: 'hour' | 'day'; + [placeType in PlaceType]: void; +} + +type After = { + [placeType in PlaceType]: void; + model: 'hour' | 'day' +} + +type AfterQuestion = { + [placeType in PlaceType]?: void; + model: 'hour' | 'day'; +} +type AfterMethod = { + [placeType in PlaceType]?: void; + model(duration: number): 'hour' | 'day'; +} + +type AfterImplicit = { + [placeType in PlaceType] + model: 'hour' | 'day'; +} +type AfterImplicitQ = { + [placeType in PlaceType]? + model: 'hour' | 'day' +} + +interface I { + [P in PlaceType]: any +} +class C { + [P in PlaceType]: any +} +const D = class { + [P in PlaceType]: any +} +const E = class { + [P in 'a' | 'b']: any +} From 605788d4ab83757c1319b53c89e464d4edefdb8d Mon Sep 17 00:00:00 2001 From: csigs Date: Mon, 18 Oct 2021 10:29:16 -0700 Subject: [PATCH 25/60] LEGO: Merge pull request 46415 LEGO: Merge pull request 46415 --- .../diagnosticMessages.generated.json.lcl | 12 ++++++------ .../diagnosticMessages.generated.json.lcl | 12 ++++++------ .../diagnosticMessages.generated.json.lcl | 12 ++++++------ .../diagnosticMessages.generated.json.lcl | 12 ++++++------ .../diagnosticMessages.generated.json.lcl | 12 ++++++------ .../diagnosticMessages.generated.json.lcl | 12 ++++++------ .../diagnosticMessages.generated.json.lcl | 12 ++++++------ .../diagnosticMessages.generated.json.lcl | 12 ++++++------ .../diagnosticMessages.generated.json.lcl | 12 ++++++------ .../diagnosticMessages.generated.json.lcl | 12 ++++++------ .../diagnosticMessages.generated.json.lcl | 12 ++++++------ .../diagnosticMessages.generated.json.lcl | 12 ++++++------ .../diagnosticMessages.generated.json.lcl | 12 ++++++------ 13 files changed, 78 insertions(+), 78 deletions(-) diff --git a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl index df4fe162f53..1d6c5552393 100644 --- a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -4065,11 +4065,11 @@ - + - + - + @@ -6294,11 +6294,11 @@ - + - + - + diff --git a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl index d5f656cc789..e43a480fd36 100644 --- a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -4065,11 +4065,11 @@ - + - + - + @@ -6294,11 +6294,11 @@ - + - + - + diff --git a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl index 36984f994f5..a7bd25b0c0b 100644 --- a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -4074,11 +4074,11 @@ - + - + - + @@ -6303,11 +6303,11 @@ - + - + - + diff --git a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl index 3fb133b117a..cc9a570a4bd 100644 --- a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -4062,11 +4062,11 @@ - + - + - + @@ -6291,11 +6291,11 @@ - + - + - + diff --git a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl index 7c9bab0e9b3..b4f820d838c 100644 --- a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -4077,11 +4077,11 @@ - + - + - + @@ -6306,11 +6306,11 @@ - + - + - + diff --git a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl index c116b296085..d737d528e35 100644 --- a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -4077,11 +4077,11 @@ - + - + - + @@ -6306,11 +6306,11 @@ - + - + - + diff --git a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl index 2368f06db8e..cdbe50862e0 100644 --- a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -4065,11 +4065,11 @@ - + - + - + @@ -6294,11 +6294,11 @@ - + - + - + diff --git a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl index 10c45cb688c..7c4202b4b6d 100644 --- a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -4065,11 +4065,11 @@ - + - + - + @@ -6294,11 +6294,11 @@ - + - + - + diff --git a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl index 5fae6012866..bbc0a47b767 100644 --- a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -4065,11 +4065,11 @@ - + - + - + @@ -6294,11 +6294,11 @@ - + - + - + diff --git a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 59b6ed3ceba..d4e05af0041 100644 --- a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -4055,11 +4055,11 @@ - + - + - + @@ -6284,11 +6284,11 @@ - + - + - + diff --git a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl index aef592eb1c7..c7ceb85cdac 100644 --- a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -4058,11 +4058,11 @@ - + - + - + @@ -6287,11 +6287,11 @@ - + - + - + diff --git a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl index dc382a224f1..353974dee7f 100644 --- a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -4064,11 +4064,11 @@ - + - + - + @@ -6293,11 +6293,11 @@ - + - + - + diff --git a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl index eda9cdcd28b..8060a4c948b 100644 --- a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -4058,11 +4058,11 @@ - + - + - + @@ -6287,11 +6287,11 @@ - + - + - + From 7c3f607032d0317d4809f56783b9801646dddd16 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sat, 16 Oct 2021 02:33:59 -0400 Subject: [PATCH 26/60] `scripts/build/utils` simplify exec Using shell-based execution is always a bad idea; this thing didn't do that via an option, but instead did it manually by constructing a shell command so it suffers from the same diseases. Perhaps there was need for this at some point in the past, but things are pretty robust now, so there's no need to avoid running the command normally. The only thing that is needed is to add `which` which also handles windows executable suffixes. I tried this with a fresh clone on windows, where the tree and TS are installed in paths that have spaces, and everything works as it should. --- scripts/build/utils.js | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/scripts/build/utils.js b/scripts/build/utils.js index 6664a2fa67a..cfb7924d623 100644 --- a/scripts/build/utils.js +++ b/scripts/build/utils.js @@ -9,12 +9,11 @@ const del = require("del"); const File = require("vinyl"); const ts = require("../../lib/typescript"); const chalk = require("chalk"); +const which = require("which"); const { spawn } = require("child_process"); const { CancellationToken, CancelError, Deferred } = require("prex"); const { Readable, Duplex } = require("stream"); -const isWindows = /^win/.test(process.platform); - /** * Executes the provided command once with the supplied arguments. * @param {string} cmd @@ -32,12 +31,8 @@ function exec(cmd, args, options = {}) { const { ignoreExitCode, cancelToken = CancellationToken.none, waitForExit = true } = options; cancelToken.throwIfCancellationRequested(); - // TODO (weswig): Update child_process types to add windowsVerbatimArguments to the type definition - const subshellFlag = isWindows ? "/c" : "-c"; - const command = isWindows ? [possiblyQuote(cmd), ...args] : [`${cmd} ${args.join(" ")}`]; - if (!options.hidePrompt) log(`> ${chalk.green(cmd)} ${args.join(" ")}`); - const proc = spawn(isWindows ? "cmd" : "/bin/sh", [subshellFlag, ...command], { stdio: waitForExit ? "inherit" : "ignore", windowsVerbatimArguments: true }); + const proc = spawn(which.sync(cmd), args, { stdio: waitForExit ? "inherit" : "ignore" }); const registration = cancelToken.register(() => { log(`${chalk.red("killing")} '${chalk.green(cmd)} ${args.join(" ")}'...`); proc.kill("SIGINT"); @@ -68,13 +63,6 @@ function exec(cmd, args, options = {}) { } exports.exec = exec; -/** - * @param {string} cmd - */ -function possiblyQuote(cmd) { - return cmd.indexOf(" ") >= 0 ? `"${cmd}"` : cmd; -} - /** * @param {ts.Diagnostic[]} diagnostics * @param {{ cwd?: string, pretty?: boolean }} [options] @@ -440,4 +428,4 @@ class Debouncer { } } } -exports.Debouncer = Debouncer; \ No newline at end of file +exports.Debouncer = Debouncer; From 556098ed50310965600aedd3053d35dc04aa2811 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 18 Oct 2021 13:13:57 -0400 Subject: [PATCH 27/60] Avoid hard-wired build-tree paths Instead, search for stuff up the directory tree, with the main functionality being to look for `Gulpfile.js` and assume the resulting directory is the root. (Unfortunatley, this is implemented twice, one in `scripts` and another in `src`. It's not possible to use a single implementation for both since that would require assuming a directory structure which this is intended to avoid.) Also, in `scripts/build/projects.js`, abstracdt common exec functionality into a local helper, and use full paths based on the above search instead of assuming relative paths assuming CWD being in the project root. --- scripts/build/findUpDir.js | 21 +++++++++++++++++++++ scripts/build/projects.js | 14 +++++++++++--- scripts/build/tests.js | 5 +++-- src/harness/findUpDir.ts | 21 +++++++++++++++++++++ 4 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 scripts/build/findUpDir.js create mode 100644 src/harness/findUpDir.ts diff --git a/scripts/build/findUpDir.js b/scripts/build/findUpDir.js new file mode 100644 index 00000000000..fab301c6dcd --- /dev/null +++ b/scripts/build/findUpDir.js @@ -0,0 +1,21 @@ +const { join, resolve, dirname } = require("path"); +const { existsSync } = require("fs"); + +// search directories upward to avoid hard-wired paths based on the +// build tree (same as src/harness/findUpDir.ts) + +function findUpFile(name) { + let dir = __dirname; + while (true) { + const fullPath = join(dir, name); + if (existsSync(fullPath)) return fullPath; + const up = resolve(dir, ".."); + if (up === dir) return name; // it'll fail anyway + dir = up; + } +} +exports.findUpFile = findUpFile; + +const findUpRoot = () => + findUpRoot.cached || (findUpRoot.cached = dirname(findUpFile("Gulpfile.js"))); +exports.findUpRoot = findUpRoot; diff --git a/scripts/build/projects.js b/scripts/build/projects.js index 954f37af84e..38db816e23b 100644 --- a/scripts/build/projects.js +++ b/scripts/build/projects.js @@ -1,5 +1,7 @@ // @ts-check const { exec, Debouncer } = require("./utils"); +const { resolve } = require("path"); +const { findUpRoot } = require("./findUpDir"); class ProjectQueue { /** @@ -33,7 +35,13 @@ class ProjectQueue { } } -const projectBuilder = new ProjectQueue((projects, lkg, force) => exec(process.execPath, [lkg ? "./lib/tsc" : "./built/local/tsc", "-b", ...(force ? ["--force"] : []), ...projects], { hidePrompt: true })); +const execTsc = (lkg, ...args) => + exec(process.execPath, + [resolve(findUpRoot(), lkg ? "./lib/tsc" : "./built/local/tsc"), + "-b", ...args], + { hidePrompt: true }) + +const projectBuilder = new ProjectQueue((projects, lkg, force) => execTsc(lkg, ...(force ? ["--force"] : []), ...projects)); /** * @param {string} project @@ -43,14 +51,14 @@ const projectBuilder = new ProjectQueue((projects, lkg, force) => exec(process.e */ exports.buildProject = (project, { lkg, force } = {}) => projectBuilder.enqueue(project, { lkg, force }); -const projectCleaner = new ProjectQueue((projects, lkg) => exec(process.execPath, [lkg ? "./lib/tsc" : "./built/local/tsc", "-b", "--clean", ...projects], { hidePrompt: true })); +const projectCleaner = new ProjectQueue((projects, lkg) => execTsc(lkg, "--clean", ...projects)); /** * @param {string} project */ exports.cleanProject = (project) => projectCleaner.enqueue(project); -const projectWatcher = new ProjectQueue((projects) => exec(process.execPath, ["./lib/tsc", "-b", "--watch", ...projects], { hidePrompt: true })); +const projectWatcher = new ProjectQueue((projects) => execTsc(true, "--watch", ...projects)); /** * @param {string} project diff --git a/scripts/build/tests.js b/scripts/build/tests.js index 7fee32566dd..10c6db79cf1 100644 --- a/scripts/build/tests.js +++ b/scripts/build/tests.js @@ -9,6 +9,7 @@ const log = require("fancy-log"); const cmdLineOptions = require("./options"); const { CancellationToken } = require("prex"); const { exec } = require("./utils"); +const { findUpFile } = require("./findUpDir"); const mochaJs = require.resolve("mocha/bin/_mocha"); exports.localBaseline = "tests/baselines/local/"; @@ -73,11 +74,11 @@ async function runConsoleTests(runJs, defaultReporter, runInParallel, watchMode, /** @type {string[]} */ let args = []; - // timeout normally isn"t necessary but Travis-CI has been timing out on compiler baselines occasionally + // timeout normally isn't necessary but Travis-CI has been timing out on compiler baselines occasionally // default timeout is 2sec which really should be enough, but maybe we just need a small amount longer if (!runInParallel) { args.push(mochaJs); - args.push("-R", "scripts/failed-tests"); + args.push("-R", findUpFile("scripts/failed-tests.js")); args.push("-O", '"reporter=' + reporter + (keepFailed ? ",keepFailed=true" : "") + '"'); if (tests) { args.push("-g", `"${tests}"`); diff --git a/src/harness/findUpDir.ts b/src/harness/findUpDir.ts new file mode 100644 index 00000000000..03b5ebdf285 --- /dev/null +++ b/src/harness/findUpDir.ts @@ -0,0 +1,21 @@ +namespace findUpDir { + import { join, resolve, dirname } from "path"; + import { existsSync } from "fs"; + + // search directories upward to avoid hard-wired paths based on the + // build tree (same as scripts/build/findUpDir.js) + + export function findUpFile(name: string) { + let dir = __dirname; + while (true) { + const fullPath = join(dir, name); + if (existsSync(fullPath)) return fullPath; + const up = resolve(dir, ".."); + if (up === dir) return name; // it'll fail anyway + dir = up; + } + } + + export const findUpRoot: { (): string; cached?: string; } = () => + findUpRoot.cached ||= dirname(findUpFile("Gulpfile.js")); +} From fd6552a3c2fdfe92afd88ccf6616ec02946e7d9e Mon Sep 17 00:00:00 2001 From: csigs Date: Tue, 19 Oct 2021 04:15:18 -0700 Subject: [PATCH 28/60] LEGO: Merge pull request 46424 LEGO: Merge pull request 46424 --- .../diagnosticMessages.generated.json.lcl | 9 +++++++++ .../diagnosticMessages.generated.json.lcl | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl index cc9a570a4bd..0ba3b3a31d1 100644 --- a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -468,6 +468,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl index 7c4202b4b6d..4c5e403fd19 100644 --- a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -468,6 +468,15 @@ + + + + + + + + + From 56b627981892844f37361d4854e339aa00c771db Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 19 Oct 2021 09:58:10 -0700 Subject: [PATCH 29/60] Improve logic for choosing between co- and contra-variant inferences (#46392) * Improve logic for choosing between co- and contra-variant inferences * Add tests --- src/compiler/checker.ts | 7 +- .../reference/coAndContraVariantInferences.js | 74 ++++++++++++ .../coAndContraVariantInferences.symbols | 114 ++++++++++++++++++ .../coAndContraVariantInferences.types | 104 ++++++++++++++++ .../compiler/coAndContraVariantInferences.ts | 37 ++++++ 5 files changed, 332 insertions(+), 4 deletions(-) create mode 100644 tests/baselines/reference/coAndContraVariantInferences.js create mode 100644 tests/baselines/reference/coAndContraVariantInferences.symbols create mode 100644 tests/baselines/reference/coAndContraVariantInferences.types create mode 100644 tests/cases/compiler/coAndContraVariantInferences.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bcf3a78f052..d149b044284 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -22329,12 +22329,11 @@ namespace ts { if (signature) { const inferredCovariantType = inference.candidates ? getCovariantInference(inference, signature) : undefined; if (inference.contraCandidates) { - const inferredContravariantType = getContravariantInference(inference); // If we have both co- and contra-variant inferences, we prefer the contra-variant inference - // unless the co-variant inference is a subtype and not 'never'. + // unless the co-variant inference is a subtype of some contra-variant inference and not 'never'. inferredType = inferredCovariantType && !(inferredCovariantType.flags & TypeFlags.Never) && - isTypeSubtypeOf(inferredCovariantType, inferredContravariantType) ? - inferredCovariantType : inferredContravariantType; + some(inference.contraCandidates, t => isTypeSubtypeOf(inferredCovariantType, t)) ? + inferredCovariantType : getContravariantInference(inference); } else if (inferredCovariantType) { inferredType = inferredCovariantType; diff --git a/tests/baselines/reference/coAndContraVariantInferences.js b/tests/baselines/reference/coAndContraVariantInferences.js new file mode 100644 index 00000000000..e90343a44f2 --- /dev/null +++ b/tests/baselines/reference/coAndContraVariantInferences.js @@ -0,0 +1,74 @@ +//// [coAndContraVariantInferences.ts] +type A = { kind: 'a' }; +type B = { kind: 'b' }; + +declare const a: A; +declare const b: B; + +declare function fab(arg: A | B): void; + +declare function foo(x: { kind: T }, f: (arg: { kind: T }) => void): void; + +foo(a, fab); +foo(b, fab); + +// Repro from #45603 + +interface Action { + name: TName, + payload: TPayload +} + +const actionA = { payload: 'any-string' } as Action<'ACTION_A', string>; +const actionB = { payload: true } as Action<'ACTION_B', boolean>; + +function call( + action: Action, + fn: (action: Action)=> any, +) { + fn(action); +} + +const printFn = (action: typeof actionA | typeof actionB)=> console.log(action); + +call(actionA, printFn); +call(actionB, printFn); + + +//// [coAndContraVariantInferences.js] +"use strict"; +foo(a, fab); +foo(b, fab); +var actionA = { payload: 'any-string' }; +var actionB = { payload: true }; +function call(action, fn) { + fn(action); +} +var printFn = function (action) { return console.log(action); }; +call(actionA, printFn); +call(actionB, printFn); + + +//// [coAndContraVariantInferences.d.ts] +declare type A = { + kind: 'a'; +}; +declare type B = { + kind: 'b'; +}; +declare const a: A; +declare const b: B; +declare function fab(arg: A | B): void; +declare function foo(x: { + kind: T; +}, f: (arg: { + kind: T; +}) => void): void; +interface Action { + name: TName; + payload: TPayload; +} +declare const actionA: Action<"ACTION_A", string>; +declare const actionB: Action<"ACTION_B", boolean>; +declare function call(action: Action, fn: (action: Action) => any): void; +declare const printFn: (action: typeof actionA | typeof actionB) => void; diff --git a/tests/baselines/reference/coAndContraVariantInferences.symbols b/tests/baselines/reference/coAndContraVariantInferences.symbols new file mode 100644 index 00000000000..d41ee57875d --- /dev/null +++ b/tests/baselines/reference/coAndContraVariantInferences.symbols @@ -0,0 +1,114 @@ +=== tests/cases/compiler/coAndContraVariantInferences.ts === +type A = { kind: 'a' }; +>A : Symbol(A, Decl(coAndContraVariantInferences.ts, 0, 0)) +>kind : Symbol(kind, Decl(coAndContraVariantInferences.ts, 0, 10)) + +type B = { kind: 'b' }; +>B : Symbol(B, Decl(coAndContraVariantInferences.ts, 0, 23)) +>kind : Symbol(kind, Decl(coAndContraVariantInferences.ts, 1, 10)) + +declare const a: A; +>a : Symbol(a, Decl(coAndContraVariantInferences.ts, 3, 13)) +>A : Symbol(A, Decl(coAndContraVariantInferences.ts, 0, 0)) + +declare const b: B; +>b : Symbol(b, Decl(coAndContraVariantInferences.ts, 4, 13)) +>B : Symbol(B, Decl(coAndContraVariantInferences.ts, 0, 23)) + +declare function fab(arg: A | B): void; +>fab : Symbol(fab, Decl(coAndContraVariantInferences.ts, 4, 19)) +>arg : Symbol(arg, Decl(coAndContraVariantInferences.ts, 6, 21)) +>A : Symbol(A, Decl(coAndContraVariantInferences.ts, 0, 0)) +>B : Symbol(B, Decl(coAndContraVariantInferences.ts, 0, 23)) + +declare function foo(x: { kind: T }, f: (arg: { kind: T }) => void): void; +>foo : Symbol(foo, Decl(coAndContraVariantInferences.ts, 6, 39)) +>T : Symbol(T, Decl(coAndContraVariantInferences.ts, 8, 21)) +>x : Symbol(x, Decl(coAndContraVariantInferences.ts, 8, 24)) +>kind : Symbol(kind, Decl(coAndContraVariantInferences.ts, 8, 28)) +>T : Symbol(T, Decl(coAndContraVariantInferences.ts, 8, 21)) +>f : Symbol(f, Decl(coAndContraVariantInferences.ts, 8, 39)) +>arg : Symbol(arg, Decl(coAndContraVariantInferences.ts, 8, 44)) +>kind : Symbol(kind, Decl(coAndContraVariantInferences.ts, 8, 50)) +>T : Symbol(T, Decl(coAndContraVariantInferences.ts, 8, 21)) + +foo(a, fab); +>foo : Symbol(foo, Decl(coAndContraVariantInferences.ts, 6, 39)) +>a : Symbol(a, Decl(coAndContraVariantInferences.ts, 3, 13)) +>fab : Symbol(fab, Decl(coAndContraVariantInferences.ts, 4, 19)) + +foo(b, fab); +>foo : Symbol(foo, Decl(coAndContraVariantInferences.ts, 6, 39)) +>b : Symbol(b, Decl(coAndContraVariantInferences.ts, 4, 13)) +>fab : Symbol(fab, Decl(coAndContraVariantInferences.ts, 4, 19)) + +// Repro from #45603 + +interface Action { +>Action : Symbol(Action, Decl(coAndContraVariantInferences.ts, 11, 12)) +>TName : Symbol(TName, Decl(coAndContraVariantInferences.ts, 15, 17)) +>TPayload : Symbol(TPayload, Decl(coAndContraVariantInferences.ts, 15, 38)) + + name: TName, +>name : Symbol(Action.name, Decl(coAndContraVariantInferences.ts, 15, 49)) +>TName : Symbol(TName, Decl(coAndContraVariantInferences.ts, 15, 17)) + + payload: TPayload +>payload : Symbol(Action.payload, Decl(coAndContraVariantInferences.ts, 16, 16)) +>TPayload : Symbol(TPayload, Decl(coAndContraVariantInferences.ts, 15, 38)) +} + +const actionA = { payload: 'any-string' } as Action<'ACTION_A', string>; +>actionA : Symbol(actionA, Decl(coAndContraVariantInferences.ts, 20, 5)) +>payload : Symbol(payload, Decl(coAndContraVariantInferences.ts, 20, 17)) +>Action : Symbol(Action, Decl(coAndContraVariantInferences.ts, 11, 12)) + +const actionB = { payload: true } as Action<'ACTION_B', boolean>; +>actionB : Symbol(actionB, Decl(coAndContraVariantInferences.ts, 21, 5)) +>payload : Symbol(payload, Decl(coAndContraVariantInferences.ts, 21, 17)) +>Action : Symbol(Action, Decl(coAndContraVariantInferences.ts, 11, 12)) + +function call( +>call : Symbol(call, Decl(coAndContraVariantInferences.ts, 21, 65)) +>TName : Symbol(TName, Decl(coAndContraVariantInferences.ts, 23, 14)) +>TPayload : Symbol(TPayload, Decl(coAndContraVariantInferences.ts, 23, 35)) + + action: Action, +>action : Symbol(action, Decl(coAndContraVariantInferences.ts, 23, 45)) +>Action : Symbol(Action, Decl(coAndContraVariantInferences.ts, 11, 12)) +>TName : Symbol(TName, Decl(coAndContraVariantInferences.ts, 23, 14)) +>TPayload : Symbol(TPayload, Decl(coAndContraVariantInferences.ts, 23, 35)) + + fn: (action: Action)=> any, +>fn : Symbol(fn, Decl(coAndContraVariantInferences.ts, 24, 33)) +>action : Symbol(action, Decl(coAndContraVariantInferences.ts, 25, 7)) +>Action : Symbol(Action, Decl(coAndContraVariantInferences.ts, 11, 12)) +>TName : Symbol(TName, Decl(coAndContraVariantInferences.ts, 23, 14)) +>TPayload : Symbol(TPayload, Decl(coAndContraVariantInferences.ts, 23, 35)) + +) { + fn(action); +>fn : Symbol(fn, Decl(coAndContraVariantInferences.ts, 24, 33)) +>action : Symbol(action, Decl(coAndContraVariantInferences.ts, 23, 45)) +} + +const printFn = (action: typeof actionA | typeof actionB)=> console.log(action); +>printFn : Symbol(printFn, Decl(coAndContraVariantInferences.ts, 30, 5)) +>action : Symbol(action, Decl(coAndContraVariantInferences.ts, 30, 17)) +>actionA : Symbol(actionA, Decl(coAndContraVariantInferences.ts, 20, 5)) +>actionB : Symbol(actionB, Decl(coAndContraVariantInferences.ts, 21, 5)) +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>action : Symbol(action, Decl(coAndContraVariantInferences.ts, 30, 17)) + +call(actionA, printFn); +>call : Symbol(call, Decl(coAndContraVariantInferences.ts, 21, 65)) +>actionA : Symbol(actionA, Decl(coAndContraVariantInferences.ts, 20, 5)) +>printFn : Symbol(printFn, Decl(coAndContraVariantInferences.ts, 30, 5)) + +call(actionB, printFn); +>call : Symbol(call, Decl(coAndContraVariantInferences.ts, 21, 65)) +>actionB : Symbol(actionB, Decl(coAndContraVariantInferences.ts, 21, 5)) +>printFn : Symbol(printFn, Decl(coAndContraVariantInferences.ts, 30, 5)) + diff --git a/tests/baselines/reference/coAndContraVariantInferences.types b/tests/baselines/reference/coAndContraVariantInferences.types new file mode 100644 index 00000000000..b8d48b41339 --- /dev/null +++ b/tests/baselines/reference/coAndContraVariantInferences.types @@ -0,0 +1,104 @@ +=== tests/cases/compiler/coAndContraVariantInferences.ts === +type A = { kind: 'a' }; +>A : A +>kind : "a" + +type B = { kind: 'b' }; +>B : B +>kind : "b" + +declare const a: A; +>a : A + +declare const b: B; +>b : B + +declare function fab(arg: A | B): void; +>fab : (arg: A | B) => void +>arg : A | B + +declare function foo(x: { kind: T }, f: (arg: { kind: T }) => void): void; +>foo : (x: { kind: T;}, f: (arg: { kind: T;}) => void) => void +>x : { kind: T; } +>kind : T +>f : (arg: { kind: T;}) => void +>arg : { kind: T; } +>kind : T + +foo(a, fab); +>foo(a, fab) : void +>foo : (x: { kind: T; }, f: (arg: { kind: T; }) => void) => void +>a : A +>fab : (arg: A | B) => void + +foo(b, fab); +>foo(b, fab) : void +>foo : (x: { kind: T; }, f: (arg: { kind: T; }) => void) => void +>b : B +>fab : (arg: A | B) => void + +// Repro from #45603 + +interface Action { + name: TName, +>name : TName + + payload: TPayload +>payload : TPayload +} + +const actionA = { payload: 'any-string' } as Action<'ACTION_A', string>; +>actionA : Action<"ACTION_A", string> +>{ payload: 'any-string' } as Action<'ACTION_A', string> : Action<"ACTION_A", string> +>{ payload: 'any-string' } : { payload: string; } +>payload : string +>'any-string' : "any-string" + +const actionB = { payload: true } as Action<'ACTION_B', boolean>; +>actionB : Action<"ACTION_B", boolean> +>{ payload: true } as Action<'ACTION_B', boolean> : Action<"ACTION_B", boolean> +>{ payload: true } : { payload: true; } +>payload : true +>true : true + +function call( +>call : (action: Action, fn: (action: Action) => any) => void + + action: Action, +>action : Action + + fn: (action: Action)=> any, +>fn : (action: Action) => any +>action : Action + +) { + fn(action); +>fn(action) : any +>fn : (action: Action) => any +>action : Action +} + +const printFn = (action: typeof actionA | typeof actionB)=> console.log(action); +>printFn : (action: typeof actionA | typeof actionB) => void +>(action: typeof actionA | typeof actionB)=> console.log(action) : (action: typeof actionA | typeof actionB) => void +>action : Action<"ACTION_A", string> | Action<"ACTION_B", boolean> +>actionA : Action<"ACTION_A", string> +>actionB : Action<"ACTION_B", boolean> +>console.log(action) : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>action : Action<"ACTION_A", string> | Action<"ACTION_B", boolean> + +call(actionA, printFn); +>call(actionA, printFn) : void +>call : (action: Action, fn: (action: Action) => any) => void +>actionA : Action<"ACTION_A", string> +>printFn : (action: Action<"ACTION_A", string> | Action<"ACTION_B", boolean>) => void + +call(actionB, printFn); +>call(actionB, printFn) : void +>call : (action: Action, fn: (action: Action) => any) => void +>actionB : Action<"ACTION_B", boolean> +>printFn : (action: Action<"ACTION_A", string> | Action<"ACTION_B", boolean>) => void + diff --git a/tests/cases/compiler/coAndContraVariantInferences.ts b/tests/cases/compiler/coAndContraVariantInferences.ts new file mode 100644 index 00000000000..1b0a6cb56db --- /dev/null +++ b/tests/cases/compiler/coAndContraVariantInferences.ts @@ -0,0 +1,37 @@ +// @strict: true +// @declaration: true + +type A = { kind: 'a' }; +type B = { kind: 'b' }; + +declare const a: A; +declare const b: B; + +declare function fab(arg: A | B): void; + +declare function foo(x: { kind: T }, f: (arg: { kind: T }) => void): void; + +foo(a, fab); +foo(b, fab); + +// Repro from #45603 + +interface Action { + name: TName, + payload: TPayload +} + +const actionA = { payload: 'any-string' } as Action<'ACTION_A', string>; +const actionB = { payload: true } as Action<'ACTION_B', boolean>; + +function call( + action: Action, + fn: (action: Action)=> any, +) { + fn(action); +} + +const printFn = (action: typeof actionA | typeof actionB)=> console.log(action); + +call(actionA, printFn); +call(actionB, printFn); From 53fa2a64948c12de8ba64552625d187bb7de3dca Mon Sep 17 00:00:00 2001 From: csigs Date: Tue, 19 Oct 2021 10:13:07 -0700 Subject: [PATCH 30/60] LEGO: Merge pull request 46430 LEGO: Merge pull request 46430 --- .../diagnosticMessages.generated.json.lcl | 9 +++++++++ .../diagnosticMessages.generated.json.lcl | 9 +++++++++ .../diagnosticMessages.generated.json.lcl | 9 +++++++++ .../diagnosticMessages.generated.json.lcl | 9 +++++++++ .../diagnosticMessages.generated.json.lcl | 9 +++++++++ .../diagnosticMessages.generated.json.lcl | 9 +++++++++ 6 files changed, 54 insertions(+) diff --git a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl index 1d6c5552393..58e658a2be2 100644 --- a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -468,6 +468,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl index e43a480fd36..c4706da3c4b 100644 --- a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -468,6 +468,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl index a7bd25b0c0b..cf6c498e219 100644 --- a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -477,6 +477,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl index b4f820d838c..bf8ec5fba57 100644 --- a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -477,6 +477,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl index bbc0a47b767..76c05cb54bc 100644 --- a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -468,6 +468,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl index c7ceb85cdac..adfe7311458 100644 --- a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -461,6 +461,15 @@ + + + + + + + + + From 248d478956489a1d005f163d3b5060a9712835ee Mon Sep 17 00:00:00 2001 From: Jack Bates Date: Tue, 19 Oct 2021 15:19:19 -0700 Subject: [PATCH 31/60] Remove defaultValueDescription: "n/a" from options (#46280) * Remove defaultValueDescription: "n/a" from options * CommandLineOption type <-> defaultValueDescription * Require defaultValueDescription of number/boolean options --- src/compiler/commandLineParser.ts | 83 ++++++++++++------- src/compiler/types.ts | 20 ++++- src/harness/harnessIO.ts | 14 ++-- .../unittests/config/commandLineParsing.ts | 3 +- 4 files changed, 80 insertions(+), 40 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 676b995d8c9..fe0031d1f2a 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1,6 +1,6 @@ namespace ts { /* @internal */ - export const compileOnSaveCommandLineOption: CommandLineOption = { name: "compileOnSave", type: "boolean" }; + export const compileOnSaveCommandLineOption: CommandLineOption = { name: "compileOnSave", type: "boolean", defaultValueDescription: "false" }; const jsxOptionMap = new Map(getEntries({ "preserve": JsxEmit.Preserve, @@ -140,6 +140,7 @@ namespace ts { type: "boolean", category: Diagnostics.Watch_and_Build_Modes, description: Diagnostics.Synchronously_call_callbacks_and_update_the_state_of_directory_watchers_on_platforms_that_don_t_support_recursive_watching_natively, + defaultValueDescription: "false", }, { name: "excludeDirectories", @@ -176,11 +177,13 @@ namespace ts { showInSimplifiedHelpView: true, category: Diagnostics.Command_line_Options, description: Diagnostics.Print_this_message, + defaultValueDescription: "false", }, { name: "help", shortName: "?", - type: "boolean" + type: "boolean", + defaultValueDescription: "false", }, { name: "watch", @@ -190,6 +193,7 @@ namespace ts { isCommandLineOnly: true, category: Diagnostics.Command_line_Options, description: Diagnostics.Watch_input_files, + defaultValueDescription: "false", }, { name: "preserveWatchOutput", @@ -197,7 +201,7 @@ namespace ts { showInSimplifiedHelpView: false, category: Diagnostics.Output_Formatting, description: Diagnostics.Disable_wiping_the_console_in_watch_mode, - defaultValueDescription: "n/a" + defaultValueDescription: "false", }, { name: "listFiles", @@ -210,7 +214,8 @@ namespace ts { name: "explainFiles", type: "boolean", category: Diagnostics.Compiler_Diagnostics, - description: Diagnostics.Print_files_read_during_the_compilation_including_why_it_was_included + description: Diagnostics.Print_files_read_during_the_compilation_including_why_it_was_included, + defaultValueDescription: "false", }, { name: "listEmittedFiles", @@ -281,7 +286,8 @@ namespace ts { affectsSemanticDiagnostics: true, affectsEmit: true, category: Diagnostics.Watch_and_Build_Modes, - description: Diagnostics.Have_recompiles_in_projects_that_use_incremental_and_watch_mode_assume_that_changes_within_a_file_will_only_affect_files_directly_depending_on_it + description: Diagnostics.Have_recompiles_in_projects_that_use_incremental_and_watch_mode_assume_that_changes_within_a_file_will_only_affect_files_directly_depending_on_it, + defaultValueDescription: "false", }, { name: "locale", @@ -328,6 +334,7 @@ namespace ts { showInSimplifiedHelpView: true, category: Diagnostics.Command_line_Options, description: Diagnostics.Show_all_compiler_options, + defaultValueDescription: "false", }, { name: "version", @@ -336,6 +343,7 @@ namespace ts { showInSimplifiedHelpView: true, category: Diagnostics.Command_line_Options, description: Diagnostics.Print_the_compiler_s_version, + defaultValueDescription: "false", }, { name: "init", @@ -343,6 +351,7 @@ namespace ts { showInSimplifiedHelpView: true, category: Diagnostics.Command_line_Options, description: Diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file, + defaultValueDescription: "false", }, { name: "project", @@ -360,7 +369,8 @@ namespace ts { shortName: "b", showInSimplifiedHelpView: true, category: Diagnostics.Command_line_Options, - description: Diagnostics.Build_one_or_more_projects_and_their_dependencies_if_out_of_date + description: Diagnostics.Build_one_or_more_projects_and_their_dependencies_if_out_of_date, + defaultValueDescription: "false", }, { name: "showConfig", @@ -368,7 +378,8 @@ namespace ts { showInSimplifiedHelpView: true, category: Diagnostics.Command_line_Options, isCommandLineOnly: true, - description: Diagnostics.Print_the_final_configuration_instead_of_building + description: Diagnostics.Print_the_final_configuration_instead_of_building, + defaultValueDescription: "false", }, { name: "listFilesOnly", @@ -377,7 +388,8 @@ namespace ts { affectsSemanticDiagnostics: true, affectsEmit: true, isCommandLineOnly: true, - description: Diagnostics.Print_names_of_files_that_are_part_of_the_compilation_and_then_stop_processing + description: Diagnostics.Print_names_of_files_that_are_part_of_the_compilation_and_then_stop_processing, + defaultValueDescription: "false", }, // Basic @@ -499,7 +511,6 @@ namespace ts { category: Diagnostics.Emit, description: Diagnostics.Specify_a_file_that_bundles_all_outputs_into_one_JavaScript_file_If_declaration_is_true_also_designates_a_file_that_bundles_all_d_ts_output, transpileOptionValue: undefined, - defaultValueDescription: "n/a" }, { name: "outDir", @@ -510,7 +521,6 @@ namespace ts { showInSimplifiedHelpView: true, category: Diagnostics.Emit, description: Diagnostics.Specify_an_output_folder_for_all_emitted_files, - defaultValueDescription: "n/a" }, { name: "rootDir", @@ -668,6 +678,7 @@ namespace ts { strictFlag: true, category: Diagnostics.Type_Checking, description: Diagnostics.Type_catch_clause_variables_as_unknown_instead_of_any, + defaultValueDescription: "false", }, { name: "alwaysStrict", @@ -701,7 +712,8 @@ namespace ts { type: "boolean", affectsSemanticDiagnostics: true, category: Diagnostics.Type_Checking, - description: Diagnostics.Interpret_optional_property_types_as_written_rather_than_adding_undefined + description: Diagnostics.Interpret_optional_property_types_as_written_rather_than_adding_undefined, + defaultValueDescription: "false", }, { name: "noImplicitReturns", @@ -717,21 +729,24 @@ namespace ts { affectsBindDiagnostics: true, affectsSemanticDiagnostics: true, category: Diagnostics.Type_Checking, - description: Diagnostics.Enable_error_reporting_for_fallthrough_cases_in_switch_statements + description: Diagnostics.Enable_error_reporting_for_fallthrough_cases_in_switch_statements, + defaultValueDescription: "false", }, { name: "noUncheckedIndexedAccess", type: "boolean", affectsSemanticDiagnostics: true, category: Diagnostics.Type_Checking, - description: Diagnostics.Include_undefined_in_index_signature_results + description: Diagnostics.Include_undefined_in_index_signature_results, + defaultValueDescription: "false", }, { name: "noImplicitOverride", type: "boolean", affectsSemanticDiagnostics: true, category: Diagnostics.Type_Checking, - description: Diagnostics.Ensure_overriding_members_in_derived_classes_are_marked_with_an_override_modifier + description: Diagnostics.Ensure_overriding_members_in_derived_classes_are_marked_with_an_override_modifier, + defaultValueDescription: "false", }, { name: "noPropertyAccessFromIndexSignature", @@ -841,7 +856,7 @@ namespace ts { type: "boolean", category: Diagnostics.Interop_Constraints, description: Diagnostics.Disable_resolving_symlinks_to_their_realpath_This_correlates_to_the_same_flag_in_node, - defaultValueDescription: "n/a" + defaultValueDescription: "false", }, { name: "allowUmdGlobalAccess", @@ -892,7 +907,8 @@ namespace ts { type: "boolean", affectsSemanticDiagnostics: true, category: Diagnostics.Language_and_Environment, - description: Diagnostics.Enable_experimental_support_for_TC39_stage_2_draft_decorators + description: Diagnostics.Enable_experimental_support_for_TC39_stage_2_draft_decorators, + defaultValueDescription: "false", }, { name: "emitDecoratorMetadata", @@ -900,7 +916,8 @@ namespace ts { affectsSemanticDiagnostics: true, affectsEmit: true, category: Diagnostics.Language_and_Environment, - description: Diagnostics.Emit_design_type_metadata_for_decorated_declarations_in_source_files + description: Diagnostics.Emit_design_type_metadata_for_decorated_declarations_in_source_files, + defaultValueDescription: "false", }, // Advanced @@ -945,7 +962,6 @@ namespace ts { category: Diagnostics.Backwards_Compatibility, paramType: Diagnostics.FILE, transpileOptionValue: undefined, - defaultValueDescription: "n/a", description: Diagnostics.Deprecated_setting_Use_outFile_instead, }, { @@ -1026,6 +1042,7 @@ namespace ts { affectsEmit: true, category: Diagnostics.Emit, description: Diagnostics.Disable_emitting_declarations_that_have_internal_in_their_JSDoc_comments, + defaultValueDescription: "false", }, { name: "disableSizeLimit", @@ -1040,21 +1057,24 @@ namespace ts { type: "boolean", isTSConfigOnly: true, category: Diagnostics.Projects, - description: Diagnostics.Disable_preferring_source_files_instead_of_declaration_files_when_referencing_composite_projects + description: Diagnostics.Disable_preferring_source_files_instead_of_declaration_files_when_referencing_composite_projects, + defaultValueDescription: "false", }, { name: "disableSolutionSearching", type: "boolean", isTSConfigOnly: true, category: Diagnostics.Projects, - description: Diagnostics.Opt_a_project_out_of_multi_project_reference_checking_when_editing + description: Diagnostics.Opt_a_project_out_of_multi_project_reference_checking_when_editing, + defaultValueDescription: "false", }, { name: "disableReferencedProjectLoad", type: "boolean", isTSConfigOnly: true, category: Diagnostics.Projects, - description: Diagnostics.Reduce_the_number_of_projects_loaded_automatically_by_TypeScript + description: Diagnostics.Reduce_the_number_of_projects_loaded_automatically_by_TypeScript, + defaultValueDescription: "false", }, { name: "noImplicitUseStrict", @@ -1087,7 +1107,7 @@ namespace ts { affectsEmit: true, category: Diagnostics.Emit, description: Diagnostics.Disable_erasing_const_enum_declarations_in_generated_code, - defaultValueDescription: "n/a" + defaultValueDescription: "false", }, { name: "declarationDir", @@ -1098,7 +1118,6 @@ namespace ts { category: Diagnostics.Emit, transpileOptionValue: undefined, description: Diagnostics.Specify_the_output_directory_for_generated_declaration_files, - defaultValueDescription: "n/a" }, { name: "skipLibCheck", @@ -1180,6 +1199,7 @@ namespace ts { affectsEmit: true, category: Diagnostics.Emit, description: Diagnostics.Preserve_unused_imported_values_in_the_JavaScript_output_that_would_otherwise_be_removed, + defaultValueDescription: "false", }, { @@ -1242,27 +1262,31 @@ namespace ts { shortName: "v", category: Diagnostics.Command_line_Options, description: Diagnostics.Enable_verbose_logging, - type: "boolean" + type: "boolean", + defaultValueDescription: "false", }, { name: "dry", shortName: "d", category: Diagnostics.Command_line_Options, description: Diagnostics.Show_what_would_be_built_or_deleted_if_specified_with_clean, - type: "boolean" + type: "boolean", + defaultValueDescription: "false", }, { name: "force", shortName: "f", category: Diagnostics.Command_line_Options, description: Diagnostics.Build_all_projects_including_those_that_appear_to_be_up_to_date, - type: "boolean" + type: "boolean", + defaultValueDescription: "false", }, { name: "clean", category: Diagnostics.Command_line_Options, description: Diagnostics.Delete_the_outputs_of_all_projects, - type: "boolean" + type: "boolean", + defaultValueDescription: "false", } ]; @@ -1280,10 +1304,12 @@ namespace ts { */ name: "enableAutoDiscovery", type: "boolean", + defaultValueDescription: "false", }, { name: "enable", type: "boolean", + defaultValueDescription: "false", }, { name: "include", @@ -1304,6 +1330,7 @@ namespace ts { { name: "disableFilenameBasedTypeAcquisition", type: "boolean", + defaultValueDescription: "false", }, ]; @@ -2285,7 +2312,7 @@ namespace ts { return getCustomTypeMapOfCommandLineOption(optionDefinition.element); } else { - return (optionDefinition as CommandLineOptionOfCustomType).type; + return optionDefinition.type; } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a5b143e06f3..6c7cb7b5187 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -6340,8 +6340,20 @@ namespace ts { } /* @internal */ - export interface CommandLineOptionOfPrimitiveType extends CommandLineOptionBase { - type: "string" | "number" | "boolean"; + export interface CommandLineOptionOfStringType extends CommandLineOptionBase { + type: "string"; + } + + /* @internal */ + export interface CommandLineOptionOfNumberType extends CommandLineOptionBase { + type: "number"; + defaultValueDescription: `${number | undefined}` | DiagnosticMessage; + } + + /* @internal */ + export interface CommandLineOptionOfBooleanType extends CommandLineOptionBase { + type: "boolean"; + defaultValueDescription: `${boolean | undefined}` | DiagnosticMessage; } /* @internal */ @@ -6373,11 +6385,11 @@ namespace ts { /* @internal */ export interface CommandLineOptionOfListType extends CommandLineOptionBase { type: "list"; - element: CommandLineOptionOfCustomType | CommandLineOptionOfPrimitiveType | TsConfigOnlyOption; + element: CommandLineOptionOfCustomType | CommandLineOptionOfStringType | CommandLineOptionOfNumberType | CommandLineOptionOfBooleanType | TsConfigOnlyOption; } /* @internal */ - export type CommandLineOption = CommandLineOptionOfCustomType | CommandLineOptionOfPrimitiveType | TsConfigOnlyOption | CommandLineOptionOfListType; + export type CommandLineOption = CommandLineOptionOfCustomType | CommandLineOptionOfStringType | CommandLineOptionOfNumberType | CommandLineOptionOfBooleanType | TsConfigOnlyOption | CommandLineOptionOfListType; /* @internal */ export const enum CharacterCodes { diff --git a/src/harness/harnessIO.ts b/src/harness/harnessIO.ts index 450ed9f6174..08c11fecf12 100644 --- a/src/harness/harnessIO.ts +++ b/src/harness/harnessIO.ts @@ -303,21 +303,21 @@ namespace Harness { // Additional options not already in ts.optionDeclarations const harnessOptionDeclarations: ts.CommandLineOption[] = [ - { name: "allowNonTsExtensions", type: "boolean" }, - { name: "useCaseSensitiveFileNames", type: "boolean" }, + { name: "allowNonTsExtensions", type: "boolean", defaultValueDescription: "false" }, + { name: "useCaseSensitiveFileNames", type: "boolean", defaultValueDescription: "false" }, { name: "baselineFile", type: "string" }, { name: "includeBuiltFile", type: "string" }, { name: "fileName", type: "string" }, { name: "libFiles", type: "string" }, - { name: "noErrorTruncation", type: "boolean" }, - { name: "suppressOutputPathCheck", type: "boolean" }, - { name: "noImplicitReferences", type: "boolean" }, + { name: "noErrorTruncation", type: "boolean", defaultValueDescription: "false" }, + { name: "suppressOutputPathCheck", type: "boolean", defaultValueDescription: "false" }, + { name: "noImplicitReferences", type: "boolean", defaultValueDescription: "false" }, { name: "currentDirectory", type: "string" }, { name: "symlink", type: "string" }, { name: "link", type: "string" }, - { name: "noTypesAndSymbols", type: "boolean" }, + { name: "noTypesAndSymbols", type: "boolean", defaultValueDescription: "false" }, // Emitted js baseline will print full paths for every output file - { name: "fullEmitPaths", type: "boolean" } + { name: "fullEmitPaths", type: "boolean", defaultValueDescription: "false" } ]; let optionsIndex: ts.ESMap; diff --git a/src/testRunner/unittests/config/commandLineParsing.ts b/src/testRunner/unittests/config/commandLineParsing.ts index 500f249288d..9739b324583 100644 --- a/src/testRunner/unittests/config/commandLineParsing.ts +++ b/src/testRunner/unittests/config/commandLineParsing.ts @@ -526,7 +526,7 @@ namespace ts { nonNullValue, diagnosticMessage: Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_null_on_command_line, workerDiagnostic: () => { - const optionDeclarations = [ + const optionDeclarations: CommandLineOption[] = [ ...compilerOptionsDidYouMeanDiagnostics.optionDeclarations, { name: "optionName", @@ -534,6 +534,7 @@ namespace ts { isTSConfigOnly: true, category: Diagnostics.Backwards_Compatibility, description: Diagnostics.Enable_project_compilation, + defaultValueDescription: "undefined", } ]; return { From dea48531f1599605ab1970b7e356a2785e0d8d49 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Wed, 20 Oct 2021 06:06:17 +0000 Subject: [PATCH 32/60] Update package-lock.json --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 049d13fa7cb..88ccc598010 100644 --- a/package-lock.json +++ b/package-lock.json @@ -430,9 +430,9 @@ "dev": true }, "@types/glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", "dev": true, "requires": { "@types/minimatch": "*", From 48e96f56be6a5ca7b43a5ce6cd032351bf47bc71 Mon Sep 17 00:00:00 2001 From: csigs Date: Wed, 20 Oct 2021 04:31:11 -0700 Subject: [PATCH 33/60] LEGO: Merge pull request 46447 LEGO: Merge pull request 46447 --- .../diagnosticMessages.generated.json.lcl | 9 +++++++++ .../diagnosticMessages.generated.json.lcl | 9 +++++++++ .../diagnosticMessages.generated.json.lcl | 9 +++++++++ .../diagnosticMessages.generated.json.lcl | 9 +++++++++ 4 files changed, 36 insertions(+) diff --git a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl index d737d528e35..53a4056ae76 100644 --- a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -477,6 +477,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl index cdbe50862e0..b9d0acf6088 100644 --- a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -468,6 +468,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl index 353974dee7f..2d66b99d92e 100644 --- a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -467,6 +467,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 8060a4c948b..44acf022a20 100644 --- a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -461,6 +461,15 @@ + + + + + + + + + From 98b4ac2cdeb9fb26e68b48ad76cf3419626b1fac Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 20 Oct 2021 08:36:40 -0700 Subject: [PATCH 34/60] @link: format trailing () as part of linkName (#46428) Parsing separates the identifier part of the link tag from its text, but the editor should present an identifier followed by `()` as a single identifier since people use that syntax as a function sigil. I prefer `#'` personally, you know, xkcd 297, nudge nudge. --- src/services/utilities.ts | 13 +- tests/baselines/reference/jsdocLink1.baseline | 6 +- tests/baselines/reference/jsdocLink2.baseline | 6 +- tests/baselines/reference/jsdocLink3.baseline | 6 +- tests/baselines/reference/jsdocLink5.baseline | 319 ++++++++++++++++++ tests/cases/fourslash/jsdocLink5.ts | 11 + 6 files changed, 341 insertions(+), 20 deletions(-) create mode 100644 tests/baselines/reference/jsdocLink5.baseline create mode 100644 tests/cases/fourslash/jsdocLink5.ts diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 5414814bd2e..05ed20effba 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -2290,9 +2290,9 @@ namespace ts { return displayPart(text, SymbolDisplayPartKind.linkText); } - export function linkNamePart(name: EntityName | JSDocMemberName, target: Declaration): JSDocLinkDisplayPart { + export function linkNamePart(text: string, target: Declaration): JSDocLinkDisplayPart { return { - text: getTextOfNode(name), + text, kind: SymbolDisplayPartKind[SymbolDisplayPartKind.linkName], target: { fileName: getSourceFileOfNode(target).fileName, @@ -2315,13 +2315,16 @@ namespace ts { } else { const symbol = checker?.getSymbolAtLocation(link.name); + const trailingParen = link.text.indexOf("()") === 0; + const name = getTextOfNode(link.name) + (trailingParen ? "()" : ""); + const text = trailingParen ? link.text.slice(2) : link.text; const decl = symbol?.valueDeclaration || symbol?.declarations?.[0]; if (decl) { - parts.push(linkNamePart(link.name, decl)); - if (link.text) parts.push(linkTextPart(link.text)); + parts.push(linkNamePart(name, decl)); + if (text) parts.push(linkTextPart(text)); } else { - parts.push(linkTextPart(getTextOfNode(link.name) + " " + link.text)); + parts.push(linkTextPart(name + (trailingParen ? "" : " ") + text)); } } parts.push(linkPart("}")); diff --git a/tests/baselines/reference/jsdocLink1.baseline b/tests/baselines/reference/jsdocLink1.baseline index ccbabd7b5c3..ebe2a61a9b6 100644 --- a/tests/baselines/reference/jsdocLink1.baseline +++ b/tests/baselines/reference/jsdocLink1.baseline @@ -107,7 +107,7 @@ "kind": "link" }, { - "text": "C", + "text": "C()", "kind": "linkName", "target": { "fileName": "/tests/cases/fourslash/jsdocLink1.ts", @@ -117,10 +117,6 @@ } } }, - { - "text": "()", - "kind": "linkText" - }, { "text": "}", "kind": "link" diff --git a/tests/baselines/reference/jsdocLink2.baseline b/tests/baselines/reference/jsdocLink2.baseline index 25697b45678..ccf6e5e3173 100644 --- a/tests/baselines/reference/jsdocLink2.baseline +++ b/tests/baselines/reference/jsdocLink2.baseline @@ -107,7 +107,7 @@ "kind": "link" }, { - "text": "C", + "text": "C()", "kind": "linkName", "target": { "fileName": "/tests/cases/fourslash/jsdocLink2.ts", @@ -117,10 +117,6 @@ } } }, - { - "text": "()", - "kind": "linkText" - }, { "text": "}", "kind": "link" diff --git a/tests/baselines/reference/jsdocLink3.baseline b/tests/baselines/reference/jsdocLink3.baseline index 56e65b430e7..d8513ef3b4c 100644 --- a/tests/baselines/reference/jsdocLink3.baseline +++ b/tests/baselines/reference/jsdocLink3.baseline @@ -107,7 +107,7 @@ "kind": "link" }, { - "text": "C", + "text": "C()", "kind": "linkName", "target": { "fileName": "/jsdocLink3.ts", @@ -117,10 +117,6 @@ } } }, - { - "text": "()", - "kind": "linkText" - }, { "text": "}", "kind": "link" diff --git a/tests/baselines/reference/jsdocLink5.baseline b/tests/baselines/reference/jsdocLink5.baseline new file mode 100644 index 00000000000..ddb421a4830 --- /dev/null +++ b/tests/baselines/reference/jsdocLink5.baseline @@ -0,0 +1,319 @@ +[ + { + "marker": { + "fileName": "/tests/cases/fourslash/jsdocLink5.ts", + "position": 210, + "name": "3" + }, + "quickInfo": { + "kind": "function", + "kindModifiers": "", + "textSpan": { + "start": 209, + "length": 1 + }, + "displayParts": [ + { + "text": "function", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "f", + "kind": "functionName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "x", + "kind": "parameterName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "any", + "kind": "keyword" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "void", + "kind": "keyword" + } + ], + "documentation": [ + { + "text": "", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "g()", + "kind": "linkName", + "target": { + "fileName": "/tests/cases/fourslash/jsdocLink5.ts", + "textSpan": { + "start": 0, + "length": 16 + } + } + }, + { + "text": "}", + "kind": "link" + }, + { + "text": " ", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "g()", + "kind": "linkName", + "target": { + "fileName": "/tests/cases/fourslash/jsdocLink5.ts", + "textSpan": { + "start": 0, + "length": 16 + } + } + }, + { + "text": " ", + "kind": "linkText" + }, + { + "text": "}", + "kind": "link" + }, + { + "text": " ", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "g()", + "kind": "linkName", + "target": { + "fileName": "/tests/cases/fourslash/jsdocLink5.ts", + "textSpan": { + "start": 0, + "length": 16 + } + } + }, + { + "text": "}", + "kind": "link" + }, + { + "text": " ", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "g()", + "kind": "linkName", + "target": { + "fileName": "/tests/cases/fourslash/jsdocLink5.ts", + "textSpan": { + "start": 0, + "length": 16 + } + } + }, + { + "text": " 0", + "kind": "linkText" + }, + { + "text": "}", + "kind": "link" + }, + { + "text": " ", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "g()", + "kind": "linkName", + "target": { + "fileName": "/tests/cases/fourslash/jsdocLink5.ts", + "textSpan": { + "start": 0, + "length": 16 + } + } + }, + { + "text": "1", + "kind": "linkText" + }, + { + "text": "}", + "kind": "link" + }, + { + "text": " ", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "g()", + "kind": "linkName", + "target": { + "fileName": "/tests/cases/fourslash/jsdocLink5.ts", + "textSpan": { + "start": 0, + "length": 16 + } + } + }, + { + "text": " 2", + "kind": "linkText" + }, + { + "text": "}", + "kind": "link" + }, + { + "text": "\n", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "u()", + "kind": "linkText" + }, + { + "text": "}", + "kind": "link" + }, + { + "text": " ", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "u() ", + "kind": "linkText" + }, + { + "text": "}", + "kind": "link" + }, + { + "text": " ", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "u()", + "kind": "linkText" + }, + { + "text": "}", + "kind": "link" + }, + { + "text": " ", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "u() 0", + "kind": "linkText" + }, + { + "text": "}", + "kind": "link" + }, + { + "text": " ", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "u()1", + "kind": "linkText" + }, + { + "text": "}", + "kind": "link" + }, + { + "text": " ", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "u() 2", + "kind": "linkText" + }, + { + "text": "}", + "kind": "link" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/cases/fourslash/jsdocLink5.ts b/tests/cases/fourslash/jsdocLink5.ts new file mode 100644 index 00000000000..d233aff2d6f --- /dev/null +++ b/tests/cases/fourslash/jsdocLink5.ts @@ -0,0 +1,11 @@ +/// + +//// function g() { } +//// /** +//// * {@link g()} {@link g() } {@link g ()} {@link g () 0} {@link g()1} {@link g() 2} +//// * {@link u()} {@link u() } {@link u ()} {@link u () 0} {@link u()1} {@link u() 2} +//// */ +//// function f(x) { +//// } +//// f/*3*/() +verify.baselineQuickInfo(); From 0d022130be83fbcf8be26b7181c18469f3a613b6 Mon Sep 17 00:00:00 2001 From: csigs Date: Wed, 20 Oct 2021 10:13:33 -0700 Subject: [PATCH 35/60] LEGO: Merge pull request 46451 LEGO: Merge pull request 46451 --- .../diagnosticMessages.generated.json.lcl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl index d4e05af0041..74d9747f5b0 100644 --- a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -461,6 +461,15 @@ + + + + + + + + + From f2e59479354c4d925949e83a377deb33d9850ea1 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 20 Oct 2021 17:01:01 -0700 Subject: [PATCH 36/60] @link parses trailing <...> as part of linkName (#46450) Similar to #46428. Fixes #44818 --- src/services/utilities.ts | 22 +- .../reference/quickInfoLink3.baseline | 227 ++++++++++++++++++ tests/cases/fourslash/quickInfoLink3.ts | 16 ++ 3 files changed, 261 insertions(+), 4 deletions(-) create mode 100644 tests/baselines/reference/quickInfoLink3.baseline create mode 100644 tests/cases/fourslash/quickInfoLink3.ts diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 05ed20effba..b7e26ffeccb 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -2315,22 +2315,36 @@ namespace ts { } else { const symbol = checker?.getSymbolAtLocation(link.name); - const trailingParen = link.text.indexOf("()") === 0; - const name = getTextOfNode(link.name) + (trailingParen ? "()" : ""); - const text = trailingParen ? link.text.slice(2) : link.text; + const suffix = findLinkNameEnd(link.text); + const name = getTextOfNode(link.name) + link.text.slice(0, suffix); + const text = link.text.slice(suffix); const decl = symbol?.valueDeclaration || symbol?.declarations?.[0]; if (decl) { parts.push(linkNamePart(name, decl)); if (text) parts.push(linkTextPart(text)); } else { - parts.push(linkTextPart(name + (trailingParen ? "" : " ") + text)); + parts.push(linkTextPart(name + (suffix ? "" : " ") + text)); } } parts.push(linkPart("}")); return parts; } + function findLinkNameEnd(text: string) { + if (text.indexOf("()") === 0) return 2; + if (text[0] !== "<") return 0; + let brackets = 0; + let i = 0; + while (i < text.length) { + if (text[i] === "<") brackets++; + if (text[i] === ">") brackets--; + i++; + if (!brackets) return i; + } + return 0; + } + const carriageReturnLineFeed = "\r\n"; /** * The default is CRLF. diff --git a/tests/baselines/reference/quickInfoLink3.baseline b/tests/baselines/reference/quickInfoLink3.baseline new file mode 100644 index 00000000000..65f4d33cef5 --- /dev/null +++ b/tests/baselines/reference/quickInfoLink3.baseline @@ -0,0 +1,227 @@ +[ + { + "marker": { + "fileName": "/tests/cases/fourslash/quickInfoLink3.ts", + "position": 169, + "name": "" + }, + "quickInfo": { + "kind": "method", + "kindModifiers": "", + "textSpan": { + "start": 166, + "length": 3 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "method", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Foo", + "kind": "className" + }, + { + "text": "<", + "kind": "punctuation" + }, + { + "text": "T", + "kind": "typeParameterName" + }, + { + "text": ">", + "kind": "punctuation" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "bar", + "kind": "methodName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "void", + "kind": "keyword" + } + ], + "documentation": [ + { + "text": "", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "Foo", + "kind": "linkName", + "target": { + "fileName": "/tests/cases/fourslash/quickInfoLink3.ts", + "textSpan": { + "start": 0, + "length": 175 + } + } + }, + { + "text": "}", + "kind": "link" + }, + { + "text": "\n", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "Foo", + "kind": "linkName", + "target": { + "fileName": "/tests/cases/fourslash/quickInfoLink3.ts", + "textSpan": { + "start": 0, + "length": 175 + } + } + }, + { + "text": "}", + "kind": "link" + }, + { + "text": "\n", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "Foo>", + "kind": "linkName", + "target": { + "fileName": "/tests/cases/fourslash/quickInfoLink3.ts", + "textSpan": { + "start": 0, + "length": 175 + } + } + }, + { + "text": "}", + "kind": "link" + }, + { + "text": "\n", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "Foo<>", + "kind": "linkName", + "target": { + "fileName": "/tests/cases/fourslash/quickInfoLink3.ts", + "textSpan": { + "start": 0, + "length": 175 + } + } + }, + { + "text": "}", + "kind": "link" + }, + { + "text": "\n", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "Foo", + "kind": "linkName", + "target": { + "fileName": "/tests/cases/fourslash/quickInfoLink3.ts", + "textSpan": { + "start": 0, + "length": 175 + } + } + }, + { + "text": ">", + "kind": "linkText" + }, + { + "text": "}", + "kind": "link" + }, + { + "text": "\n", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "Foo", + "kind": "linkName", + "target": { + "fileName": "/tests/cases/fourslash/quickInfoLink3.ts", + "textSpan": { + "start": 0, + "length": 175 + } + } + }, + { + "text": "<", + "kind": "linkText" + }, + { + "text": "}", + "kind": "link" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/cases/fourslash/quickInfoLink3.ts b/tests/cases/fourslash/quickInfoLink3.ts new file mode 100644 index 00000000000..7c0681c25aa --- /dev/null +++ b/tests/cases/fourslash/quickInfoLink3.ts @@ -0,0 +1,16 @@ +/// + +//// class Foo { +//// /** +//// * {@link Foo} +//// * {@link Foo} +//// * {@link Foo>} +//// * {@link Foo<>} +//// * {@link Foo>} +//// * {@link Foo<} +//// */ +//// bar/**/(){} +//// } + +verify.noErrors() +verify.baselineQuickInfo(); From 22f37cda859f1251029d079eb3004614d47dc831 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Thu, 21 Oct 2021 11:43:57 -0700 Subject: [PATCH 37/60] Fix ordering of module specifiers based on package.json presence (#46437) * Add failing test * Fix ordering of module specifiers based on package.json presence --- src/services/codefixes/importFixes.ts | 4 +- .../fourslash/completionsImport_46332.ts | 93 +++++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/completionsImport_46332.ts diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index d910128f6db..89b673097b7 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -663,13 +663,15 @@ namespace ts.codefix { } const { allowsImportingSpecifier } = createPackageJsonImportFilter(sourceFile, preferences, host); return fixes.reduce((best, fix) => + // Takes true branch of conditional if `fix` is better than `best` compareModuleSpecifiers(fix, best, sourceFile, program, allowsImportingSpecifier) === Comparison.LessThan ? fix : best ); } + /** @returns `Comparison.LessThan` if `a` is better than `b`. */ function compareModuleSpecifiers(a: ImportFix, b: ImportFix, importingFile: SourceFile, program: Program, allowsImportingSpecifier: (specifier: string) => boolean): Comparison { if (a.kind !== ImportFixKind.UseNamespace && b.kind !== ImportFixKind.UseNamespace) { - return compareBooleans(allowsImportingSpecifier(a.moduleSpecifier), allowsImportingSpecifier(b.moduleSpecifier)) + return compareBooleans(allowsImportingSpecifier(b.moduleSpecifier), allowsImportingSpecifier(a.moduleSpecifier)) || compareNodeCoreModuleSpecifiers(a.moduleSpecifier, b.moduleSpecifier, importingFile, program) || compareNumberOfDirectorySeparators(a.moduleSpecifier, b.moduleSpecifier); } diff --git a/tests/cases/fourslash/completionsImport_46332.ts b/tests/cases/fourslash/completionsImport_46332.ts new file mode 100644 index 00000000000..836faa59747 --- /dev/null +++ b/tests/cases/fourslash/completionsImport_46332.ts @@ -0,0 +1,93 @@ +/// + +// @module: esnext +// @moduleResolution: node + +// @Filename: /node_modules/vue/package.json +//// { +//// "name": "vue", +//// "types": "dist/vue.d.ts" +//// } + +// @Filename: /node_modules/vue/dist/vue.d.ts +//// export * from "@vue/runtime-dom" + +// @Filename: /node_modules/@vue/runtime-dom/package.json +//// { +//// "name": "@vue/runtime-dom", +//// "types": "dist/runtime-dom.d.ts" +//// } + +// @Filename: /node_modules/@vue/runtime-dom/dist/runtime-dom.d.ts +//// export * from "@vue/runtime-core"; +//// export {} +//// declare module '@vue/reactivity' { +//// export interface RefUnwrapBailTypes { +//// runtimeDOMBailTypes: any +//// } +//// } + +// @Filename: /node_modules/@vue/runtime-core/package.json +//// { +//// "name": "@vue/runtime-core", +//// "types": "dist/runtime-core.d.ts" +//// } + +// @Filename: /node_modules/@vue/runtime-core/dist/runtime-core.d.ts +//// import { ref } from '@vue/reactivity'; +//// export { ref }; +//// declare module '@vue/reactivity' { +//// export interface RefUnwrapBailTypes { +//// runtimeCoreBailTypes: any +//// } +//// } + +// @Filename: /node_modules/@vue/reactivity/package.json +//// { +//// "name": "@vue/reactivity", +//// "types": "dist/reactivity.d.ts" +//// } + +// @Filename: /node_modules/@vue/reactivity/dist/reactivity.d.ts +//// export declare function ref(): T; + +// @Filename: /package.json +//// { +//// "dependencies": { +//// "vue": "*" +//// } +//// } + +// @Filename: /index.ts +//// import {} from "vue"; +//// ref/**/ + +verify.completions({ + marker: "", + includes: [{ + name: "ref", + source: "vue", + sourceDisplay: "vue", + hasAction: true, + sortText: completion.SortText.AutoImportSuggestions, + }], + preferences: { + includeCompletionsForModuleExports: true, + allowIncompleteCompletions: true, + }, +}); + +verify.applyCodeActionFromCompletion("", { + name: "ref", + source: "vue", + description: `Add 'ref' to existing import declaration from "vue"`, + data: { + exportName: "ref", + fileName: "/node_modules/vue/dist/vue.d.ts", + }, + preferences: { + includeCompletionsForModuleExports: true, + allowIncompleteCompletions: true, + }, + newFileContent: `import { ref } from "vue";\nref` +}); From 5725cfeb10f147c884ce0f5672a48713edac31f2 Mon Sep 17 00:00:00 2001 From: Warren Lu Date: Thu, 21 Oct 2021 14:59:01 -0400 Subject: [PATCH 38/60] Fix typos in es5.d.ts (#46321) --- src/lib/es5.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index f8715e49373..b10358a0f7e 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -196,13 +196,13 @@ interface ObjectConstructor { /** * Prevents the modification of existing property attributes and values, and prevents the addition of new properties. - * @param o Object on which to lock the attributes. + * @param a Object on which to lock the attributes. */ freeze(a: T[]): readonly T[]; /** * Prevents the modification of existing property attributes and values, and prevents the addition of new properties. - * @param o Object on which to lock the attributes. + * @param f Object on which to lock the attributes. */ freeze(f: T): T; From 55b4928e820c0a16698eff41ba08bfe550a75604 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Thu, 21 Oct 2021 12:22:53 -0700 Subject: [PATCH 39/60] Pass absolute path to directoryExists (#46086) * Pass absolute path to directoryExists As pointed out by @gretzkiy, the `directoryExists` call added to `matchFiles` in #44710 should have been passing the absolute path (since the current directory might not match `currentDirectory`). * Add test, simplify/clarify/fix matchFiles and friends Co-authored-by: Andrew Branch --- src/compiler/utilities.ts | 28 ++++++++++++------------ src/testRunner/unittests/publicApi.ts | 31 +++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 4b225a0ad0e..82015d6148e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -6613,7 +6613,7 @@ namespace ts { includeFilePattern: getRegularExpressionForWildcard(includes, absolutePath, "files"), includeDirectoryPattern: getRegularExpressionForWildcard(includes, absolutePath, "directories"), excludePattern: getRegularExpressionForWildcard(excludes, absolutePath, "exclude"), - basePaths: getBasePaths(path, includes, useCaseSensitiveFileNames) + basePaths: getBasePaths(absolutePath, includes, useCaseSensitiveFileNames) }; } @@ -6637,22 +6637,22 @@ namespace ts { const results: string[][] = includeFileRegexes ? includeFileRegexes.map(() => []) : [[]]; const visited = new Map(); const toCanonical = createGetCanonicalFileName(useCaseSensitiveFileNames); - for (const basePath of patterns.basePaths) { - if (directoryExists(basePath)) { - visitDirectory(basePath, combinePaths(currentDirectory, basePath), depth); + for (const absoluteBasePath of patterns.basePaths) { + if (directoryExists(absoluteBasePath)) { + visitDirectory(absoluteBasePath, depth); } } return flatten(results); - function visitDirectory(path: string, absolutePath: string, depth: number | undefined) { + function visitDirectory(absolutePath: string, depth: number | undefined) { const canonicalPath = toCanonical(realpath(absolutePath)); if (visited.has(canonicalPath)) return; visited.set(canonicalPath, true); - const { files, directories } = getFileSystemEntries(path); + const { files, directories } = getFileSystemEntries(absolutePath); for (const current of sort(files, compareStringsCaseSensitive)) { - const name = combinePaths(path, current); + const name = combinePaths(absolutePath, current); const absoluteName = combinePaths(absolutePath, current); if (extensions && !fileExtensionIsOneOf(name, extensions)) continue; if (excludeRegex && excludeRegex.test(absoluteName)) continue; @@ -6675,11 +6675,10 @@ namespace ts { } for (const current of sort(directories, compareStringsCaseSensitive)) { - const name = combinePaths(path, current); const absoluteName = combinePaths(absolutePath, current); if ((!includeDirectoryRegex || includeDirectoryRegex.test(absoluteName)) && (!excludeRegex || !excludeRegex.test(absoluteName))) { - visitDirectory(name, absoluteName, depth); + visitDirectory(absoluteName, depth); } } } @@ -6687,10 +6686,11 @@ namespace ts { /** * Computes the unique non-wildcard base paths amongst the provided include patterns. + * @returns Absolute directory paths */ - function getBasePaths(path: string, includes: readonly string[] | undefined, useCaseSensitiveFileNames: boolean): string[] { + function getBasePaths(absoluteTsconfigPath: string, includes: readonly string[] | undefined, useCaseSensitiveFileNames: boolean): string[] { // Storage for our results in the form of literal paths (e.g. the paths as written by the user). - const basePaths: string[] = [path]; + const basePaths: string[] = [absoluteTsconfigPath]; if (includes) { // Storage for literal base paths amongst the include patterns. @@ -6698,9 +6698,9 @@ namespace ts { for (const include of includes) { // We also need to check the relative paths by converting them to absolute and normalizing // in case they escape the base path (e.g "..\somedirectory") - const absolute: string = isRootedDiskPath(include) ? include : normalizePath(combinePaths(path, include)); + const absoluteIncludePath: string = isRootedDiskPath(include) ? include : normalizePath(combinePaths(absoluteTsconfigPath, include)); // Append the literal and canonical candidate base paths. - includeBasePaths.push(getIncludeBasePath(absolute)); + includeBasePaths.push(getIncludeBasePath(absoluteIncludePath)); } // Sort the offsets array using either the literal or canonical path representations. @@ -6709,7 +6709,7 @@ namespace ts { // Iterate over each include base path and include unique base paths that are not a // subpath of an existing base path for (const includeBasePath of includeBasePaths) { - if (every(basePaths, basePath => !containsPath(basePath, includeBasePath, path, !useCaseSensitiveFileNames))) { + if (every(basePaths, basePath => !containsPath(basePath, includeBasePath, absoluteTsconfigPath, !useCaseSensitiveFileNames))) { basePaths.push(includeBasePath); } } diff --git a/src/testRunner/unittests/publicApi.ts b/src/testRunner/unittests/publicApi.ts index 883b979f9c7..e741e902b4e 100644 --- a/src/testRunner/unittests/publicApi.ts +++ b/src/testRunner/unittests/publicApi.ts @@ -182,3 +182,34 @@ describe("unittests:: Public APIs:: getChild* methods on EndOfFileToken with JSD assert.equal(endOfFileToken.getChildCount(), 1); assert.notEqual(endOfFileToken.getChildAt(0), /*expected*/ undefined); }); + +describe("unittests:: Public APIs:: sys", () => { + it("readDirectory", () => { + // #45990, testing passing a non-absolute path + // `sys.readDirectory` is just `matchFiles` plugged into the real FS + const read = ts.matchFiles( + /*path*/ "", + /*extensions*/ [".ts", ".tsx"], + /*excludes*/ ["node_modules", "dist"], + /*includes*/ ["**/*"], + /*useCaseSensitiveFileNames*/ true, + /*currentDirectory*/ "/", + /*depth*/ undefined, + /*getFileSystemEntries*/ path => { + switch (path) { + case "/": return { directories: [], files: ["file.ts"] }; + default: return { directories: [], files: [] }; + } + }, + /*realpath*/ ts.identity, + /*directoryExists*/ path => { + switch (path) { + case "/": return true; + default: return false; + } + } + ); + + assert.deepEqual(read, ["/file.ts"]); + }); +}); From bd12ae24540e395a148abd5d748b3c69c40bae63 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Fri, 22 Oct 2021 01:56:45 +0300 Subject: [PATCH 40/60] fix(46466): add missing async keyword before type parameters (#46467) --- src/services/codefixes/fixAwaitInSyncFunction.ts | 3 ++- tests/cases/fourslash/codeFixAddMissingAsync3.ts | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/codeFixAddMissingAsync3.ts diff --git a/src/services/codefixes/fixAwaitInSyncFunction.ts b/src/services/codefixes/fixAwaitInSyncFunction.ts index bfd68e05d0a..0f0f2880ec3 100644 --- a/src/services/codefixes/fixAwaitInSyncFunction.ts +++ b/src/services/codefixes/fixAwaitInSyncFunction.ts @@ -53,7 +53,8 @@ namespace ts.codefix { insertBefore = findChildOfKind(containingFunction, SyntaxKind.FunctionKeyword, sourceFile); break; case SyntaxKind.ArrowFunction: - insertBefore = findChildOfKind(containingFunction, SyntaxKind.OpenParenToken, sourceFile) || first(containingFunction.parameters); + const kind = containingFunction.typeParameters ? SyntaxKind.LessThanToken : SyntaxKind.OpenParenToken; + insertBefore = findChildOfKind(containingFunction, kind, sourceFile) || first(containingFunction.parameters); break; default: return; diff --git a/tests/cases/fourslash/codeFixAddMissingAsync3.ts b/tests/cases/fourslash/codeFixAddMissingAsync3.ts new file mode 100644 index 00000000000..9588556afbe --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingAsync3.ts @@ -0,0 +1,16 @@ +/// + +////const foo = (x: T): string => { +//// await new Promise(resolve => resolve(true)); +//// return ""; +////} + +verify.codeFix({ + description: ts.Diagnostics.Add_async_modifier_to_containing_function.message, + index: 0, + newFileContent: +`const foo = async (x: T): Promise => { + await new Promise(resolve => resolve(true)); + return ""; +}` +}); From f2f35ae78bca07dea75a392f2582025894d4e2ab Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 21 Oct 2021 17:35:23 -0700 Subject: [PATCH 41/60] Simplify relationship check for conditional type on target side (#46429) * Simplify relationship check for conditional type on target side * Accept new baselines * Better support for non-distribution-dependent types * Accept new API baselines * Accept new baselines --- src/compiler/checker.ts | 54 +++++++------------ src/compiler/types.ts | 1 + .../reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + 4 files changed, 23 insertions(+), 34 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d149b044284..c9243e811b8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15315,13 +15315,6 @@ namespace ts { return type[cache] = type; } - function isConditionalTypeAlwaysTrueDisregardingInferTypes(type: ConditionalType) { - const extendsInferParamMapper = type.root.inferTypeParameters && createTypeMapper(type.root.inferTypeParameters, map(type.root.inferTypeParameters, () => wildcardType)); - const checkType = type.checkType; - const extendsType = type.extendsType; - return isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(instantiateType(extendsType, extendsInferParamMapper))); - } - function getSimplifiedConditionalType(type: ConditionalType, writing: boolean) { const checkType = type.checkType; const extendsType = type.extendsType; @@ -15649,6 +15642,10 @@ namespace ts { const links = getNodeLinks(node); if (!links.resolvedType) { const checkType = getTypeFromTypeNode(node.checkType); + const isDistributive = !!(checkType.flags & TypeFlags.TypeParameter); + const isDistributionDependent = isDistributive && ( + isTypeParameterPossiblyReferenced(checkType as TypeParameter, node.trueType) || + isTypeParameterPossiblyReferenced(checkType as TypeParameter, node.falseType)); const aliasSymbol = getAliasSymbolForTypeNode(node); const aliasTypeArguments = getTypeArgumentsForAliasSymbol(aliasSymbol); const allOuterTypeParameters = getOuterTypeParameters(node, /*includeThisTypes*/ true); @@ -15657,7 +15654,8 @@ namespace ts { node, checkType, extendsType: getTypeFromTypeNode(node.extendsType), - isDistributive: !!(checkType.flags & TypeFlags.TypeParameter), + isDistributive, + isDistributionDependent, inferTypeParameters: getInferTypeParameters(node), outerTypeParameters, instantiations: undefined, @@ -19031,34 +19029,22 @@ namespace ts { return Ternary.Maybe; } const c = target as ConditionalType; - // Check if the conditional is always true or always false but still deferred for distribution purposes - const skipTrue = !isTypeAssignableTo(getPermissiveInstantiation(c.checkType), getPermissiveInstantiation(c.extendsType)); - const skipFalse = !skipTrue && isConditionalTypeAlwaysTrueDisregardingInferTypes(c); - - // Instantiate with a replacement mapper if the conditional is distributive, replacing the check type with a clone of itself, - // this way {x: string | number, y: string | number} -> (T extends T ? { x: T, y: T } : never) appropriately _fails_ when - // T = string | number (since that will end up distributing and producing `{x: string, y: string} | {x: number, y: number}`, - // to which `{x: string | number, y: string | number}` isn't assignable) - let distributionMapper: TypeMapper | undefined; - const checkVar = getActualTypeVariable(c.root.checkType); - if (c.root.isDistributive && checkVar.flags & TypeFlags.TypeParameter) { - const newParam = cloneTypeParameter(checkVar); - distributionMapper = prependTypeMapping(checkVar, newParam, c.mapper); - newParam.mapper = distributionMapper; - } - - // TODO: Find a nice way to include potential conditional type breakdowns in error output, if they seem good (they usually don't) - const expanding = isDeeplyNestedType(target, targetStack, targetDepth); - let localResult: Ternary | undefined = expanding ? Ternary.Maybe : undefined; - if (skipTrue || expanding || (localResult = isRelatedTo(source, distributionMapper ? instantiateType(getTypeFromTypeNode(c.root.node.trueType), distributionMapper) : getTrueTypeFromConditionalType(c), RecursionFlags.Target, /*reportErrors*/ false))) { - if (!skipFalse && !expanding) { - localResult = (localResult || Ternary.Maybe) & isRelatedTo(source, distributionMapper ? instantiateType(getTypeFromTypeNode(c.root.node.falseType), distributionMapper) : getFalseTypeFromConditionalType(c), RecursionFlags.Target, /*reportErrors*/ false); + // We check for a relationship to a conditional type target only when the conditional type has no + // 'infer' positions and is not distributive or is distributive but doesn't reference the check type + // parameter in either of the result types. + if (!c.root.inferTypeParameters && !c.root.isDistributionDependent) { + // Check if the conditional is always true or always false but still deferred for distribution purposes. + const skipTrue = !isTypeAssignableTo(getPermissiveInstantiation(c.checkType), getPermissiveInstantiation(c.extendsType)); + const skipFalse = !skipTrue && isTypeAssignableTo(getRestrictiveInstantiation(c.checkType), getRestrictiveInstantiation(c.extendsType)); + // TODO: Find a nice way to include potential conditional type breakdowns in error output, if they seem good (they usually don't) + if (result = skipTrue ? Ternary.True : isRelatedTo(source, getTrueTypeFromConditionalType(c), RecursionFlags.Target, /*reportErrors*/ false)) { + result &= skipFalse ? Ternary.True : isRelatedTo(source, getFalseTypeFromConditionalType(c), RecursionFlags.Target, /*reportErrors*/ false); + if (result) { + resetErrorInfo(saveErrorInfo); + return result; + } } } - if (localResult) { - resetErrorInfo(saveErrorInfo); - return localResult; - } } else if (target.flags & TypeFlags.TemplateLiteral) { if (source.flags & TypeFlags.TemplateLiteral) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 6c7cb7b5187..1343e1859ae 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5648,6 +5648,7 @@ namespace ts { checkType: Type; extendsType: Type; isDistributive: boolean; + isDistributionDependent: boolean; inferTypeParameters?: TypeParameter[]; outerTypeParameters?: TypeParameter[]; instantiations?: Map; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 116be4316f9..e1512586cff 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2747,6 +2747,7 @@ declare namespace ts { checkType: Type; extendsType: Type; isDistributive: boolean; + isDistributionDependent: boolean; inferTypeParameters?: TypeParameter[]; outerTypeParameters?: TypeParameter[]; instantiations?: Map; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 56d764c664c..f93ca902bbf 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2747,6 +2747,7 @@ declare namespace ts { checkType: Type; extendsType: Type; isDistributive: boolean; + isDistributionDependent: boolean; inferTypeParameters?: TypeParameter[]; outerTypeParameters?: TypeParameter[]; instantiations?: Map; From 65ae16cdea7ec887a6a16f9e709a07c2abe88387 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Fri, 22 Oct 2021 06:06:14 +0000 Subject: [PATCH 42/60] Update package-lock.json --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 88ccc598010..06751eebd71 100644 --- a/package-lock.json +++ b/package-lock.json @@ -676,9 +676,9 @@ "dev": true }, "@types/node": { - "version": "16.11.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.1.tgz", - "integrity": "sha512-PYGcJHL9mwl1Ek3PLiYgyEKtwTMmkMw4vbiyz/ps3pfdRYLVv+SN7qHVAImrjdAXxgluDEw6Ph4lyv+m9UpRmA==", + "version": "16.11.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.2.tgz", + "integrity": "sha512-w34LtBB0OkDTs19FQHXy4Ig/TOXI4zqvXS2Kk1PAsRKZ0I+nik7LlMYxckW0tSNGtvWmzB+mrCTbuEjuB9DVsw==", "dev": true }, "@types/node-fetch": { @@ -6797,9 +6797,9 @@ } }, "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", + "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==", "dev": true }, "side-channel": { From 449aaa118fbbed36bfd886cc05957a49682111e6 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 22 Oct 2021 09:13:54 -0700 Subject: [PATCH 43/60] Defer computation of isDistributionDependent to avoid circularities (#46474) * Defer computation of isDistributionDependent to avoid circularities * Accept new API baselines --- src/compiler/checker.ts | 15 ++++++++------- src/compiler/types.ts | 1 - .../baselines/reference/api/tsserverlibrary.d.ts | 1 - tests/baselines/reference/api/typescript.d.ts | 1 - 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c9243e811b8..75df0d653be 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15638,14 +15638,16 @@ namespace ts { return result; } + function isDistributionDependent(root: ConditionalRoot) { + return root.isDistributive && ( + isTypeParameterPossiblyReferenced(root.checkType as TypeParameter, root.node.trueType) || + isTypeParameterPossiblyReferenced(root.checkType as TypeParameter, root.node.falseType)); + } + function getTypeFromConditionalTypeNode(node: ConditionalTypeNode): Type { const links = getNodeLinks(node); if (!links.resolvedType) { const checkType = getTypeFromTypeNode(node.checkType); - const isDistributive = !!(checkType.flags & TypeFlags.TypeParameter); - const isDistributionDependent = isDistributive && ( - isTypeParameterPossiblyReferenced(checkType as TypeParameter, node.trueType) || - isTypeParameterPossiblyReferenced(checkType as TypeParameter, node.falseType)); const aliasSymbol = getAliasSymbolForTypeNode(node); const aliasTypeArguments = getTypeArgumentsForAliasSymbol(aliasSymbol); const allOuterTypeParameters = getOuterTypeParameters(node, /*includeThisTypes*/ true); @@ -15654,8 +15656,7 @@ namespace ts { node, checkType, extendsType: getTypeFromTypeNode(node.extendsType), - isDistributive, - isDistributionDependent, + isDistributive: !!(checkType.flags & TypeFlags.TypeParameter), inferTypeParameters: getInferTypeParameters(node), outerTypeParameters, instantiations: undefined, @@ -19032,7 +19033,7 @@ namespace ts { // We check for a relationship to a conditional type target only when the conditional type has no // 'infer' positions and is not distributive or is distributive but doesn't reference the check type // parameter in either of the result types. - if (!c.root.inferTypeParameters && !c.root.isDistributionDependent) { + if (!c.root.inferTypeParameters && !isDistributionDependent(c.root)) { // Check if the conditional is always true or always false but still deferred for distribution purposes. const skipTrue = !isTypeAssignableTo(getPermissiveInstantiation(c.checkType), getPermissiveInstantiation(c.extendsType)); const skipFalse = !skipTrue && isTypeAssignableTo(getRestrictiveInstantiation(c.checkType), getRestrictiveInstantiation(c.extendsType)); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 1343e1859ae..6c7cb7b5187 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5648,7 +5648,6 @@ namespace ts { checkType: Type; extendsType: Type; isDistributive: boolean; - isDistributionDependent: boolean; inferTypeParameters?: TypeParameter[]; outerTypeParameters?: TypeParameter[]; instantiations?: Map; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index e1512586cff..116be4316f9 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2747,7 +2747,6 @@ declare namespace ts { checkType: Type; extendsType: Type; isDistributive: boolean; - isDistributionDependent: boolean; inferTypeParameters?: TypeParameter[]; outerTypeParameters?: TypeParameter[]; instantiations?: Map; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index f93ca902bbf..56d764c664c 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2747,7 +2747,6 @@ declare namespace ts { checkType: Type; extendsType: Type; isDistributive: boolean; - isDistributionDependent: boolean; inferTypeParameters?: TypeParameter[]; outerTypeParameters?: TypeParameter[]; instantiations?: Map; From ce676d0963afb857fe9023a4366cc0b2a876dd0b Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Fri, 22 Oct 2021 19:58:01 +0300 Subject: [PATCH 44/60] fix(46433): forbid using keywords as parameter names (#46459) --- src/compiler/diagnosticMessages.json | 4 ++ src/compiler/parser.ts | 5 ++- .../reference/reservedWords2.errors.txt | 1 - tests/baselines/reference/reservedWords2.js | 1 - .../reference/reservedWords2.symbols | 1 - .../baselines/reference/reservedWords2.types | 1 - .../reference/reservedWords3.errors.txt | 45 +++++++++++++++++++ tests/baselines/reference/reservedWords3.js | 28 ++++++++++++ .../reference/reservedWords3.symbols | 18 ++++++++ .../baselines/reference/reservedWords3.types | 20 +++++++++ tests/cases/compiler/reservedWords2.ts | 1 - tests/cases/compiler/reservedWords3.ts | 5 +++ 12 files changed, 124 insertions(+), 6 deletions(-) create mode 100644 tests/baselines/reference/reservedWords3.errors.txt create mode 100644 tests/baselines/reference/reservedWords3.js create mode 100644 tests/baselines/reference/reservedWords3.symbols create mode 100644 tests/baselines/reference/reservedWords3.types create mode 100644 tests/cases/compiler/reservedWords3.ts diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index a40439d012a..1428ee95b4c 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1164,6 +1164,10 @@ "category": "Error", "code": 1389 }, + "'{0}' is not allowed as a parameter name.": { + "category": "Error", + "code": 1390 + }, "An import alias cannot use 'import type'": { "category": "Error", "code": 1392 diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 1109d36a610..6bb5d0aec31 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2611,7 +2611,10 @@ namespace ts { case ParsingContext.ObjectLiteralMembers: return parseErrorAtCurrentToken(Diagnostics.Property_assignment_expected); case ParsingContext.ArrayLiteralMembers: return parseErrorAtCurrentToken(Diagnostics.Expression_or_comma_expected); case ParsingContext.JSDocParameters: return parseErrorAtCurrentToken(Diagnostics.Parameter_declaration_expected); - case ParsingContext.Parameters: return parseErrorAtCurrentToken(Diagnostics.Parameter_declaration_expected); + case ParsingContext.Parameters: + return isKeyword(token()) + ? parseErrorAtCurrentToken(Diagnostics._0_is_not_allowed_as_a_parameter_name, tokenToString(token())) + : parseErrorAtCurrentToken(Diagnostics.Parameter_declaration_expected); case ParsingContext.TypeParameters: return parseErrorAtCurrentToken(Diagnostics.Type_parameter_declaration_expected); case ParsingContext.TypeArguments: return parseErrorAtCurrentToken(Diagnostics.Type_argument_expected); case ParsingContext.TupleElementTypes: return parseErrorAtCurrentToken(Diagnostics.Type_expected); diff --git a/tests/baselines/reference/reservedWords2.errors.txt b/tests/baselines/reference/reservedWords2.errors.txt index 18f594005c4..7e38ea1f851 100644 --- a/tests/baselines/reference/reservedWords2.errors.txt +++ b/tests/baselines/reference/reservedWords2.errors.txt @@ -118,5 +118,4 @@ tests/cases/compiler/reservedWords2.ts(12,17): error TS1138: Parameter declarati !!! error TS1359: Identifier expected. 'null' is a reserved word that cannot be used here. ~ !!! error TS1138: Parameter declaration expected. - \ No newline at end of file diff --git a/tests/baselines/reference/reservedWords2.js b/tests/baselines/reference/reservedWords2.js index 49a680085ee..329ca94a532 100644 --- a/tests/baselines/reference/reservedWords2.js +++ b/tests/baselines/reference/reservedWords2.js @@ -11,7 +11,6 @@ var [debugger, if] = [1, 2]; enum void {} function f(default: number) {} class C { m(null: string) {} } - //// [reservedWords2.js] diff --git a/tests/baselines/reference/reservedWords2.symbols b/tests/baselines/reference/reservedWords2.symbols index 865ee314ba7..7091d453dc3 100644 --- a/tests/baselines/reference/reservedWords2.symbols +++ b/tests/baselines/reference/reservedWords2.symbols @@ -40,4 +40,3 @@ class C { m(null: string) {} } > : Symbol((Missing), Decl(reservedWords2.ts, 11, 12)) >string : Symbol(string, Decl(reservedWords2.ts, 11, 17)) - diff --git a/tests/baselines/reference/reservedWords2.types b/tests/baselines/reference/reservedWords2.types index abb5717cad3..498bd518a7c 100644 --- a/tests/baselines/reference/reservedWords2.types +++ b/tests/baselines/reference/reservedWords2.types @@ -74,4 +74,3 @@ class C { m(null: string) {} } > : any >string : any - diff --git a/tests/baselines/reference/reservedWords3.errors.txt b/tests/baselines/reference/reservedWords3.errors.txt new file mode 100644 index 00000000000..e1bd27f4185 --- /dev/null +++ b/tests/baselines/reference/reservedWords3.errors.txt @@ -0,0 +1,45 @@ +tests/cases/compiler/reservedWords3.ts(1,13): error TS1390: 'enum' is not allowed as a parameter name. +tests/cases/compiler/reservedWords3.ts(1,17): error TS2567: Enum declarations can only merge with namespace or other enum declarations. +tests/cases/compiler/reservedWords3.ts(1,17): error TS1003: Identifier expected. +tests/cases/compiler/reservedWords3.ts(2,13): error TS1390: 'class' is not allowed as a parameter name. +tests/cases/compiler/reservedWords3.ts(2,18): error TS1005: '{' expected. +tests/cases/compiler/reservedWords3.ts(3,13): error TS1390: 'function' is not allowed as a parameter name. +tests/cases/compiler/reservedWords3.ts(3,21): error TS2567: Enum declarations can only merge with namespace or other enum declarations. +tests/cases/compiler/reservedWords3.ts(3,21): error TS1003: Identifier expected. +tests/cases/compiler/reservedWords3.ts(4,13): error TS1390: 'while' is not allowed as a parameter name. +tests/cases/compiler/reservedWords3.ts(4,18): error TS1005: '(' expected. +tests/cases/compiler/reservedWords3.ts(5,13): error TS1390: 'for' is not allowed as a parameter name. +tests/cases/compiler/reservedWords3.ts(5,16): error TS1005: '(' expected. + + +==== tests/cases/compiler/reservedWords3.ts (12 errors) ==== + function f1(enum) {} + ~~~~ +!!! error TS1390: 'enum' is not allowed as a parameter name. + +!!! error TS2567: Enum declarations can only merge with namespace or other enum declarations. + ~ +!!! error TS1003: Identifier expected. + function f2(class) {} + ~~~~~ +!!! error TS1390: 'class' is not allowed as a parameter name. + ~ +!!! error TS1005: '{' expected. + function f3(function) {} + ~~~~~~~~ +!!! error TS1390: 'function' is not allowed as a parameter name. + +!!! error TS2567: Enum declarations can only merge with namespace or other enum declarations. + ~ +!!! error TS1003: Identifier expected. + function f4(while) {} + ~~~~~ +!!! error TS1390: 'while' is not allowed as a parameter name. + ~ +!!! error TS1005: '(' expected. + function f5(for) {} + ~~~ +!!! error TS1390: 'for' is not allowed as a parameter name. + ~ +!!! error TS1005: '(' expected. + \ No newline at end of file diff --git a/tests/baselines/reference/reservedWords3.js b/tests/baselines/reference/reservedWords3.js new file mode 100644 index 00000000000..8957622d7ab --- /dev/null +++ b/tests/baselines/reference/reservedWords3.js @@ -0,0 +1,28 @@ +//// [reservedWords3.ts] +function f1(enum) {} +function f2(class) {} +function f3(function) {} +function f4(while) {} +function f5(for) {} + + +//// [reservedWords3.js] +function f1() { } +var ; +(function () { +})( || ( = {})); +{ } +function f2() { } +var default_1 = /** @class */ (function () { + function default_1() { + } + return default_1; +}()); +{ } +function f3() { } +function () { } +{ } +function f4() { } +while () { } +function f5() { } +for (;;) { } diff --git a/tests/baselines/reference/reservedWords3.symbols b/tests/baselines/reference/reservedWords3.symbols new file mode 100644 index 00000000000..68d36d3641c --- /dev/null +++ b/tests/baselines/reference/reservedWords3.symbols @@ -0,0 +1,18 @@ +=== tests/cases/compiler/reservedWords3.ts === +function f1(enum) {} +>f1 : Symbol(f1, Decl(reservedWords3.ts, 0, 0)) +> : Symbol((Missing), Decl(reservedWords3.ts, 0, 12)) + +function f2(class) {} +>f2 : Symbol(f2, Decl(reservedWords3.ts, 0, 20)) + +function f3(function) {} +>f3 : Symbol(f3, Decl(reservedWords3.ts, 1, 21)) +> : Symbol((Missing), Decl(reservedWords3.ts, 2, 12)) + +function f4(while) {} +>f4 : Symbol(f4, Decl(reservedWords3.ts, 2, 24)) + +function f5(for) {} +>f5 : Symbol(f5, Decl(reservedWords3.ts, 3, 21)) + diff --git a/tests/baselines/reference/reservedWords3.types b/tests/baselines/reference/reservedWords3.types new file mode 100644 index 00000000000..fd9ec4ce234 --- /dev/null +++ b/tests/baselines/reference/reservedWords3.types @@ -0,0 +1,20 @@ +=== tests/cases/compiler/reservedWords3.ts === +function f1(enum) {} +>f1 : () => any +> : (Missing) + +function f2(class) {} +>f2 : () => any + +function f3(function) {} +>f3 : () => any +> : () => any + +function f4(while) {} +>f4 : () => any +> : any + +function f5(for) {} +>f5 : () => any +> : any + diff --git a/tests/cases/compiler/reservedWords2.ts b/tests/cases/compiler/reservedWords2.ts index fe261f0cf4d..e74b403d27b 100644 --- a/tests/cases/compiler/reservedWords2.ts +++ b/tests/cases/compiler/reservedWords2.ts @@ -10,4 +10,3 @@ var [debugger, if] = [1, 2]; enum void {} function f(default: number) {} class C { m(null: string) {} } - diff --git a/tests/cases/compiler/reservedWords3.ts b/tests/cases/compiler/reservedWords3.ts new file mode 100644 index 00000000000..d2713503c38 --- /dev/null +++ b/tests/cases/compiler/reservedWords3.ts @@ -0,0 +1,5 @@ +function f1(enum) {} +function f2(class) {} +function f3(function) {} +function f4(while) {} +function f5(for) {} From de1ac8191e6d6fccead4db63153cbe0a557cd9d4 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Fri, 22 Oct 2021 12:28:04 -0700 Subject: [PATCH 45/60] Fix isNewIdentifierLocation after async (#46485) --- src/services/completions.ts | 14 +++++++---- .../completionsAsyncMethodDeclaration.ts | 25 +++++++++++++++++++ 2 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 tests/cases/fourslash/completionsAsyncMethodDeclaration.ts diff --git a/src/services/completions.ts b/src/services/completions.ts index 40053d2e873..18cb2ed9b79 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -2209,8 +2209,9 @@ namespace ts.Completions { function isNewIdentifierDefinitionLocation(): boolean { if (contextToken) { const containingNodeKind = contextToken.parent.kind; + const tokenKind = keywordForNode(contextToken); // Previous token may have been a keyword that was converted to an identifier. - switch (keywordForNode(contextToken)) { + switch (tokenKind) { case SyntaxKind.CommaToken: return containingNodeKind === SyntaxKind.CallExpression // func( a, | || containingNodeKind === SyntaxKind.Constructor // constructor( a, | /* public, protected, private keywords are allowed here, so show completion */ @@ -2254,10 +2255,13 @@ namespace ts.Completions { case SyntaxKind.TemplateMiddle: return containingNodeKind === SyntaxKind.TemplateSpan; // `aa ${10} dd ${| - case SyntaxKind.PublicKeyword: - case SyntaxKind.PrivateKeyword: - case SyntaxKind.ProtectedKeyword: - return containingNodeKind === SyntaxKind.PropertyDeclaration; // class A{ public | + case SyntaxKind.AsyncKeyword: + return containingNodeKind === SyntaxKind.MethodDeclaration // const obj = { async c|() + || containingNodeKind === SyntaxKind.ShorthandPropertyAssignment; // const obj = { async c| + } + + if (isClassMemberCompletionKeyword(tokenKind)) { + return true; } } diff --git a/tests/cases/fourslash/completionsAsyncMethodDeclaration.ts b/tests/cases/fourslash/completionsAsyncMethodDeclaration.ts new file mode 100644 index 00000000000..ddb3070d2d7 --- /dev/null +++ b/tests/cases/fourslash/completionsAsyncMethodDeclaration.ts @@ -0,0 +1,25 @@ +/// + +//// const obj = { +//// a() {}, +//// async b/*1*/ +//// }; +//// const obj2 = { +//// async /*2*/ +//// }; +//// class Foo { +//// async b/*3*/ +//// } +//// class Foo2 { +//// async /*4*/ +//// } +//// class Bar { +//// static async b/*5*/ +//// } + +test.markerNames().forEach(marker => { + verify.completions({ + marker, + isNewIdentifierLocation: true + }); +}); From 334b8eaa572794cecdb3c12fe3a968e7bd41e192 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 22 Oct 2021 15:44:35 -0700 Subject: [PATCH 46/60] Bind assignments to 'this' within static blocks in JS files (#46472) * Add failing test case. * Handle 'this' assignments on class static blocks in JavaScript. * Accepted baselines. --- src/compiler/binder.ts | 1 + ...riptThisAssignmentInStaticBlock.errors.txt | 30 ++++++++ .../javascriptThisAssignmentInStaticBlock.js | 73 +++++++++++++++++++ ...ascriptThisAssignmentInStaticBlock.symbols | 49 +++++++++++++ ...avascriptThisAssignmentInStaticBlock.types | 57 +++++++++++++++ .../javascriptThisAssignmentInStaticBlock.ts | 24 ++++++ 6 files changed, 234 insertions(+) create mode 100644 tests/baselines/reference/javascriptThisAssignmentInStaticBlock.errors.txt create mode 100644 tests/baselines/reference/javascriptThisAssignmentInStaticBlock.js create mode 100644 tests/baselines/reference/javascriptThisAssignmentInStaticBlock.symbols create mode 100644 tests/baselines/reference/javascriptThisAssignmentInStaticBlock.types create mode 100644 tests/cases/compiler/javascriptThisAssignmentInStaticBlock.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index d26da9bcbf0..8ff6712ad30 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2947,6 +2947,7 @@ namespace ts { case SyntaxKind.MethodDeclaration: case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: + case SyntaxKind.ClassStaticBlockDeclaration: // this.foo assignment in a JavaScript class // Bind this property to the containing class const containingClass = thisContainer.parent; diff --git a/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.errors.txt b/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.errors.txt new file mode 100644 index 00000000000..a4729d56ef5 --- /dev/null +++ b/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.errors.txt @@ -0,0 +1,30 @@ +/src/a.js(10,7): error TS2417: Class static side 'typeof ElementsArray' incorrectly extends base class static side '{ isArray(arg: any): arg is any[]; readonly prototype: any[]; }'. + Types of property 'isArray' are incompatible. + Type '(arg: any) => boolean' is not assignable to type '(arg: any) => arg is any[]'. + Signature '(arg: any): boolean' must be a type predicate. + + +==== /src/a.js (1 errors) ==== + class Thing { + static { + this.doSomething = () => {}; + } + } + + Thing.doSomething(); + + // GH#46468 + class ElementsArray extends Array { + ~~~~~~~~~~~~~ +!!! error TS2417: Class static side 'typeof ElementsArray' incorrectly extends base class static side '{ isArray(arg: any): arg is any[]; readonly prototype: any[]; }'. +!!! error TS2417: Types of property 'isArray' are incompatible. +!!! error TS2417: Type '(arg: any) => boolean' is not assignable to type '(arg: any) => arg is any[]'. +!!! error TS2417: Signature '(arg: any): boolean' must be a type predicate. + static { + const superisArray = super.isArray; + const customIsArray = (arg)=> superisArray(arg); + this.isArray = customIsArray; + } + } + + ElementsArray.isArray(new ElementsArray()); \ No newline at end of file diff --git a/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.js b/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.js new file mode 100644 index 00000000000..5d25a1a9e49 --- /dev/null +++ b/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.js @@ -0,0 +1,73 @@ +//// [a.js] +class Thing { + static { + this.doSomething = () => {}; + } +} + +Thing.doSomething(); + +// GH#46468 +class ElementsArray extends Array { + static { + const superisArray = super.isArray; + const customIsArray = (arg)=> superisArray(arg); + this.isArray = customIsArray; + } +} + +ElementsArray.isArray(new ElementsArray()); + +//// [a.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var _a, _b; +var _this = this; +var Thing = /** @class */ (function () { + function Thing() { + } + return Thing; +}()); +_a = Thing; +(function () { + _a.doSomething = function () { }; +})(); +Thing.doSomething(); +// GH#46468 +var ElementsArray = /** @class */ (function (_super) { + __extends(ElementsArray, _super); + function ElementsArray() { + return _super !== null && _super.apply(this, arguments) || this; + } + return ElementsArray; +}(Array)); +_b = ElementsArray; +(function () { + var superisArray = _super.isArray; + var customIsArray = function (arg) { return superisArray(arg); }; + _b.isArray = customIsArray; +})(); +ElementsArray.isArray(new ElementsArray()); + + +//// [a.d.ts] +declare class Thing { +} +declare class ElementsArray extends Array { + constructor(arrayLength?: number); + constructor(arrayLength: number); + constructor(...items: any[]); +} diff --git a/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.symbols b/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.symbols new file mode 100644 index 00000000000..51d648a9ed7 --- /dev/null +++ b/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.symbols @@ -0,0 +1,49 @@ +=== /src/a.js === +class Thing { +>Thing : Symbol(Thing, Decl(a.js, 0, 0)) + + static { + this.doSomething = () => {}; +>this.doSomething : Symbol(Thing.doSomething, Decl(a.js, 1, 12)) +>this : Symbol(Thing, Decl(a.js, 0, 0)) +>doSomething : Symbol(Thing.doSomething, Decl(a.js, 1, 12)) + } +} + +Thing.doSomething(); +>Thing.doSomething : Symbol(Thing.doSomething, Decl(a.js, 1, 12)) +>Thing : Symbol(Thing, Decl(a.js, 0, 0)) +>doSomething : Symbol(Thing.doSomething, Decl(a.js, 1, 12)) + +// GH#46468 +class ElementsArray extends Array { +>ElementsArray : Symbol(ElementsArray, Decl(a.js, 6, 20)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + static { + const superisArray = super.isArray; +>superisArray : Symbol(superisArray, Decl(a.js, 11, 13)) +>super.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --)) +>super : Symbol(ArrayConstructor, Decl(lib.es5.d.ts, --, --)) +>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --)) + + const customIsArray = (arg)=> superisArray(arg); +>customIsArray : Symbol(customIsArray, Decl(a.js, 12, 13)) +>arg : Symbol(arg, Decl(a.js, 12, 31)) +>superisArray : Symbol(superisArray, Decl(a.js, 11, 13)) +>arg : Symbol(arg, Decl(a.js, 12, 31)) + + this.isArray = customIsArray; +>this.isArray : Symbol(ElementsArray.isArray, Decl(a.js, 12, 56)) +>this : Symbol(ElementsArray, Decl(a.js, 6, 20)) +>isArray : Symbol(ElementsArray.isArray, Decl(a.js, 12, 56)) +>customIsArray : Symbol(customIsArray, Decl(a.js, 12, 13)) + } +} + +ElementsArray.isArray(new ElementsArray()); +>ElementsArray.isArray : Symbol(ElementsArray.isArray, Decl(a.js, 12, 56)) +>ElementsArray : Symbol(ElementsArray, Decl(a.js, 6, 20)) +>isArray : Symbol(ElementsArray.isArray, Decl(a.js, 12, 56)) +>ElementsArray : Symbol(ElementsArray, Decl(a.js, 6, 20)) + diff --git a/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.types b/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.types new file mode 100644 index 00000000000..bbb41f4ea47 --- /dev/null +++ b/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.types @@ -0,0 +1,57 @@ +=== /src/a.js === +class Thing { +>Thing : Thing + + static { + this.doSomething = () => {}; +>this.doSomething = () => {} : () => void +>this.doSomething : () => void +>this : typeof Thing +>doSomething : () => void +>() => {} : () => void + } +} + +Thing.doSomething(); +>Thing.doSomething() : void +>Thing.doSomething : () => void +>Thing : typeof Thing +>doSomething : () => void + +// GH#46468 +class ElementsArray extends Array { +>ElementsArray : ElementsArray +>Array : any[] + + static { + const superisArray = super.isArray; +>superisArray : (arg: any) => arg is any[] +>super.isArray : (arg: any) => arg is any[] +>super : ArrayConstructor +>isArray : (arg: any) => arg is any[] + + const customIsArray = (arg)=> superisArray(arg); +>customIsArray : (arg: any) => boolean +>(arg)=> superisArray(arg) : (arg: any) => boolean +>arg : any +>superisArray(arg) : boolean +>superisArray : (arg: any) => arg is any[] +>arg : any + + this.isArray = customIsArray; +>this.isArray = customIsArray : (arg: any) => boolean +>this.isArray : (arg: any) => boolean +>this : typeof ElementsArray +>isArray : (arg: any) => boolean +>customIsArray : (arg: any) => boolean + } +} + +ElementsArray.isArray(new ElementsArray()); +>ElementsArray.isArray(new ElementsArray()) : boolean +>ElementsArray.isArray : (arg: any) => boolean +>ElementsArray : typeof ElementsArray +>isArray : (arg: any) => boolean +>new ElementsArray() : ElementsArray +>ElementsArray : typeof ElementsArray + diff --git a/tests/cases/compiler/javascriptThisAssignmentInStaticBlock.ts b/tests/cases/compiler/javascriptThisAssignmentInStaticBlock.ts new file mode 100644 index 00000000000..f86508dc986 --- /dev/null +++ b/tests/cases/compiler/javascriptThisAssignmentInStaticBlock.ts @@ -0,0 +1,24 @@ +// @allowJs: true +// @checkJs: true +// @declaration: true +// @outDir: /out/ +// @filename: /src/a.js + +class Thing { + static { + this.doSomething = () => {}; + } +} + +Thing.doSomething(); + +// GH#46468 +class ElementsArray extends Array { + static { + const superisArray = super.isArray; + const customIsArray = (arg)=> superisArray(arg); + this.isArray = customIsArray; + } +} + +ElementsArray.isArray(new ElementsArray()); \ No newline at end of file From 907fc72db426667fff4047a7a0494c6424d5052f Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Fri, 22 Oct 2021 16:09:32 -0700 Subject: [PATCH 47/60] Fix auto import crash on weird JS aliasing (#46490) * Fix auto import crash on weird JS aliasing * Comment up the weird test * Fix setting members on union/intersection type, happens later --- src/compiler/checker.ts | 21 ++++++- src/services/codefixes/importFixes.ts | 12 ++-- src/services/completions.ts | 4 +- src/services/exportInfoMap.ts | 16 ++++-- ...letionsImport_jsModuleExportsAssignment.ts | 57 +++++++++++++++++++ 5 files changed, 93 insertions(+), 17 deletions(-) create mode 100644 tests/cases/fourslash/server/completionsImport_jsModuleExportsAssignment.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 75df0d653be..217eb47cfa6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3656,8 +3656,8 @@ namespace ts { if (exportEquals !== moduleSymbol) { const type = getTypeOfSymbol(exportEquals); if (shouldTreatPropertiesOfExternalModuleAsExports(type)) { - getPropertiesOfType(type).forEach(symbol => { - cb(symbol, symbol.escapedName); + forEachPropertyOfType(type, (symbol, escapedName) => { + cb(symbol, escapedName); }); } } @@ -4033,13 +4033,17 @@ namespace ts { function getNamedMembers(members: SymbolTable): Symbol[] { let result: Symbol[] | undefined; members.forEach((symbol, id) => { - if (!isReservedMemberName(id) && symbolIsValue(symbol)) { + if (isNamedMember(symbol, id)) { (result || (result = [])).push(symbol); } }); return result || emptyArray; } + function isNamedMember(member: Symbol, escapedName: __String) { + return !isReservedMemberName(escapedName) && symbolIsValue(member); + } + function getNamedOrIndexSignatureMembers(members: SymbolTable): Symbol[] { const result = getNamedMembers(members); const index = getIndexSymbolFromSymbolTable(members); @@ -11571,6 +11575,17 @@ namespace ts { getPropertiesOfObjectType(type); } + function forEachPropertyOfType(type: Type, action: (symbol: Symbol, escapedName: __String) => void): void { + type = getReducedApparentType(type); + if (type.flags & TypeFlags.StructuredType) { + resolveStructuredTypeMembers(type as StructuredType).members.forEach((symbol, escapedName) => { + if (isNamedMember(symbol, escapedName)) { + action(symbol, escapedName); + } + }); + } + } + function isTypeInvalidDueToUnionDiscriminant(contextualType: Type, obj: ObjectLiteralExpression | JsxAttributes): boolean { const list = obj.properties as NodeArray; return list.some(property => { diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 89b673097b7..0b95a88b930 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -268,7 +268,7 @@ namespace ts.codefix { } export function getImportCompletionAction( - exportedSymbol: Symbol, + targetSymbol: Symbol, moduleSymbol: Symbol, sourceFile: SourceFile, symbolName: string, @@ -280,8 +280,8 @@ namespace ts.codefix { ): { readonly moduleSpecifier: string, readonly codeAction: CodeAction } { const compilerOptions = program.getCompilerOptions(); const exportInfos = pathIsBareSpecifier(stripQuotes(moduleSymbol.name)) - ? [getSymbolExportInfoForSymbol(exportedSymbol, moduleSymbol, program, host)] - : getAllReExportingModules(sourceFile, exportedSymbol, moduleSymbol, symbolName, host, program, preferences, /*useAutoImportProvider*/ true); + ? [getSymbolExportInfoForSymbol(targetSymbol, moduleSymbol, program, host)] + : getAllReExportingModules(sourceFile, targetSymbol, moduleSymbol, symbolName, host, program, preferences, /*useAutoImportProvider*/ true); const useRequire = shouldUseRequire(sourceFile, program); const isValidTypeOnlyUseSite = isValidTypeOnlyAliasUseSite(getTokenAtPosition(sourceFile, position)); const fix = Debug.checkDefined(getImportFixForSymbol(sourceFile, exportInfos, moduleSymbol, symbolName, program, position, isValidTypeOnlyUseSite, useRequire, host, preferences)); @@ -326,7 +326,7 @@ namespace ts.codefix { } } - function getAllReExportingModules(importingFile: SourceFile, exportedSymbol: Symbol, exportingModuleSymbol: Symbol, symbolName: string, host: LanguageServiceHost, program: Program, preferences: UserPreferences, useAutoImportProvider: boolean): readonly SymbolExportInfo[] { + function getAllReExportingModules(importingFile: SourceFile, targetSymbol: Symbol, exportingModuleSymbol: Symbol, symbolName: string, host: LanguageServiceHost, program: Program, preferences: UserPreferences, useAutoImportProvider: boolean): readonly SymbolExportInfo[] { const result: SymbolExportInfo[] = []; const compilerOptions = program.getCompilerOptions(); const getModuleSpecifierResolutionHost = memoizeOne((isFromPackageJson: boolean) => { @@ -341,12 +341,12 @@ namespace ts.codefix { } const defaultInfo = getDefaultLikeExportInfo(moduleSymbol, checker, compilerOptions); - if (defaultInfo && (defaultInfo.name === symbolName || moduleSymbolToValidIdentifier(moduleSymbol, getEmitScriptTarget(compilerOptions)) === symbolName) && skipAlias(defaultInfo.symbol, checker) === exportedSymbol && isImportable(program, moduleFile, isFromPackageJson)) { + if (defaultInfo && (defaultInfo.name === symbolName || moduleSymbolToValidIdentifier(moduleSymbol, getEmitScriptTarget(compilerOptions)) === symbolName) && skipAlias(defaultInfo.symbol, checker) === targetSymbol && isImportable(program, moduleFile, isFromPackageJson)) { result.push({ symbol: defaultInfo.symbol, moduleSymbol, moduleFileName: moduleFile?.fileName, exportKind: defaultInfo.exportKind, targetFlags: skipAlias(defaultInfo.symbol, checker).flags, isFromPackageJson }); } for (const exported of checker.getExportsAndPropertiesOfModule(moduleSymbol)) { - if (exported.name === symbolName && skipAlias(exported, checker) === exportedSymbol && isImportable(program, moduleFile, isFromPackageJson)) { + if (exported.name === symbolName && checker.getMergedSymbol(skipAlias(exported, checker)) === targetSymbol && isImportable(program, moduleFile, isFromPackageJson)) { result.push({ symbol: exported, moduleSymbol, moduleFileName: moduleFile?.fileName, exportKind: ExportKind.Named, targetFlags: skipAlias(exported, checker).flags, isFromPackageJson }); } } diff --git a/src/services/completions.ts b/src/services/completions.ts index 18cb2ed9b79..a30da4071c5 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1183,9 +1183,9 @@ namespace ts.Completions { const checker = origin.isFromPackageJson ? host.getPackageJsonAutoImportProvider!()!.getTypeChecker() : program.getTypeChecker(); const { moduleSymbol } = origin; - const exportedSymbol = checker.getMergedSymbol(skipAlias(symbol.exportSymbol || symbol, checker)); + const targetSymbol = checker.getMergedSymbol(skipAlias(symbol.exportSymbol || symbol, checker)); const { moduleSpecifier, codeAction } = codefix.getImportCompletionAction( - exportedSymbol, + targetSymbol, moduleSymbol, sourceFile, getNameForExportedSymbol(symbol, getEmitScriptTarget(compilerOptions)), diff --git a/src/services/exportInfoMap.ts b/src/services/exportInfoMap.ts index 4d49f631174..2a43faf3269 100644 --- a/src/services/exportInfoMap.ts +++ b/src/services/exportInfoMap.ts @@ -79,10 +79,14 @@ namespace ts { } const isDefault = exportKind === ExportKind.Default; const namedSymbol = isDefault && getLocalSymbolForExportDefault(symbol) || symbol; - // A re-export merged with an export from a module augmentation can result in `symbol` - // being an external module symbol; the name it is re-exported by will be `symbolTableKey` - // (which comes from the keys of `moduleSymbol.exports`.) - const importedName = isExternalModuleSymbol(namedSymbol) + // 1. A named export must be imported by its key in `moduleSymbol.exports` or `moduleSymbol.members`. + // 2. A re-export merged with an export from a module augmentation can result in `symbol` + // being an external module symbol; the name it is re-exported by will be `symbolTableKey` + // (which comes from the keys of `moduleSymbol.exports`.) + // 3. Otherwise, we have a default/namespace import that can be imported by any name, and + // `symbolTableKey` will be something undesirable like `export=` or `default`, so we try to + // get a better name. + const importedName = exportKind === ExportKind.Named || isExternalModuleSymbol(namedSymbol) ? unescapeLeadingUnderscores(symbolTableKey) : getNameForExportedSymbol(namedSymbol, scriptTarget); const moduleName = stripQuotes(moduleSymbol.name); @@ -321,7 +325,7 @@ namespace ts { let moduleCount = 0; forEachExternalModuleToImportFrom(program, host, /*useAutoImportProvider*/ true, (moduleSymbol, moduleFile, program, isFromPackageJson) => { if (++moduleCount % 100 === 0) cancellationToken?.throwIfCancellationRequested(); - const seenExports = new Map(); + const seenExports = new Map<__String, true>(); const checker = program.getTypeChecker(); const defaultInfo = getDefaultLikeExportInfo(moduleSymbol, checker, compilerOptions); // Note: I think we shouldn't actually see resolved module symbols here, but weird merges @@ -339,7 +343,7 @@ namespace ts { checker); } checker.forEachExportAndPropertyOfModule(moduleSymbol, (exported, key) => { - if (exported !== defaultInfo?.symbol && isImportableSymbol(exported, checker) && addToSeen(seenExports, exported)) { + if (exported !== defaultInfo?.symbol && isImportableSymbol(exported, checker) && addToSeen(seenExports, key)) { cache.add( importingFile.path, exported, diff --git a/tests/cases/fourslash/server/completionsImport_jsModuleExportsAssignment.ts b/tests/cases/fourslash/server/completionsImport_jsModuleExportsAssignment.ts new file mode 100644 index 00000000000..37345dcc3e9 --- /dev/null +++ b/tests/cases/fourslash/server/completionsImport_jsModuleExportsAssignment.ts @@ -0,0 +1,57 @@ +/// + +// @Filename: /tsconfig.json +//// { "compilerOptions": { "module": "commonjs", "allowJs": true } } + +// @Filename: /third_party/marked/src/defaults.js +//// function getDefaults() { +//// return { +//// baseUrl: null, +//// }; +//// } +//// +//// function changeDefaults(newDefaults) { +//// module.exports.defaults = newDefaults; +//// } +//// +//// module.exports = { +//// defaults: getDefaults(), +//// getDefaults, +//// changeDefaults +//// }; + +// @Filename: /index.ts +//// /**/ + +format.setOption("newLineCharacter", "\n") +goTo.marker(""); + +// Create the exportInfoMap +verify.completions({ marker: "", preferences: { includeCompletionsForModuleExports: true } }); + +// Create a new program and reuse the exportInfoMap from the last request +edit.insert("d"); +verify.completions({ + marker: "", + excludes: ["newDefaults"], + includes: [{ + name: "defaults", + source: "/third_party/marked/src/defaults", + hasAction: true, + sortText: completion.SortText.AutoImportSuggestions, + }], + preferences: { includeCompletionsForModuleExports: true } +}); + +verify.applyCodeActionFromCompletion("", { + name: "defaults", + source: "/third_party/marked/src/defaults", + description: `Import 'defaults' from module "./third_party/marked/src/defaults"`, + data: { + exportName: "defaults", + fileName: "/third_party/marked/src/defaults.js", + }, + newFileContent: `import { defaults } from "./third_party/marked/src/defaults"; + +d` +}); From cb07891d19cf714262a35ad9753f238e4225012c Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Sat, 23 Oct 2021 06:06:04 +0000 Subject: [PATCH 48/60] Update package-lock.json --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 06751eebd71..d333de4a61e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -676,9 +676,9 @@ "dev": true }, "@types/node": { - "version": "16.11.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.2.tgz", - "integrity": "sha512-w34LtBB0OkDTs19FQHXy4Ig/TOXI4zqvXS2Kk1PAsRKZ0I+nik7LlMYxckW0tSNGtvWmzB+mrCTbuEjuB9DVsw==", + "version": "16.11.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.4.tgz", + "integrity": "sha512-TMgXmy0v2xWyuCSCJM6NCna2snndD8yvQF67J29ipdzMcsPa9u+o0tjF5+EQNdhcuZplYuouYqpc4zcd5I6amQ==", "dev": true }, "@types/node-fetch": { From 1055119164edf0a4d4da403fa7ee09d088a2b606 Mon Sep 17 00:00:00 2001 From: csigs Date: Sat, 23 Oct 2021 10:14:28 -0700 Subject: [PATCH 49/60] LEGO: Merge pull request 46496 LEGO: Merge pull request 46496 --- .../diagnosticMessages.generated.json.lcl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl index 58e658a2be2..d2de163f23d 100644 --- a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -15267,6 +15267,15 @@ + + + + + + + + + From c2a4bda133d84b5d4c7dee1931fc5443449f1d00 Mon Sep 17 00:00:00 2001 From: csigs Date: Sat, 23 Oct 2021 22:14:29 -0700 Subject: [PATCH 50/60] LEGO: Merge pull request 46501 LEGO: Merge pull request 46501 --- .../diagnosticMessages.generated.json.lcl | 9 +++++++++ .../diagnosticMessages.generated.json.lcl | 9 +++++++++ .../diagnosticMessages.generated.json.lcl | 9 +++++++++ .../diagnosticMessages.generated.json.lcl | 9 +++++++++ 4 files changed, 36 insertions(+) diff --git a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl index c4706da3c4b..1bfd3232d00 100644 --- a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -15267,6 +15267,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl index bf8ec5fba57..7b6010b72cb 100644 --- a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -15279,6 +15279,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl index adfe7311458..9150f261f70 100644 --- a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -15257,6 +15257,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl index 2d66b99d92e..b1da5272afa 100644 --- a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -15266,6 +15266,15 @@ + + + + + + + + + From dd89e06520e7b3f2dada1f207c11191e8db6795f Mon Sep 17 00:00:00 2001 From: csigs Date: Sun, 24 Oct 2021 04:13:27 -0700 Subject: [PATCH 51/60] LEGO: Merge pull request 46502 LEGO: Merge pull request 46502 --- .../diagnosticMessages.generated.json.lcl | 9 +++++++++ .../diagnosticMessages.generated.json.lcl | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl index b9d0acf6088..54a7bb72719 100644 --- a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -15267,6 +15267,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl index 4c5e403fd19..0c3403c75a5 100644 --- a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -15267,6 +15267,15 @@ + + + + + + + + + From e88e5961261866f52f8781495f6d712efe201008 Mon Sep 17 00:00:00 2001 From: csigs Date: Sun, 24 Oct 2021 10:14:16 -0700 Subject: [PATCH 52/60] LEGO: Merge pull request 46504 LEGO: Merge pull request 46504 --- .../diagnosticMessages.generated.json.lcl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 44acf022a20..5445462ae5a 100644 --- a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -15260,6 +15260,15 @@ + + + + + + + + + From 7799113e9a94ece58268d67108d25834acbda7f1 Mon Sep 17 00:00:00 2001 From: csigs Date: Sun, 24 Oct 2021 22:14:38 -0700 Subject: [PATCH 53/60] LEGO: Merge pull request 46510 LEGO: Merge pull request 46510 --- .../diagnosticMessages.generated.json.lcl | 9 +++++++++ .../diagnosticMessages.generated.json.lcl | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl index 76c05cb54bc..f44f5d6f84c 100644 --- a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -15267,6 +15267,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 74d9747f5b0..89cb0588362 100644 --- a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -15254,6 +15254,15 @@ + + + + + + + + + From 61f5ceb8322ada7e24ba4ac14491248eb7bd202e Mon Sep 17 00:00:00 2001 From: Adam Burgess Date: Mon, 25 Oct 2021 17:49:31 +1100 Subject: [PATCH 54/60] Fix isNewIdentifierLocation after generator (#46491) --- src/services/completions.ts | 3 ++ .../completionsGeneratorMethodDeclaration.ts | 28 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 tests/cases/fourslash/completionsGeneratorMethodDeclaration.ts diff --git a/src/services/completions.ts b/src/services/completions.ts index a30da4071c5..2f5f0323a9a 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -2258,6 +2258,9 @@ namespace ts.Completions { case SyntaxKind.AsyncKeyword: return containingNodeKind === SyntaxKind.MethodDeclaration // const obj = { async c|() || containingNodeKind === SyntaxKind.ShorthandPropertyAssignment; // const obj = { async c| + + case SyntaxKind.AsteriskToken: + return containingNodeKind === SyntaxKind.MethodDeclaration; // const obj = { * c| } if (isClassMemberCompletionKeyword(tokenKind)) { diff --git a/tests/cases/fourslash/completionsGeneratorMethodDeclaration.ts b/tests/cases/fourslash/completionsGeneratorMethodDeclaration.ts new file mode 100644 index 00000000000..d4c6ad99e8e --- /dev/null +++ b/tests/cases/fourslash/completionsGeneratorMethodDeclaration.ts @@ -0,0 +1,28 @@ +/// + +//// const obj = { +//// a() {}, +//// * b/*1*/ +//// }; +//// const obj2 = { +//// * /*2*/ +//// }; +//// const obj3 = { +//// async * /*3*/ +//// }; +//// class Foo { +//// * b/*4*/ +//// } +//// class Foo2 { +//// * /*5*/ +//// } +//// class Bar { +//// static * b/*6*/ +//// } + +test.markerNames().forEach(marker => { + verify.completions({ + marker, + isNewIdentifierLocation: true + }); +}); From 6b6665e6ae3b97e69d687412ec8f9b13c02547c7 Mon Sep 17 00:00:00 2001 From: csigs Date: Mon, 25 Oct 2021 10:13:29 -0700 Subject: [PATCH 55/60] LEGO: Merge pull request 46520 LEGO: Merge pull request 46520 --- .../diagnosticMessages.generated.json.lcl | 9 +++++++++ .../diagnosticMessages.generated.json.lcl | 9 +++++++++ .../diagnosticMessages.generated.json.lcl | 9 +++++++++ 3 files changed, 27 insertions(+) diff --git a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl index cf6c498e219..4b609c91e38 100644 --- a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -15276,6 +15276,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl index 0ba3b3a31d1..8a20f065c67 100644 --- a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -15261,6 +15261,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl index 53a4056ae76..404eafcaea7 100644 --- a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -15279,6 +15279,15 @@ + + + + + + + + + From 3519af0bab9c8b7b4ca612da0cb7b5693f28713a Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 25 Oct 2021 10:53:41 -0700 Subject: [PATCH 56/60] Fix crash pulling on global types before they're initialized (#46471) * Add failing test * Dumb fix * Compute error message info more lazily * One more laziness --- src/compiler/checker.ts | 39 ++++++++++++++----- .../importEqualsError45874.errors.txt | 15 +++++++ .../reference/importEqualsError45874.js | 21 ++++++++++ .../reference/importEqualsError45874.symbols | 18 +++++++++ .../reference/importEqualsError45874.types | 22 +++++++++++ .../cases/compiler/importEqualsError45874.ts | 9 +++++ 6 files changed, 114 insertions(+), 10 deletions(-) create mode 100644 tests/baselines/reference/importEqualsError45874.errors.txt create mode 100644 tests/baselines/reference/importEqualsError45874.js create mode 100644 tests/baselines/reference/importEqualsError45874.symbols create mode 100644 tests/baselines/reference/importEqualsError45874.types create mode 100644 tests/cases/compiler/importEqualsError45874.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 217eb47cfa6..80122a58463 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3275,21 +3275,40 @@ namespace ts { const namespaceName = getFullyQualifiedName(namespace); const declarationName = declarationNameToString(right); const suggestionForNonexistentModule = getSuggestedSymbolForNonexistentModule(right, namespace); - const exportedTypeSymbol = getMergedSymbol(getSymbol(getExportsOfSymbol(namespace), right.escapedText, SymbolFlags.Type)); - const containingQualifiedName = isQualifiedName(name) && getContainingQualifiedNameNode(name); - const canSuggestTypeof = containingQualifiedName && !isTypeOfExpression(containingQualifiedName.parent) && tryGetQualifiedNameAsValue(containingQualifiedName); if (suggestionForNonexistentModule) { error(right, Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, namespaceName, declarationName, symbolToString(suggestionForNonexistentModule)); + return undefined; } - else if (canSuggestTypeof) { - error(containingQualifiedName, Diagnostics._0_refers_to_a_value_but_is_being_used_as_a_type_here_Did_you_mean_typeof_0, entityNameToString(containingQualifiedName)); + + const containingQualifiedName = isQualifiedName(name) && getContainingQualifiedNameNode(name); + const canSuggestTypeof = globalObjectType // <-- can't pull on types if global types aren't initialized yet + && (meaning & SymbolFlags.Type) + && containingQualifiedName + && !isTypeOfExpression(containingQualifiedName.parent) + && tryGetQualifiedNameAsValue(containingQualifiedName); + if (canSuggestTypeof) { + error( + containingQualifiedName, + Diagnostics._0_refers_to_a_value_but_is_being_used_as_a_type_here_Did_you_mean_typeof_0, + entityNameToString(containingQualifiedName) + ); + return undefined; } - else if (meaning & SymbolFlags.Namespace && exportedTypeSymbol && isQualifiedName(name.parent)) { - error(name.parent.right, Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1, symbolToString(exportedTypeSymbol), unescapeLeadingUnderscores(name.parent.right.escapedText)); - } - else { - error(right, Diagnostics.Namespace_0_has_no_exported_member_1, namespaceName, declarationName); + + if (meaning & SymbolFlags.Namespace && isQualifiedName(name.parent)) { + const exportedTypeSymbol = getMergedSymbol(getSymbol(getExportsOfSymbol(namespace), right.escapedText, SymbolFlags.Type)); + if (exportedTypeSymbol) { + error( + name.parent.right, + Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1, + symbolToString(exportedTypeSymbol), + unescapeLeadingUnderscores(name.parent.right.escapedText) + ); + return undefined; + } } + + error(right, Diagnostics.Namespace_0_has_no_exported_member_1, namespaceName, declarationName); } return undefined; } diff --git a/tests/baselines/reference/importEqualsError45874.errors.txt b/tests/baselines/reference/importEqualsError45874.errors.txt new file mode 100644 index 00000000000..82718c71c3f --- /dev/null +++ b/tests/baselines/reference/importEqualsError45874.errors.txt @@ -0,0 +1,15 @@ +/globals.ts(5,22): error TS2694: Namespace 'globals' has no exported member 'toString'. + + +==== /globals.ts (1 errors) ==== + namespace globals { + export type Foo = {}; + export const Bar = {}; + } + import Foo = globals.toString.Blah; + ~~~~~~~~ +!!! error TS2694: Namespace 'globals' has no exported member 'toString'. + +==== /index.ts (0 errors) ==== + const Foo = {}; + \ No newline at end of file diff --git a/tests/baselines/reference/importEqualsError45874.js b/tests/baselines/reference/importEqualsError45874.js new file mode 100644 index 00000000000..7f153fe422f --- /dev/null +++ b/tests/baselines/reference/importEqualsError45874.js @@ -0,0 +1,21 @@ +//// [tests/cases/compiler/importEqualsError45874.ts] //// + +//// [globals.ts] +namespace globals { + export type Foo = {}; + export const Bar = {}; +} +import Foo = globals.toString.Blah; + +//// [index.ts] +const Foo = {}; + + +//// [globals.js] +var globals; +(function (globals) { + globals.Bar = {}; +})(globals || (globals = {})); +var Foo = globals.toString.Blah; +//// [index.js] +var Foo = {}; diff --git a/tests/baselines/reference/importEqualsError45874.symbols b/tests/baselines/reference/importEqualsError45874.symbols new file mode 100644 index 00000000000..59fb03ce510 --- /dev/null +++ b/tests/baselines/reference/importEqualsError45874.symbols @@ -0,0 +1,18 @@ +=== /globals.ts === +namespace globals { +>globals : Symbol(globals, Decl(globals.ts, 0, 0)) + + export type Foo = {}; +>Foo : Symbol(Foo, Decl(globals.ts, 0, 19)) + + export const Bar = {}; +>Bar : Symbol(Bar, Decl(globals.ts, 2, 14)) +} +import Foo = globals.toString.Blah; +>Foo : Symbol(Foo, Decl(globals.ts, 3, 1)) +>globals : Symbol(globals, Decl(globals.ts, 0, 0)) + +=== /index.ts === +const Foo = {}; +>Foo : Symbol(Foo, Decl(index.ts, 0, 5)) + diff --git a/tests/baselines/reference/importEqualsError45874.types b/tests/baselines/reference/importEqualsError45874.types new file mode 100644 index 00000000000..9e3c9c2945e --- /dev/null +++ b/tests/baselines/reference/importEqualsError45874.types @@ -0,0 +1,22 @@ +=== /globals.ts === +namespace globals { +>globals : typeof globals + + export type Foo = {}; +>Foo : Foo + + export const Bar = {}; +>Bar : {} +>{} : {} +} +import Foo = globals.toString.Blah; +>Foo : any +>globals : typeof globals +>toString : any +>Blah : any + +=== /index.ts === +const Foo = {}; +>Foo : {} +>{} : {} + diff --git a/tests/cases/compiler/importEqualsError45874.ts b/tests/cases/compiler/importEqualsError45874.ts new file mode 100644 index 00000000000..5bb214ee22a --- /dev/null +++ b/tests/cases/compiler/importEqualsError45874.ts @@ -0,0 +1,9 @@ +// @Filename: /globals.ts +namespace globals { + export type Foo = {}; + export const Bar = {}; +} +import Foo = globals.toString.Blah; + +// @Filename: /index.ts +const Foo = {}; From e1a2c2c5a96760f841e461195ec7ccc59621431a Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Tue, 26 Oct 2021 06:07:59 +0000 Subject: [PATCH 57/60] Update package-lock.json --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d333de4a61e..9edbe33374d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -676,9 +676,9 @@ "dev": true }, "@types/node": { - "version": "16.11.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.4.tgz", - "integrity": "sha512-TMgXmy0v2xWyuCSCJM6NCna2snndD8yvQF67J29ipdzMcsPa9u+o0tjF5+EQNdhcuZplYuouYqpc4zcd5I6amQ==", + "version": "16.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz", + "integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==", "dev": true }, "@types/node-fetch": { From 658764e4993d729faac86edd3fd606135144e263 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 26 Oct 2021 09:34:15 -0700 Subject: [PATCH 58/60] Bypass caching in removeStringLiteralsMatchedByTemplateLiterals (#46525) * Bypass caching in removeStringLiteralsMatchedByTemplateLiterals * Add regression test --- src/compiler/checker.ts | 12 +- .../templateLiteralTypes1.errors.txt | 22 +- .../reference/templateLiteralTypes1.js | 259 ++---------------- .../reference/templateLiteralTypes1.symbols | 36 +++ .../reference/templateLiteralTypes1.types | 25 ++ .../types/literal/templateLiteralTypes1.ts | 17 ++ 6 files changed, 129 insertions(+), 242 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 80122a58463..a97e96bff26 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14203,13 +14203,13 @@ namespace ts { } function removeStringLiteralsMatchedByTemplateLiterals(types: Type[]) { - const templates = filter(types, isPatternLiteralType); + const templates = filter(types, isPatternLiteralType) as TemplateLiteralType[]; if (templates.length) { let i = types.length; while (i > 0) { i--; const t = types[i]; - if (t.flags & TypeFlags.StringLiteral && some(templates, template => isTypeSubtypeOf(t, template))) { + if (t.flags & TypeFlags.StringLiteral && some(templates, template => isTypeMatchedByTemplateLiteralType(t, template))) { orderedRemoveItemAt(types, i); } } @@ -19090,8 +19090,7 @@ namespace ts { // For example, `foo-${number}` is related to `foo-${string}` even though number isn't related to string. instantiateType(source, makeFunctionTypeMapper(reportUnreliableMarkers)); } - const result = inferTypesFromTemplateLiteralType(source, target as TemplateLiteralType); - if (result && every(result, (r, i) => isValidTypeForTemplateLiteralPlaceholder(r, (target as TemplateLiteralType).types[i]))) { + if (isTypeMatchedByTemplateLiteralType(source, target as TemplateLiteralType)) { return Ternary.True; } } @@ -21561,6 +21560,11 @@ namespace ts { undefined; } + function isTypeMatchedByTemplateLiteralType(source: Type, target: TemplateLiteralType): boolean { + const inferences = inferTypesFromTemplateLiteralType(source, target); + return !!inferences && every(inferences, (r, i) => isValidTypeForTemplateLiteralPlaceholder(r, target.types[i])); + } + function getStringLikeTypeForType(type: Type) { return type.flags & (TypeFlags.Any | TypeFlags.StringLike) ? type : getTemplateLiteralType(["", ""], [type]); } diff --git a/tests/baselines/reference/templateLiteralTypes1.errors.txt b/tests/baselines/reference/templateLiteralTypes1.errors.txt index dae7b7009fd..e586a1678eb 100644 --- a/tests/baselines/reference/templateLiteralTypes1.errors.txt +++ b/tests/baselines/reference/templateLiteralTypes1.errors.txt @@ -6,9 +6,10 @@ tests/cases/conformance/types/literal/templateLiteralTypes1.ts(165,15): error TS tests/cases/conformance/types/literal/templateLiteralTypes1.ts(197,16): error TS2590: Expression produces a union type that is too complex to represent. tests/cases/conformance/types/literal/templateLiteralTypes1.ts(201,16): error TS2590: Expression produces a union type that is too complex to represent. tests/cases/conformance/types/literal/templateLiteralTypes1.ts(205,16): error TS2590: Expression produces a union type that is too complex to represent. +tests/cases/conformance/types/literal/templateLiteralTypes1.ts(251,7): error TS2590: Expression produces a union type that is too complex to represent. -==== tests/cases/conformance/types/literal/templateLiteralTypes1.ts (6 errors) ==== +==== tests/cases/conformance/types/literal/templateLiteralTypes1.ts (7 errors) ==== // Template types example from #12754 const createScopedActionType = (scope: S) => (type: T) => `${scope}/${type}` as `${S}/${T}`; @@ -259,4 +260,23 @@ tests/cases/conformance/types/literal/templateLiteralTypes1.ts(205,16): error TS } as const; let make = getProp2(obj2, 'cars.1.make'); // 'Trabant' + + // Repro from #46480 + + export type Spacing = + | `0` + | `${number}px` + | `${number}rem` + | `s${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20}`; + + const spacing: Spacing = "s12" + + export type SpacingShorthand = + | `${Spacing} ${Spacing}` + | `${Spacing} ${Spacing} ${Spacing}` + | `${Spacing} ${Spacing} ${Spacing} ${Spacing}`; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2590: Expression produces a union type that is too complex to represent. + + const test1: SpacingShorthand = "0 0 0"; \ No newline at end of file diff --git a/tests/baselines/reference/templateLiteralTypes1.js b/tests/baselines/reference/templateLiteralTypes1.js index b8f7d0f4066..d212909fd7d 100644 --- a/tests/baselines/reference/templateLiteralTypes1.js +++ b/tests/baselines/reference/templateLiteralTypes1.js @@ -235,11 +235,29 @@ const obj2 = { } as const; let make = getProp2(obj2, 'cars.1.make'); // 'Trabant' + +// Repro from #46480 + +export type Spacing = + | `0` + | `${number}px` + | `${number}rem` + | `s${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20}`; + +const spacing: Spacing = "s12" + +export type SpacingShorthand = + | `${Spacing} ${Spacing}` + | `${Spacing} ${Spacing} ${Spacing}` + | `${Spacing} ${Spacing} ${Spacing} ${Spacing}`; + +const test1: SpacingShorthand = "0 0 0"; //// [templateLiteralTypes1.js] "use strict"; // Template types example from #12754 +exports.__esModule = true; var createScopedActionType = function (scope) { return function (type) { return "".concat(scope, "/").concat(type); }; }; var createActionInMyScope = createScopedActionType("MyScope"); // (type: T) => `MyScope/${T}` var MY_ACTION = createActionInMyScope("MY_ACTION"); // 'MyScope/MY_ACTION' @@ -274,243 +292,10 @@ var obj2 = { ] }; var make = getProp2(obj2, 'cars.1.make'); // 'Trabant' +var spacing = "s12"; +var test1 = "0 0 0"; //// [templateLiteralTypes1.d.ts] -declare const createScopedActionType: (scope: S) => (type: T) => `${S}/${T}`; -declare const createActionInMyScope: (type: T) => `MyScope/${T}`; -declare const MY_ACTION: "MyScope/MY_ACTION"; -declare type EventName = `${S}Changed`; -declare type EN1 = EventName<'Foo' | 'Bar' | 'Baz'>; -declare type Loc = `${'top' | 'middle' | 'bottom'}-${'left' | 'center' | 'right'}`; -declare type ToString = `${T}`; -declare type TS1 = ToString<'abc' | 42 | true | -1234n>; -declare type TL1 = `a${T}b${T}c`; -declare type TL2 = TL1<`x${U}y`>; -declare type TL3 = TL2<'o'>; -declare type Cases = `${Uppercase} ${Lowercase} ${Capitalize} ${Uncapitalize}`; -declare type TCA1 = Cases<'bar'>; -declare type TCA2 = Cases<'BAR'>; -declare function test(name: `get${Capitalize}`): void; -declare function fa1(x: T, y: { - [P in keyof T]: T[P]; -}, z: { - [P in keyof T & string as `p_${P}`]: T[P]; -}): void; -declare function fa2(x: { - [P in B as `p_${P}`]: T; -}, y: { - [Q in A as `p_${Q}`]: U; -}): void; -declare type Join = T extends [] ? '' : T extends [string | number | boolean | bigint] ? `${T[0]}` : T extends [string | number | boolean | bigint, ...infer U] ? `${T[0]}${D}${Join}` : string; -declare type TJ1 = Join<[1, 2, 3, 4], '.'>; -declare type TJ2 = Join<['foo', 'bar', 'baz'], '-'>; -declare type TJ3 = Join<[], '.'>; -declare type MatchPair = S extends `[${infer A},${infer B}]` ? [A, B] : unknown; -declare type T20 = MatchPair<'[1,2]'>; -declare type T21 = MatchPair<'[foo,bar]'>; -declare type T22 = MatchPair<' [1,2]'>; -declare type T23 = MatchPair<'[123]'>; -declare type T24 = MatchPair<'[1,2,3,4]'>; -declare type SnakeToCamelCase = S extends `${infer T}_${infer U}` ? `${Lowercase}${SnakeToPascalCase}` : S extends `${infer T}` ? `${Lowercase}` : SnakeToPascalCase; -declare type SnakeToPascalCase = string extends S ? string : S extends `${infer T}_${infer U}` ? `${Capitalize>}${SnakeToPascalCase}` : S extends `${infer T}` ? `${Capitalize>}` : never; -declare type RR0 = SnakeToPascalCase<'hello_world_foo'>; -declare type RR1 = SnakeToPascalCase<'FOO_BAR_BAZ'>; -declare type RR2 = SnakeToCamelCase<'hello_world_foo'>; -declare type RR3 = SnakeToCamelCase<'FOO_BAR_BAZ'>; -declare type FirstTwoAndRest = S extends `${infer A}${infer B}${infer R}` ? [`${A}${B}`, R] : unknown; -declare type T25 = FirstTwoAndRest<'abcde'>; -declare type T26 = FirstTwoAndRest<'ab'>; -declare type T27 = FirstTwoAndRest<'a'>; -declare type HexDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f'; -declare type HexColor = S extends `#${infer R1}${infer R2}${infer G1}${infer G2}${infer B1}${infer B2}` ? [ - R1, - R2, - G1, - G2, - B1, - B2 -] extends [HexDigit, HexDigit, HexDigit, HexDigit, HexDigit, HexDigit] ? S : never : never; -declare type TH1 = HexColor<'#8080FF'>; -declare type TH2 = HexColor<'#80c0ff'>; -declare type TH3 = HexColor<'#8080F'>; -declare type TH4 = HexColor<'#8080FFF'>; -declare type Trim = S extends ` ${infer T}` ? Trim : S extends `${infer T} ` ? Trim : S; -declare type TR1 = Trim<'xx '>; -declare type TR2 = Trim<' xx'>; -declare type TR3 = Trim<' xx '>; -declare type Split = string extends S ? string[] : S extends '' ? [] : S extends `${infer T}${D}${infer U}` ? [T, ...Split] : [ - S -]; -declare type T40 = Split<'foo', '.'>; -declare type T41 = Split<'foo.bar.baz', '.'>; -declare type T42 = Split<'foo.bar', ''>; -declare type T43 = Split; -declare function getProp(obj: T, path: `${P0}.${P1}.${P2}`): T[P0][P1][P2]; -declare function getProp(obj: T, path: `${P0}.${P1}`): T[P0][P1]; -declare function getProp(obj: T, path: P0): T[P0]; -declare function getProp(obj: object, path: string): unknown; -declare let p1: { - readonly b: { - readonly c: 42; - readonly d: "hello"; - }; -}; -declare let p2: { - readonly c: 42; - readonly d: "hello"; -}; -declare let p3: "hello"; -declare type PropType = string extends Path ? unknown : Path extends keyof T ? T[Path] : Path extends `${infer K}.${infer R}` ? K extends keyof T ? PropType : unknown : unknown; -declare function getPropValue(obj: T, path: P): PropType; -declare const s: string; -declare const obj: { - a: { - b: { - c: number; - d: string; - }; - }; -}; -declare type S1 = T extends `foo${infer U}bar` ? S2 : never; -declare type S2 = S; -declare type TV1 = `${infer X}`; -declare type Chars = string extends S ? string[] : S extends `${infer C0}${infer C1}${infer C2}${infer C3}${infer C4}${infer C5}${infer C6}${infer C7}${infer C8}${infer C9}${infer R}` ? [C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, ...Chars] : S extends `${infer C}${infer R}` ? [C, ...Chars] : S extends '' ? [] : never; -declare type L1 = Chars<'FooBarBazThisIsALongerString'>; -declare type Foo = T extends `*${infer S}*` ? S : never; -declare type TF1 = Foo; -declare type TF2 = Foo; -declare type TF3 = Foo<'abc'>; -declare type TF4 = Foo<'*abc*'>; -declare type A = any; -declare type U1 = { - a1: A; -} | { - b1: A; -} | { - c1: A; -} | { - d1: A; -} | { - e1: A; -} | { - f1: A; -} | { - g1: A; -} | { - h1: A; -} | { - i1: A; -} | { - j1: A; -}; -declare type U2 = { - a2: A; -} | { - b2: A; -} | { - c2: A; -} | { - d2: A; -} | { - e2: A; -} | { - f2: A; -} | { - g2: A; -} | { - h2: A; -} | { - i2: A; -} | { - j2: A; -}; -declare type U3 = { - a3: A; -} | { - b3: A; -} | { - c3: A; -} | { - d3: A; -} | { - e3: A; -} | { - f3: A; -} | { - g3: A; -} | { - h3: A; -} | { - i3: A; -} | { - j3: A; -}; -declare type U4 = { - a4: A; -} | { - b4: A; -} | { - c4: A; -} | { - d4: A; -} | { - e4: A; -} | { - f4: A; -} | { - g4: A; -} | { - h4: A; -} | { - i4: A; -} | { - j4: A; -}; -declare type U5 = { - a5: A; -} | { - b5: A; -} | { - c5: A; -} | { - d5: A; -} | { - e5: A; -} | { - f5: A; -} | { - g5: A; -} | { - h5: A; -} | { - i5: A; -} | { - j5: A; -}; -declare type U100000 = U1 & U2 & U3 & U4 & U5; -declare type Digits = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9; -declare type D100000 = `${Digits}${Digits}${Digits}${Digits}${Digits}`; -declare type TDigits = [0] | [1] | [2] | [3] | [4] | [5] | [6] | [7] | [8] | [9]; -declare type T100000 = [...TDigits, ...TDigits, ...TDigits, ...TDigits, ...TDigits]; -declare type IsNegative = `${T}` extends `-${string}` ? true : false; -declare type AA = [ - true, - true -] extends [IsNegative, IsNegative] ? 'Every thing is ok!' : ['strange', IsNegative, IsNegative]; -declare type BB = AA<-2, -2>; -declare type PathKeys = T extends readonly any[] ? Extract | SubKeys> : T extends object ? Extract | SubKeys> : never; -declare type SubKeys = K extends keyof T ? `${K}.${PathKeys}` : never; -declare function getProp2>(obj: T, path: P): PropType; -declare const obj2: { - readonly name: "John"; - readonly age: 42; - readonly cars: readonly [{ - readonly make: "Ford"; - readonly age: 10; - }, { - readonly make: "Trabant"; - readonly age: 35; - }]; -}; -declare let make: "Trabant"; +export declare type Spacing = `0` | `${number}px` | `${number}rem` | `s${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20}`; +export declare type SpacingShorthand = `${Spacing} ${Spacing}` | `${Spacing} ${Spacing} ${Spacing}` | `${Spacing} ${Spacing} ${Spacing} ${Spacing}`; diff --git a/tests/baselines/reference/templateLiteralTypes1.symbols b/tests/baselines/reference/templateLiteralTypes1.symbols index bc2f7990a24..8f539fe347e 100644 --- a/tests/baselines/reference/templateLiteralTypes1.symbols +++ b/tests/baselines/reference/templateLiteralTypes1.symbols @@ -952,3 +952,39 @@ let make = getProp2(obj2, 'cars.1.make'); // 'Trabant' >getProp2 : Symbol(getProp2, Decl(templateLiteralTypes1.ts, 222, 89)) >obj2 : Symbol(obj2, Decl(templateLiteralTypes1.ts, 226, 5)) +// Repro from #46480 + +export type Spacing = +>Spacing : Symbol(Spacing, Decl(templateLiteralTypes1.ts, 235, 41)) + + | `0` + | `${number}px` + | `${number}rem` + | `s${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20}`; + +const spacing: Spacing = "s12" +>spacing : Symbol(spacing, Decl(templateLiteralTypes1.ts, 245, 5)) +>Spacing : Symbol(Spacing, Decl(templateLiteralTypes1.ts, 235, 41)) + +export type SpacingShorthand = +>SpacingShorthand : Symbol(SpacingShorthand, Decl(templateLiteralTypes1.ts, 245, 30)) + + | `${Spacing} ${Spacing}` +>Spacing : Symbol(Spacing, Decl(templateLiteralTypes1.ts, 235, 41)) +>Spacing : Symbol(Spacing, Decl(templateLiteralTypes1.ts, 235, 41)) + + | `${Spacing} ${Spacing} ${Spacing}` +>Spacing : Symbol(Spacing, Decl(templateLiteralTypes1.ts, 235, 41)) +>Spacing : Symbol(Spacing, Decl(templateLiteralTypes1.ts, 235, 41)) +>Spacing : Symbol(Spacing, Decl(templateLiteralTypes1.ts, 235, 41)) + + | `${Spacing} ${Spacing} ${Spacing} ${Spacing}`; +>Spacing : Symbol(Spacing, Decl(templateLiteralTypes1.ts, 235, 41)) +>Spacing : Symbol(Spacing, Decl(templateLiteralTypes1.ts, 235, 41)) +>Spacing : Symbol(Spacing, Decl(templateLiteralTypes1.ts, 235, 41)) +>Spacing : Symbol(Spacing, Decl(templateLiteralTypes1.ts, 235, 41)) + +const test1: SpacingShorthand = "0 0 0"; +>test1 : Symbol(test1, Decl(templateLiteralTypes1.ts, 252, 5)) +>SpacingShorthand : Symbol(SpacingShorthand, Decl(templateLiteralTypes1.ts, 245, 30)) + diff --git a/tests/baselines/reference/templateLiteralTypes1.types b/tests/baselines/reference/templateLiteralTypes1.types index 102e9a91930..d143dc764ca 100644 --- a/tests/baselines/reference/templateLiteralTypes1.types +++ b/tests/baselines/reference/templateLiteralTypes1.types @@ -594,3 +594,28 @@ let make = getProp2(obj2, 'cars.1.make'); // 'Trabant' >obj2 : { readonly name: "John"; readonly age: 42; readonly cars: readonly [{ readonly make: "Ford"; readonly age: 10; }, { readonly make: "Trabant"; readonly age: 35; }]; } >'cars.1.make' : "cars.1.make" +// Repro from #46480 + +export type Spacing = +>Spacing : Spacing + + | `0` + | `${number}px` + | `${number}rem` + | `s${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20}`; + +const spacing: Spacing = "s12" +>spacing : Spacing +>"s12" : "s12" + +export type SpacingShorthand = +>SpacingShorthand : any + + | `${Spacing} ${Spacing}` + | `${Spacing} ${Spacing} ${Spacing}` + | `${Spacing} ${Spacing} ${Spacing} ${Spacing}`; + +const test1: SpacingShorthand = "0 0 0"; +>test1 : any +>"0 0 0" : "0 0 0" + diff --git a/tests/cases/conformance/types/literal/templateLiteralTypes1.ts b/tests/cases/conformance/types/literal/templateLiteralTypes1.ts index 185e0bf402d..daa3fbaeb78 100644 --- a/tests/cases/conformance/types/literal/templateLiteralTypes1.ts +++ b/tests/cases/conformance/types/literal/templateLiteralTypes1.ts @@ -237,3 +237,20 @@ const obj2 = { } as const; let make = getProp2(obj2, 'cars.1.make'); // 'Trabant' + +// Repro from #46480 + +export type Spacing = + | `0` + | `${number}px` + | `${number}rem` + | `s${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20}`; + +const spacing: Spacing = "s12" + +export type SpacingShorthand = + | `${Spacing} ${Spacing}` + | `${Spacing} ${Spacing} ${Spacing}` + | `${Spacing} ${Spacing} ${Spacing} ${Spacing}`; + +const test1: SpacingShorthand = "0 0 0"; From 44c63a757e06abcc3f5812e7b762400ff567c186 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 26 Oct 2021 09:36:19 -0700 Subject: [PATCH 59/60] Always cache relations involving intersection types (#46523) * Always cache relations involving intersection types * Accept new baselines * Add regression test --- src/compiler/checker.ts | 23 ++++---- ...yofReliesOnKeyofNeverUpperBound.errors.txt | 36 ++++++------- .../reference/deepComparisons.errors.txt | 21 +++++++- tests/baselines/reference/deepComparisons.js | 24 ++++++++- .../reference/deepComparisons.symbols | 54 +++++++++++++++++++ .../baselines/reference/deepComparisons.types | 31 +++++++++++ .../intersectionAndUnionTypes.errors.txt | 2 - .../keyofAndIndexedAccessErrors.errors.txt | 6 +++ .../unionTypeCallSignatures6.errors.txt | 4 -- tests/cases/compiler/deepComparisons.ts | 20 ++++++- 10 files changed, 180 insertions(+), 41 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a97e96bff26..3c647af6313 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18226,13 +18226,12 @@ namespace ts { let result = Ternary.False; const saveErrorInfo = captureErrorCalculationState(); - // Note that these checks are specifically ordered to produce correct results. In particular, - // we need to deconstruct unions before intersections (because unions are always at the top), - // and we need to handle "each" relations before "some" relations for the same kind of type. - if (source.flags & TypeFlags.UnionOrIntersection || target.flags & TypeFlags.UnionOrIntersection) { - result = getConstituentCount(source) * getConstituentCount(target) >= 4 ? - recursiveTypeRelatedTo(source, target, reportErrors, intersectionState | IntersectionState.UnionIntersectionCheck, recursionFlags) : - structuredTypeRelatedTo(source, target, reportErrors, intersectionState | IntersectionState.UnionIntersectionCheck); + if ((source.flags & TypeFlags.Union || target.flags & TypeFlags.Union) && getConstituentCount(source) * getConstituentCount(target) < 4) { + // We skip caching when source or target is a union with no more than three constituents. + result = structuredTypeRelatedTo(source, target, reportErrors, intersectionState | IntersectionState.UnionIntersectionCheck); + } + else if (source.flags & TypeFlags.UnionOrIntersection || target.flags & TypeFlags.UnionOrIntersection) { + result = recursiveTypeRelatedTo(source, target, reportErrors, intersectionState | IntersectionState.UnionIntersectionCheck, recursionFlags); } if (!result && !(source.flags & TypeFlags.Union) && (source.flags & (TypeFlags.StructuredOrInstantiable) || target.flags & TypeFlags.StructuredOrInstantiable)) { if (result = recursiveTypeRelatedTo(source, target, reportErrors, intersectionState, recursionFlags)) { @@ -18696,17 +18695,17 @@ namespace ts { const maybeStart = maybeCount; maybeKeys[maybeCount] = id; maybeCount++; + const saveExpandingFlags = expandingFlags; if (recursionFlags & RecursionFlags.Source) { sourceStack[sourceDepth] = source; sourceDepth++; + if (!(expandingFlags & ExpandingFlags.Source) && isDeeplyNestedType(source, sourceStack, sourceDepth)) expandingFlags |= ExpandingFlags.Source; } if (recursionFlags & RecursionFlags.Target) { targetStack[targetDepth] = target; targetDepth++; + if (!(expandingFlags & ExpandingFlags.Target) && isDeeplyNestedType(target, targetStack, targetDepth)) expandingFlags |= ExpandingFlags.Target; } - const saveExpandingFlags = expandingFlags; - if (!(expandingFlags & ExpandingFlags.Source) && isDeeplyNestedType(source, sourceStack, sourceDepth)) expandingFlags |= ExpandingFlags.Source; - if (!(expandingFlags & ExpandingFlags.Target) && isDeeplyNestedType(target, targetStack, targetDepth)) expandingFlags |= ExpandingFlags.Target; let originalHandler: typeof outofbandVarianceMarkerHandler; let propagatingVarianceFlags: RelationComparisonResult = 0; if (outofbandVarianceMarkerHandler) { @@ -18732,13 +18731,13 @@ namespace ts { if (outofbandVarianceMarkerHandler) { outofbandVarianceMarkerHandler = originalHandler; } - expandingFlags = saveExpandingFlags; if (recursionFlags & RecursionFlags.Source) { sourceDepth--; } if (recursionFlags & RecursionFlags.Target) { targetDepth--; } + expandingFlags = saveExpandingFlags; if (result) { if (result === Ternary.True || (sourceDepth === 0 && targetDepth === 0)) { if (result === Ternary.True || result === Ternary.Maybe) { @@ -23173,7 +23172,7 @@ namespace ts { } function getConstituentCount(type: Type) { - return type.flags & TypeFlags.UnionOrIntersection ? (type as UnionOrIntersectionType).types.length : 1; + return type.flags & TypeFlags.Union ? (type as UnionType).types.length : 1; } function extractTypesOfKind(type: Type, kind: TypeFlags) { diff --git a/tests/baselines/reference/complicatedIndexedAccessKeyofReliesOnKeyofNeverUpperBound.errors.txt b/tests/baselines/reference/complicatedIndexedAccessKeyofReliesOnKeyofNeverUpperBound.errors.txt index af63c18523d..ec5fce9a382 100644 --- a/tests/baselines/reference/complicatedIndexedAccessKeyofReliesOnKeyofNeverUpperBound.errors.txt +++ b/tests/baselines/reference/complicatedIndexedAccessKeyofReliesOnKeyofNeverUpperBound.errors.txt @@ -9,16 +9,14 @@ tests/cases/compiler/complicatedIndexedAccessKeyofReliesOnKeyofNeverUpperBound.t Type '"text" | "email"' is not assignable to type 'ChannelOfType["type"]'. Type '"text"' is not assignable to type 'ChannelOfType["type"]'. Type '"text"' is not assignable to type 'T & "text"'. - Type '"text"' is not assignable to type 'T'. - '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'. - Type 'T' is not assignable to type 'T & "text"'. - Type '"text" | "email"' is not assignable to type 'T & "text"'. - Type '"text"' is not assignable to type 'T & "text"'. - Type '"text"' is not assignable to type 'T'. - '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'. - Type 'T' is not assignable to type '"text"'. - Type '"text" | "email"' is not assignable to type '"text"'. - Type '"email"' is not assignable to type '"text"'. + Type 'T' is not assignable to type 'T & "text"'. + Type '"text" | "email"' is not assignable to type 'T & "text"'. + Type '"text"' is not assignable to type 'T & "text"'. + Type '"text"' is not assignable to type 'T'. + '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'. + Type 'T' is not assignable to type '"text"'. + Type '"text" | "email"' is not assignable to type '"text"'. + Type '"email"' is not assignable to type '"text"'. ==== tests/cases/compiler/complicatedIndexedAccessKeyofReliesOnKeyofNeverUpperBound.ts (1 errors) ==== @@ -67,16 +65,14 @@ tests/cases/compiler/complicatedIndexedAccessKeyofReliesOnKeyofNeverUpperBound.t !!! error TS2322: Type '"text" | "email"' is not assignable to type 'ChannelOfType["type"]'. !!! error TS2322: Type '"text"' is not assignable to type 'ChannelOfType["type"]'. !!! error TS2322: Type '"text"' is not assignable to type 'T & "text"'. -!!! error TS2322: Type '"text"' is not assignable to type 'T'. -!!! error TS2322: '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'. -!!! error TS2322: Type 'T' is not assignable to type 'T & "text"'. -!!! error TS2322: Type '"text" | "email"' is not assignable to type 'T & "text"'. -!!! error TS2322: Type '"text"' is not assignable to type 'T & "text"'. -!!! error TS2322: Type '"text"' is not assignable to type 'T'. -!!! error TS2322: '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'. -!!! error TS2322: Type 'T' is not assignable to type '"text"'. -!!! error TS2322: Type '"text" | "email"' is not assignable to type '"text"'. -!!! error TS2322: Type '"email"' is not assignable to type '"text"'. +!!! error TS2322: Type 'T' is not assignable to type 'T & "text"'. +!!! error TS2322: Type '"text" | "email"' is not assignable to type 'T & "text"'. +!!! error TS2322: Type '"text"' is not assignable to type 'T & "text"'. +!!! error TS2322: Type '"text"' is not assignable to type 'T'. +!!! error TS2322: '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'. +!!! error TS2322: Type 'T' is not assignable to type '"text"'. +!!! error TS2322: Type '"text" | "email"' is not assignable to type '"text"'. +!!! error TS2322: Type '"email"' is not assignable to type '"text"'. } const newTextChannel = makeNewChannel('text'); diff --git a/tests/baselines/reference/deepComparisons.errors.txt b/tests/baselines/reference/deepComparisons.errors.txt index 43eec648b7f..663d5d80d1b 100644 --- a/tests/baselines/reference/deepComparisons.errors.txt +++ b/tests/baselines/reference/deepComparisons.errors.txt @@ -46,4 +46,23 @@ tests/cases/compiler/deepComparisons.ts(4,9): error TS2322: Type 'T[K1][K2]' is function f3() { let x: Foo1 = 0 as any as Bar; // No error! - } \ No newline at end of file + } + + // Repro from #46500 + + type F = {} & ( + T extends [any, ...any[]] + ? { [K in keyof T]?: F } + : T extends any[] + ? F[] + : T extends { [K: string]: any } + ? { [K in keyof T]?: F } + : { x: string } + ); + + declare function f(): F; + + function g() { + return f() as F; + } + \ No newline at end of file diff --git a/tests/baselines/reference/deepComparisons.js b/tests/baselines/reference/deepComparisons.js index 95d81ea96cf..78bd274047a 100644 --- a/tests/baselines/reference/deepComparisons.js +++ b/tests/baselines/reference/deepComparisons.js @@ -17,7 +17,26 @@ type Foo2 = { x: Foo1 }; function f3() { let x: Foo1 = 0 as any as Bar; // No error! -} +} + +// Repro from #46500 + +type F = {} & ( + T extends [any, ...any[]] + ? { [K in keyof T]?: F } + : T extends any[] + ? F[] + : T extends { [K: string]: any } + ? { [K in keyof T]?: F } + : { x: string } +); + +declare function f(): F; + +function g() { + return f() as F; +} + //// [deepComparisons.js] function f1() { @@ -31,3 +50,6 @@ function f2() { function f3() { var x = 0; // No error! } +function g() { + return f(); +} diff --git a/tests/baselines/reference/deepComparisons.symbols b/tests/baselines/reference/deepComparisons.symbols index 4c172345e07..7b2dbd596eb 100644 --- a/tests/baselines/reference/deepComparisons.symbols +++ b/tests/baselines/reference/deepComparisons.symbols @@ -84,3 +84,57 @@ function f3() { >Bar : Symbol(Bar, Decl(deepComparisons.ts, 6, 28)) >U : Symbol(U, Decl(deepComparisons.ts, 16, 12)) } + +// Repro from #46500 + +type F = {} & ( +>F : Symbol(F, Decl(deepComparisons.ts, 18, 1)) +>T : Symbol(T, Decl(deepComparisons.ts, 22, 7)) + + T extends [any, ...any[]] +>T : Symbol(T, Decl(deepComparisons.ts, 22, 7)) + + ? { [K in keyof T]?: F } +>K : Symbol(K, Decl(deepComparisons.ts, 24, 13)) +>T : Symbol(T, Decl(deepComparisons.ts, 22, 7)) +>F : Symbol(F, Decl(deepComparisons.ts, 18, 1)) +>T : Symbol(T, Decl(deepComparisons.ts, 22, 7)) +>K : Symbol(K, Decl(deepComparisons.ts, 24, 13)) + + : T extends any[] +>T : Symbol(T, Decl(deepComparisons.ts, 22, 7)) + + ? F[] +>F : Symbol(F, Decl(deepComparisons.ts, 18, 1)) +>T : Symbol(T, Decl(deepComparisons.ts, 22, 7)) + + : T extends { [K: string]: any } +>T : Symbol(T, Decl(deepComparisons.ts, 22, 7)) +>K : Symbol(K, Decl(deepComparisons.ts, 27, 27)) + + ? { [K in keyof T]?: F } +>K : Symbol(K, Decl(deepComparisons.ts, 28, 21)) +>T : Symbol(T, Decl(deepComparisons.ts, 22, 7)) +>F : Symbol(F, Decl(deepComparisons.ts, 18, 1)) +>T : Symbol(T, Decl(deepComparisons.ts, 22, 7)) +>K : Symbol(K, Decl(deepComparisons.ts, 28, 21)) + + : { x: string } +>x : Symbol(x, Decl(deepComparisons.ts, 29, 19)) + +); + +declare function f(): F; +>f : Symbol(f, Decl(deepComparisons.ts, 30, 2)) +>T : Symbol(T, Decl(deepComparisons.ts, 32, 19)) +>F : Symbol(F, Decl(deepComparisons.ts, 18, 1)) +>T : Symbol(T, Decl(deepComparisons.ts, 32, 19)) + +function g() { +>g : Symbol(g, Decl(deepComparisons.ts, 32, 36)) + + return f() as F; +>f : Symbol(f, Decl(deepComparisons.ts, 30, 2)) +>F : Symbol(F, Decl(deepComparisons.ts, 18, 1)) +} + diff --git a/tests/baselines/reference/deepComparisons.types b/tests/baselines/reference/deepComparisons.types index 7bc16b70f8a..f7cbbfae8a0 100644 --- a/tests/baselines/reference/deepComparisons.types +++ b/tests/baselines/reference/deepComparisons.types @@ -56,3 +56,34 @@ function f3() { >0 as any : any >0 : 0 } + +// Repro from #46500 + +type F = {} & ( +>F : F + + T extends [any, ...any[]] + ? { [K in keyof T]?: F } + : T extends any[] + ? F[] + : T extends { [K: string]: any } +>K : string + + ? { [K in keyof T]?: F } + : { x: string } +>x : string + +); + +declare function f(): F; +>f : () => F + +function g() { +>g : () => F + + return f() as F; +>f() as F : F +>f() : F +>f : () => F +} + diff --git a/tests/baselines/reference/intersectionAndUnionTypes.errors.txt b/tests/baselines/reference/intersectionAndUnionTypes.errors.txt index e700e7c4721..f2d810fb0af 100644 --- a/tests/baselines/reference/intersectionAndUnionTypes.errors.txt +++ b/tests/baselines/reference/intersectionAndUnionTypes.errors.txt @@ -5,7 +5,6 @@ tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(20,1): e tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(23,1): error TS2322: Type 'A | B' is not assignable to type '(A & B) | (C & D)'. Type 'A' is not assignable to type '(A & B) | (C & D)'. Type 'A' is not assignable to type 'A & B'. - Type 'A' is not assignable to type 'B'. tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(25,1): error TS2322: Type 'C | D' is not assignable to type '(A & B) | (C & D)'. Type 'C' is not assignable to type '(A & B) | (C & D)'. Type 'C' is not assignable to type 'C & D'. @@ -80,7 +79,6 @@ tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(37,1): e !!! error TS2322: Type 'A | B' is not assignable to type '(A & B) | (C & D)'. !!! error TS2322: Type 'A' is not assignable to type '(A & B) | (C & D)'. !!! error TS2322: Type 'A' is not assignable to type 'A & B'. -!!! error TS2322: Type 'A' is not assignable to type 'B'. x = cnd; // Ok x = cod; ~ diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt index ba319beca32..b6295981562 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt @@ -33,8 +33,11 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(82,5): error Type 'string | number | symbol' is not assignable to type 'keyof U'. Type 'string' is not assignable to type 'keyof U'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(83,5): error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'. + Type 'keyof T' is not assignable to type 'keyof T & keyof U'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(86,5): error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'. + Type 'keyof T' is not assignable to type 'keyof T & keyof U'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(87,5): error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'. + Type 'keyof T' is not assignable to type 'keyof T & keyof U'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(103,9): error TS2322: Type 'Extract' is not assignable to type 'K'. 'Extract' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'. Type 'string & keyof T' is not assignable to type 'K'. @@ -209,14 +212,17 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(142,5): error k1 = k4; // Error ~~ !!! error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof T & keyof U'. k2 = k1; k2 = k3; // Error ~~ !!! error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof T & keyof U'. k2 = k4; // Error ~~ !!! error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof T & keyof U'. k3 = k1; k3 = k2; diff --git a/tests/baselines/reference/unionTypeCallSignatures6.errors.txt b/tests/baselines/reference/unionTypeCallSignatures6.errors.txt index 51b18b204a7..2d162fc354d 100644 --- a/tests/baselines/reference/unionTypeCallSignatures6.errors.txt +++ b/tests/baselines/reference/unionTypeCallSignatures6.errors.txt @@ -6,14 +6,12 @@ tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(38,4): error TS2 tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(39,1): error TS2684: The 'this' context of type 'A & C & { f0: F0 | F3; f1: F1 | F3; f2: F1 | F4; f3: F3 | F4; f4: F3 | F5; }' is not assignable to method's 'this' of type 'B'. Property 'b' is missing in type 'A & C & { f0: F0 | F3; f1: F1 | F3; f2: F1 | F4; f3: F3 | F4; f4: F3 | F5; }' but required in type 'B'. tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(48,1): error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B'. - Type 'void' is not assignable to type 'A'. tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(55,1): error TS2769: No overload matches this call. Overload 1 of 2, '(this: A & B & C): void', gave the following error. The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B & C'. Type 'void' is not assignable to type 'A'. Overload 2 of 2, '(this: A & B): void', gave the following error. The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B'. - Type 'void' is not assignable to type 'A'. ==== tests/cases/conformance/types/union/unionTypeCallSignatures6.ts (6 errors) ==== @@ -79,7 +77,6 @@ tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(55,1): error TS2 f3(); // error ~~~~ !!! error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B'. -!!! error TS2684: Type 'void' is not assignable to type 'A'. interface F7 { (this: A & B & C): void; @@ -94,5 +91,4 @@ tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(55,1): error TS2 !!! error TS2769: Type 'void' is not assignable to type 'A'. !!! error TS2769: Overload 2 of 2, '(this: A & B): void', gave the following error. !!! error TS2769: The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B'. -!!! error TS2769: Type 'void' is not assignable to type 'A'. \ No newline at end of file diff --git a/tests/cases/compiler/deepComparisons.ts b/tests/cases/compiler/deepComparisons.ts index 1323673945a..a14fafc8ffe 100644 --- a/tests/cases/compiler/deepComparisons.ts +++ b/tests/cases/compiler/deepComparisons.ts @@ -16,4 +16,22 @@ type Foo2 = { x: Foo1 }; function f3() { let x: Foo1 = 0 as any as Bar; // No error! -} \ No newline at end of file +} + +// Repro from #46500 + +type F = {} & ( + T extends [any, ...any[]] + ? { [K in keyof T]?: F } + : T extends any[] + ? F[] + : T extends { [K: string]: any } + ? { [K in keyof T]?: F } + : { x: string } +); + +declare function f(): F; + +function g() { + return f() as F; +} From f424dfc18a01c45b8709950b6e2dc3beafaf9960 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 26 Oct 2021 11:54:46 -0700 Subject: [PATCH 60/60] Slightly less conservative check in isConstraintPosition (#46526) * Slight adjustment to check in isConstraintPosition * Add regression test --- src/compiler/checker.ts | 2 +- .../controlFlowGenericTypes.errors.txt | 20 +++++++ .../reference/controlFlowGenericTypes.js | 25 +++++++++ .../reference/controlFlowGenericTypes.symbols | 52 +++++++++++++++++++ .../reference/controlFlowGenericTypes.types | 41 +++++++++++++++ .../controlFlow/controlFlowGenericTypes.ts | 20 +++++++ 6 files changed, 159 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3c647af6313..a33f986723a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -24758,7 +24758,7 @@ namespace ts { return parent.kind === SyntaxKind.PropertyAccessExpression || parent.kind === SyntaxKind.CallExpression && (parent as CallExpression).expression === node || parent.kind === SyntaxKind.ElementAccessExpression && (parent as ElementAccessExpression).expression === node && - !(isGenericTypeWithoutNullableConstraint(type) && isGenericIndexType(getTypeOfExpression((parent as ElementAccessExpression).argumentExpression))); + !(someType(type, isGenericTypeWithoutNullableConstraint) && isGenericIndexType(getTypeOfExpression((parent as ElementAccessExpression).argumentExpression))); } function isGenericTypeWithUnionConstraint(type: Type) { diff --git a/tests/baselines/reference/controlFlowGenericTypes.errors.txt b/tests/baselines/reference/controlFlowGenericTypes.errors.txt index 620c3ebb6d5..3130ba416fb 100644 --- a/tests/baselines/reference/controlFlowGenericTypes.errors.txt +++ b/tests/baselines/reference/controlFlowGenericTypes.errors.txt @@ -220,4 +220,24 @@ tests/cases/conformance/controlFlow/controlFlowGenericTypes.ts(168,9): error TS2 this.validateRow(row); } } + + // Repro from #46495 + + interface Button { + type: "button"; + text: string; + } + + interface Checkbox { + type: "checkbox"; + isChecked: boolean; + } + + type Control = Button | Checkbox; + + function update(control : T | undefined, key: K, value: T[K]): void { + if (control !== undefined) { + control[key] = value; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/controlFlowGenericTypes.js b/tests/baselines/reference/controlFlowGenericTypes.js index d080434b17c..a59b496ecd7 100644 --- a/tests/baselines/reference/controlFlowGenericTypes.js +++ b/tests/baselines/reference/controlFlowGenericTypes.js @@ -190,6 +190,26 @@ class SqlTable { this.validateRow(row); } } + +// Repro from #46495 + +interface Button { + type: "button"; + text: string; +} + +interface Checkbox { + type: "checkbox"; + isChecked: boolean; +} + +type Control = Button | Checkbox; + +function update(control : T | undefined, key: K, value: T[K]): void { + if (control !== undefined) { + control[key] = value; + } +} //// [controlFlowGenericTypes.js] @@ -343,3 +363,8 @@ var SqlTable = /** @class */ (function () { }; return SqlTable; }()); +function update(control, key, value) { + if (control !== undefined) { + control[key] = value; + } +} diff --git a/tests/baselines/reference/controlFlowGenericTypes.symbols b/tests/baselines/reference/controlFlowGenericTypes.symbols index c940c7983d6..1a1edf72f0a 100644 --- a/tests/baselines/reference/controlFlowGenericTypes.symbols +++ b/tests/baselines/reference/controlFlowGenericTypes.symbols @@ -574,3 +574,55 @@ class SqlTable { } } +// Repro from #46495 + +interface Button { +>Button : Symbol(Button, Decl(controlFlowGenericTypes.ts, 190, 1)) + + type: "button"; +>type : Symbol(Button.type, Decl(controlFlowGenericTypes.ts, 194, 18)) + + text: string; +>text : Symbol(Button.text, Decl(controlFlowGenericTypes.ts, 195, 19)) +} + +interface Checkbox { +>Checkbox : Symbol(Checkbox, Decl(controlFlowGenericTypes.ts, 197, 1)) + + type: "checkbox"; +>type : Symbol(Checkbox.type, Decl(controlFlowGenericTypes.ts, 199, 20)) + + isChecked: boolean; +>isChecked : Symbol(Checkbox.isChecked, Decl(controlFlowGenericTypes.ts, 200, 21)) +} + +type Control = Button | Checkbox; +>Control : Symbol(Control, Decl(controlFlowGenericTypes.ts, 202, 1)) +>Button : Symbol(Button, Decl(controlFlowGenericTypes.ts, 190, 1)) +>Checkbox : Symbol(Checkbox, Decl(controlFlowGenericTypes.ts, 197, 1)) + +function update(control : T | undefined, key: K, value: T[K]): void { +>update : Symbol(update, Decl(controlFlowGenericTypes.ts, 204, 33)) +>T : Symbol(T, Decl(controlFlowGenericTypes.ts, 206, 16)) +>Control : Symbol(Control, Decl(controlFlowGenericTypes.ts, 202, 1)) +>K : Symbol(K, Decl(controlFlowGenericTypes.ts, 206, 34)) +>T : Symbol(T, Decl(controlFlowGenericTypes.ts, 206, 16)) +>control : Symbol(control, Decl(controlFlowGenericTypes.ts, 206, 54)) +>T : Symbol(T, Decl(controlFlowGenericTypes.ts, 206, 16)) +>key : Symbol(key, Decl(controlFlowGenericTypes.ts, 206, 78)) +>K : Symbol(K, Decl(controlFlowGenericTypes.ts, 206, 34)) +>value : Symbol(value, Decl(controlFlowGenericTypes.ts, 206, 86)) +>T : Symbol(T, Decl(controlFlowGenericTypes.ts, 206, 16)) +>K : Symbol(K, Decl(controlFlowGenericTypes.ts, 206, 34)) + + if (control !== undefined) { +>control : Symbol(control, Decl(controlFlowGenericTypes.ts, 206, 54)) +>undefined : Symbol(undefined) + + control[key] = value; +>control : Symbol(control, Decl(controlFlowGenericTypes.ts, 206, 54)) +>key : Symbol(key, Decl(controlFlowGenericTypes.ts, 206, 78)) +>value : Symbol(value, Decl(controlFlowGenericTypes.ts, 206, 86)) + } +} + diff --git a/tests/baselines/reference/controlFlowGenericTypes.types b/tests/baselines/reference/controlFlowGenericTypes.types index 5bf18f4e37a..6ee07abf4d6 100644 --- a/tests/baselines/reference/controlFlowGenericTypes.types +++ b/tests/baselines/reference/controlFlowGenericTypes.types @@ -542,3 +542,44 @@ class SqlTable { } } +// Repro from #46495 + +interface Button { + type: "button"; +>type : "button" + + text: string; +>text : string +} + +interface Checkbox { + type: "checkbox"; +>type : "checkbox" + + isChecked: boolean; +>isChecked : boolean +} + +type Control = Button | Checkbox; +>Control : Control + +function update(control : T | undefined, key: K, value: T[K]): void { +>update : (control: T | undefined, key: K, value: T[K]) => void +>control : T | undefined +>key : K +>value : T[K] + + if (control !== undefined) { +>control !== undefined : boolean +>control : T | undefined +>undefined : undefined + + control[key] = value; +>control[key] = value : T[K] +>control[key] : T[K] +>control : T +>key : K +>value : T[K] + } +} + diff --git a/tests/cases/conformance/controlFlow/controlFlowGenericTypes.ts b/tests/cases/conformance/controlFlow/controlFlowGenericTypes.ts index f2cac082f5e..3e67f3247da 100644 --- a/tests/cases/conformance/controlFlow/controlFlowGenericTypes.ts +++ b/tests/cases/conformance/controlFlow/controlFlowGenericTypes.ts @@ -191,3 +191,23 @@ class SqlTable { this.validateRow(row); } } + +// Repro from #46495 + +interface Button { + type: "button"; + text: string; +} + +interface Checkbox { + type: "checkbox"; + isChecked: boolean; +} + +type Control = Button | Checkbox; + +function update(control : T | undefined, key: K, value: T[K]): void { + if (control !== undefined) { + control[key] = value; + } +}