From e1bca8ff2a077931e6fdd569663118782378adc3 Mon Sep 17 00:00:00 2001 From: xiaofa Date: Tue, 6 Aug 2019 08:35:34 +0800 Subject: [PATCH 01/11] 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 bf054ae79691a82136f73f1340dc133ea8769622 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 12 Aug 2019 13:00:58 -0700 Subject: [PATCH 02/11] Add support for import.meta in System modules (#32797) --- src/compiler/checker.ts | 4 +- src/compiler/diagnosticMessages.json | 2 +- src/compiler/transformers/module/system.ts | 16 +- src/compiler/types.ts | 6 + src/compiler/utilities.ts | 6 + ...ta(module=commonjs,target=es5).errors.txt} | 52 +++--- ...importMeta(module=commonjs,target=es5).js} | 2 +- ...tMeta(module=commonjs,target=es5).symbols} | 0 ...ortMeta(module=commonjs,target=es5).types} | 0 ...(module=commonjs,target=esnext).errors.txt | 110 ++++++++++++ ...portMeta(module=commonjs,target=esnext).js | 71 ++++++++ ...ta(module=commonjs,target=esnext).symbols} | 0 ...Meta(module=commonjs,target=esnext).types} | 0 ...Meta(module=esnext,target=es5).errors.txt} | 0 .../importMeta(module=esnext,target=es5).js | 110 ++++++++++++ ...portMeta(module=esnext,target=es5).symbols | 101 +++++++++++ ...importMeta(module=esnext,target=es5).types | 166 ++++++++++++++++++ ...ta(module=esnext,target=esnext).errors.txt | 71 ++++++++ ...mportMeta(module=esnext,target=esnext).js} | 0 ...tMeta(module=esnext,target=esnext).symbols | 101 +++++++++++ ...ortMeta(module=esnext,target=esnext).types | 166 ++++++++++++++++++ ...tMeta(module=system,target=es5).errors.txt | 71 ++++++++ .../importMeta(module=system,target=es5).js | 150 ++++++++++++++++ ...portMeta(module=system,target=es5).symbols | 101 +++++++++++ ...importMeta(module=system,target=es5).types | 166 ++++++++++++++++++ ...ta(module=system,target=esnext).errors.txt | 71 ++++++++ ...importMeta(module=system,target=esnext).js | 102 +++++++++++ ...tMeta(module=system,target=esnext).symbols | 101 +++++++++++ ...ortMeta(module=system,target=esnext).types | 166 ++++++++++++++++++ .../es2019/importMeta/importMeta.ts | 4 +- .../es2019/importMeta/importMetaES5.ts | 42 ----- 31 files changed, 1883 insertions(+), 75 deletions(-) rename tests/baselines/reference/{importMetaES5.errors.txt => importMeta(module=commonjs,target=es5).errors.txt} (79%) rename tests/baselines/reference/{importMetaES5.js => importMeta(module=commonjs,target=es5).js} (97%) rename tests/baselines/reference/{importMeta.symbols => importMeta(module=commonjs,target=es5).symbols} (100%) rename tests/baselines/reference/{importMeta.types => importMeta(module=commonjs,target=es5).types} (100%) create mode 100644 tests/baselines/reference/importMeta(module=commonjs,target=esnext).errors.txt create mode 100644 tests/baselines/reference/importMeta(module=commonjs,target=esnext).js rename tests/baselines/reference/{importMetaES5.symbols => importMeta(module=commonjs,target=esnext).symbols} (100%) rename tests/baselines/reference/{importMetaES5.types => importMeta(module=commonjs,target=esnext).types} (100%) rename tests/baselines/reference/{importMeta.errors.txt => importMeta(module=esnext,target=es5).errors.txt} (100%) create mode 100644 tests/baselines/reference/importMeta(module=esnext,target=es5).js create mode 100644 tests/baselines/reference/importMeta(module=esnext,target=es5).symbols create mode 100644 tests/baselines/reference/importMeta(module=esnext,target=es5).types create mode 100644 tests/baselines/reference/importMeta(module=esnext,target=esnext).errors.txt rename tests/baselines/reference/{importMeta.js => importMeta(module=esnext,target=esnext).js} (100%) create mode 100644 tests/baselines/reference/importMeta(module=esnext,target=esnext).symbols create mode 100644 tests/baselines/reference/importMeta(module=esnext,target=esnext).types create mode 100644 tests/baselines/reference/importMeta(module=system,target=es5).errors.txt create mode 100644 tests/baselines/reference/importMeta(module=system,target=es5).js create mode 100644 tests/baselines/reference/importMeta(module=system,target=es5).symbols create mode 100644 tests/baselines/reference/importMeta(module=system,target=es5).types create mode 100644 tests/baselines/reference/importMeta(module=system,target=esnext).errors.txt create mode 100644 tests/baselines/reference/importMeta(module=system,target=esnext).js create mode 100644 tests/baselines/reference/importMeta(module=system,target=esnext).symbols create mode 100644 tests/baselines/reference/importMeta(module=system,target=esnext).types delete mode 100644 tests/cases/conformance/es2019/importMeta/importMetaES5.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 65f550cb664..62308cbfbbf 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -23161,8 +23161,8 @@ namespace ts { } function checkImportMetaProperty(node: MetaProperty) { - if (languageVersion < ScriptTarget.ESNext || moduleKind < ModuleKind.ESNext) { - error(node, Diagnostics.The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_options); + if (moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.System) { + error(node, Diagnostics.The_import_meta_meta_property_is_only_allowed_when_the_module_option_is_esnext_or_system); } const file = getSourceFileOfNode(node); Debug.assert(!!(file.flags & NodeFlags.PossiblyContainsImportMeta), "Containing file is missing import meta node flag."); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 5cca456dd49..e22d64e0f72 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -979,7 +979,7 @@ "category": "Error", "code": 1342 }, - "The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.": { + "The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.": { "category": "Error", "code": 1343 }, diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index ae303440bc1..0607e8c77c7 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -24,12 +24,14 @@ namespace ts { context.enableSubstitution(SyntaxKind.BinaryExpression); // Substitutes assignments to exported symbols. context.enableSubstitution(SyntaxKind.PrefixUnaryExpression); // Substitutes updates to exported symbols. context.enableSubstitution(SyntaxKind.PostfixUnaryExpression); // Substitutes updates to exported symbols. + context.enableSubstitution(SyntaxKind.MetaProperty); // Substitutes 'import.meta' context.enableEmitNotification(SyntaxKind.SourceFile); // Restore state when substituting nodes in a file. const moduleInfoMap: ExternalModuleInfo[] = []; // The ExternalModuleInfo for each file. const deferredExports: (Statement[] | undefined)[] = []; // Exports to defer until an EndOfDeclarationMarker is found. const exportFunctionsMap: Identifier[] = []; // The export function associated with a source file. const noSubstitutionMap: boolean[][] = []; // Set of nodes for which substitution rules should be ignored for each file. + const contextObjectMap: Identifier[] = []; // The context object associated with a source file. let currentSourceFile: SourceFile; // The current file. let moduleInfo: ExternalModuleInfo; // ExternalModuleInfo for the current file. @@ -75,7 +77,7 @@ namespace ts { // existing identifiers. exportFunction = createUniqueName("exports"); exportFunctionsMap[id] = exportFunction; - contextObject = createUniqueName("context"); + contextObject = contextObjectMap[id] = createUniqueName("context"); // Add the body of the module. const dependencyGroups = collectDependencyGroups(moduleInfo.externalImports); @@ -1586,6 +1588,7 @@ namespace ts { moduleInfo = moduleInfoMap[id]; exportFunction = exportFunctionsMap[id]; noSubstitution = noSubstitutionMap[id]; + contextObject = contextObjectMap[id]; if (noSubstitution) { delete noSubstitutionMap[id]; @@ -1596,6 +1599,7 @@ namespace ts { currentSourceFile = undefined!; moduleInfo = undefined!; exportFunction = undefined!; + contextObject = undefined!; noSubstitution = undefined; } else { @@ -1641,6 +1645,7 @@ namespace ts { } return node; } + /** * Substitution for a ShorthandPropertyAssignment whose name that may contain an imported or exported symbol. * @@ -1694,6 +1699,8 @@ namespace ts { case SyntaxKind.PrefixUnaryExpression: case SyntaxKind.PostfixUnaryExpression: return substituteUnaryExpression(node); + case SyntaxKind.MetaProperty: + return substituteMetaProperty(node); } return node; @@ -1830,6 +1837,13 @@ namespace ts { return node; } + function substituteMetaProperty(node: MetaProperty) { + if (isImportMeta(node)) { + return createPropertyAccess(contextObject, createIdentifier("meta")); + } + return node; + } + /** * Gets the exports of a name. * diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b04cac47143..02dcc828486 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1864,6 +1864,12 @@ namespace ts { name: Identifier; } + /* @internal */ + export interface ImportMetaProperty extends MetaProperty { + keywordToken: SyntaxKind.ImportKeyword; + name: Identifier & { escapedText: __String & "meta" }; + } + /// A JSX expression of the form ... export interface JsxElement extends PrimaryExpression { kind: SyntaxKind.JsxElement; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 02ca57919c9..c020c1e859e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -987,6 +987,12 @@ namespace ts { return n.kind === SyntaxKind.CallExpression && (n).expression.kind === SyntaxKind.ImportKeyword; } + export function isImportMeta(n: Node): n is ImportMetaProperty { + return isMetaProperty(n) + && n.keywordToken === SyntaxKind.ImportKeyword + && n.name.escapedText === "meta"; + } + export function isLiteralImportTypeNode(n: Node): n is LiteralImportTypeNode { return isImportTypeNode(n) && isLiteralTypeNode(n.argument) && isStringLiteral(n.argument.literal); } diff --git a/tests/baselines/reference/importMetaES5.errors.txt b/tests/baselines/reference/importMeta(module=commonjs,target=es5).errors.txt similarity index 79% rename from tests/baselines/reference/importMetaES5.errors.txt rename to tests/baselines/reference/importMeta(module=commonjs,target=es5).errors.txt index 71b67efae01..6642c54ac48 100644 --- a/tests/baselines/reference/importMetaES5.errors.txt +++ b/tests/baselines/reference/importMeta(module=commonjs,target=es5).errors.txt @@ -1,26 +1,26 @@ error TS2468: Cannot find global value 'Promise'. -tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,32): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,32): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,44): error TS2339: Property 'blah' does not exist on type 'ImportMeta'. -tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,51): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,51): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,63): error TS2339: Property 'blue' does not exist on type 'ImportMeta'. -tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,70): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. -tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(2,1): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,70): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(2,1): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(2,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. -tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(11,21): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(11,21): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. tests/cases/conformance/es2019/importMeta/example.ts(2,2): error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. -tests/cases/conformance/es2019/importMeta/example.ts(3,59): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/example.ts(3,59): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. tests/cases/conformance/es2019/importMeta/example.ts(3,71): error TS2339: Property 'url' does not exist on type 'ImportMeta'. -tests/cases/conformance/es2019/importMeta/example.ts(6,16): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/example.ts(6,16): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. tests/cases/conformance/es2019/importMeta/example.ts(6,28): error TS2339: Property 'scriptElement' does not exist on type 'ImportMeta'. -tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(1,16): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. -tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,16): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(1,16): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,16): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,23): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? -tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,16): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,16): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,23): error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? -tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(1,15): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. -tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(2,15): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(1,15): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(2,15): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(2,22): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? -tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,15): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,15): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? @@ -32,14 +32,14 @@ tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS !!! error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); ~~~~~~~~~~~ -!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. ~~~ !!! error TS2339: Property 'url' does not exist on type 'ImportMeta'. const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; ~~~~~~~~~~~ -!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. ~~~~~~~~~~~~~ !!! error TS2339: Property 'scriptElement' does not exist on type 'ImportMeta'. @@ -53,48 +53,48 @@ tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS ==== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts (5 errors) ==== export let x = import.meta; ~~~~~~~~~~~ -!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. export let y = import.metal; ~~~~~~~~~~~~ -!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. ~~~~~ !!! error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? export let z = import.import.import.malkovich; ~~~~~~~~~~~~~ -!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. ~~~~~~ !!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? ==== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts (5 errors) ==== let globalA = import.meta; ~~~~~~~~~~~ -!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. let globalB = import.metal; ~~~~~~~~~~~~ -!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. ~~~~~ !!! error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? let globalC = import.import.import.malkovich; ~~~~~~~~~~~~~ -!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. ~~~~~~ !!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? ==== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts (8 errors) ==== export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; ~~~~~~~~~~~ -!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. ~~~~ !!! error TS2339: Property 'blah' does not exist on type 'ImportMeta'. ~~~~~~~~~~~ -!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. ~~~~ !!! error TS2339: Property 'blue' does not exist on type 'ImportMeta'. ~~~~~~~~~~~ -!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. import.meta = foo; ~~~~~~~~~~~ -!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. ~~~~~~~~~~~ !!! error TS2364: The left-hand side of an assignment expression must be a variable or a property access. @@ -107,4 +107,4 @@ tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS const { a, b, c } = import.meta.wellKnownProperty; ~~~~~~~~~~~ -!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. \ No newline at end of file +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. \ No newline at end of file diff --git a/tests/baselines/reference/importMetaES5.js b/tests/baselines/reference/importMeta(module=commonjs,target=es5).js similarity index 97% rename from tests/baselines/reference/importMetaES5.js rename to tests/baselines/reference/importMeta(module=commonjs,target=es5).js index 6b69557e419..1a8c764dd32 100644 --- a/tests/baselines/reference/importMetaES5.js +++ b/tests/baselines/reference/importMeta(module=commonjs,target=es5).js @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/es2019/importMeta/importMetaES5.ts] //// +//// [tests/cases/conformance/es2019/importMeta/importMeta.ts] //// //// [example.ts] // Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example diff --git a/tests/baselines/reference/importMeta.symbols b/tests/baselines/reference/importMeta(module=commonjs,target=es5).symbols similarity index 100% rename from tests/baselines/reference/importMeta.symbols rename to tests/baselines/reference/importMeta(module=commonjs,target=es5).symbols diff --git a/tests/baselines/reference/importMeta.types b/tests/baselines/reference/importMeta(module=commonjs,target=es5).types similarity index 100% rename from tests/baselines/reference/importMeta.types rename to tests/baselines/reference/importMeta(module=commonjs,target=es5).types diff --git a/tests/baselines/reference/importMeta(module=commonjs,target=esnext).errors.txt b/tests/baselines/reference/importMeta(module=commonjs,target=esnext).errors.txt new file mode 100644 index 00000000000..6642c54ac48 --- /dev/null +++ b/tests/baselines/reference/importMeta(module=commonjs,target=esnext).errors.txt @@ -0,0 +1,110 @@ +error TS2468: Cannot find global value 'Promise'. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,32): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,44): error TS2339: Property 'blah' does not exist on type 'ImportMeta'. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,51): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,63): error TS2339: Property 'blue' does not exist on type 'ImportMeta'. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,70): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(2,1): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(2,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(11,21): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. +tests/cases/conformance/es2019/importMeta/example.ts(2,2): error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. +tests/cases/conformance/es2019/importMeta/example.ts(3,59): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. +tests/cases/conformance/es2019/importMeta/example.ts(3,71): error TS2339: Property 'url' does not exist on type 'ImportMeta'. +tests/cases/conformance/es2019/importMeta/example.ts(6,16): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. +tests/cases/conformance/es2019/importMeta/example.ts(6,28): error TS2339: Property 'scriptElement' does not exist on type 'ImportMeta'. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(1,16): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,16): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,23): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,16): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,23): error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(1,15): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(2,15): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(2,22): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,15): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + + +!!! error TS2468: Cannot find global value 'Promise'. +==== tests/cases/conformance/es2019/importMeta/example.ts (5 errors) ==== + // Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example + (async () => { + ~~~~~~~~~~~~~ +!!! error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); + ~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. + ~~~ +!!! error TS2339: Property 'url' does not exist on type 'ImportMeta'. + const blob = await response.blob(); + + const size = import.meta.scriptElement.dataset.size || 300; + ~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'scriptElement' does not exist on type 'ImportMeta'. + + const image = new Image(); + image.src = URL.createObjectURL(blob); + image.width = image.height = size; + + document.body.appendChild(image); + })(); + +==== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts (5 errors) ==== + export let x = import.meta; + ~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. + export let y = import.metal; + ~~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. + ~~~~~ +!!! error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + export let z = import.import.import.malkovich; + ~~~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. + ~~~~~~ +!!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + +==== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts (5 errors) ==== + let globalA = import.meta; + ~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. + let globalB = import.metal; + ~~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. + ~~~~~ +!!! error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + let globalC = import.import.import.malkovich; + ~~~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. + ~~~~~~ +!!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + +==== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts (8 errors) ==== + export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; + ~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. + ~~~~ +!!! error TS2339: Property 'blah' does not exist on type 'ImportMeta'. + ~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. + ~~~~ +!!! error TS2339: Property 'blue' does not exist on type 'ImportMeta'. + ~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. + import.meta = foo; + ~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. + ~~~~~~~~~~~ +!!! error TS2364: The left-hand side of an assignment expression must be a variable or a property access. + + // @Filename augmentations.ts + declare global { + interface ImportMeta { + wellKnownProperty: { a: number, b: string, c: boolean }; + } + } + + const { a, b, c } = import.meta.wellKnownProperty; + ~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'. \ No newline at end of file diff --git a/tests/baselines/reference/importMeta(module=commonjs,target=esnext).js b/tests/baselines/reference/importMeta(module=commonjs,target=esnext).js new file mode 100644 index 00000000000..15dcfe01d29 --- /dev/null +++ b/tests/baselines/reference/importMeta(module=commonjs,target=esnext).js @@ -0,0 +1,71 @@ +//// [tests/cases/conformance/es2019/importMeta/importMeta.ts] //// + +//// [example.ts] +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(async () => { + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); + const blob = await response.blob(); + + const size = import.meta.scriptElement.dataset.size || 300; + + const image = new Image(); + image.src = URL.createObjectURL(blob); + image.width = image.height = size; + + document.body.appendChild(image); +})(); + +//// [moduleLookingFile01.ts] +export let x = import.meta; +export let y = import.metal; +export let z = import.import.import.malkovich; + +//// [scriptLookingFile01.ts] +let globalA = import.meta; +let globalB = import.metal; +let globalC = import.import.import.malkovich; + +//// [assignmentTargets.ts] +export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; +import.meta = foo; + +// @Filename augmentations.ts +declare global { + interface ImportMeta { + wellKnownProperty: { a: number, b: string, c: boolean }; + } +} + +const { a, b, c } = import.meta.wellKnownProperty; + +//// [example.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(async () => { + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); + const blob = await response.blob(); + const size = import.meta.scriptElement.dataset.size || 300; + const image = new Image(); + image.src = URL.createObjectURL(blob); + image.width = image.height = size; + document.body.appendChild(image); +})(); +//// [moduleLookingFile01.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.x = (import.meta); +exports.y = (import.metal); +exports.z = import.import.import.malkovich; +//// [scriptLookingFile01.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +let globalA = import.meta; +let globalB = import.metal; +let globalC = import.import.import.malkovich; +//// [assignmentTargets.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.foo = import.meta.blah = import.meta.blue = import.meta; +import.meta = exports.foo; +const { a, b, c } = import.meta.wellKnownProperty; diff --git a/tests/baselines/reference/importMetaES5.symbols b/tests/baselines/reference/importMeta(module=commonjs,target=esnext).symbols similarity index 100% rename from tests/baselines/reference/importMetaES5.symbols rename to tests/baselines/reference/importMeta(module=commonjs,target=esnext).symbols diff --git a/tests/baselines/reference/importMetaES5.types b/tests/baselines/reference/importMeta(module=commonjs,target=esnext).types similarity index 100% rename from tests/baselines/reference/importMetaES5.types rename to tests/baselines/reference/importMeta(module=commonjs,target=esnext).types diff --git a/tests/baselines/reference/importMeta.errors.txt b/tests/baselines/reference/importMeta(module=esnext,target=es5).errors.txt similarity index 100% rename from tests/baselines/reference/importMeta.errors.txt rename to tests/baselines/reference/importMeta(module=esnext,target=es5).errors.txt diff --git a/tests/baselines/reference/importMeta(module=esnext,target=es5).js b/tests/baselines/reference/importMeta(module=esnext,target=es5).js new file mode 100644 index 00000000000..57a51318e25 --- /dev/null +++ b/tests/baselines/reference/importMeta(module=esnext,target=es5).js @@ -0,0 +1,110 @@ +//// [tests/cases/conformance/es2019/importMeta/importMeta.ts] //// + +//// [example.ts] +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(async () => { + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); + const blob = await response.blob(); + + const size = import.meta.scriptElement.dataset.size || 300; + + const image = new Image(); + image.src = URL.createObjectURL(blob); + image.width = image.height = size; + + document.body.appendChild(image); +})(); + +//// [moduleLookingFile01.ts] +export let x = import.meta; +export let y = import.metal; +export let z = import.import.import.malkovich; + +//// [scriptLookingFile01.ts] +let globalA = import.meta; +let globalB = import.metal; +let globalC = import.import.import.malkovich; + +//// [assignmentTargets.ts] +export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; +import.meta = foo; + +// @Filename augmentations.ts +declare global { + interface ImportMeta { + wellKnownProperty: { a: number, b: string, c: boolean }; + } +} + +const { a, b, c } = import.meta.wellKnownProperty; + +//// [example.js] +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var _this = this; +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(function () { return __awaiter(_this, void 0, void 0, function () { + var response, blob, size, image; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, fetch(new URL("../hamsters.jpg", import.meta.url).toString())]; + case 1: + response = _a.sent(); + return [4 /*yield*/, response.blob()]; + case 2: + blob = _a.sent(); + size = import.meta.scriptElement.dataset.size || 300; + image = new Image(); + image.src = URL.createObjectURL(blob); + image.width = image.height = size; + document.body.appendChild(image); + return [2 /*return*/]; + } + }); +}); })(); +//// [moduleLookingFile01.js] +export var x = import.meta; +export var y = import.metal; +export var z = import.import.import.malkovich; +//// [scriptLookingFile01.js] +var globalA = import.meta; +var globalB = import.metal; +var globalC = import.import.import.malkovich; +//// [assignmentTargets.js] +export var foo = import.meta.blah = import.meta.blue = import.meta; +import.meta = foo; +var _a = import.meta.wellKnownProperty, a = _a.a, b = _a.b, c = _a.c; diff --git a/tests/baselines/reference/importMeta(module=esnext,target=es5).symbols b/tests/baselines/reference/importMeta(module=esnext,target=es5).symbols new file mode 100644 index 00000000000..d21785639ed --- /dev/null +++ b/tests/baselines/reference/importMeta(module=esnext,target=es5).symbols @@ -0,0 +1,101 @@ +=== tests/cases/conformance/es2019/importMeta/example.ts === +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(async () => { + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); +>response : Symbol(response, Decl(example.ts, 2, 7)) +>fetch : Symbol(fetch, Decl(lib.dom.d.ts, --, --)) +>new URL("../hamsters.jpg", import.meta.url).toString : Symbol(Object.toString, Decl(lib.es5.d.ts, --, --)) +>URL : Symbol(URL, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>toString : Symbol(Object.toString, Decl(lib.es5.d.ts, --, --)) + + const blob = await response.blob(); +>blob : Symbol(blob, Decl(example.ts, 3, 7)) +>response.blob : Symbol(Body.blob, Decl(lib.dom.d.ts, --, --)) +>response : Symbol(response, Decl(example.ts, 2, 7)) +>blob : Symbol(Body.blob, Decl(lib.dom.d.ts, --, --)) + + const size = import.meta.scriptElement.dataset.size || 300; +>size : Symbol(size, Decl(example.ts, 5, 7)) + + const image = new Image(); +>image : Symbol(image, Decl(example.ts, 7, 7)) +>Image : Symbol(Image, Decl(lib.dom.d.ts, --, --)) + + image.src = URL.createObjectURL(blob); +>image.src : Symbol(HTMLImageElement.src, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) +>src : Symbol(HTMLImageElement.src, Decl(lib.dom.d.ts, --, --)) +>URL.createObjectURL : Symbol(createObjectURL, Decl(lib.dom.d.ts, --, --)) +>URL : Symbol(URL, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>createObjectURL : Symbol(createObjectURL, Decl(lib.dom.d.ts, --, --)) +>blob : Symbol(blob, Decl(example.ts, 3, 7)) + + image.width = image.height = size; +>image.width : Symbol(HTMLImageElement.width, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) +>width : Symbol(HTMLImageElement.width, Decl(lib.dom.d.ts, --, --)) +>image.height : Symbol(HTMLImageElement.height, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) +>height : Symbol(HTMLImageElement.height, Decl(lib.dom.d.ts, --, --)) +>size : Symbol(size, Decl(example.ts, 5, 7)) + + document.body.appendChild(image); +>document.body.appendChild : Symbol(Node.appendChild, Decl(lib.dom.d.ts, --, --)) +>document.body : Symbol(Document.body, Decl(lib.dom.d.ts, --, --)) +>document : Symbol(document, Decl(lib.dom.d.ts, --, --)) +>body : Symbol(Document.body, Decl(lib.dom.d.ts, --, --)) +>appendChild : Symbol(Node.appendChild, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) + +})(); + +=== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts === +export let x = import.meta; +>x : Symbol(x, Decl(moduleLookingFile01.ts, 0, 10)) + +export let y = import.metal; +>y : Symbol(y, Decl(moduleLookingFile01.ts, 1, 10)) + +export let z = import.import.import.malkovich; +>z : Symbol(z, Decl(moduleLookingFile01.ts, 2, 10)) + +=== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts === +let globalA = import.meta; +>globalA : Symbol(globalA, Decl(scriptLookingFile01.ts, 0, 3)) + +let globalB = import.metal; +>globalB : Symbol(globalB, Decl(scriptLookingFile01.ts, 1, 3)) + +let globalC = import.import.import.malkovich; +>globalC : Symbol(globalC, Decl(scriptLookingFile01.ts, 2, 3)) + +=== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts === +export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; +>foo : Symbol(foo, Decl(assignmentTargets.ts, 0, 12)) +>ImportMeta : Symbol(ImportMeta, Decl(lib.es5.d.ts, --, --), Decl(assignmentTargets.ts, 4, 16)) + +import.meta = foo; +>foo : Symbol(foo, Decl(assignmentTargets.ts, 0, 12)) + +// @Filename augmentations.ts +declare global { +>global : Symbol(global, Decl(assignmentTargets.ts, 1, 18)) + + interface ImportMeta { +>ImportMeta : Symbol(ImportMeta, Decl(lib.es5.d.ts, --, --), Decl(assignmentTargets.ts, 4, 16)) + + wellKnownProperty: { a: number, b: string, c: boolean }; +>wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24)) +>a : Symbol(a, Decl(assignmentTargets.ts, 6, 24)) +>b : Symbol(b, Decl(assignmentTargets.ts, 6, 35)) +>c : Symbol(c, Decl(assignmentTargets.ts, 6, 46)) + } +} + +const { a, b, c } = import.meta.wellKnownProperty; +>a : Symbol(a, Decl(assignmentTargets.ts, 10, 7)) +>b : Symbol(b, Decl(assignmentTargets.ts, 10, 10)) +>c : Symbol(c, Decl(assignmentTargets.ts, 10, 13)) +>import.meta.wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24)) +>wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24)) + diff --git a/tests/baselines/reference/importMeta(module=esnext,target=es5).types b/tests/baselines/reference/importMeta(module=esnext,target=es5).types new file mode 100644 index 00000000000..78d2e3395c8 --- /dev/null +++ b/tests/baselines/reference/importMeta(module=esnext,target=es5).types @@ -0,0 +1,166 @@ +=== tests/cases/conformance/es2019/importMeta/example.ts === +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(async () => { +>(async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);})() : Promise +>(async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);}) : () => Promise +>async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);} : () => Promise + + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); +>response : Response +>await fetch(new URL("../hamsters.jpg", import.meta.url).toString()) : Response +>fetch(new URL("../hamsters.jpg", import.meta.url).toString()) : Promise +>fetch : (input: RequestInfo, init?: RequestInit) => Promise +>new URL("../hamsters.jpg", import.meta.url).toString() : string +>new URL("../hamsters.jpg", import.meta.url).toString : () => string +>new URL("../hamsters.jpg", import.meta.url) : URL +>URL : { new (url: string, base?: string | URL): URL; prototype: URL; createObjectURL(object: any): string; revokeObjectURL(url: string): void; } +>"../hamsters.jpg" : "../hamsters.jpg" +>import.meta.url : any +>import.meta : ImportMeta +>meta : any +>url : any +>toString : () => string + + const blob = await response.blob(); +>blob : Blob +>await response.blob() : Blob +>response.blob() : Promise +>response.blob : () => Promise +>response : Response +>blob : () => Promise + + const size = import.meta.scriptElement.dataset.size || 300; +>size : any +>import.meta.scriptElement.dataset.size || 300 : any +>import.meta.scriptElement.dataset.size : any +>import.meta.scriptElement.dataset : any +>import.meta.scriptElement : any +>import.meta : ImportMeta +>meta : any +>scriptElement : any +>dataset : any +>size : any +>300 : 300 + + const image = new Image(); +>image : HTMLImageElement +>new Image() : HTMLImageElement +>Image : new (width?: number, height?: number) => HTMLImageElement + + image.src = URL.createObjectURL(blob); +>image.src = URL.createObjectURL(blob) : string +>image.src : string +>image : HTMLImageElement +>src : string +>URL.createObjectURL(blob) : string +>URL.createObjectURL : (object: any) => string +>URL : { new (url: string, base?: string | URL): URL; prototype: URL; createObjectURL(object: any): string; revokeObjectURL(url: string): void; } +>createObjectURL : (object: any) => string +>blob : Blob + + image.width = image.height = size; +>image.width = image.height = size : any +>image.width : number +>image : HTMLImageElement +>width : number +>image.height = size : any +>image.height : number +>image : HTMLImageElement +>height : number +>size : any + + document.body.appendChild(image); +>document.body.appendChild(image) : HTMLImageElement +>document.body.appendChild : (newChild: T) => T +>document.body : HTMLElement +>document : Document +>body : HTMLElement +>appendChild : (newChild: T) => T +>image : HTMLImageElement + +})(); + +=== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts === +export let x = import.meta; +>x : ImportMeta +>import.meta : ImportMeta +>meta : any + +export let y = import.metal; +>y : any +>import.metal : any +>metal : any + +export let z = import.import.import.malkovich; +>z : any +>import.import.import.malkovich : any +>import.import.import : any +>import.import : any +>import : any +>import : any +>malkovich : any + +=== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts === +let globalA = import.meta; +>globalA : ImportMeta +>import.meta : ImportMeta +>meta : any + +let globalB = import.metal; +>globalB : any +>import.metal : any +>metal : any + +let globalC = import.import.import.malkovich; +>globalC : any +>import.import.import.malkovich : any +>import.import.import : any +>import.import : any +>import : any +>import : any +>malkovich : any + +=== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts === +export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; +>foo : ImportMeta +>import.meta.blah = import.meta.blue = import.meta : ImportMeta +>import.meta.blah : any +>import.meta : ImportMeta +>meta : any +>blah : any +>import.meta.blue = import.meta : ImportMeta +>import.meta.blue : any +>import.meta : ImportMeta +>meta : any +>blue : any +>import.meta : ImportMeta +>meta : any + +import.meta = foo; +>import.meta = foo : ImportMeta +>import.meta : ImportMeta +>meta : any +>foo : ImportMeta + +// @Filename augmentations.ts +declare global { +>global : any + + interface ImportMeta { + wellKnownProperty: { a: number, b: string, c: boolean }; +>wellKnownProperty : { a: number; b: string; c: boolean; } +>a : number +>b : string +>c : boolean + } +} + +const { a, b, c } = import.meta.wellKnownProperty; +>a : number +>b : string +>c : boolean +>import.meta.wellKnownProperty : { a: number; b: string; c: boolean; } +>import.meta : ImportMeta +>meta : any +>wellKnownProperty : { a: number; b: string; c: boolean; } + diff --git a/tests/baselines/reference/importMeta(module=esnext,target=esnext).errors.txt b/tests/baselines/reference/importMeta(module=esnext,target=esnext).errors.txt new file mode 100644 index 00000000000..999c883f266 --- /dev/null +++ b/tests/baselines/reference/importMeta(module=esnext,target=esnext).errors.txt @@ -0,0 +1,71 @@ +error TS2468: Cannot find global value 'Promise'. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,44): error TS2339: Property 'blah' does not exist on type 'ImportMeta'. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,63): error TS2339: Property 'blue' does not exist on type 'ImportMeta'. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(2,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. +tests/cases/conformance/es2019/importMeta/example.ts(2,2): error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. +tests/cases/conformance/es2019/importMeta/example.ts(3,71): error TS2339: Property 'url' does not exist on type 'ImportMeta'. +tests/cases/conformance/es2019/importMeta/example.ts(6,28): error TS2339: Property 'scriptElement' does not exist on type 'ImportMeta'. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,23): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,23): error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(2,22): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + + +!!! error TS2468: Cannot find global value 'Promise'. +==== tests/cases/conformance/es2019/importMeta/example.ts (3 errors) ==== + // Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example + (async () => { + ~~~~~~~~~~~~~ +!!! error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); + ~~~ +!!! error TS2339: Property 'url' does not exist on type 'ImportMeta'. + const blob = await response.blob(); + + const size = import.meta.scriptElement.dataset.size || 300; + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'scriptElement' does not exist on type 'ImportMeta'. + + const image = new Image(); + image.src = URL.createObjectURL(blob); + image.width = image.height = size; + + document.body.appendChild(image); + })(); + +==== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts (2 errors) ==== + export let x = import.meta; + export let y = import.metal; + ~~~~~ +!!! error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + export let z = import.import.import.malkovich; + ~~~~~~ +!!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + +==== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts (2 errors) ==== + let globalA = import.meta; + let globalB = import.metal; + ~~~~~ +!!! error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + let globalC = import.import.import.malkovich; + ~~~~~~ +!!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + +==== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts (3 errors) ==== + export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; + ~~~~ +!!! error TS2339: Property 'blah' does not exist on type 'ImportMeta'. + ~~~~ +!!! error TS2339: Property 'blue' does not exist on type 'ImportMeta'. + import.meta = foo; + ~~~~~~~~~~~ +!!! error TS2364: The left-hand side of an assignment expression must be a variable or a property access. + + // @Filename augmentations.ts + declare global { + interface ImportMeta { + wellKnownProperty: { a: number, b: string, c: boolean }; + } + } + + const { a, b, c } = import.meta.wellKnownProperty; \ No newline at end of file diff --git a/tests/baselines/reference/importMeta.js b/tests/baselines/reference/importMeta(module=esnext,target=esnext).js similarity index 100% rename from tests/baselines/reference/importMeta.js rename to tests/baselines/reference/importMeta(module=esnext,target=esnext).js diff --git a/tests/baselines/reference/importMeta(module=esnext,target=esnext).symbols b/tests/baselines/reference/importMeta(module=esnext,target=esnext).symbols new file mode 100644 index 00000000000..d21785639ed --- /dev/null +++ b/tests/baselines/reference/importMeta(module=esnext,target=esnext).symbols @@ -0,0 +1,101 @@ +=== tests/cases/conformance/es2019/importMeta/example.ts === +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(async () => { + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); +>response : Symbol(response, Decl(example.ts, 2, 7)) +>fetch : Symbol(fetch, Decl(lib.dom.d.ts, --, --)) +>new URL("../hamsters.jpg", import.meta.url).toString : Symbol(Object.toString, Decl(lib.es5.d.ts, --, --)) +>URL : Symbol(URL, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>toString : Symbol(Object.toString, Decl(lib.es5.d.ts, --, --)) + + const blob = await response.blob(); +>blob : Symbol(blob, Decl(example.ts, 3, 7)) +>response.blob : Symbol(Body.blob, Decl(lib.dom.d.ts, --, --)) +>response : Symbol(response, Decl(example.ts, 2, 7)) +>blob : Symbol(Body.blob, Decl(lib.dom.d.ts, --, --)) + + const size = import.meta.scriptElement.dataset.size || 300; +>size : Symbol(size, Decl(example.ts, 5, 7)) + + const image = new Image(); +>image : Symbol(image, Decl(example.ts, 7, 7)) +>Image : Symbol(Image, Decl(lib.dom.d.ts, --, --)) + + image.src = URL.createObjectURL(blob); +>image.src : Symbol(HTMLImageElement.src, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) +>src : Symbol(HTMLImageElement.src, Decl(lib.dom.d.ts, --, --)) +>URL.createObjectURL : Symbol(createObjectURL, Decl(lib.dom.d.ts, --, --)) +>URL : Symbol(URL, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>createObjectURL : Symbol(createObjectURL, Decl(lib.dom.d.ts, --, --)) +>blob : Symbol(blob, Decl(example.ts, 3, 7)) + + image.width = image.height = size; +>image.width : Symbol(HTMLImageElement.width, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) +>width : Symbol(HTMLImageElement.width, Decl(lib.dom.d.ts, --, --)) +>image.height : Symbol(HTMLImageElement.height, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) +>height : Symbol(HTMLImageElement.height, Decl(lib.dom.d.ts, --, --)) +>size : Symbol(size, Decl(example.ts, 5, 7)) + + document.body.appendChild(image); +>document.body.appendChild : Symbol(Node.appendChild, Decl(lib.dom.d.ts, --, --)) +>document.body : Symbol(Document.body, Decl(lib.dom.d.ts, --, --)) +>document : Symbol(document, Decl(lib.dom.d.ts, --, --)) +>body : Symbol(Document.body, Decl(lib.dom.d.ts, --, --)) +>appendChild : Symbol(Node.appendChild, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) + +})(); + +=== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts === +export let x = import.meta; +>x : Symbol(x, Decl(moduleLookingFile01.ts, 0, 10)) + +export let y = import.metal; +>y : Symbol(y, Decl(moduleLookingFile01.ts, 1, 10)) + +export let z = import.import.import.malkovich; +>z : Symbol(z, Decl(moduleLookingFile01.ts, 2, 10)) + +=== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts === +let globalA = import.meta; +>globalA : Symbol(globalA, Decl(scriptLookingFile01.ts, 0, 3)) + +let globalB = import.metal; +>globalB : Symbol(globalB, Decl(scriptLookingFile01.ts, 1, 3)) + +let globalC = import.import.import.malkovich; +>globalC : Symbol(globalC, Decl(scriptLookingFile01.ts, 2, 3)) + +=== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts === +export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; +>foo : Symbol(foo, Decl(assignmentTargets.ts, 0, 12)) +>ImportMeta : Symbol(ImportMeta, Decl(lib.es5.d.ts, --, --), Decl(assignmentTargets.ts, 4, 16)) + +import.meta = foo; +>foo : Symbol(foo, Decl(assignmentTargets.ts, 0, 12)) + +// @Filename augmentations.ts +declare global { +>global : Symbol(global, Decl(assignmentTargets.ts, 1, 18)) + + interface ImportMeta { +>ImportMeta : Symbol(ImportMeta, Decl(lib.es5.d.ts, --, --), Decl(assignmentTargets.ts, 4, 16)) + + wellKnownProperty: { a: number, b: string, c: boolean }; +>wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24)) +>a : Symbol(a, Decl(assignmentTargets.ts, 6, 24)) +>b : Symbol(b, Decl(assignmentTargets.ts, 6, 35)) +>c : Symbol(c, Decl(assignmentTargets.ts, 6, 46)) + } +} + +const { a, b, c } = import.meta.wellKnownProperty; +>a : Symbol(a, Decl(assignmentTargets.ts, 10, 7)) +>b : Symbol(b, Decl(assignmentTargets.ts, 10, 10)) +>c : Symbol(c, Decl(assignmentTargets.ts, 10, 13)) +>import.meta.wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24)) +>wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24)) + diff --git a/tests/baselines/reference/importMeta(module=esnext,target=esnext).types b/tests/baselines/reference/importMeta(module=esnext,target=esnext).types new file mode 100644 index 00000000000..78d2e3395c8 --- /dev/null +++ b/tests/baselines/reference/importMeta(module=esnext,target=esnext).types @@ -0,0 +1,166 @@ +=== tests/cases/conformance/es2019/importMeta/example.ts === +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(async () => { +>(async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);})() : Promise +>(async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);}) : () => Promise +>async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);} : () => Promise + + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); +>response : Response +>await fetch(new URL("../hamsters.jpg", import.meta.url).toString()) : Response +>fetch(new URL("../hamsters.jpg", import.meta.url).toString()) : Promise +>fetch : (input: RequestInfo, init?: RequestInit) => Promise +>new URL("../hamsters.jpg", import.meta.url).toString() : string +>new URL("../hamsters.jpg", import.meta.url).toString : () => string +>new URL("../hamsters.jpg", import.meta.url) : URL +>URL : { new (url: string, base?: string | URL): URL; prototype: URL; createObjectURL(object: any): string; revokeObjectURL(url: string): void; } +>"../hamsters.jpg" : "../hamsters.jpg" +>import.meta.url : any +>import.meta : ImportMeta +>meta : any +>url : any +>toString : () => string + + const blob = await response.blob(); +>blob : Blob +>await response.blob() : Blob +>response.blob() : Promise +>response.blob : () => Promise +>response : Response +>blob : () => Promise + + const size = import.meta.scriptElement.dataset.size || 300; +>size : any +>import.meta.scriptElement.dataset.size || 300 : any +>import.meta.scriptElement.dataset.size : any +>import.meta.scriptElement.dataset : any +>import.meta.scriptElement : any +>import.meta : ImportMeta +>meta : any +>scriptElement : any +>dataset : any +>size : any +>300 : 300 + + const image = new Image(); +>image : HTMLImageElement +>new Image() : HTMLImageElement +>Image : new (width?: number, height?: number) => HTMLImageElement + + image.src = URL.createObjectURL(blob); +>image.src = URL.createObjectURL(blob) : string +>image.src : string +>image : HTMLImageElement +>src : string +>URL.createObjectURL(blob) : string +>URL.createObjectURL : (object: any) => string +>URL : { new (url: string, base?: string | URL): URL; prototype: URL; createObjectURL(object: any): string; revokeObjectURL(url: string): void; } +>createObjectURL : (object: any) => string +>blob : Blob + + image.width = image.height = size; +>image.width = image.height = size : any +>image.width : number +>image : HTMLImageElement +>width : number +>image.height = size : any +>image.height : number +>image : HTMLImageElement +>height : number +>size : any + + document.body.appendChild(image); +>document.body.appendChild(image) : HTMLImageElement +>document.body.appendChild : (newChild: T) => T +>document.body : HTMLElement +>document : Document +>body : HTMLElement +>appendChild : (newChild: T) => T +>image : HTMLImageElement + +})(); + +=== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts === +export let x = import.meta; +>x : ImportMeta +>import.meta : ImportMeta +>meta : any + +export let y = import.metal; +>y : any +>import.metal : any +>metal : any + +export let z = import.import.import.malkovich; +>z : any +>import.import.import.malkovich : any +>import.import.import : any +>import.import : any +>import : any +>import : any +>malkovich : any + +=== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts === +let globalA = import.meta; +>globalA : ImportMeta +>import.meta : ImportMeta +>meta : any + +let globalB = import.metal; +>globalB : any +>import.metal : any +>metal : any + +let globalC = import.import.import.malkovich; +>globalC : any +>import.import.import.malkovich : any +>import.import.import : any +>import.import : any +>import : any +>import : any +>malkovich : any + +=== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts === +export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; +>foo : ImportMeta +>import.meta.blah = import.meta.blue = import.meta : ImportMeta +>import.meta.blah : any +>import.meta : ImportMeta +>meta : any +>blah : any +>import.meta.blue = import.meta : ImportMeta +>import.meta.blue : any +>import.meta : ImportMeta +>meta : any +>blue : any +>import.meta : ImportMeta +>meta : any + +import.meta = foo; +>import.meta = foo : ImportMeta +>import.meta : ImportMeta +>meta : any +>foo : ImportMeta + +// @Filename augmentations.ts +declare global { +>global : any + + interface ImportMeta { + wellKnownProperty: { a: number, b: string, c: boolean }; +>wellKnownProperty : { a: number; b: string; c: boolean; } +>a : number +>b : string +>c : boolean + } +} + +const { a, b, c } = import.meta.wellKnownProperty; +>a : number +>b : string +>c : boolean +>import.meta.wellKnownProperty : { a: number; b: string; c: boolean; } +>import.meta : ImportMeta +>meta : any +>wellKnownProperty : { a: number; b: string; c: boolean; } + diff --git a/tests/baselines/reference/importMeta(module=system,target=es5).errors.txt b/tests/baselines/reference/importMeta(module=system,target=es5).errors.txt new file mode 100644 index 00000000000..999c883f266 --- /dev/null +++ b/tests/baselines/reference/importMeta(module=system,target=es5).errors.txt @@ -0,0 +1,71 @@ +error TS2468: Cannot find global value 'Promise'. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,44): error TS2339: Property 'blah' does not exist on type 'ImportMeta'. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,63): error TS2339: Property 'blue' does not exist on type 'ImportMeta'. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(2,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. +tests/cases/conformance/es2019/importMeta/example.ts(2,2): error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. +tests/cases/conformance/es2019/importMeta/example.ts(3,71): error TS2339: Property 'url' does not exist on type 'ImportMeta'. +tests/cases/conformance/es2019/importMeta/example.ts(6,28): error TS2339: Property 'scriptElement' does not exist on type 'ImportMeta'. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,23): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,23): error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(2,22): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + + +!!! error TS2468: Cannot find global value 'Promise'. +==== tests/cases/conformance/es2019/importMeta/example.ts (3 errors) ==== + // Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example + (async () => { + ~~~~~~~~~~~~~ +!!! error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); + ~~~ +!!! error TS2339: Property 'url' does not exist on type 'ImportMeta'. + const blob = await response.blob(); + + const size = import.meta.scriptElement.dataset.size || 300; + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'scriptElement' does not exist on type 'ImportMeta'. + + const image = new Image(); + image.src = URL.createObjectURL(blob); + image.width = image.height = size; + + document.body.appendChild(image); + })(); + +==== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts (2 errors) ==== + export let x = import.meta; + export let y = import.metal; + ~~~~~ +!!! error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + export let z = import.import.import.malkovich; + ~~~~~~ +!!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + +==== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts (2 errors) ==== + let globalA = import.meta; + let globalB = import.metal; + ~~~~~ +!!! error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + let globalC = import.import.import.malkovich; + ~~~~~~ +!!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + +==== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts (3 errors) ==== + export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; + ~~~~ +!!! error TS2339: Property 'blah' does not exist on type 'ImportMeta'. + ~~~~ +!!! error TS2339: Property 'blue' does not exist on type 'ImportMeta'. + import.meta = foo; + ~~~~~~~~~~~ +!!! error TS2364: The left-hand side of an assignment expression must be a variable or a property access. + + // @Filename augmentations.ts + declare global { + interface ImportMeta { + wellKnownProperty: { a: number, b: string, c: boolean }; + } + } + + const { a, b, c } = import.meta.wellKnownProperty; \ No newline at end of file diff --git a/tests/baselines/reference/importMeta(module=system,target=es5).js b/tests/baselines/reference/importMeta(module=system,target=es5).js new file mode 100644 index 00000000000..ce9321f5fe9 --- /dev/null +++ b/tests/baselines/reference/importMeta(module=system,target=es5).js @@ -0,0 +1,150 @@ +//// [tests/cases/conformance/es2019/importMeta/importMeta.ts] //// + +//// [example.ts] +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(async () => { + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); + const blob = await response.blob(); + + const size = import.meta.scriptElement.dataset.size || 300; + + const image = new Image(); + image.src = URL.createObjectURL(blob); + image.width = image.height = size; + + document.body.appendChild(image); +})(); + +//// [moduleLookingFile01.ts] +export let x = import.meta; +export let y = import.metal; +export let z = import.import.import.malkovich; + +//// [scriptLookingFile01.ts] +let globalA = import.meta; +let globalB = import.metal; +let globalC = import.import.import.malkovich; + +//// [assignmentTargets.ts] +export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; +import.meta = foo; + +// @Filename augmentations.ts +declare global { + interface ImportMeta { + wellKnownProperty: { a: number, b: string, c: boolean }; + } +} + +const { a, b, c } = import.meta.wellKnownProperty; + +//// [example.js] +System.register([], function (exports_1, context_1) { + "use strict"; + var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } + }; + var _this; + _this = this; + var __moduleName = context_1 && context_1.id; + return { + setters: [], + execute: function () { + // Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example + (function () { return __awaiter(_this, void 0, void 0, function () { + var response, blob, size, image; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, fetch(new URL("../hamsters.jpg", context_1.meta.url).toString())]; + case 1: + response = _a.sent(); + return [4 /*yield*/, response.blob()]; + case 2: + blob = _a.sent(); + size = context_1.meta.scriptElement.dataset.size || 300; + image = new Image(); + image.src = URL.createObjectURL(blob); + image.width = image.height = size; + document.body.appendChild(image); + return [2 /*return*/]; + } + }); + }); })(); + } + }; +}); +//// [moduleLookingFile01.js] +System.register([], function (exports_1, context_1) { + "use strict"; + var x, y, z; + var __moduleName = context_1 && context_1.id; + return { + setters: [], + execute: function () { + exports_1("x", x = (context_1.meta)); + exports_1("y", y = (import.metal)); + exports_1("z", z = import.import.import.malkovich); + } + }; +}); +//// [scriptLookingFile01.js] +System.register([], function (exports_1, context_1) { + "use strict"; + var globalA, globalB, globalC; + var __moduleName = context_1 && context_1.id; + return { + setters: [], + execute: function () { + globalA = (context_1.meta); + globalB = (import.metal); + globalC = import.import.import.malkovich; + } + }; +}); +//// [assignmentTargets.js] +System.register([], function (exports_1, context_1) { + "use strict"; + var foo, _a, a, b, c; + var __moduleName = context_1 && context_1.id; + return { + setters: [], + execute: function () { + exports_1("foo", foo = context_1.meta.blah = context_1.meta.blue = context_1.meta); + context_1.meta = foo; + _a = context_1.meta.wellKnownProperty, a = _a.a, b = _a.b, c = _a.c; + } + }; +}); diff --git a/tests/baselines/reference/importMeta(module=system,target=es5).symbols b/tests/baselines/reference/importMeta(module=system,target=es5).symbols new file mode 100644 index 00000000000..d21785639ed --- /dev/null +++ b/tests/baselines/reference/importMeta(module=system,target=es5).symbols @@ -0,0 +1,101 @@ +=== tests/cases/conformance/es2019/importMeta/example.ts === +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(async () => { + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); +>response : Symbol(response, Decl(example.ts, 2, 7)) +>fetch : Symbol(fetch, Decl(lib.dom.d.ts, --, --)) +>new URL("../hamsters.jpg", import.meta.url).toString : Symbol(Object.toString, Decl(lib.es5.d.ts, --, --)) +>URL : Symbol(URL, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>toString : Symbol(Object.toString, Decl(lib.es5.d.ts, --, --)) + + const blob = await response.blob(); +>blob : Symbol(blob, Decl(example.ts, 3, 7)) +>response.blob : Symbol(Body.blob, Decl(lib.dom.d.ts, --, --)) +>response : Symbol(response, Decl(example.ts, 2, 7)) +>blob : Symbol(Body.blob, Decl(lib.dom.d.ts, --, --)) + + const size = import.meta.scriptElement.dataset.size || 300; +>size : Symbol(size, Decl(example.ts, 5, 7)) + + const image = new Image(); +>image : Symbol(image, Decl(example.ts, 7, 7)) +>Image : Symbol(Image, Decl(lib.dom.d.ts, --, --)) + + image.src = URL.createObjectURL(blob); +>image.src : Symbol(HTMLImageElement.src, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) +>src : Symbol(HTMLImageElement.src, Decl(lib.dom.d.ts, --, --)) +>URL.createObjectURL : Symbol(createObjectURL, Decl(lib.dom.d.ts, --, --)) +>URL : Symbol(URL, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>createObjectURL : Symbol(createObjectURL, Decl(lib.dom.d.ts, --, --)) +>blob : Symbol(blob, Decl(example.ts, 3, 7)) + + image.width = image.height = size; +>image.width : Symbol(HTMLImageElement.width, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) +>width : Symbol(HTMLImageElement.width, Decl(lib.dom.d.ts, --, --)) +>image.height : Symbol(HTMLImageElement.height, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) +>height : Symbol(HTMLImageElement.height, Decl(lib.dom.d.ts, --, --)) +>size : Symbol(size, Decl(example.ts, 5, 7)) + + document.body.appendChild(image); +>document.body.appendChild : Symbol(Node.appendChild, Decl(lib.dom.d.ts, --, --)) +>document.body : Symbol(Document.body, Decl(lib.dom.d.ts, --, --)) +>document : Symbol(document, Decl(lib.dom.d.ts, --, --)) +>body : Symbol(Document.body, Decl(lib.dom.d.ts, --, --)) +>appendChild : Symbol(Node.appendChild, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) + +})(); + +=== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts === +export let x = import.meta; +>x : Symbol(x, Decl(moduleLookingFile01.ts, 0, 10)) + +export let y = import.metal; +>y : Symbol(y, Decl(moduleLookingFile01.ts, 1, 10)) + +export let z = import.import.import.malkovich; +>z : Symbol(z, Decl(moduleLookingFile01.ts, 2, 10)) + +=== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts === +let globalA = import.meta; +>globalA : Symbol(globalA, Decl(scriptLookingFile01.ts, 0, 3)) + +let globalB = import.metal; +>globalB : Symbol(globalB, Decl(scriptLookingFile01.ts, 1, 3)) + +let globalC = import.import.import.malkovich; +>globalC : Symbol(globalC, Decl(scriptLookingFile01.ts, 2, 3)) + +=== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts === +export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; +>foo : Symbol(foo, Decl(assignmentTargets.ts, 0, 12)) +>ImportMeta : Symbol(ImportMeta, Decl(lib.es5.d.ts, --, --), Decl(assignmentTargets.ts, 4, 16)) + +import.meta = foo; +>foo : Symbol(foo, Decl(assignmentTargets.ts, 0, 12)) + +// @Filename augmentations.ts +declare global { +>global : Symbol(global, Decl(assignmentTargets.ts, 1, 18)) + + interface ImportMeta { +>ImportMeta : Symbol(ImportMeta, Decl(lib.es5.d.ts, --, --), Decl(assignmentTargets.ts, 4, 16)) + + wellKnownProperty: { a: number, b: string, c: boolean }; +>wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24)) +>a : Symbol(a, Decl(assignmentTargets.ts, 6, 24)) +>b : Symbol(b, Decl(assignmentTargets.ts, 6, 35)) +>c : Symbol(c, Decl(assignmentTargets.ts, 6, 46)) + } +} + +const { a, b, c } = import.meta.wellKnownProperty; +>a : Symbol(a, Decl(assignmentTargets.ts, 10, 7)) +>b : Symbol(b, Decl(assignmentTargets.ts, 10, 10)) +>c : Symbol(c, Decl(assignmentTargets.ts, 10, 13)) +>import.meta.wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24)) +>wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24)) + diff --git a/tests/baselines/reference/importMeta(module=system,target=es5).types b/tests/baselines/reference/importMeta(module=system,target=es5).types new file mode 100644 index 00000000000..78d2e3395c8 --- /dev/null +++ b/tests/baselines/reference/importMeta(module=system,target=es5).types @@ -0,0 +1,166 @@ +=== tests/cases/conformance/es2019/importMeta/example.ts === +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(async () => { +>(async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);})() : Promise +>(async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);}) : () => Promise +>async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);} : () => Promise + + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); +>response : Response +>await fetch(new URL("../hamsters.jpg", import.meta.url).toString()) : Response +>fetch(new URL("../hamsters.jpg", import.meta.url).toString()) : Promise +>fetch : (input: RequestInfo, init?: RequestInit) => Promise +>new URL("../hamsters.jpg", import.meta.url).toString() : string +>new URL("../hamsters.jpg", import.meta.url).toString : () => string +>new URL("../hamsters.jpg", import.meta.url) : URL +>URL : { new (url: string, base?: string | URL): URL; prototype: URL; createObjectURL(object: any): string; revokeObjectURL(url: string): void; } +>"../hamsters.jpg" : "../hamsters.jpg" +>import.meta.url : any +>import.meta : ImportMeta +>meta : any +>url : any +>toString : () => string + + const blob = await response.blob(); +>blob : Blob +>await response.blob() : Blob +>response.blob() : Promise +>response.blob : () => Promise +>response : Response +>blob : () => Promise + + const size = import.meta.scriptElement.dataset.size || 300; +>size : any +>import.meta.scriptElement.dataset.size || 300 : any +>import.meta.scriptElement.dataset.size : any +>import.meta.scriptElement.dataset : any +>import.meta.scriptElement : any +>import.meta : ImportMeta +>meta : any +>scriptElement : any +>dataset : any +>size : any +>300 : 300 + + const image = new Image(); +>image : HTMLImageElement +>new Image() : HTMLImageElement +>Image : new (width?: number, height?: number) => HTMLImageElement + + image.src = URL.createObjectURL(blob); +>image.src = URL.createObjectURL(blob) : string +>image.src : string +>image : HTMLImageElement +>src : string +>URL.createObjectURL(blob) : string +>URL.createObjectURL : (object: any) => string +>URL : { new (url: string, base?: string | URL): URL; prototype: URL; createObjectURL(object: any): string; revokeObjectURL(url: string): void; } +>createObjectURL : (object: any) => string +>blob : Blob + + image.width = image.height = size; +>image.width = image.height = size : any +>image.width : number +>image : HTMLImageElement +>width : number +>image.height = size : any +>image.height : number +>image : HTMLImageElement +>height : number +>size : any + + document.body.appendChild(image); +>document.body.appendChild(image) : HTMLImageElement +>document.body.appendChild : (newChild: T) => T +>document.body : HTMLElement +>document : Document +>body : HTMLElement +>appendChild : (newChild: T) => T +>image : HTMLImageElement + +})(); + +=== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts === +export let x = import.meta; +>x : ImportMeta +>import.meta : ImportMeta +>meta : any + +export let y = import.metal; +>y : any +>import.metal : any +>metal : any + +export let z = import.import.import.malkovich; +>z : any +>import.import.import.malkovich : any +>import.import.import : any +>import.import : any +>import : any +>import : any +>malkovich : any + +=== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts === +let globalA = import.meta; +>globalA : ImportMeta +>import.meta : ImportMeta +>meta : any + +let globalB = import.metal; +>globalB : any +>import.metal : any +>metal : any + +let globalC = import.import.import.malkovich; +>globalC : any +>import.import.import.malkovich : any +>import.import.import : any +>import.import : any +>import : any +>import : any +>malkovich : any + +=== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts === +export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; +>foo : ImportMeta +>import.meta.blah = import.meta.blue = import.meta : ImportMeta +>import.meta.blah : any +>import.meta : ImportMeta +>meta : any +>blah : any +>import.meta.blue = import.meta : ImportMeta +>import.meta.blue : any +>import.meta : ImportMeta +>meta : any +>blue : any +>import.meta : ImportMeta +>meta : any + +import.meta = foo; +>import.meta = foo : ImportMeta +>import.meta : ImportMeta +>meta : any +>foo : ImportMeta + +// @Filename augmentations.ts +declare global { +>global : any + + interface ImportMeta { + wellKnownProperty: { a: number, b: string, c: boolean }; +>wellKnownProperty : { a: number; b: string; c: boolean; } +>a : number +>b : string +>c : boolean + } +} + +const { a, b, c } = import.meta.wellKnownProperty; +>a : number +>b : string +>c : boolean +>import.meta.wellKnownProperty : { a: number; b: string; c: boolean; } +>import.meta : ImportMeta +>meta : any +>wellKnownProperty : { a: number; b: string; c: boolean; } + diff --git a/tests/baselines/reference/importMeta(module=system,target=esnext).errors.txt b/tests/baselines/reference/importMeta(module=system,target=esnext).errors.txt new file mode 100644 index 00000000000..999c883f266 --- /dev/null +++ b/tests/baselines/reference/importMeta(module=system,target=esnext).errors.txt @@ -0,0 +1,71 @@ +error TS2468: Cannot find global value 'Promise'. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,44): error TS2339: Property 'blah' does not exist on type 'ImportMeta'. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,63): error TS2339: Property 'blue' does not exist on type 'ImportMeta'. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(2,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. +tests/cases/conformance/es2019/importMeta/example.ts(2,2): error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. +tests/cases/conformance/es2019/importMeta/example.ts(3,71): error TS2339: Property 'url' does not exist on type 'ImportMeta'. +tests/cases/conformance/es2019/importMeta/example.ts(6,28): error TS2339: Property 'scriptElement' does not exist on type 'ImportMeta'. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,23): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,23): error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(2,22): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + + +!!! error TS2468: Cannot find global value 'Promise'. +==== tests/cases/conformance/es2019/importMeta/example.ts (3 errors) ==== + // Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example + (async () => { + ~~~~~~~~~~~~~ +!!! error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); + ~~~ +!!! error TS2339: Property 'url' does not exist on type 'ImportMeta'. + const blob = await response.blob(); + + const size = import.meta.scriptElement.dataset.size || 300; + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'scriptElement' does not exist on type 'ImportMeta'. + + const image = new Image(); + image.src = URL.createObjectURL(blob); + image.width = image.height = size; + + document.body.appendChild(image); + })(); + +==== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts (2 errors) ==== + export let x = import.meta; + export let y = import.metal; + ~~~~~ +!!! error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + export let z = import.import.import.malkovich; + ~~~~~~ +!!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + +==== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts (2 errors) ==== + let globalA = import.meta; + let globalB = import.metal; + ~~~~~ +!!! error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + let globalC = import.import.import.malkovich; + ~~~~~~ +!!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + +==== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts (3 errors) ==== + export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; + ~~~~ +!!! error TS2339: Property 'blah' does not exist on type 'ImportMeta'. + ~~~~ +!!! error TS2339: Property 'blue' does not exist on type 'ImportMeta'. + import.meta = foo; + ~~~~~~~~~~~ +!!! error TS2364: The left-hand side of an assignment expression must be a variable or a property access. + + // @Filename augmentations.ts + declare global { + interface ImportMeta { + wellKnownProperty: { a: number, b: string, c: boolean }; + } + } + + const { a, b, c } = import.meta.wellKnownProperty; \ No newline at end of file diff --git a/tests/baselines/reference/importMeta(module=system,target=esnext).js b/tests/baselines/reference/importMeta(module=system,target=esnext).js new file mode 100644 index 00000000000..b3639b579a8 --- /dev/null +++ b/tests/baselines/reference/importMeta(module=system,target=esnext).js @@ -0,0 +1,102 @@ +//// [tests/cases/conformance/es2019/importMeta/importMeta.ts] //// + +//// [example.ts] +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(async () => { + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); + const blob = await response.blob(); + + const size = import.meta.scriptElement.dataset.size || 300; + + const image = new Image(); + image.src = URL.createObjectURL(blob); + image.width = image.height = size; + + document.body.appendChild(image); +})(); + +//// [moduleLookingFile01.ts] +export let x = import.meta; +export let y = import.metal; +export let z = import.import.import.malkovich; + +//// [scriptLookingFile01.ts] +let globalA = import.meta; +let globalB = import.metal; +let globalC = import.import.import.malkovich; + +//// [assignmentTargets.ts] +export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; +import.meta = foo; + +// @Filename augmentations.ts +declare global { + interface ImportMeta { + wellKnownProperty: { a: number, b: string, c: boolean }; + } +} + +const { a, b, c } = import.meta.wellKnownProperty; + +//// [example.js] +System.register([], function (exports_1, context_1) { + "use strict"; + var __moduleName = context_1 && context_1.id; + return { + setters: [], + execute: function () { + // Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example + (async () => { + const response = await fetch(new URL("../hamsters.jpg", context_1.meta.url).toString()); + const blob = await response.blob(); + const size = context_1.meta.scriptElement.dataset.size || 300; + const image = new Image(); + image.src = URL.createObjectURL(blob); + image.width = image.height = size; + document.body.appendChild(image); + })(); + } + }; +}); +//// [moduleLookingFile01.js] +System.register([], function (exports_1, context_1) { + "use strict"; + var x, y, z; + var __moduleName = context_1 && context_1.id; + return { + setters: [], + execute: function () { + exports_1("x", x = (context_1.meta)); + exports_1("y", y = (import.metal)); + exports_1("z", z = import.import.import.malkovich); + } + }; +}); +//// [scriptLookingFile01.js] +System.register([], function (exports_1, context_1) { + "use strict"; + var globalA, globalB, globalC; + var __moduleName = context_1 && context_1.id; + return { + setters: [], + execute: function () { + globalA = (context_1.meta); + globalB = (import.metal); + globalC = import.import.import.malkovich; + } + }; +}); +//// [assignmentTargets.js] +System.register([], function (exports_1, context_1) { + "use strict"; + var foo, _a, a, b, c; + var __moduleName = context_1 && context_1.id; + return { + setters: [], + execute: function () { + exports_1("foo", foo = context_1.meta.blah = context_1.meta.blue = context_1.meta); + context_1.meta = foo; + _a = context_1.meta.wellKnownProperty, a = _a.a, b = _a.b, c = _a.c; + } + }; +}); diff --git a/tests/baselines/reference/importMeta(module=system,target=esnext).symbols b/tests/baselines/reference/importMeta(module=system,target=esnext).symbols new file mode 100644 index 00000000000..d21785639ed --- /dev/null +++ b/tests/baselines/reference/importMeta(module=system,target=esnext).symbols @@ -0,0 +1,101 @@ +=== tests/cases/conformance/es2019/importMeta/example.ts === +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(async () => { + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); +>response : Symbol(response, Decl(example.ts, 2, 7)) +>fetch : Symbol(fetch, Decl(lib.dom.d.ts, --, --)) +>new URL("../hamsters.jpg", import.meta.url).toString : Symbol(Object.toString, Decl(lib.es5.d.ts, --, --)) +>URL : Symbol(URL, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>toString : Symbol(Object.toString, Decl(lib.es5.d.ts, --, --)) + + const blob = await response.blob(); +>blob : Symbol(blob, Decl(example.ts, 3, 7)) +>response.blob : Symbol(Body.blob, Decl(lib.dom.d.ts, --, --)) +>response : Symbol(response, Decl(example.ts, 2, 7)) +>blob : Symbol(Body.blob, Decl(lib.dom.d.ts, --, --)) + + const size = import.meta.scriptElement.dataset.size || 300; +>size : Symbol(size, Decl(example.ts, 5, 7)) + + const image = new Image(); +>image : Symbol(image, Decl(example.ts, 7, 7)) +>Image : Symbol(Image, Decl(lib.dom.d.ts, --, --)) + + image.src = URL.createObjectURL(blob); +>image.src : Symbol(HTMLImageElement.src, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) +>src : Symbol(HTMLImageElement.src, Decl(lib.dom.d.ts, --, --)) +>URL.createObjectURL : Symbol(createObjectURL, Decl(lib.dom.d.ts, --, --)) +>URL : Symbol(URL, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>createObjectURL : Symbol(createObjectURL, Decl(lib.dom.d.ts, --, --)) +>blob : Symbol(blob, Decl(example.ts, 3, 7)) + + image.width = image.height = size; +>image.width : Symbol(HTMLImageElement.width, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) +>width : Symbol(HTMLImageElement.width, Decl(lib.dom.d.ts, --, --)) +>image.height : Symbol(HTMLImageElement.height, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) +>height : Symbol(HTMLImageElement.height, Decl(lib.dom.d.ts, --, --)) +>size : Symbol(size, Decl(example.ts, 5, 7)) + + document.body.appendChild(image); +>document.body.appendChild : Symbol(Node.appendChild, Decl(lib.dom.d.ts, --, --)) +>document.body : Symbol(Document.body, Decl(lib.dom.d.ts, --, --)) +>document : Symbol(document, Decl(lib.dom.d.ts, --, --)) +>body : Symbol(Document.body, Decl(lib.dom.d.ts, --, --)) +>appendChild : Symbol(Node.appendChild, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) + +})(); + +=== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts === +export let x = import.meta; +>x : Symbol(x, Decl(moduleLookingFile01.ts, 0, 10)) + +export let y = import.metal; +>y : Symbol(y, Decl(moduleLookingFile01.ts, 1, 10)) + +export let z = import.import.import.malkovich; +>z : Symbol(z, Decl(moduleLookingFile01.ts, 2, 10)) + +=== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts === +let globalA = import.meta; +>globalA : Symbol(globalA, Decl(scriptLookingFile01.ts, 0, 3)) + +let globalB = import.metal; +>globalB : Symbol(globalB, Decl(scriptLookingFile01.ts, 1, 3)) + +let globalC = import.import.import.malkovich; +>globalC : Symbol(globalC, Decl(scriptLookingFile01.ts, 2, 3)) + +=== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts === +export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; +>foo : Symbol(foo, Decl(assignmentTargets.ts, 0, 12)) +>ImportMeta : Symbol(ImportMeta, Decl(lib.es5.d.ts, --, --), Decl(assignmentTargets.ts, 4, 16)) + +import.meta = foo; +>foo : Symbol(foo, Decl(assignmentTargets.ts, 0, 12)) + +// @Filename augmentations.ts +declare global { +>global : Symbol(global, Decl(assignmentTargets.ts, 1, 18)) + + interface ImportMeta { +>ImportMeta : Symbol(ImportMeta, Decl(lib.es5.d.ts, --, --), Decl(assignmentTargets.ts, 4, 16)) + + wellKnownProperty: { a: number, b: string, c: boolean }; +>wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24)) +>a : Symbol(a, Decl(assignmentTargets.ts, 6, 24)) +>b : Symbol(b, Decl(assignmentTargets.ts, 6, 35)) +>c : Symbol(c, Decl(assignmentTargets.ts, 6, 46)) + } +} + +const { a, b, c } = import.meta.wellKnownProperty; +>a : Symbol(a, Decl(assignmentTargets.ts, 10, 7)) +>b : Symbol(b, Decl(assignmentTargets.ts, 10, 10)) +>c : Symbol(c, Decl(assignmentTargets.ts, 10, 13)) +>import.meta.wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24)) +>wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24)) + diff --git a/tests/baselines/reference/importMeta(module=system,target=esnext).types b/tests/baselines/reference/importMeta(module=system,target=esnext).types new file mode 100644 index 00000000000..78d2e3395c8 --- /dev/null +++ b/tests/baselines/reference/importMeta(module=system,target=esnext).types @@ -0,0 +1,166 @@ +=== tests/cases/conformance/es2019/importMeta/example.ts === +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(async () => { +>(async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);})() : Promise +>(async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);}) : () => Promise +>async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);} : () => Promise + + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); +>response : Response +>await fetch(new URL("../hamsters.jpg", import.meta.url).toString()) : Response +>fetch(new URL("../hamsters.jpg", import.meta.url).toString()) : Promise +>fetch : (input: RequestInfo, init?: RequestInit) => Promise +>new URL("../hamsters.jpg", import.meta.url).toString() : string +>new URL("../hamsters.jpg", import.meta.url).toString : () => string +>new URL("../hamsters.jpg", import.meta.url) : URL +>URL : { new (url: string, base?: string | URL): URL; prototype: URL; createObjectURL(object: any): string; revokeObjectURL(url: string): void; } +>"../hamsters.jpg" : "../hamsters.jpg" +>import.meta.url : any +>import.meta : ImportMeta +>meta : any +>url : any +>toString : () => string + + const blob = await response.blob(); +>blob : Blob +>await response.blob() : Blob +>response.blob() : Promise +>response.blob : () => Promise +>response : Response +>blob : () => Promise + + const size = import.meta.scriptElement.dataset.size || 300; +>size : any +>import.meta.scriptElement.dataset.size || 300 : any +>import.meta.scriptElement.dataset.size : any +>import.meta.scriptElement.dataset : any +>import.meta.scriptElement : any +>import.meta : ImportMeta +>meta : any +>scriptElement : any +>dataset : any +>size : any +>300 : 300 + + const image = new Image(); +>image : HTMLImageElement +>new Image() : HTMLImageElement +>Image : new (width?: number, height?: number) => HTMLImageElement + + image.src = URL.createObjectURL(blob); +>image.src = URL.createObjectURL(blob) : string +>image.src : string +>image : HTMLImageElement +>src : string +>URL.createObjectURL(blob) : string +>URL.createObjectURL : (object: any) => string +>URL : { new (url: string, base?: string | URL): URL; prototype: URL; createObjectURL(object: any): string; revokeObjectURL(url: string): void; } +>createObjectURL : (object: any) => string +>blob : Blob + + image.width = image.height = size; +>image.width = image.height = size : any +>image.width : number +>image : HTMLImageElement +>width : number +>image.height = size : any +>image.height : number +>image : HTMLImageElement +>height : number +>size : any + + document.body.appendChild(image); +>document.body.appendChild(image) : HTMLImageElement +>document.body.appendChild : (newChild: T) => T +>document.body : HTMLElement +>document : Document +>body : HTMLElement +>appendChild : (newChild: T) => T +>image : HTMLImageElement + +})(); + +=== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts === +export let x = import.meta; +>x : ImportMeta +>import.meta : ImportMeta +>meta : any + +export let y = import.metal; +>y : any +>import.metal : any +>metal : any + +export let z = import.import.import.malkovich; +>z : any +>import.import.import.malkovich : any +>import.import.import : any +>import.import : any +>import : any +>import : any +>malkovich : any + +=== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts === +let globalA = import.meta; +>globalA : ImportMeta +>import.meta : ImportMeta +>meta : any + +let globalB = import.metal; +>globalB : any +>import.metal : any +>metal : any + +let globalC = import.import.import.malkovich; +>globalC : any +>import.import.import.malkovich : any +>import.import.import : any +>import.import : any +>import : any +>import : any +>malkovich : any + +=== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts === +export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; +>foo : ImportMeta +>import.meta.blah = import.meta.blue = import.meta : ImportMeta +>import.meta.blah : any +>import.meta : ImportMeta +>meta : any +>blah : any +>import.meta.blue = import.meta : ImportMeta +>import.meta.blue : any +>import.meta : ImportMeta +>meta : any +>blue : any +>import.meta : ImportMeta +>meta : any + +import.meta = foo; +>import.meta = foo : ImportMeta +>import.meta : ImportMeta +>meta : any +>foo : ImportMeta + +// @Filename augmentations.ts +declare global { +>global : any + + interface ImportMeta { + wellKnownProperty: { a: number, b: string, c: boolean }; +>wellKnownProperty : { a: number; b: string; c: boolean; } +>a : number +>b : string +>c : boolean + } +} + +const { a, b, c } = import.meta.wellKnownProperty; +>a : number +>b : string +>c : boolean +>import.meta.wellKnownProperty : { a: number; b: string; c: boolean; } +>import.meta : ImportMeta +>meta : any +>wellKnownProperty : { a: number; b: string; c: boolean; } + diff --git a/tests/cases/conformance/es2019/importMeta/importMeta.ts b/tests/cases/conformance/es2019/importMeta/importMeta.ts index 71d635a6534..30d604b51f8 100644 --- a/tests/cases/conformance/es2019/importMeta/importMeta.ts +++ b/tests/cases/conformance/es2019/importMeta/importMeta.ts @@ -1,6 +1,6 @@ -// @target: esnext -// @module: esnext +// @target: esnext,es5 +// @module: esnext,commonjs,system // @lib: es5,dom // @Filename: example.ts diff --git a/tests/cases/conformance/es2019/importMeta/importMetaES5.ts b/tests/cases/conformance/es2019/importMeta/importMetaES5.ts deleted file mode 100644 index b11a32ecc9b..00000000000 --- a/tests/cases/conformance/es2019/importMeta/importMetaES5.ts +++ /dev/null @@ -1,42 +0,0 @@ - -// @target: es5 -// @module: commonjs -// @lib: es5,dom - -// @Filename: example.ts -// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example -(async () => { - const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); - const blob = await response.blob(); - - const size = import.meta.scriptElement.dataset.size || 300; - - const image = new Image(); - image.src = URL.createObjectURL(blob); - image.width = image.height = size; - - document.body.appendChild(image); -})(); - -// @Filename: moduleLookingFile01.ts -export let x = import.meta; -export let y = import.metal; -export let z = import.import.import.malkovich; - -// @Filename: scriptLookingFile01.ts -let globalA = import.meta; -let globalB = import.metal; -let globalC = import.import.import.malkovich; - -// @Filename: assignmentTargets.ts -export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; -import.meta = foo; - -// @Filename augmentations.ts -declare global { - interface ImportMeta { - wellKnownProperty: { a: number, b: string, c: boolean }; - } -} - -const { a, b, c } = import.meta.wellKnownProperty; \ No newline at end of file From e10991413c0d966eeee3e2f619a2c5c3d192f6be Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 12 Aug 2019 13:13:28 -0700 Subject: [PATCH 03/11] Print program only if there are files are added or removed from the program. --- src/server/project.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/server/project.ts b/src/server/project.ts index 91ac212ea13..f9465d8b242 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1009,9 +1009,12 @@ namespace ts.server { ); const elapsed = timestamp() - start; this.writeLog(`Finishing updateGraphWorker: Project: ${this.getProjectName()} Version: ${this.getProjectVersion()} structureChanged: ${hasNewProgram} Elapsed: ${elapsed}ms`); - if (this.program !== oldProgram) { + if (this.hasAddedorRemovedFiles) { this.print(); } + else if (this.program !== oldProgram) { + this.writeLog(`Different program with same set of files:: oldProgram.structureIsReused:: ${oldProgram && oldProgram.structureIsReused}`); + } return hasNewProgram; } From b3268a7e061481a5d491e88f21d076943b342051 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 12 Aug 2019 13:33:04 -0700 Subject: [PATCH 04/11] Do not emit 'this' for __awaiter helper at the top level of a strict-mode file. (#32823) --- src/compiler/transformers/es2017.ts | 36 +++++++++++++++--- src/compiler/transformers/es2018.ts | 38 ++++++++++++++----- src/compiler/utilities.ts | 37 ++++++++++++++++++ .../asyncAwaitIsolatedModules_es5.js | 15 ++++---- .../asyncAwaitIsolatedModules_es6.js | 14 +++---- .../reference/asyncFunctionsAcrossFiles.js | 4 +- .../reference/exportDefaultAsyncFunction2.js | 2 +- .../importCallExpressionAsyncES3AMD.js | 5 +-- .../importCallExpressionAsyncES3CJS.js | 5 +-- .../importCallExpressionAsyncES3System.js | 7 ++-- .../importCallExpressionAsyncES3UMD.js | 5 +-- .../importCallExpressionAsyncES5AMD.js | 5 +-- .../importCallExpressionAsyncES5CJS.js | 5 +-- .../importCallExpressionAsyncES5System.js | 7 ++-- .../importCallExpressionAsyncES5UMD.js | 5 +-- .../importCallExpressionAsyncES6AMD.js | 4 +- .../importCallExpressionAsyncES6CJS.js | 4 +- .../importCallExpressionAsyncES6System.js | 4 +- .../importCallExpressionAsyncES6UMD.js | 4 +- .../importMeta(module=commonjs,target=es5).js | 3 +- .../importMeta(module=esnext,target=es5).js | 3 +- .../importMeta(module=system,target=es5).js | 4 +- ...uxLikeDeferredInferenceAllowsAssignment.js | 3 +- 23 files changed, 144 insertions(+), 75 deletions(-) diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 98f42b5a564..005d5a8fdd6 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -41,6 +41,8 @@ namespace ts { /** A set of node IDs for generated super accessors (variable statements). */ const substitutedSuperAccessors: boolean[] = []; + let topLevel: boolean; + // Save the previous transformation hooks. const previousOnEmitNode = context.onEmitNode; const previousOnSubstituteNode = context.onSubstituteNode; @@ -56,11 +58,26 @@ namespace ts { return node; } + topLevel = isEffectiveStrictModeSourceFile(node, compilerOptions); const visited = visitEachChild(node, visitor, context); addEmitHelpers(visited, context.readEmitHelpers()); return visited; } + function doOutsideOfTopLevel(cb: (value: T) => U, value: T) { + if (topLevel) { + topLevel = false; + const result = cb(value); + topLevel = true; + return result; + } + return cb(value); + } + + function visitDefault(node: Node): VisitResult { + return visitEachChild(node, visitor, context); + } + function visitor(node: Node): VisitResult { if ((node.transformFlags & TransformFlags.ContainsES2017) === 0) { return node; @@ -74,13 +91,13 @@ namespace ts { return visitAwaitExpression(node); case SyntaxKind.MethodDeclaration: - return visitMethodDeclaration(node); + return doOutsideOfTopLevel(visitMethodDeclaration, node); case SyntaxKind.FunctionDeclaration: - return visitFunctionDeclaration(node); + return doOutsideOfTopLevel(visitFunctionDeclaration, node); case SyntaxKind.FunctionExpression: - return visitFunctionExpression(node); + return doOutsideOfTopLevel(visitFunctionExpression, node); case SyntaxKind.ArrowFunction: return visitArrowFunction(node); @@ -97,6 +114,13 @@ namespace ts { } return visitEachChild(node, visitor, context); + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + case SyntaxKind.Constructor: + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: + return doOutsideOfTopLevel(visitDefault, node); + default: return visitEachChild(node, visitor, context); } @@ -433,6 +457,7 @@ namespace ts { createReturn( createAwaiterHelper( context, + !topLevel, hasLexicalArguments, promiseConstructor, transformAsyncFunctionBodyWorker(node.body, statementOffset) @@ -473,6 +498,7 @@ namespace ts { else { const expression = createAwaiterHelper( context, + !topLevel, hasLexicalArguments, promiseConstructor, transformAsyncFunctionBodyWorker(node.body!) @@ -786,7 +812,7 @@ namespace ts { };` }; - function createAwaiterHelper(context: TransformationContext, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression | undefined, body: Block) { + function createAwaiterHelper(context: TransformationContext, hasLexicalThis: boolean, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression | undefined, body: Block) { context.requestEmitHelper(awaiterHelper); const generatorFunc = createFunctionExpression( @@ -806,7 +832,7 @@ namespace ts { getUnscopedHelperName("__awaiter"), /*typeArguments*/ undefined, [ - createThis(), + hasLexicalThis ? createThis() : createVoidZero(), hasLexicalArguments ? createIdentifier("arguments") : createVoidZero(), promiseConstructor ? createExpressionFromEntityName(promiseConstructor) : createVoidZero(), generatorFunc diff --git a/src/compiler/transformers/es2018.ts b/src/compiler/transformers/es2018.ts index c723da3d312..bf9cc61039d 100644 --- a/src/compiler/transformers/es2018.ts +++ b/src/compiler/transformers/es2018.ts @@ -26,6 +26,7 @@ namespace ts { let enabledSubstitutions: ESNextSubstitutionFlags; let enclosingFunctionFlags: FunctionFlags; let enclosingSuperContainerFlags: NodeCheckFlags = 0; + let topLevel: boolean; /** Keeps track of property names accessed on super (`super.x`) within async functions. */ let capturedSuperProperties: UnderscoreEscapedMap; @@ -42,6 +43,7 @@ namespace ts { } exportedVariableStatement = false; + topLevel = isEffectiveStrictModeSourceFile(node, compilerOptions); const visited = visitEachChild(node, visitor, context); addEmitHelpers(visited, context.readEmitHelpers()); return visited; @@ -62,6 +64,20 @@ namespace ts { return node; } + function doOutsideOfTopLevel(cb: (value: T) => U, value: T) { + if (topLevel) { + topLevel = false; + const result = cb(value); + topLevel = true; + return result; + } + return cb(value); + } + + function visitDefault(node: Node): VisitResult { + return visitEachChild(node, visitor, context); + } + function visitorWorker(node: Node, noDestructuringValue: boolean): VisitResult { if ((node.transformFlags & TransformFlags.ContainsES2018) === 0) { return node; @@ -92,17 +108,17 @@ namespace ts { case SyntaxKind.VoidExpression: return visitVoidExpression(node as VoidExpression); case SyntaxKind.Constructor: - return visitConstructorDeclaration(node as ConstructorDeclaration); + return doOutsideOfTopLevel(visitConstructorDeclaration, node as ConstructorDeclaration); case SyntaxKind.MethodDeclaration: - return visitMethodDeclaration(node as MethodDeclaration); + return doOutsideOfTopLevel(visitMethodDeclaration, node as MethodDeclaration); case SyntaxKind.GetAccessor: - return visitGetAccessorDeclaration(node as GetAccessorDeclaration); + return doOutsideOfTopLevel(visitGetAccessorDeclaration, node as GetAccessorDeclaration); case SyntaxKind.SetAccessor: - return visitSetAccessorDeclaration(node as SetAccessorDeclaration); + return doOutsideOfTopLevel(visitSetAccessorDeclaration, node as SetAccessorDeclaration); case SyntaxKind.FunctionDeclaration: - return visitFunctionDeclaration(node as FunctionDeclaration); + return doOutsideOfTopLevel(visitFunctionDeclaration, node as FunctionDeclaration); case SyntaxKind.FunctionExpression: - return visitFunctionExpression(node as FunctionExpression); + return doOutsideOfTopLevel(visitFunctionExpression, node as FunctionExpression); case SyntaxKind.ArrowFunction: return visitArrowFunction(node as ArrowFunction); case SyntaxKind.Parameter: @@ -121,6 +137,9 @@ namespace ts { hasSuperElementAccess = true; } return visitEachChild(node, visitor, context); + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: + return doOutsideOfTopLevel(visitDefault, node); default: return visitEachChild(node, visitor, context); } @@ -754,7 +773,8 @@ namespace ts { node.body!, visitLexicalEnvironment(node.body!.statements, visitor, context, statementOffset) ) - ) + ), + !topLevel ) ); @@ -1057,7 +1077,7 @@ namespace ts { };` }; - function createAsyncGeneratorHelper(context: TransformationContext, generatorFunc: FunctionExpression) { + function createAsyncGeneratorHelper(context: TransformationContext, generatorFunc: FunctionExpression, hasLexicalThis: boolean) { context.requestEmitHelper(awaitHelper); context.requestEmitHelper(asyncGeneratorHelper); @@ -1068,7 +1088,7 @@ namespace ts { getUnscopedHelperName("__asyncGenerator"), /*typeArguments*/ undefined, [ - createThis(), + hasLexicalThis ? createThis() : createVoidZero(), createIdentifier("arguments"), generatorFunc ] diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index c020c1e859e..aa442d822e4 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -700,6 +700,43 @@ namespace ts { return isExternalModule(node) || compilerOptions.isolatedModules || ((getEmitModuleKind(compilerOptions) === ModuleKind.CommonJS) && !!node.commonJsModuleIndicator); } + /** + * Returns whether the source file will be treated as if it were in strict mode at runtime. + */ + export function isEffectiveStrictModeSourceFile(node: SourceFile, compilerOptions: CompilerOptions) { + // We can only verify strict mode for JS/TS files + switch (node.scriptKind) { + case ScriptKind.JS: + case ScriptKind.TS: + case ScriptKind.JSX: + case ScriptKind.TSX: + break; + default: + return false; + } + // Strict mode does not matter for declaration files. + if (node.isDeclarationFile) { + return false; + } + // If `alwaysStrict` is set, then treat the file as strict. + if (getStrictOptionValue(compilerOptions, "alwaysStrict")) { + return true; + } + // Starting with a "use strict" directive indicates the file is strict. + if (startsWithUseStrict(node.statements)) { + return true; + } + if (isExternalModule(node) || compilerOptions.isolatedModules) { + // ECMAScript Modules are always strict. + if (getEmitModuleKind(compilerOptions) >= ModuleKind.ES2015) { + return true; + } + // Other modules are strict unless otherwise specified. + return !compilerOptions.noImplicitUseStrict; + } + return false; + } + export function isBlockScope(node: Node, parentNode: Node): boolean { switch (node.kind) { case SyntaxKind.SourceFile: diff --git a/tests/baselines/reference/asyncAwaitIsolatedModules_es5.js b/tests/baselines/reference/asyncAwaitIsolatedModules_es5.js index 934f6be814a..ec3837911de 100644 --- a/tests/baselines/reference/asyncAwaitIsolatedModules_es5.js +++ b/tests/baselines/reference/asyncAwaitIsolatedModules_es5.js @@ -77,7 +77,6 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var _this = this; Object.defineProperty(exports, "__esModule", { value: true }); var missing_1 = require("missing"); function f0() { @@ -110,25 +109,25 @@ var f6 = function () { return [2 /*return*/]; }); }); }; -var f7 = function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { +var f7 = function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/]; }); }); }; -var f8 = function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { +var f8 = function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/]; }); }); }; -var f9 = function () { return __awaiter(_this, void 0, missing_1.MyPromise, function () { return __generator(this, function (_a) { +var f9 = function () { return __awaiter(void 0, void 0, missing_1.MyPromise, function () { return __generator(this, function (_a) { return [2 /*return*/]; }); }); }; -var f10 = function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { +var f10 = function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, p]; }); }); }; -var f11 = function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { +var f11 = function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, mp]; }); }); }; -var f12 = function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { +var f12 = function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, mp]; }); }); }; -var f13 = function () { return __awaiter(_this, void 0, missing_1.MyPromise, function () { return __generator(this, function (_a) { +var f13 = function () { return __awaiter(void 0, void 0, missing_1.MyPromise, function () { return __generator(this, function (_a) { return [2 /*return*/, p]; }); }); }; var o = { diff --git a/tests/baselines/reference/asyncAwaitIsolatedModules_es6.js b/tests/baselines/reference/asyncAwaitIsolatedModules_es6.js index 2b956515ba1..015992805bc 100644 --- a/tests/baselines/reference/asyncAwaitIsolatedModules_es6.js +++ b/tests/baselines/reference/asyncAwaitIsolatedModules_es6.js @@ -67,13 +67,13 @@ let f5 = function () { let f6 = function () { return __awaiter(this, void 0, void 0, function* () { }); }; -let f7 = () => __awaiter(this, void 0, void 0, function* () { }); -let f8 = () => __awaiter(this, void 0, void 0, function* () { }); -let f9 = () => __awaiter(this, void 0, void 0, function* () { }); -let f10 = () => __awaiter(this, void 0, void 0, function* () { return p; }); -let f11 = () => __awaiter(this, void 0, void 0, function* () { return mp; }); -let f12 = () => __awaiter(this, void 0, void 0, function* () { return mp; }); -let f13 = () => __awaiter(this, void 0, void 0, function* () { return p; }); +let f7 = () => __awaiter(void 0, void 0, void 0, function* () { }); +let f8 = () => __awaiter(void 0, void 0, void 0, function* () { }); +let f9 = () => __awaiter(void 0, void 0, void 0, function* () { }); +let f10 = () => __awaiter(void 0, void 0, void 0, function* () { return p; }); +let f11 = () => __awaiter(void 0, void 0, void 0, function* () { return mp; }); +let f12 = () => __awaiter(void 0, void 0, void 0, function* () { return mp; }); +let f13 = () => __awaiter(void 0, void 0, void 0, function* () { return p; }); let o = { m1() { return __awaiter(this, void 0, void 0, function* () { }); diff --git a/tests/baselines/reference/asyncFunctionsAcrossFiles.js b/tests/baselines/reference/asyncFunctionsAcrossFiles.js index cd86f20c69d..642558c7206 100644 --- a/tests/baselines/reference/asyncFunctionsAcrossFiles.js +++ b/tests/baselines/reference/asyncFunctionsAcrossFiles.js @@ -27,7 +27,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }; import { a } from './a'; export const b = { - f: () => __awaiter(this, void 0, void 0, function* () { + f: () => __awaiter(void 0, void 0, void 0, function* () { yield a.f(); }) }; @@ -43,7 +43,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }; import { b } from './b'; export const a = { - f: () => __awaiter(this, void 0, void 0, function* () { + f: () => __awaiter(void 0, void 0, void 0, function* () { yield b.f(); }) }; diff --git a/tests/baselines/reference/exportDefaultAsyncFunction2.js b/tests/baselines/reference/exportDefaultAsyncFunction2.js index ad9b9086a74..a94ad0f12d4 100644 --- a/tests/baselines/reference/exportDefaultAsyncFunction2.js +++ b/tests/baselines/reference/exportDefaultAsyncFunction2.js @@ -43,7 +43,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; -export default () => __awaiter(this, void 0, void 0, function* () { return 0; }); +export default () => __awaiter(void 0, void 0, void 0, function* () { return 0; }); //// [c.js] import { async } from 'asyncawait'; export default async(); diff --git a/tests/baselines/reference/importCallExpressionAsyncES3AMD.js b/tests/baselines/reference/importCallExpressionAsyncES3AMD.js index 9b4f7f76cc7..5f83ff55b04 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES3AMD.js +++ b/tests/baselines/reference/importCallExpressionAsyncES3AMD.js @@ -67,7 +67,6 @@ var __generator = (this && this.__generator) || function (thisArg, body) { }; define(["require", "exports"], function (require, exports) { "use strict"; - var _this = this; exports.__esModule = true; function fn() { return __awaiter(this, void 0, void 0, function () { @@ -105,7 +104,7 @@ define(["require", "exports"], function (require, exports) { }()); exports.cl1 = cl1; exports.obj = { - m: function () { return __awaiter(_this, void 0, void 0, function () { + m: function () { return __awaiter(void 0, void 0, void 0, function () { var req; return __generator(this, function (_a) { switch (_a.label) { @@ -139,7 +138,7 @@ define(["require", "exports"], function (require, exports) { return cl2; }()); exports.cl2 = cl2; - exports.l = function () { return __awaiter(_this, void 0, void 0, function () { + exports.l = function () { return __awaiter(void 0, void 0, void 0, function () { var req; return __generator(this, function (_a) { switch (_a.label) { diff --git a/tests/baselines/reference/importCallExpressionAsyncES3CJS.js b/tests/baselines/reference/importCallExpressionAsyncES3CJS.js index 43b4c868529..fe621973598 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES3CJS.js +++ b/tests/baselines/reference/importCallExpressionAsyncES3CJS.js @@ -66,7 +66,6 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var _this = this; exports.__esModule = true; function fn() { return __awaiter(this, void 0, void 0, function () { @@ -104,7 +103,7 @@ var cl1 = /** @class */ (function () { }()); exports.cl1 = cl1; exports.obj = { - m: function () { return __awaiter(_this, void 0, void 0, function () { + m: function () { return __awaiter(void 0, void 0, void 0, function () { var req; return __generator(this, function (_a) { switch (_a.label) { @@ -138,7 +137,7 @@ var cl2 = /** @class */ (function () { return cl2; }()); exports.cl2 = cl2; -exports.l = function () { return __awaiter(_this, void 0, void 0, function () { +exports.l = function () { return __awaiter(void 0, void 0, void 0, function () { var req; return __generator(this, function (_a) { switch (_a.label) { diff --git a/tests/baselines/reference/importCallExpressionAsyncES3System.js b/tests/baselines/reference/importCallExpressionAsyncES3System.js index 6369c73b68b..e4cc24387bc 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES3System.js +++ b/tests/baselines/reference/importCallExpressionAsyncES3System.js @@ -67,8 +67,7 @@ System.register([], function (exports_1, context_1) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; - var _this, cl1, obj, cl2, l; - _this = this; + var cl1, obj, cl2, l; var __moduleName = context_1 && context_1.id; function fn() { return __awaiter(this, void 0, void 0, function () { @@ -109,7 +108,7 @@ System.register([], function (exports_1, context_1) { }()); exports_1("cl1", cl1); exports_1("obj", obj = { - m: function () { return __awaiter(_this, void 0, void 0, function () { + m: function () { return __awaiter(void 0, void 0, void 0, function () { var req; return __generator(this, function (_a) { switch (_a.label) { @@ -143,7 +142,7 @@ System.register([], function (exports_1, context_1) { return cl2; }()); exports_1("cl2", cl2); - exports_1("l", l = function () { return __awaiter(_this, void 0, void 0, function () { + exports_1("l", l = function () { return __awaiter(void 0, void 0, void 0, function () { var req; return __generator(this, function (_a) { switch (_a.label) { diff --git a/tests/baselines/reference/importCallExpressionAsyncES3UMD.js b/tests/baselines/reference/importCallExpressionAsyncES3UMD.js index 794678e871d..26788580672 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES3UMD.js +++ b/tests/baselines/reference/importCallExpressionAsyncES3UMD.js @@ -76,7 +76,6 @@ var __generator = (this && this.__generator) || function (thisArg, body) { })(function (require, exports) { "use strict"; var __syncRequire = typeof module === "object" && typeof module.exports === "object"; - var _this = this; exports.__esModule = true; function fn() { return __awaiter(this, void 0, void 0, function () { @@ -114,7 +113,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { }()); exports.cl1 = cl1; exports.obj = { - m: function () { return __awaiter(_this, void 0, void 0, function () { + m: function () { return __awaiter(void 0, void 0, void 0, function () { var req; return __generator(this, function (_a) { switch (_a.label) { @@ -148,7 +147,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { return cl2; }()); exports.cl2 = cl2; - exports.l = function () { return __awaiter(_this, void 0, void 0, function () { + exports.l = function () { return __awaiter(void 0, void 0, void 0, function () { var req; return __generator(this, function (_a) { switch (_a.label) { diff --git a/tests/baselines/reference/importCallExpressionAsyncES5AMD.js b/tests/baselines/reference/importCallExpressionAsyncES5AMD.js index 2451190c793..d2310ece41f 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES5AMD.js +++ b/tests/baselines/reference/importCallExpressionAsyncES5AMD.js @@ -67,7 +67,6 @@ var __generator = (this && this.__generator) || function (thisArg, body) { }; define(["require", "exports"], function (require, exports) { "use strict"; - var _this = this; Object.defineProperty(exports, "__esModule", { value: true }); function fn() { return __awaiter(this, void 0, void 0, function () { @@ -105,7 +104,7 @@ define(["require", "exports"], function (require, exports) { }()); exports.cl1 = cl1; exports.obj = { - m: function () { return __awaiter(_this, void 0, void 0, function () { + m: function () { return __awaiter(void 0, void 0, void 0, function () { var req; return __generator(this, function (_a) { switch (_a.label) { @@ -139,7 +138,7 @@ define(["require", "exports"], function (require, exports) { return cl2; }()); exports.cl2 = cl2; - exports.l = function () { return __awaiter(_this, void 0, void 0, function () { + exports.l = function () { return __awaiter(void 0, void 0, void 0, function () { var req; return __generator(this, function (_a) { switch (_a.label) { diff --git a/tests/baselines/reference/importCallExpressionAsyncES5CJS.js b/tests/baselines/reference/importCallExpressionAsyncES5CJS.js index cd60c69c4cf..4cc52e2add7 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES5CJS.js +++ b/tests/baselines/reference/importCallExpressionAsyncES5CJS.js @@ -66,7 +66,6 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var _this = this; Object.defineProperty(exports, "__esModule", { value: true }); function fn() { return __awaiter(this, void 0, void 0, function () { @@ -104,7 +103,7 @@ var cl1 = /** @class */ (function () { }()); exports.cl1 = cl1; exports.obj = { - m: function () { return __awaiter(_this, void 0, void 0, function () { + m: function () { return __awaiter(void 0, void 0, void 0, function () { var req; return __generator(this, function (_a) { switch (_a.label) { @@ -138,7 +137,7 @@ var cl2 = /** @class */ (function () { return cl2; }()); exports.cl2 = cl2; -exports.l = function () { return __awaiter(_this, void 0, void 0, function () { +exports.l = function () { return __awaiter(void 0, void 0, void 0, function () { var req; return __generator(this, function (_a) { switch (_a.label) { diff --git a/tests/baselines/reference/importCallExpressionAsyncES5System.js b/tests/baselines/reference/importCallExpressionAsyncES5System.js index da510e8d098..bc577e5c981 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES5System.js +++ b/tests/baselines/reference/importCallExpressionAsyncES5System.js @@ -67,8 +67,7 @@ System.register([], function (exports_1, context_1) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; - var _this, cl1, obj, cl2, l; - _this = this; + var cl1, obj, cl2, l; var __moduleName = context_1 && context_1.id; function fn() { return __awaiter(this, void 0, void 0, function () { @@ -109,7 +108,7 @@ System.register([], function (exports_1, context_1) { }()); exports_1("cl1", cl1); exports_1("obj", obj = { - m: function () { return __awaiter(_this, void 0, void 0, function () { + m: function () { return __awaiter(void 0, void 0, void 0, function () { var req; return __generator(this, function (_a) { switch (_a.label) { @@ -143,7 +142,7 @@ System.register([], function (exports_1, context_1) { return cl2; }()); exports_1("cl2", cl2); - exports_1("l", l = function () { return __awaiter(_this, void 0, void 0, function () { + exports_1("l", l = function () { return __awaiter(void 0, void 0, void 0, function () { var req; return __generator(this, function (_a) { switch (_a.label) { diff --git a/tests/baselines/reference/importCallExpressionAsyncES5UMD.js b/tests/baselines/reference/importCallExpressionAsyncES5UMD.js index 111b747ff32..8091c83c0ee 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES5UMD.js +++ b/tests/baselines/reference/importCallExpressionAsyncES5UMD.js @@ -76,7 +76,6 @@ var __generator = (this && this.__generator) || function (thisArg, body) { })(function (require, exports) { "use strict"; var __syncRequire = typeof module === "object" && typeof module.exports === "object"; - var _this = this; Object.defineProperty(exports, "__esModule", { value: true }); function fn() { return __awaiter(this, void 0, void 0, function () { @@ -114,7 +113,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { }()); exports.cl1 = cl1; exports.obj = { - m: function () { return __awaiter(_this, void 0, void 0, function () { + m: function () { return __awaiter(void 0, void 0, void 0, function () { var req; return __generator(this, function (_a) { switch (_a.label) { @@ -148,7 +147,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { return cl2; }()); exports.cl2 = cl2; - exports.l = function () { return __awaiter(_this, void 0, void 0, function () { + exports.l = function () { return __awaiter(void 0, void 0, void 0, function () { var req; return __generator(this, function (_a) { switch (_a.label) { diff --git a/tests/baselines/reference/importCallExpressionAsyncES6AMD.js b/tests/baselines/reference/importCallExpressionAsyncES6AMD.js index 80cf843ade9..b6c74d5cf73 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES6AMD.js +++ b/tests/baselines/reference/importCallExpressionAsyncES6AMD.js @@ -56,7 +56,7 @@ define(["require", "exports"], function (require, exports) { } exports.cl1 = cl1; exports.obj = { - m: () => __awaiter(this, void 0, void 0, function* () { + m: () => __awaiter(void 0, void 0, void 0, function* () { const req = yield new Promise((resolve_3, reject_3) => { require(['./test'], resolve_3, reject_3); }); // THREE }) }; @@ -70,7 +70,7 @@ define(["require", "exports"], function (require, exports) { } } exports.cl2 = cl2; - exports.l = () => __awaiter(this, void 0, void 0, function* () { + exports.l = () => __awaiter(void 0, void 0, void 0, function* () { const req = yield new Promise((resolve_5, reject_5) => { require(['./test'], resolve_5, reject_5); }); // FIVE }); }); diff --git a/tests/baselines/reference/importCallExpressionAsyncES6CJS.js b/tests/baselines/reference/importCallExpressionAsyncES6CJS.js index 7ce2b69b44c..8c4e7596bd5 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES6CJS.js +++ b/tests/baselines/reference/importCallExpressionAsyncES6CJS.js @@ -55,7 +55,7 @@ class cl1 { } exports.cl1 = cl1; exports.obj = { - m: () => __awaiter(this, void 0, void 0, function* () { + m: () => __awaiter(void 0, void 0, void 0, function* () { const req = yield Promise.resolve().then(() => require('./test')); // THREE }) }; @@ -69,6 +69,6 @@ class cl2 { } } exports.cl2 = cl2; -exports.l = () => __awaiter(this, void 0, void 0, function* () { +exports.l = () => __awaiter(void 0, void 0, void 0, function* () { const req = yield Promise.resolve().then(() => require('./test')); // FIVE }); diff --git a/tests/baselines/reference/importCallExpressionAsyncES6System.js b/tests/baselines/reference/importCallExpressionAsyncES6System.js index 8dd7e2f32e8..51c8832bb52 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES6System.js +++ b/tests/baselines/reference/importCallExpressionAsyncES6System.js @@ -60,7 +60,7 @@ System.register([], function (exports_1, context_1) { }; exports_1("cl1", cl1); exports_1("obj", obj = { - m: () => __awaiter(this, void 0, void 0, function* () { + m: () => __awaiter(void 0, void 0, void 0, function* () { const req = yield context_1.import('./test'); // THREE }) }); @@ -74,7 +74,7 @@ System.register([], function (exports_1, context_1) { } }; exports_1("cl2", cl2); - exports_1("l", l = () => __awaiter(this, void 0, void 0, function* () { + exports_1("l", l = () => __awaiter(void 0, void 0, void 0, function* () { const req = yield context_1.import('./test'); // FIVE })); } diff --git a/tests/baselines/reference/importCallExpressionAsyncES6UMD.js b/tests/baselines/reference/importCallExpressionAsyncES6UMD.js index f7dfe0d9934..2be59a1de74 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES6UMD.js +++ b/tests/baselines/reference/importCallExpressionAsyncES6UMD.js @@ -65,7 +65,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } exports.cl1 = cl1; exports.obj = { - m: () => __awaiter(this, void 0, void 0, function* () { + m: () => __awaiter(void 0, void 0, void 0, function* () { const req = yield __syncRequire ? Promise.resolve().then(() => require('./test')) : new Promise((resolve_3, reject_3) => { require(['./test'], resolve_3, reject_3); }); // THREE }) }; @@ -79,7 +79,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } } exports.cl2 = cl2; - exports.l = () => __awaiter(this, void 0, void 0, function* () { + exports.l = () => __awaiter(void 0, void 0, void 0, function* () { const req = yield __syncRequire ? Promise.resolve().then(() => require('./test')) : new Promise((resolve_5, reject_5) => { require(['./test'], resolve_5, reject_5); }); // FIVE }); }); diff --git a/tests/baselines/reference/importMeta(module=commonjs,target=es5).js b/tests/baselines/reference/importMeta(module=commonjs,target=es5).js index 1a8c764dd32..a4290bcb592 100644 --- a/tests/baselines/reference/importMeta(module=commonjs,target=es5).js +++ b/tests/baselines/reference/importMeta(module=commonjs,target=es5).js @@ -76,10 +76,9 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var _this = this; Object.defineProperty(exports, "__esModule", { value: true }); // Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example -(function () { return __awaiter(_this, void 0, void 0, function () { +(function () { return __awaiter(void 0, void 0, void 0, function () { var response, blob, size, image; return __generator(this, function (_a) { switch (_a.label) { diff --git a/tests/baselines/reference/importMeta(module=esnext,target=es5).js b/tests/baselines/reference/importMeta(module=esnext,target=es5).js index 57a51318e25..522b0f01661 100644 --- a/tests/baselines/reference/importMeta(module=esnext,target=es5).js +++ b/tests/baselines/reference/importMeta(module=esnext,target=es5).js @@ -75,9 +75,8 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var _this = this; // Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example -(function () { return __awaiter(_this, void 0, void 0, function () { +(function () { return __awaiter(void 0, void 0, void 0, function () { var response, blob, size, image; return __generator(this, function (_a) { switch (_a.label) { diff --git a/tests/baselines/reference/importMeta(module=system,target=es5).js b/tests/baselines/reference/importMeta(module=system,target=es5).js index ce9321f5fe9..3eda4156d8b 100644 --- a/tests/baselines/reference/importMeta(module=system,target=es5).js +++ b/tests/baselines/reference/importMeta(module=system,target=es5).js @@ -77,14 +77,12 @@ System.register([], function (exports_1, context_1) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; - var _this; - _this = this; var __moduleName = context_1 && context_1.id; return { setters: [], execute: function () { // Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example - (function () { return __awaiter(_this, void 0, void 0, function () { + (function () { return __awaiter(void 0, void 0, void 0, function () { var response, blob, size, image; return __generator(this, function (_a) { switch (_a.label) { diff --git a/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.js b/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.js index 88ae943f92a..3c2cb0e7626 100644 --- a/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.js +++ b/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.js @@ -198,7 +198,6 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var _this = this; exports.__esModule = true; var simpleAction = function (payload) { return ({ type: "SIMPLE_ACTION", @@ -206,7 +205,7 @@ var simpleAction = function (payload) { return ({ }); }; var thunkAction = function (param1, param2) { return function (dispatch, _a) { var foo = _a.foo; - return __awaiter(_this, void 0, void 0, function () { + return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_b) { return [2 /*return*/, foo]; }); From 4ab85bbf350b7a0b9a6ad320efcc58a67c155c68 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 12 Aug 2019 16:00:38 -0700 Subject: [PATCH 05/11] Add error message for keywords with escapes in them (#32718) * Add error message for keywords with escapes in them * Move check into parser during advance to next token to utilize context for contextual keywords * git add . * Add tests for extended escapes * Better error courtesy of @DanielRossenwaser * Add test of browser-inconsistent case and alter condition to match spec * Merge adjacent conditions * Use seperate functions for checking keywords vs not * Use flags to track unicode escape presence * Adjust error text --- src/compiler/diagnosticMessages.json | 4 + src/compiler/parser.ts | 13 +++- src/compiler/scanner.ts | 6 ++ src/compiler/types.ts | 2 + src/compiler/utilities.ts | 4 + .../reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + .../scannerUnicodeEscapeInKeyword1.errors.txt | 7 ++ .../scannerUnicodeEscapeInKeyword2.errors.txt | 61 +++++++++++++++ .../scannerUnicodeEscapeInKeyword2.js | 62 +++++++++++++++ .../scannerUnicodeEscapeInKeyword2.symbols | 62 +++++++++++++++ .../scannerUnicodeEscapeInKeyword2.types | 77 +++++++++++++++++++ ...hStatementsWithMultipleDefaults.errors.txt | 14 +--- .../scannerUnicodeEscapeInKeyword2.ts | 39 ++++++++++ 14 files changed, 341 insertions(+), 12 deletions(-) create mode 100644 tests/baselines/reference/scannerUnicodeEscapeInKeyword1.errors.txt create mode 100644 tests/baselines/reference/scannerUnicodeEscapeInKeyword2.errors.txt create mode 100644 tests/baselines/reference/scannerUnicodeEscapeInKeyword2.js create mode 100644 tests/baselines/reference/scannerUnicodeEscapeInKeyword2.symbols create mode 100644 tests/baselines/reference/scannerUnicodeEscapeInKeyword2.types create mode 100644 tests/cases/conformance/scanner/ecmascript5/scannerUnicodeEscapeInKeyword2.ts diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index e22d64e0f72..47ec8756d20 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -851,6 +851,10 @@ "category": "Error", "code": 1259 }, + "Keywords cannot contain escape characters.": { + "category": "Error", + "code": 1260 + }, "'with' statements are not allowed in an async function block.": { "category": "Error", "code": 1300 diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 4c8a5e567f8..6451a4f5c96 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1086,10 +1086,19 @@ namespace ts { return currentToken; } - function nextToken(): SyntaxKind { + function nextTokenWithoutCheck() { return currentToken = scanner.scan(); } + function nextToken(): SyntaxKind { + // if the keyword had an escape + if (isKeyword(currentToken) && (scanner.hasUnicodeEscape() || scanner.hasExtendedUnicodeEscape())) { + // issue a parse error for the escape + parseErrorAt(scanner.getTokenPos(), scanner.getTextPos(), Diagnostics.Keywords_cannot_contain_escape_characters); + } + return nextTokenWithoutCheck(); + } + function nextTokenJSDoc(): JSDocSyntaxKind { return currentToken = scanner.scanJsDocToken(); } @@ -1380,7 +1389,7 @@ namespace ts { node.originalKeywordKind = token(); } node.escapedText = escapeLeadingUnderscores(internIdentifier(scanner.getTokenValue())); - nextToken(); + nextTokenWithoutCheck(); return finishNode(node); } diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 44a28916185..75f0b31c896 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -18,6 +18,7 @@ namespace ts { getTokenPos(): number; getTokenText(): string; getTokenValue(): string; + hasUnicodeEscape(): boolean; hasExtendedUnicodeEscape(): boolean; hasPrecedingLineBreak(): boolean; isIdentifier(): boolean; @@ -884,6 +885,7 @@ namespace ts { getTokenPos: () => tokenPos, getTokenText: () => text.substring(tokenPos, pos), getTokenValue: () => tokenValue, + hasUnicodeEscape: () => (tokenFlags & TokenFlags.UnicodeEscape) !== 0, hasExtendedUnicodeEscape: () => (tokenFlags & TokenFlags.ExtendedUnicodeEscape) !== 0, hasPrecedingLineBreak: () => (tokenFlags & TokenFlags.PrecedingLineBreak) !== 0, isIdentifier: () => token === SyntaxKind.Identifier || token > SyntaxKind.LastReservedWord, @@ -1245,6 +1247,7 @@ namespace ts { return scanExtendedUnicodeEscape(); } + tokenFlags |= TokenFlags.UnicodeEscape; // '\uDDDD' return scanHexadecimalEscape(/*numDigits*/ 4); @@ -1376,6 +1379,7 @@ namespace ts { if (!(ch >= 0 && isIdentifierPart(ch, languageVersion))) { break; } + tokenFlags |= TokenFlags.UnicodeEscape; result += text.substring(start, pos); result += utf16EncodeAsString(ch); // Valid Unicode escape is always six characters @@ -1868,6 +1872,7 @@ namespace ts { const cookedChar = peekUnicodeEscape(); if (cookedChar >= 0 && isIdentifierStart(cookedChar, languageVersion)) { pos += 6; + tokenFlags |= TokenFlags.UnicodeEscape; tokenValue = String.fromCharCode(cookedChar) + scanIdentifierParts(); return token = getIdentifierToken(); } @@ -2156,6 +2161,7 @@ namespace ts { const cookedChar = peekUnicodeEscape(); if (cookedChar >= 0 && isIdentifierStart(cookedChar, languageVersion)) { pos += 6; + tokenFlags |= TokenFlags.UnicodeEscape; tokenValue = String.fromCharCode(cookedChar) + scanIdentifierParts(); return token = getIdentifierToken(); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 02dcc828486..a4373b7dc01 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1679,6 +1679,8 @@ namespace ts { /* @internal */ ContainsSeparator = 1 << 9, // e.g. `0b1100_0101` /* @internal */ + UnicodeEscape = 1 << 10, + /* @internal */ BinaryOrOctalSpecifier = BinarySpecifier | OctalSpecifier, /* @internal */ NumericLiteralFlags = Scientific | Octal | HexSpecifier | BinaryOrOctalSpecifier | ContainsSeparator diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index aa442d822e4..0bb3c799af5 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2682,6 +2682,10 @@ namespace ts { return isKeyword(token) && !isContextualKeyword(token); } + export function isFutureReservedKeyword(token: SyntaxKind): boolean { + return SyntaxKind.FirstFutureReservedWord <= token && token <= SyntaxKind.LastFutureReservedWord; + } + export function isStringANonContextualKeyword(name: string) { const token = stringToToken(name); return token !== undefined && isNonContextualKeyword(token); diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 3ed8570cab8..4c88e5fe219 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3174,6 +3174,7 @@ declare namespace ts { getTokenPos(): number; getTokenText(): string; getTokenValue(): string; + hasUnicodeEscape(): boolean; hasExtendedUnicodeEscape(): boolean; hasPrecedingLineBreak(): boolean; isIdentifier(): boolean; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 3b2ad792601..bb30ccc908d 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3174,6 +3174,7 @@ declare namespace ts { getTokenPos(): number; getTokenText(): string; getTokenValue(): string; + hasUnicodeEscape(): boolean; hasExtendedUnicodeEscape(): boolean; hasPrecedingLineBreak(): boolean; isIdentifier(): boolean; diff --git a/tests/baselines/reference/scannerUnicodeEscapeInKeyword1.errors.txt b/tests/baselines/reference/scannerUnicodeEscapeInKeyword1.errors.txt new file mode 100644 index 00000000000..ec7c0033271 --- /dev/null +++ b/tests/baselines/reference/scannerUnicodeEscapeInKeyword1.errors.txt @@ -0,0 +1,7 @@ +tests/cases/conformance/scanner/ecmascript5/scannerUnicodeEscapeInKeyword1.ts(1,1): error TS1260: Keywords cannot contain escape characters. + + +==== tests/cases/conformance/scanner/ecmascript5/scannerUnicodeEscapeInKeyword1.ts (1 errors) ==== + \u0076ar x = "hello"; + ~~~~~~~~ +!!! error TS1260: Keywords cannot contain escape characters. \ No newline at end of file diff --git a/tests/baselines/reference/scannerUnicodeEscapeInKeyword2.errors.txt b/tests/baselines/reference/scannerUnicodeEscapeInKeyword2.errors.txt new file mode 100644 index 00000000000..f65d70920c5 --- /dev/null +++ b/tests/baselines/reference/scannerUnicodeEscapeInKeyword2.errors.txt @@ -0,0 +1,61 @@ +tests/cases/conformance/scanner/ecmascript5/file1.ts(3,5): error TS1260: Keywords cannot contain escape characters. +tests/cases/conformance/scanner/ecmascript5/file1.ts(8,5): error TS1260: Keywords cannot contain escape characters. +tests/cases/conformance/scanner/ecmascript5/file1.ts(13,1): error TS1260: Keywords cannot contain escape characters. +tests/cases/conformance/scanner/ecmascript5/file2.ts(1,1): error TS1260: Keywords cannot contain escape characters. +tests/cases/conformance/scanner/ecmascript5/file2.ts(5,5): error TS1260: Keywords cannot contain escape characters. +tests/cases/conformance/scanner/ecmascript5/file2.ts(10,5): error TS1260: Keywords cannot contain escape characters. +tests/cases/conformance/scanner/ecmascript5/file2.ts(15,1): error TS1260: Keywords cannot contain escape characters. + + +==== tests/cases/conformance/scanner/ecmascript5/file1.ts (3 errors) ==== + var \u0061wait = 12; // ok + async function main() { + \u0061wait 12; // not ok + ~~~~~~~~~~ +!!! error TS1260: Keywords cannot contain escape characters. + } + + var \u0079ield = 12; // ok + function *gen() { + \u0079ield 12; //not ok + ~~~~~~~~~~ +!!! error TS1260: Keywords cannot contain escape characters. + } + + type typ\u0065 = 12; // ok + + typ\u0065 notok = 0; // not ok + ~~~~~~~~~ +!!! error TS1260: Keywords cannot contain escape characters. + + export {}; +==== tests/cases/conformance/scanner/ecmascript5/file2.ts (4 errors) ==== + \u{0076}ar x = "hello"; // not ok + ~~~~~~~~~~ +!!! error TS1260: Keywords cannot contain escape characters. + + var \u{0061}wait = 12; // ok + async function main() { + \u{0061}wait 12; // not ok + ~~~~~~~~~~~~ +!!! error TS1260: Keywords cannot contain escape characters. + } + + var \u{0079}ield = 12; // ok + function *gen() { + \u{0079}ield 12; //not ok + ~~~~~~~~~~~~ +!!! error TS1260: Keywords cannot contain escape characters. + } + + type typ\u{0065} = 12; // ok + + typ\u{0065} notok = 0; // not ok + ~~~~~~~~~~~ +!!! error TS1260: Keywords cannot contain escape characters. + + export {}; + + const a = {def\u0061ult: 12}; // OK, `default` not in keyword position + // chrome and jsc may still error on this, ref https://bugs.chromium.org/p/chromium/issues/detail?id=993000 and https://bugs.webkit.org/show_bug.cgi?id=200638 + \ No newline at end of file diff --git a/tests/baselines/reference/scannerUnicodeEscapeInKeyword2.js b/tests/baselines/reference/scannerUnicodeEscapeInKeyword2.js new file mode 100644 index 00000000000..d93ba71d1d3 --- /dev/null +++ b/tests/baselines/reference/scannerUnicodeEscapeInKeyword2.js @@ -0,0 +1,62 @@ +//// [tests/cases/conformance/scanner/ecmascript5/scannerUnicodeEscapeInKeyword2.ts] //// + +//// [file1.ts] +var \u0061wait = 12; // ok +async function main() { + \u0061wait 12; // not ok +} + +var \u0079ield = 12; // ok +function *gen() { + \u0079ield 12; //not ok +} + +type typ\u0065 = 12; // ok + +typ\u0065 notok = 0; // not ok + +export {}; +//// [file2.ts] +\u{0076}ar x = "hello"; // not ok + +var \u{0061}wait = 12; // ok +async function main() { + \u{0061}wait 12; // not ok +} + +var \u{0079}ield = 12; // ok +function *gen() { + \u{0079}ield 12; //not ok +} + +type typ\u{0065} = 12; // ok + +typ\u{0065} notok = 0; // not ok + +export {}; + +const a = {def\u0061ult: 12}; // OK, `default` not in keyword position +// chrome and jsc may still error on this, ref https://bugs.chromium.org/p/chromium/issues/detail?id=993000 and https://bugs.webkit.org/show_bug.cgi?id=200638 + + +//// [file1.js] +var \u0061wait = 12; // ok +async function main() { + await 12; // not ok +} +var \u0079ield = 12; // ok +function* gen() { + yield 12; //not ok +} +//// [file2.js] +var x = "hello"; // not ok +var \u{0061}wait = 12; // ok +async function main() { + await 12; // not ok +} +var \u{0079}ield = 12; // ok +function* gen() { + yield 12; //not ok +} +const a = { def\u0061ult: 12 }; // OK, `default` not in keyword position +// chrome and jsc may still error on this, ref https://bugs.chromium.org/p/chromium/issues/detail?id=993000 and https://bugs.webkit.org/show_bug.cgi?id=200638 diff --git a/tests/baselines/reference/scannerUnicodeEscapeInKeyword2.symbols b/tests/baselines/reference/scannerUnicodeEscapeInKeyword2.symbols new file mode 100644 index 00000000000..bd6c92ec26d --- /dev/null +++ b/tests/baselines/reference/scannerUnicodeEscapeInKeyword2.symbols @@ -0,0 +1,62 @@ +=== tests/cases/conformance/scanner/ecmascript5/file1.ts === +var \u0061wait = 12; // ok +>\u0061wait : Symbol(\u0061wait, Decl(file1.ts, 0, 3)) + +async function main() { +>main : Symbol(main, Decl(file1.ts, 0, 20)) + + \u0061wait 12; // not ok +} + +var \u0079ield = 12; // ok +>\u0079ield : Symbol(\u0079ield, Decl(file1.ts, 5, 3)) + +function *gen() { +>gen : Symbol(gen, Decl(file1.ts, 5, 20)) + + \u0079ield 12; //not ok +} + +type typ\u0065 = 12; // ok +>typ\u0065 : Symbol(typ\u0065, Decl(file1.ts, 8, 1)) + +typ\u0065 notok = 0; // not ok +>notok : Symbol(notok, Decl(file1.ts, 10, 20)) + +export {}; +=== tests/cases/conformance/scanner/ecmascript5/file2.ts === +\u{0076}ar x = "hello"; // not ok +>x : Symbol(x, Decl(file2.ts, 0, 10)) + +var \u{0061}wait = 12; // ok +>\u{0061}wait : Symbol(\u{0061}wait, Decl(file2.ts, 2, 3)) + +async function main() { +>main : Symbol(main, Decl(file2.ts, 2, 22)) + + \u{0061}wait 12; // not ok +} + +var \u{0079}ield = 12; // ok +>\u{0079}ield : Symbol(\u{0079}ield, Decl(file2.ts, 7, 3)) + +function *gen() { +>gen : Symbol(gen, Decl(file2.ts, 7, 22)) + + \u{0079}ield 12; //not ok +} + +type typ\u{0065} = 12; // ok +>typ\u{0065} : Symbol(typ\u{0065}, Decl(file2.ts, 10, 1)) + +typ\u{0065} notok = 0; // not ok +>notok : Symbol(notok, Decl(file2.ts, 12, 22)) + +export {}; + +const a = {def\u0061ult: 12}; // OK, `default` not in keyword position +>a : Symbol(a, Decl(file2.ts, 18, 5)) +>def\u0061ult : Symbol(def\u0061ult, Decl(file2.ts, 18, 11)) + +// chrome and jsc may still error on this, ref https://bugs.chromium.org/p/chromium/issues/detail?id=993000 and https://bugs.webkit.org/show_bug.cgi?id=200638 + diff --git a/tests/baselines/reference/scannerUnicodeEscapeInKeyword2.types b/tests/baselines/reference/scannerUnicodeEscapeInKeyword2.types new file mode 100644 index 00000000000..e4460866a51 --- /dev/null +++ b/tests/baselines/reference/scannerUnicodeEscapeInKeyword2.types @@ -0,0 +1,77 @@ +=== tests/cases/conformance/scanner/ecmascript5/file1.ts === +var \u0061wait = 12; // ok +>\u0061wait : number +>12 : 12 + +async function main() { +>main : () => Promise + + \u0061wait 12; // not ok +>\u0061wait 12 : 12 +>12 : 12 +} + +var \u0079ield = 12; // ok +>\u0079ield : number +>12 : 12 + +function *gen() { +>gen : () => Generator + + \u0079ield 12; //not ok +>\u0079ield 12 : any +>12 : 12 +} + +type typ\u0065 = 12; // ok +>typ\u0065 : 12 + +typ\u0065 notok = 0; // not ok +>notok : 0 + +export {}; +=== tests/cases/conformance/scanner/ecmascript5/file2.ts === +\u{0076}ar x = "hello"; // not ok +>x : string +>"hello" : "hello" + +var \u{0061}wait = 12; // ok +>\u{0061}wait : number +>12 : 12 + +async function main() { +>main : () => Promise + + \u{0061}wait 12; // not ok +>\u{0061}wait 12 : 12 +>12 : 12 +} + +var \u{0079}ield = 12; // ok +>\u{0079}ield : number +>12 : 12 + +function *gen() { +>gen : () => Generator + + \u{0079}ield 12; //not ok +>\u{0079}ield 12 : any +>12 : 12 +} + +type typ\u{0065} = 12; // ok +>typ\u{0065} : 12 + +typ\u{0065} notok = 0; // not ok +>notok : 0 + +export {}; + +const a = {def\u0061ult: 12}; // OK, `default` not in keyword position +>a : { def\u0061ult: number; } +>{def\u0061ult: 12} : { def\u0061ult: number; } +>def\u0061ult : number +>12 : 12 + +// chrome and jsc may still error on this, ref https://bugs.chromium.org/p/chromium/issues/detail?id=993000 and https://bugs.webkit.org/show_bug.cgi?id=200638 + diff --git a/tests/baselines/reference/switchStatementsWithMultipleDefaults.errors.txt b/tests/baselines/reference/switchStatementsWithMultipleDefaults.errors.txt index 9760ce4d99b..65565857894 100644 --- a/tests/baselines/reference/switchStatementsWithMultipleDefaults.errors.txt +++ b/tests/baselines/reference/switchStatementsWithMultipleDefaults.errors.txt @@ -1,9 +1,7 @@ -tests/cases/compiler/switchStatementsWithMultipleDefaults.ts(8,5): error TS1113: A 'default' clause cannot appear more than once in a 'switch' statement. -tests/cases/compiler/switchStatementsWithMultipleDefaults.ts(20,13): error TS1113: A 'default' clause cannot appear more than once in a 'switch' statement. -tests/cases/compiler/switchStatementsWithMultipleDefaults.ts(27,22): error TS1108: A 'return' statement can only be used within a function body. +tests/cases/compiler/switchStatementsWithMultipleDefaults.ts(25,13): error TS1260: Keywords cannot contain escape characters. -==== tests/cases/compiler/switchStatementsWithMultipleDefaults.ts (3 errors) ==== +==== tests/cases/compiler/switchStatementsWithMultipleDefaults.ts (1 errors) ==== var x = 10; switch (x) { @@ -12,8 +10,6 @@ tests/cases/compiler/switchStatementsWithMultipleDefaults.ts(27,22): error TS110 default: // No issues. break; default: // Error; second 'default' clause. - ~~~~~~~~ -!!! error TS1113: A 'default' clause cannot appear more than once in a 'switch' statement. default: // Error; third 'default' clause. case 3: x *= x; @@ -26,17 +22,15 @@ tests/cases/compiler/switchStatementsWithMultipleDefaults.ts(27,22): error TS110 switch (x * x) { default: // No issues. default: // Error; second 'default' clause. - ~~~~~~~~ -!!! error TS1113: A 'default' clause cannot appear more than once in a 'switch' statement. break; case 10000: x /= x; default: // Error, third 'default' clause def\u0061ult: // Error, fourth 'default' clause. + ~~~~~~~~~~~~ +!!! error TS1260: Keywords cannot contain escape characters. // Errors on fifth-seventh default: return; - ~~~~~~ -!!! error TS1108: A 'return' statement can only be used within a function body. default: default: } } \ No newline at end of file diff --git a/tests/cases/conformance/scanner/ecmascript5/scannerUnicodeEscapeInKeyword2.ts b/tests/cases/conformance/scanner/ecmascript5/scannerUnicodeEscapeInKeyword2.ts new file mode 100644 index 00000000000..a92c22569db --- /dev/null +++ b/tests/cases/conformance/scanner/ecmascript5/scannerUnicodeEscapeInKeyword2.ts @@ -0,0 +1,39 @@ +// @target: esnext +// @filename: file1.ts +var \u0061wait = 12; // ok +async function main() { + \u0061wait 12; // not ok +} + +var \u0079ield = 12; // ok +function *gen() { + \u0079ield 12; //not ok +} + +type typ\u0065 = 12; // ok + +typ\u0065 notok = 0; // not ok + +export {}; +// @filename: file2.ts + +\u{0076}ar x = "hello"; // not ok + +var \u{0061}wait = 12; // ok +async function main() { + \u{0061}wait 12; // not ok +} + +var \u{0079}ield = 12; // ok +function *gen() { + \u{0079}ield 12; //not ok +} + +type typ\u{0065} = 12; // ok + +typ\u{0065} notok = 0; // not ok + +export {}; + +const a = {def\u0061ult: 12}; // OK, `default` not in keyword position +// chrome and jsc may still error on this, ref https://bugs.chromium.org/p/chromium/issues/detail?id=993000 and https://bugs.webkit.org/show_bug.cgi?id=200638 From decc3cd671125acc66e1a2fd3941167985e5c145 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 12 Aug 2019 16:05:15 -0700 Subject: [PATCH 06/11] Elide /index from auto-import when using rootDirs compiler option (#32828) --- src/compiler/moduleSpecifiers.ts | 8 ++++--- .../importNameCodeFixNewImportRootDirs1.ts | 22 +++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 tests/cases/fourslash/importNameCodeFixNewImportRootDirs1.ts diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index fbed429e312..8c96199b7bf 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -114,7 +114,7 @@ namespace ts.moduleSpecifiers { function getLocalModuleSpecifier(moduleFileName: string, { getCanonicalFileName, sourceDirectory }: Info, compilerOptions: CompilerOptions, { ending, relativePreference }: Preferences): string { const { baseUrl, paths, rootDirs } = compilerOptions; - const relativePath = rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) || + const relativePath = rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName, ending, compilerOptions) || removeExtensionAndIndexPostFix(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), ending, compilerOptions); if (!baseUrl || relativePreference === RelativePreference.Relative) { return relativePath; @@ -248,7 +248,7 @@ namespace ts.moduleSpecifiers { } } - function tryGetModuleNameFromRootDirs(rootDirs: ReadonlyArray, moduleFileName: string, sourceDirectory: string, getCanonicalFileName: (file: string) => string): string | undefined { + function tryGetModuleNameFromRootDirs(rootDirs: ReadonlyArray, moduleFileName: string, sourceDirectory: string, getCanonicalFileName: (file: string) => string, ending: Ending, compilerOptions: CompilerOptions): string | undefined { const normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, rootDirs, getCanonicalFileName); if (normalizedTargetPath === undefined) { return undefined; @@ -256,7 +256,9 @@ namespace ts.moduleSpecifiers { const normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, rootDirs, getCanonicalFileName); const relativePath = normalizedSourcePath !== undefined ? ensurePathIsNonModuleName(getRelativePathFromDirectory(normalizedSourcePath, normalizedTargetPath, getCanonicalFileName)) : normalizedTargetPath; - return removeFileExtension(relativePath); + return getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeJs + ? removeExtensionAndIndexPostFix(relativePath, ending, compilerOptions) + : removeFileExtension(relativePath); } function tryGetModuleNameAsNodeModule(moduleFileName: string, { getCanonicalFileName, sourceDirectory }: Info, host: ModuleSpecifierResolutionHost, options: CompilerOptions): string | undefined { diff --git a/tests/cases/fourslash/importNameCodeFixNewImportRootDirs1.ts b/tests/cases/fourslash/importNameCodeFixNewImportRootDirs1.ts new file mode 100644 index 00000000000..dfac047ae19 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixNewImportRootDirs1.ts @@ -0,0 +1,22 @@ +/// + +// @Filename: a/f1.ts +//// [|foo/*0*/();|] + +// @Filename: a/b/index.ts +//// export function foo() {}; + +// @Filename: tsconfig.json +//// { +//// "compilerOptions": { +//// "rootDirs": [ +//// "a" +//// ] +//// } +//// } + +verify.importFixAtPosition([ +`import { foo } from "./b"; + +foo();` +]); From df3c746070e20adf39fa601b35cb44d76c9efe6e Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Tue, 13 Aug 2019 08:35:42 -0700 Subject: [PATCH 07/11] 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 08/11] 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 09/11] 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 10/11] 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; From 602966ba4ecd0ef7923be61806b98755e2919501 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 13 Aug 2019 16:34:03 -0700 Subject: [PATCH 11/11] Fix references to path-mapped ambient modules in declaration files (#32878) * Fix references to path-mapped ambient modules in declaration files * Fix lint --- src/compiler/emitter.ts | 1 + src/compiler/program.ts | 1 + src/compiler/transformers/declarations.ts | 20 +++++++++++++ src/compiler/types.ts | 1 + .../declarationEmitPathMappingMonorepo.js | 30 +++++++++++++++++++ ...declarationEmitPathMappingMonorepo.symbols | 29 ++++++++++++++++++ .../declarationEmitPathMappingMonorepo.types | 29 ++++++++++++++++++ .../declarationEmitPathMappingMonorepo.ts | 28 +++++++++++++++++ 8 files changed, 139 insertions(+) create mode 100644 tests/baselines/reference/declarationEmitPathMappingMonorepo.js create mode 100644 tests/baselines/reference/declarationEmitPathMappingMonorepo.symbols create mode 100644 tests/baselines/reference/declarationEmitPathMappingMonorepo.types create mode 100644 tests/cases/compiler/declarationEmitPathMappingMonorepo.ts diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index a70973825d1..474d0e67932 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -752,6 +752,7 @@ namespace ts { useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(), getProgramBuildInfo: returnUndefined, getSourceFileFromReference: returnUndefined, + redirectTargetsMap: createMultiMap() }; emitFiles( notImplementedResolver, diff --git a/src/compiler/program.ts b/src/compiler/program.ts index a7cb013c8ee..f7453b1f68c 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1446,6 +1446,7 @@ namespace ts { useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(), getProgramBuildInfo: () => program.getProgramBuildInfo && program.getProgramBuildInfo(), getSourceFileFromReference: (file, ref) => program.getSourceFileFromReference(file, ref), + redirectTargetsMap, }; } diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 2eaab8c0692..8c3f843bf18 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -327,6 +327,26 @@ namespace ts { } if (declFileName) { + const specifier = moduleSpecifiers.getModuleSpecifier( + // We pathify the baseUrl since we pathify the other paths here, so we can still easily check if the other paths are within the baseUrl + // TODO: Should we _always_ be pathifying the baseUrl as we read it in? + { ...options, baseUrl: options.baseUrl && toPath(options.baseUrl, host.getCurrentDirectory(), host.getCanonicalFileName) }, + currentSourceFile, + toPath(outputFilePath, host.getCurrentDirectory(), host.getCanonicalFileName), + toPath(declFileName, host.getCurrentDirectory(), host.getCanonicalFileName), + host, + host.getSourceFiles(), + /*preferences*/ undefined, + host.redirectTargetsMap + ); + if (!pathIsRelative(specifier)) { + // If some compiler option/symlink/whatever allows access to the file containing the ambient module declaration + // via a non-relative name, emit a type reference directive to that non-relative name, rather than + // a relative path to the declaration file + recordTypeReferenceDirectivesIfNecessary([specifier]); + return; + } + let fileName = getRelativePathToDirectoryOrUrl( outputFilePath, declFileName, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f50eb4d6399..04c71dd76df 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5444,6 +5444,7 @@ namespace ts { writeFile: WriteFileCallback; getProgramBuildInfo(): ProgramBuildInfo | undefined; getSourceFileFromReference: Program["getSourceFileFromReference"]; + readonly redirectTargetsMap: RedirectTargetsMap; } export interface TransformationContext { diff --git a/tests/baselines/reference/declarationEmitPathMappingMonorepo.js b/tests/baselines/reference/declarationEmitPathMappingMonorepo.js new file mode 100644 index 00000000000..32da7189004 --- /dev/null +++ b/tests/baselines/reference/declarationEmitPathMappingMonorepo.js @@ -0,0 +1,30 @@ +//// [tests/cases/compiler/declarationEmitPathMappingMonorepo.ts] //// + +//// [index.d.ts] +declare module "@ts-bug/a" { + export type AText = { + value: string; + }; + export function a(text: string): AText; + } + +//// [index.ts] +import { a } from "@ts-bug/a"; + +export function b(text: string) { + return a(text); +} + +//// [index.js] +"use strict"; +exports.__esModule = true; +var a_1 = require("@ts-bug/a"); +function b(text) { + return a_1.a(text); +} +exports.b = b; + + +//// [index.d.ts] +/// +export declare function b(text: string): import("@ts-bug/a").AText; diff --git a/tests/baselines/reference/declarationEmitPathMappingMonorepo.symbols b/tests/baselines/reference/declarationEmitPathMappingMonorepo.symbols new file mode 100644 index 00000000000..e94b520dead --- /dev/null +++ b/tests/baselines/reference/declarationEmitPathMappingMonorepo.symbols @@ -0,0 +1,29 @@ +=== tests/cases/compiler/packages/a/index.d.ts === +declare module "@ts-bug/a" { +>"@ts-bug/a" : Symbol("@ts-bug/a", Decl(index.d.ts, 0, 0)) + + export type AText = { +>AText : Symbol(AText, Decl(index.d.ts, 0, 28)) + + value: string; +>value : Symbol(value, Decl(index.d.ts, 1, 25)) + + }; + export function a(text: string): AText; +>a : Symbol(a, Decl(index.d.ts, 3, 6)) +>text : Symbol(text, Decl(index.d.ts, 4, 22)) +>AText : Symbol(AText, Decl(index.d.ts, 0, 28)) + } + +=== tests/cases/compiler/packages/b/src/index.ts === +import { a } from "@ts-bug/a"; +>a : Symbol(a, Decl(index.ts, 0, 8)) + +export function b(text: string) { +>b : Symbol(b, Decl(index.ts, 0, 30)) +>text : Symbol(text, Decl(index.ts, 2, 18)) + + return a(text); +>a : Symbol(a, Decl(index.ts, 0, 8)) +>text : Symbol(text, Decl(index.ts, 2, 18)) +} diff --git a/tests/baselines/reference/declarationEmitPathMappingMonorepo.types b/tests/baselines/reference/declarationEmitPathMappingMonorepo.types new file mode 100644 index 00000000000..8c4c1678c29 --- /dev/null +++ b/tests/baselines/reference/declarationEmitPathMappingMonorepo.types @@ -0,0 +1,29 @@ +=== tests/cases/compiler/packages/a/index.d.ts === +declare module "@ts-bug/a" { +>"@ts-bug/a" : typeof import("@ts-bug/a") + + export type AText = { +>AText : AText + + value: string; +>value : string + + }; + export function a(text: string): AText; +>a : (text: string) => AText +>text : string + } + +=== tests/cases/compiler/packages/b/src/index.ts === +import { a } from "@ts-bug/a"; +>a : (text: string) => import("@ts-bug/a").AText + +export function b(text: string) { +>b : (text: string) => import("@ts-bug/a").AText +>text : string + + return a(text); +>a(text) : import("@ts-bug/a").AText +>a : (text: string) => import("@ts-bug/a").AText +>text : string +} diff --git a/tests/cases/compiler/declarationEmitPathMappingMonorepo.ts b/tests/cases/compiler/declarationEmitPathMappingMonorepo.ts new file mode 100644 index 00000000000..998ef63fae2 --- /dev/null +++ b/tests/cases/compiler/declarationEmitPathMappingMonorepo.ts @@ -0,0 +1,28 @@ +// @filename: packages/a/index.d.ts +declare module "@ts-bug/a" { + export type AText = { + value: string; + }; + export function a(text: string): AText; + } + +// @filename: packages/b/src/index.ts +import { a } from "@ts-bug/a"; + +export function b(text: string) { + return a(text); +} +// @filename: packages/b/tsconfig.json +{ + "compilerOptions": { + "outDir": "dist", + "declaration": true, + "baseUrl": ".", + "paths": { + "@ts-bug/a": ["../a"] + } + } +} + +// @link: tests/cases/compiler/packages/a -> tests/cases/compiler/node_modules/@ts-bug/a +// @link: tests/cases/compiler/packages/b -> tests/cases/compiler/node_modules/@ts-bug/b