Add new compiler flag to suppress noImplicitAny errors for object access

This commit is contained in:
Mohamed Hegazy 2014-12-09 14:08:44 -08:00
parent 0871801352
commit 0a1eabc9aa
10 changed files with 292 additions and 6 deletions

View file

@ -5385,7 +5385,7 @@ module ts {
}
// Fall back to any.
if (compilerOptions.noImplicitAny && objectType !== anyType) {
if (compilerOptions.noImplicitAny && (compilerOptions.suppress & ErrorGroup.ImplicitAnyIndex) === 0 && objectType !== anyType) {
error(node, Diagnostics.Index_signature_of_object_type_implicitly_has_an_any_type);
}

View file

@ -128,9 +128,16 @@ module ts {
name: "preserveConstEnums",
type: "boolean",
description: Diagnostics.Do_not_erase_const_enum_declarations_in_generated_code
}
},
{
name: "suppress",
type: { "implicitanyindex": ErrorGroup.ImplicitAnyIndex},
description: Diagnostics.Suppress_a_set_of_compiler_checks,
paramType: Diagnostics.ERRORGROUP,
error: Diagnostics.Argument_for_suppress_option_can_only_be_implicitAnyIndex
},
];
var shortOptionNames: Map<string> = {};
var optionNameMap: Map<CommandLineOption> = {};

View file

@ -398,6 +398,7 @@ module ts {
VERSION: { code: 6036, category: DiagnosticCategory.Message, key: "VERSION" },
LOCATION: { code: 6037, category: DiagnosticCategory.Message, key: "LOCATION" },
DIRECTORY: { code: 6038, category: DiagnosticCategory.Message, key: "DIRECTORY" },
ERRORGROUP: { code: 6039, category: DiagnosticCategory.Message, key: "ERRORGROUP" },
Compilation_complete_Watching_for_file_changes: { code: 6042, category: DiagnosticCategory.Message, key: "Compilation complete. Watching for file changes." },
Generates_corresponding_map_file: { code: 6043, category: DiagnosticCategory.Message, key: "Generates corresponding '.map' file." },
Compiler_option_0_expects_an_argument: { code: 6044, category: DiagnosticCategory.Error, key: "Compiler option '{0}' expects an argument." },
@ -411,6 +412,8 @@ module ts {
Warn_on_expressions_and_declarations_with_an_implied_any_type: { code: 6052, category: DiagnosticCategory.Message, key: "Warn on expressions and declarations with an implied 'any' type." },
File_0_not_found: { code: 6053, category: DiagnosticCategory.Error, key: "File '{0}' not found." },
File_0_must_have_extension_ts_or_d_ts: { code: 6054, category: DiagnosticCategory.Error, key: "File '{0}' must have extension '.ts' or '.d.ts'." },
Suppress_a_set_of_compiler_checks: { code: 6055, category: DiagnosticCategory.Message, key: "Suppress a set of compiler checks." },
Argument_for_suppress_option_can_only_be_implicitAnyIndex: { code: 6056, category: DiagnosticCategory.Error, key: "Argument for '--suppress' option can only be 'implicitAnyIndex'." },
Variable_0_implicitly_has_an_1_type: { code: 7005, category: DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." },
Parameter_0_implicitly_has_an_1_type: { code: 7006, category: DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." },
Member_0_implicitly_has_an_1_type: { code: 7008, category: DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." },

View file

@ -1591,6 +1591,10 @@
"category": "Message",
"code": 6038
},
"ERRORGROUP": {
"category": "Message",
"code": 6039
},
"Compilation complete. Watching for file changes.": {
"category": "Message",
"code": 6042
@ -1643,6 +1647,15 @@
"category": "Error",
"code": 6054
},
"Suppress a set of compiler checks.": {
"category": "Message",
"code": 6055
},
"Argument for '--suppress' option can only be 'implicitAnyIndex'.": {
"category": "Error",
"code": 6056
},
"Variable '{0}' implicitly has an '{1}' type.": {
"category": "Error",

View file

@ -27,7 +27,7 @@ module ts {
node.parserContextFlags |= ParserContextFlags.ContainsError;
}
// Also mark that we've propogated the child information to this node. This way we can
// Also mark that we've propagated the child information to this node. This way we can
// always consult the bit directly on this node without needing to check its children
// again.
node.parserContextFlags |= ParserContextFlags.HasPropagatedChildContainsErrorFlag;

View file

@ -1381,6 +1381,7 @@ module ts {
watch?: boolean;
preserveConstEnums?: boolean;
allowNonTsExtensions?: boolean;
suppress?: ErrorGroup;
[option: string]: string | number | boolean;
}
@ -1555,7 +1556,11 @@ module ts {
tab = 0x09, // \t
verticalTab = 0x0B, // \v
}
export const enum ErrorGroup {
ImplicitAnyIndex = 0x01
}
export interface CancellationToken {
isCancellationRequested(): boolean;
}

View file

@ -777,6 +777,16 @@ module Harness {
case 'preserveconstenums':
options.preserveConstEnums = setting.value === 'true';
break;
case 'suppress':
if (typeof setting.value === 'string' && setting.value.toLowerCase() === 'implicitanyindex') {
options.suppress = ts.ErrorGroup.ImplicitAnyIndex;
}
else {
throw new Error('Unkown value for suppress ' + setting.value);
}
break;
default:
throw new Error('Unsupported compiler setting ' + setting.flag);
}
@ -1162,7 +1172,7 @@ module Harness {
var optionRegex = /^[\/]{2}\s*@(\w+)\s*:\s*(\S*)/gm; // multiple matches on multiple lines
// List of allowed metadata names
var fileMetadataNames = ["filename", "comments", "declaration", "module", "nolib", "sourcemap", "target", "out", "outdir", "noemitonerror","noimplicitany", "noresolve", "newline", "newlines", "emitbom", "errortruncation", "usecasesensitivefilenames", "preserveconstenums"];
var fileMetadataNames = ["filename", "comments", "declaration", "module", "nolib", "sourcemap", "target", "out", "outdir", "noemitonerror", "noimplicitany", "noresolve", "newline", "newlines", "emitbom", "errortruncation", "usecasesensitivefilenames", "preserveconstenums", "suppress"];
function extractCompilerSettings(content: string): CompilerSetting[] {

View file

@ -0,0 +1,81 @@
//// [noImplicitAnyIndexingSuppressed.ts]
enum MyEmusEnum {
emu
}
// Should be okay; should be a string.
var strRepresentation1 = MyEmusEnum[0]
// Should be okay; should be a string.
var strRepresentation2 = MyEmusEnum[MyEmusEnum.emu]
// Should be okay, as we suppress implicit 'any' property access checks
var strRepresentation3 = MyEmusEnum["monehh"];
// Should be okay; should be a MyEmusEnum
var strRepresentation4 = MyEmusEnum["emu"];
// Should be okay, as we suppress implicit 'any' property access checks
var x = {}["hi"];
// Should be okay, as we suppress implicit 'any' property access checks
var y = {}[10];
var hi: any = "hi";
var emptyObj = {};
// Should be okay, as we suppress implicit 'any' property access checks
var z1 = emptyObj[hi];
var z2 = (<any>emptyObj)[hi];
interface MyMap<T> {
[key: string]: T;
}
var m: MyMap<number> = {
"0": 0,
"1": 1,
"2": 2,
"Okay that's enough for today.": NaN
};
var mResult1 = m[MyEmusEnum.emu];
var mResult2 = m[MyEmusEnum[MyEmusEnum.emu]];
var mResult3 = m[hi];
//// [noImplicitAnyIndexingSuppressed.js]
var MyEmusEnum;
(function (MyEmusEnum) {
MyEmusEnum[MyEmusEnum["emu"] = 0] = "emu";
})(MyEmusEnum || (MyEmusEnum = {}));
// Should be okay; should be a string.
var strRepresentation1 = MyEmusEnum[0];
// Should be okay; should be a string.
var strRepresentation2 = MyEmusEnum[0 /* emu */];
// Should be okay, as we suppress implicit 'any' property access checks
var strRepresentation3 = MyEmusEnum["monehh"];
// Should be okay; should be a MyEmusEnum
var strRepresentation4 = 0 /* "emu" */;
// Should be okay, as we suppress implicit 'any' property access checks
var x = {}["hi"];
// Should be okay, as we suppress implicit 'any' property access checks
var y = {}[10];
var hi = "hi";
var emptyObj = {};
// Should be okay, as we suppress implicit 'any' property access checks
var z1 = emptyObj[hi];
var z2 = emptyObj[hi];
var m = {
"0": 0,
"1": 1,
"2": 2,
"Okay that's enough for today.": NaN
};
var mResult1 = m[0 /* emu */];
var mResult2 = m[MyEmusEnum[0 /* emu */]];
var mResult3 = m[hi];

View file

@ -0,0 +1,118 @@
=== tests/cases/compiler/noImplicitAnyIndexingSuppressed.ts ===
enum MyEmusEnum {
>MyEmusEnum : MyEmusEnum
emu
>emu : MyEmusEnum
}
// Should be okay; should be a string.
var strRepresentation1 = MyEmusEnum[0]
>strRepresentation1 : string
>MyEmusEnum[0] : string
>MyEmusEnum : typeof MyEmusEnum
// Should be okay; should be a string.
var strRepresentation2 = MyEmusEnum[MyEmusEnum.emu]
>strRepresentation2 : string
>MyEmusEnum[MyEmusEnum.emu] : string
>MyEmusEnum : typeof MyEmusEnum
>MyEmusEnum.emu : MyEmusEnum
>MyEmusEnum : typeof MyEmusEnum
>emu : MyEmusEnum
// Should be okay, as we suppress implicit 'any' property access checks
var strRepresentation3 = MyEmusEnum["monehh"];
>strRepresentation3 : any
>MyEmusEnum["monehh"] : any
>MyEmusEnum : typeof MyEmusEnum
// Should be okay; should be a MyEmusEnum
var strRepresentation4 = MyEmusEnum["emu"];
>strRepresentation4 : MyEmusEnum
>MyEmusEnum["emu"] : MyEmusEnum
>MyEmusEnum : typeof MyEmusEnum
// Should be okay, as we suppress implicit 'any' property access checks
var x = {}["hi"];
>x : any
>{}["hi"] : any
>{} : {}
// Should be okay, as we suppress implicit 'any' property access checks
var y = {}[10];
>y : any
>{}[10] : any
>{} : {}
var hi: any = "hi";
>hi : any
var emptyObj = {};
>emptyObj : {}
>{} : {}
// Should be okay, as we suppress implicit 'any' property access checks
var z1 = emptyObj[hi];
>z1 : any
>emptyObj[hi] : any
>emptyObj : {}
>hi : any
var z2 = (<any>emptyObj)[hi];
>z2 : any
>(<any>emptyObj)[hi] : any
>(<any>emptyObj) : any
><any>emptyObj : any
>emptyObj : {}
>hi : any
interface MyMap<T> {
>MyMap : MyMap<T>
>T : T
[key: string]: T;
>key : string
>T : T
}
var m: MyMap<number> = {
>m : MyMap<number>
>MyMap : MyMap<T>
>{ "0": 0, "1": 1, "2": 2, "Okay that's enough for today.": NaN} : { [x: string]: number; "0": number; "1": number; "2": number; "Okay that's enough for today.": number; }
"0": 0,
"1": 1,
"2": 2,
"Okay that's enough for today.": NaN
>NaN : number
};
var mResult1 = m[MyEmusEnum.emu];
>mResult1 : number
>m[MyEmusEnum.emu] : number
>m : MyMap<number>
>MyEmusEnum.emu : MyEmusEnum
>MyEmusEnum : typeof MyEmusEnum
>emu : MyEmusEnum
var mResult2 = m[MyEmusEnum[MyEmusEnum.emu]];
>mResult2 : number
>m[MyEmusEnum[MyEmusEnum.emu]] : number
>m : MyMap<number>
>MyEmusEnum[MyEmusEnum.emu] : string
>MyEmusEnum : typeof MyEmusEnum
>MyEmusEnum.emu : MyEmusEnum
>MyEmusEnum : typeof MyEmusEnum
>emu : MyEmusEnum
var mResult3 = m[hi];
>mResult3 : number
>m[hi] : number
>m : MyMap<number>
>hi : any

View file

@ -0,0 +1,49 @@
//@noImplicitAny: true
//@suppress: implicitAnyIndex
enum MyEmusEnum {
emu
}
// Should be okay; should be a string.
var strRepresentation1 = MyEmusEnum[0]
// Should be okay; should be a string.
var strRepresentation2 = MyEmusEnum[MyEmusEnum.emu]
// Should be okay, as we suppress implicit 'any' property access checks
var strRepresentation3 = MyEmusEnum["monehh"];
// Should be okay; should be a MyEmusEnum
var strRepresentation4 = MyEmusEnum["emu"];
// Should be okay, as we suppress implicit 'any' property access checks
var x = {}["hi"];
// Should be okay, as we suppress implicit 'any' property access checks
var y = {}[10];
var hi: any = "hi";
var emptyObj = {};
// Should be okay, as we suppress implicit 'any' property access checks
var z1 = emptyObj[hi];
var z2 = (<any>emptyObj)[hi];
interface MyMap<T> {
[key: string]: T;
}
var m: MyMap<number> = {
"0": 0,
"1": 1,
"2": 2,
"Okay that's enough for today.": NaN
};
var mResult1 = m[MyEmusEnum.emu];
var mResult2 = m[MyEmusEnum[MyEmusEnum.emu]];
var mResult3 = m[hi];