diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 6139dda0013..ed9f010c56a 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -661,19 +661,17 @@ namespace ts { } function getSemanticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] { - // For JavaScript files, we don't want to report the normal typescript semantic errors. - // Instead, we just report errors for using TypeScript-only constructs from within a - // JavaScript file. - if (isSourceFileJavaScript(sourceFile)) { - return getJavaScriptSemanticDiagnosticsForFile(sourceFile, cancellationToken); - } - return runWithCancellationToken(() => { const typeChecker = getDiagnosticsProducingTypeChecker(); Debug.assert(!!sourceFile.bindDiagnostics); const bindDiagnostics = sourceFile.bindDiagnostics; - const checkDiagnostics = typeChecker.getDiagnostics(sourceFile, cancellationToken); + // For JavaScript files, we don't want to report the normal typescript semantic errors. + // Instead, we just report errors for using TypeScript-only constructs from within a + // JavaScript file. + const checkDiagnostics = isSourceFileJavaScript(sourceFile) ? + getJavaScriptSemanticDiagnosticsForFile(sourceFile, cancellationToken) : + typeChecker.getDiagnostics(sourceFile, cancellationToken); const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName); const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName); @@ -1079,6 +1077,8 @@ namespace ts { const importedFile = findSourceFile(resolution.resolvedFileName, toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName), /*isDefaultLib*/ false, file, skipTrivia(file.text, file.imports[i].pos), file.imports[i].end); if (importedFile && resolution.isExternalLibraryImport) { + // Since currently irrespective of allowJs, we only look for supportedTypeScript extension external module files, + // this check is ok. Otherwise this would be never true for javascript file if (!isExternalModule(importedFile)) { const start = getTokenPosOfNode(file.imports[i], file); fileProcessingDiagnostics.add(createFileDiagnostic(file, start, file.imports[i].end - start, Diagnostics.Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_the_package_definition, importedFile.fileName)); diff --git a/tests/baselines/reference/jsFileCompilationBindDuplicateIdentifier.errors.txt b/tests/baselines/reference/jsFileCompilationBindDuplicateIdentifier.errors.txt new file mode 100644 index 00000000000..2816eaee8b4 --- /dev/null +++ b/tests/baselines/reference/jsFileCompilationBindDuplicateIdentifier.errors.txt @@ -0,0 +1,12 @@ +tests/cases/compiler/a.js(1,5): error TS2300: Duplicate identifier 'a'. +tests/cases/compiler/a.js(2,7): error TS2300: Duplicate identifier 'a'. + + +==== tests/cases/compiler/a.js (2 errors) ==== + var a = 10; + ~ +!!! error TS2300: Duplicate identifier 'a'. + class a { + ~ +!!! error TS2300: Duplicate identifier 'a'. + } \ No newline at end of file diff --git a/tests/baselines/reference/jsFileCompilationBindErrors.errors.txt b/tests/baselines/reference/jsFileCompilationBindErrors.errors.txt new file mode 100644 index 00000000000..eeae7053333 --- /dev/null +++ b/tests/baselines/reference/jsFileCompilationBindErrors.errors.txt @@ -0,0 +1,27 @@ +tests/cases/compiler/a.js(1,5): error TS2451: Cannot redeclare block-scoped variable 'C'. +tests/cases/compiler/a.js(2,5): error TS2451: Cannot redeclare block-scoped variable 'C'. +tests/cases/compiler/a.js(6,5): error TS7027: Unreachable code detected. +tests/cases/compiler/a.js(11,9): error TS1100: Invalid use of 'arguments' in strict mode. + + +==== tests/cases/compiler/a.js (4 errors) ==== + let C = "sss"; + ~ +!!! error TS2451: Cannot redeclare block-scoped variable 'C'. + let C = 0; // Error: Cannot redeclare block-scoped variable 'C'. + ~ +!!! error TS2451: Cannot redeclare block-scoped variable 'C'. + + function f() { + return; + return; // Error: Unreachable code detected. + ~~~~~~ +!!! error TS7027: Unreachable code detected. + } + + function b() { + "use strict"; + var arguments = 0; // Error: Invalid use of 'arguments' in strict mode. + ~~~~~~~~~ +!!! error TS1100: Invalid use of 'arguments' in strict mode. + } \ No newline at end of file diff --git a/tests/baselines/reference/jsFileCompilationBindErrors.symbols b/tests/baselines/reference/jsFileCompilationBindErrors.symbols deleted file mode 100644 index 6ad06da1df6..00000000000 --- a/tests/baselines/reference/jsFileCompilationBindErrors.symbols +++ /dev/null @@ -1,21 +0,0 @@ -=== tests/cases/compiler/a.js === -let C = "sss"; ->C : Symbol(C, Decl(a.js, 0, 3)) - -let C = 0; // Error: Cannot redeclare block-scoped variable 'C'. ->C : Symbol(C, Decl(a.js, 1, 3)) - -function f() { ->f : Symbol(f, Decl(a.js, 1, 10)) - - return; - return; // Error: Unreachable code detected. -} - -function b() { ->b : Symbol(b, Decl(a.js, 6, 1)) - - "use strict"; - var arguments = 0; // Error: Invalid use of 'arguments' in strict mode. ->arguments : Symbol(arguments, Decl(a.js, 10, 7)) -} diff --git a/tests/baselines/reference/jsFileCompilationBindErrors.types b/tests/baselines/reference/jsFileCompilationBindErrors.types deleted file mode 100644 index 113bcd08bc9..00000000000 --- a/tests/baselines/reference/jsFileCompilationBindErrors.types +++ /dev/null @@ -1,26 +0,0 @@ -=== tests/cases/compiler/a.js === -let C = "sss"; ->C : string ->"sss" : string - -let C = 0; // Error: Cannot redeclare block-scoped variable 'C'. ->C : number ->0 : number - -function f() { ->f : () => void - - return; - return; // Error: Unreachable code detected. -} - -function b() { ->b : () => void - - "use strict"; ->"use strict" : string - - var arguments = 0; // Error: Invalid use of 'arguments' in strict mode. ->arguments : number ->0 : number -} diff --git a/tests/baselines/reference/jsFileCompilationBindMultipleDefaultExports.errors.txt b/tests/baselines/reference/jsFileCompilationBindMultipleDefaultExports.errors.txt new file mode 100644 index 00000000000..733f66922ab --- /dev/null +++ b/tests/baselines/reference/jsFileCompilationBindMultipleDefaultExports.errors.txt @@ -0,0 +1,18 @@ +tests/cases/compiler/a.js(1,22): error TS2528: A module cannot have multiple default exports. +tests/cases/compiler/a.js(3,1): error TS2528: A module cannot have multiple default exports. +tests/cases/compiler/a.js(3,1): error TS8003: 'export=' can only be used in a .ts file. +tests/cases/compiler/a.js(3,16): error TS1109: Expression expected. + + +==== tests/cases/compiler/a.js (4 errors) ==== + export default class a { + ~ +!!! error TS2528: A module cannot have multiple default exports. + } + export default var a = 10; + ~~~~~~~~~~~~~~ +!!! error TS2528: A module cannot have multiple default exports. + ~~~~~~~~~~~~~~ +!!! error TS8003: 'export=' can only be used in a .ts file. + ~~~ +!!! error TS1109: Expression expected. \ No newline at end of file diff --git a/tests/baselines/reference/jsFileCompilationBindReachabilityErrors.errors.txt b/tests/baselines/reference/jsFileCompilationBindReachabilityErrors.errors.txt new file mode 100644 index 00000000000..a883e66e607 --- /dev/null +++ b/tests/baselines/reference/jsFileCompilationBindReachabilityErrors.errors.txt @@ -0,0 +1,31 @@ +tests/cases/compiler/a.js(3,9): error TS7029: Fallthrough case in switch. +tests/cases/compiler/a.js(16,5): error TS7027: Unreachable code detected. +tests/cases/compiler/a.js(19,1): error TS7028: Unused label. + + +==== tests/cases/compiler/a.js (3 errors) ==== + function foo(a, b) { + switch (a) { + case 10: + ~~~~ +!!! error TS7029: Fallthrough case in switch. + if (b) { + return b; + } + case 20: + return a; + } + } + + function bar() { + return x; + function bar2() { + } + var x = 10; // error + ~~~ +!!! error TS7027: Unreachable code detected. + } + + label1: var x2 = 10; + ~~~~~~ +!!! error TS7028: Unused label. \ No newline at end of file diff --git a/tests/baselines/reference/jsFileCompilationBindStrictModeErrors.errors.txt b/tests/baselines/reference/jsFileCompilationBindStrictModeErrors.errors.txt new file mode 100644 index 00000000000..65dffb5a08e --- /dev/null +++ b/tests/baselines/reference/jsFileCompilationBindStrictModeErrors.errors.txt @@ -0,0 +1,81 @@ +tests/cases/compiler/a.js(3,5): error TS2300: Duplicate identifier 'a'. +tests/cases/compiler/a.js(5,5): error TS1117: An object literal cannot have multiple properties with the same name in strict mode. +tests/cases/compiler/a.js(5,5): error TS2300: Duplicate identifier 'a'. +tests/cases/compiler/a.js(7,5): error TS1212: Identifier expected. 'let' is a reserved word in strict mode +tests/cases/compiler/a.js(8,8): error TS1102: 'delete' cannot be called on an identifier in strict mode. +tests/cases/compiler/a.js(10,10): error TS1100: Invalid use of 'eval' in strict mode. +tests/cases/compiler/a.js(12,10): error TS1100: Invalid use of 'arguments' in strict mode. +tests/cases/compiler/a.js(15,1): error TS1101: 'with' statements are not allowed in strict mode. +tests/cases/compiler/b.js(3,7): error TS1210: Invalid use of 'eval'. Class definitions are automatically in strict mode. +tests/cases/compiler/b.js(6,13): error TS1213: Identifier expected. 'let' is a reserved word in strict mode. Class definitions are automatically in strict mode. +tests/cases/compiler/c.js(1,12): error TS1214: Identifier expected. 'let' is a reserved word in strict mode. Modules are automatically in strict mode. +tests/cases/compiler/c.js(2,5): error TS1215: Invalid use of 'eval'. Modules are automatically in strict mode. +tests/cases/compiler/d.js(2,9): error TS1121: Octal literals are not allowed in strict mode. +tests/cases/compiler/d.js(2,11): error TS1005: ',' expected. + + +==== tests/cases/compiler/a.js (8 errors) ==== + "use strict"; + var a = { + a: "hello", // error + ~ +!!! error TS2300: Duplicate identifier 'a'. + b: 10, + a: 10 // error + ~ +!!! error TS1117: An object literal cannot have multiple properties with the same name in strict mode. + ~ +!!! error TS2300: Duplicate identifier 'a'. + }; + var let = 10; // error + ~~~ +!!! error TS1212: Identifier expected. 'let' is a reserved word in strict mode + delete a; // error + ~ +!!! error TS1102: 'delete' cannot be called on an identifier in strict mode. + try { + } catch (eval) { // error + ~~~~ +!!! error TS1100: Invalid use of 'eval' in strict mode. + } + function arguments() { // error + ~~~~~~~~~ +!!! error TS1100: Invalid use of 'arguments' in strict mode. + } + + with (a) { + ~~~~ +!!! error TS1101: 'with' statements are not allowed in strict mode. + b = 10; + } + +==== tests/cases/compiler/b.js (2 errors) ==== + // this is not in strict mode but class definitions are always in strict mode + class c { + a(eval) { //error + ~~~~ +!!! error TS1210: Invalid use of 'eval'. Class definitions are automatically in strict mode. + } + method() { + var let = 10; // error + ~~~ +!!! error TS1213: Identifier expected. 'let' is a reserved word in strict mode. Class definitions are automatically in strict mode. + } + } + +==== tests/cases/compiler/c.js (2 errors) ==== + export var let = 10; // external modules are automatically in strict mode + ~~~ +!!! error TS1214: Identifier expected. 'let' is a reserved word in strict mode. Modules are automatically in strict mode. + var eval = function () { + ~~~~ +!!! error TS1215: Invalid use of 'eval'. Modules are automatically in strict mode. + }; + +==== tests/cases/compiler/d.js (2 errors) ==== + "use strict"; + var x = 009; // error + ~~ +!!! error TS1121: Octal literals are not allowed in strict mode. + ~ +!!! error TS1005: ',' expected. \ No newline at end of file diff --git a/tests/baselines/reference/jsFileCompilationExportAssignmentSyntax.errors.txt b/tests/baselines/reference/jsFileCompilationExportAssignmentSyntax.errors.txt index f537941c55c..3be5f99823a 100644 --- a/tests/baselines/reference/jsFileCompilationExportAssignmentSyntax.errors.txt +++ b/tests/baselines/reference/jsFileCompilationExportAssignmentSyntax.errors.txt @@ -1,9 +1,12 @@ error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file. +tests/cases/compiler/a.js(1,1): error TS1148: Cannot compile modules unless the '--module' flag is provided. tests/cases/compiler/a.js(1,1): error TS8003: 'export=' can only be used in a .ts file. !!! error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file. -==== tests/cases/compiler/a.js (1 errors) ==== +==== tests/cases/compiler/a.js (2 errors) ==== export = b; ~~~~~~~~~~~ +!!! error TS1148: Cannot compile modules unless the '--module' flag is provided. + ~~~~~~~~~~~ !!! error TS8003: 'export=' can only be used in a .ts file. \ No newline at end of file diff --git a/tests/baselines/reference/jsFileCompilationExternalPackageError.errors.txt b/tests/baselines/reference/jsFileCompilationExternalPackageError.errors.txt new file mode 100644 index 00000000000..58111c777f1 --- /dev/null +++ b/tests/baselines/reference/jsFileCompilationExternalPackageError.errors.txt @@ -0,0 +1,19 @@ +tests/cases/compiler/moduleA/a.js(2,17): error TS2656: Exported external package typings file 'tests/cases/compiler/node_modules/b.ts' is not a module. Please contact the package author to update the package definition. + + +==== tests/cases/compiler/moduleA/a.js (1 errors) ==== + + import {a} from "b"; + ~~~ +!!! error TS2656: Exported external package typings file 'b.ts' is not a module. Please contact the package author to update the package definition. + a++; + import {c} from "c"; + c++; + +==== tests/cases/compiler/node_modules/b.ts (0 errors) ==== + var a = 10; + +==== tests/cases/compiler/node_modules/c.js (0 errors) ==== + exports.a = 10; + c = 10; + \ No newline at end of file diff --git a/tests/cases/compiler/jsFileCompilationBindDuplicateIdentifier.ts b/tests/cases/compiler/jsFileCompilationBindDuplicateIdentifier.ts new file mode 100644 index 00000000000..3433adc17d5 --- /dev/null +++ b/tests/cases/compiler/jsFileCompilationBindDuplicateIdentifier.ts @@ -0,0 +1,6 @@ +// @allowJs: true +// @noEmit: true +// @filename: a.js +var a = 10; +class a { +} \ No newline at end of file diff --git a/tests/cases/compiler/jsFileCompilationBindMultipleDefaultExports.ts b/tests/cases/compiler/jsFileCompilationBindMultipleDefaultExports.ts new file mode 100644 index 00000000000..32a9e77fcc7 --- /dev/null +++ b/tests/cases/compiler/jsFileCompilationBindMultipleDefaultExports.ts @@ -0,0 +1,7 @@ +// @allowJs: true +// @noEmit: true +// @filename: a.js +// @target: es6 +export default class a { +} +export default var a = 10; \ No newline at end of file diff --git a/tests/cases/compiler/jsFileCompilationBindReachabilityErrors.ts b/tests/cases/compiler/jsFileCompilationBindReachabilityErrors.ts new file mode 100644 index 00000000000..b95f85c2139 --- /dev/null +++ b/tests/cases/compiler/jsFileCompilationBindReachabilityErrors.ts @@ -0,0 +1,23 @@ +// @allowJs: true +// @noEmit: true +// @filename: a.js +// @noFallthroughCasesInSwitch: true +function foo(a, b) { + switch (a) { + case 10: + if (b) { + return b; + } + case 20: + return a; + } +} + +function bar() { + return x; + function bar2() { + } + var x = 10; // error +} + +label1: var x2 = 10; \ No newline at end of file diff --git a/tests/cases/compiler/jsFileCompilationBindStrictModeErrors.ts b/tests/cases/compiler/jsFileCompilationBindStrictModeErrors.ts new file mode 100644 index 00000000000..30b43b1990e --- /dev/null +++ b/tests/cases/compiler/jsFileCompilationBindStrictModeErrors.ts @@ -0,0 +1,40 @@ +// @allowJs: true +// @noEmit: true +// @filename: a.js +// @target: es6 +"use strict"; +var a = { + a: "hello", // error + b: 10, + a: 10 // error +}; +var let = 10; // error +delete a; // error +try { +} catch (eval) { // error +} +function arguments() { // error +} + +with (a) { + b = 10; +} + +// @filename: b.js +// this is not in strict mode but class definitions are always in strict mode +class c { + a(eval) { //error + } + method() { + var let = 10; // error + } +} + +// @filename: c.js +export var let = 10; // external modules are automatically in strict mode +var eval = function () { +}; + +//@filename: d.js +"use strict"; +var x = 009; // error \ No newline at end of file diff --git a/tests/cases/compiler/jsFileCompilationExternalPackageError.ts b/tests/cases/compiler/jsFileCompilationExternalPackageError.ts new file mode 100644 index 00000000000..cb9d32adb82 --- /dev/null +++ b/tests/cases/compiler/jsFileCompilationExternalPackageError.ts @@ -0,0 +1,16 @@ +// @allowJs: true +// @noEmit: true +// @module: commonjs + +// @filename: moduleA/a.js +import {a} from "b"; +a++; +import {c} from "c"; +c++; + +// @filename: node_modules/b.ts +var a = 10; + +// @filename: node_modules/c.js +exports.a = 10; +c = 10; diff --git a/tests/cases/fourslash/getJavaScriptSemanticDiagnostics2.ts b/tests/cases/fourslash/getJavaScriptSemanticDiagnostics2.ts index 9ab29b41798..58c02dae183 100644 --- a/tests/cases/fourslash/getJavaScriptSemanticDiagnostics2.ts +++ b/tests/cases/fourslash/getJavaScriptSemanticDiagnostics2.ts @@ -11,5 +11,12 @@ verify.getSemanticDiagnostics(`[ "length": 11, "category": "error", "code": 8003 + }, + { + "message": "Cannot compile modules unless the '--module' flag is provided.", + "start": 0, + "length": 11, + "category": "error", + "code": 1148 } ]`); \ No newline at end of file