From e1bca8ff2a077931e6fdd569663118782378adc3 Mon Sep 17 00:00:00 2001 From: xiaofa Date: Tue, 6 Aug 2019 08:35:34 +0800 Subject: [PATCH 1/5] Fix class member completion disappear after a property declaration with a private modifier --- src/services/completions.ts | 2 +- ...completionsClassPropertiesAfterPrivateProperty.ts | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/completionsClassPropertiesAfterPrivateProperty.ts diff --git a/src/services/completions.ts b/src/services/completions.ts index e9a38fb1516..bf7ff041f2d 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1566,7 +1566,7 @@ namespace ts.Completions { // If you're in an interface you don't want to repeat things from super-interface. So just stop here. if (!isClassLike(decl)) return GlobalsSearch.Success; - const classElement = contextToken.parent; + const classElement = contextToken.kind === SyntaxKind.SemicolonToken ? contextToken.parent.parent : contextToken.parent; let classElementModifierFlags = isClassElement(classElement) ? getModifierFlags(classElement) : ModifierFlags.None; // If this is context token is not something we are editing now, consider if this would lead to be modifier if (contextToken.kind === SyntaxKind.Identifier && !isCurrentlyEditingNode(contextToken)) { diff --git a/tests/cases/fourslash/completionsClassPropertiesAfterPrivateProperty.ts b/tests/cases/fourslash/completionsClassPropertiesAfterPrivateProperty.ts new file mode 100644 index 00000000000..2efd70110b9 --- /dev/null +++ b/tests/cases/fourslash/completionsClassPropertiesAfterPrivateProperty.ts @@ -0,0 +1,12 @@ +/// + +//// interface X { +//// bla: string; +//// } +//// class Y implements X { +//// private blub = ""; +//// /**/ +//// } + + +verify.completions({ marker: "", includes: "bla", isNewIdentifierLocation: true }); From df3c746070e20adf39fa601b35cb44d76c9efe6e Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Tue, 13 Aug 2019 08:35:42 -0700 Subject: [PATCH 2/5] Update user baselines (#32837) --- .../baselines/reference/docker/azure-sdk.log | 137 +++++++++++++----- .../reference/docker/office-ui-fabric.log | 2 +- .../user/TypeScript-React-Native-Starter.log | 2 +- tests/baselines/reference/user/async.log | 17 --- tests/baselines/reference/user/prettier.log | 4 +- 5 files changed, 102 insertions(+), 60 deletions(-) diff --git a/tests/baselines/reference/docker/azure-sdk.log b/tests/baselines/reference/docker/azure-sdk.log index 2a870effa9b..2c8c866ea20 100644 --- a/tests/baselines/reference/docker/azure-sdk.log +++ b/tests/baselines/reference/docker/azure-sdk.log @@ -2,94 +2,153 @@ Exit Code: 1 Standard output: Rush Multi-Project Build Tool 5.X.X - https://rushjs.io -Node.js version is 12.7.0 (pre-LTS) +Node.js version is 12.8.0 (pre-LTS) Starting "rush rebuild" Executing a maximum of ?simultaneous processes... +XX of XX: [@azure/identity] completed successfully in ? seconds +XX of XX: [@azure/event-processor-host] completed successfully in ? seconds +XX of XX: [@azure/abort-controller] completed successfully in ? seconds +XX of XX: [@azure/core-arm] completed successfully in ? seconds +XX of XX: [@azure/core-asynciterator-polyfill] completed successfully in ? seconds +XX of XX: [@azure/core-auth] completed successfully in ? seconds npm ERR! code ELIFECYCLE npm ERR! errno 2 -npm ERR! @azure/core-http@X.X.X-preview.2 build:tsc: `tsc -p tsconfig.es.json` +npm ERR! @azure/core-http@X.X.X-preview.3 build:tsc: `tsc -p tsconfig.es.json` npm ERR! Exit status 2 npm ERR! -npm ERR! Failed at the @azure/core-http@X.X.X-preview.2 build:tsc script. +npm ERR! Failed at the @azure/core-http@X.X.X-preview.3 build:tsc script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above. npm ERR! A complete log of this run can be found in: npm ERR! /root/.npm/_logs/XXXX-XX-XXXXXXXXX-debug.log ERROR: "build:tsc" exited with 2. npm ERR! code ELIFECYCLE npm ERR! errno 1 -npm ERR! @azure/core-http@X.X.X-preview.2 build:lib: `run-s build:tsc build:rollup build:minify-browser` +npm ERR! @azure/core-http@X.X.X-preview.3 build:lib: `run-s build:tsc build:rollup build:minify-browser` npm ERR! Exit status 1 npm ERR! -npm ERR! Failed at the @azure/core-http@X.X.X-preview.2 build:lib script. +npm ERR! Failed at the @azure/core-http@X.X.X-preview.3 build:lib script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above. npm ERR! A complete log of this run can be found in: npm ERR! /root/.npm/_logs/XXXX-XX-XXXXXXXXX-debug.log ERROR: "build:lib" exited with 1. -XX of XX: [@azure/core-tracing] completed successfully in ? seconds -XX of XX: [@azure/event-processor-host] completed successfully in ? seconds -XX of XX: [@azure/abort-controller] completed successfully in ? seconds -XX of XX: [@azure/core-asynciterator-polyfill] completed successfully in ? seconds -XX of XX: [@azure/core-auth] completed successfully in ? seconds XX of XX: [@azure/core-paging] completed successfully in ? seconds +XX of XX: [@azure/core-tracing] completed successfully in ? seconds XX of XX: [@azure/cosmos] completed successfully in ? seconds -Warning: You have changed the public API signature for this project. Updating review/service-bus.api.md +npm ERR! code ELIFECYCLE +npm ERR! errno 2 +npm ERR! @azure/keyvault-certificates@X.X.X extract-api: `tsc -p . && api-extractor run --local` +npm ERR! Exit status 2 +npm ERR! +npm ERR! Failed at the @azure/keyvault-certificates@X.X.X extract-api script. +npm ERR! This is probably not a problem with npm. There is likely additional logging output above. +npm ERR! A complete log of this run can be found in: +npm ERR! /root/.npm/_logs/XXXX-XX-XXXXXXXXX-debug.log +npm ERR! code ELIFECYCLE +npm ERR! errno 2 +npm ERR! @azure/keyvault-keys@X.X.X-preview.3 extract-api: `tsc -p . && api-extractor run --local` +npm ERR! Exit status 2 +npm ERR! +npm ERR! Failed at the @azure/keyvault-keys@X.X.X-preview.3 extract-api script. +npm ERR! This is probably not a problem with npm. There is likely additional logging output above. +npm ERR! A complete log of this run can be found in: +npm ERR! /root/.npm/_logs/XXXX-XX-XXXXXXXXX-debug.log +npm ERR! code ELIFECYCLE +npm ERR! errno 2 +npm ERR! @azure/keyvault-secrets@X.X.X-preview.4 extract-api: `tsc -p . && api-extractor run --local` +npm ERR! Exit status 2 +npm ERR! +npm ERR! Failed at the @azure/keyvault-secrets@X.X.X-preview.4 extract-api script. +npm ERR! This is probably not a problem with npm. There is likely additional logging output above. +npm ERR! A complete log of this run can be found in: +npm ERR! /root/.npm/_logs/XXXX-XX-XXXXXXXXX-debug.log +XX of XX: [@azure/service-bus] completed successfully in ? seconds XX of XX: [@azure/storage-blob] completed successfully in ? seconds XX of XX: [@azure/storage-file] completed successfully in ? seconds XX of XX: [@azure/storage-queue] completed successfully in ? seconds +XX of XX: [@azure/template] completed successfully in ? seconds XX of XX: [testhub] completed successfully in ? seconds -SUCCESS (11) +SUCCESS (15) ================================ @azure/abort-controller (? seconds) +@azure/core-arm (? seconds) @azure/core-asynciterator-polyfill (? seconds) @azure/core-auth (? seconds) @azure/core-paging (? seconds) @azure/core-tracing (? seconds) @azure/cosmos (? seconds) @azure/event-processor-host (? seconds) +@azure/identity (? seconds) +@azure/service-bus (? seconds) @azure/storage-blob (? seconds) @azure/storage-file (? seconds) @azure/storage-queue (? seconds) +@azure/template (? seconds) testhub (? seconds) ================================ -SUCCESS WITH WARNINGS (1) +BLOCKED (1) ================================ -@azure/service-bus (? seconds) -Warning: You have changed the public API signature for this project. Updating review/service-bus.api.md -================================ -BLOCKED (8) -================================ -@azure/core-amqp -@azure/core-arm @azure/event-hubs -@azure/identity -@azure/keyvault-certificates -@azure/keyvault-keys -@azure/keyvault-secrets -@azure/template ================================ -FAILURE (1) +FAILURE (5) ================================ +@azure/core-amqp ( ? seconds) +>>> @azure/core-amqp +tsc -p . && rollup -c 2>&1 +src/errors.ts(580,20): error TS7053: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'typeof ConditionErrorNameMapper'. +src/errors.ts(604,34): error TS7053: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'typeof SystemErrorConditionMapper'. +src/errors.ts(605,20): error TS7053: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'typeof ConditionErrorNameMapper'. +src/shims.d.ts(14,13): error TS2403: Subsequent variable declarations must have the same type. Variable 'window' must be of type 'Window & typeof globalThis', but here has type 'Window'. @azure/core-http ( ? seconds) npm ERR! code ELIFECYCLE npm ERR! errno 2 -npm ERR! @azure/core-http@X.X.X-preview.2 build:tsc: `tsc -p tsconfig.es.json` +npm ERR! @azure/core-http@X.X.X-preview.3 build:tsc: `tsc -p tsconfig.es.json` npm ERR! Exit status 2 npm ERR! -npm ERR! Failed at the @azure/core-http@X.X.X-preview.2 build:tsc script. +npm ERR! Failed at the @azure/core-http@X.X.X-preview.3 build:tsc script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above. npm ERR! A complete log of this run can be found in: npm ERR! /root/.npm/_logs/XXXX-XX-XXXXXXXXX-debug.log ERROR: "build:tsc" exited with 2. npm ERR! code ELIFECYCLE npm ERR! errno 1 -npm ERR! @azure/core-http@X.X.X-preview.2 build:lib: `run-s build:tsc build:rollup build:minify-browser` +npm ERR! @azure/core-http@X.X.X-preview.3 build:lib: `run-s build:tsc build:rollup build:minify-browser` npm ERR! Exit status 1 npm ERR! -npm ERR! Failed at the @azure/core-http@X.X.X-preview.2 build:lib script. +npm ERR! Failed at the @azure/core-http@X.X.X-preview.3 build:lib script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above. npm ERR! A complete log of this run can be found in: npm ERR! /root/.npm/_logs/XXXX-XX-XXXXXXXXX-debug.log ERROR: "build:lib" exited with 1. +@azure/keyvault-certificates ( ? seconds) +npm ERR! code ELIFECYCLE +npm ERR! errno 2 +npm ERR! @azure/keyvault-certificates@X.X.X extract-api: `tsc -p . && api-extractor run --local` +npm ERR! Exit status 2 +npm ERR! +npm ERR! Failed at the @azure/keyvault-certificates@X.X.X extract-api script. +npm ERR! This is probably not a problem with npm. There is likely additional logging output above. +npm ERR! A complete log of this run can be found in: +npm ERR! /root/.npm/_logs/XXXX-XX-XXXXXXXXX-debug.log +@azure/keyvault-keys ( ? seconds) +npm ERR! code ELIFECYCLE +npm ERR! errno 2 +npm ERR! @azure/keyvault-keys@X.X.X-preview.3 extract-api: `tsc -p . && api-extractor run --local` +npm ERR! Exit status 2 +npm ERR! +npm ERR! Failed at the @azure/keyvault-keys@X.X.X-preview.3 extract-api script. +npm ERR! This is probably not a problem with npm. There is likely additional logging output above. +npm ERR! A complete log of this run can be found in: +npm ERR! /root/.npm/_logs/XXXX-XX-XXXXXXXXX-debug.log +@azure/keyvault-secrets ( ? seconds) +npm ERR! code ELIFECYCLE +npm ERR! errno 2 +npm ERR! @azure/keyvault-secrets@X.X.X-preview.4 extract-api: `tsc -p . && api-extractor run --local` +npm ERR! Exit status 2 +npm ERR! +npm ERR! Failed at the @azure/keyvault-secrets@X.X.X-preview.4 extract-api script. +npm ERR! This is probably not a problem with npm. There is likely additional logging output above. +npm ERR! A complete log of this run can be found in: +npm ERR! /root/.npm/_logs/XXXX-XX-XXXXXXXXX-debug.log ================================ Error: Project(s) failed to build rush rebuild - Errors! ( ? seconds) @@ -98,14 +157,14 @@ rush rebuild - Errors! ( ? seconds) Standard error: +XX of XX: [@azure/core-amqp] failed to build! +XX of XX: [@azure/event-hubs] blocked by [@azure/core-amqp]! XX of XX: [@azure/core-http] failed to build! -XX of XX: [@azure/core-arm] blocked by [@azure/core-http]! -XX of XX: [@azure/keyvault-certificates] blocked by [@azure/core-http]! -XX of XX: [@azure/keyvault-keys] blocked by [@azure/core-http]! -XX of XX: [@azure/keyvault-secrets] blocked by [@azure/core-http]! -XX of XX: [@azure/identity] blocked by [@azure/core-http]! -XX of XX: [@azure/core-amqp] blocked by [@azure/core-http]! -XX of XX: [@azure/event-hubs] blocked by [@azure/core-http]! -XX of XX: [@azure/template] blocked by [@azure/core-http]! -XX of XX: [@azure/service-bus] completed with warnings in ? seconds +XX of XX: [@azure/keyvault-certificates] failed to build! +XX of XX: [@azure/keyvault-keys] failed to build! +XX of XX: [@azure/keyvault-secrets] failed to build! +[@azure/core-amqp] Returned error code: 2 [@azure/core-http] Returned error code: 1 +[@azure/keyvault-certificates] Returned error code: 2 +[@azure/keyvault-keys] Returned error code: 2 +[@azure/keyvault-secrets] Returned error code: 2 diff --git a/tests/baselines/reference/docker/office-ui-fabric.log b/tests/baselines/reference/docker/office-ui-fabric.log index 440a14e9044..506e180a5b8 100644 --- a/tests/baselines/reference/docker/office-ui-fabric.log +++ b/tests/baselines/reference/docker/office-ui-fabric.log @@ -426,7 +426,7 @@ lerna info Executing command in 40 packages: "yarn run build --production --lint @uifabric/foundation: [XX:XX:XX XM] x Error: Command failed: /usr/local/bin/node /office-ui-fabric-react/node_modules/jest/bin/jest.js --config /office-ui-fabric-react/packages/foundation/jest.config.js --passWithNoTests --colors @uifabric/foundation: at ChildProcess. (/office-ui-fabric-react/node_modules/just-scripts-utils/lib/exec.js:70:31) @uifabric/foundation: at ChildProcess.emit (events.js:203:13) -@uifabric/foundation: at ChildProcess.EventEmitter.emit (domain.js:494:23) +@uifabric/foundation: at ChildProcess.EventEmitter.emit (domain.js:499:23) @uifabric/foundation: at Process.ChildProcess._handle.onexit (internal/child_process.js:272:12) @uifabric/foundation: [XX:XX:XX XM] x ------------------------------------ @uifabric/foundation: [XX:XX:XX XM] x Error previously detected. See above for error messages. diff --git a/tests/baselines/reference/user/TypeScript-React-Native-Starter.log b/tests/baselines/reference/user/TypeScript-React-Native-Starter.log index 87439a7c4e6..51763a2b4b8 100644 --- a/tests/baselines/reference/user/TypeScript-React-Native-Starter.log +++ b/tests/baselines/reference/user/TypeScript-React-Native-Starter.log @@ -3,7 +3,7 @@ Standard output: node_modules/@types/react-native/index.d.ts(3425,42): error TS2583: Cannot find name 'Map'. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later. node_modules/@types/react-native/index.d.ts(3438,42): error TS2583: Cannot find name 'Map'. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later. node_modules/@types/react-native/index.d.ts(8745,18): error TS2717: Subsequent property declarations must have the same type. Property 'geolocation' must be of type 'Geolocation', but here has type 'GeolocationStatic'. -node_modules/@types/react/index.d.ts(377,23): error TS2583: Cannot find name 'Set'. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later. +node_modules/@types/react/index.d.ts(369,23): error TS2583: Cannot find name 'Set'. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later. diff --git a/tests/baselines/reference/user/async.log b/tests/baselines/reference/user/async.log index 18fb7988358..a64d3b22cb5 100644 --- a/tests/baselines/reference/user/async.log +++ b/tests/baselines/reference/user/async.log @@ -51,8 +51,6 @@ node_modules/async/autoInject.js(160,28): error TS2695: Left side of comma opera node_modules/async/autoInject.js(164,14): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/autoInject.js(168,6): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/cargo.js(62,12): error TS2304: Cannot find name 'AsyncFunction'. -node_modules/async/cargo.js(67,14): error TS2749: 'module' refers to a value, but is being used as a type here. -node_modules/async/cargo.js(67,20): error TS1005: '}' expected. node_modules/async/cargo.js(92,11): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/compose.js(8,37): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/compose.js(36,15): error TS2304: Cannot find name 'AsyncFunction'. @@ -123,8 +121,6 @@ node_modules/async/dist/async.js(1990,16): error TS2554: Expected 3 arguments, b node_modules/async/dist/async.js(2116,20): error TS2345: Argument of type 'Function | undefined' is not assignable to parameter of type 'number | undefined'. Type 'Function' is not assignable to type 'number'. node_modules/async/dist/async.js(2274,29): error TS2554: Expected 0 arguments, but got 2. -node_modules/async/dist/async.js(2425,20): error TS1005: '}' expected. -node_modules/async/dist/async.js(2450,5): error TS2740: Type '{ _tasks: DLL; concurrency: any; payload: any; saturated: () => void; unsaturated: () => void; buffer: number; empty: () => void; drain: () => void; error: () => void; started: boolean; paused: boolean; push: (data: any, callback: any) => void; ... 9 more ...; resume: () => void; }' is missing the following properties from type 'NodeModule': exports, require, id, filename, and 4 more. node_modules/async/dist/async.js(2521,9): error TS2722: Cannot invoke an object which is possibly 'undefined'. node_modules/async/dist/async.js(2564,31): error TS2345: Argument of type 'IArguments' is not assignable to parameter of type 'any[]'. Type 'IArguments' is missing the following properties from type 'any[]': pop, push, concat, join, and 26 more. @@ -157,17 +153,6 @@ node_modules/async/dist/async.js(3828,14): error TS2339: Property 'unmemoized' d node_modules/async/dist/async.js(3848,23): error TS1003: Identifier expected. node_modules/async/dist/async.js(3848,24): error TS1003: Identifier expected. node_modules/async/dist/async.js(3848,25): error TS1003: Identifier expected. -node_modules/async/dist/async.js(4059,20): error TS1005: '}' expected. -node_modules/async/dist/async.js(4095,5): error TS2322: Type '{ _tasks: DLL; concurrency: any; payload: any; saturated: () => void; unsaturated: () => void; buffer: number; empty: () => void; drain: () => void; error: () => void; started: boolean; paused: boolean; push: (data: any, callback: any) => void; ... 9 more ...; resume: () => void; }' is not assignable to type 'NodeModule'. -node_modules/async/dist/async.js(4117,20): error TS1005: '}' expected. -node_modules/async/dist/async.js(4128,7): error TS2339: Property 'push' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(4133,11): error TS2339: Property 'started' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(4140,19): error TS2339: Property 'drain' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(4145,26): error TS2339: Property '_tasks' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(4158,19): error TS2339: Property '_tasks' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(4160,19): error TS2339: Property '_tasks' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(4163,26): error TS2339: Property 'process' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(4167,14): error TS2339: Property 'unshift' does not exist on type 'NodeModule'. node_modules/async/dist/async.js(4381,5): error TS2322: Type 'any[] | {}' is not assignable to type 'any[]'. Type '{}' is missing the following properties from type 'any[]': length, pop, push, concat, and 28 more. node_modules/async/dist/async.js(4617,17): error TS2532: Object is possibly 'undefined'. @@ -581,11 +566,9 @@ node_modules/async/priorityQueue.js(18,15): error TS2695: Left side of comma ope node_modules/async/priorityQueue.js(23,21): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/priorityQueue.js(47,10): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/priorityQueue.js(86,12): error TS2304: Cannot find name 'AsyncFunction'. -node_modules/async/priorityQueue.js(93,20): error TS1005: '}' expected. node_modules/async/queue.js(8,18): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/queue.js(9,11): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/queue.js(91,12): error TS2304: Cannot find name 'AsyncFunction'. -node_modules/async/queue.js(97,20): error TS1005: '}' expected. node_modules/async/race.js(63,17): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/race.js(64,11): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/race.js(67,10): error TS2695: Left side of comma operator is unused and has no side effects. diff --git a/tests/baselines/reference/user/prettier.log b/tests/baselines/reference/user/prettier.log index ff4b267a459..713126ec61b 100644 --- a/tests/baselines/reference/user/prettier.log +++ b/tests/baselines/reference/user/prettier.log @@ -1,7 +1,7 @@ Exit Code: 1 Standard output: node_modules/@typescript-eslint/typescript-estree/dist/parser.d.ts(1,8): error TS1259: Module '"/prettier/prettier/node_modules/typescript/lib/typescript"' can only be default-imported using the 'esModuleInterop' flag -src/cli/util.js(60,44): error TS2345: Argument of type 'null' is not assignable to parameter of type 'number | undefined'. +src/cli/util.js(60,44): error TS2345: Argument of type 'null' is not assignable to parameter of type 'number'. src/cli/util.js(119,38): error TS2339: Property 'sync' does not exist on type '(...args: any[]) => any'. src/cli/util.js(372,29): error TS2532: Object is possibly 'undefined'. src/cli/util.js(372,64): error TS2339: Property 'length' does not exist on type 'Ignore'. @@ -9,7 +9,7 @@ src/cli/util.js(413,36): error TS2345: Argument of type '{ dot: true; nodir: boo Object literal may only specify known properties, and 'nodir' does not exist in type 'GlobbyOptions'. src/cli/util.js(452,25): error TS2532: Object is possibly 'undefined'. src/cli/util.js(452,52): error TS2339: Property 'length' does not exist on type 'Ignore'. -src/cli/util.js(510,44): error TS2345: Argument of type 'null' is not assignable to parameter of type 'number | undefined'. +src/cli/util.js(510,44): error TS2345: Argument of type 'null' is not assignable to parameter of type 'number'. src/cli/util.js(531,37): error TS2339: Property 'grey' does not exist on type 'typeof import("../../../node_modules/chalk/types/index")'. src/cli/util.js(594,16): error TS2339: Property 'type' does not exist on type 'never'. src/cli/util.js(595,16): error TS2339: Property 'oppositeDescription' does not exist on type 'never'. From a35f7996a63c2ab2c77746e984a00d1fb14fba19 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 13 Aug 2019 08:13:24 -0700 Subject: [PATCH 3/5] Do cleanup after opening files only if opening a file. --- src/server/editorServices.ts | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index a25256a3aec..9fd15333cc9 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -2705,8 +2705,6 @@ namespace ts.server { // It was then postponed to cleanup these script infos so that they can be reused if // the file from that old project is reopened because of opening file from here. this.removeOrphanScriptInfos(); - - this.printProjects(); } openClientFileWithNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, projectRootPath?: NormalizedPath): OpenConfiguredProjectResult { @@ -2714,6 +2712,7 @@ namespace ts.server { const { defaultConfigProject, ...result } = this.assignProjectToOpenedScriptInfo(info); this.cleanupAfterOpeningFile(defaultConfigProject); this.telemetryOnOpenFile(info); + this.printProjects(); return result; } @@ -2914,12 +2913,16 @@ namespace ts.server { this.assignOrphanScriptInfosToInferredProject(); } - // Cleanup projects - this.cleanupAfterOpeningFile(defaultConfigProjects); - - // Telemetry - forEach(openScriptInfos, info => this.telemetryOnOpenFile(info)); - this.printProjects(); + if (openScriptInfos) { + // Cleanup projects + this.cleanupAfterOpeningFile(defaultConfigProjects); + // Telemetry + openScriptInfos.forEach(info => this.telemetryOnOpenFile(info)); + this.printProjects(); + } + else if (length(closedFiles)) { + this.printProjects(); + } } /* @internal */ From c52b129a193581d168ae82c91d8e3a59f455c9c5 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 13 Aug 2019 11:40:00 -0700 Subject: [PATCH 4/5] Add cancellation token check for function expression, arrow expression and class expression just like their counter part declarations This helps in early exit if request is cancelled and intellisense in js files is super quick with edits --- src/compiler/checker.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 62308cbfbbf..9d6fa60306c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25271,7 +25271,18 @@ namespace ts { } function checkExpressionWorker(node: Expression | QualifiedName, checkMode: CheckMode | undefined, forceTuple?: boolean): Type { - switch (node.kind) { + const kind = node.kind; + if (cancellationToken) { + // Only bother checking on a few construct kinds. We don't want to be excessively + // hitting the cancellation token on every node we check. + switch (kind) { + case SyntaxKind.ClassExpression: + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: + cancellationToken.throwIfCancellationRequested(); + } + } + switch (kind) { case SyntaxKind.Identifier: return checkIdentifier(node); case SyntaxKind.ThisKeyword: From a74f109f95a43c70311ee551dd1c4a9b42fbd4f5 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 13 Aug 2019 15:54:35 -0700 Subject: [PATCH 5/5] Do not escape actual template literals on emit (#32844) --- src/compiler/factory.ts | 88 +++++++++++++++++-- src/compiler/parser.ts | 14 ++- src/compiler/transformers/es2015.ts | 19 ++-- src/compiler/types.ts | 12 ++- src/compiler/utilities.ts | 29 +++--- src/harness/evaluator.ts | 24 ++--- src/testRunner/unittests/transform.ts | 43 +++++++++ .../reference/api/tsserverlibrary.d.ts | 19 ++-- tests/baselines/reference/api/typescript.d.ts | 19 ++-- .../transformsCorrectly.templateSpans.js | 4 + 10 files changed, 209 insertions(+), 62 deletions(-) create mode 100644 tests/baselines/reference/transformApi/transformsCorrectly.templateSpans.js diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 8678ba4c122..d0d617b3495 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1329,27 +1329,97 @@ namespace ts { : node; } - export function createTemplateHead(text: string) { - const node = createSynthesizedNode(SyntaxKind.TemplateHead); + let rawTextScanner: Scanner | undefined; + const invalidValueSentinel: object = {}; + + function getCookedText(kind: TemplateLiteralToken["kind"], rawText: string) { + if (!rawTextScanner) { + rawTextScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, LanguageVariant.Standard); + } + switch (kind) { + case SyntaxKind.NoSubstitutionTemplateLiteral: + rawTextScanner.setText("`" + rawText + "`"); + break; + case SyntaxKind.TemplateHead: + // tslint:disable-next-line no-invalid-template-strings + rawTextScanner.setText("`" + rawText + "${"); + break; + case SyntaxKind.TemplateMiddle: + // tslint:disable-next-line no-invalid-template-strings + rawTextScanner.setText("}" + rawText + "${"); + break; + case SyntaxKind.TemplateTail: + rawTextScanner.setText("}" + rawText + "`"); + break; + } + + let token = rawTextScanner.scan(); + if (token === SyntaxKind.CloseBracketToken) { + token = rawTextScanner.reScanTemplateToken(); + } + + if (rawTextScanner.isUnterminated()) { + rawTextScanner.setText(undefined); + return invalidValueSentinel; + } + + let tokenValue: string | undefined; + switch (token) { + case SyntaxKind.NoSubstitutionTemplateLiteral: + case SyntaxKind.TemplateHead: + case SyntaxKind.TemplateMiddle: + case SyntaxKind.TemplateTail: + tokenValue = rawTextScanner.getTokenValue(); + break; + } + + if (rawTextScanner.scan() !== SyntaxKind.EndOfFileToken) { + rawTextScanner.setText(undefined); + return invalidValueSentinel; + } + + rawTextScanner.setText(undefined); + return tokenValue; + } + + function createTemplateLiteralLikeNode(kind: TemplateLiteralToken["kind"], text: string, rawText: string | undefined) { + const node = createSynthesizedNode(kind); + node.text = text; + if (rawText === undefined || text === rawText) { + node.rawText = rawText; + } + else { + const cooked = getCookedText(kind, rawText); + if (typeof cooked === "object") { + return Debug.fail("Invalid raw text"); + } + + Debug.assert(text === cooked, "Expected argument 'text' to be the normalized (i.e. 'cooked') version of argument 'rawText'."); + node.rawText = rawText; + } + return node; + } + + export function createTemplateHead(text: string, rawText?: string) { + const node = createTemplateLiteralLikeNode(SyntaxKind.TemplateHead, text, rawText); node.text = text; return node; } - export function createTemplateMiddle(text: string) { - const node = createSynthesizedNode(SyntaxKind.TemplateMiddle); + export function createTemplateMiddle(text: string, rawText?: string) { + const node = createTemplateLiteralLikeNode(SyntaxKind.TemplateMiddle, text, rawText); node.text = text; return node; } - export function createTemplateTail(text: string) { - const node = createSynthesizedNode(SyntaxKind.TemplateTail); + export function createTemplateTail(text: string, rawText?: string) { + const node = createTemplateLiteralLikeNode(SyntaxKind.TemplateTail, text, rawText); node.text = text; return node; } - export function createNoSubstitutionTemplateLiteral(text: string) { - const node = createSynthesizedNode(SyntaxKind.NoSubstitutionTemplateLiteral); - node.text = text; + export function createNoSubstitutionTemplateLiteral(text: string, rawText?: string) { + const node = createTemplateLiteralLikeNode(SyntaxKind.NoSubstitutionTemplateLiteral, text, rawText); return node; } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 6451a4f5c96..3ce7f411e24 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2300,9 +2300,19 @@ namespace ts { return fragment; } - function parseLiteralLikeNode(kind: SyntaxKind): LiteralExpression | LiteralLikeNode { - const node = createNode(kind); + function parseLiteralLikeNode(kind: SyntaxKind): LiteralLikeNode { + const node = createNode(kind); node.text = scanner.getTokenValue(); + switch (kind) { + case SyntaxKind.NoSubstitutionTemplateLiteral: + case SyntaxKind.TemplateHead: + case SyntaxKind.TemplateMiddle: + case SyntaxKind.TemplateTail: + const isLast = kind === SyntaxKind.NoSubstitutionTemplateLiteral || kind === SyntaxKind.TemplateTail; + const tokenText = scanner.getTokenText(); + (node).rawText = tokenText.substring(1, tokenText.length - (scanner.isUnterminated() ? 0 : isLast ? 1 : 2)); + break; + } if (scanner.hasExtendedUnicodeEscape()) { node.hasExtendedUnicodeEscape = true; diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 793f6e1b1ef..b86db737879 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -3993,18 +3993,21 @@ namespace ts { * * @param node The ES6 template literal. */ - function getRawLiteral(node: LiteralLikeNode) { + function getRawLiteral(node: TemplateLiteralLikeNode) { // Find original source text, since we need to emit the raw strings of the tagged template. // The raw strings contain the (escaped) strings of what the user wrote. // Examples: `\n` is converted to "\\n", a template string with a newline to "\n". - let text = getSourceTextOfNodeFromSourceFile(currentSourceFile, node); + let text = node.rawText; + if (text === undefined) { + text = getSourceTextOfNodeFromSourceFile(currentSourceFile, node); - // text contains the original source, it will also contain quotes ("`"), dolar signs and braces ("${" and "}"), - // thus we need to remove those characters. - // First template piece starts with "`", others with "}" - // Last template piece ends with "`", others with "${" - const isLast = node.kind === SyntaxKind.NoSubstitutionTemplateLiteral || node.kind === SyntaxKind.TemplateTail; - text = text.substring(1, text.length - (isLast ? 1 : 2)); + // text contains the original source, it will also contain quotes ("`"), dolar signs and braces ("${" and "}"), + // thus we need to remove those characters. + // First template piece starts with "`", others with "}" + // Last template piece ends with "`", others with "${" + const isLast = node.kind === SyntaxKind.NoSubstitutionTemplateLiteral || node.kind === SyntaxKind.TemplateTail; + text = text.substring(1, text.length - (isLast ? 1 : 2)); + } // Newline normalization: // ES6 Spec 11.8.6.1 - Static Semantics of TV's and TRV's diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a4373b7dc01..f50eb4d6399 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1646,6 +1646,10 @@ namespace ts { hasExtendedUnicodeEscape?: boolean; } + export interface TemplateLiteralLikeNode extends LiteralLikeNode { + rawText?: string; + } + // The text property of a LiteralExpression stores the interpreted value of the literal in text form. For a StringLiteral, // or any literal of a template, this means quotes have been removed and escapes have been converted to actual characters. // For a NumericLiteral, the stored value is the toString() representation of the number. For example 1, 1.00, and 1e0 are all stored as just "1". @@ -1657,7 +1661,7 @@ namespace ts { kind: SyntaxKind.RegularExpressionLiteral; } - export interface NoSubstitutionTemplateLiteral extends LiteralExpression { + export interface NoSubstitutionTemplateLiteral extends LiteralExpression, TemplateLiteralLikeNode { kind: SyntaxKind.NoSubstitutionTemplateLiteral; } @@ -1696,17 +1700,17 @@ namespace ts { kind: SyntaxKind.BigIntLiteral; } - export interface TemplateHead extends LiteralLikeNode { + export interface TemplateHead extends TemplateLiteralLikeNode { kind: SyntaxKind.TemplateHead; parent: TemplateExpression; } - export interface TemplateMiddle extends LiteralLikeNode { + export interface TemplateMiddle extends TemplateLiteralLikeNode { kind: SyntaxKind.TemplateMiddle; parent: TemplateSpan; } - export interface TemplateTail extends LiteralLikeNode { + export interface TemplateTail extends TemplateLiteralLikeNode { kind: SyntaxKind.TemplateTail; parent: TemplateSpan; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 0bb3c799af5..96acefdf135 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -566,8 +566,6 @@ namespace ts { return emitNode && emitNode.flags || 0; } - const escapeNoSubstitutionTemplateLiteralText = compose(escapeString, escapeTemplateSubstitution); - const escapeNonAsciiNoSubstitutionTemplateLiteralText = compose(escapeNonAsciiString, escapeTemplateSubstitution); export function getLiteralText(node: LiteralLikeNode, sourceFile: SourceFile, neverAsciiEscape: boolean | undefined) { // If we don't need to downlevel and we can reach the original source text using // the node's parent reference, then simply get the text as it was originally written. @@ -580,9 +578,7 @@ namespace ts { // If a NoSubstitutionTemplateLiteral appears to have a substitution in it, the original text // had to include a backslash: `not \${a} substitution`. - const escapeText = neverAsciiEscape || (getEmitFlags(node) & EmitFlags.NoAsciiEscaping) ? - node.kind === SyntaxKind.NoSubstitutionTemplateLiteral ? escapeNoSubstitutionTemplateLiteralText : escapeString : - node.kind === SyntaxKind.NoSubstitutionTemplateLiteral ? escapeNonAsciiNoSubstitutionTemplateLiteralText : escapeNonAsciiString; + const escapeText = neverAsciiEscape || (getEmitFlags(node) & EmitFlags.NoAsciiEscaping) ? escapeString : escapeNonAsciiString; // If we can't reach the original source text, use the canonical form if it's a number, // or a (possibly escaped) quoted form of the original text if it's string-like. @@ -595,15 +591,23 @@ namespace ts { return '"' + escapeText(node.text, CharacterCodes.doubleQuote) + '"'; } case SyntaxKind.NoSubstitutionTemplateLiteral: - return "`" + escapeText(node.text, CharacterCodes.backtick) + "`"; case SyntaxKind.TemplateHead: - // tslint:disable-next-line no-invalid-template-strings - return "`" + escapeText(node.text, CharacterCodes.backtick) + "${"; case SyntaxKind.TemplateMiddle: - // tslint:disable-next-line no-invalid-template-strings - return "}" + escapeText(node.text, CharacterCodes.backtick) + "${"; case SyntaxKind.TemplateTail: - return "}" + escapeText(node.text, CharacterCodes.backtick) + "`"; + const rawText = (node).rawText || escapeTemplateSubstitution(escapeText(node.text, CharacterCodes.backtick)); + switch (node.kind) { + case SyntaxKind.NoSubstitutionTemplateLiteral: + return "`" + rawText + "`"; + case SyntaxKind.TemplateHead: + // tslint:disable-next-line no-invalid-template-strings + return "`" + rawText + "${"; + case SyntaxKind.TemplateMiddle: + // tslint:disable-next-line no-invalid-template-strings + return "}" + rawText + "${"; + case SyntaxKind.TemplateTail: + return "}" + rawText + "`"; + } + break; case SyntaxKind.NumericLiteral: case SyntaxKind.BigIntLiteral: case SyntaxKind.RegularExpressionLiteral: @@ -3178,7 +3182,8 @@ namespace ts { // There is no reason for this other than that JSON.stringify does not handle it either. const doubleQuoteEscapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; const singleQuoteEscapedCharsRegExp = /[\\\'\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; - const backtickQuoteEscapedCharsRegExp = /[\\\`\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; + // Template strings should be preserved as much as possible + const backtickQuoteEscapedCharsRegExp = /[\\\`]/g; const escapedCharsMap = createMapFromTemplate({ "\t": "\\t", "\v": "\\v", diff --git a/src/harness/evaluator.ts b/src/harness/evaluator.ts index a22bdb958bc..c4cfc53069c 100644 --- a/src/harness/evaluator.ts +++ b/src/harness/evaluator.ts @@ -2,6 +2,7 @@ namespace evaluator { declare var Symbol: SymbolConstructor; const sourceFile = vpath.combine(vfs.srcFolder, "source.ts"); + const sourceFileJs = vpath.combine(vfs.srcFolder, "source.js"); function compile(sourceText: string, options?: ts.CompilerOptions) { const fs = vfs.createFromFileSystem(Harness.IO, /*ignoreCase*/ false); @@ -32,9 +33,8 @@ namespace evaluator { // Add "asyncIterator" if missing if (!ts.hasProperty(FakeSymbol, "asyncIterator")) Object.defineProperty(FakeSymbol, "asyncIterator", { value: Symbol.for("Symbol.asyncIterator"), configurable: true }); - function evaluate(result: compiler.CompilationResult, globals?: Record) { - globals = { Symbol: FakeSymbol, ...globals }; - + export function evaluateTypeScript(sourceText: string, options?: ts.CompilerOptions, globals?: Record) { + const result = compile(sourceText, options); if (ts.some(result.diagnostics)) { assert.ok(/*value*/ false, "Syntax error in evaluation source text:\n" + ts.formatDiagnostics(result.diagnostics, { getCanonicalFileName: file => file, @@ -46,6 +46,12 @@ namespace evaluator { const output = result.getOutput(sourceFile, "js")!; assert.isDefined(output); + return evaluateJavaScript(output.text, globals, output.file); + } + + export function evaluateJavaScript(sourceText: string, globals?: Record, sourceFile = sourceFileJs) { + globals = { Symbol: FakeSymbol, ...globals }; + const globalNames: string[] = []; const globalArgs: any[] = []; for (const name in globals) { @@ -55,15 +61,11 @@ namespace evaluator { } } - const evaluateText = `(function (module, exports, require, __dirname, __filename, ${globalNames.join(", ")}) { ${output.text} })`; - // tslint:disable-next-line:no-eval - const evaluateThunk = eval(evaluateText) as (module: any, exports: any, require: (id: string) => any, dirname: string, filename: string, ...globalArgs: any[]) => void; + const evaluateText = `(function (module, exports, require, __dirname, __filename, ${globalNames.join(", ")}) { ${sourceText} })`; + // tslint:disable-next-line:no-eval no-unused-expression + const evaluateThunk = (void 0, eval)(evaluateText) as (module: any, exports: any, require: (id: string) => any, dirname: string, filename: string, ...globalArgs: any[]) => void; const module: { exports: any; } = { exports: {} }; - evaluateThunk.call(globals, module, module.exports, noRequire, vpath.dirname(output.file), output.file, FakeSymbol, ...globalArgs); + evaluateThunk.call(globals, module, module.exports, noRequire, vpath.dirname(sourceFile), sourceFile, FakeSymbol, ...globalArgs); return module.exports; } - - export function evaluateTypeScript(sourceText: string, options?: ts.CompilerOptions, globals?: Record) { - return evaluate(compile(sourceText, options), globals); - } } \ No newline at end of file diff --git a/src/testRunner/unittests/transform.ts b/src/testRunner/unittests/transform.ts index 376b7d16ec8..35c3ab9a942 100644 --- a/src/testRunner/unittests/transform.ts +++ b/src/testRunner/unittests/transform.ts @@ -67,6 +67,24 @@ namespace ts { }); } + function testBaselineAndEvaluate(testName: string, test: () => string, onEvaluate: (exports: any) => void) { + describe(testName, () => { + let sourceText!: string; + before(() => { + sourceText = test(); + }); + after(() => { + sourceText = undefined!; + }); + it("compare baselines", () => { + Harness.Baseline.runBaseline(`transformApi/transformsCorrectly.${testName}.js`, sourceText); + }); + it("evaluate", () => { + onEvaluate(evaluator.evaluateJavaScript(sourceText)); + }); + }); + } + testBaseline("substitution", () => { return transformSourceFile(`var a = undefined;`, [replaceUndefinedWithVoid0]); }); @@ -440,6 +458,31 @@ namespace Foo { }); + testBaselineAndEvaluate("templateSpans", () => { + return transpileModule("const x = String.raw`\n\nhello`; exports.stringLength = x.trim().length;", { + compilerOptions: { + target: ScriptTarget.ESNext, + newLine: NewLineKind.CarriageReturnLineFeed, + }, + transformers: { + before: [transformSourceFile] + } + }).outputText; + + function transformSourceFile(context: TransformationContext): Transformer { + function visitor(node: Node): VisitResult { + if (isNoSubstitutionTemplateLiteral(node)) { + return createNoSubstitutionTemplateLiteral(node.text, node.rawText); + } + else { + return visitEachChild(node, visitor, context); + } + } + return sourceFile => visitNode(sourceFile, visitor, isSourceFile); + } + }, exports => { + assert.equal(exports.stringLength, 5); + }); }); } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 4c88e5fe219..c877d7d2d9a 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -997,13 +997,16 @@ declare namespace ts { isUnterminated?: boolean; hasExtendedUnicodeEscape?: boolean; } + export interface TemplateLiteralLikeNode extends LiteralLikeNode { + rawText?: string; + } export interface LiteralExpression extends LiteralLikeNode, PrimaryExpression { _literalExpressionBrand: any; } export interface RegularExpressionLiteral extends LiteralExpression { kind: SyntaxKind.RegularExpressionLiteral; } - export interface NoSubstitutionTemplateLiteral extends LiteralExpression { + export interface NoSubstitutionTemplateLiteral extends LiteralExpression, TemplateLiteralLikeNode { kind: SyntaxKind.NoSubstitutionTemplateLiteral; } export enum TokenFlags { @@ -1020,15 +1023,15 @@ declare namespace ts { export interface BigIntLiteral extends LiteralExpression { kind: SyntaxKind.BigIntLiteral; } - export interface TemplateHead extends LiteralLikeNode { + export interface TemplateHead extends TemplateLiteralLikeNode { kind: SyntaxKind.TemplateHead; parent: TemplateExpression; } - export interface TemplateMiddle extends LiteralLikeNode { + export interface TemplateMiddle extends TemplateLiteralLikeNode { kind: SyntaxKind.TemplateMiddle; parent: TemplateSpan; } - export interface TemplateTail extends LiteralLikeNode { + export interface TemplateTail extends TemplateLiteralLikeNode { kind: SyntaxKind.TemplateTail; parent: TemplateSpan; } @@ -3921,10 +3924,10 @@ declare namespace ts { function updateConditional(node: ConditionalExpression, condition: Expression, questionToken: Token, whenTrue: Expression, colonToken: Token, whenFalse: Expression): ConditionalExpression; function createTemplateExpression(head: TemplateHead, templateSpans: ReadonlyArray): TemplateExpression; function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: ReadonlyArray): TemplateExpression; - function createTemplateHead(text: string): TemplateHead; - function createTemplateMiddle(text: string): TemplateMiddle; - function createTemplateTail(text: string): TemplateTail; - function createNoSubstitutionTemplateLiteral(text: string): NoSubstitutionTemplateLiteral; + function createTemplateHead(text: string, rawText?: string): TemplateHead; + function createTemplateMiddle(text: string, rawText?: string): TemplateMiddle; + function createTemplateTail(text: string, rawText?: string): TemplateTail; + function createNoSubstitutionTemplateLiteral(text: string, rawText?: string): NoSubstitutionTemplateLiteral; function createYield(expression?: Expression): YieldExpression; function createYield(asteriskToken: AsteriskToken | undefined, expression: Expression): YieldExpression; function updateYield(node: YieldExpression, asteriskToken: AsteriskToken | undefined, expression: Expression): YieldExpression; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index bb30ccc908d..4c28abcbbc3 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -997,13 +997,16 @@ declare namespace ts { isUnterminated?: boolean; hasExtendedUnicodeEscape?: boolean; } + export interface TemplateLiteralLikeNode extends LiteralLikeNode { + rawText?: string; + } export interface LiteralExpression extends LiteralLikeNode, PrimaryExpression { _literalExpressionBrand: any; } export interface RegularExpressionLiteral extends LiteralExpression { kind: SyntaxKind.RegularExpressionLiteral; } - export interface NoSubstitutionTemplateLiteral extends LiteralExpression { + export interface NoSubstitutionTemplateLiteral extends LiteralExpression, TemplateLiteralLikeNode { kind: SyntaxKind.NoSubstitutionTemplateLiteral; } export enum TokenFlags { @@ -1020,15 +1023,15 @@ declare namespace ts { export interface BigIntLiteral extends LiteralExpression { kind: SyntaxKind.BigIntLiteral; } - export interface TemplateHead extends LiteralLikeNode { + export interface TemplateHead extends TemplateLiteralLikeNode { kind: SyntaxKind.TemplateHead; parent: TemplateExpression; } - export interface TemplateMiddle extends LiteralLikeNode { + export interface TemplateMiddle extends TemplateLiteralLikeNode { kind: SyntaxKind.TemplateMiddle; parent: TemplateSpan; } - export interface TemplateTail extends LiteralLikeNode { + export interface TemplateTail extends TemplateLiteralLikeNode { kind: SyntaxKind.TemplateTail; parent: TemplateSpan; } @@ -3921,10 +3924,10 @@ declare namespace ts { function updateConditional(node: ConditionalExpression, condition: Expression, questionToken: Token, whenTrue: Expression, colonToken: Token, whenFalse: Expression): ConditionalExpression; function createTemplateExpression(head: TemplateHead, templateSpans: ReadonlyArray): TemplateExpression; function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: ReadonlyArray): TemplateExpression; - function createTemplateHead(text: string): TemplateHead; - function createTemplateMiddle(text: string): TemplateMiddle; - function createTemplateTail(text: string): TemplateTail; - function createNoSubstitutionTemplateLiteral(text: string): NoSubstitutionTemplateLiteral; + function createTemplateHead(text: string, rawText?: string): TemplateHead; + function createTemplateMiddle(text: string, rawText?: string): TemplateMiddle; + function createTemplateTail(text: string, rawText?: string): TemplateTail; + function createNoSubstitutionTemplateLiteral(text: string, rawText?: string): NoSubstitutionTemplateLiteral; function createYield(expression?: Expression): YieldExpression; function createYield(asteriskToken: AsteriskToken | undefined, expression: Expression): YieldExpression; function updateYield(node: YieldExpression, asteriskToken: AsteriskToken | undefined, expression: Expression): YieldExpression; diff --git a/tests/baselines/reference/transformApi/transformsCorrectly.templateSpans.js b/tests/baselines/reference/transformApi/transformsCorrectly.templateSpans.js new file mode 100644 index 00000000000..00c8f992444 --- /dev/null +++ b/tests/baselines/reference/transformApi/transformsCorrectly.templateSpans.js @@ -0,0 +1,4 @@ +const x = String.raw ` + +hello`; +exports.stringLength = x.trim().length;