mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-14 02:15:12 -06:00
Merge branch '10758-always-strict' of https://github.com/slawomir/TypeScript into slawomir-10758-always-strict
This commit is contained in:
commit
418a251237
@ -121,7 +121,8 @@ namespace ts {
|
||||
|
||||
// If this file is an external module, then it is automatically in strict-mode according to
|
||||
// ES6. If it is not an external module, then we'll determine if it is in strict mode or
|
||||
// not depending on if we see "use strict" in certain places (or if we hit a class/namespace).
|
||||
// not depending on if we see "use strict" in certain places or if we hit a class/namespace
|
||||
// or if compiler options contain alwaysStrict.
|
||||
let inStrictMode: boolean;
|
||||
|
||||
let symbolCount = 0;
|
||||
@ -139,7 +140,7 @@ namespace ts {
|
||||
file = f;
|
||||
options = opts;
|
||||
languageVersion = getEmitScriptTarget(options);
|
||||
inStrictMode = !!file.externalModuleIndicator;
|
||||
inStrictMode = bindInStrictMode(file, opts);
|
||||
classifiableNames = createMap<string>();
|
||||
symbolCount = 0;
|
||||
skipTransformFlagAggregation = isDeclarationFile(file);
|
||||
@ -174,6 +175,16 @@ namespace ts {
|
||||
|
||||
return bindSourceFile;
|
||||
|
||||
function bindInStrictMode(file: SourceFile, opts: CompilerOptions): boolean {
|
||||
if (opts.alwaysStrict && !isDeclarationFile(file)) {
|
||||
// bind in strict mode source files with alwaysStrict option
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return !!file.externalModuleIndicator;
|
||||
}
|
||||
}
|
||||
|
||||
function createSymbol(flags: SymbolFlags, name: string): Symbol {
|
||||
symbolCount++;
|
||||
return new Symbol(flags, name);
|
||||
|
||||
@ -444,6 +444,11 @@ namespace ts {
|
||||
name: "importHelpers",
|
||||
type: "boolean",
|
||||
description: Diagnostics.Import_emit_helpers_from_tslib
|
||||
},
|
||||
{
|
||||
name: "alwaysStrict",
|
||||
type: "boolean",
|
||||
description: Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@ -2861,6 +2861,10 @@
|
||||
"category": "Error",
|
||||
"code": 6140
|
||||
},
|
||||
"Parse in strict mode and emit \"use strict\" for each source file": {
|
||||
"category": "Message",
|
||||
"code": 6141
|
||||
},
|
||||
"Variable '{0}' implicitly has an '{1}' type.": {
|
||||
"category": "Error",
|
||||
"code": 7005
|
||||
|
||||
@ -2235,6 +2235,33 @@ namespace ts {
|
||||
return statementOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures "use strict" directive is added
|
||||
*
|
||||
* @param node source file
|
||||
*/
|
||||
export function ensureUseStrict(node: SourceFile): SourceFile {
|
||||
let foundUseStrict = false;
|
||||
for (const statement of node.statements) {
|
||||
if (isPrologueDirective(statement)) {
|
||||
if (isUseStrictPrologue(statement as ExpressionStatement)) {
|
||||
foundUseStrict = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundUseStrict) {
|
||||
const statements: Statement[] = [];
|
||||
statements.push(startOnNewLine(createStatement(createLiteral("use strict"))));
|
||||
// add "use strict" as the first statement
|
||||
return updateSourceFileNode(node, statements.concat(node.statements));
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the operand to a BinaryExpression in parentheses if they are needed to preserve the intended
|
||||
* order of operations.
|
||||
|
||||
@ -436,6 +436,11 @@ namespace ts {
|
||||
function visitSourceFile(node: SourceFile) {
|
||||
currentSourceFile = node;
|
||||
|
||||
// ensure "use strict" is emitted in all scenarios in alwaysStrict mode
|
||||
if (compilerOptions.alwaysStrict) {
|
||||
node = ensureUseStrict(node);
|
||||
}
|
||||
|
||||
// If the source file requires any helpers and is an external module, and
|
||||
// the importHelpers compiler option is enabled, emit a synthesized import
|
||||
// statement for the helpers library.
|
||||
|
||||
@ -2925,6 +2925,7 @@ namespace ts {
|
||||
allowSyntheticDefaultImports?: boolean;
|
||||
allowUnreachableCode?: boolean;
|
||||
allowUnusedLabels?: boolean;
|
||||
alwaysStrict?: boolean;
|
||||
baseUrl?: string;
|
||||
charset?: string;
|
||||
/* @internal */ configFilePath?: string;
|
||||
|
||||
@ -253,6 +253,10 @@ var x = 0;`, {
|
||||
options: { compilerOptions: { allowUnusedLabels: true }, fileName: "input.js", reportDiagnostics: true }
|
||||
});
|
||||
|
||||
transpilesCorrectly("Supports setting 'alwaysStrict'", "x;", {
|
||||
options: { compilerOptions: { alwaysStrict: true }, fileName: "input.js", reportDiagnostics: true }
|
||||
});
|
||||
|
||||
transpilesCorrectly("Supports setting 'baseUrl'", "x;", {
|
||||
options: { compilerOptions: { baseUrl: "./folder/baseUrl" }, fileName: "input.js", reportDiagnostics: true }
|
||||
});
|
||||
|
||||
10
tests/baselines/reference/alwaysStrict.errors.txt
Normal file
10
tests/baselines/reference/alwaysStrict.errors.txt
Normal file
@ -0,0 +1,10 @@
|
||||
tests/cases/compiler/alwaysStrict.ts(3,9): error TS1100: Invalid use of 'arguments' in strict mode.
|
||||
|
||||
|
||||
==== tests/cases/compiler/alwaysStrict.ts (1 errors) ====
|
||||
|
||||
function f() {
|
||||
var arguments = [];
|
||||
~~~~~~~~~
|
||||
!!! error TS1100: Invalid use of 'arguments' in strict mode.
|
||||
}
|
||||
11
tests/baselines/reference/alwaysStrict.js
Normal file
11
tests/baselines/reference/alwaysStrict.js
Normal file
@ -0,0 +1,11 @@
|
||||
//// [alwaysStrict.ts]
|
||||
|
||||
function f() {
|
||||
var arguments = [];
|
||||
}
|
||||
|
||||
//// [alwaysStrict.js]
|
||||
"use strict";
|
||||
function f() {
|
||||
var arguments = [];
|
||||
}
|
||||
11
tests/baselines/reference/alwaysStrictAlreadyUseStrict.js
Normal file
11
tests/baselines/reference/alwaysStrictAlreadyUseStrict.js
Normal file
@ -0,0 +1,11 @@
|
||||
//// [alwaysStrictAlreadyUseStrict.ts]
|
||||
"use strict"
|
||||
function f() {
|
||||
var a = [];
|
||||
}
|
||||
|
||||
//// [alwaysStrictAlreadyUseStrict.js]
|
||||
"use strict";
|
||||
function f() {
|
||||
var a = [];
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
=== tests/cases/compiler/alwaysStrictAlreadyUseStrict.ts ===
|
||||
"use strict"
|
||||
function f() {
|
||||
>f : Symbol(f, Decl(alwaysStrictAlreadyUseStrict.ts, 0, 12))
|
||||
|
||||
var a = [];
|
||||
>a : Symbol(a, Decl(alwaysStrictAlreadyUseStrict.ts, 2, 7))
|
||||
}
|
||||
11
tests/baselines/reference/alwaysStrictAlreadyUseStrict.types
Normal file
11
tests/baselines/reference/alwaysStrictAlreadyUseStrict.types
Normal file
@ -0,0 +1,11 @@
|
||||
=== tests/cases/compiler/alwaysStrictAlreadyUseStrict.ts ===
|
||||
"use strict"
|
||||
>"use strict" : "use strict"
|
||||
|
||||
function f() {
|
||||
>f : () => void
|
||||
|
||||
var a = [];
|
||||
>a : any[]
|
||||
>[] : undefined[]
|
||||
}
|
||||
10
tests/baselines/reference/alwaysStrictES6.errors.txt
Normal file
10
tests/baselines/reference/alwaysStrictES6.errors.txt
Normal file
@ -0,0 +1,10 @@
|
||||
tests/cases/compiler/alwaysStrictES6.ts(3,9): error TS1100: Invalid use of 'arguments' in strict mode.
|
||||
|
||||
|
||||
==== tests/cases/compiler/alwaysStrictES6.ts (1 errors) ====
|
||||
|
||||
function f() {
|
||||
var arguments = [];
|
||||
~~~~~~~~~
|
||||
!!! error TS1100: Invalid use of 'arguments' in strict mode.
|
||||
}
|
||||
11
tests/baselines/reference/alwaysStrictES6.js
Normal file
11
tests/baselines/reference/alwaysStrictES6.js
Normal file
@ -0,0 +1,11 @@
|
||||
//// [alwaysStrictES6.ts]
|
||||
|
||||
function f() {
|
||||
var arguments = [];
|
||||
}
|
||||
|
||||
//// [alwaysStrictES6.js]
|
||||
"use strict";
|
||||
function f() {
|
||||
var arguments = [];
|
||||
}
|
||||
12
tests/baselines/reference/alwaysStrictModule.errors.txt
Normal file
12
tests/baselines/reference/alwaysStrictModule.errors.txt
Normal file
@ -0,0 +1,12 @@
|
||||
tests/cases/compiler/alwaysStrictModule.ts(4,13): error TS1100: Invalid use of 'arguments' in strict mode.
|
||||
|
||||
|
||||
==== tests/cases/compiler/alwaysStrictModule.ts (1 errors) ====
|
||||
|
||||
module M {
|
||||
export function f() {
|
||||
var arguments = [];
|
||||
~~~~~~~~~
|
||||
!!! error TS1100: Invalid use of 'arguments' in strict mode.
|
||||
}
|
||||
}
|
||||
17
tests/baselines/reference/alwaysStrictModule.js
Normal file
17
tests/baselines/reference/alwaysStrictModule.js
Normal file
@ -0,0 +1,17 @@
|
||||
//// [alwaysStrictModule.ts]
|
||||
|
||||
module M {
|
||||
export function f() {
|
||||
var arguments = [];
|
||||
}
|
||||
}
|
||||
|
||||
//// [alwaysStrictModule.js]
|
||||
"use strict";
|
||||
var M;
|
||||
(function (M) {
|
||||
function f() {
|
||||
var arguments = [];
|
||||
}
|
||||
M.f = f;
|
||||
})(M || (M = {}));
|
||||
@ -0,0 +1,12 @@
|
||||
tests/cases/compiler/alwaysStrictNoImplicitUseStrict.ts(4,13): error TS1100: Invalid use of 'arguments' in strict mode.
|
||||
|
||||
|
||||
==== tests/cases/compiler/alwaysStrictNoImplicitUseStrict.ts (1 errors) ====
|
||||
|
||||
module M {
|
||||
export function f() {
|
||||
var arguments = [];
|
||||
~~~~~~~~~
|
||||
!!! error TS1100: Invalid use of 'arguments' in strict mode.
|
||||
}
|
||||
}
|
||||
17
tests/baselines/reference/alwaysStrictNoImplicitUseStrict.js
Normal file
17
tests/baselines/reference/alwaysStrictNoImplicitUseStrict.js
Normal file
@ -0,0 +1,17 @@
|
||||
//// [alwaysStrictNoImplicitUseStrict.ts]
|
||||
|
||||
module M {
|
||||
export function f() {
|
||||
var arguments = [];
|
||||
}
|
||||
}
|
||||
|
||||
//// [alwaysStrictNoImplicitUseStrict.js]
|
||||
"use strict";
|
||||
var M;
|
||||
(function (M) {
|
||||
function f() {
|
||||
var arguments = [];
|
||||
}
|
||||
M.f = f;
|
||||
})(M || (M = {}));
|
||||
@ -0,0 +1,3 @@
|
||||
"use strict";
|
||||
x;
|
||||
//# sourceMappingURL=input.js.map
|
||||
5
tests/cases/compiler/alwaysStrict.ts
Normal file
5
tests/cases/compiler/alwaysStrict.ts
Normal file
@ -0,0 +1,5 @@
|
||||
// @alwaysStrict: true
|
||||
|
||||
function f() {
|
||||
var arguments = [];
|
||||
}
|
||||
5
tests/cases/compiler/alwaysStrictAlreadyUseStrict.ts
Normal file
5
tests/cases/compiler/alwaysStrictAlreadyUseStrict.ts
Normal file
@ -0,0 +1,5 @@
|
||||
// @alwaysStrict: true
|
||||
"use strict"
|
||||
function f() {
|
||||
var a = [];
|
||||
}
|
||||
6
tests/cases/compiler/alwaysStrictES6.ts
Normal file
6
tests/cases/compiler/alwaysStrictES6.ts
Normal file
@ -0,0 +1,6 @@
|
||||
// @target: ES6
|
||||
// @alwaysStrict: true
|
||||
|
||||
function f() {
|
||||
var arguments = [];
|
||||
}
|
||||
8
tests/cases/compiler/alwaysStrictModule.ts
Normal file
8
tests/cases/compiler/alwaysStrictModule.ts
Normal file
@ -0,0 +1,8 @@
|
||||
// @module: commonjs
|
||||
// @alwaysStrict: true
|
||||
|
||||
module M {
|
||||
export function f() {
|
||||
var arguments = [];
|
||||
}
|
||||
}
|
||||
9
tests/cases/compiler/alwaysStrictNoImplicitUseStrict.ts
Normal file
9
tests/cases/compiler/alwaysStrictNoImplicitUseStrict.ts
Normal file
@ -0,0 +1,9 @@
|
||||
// @module: commonjs
|
||||
// @alwaysStrict: true
|
||||
// @noImplicitUseStrict: true
|
||||
|
||||
module M {
|
||||
export function f() {
|
||||
var arguments = [];
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user