Skip to content

Commit

Permalink
Merge pull request #14486 from Microsoft/strictChecks
Browse files Browse the repository at this point in the history
New --strict master option
  • Loading branch information
ahejlsberg authored Mar 6, 2017
2 parents c968eed + de120b3 commit f7242f3
Show file tree
Hide file tree
Showing 15 changed files with 48 additions and 35 deletions.
2 changes: 1 addition & 1 deletion src/compiler/binder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ namespace ts {
return bindSourceFile;

function bindInStrictMode(file: SourceFile, opts: CompilerOptions): boolean {
if (opts.alwaysStrict && !isDeclarationFile(file)) {
if ((opts.alwaysStrict === undefined ? opts.strict : opts.alwaysStrict) && !isDeclarationFile(file)) {
// bind in strict mode source files with alwaysStrict option
return true;
}
Expand Down
40 changes: 21 additions & 19 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ namespace ts {
const modulekind = getEmitModuleKind(compilerOptions);
const noUnusedIdentifiers = !!compilerOptions.noUnusedLocals || !!compilerOptions.noUnusedParameters;
const allowSyntheticDefaultImports = typeof compilerOptions.allowSyntheticDefaultImports !== "undefined" ? compilerOptions.allowSyntheticDefaultImports : modulekind === ModuleKind.System;
const strictNullChecks = compilerOptions.strictNullChecks;
const strictNullChecks = compilerOptions.strictNullChecks === undefined ? compilerOptions.strict : compilerOptions.strictNullChecks;
const noImplicitAny = compilerOptions.noImplicitAny === undefined ? compilerOptions.strict : compilerOptions.noImplicitAny;
const noImplicitThis = compilerOptions.noImplicitThis === undefined ? compilerOptions.strict : compilerOptions.noImplicitThis;

const emitResolver = createResolver();

Expand Down Expand Up @@ -1571,7 +1573,7 @@ namespace ts {
error(errorNode, diag, moduleReference, resolvedModule.resolvedFileName);
return undefined;
}
else if (compilerOptions.noImplicitAny && moduleNotFoundError) {
else if (noImplicitAny && moduleNotFoundError) {
error(errorNode,
Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type,
moduleReference,
Expand Down Expand Up @@ -3414,7 +3416,7 @@ namespace ts {
return addOptionality(declaredType, /*optional*/ declaration.questionToken && includeOptionality);
}

if ((compilerOptions.noImplicitAny || declaration.flags & NodeFlags.JavaScriptFile) &&
if ((noImplicitAny || declaration.flags & NodeFlags.JavaScriptFile) &&
declaration.kind === SyntaxKind.VariableDeclaration && !isBindingPattern(declaration.name) &&
!(getCombinedModifierFlags(declaration) & ModifierFlags.Export) && !isInAmbientContext(declaration)) {
// If --noImplicitAny is on or the declaration is in a Javascript file,
Expand Down Expand Up @@ -3516,7 +3518,7 @@ namespace ts {
if (isBindingPattern(element.name)) {
return getTypeFromBindingPattern(<BindingPattern>element.name, includePatternInType, reportErrors);
}
if (reportErrors && compilerOptions.noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) {
if (reportErrors && noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) {
reportImplicitAnyError(element, anyType);
}
return anyType;
Expand Down Expand Up @@ -3614,7 +3616,7 @@ namespace ts {
type = declaration.dotDotDotToken ? anyArrayType : anyType;

// Report implicit any errors unless this is a private property within an ambient declaration
if (reportErrors && compilerOptions.noImplicitAny) {
if (reportErrors && noImplicitAny) {
if (!declarationBelongsToPrivateAmbientMember(declaration)) {
reportImplicitAnyError(declaration, type);
}
Expand Down Expand Up @@ -3733,7 +3735,7 @@ namespace ts {
}
// Otherwise, fall back to 'any'.
else {
if (compilerOptions.noImplicitAny) {
if (noImplicitAny) {
if (setter) {
error(setter, Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation, symbolToString(symbol));
}
Expand All @@ -3748,7 +3750,7 @@ namespace ts {
}
if (!popTypeResolution()) {
type = anyType;
if (compilerOptions.noImplicitAny) {
if (noImplicitAny) {
const getter = <AccessorDeclaration>getDeclarationOfKind(symbol, SyntaxKind.GetAccessor);
error(getter, Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, symbolToString(symbol));
}
Expand Down Expand Up @@ -3831,7 +3833,7 @@ namespace ts {
return unknownType;
}
// Otherwise variable has initializer that circularly references the variable itself
if (compilerOptions.noImplicitAny) {
if (noImplicitAny) {
error(symbol.valueDeclaration, Diagnostics._0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer,
symbolToString(symbol));
}
Expand Down Expand Up @@ -5592,7 +5594,7 @@ namespace ts {
}
if (!popTypeResolution()) {
type = anyType;
if (compilerOptions.noImplicitAny) {
if (noImplicitAny) {
const declaration = <Declaration>signature.declaration;
if (declaration.name) {
error(declaration.name, Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, declarationNameToString(declaration.name));
Expand Down Expand Up @@ -6552,7 +6554,7 @@ namespace ts {
return indexInfo.type;
}
if (accessExpression && !isConstEnumObjectType(objectType)) {
if (compilerOptions.noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors) {
if (noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors) {
if (getIndexTypeOfType(objectType, IndexKind.Number)) {
error(accessExpression.argumentExpression, Diagnostics.Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number);
}
Expand Down Expand Up @@ -9146,7 +9148,7 @@ namespace ts {
}

function reportErrorsFromWidening(declaration: Declaration, type: Type) {
if (produceDiagnostics && compilerOptions.noImplicitAny && type.flags & TypeFlags.ContainsWideningType) {
if (produceDiagnostics && noImplicitAny && type.flags & TypeFlags.ContainsWideningType) {
// Report implicit any error within type if possible, otherwise report error on declaration
if (!reportWideningErrorsInType(type)) {
reportImplicitAnyError(declaration, type);
Expand Down Expand Up @@ -11056,7 +11058,7 @@ namespace ts {
// control flow based type does include undefined.
if (type === autoType || type === autoArrayType) {
if (flowType === autoType || flowType === autoArrayType) {
if (compilerOptions.noImplicitAny) {
if (noImplicitAny) {
error(declaration.name, Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined, symbolToString(symbol), typeToString(flowType));
error(node, Diagnostics.Variable_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(flowType));
}
Expand Down Expand Up @@ -11326,7 +11328,7 @@ namespace ts {
}
}

if (compilerOptions.noImplicitThis) {
if (noImplicitThis) {
// With noImplicitThis, functions may not reference 'this' if it has type 'any'
error(node, Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation);
}
Expand Down Expand Up @@ -12599,7 +12601,7 @@ namespace ts {
return links.resolvedSymbol = unknownSymbol;
}
else {
if (compilerOptions.noImplicitAny) {
if (noImplicitAny) {
error(node, Diagnostics.JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists, JsxNames.IntrinsicElements);
}
return links.resolvedSymbol = unknownSymbol;
Expand Down Expand Up @@ -12987,7 +12989,7 @@ namespace ts {
}

if (jsxElementType === undefined) {
if (compilerOptions.noImplicitAny) {
if (noImplicitAny) {
error(errorNode, Diagnostics.JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist);
}
}
Expand Down Expand Up @@ -14810,7 +14812,7 @@ namespace ts {
if (funcSymbol && funcSymbol.members && funcSymbol.flags & SymbolFlags.Function) {
return getInferredClassType(funcSymbol);
}
else if (compilerOptions.noImplicitAny) {
else if (noImplicitAny) {
error(node, Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type);
}
return anyType;
Expand Down Expand Up @@ -15070,7 +15072,7 @@ namespace ts {
const iterableIteratorAny = functionFlags & FunctionFlags.Async
? createAsyncIterableIteratorType(anyType) // AsyncGenerator function
: createIterableIteratorType(anyType); // Generator function
if (compilerOptions.noImplicitAny) {
if (noImplicitAny) {
error(func.asteriskToken,
Diagnostics.Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type, typeToString(iterableIteratorAny));
}
Expand Down Expand Up @@ -16619,7 +16621,7 @@ namespace ts {

if (produceDiagnostics) {
checkCollisionWithArgumentsInGeneratedCode(node);
if (compilerOptions.noImplicitAny && !node.type) {
if (noImplicitAny && !node.type) {
switch (node.kind) {
case SyntaxKind.ConstructSignature:
error(node, Diagnostics.Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type);
Expand Down Expand Up @@ -17921,7 +17923,7 @@ namespace ts {
if (produceDiagnostics && !node.type) {
// Report an implicit any error if there is no body, no explicit return type, and node is not a private method
// in an ambient context
if (compilerOptions.noImplicitAny && nodeIsMissing(node.body) && !isPrivateWithinAmbient(node)) {
if (noImplicitAny && nodeIsMissing(node.body) && !isPrivateWithinAmbient(node)) {
reportImplicitAnyError(node, anyType);
}

Expand Down
7 changes: 6 additions & 1 deletion src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,11 @@ namespace ts {
type: "boolean",
description: Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file
},
{
name: "strict",
type: "boolean",
description: Diagnostics.Enable_all_strict_type_checks
},
{
// A list of plugins to load in the language service
name: "plugins",
Expand Down Expand Up @@ -520,7 +525,7 @@ namespace ts {
export const defaultInitCompilerOptions: CompilerOptions = {
module: ModuleKind.CommonJS,
target: ScriptTarget.ES5,
noImplicitAny: false,
strict: true,
sourceMap: false,
};

Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3045,6 +3045,10 @@
"category": "Message",
"code": 6149
},
"Enable all strict type checks.": {
"category": "Message",
"code": 6150
},
"Variable '{0}' implicitly has an '{1}' type.": {
"category": "Error",
"code": 7005
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1630,7 +1630,7 @@ namespace ts {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "lib", "noLib"));
}

if (options.noImplicitUseStrict && options.alwaysStrict) {
if (options.noImplicitUseStrict && (options.alwaysStrict === undefined ? options.strict : options.alwaysStrict)) {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noImplicitUseStrict", "alwaysStrict"));
}

Expand Down
3 changes: 2 additions & 1 deletion src/compiler/transformers/ts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,8 @@ namespace ts {
}

function visitSourceFile(node: SourceFile) {
const alwaysStrict = compilerOptions.alwaysStrict && !(isExternalModule(node) && moduleKind === ModuleKind.ES2015);
const alwaysStrict = (compilerOptions.alwaysStrict === undefined ? compilerOptions.strict : compilerOptions.alwaysStrict) &&
!(isExternalModule(node) && moduleKind === ModuleKind.ES2015);
return updateSourceFileNode(
node,
visitLexicalEnvironment(node.statements, sourceElementVisitor, context, /*start*/ 0, alwaysStrict));
Expand Down
9 changes: 5 additions & 4 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3309,7 +3309,7 @@
allowSyntheticDefaultImports?: boolean;
allowUnreachableCode?: boolean;
allowUnusedLabels?: boolean;
alwaysStrict?: boolean;
alwaysStrict?: boolean; // Always combine with strict property
baseUrl?: string;
charset?: string;
/* @internal */ configFilePath?: string;
Expand Down Expand Up @@ -3345,9 +3345,9 @@
noEmitOnError?: boolean;
noErrorTruncation?: boolean;
noFallthroughCasesInSwitch?: boolean;
noImplicitAny?: boolean;
noImplicitAny?: boolean; // Always combine with strict property
noImplicitReturns?: boolean;
noImplicitThis?: boolean;
noImplicitThis?: boolean; // Always combine with strict property
noUnusedLocals?: boolean;
noUnusedParameters?: boolean;
noImplicitUseStrict?: boolean;
Expand All @@ -3370,7 +3370,8 @@
skipDefaultLibCheck?: boolean;
sourceMap?: boolean;
sourceRoot?: string;
strictNullChecks?: boolean;
strict?: boolean;
strictNullChecks?: boolean; // Always combine with strict property
/* @internal */ stripInternal?: boolean;
suppressExcessPropertyErrors?: boolean;
suppressImplicitAnyIndexErrors?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"strict": true,
"sourceMap": false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"strict": true,
"sourceMap": false,
"noUnusedLocals": true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"strict": true,
"sourceMap": false,
"jsx": "react"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"strict": true,
"sourceMap": false
},
"files": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"strict": true,
"sourceMap": false,
"lib": [
"es5",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"strict": true,
"sourceMap": false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"strict": true,
"sourceMap": false,
"lib": [
"es5",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"strict": true,
"sourceMap": false,
"types": [
"jquery",
Expand Down

0 comments on commit f7242f3

Please sign in to comment.