Skip to content

Commit b015c1d

Browse files
committed
Allow @check directives to switch on/off checking in a file
1 parent 1f9bb69 commit b015c1d

File tree

10 files changed

+68
-11
lines changed

10 files changed

+68
-11
lines changed

src/compiler/parser.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5817,7 +5817,7 @@ namespace ts {
58175817
const typeReferenceDirectives: FileReference[] = [];
58185818
const amdDependencies: { path: string; name: string }[] = [];
58195819
let amdModuleName: string;
5820-
let hasCheckDirective = false;
5820+
let checkJsDirective: CheckJsDirective = undefined;
58215821

58225822
// Keep scanning all the leading trivia in the file until we get to something that
58235823
// isn't trivia. Any single line comment will be analyzed to see if it is a
@@ -5880,16 +5880,23 @@ namespace ts {
58805880
}
58815881
}
58825882

5883-
const checkDirectiveRegEx = /^\/\/\s*@check\s*/gim;
5884-
hasCheckDirective = hasCheckDirective || !!checkDirectiveRegEx.exec(comment);
5883+
const checkJsDirectiveRegEx = /^\/\/\/?\s*@check(\s+(true|false))?/gim;
5884+
const checkJsDirectiveMatchResult = checkJsDirectiveRegEx.exec(comment);
5885+
if (checkJsDirectiveMatchResult) {
5886+
checkJsDirective = {
5887+
enabled: compareStrings(checkJsDirectiveMatchResult[2], "false", /*ignoreCase*/ true) !== Comparison.EqualTo,
5888+
end: range.end,
5889+
pos: range.pos
5890+
};
5891+
}
58855892
}
58865893
}
58875894

58885895
sourceFile.referencedFiles = referencedFiles;
58895896
sourceFile.typeReferenceDirectives = typeReferenceDirectives;
58905897
sourceFile.amdDependencies = amdDependencies;
58915898
sourceFile.moduleName = amdModuleName;
5892-
sourceFile.hasCheckDirective = hasCheckDirective;
5899+
sourceFile.checkJsDirective = checkJsDirective;
58935900
}
58945901

58955902
function setExternalModuleIndicator(sourceFile: SourceFile) {

src/compiler/program.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -904,10 +904,9 @@ namespace ts {
904904

905905
Debug.assert(!!sourceFile.bindDiagnostics);
906906
const bindDiagnostics = sourceFile.bindDiagnostics;
907-
// For JavaScript files, we don't want to report semantic errors.
908-
// Instead, we'll report errors for using TypeScript-only constructs from within a
909-
// JavaScript file when we get syntactic diagnostics for the file.
910-
const includeCheckDiagnostics = options.checkJsFiles || sourceFile.hasCheckDirective || !isSourceFileJavaScript(sourceFile);
907+
// For JavaScript files, we don't want to report semantic errors unless ecplicitlly requested.
908+
const includeCheckDiagnostics = !isSourceFileJavaScript(sourceFile) ||
909+
(sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : options.checkJsFiles);
911910
const checkDiagnostics = includeCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : [];
912911
const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName);
913912
const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName);

src/compiler/types.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1940,6 +1940,10 @@
19401940
fileName: string;
19411941
}
19421942

1943+
export interface CheckJsDirective extends TextRange {
1944+
enabled: boolean;
1945+
}
1946+
19431947
export type CommentKind = SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia;
19441948

19451949
export interface CommentRange extends TextRange {
@@ -2272,7 +2276,7 @@
22722276
/* @internal */ moduleAugmentations: LiteralExpression[];
22732277
/* @internal */ patternAmbientModules?: PatternAmbientModule[];
22742278
/* @internal */ ambientModuleNames: string[];
2275-
/* @internal */ hasCheckDirective: boolean;
2279+
/* @internal */ checkJsDirective: CheckJsDirective | undefined;
22762280
}
22772281

22782282
export interface Bundle extends Node {

src/harness/harness.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ namespace Utils {
202202
for (const childName in node) {
203203
if (childName === "parent" || childName === "nextContainer" || childName === "modifiers" || childName === "externalModuleIndicator" ||
204204
// for now ignore jsdoc comments
205-
childName === "jsDocComment") {
205+
childName === "jsDocComment" || childName === "checkJsDirective") {
206206
continue;
207207
}
208208
const child = (<any>node)[childName];

src/services/services.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ namespace ts {
473473
public moduleAugmentations: LiteralExpression[];
474474
private namedDeclarations: Map<Declaration[]>;
475475
public ambientModuleNames: string[];
476-
public hasCheckDirective: boolean;
476+
public checkJsDirective: CheckJsDirective | undefined;
477477

478478
constructor(kind: SyntaxKind, pos: number, end: number) {
479479
super(kind, pos, end);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
tests/cases/compiler/a.js(4,1): error TS2322: Type '0' is not assignable to type 'string'.
2+
3+
4+
==== tests/cases/compiler/a.js (1 errors) ====
5+
6+
// @check true
7+
var x = "string";
8+
x = 0;
9+
~
10+
!!! error TS2322: Type '0' is not assignable to type 'string'.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
=== tests/cases/compiler/a.js ===
2+
3+
// @check false
4+
var x = "string";
5+
>x : Symbol(x, Decl(a.js, 2, 3))
6+
7+
x = 0;
8+
>x : Symbol(x, Decl(a.js, 2, 3))
9+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
=== tests/cases/compiler/a.js ===
2+
3+
// @check false
4+
var x = "string";
5+
>x : string
6+
>"string" : "string"
7+
8+
x = 0;
9+
>x = 0 : 0
10+
>x : string
11+
>0 : 0
12+

tests/cases/compiler/checkJsFiles4.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// @allowJs: true
2+
// @checkJsFiles: false
3+
// @noEmit: true
4+
5+
// @fileName: a.js
6+
// @check true
7+
var x = "string";
8+
x = 0;

tests/cases/compiler/checkJsFiles5.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// @allowJs: true
2+
// @checkJsFiles: true
3+
// @noEmit: true
4+
5+
// @fileName: a.js
6+
// @check false
7+
var x = "string";
8+
x = 0;

0 commit comments

Comments
 (0)