From 0f619db0345aa48627e51beeba797b2501a8a104 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 12 Nov 2021 13:27:04 -0800 Subject: [PATCH 1/5] Plain JS binder errors Issue select errors from the binder in JS files that do not have checkJS explicitly turned on or off. These errors mirror runtime checks done by Javascript. --- src/compiler/program.ts | 35 +++++++-- ...mentsReferenceInConstructor4_Js.errors.txt | 46 ++++++++++++ .../argumentsReferenceInMethod4_Js.errors.txt | 44 +++++++++++ .../reference/jsdocTypedefNoCrash2.errors.txt | 10 ++- .../reference/plainJSModuleStrict.errors.txt | 37 +++++++++ .../reference/plainJSModuleStrict.js | 30 ++++++++ .../reference/plainJSModuleStrict.symbols | 28 +++++++ .../reference/plainJSModuleStrict.types | 33 ++++++++ .../reference/plainJSRedeclare.errors.txt | 13 ++++ tests/baselines/reference/plainJSRedeclare.js | 10 +++ .../reference/plainJSRedeclare.symbols | 12 +++ .../reference/plainJSRedeclare.types | 17 +++++ .../reference/plainJSRedeclare2.errors.txt | 16 ++++ .../baselines/reference/plainJSRedeclare2.js | 10 +++ .../reference/plainJSRedeclare2.symbols | 12 +++ .../reference/plainJSRedeclare2.types | 17 +++++ .../baselines/reference/plainJSRedeclare3.js | 10 +++ .../reference/plainJSRedeclare3.symbols | 12 +++ .../reference/plainJSRedeclare3.types | 17 +++++ .../plainJSReservedStrict.errors.txt | 17 +++++ .../reference/plainJSReservedStrict.js | 10 +++ .../reference/plainJSReservedStrict.symbols | 8 ++ .../reference/plainJSReservedStrict.types | 12 +++ .../reference/plainJSReservedWord.errors.txt | 75 +++++++++++++++++++ .../reference/plainJSReservedWord.js | 58 ++++++++++++++ .../reference/plainJSReservedWord.symbols | 62 +++++++++++++++ .../reference/plainJSReservedWord.types | 75 +++++++++++++++++++ .../conformance/salsa/plainJSRedeclare.ts | 6 ++ .../conformance/salsa/plainJSRedeclare2.ts | 7 ++ .../conformance/salsa/plainJSRedeclare3.ts | 7 ++ .../salsa/plainJSReservedStrict.ts | 7 ++ .../conformance/salsa/plainJSReservedWord.ts | 31 ++++++++ 32 files changed, 776 insertions(+), 8 deletions(-) create mode 100644 tests/baselines/reference/argumentsReferenceInConstructor4_Js.errors.txt create mode 100644 tests/baselines/reference/argumentsReferenceInMethod4_Js.errors.txt create mode 100644 tests/baselines/reference/plainJSModuleStrict.errors.txt create mode 100644 tests/baselines/reference/plainJSModuleStrict.js create mode 100644 tests/baselines/reference/plainJSModuleStrict.symbols create mode 100644 tests/baselines/reference/plainJSModuleStrict.types create mode 100644 tests/baselines/reference/plainJSRedeclare.errors.txt create mode 100644 tests/baselines/reference/plainJSRedeclare.js create mode 100644 tests/baselines/reference/plainJSRedeclare.symbols create mode 100644 tests/baselines/reference/plainJSRedeclare.types create mode 100644 tests/baselines/reference/plainJSRedeclare2.errors.txt create mode 100644 tests/baselines/reference/plainJSRedeclare2.js create mode 100644 tests/baselines/reference/plainJSRedeclare2.symbols create mode 100644 tests/baselines/reference/plainJSRedeclare2.types create mode 100644 tests/baselines/reference/plainJSRedeclare3.js create mode 100644 tests/baselines/reference/plainJSRedeclare3.symbols create mode 100644 tests/baselines/reference/plainJSRedeclare3.types create mode 100644 tests/baselines/reference/plainJSReservedStrict.errors.txt create mode 100644 tests/baselines/reference/plainJSReservedStrict.js create mode 100644 tests/baselines/reference/plainJSReservedStrict.symbols create mode 100644 tests/baselines/reference/plainJSReservedStrict.types create mode 100644 tests/baselines/reference/plainJSReservedWord.errors.txt create mode 100644 tests/baselines/reference/plainJSReservedWord.js create mode 100644 tests/baselines/reference/plainJSReservedWord.symbols create mode 100644 tests/baselines/reference/plainJSReservedWord.types create mode 100644 tests/cases/conformance/salsa/plainJSRedeclare.ts create mode 100644 tests/cases/conformance/salsa/plainJSRedeclare2.ts create mode 100644 tests/cases/conformance/salsa/plainJSRedeclare3.ts create mode 100644 tests/cases/conformance/salsa/plainJSReservedStrict.ts create mode 100644 tests/cases/conformance/salsa/plainJSReservedWord.ts diff --git a/src/compiler/program.ts b/src/compiler/program.ts index c29876ce619f5..e1a0cedd88ddd 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -818,6 +818,22 @@ namespace ts { } } + /** @internal */ + export const plainJSErrors: Set = new Set([ + Diagnostics.Cannot_redeclare_block_scoped_variable_0.code, + Diagnostics.A_module_cannot_have_multiple_default_exports.code, + Diagnostics.Another_export_default_is_here.code, + Diagnostics.The_first_export_default_is_here.code, + Diagnostics.Identifier_expected_0_is_a_reserved_word_at_the_top_level_of_a_module.code, + Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode.code, + Diagnostics.Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here.code, + Diagnostics.constructor_is_a_reserved_word.code, + Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode.code, + Diagnostics.Code_contained_in_a_class_is_evaluated_in_JavaScript_s_strict_mode_which_does_not_allow_this_use_of_0_For_more_information_see_https_Colon_Slash_Slashdeveloper_mozilla_org_Slashen_US_Slashdocs_SlashWeb_SlashJavaScript_SlashReference_SlashStrict_mode.code, + Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode.code, + Diagnostics.Invalid_use_of_0_in_strict_mode.code, + ]); + /** * Determine if source file needs to be re-created even if its text hasn't changed */ @@ -2004,15 +2020,22 @@ namespace ts { Debug.assert(!!sourceFile.bindDiagnostics); - const isCheckJs = isCheckJsEnabledForFile(sourceFile, options); + const isCheckJs = !!isCheckJsEnabledForFile(sourceFile, options) && (sourceFile.scriptKind === ScriptKind.JS || sourceFile.scriptKind === ScriptKind.JSX); + const isPlainJs = !sourceFile.checkJsDirective && options.checkJs === undefined && (sourceFile.scriptKind === ScriptKind.JS || sourceFile.scriptKind === ScriptKind.JSX); const isTsNoCheck = !!sourceFile.checkJsDirective && sourceFile.checkJsDirective.enabled === false; + // By default, only type-check .ts, .tsx, 'Deferred' and 'External' files (external files are added by plugins) - const includeBindAndCheckDiagnostics = !isTsNoCheck && (sourceFile.scriptKind === ScriptKind.TS || sourceFile.scriptKind === ScriptKind.TSX - || sourceFile.scriptKind === ScriptKind.External || isCheckJs || sourceFile.scriptKind === ScriptKind.Deferred); - const bindDiagnostics: readonly Diagnostic[] = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : emptyArray; - const checkDiagnostics = includeBindAndCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : emptyArray; + const includeBindAndCheckDiagnostics = !isTsNoCheck && ( + sourceFile.scriptKind === ScriptKind.TS || sourceFile.scriptKind === ScriptKind.TSX + || sourceFile.scriptKind === ScriptKind.External || isPlainJs || isCheckJs || sourceFile.scriptKind === ScriptKind.Deferred); + let bindDiagnostics: readonly Diagnostic[] = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : emptyArray; + let checkDiagnostics = includeBindAndCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : emptyArray; + if (isPlainJs) { + bindDiagnostics = bindDiagnostics.filter(d => plainJSErrors.has(d.code)); + checkDiagnostics = checkDiagnostics.filter(d => plainJSErrors.has(d.code)); + } - return getMergedBindAndCheckDiagnostics(sourceFile, includeBindAndCheckDiagnostics, bindDiagnostics, checkDiagnostics, isCheckJs ? sourceFile.jsDocDiagnostics : undefined); + return getMergedBindAndCheckDiagnostics(sourceFile, includeBindAndCheckDiagnostics && !isPlainJs, bindDiagnostics, checkDiagnostics, isCheckJs ? sourceFile.jsDocDiagnostics : undefined); }); } diff --git a/tests/baselines/reference/argumentsReferenceInConstructor4_Js.errors.txt b/tests/baselines/reference/argumentsReferenceInConstructor4_Js.errors.txt new file mode 100644 index 0000000000000..30d6092c3f9a4 --- /dev/null +++ b/tests/baselines/reference/argumentsReferenceInConstructor4_Js.errors.txt @@ -0,0 +1,46 @@ +/a.js(18,9): error TS1210: Code contained in a class is evaluated in JavaScript's strict mode which does not allow this use of 'arguments'. For more information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode. + + +==== /a.js (1 errors) ==== + class A { + /** + * Constructor + * + * @param {object} [foo={}] + */ + constructor(foo = {}) { + const key = "bar"; + + /** + * @type object + */ + this.foo = foo; + + /** + * @type object + */ + const arguments = this.arguments; + ~~~~~~~~~ +!!! error TS1210: Code contained in a class is evaluated in JavaScript's strict mode which does not allow this use of 'arguments'. For more information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode. + + /** + * @type object + */ + this.bar = arguments.bar; + + /** + * @type object + */ + this.baz = arguments[key]; + + /** + * @type object + */ + this.options = arguments; + } + + get arguments() { + return { bar: {} }; + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/argumentsReferenceInMethod4_Js.errors.txt b/tests/baselines/reference/argumentsReferenceInMethod4_Js.errors.txt new file mode 100644 index 0000000000000..8c90a67da1700 --- /dev/null +++ b/tests/baselines/reference/argumentsReferenceInMethod4_Js.errors.txt @@ -0,0 +1,44 @@ +/a.js(16,9): error TS1210: Code contained in a class is evaluated in JavaScript's strict mode which does not allow this use of 'arguments'. For more information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode. + + +==== /a.js (1 errors) ==== + class A { + /** + * @param {object} [foo={}] + */ + m(foo = {}) { + const key = "bar"; + + /** + * @type object + */ + this.foo = foo; + + /** + * @type object + */ + const arguments = this.arguments; + ~~~~~~~~~ +!!! error TS1210: Code contained in a class is evaluated in JavaScript's strict mode which does not allow this use of 'arguments'. For more information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode. + + /** + * @type object + */ + this.bar = arguments.bar; + + /** + * @type object + */ + this.baz = arguments[key]; + + /** + * @type object + */ + this.options = arguments; + } + + get arguments() { + return { bar: {} }; + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/jsdocTypedefNoCrash2.errors.txt b/tests/baselines/reference/jsdocTypedefNoCrash2.errors.txt index 9448bf84a2a32..4545e41dc4991 100644 --- a/tests/baselines/reference/jsdocTypedefNoCrash2.errors.txt +++ b/tests/baselines/reference/jsdocTypedefNoCrash2.errors.txt @@ -1,12 +1,18 @@ +tests/cases/compiler/export.js(1,13): error TS2451: Cannot redeclare block-scoped variable 'foo'. tests/cases/compiler/export.js(1,13): error TS8008: Type aliases can only be used in TypeScript files. +tests/cases/compiler/export.js(6,14): error TS2451: Cannot redeclare block-scoped variable 'foo'. -==== tests/cases/compiler/export.js (1 errors) ==== +==== tests/cases/compiler/export.js (3 errors) ==== export type foo = 5; ~~~ +!!! error TS2451: Cannot redeclare block-scoped variable 'foo'. + ~~~ !!! error TS8008: Type aliases can only be used in TypeScript files. /** * @typedef {{ * }} */ - export const foo = 5; \ No newline at end of file + export const foo = 5; + ~~~ +!!! error TS2451: Cannot redeclare block-scoped variable 'foo'. \ No newline at end of file diff --git a/tests/baselines/reference/plainJSModuleStrict.errors.txt b/tests/baselines/reference/plainJSModuleStrict.errors.txt new file mode 100644 index 0000000000000..fa3b605f9ed12 --- /dev/null +++ b/tests/baselines/reference/plainJSModuleStrict.errors.txt @@ -0,0 +1,37 @@ +tests/cases/conformance/salsa/plainJSMultipleDefaultExport.js(1,1): error TS2528: A module cannot have multiple default exports. +tests/cases/conformance/salsa/plainJSMultipleDefaultExport.js(2,1): error TS2528: A module cannot have multiple default exports. +tests/cases/conformance/salsa/plainJSMultipleDefaultExport.js(3,7): error TS1262: Identifier expected. 'await' is a reserved word at the top-level of a module. +tests/cases/conformance/salsa/plainJSMultipleDefaultExport.js(4,7): error TS1214: Identifier expected. 'yield' is a reserved word in strict mode. Modules are automatically in strict mode. +tests/cases/conformance/salsa/plainJSMultipleDefaultExport.js(6,11): error TS1359: Identifier expected. 'await' is a reserved word that cannot be used here. +tests/cases/conformance/salsa/plainJSMultipleDefaultExport.js(9,11): error TS1214: Identifier expected. 'yield' is a reserved word in strict mode. Modules are automatically in strict mode. + + +==== tests/cases/conformance/salsa/plainJSMultipleDefaultExport.js (6 errors) ==== + export default 12 + ~~~~~~~~~~~~~~~~~ +!!! error TS2528: A module cannot have multiple default exports. +!!! related TS2753 tests/cases/conformance/salsa/plainJSMultipleDefaultExport.js:2:1: Another export default is here. + export default 13 + ~~~~~~~~~~~~~~~~~ +!!! error TS2528: A module cannot have multiple default exports. +!!! related TS2752 tests/cases/conformance/salsa/plainJSMultipleDefaultExport.js:1:1: The first export default is here. + const await = 1 + ~~~~~ +!!! error TS1262: Identifier expected. 'await' is a reserved word at the top-level of a module. + const yield = 2 + ~~~~~ +!!! error TS1214: Identifier expected. 'yield' is a reserved word in strict mode. Modules are automatically in strict mode. + async function f() { + const await = 3 + ~~~~~ +!!! error TS1359: Identifier expected. 'await' is a reserved word that cannot be used here. + } + function* g() { + const yield = 4 + ~~~~~ +!!! error TS1214: Identifier expected. 'yield' is a reserved word in strict mode. Modules are automatically in strict mode. + } + class C { + #constructor = 1 + } + \ No newline at end of file diff --git a/tests/baselines/reference/plainJSModuleStrict.js b/tests/baselines/reference/plainJSModuleStrict.js new file mode 100644 index 0000000000000..4a6d28c392d6d --- /dev/null +++ b/tests/baselines/reference/plainJSModuleStrict.js @@ -0,0 +1,30 @@ +//// [plainJSMultipleDefaultExport.js] +export default 12 +export default 13 +const await = 1 +const yield = 2 +async function f() { + const await = 3 +} +function* g() { + const yield = 4 +} +class C { + #constructor = 1 +} + + +//// [plainJSMultipleDefaultExport.js] +export default 12; +export default 13; +const await = 1; +const yield = 2; +async function f() { + const await = 3; +} +function* g() { + const yield = 4; +} +class C { + #constructor = 1; +} diff --git a/tests/baselines/reference/plainJSModuleStrict.symbols b/tests/baselines/reference/plainJSModuleStrict.symbols new file mode 100644 index 0000000000000..2b572478c42aa --- /dev/null +++ b/tests/baselines/reference/plainJSModuleStrict.symbols @@ -0,0 +1,28 @@ +=== tests/cases/conformance/salsa/plainJSMultipleDefaultExport.js === +export default 12 +export default 13 +const await = 1 +>await : Symbol(await, Decl(plainJSMultipleDefaultExport.js, 2, 5)) + +const yield = 2 +>yield : Symbol(yield, Decl(plainJSMultipleDefaultExport.js, 3, 5)) + +async function f() { +>f : Symbol(f, Decl(plainJSMultipleDefaultExport.js, 3, 15)) + + const await = 3 +>await : Symbol(await, Decl(plainJSMultipleDefaultExport.js, 5, 9)) +} +function* g() { +>g : Symbol(g, Decl(plainJSMultipleDefaultExport.js, 6, 1)) + + const yield = 4 +>yield : Symbol(yield, Decl(plainJSMultipleDefaultExport.js, 8, 9)) +} +class C { +>C : Symbol(C, Decl(plainJSMultipleDefaultExport.js, 9, 1)) + + #constructor = 1 +>#constructor : Symbol(C.#constructor, Decl(plainJSMultipleDefaultExport.js, 10, 9)) +} + diff --git a/tests/baselines/reference/plainJSModuleStrict.types b/tests/baselines/reference/plainJSModuleStrict.types new file mode 100644 index 0000000000000..51d45840d0fd5 --- /dev/null +++ b/tests/baselines/reference/plainJSModuleStrict.types @@ -0,0 +1,33 @@ +=== tests/cases/conformance/salsa/plainJSMultipleDefaultExport.js === +export default 12 +export default 13 +const await = 1 +>await : 1 +>1 : 1 + +const yield = 2 +>yield : 2 +>2 : 2 + +async function f() { +>f : () => Promise + + const await = 3 +>await : 3 +>3 : 3 +} +function* g() { +>g : () => Generator + + const yield = 4 +>yield : 4 +>4 : 4 +} +class C { +>C : C + + #constructor = 1 +>#constructor : number +>1 : 1 +} + diff --git a/tests/baselines/reference/plainJSRedeclare.errors.txt b/tests/baselines/reference/plainJSRedeclare.errors.txt new file mode 100644 index 0000000000000..c47a3f90d0b29 --- /dev/null +++ b/tests/baselines/reference/plainJSRedeclare.errors.txt @@ -0,0 +1,13 @@ +tests/cases/conformance/salsa/plainJSRedeclare.js(1,7): error TS2451: Cannot redeclare block-scoped variable 'orbitol'. +tests/cases/conformance/salsa/plainJSRedeclare.js(2,5): error TS2451: Cannot redeclare block-scoped variable 'orbitol'. + + +==== tests/cases/conformance/salsa/plainJSRedeclare.js (2 errors) ==== + const orbitol = 1 + ~~~~~~~ +!!! error TS2451: Cannot redeclare block-scoped variable 'orbitol'. + var orbitol = 1 + false + ~~~~~~~ +!!! error TS2451: Cannot redeclare block-scoped variable 'orbitol'. + orbitol.toExponential() + \ No newline at end of file diff --git a/tests/baselines/reference/plainJSRedeclare.js b/tests/baselines/reference/plainJSRedeclare.js new file mode 100644 index 0000000000000..32b3249fe6773 --- /dev/null +++ b/tests/baselines/reference/plainJSRedeclare.js @@ -0,0 +1,10 @@ +//// [plainJSRedeclare.js] +const orbitol = 1 +var orbitol = 1 + false +orbitol.toExponential() + + +//// [plainJSRedeclare.js] +var orbitol = 1; +var orbitol = 1 + false; +orbitol.toExponential(); diff --git a/tests/baselines/reference/plainJSRedeclare.symbols b/tests/baselines/reference/plainJSRedeclare.symbols new file mode 100644 index 0000000000000..5214b68b4fefd --- /dev/null +++ b/tests/baselines/reference/plainJSRedeclare.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/salsa/plainJSRedeclare.js === +const orbitol = 1 +>orbitol : Symbol(orbitol, Decl(plainJSRedeclare.js, 0, 5)) + +var orbitol = 1 + false +>orbitol : Symbol(orbitol, Decl(plainJSRedeclare.js, 1, 3)) + +orbitol.toExponential() +>orbitol.toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --)) +>orbitol : Symbol(orbitol, Decl(plainJSRedeclare.js, 0, 5)) +>toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --)) + diff --git a/tests/baselines/reference/plainJSRedeclare.types b/tests/baselines/reference/plainJSRedeclare.types new file mode 100644 index 0000000000000..0962bb3221fd7 --- /dev/null +++ b/tests/baselines/reference/plainJSRedeclare.types @@ -0,0 +1,17 @@ +=== tests/cases/conformance/salsa/plainJSRedeclare.js === +const orbitol = 1 +>orbitol : 1 +>1 : 1 + +var orbitol = 1 + false +>orbitol : any +>1 + false : any +>1 : 1 +>false : false + +orbitol.toExponential() +>orbitol.toExponential() : string +>orbitol.toExponential : (fractionDigits?: number) => string +>orbitol : 1 +>toExponential : (fractionDigits?: number) => string + diff --git a/tests/baselines/reference/plainJSRedeclare2.errors.txt b/tests/baselines/reference/plainJSRedeclare2.errors.txt new file mode 100644 index 0000000000000..ca4ef82bbc756 --- /dev/null +++ b/tests/baselines/reference/plainJSRedeclare2.errors.txt @@ -0,0 +1,16 @@ +tests/cases/conformance/salsa/plainJSRedeclare.js(1,7): error TS2451: Cannot redeclare block-scoped variable 'orbitol'. +tests/cases/conformance/salsa/plainJSRedeclare.js(2,5): error TS2451: Cannot redeclare block-scoped variable 'orbitol'. +tests/cases/conformance/salsa/plainJSRedeclare.js(2,15): error TS2365: Operator '+' cannot be applied to types 'number' and 'boolean'. + + +==== tests/cases/conformance/salsa/plainJSRedeclare.js (3 errors) ==== + const orbitol = 1 + ~~~~~~~ +!!! error TS2451: Cannot redeclare block-scoped variable 'orbitol'. + var orbitol = 1 + false + ~~~~~~~ +!!! error TS2451: Cannot redeclare block-scoped variable 'orbitol'. + ~~~~~~~~~ +!!! error TS2365: Operator '+' cannot be applied to types 'number' and 'boolean'. + orbitol.toExponential() + \ No newline at end of file diff --git a/tests/baselines/reference/plainJSRedeclare2.js b/tests/baselines/reference/plainJSRedeclare2.js new file mode 100644 index 0000000000000..32b3249fe6773 --- /dev/null +++ b/tests/baselines/reference/plainJSRedeclare2.js @@ -0,0 +1,10 @@ +//// [plainJSRedeclare.js] +const orbitol = 1 +var orbitol = 1 + false +orbitol.toExponential() + + +//// [plainJSRedeclare.js] +var orbitol = 1; +var orbitol = 1 + false; +orbitol.toExponential(); diff --git a/tests/baselines/reference/plainJSRedeclare2.symbols b/tests/baselines/reference/plainJSRedeclare2.symbols new file mode 100644 index 0000000000000..5214b68b4fefd --- /dev/null +++ b/tests/baselines/reference/plainJSRedeclare2.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/salsa/plainJSRedeclare.js === +const orbitol = 1 +>orbitol : Symbol(orbitol, Decl(plainJSRedeclare.js, 0, 5)) + +var orbitol = 1 + false +>orbitol : Symbol(orbitol, Decl(plainJSRedeclare.js, 1, 3)) + +orbitol.toExponential() +>orbitol.toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --)) +>orbitol : Symbol(orbitol, Decl(plainJSRedeclare.js, 0, 5)) +>toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --)) + diff --git a/tests/baselines/reference/plainJSRedeclare2.types b/tests/baselines/reference/plainJSRedeclare2.types new file mode 100644 index 0000000000000..0962bb3221fd7 --- /dev/null +++ b/tests/baselines/reference/plainJSRedeclare2.types @@ -0,0 +1,17 @@ +=== tests/cases/conformance/salsa/plainJSRedeclare.js === +const orbitol = 1 +>orbitol : 1 +>1 : 1 + +var orbitol = 1 + false +>orbitol : any +>1 + false : any +>1 : 1 +>false : false + +orbitol.toExponential() +>orbitol.toExponential() : string +>orbitol.toExponential : (fractionDigits?: number) => string +>orbitol : 1 +>toExponential : (fractionDigits?: number) => string + diff --git a/tests/baselines/reference/plainJSRedeclare3.js b/tests/baselines/reference/plainJSRedeclare3.js new file mode 100644 index 0000000000000..32b3249fe6773 --- /dev/null +++ b/tests/baselines/reference/plainJSRedeclare3.js @@ -0,0 +1,10 @@ +//// [plainJSRedeclare.js] +const orbitol = 1 +var orbitol = 1 + false +orbitol.toExponential() + + +//// [plainJSRedeclare.js] +var orbitol = 1; +var orbitol = 1 + false; +orbitol.toExponential(); diff --git a/tests/baselines/reference/plainJSRedeclare3.symbols b/tests/baselines/reference/plainJSRedeclare3.symbols new file mode 100644 index 0000000000000..5214b68b4fefd --- /dev/null +++ b/tests/baselines/reference/plainJSRedeclare3.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/salsa/plainJSRedeclare.js === +const orbitol = 1 +>orbitol : Symbol(orbitol, Decl(plainJSRedeclare.js, 0, 5)) + +var orbitol = 1 + false +>orbitol : Symbol(orbitol, Decl(plainJSRedeclare.js, 1, 3)) + +orbitol.toExponential() +>orbitol.toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --)) +>orbitol : Symbol(orbitol, Decl(plainJSRedeclare.js, 0, 5)) +>toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --)) + diff --git a/tests/baselines/reference/plainJSRedeclare3.types b/tests/baselines/reference/plainJSRedeclare3.types new file mode 100644 index 0000000000000..0962bb3221fd7 --- /dev/null +++ b/tests/baselines/reference/plainJSRedeclare3.types @@ -0,0 +1,17 @@ +=== tests/cases/conformance/salsa/plainJSRedeclare.js === +const orbitol = 1 +>orbitol : 1 +>1 : 1 + +var orbitol = 1 + false +>orbitol : any +>1 + false : any +>1 : 1 +>false : false + +orbitol.toExponential() +>orbitol.toExponential() : string +>orbitol.toExponential : (fractionDigits?: number) => string +>orbitol : 1 +>toExponential : (fractionDigits?: number) => string + diff --git a/tests/baselines/reference/plainJSReservedStrict.errors.txt b/tests/baselines/reference/plainJSReservedStrict.errors.txt new file mode 100644 index 0000000000000..a040fce591c17 --- /dev/null +++ b/tests/baselines/reference/plainJSReservedStrict.errors.txt @@ -0,0 +1,17 @@ +tests/cases/conformance/salsa/plainJSReservedStrict.js(2,7): error TS1100: Invalid use of 'eval' in strict mode. +tests/cases/conformance/salsa/plainJSReservedStrict.js(2,7): error TS2451: Cannot redeclare block-scoped variable 'eval'. +tests/cases/conformance/salsa/plainJSReservedStrict.js(3,7): error TS1100: Invalid use of 'arguments' in strict mode. + + +==== tests/cases/conformance/salsa/plainJSReservedStrict.js (3 errors) ==== + "use strict" + const eval = 1 + ~~~~ +!!! error TS1100: Invalid use of 'eval' in strict mode. + ~~~~ +!!! error TS2451: Cannot redeclare block-scoped variable 'eval'. +!!! related TS6203 /.ts/lib.es5.d.ts:32:18: 'eval' was also declared here. + const arguments = 2 + ~~~~~~~~~ +!!! error TS1100: Invalid use of 'arguments' in strict mode. + \ No newline at end of file diff --git a/tests/baselines/reference/plainJSReservedStrict.js b/tests/baselines/reference/plainJSReservedStrict.js new file mode 100644 index 0000000000000..9f35d353afc6a --- /dev/null +++ b/tests/baselines/reference/plainJSReservedStrict.js @@ -0,0 +1,10 @@ +//// [plainJSReservedStrict.js] +"use strict" +const eval = 1 +const arguments = 2 + + +//// [plainJSReservedStrict.js] +"use strict"; +const eval = 1; +const arguments = 2; diff --git a/tests/baselines/reference/plainJSReservedStrict.symbols b/tests/baselines/reference/plainJSReservedStrict.symbols new file mode 100644 index 0000000000000..e89d121657979 --- /dev/null +++ b/tests/baselines/reference/plainJSReservedStrict.symbols @@ -0,0 +1,8 @@ +=== tests/cases/conformance/salsa/plainJSReservedStrict.js === +"use strict" +const eval = 1 +>eval : Symbol(eval, Decl(plainJSReservedStrict.js, 1, 5)) + +const arguments = 2 +>arguments : Symbol(arguments, Decl(plainJSReservedStrict.js, 2, 5)) + diff --git a/tests/baselines/reference/plainJSReservedStrict.types b/tests/baselines/reference/plainJSReservedStrict.types new file mode 100644 index 0000000000000..f4462e1cdab91 --- /dev/null +++ b/tests/baselines/reference/plainJSReservedStrict.types @@ -0,0 +1,12 @@ +=== tests/cases/conformance/salsa/plainJSReservedStrict.js === +"use strict" +>"use strict" : "use strict" + +const eval = 1 +>eval : 1 +>1 : 1 + +const arguments = 2 +>arguments : 2 +>2 : 2 + diff --git a/tests/baselines/reference/plainJSReservedWord.errors.txt b/tests/baselines/reference/plainJSReservedWord.errors.txt new file mode 100644 index 0000000000000..3b0e9ac5ef4fd --- /dev/null +++ b/tests/baselines/reference/plainJSReservedWord.errors.txt @@ -0,0 +1,75 @@ +tests/cases/conformance/salsa/plainJSReservedWord.js(1,1): error TS2528: A module cannot have multiple default exports. +tests/cases/conformance/salsa/plainJSReservedWord.js(2,1): error TS2528: A module cannot have multiple default exports. +tests/cases/conformance/salsa/plainJSReservedWord.js(3,7): error TS1262: Identifier expected. 'await' is a reserved word at the top-level of a module. +tests/cases/conformance/salsa/plainJSReservedWord.js(4,7): error TS1214: Identifier expected. 'yield' is a reserved word in strict mode. Modules are automatically in strict mode. +tests/cases/conformance/salsa/plainJSReservedWord.js(6,11): error TS1359: Identifier expected. 'await' is a reserved word that cannot be used here. +tests/cases/conformance/salsa/plainJSReservedWord.js(9,11): error TS1214: Identifier expected. 'yield' is a reserved word in strict mode. Modules are automatically in strict mode. +tests/cases/conformance/salsa/plainJSReservedWord.js(12,5): error TS18012: '#constructor' is a reserved word. +tests/cases/conformance/salsa/plainJSReservedWord.js(15,20): error TS1102: 'delete' cannot be called on an identifier in strict mode. +tests/cases/conformance/salsa/plainJSReservedWord.js(18,16): error TS1102: 'delete' cannot be called on an identifier in strict mode. +tests/cases/conformance/salsa/plainJSReservedWord.js(19,16): error TS1102: 'delete' cannot be called on an identifier in strict mode. +tests/cases/conformance/salsa/plainJSReservedWord.js(22,15): error TS1210: Code contained in a class is evaluated in JavaScript's strict mode which does not allow this use of 'eval'. For more information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode. +tests/cases/conformance/salsa/plainJSReservedWord.js(23,15): error TS1210: Code contained in a class is evaluated in JavaScript's strict mode which does not allow this use of 'arguments'. For more information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode. +tests/cases/conformance/salsa/plainJSReservedWord.js(26,7): error TS1215: Invalid use of 'eval'. Modules are automatically in strict mode. +tests/cases/conformance/salsa/plainJSReservedWord.js(27,7): error TS1215: Invalid use of 'arguments'. Modules are automatically in strict mode. + + +==== tests/cases/conformance/salsa/plainJSReservedWord.js (14 errors) ==== + export default 12 + ~~~~~~~~~~~~~~~~~ +!!! error TS2528: A module cannot have multiple default exports. +!!! related TS2753 tests/cases/conformance/salsa/plainJSReservedWord.js:2:1: Another export default is here. + export default 13 + ~~~~~~~~~~~~~~~~~ +!!! error TS2528: A module cannot have multiple default exports. +!!! related TS2752 tests/cases/conformance/salsa/plainJSReservedWord.js:1:1: The first export default is here. + const await = 1 + ~~~~~ +!!! error TS1262: Identifier expected. 'await' is a reserved word at the top-level of a module. + const yield = 2 + ~~~~~ +!!! error TS1214: Identifier expected. 'yield' is a reserved word in strict mode. Modules are automatically in strict mode. + async function f() { + const await = 3 + ~~~~~ +!!! error TS1359: Identifier expected. 'await' is a reserved word that cannot be used here. + } + function* g() { + const yield = 4 + ~~~~~ +!!! error TS1214: Identifier expected. 'yield' is a reserved word in strict mode. Modules are automatically in strict mode. + } + class C { + #constructor = 5 + ~~~~~~~~~~~~ +!!! error TS18012: '#constructor' is a reserved word. + deleted() { + function container(f) { + delete f + ~ +!!! error TS1102: 'delete' cannot be called on an identifier in strict mode. + } + var g = 6 + delete g + ~ +!!! error TS1102: 'delete' cannot be called on an identifier in strict mode. + delete container + ~~~~~~~~~ +!!! error TS1102: 'delete' cannot be called on an identifier in strict mode. + } + evalArguments() { + const eval = 7 + ~~~~ +!!! error TS1210: Code contained in a class is evaluated in JavaScript's strict mode which does not allow this use of 'eval'. For more information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode. + const arguments = 8 + ~~~~~~~~~ +!!! error TS1210: Code contained in a class is evaluated in JavaScript's strict mode which does not allow this use of 'arguments'. For more information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode. + } + } + const eval = 9 + ~~~~ +!!! error TS1215: Invalid use of 'eval'. Modules are automatically in strict mode. + const arguments = 10 + ~~~~~~~~~ +!!! error TS1215: Invalid use of 'arguments'. Modules are automatically in strict mode. + \ No newline at end of file diff --git a/tests/baselines/reference/plainJSReservedWord.js b/tests/baselines/reference/plainJSReservedWord.js new file mode 100644 index 0000000000000..a412fad4bc7a4 --- /dev/null +++ b/tests/baselines/reference/plainJSReservedWord.js @@ -0,0 +1,58 @@ +//// [plainJSReservedWord.js] +export default 12 +export default 13 +const await = 1 +const yield = 2 +async function f() { + const await = 3 +} +function* g() { + const yield = 4 +} +class C { + #constructor = 5 + deleted() { + function container(f) { + delete f + } + var g = 6 + delete g + delete container + } + evalArguments() { + const eval = 7 + const arguments = 8 + } +} +const eval = 9 +const arguments = 10 + + +//// [plainJSReservedWord.js] +export default 12; +export default 13; +const await = 1; +const yield = 2; +async function f() { + const await = 3; +} +function* g() { + const yield = 4; +} +class C { + #constructor = 5; + deleted() { + function container(f) { + delete f; + } + var g = 6; + delete g; + delete container; + } + evalArguments() { + const eval = 7; + const arguments = 8; + } +} +const eval = 9; +const arguments = 10; diff --git a/tests/baselines/reference/plainJSReservedWord.symbols b/tests/baselines/reference/plainJSReservedWord.symbols new file mode 100644 index 0000000000000..64e9c9eed79ee --- /dev/null +++ b/tests/baselines/reference/plainJSReservedWord.symbols @@ -0,0 +1,62 @@ +=== tests/cases/conformance/salsa/plainJSReservedWord.js === +export default 12 +export default 13 +const await = 1 +>await : Symbol(await, Decl(plainJSReservedWord.js, 2, 5)) + +const yield = 2 +>yield : Symbol(yield, Decl(plainJSReservedWord.js, 3, 5)) + +async function f() { +>f : Symbol(f, Decl(plainJSReservedWord.js, 3, 15)) + + const await = 3 +>await : Symbol(await, Decl(plainJSReservedWord.js, 5, 9)) +} +function* g() { +>g : Symbol(g, Decl(plainJSReservedWord.js, 6, 1)) + + const yield = 4 +>yield : Symbol(yield, Decl(plainJSReservedWord.js, 8, 9)) +} +class C { +>C : Symbol(C, Decl(plainJSReservedWord.js, 9, 1)) + + #constructor = 5 +>#constructor : Symbol(C.#constructor, Decl(plainJSReservedWord.js, 10, 9)) + + deleted() { +>deleted : Symbol(C.deleted, Decl(plainJSReservedWord.js, 11, 20)) + + function container(f) { +>container : Symbol(container, Decl(plainJSReservedWord.js, 12, 15)) +>f : Symbol(f, Decl(plainJSReservedWord.js, 13, 27)) + + delete f +>f : Symbol(f, Decl(plainJSReservedWord.js, 13, 27)) + } + var g = 6 +>g : Symbol(g, Decl(plainJSReservedWord.js, 16, 11)) + + delete g +>g : Symbol(g, Decl(plainJSReservedWord.js, 16, 11)) + + delete container +>container : Symbol(container, Decl(plainJSReservedWord.js, 12, 15)) + } + evalArguments() { +>evalArguments : Symbol(C.evalArguments, Decl(plainJSReservedWord.js, 19, 5)) + + const eval = 7 +>eval : Symbol(eval, Decl(plainJSReservedWord.js, 21, 13)) + + const arguments = 8 +>arguments : Symbol(arguments, Decl(plainJSReservedWord.js, 22, 13)) + } +} +const eval = 9 +>eval : Symbol(eval, Decl(plainJSReservedWord.js, 25, 5)) + +const arguments = 10 +>arguments : Symbol(arguments, Decl(plainJSReservedWord.js, 26, 5)) + diff --git a/tests/baselines/reference/plainJSReservedWord.types b/tests/baselines/reference/plainJSReservedWord.types new file mode 100644 index 0000000000000..9b8c76a2dab0a --- /dev/null +++ b/tests/baselines/reference/plainJSReservedWord.types @@ -0,0 +1,75 @@ +=== tests/cases/conformance/salsa/plainJSReservedWord.js === +export default 12 +export default 13 +const await = 1 +>await : 1 +>1 : 1 + +const yield = 2 +>yield : 2 +>2 : 2 + +async function f() { +>f : () => Promise + + const await = 3 +>await : 3 +>3 : 3 +} +function* g() { +>g : () => Generator + + const yield = 4 +>yield : 4 +>4 : 4 +} +class C { +>C : C + + #constructor = 5 +>#constructor : number +>5 : 5 + + deleted() { +>deleted : () => void + + function container(f) { +>container : (f: any) => void +>f : any + + delete f +>delete f : boolean +>f : any + } + var g = 6 +>g : number +>6 : 6 + + delete g +>delete g : boolean +>g : number + + delete container +>delete container : boolean +>container : (f: any) => void + } + evalArguments() { +>evalArguments : () => void + + const eval = 7 +>eval : 7 +>7 : 7 + + const arguments = 8 +>arguments : 8 +>8 : 8 + } +} +const eval = 9 +>eval : 9 +>9 : 9 + +const arguments = 10 +>arguments : 10 +>10 : 10 + diff --git a/tests/cases/conformance/salsa/plainJSRedeclare.ts b/tests/cases/conformance/salsa/plainJSRedeclare.ts new file mode 100644 index 0000000000000..be6831d0cdf12 --- /dev/null +++ b/tests/cases/conformance/salsa/plainJSRedeclare.ts @@ -0,0 +1,6 @@ +// @outdir: out/ +// @allowJS: true +// @filename: plainJSRedeclare.js +const orbitol = 1 +var orbitol = 1 + false +orbitol.toExponential() diff --git a/tests/cases/conformance/salsa/plainJSRedeclare2.ts b/tests/cases/conformance/salsa/plainJSRedeclare2.ts new file mode 100644 index 0000000000000..7409b6c8fe071 --- /dev/null +++ b/tests/cases/conformance/salsa/plainJSRedeclare2.ts @@ -0,0 +1,7 @@ +// @outdir: out/ +// @allowJS: true +// @checkJS: true +// @filename: plainJSRedeclare.js +const orbitol = 1 +var orbitol = 1 + false +orbitol.toExponential() diff --git a/tests/cases/conformance/salsa/plainJSRedeclare3.ts b/tests/cases/conformance/salsa/plainJSRedeclare3.ts new file mode 100644 index 0000000000000..1327fcfc1777c --- /dev/null +++ b/tests/cases/conformance/salsa/plainJSRedeclare3.ts @@ -0,0 +1,7 @@ +// @outdir: out/ +// @allowJS: true +// @checkJS: false +// @filename: plainJSRedeclare.js +const orbitol = 1 +var orbitol = 1 + false +orbitol.toExponential() diff --git a/tests/cases/conformance/salsa/plainJSReservedStrict.ts b/tests/cases/conformance/salsa/plainJSReservedStrict.ts new file mode 100644 index 0000000000000..fbd654927d1ea --- /dev/null +++ b/tests/cases/conformance/salsa/plainJSReservedStrict.ts @@ -0,0 +1,7 @@ +// @outdir: out/ +// @target: esnext +// @allowJS: true +// @filename: plainJSReservedStrict.js +"use strict" +const eval = 1 +const arguments = 2 diff --git a/tests/cases/conformance/salsa/plainJSReservedWord.ts b/tests/cases/conformance/salsa/plainJSReservedWord.ts new file mode 100644 index 0000000000000..7eaaa6af97f0b --- /dev/null +++ b/tests/cases/conformance/salsa/plainJSReservedWord.ts @@ -0,0 +1,31 @@ +// @outdir: out/ +// @target: esnext +// @allowJS: true +// @filename: plainJSReservedWord.js +export default 12 +export default 13 +const await = 1 +const yield = 2 +async function f() { + const await = 3 +} +function* g() { + const yield = 4 +} +class C { + #constructor = 5 + deleted() { + function container(f) { + delete f + } + var g = 6 + delete g + delete container + } + evalArguments() { + const eval = 7 + const arguments = 8 + } +} +const eval = 9 +const arguments = 10 From 9c85b4b716edcf0d3e2e44c34571a986872d5498 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 15 Nov 2021 11:36:46 -0800 Subject: [PATCH 2/5] Rest of plain JS binder errors --- src/compiler/program.ts | 8 +- ...ors.txt => plainJSBinderErrors.errors.txt} | 56 ++++++++---- ...ReservedWord.js => plainJSBinderErrors.js} | 30 ++++++- .../reference/plainJSBinderErrors.symbols | 86 +++++++++++++++++++ ...edWord.types => plainJSBinderErrors.types} | 32 ++++++- .../reference/plainJSReservedWord.symbols | 62 ------------- ...ReservedWord.ts => plainJSBinderErrors.ts} | 15 +++- 7 files changed, 203 insertions(+), 86 deletions(-) rename tests/baselines/reference/{plainJSReservedWord.errors.txt => plainJSBinderErrors.errors.txt} (63%) rename tests/baselines/reference/{plainJSReservedWord.js => plainJSBinderErrors.js} (60%) create mode 100644 tests/baselines/reference/plainJSBinderErrors.symbols rename tests/baselines/reference/{plainJSReservedWord.types => plainJSBinderErrors.types} (61%) delete mode 100644 tests/baselines/reference/plainJSReservedWord.symbols rename tests/cases/conformance/salsa/{plainJSReservedWord.ts => plainJSBinderErrors.ts} (64%) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index e1a0cedd88ddd..b66e50ef6165a 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -832,6 +832,9 @@ namespace ts { Diagnostics.Code_contained_in_a_class_is_evaluated_in_JavaScript_s_strict_mode_which_does_not_allow_this_use_of_0_For_more_information_see_https_Colon_Slash_Slashdeveloper_mozilla_org_Slashen_US_Slashdocs_SlashWeb_SlashJavaScript_SlashReference_SlashStrict_mode.code, Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode.code, Diagnostics.Invalid_use_of_0_in_strict_mode.code, + Diagnostics.A_label_is_not_allowed_here.code, + Diagnostics.Octal_literals_are_not_allowed_in_strict_mode.code, + Diagnostics.with_statements_are_not_allowed_in_strict_mode.code, ]); /** @@ -2020,13 +2023,12 @@ namespace ts { Debug.assert(!!sourceFile.bindDiagnostics); - const isCheckJs = !!isCheckJsEnabledForFile(sourceFile, options) && (sourceFile.scriptKind === ScriptKind.JS || sourceFile.scriptKind === ScriptKind.JSX); + const isCheckJs = isCheckJsEnabledForFile(sourceFile, options) && (sourceFile.scriptKind === ScriptKind.JS || sourceFile.scriptKind === ScriptKind.JSX); const isPlainJs = !sourceFile.checkJsDirective && options.checkJs === undefined && (sourceFile.scriptKind === ScriptKind.JS || sourceFile.scriptKind === ScriptKind.JSX); const isTsNoCheck = !!sourceFile.checkJsDirective && sourceFile.checkJsDirective.enabled === false; // By default, only type-check .ts, .tsx, 'Deferred' and 'External' files (external files are added by plugins) - const includeBindAndCheckDiagnostics = !isTsNoCheck && ( - sourceFile.scriptKind === ScriptKind.TS || sourceFile.scriptKind === ScriptKind.TSX + const includeBindAndCheckDiagnostics = !isTsNoCheck && (sourceFile.scriptKind === ScriptKind.TS || sourceFile.scriptKind === ScriptKind.TSX || sourceFile.scriptKind === ScriptKind.External || isPlainJs || isCheckJs || sourceFile.scriptKind === ScriptKind.Deferred); let bindDiagnostics: readonly Diagnostic[] = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : emptyArray; let checkDiagnostics = includeBindAndCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : emptyArray; diff --git a/tests/baselines/reference/plainJSReservedWord.errors.txt b/tests/baselines/reference/plainJSBinderErrors.errors.txt similarity index 63% rename from tests/baselines/reference/plainJSReservedWord.errors.txt rename to tests/baselines/reference/plainJSBinderErrors.errors.txt index 3b0e9ac5ef4fd..72aaa17b1e892 100644 --- a/tests/baselines/reference/plainJSReservedWord.errors.txt +++ b/tests/baselines/reference/plainJSBinderErrors.errors.txt @@ -1,28 +1,31 @@ -tests/cases/conformance/salsa/plainJSReservedWord.js(1,1): error TS2528: A module cannot have multiple default exports. -tests/cases/conformance/salsa/plainJSReservedWord.js(2,1): error TS2528: A module cannot have multiple default exports. -tests/cases/conformance/salsa/plainJSReservedWord.js(3,7): error TS1262: Identifier expected. 'await' is a reserved word at the top-level of a module. -tests/cases/conformance/salsa/plainJSReservedWord.js(4,7): error TS1214: Identifier expected. 'yield' is a reserved word in strict mode. Modules are automatically in strict mode. -tests/cases/conformance/salsa/plainJSReservedWord.js(6,11): error TS1359: Identifier expected. 'await' is a reserved word that cannot be used here. -tests/cases/conformance/salsa/plainJSReservedWord.js(9,11): error TS1214: Identifier expected. 'yield' is a reserved word in strict mode. Modules are automatically in strict mode. -tests/cases/conformance/salsa/plainJSReservedWord.js(12,5): error TS18012: '#constructor' is a reserved word. -tests/cases/conformance/salsa/plainJSReservedWord.js(15,20): error TS1102: 'delete' cannot be called on an identifier in strict mode. -tests/cases/conformance/salsa/plainJSReservedWord.js(18,16): error TS1102: 'delete' cannot be called on an identifier in strict mode. -tests/cases/conformance/salsa/plainJSReservedWord.js(19,16): error TS1102: 'delete' cannot be called on an identifier in strict mode. -tests/cases/conformance/salsa/plainJSReservedWord.js(22,15): error TS1210: Code contained in a class is evaluated in JavaScript's strict mode which does not allow this use of 'eval'. For more information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode. -tests/cases/conformance/salsa/plainJSReservedWord.js(23,15): error TS1210: Code contained in a class is evaluated in JavaScript's strict mode which does not allow this use of 'arguments'. For more information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode. -tests/cases/conformance/salsa/plainJSReservedWord.js(26,7): error TS1215: Invalid use of 'eval'. Modules are automatically in strict mode. -tests/cases/conformance/salsa/plainJSReservedWord.js(27,7): error TS1215: Invalid use of 'arguments'. Modules are automatically in strict mode. +tests/cases/conformance/salsa/plainJSBinderErrors.js(1,1): error TS2528: A module cannot have multiple default exports. +tests/cases/conformance/salsa/plainJSBinderErrors.js(2,1): error TS2528: A module cannot have multiple default exports. +tests/cases/conformance/salsa/plainJSBinderErrors.js(3,7): error TS1262: Identifier expected. 'await' is a reserved word at the top-level of a module. +tests/cases/conformance/salsa/plainJSBinderErrors.js(4,7): error TS1214: Identifier expected. 'yield' is a reserved word in strict mode. Modules are automatically in strict mode. +tests/cases/conformance/salsa/plainJSBinderErrors.js(6,11): error TS1359: Identifier expected. 'await' is a reserved word that cannot be used here. +tests/cases/conformance/salsa/plainJSBinderErrors.js(9,11): error TS1214: Identifier expected. 'yield' is a reserved word in strict mode. Modules are automatically in strict mode. +tests/cases/conformance/salsa/plainJSBinderErrors.js(12,5): error TS18012: '#constructor' is a reserved word. +tests/cases/conformance/salsa/plainJSBinderErrors.js(15,20): error TS1102: 'delete' cannot be called on an identifier in strict mode. +tests/cases/conformance/salsa/plainJSBinderErrors.js(18,16): error TS1102: 'delete' cannot be called on an identifier in strict mode. +tests/cases/conformance/salsa/plainJSBinderErrors.js(19,16): error TS1102: 'delete' cannot be called on an identifier in strict mode. +tests/cases/conformance/salsa/plainJSBinderErrors.js(22,15): error TS1210: Code contained in a class is evaluated in JavaScript's strict mode which does not allow this use of 'eval'. For more information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode. +tests/cases/conformance/salsa/plainJSBinderErrors.js(23,15): error TS1210: Code contained in a class is evaluated in JavaScript's strict mode which does not allow this use of 'arguments'. For more information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode. +tests/cases/conformance/salsa/plainJSBinderErrors.js(26,27): error TS1121: Octal literals are not allowed in strict mode. +tests/cases/conformance/salsa/plainJSBinderErrors.js(27,9): error TS1101: 'with' statements are not allowed in strict mode. +tests/cases/conformance/salsa/plainJSBinderErrors.js(33,13): error TS1344: 'A label is not allowed here. +tests/cases/conformance/salsa/plainJSBinderErrors.js(39,7): error TS1215: Invalid use of 'eval'. Modules are automatically in strict mode. +tests/cases/conformance/salsa/plainJSBinderErrors.js(40,7): error TS1215: Invalid use of 'arguments'. Modules are automatically in strict mode. -==== tests/cases/conformance/salsa/plainJSReservedWord.js (14 errors) ==== +==== tests/cases/conformance/salsa/plainJSBinderErrors.js (17 errors) ==== export default 12 ~~~~~~~~~~~~~~~~~ !!! error TS2528: A module cannot have multiple default exports. -!!! related TS2753 tests/cases/conformance/salsa/plainJSReservedWord.js:2:1: Another export default is here. +!!! related TS2753 tests/cases/conformance/salsa/plainJSBinderErrors.js:2:1: Another export default is here. export default 13 ~~~~~~~~~~~~~~~~~ !!! error TS2528: A module cannot have multiple default exports. -!!! related TS2752 tests/cases/conformance/salsa/plainJSReservedWord.js:1:1: The first export default is here. +!!! related TS2752 tests/cases/conformance/salsa/plainJSBinderErrors.js:1:1: The first export default is here. const await = 1 ~~~~~ !!! error TS1262: Identifier expected. 'await' is a reserved word at the top-level of a module. @@ -65,6 +68,25 @@ tests/cases/conformance/salsa/plainJSReservedWord.js(27,7): error TS1215: Invali ~~~~~~~~~ !!! error TS1210: Code contained in a class is evaluated in JavaScript's strict mode which does not allow this use of 'arguments'. For more information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode. } + withOctal() { + const redundant = 010 + ~~~ +!!! error TS1121: Octal literals are not allowed in strict mode. + with (redundant) { + ~~~~ +!!! error TS1101: 'with' statements are not allowed in strict mode. + return toFixed() + } + } + label() { + for(;;) { + label: var x = 1 + ~~~~~ +!!! error TS1344: 'A label is not allowed here. + break label + } + return x + } } const eval = 9 ~~~~ diff --git a/tests/baselines/reference/plainJSReservedWord.js b/tests/baselines/reference/plainJSBinderErrors.js similarity index 60% rename from tests/baselines/reference/plainJSReservedWord.js rename to tests/baselines/reference/plainJSBinderErrors.js index a412fad4bc7a4..5f8f3138a64c5 100644 --- a/tests/baselines/reference/plainJSReservedWord.js +++ b/tests/baselines/reference/plainJSBinderErrors.js @@ -1,4 +1,4 @@ -//// [plainJSReservedWord.js] +//// [plainJSBinderErrors.js] export default 12 export default 13 const await = 1 @@ -23,12 +23,25 @@ class C { const eval = 7 const arguments = 8 } + withOctal() { + const redundant = 010 + with (redundant) { + return toFixed() + } + } + label() { + for(;;) { + label: var x = 1 + break label + } + return x + } } const eval = 9 const arguments = 10 -//// [plainJSReservedWord.js] +//// [plainJSBinderErrors.js] export default 12; export default 13; const await = 1; @@ -53,6 +66,19 @@ class C { const eval = 7; const arguments = 8; } + withOctal() { + const redundant = 010; + with (redundant) { + return toFixed(); + } + } + label() { + for (;;) { + label: var x = 1; + break label; + } + return x; + } } const eval = 9; const arguments = 10; diff --git a/tests/baselines/reference/plainJSBinderErrors.symbols b/tests/baselines/reference/plainJSBinderErrors.symbols new file mode 100644 index 0000000000000..55b2866141718 --- /dev/null +++ b/tests/baselines/reference/plainJSBinderErrors.symbols @@ -0,0 +1,86 @@ +=== tests/cases/conformance/salsa/plainJSBinderErrors.js === +export default 12 +export default 13 +const await = 1 +>await : Symbol(await, Decl(plainJSBinderErrors.js, 2, 5)) + +const yield = 2 +>yield : Symbol(yield, Decl(plainJSBinderErrors.js, 3, 5)) + +async function f() { +>f : Symbol(f, Decl(plainJSBinderErrors.js, 3, 15)) + + const await = 3 +>await : Symbol(await, Decl(plainJSBinderErrors.js, 5, 9)) +} +function* g() { +>g : Symbol(g, Decl(plainJSBinderErrors.js, 6, 1)) + + const yield = 4 +>yield : Symbol(yield, Decl(plainJSBinderErrors.js, 8, 9)) +} +class C { +>C : Symbol(C, Decl(plainJSBinderErrors.js, 9, 1)) + + #constructor = 5 +>#constructor : Symbol(C.#constructor, Decl(plainJSBinderErrors.js, 10, 9)) + + deleted() { +>deleted : Symbol(C.deleted, Decl(plainJSBinderErrors.js, 11, 20)) + + function container(f) { +>container : Symbol(container, Decl(plainJSBinderErrors.js, 12, 15)) +>f : Symbol(f, Decl(plainJSBinderErrors.js, 13, 27)) + + delete f +>f : Symbol(f, Decl(plainJSBinderErrors.js, 13, 27)) + } + var g = 6 +>g : Symbol(g, Decl(plainJSBinderErrors.js, 16, 11)) + + delete g +>g : Symbol(g, Decl(plainJSBinderErrors.js, 16, 11)) + + delete container +>container : Symbol(container, Decl(plainJSBinderErrors.js, 12, 15)) + } + evalArguments() { +>evalArguments : Symbol(C.evalArguments, Decl(plainJSBinderErrors.js, 19, 5)) + + const eval = 7 +>eval : Symbol(eval, Decl(plainJSBinderErrors.js, 21, 13)) + + const arguments = 8 +>arguments : Symbol(arguments, Decl(plainJSBinderErrors.js, 22, 13)) + } + withOctal() { +>withOctal : Symbol(C.withOctal, Decl(plainJSBinderErrors.js, 23, 5)) + + const redundant = 010 +>redundant : Symbol(redundant, Decl(plainJSBinderErrors.js, 25, 13)) + + with (redundant) { +>redundant : Symbol(redundant, Decl(plainJSBinderErrors.js, 25, 13)) + + return toFixed() + } + } + label() { +>label : Symbol(C.label, Decl(plainJSBinderErrors.js, 29, 5)) + + for(;;) { + label: var x = 1 +>x : Symbol(x, Decl(plainJSBinderErrors.js, 32, 22)) + + break label + } + return x +>x : Symbol(x, Decl(plainJSBinderErrors.js, 32, 22)) + } +} +const eval = 9 +>eval : Symbol(eval, Decl(plainJSBinderErrors.js, 38, 5)) + +const arguments = 10 +>arguments : Symbol(arguments, Decl(plainJSBinderErrors.js, 39, 5)) + diff --git a/tests/baselines/reference/plainJSReservedWord.types b/tests/baselines/reference/plainJSBinderErrors.types similarity index 61% rename from tests/baselines/reference/plainJSReservedWord.types rename to tests/baselines/reference/plainJSBinderErrors.types index 9b8c76a2dab0a..29c4be2c11a20 100644 --- a/tests/baselines/reference/plainJSReservedWord.types +++ b/tests/baselines/reference/plainJSBinderErrors.types @@ -1,4 +1,4 @@ -=== tests/cases/conformance/salsa/plainJSReservedWord.js === +=== tests/cases/conformance/salsa/plainJSBinderErrors.js === export default 12 export default 13 const await = 1 @@ -64,6 +64,36 @@ class C { >arguments : 8 >8 : 8 } + withOctal() { +>withOctal : () => any + + const redundant = 010 +>redundant : 10 +>010 : 10 + + with (redundant) { +>redundant : 10 + + return toFixed() +>toFixed() : any +>toFixed : any + } + } + label() { +>label : () => number + + for(;;) { + label: var x = 1 +>label : any +>x : number +>1 : 1 + + break label +>label : any + } + return x +>x : number + } } const eval = 9 >eval : 9 diff --git a/tests/baselines/reference/plainJSReservedWord.symbols b/tests/baselines/reference/plainJSReservedWord.symbols deleted file mode 100644 index 64e9c9eed79ee..0000000000000 --- a/tests/baselines/reference/plainJSReservedWord.symbols +++ /dev/null @@ -1,62 +0,0 @@ -=== tests/cases/conformance/salsa/plainJSReservedWord.js === -export default 12 -export default 13 -const await = 1 ->await : Symbol(await, Decl(plainJSReservedWord.js, 2, 5)) - -const yield = 2 ->yield : Symbol(yield, Decl(plainJSReservedWord.js, 3, 5)) - -async function f() { ->f : Symbol(f, Decl(plainJSReservedWord.js, 3, 15)) - - const await = 3 ->await : Symbol(await, Decl(plainJSReservedWord.js, 5, 9)) -} -function* g() { ->g : Symbol(g, Decl(plainJSReservedWord.js, 6, 1)) - - const yield = 4 ->yield : Symbol(yield, Decl(plainJSReservedWord.js, 8, 9)) -} -class C { ->C : Symbol(C, Decl(plainJSReservedWord.js, 9, 1)) - - #constructor = 5 ->#constructor : Symbol(C.#constructor, Decl(plainJSReservedWord.js, 10, 9)) - - deleted() { ->deleted : Symbol(C.deleted, Decl(plainJSReservedWord.js, 11, 20)) - - function container(f) { ->container : Symbol(container, Decl(plainJSReservedWord.js, 12, 15)) ->f : Symbol(f, Decl(plainJSReservedWord.js, 13, 27)) - - delete f ->f : Symbol(f, Decl(plainJSReservedWord.js, 13, 27)) - } - var g = 6 ->g : Symbol(g, Decl(plainJSReservedWord.js, 16, 11)) - - delete g ->g : Symbol(g, Decl(plainJSReservedWord.js, 16, 11)) - - delete container ->container : Symbol(container, Decl(plainJSReservedWord.js, 12, 15)) - } - evalArguments() { ->evalArguments : Symbol(C.evalArguments, Decl(plainJSReservedWord.js, 19, 5)) - - const eval = 7 ->eval : Symbol(eval, Decl(plainJSReservedWord.js, 21, 13)) - - const arguments = 8 ->arguments : Symbol(arguments, Decl(plainJSReservedWord.js, 22, 13)) - } -} -const eval = 9 ->eval : Symbol(eval, Decl(plainJSReservedWord.js, 25, 5)) - -const arguments = 10 ->arguments : Symbol(arguments, Decl(plainJSReservedWord.js, 26, 5)) - diff --git a/tests/cases/conformance/salsa/plainJSReservedWord.ts b/tests/cases/conformance/salsa/plainJSBinderErrors.ts similarity index 64% rename from tests/cases/conformance/salsa/plainJSReservedWord.ts rename to tests/cases/conformance/salsa/plainJSBinderErrors.ts index 7eaaa6af97f0b..d2019e3f78b2f 100644 --- a/tests/cases/conformance/salsa/plainJSReservedWord.ts +++ b/tests/cases/conformance/salsa/plainJSBinderErrors.ts @@ -1,7 +1,7 @@ // @outdir: out/ // @target: esnext // @allowJS: true -// @filename: plainJSReservedWord.js +// @filename: plainJSBinderErrors.js export default 12 export default 13 const await = 1 @@ -26,6 +26,19 @@ class C { const eval = 7 const arguments = 8 } + withOctal() { + const redundant = 010 + with (redundant) { + return toFixed() + } + } + label() { + for(;;) { + label: var x = 1 + break label + } + return x + } } const eval = 9 const arguments = 10 From 6a0fe2191f39a958f4797c1fa9f4e108e12659ba Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 16 Nov 2021 08:13:12 -0800 Subject: [PATCH 3/5] address PR comments --- src/compiler/program.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index b66e50ef6165a..3fd6658572a12 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2023,20 +2023,24 @@ namespace ts { Debug.assert(!!sourceFile.bindDiagnostics); - const isCheckJs = isCheckJsEnabledForFile(sourceFile, options) && (sourceFile.scriptKind === ScriptKind.JS || sourceFile.scriptKind === ScriptKind.JSX); - const isPlainJs = !sourceFile.checkJsDirective && options.checkJs === undefined && (sourceFile.scriptKind === ScriptKind.JS || sourceFile.scriptKind === ScriptKind.JSX); + const isJs = sourceFile.scriptKind === ScriptKind.JS || sourceFile.scriptKind === ScriptKind.JSX; + const isCheckJs = isJs && isCheckJsEnabledForFile(sourceFile, options); + const isPlainJs = isJs && !sourceFile.checkJsDirective && options.checkJs === undefined; const isTsNoCheck = !!sourceFile.checkJsDirective && sourceFile.checkJsDirective.enabled === false; - // By default, only type-check .ts, .tsx, 'Deferred' and 'External' files (external files are added by plugins) + // By default, only type-check .ts, .tsx, Deferred, plain JS, checked JS and External + // - plain JS: .js files with no // ts-check and checkJs: undefined + // - check JS: .js files with either // ts-check or checkJs: true + // - external: files that are added by plugins const includeBindAndCheckDiagnostics = !isTsNoCheck && (sourceFile.scriptKind === ScriptKind.TS || sourceFile.scriptKind === ScriptKind.TSX || sourceFile.scriptKind === ScriptKind.External || isPlainJs || isCheckJs || sourceFile.scriptKind === ScriptKind.Deferred); let bindDiagnostics: readonly Diagnostic[] = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : emptyArray; let checkDiagnostics = includeBindAndCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : emptyArray; if (isPlainJs) { - bindDiagnostics = bindDiagnostics.filter(d => plainJSErrors.has(d.code)); - checkDiagnostics = checkDiagnostics.filter(d => plainJSErrors.has(d.code)); + bindDiagnostics = filter(bindDiagnostics, d => plainJSErrors.has(d.code)); + checkDiagnostics = filter(checkDiagnostics, d => plainJSErrors.has(d.code)); } - + // skip ts-expect-error errors in plain JS files, and skip JSDoc errors except in checked JS return getMergedBindAndCheckDiagnostics(sourceFile, includeBindAndCheckDiagnostics && !isPlainJs, bindDiagnostics, checkDiagnostics, isCheckJs ? sourceFile.jsDocDiagnostics : undefined); }); } From 2f9f77eb65413f6a29d453d8487a2a82243704cc Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 18 Nov 2021 13:56:23 -0800 Subject: [PATCH 4/5] Only issue binder errors in plain JS. Checker errors require requesting diagnostics, which stll needs to be peformance tested. This commit removes one cross-file duplicate declaration error in the tests. --- src/compiler/program.ts | 3 +-- tests/baselines/reference/plainJSReservedStrict.errors.txt | 6 +----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 3fd6658572a12..971e9ca4d69cb 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2035,10 +2035,9 @@ namespace ts { const includeBindAndCheckDiagnostics = !isTsNoCheck && (sourceFile.scriptKind === ScriptKind.TS || sourceFile.scriptKind === ScriptKind.TSX || sourceFile.scriptKind === ScriptKind.External || isPlainJs || isCheckJs || sourceFile.scriptKind === ScriptKind.Deferred); let bindDiagnostics: readonly Diagnostic[] = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : emptyArray; - let checkDiagnostics = includeBindAndCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : emptyArray; + let checkDiagnostics = includeBindAndCheckDiagnostics && !isPlainJs ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : emptyArray; if (isPlainJs) { bindDiagnostics = filter(bindDiagnostics, d => plainJSErrors.has(d.code)); - checkDiagnostics = filter(checkDiagnostics, d => plainJSErrors.has(d.code)); } // skip ts-expect-error errors in plain JS files, and skip JSDoc errors except in checked JS return getMergedBindAndCheckDiagnostics(sourceFile, includeBindAndCheckDiagnostics && !isPlainJs, bindDiagnostics, checkDiagnostics, isCheckJs ? sourceFile.jsDocDiagnostics : undefined); diff --git a/tests/baselines/reference/plainJSReservedStrict.errors.txt b/tests/baselines/reference/plainJSReservedStrict.errors.txt index a040fce591c17..db4714a10c194 100644 --- a/tests/baselines/reference/plainJSReservedStrict.errors.txt +++ b/tests/baselines/reference/plainJSReservedStrict.errors.txt @@ -1,16 +1,12 @@ tests/cases/conformance/salsa/plainJSReservedStrict.js(2,7): error TS1100: Invalid use of 'eval' in strict mode. -tests/cases/conformance/salsa/plainJSReservedStrict.js(2,7): error TS2451: Cannot redeclare block-scoped variable 'eval'. tests/cases/conformance/salsa/plainJSReservedStrict.js(3,7): error TS1100: Invalid use of 'arguments' in strict mode. -==== tests/cases/conformance/salsa/plainJSReservedStrict.js (3 errors) ==== +==== tests/cases/conformance/salsa/plainJSReservedStrict.js (2 errors) ==== "use strict" const eval = 1 ~~~~ !!! error TS1100: Invalid use of 'eval' in strict mode. - ~~~~ -!!! error TS2451: Cannot redeclare block-scoped variable 'eval'. -!!! related TS6203 /.ts/lib.es5.d.ts:32:18: 'eval' was also declared here. const arguments = 2 ~~~~~~~~~ !!! error TS1100: Invalid use of 'arguments' in strict mode. From 4824d64dc0f993dcd493e08ae07220f770773d7f Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 18 Nov 2021 15:51:03 -0800 Subject: [PATCH 5/5] fix const lint --- src/compiler/program.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 971e9ca4d69cb..0b577f586e8a8 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2035,7 +2035,7 @@ namespace ts { const includeBindAndCheckDiagnostics = !isTsNoCheck && (sourceFile.scriptKind === ScriptKind.TS || sourceFile.scriptKind === ScriptKind.TSX || sourceFile.scriptKind === ScriptKind.External || isPlainJs || isCheckJs || sourceFile.scriptKind === ScriptKind.Deferred); let bindDiagnostics: readonly Diagnostic[] = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : emptyArray; - let checkDiagnostics = includeBindAndCheckDiagnostics && !isPlainJs ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : emptyArray; + const checkDiagnostics = includeBindAndCheckDiagnostics && !isPlainJs ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : emptyArray; if (isPlainJs) { bindDiagnostics = filter(bindDiagnostics, d => plainJSErrors.has(d.code)); }