|
4 | 4 |
|
5 | 5 | namespace ts { |
6 | 6 | const emptyArray: any[] = []; |
| 7 | + const ignoreDiagnosticCommentRegEx = /(^\s*$)|(^\s*\/\/\/?\s*(@ts-ignore)?)/; |
7 | 8 |
|
8 | 9 | export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string { |
9 | 10 | while (true) { |
@@ -911,17 +912,42 @@ namespace ts { |
911 | 912 |
|
912 | 913 | Debug.assert(!!sourceFile.bindDiagnostics); |
913 | 914 | const bindDiagnostics = sourceFile.bindDiagnostics; |
914 | | - // For JavaScript files, we don't want to report semantic errors. |
915 | | - // Instead, we'll report errors for using TypeScript-only constructs from within a |
916 | | - // JavaScript file when we get syntactic diagnostics for the file. |
917 | | - const checkDiagnostics = isSourceFileJavaScript(sourceFile) ? [] : typeChecker.getDiagnostics(sourceFile, cancellationToken); |
| 915 | + // For JavaScript files, we don't want to report semantic errors unless explicitly requested. |
| 916 | + const includeCheckDiagnostics = !isSourceFileJavaScript(sourceFile) || isCheckJsEnabledForFile(sourceFile, options); |
| 917 | + const checkDiagnostics = includeCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : []; |
918 | 918 | const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName); |
919 | 919 | const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName); |
920 | 920 |
|
921 | | - return bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile); |
| 921 | + const diagnostics = bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile); |
| 922 | + return isSourceFileJavaScript(sourceFile) |
| 923 | + ? filter(diagnostics, shouldReportDiagnostic) |
| 924 | + : diagnostics; |
922 | 925 | }); |
923 | 926 | } |
924 | 927 |
|
| 928 | + /** |
| 929 | + * Skip errors if previous line start with '// @ts-ignore' comment, not counting non-empty non-comment lines |
| 930 | + */ |
| 931 | + function shouldReportDiagnostic(diagnostic: Diagnostic) { |
| 932 | + const { file, start } = diagnostic; |
| 933 | + const lineStarts = getLineStarts(file); |
| 934 | + let { line } = computeLineAndCharacterOfPosition(lineStarts, start); |
| 935 | + while (line > 0) { |
| 936 | + const previousLineText = file.text.slice(lineStarts[line - 1], lineStarts[line]); |
| 937 | + const result = ignoreDiagnosticCommentRegEx.exec(previousLineText); |
| 938 | + if (!result) { |
| 939 | + // non-empty line |
| 940 | + return true; |
| 941 | + } |
| 942 | + if (result[3]) { |
| 943 | + // @ts-ignore |
| 944 | + return false; |
| 945 | + } |
| 946 | + line--; |
| 947 | + } |
| 948 | + return true; |
| 949 | + } |
| 950 | + |
925 | 951 | function getJavaScriptSyntacticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] { |
926 | 952 | return runWithCancellationToken(() => { |
927 | 953 | const diagnostics: Diagnostic[] = []; |
@@ -1722,6 +1748,10 @@ namespace ts { |
1722 | 1748 | programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration")); |
1723 | 1749 | } |
1724 | 1750 |
|
| 1751 | + if (options.checkJs && !options.allowJs) { |
| 1752 | + programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "checkJs", "allowJs")); |
| 1753 | + } |
| 1754 | + |
1725 | 1755 | if (options.emitDecoratorMetadata && |
1726 | 1756 | !options.experimentalDecorators) { |
1727 | 1757 | programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators")); |
|
0 commit comments