Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 29a85e0

Browse filesBrowse files
committed
Fix microsoft#10758 Add compiler option to parse in strict mode
* add compiler option alwaysStrict * compile in strict mode when option is set * emit "use strict"
1 parent d34916a commit 29a85e0
Copy full SHA for 29a85e0

19 files changed

+170-2Lines changed: 170 additions & 2 deletions
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/compiler/binder.ts‎

Copy file name to clipboardExpand all lines: src/compiler/binder.ts
+13-2Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ namespace ts {
121121

122122
// If this file is an external module, then it is automatically in strict-mode according to
123123
// ES6. If it is not an external module, then we'll determine if it is in strict mode or
124-
// not depending on if we see "use strict" in certain places (or if we hit a class/namespace).
124+
// not depending on if we see "use strict" in certain places or if we hit a class/namespace
125+
// or if compiler options contain alwaysStrict.
125126
let inStrictMode: boolean;
126127

127128
let symbolCount = 0;
@@ -139,7 +140,7 @@ namespace ts {
139140
file = f;
140141
options = opts;
141142
languageVersion = getEmitScriptTarget(options);
142-
inStrictMode = !!file.externalModuleIndicator;
143+
inStrictMode = bindInStrictMode(file, opts);
143144
classifiableNames = createMap<string>();
144145
symbolCount = 0;
145146
skipTransformFlagAggregation = isDeclarationFile(file);
@@ -174,6 +175,16 @@ namespace ts {
174175

175176
return bindSourceFile;
176177

178+
function bindInStrictMode(file: SourceFile, opts: CompilerOptions): boolean {
179+
if (opts.alwaysStrict && !isDeclarationFile(file)) {
180+
// bind in strict mode source files with alwaysStrict option
181+
return true;
182+
}
183+
else {
184+
return !!file.externalModuleIndicator;
185+
}
186+
}
187+
177188
function createSymbol(flags: SymbolFlags, name: string): Symbol {
178189
symbolCount++;
179190
return new Symbol(flags, name);
Collapse file

‎src/compiler/commandLineParser.ts‎

Copy file name to clipboardExpand all lines: src/compiler/commandLineParser.ts
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,11 @@ namespace ts {
444444
name: "importHelpers",
445445
type: "boolean",
446446
description: Diagnostics.Import_emit_helpers_from_tslib
447+
},
448+
{
449+
name: "alwaysStrict",
450+
type: "boolean",
451+
description: Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file
447452
}
448453
];
449454

Collapse file

‎src/compiler/diagnosticMessages.json‎

Copy file name to clipboardExpand all lines: src/compiler/diagnosticMessages.json
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2861,6 +2861,10 @@
28612861
"category": "Error",
28622862
"code": 6140
28632863
},
2864+
"Parse in strict mode and emit \"use strict\" for each source file": {
2865+
"category": "Message",
2866+
"code": 6141
2867+
},
28642868
"Variable '{0}' implicitly has an '{1}' type.": {
28652869
"category": "Error",
28662870
"code": 7005
Collapse file

‎src/compiler/transformers/ts.ts‎

Copy file name to clipboardExpand all lines: src/compiler/transformers/ts.ts
+12Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,11 @@ namespace ts {
436436
function visitSourceFile(node: SourceFile) {
437437
currentSourceFile = node;
438438

439+
// ensure "use strict"" is emitted in all scenarios in alwaysStrict mode
440+
if (compilerOptions.alwaysStrict) {
441+
node = emitUseStrict(node);
442+
}
443+
439444
// If the source file requires any helpers and is an external module, and
440445
// the importHelpers compiler option is enabled, emit a synthesized import
441446
// statement for the helpers library.
@@ -472,6 +477,13 @@ namespace ts {
472477
return node;
473478
}
474479

480+
function emitUseStrict(node: SourceFile): SourceFile {
481+
const statements: Statement[] = [];
482+
statements.push(startOnNewLine(createStatement(createLiteral("use strict"))));
483+
// add "use strict" as the first statement
484+
return updateSourceFileNode(node, statements.concat(node.statements));
485+
}
486+
475487
/**
476488
* Tests whether we should emit a __decorate call for a class declaration.
477489
*/
Collapse file

‎src/compiler/types.ts‎

Copy file name to clipboardExpand all lines: src/compiler/types.ts
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2929,6 +2929,7 @@ namespace ts {
29292929
allowSyntheticDefaultImports?: boolean;
29302930
allowUnreachableCode?: boolean;
29312931
allowUnusedLabels?: boolean;
2932+
alwaysStrict?: boolean;
29322933
baseUrl?: string;
29332934
charset?: string;
29342935
/* @internal */ configFilePath?: string;
Collapse file

‎src/harness/unittests/transpile.ts‎

Copy file name to clipboardExpand all lines: src/harness/unittests/transpile.ts
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,10 @@ var x = 0;`, {
253253
options: { compilerOptions: { allowUnusedLabels: true }, fileName: "input.js", reportDiagnostics: true }
254254
});
255255

256+
transpilesCorrectly("Supports setting 'alwaysStrict'", "x;", {
257+
options: { compilerOptions: { alwaysStrict: true }, fileName: "input.js", reportDiagnostics: true }
258+
});
259+
256260
transpilesCorrectly("Supports setting 'baseUrl'", "x;", {
257261
options: { compilerOptions: { baseUrl: "./folder/baseUrl" }, fileName: "input.js", reportDiagnostics: true }
258262
});
Collapse file
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
tests/cases/compiler/alwaysStrict.ts(3,9): error TS1100: Invalid use of 'arguments' in strict mode.
2+
3+
4+
==== tests/cases/compiler/alwaysStrict.ts (1 errors) ====
5+
6+
function f() {
7+
var arguments = [];
8+
~~~~~~~~~
9+
!!! error TS1100: Invalid use of 'arguments' in strict mode.
10+
}
Collapse file
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//// [alwaysStrict.ts]
2+
3+
function f() {
4+
var arguments = [];
5+
}
6+
7+
//// [alwaysStrict.js]
8+
"use strict";
9+
function f() {
10+
var arguments = [];
11+
}
Collapse file
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
tests/cases/compiler/alwaysStrictES6.ts(3,9): error TS1100: Invalid use of 'arguments' in strict mode.
2+
3+
4+
==== tests/cases/compiler/alwaysStrictES6.ts (1 errors) ====
5+
6+
function f() {
7+
var arguments = [];
8+
~~~~~~~~~
9+
!!! error TS1100: Invalid use of 'arguments' in strict mode.
10+
}
Collapse file
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//// [alwaysStrictES6.ts]
2+
3+
function f() {
4+
var arguments = [];
5+
}
6+
7+
//// [alwaysStrictES6.js]
8+
"use strict";
9+
function f() {
10+
var arguments = [];
11+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.