From 456a6bf658b25d559d3eadc9e9ea04aaa5faf7f4 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Sat, 3 Jun 2017 00:10:41 +0200 Subject: [PATCH 001/235] program.getSourceFile[ByPath] can return undefined --- src/compiler/program.ts | 4 ++-- src/compiler/types.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 834122b3584..d481e72b689 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -969,11 +969,11 @@ namespace ts { return emitResult; } - function getSourceFile(fileName: string): SourceFile { + function getSourceFile(fileName: string): SourceFile | undefined { return getSourceFileByPath(toPath(fileName, currentDirectory, getCanonicalFileName)); } - function getSourceFileByPath(path: Path): SourceFile { + function getSourceFileByPath(path: Path): SourceFile | undefined { return filesByName.get(path); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ed1d5dcbe23..da438809d92 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2352,8 +2352,8 @@ namespace ts { export interface ScriptReferenceHost { getCompilerOptions(): CompilerOptions; - getSourceFile(fileName: string): SourceFile; - getSourceFileByPath(path: Path): SourceFile; + getSourceFile(fileName: string): SourceFile | undefined; + getSourceFileByPath(path: Path): SourceFile | undefined; getCurrentDirectory(): string; } From 1f77317b6459641212efcf3fd6b9b6aa005ba968 Mon Sep 17 00:00:00 2001 From: Tycho Grouwstra Date: Sun, 13 Aug 2017 15:12:11 +0800 Subject: [PATCH 002/235] add strictTuples flag giving tuples known length --- src/compiler/checker.ts | 7 +++ src/compiler/commandLineParser.ts | 7 +++ src/compiler/diagnosticMessages.json | 4 ++ src/compiler/types.ts | 1 + .../unittests/configurationExtension.ts | 6 +++ src/harness/unittests/transpile.ts | 4 ++ src/server/protocol.ts | 1 + .../baselines/reference/genericTypeAliases.js | 4 +- .../reference/genericTypeAliases.symbols | 32 ++++++------- .../reference/genericTypeAliases.types | 12 ++--- .../nominalSubtypeCheckOfTypeParameter.js | 10 ++-- ...nominalSubtypeCheckOfTypeParameter.symbols | 46 +++++++++---------- .../nominalSubtypeCheckOfTypeParameter.types | 20 ++++---- .../Supports setting strictTuples.js | 2 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../reference/tupleLength.errors.txt | 26 +++++++++++ tests/baselines/reference/tupleLength.js | 32 +++++++++++++ tests/cases/compiler/tupleLength.ts | 18 ++++++++ .../types/typeAliases/genericTypeAliases.ts | 4 +- .../nominalSubtypeCheckOfTypeParameter.ts | 10 ++-- 27 files changed, 185 insertions(+), 69 deletions(-) create mode 100644 tests/baselines/reference/transpile/Supports setting strictTuples.js create mode 100644 tests/baselines/reference/tupleLength.errors.txt create mode 100644 tests/baselines/reference/tupleLength.js create mode 100644 tests/cases/compiler/tupleLength.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 90328770750..d533f5f82fb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -64,6 +64,7 @@ namespace ts { const noUnusedIdentifiers = !!compilerOptions.noUnusedLocals || !!compilerOptions.noUnusedParameters; const allowSyntheticDefaultImports = typeof compilerOptions.allowSyntheticDefaultImports !== "undefined" ? compilerOptions.allowSyntheticDefaultImports : modulekind === ModuleKind.System; const strictNullChecks = compilerOptions.strictNullChecks === undefined ? compilerOptions.strict : compilerOptions.strictNullChecks; + const strictTuples = compilerOptions.strictTuples === undefined ? compilerOptions.strict : compilerOptions.strictTuples; const noImplicitAny = compilerOptions.noImplicitAny === undefined ? compilerOptions.strict : compilerOptions.noImplicitAny; const noImplicitThis = compilerOptions.noImplicitThis === undefined ? compilerOptions.strict : compilerOptions.noImplicitThis; @@ -7161,6 +7162,12 @@ namespace ts { property.type = typeParameter; properties.push(property); } + if (strictTuples) { + const lengthSymbol = createSymbol(SymbolFlags.Property, "length" as __String); + lengthSymbol.type = getLiteralType(arity); + lengthSymbol.checkFlags = CheckFlags.Readonly; + properties.push(lengthSymbol); + } const type = createObjectType(ObjectFlags.Tuple | ObjectFlags.Reference); type.typeParameters = typeParameters; type.outerTypeParameters = undefined; diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index c92d147f9a9..f6baca68647 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -269,6 +269,13 @@ namespace ts { category: Diagnostics.Strict_Type_Checking_Options, description: Diagnostics.Enable_strict_null_checks }, + { + name: "strictTuples", + type: "boolean", + showInSimplifiedHelpView: true, + category: Diagnostics.Strict_Type_Checking_Options, + description: Diagnostics.Enable_strict_tuple_checks + }, { name: "noImplicitThis", type: "boolean", diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 77e7f7e7b62..bda14f2c9ce 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3302,6 +3302,10 @@ "category": "Message", "code": 6185 }, + "Enable strict tuple checks.": { + "category": "Message", + "code": 6187 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", "code": 7005 diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0a09bb5b6ec..bc06d247f2c 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3622,6 +3622,7 @@ namespace ts { sourceRoot?: string; strict?: boolean; strictNullChecks?: boolean; // Always combine with strict property + strictTuples?: boolean; /* @internal */ stripInternal?: boolean; suppressExcessPropertyErrors?: boolean; suppressImplicitAnyIndexErrors?: boolean; diff --git a/src/harness/unittests/configurationExtension.ts b/src/harness/unittests/configurationExtension.ts index 2d50d2cb2af..776feb535c5 100644 --- a/src/harness/unittests/configurationExtension.ts +++ b/src/harness/unittests/configurationExtension.ts @@ -16,6 +16,12 @@ namespace ts { strictNullChecks: false } }, + "/dev/tsconfig.strictTuples.json": { + extends: "./tsconfig", + compilerOptions: { + strictTuples: false + } + }, "/dev/configs/base.json": { compilerOptions: { allowJs: true, diff --git a/src/harness/unittests/transpile.ts b/src/harness/unittests/transpile.ts index e0c96797827..f727fff5594 100644 --- a/src/harness/unittests/transpile.ts +++ b/src/harness/unittests/transpile.ts @@ -413,6 +413,10 @@ var x = 0;`, { options: { compilerOptions: { strictNullChecks: true }, fileName: "input.js", reportDiagnostics: true } }); + transpilesCorrectly("Supports setting 'strictTuples'", "x;", { + options: { compilerOptions: { strictTuples: true }, fileName: "input.js", reportDiagnostics: true } + }); + transpilesCorrectly("Supports setting 'stripInternal'", "x;", { options: { compilerOptions: { stripInternal: true }, fileName: "input.js", reportDiagnostics: true } }); diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 0b7405c7b69..b5c959b484f 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -2448,6 +2448,7 @@ namespace ts.server.protocol { sourceRoot?: string; strict?: boolean; strictNullChecks?: boolean; + strictTuples?: boolean; suppressExcessPropertyErrors?: boolean; suppressImplicitAnyIndexErrors?: boolean; target?: ScriptTarget | ts.ScriptTarget; diff --git a/tests/baselines/reference/genericTypeAliases.js b/tests/baselines/reference/genericTypeAliases.js index 8218f5c886c..282fd9868a9 100644 --- a/tests/baselines/reference/genericTypeAliases.js +++ b/tests/baselines/reference/genericTypeAliases.js @@ -40,12 +40,12 @@ type Strange = string; // Type parameter not used var s: Strange; s = "hello"; -interface Tuple { +interface AB { a: A; b: B; } -type Pair = Tuple; +type Pair = AB; interface TaggedPair extends Pair { tag: string; diff --git a/tests/baselines/reference/genericTypeAliases.symbols b/tests/baselines/reference/genericTypeAliases.symbols index d5f68ec0615..521afe800b3 100644 --- a/tests/baselines/reference/genericTypeAliases.symbols +++ b/tests/baselines/reference/genericTypeAliases.symbols @@ -124,29 +124,29 @@ var s: Strange; s = "hello"; >s : Symbol(s, Decl(genericTypeAliases.ts, 38, 3)) -interface Tuple { ->Tuple : Symbol(Tuple, Decl(genericTypeAliases.ts, 39, 12)) ->A : Symbol(A, Decl(genericTypeAliases.ts, 41, 16)) ->B : Symbol(B, Decl(genericTypeAliases.ts, 41, 18)) +interface AB { +>AB : Symbol(AB, Decl(genericTypeAliases.ts, 39, 12)) +>A : Symbol(A, Decl(genericTypeAliases.ts, 41, 13)) +>B : Symbol(B, Decl(genericTypeAliases.ts, 41, 15)) a: A; ->a : Symbol(Tuple.a, Decl(genericTypeAliases.ts, 41, 23)) ->A : Symbol(A, Decl(genericTypeAliases.ts, 41, 16)) +>a : Symbol(AB.a, Decl(genericTypeAliases.ts, 41, 20)) +>A : Symbol(A, Decl(genericTypeAliases.ts, 41, 13)) b: B; ->b : Symbol(Tuple.b, Decl(genericTypeAliases.ts, 42, 9)) ->B : Symbol(B, Decl(genericTypeAliases.ts, 41, 18)) +>b : Symbol(AB.b, Decl(genericTypeAliases.ts, 42, 9)) +>B : Symbol(B, Decl(genericTypeAliases.ts, 41, 15)) } -type Pair = Tuple; +type Pair = AB; >Pair : Symbol(Pair, Decl(genericTypeAliases.ts, 44, 1)) >T : Symbol(T, Decl(genericTypeAliases.ts, 46, 10)) ->Tuple : Symbol(Tuple, Decl(genericTypeAliases.ts, 39, 12)) +>AB : Symbol(AB, Decl(genericTypeAliases.ts, 39, 12)) >T : Symbol(T, Decl(genericTypeAliases.ts, 46, 10)) >T : Symbol(T, Decl(genericTypeAliases.ts, 46, 10)) interface TaggedPair extends Pair { ->TaggedPair : Symbol(TaggedPair, Decl(genericTypeAliases.ts, 46, 27)) +>TaggedPair : Symbol(TaggedPair, Decl(genericTypeAliases.ts, 46, 24)) >T : Symbol(T, Decl(genericTypeAliases.ts, 48, 21)) >Pair : Symbol(Pair, Decl(genericTypeAliases.ts, 44, 1)) >T : Symbol(T, Decl(genericTypeAliases.ts, 48, 21)) @@ -157,17 +157,17 @@ interface TaggedPair extends Pair { var p: TaggedPair; >p : Symbol(p, Decl(genericTypeAliases.ts, 52, 3)) ->TaggedPair : Symbol(TaggedPair, Decl(genericTypeAliases.ts, 46, 27)) +>TaggedPair : Symbol(TaggedPair, Decl(genericTypeAliases.ts, 46, 24)) p.a = 1; ->p.a : Symbol(Tuple.a, Decl(genericTypeAliases.ts, 41, 23)) +>p.a : Symbol(AB.a, Decl(genericTypeAliases.ts, 41, 20)) >p : Symbol(p, Decl(genericTypeAliases.ts, 52, 3)) ->a : Symbol(Tuple.a, Decl(genericTypeAliases.ts, 41, 23)) +>a : Symbol(AB.a, Decl(genericTypeAliases.ts, 41, 20)) p.b = 2; ->p.b : Symbol(Tuple.b, Decl(genericTypeAliases.ts, 42, 9)) +>p.b : Symbol(AB.b, Decl(genericTypeAliases.ts, 42, 9)) >p : Symbol(p, Decl(genericTypeAliases.ts, 52, 3)) ->b : Symbol(Tuple.b, Decl(genericTypeAliases.ts, 42, 9)) +>b : Symbol(AB.b, Decl(genericTypeAliases.ts, 42, 9)) p.tag = "test"; >p.tag : Symbol(TaggedPair.tag, Decl(genericTypeAliases.ts, 48, 41)) diff --git a/tests/baselines/reference/genericTypeAliases.types b/tests/baselines/reference/genericTypeAliases.types index b4c75841245..722347b0f72 100644 --- a/tests/baselines/reference/genericTypeAliases.types +++ b/tests/baselines/reference/genericTypeAliases.types @@ -158,8 +158,8 @@ s = "hello"; >s : string >"hello" : "hello" -interface Tuple { ->Tuple : Tuple +interface AB { +>AB : AB >A : A >B : B @@ -172,17 +172,17 @@ interface Tuple { >B : B } -type Pair = Tuple; ->Pair : Tuple +type Pair = AB; +>Pair : AB >T : T ->Tuple : Tuple +>AB : AB >T : T >T : T interface TaggedPair extends Pair { >TaggedPair : TaggedPair >T : T ->Pair : Tuple +>Pair : AB >T : T tag: string; diff --git a/tests/baselines/reference/nominalSubtypeCheckOfTypeParameter.js b/tests/baselines/reference/nominalSubtypeCheckOfTypeParameter.js index 3259b3287fa..5712fb7c244 100644 --- a/tests/baselines/reference/nominalSubtypeCheckOfTypeParameter.js +++ b/tests/baselines/reference/nominalSubtypeCheckOfTypeParameter.js @@ -1,20 +1,20 @@ //// [nominalSubtypeCheckOfTypeParameter.ts] -interface Tuple { +interface BinaryTuple { first: T - second: S + second: S } interface Sequence { hasNext(): boolean - pop(): T - zip(seq: Sequence): Sequence> + pop(): T + zip(seq: Sequence): Sequence> } // error, despite the fact that the code explicitly says List extends Sequence, the current rules for infinitely expanding type references // perform nominal subtyping checks that allow variance for type arguments, but not nominal subtyping for the generic type itself interface List extends Sequence { getLength(): number - zip(seq: Sequence): List> + zip(seq: Sequence): List> } diff --git a/tests/baselines/reference/nominalSubtypeCheckOfTypeParameter.symbols b/tests/baselines/reference/nominalSubtypeCheckOfTypeParameter.symbols index c7d9a1b50f4..3d24b82aa8f 100644 --- a/tests/baselines/reference/nominalSubtypeCheckOfTypeParameter.symbols +++ b/tests/baselines/reference/nominalSubtypeCheckOfTypeParameter.symbols @@ -1,16 +1,16 @@ === tests/cases/conformance/types/typeRelationships/recursiveTypes/nominalSubtypeCheckOfTypeParameter.ts === -interface Tuple { ->Tuple : Symbol(Tuple, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 0)) ->T : Symbol(T, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 16)) ->S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 18)) +interface BinaryTuple { +>BinaryTuple : Symbol(BinaryTuple, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 0)) +>T : Symbol(T, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 22)) +>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 24)) first: T ->first : Symbol(Tuple.first, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 23)) ->T : Symbol(T, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 16)) +>first : Symbol(BinaryTuple.first, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 29)) +>T : Symbol(T, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 22)) - second: S ->second : Symbol(Tuple.second, Decl(nominalSubtypeCheckOfTypeParameter.ts, 1, 12)) ->S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 18)) + second: S +>second : Symbol(BinaryTuple.second, Decl(nominalSubtypeCheckOfTypeParameter.ts, 1, 12)) +>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 24)) } interface Sequence { @@ -20,20 +20,20 @@ interface Sequence { hasNext(): boolean >hasNext : Symbol(Sequence.hasNext, Decl(nominalSubtypeCheckOfTypeParameter.ts, 5, 23)) - pop(): T + pop(): T >pop : Symbol(Sequence.pop, Decl(nominalSubtypeCheckOfTypeParameter.ts, 6, 22)) >T : Symbol(T, Decl(nominalSubtypeCheckOfTypeParameter.ts, 5, 19)) - zip(seq: Sequence): Sequence> ->zip : Symbol(Sequence.zip, Decl(nominalSubtypeCheckOfTypeParameter.ts, 7, 14)) ->S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 8, 10)) ->seq : Symbol(seq, Decl(nominalSubtypeCheckOfTypeParameter.ts, 8, 13)) + zip(seq: Sequence): Sequence> +>zip : Symbol(Sequence.zip, Decl(nominalSubtypeCheckOfTypeParameter.ts, 7, 12)) +>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 8, 8)) +>seq : Symbol(seq, Decl(nominalSubtypeCheckOfTypeParameter.ts, 8, 11)) >Sequence : Symbol(Sequence, Decl(nominalSubtypeCheckOfTypeParameter.ts, 3, 1)) ->S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 8, 10)) +>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 8, 8)) >Sequence : Symbol(Sequence, Decl(nominalSubtypeCheckOfTypeParameter.ts, 3, 1)) ->Tuple : Symbol(Tuple, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 0)) +>BinaryTuple : Symbol(BinaryTuple, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 0)) >T : Symbol(T, Decl(nominalSubtypeCheckOfTypeParameter.ts, 5, 19)) ->S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 8, 10)) +>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 8, 8)) } // error, despite the fact that the code explicitly says List extends Sequence, the current rules for infinitely expanding type references @@ -47,15 +47,15 @@ interface List extends Sequence { getLength(): number >getLength : Symbol(List.getLength, Decl(nominalSubtypeCheckOfTypeParameter.ts, 13, 39)) - zip(seq: Sequence): List> + zip(seq: Sequence): List> >zip : Symbol(List.zip, Decl(nominalSubtypeCheckOfTypeParameter.ts, 14, 23)) ->S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 15, 10)) ->seq : Symbol(seq, Decl(nominalSubtypeCheckOfTypeParameter.ts, 15, 13)) +>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 15, 8)) +>seq : Symbol(seq, Decl(nominalSubtypeCheckOfTypeParameter.ts, 15, 11)) >Sequence : Symbol(Sequence, Decl(nominalSubtypeCheckOfTypeParameter.ts, 3, 1)) ->S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 15, 10)) +>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 15, 8)) >List : Symbol(List, Decl(nominalSubtypeCheckOfTypeParameter.ts, 9, 1)) ->Tuple : Symbol(Tuple, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 0)) +>BinaryTuple : Symbol(BinaryTuple, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 0)) >T : Symbol(T, Decl(nominalSubtypeCheckOfTypeParameter.ts, 13, 15)) ->S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 15, 10)) +>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 15, 8)) } diff --git a/tests/baselines/reference/nominalSubtypeCheckOfTypeParameter.types b/tests/baselines/reference/nominalSubtypeCheckOfTypeParameter.types index 79b2ac77d78..5da84d0c8a4 100644 --- a/tests/baselines/reference/nominalSubtypeCheckOfTypeParameter.types +++ b/tests/baselines/reference/nominalSubtypeCheckOfTypeParameter.types @@ -1,6 +1,6 @@ === tests/cases/conformance/types/typeRelationships/recursiveTypes/nominalSubtypeCheckOfTypeParameter.ts === -interface Tuple { ->Tuple : Tuple +interface BinaryTuple { +>BinaryTuple : BinaryTuple >T : T >S : S @@ -8,7 +8,7 @@ interface Tuple { >first : T >T : T - second: S + second: S >second : S >S : S } @@ -20,18 +20,18 @@ interface Sequence { hasNext(): boolean >hasNext : () => boolean - pop(): T + pop(): T >pop : () => T >T : T - zip(seq: Sequence): Sequence> ->zip : (seq: Sequence) => Sequence> + zip(seq: Sequence): Sequence> +>zip : (seq: Sequence) => Sequence> >S : S >seq : Sequence >Sequence : Sequence >S : S >Sequence : Sequence ->Tuple : Tuple +>BinaryTuple : BinaryTuple >T : T >S : S } @@ -47,14 +47,14 @@ interface List extends Sequence { getLength(): number >getLength : () => number - zip(seq: Sequence): List> ->zip : (seq: Sequence) => List> + zip(seq: Sequence): List> +>zip : (seq: Sequence) => List> >S : S >seq : Sequence >Sequence : Sequence >S : S >List : List ->Tuple : Tuple +>BinaryTuple : BinaryTuple >T : T >S : S } diff --git a/tests/baselines/reference/transpile/Supports setting strictTuples.js b/tests/baselines/reference/transpile/Supports setting strictTuples.js new file mode 100644 index 00000000000..8394371f908 --- /dev/null +++ b/tests/baselines/reference/transpile/Supports setting strictTuples.js @@ -0,0 +1,2 @@ +x; +//# sourceMappingURL=input.js.map \ No newline at end of file diff --git a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json index 0f5b2378468..5218d687724 100644 --- a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json @@ -22,6 +22,7 @@ "strict": true /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictTuples": true, /* Enable strict tuple checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json index a545124a723..4fc67f07f0e 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json @@ -22,6 +22,7 @@ "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictTuples": true, /* Enable strict tuple checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json index b53ac2d8552..cd190298fd8 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json @@ -22,6 +22,7 @@ "strict": true /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictTuples": true, /* Enable strict tuple checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json index 4e06e06d159..278322852f8 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json @@ -22,6 +22,7 @@ "strict": true /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictTuples": true, /* Enable strict tuple checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json index 94808d89ed0..c81634bccea 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json @@ -22,6 +22,7 @@ "strict": true /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictTuples": true, /* Enable strict tuple checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json index 0f5b2378468..5218d687724 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json @@ -22,6 +22,7 @@ "strict": true /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictTuples": true, /* Enable strict tuple checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json index d165b0f2775..0b34f4724f8 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json @@ -22,6 +22,7 @@ "strict": true /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictTuples": true, /* Enable strict tuple checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json index 2a169b3aaaf..9a63db2069b 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json @@ -22,6 +22,7 @@ "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictTuples": true, /* Enable strict tuple checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tupleLength.errors.txt b/tests/baselines/reference/tupleLength.errors.txt new file mode 100644 index 00000000000..c68bd652c85 --- /dev/null +++ b/tests/baselines/reference/tupleLength.errors.txt @@ -0,0 +1,26 @@ +tests/cases/compiler/tupleLength.ts(11,5): error TS2403: Subsequent variable declarations must have the same type. Variable 't1' must be of type '[number]', but here has type '[number, number]'. +tests/cases/compiler/tupleLength.ts(12,5): error TS2403: Subsequent variable declarations must have the same type. Variable 't2' must be of type '[number, number]', but here has type '[number]'. + + +==== tests/cases/compiler/tupleLength.ts (2 errors) ==== + // var t0: []; + var t1: [number]; + var t2: [number, number]; + var arr: number[]; + + // var len0: 0 = t0.length; + var len1: 1 = t1.length; + var len2: 2 = t2.length; + var lena: number = arr.length; + + var t1 = t2; // error + ~~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 't1' must be of type '[number]', but here has type '[number, number]'. + var t2 = t1; // error + ~~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 't2' must be of type '[number, number]', but here has type '[number]'. + + type A = T['length']; + var b: A<[boolean]>; + var c: 1 = b; + \ No newline at end of file diff --git a/tests/baselines/reference/tupleLength.js b/tests/baselines/reference/tupleLength.js new file mode 100644 index 00000000000..3893305421b --- /dev/null +++ b/tests/baselines/reference/tupleLength.js @@ -0,0 +1,32 @@ +//// [tupleLength.ts] +// var t0: []; +var t1: [number]; +var t2: [number, number]; +var arr: number[]; + +// var len0: 0 = t0.length; +var len1: 1 = t1.length; +var len2: 2 = t2.length; +var lena: number = arr.length; + +var t1 = t2; // error +var t2 = t1; // error + +type A = T['length']; +var b: A<[boolean]>; +var c: 1 = b; + + +//// [tupleLength.js] +// var t0: []; +var t1; +var t2; +var arr; +// var len0: 0 = t0.length; +var len1 = t1.length; +var len2 = t2.length; +var lena = arr.length; +var t1 = t2; // error +var t2 = t1; // error +var b; +var c = b; diff --git a/tests/cases/compiler/tupleLength.ts b/tests/cases/compiler/tupleLength.ts new file mode 100644 index 00000000000..3c6db1a034a --- /dev/null +++ b/tests/cases/compiler/tupleLength.ts @@ -0,0 +1,18 @@ +// @strictTuples: true + +// var t0: []; +var t1: [number]; +var t2: [number, number]; +var arr: number[]; + +// var len0: 0 = t0.length; +var len1: 1 = t1.length; +var len2: 2 = t2.length; +var lena: number = arr.length; + +var t1 = t2; // error +var t2 = t1; // error + +type A = T['length']; +var b: A<[boolean]>; +var c: 1 = b; diff --git a/tests/cases/conformance/types/typeAliases/genericTypeAliases.ts b/tests/cases/conformance/types/typeAliases/genericTypeAliases.ts index e26279a8a41..8c8ab3291fa 100644 --- a/tests/cases/conformance/types/typeAliases/genericTypeAliases.ts +++ b/tests/cases/conformance/types/typeAliases/genericTypeAliases.ts @@ -39,12 +39,12 @@ type Strange = string; // Type parameter not used var s: Strange; s = "hello"; -interface Tuple { +interface AB { a: A; b: B; } -type Pair = Tuple; +type Pair = AB; interface TaggedPair extends Pair { tag: string; diff --git a/tests/cases/conformance/types/typeRelationships/recursiveTypes/nominalSubtypeCheckOfTypeParameter.ts b/tests/cases/conformance/types/typeRelationships/recursiveTypes/nominalSubtypeCheckOfTypeParameter.ts index ed8d724300d..ea16201ae91 100644 --- a/tests/cases/conformance/types/typeRelationships/recursiveTypes/nominalSubtypeCheckOfTypeParameter.ts +++ b/tests/cases/conformance/types/typeRelationships/recursiveTypes/nominalSubtypeCheckOfTypeParameter.ts @@ -1,17 +1,17 @@ -interface Tuple { +interface BinaryTuple { first: T - second: S + second: S } interface Sequence { hasNext(): boolean - pop(): T - zip(seq: Sequence): Sequence> + pop(): T + zip(seq: Sequence): Sequence> } // error, despite the fact that the code explicitly says List extends Sequence, the current rules for infinitely expanding type references // perform nominal subtyping checks that allow variance for type arguments, but not nominal subtyping for the generic type itself interface List extends Sequence { getLength(): number - zip(seq: Sequence): List> + zip(seq: Sequence): List> } From ff0961b85e33f6dd6f876df5c5ed2777ea309bde Mon Sep 17 00:00:00 2001 From: Yuval Greenfield Date: Fri, 8 Sep 2017 15:02:59 -0700 Subject: [PATCH 003/235] Remove trailing space from emitLeadingComment This will prevent emiting an extraneous trailing space on comments to match https://eslint.org/docs/rules/no-trailing-spaces This also removes a space that may have been originally there after a comment but isn't necessary syntactically. --- src/compiler/comments.ts | 3 --- .../baselines/reference/ambientDeclarationsExternal.js | 2 +- tests/baselines/reference/anyAssignableToEveryType.js | 2 +- tests/baselines/reference/augmentedTypesClass3.js | 2 +- tests/baselines/reference/augmentedTypesEnum.js | 2 +- tests/baselines/reference/augmentedTypesEnum2.js | 2 +- tests/baselines/reference/augmentedTypesFunction.js | 2 +- tests/baselines/reference/augmentedTypesInterface.js | 2 +- .../reference/baseIndexSignatureResolution.js | 2 +- tests/baselines/reference/commentEmitAtEndOfFile1.js | 2 +- .../reference/commentEmitWithCommentOnLastLine.js | 2 +- tests/baselines/reference/commentOnArrayElement1.js | 2 +- tests/baselines/reference/commentOnArrayElement3.js | 4 ++-- tests/baselines/reference/commentOnBlock1.js | 2 +- .../reference/commentsArgumentsOfCallExpression1.js | 2 +- .../reference/commentsArgumentsOfCallExpression2.js | 6 +++--- tests/baselines/reference/commentsCommentParsing.js | 10 +++++----- tests/baselines/reference/commentsFunction.js | 4 ++-- .../reference/commentsOnPropertyOfObjectLiteral1.js | 2 +- ...mparisonOperatorWithSubtypeObjectOnCallSignature.js | 2 +- ...nOperatorWithSubtypeObjectOnConstructorSignature.js | 2 +- ...atorWithSubtypeObjectOnInstantiatedCallSignature.js | 2 +- ...hSubtypeObjectOnInstantiatedConstructorSignature.js | 2 +- tests/baselines/reference/concatError.js | 2 +- tests/baselines/reference/errorSupression1.js | 2 +- tests/baselines/reference/everyTypeAssignableToAny.js | 2 +- .../reference/functionConstraintSatisfaction.js | 2 +- .../genericCallWithObjectTypeArgsAndNumericIndexer.js | 2 +- .../genericCallWithObjectTypeArgsAndStringIndexer.js | 2 +- .../baselines/reference/heterogeneousArrayLiterals.js | 2 +- .../reference/innerTypeParameterShadowingOuterOne.js | 2 +- .../reference/innerTypeParameterShadowingOuterOne2.js | 2 +- .../reference/literalsInComputedProperties1.js | 2 +- tests/baselines/reference/moduleIdentifiers.js | 2 +- .../reference/moduleResolutionWithExtensions.js | 4 ++-- tests/baselines/reference/nullAssignableToEveryType.js | 2 +- tests/baselines/reference/parserSkippedTokens10.js | 2 +- .../recursivelySpecializedConstructorDeclaration.js | 2 +- tests/baselines/reference/scannerS7.4_A2_T2.js | 2 +- tests/baselines/reference/sourceMap-Comment1.js | 2 +- .../reference/sourceMap-Comment1.sourcemap.txt | 2 +- .../reference/systemDefaultExportCommentValidity.js | 2 +- .../reference/systemModuleTrailingComments.js | 2 +- .../typeParameterUsedAsTypeParameterConstraint3.js | 2 +- .../reference/undefinedAssignableToEveryType.js | 2 +- 45 files changed, 53 insertions(+), 56 deletions(-) diff --git a/src/compiler/comments.ts b/src/compiler/comments.ts index 025a4f36d26..b936c0655e1 100644 --- a/src/compiler/comments.ts +++ b/src/compiler/comments.ts @@ -274,9 +274,6 @@ namespace ts { if (hasTrailingNewLine) { writer.writeLine(); } - else { - writer.write(" "); - } } function emitLeadingCommentsOfPosition(pos: number) { diff --git a/tests/baselines/reference/ambientDeclarationsExternal.js b/tests/baselines/reference/ambientDeclarationsExternal.js index fb531586467..ed413fb0d8e 100644 --- a/tests/baselines/reference/ambientDeclarationsExternal.js +++ b/tests/baselines/reference/ambientDeclarationsExternal.js @@ -24,7 +24,7 @@ var n: number; //// [decls.js] -// Ambient external import declaration referencing ambient external module using top level module name +// Ambient external import declaration referencing ambient external module using top level module name //// [consumer.js] "use strict"; exports.__esModule = true; diff --git a/tests/baselines/reference/anyAssignableToEveryType.js b/tests/baselines/reference/anyAssignableToEveryType.js index d6b2303de48..eff97905e4f 100644 --- a/tests/baselines/reference/anyAssignableToEveryType.js +++ b/tests/baselines/reference/anyAssignableToEveryType.js @@ -87,4 +87,4 @@ function foo(x, y, z) { // x = a; // y = a; // z = a; -//} +//} diff --git a/tests/baselines/reference/augmentedTypesClass3.js b/tests/baselines/reference/augmentedTypesClass3.js index d2ad63161b5..045109f8587 100644 --- a/tests/baselines/reference/augmentedTypesClass3.js +++ b/tests/baselines/reference/augmentedTypesClass3.js @@ -46,4 +46,4 @@ var c5c = /** @class */ (function () { c5c.prototype.foo = function () { }; return c5c; }()); -//import c5c = require(''); +//import c5c = require(''); diff --git a/tests/baselines/reference/augmentedTypesEnum.js b/tests/baselines/reference/augmentedTypesEnum.js index ff0ad93f817..edd4a92d767 100644 --- a/tests/baselines/reference/augmentedTypesEnum.js +++ b/tests/baselines/reference/augmentedTypesEnum.js @@ -100,4 +100,4 @@ var e6b; })(e6b || (e6b = {})); // should be error // enum then import, messes with error reporting //enum e7 { One } -//import e7 = require(''); // should be error +//import e7 = require(''); // should be error diff --git a/tests/baselines/reference/augmentedTypesEnum2.js b/tests/baselines/reference/augmentedTypesEnum2.js index 66fc96b62a0..0e6e70df263 100644 --- a/tests/baselines/reference/augmentedTypesEnum2.js +++ b/tests/baselines/reference/augmentedTypesEnum2.js @@ -41,4 +41,4 @@ var e2 = /** @class */ (function () { return e2; }()); //enum then enum - covered -//enum then import - covered +//enum then import - covered diff --git a/tests/baselines/reference/augmentedTypesFunction.js b/tests/baselines/reference/augmentedTypesFunction.js index 3c6066e5bb4..a2dd4a664a3 100644 --- a/tests/baselines/reference/augmentedTypesFunction.js +++ b/tests/baselines/reference/augmentedTypesFunction.js @@ -79,4 +79,4 @@ function y5b() { } function y5c() { } // function then import, messes with other errors //function y6() { } -//import y6 = require(''); +//import y6 = require(''); diff --git a/tests/baselines/reference/augmentedTypesInterface.js b/tests/baselines/reference/augmentedTypesInterface.js index b74da5bbfee..0409e157584 100644 --- a/tests/baselines/reference/augmentedTypesInterface.js +++ b/tests/baselines/reference/augmentedTypesInterface.js @@ -48,4 +48,4 @@ var i3; i3[i3["One"] = 0] = "One"; })(i3 || (i3 = {})); ; // error -//import i4 = require(''); // error +//import i4 = require(''); // error diff --git a/tests/baselines/reference/baseIndexSignatureResolution.js b/tests/baselines/reference/baseIndexSignatureResolution.js index 4053e588e44..3fdeecf78f6 100644 --- a/tests/baselines/reference/baseIndexSignatureResolution.js +++ b/tests/baselines/reference/baseIndexSignatureResolution.js @@ -59,4 +59,4 @@ interface B extends A { } var b: B = null; var z: Derived = b.foo(); -*/ +*/ diff --git a/tests/baselines/reference/commentEmitAtEndOfFile1.js b/tests/baselines/reference/commentEmitAtEndOfFile1.js index 1be031fa84a..d6ba7b158d6 100644 --- a/tests/baselines/reference/commentEmitAtEndOfFile1.js +++ b/tests/baselines/reference/commentEmitAtEndOfFile1.js @@ -18,4 +18,4 @@ var foo; (function (foo) { function bar() { } })(foo || (foo = {})); -// test #4 +// test #4 diff --git a/tests/baselines/reference/commentEmitWithCommentOnLastLine.js b/tests/baselines/reference/commentEmitWithCommentOnLastLine.js index ffd4addb264..077286a7364 100644 --- a/tests/baselines/reference/commentEmitWithCommentOnLastLine.js +++ b/tests/baselines/reference/commentEmitWithCommentOnLastLine.js @@ -8,4 +8,4 @@ var bar; var x; /* var bar; -*/ +*/ diff --git a/tests/baselines/reference/commentOnArrayElement1.js b/tests/baselines/reference/commentOnArrayElement1.js index 960df336dbb..c93cf634096 100644 --- a/tests/baselines/reference/commentOnArrayElement1.js +++ b/tests/baselines/reference/commentOnArrayElement1.js @@ -11,7 +11,7 @@ var array = [ var array = [ /* element 1*/ 1 - /* end of element 1 */ , + /* end of element 1 */, 2 /* end of element 2 */ ]; diff --git a/tests/baselines/reference/commentOnArrayElement3.js b/tests/baselines/reference/commentOnArrayElement3.js index e31f8adf26a..f19ef5d6050 100644 --- a/tests/baselines/reference/commentOnArrayElement3.js +++ b/tests/baselines/reference/commentOnArrayElement3.js @@ -12,8 +12,8 @@ var array = [ var array = [ /* element 1*/ 1 - /* end of element 1 */ , + /* end of element 1 */, 2 - /* end of element 2 */ , + /* end of element 2 */, , ]; diff --git a/tests/baselines/reference/commentOnBlock1.js b/tests/baselines/reference/commentOnBlock1.js index ed5437c1f66..20df3764b77 100644 --- a/tests/baselines/reference/commentOnBlock1.js +++ b/tests/baselines/reference/commentOnBlock1.js @@ -7,5 +7,5 @@ function f() { //// [commentOnBlock1.js] // asdf function f() { - /*asdf*/ { } + /*asdf*/{ } } diff --git a/tests/baselines/reference/commentsArgumentsOfCallExpression1.js b/tests/baselines/reference/commentsArgumentsOfCallExpression1.js index 4e6d693c5c2..f32e0bb8098 100644 --- a/tests/baselines/reference/commentsArgumentsOfCallExpression1.js +++ b/tests/baselines/reference/commentsArgumentsOfCallExpression1.js @@ -29,4 +29,4 @@ function () { }); foo(/*c7*/ function () { }); foo( /*c7*/ -/*c8*/ function () { }); +/*c8*/function () { }); diff --git a/tests/baselines/reference/commentsArgumentsOfCallExpression2.js b/tests/baselines/reference/commentsArgumentsOfCallExpression2.js index f89e67ef3d8..1e1079a4d22 100644 --- a/tests/baselines/reference/commentsArgumentsOfCallExpression2.js +++ b/tests/baselines/reference/commentsArgumentsOfCallExpression2.js @@ -17,7 +17,7 @@ foo(/*c2*/ 1, /*d2*/ 1 + 2, /*e1*/ a + b); foo(/*c3*/ function () { }, /*d2*/ function () { }, /*e2*/ a + /*e3*/ b); foo(/*c3*/ function () { }, /*d3*/ function () { }, /*e3*/ (a + b)); foo( -/*c4*/ function () { }, -/*d4*/ function () { }, +/*c4*/function () { }, +/*d4*/function () { }, /*e4*/ -/*e5*/ "hello"); +/*e5*/"hello"); diff --git a/tests/baselines/reference/commentsCommentParsing.js b/tests/baselines/reference/commentsCommentParsing.js index 889067a3c05..c39bf05e556 100644 --- a/tests/baselines/reference/commentsCommentParsing.js +++ b/tests/baselines/reference/commentsCommentParsing.js @@ -178,7 +178,7 @@ jsDocMultiLine(); *New line1 *New Line2*/ /** Shoul mege this line as well -* and this too*/ /** Another this one too*/ +* and this too*//** Another this one too*/ function jsDocMultiLineMerge() { } jsDocMultiLineMerge(); @@ -188,23 +188,23 @@ function jsDocMixedComments1() { } jsDocMixedComments1(); /// Triple slash comment -/** jsdoc comment */ /*** another jsDocComment*/ +/** jsdoc comment *//*** another jsDocComment*/ function jsDocMixedComments2() { } jsDocMixedComments2(); -/** jsdoc comment */ /*** another jsDocComment*/ +/** jsdoc comment *//*** another jsDocComment*/ /// Triple slash comment function jsDocMixedComments3() { } jsDocMixedComments3(); -/** jsdoc comment */ /*** another jsDocComment*/ +/** jsdoc comment *//*** another jsDocComment*/ /// Triple slash comment /// Triple slash comment 2 function jsDocMixedComments4() { } jsDocMixedComments4(); /// Triple slash comment 1 -/** jsdoc comment */ /*** another jsDocComment*/ +/** jsdoc comment *//*** another jsDocComment*/ /// Triple slash comment /// Triple slash comment 2 function jsDocMixedComments5() { diff --git a/tests/baselines/reference/commentsFunction.js b/tests/baselines/reference/commentsFunction.js index ad31aa47b91..a02ffb3b364 100644 --- a/tests/baselines/reference/commentsFunction.js +++ b/tests/baselines/reference/commentsFunction.js @@ -86,8 +86,8 @@ function blah3(a // trailing commen single line ) { } lambdaFoo = function (a, b) { return a * b; }; // This is trailing comment -/*leading comment*/ (function () { return 0; }); // Needs to be wrapped in parens to be a valid expression (not declaration) -/*leading comment*/ (function () { return 0; }); //trailing comment +/*leading comment*/(function () { return 0; }); // Needs to be wrapped in parens to be a valid expression (not declaration) +/*leading comment*/(function () { return 0; }); //trailing comment function blah4(/*1*/ a /*2*/, /*3*/ b /*4*/) { } function foo1() { diff --git a/tests/baselines/reference/commentsOnPropertyOfObjectLiteral1.js b/tests/baselines/reference/commentsOnPropertyOfObjectLiteral1.js index fa7790443ac..39190d9173a 100644 --- a/tests/baselines/reference/commentsOnPropertyOfObjectLiteral1.js +++ b/tests/baselines/reference/commentsOnPropertyOfObjectLiteral1.js @@ -18,7 +18,7 @@ var resolve = { id: /*! @ngInject */ function (details) { return details.id; }, id1: /* c1 */ "hello", id2: - /*! @ngInject */ function (details) { return details.id; }, + /*! @ngInject */function (details) { return details.id; }, id3: /*! @ngInject */ function (details) { return details.id; }, diff --git a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnCallSignature.js b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnCallSignature.js index 079a1e276fb..bcd87998f83 100644 --- a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnCallSignature.js +++ b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnCallSignature.js @@ -505,4 +505,4 @@ var r8b8 = b8 !== a8; var r8b9 = b9 !== a9; var r8b10 = b10 !== a10; var r8b11 = b11 !== a11; -//var r8b12 = b12 !== a12; +//var r8b12 = b12 !== a12; diff --git a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnConstructorSignature.js b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnConstructorSignature.js index 38097a936e3..1721f564865 100644 --- a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnConstructorSignature.js +++ b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnConstructorSignature.js @@ -431,4 +431,4 @@ var r8b6 = b6 !== a6; var r8b7 = b7 !== a7; var r8b8 = b8 !== a8; var r8b9 = b9 !== a9; -//var r8b10 = b10 !== a10; +//var r8b10 = b10 !== a10; diff --git a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedCallSignature.js b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedCallSignature.js index 87359ea0074..72dd4be0afc 100644 --- a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedCallSignature.js +++ b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedCallSignature.js @@ -320,4 +320,4 @@ var r8b3 = b3 !== a3; var r8b4 = b4 !== a4; var r8b5 = b5 !== a5; var r8b6 = b6 !== a6; -//var r8b7 = b7 !== a7; +//var r8b7 = b7 !== a7; diff --git a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedConstructorSignature.js b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedConstructorSignature.js index fcfbfa4bfbc..19183773406 100644 --- a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedConstructorSignature.js +++ b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedConstructorSignature.js @@ -320,4 +320,4 @@ var r8b3 = b3 !== a3; var r8b4 = b4 !== a4; var r8b5 = b5 !== a5; var r8b6 = b6 !== a6; -//var r8b7 = b7 !== a7; +//var r8b7 = b7 !== a7; diff --git a/tests/baselines/reference/concatError.js b/tests/baselines/reference/concatError.js index 67361719702..d2b30218e50 100644 --- a/tests/baselines/reference/concatError.js +++ b/tests/baselines/reference/concatError.js @@ -56,4 +56,4 @@ var c: C; var cc: C>; c = c.m(cc); -*/ +*/ diff --git a/tests/baselines/reference/errorSupression1.js b/tests/baselines/reference/errorSupression1.js index 2f467871434..4b635a0d660 100644 --- a/tests/baselines/reference/errorSupression1.js +++ b/tests/baselines/reference/errorSupression1.js @@ -17,4 +17,4 @@ var Foo = /** @class */ (function () { var baz = Foo.b; // Foo.b won't bind. baz.concat("y"); -// So we don't want an error on 'concat'. +// So we don't want an error on 'concat'. diff --git a/tests/baselines/reference/everyTypeAssignableToAny.js b/tests/baselines/reference/everyTypeAssignableToAny.js index 7f02badca00..fd71ec624be 100644 --- a/tests/baselines/reference/everyTypeAssignableToAny.js +++ b/tests/baselines/reference/everyTypeAssignableToAny.js @@ -117,4 +117,4 @@ function foo(x, y, z) { // a = x; // a = y; // a = z; -//} +//} diff --git a/tests/baselines/reference/functionConstraintSatisfaction.js b/tests/baselines/reference/functionConstraintSatisfaction.js index fc8a2be88a7..f24fd32aff6 100644 --- a/tests/baselines/reference/functionConstraintSatisfaction.js +++ b/tests/baselines/reference/functionConstraintSatisfaction.js @@ -108,4 +108,4 @@ function foo2(x, y) { //function foo2(x: T, y: U) { // foo(x); // foo(y); -//} +//} diff --git a/tests/baselines/reference/genericCallWithObjectTypeArgsAndNumericIndexer.js b/tests/baselines/reference/genericCallWithObjectTypeArgsAndNumericIndexer.js index f300e3a8093..27e4093d9c7 100644 --- a/tests/baselines/reference/genericCallWithObjectTypeArgsAndNumericIndexer.js +++ b/tests/baselines/reference/genericCallWithObjectTypeArgsAndNumericIndexer.js @@ -63,4 +63,4 @@ function other3(arg) { // var d = r2[1]; // // BUG 821629 // //var u: U = r2[1]; // ok -//} +//} diff --git a/tests/baselines/reference/genericCallWithObjectTypeArgsAndStringIndexer.js b/tests/baselines/reference/genericCallWithObjectTypeArgsAndStringIndexer.js index eee87caf3de..ee33746b152 100644 --- a/tests/baselines/reference/genericCallWithObjectTypeArgsAndStringIndexer.js +++ b/tests/baselines/reference/genericCallWithObjectTypeArgsAndStringIndexer.js @@ -64,4 +64,4 @@ function other3(arg) { // var d: Date = r2['hm']; // ok // // BUG 821629 // //var u: U = r2['hm']; // ok -//} +//} diff --git a/tests/baselines/reference/heterogeneousArrayLiterals.js b/tests/baselines/reference/heterogeneousArrayLiterals.js index 499aa7e7818..46dee284ae9 100644 --- a/tests/baselines/reference/heterogeneousArrayLiterals.js +++ b/tests/baselines/reference/heterogeneousArrayLiterals.js @@ -268,4 +268,4 @@ function foo4(t, u) { // var i = [u, base]; // Base[] // var j = [u, derived]; // Derived[] // var k: Base[] = [t, u]; -//} +//} diff --git a/tests/baselines/reference/innerTypeParameterShadowingOuterOne.js b/tests/baselines/reference/innerTypeParameterShadowingOuterOne.js index 74354468e32..f566bbdd878 100644 --- a/tests/baselines/reference/innerTypeParameterShadowingOuterOne.js +++ b/tests/baselines/reference/innerTypeParameterShadowingOuterOne.js @@ -54,4 +54,4 @@ function f2() { // } // var x: U; // x.getDate(); -//} +//} diff --git a/tests/baselines/reference/innerTypeParameterShadowingOuterOne2.js b/tests/baselines/reference/innerTypeParameterShadowingOuterOne2.js index 984584389f6..824061fce1f 100644 --- a/tests/baselines/reference/innerTypeParameterShadowingOuterOne2.js +++ b/tests/baselines/reference/innerTypeParameterShadowingOuterOne2.js @@ -75,4 +75,4 @@ var C2 = /** @class */ (function () { // var x: U; // x.getDate(); // } -//} +//} diff --git a/tests/baselines/reference/literalsInComputedProperties1.js b/tests/baselines/reference/literalsInComputedProperties1.js index c5b0060f626..4611925f2d4 100644 --- a/tests/baselines/reference/literalsInComputedProperties1.js +++ b/tests/baselines/reference/literalsInComputedProperties1.js @@ -89,4 +89,4 @@ var X; var a = X["foo"]; var a0 = X["bar"]; var _a; -// TODO: make sure that enum still disallow template literals as member names +// TODO: make sure that enum still disallow template literals as member names diff --git a/tests/baselines/reference/moduleIdentifiers.js b/tests/baselines/reference/moduleIdentifiers.js index 04d39019482..d3a654b8670 100644 --- a/tests/baselines/reference/moduleIdentifiers.js +++ b/tests/baselines/reference/moduleIdentifiers.js @@ -19,4 +19,4 @@ var M; //var m: M = M; var x1 = M.a; //var x2 = m.a; -//var q: m.P; +//var q: m.P; diff --git a/tests/baselines/reference/moduleResolutionWithExtensions.js b/tests/baselines/reference/moduleResolutionWithExtensions.js index c1e0310e995..3406bb0adae 100644 --- a/tests/baselines/reference/moduleResolutionWithExtensions.js +++ b/tests/baselines/reference/moduleResolutionWithExtensions.js @@ -28,11 +28,11 @@ import j from "./jquery.js" "use strict"; exports.__esModule = true; exports["default"] = 0; -// No extension: '.ts' added +// No extension: '.ts' added //// [b.js] "use strict"; exports.__esModule = true; -// '.js' extension: stripped and replaced with '.ts' +// '.js' extension: stripped and replaced with '.ts' //// [d.js] "use strict"; exports.__esModule = true; diff --git a/tests/baselines/reference/nullAssignableToEveryType.js b/tests/baselines/reference/nullAssignableToEveryType.js index f04ae865692..50914b366f8 100644 --- a/tests/baselines/reference/nullAssignableToEveryType.js +++ b/tests/baselines/reference/nullAssignableToEveryType.js @@ -84,4 +84,4 @@ function foo(x, y, z) { // x = null; // y = null; // z = null; -//} +//} diff --git a/tests/baselines/reference/parserSkippedTokens10.js b/tests/baselines/reference/parserSkippedTokens10.js index cfacb2e21bd..3af628a2e1e 100644 --- a/tests/baselines/reference/parserSkippedTokens10.js +++ b/tests/baselines/reference/parserSkippedTokens10.js @@ -5,4 +5,4 @@ //// [parserSkippedTokens10.js] -/*existing trivia*/ ; +/*existing trivia*/; diff --git a/tests/baselines/reference/recursivelySpecializedConstructorDeclaration.js b/tests/baselines/reference/recursivelySpecializedConstructorDeclaration.js index beff303c540..dbf4b6b27d1 100644 --- a/tests/baselines/reference/recursivelySpecializedConstructorDeclaration.js +++ b/tests/baselines/reference/recursivelySpecializedConstructorDeclaration.js @@ -78,4 +78,4 @@ declare module MsPortal.Controls.Base.ItemList { class ViewModel extends ItemValue { } } -*/ +*/ diff --git a/tests/baselines/reference/scannerS7.4_A2_T2.js b/tests/baselines/reference/scannerS7.4_A2_T2.js index 9cfc0b03bd8..4a446b520ad 100644 --- a/tests/baselines/reference/scannerS7.4_A2_T2.js +++ b/tests/baselines/reference/scannerS7.4_A2_T2.js @@ -26,4 +26,4 @@ */ /*CHECK#1/ - + diff --git a/tests/baselines/reference/sourceMap-Comment1.js b/tests/baselines/reference/sourceMap-Comment1.js index 071e54b5716..6f1f43cd8e2 100644 --- a/tests/baselines/reference/sourceMap-Comment1.js +++ b/tests/baselines/reference/sourceMap-Comment1.js @@ -2,5 +2,5 @@ // Comment //// [sourceMap-Comment1.js] -// Comment +// Comment //# sourceMappingURL=sourceMap-Comment1.js.map \ No newline at end of file diff --git a/tests/baselines/reference/sourceMap-Comment1.sourcemap.txt b/tests/baselines/reference/sourceMap-Comment1.sourcemap.txt index 4d427d1de89..e2f9174a45f 100644 --- a/tests/baselines/reference/sourceMap-Comment1.sourcemap.txt +++ b/tests/baselines/reference/sourceMap-Comment1.sourcemap.txt @@ -8,7 +8,7 @@ sources: sourceMap-Comment1.ts emittedFile:tests/cases/compiler/sourceMap-Comment1.js sourceFile:sourceMap-Comment1.ts ------------------------------------------------------------------- ->>>// Comment +>>>// Comment 1 > 2 >^^^^^^^^^^ 3 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-> diff --git a/tests/baselines/reference/systemDefaultExportCommentValidity.js b/tests/baselines/reference/systemDefaultExportCommentValidity.js index a56110b0de9..45fe1df3ccd 100644 --- a/tests/baselines/reference/systemDefaultExportCommentValidity.js +++ b/tests/baselines/reference/systemDefaultExportCommentValidity.js @@ -14,7 +14,7 @@ System.register([], function (exports_1, context_1) { execute: function () { Home = {}; exports_1("default", Home); - // There is intentionally no semicolon on the prior line, this comment should not break emit + // There is intentionally no semicolon on the prior line, this comment should not break emit } }; }); diff --git a/tests/baselines/reference/systemModuleTrailingComments.js b/tests/baselines/reference/systemModuleTrailingComments.js index 41b0bd299a0..01f17d1facf 100644 --- a/tests/baselines/reference/systemModuleTrailingComments.js +++ b/tests/baselines/reference/systemModuleTrailingComments.js @@ -12,7 +12,7 @@ System.register([], function (exports_1, context_1) { setters: [], execute: function () { exports_1("test", test = "TEST"); - //some comment + //some comment } }; }); diff --git a/tests/baselines/reference/typeParameterUsedAsTypeParameterConstraint3.js b/tests/baselines/reference/typeParameterUsedAsTypeParameterConstraint3.js index 95c65d5f3a9..0655ad17138 100644 --- a/tests/baselines/reference/typeParameterUsedAsTypeParameterConstraint3.js +++ b/tests/baselines/reference/typeParameterUsedAsTypeParameterConstraint3.js @@ -64,4 +64,4 @@ interface I2 { // y: U; // z: V; // foo(x: W): T; -//} +//} diff --git a/tests/baselines/reference/undefinedAssignableToEveryType.js b/tests/baselines/reference/undefinedAssignableToEveryType.js index 507f647763a..de64f97f70b 100644 --- a/tests/baselines/reference/undefinedAssignableToEveryType.js +++ b/tests/baselines/reference/undefinedAssignableToEveryType.js @@ -83,4 +83,4 @@ function foo(x, y, z) { // x = undefined; // y = undefined; // z = undefined; -//} +//} From dcd2ddd0b71f6682c3d020ada0e9ac482b9b3d33 Mon Sep 17 00:00:00 2001 From: Yuval Greenfield Date: Tue, 26 Sep 2017 12:09:58 -0700 Subject: [PATCH 004/235] Yes space after multiline comments --- src/compiler/comments.ts | 3 +++ .../reference/baseIndexSignatureResolution.js | 2 +- .../reference/commentEmitWithCommentOnLastLine.js | 2 +- tests/baselines/reference/commentOnArrayElement1.js | 2 +- tests/baselines/reference/commentOnArrayElement3.js | 4 ++-- tests/baselines/reference/commentOnBlock1.js | 2 +- .../reference/commentsArgumentsOfCallExpression1.js | 2 +- .../reference/commentsArgumentsOfCallExpression2.js | 6 +++--- tests/baselines/reference/commentsCommentParsing.js | 10 +++++----- tests/baselines/reference/commentsFunction.js | 4 ++-- .../reference/commentsOnPropertyOfObjectLiteral1.js | 2 +- tests/baselines/reference/concatError.js | 2 +- tests/baselines/reference/parserSkippedTokens10.js | 2 +- .../recursivelySpecializedConstructorDeclaration.js | 2 +- tests/baselines/reference/scannerS7.4_A2_T2.js | 2 +- 15 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/compiler/comments.ts b/src/compiler/comments.ts index b936c0655e1..bb8ec9bf3e7 100644 --- a/src/compiler/comments.ts +++ b/src/compiler/comments.ts @@ -274,6 +274,9 @@ namespace ts { if (hasTrailingNewLine) { writer.writeLine(); } + else if (_kind === SyntaxKind.MultiLineCommentTrivia) { + writer.write(" "); + } } function emitLeadingCommentsOfPosition(pos: number) { diff --git a/tests/baselines/reference/baseIndexSignatureResolution.js b/tests/baselines/reference/baseIndexSignatureResolution.js index 3fdeecf78f6..4053e588e44 100644 --- a/tests/baselines/reference/baseIndexSignatureResolution.js +++ b/tests/baselines/reference/baseIndexSignatureResolution.js @@ -59,4 +59,4 @@ interface B extends A { } var b: B = null; var z: Derived = b.foo(); -*/ +*/ diff --git a/tests/baselines/reference/commentEmitWithCommentOnLastLine.js b/tests/baselines/reference/commentEmitWithCommentOnLastLine.js index 077286a7364..ffd4addb264 100644 --- a/tests/baselines/reference/commentEmitWithCommentOnLastLine.js +++ b/tests/baselines/reference/commentEmitWithCommentOnLastLine.js @@ -8,4 +8,4 @@ var bar; var x; /* var bar; -*/ +*/ diff --git a/tests/baselines/reference/commentOnArrayElement1.js b/tests/baselines/reference/commentOnArrayElement1.js index c93cf634096..960df336dbb 100644 --- a/tests/baselines/reference/commentOnArrayElement1.js +++ b/tests/baselines/reference/commentOnArrayElement1.js @@ -11,7 +11,7 @@ var array = [ var array = [ /* element 1*/ 1 - /* end of element 1 */, + /* end of element 1 */ , 2 /* end of element 2 */ ]; diff --git a/tests/baselines/reference/commentOnArrayElement3.js b/tests/baselines/reference/commentOnArrayElement3.js index f19ef5d6050..e31f8adf26a 100644 --- a/tests/baselines/reference/commentOnArrayElement3.js +++ b/tests/baselines/reference/commentOnArrayElement3.js @@ -12,8 +12,8 @@ var array = [ var array = [ /* element 1*/ 1 - /* end of element 1 */, + /* end of element 1 */ , 2 - /* end of element 2 */, + /* end of element 2 */ , , ]; diff --git a/tests/baselines/reference/commentOnBlock1.js b/tests/baselines/reference/commentOnBlock1.js index 20df3764b77..ed5437c1f66 100644 --- a/tests/baselines/reference/commentOnBlock1.js +++ b/tests/baselines/reference/commentOnBlock1.js @@ -7,5 +7,5 @@ function f() { //// [commentOnBlock1.js] // asdf function f() { - /*asdf*/{ } + /*asdf*/ { } } diff --git a/tests/baselines/reference/commentsArgumentsOfCallExpression1.js b/tests/baselines/reference/commentsArgumentsOfCallExpression1.js index f32e0bb8098..4e6d693c5c2 100644 --- a/tests/baselines/reference/commentsArgumentsOfCallExpression1.js +++ b/tests/baselines/reference/commentsArgumentsOfCallExpression1.js @@ -29,4 +29,4 @@ function () { }); foo(/*c7*/ function () { }); foo( /*c7*/ -/*c8*/function () { }); +/*c8*/ function () { }); diff --git a/tests/baselines/reference/commentsArgumentsOfCallExpression2.js b/tests/baselines/reference/commentsArgumentsOfCallExpression2.js index 1e1079a4d22..f89e67ef3d8 100644 --- a/tests/baselines/reference/commentsArgumentsOfCallExpression2.js +++ b/tests/baselines/reference/commentsArgumentsOfCallExpression2.js @@ -17,7 +17,7 @@ foo(/*c2*/ 1, /*d2*/ 1 + 2, /*e1*/ a + b); foo(/*c3*/ function () { }, /*d2*/ function () { }, /*e2*/ a + /*e3*/ b); foo(/*c3*/ function () { }, /*d3*/ function () { }, /*e3*/ (a + b)); foo( -/*c4*/function () { }, -/*d4*/function () { }, +/*c4*/ function () { }, +/*d4*/ function () { }, /*e4*/ -/*e5*/"hello"); +/*e5*/ "hello"); diff --git a/tests/baselines/reference/commentsCommentParsing.js b/tests/baselines/reference/commentsCommentParsing.js index c39bf05e556..889067a3c05 100644 --- a/tests/baselines/reference/commentsCommentParsing.js +++ b/tests/baselines/reference/commentsCommentParsing.js @@ -178,7 +178,7 @@ jsDocMultiLine(); *New line1 *New Line2*/ /** Shoul mege this line as well -* and this too*//** Another this one too*/ +* and this too*/ /** Another this one too*/ function jsDocMultiLineMerge() { } jsDocMultiLineMerge(); @@ -188,23 +188,23 @@ function jsDocMixedComments1() { } jsDocMixedComments1(); /// Triple slash comment -/** jsdoc comment *//*** another jsDocComment*/ +/** jsdoc comment */ /*** another jsDocComment*/ function jsDocMixedComments2() { } jsDocMixedComments2(); -/** jsdoc comment *//*** another jsDocComment*/ +/** jsdoc comment */ /*** another jsDocComment*/ /// Triple slash comment function jsDocMixedComments3() { } jsDocMixedComments3(); -/** jsdoc comment *//*** another jsDocComment*/ +/** jsdoc comment */ /*** another jsDocComment*/ /// Triple slash comment /// Triple slash comment 2 function jsDocMixedComments4() { } jsDocMixedComments4(); /// Triple slash comment 1 -/** jsdoc comment *//*** another jsDocComment*/ +/** jsdoc comment */ /*** another jsDocComment*/ /// Triple slash comment /// Triple slash comment 2 function jsDocMixedComments5() { diff --git a/tests/baselines/reference/commentsFunction.js b/tests/baselines/reference/commentsFunction.js index a02ffb3b364..ad31aa47b91 100644 --- a/tests/baselines/reference/commentsFunction.js +++ b/tests/baselines/reference/commentsFunction.js @@ -86,8 +86,8 @@ function blah3(a // trailing commen single line ) { } lambdaFoo = function (a, b) { return a * b; }; // This is trailing comment -/*leading comment*/(function () { return 0; }); // Needs to be wrapped in parens to be a valid expression (not declaration) -/*leading comment*/(function () { return 0; }); //trailing comment +/*leading comment*/ (function () { return 0; }); // Needs to be wrapped in parens to be a valid expression (not declaration) +/*leading comment*/ (function () { return 0; }); //trailing comment function blah4(/*1*/ a /*2*/, /*3*/ b /*4*/) { } function foo1() { diff --git a/tests/baselines/reference/commentsOnPropertyOfObjectLiteral1.js b/tests/baselines/reference/commentsOnPropertyOfObjectLiteral1.js index 39190d9173a..fa7790443ac 100644 --- a/tests/baselines/reference/commentsOnPropertyOfObjectLiteral1.js +++ b/tests/baselines/reference/commentsOnPropertyOfObjectLiteral1.js @@ -18,7 +18,7 @@ var resolve = { id: /*! @ngInject */ function (details) { return details.id; }, id1: /* c1 */ "hello", id2: - /*! @ngInject */function (details) { return details.id; }, + /*! @ngInject */ function (details) { return details.id; }, id3: /*! @ngInject */ function (details) { return details.id; }, diff --git a/tests/baselines/reference/concatError.js b/tests/baselines/reference/concatError.js index d2b30218e50..67361719702 100644 --- a/tests/baselines/reference/concatError.js +++ b/tests/baselines/reference/concatError.js @@ -56,4 +56,4 @@ var c: C; var cc: C>; c = c.m(cc); -*/ +*/ diff --git a/tests/baselines/reference/parserSkippedTokens10.js b/tests/baselines/reference/parserSkippedTokens10.js index 3af628a2e1e..cfacb2e21bd 100644 --- a/tests/baselines/reference/parserSkippedTokens10.js +++ b/tests/baselines/reference/parserSkippedTokens10.js @@ -5,4 +5,4 @@ //// [parserSkippedTokens10.js] -/*existing trivia*/; +/*existing trivia*/ ; diff --git a/tests/baselines/reference/recursivelySpecializedConstructorDeclaration.js b/tests/baselines/reference/recursivelySpecializedConstructorDeclaration.js index dbf4b6b27d1..beff303c540 100644 --- a/tests/baselines/reference/recursivelySpecializedConstructorDeclaration.js +++ b/tests/baselines/reference/recursivelySpecializedConstructorDeclaration.js @@ -78,4 +78,4 @@ declare module MsPortal.Controls.Base.ItemList { class ViewModel extends ItemValue { } } -*/ +*/ diff --git a/tests/baselines/reference/scannerS7.4_A2_T2.js b/tests/baselines/reference/scannerS7.4_A2_T2.js index 4a446b520ad..9cfc0b03bd8 100644 --- a/tests/baselines/reference/scannerS7.4_A2_T2.js +++ b/tests/baselines/reference/scannerS7.4_A2_T2.js @@ -26,4 +26,4 @@ */ /*CHECK#1/ - + From 405d8cf8ebd3f6c9c2a5f7e19c2a687235ec0a18 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 9 Oct 2017 10:45:50 -0700 Subject: [PATCH 005/235] In getSuggestionForNonexistentSymbol, guard name against undefined --- src/compiler/checker.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a8e18c432a6..738a484d254 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15064,7 +15064,10 @@ namespace ts { function getSuggestionForNonexistentSymbol(location: Node, name: __String, meaning: SymbolFlags): string { const result = resolveNameHelper(location, name, meaning, /*nameNotFoundMessage*/ undefined, name, /*isUse*/ false, (symbols, name, meaning) => { - // `name` from the callback === the outer `name` + // NOTE: `name` from the callback is supposed to === the outer `name`, but is undefined in some cases + if (name === undefined) { + return undefined; + } const symbol = getSymbol(symbols, name, meaning); // Sometimes the symbol is found when location is a return type of a function: `typeof x` and `x` is declared in the body of the function // So the table *contains* `x` but `x` isn't actually in scope. From 1cb2d24c5d218a8119655d584bd61d749b18dec2 Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Thu, 12 Oct 2017 17:18:38 -0700 Subject: [PATCH 006/235] Added DefinitionAndBoundSpan command --- src/harness/harnessLanguageService.ts | 3 +++ src/harness/unittests/session.ts | 5 +++-- src/server/client.ts | 6 +++++- src/server/protocol.ts | 2 ++ src/server/session.ts | 20 +++++++++++++++++-- src/services/services.ts | 14 +++++++++++-- src/services/types.ts | 1 + .../reference/api/tsserverlibrary.d.ts | 18 +++++++++-------- tests/baselines/reference/api/typescript.d.ts | 7 ++++--- 9 files changed, 58 insertions(+), 18 deletions(-) diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index ad79c96d833..34043195429 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -490,6 +490,9 @@ namespace Harness.LanguageService { getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): ts.TextSpan { return unwrapJSONCallResult(this.shim.getSpanOfEnclosingComment(fileName, position, onlyMultiLine)); } + getSpanForPosition(): ts.TextSpan { + throw new Error("Not supportred on the shim."); + } getCodeFixesAtPosition(): ts.CodeAction[] { throw new Error("Not supported on the shim."); } diff --git a/src/harness/unittests/session.ts b/src/harness/unittests/session.ts index 3b5efc2d6de..2ce5ef530e4 100644 --- a/src/harness/unittests/session.ts +++ b/src/harness/unittests/session.ts @@ -117,7 +117,7 @@ namespace ts.server { body: undefined }); }); - it ("should handle literal types in request", () => { + it("should handle literal types in request", () => { const configureRequest: protocol.ConfigureRequest = { command: CommandNames.Configure, seq: 0, @@ -175,6 +175,7 @@ namespace ts.server { CommandNames.Configure, CommandNames.Definition, CommandNames.DefinitionFull, + CommandNames.DefinitionAndBoundSpan, CommandNames.Implementation, CommandNames.ImplementationFull, CommandNames.Exit, @@ -341,7 +342,7 @@ namespace ts.server { session.addProtocolHandler(command, () => resp); expect(() => session.addProtocolHandler(command, () => resp)) - .to.throw(`Protocol handler already exists for command "${command}"`); + .to.throw(`Protocol handler already exists for command "${command}"`); }); }); diff --git a/src/server/client.ts b/src/server/client.ts index d08d1e13d2e..f467f7f9224 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -322,7 +322,7 @@ namespace ts.server { } getSyntacticDiagnostics(file: string): Diagnostic[] { - const args: protocol.SyntacticDiagnosticsSyncRequestArgs = { file, includeLinePosition: true }; + const args: protocol.SyntacticDiagnosticsSyncRequestArgs = { file, includeLinePosition: true }; const request = this.processRequest(CommandNames.SyntacticDiagnosticsSync, args); const response = this.processResponse(request); @@ -531,6 +531,10 @@ namespace ts.server { return notImplemented(); } + getSpanForPosition(_fileName: string, _position: number): TextSpan { + return notImplemented(); + } + getCodeFixesAtPosition(file: string, start: number, end: number, errorCodes: number[]): CodeAction[] { const args: protocol.CodeFixRequestArgs = { ...this.createFileRangeRequestArgs(file, start, end), errorCodes }; diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 3d07392bbe6..0685728c3b0 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -21,6 +21,8 @@ namespace ts.server.protocol { Definition = "definition", /* @internal */ DefinitionFull = "definition-full", + /* @internal */ + DefinitionAndBoundSpan = "definitionAndBoundSpan", Implementation = "implementation", /* @internal */ ImplementationFull = "implementation-full", diff --git a/src/server/session.ts b/src/server/session.ts index 800d09ff6c2..5a8426f23b3 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -167,7 +167,7 @@ namespace ts.server { private timerHandle: any; private immediateId: number | undefined; - constructor(private readonly operationHost: MultistepOperationHost) {} + constructor(private readonly operationHost: MultistepOperationHost) { } public startNew(action: (next: NextStep) => void) { this.complete(); @@ -579,7 +579,7 @@ namespace ts.server { private getDiagnosticsWorker( args: protocol.FileRequestArgs, isSemantic: boolean, selector: (project: Project, file: string) => ReadonlyArray, includeLinePosition: boolean - ): ReadonlyArray | ReadonlyArray { + ): ReadonlyArray | ReadonlyArray { const { project, file } = this.getFileAndProject(args); if (isSemantic && isDeclarationFileInJSOnlyNonConfiguredProject(project, file)) { return emptyArray; @@ -1081,6 +1081,13 @@ namespace ts.server { } } + private getSpanForLocation(args: protocol.FileLocationRequestArgs): TextSpan { + const { file, project } = this.getFileAndProject(args); + const scriptInfo = project.getScriptInfoForNormalizedPath(file); + + return project.getLanguageService().getSpanForPosition(file, this.getPosition(args, scriptInfo)); + } + private getFormattingEditsForRange(args: protocol.FormatRequestArgs): protocol.CodeEdit[] { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); @@ -1707,6 +1714,15 @@ namespace ts.server { [CommandNames.DefinitionFull]: (request: protocol.DefinitionRequest) => { return this.requiredResponse(this.getDefinition(request.arguments, /*simplifiedResult*/ false)); }, + [CommandNames.DefinitionAndBoundSpan]: (request: protocol.DefinitionRequest) => { + const definitions = this.getDefinition(request.arguments, /*simplifiedResult*/ false); + const textSpan = definitions.length !== 0 ? this.getSpanForLocation(request.arguments) : {}; + + return this.requiredResponse({ + definitions, + textSpan + }); + }, [CommandNames.TypeDefinition]: (request: protocol.FileLocationRequest) => { return this.requiredResponse(this.getTypeDefinition(request.arguments)); }, diff --git a/src/services/services.ts b/src/services/services.ts index 6bdc96d8b4d..5b24fa1947e 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -724,9 +724,9 @@ namespace ts { case SyntaxKind.BinaryExpression: if (getSpecialPropertyAssignmentKind(node as BinaryExpression) !== SpecialPropertyAssignmentKind.None) { - addDeclaration(node as BinaryExpression); + addDeclaration(node as BinaryExpression); } - // falls through + // falls through default: forEachChild(node, visit); @@ -1807,6 +1807,15 @@ namespace ts { return range && createTextSpanFromRange(range); } + function getSpanForPosition(fileName: string, position: number): TextSpan { + synchronizeHostData(); + + const sourceFile = getValidSourceFile(fileName); + const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocCcomment*/ false); + + return createTextSpan(node.getStart(), node.getWidth()); + } + function getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[] { // Note: while getting todo comments seems like a syntactic operation, we actually // treat it as a semantic operation here. This is because we expect our host to call @@ -2032,6 +2041,7 @@ namespace ts { getDocCommentTemplateAtPosition, isValidBraceCompletionAtPosition, getSpanOfEnclosingComment, + getSpanForPosition, getCodeFixesAtPosition, getEmitOutput, getNonBoundSourceFile, diff --git a/src/services/types.ts b/src/services/types.ts index e853eb7b96c..034b45100e0 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -273,6 +273,7 @@ namespace ts { isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean; getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan; + getSpanForPosition(fileName: string, position: number): TextSpan; getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[]; getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[]; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 151c948602d..1cf429546de 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -44,9 +44,9 @@ declare namespace ts { value: T; done: false; } | { - value: never; - done: true; - }; + value: never; + done: true; + }; } /** Array that is only intended to be pushed to, never read. */ interface Push { @@ -3942,6 +3942,7 @@ declare namespace ts { getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion; isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean; getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan; + getSpanForPosition(fileName: string, position: number): TextSpan; getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[]; getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined; @@ -4609,12 +4610,12 @@ declare namespace ts.server { module: {}; error: undefined; } | { - module: undefined; - error: { - stack?: string; - message?: string; + module: undefined; + error: { + stack?: string; + message?: string; + }; }; - }; interface ServerHost extends System { setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): any; clearTimeout(timeoutId: any): void; @@ -6887,6 +6888,7 @@ declare namespace ts.server { private getNameOrDottedNameSpan(args); private isValidBraceCompletion(args); private getQuickInfoWorker(args, simplifiedResult); + private getSpanForLocation(args); private getFormattingEditsForRange(args); private getFormattingEditsForRangeFull(args); private getFormattingEditsForDocumentFull(args); diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 14fae7d0d77..8350b2d7a9d 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -44,9 +44,9 @@ declare namespace ts { value: T; done: false; } | { - value: never; - done: true; - }; + value: never; + done: true; + }; } /** Array that is only intended to be pushed to, never read. */ interface Push { @@ -3942,6 +3942,7 @@ declare namespace ts { getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion; isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean; getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan; + getSpanForPosition(fileName: string, position: number): TextSpan; getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[]; getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined; From c6a8a32b710a3c8c3581c1792e7858c97e22318a Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Fri, 13 Oct 2017 16:36:25 -0700 Subject: [PATCH 007/235] Fixed api reference tests --- .../baselines/reference/api/tsserverlibrary.d.ts | 16 ++++++++-------- tests/baselines/reference/api/typescript.d.ts | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 1cf429546de..8beb5ff60e4 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -44,9 +44,9 @@ declare namespace ts { value: T; done: false; } | { - value: never; - done: true; - }; + value: never; + done: true; + }; } /** Array that is only intended to be pushed to, never read. */ interface Push { @@ -4610,12 +4610,12 @@ declare namespace ts.server { module: {}; error: undefined; } | { - module: undefined; - error: { - stack?: string; - message?: string; - }; + module: undefined; + error: { + stack?: string; + message?: string; }; + }; interface ServerHost extends System { setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): any; clearTimeout(timeoutId: any): void; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 8350b2d7a9d..2733bb20e56 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -44,9 +44,9 @@ declare namespace ts { value: T; done: false; } | { - value: never; - done: true; - }; + value: never; + done: true; + }; } /** Array that is only intended to be pushed to, never read. */ interface Push { From b86153da8806a0b9ee7aaa76cc549ee37b2dc3bc Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Mon, 16 Oct 2017 17:50:35 -0700 Subject: [PATCH 008/235] Changed command designed based on review input --- src/harness/harnessLanguageService.ts | 6 +- src/harness/unittests/session.ts | 1 + src/server/client.ts | 8 +-- src/server/protocol.ts | 8 ++- src/server/session.ts | 71 +++++++++++++------ src/services/services.ts | 25 ++++--- src/services/types.ts | 7 +- .../reference/api/tsserverlibrary.d.ts | 15 +++- tests/baselines/reference/api/typescript.d.ts | 6 +- 9 files changed, 103 insertions(+), 44 deletions(-) diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 34043195429..2ec40a8981d 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -432,6 +432,9 @@ namespace Harness.LanguageService { getDefinitionAtPosition(fileName: string, position: number): ts.DefinitionInfo[] { return unwrapJSONCallResult(this.shim.getDefinitionAtPosition(fileName, position)); } + getDefinitionAndBoundSpan(): ts.DefinitionInfoAndBoundSpan { + throw new Error("Not supported on the shim."); + } getTypeDefinitionAtPosition(fileName: string, position: number): ts.DefinitionInfo[] { return unwrapJSONCallResult(this.shim.getTypeDefinitionAtPosition(fileName, position)); } @@ -490,9 +493,6 @@ namespace Harness.LanguageService { getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): ts.TextSpan { return unwrapJSONCallResult(this.shim.getSpanOfEnclosingComment(fileName, position, onlyMultiLine)); } - getSpanForPosition(): ts.TextSpan { - throw new Error("Not supportred on the shim."); - } getCodeFixesAtPosition(): ts.CodeAction[] { throw new Error("Not supported on the shim."); } diff --git a/src/harness/unittests/session.ts b/src/harness/unittests/session.ts index 2ce5ef530e4..fd278dc3c3a 100644 --- a/src/harness/unittests/session.ts +++ b/src/harness/unittests/session.ts @@ -176,6 +176,7 @@ namespace ts.server { CommandNames.Definition, CommandNames.DefinitionFull, CommandNames.DefinitionAndBoundSpan, + CommandNames.DefinitionAndBoundSpanFull, CommandNames.Implementation, CommandNames.ImplementationFull, CommandNames.Exit, diff --git a/src/server/client.ts b/src/server/client.ts index f467f7f9224..0fe5f48ed31 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -268,6 +268,10 @@ namespace ts.server { })); } + getDefinitionAndBoundSpan(_fileName: string, _position: number): DefinitionInfoAndBoundSpan { + return notImplemented(); + } + getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] { const args: protocol.FileLocationRequestArgs = this.createFileLocationRequestArgs(fileName, position); @@ -531,10 +535,6 @@ namespace ts.server { return notImplemented(); } - getSpanForPosition(_fileName: string, _position: number): TextSpan { - return notImplemented(); - } - getCodeFixesAtPosition(file: string, start: number, end: number, errorCodes: number[]): CodeAction[] { const args: protocol.CodeFixRequestArgs = { ...this.createFileRangeRequestArgs(file, start, end), errorCodes }; diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 0685728c3b0..327c351ba6f 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -21,8 +21,9 @@ namespace ts.server.protocol { Definition = "definition", /* @internal */ DefinitionFull = "definition-full", - /* @internal */ DefinitionAndBoundSpan = "definitionAndBoundSpan", + /* @internal */ + DefinitionAndBoundSpanFull = "definitionAndBoundSpan-full", Implementation = "implementation", /* @internal */ ImplementationFull = "implementation-full", @@ -690,6 +691,11 @@ namespace ts.server.protocol { file: string; } + export interface DefinitionInfoAndBoundSpan { + definitions: ReadonlyArray; + textSpan: TextSpan; + } + /** * Definition response message. Gives text range for definition. */ diff --git a/src/server/session.ts b/src/server/session.ts index 5a8426f23b3..54ac3082c18 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -601,20 +601,57 @@ namespace ts.server { } if (simplifiedResult) { - return definitions.map(def => { - const defScriptInfo = project.getScriptInfo(def.fileName); - return { - file: def.fileName, - start: defScriptInfo.positionToLineOffset(def.textSpan.start), - end: defScriptInfo.positionToLineOffset(textSpanEnd(def.textSpan)) - }; - }); + return this.getSimplifiedDefinition(definitions, project); } else { return definitions; } } + private getDefinitionAndBoundSpan(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.DefinitionInfoAndBoundSpan | DefinitionInfoAndBoundSpan { + const { file, project } = this.getFileAndProject(args); + const position = this.getPositionInFile(args, file); + const scriptInfo = project.getScriptInfo(file); + + const definitionAndBoundSpan = project.getLanguageService().getDefinitionAndBoundSpan(file, position); + + if (!definitionAndBoundSpan || !definitionAndBoundSpan.definitions) { + return { + definitions: emptyArray, + textSpan: undefined + }; + } + + if (simplifiedResult) { + return { + definitions: this.getSimplifiedDefinition(definitionAndBoundSpan.definitions, project), + textSpan: this.getSimplifiedTextSpan(definitionAndBoundSpan.textSpan, scriptInfo) + }; + } + + return definitionAndBoundSpan; + } + + private getSimplifiedDefinition(definitions: ReadonlyArray, project: Project): ReadonlyArray { + return definitions.map(def => { + const defScriptInfo = project.getScriptInfo(def.fileName); + const simplifiedTextSpan = this.getSimplifiedTextSpan(def.textSpan, defScriptInfo); + + return { + file: def.fileName, + start: simplifiedTextSpan.start, + end: simplifiedTextSpan.end + }; + }); + } + + private getSimplifiedTextSpan(textSpan: TextSpan, scriptInfo: ScriptInfo): protocol.TextSpan { + return { + start: scriptInfo.positionToLineOffset(textSpan.start), + end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan)) + }; + } + private getTypeDefinition(args: protocol.FileLocationRequestArgs): ReadonlyArray { const { file, project } = this.getFileAndProject(args); const position = this.getPositionInFile(args, file); @@ -1081,13 +1118,6 @@ namespace ts.server { } } - private getSpanForLocation(args: protocol.FileLocationRequestArgs): TextSpan { - const { file, project } = this.getFileAndProject(args); - const scriptInfo = project.getScriptInfoForNormalizedPath(file); - - return project.getLanguageService().getSpanForPosition(file, this.getPosition(args, scriptInfo)); - } - private getFormattingEditsForRange(args: protocol.FormatRequestArgs): protocol.CodeEdit[] { const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args); const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); @@ -1715,13 +1745,10 @@ namespace ts.server { return this.requiredResponse(this.getDefinition(request.arguments, /*simplifiedResult*/ false)); }, [CommandNames.DefinitionAndBoundSpan]: (request: protocol.DefinitionRequest) => { - const definitions = this.getDefinition(request.arguments, /*simplifiedResult*/ false); - const textSpan = definitions.length !== 0 ? this.getSpanForLocation(request.arguments) : {}; - - return this.requiredResponse({ - definitions, - textSpan - }); + return this.requiredResponse(this.getDefinitionAndBoundSpan(request.arguments, /*simplifiedResult*/ true)); + }, + [CommandNames.DefinitionAndBoundSpanFull]: (request: protocol.DefinitionRequest) => { + return this.requiredResponse(this.getDefinitionAndBoundSpan(request.arguments, /*simplifiedResult*/ false)); }, [CommandNames.TypeDefinition]: (request: protocol.FileLocationRequest) => { return this.requiredResponse(this.getTypeDefinition(request.arguments)); diff --git a/src/services/services.ts b/src/services/services.ts index 5b24fa1947e..f2702082470 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1411,6 +1411,20 @@ namespace ts { return GoToDefinition.getDefinitionAtPosition(program, getValidSourceFile(fileName), position); } + function getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan { + const definitions = getDefinitionAtPosition(fileName, position); + + if (!definitions) { + return undefined; + } + + const sourceFile = getValidSourceFile(fileName); + const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); + const textSpan = createTextSpan(node.getStart(), node.getWidth()); + + return { definitions, textSpan }; + } + function getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] { synchronizeHostData(); return GoToDefinition.getTypeDefinitionAtPosition(program.getTypeChecker(), getValidSourceFile(fileName), position); @@ -1807,15 +1821,6 @@ namespace ts { return range && createTextSpanFromRange(range); } - function getSpanForPosition(fileName: string, position: number): TextSpan { - synchronizeHostData(); - - const sourceFile = getValidSourceFile(fileName); - const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocCcomment*/ false); - - return createTextSpan(node.getStart(), node.getWidth()); - } - function getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[] { // Note: while getting todo comments seems like a syntactic operation, we actually // treat it as a semantic operation here. This is because we expect our host to call @@ -2018,6 +2023,7 @@ namespace ts { getSignatureHelpItems, getQuickInfoAtPosition, getDefinitionAtPosition, + getDefinitionAndBoundSpan, getImplementationAtPosition, getTypeDefinitionAtPosition, getReferencesAtPosition, @@ -2041,7 +2047,6 @@ namespace ts { getDocCommentTemplateAtPosition, isValidBraceCompletionAtPosition, getSpanOfEnclosingComment, - getSpanForPosition, getCodeFixesAtPosition, getEmitOutput, getNonBoundSourceFile, diff --git a/src/services/types.ts b/src/services/types.ts index 034b45100e0..c6ab8c876f0 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -245,6 +245,7 @@ namespace ts { findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[]; getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[]; + getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan; getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[]; getImplementationAtPosition(fileName: string, position: number): ImplementationLocation[]; @@ -273,7 +274,6 @@ namespace ts { isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean; getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan; - getSpanForPosition(fileName: string, position: number): TextSpan; getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[]; getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[]; @@ -549,6 +549,11 @@ namespace ts { containerName: string; } + export interface DefinitionInfoAndBoundSpan { + definitions: ReadonlyArray; + textSpan: TextSpan; + } + export interface ReferencedSymbolDefinitionInfo extends DefinitionInfo { displayParts: SymbolDisplayPart[]; } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 8beb5ff60e4..b69b44e98a0 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3922,6 +3922,7 @@ declare namespace ts { getRenameInfo(fileName: string, position: number): RenameInfo; findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[]; getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[]; + getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan; getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[]; getImplementationAtPosition(fileName: string, position: number): ImplementationLocation[]; getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[]; @@ -3942,7 +3943,6 @@ declare namespace ts { getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion; isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean; getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan; - getSpanForPosition(fileName: string, position: number): TextSpan; getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[]; getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined; @@ -4174,6 +4174,10 @@ declare namespace ts { containerKind: ScriptElementKind; containerName: string; } + interface DefinitionInfoAndBoundSpan { + definitions: ReadonlyArray; + textSpan: TextSpan; + } interface ReferencedSymbolDefinitionInfo extends DefinitionInfo { displayParts: SymbolDisplayPart[]; } @@ -4793,6 +4797,7 @@ declare namespace ts.server.protocol { CompileOnSaveEmitFile = "compileOnSaveEmitFile", Configure = "configure", Definition = "definition", + DefinitionAndBoundSpan = "definitionAndBoundSpan", Implementation = "implementation", Exit = "exit", Format = "format", @@ -5298,6 +5303,10 @@ declare namespace ts.server.protocol { */ file: string; } + interface DefinitionInfoAndBoundSpan { + definitions: ReadonlyArray; + textSpan: TextSpan; + } /** * Definition response message. Gives text range for definition. */ @@ -6855,6 +6864,9 @@ declare namespace ts.server { private convertToDiagnosticsWithLinePosition(diagnostics, scriptInfo); private getDiagnosticsWorker(args, isSemantic, selector, includeLinePosition); private getDefinition(args, simplifiedResult); + private getDefinitionAndBoundSpan(args, simplifiedResult); + private getSimplifiedDefinition(definitions, project); + private getSimplifiedTextSpan(textSpan, scriptInfo); private getTypeDefinition(args); private getImplementation(args, simplifiedResult); private getOccurrences(args); @@ -6888,7 +6900,6 @@ declare namespace ts.server { private getNameOrDottedNameSpan(args); private isValidBraceCompletion(args); private getQuickInfoWorker(args, simplifiedResult); - private getSpanForLocation(args); private getFormattingEditsForRange(args); private getFormattingEditsForRangeFull(args); private getFormattingEditsForDocumentFull(args); diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 2733bb20e56..9f9319fd7fa 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3922,6 +3922,7 @@ declare namespace ts { getRenameInfo(fileName: string, position: number): RenameInfo; findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[]; getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[]; + getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan; getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[]; getImplementationAtPosition(fileName: string, position: number): ImplementationLocation[]; getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[]; @@ -3942,7 +3943,6 @@ declare namespace ts { getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion; isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean; getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan; - getSpanForPosition(fileName: string, position: number): TextSpan; getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[]; getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined; @@ -4174,6 +4174,10 @@ declare namespace ts { containerKind: ScriptElementKind; containerName: string; } + interface DefinitionInfoAndBoundSpan { + definitions: ReadonlyArray; + textSpan: TextSpan; + } interface ReferencedSymbolDefinitionInfo extends DefinitionInfo { displayParts: SymbolDisplayPart[]; } From 8004fec2ceebc69c2dad06c61990bb47c8cd8daf Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Wed, 18 Oct 2017 14:48:06 -0700 Subject: [PATCH 009/235] Addressed PR comments: added simplified/full version, changed design --- src/harness/harnessLanguageService.ts | 4 +-- src/server/client.ts | 19 ++++++++++-- src/server/protocol.ts | 4 +++ src/server/session.ts | 31 ++++++++++--------- src/services/goToDefinition.ts | 17 +++++++++- src/services/services.ts | 13 ++------ src/services/shims.ts | 13 ++++++++ .../reference/api/tsserverlibrary.d.ts | 8 +++-- 8 files changed, 76 insertions(+), 33 deletions(-) diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 2ec40a8981d..9740d493662 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -432,8 +432,8 @@ namespace Harness.LanguageService { getDefinitionAtPosition(fileName: string, position: number): ts.DefinitionInfo[] { return unwrapJSONCallResult(this.shim.getDefinitionAtPosition(fileName, position)); } - getDefinitionAndBoundSpan(): ts.DefinitionInfoAndBoundSpan { - throw new Error("Not supported on the shim."); + getDefinitionAndBoundSpan(fileName: string, position: number): ts.DefinitionInfoAndBoundSpan { + return unwrapJSONCallResult(this.shim.getDefinitionAndBoundSpan(fileName, position)); } getTypeDefinitionAtPosition(fileName: string, position: number): ts.DefinitionInfo[] { return unwrapJSONCallResult(this.shim.getTypeDefinitionAtPosition(fileName, position)); diff --git a/src/server/client.ts b/src/server/client.ts index 0fe5f48ed31..c0208d74903 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -268,8 +268,23 @@ namespace ts.server { })); } - getDefinitionAndBoundSpan(_fileName: string, _position: number): DefinitionInfoAndBoundSpan { - return notImplemented(); + getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan { + const args: protocol.FileLocationRequestArgs = this.createFileLocationRequestArgs(fileName, position); + + const request = this.processRequest(CommandNames.DefinitionAndBoundSpan, args); + const response = this.processResponse(request); + + return { + definitions: response.body.definitions.map(entry => ({ + containerKind: ScriptElementKind.unknown, + containerName: "", + fileName: entry.file, + textSpan: this.decodeSpan(entry), + kind: ScriptElementKind.unknown, + name: "" + })), + textSpan: this.decodeSpan(response.body.textSpan, request.arguments.file) + }; } getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] { diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 327c351ba6f..21b090548ff 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -703,6 +703,10 @@ namespace ts.server.protocol { body?: FileSpan[]; } + export interface DefinitionInfoAndBoundSpanReponse extends Response { + body?: DefinitionInfoAndBoundSpan; + } + /** * Definition response message. Gives text range for definition. */ diff --git a/src/server/session.ts b/src/server/session.ts index 54ac3082c18..fb37bf55408 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -601,7 +601,7 @@ namespace ts.server { } if (simplifiedResult) { - return this.getSimplifiedDefinition(definitions, project); + return this.getSimplifiedDefinitions(definitions, project); } else { return definitions; @@ -624,28 +624,29 @@ namespace ts.server { if (simplifiedResult) { return { - definitions: this.getSimplifiedDefinition(definitionAndBoundSpan.definitions, project), - textSpan: this.getSimplifiedTextSpan(definitionAndBoundSpan.textSpan, scriptInfo) + definitions: this.getSimplifiedDefinitions(definitionAndBoundSpan.definitions, project), + textSpan: this.getSimplifiedTextSpan(scriptInfo, definitionAndBoundSpan.textSpan) }; } return definitionAndBoundSpan; } - private getSimplifiedDefinition(definitions: ReadonlyArray, project: Project): ReadonlyArray { - return definitions.map(def => { - const defScriptInfo = project.getScriptInfo(def.fileName); - const simplifiedTextSpan = this.getSimplifiedTextSpan(def.textSpan, defScriptInfo); - - return { - file: def.fileName, - start: simplifiedTextSpan.start, - end: simplifiedTextSpan.end - }; - }); + private getSimplifiedDefinitions(definitions: ReadonlyArray, project: Project): ReadonlyArray { + return definitions.map(def => this.getSimplifiedFileSpan(def.fileName, def.textSpan, project)); } - private getSimplifiedTextSpan(textSpan: TextSpan, scriptInfo: ScriptInfo): protocol.TextSpan { + private getSimplifiedFileSpan(fileName: string, textSpan: TextSpan, project: Project): protocol.FileSpan { + const scriptInfo = project.getScriptInfo(fileName); + const simplifiedTextSpan = this.getSimplifiedTextSpan(scriptInfo, textSpan); + + return { + file: fileName, + ...simplifiedTextSpan + }; + } + + private getSimplifiedTextSpan(scriptInfo: ScriptInfo, textSpan: TextSpan): protocol.TextSpan { return { start: scriptInfo.positionToLineOffset(textSpan.start), end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan)) diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index cb2be7d484c..158d6d6ac6f 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -88,7 +88,7 @@ namespace ts.GoToDefinition { // } // bar(({pr/*goto*/op1})=>{}); if (isPropertyName(node) && isBindingElement(node.parent) && isObjectBindingPattern(node.parent.parent) && - (node === (node.parent.propertyName || node.parent.name))) { + (node === (node.parent.propertyName || node.parent.name))) { const type = typeChecker.getTypeAtLocation(node.parent.parent); if (type) { const propSymbols = getPropertySymbolsFromType(type, node); @@ -149,6 +149,21 @@ namespace ts.GoToDefinition { return getDefinitionFromSymbol(typeChecker, type.symbol, node); } + export function getDefinitionAndBoundSpan(program: Program, sourceFile: SourceFile, position: number): DefinitionInfoAndBoundSpan { + const definitions = getDefinitionAtPosition(program, sourceFile, position); + + if (!definitions || definitions.length === 0) { + return undefined; + } + + // TODO: Add textSpan for triple slash references (file and type). + + const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); + const textSpan = createTextSpan(node.getStart(), node.getWidth()); + + return { definitions, textSpan }; + } + // Go to the original declaration for cases: // // (1) when the aliased symbol was declared in the location(parent). diff --git a/src/services/services.ts b/src/services/services.ts index f2702082470..90ff50e45d0 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1412,17 +1412,8 @@ namespace ts { } function getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan { - const definitions = getDefinitionAtPosition(fileName, position); - - if (!definitions) { - return undefined; - } - - const sourceFile = getValidSourceFile(fileName); - const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); - const textSpan = createTextSpan(node.getStart(), node.getWidth()); - - return { definitions, textSpan }; + synchronizeHostData(); + return GoToDefinition.getDefinitionAndBoundSpan(program, getValidSourceFile(fileName), position); } function getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] { diff --git a/src/services/shims.ts b/src/services/shims.ts index 9d4baccc3c4..f97628d6388 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -170,6 +170,8 @@ namespace ts { */ getDefinitionAtPosition(fileName: string, position: number): string; + getDefinitionAndBoundSpan(fileName: string, position: number): string; + /** * Returns a JSON-encoded value of the type: * { fileName: string; textSpan: { start: number; length: number}; kind: string; name: string; containerKind: string; containerName: string } @@ -772,6 +774,17 @@ namespace ts { ); } + /** + * Computes the definition location and file for the symbol + * at the requested position. + */ + public getDefinitionAndBoundSpan(fileName: string, position: number): string { + return this.forwardJSONCall( + `getDefinitionAndBoundSpan('${fileName}', ${position})`, + () => this.languageService.getDefinitionAndBoundSpan(fileName, position) + ); + } + /// GOTO Type /** diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index b69b44e98a0..306f15e9521 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -5313,6 +5313,9 @@ declare namespace ts.server.protocol { interface DefinitionResponse extends Response { body?: FileSpan[]; } + interface DefinitionInfoAndBoundSpanReponse extends Response { + body?: DefinitionInfoAndBoundSpan; + } /** * Definition response message. Gives text range for definition. */ @@ -6865,8 +6868,9 @@ declare namespace ts.server { private getDiagnosticsWorker(args, isSemantic, selector, includeLinePosition); private getDefinition(args, simplifiedResult); private getDefinitionAndBoundSpan(args, simplifiedResult); - private getSimplifiedDefinition(definitions, project); - private getSimplifiedTextSpan(textSpan, scriptInfo); + private getSimplifiedDefinitions(definitions, project); + private getSimplifiedFileSpan(fileName, textSpan, project); + private getSimplifiedTextSpan(scriptInfo, textSpan); private getTypeDefinition(args); private getImplementation(args, simplifiedResult); private getOccurrences(args); From 16c32559886a31cf62b87be1fccb521ab9d5d2b4 Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Wed, 18 Oct 2017 15:49:46 -0700 Subject: [PATCH 010/235] Updated an incredible amount of tests. --- src/harness/fourslash.ts | 56 ++++++++++++++++--- src/services/goToDefinition.ts | 4 ++ .../ambientShorthandGotoDefinition.ts | 8 +-- tests/cases/fourslash/definition.ts | 2 +- .../fourslash/definitionNameOnEnumMember.ts | 2 +- .../fourslash/duplicatePackageServices.ts | 4 +- .../fourslash/findAllRefsForDefaultExport.ts | 2 +- tests/cases/fourslash/fourslash.ts | 1 + .../goToDefinitionAcrossMultipleProjects.ts | 2 +- tests/cases/fourslash/goToDefinitionAlias.ts | 8 +-- .../goToDefinitionApparentTypeProperties.ts | 4 +- ...efinitionConstructorOfClassExpression01.ts | 2 +- ...OfClassWhenClassIsPrecededByNamespace01.ts | 2 +- .../goToDefinitionConstructorOverloads.ts | 6 +- .../fourslash/goToDefinitionDecorator.ts | 4 +- .../goToDefinitionDecoratorOverloads.ts | 4 +- .../fourslash/goToDefinitionDynamicImport1.ts | 4 +- .../fourslash/goToDefinitionDynamicImport2.ts | 2 +- .../fourslash/goToDefinitionDynamicImport3.ts | 2 +- .../fourslash/goToDefinitionDynamicImport4.ts | 2 +- .../goToDefinitionExternalModuleName.ts | 2 +- .../goToDefinitionExternalModuleName2.ts | 2 +- .../goToDefinitionExternalModuleName3.ts | 2 +- .../goToDefinitionExternalModuleName5.ts | 2 +- .../goToDefinitionExternalModuleName6.ts | 2 +- .../goToDefinitionExternalModuleName7.ts | 2 +- .../goToDefinitionExternalModuleName8.ts | 2 +- .../goToDefinitionExternalModuleName9.ts | 2 +- .../goToDefinitionFunctionOverloads.ts | 8 +-- .../goToDefinitionFunctionOverloadsInClass.ts | 4 +- .../fourslash/goToDefinitionImportedNames.ts | 2 +- .../fourslash/goToDefinitionImportedNames2.ts | 2 +- .../fourslash/goToDefinitionImportedNames3.ts | 4 +- .../fourslash/goToDefinitionImportedNames4.ts | 2 +- .../fourslash/goToDefinitionImportedNames5.ts | 2 +- .../fourslash/goToDefinitionImportedNames6.ts | 2 +- .../fourslash/goToDefinitionImportedNames7.ts | 2 +- .../cases/fourslash/goToDefinitionImports.ts | 8 +-- .../goToDefinitionInMemberDeclaration.ts | 12 ++-- .../fourslash/goToDefinitionJsModuleName.ts | 2 +- tests/cases/fourslash/goToDefinitionLabels.ts | 6 +- .../goToDefinitionMethodOverloads.ts | 12 ++-- .../goToDefinitionMultipleDefinitions.ts | 4 +- ...itionObjectBindingElementPropertyName01.ts | 2 +- .../goToDefinitionObjectLiteralProperties1.ts | 4 +- .../fourslash/goToDefinitionObjectSpread.ts | 2 +- ...tionOverloadsInMultiplePropertyAccesses.ts | 2 +- .../goToDefinitionPartialImplementation.ts | 2 +- tests/cases/fourslash/goToDefinitionRest.ts | 2 +- .../goToDefinitionShorthandProperty01.ts | 6 +- .../goToDefinitionShorthandProperty02.ts | 2 +- .../goToDefinitionShorthandProperty03.ts | 4 +- tests/cases/fourslash/goToDefinitionSimple.ts | 4 +- .../goToDefinitionTaggedTemplateOverloads.ts | 4 +- tests/cases/fourslash/goToDefinitionThis.ts | 6 +- .../fourslash/goToDefinitionTypePredicate.ts | 2 +- .../goToDefinitionUnionTypeProperty1.ts | 2 +- .../goToDefinitionUnionTypeProperty2.ts | 2 +- .../goToDefinitionUnionTypeProperty3.ts | 2 +- .../goToDefinitionUnionTypeProperty4.ts | 2 +- tests/cases/fourslash/goToDefinition_super.ts | 4 +- .../fourslash/goToDefinition_untypedModule.ts | 2 +- .../fourslash/goToModuleAliasDefinition.ts | 2 +- .../gotoDefinitionInObjectBindingPattern1.ts | 2 +- .../gotoDefinitionInObjectBindingPattern2.ts | 2 +- ...nPropertyAccessExpressionHeritageClause.ts | 4 +- tests/cases/fourslash/javaScriptClass3.ts | 4 +- .../fourslash/jsdocTypedefTagServices.ts | 2 +- tests/cases/fourslash/server/definition01.ts | 2 +- .../server/jsdocTypedefTagGoToDefinition.ts | 4 +- .../fourslash/tsxGoToDefinitionClasses.ts | 6 +- .../fourslash/tsxGoToDefinitionIntrinsics.ts | 6 +- .../tsxGoToDefinitionStatelessFunction1.ts | 8 +-- .../tsxGoToDefinitionStatelessFunction2.ts | 12 ++-- .../tsxGoToDefinitionUnionElementType1.ts | 2 +- .../tsxGoToDefinitionUnionElementType2.ts | 2 +- 76 files changed, 184 insertions(+), 139 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index de6d92eda05..a95221e3b26 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -584,18 +584,23 @@ namespace FourSlash { public verifyGoToDefinition(arg0: any, endMarkerNames?: string | string[]) { this.verifyGoToX(arg0, endMarkerNames, () => this.getGoToDefinition()); + this.verifyGoToX(arg0, endMarkerNames, () => this.getGoToDefinitionAndBoundSpan()); } private getGoToDefinition(): ts.DefinitionInfo[] { return this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); } + private getGoToDefinitionAndBoundSpan(): ts.DefinitionInfoAndBoundSpan { + return this.languageService.getDefinitionAndBoundSpan(this.activeFile.fileName, this.currentCaretPosition); + } + public verifyGoToType(arg0: any, endMarkerNames?: string | string[]) { this.verifyGoToX(arg0, endMarkerNames, () => this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition)); } - private verifyGoToX(arg0: any, endMarkerNames: string | string[] | undefined, getDefs: () => ts.DefinitionInfo[] | undefined) { + private verifyGoToX(arg0: any, endMarkerNames: string | string[] | undefined, getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) { if (endMarkerNames) { this.verifyGoToXPlain(arg0, endMarkerNames, getDefs); } @@ -615,7 +620,7 @@ namespace FourSlash { } } - private verifyGoToXPlain(startMarkerNames: string | string[], endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | undefined) { + private verifyGoToXPlain(startMarkerNames: string | string[], endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) { for (const start of toArray(startMarkerNames)) { this.verifyGoToXSingle(start, endMarkerNames, getDefs); } @@ -627,26 +632,60 @@ namespace FourSlash { } } - private verifyGoToXSingle(startMarkerName: string, endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | undefined) { + private verifyGoToXSingle(startMarkerName: string, endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) { this.goToMarker(startMarkerName); - this.verifyGoToXWorker(toArray(endMarkerNames), getDefs); + this.verifyGoToXWorker(toArray(endMarkerNames), getDefs, startMarkerName); } - private verifyGoToXWorker(endMarkers: string[], getDefs: () => ts.DefinitionInfo[] | undefined) { - const definitions = getDefs() || []; + private verifyGoToXWorker(endMarkers: string[], getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined, startMarkerName?: string) { + const defs = getDefs(); + let definitions: ts.DefinitionInfo[] | ReadonlyArray; + let testName: string; + if (this.isDefinitionInfoAndBoundSpan(defs)) { + this.verifyDefinitionTextSpan(defs, startMarkerName); + + definitions = defs.definitions; + testName = "goToDefinitionsAndBoundSpan"; + } + else { + definitions = defs || []; + testName = "goToDefinitions"; + } if (endMarkers.length !== definitions.length) { - this.raiseError(`goToDefinitions failed - expected to find ${endMarkers.length} definitions but got ${definitions.length}`); + this.raiseError(`${testName} failed - expected to find ${endMarkers.length} definitions but got ${definitions.length}`); } ts.zipWith(endMarkers, definitions, (endMarker, definition, i) => { const marker = this.getMarkerByName(endMarker); if (marker.fileName !== definition.fileName || marker.position !== definition.textSpan.start) { - this.raiseError(`goToDefinition failed for definition ${endMarker} (${i}): expected ${marker.fileName} at ${marker.position}, got ${definition.fileName} at ${definition.textSpan.start}`); + this.raiseError(`${testName} failed for definition ${endMarker} (${i}): expected ${marker.fileName} at ${marker.position}, got ${definition.fileName} at ${definition.textSpan.start}`); } }); } + private verifyDefinitionTextSpan(defs: ts.DefinitionInfoAndBoundSpan, startMarkerName: string) { + const range = this.testData.ranges.find(range => this.markerName(range.marker) === startMarkerName); + + if (!range && !defs.textSpan) { + return; + } + + if (!range) { + this.raiseError(`goToDefinitionsAndBoundSpan failed - found a TextSpan ${JSON.stringify(defs.textSpan)} when it wasn't expected.`); + } + else if (defs.textSpan.start !== range.start || defs.textSpan.length !== range.end - range.start) { + const expected: ts.TextSpan = { + start: range.start, length: range.end - range.start + }; + this.raiseError(`goToDefinitionsAndBoundSpan failed - expected to find TextSpan ${JSON.stringify(expected)} but got ${JSON.stringify(defs.textSpan)}`); + } + } + + private isDefinitionInfoAndBoundSpan(definition: ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined): definition is ts.DefinitionInfoAndBoundSpan { + return definition && (definition).definitions !== undefined; + } + public verifyGetEmitOutputForCurrentFile(expected: string): void { const emit = this.languageService.getEmitOutput(this.activeFile.fileName); if (emit.outputFiles.length !== 1) { @@ -3828,6 +3867,7 @@ namespace FourSlashInterface { } public goToDefinition(startMarkerName: string | string[], endMarkerName: string | string[]): void; + public goToDefinition(startMarkerName: string | string[], endMarkerName: string | string[], range: FourSlash.Range): void; public goToDefinition(startsAndEnds: [string | string[], string | string[]][]): void; public goToDefinition(startsAndEnds: { [startMarkerName: string]: string | string[] }): void; public goToDefinition(arg0: any, endMarkerName?: string | string[]) { diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 158d6d6ac6f..eaee0afdd1e 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -157,6 +157,10 @@ namespace ts.GoToDefinition { } // TODO: Add textSpan for triple slash references (file and type). + const comment = findReferenceInPosition(sourceFile.referencedFiles, position); + if (comment && tryResolveScriptReference(program, sourceFile, comment) || findReferenceInPosition(sourceFile.typeReferenceDirectives, position)) { + return { definitions, textSpan: undefined }; + } const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); const textSpan = createTextSpan(node.getStart(), node.getWidth()); diff --git a/tests/cases/fourslash/ambientShorthandGotoDefinition.ts b/tests/cases/fourslash/ambientShorthandGotoDefinition.ts index 74e348beb74..f0e717999cf 100644 --- a/tests/cases/fourslash/ambientShorthandGotoDefinition.ts +++ b/tests/cases/fourslash/ambientShorthandGotoDefinition.ts @@ -5,10 +5,10 @@ // @Filename: user.ts /////// -////import /*importFoo*/foo, {bar} from "jquery"; -////import * as /*importBaz*/baz from "jquery"; -////import /*importBang*/bang = require("jquery"); -////foo/*useFoo*/(bar/*useBar*/, baz/*useBaz*/, bang/*useBang*/); +////import [|/*importFoo*/foo|], {bar} from "jquery"; +////import * as [|/*importBaz*/baz|] from "jquery"; +////import [|/*importBang*/bang|] = require("jquery"); +////[|foo/*useFoo*/|]([|bar/*useBar*/|], [|baz/*useBaz*/|], [|bang/*useBang*/|]); verify.quickInfoAt("useFoo", "import foo"); verify.goToDefinition({ diff --git a/tests/cases/fourslash/definition.ts b/tests/cases/fourslash/definition.ts index 705cdd65583..f91d8a9e346 100644 --- a/tests/cases/fourslash/definition.ts +++ b/tests/cases/fourslash/definition.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////import n = require('./a/*1*/'); +////import n = require([|'./a/*1*/'|]); ////var x = new n.Foo(); // @Filename: a.ts diff --git a/tests/cases/fourslash/definitionNameOnEnumMember.ts b/tests/cases/fourslash/definitionNameOnEnumMember.ts index b82b0dc0465..5529dc2bb55 100644 --- a/tests/cases/fourslash/definitionNameOnEnumMember.ts +++ b/tests/cases/fourslash/definitionNameOnEnumMember.ts @@ -5,7 +5,7 @@ //// secondMember, //// thirdMember ////} -////var enumMember = e./*1*/thirdMember; +////var enumMember = e.[|/*1*/thirdMember|]; goTo.marker("1"); verify.goToDefinitionName("thirdMember", "e"); diff --git a/tests/cases/fourslash/duplicatePackageServices.ts b/tests/cases/fourslash/duplicatePackageServices.ts index 360611ad140..c84c43cdd9e 100644 --- a/tests/cases/fourslash/duplicatePackageServices.ts +++ b/tests/cases/fourslash/duplicatePackageServices.ts @@ -2,7 +2,7 @@ // @noImplicitReferences: true // @Filename: /node_modules/a/index.d.ts -////import /*useAX*/[|{| "isWriteAccess": true, "isDefinition": true |}X|] from "x"; +////import [|{| "name": "useAX", "isWriteAccess": true, "isDefinition": true |}X|] from "x"; ////export function a(x: [|X|]): void; // @Filename: /node_modules/a/node_modules/x/index.d.ts @@ -14,7 +14,7 @@ ////{ "name": "x", "version": "1.2.3" } // @Filename: /node_modules/b/index.d.ts -////import /*useBX*/[|{| "isWriteAccess": true, "isDefinition": true |}X|] from "x"; +////import [|{| "name": "useBX", "isWriteAccess": true, "isDefinition": true |}X|] from "x"; ////export const b: [|X|]; // @Filename: /node_modules/b/node_modules/x/index.d.ts diff --git a/tests/cases/fourslash/findAllRefsForDefaultExport.ts b/tests/cases/fourslash/findAllRefsForDefaultExport.ts index 7cd6fe8d57c..414b2503391 100644 --- a/tests/cases/fourslash/findAllRefsForDefaultExport.ts +++ b/tests/cases/fourslash/findAllRefsForDefaultExport.ts @@ -5,7 +5,7 @@ // @Filename: b.ts ////import [|{| "isWriteAccess": true, "isDefinition": true |}g|] from "./a"; -/////*ref*/[|g|](); +////[|/*ref*/g|](); // @Filename: c.ts ////import { f } from "./a"; diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index f4d47abc9c9..5a0bd4bd2e7 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -193,6 +193,7 @@ declare namespace FourSlashInterface { * `verify.goToDefinition("a", ["b", "bb"]);` verifies that "a" has multiple definitions available. */ goToDefinition(startMarkerNames: string | string[], endMarkerNames: string | string[]): void; + goToDefinition(startMarkerNames: string | string[], endMarkerNames: string | string[], range: Range): void; /** Performs `goToDefinition` for each pair. */ goToDefinition(startsAndEnds: [string | string[], string | string[]][]): void; /** Performs `goToDefinition` on each key and value. */ diff --git a/tests/cases/fourslash/goToDefinitionAcrossMultipleProjects.ts b/tests/cases/fourslash/goToDefinitionAcrossMultipleProjects.ts index 7c0565c626a..5447609c027 100644 --- a/tests/cases/fourslash/goToDefinitionAcrossMultipleProjects.ts +++ b/tests/cases/fourslash/goToDefinitionAcrossMultipleProjects.ts @@ -9,6 +9,6 @@ //@Filename: c.ts /////// /////// -/////*use*/x++; +////[|/*use*/x|]++; verify.goToDefinition("use", ["def1", "def2"]); diff --git a/tests/cases/fourslash/goToDefinitionAlias.ts b/tests/cases/fourslash/goToDefinitionAlias.ts index 22aa049fde3..66afe07b633 100644 --- a/tests/cases/fourslash/goToDefinitionAlias.ts +++ b/tests/cases/fourslash/goToDefinitionAlias.ts @@ -7,12 +7,12 @@ ////} //// ////// Type position -////var t1: /*alias1Type*/alias1.IFoo; -////var t2: Module./*alias2Type*/alias2.IFoo; +////var t1: [|/*alias1Type*/alias1|].IFoo; +////var t2: Module.[|/*alias2Type*/alias2|].IFoo; //// ////// Value posistion -////var v1 = new /*alias1Value*/alias1.Foo(); -////var v2 = new Module./*alias2Value*/alias2.Foo(); +////var v1 = new [|/*alias1Value*/alias1|].Foo(); +////var v2 = new Module.[|/*alias2Value*/alias2|].Foo(); // @Filename: a.ts diff --git a/tests/cases/fourslash/goToDefinitionApparentTypeProperties.ts b/tests/cases/fourslash/goToDefinitionApparentTypeProperties.ts index dd0d91810c4..5d4ec896380 100644 --- a/tests/cases/fourslash/goToDefinitionApparentTypeProperties.ts +++ b/tests/cases/fourslash/goToDefinitionApparentTypeProperties.ts @@ -5,7 +5,7 @@ ////} //// ////var o = 0; -////o./*reference1*/myObjectMethod(); -////o["/*reference2*/myObjectMethod"](); +////o.[|/*reference1*/myObjectMethod|](); +////o[[|"/*reference2*/myObjectMethod"|]](); verify.goToDefinition(["reference1", "reference2"], "definition"); diff --git a/tests/cases/fourslash/goToDefinitionConstructorOfClassExpression01.ts b/tests/cases/fourslash/goToDefinitionConstructorOfClassExpression01.ts index 4b774b8b0ee..b9f17611b18 100644 --- a/tests/cases/fourslash/goToDefinitionConstructorOfClassExpression01.ts +++ b/tests/cases/fourslash/goToDefinitionConstructorOfClassExpression01.ts @@ -2,7 +2,7 @@ ////var x = class C { //// /*definition*/constructor() { -//// var other = new /*usage*/C; +//// var other = new [|/*usage*/C|]; //// } ////} diff --git a/tests/cases/fourslash/goToDefinitionConstructorOfClassWhenClassIsPrecededByNamespace01.ts b/tests/cases/fourslash/goToDefinitionConstructorOfClassWhenClassIsPrecededByNamespace01.ts index bf698c0752d..8f1bc2496dc 100644 --- a/tests/cases/fourslash/goToDefinitionConstructorOfClassWhenClassIsPrecededByNamespace01.ts +++ b/tests/cases/fourslash/goToDefinitionConstructorOfClassWhenClassIsPrecededByNamespace01.ts @@ -9,6 +9,6 @@ //// } ////} //// -////var x = new /*usage*/Foo(); +////var x = new [|/*usage*/Foo|](); verify.goToDefinition("usage", "definition"); diff --git a/tests/cases/fourslash/goToDefinitionConstructorOverloads.ts b/tests/cases/fourslash/goToDefinitionConstructorOverloads.ts index a3a5e3286b2..edc9e85d444 100644 --- a/tests/cases/fourslash/goToDefinitionConstructorOverloads.ts +++ b/tests/cases/fourslash/goToDefinitionConstructorOverloads.ts @@ -1,13 +1,13 @@ /// ////class ConstructorOverload { -//// /*constructorOverload1*/constructor(); +//// [|/*constructorOverload1*/constructor|](); //// /*constructorOverload2*/constructor(foo: string); //// /*constructorDefinition*/constructor(foo: any) { } ////} //// -////var constructorOverload = new /*constructorOverloadReference1*/ConstructorOverload(); -////var constructorOverload = new /*constructorOverloadReference2*/ConstructorOverload("foo"); +////var constructorOverload = new [|/*constructorOverloadReference1*/ConstructorOverload|](); +////var constructorOverload = new [|/*constructorOverloadReference2*/ConstructorOverload|]("foo"); verify.goToDefinition({ constructorOverloadReference1: "constructorOverload1", diff --git a/tests/cases/fourslash/goToDefinitionDecorator.ts b/tests/cases/fourslash/goToDefinitionDecorator.ts index bef9c8fa5f1..535726aef08 100644 --- a/tests/cases/fourslash/goToDefinitionDecorator.ts +++ b/tests/cases/fourslash/goToDefinitionDecorator.ts @@ -1,9 +1,9 @@ /// // @Filename: b.ts -////@/*decoratorUse*/decorator +////@[|/*decoratorUse*/decorator|] ////class C { -//// @decora/*decoratorFactoryUse*/torFactory(a, "22", true) +//// @[|decora/*decoratorFactoryUse*/torFactory|](a, "22", true) //// method() {} ////} diff --git a/tests/cases/fourslash/goToDefinitionDecoratorOverloads.ts b/tests/cases/fourslash/goToDefinitionDecoratorOverloads.ts index 965c8bbbc6d..4943c23e392 100644 --- a/tests/cases/fourslash/goToDefinitionDecoratorOverloads.ts +++ b/tests/cases/fourslash/goToDefinitionDecoratorOverloads.ts @@ -9,8 +9,8 @@ //// ////declare const s: symbol; ////class C { -//// @/*useDecString*/dec f() {} -//// @/*useDecSymbol*/dec [s]() {} +//// @[|/*useDecString*/dec|] f() {} +//// @[|/*useDecSymbol*/dec|] [s]() {} ////} verify.goToDefinition({ diff --git a/tests/cases/fourslash/goToDefinitionDynamicImport1.ts b/tests/cases/fourslash/goToDefinitionDynamicImport1.ts index 2e93534496a..d85ba12d725 100644 --- a/tests/cases/fourslash/goToDefinitionDynamicImport1.ts +++ b/tests/cases/fourslash/goToDefinitionDynamicImport1.ts @@ -3,8 +3,8 @@ // @Filename: foo.ts //// /*Destination*/export function foo() { return "foo"; } -//// import("./f/*1*/oo") -//// var x = import("./fo/*2*/o") +//// import([|"./f/*1*/oo"|]) +//// var x = import([|"./fo/*2*/o"|]) verify.goToDefinition("1", "Destination"); verify.goToDefinition("2", "Destination"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToDefinitionDynamicImport2.ts b/tests/cases/fourslash/goToDefinitionDynamicImport2.ts index c3c213a6cdb..678628d641f 100644 --- a/tests/cases/fourslash/goToDefinitionDynamicImport2.ts +++ b/tests/cases/fourslash/goToDefinitionDynamicImport2.ts @@ -5,7 +5,7 @@ //// var x = import("./foo"); //// x.then(foo => { -//// foo.b/*1*/ar(); +//// foo.[|b/*1*/ar|](); //// }) verify.goToDefinition("1", "Destination"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToDefinitionDynamicImport3.ts b/tests/cases/fourslash/goToDefinitionDynamicImport3.ts index f8c5962f984..dc63696d62a 100644 --- a/tests/cases/fourslash/goToDefinitionDynamicImport3.ts +++ b/tests/cases/fourslash/goToDefinitionDynamicImport3.ts @@ -3,6 +3,6 @@ // @Filename: foo.ts //// export function /*Destination*/bar() { return "bar"; } -//// import('./foo').then(({ ba/*1*/r }) => undefined); +//// import('./foo').then(({ [|ba/*1*/r|] }) => undefined); verify.goToDefinition("1", "Destination"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToDefinitionDynamicImport4.ts b/tests/cases/fourslash/goToDefinitionDynamicImport4.ts index f8c5962f984..dc63696d62a 100644 --- a/tests/cases/fourslash/goToDefinitionDynamicImport4.ts +++ b/tests/cases/fourslash/goToDefinitionDynamicImport4.ts @@ -3,6 +3,6 @@ // @Filename: foo.ts //// export function /*Destination*/bar() { return "bar"; } -//// import('./foo').then(({ ba/*1*/r }) => undefined); +//// import('./foo').then(({ [|ba/*1*/r|] }) => undefined); verify.goToDefinition("1", "Destination"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToDefinitionExternalModuleName.ts b/tests/cases/fourslash/goToDefinitionExternalModuleName.ts index 705cdd65583..f91d8a9e346 100644 --- a/tests/cases/fourslash/goToDefinitionExternalModuleName.ts +++ b/tests/cases/fourslash/goToDefinitionExternalModuleName.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////import n = require('./a/*1*/'); +////import n = require([|'./a/*1*/'|]); ////var x = new n.Foo(); // @Filename: a.ts diff --git a/tests/cases/fourslash/goToDefinitionExternalModuleName2.ts b/tests/cases/fourslash/goToDefinitionExternalModuleName2.ts index 866d21b3632..913b297feb8 100644 --- a/tests/cases/fourslash/goToDefinitionExternalModuleName2.ts +++ b/tests/cases/fourslash/goToDefinitionExternalModuleName2.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////import n = require('./a/*1*/'); +////import n = require([|'./a/*1*/'|]); ////var x = new n.Foo(); // @Filename: a.ts diff --git a/tests/cases/fourslash/goToDefinitionExternalModuleName3.ts b/tests/cases/fourslash/goToDefinitionExternalModuleName3.ts index 7ac0376474d..d6e28263239 100644 --- a/tests/cases/fourslash/goToDefinitionExternalModuleName3.ts +++ b/tests/cases/fourslash/goToDefinitionExternalModuleName3.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////import n = require('e/*1*/'); +////import n = require([|'e/*1*/'|]); ////var x = new n.Foo(); // @Filename: a.ts diff --git a/tests/cases/fourslash/goToDefinitionExternalModuleName5.ts b/tests/cases/fourslash/goToDefinitionExternalModuleName5.ts index 36ae9dd716f..9dede44a7bc 100644 --- a/tests/cases/fourslash/goToDefinitionExternalModuleName5.ts +++ b/tests/cases/fourslash/goToDefinitionExternalModuleName5.ts @@ -1,7 +1,7 @@ /// // @Filename: a.ts -////declare module /*2*/"external/*1*/" { +////declare module /*2*/[|"external/*1*/"|] { //// class Foo { } ////} diff --git a/tests/cases/fourslash/goToDefinitionExternalModuleName6.ts b/tests/cases/fourslash/goToDefinitionExternalModuleName6.ts index a71030628e6..51b96cfe3ba 100644 --- a/tests/cases/fourslash/goToDefinitionExternalModuleName6.ts +++ b/tests/cases/fourslash/goToDefinitionExternalModuleName6.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////import * from 'e/*1*/'; +////import * from [|'e/*1*/'|]; // @Filename: a.ts ////declare module /*2*/"e" { diff --git a/tests/cases/fourslash/goToDefinitionExternalModuleName7.ts b/tests/cases/fourslash/goToDefinitionExternalModuleName7.ts index b025944d012..591577bf470 100644 --- a/tests/cases/fourslash/goToDefinitionExternalModuleName7.ts +++ b/tests/cases/fourslash/goToDefinitionExternalModuleName7.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////import {Foo, Bar} from 'e/*1*/'; +////import {Foo, Bar} from [|'e/*1*/'|]; // @Filename: a.ts ////declare module /*2*/"e" { diff --git a/tests/cases/fourslash/goToDefinitionExternalModuleName8.ts b/tests/cases/fourslash/goToDefinitionExternalModuleName8.ts index ca9d7c83e66..636c234c79e 100644 --- a/tests/cases/fourslash/goToDefinitionExternalModuleName8.ts +++ b/tests/cases/fourslash/goToDefinitionExternalModuleName8.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////export {Foo, Bar} from 'e/*1*/'; +////export {Foo, Bar} from [|'e/*1*/'|]; // @Filename: a.ts ////declare module /*2*/"e" { diff --git a/tests/cases/fourslash/goToDefinitionExternalModuleName9.ts b/tests/cases/fourslash/goToDefinitionExternalModuleName9.ts index 80971be100f..60decba626c 100644 --- a/tests/cases/fourslash/goToDefinitionExternalModuleName9.ts +++ b/tests/cases/fourslash/goToDefinitionExternalModuleName9.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////export * from 'e/*1*/'; +////export * from [|'e/*1*/'|]; // @Filename: a.ts ////declare module /*2*/"e" { diff --git a/tests/cases/fourslash/goToDefinitionFunctionOverloads.ts b/tests/cases/fourslash/goToDefinitionFunctionOverloads.ts index 60c7a8111ee..ca3883be86c 100644 --- a/tests/cases/fourslash/goToDefinitionFunctionOverloads.ts +++ b/tests/cases/fourslash/goToDefinitionFunctionOverloads.ts @@ -1,12 +1,12 @@ /// -////function /*functionOverload1*/functionOverload(value: number); +////function [|/*functionOverload1*/functionOverload|](value: number); ////function /*functionOverload2*/functionOverload(value: string); ////function /*functionOverloadDefinition*/functionOverload() {} //// -/////*functionOverloadReference1*/functionOverload(123); -/////*functionOverloadReference2*/functionOverload("123"); -/////*brokenOverload*/functionOverload({}); +////[|/*functionOverloadReference1*/functionOverload|](123); +////[|/*functionOverloadReference2*/functionOverload|]("123"); +////[|/*brokenOverload*/functionOverload|]({}); verify.goToDefinition({ functionOverloadReference1: "functionOverload1", diff --git a/tests/cases/fourslash/goToDefinitionFunctionOverloadsInClass.ts b/tests/cases/fourslash/goToDefinitionFunctionOverloadsInClass.ts index 04017123fd8..08ec93b5eea 100644 --- a/tests/cases/fourslash/goToDefinitionFunctionOverloadsInClass.ts +++ b/tests/cases/fourslash/goToDefinitionFunctionOverloadsInClass.ts @@ -2,9 +2,9 @@ ////class clsInOverload { //// static fnOverload(); -//// static /*staticFunctionOverload*/fnOverload(foo: string); +//// static [|/*staticFunctionOverload*/fnOverload|](foo: string); //// static /*staticFunctionOverloadDefinition*/fnOverload(foo: any) { } -//// public /*functionOverload*/fnOverload(): any; +//// public [|/*functionOverload*/fnOverload|](): any; //// public fnOverload(foo: string); //// public /*functionOverloadDefinition*/fnOverload(foo: any) { return "foo" } //// diff --git a/tests/cases/fourslash/goToDefinitionImportedNames.ts b/tests/cases/fourslash/goToDefinitionImportedNames.ts index 41a1c443b28..c525783b9c2 100644 --- a/tests/cases/fourslash/goToDefinitionImportedNames.ts +++ b/tests/cases/fourslash/goToDefinitionImportedNames.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////export {/*classAliasDefinition*/Class} from "./a"; +////export {[|/*classAliasDefinition*/Class|]} from "./a"; // @Filename: a.ts diff --git a/tests/cases/fourslash/goToDefinitionImportedNames2.ts b/tests/cases/fourslash/goToDefinitionImportedNames2.ts index fa3c5c862b7..58a5d018eef 100644 --- a/tests/cases/fourslash/goToDefinitionImportedNames2.ts +++ b/tests/cases/fourslash/goToDefinitionImportedNames2.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////import {/*classAliasDefinition*/Class} from "./a"; +////import {[|/*classAliasDefinition*/Class|]} from "./a"; // @Filename: a.ts diff --git a/tests/cases/fourslash/goToDefinitionImportedNames3.ts b/tests/cases/fourslash/goToDefinitionImportedNames3.ts index b9f598f30cd..ea52f660c11 100644 --- a/tests/cases/fourslash/goToDefinitionImportedNames3.ts +++ b/tests/cases/fourslash/goToDefinitionImportedNames3.ts @@ -1,8 +1,8 @@ /// // @Filename: e.ts -//// import {M, /*classAliasDefinition*/C, I} from "./d"; -//// var c = new /*classReference*/C(); +//// import {M, [|/*classAliasDefinition*/C|], I} from "./d"; +//// var c = new [|/*classReference*/C|](); // @Filename: d.ts diff --git a/tests/cases/fourslash/goToDefinitionImportedNames4.ts b/tests/cases/fourslash/goToDefinitionImportedNames4.ts index 81f2e671266..435ab41a2ad 100644 --- a/tests/cases/fourslash/goToDefinitionImportedNames4.ts +++ b/tests/cases/fourslash/goToDefinitionImportedNames4.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////import {Class as /*classAliasDefinition*/ClassAlias} from "./a"; +////import {Class as [|/*classAliasDefinition*/ClassAlias|]} from "./a"; // @Filename: a.ts diff --git a/tests/cases/fourslash/goToDefinitionImportedNames5.ts b/tests/cases/fourslash/goToDefinitionImportedNames5.ts index b78110c95d9..7965b341d9e 100644 --- a/tests/cases/fourslash/goToDefinitionImportedNames5.ts +++ b/tests/cases/fourslash/goToDefinitionImportedNames5.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////export {Class as /*classAliasDefinition*/ClassAlias} from "./a"; +////export {Class as [|/*classAliasDefinition*/ClassAlias|]} from "./a"; // @Filename: a.ts diff --git a/tests/cases/fourslash/goToDefinitionImportedNames6.ts b/tests/cases/fourslash/goToDefinitionImportedNames6.ts index 21603cded42..a8acf33e42a 100644 --- a/tests/cases/fourslash/goToDefinitionImportedNames6.ts +++ b/tests/cases/fourslash/goToDefinitionImportedNames6.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////import /*moduleAliasDefinition*/alias = require("./a"); +////import [|/*moduleAliasDefinition*/alias|] = require("./a"); // @Filename: a.ts diff --git a/tests/cases/fourslash/goToDefinitionImportedNames7.ts b/tests/cases/fourslash/goToDefinitionImportedNames7.ts index bdf1eff86eb..d798dcfff0c 100644 --- a/tests/cases/fourslash/goToDefinitionImportedNames7.ts +++ b/tests/cases/fourslash/goToDefinitionImportedNames7.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////import /*classAliasDefinition*/defaultExport from "./a"; +////import [|/*classAliasDefinition*/defaultExport|] from "./a"; // @Filename: a.ts diff --git a/tests/cases/fourslash/goToDefinitionImports.ts b/tests/cases/fourslash/goToDefinitionImports.ts index 4fdaedb5c3d..1debd3c6b6f 100644 --- a/tests/cases/fourslash/goToDefinitionImports.ts +++ b/tests/cases/fourslash/goToDefinitionImports.ts @@ -12,10 +12,10 @@ ////import f, { x } from "./a"; ////import * as /*aDef*/a from "./a"; ////import b = require("./b"); -/////*fUse*/f; -/////*xUse*/x; -/////*aUse*/a; -/////*bUse*/b; +////[|/*fUse*/f|]; +////[|/*xUse*/x|]; +////[|/*aUse*/a|]; +////[|/*bUse*/b|]; verify.goToDefinition({ aUse: "aDef", // Namespace import isn't "skipped" diff --git a/tests/cases/fourslash/goToDefinitionInMemberDeclaration.ts b/tests/cases/fourslash/goToDefinitionInMemberDeclaration.ts index 93be2086440..4a09a931bf6 100644 --- a/tests/cases/fourslash/goToDefinitionInMemberDeclaration.ts +++ b/tests/cases/fourslash/goToDefinitionInMemberDeclaration.ts @@ -9,13 +9,13 @@ ////enum /*enumDefinition*/Enum { value1, value2 }; //// ////class /*selfDefinition*/Bar { -//// public _interface: IFo/*interfaceReference*/o = new Fo/*classReferenceInInitializer*/o(); -//// public _class: Fo/*classReference*/o = new Foo(); -//// public _list: IF/*interfaceReferenceInList*/oo[]=[]; -//// public _enum: E/*enumReference*/num = En/*enumReferenceInInitializer*/um.value1; -//// public _self: Ba/*selfReference*/r; +//// public _interface: [|IFo/*interfaceReference*/o|] = new [|Fo/*classReferenceInInitializer*/o|](); +//// public _class: [|Fo/*classReference*/o|] = new Foo(); +//// public _list: [|IF/*interfaceReferenceInList*/oo|][]=[]; +//// public _enum: [|E/*enumReference*/num|] = [|En/*enumReferenceInInitializer*/um|].value1; +//// public _self: [|Ba/*selfReference*/r|]; //// -//// constructor(public _inConstructor: IFo/*interfaceReferenceInConstructor*/o) { +//// constructor(public _inConstructor: [|IFo/*interfaceReferenceInConstructor*/o|]) { //// } ////} diff --git a/tests/cases/fourslash/goToDefinitionJsModuleName.ts b/tests/cases/fourslash/goToDefinitionJsModuleName.ts index cdd322158f7..8514e7070e4 100644 --- a/tests/cases/fourslash/goToDefinitionJsModuleName.ts +++ b/tests/cases/fourslash/goToDefinitionJsModuleName.ts @@ -5,6 +5,6 @@ /////*2*/module.exports = {}; // @Filename: bar.js -////var x = require(/*1*/"./foo"); +////var x = require([|/*1*/"./foo"|]); verify.goToDefinition("1", "2"); diff --git a/tests/cases/fourslash/goToDefinitionLabels.ts b/tests/cases/fourslash/goToDefinitionLabels.ts index 5cbf3ac8f2f..3736d9207ee 100644 --- a/tests/cases/fourslash/goToDefinitionLabels.ts +++ b/tests/cases/fourslash/goToDefinitionLabels.ts @@ -2,9 +2,9 @@ /////*label1Definition*/label1: while (true) { //// /*label2Definition*/label2: while (true) { -//// break /*1*/label1; -//// continue /*2*/label2; -//// () => { break /*3*/label1; } +//// break [|/*1*/label1|]; +//// continue [|/*2*/label2|]; +//// () => { break [|/*3*/label1|]; } //// continue /*4*/unknownLabel; //// } ////} diff --git a/tests/cases/fourslash/goToDefinitionMethodOverloads.ts b/tests/cases/fourslash/goToDefinitionMethodOverloads.ts index 4dfe4753ce7..fa67b5dbef5 100644 --- a/tests/cases/fourslash/goToDefinitionMethodOverloads.ts +++ b/tests/cases/fourslash/goToDefinitionMethodOverloads.ts @@ -1,22 +1,22 @@ /// ////class MethodOverload { -//// static /*staticMethodOverload1*/method(); +//// static [|/*staticMethodOverload1*/method|](); //// static /*staticMethodOverload2*/method(foo: string); //// static /*staticMethodDefinition*/method(foo?: any) { } -//// public /*instanceMethodOverload1*/method(): any; +//// public [|/*instanceMethodOverload1*/method|](): any; //// public /*instanceMethodOverload2*/method(foo: string); //// public /*instanceMethodDefinition*/method(foo?: any) { return "foo" } ////} ////// static method -////MethodOverload./*staticMethodReference1*/method(); -////MethodOverload./*staticMethodReference2*/method("123"); +////MethodOverload.[|/*staticMethodReference1*/method|](); +////MethodOverload.[|/*staticMethodReference2*/method|]("123"); ////// instance method ////var methodOverload = new MethodOverload(); -////methodOverload./*instanceMethodReference1*/method(); -////methodOverload./*instanceMethodReference2*/method("456"); +////methodOverload.[|/*instanceMethodReference1*/method|](); +////methodOverload.[|/*instanceMethodReference2*/method|]("456"); verify.goToDefinition({ staticMethodReference1: "staticMethodOverload1", diff --git a/tests/cases/fourslash/goToDefinitionMultipleDefinitions.ts b/tests/cases/fourslash/goToDefinitionMultipleDefinitions.ts index fb022f7711f..99b6d32e7f3 100644 --- a/tests/cases/fourslash/goToDefinitionMultipleDefinitions.ts +++ b/tests/cases/fourslash/goToDefinitionMultipleDefinitions.ts @@ -14,7 +14,7 @@ //// instance3: number; ////} //// -////var ifoo: IFo/*interfaceReference*/o; +////var ifoo: [|IFo/*interfaceReference*/o|]; verify.goToDefinition("interfaceReference", ["interfaceDefinition1", "interfaceDefinition2", "interfaceDefinition3"]); @@ -29,6 +29,6 @@ verify.goToDefinition("interfaceReference", ["interfaceDefinition1", "interfaceD ////} // @Filename: e.ts -////Modul/*moduleReference*/e; +////[|Modul/*moduleReference*/e|]; verify.goToDefinition("moduleReference", ["moduleDefinition1", "moduleDefinition2"]); diff --git a/tests/cases/fourslash/goToDefinitionObjectBindingElementPropertyName01.ts b/tests/cases/fourslash/goToDefinitionObjectBindingElementPropertyName01.ts index 32b08ab710d..1bcae727971 100644 --- a/tests/cases/fourslash/goToDefinitionObjectBindingElementPropertyName01.ts +++ b/tests/cases/fourslash/goToDefinitionObjectBindingElementPropertyName01.ts @@ -6,6 +6,6 @@ ////} //// ////var foo: I; -////var { /*use*/property1: prop1 } = foo; +////var { [|/*use*/property1|]: prop1 } = foo; verify.goToDefinition("use", "def"); diff --git a/tests/cases/fourslash/goToDefinitionObjectLiteralProperties1.ts b/tests/cases/fourslash/goToDefinitionObjectLiteralProperties1.ts index a1c22ca4ca3..0024682dc71 100644 --- a/tests/cases/fourslash/goToDefinitionObjectLiteralProperties1.ts +++ b/tests/cases/fourslash/goToDefinitionObjectLiteralProperties1.ts @@ -5,11 +5,11 @@ //// } //// function foo(arg: PropsBag) {} //// foo({ -//// pr/*p1*/opx: 10 +//// [|pr/*p1*/opx|]: 10 //// }) //// function bar(firstarg: boolean, secondarg: PropsBag) {} //// bar(true, { -//// pr/*p2*/opx: 10 +//// [|pr/*p2*/opx|]: 10 //// }) diff --git a/tests/cases/fourslash/goToDefinitionObjectSpread.ts b/tests/cases/fourslash/goToDefinitionObjectSpread.ts index b23d0a80448..918fa555f86 100644 --- a/tests/cases/fourslash/goToDefinitionObjectSpread.ts +++ b/tests/cases/fourslash/goToDefinitionObjectSpread.ts @@ -5,5 +5,5 @@ ////let a1: A1; ////let a2: A2; ////let a12 = { ...a1, ...a2 }; -////a12.a/*3*/; +////a12.[|a/*3*/|]; verify.goToDefinition('3', [ '1', '2' ]); diff --git a/tests/cases/fourslash/goToDefinitionOverloadsInMultiplePropertyAccesses.ts b/tests/cases/fourslash/goToDefinitionOverloadsInMultiplePropertyAccesses.ts index 04a07f41a7f..9898b6dad1e 100644 --- a/tests/cases/fourslash/goToDefinitionOverloadsInMultiplePropertyAccesses.ts +++ b/tests/cases/fourslash/goToDefinitionOverloadsInMultiplePropertyAccesses.ts @@ -9,6 +9,6 @@ //// export function f(value: number | string) {} //// } ////} -////A.B./*2*/f(""); +////A.B.[|/*2*/f|](""); verify.goToDefinition("2", "1"); diff --git a/tests/cases/fourslash/goToDefinitionPartialImplementation.ts b/tests/cases/fourslash/goToDefinitionPartialImplementation.ts index 81f19b578ed..00cf6fd1819 100644 --- a/tests/cases/fourslash/goToDefinitionPartialImplementation.ts +++ b/tests/cases/fourslash/goToDefinitionPartialImplementation.ts @@ -13,7 +13,7 @@ //// x: number; //// } //// -//// var x: /*Part2Use*/IA; +//// var x: [|/*Part2Use*/IA|]; ////} verify.goToDefinition("Part2Use", ["Part1Definition", "Part2Definition"]); diff --git a/tests/cases/fourslash/goToDefinitionRest.ts b/tests/cases/fourslash/goToDefinitionRest.ts index 1459b9ffa88..2577aafb625 100644 --- a/tests/cases/fourslash/goToDefinitionRest.ts +++ b/tests/cases/fourslash/goToDefinitionRest.ts @@ -7,6 +7,6 @@ ////} ////let t: Gen; ////var { x, ...rest } = t; -////rest./*2*/parent; +////rest.[|/*2*/parent|]; const ranges = test.ranges(); verify.goToDefinition('2', [ '1' ]); diff --git a/tests/cases/fourslash/goToDefinitionShorthandProperty01.ts b/tests/cases/fourslash/goToDefinitionShorthandProperty01.ts index 4107049286c..7e46894d244 100644 --- a/tests/cases/fourslash/goToDefinitionShorthandProperty01.ts +++ b/tests/cases/fourslash/goToDefinitionShorthandProperty01.ts @@ -3,9 +3,9 @@ //// var /*valueDeclaration1*/name = "hello"; //// var /*valueDeclaration2*/id = 100000; //// declare var /*valueDeclaration3*/id; -//// var obj = {/*valueDefinition1*/name, /*valueDefinition2*/id}; -//// obj./*valueReference1*/name; -//// obj./*valueReference2*/id; +//// var obj = {[|/*valueDefinition1*/name|], [|/*valueDefinition2*/id|]}; +//// obj.[|/*valueReference1*/name|]; +//// obj.[|/*valueReference2*/id|]; verify.goToDefinition({ valueDefinition1: "valueDeclaration1", diff --git a/tests/cases/fourslash/goToDefinitionShorthandProperty02.ts b/tests/cases/fourslash/goToDefinitionShorthandProperty02.ts index 0ecdcacdcd6..1d78ade4267 100644 --- a/tests/cases/fourslash/goToDefinitionShorthandProperty02.ts +++ b/tests/cases/fourslash/goToDefinitionShorthandProperty02.ts @@ -1,7 +1,7 @@ /// ////let x = { -//// f/*1*/oo +//// [|f/*1*/oo|] ////} verify.goToDefinition("1", []); diff --git a/tests/cases/fourslash/goToDefinitionShorthandProperty03.ts b/tests/cases/fourslash/goToDefinitionShorthandProperty03.ts index 42a9ee0a4d6..3a04d3efa06 100644 --- a/tests/cases/fourslash/goToDefinitionShorthandProperty03.ts +++ b/tests/cases/fourslash/goToDefinitionShorthandProperty03.ts @@ -1,10 +1,10 @@ /// ////var /*varDef*/x = { -//// /*varProp*/x +//// [|/*varProp*/x|] ////} ////let /*letDef*/y = { -//// /*letProp*/y +//// [|/*letProp*/y|] ////} verify.goToDefinition({ diff --git a/tests/cases/fourslash/goToDefinitionSimple.ts b/tests/cases/fourslash/goToDefinitionSimple.ts index 9ae02f26bf2..3d1cdd632ba 100644 --- a/tests/cases/fourslash/goToDefinitionSimple.ts +++ b/tests/cases/fourslash/goToDefinitionSimple.ts @@ -4,7 +4,7 @@ ////class /*2*/c { } // @Filename: Consumption.ts -//// var n = new /*1*/c(); -//// var n = new c/*3*/(); +//// var n = new [|/*1*/c|](); +//// var n = new [|c/*3*/|](); verify.goToDefinition(["1", "3"], "2"); diff --git a/tests/cases/fourslash/goToDefinitionTaggedTemplateOverloads.ts b/tests/cases/fourslash/goToDefinitionTaggedTemplateOverloads.ts index b01bace4feb..fcb28f86d05 100644 --- a/tests/cases/fourslash/goToDefinitionTaggedTemplateOverloads.ts +++ b/tests/cases/fourslash/goToDefinitionTaggedTemplateOverloads.ts @@ -4,8 +4,8 @@ ////function /*defFBool*/f(strs: TemplateStringsArray, x: boolean): void; ////function f(strs: TemplateStringsArray, x: number | boolean) {} //// -/////*useFNumber*/f`${0}`; -/////*useFBool*/f`${false}`; +////[|/*useFNumber*/f|]`${0}`; +////[|/*useFBool*/f|]`${false}`; verify.goToDefinition({ useFNumber: "defFNumber", diff --git a/tests/cases/fourslash/goToDefinitionThis.ts b/tests/cases/fourslash/goToDefinitionThis.ts index 923fb6c8feb..88cbcb8ca96 100644 --- a/tests/cases/fourslash/goToDefinitionThis.ts +++ b/tests/cases/fourslash/goToDefinitionThis.ts @@ -1,11 +1,11 @@ /// ////function f(/*fnDecl*/this: number) { -//// return /*fnUse*/this; +//// return [|/*fnUse*/this|]; ////} ////class /*cls*/C { -//// constructor() { return /*clsUse*/this; } -//// get self(/*getterDecl*/this: number) { return /*getterUse*/this; } +//// constructor() { return [|/*clsUse*/this|]; } +//// get self(/*getterDecl*/this: number) { return [|/*getterUse*/this|]; } ////} verify.goToDefinition({ diff --git a/tests/cases/fourslash/goToDefinitionTypePredicate.ts b/tests/cases/fourslash/goToDefinitionTypePredicate.ts index 17e6fc1be6b..9988611885c 100644 --- a/tests/cases/fourslash/goToDefinitionTypePredicate.ts +++ b/tests/cases/fourslash/goToDefinitionTypePredicate.ts @@ -1,7 +1,7 @@ /// //// class /*classDeclaration*/A {} -//// function f(/*parameterDeclaration*/parameter: any): /*parameterName*/parameter is /*typeReference*/A { +//// function f(/*parameterDeclaration*/parameter: any): [|/*parameterName*/parameter|] is [|/*typeReference*/A|] { //// return typeof parameter === "string"; //// } diff --git a/tests/cases/fourslash/goToDefinitionUnionTypeProperty1.ts b/tests/cases/fourslash/goToDefinitionUnionTypeProperty1.ts index 82bd07e32f0..6baca39e011 100644 --- a/tests/cases/fourslash/goToDefinitionUnionTypeProperty1.ts +++ b/tests/cases/fourslash/goToDefinitionUnionTypeProperty1.ts @@ -12,7 +12,7 @@ //// ////var x : One | Two; //// -////x./*propertyReference*/commonProperty; +////x.[|/*propertyReference*/commonProperty|]; ////x./*3*/commonFunction; verify.goToDefinition("propertyReference", ["propertyDefinition1", "propertyDefinition2"]); diff --git a/tests/cases/fourslash/goToDefinitionUnionTypeProperty2.ts b/tests/cases/fourslash/goToDefinitionUnionTypeProperty2.ts index 22ffb906e8e..3ade25ca622 100644 --- a/tests/cases/fourslash/goToDefinitionUnionTypeProperty2.ts +++ b/tests/cases/fourslash/goToDefinitionUnionTypeProperty2.ts @@ -14,6 +14,6 @@ //// ////var x : One | Two; //// -////x.common./*propertyReference*/a; +////x.common.[|/*propertyReference*/a|]; verify.goToDefinition("propertyReference", ["propertyDefinition2", "propertyDefinition1"]); diff --git a/tests/cases/fourslash/goToDefinitionUnionTypeProperty3.ts b/tests/cases/fourslash/goToDefinitionUnionTypeProperty3.ts index fde4d2319fe..3f5666f19b8 100644 --- a/tests/cases/fourslash/goToDefinitionUnionTypeProperty3.ts +++ b/tests/cases/fourslash/goToDefinitionUnionTypeProperty3.ts @@ -7,6 +7,6 @@ ////var strings: string[]; ////var numbers: number[]; //// -////var x = (strings || numbers)./*usage*/specialPop() +////var x = (strings || numbers).[|/*usage*/specialPop|]() verify.goToDefinition("usage", "definition"); diff --git a/tests/cases/fourslash/goToDefinitionUnionTypeProperty4.ts b/tests/cases/fourslash/goToDefinitionUnionTypeProperty4.ts index f69554098c5..a4c59961592 100644 --- a/tests/cases/fourslash/goToDefinitionUnionTypeProperty4.ts +++ b/tests/cases/fourslash/goToDefinitionUnionTypeProperty4.ts @@ -16,6 +16,6 @@ ////var magnitude: Magnitude; ////var snapcrackle: SnapCrackle; //// -////var x = (snapcrackle || magnitude || art)./*usage*/pop; +////var x = (snapcrackle || magnitude || art).[|/*usage*/pop|]; verify.goToDefinition("usage", ["def1", "def2", "def3"]); diff --git a/tests/cases/fourslash/goToDefinition_super.ts b/tests/cases/fourslash/goToDefinition_super.ts index 115e4a4a6ed..22f00aff7dc 100644 --- a/tests/cases/fourslash/goToDefinition_super.ts +++ b/tests/cases/fourslash/goToDefinition_super.ts @@ -7,10 +7,10 @@ ////class /*B*/B extends A {} ////class C extends B { //// constructor() { -//// /*super*/super(); +//// [|/*super*/super|](); //// } //// method() { -//// /*superExpression*/super.x(); +//// [|/*superExpression*/super|].x(); //// } ////} ////class D { diff --git a/tests/cases/fourslash/goToDefinition_untypedModule.ts b/tests/cases/fourslash/goToDefinition_untypedModule.ts index fe29f7104cf..8c9e83711a9 100644 --- a/tests/cases/fourslash/goToDefinition_untypedModule.ts +++ b/tests/cases/fourslash/goToDefinition_untypedModule.ts @@ -5,6 +5,6 @@ // @Filename: /a.ts ////import { /*def*/f } from "foo"; -/////*use*/f(); +////[|/*use*/f|](); verify.goToDefinition("use", "def"); diff --git a/tests/cases/fourslash/goToModuleAliasDefinition.ts b/tests/cases/fourslash/goToModuleAliasDefinition.ts index dfccc3393c5..98724228a6e 100644 --- a/tests/cases/fourslash/goToModuleAliasDefinition.ts +++ b/tests/cases/fourslash/goToModuleAliasDefinition.ts @@ -5,7 +5,7 @@ // @Filename: b.ts //// import /*3*/n = require('a'); -//// var x = new /*1*/n.Foo(); +//// var x = new [|/*1*/n|].Foo(); // Won't-fixed: Should go to '2' instead verify.goToDefinition("1", "3"); diff --git a/tests/cases/fourslash/gotoDefinitionInObjectBindingPattern1.ts b/tests/cases/fourslash/gotoDefinitionInObjectBindingPattern1.ts index 98c06c06d7b..dcc5a977be5 100644 --- a/tests/cases/fourslash/gotoDefinitionInObjectBindingPattern1.ts +++ b/tests/cases/fourslash/gotoDefinitionInObjectBindingPattern1.ts @@ -7,6 +7,6 @@ //// interface Test { //// /*destination*/prop2: number //// } -//// bar(({pr/*goto*/op2})=>{}); +//// bar(({[|pr/*goto*/op2|]})=>{}); verify.goToDefinition("goto", "destination"); \ No newline at end of file diff --git a/tests/cases/fourslash/gotoDefinitionInObjectBindingPattern2.ts b/tests/cases/fourslash/gotoDefinitionInObjectBindingPattern2.ts index 9e41f646c46..6d513d6abee 100644 --- a/tests/cases/fourslash/gotoDefinitionInObjectBindingPattern2.ts +++ b/tests/cases/fourslash/gotoDefinitionInObjectBindingPattern2.ts @@ -1,7 +1,7 @@ /// //// var p0 = ({a/*1*/a}) => {console.log(aa)}; -//// function f2({ a/*a1*/1, b/*b1*/1 }: { /*a1_dest*/a1: number, /*b1_dest*/b1: number } = { a1: 0, b1: 0 }) {} +//// function f2({ [|a/*a1*/1|], [|b/*b1*/1|] }: { /*a1_dest*/a1: number, /*b1_dest*/b1: number } = { a1: 0, b1: 0 }) {} verify.goToDefinition("1", []); verify.goToDefinition("a1", "a1_dest"); diff --git a/tests/cases/fourslash/gotoDefinitionPropertyAccessExpressionHeritageClause.ts b/tests/cases/fourslash/gotoDefinitionPropertyAccessExpressionHeritageClause.ts index d46ea7c8422..3d58d869c49 100644 --- a/tests/cases/fourslash/gotoDefinitionPropertyAccessExpressionHeritageClause.ts +++ b/tests/cases/fourslash/gotoDefinitionPropertyAccessExpressionHeritageClause.ts @@ -4,7 +4,7 @@ //// function foo() { //// return {/*refB*/B: B}; //// } -//// class C extends (foo())./*B*/B {} -//// class C1 extends foo()./*B1*/B {} +//// class C extends (foo()).[|/*B*/B|] {} +//// class C1 extends foo().[|/*B1*/B|] {} verify.goToDefinition([["B", "refB"], ["B1", "refB"]]); \ No newline at end of file diff --git a/tests/cases/fourslash/javaScriptClass3.ts b/tests/cases/fourslash/javaScriptClass3.ts index fd67f6f53a5..60f51b4ac79 100644 --- a/tests/cases/fourslash/javaScriptClass3.ts +++ b/tests/cases/fourslash/javaScriptClass3.ts @@ -12,8 +12,8 @@ //// method() { return this.alpha; } //// } //// var x = new Foo(); -//// x.alpha/*src1*/; -//// x.beta/*src2*/; +//// x.[|alpha/*src1*/|]; +//// x.[|beta/*src2*/|]; verify.goToDefinition({ src1: "dst1", diff --git a/tests/cases/fourslash/jsdocTypedefTagServices.ts b/tests/cases/fourslash/jsdocTypedefTagServices.ts index c97707e4d25..e4b262c3ee4 100644 --- a/tests/cases/fourslash/jsdocTypedefTagServices.ts +++ b/tests/cases/fourslash/jsdocTypedefTagServices.ts @@ -10,7 +10,7 @@ //// */ /////** -//// * @type {/*use*/[|Product|]} +//// * @type {[|/*use*/Product|]} //// */ ////const product = null; diff --git a/tests/cases/fourslash/server/definition01.ts b/tests/cases/fourslash/server/definition01.ts index 7889d185fcd..70921b72ed4 100644 --- a/tests/cases/fourslash/server/definition01.ts +++ b/tests/cases/fourslash/server/definition01.ts @@ -1,7 +1,7 @@ /// // @Filename: b.ts -////import n = require('./a/*1*/'); +////import n = require([|'./a/*1*/'|]); ////var x = new n.Foo(); // @Filename: a.ts diff --git a/tests/cases/fourslash/server/jsdocTypedefTagGoToDefinition.ts b/tests/cases/fourslash/server/jsdocTypedefTagGoToDefinition.ts index 000adef9081..dd72fdd42ad 100644 --- a/tests/cases/fourslash/server/jsdocTypedefTagGoToDefinition.ts +++ b/tests/cases/fourslash/server/jsdocTypedefTagGoToDefinition.ts @@ -14,10 +14,10 @@ //// */ //// //// /** @type {Person} */ -//// var person; person.personName/*3*/ +//// var person; person.[|personName/*3*/|] //// //// /** @type {Animal} */ -//// var animal; animal.animalName/*4*/ +//// var animal; animal.[|animalName/*4*/|] verify.goToDefinition({ 3: "1", diff --git a/tests/cases/fourslash/tsxGoToDefinitionClasses.ts b/tests/cases/fourslash/tsxGoToDefinitionClasses.ts index 688ce879adf..f0b58155bf5 100644 --- a/tests/cases/fourslash/tsxGoToDefinitionClasses.ts +++ b/tests/cases/fourslash/tsxGoToDefinitionClasses.ts @@ -11,9 +11,9 @@ //// /*pt*/foo: string; //// } //// } -//// var x = ; -//// var y = ; -//// var z = ; +//// var x = <[|My/*c*/Class|] />; +//// var y = ; +//// var z = <[|MyCl/*w*/ass|] wrong= 'hello' />; verify.goToDefinition({ c: "ct", diff --git a/tests/cases/fourslash/tsxGoToDefinitionIntrinsics.ts b/tests/cases/fourslash/tsxGoToDefinitionIntrinsics.ts index a82e813baa7..9b202a64c21 100644 --- a/tests/cases/fourslash/tsxGoToDefinitionIntrinsics.ts +++ b/tests/cases/fourslash/tsxGoToDefinitionIntrinsics.ts @@ -11,9 +11,9 @@ //// /*st*/span: { n: string; }; //// } //// } -//// var x = ; -//// var y = ; -//// var z =
; +//// var x = <[|di/*ds*/v|] />; +//// var y = <[|s/*ss*/pan|] />; +//// var z =
; verify.goToDefinition({ ds: "dt", diff --git a/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction1.ts b/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction1.ts index d620b3585af..6ef0e93445f 100644 --- a/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction1.ts +++ b/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction1.ts @@ -16,10 +16,10 @@ //// /*pt2*/optional?: boolean //// } //// declare function /*opt*/Opt(attributes: OptionPropBag): JSX.Element; -//// let opt = ; -//// let opt1 = ; -//// let opt2 = ; -//// let opt3 = ; +//// let opt = <[|O/*one*/pt|] />; +//// let opt1 = <[|Op/*two*/t|] [|pr/*p1*/opx|]={100} />; +//// let opt2 = <[|Op/*three*/t|] propx={100} [|opt/*p2*/ional|] />; +//// let opt3 = <[|Op/*four*/t|] wr/*p3*/ong />; verify.goToDefinition({ one: "opt", diff --git a/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction2.ts b/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction2.ts index 17737983230..9d5efe2442b 100644 --- a/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction2.ts +++ b/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction2.ts @@ -23,12 +23,12 @@ //// declare function /*firstSource*/MainButton(buttonProps: ButtonProps): JSX.Element; //// declare function /*secondSource*/MainButton(linkProps: LinkProps): JSX.Element; //// declare function /*thirdSource*/MainButton(props: ButtonProps | LinkProps): JSX.Element; -//// let opt =
; -//// let opt =
; -//// let opt =
{}} />; -//// let opt =
{}} ignore-prop />; -//// let opt =
; -//// let opt =
; +//// let opt = <[|Main/*firstTarget*/Button|] />; +//// let opt = <[|Main/*secondTarget*/Button|] children="chidlren" />; +//// let opt = <[|Main/*thirdTarget*/Button|] onClick={()=>{}} />; +//// let opt = <[|Main/*fourthTarget*/Button|] onClick={()=>{}} ignore-prop />; +//// let opt = <[|Main/*fivethTarget*/Button|] goTo="goTo" />; +//// let opt = <[|Main/*sixthTarget*/Button|] wrong />; verify.goToDefinition({ firstTarget: "thirdSource", diff --git a/tests/cases/fourslash/tsxGoToDefinitionUnionElementType1.ts b/tests/cases/fourslash/tsxGoToDefinitionUnionElementType1.ts index db78f46f3ad..d6b5dfab709 100644 --- a/tests/cases/fourslash/tsxGoToDefinitionUnionElementType1.ts +++ b/tests/cases/fourslash/tsxGoToDefinitionUnionElementType1.ts @@ -19,7 +19,7 @@ //// } //// var SFCComp = SFC1 || SFC2; -//// +//// <[|SFC/*one*/Comp|] x /> verify.goToDefinition({ "one": "pt1" diff --git a/tests/cases/fourslash/tsxGoToDefinitionUnionElementType2.ts b/tests/cases/fourslash/tsxGoToDefinitionUnionElementType2.ts index 75ca81998a0..548ce94db5a 100644 --- a/tests/cases/fourslash/tsxGoToDefinitionUnionElementType2.ts +++ b/tests/cases/fourslash/tsxGoToDefinitionUnionElementType2.ts @@ -19,7 +19,7 @@ //// var /*pt1*/RCComp = RC1 || RC2; -//// +//// <[|RC/*one*/Comp|] /> verify.goToDefinition({ "one": "pt1" From b75ccb1c49f3ed42e819fd741c8f2655d571a593 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Sun, 22 Oct 2017 23:01:23 +0200 Subject: [PATCH 011/235] accept baselines --- tests/baselines/reference/api/tsserverlibrary.d.ts | 4 ++-- tests/baselines/reference/api/typescript.d.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 62f4f68d148..9769a9b1a7c 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1592,8 +1592,8 @@ declare namespace ts { } interface ScriptReferenceHost { getCompilerOptions(): CompilerOptions; - getSourceFile(fileName: string): SourceFile; - getSourceFileByPath(path: Path): SourceFile; + getSourceFile(fileName: string): SourceFile | undefined; + getSourceFileByPath(path: Path): SourceFile | undefined; getCurrentDirectory(): string; } interface ParseConfigHost { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index c7c8ba88d72..f185ef0daeb 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1592,8 +1592,8 @@ declare namespace ts { } interface ScriptReferenceHost { getCompilerOptions(): CompilerOptions; - getSourceFile(fileName: string): SourceFile; - getSourceFileByPath(path: Path): SourceFile; + getSourceFile(fileName: string): SourceFile | undefined; + getSourceFileByPath(path: Path): SourceFile | undefined; getCurrentDirectory(): string; } interface ParseConfigHost { From 051da1111366f74ec9714ca8edfc35570d76ce73 Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Mon, 23 Oct 2017 16:03:47 -0700 Subject: [PATCH 012/235] Removed custom guard and added isArray --- src/harness/fourslash.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index a95221e3b26..1addfba6396 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -641,16 +641,17 @@ namespace FourSlash { const defs = getDefs(); let definitions: ts.DefinitionInfo[] | ReadonlyArray; let testName: string; - if (this.isDefinitionInfoAndBoundSpan(defs)) { + + if (!defs || Array.isArray(defs)) { + definitions = defs as ts.DefinitionInfo[] || []; + testName = "goToDefinitions"; + } + else { this.verifyDefinitionTextSpan(defs, startMarkerName); definitions = defs.definitions; testName = "goToDefinitionsAndBoundSpan"; } - else { - definitions = defs || []; - testName = "goToDefinitions"; - } if (endMarkers.length !== definitions.length) { this.raiseError(`${testName} failed - expected to find ${endMarkers.length} definitions but got ${definitions.length}`); @@ -682,10 +683,6 @@ namespace FourSlash { } } - private isDefinitionInfoAndBoundSpan(definition: ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined): definition is ts.DefinitionInfoAndBoundSpan { - return definition && (definition).definitions !== undefined; - } - public verifyGetEmitOutputForCurrentFile(expected: string): void { const emit = this.languageService.getEmitOutput(this.activeFile.fileName); if (emit.outputFiles.length !== 1) { From f8ccde5218e72d23753d596744797e0318c64f9e Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Tue, 24 Oct 2017 11:05:21 -0700 Subject: [PATCH 013/235] Renamed a couple of methods, refactored code for reusability --- src/server/session.ts | 105 ++++++------------ .../reference/api/tsserverlibrary.d.ts | 11 +- 2 files changed, 41 insertions(+), 75 deletions(-) diff --git a/src/server/session.ts b/src/server/session.ts index fb37bf55408..b5c0c1b4d29 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -601,7 +601,7 @@ namespace ts.server { } if (simplifiedResult) { - return this.getSimplifiedDefinitions(definitions, project); + return this.mapFileSpan(definitions, project); } else { return definitions; @@ -624,32 +624,24 @@ namespace ts.server { if (simplifiedResult) { return { - definitions: this.getSimplifiedDefinitions(definitionAndBoundSpan.definitions, project), - textSpan: this.getSimplifiedTextSpan(scriptInfo, definitionAndBoundSpan.textSpan) + definitions: this.mapFileSpan(definitionAndBoundSpan.definitions, project), + textSpan: this.toLocationTextSpan(definitionAndBoundSpan.textSpan, scriptInfo) }; } return definitionAndBoundSpan; } - private getSimplifiedDefinitions(definitions: ReadonlyArray, project: Project): ReadonlyArray { - return definitions.map(def => this.getSimplifiedFileSpan(def.fileName, def.textSpan, project)); + private mapFileSpan(definitions: ReadonlyArray, project: Project): ReadonlyArray { + return definitions.map(def => this.getFileSpan(def.fileName, def.textSpan, project)); } - private getSimplifiedFileSpan(fileName: string, textSpan: TextSpan, project: Project): protocol.FileSpan { + private getFileSpan(fileName: string, textSpan: TextSpan, project: Project): protocol.FileSpan { const scriptInfo = project.getScriptInfo(fileName); - const simplifiedTextSpan = this.getSimplifiedTextSpan(scriptInfo, textSpan); return { file: fileName, - ...simplifiedTextSpan - }; - } - - private getSimplifiedTextSpan(scriptInfo: ScriptInfo, textSpan: TextSpan): protocol.TextSpan { - return { - start: scriptInfo.positionToLineOffset(textSpan.start), - end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan)) + ...this.toLocationTextSpan(textSpan, scriptInfo) }; } @@ -662,14 +654,7 @@ namespace ts.server { return emptyArray; } - return definitions.map(def => { - const defScriptInfo = project.getScriptInfo(def.fileName); - return { - file: def.fileName, - start: defScriptInfo.positionToLineOffset(def.textSpan.start), - end: defScriptInfo.positionToLineOffset(textSpanEnd(def.textSpan)) - }; - }); + return this.mapFileSpan(definitions, project); } private getImplementation(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): ReadonlyArray | ReadonlyArray { @@ -680,14 +665,7 @@ namespace ts.server { return emptyArray; } if (simplifiedResult) { - return implementations.map(({ fileName, textSpan }) => { - const scriptInfo = project.getScriptInfo(fileName); - return { - file: fileName, - start: scriptInfo.positionToLineOffset(textSpan.start), - end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan)) - }; - }); + return implementations.map(({ fileName, textSpan }) => this.getFileSpan(fileName, textSpan, project)); } else { return implementations; @@ -707,13 +685,10 @@ namespace ts.server { return occurrences.map(occurrence => { const { fileName, isWriteAccess, textSpan, isInString } = occurrence; const scriptInfo = project.getScriptInfo(fileName); - const start = scriptInfo.positionToLineOffset(textSpan.start); - const end = scriptInfo.positionToLineOffset(textSpanEnd(textSpan)); const result: protocol.OccurrencesResponseItem = { - start, - end, file: fileName, isWriteAccess, + ...this.toLocationTextSpan(textSpan, scriptInfo) }; // no need to serialize the property if it is not true if (isInString) { @@ -751,13 +726,13 @@ namespace ts.server { } if (simplifiedResult) { - return documentHighlights.map(convertToDocumentHighlightsItem); + return documentHighlights.map(x => convertToDocumentHighlightsItem(x, this.toLocationTextSpan)); } else { return documentHighlights; } - function convertToDocumentHighlightsItem(documentHighlights: DocumentHighlights): protocol.DocumentHighlightsItem { + function convertToDocumentHighlightsItem(documentHighlights: DocumentHighlights, toLocationSpan: (textSpan: TextSpan, scriptInfo: ScriptInfo) => protocol.TextSpan): protocol.DocumentHighlightsItem { const { fileName, highlightSpans } = documentHighlights; const scriptInfo = project.getScriptInfo(fileName); @@ -766,11 +741,10 @@ namespace ts.server { highlightSpans: highlightSpans.map(convertHighlightSpan) }; - function convertHighlightSpan(highlightSpan: HighlightSpan): protocol.HighlightSpan { + function convertHighlightSpan(this: Session, highlightSpan: HighlightSpan): protocol.HighlightSpan { const { textSpan, kind } = highlightSpan; - const start = scriptInfo.positionToLineOffset(textSpan.start); - const end = scriptInfo.positionToLineOffset(textSpanEnd(textSpan)); - return { start, end, kind }; + + return { kind, ...toLocationSpan(textSpan, scriptInfo) }; } } } @@ -863,8 +837,7 @@ namespace ts.server { const locationScriptInfo = project.getScriptInfo(location.fileName); return { file: location.fileName, - start: locationScriptInfo.positionToLineOffset(location.textSpan.start), - end: locationScriptInfo.positionToLineOffset(textSpanEnd(location.textSpan)), + ...this.toLocationTextSpan(location.textSpan, locationScriptInfo) }; }); }, @@ -959,16 +932,15 @@ namespace ts.server { return references.map(ref => { const refScriptInfo = project.getScriptInfo(ref.fileName); - const start = refScriptInfo.positionToLineOffset(ref.textSpan.start); - const refLineSpan = refScriptInfo.lineToTextSpan(start.line - 1); + const textSpan = this.toLocationTextSpan(ref.textSpan, refScriptInfo); + const refLineSpan = refScriptInfo.lineToTextSpan(textSpan.start.line - 1); const lineText = refScriptInfo.getSnapshot().getText(refLineSpan.start, textSpanEnd(refLineSpan)).replace(/\r|\n/g, ""); return { file: ref.fileName, - start, lineText, - end: refScriptInfo.positionToLineOffset(textSpanEnd(ref.textSpan)), isWriteAccess: ref.isWriteAccess, - isDefinition: ref.isDefinition + isDefinition: ref.isDefinition, + ...textSpan }; }); }, @@ -1107,11 +1079,10 @@ namespace ts.server { return { kind: quickInfo.kind, kindModifiers: quickInfo.kindModifiers, - start: scriptInfo.positionToLineOffset(quickInfo.textSpan.start), - end: scriptInfo.positionToLineOffset(textSpanEnd(quickInfo.textSpan)), displayString, documentation: docString, - tags: quickInfo.tags || [] + tags: quickInfo.tags || [], + ...this.toLocationTextSpan(quickInfo.textSpan, scriptInfo) }; } else { @@ -1201,9 +1172,8 @@ namespace ts.server { return edits.map((edit) => { return { - start: scriptInfo.positionToLineOffset(edit.span.start), - end: scriptInfo.positionToLineOffset(textSpanEnd(edit.span)), - newText: edit.newText ? edit.newText : "" + newText: edit.newText ? edit.newText : "", + ...this.toLocationTextSpan(edit.span, scriptInfo) }; }); } @@ -1219,7 +1189,7 @@ namespace ts.server { return mapDefined(completions && completions.entries, entry => { if (completions.isMemberCompletion || (entry.name.toLowerCase().indexOf(prefix.toLowerCase()) === 0)) { const { name, kind, kindModifiers, sortText, replacementSpan } = entry; - const convertedSpan = replacementSpan ? this.decorateSpan(replacementSpan, scriptInfo) : undefined; + const convertedSpan = replacementSpan ? this.toLocationTextSpan(replacementSpan, scriptInfo) : undefined; return { name, kind, kindModifiers, sortText, replacementSpan: convertedSpan }; } }).sort((a, b) => compareStrings(a.name, b.name)); @@ -1353,13 +1323,13 @@ namespace ts.server { this.projectService.closeClientFile(file); } - private decorateNavigationBarItems(items: NavigationBarItem[], scriptInfo: ScriptInfo): protocol.NavigationBarItem[] { + private mapLocationNavigationBarItems(items: NavigationBarItem[], scriptInfo: ScriptInfo): protocol.NavigationBarItem[] { return map(items, item => ({ text: item.text, kind: item.kind, kindModifiers: item.kindModifiers, - spans: item.spans.map(span => this.decorateSpan(span, scriptInfo)), - childItems: this.decorateNavigationBarItems(item.childItems, scriptInfo), + spans: item.spans.map(span => this.toLocationTextSpan(span, scriptInfo)), + childItems: this.mapLocationNavigationBarItems(item.childItems, scriptInfo), indent: item.indent })); } @@ -1370,21 +1340,21 @@ namespace ts.server { return !items ? undefined : simplifiedResult - ? this.decorateNavigationBarItems(items, this.projectService.getScriptInfoForNormalizedPath(file)) + ? this.mapLocationNavigationBarItems(items, this.projectService.getScriptInfoForNormalizedPath(file)) : items; } - private decorateNavigationTree(tree: NavigationTree, scriptInfo: ScriptInfo): protocol.NavigationTree { + private toLocationNavigationTree(tree: NavigationTree, scriptInfo: ScriptInfo): protocol.NavigationTree { return { text: tree.text, kind: tree.kind, kindModifiers: tree.kindModifiers, - spans: tree.spans.map(span => this.decorateSpan(span, scriptInfo)), - childItems: map(tree.childItems, item => this.decorateNavigationTree(item, scriptInfo)) + spans: tree.spans.map(span => this.toLocationTextSpan(span, scriptInfo)), + childItems: map(tree.childItems, item => this.toLocationNavigationTree(item, scriptInfo)) }; } - private decorateSpan(span: TextSpan, scriptInfo: ScriptInfo): protocol.TextSpan { + private toLocationTextSpan(span: TextSpan, scriptInfo: ScriptInfo): protocol.TextSpan { return { start: scriptInfo.positionToLineOffset(span.start), end: scriptInfo.positionToLineOffset(textSpanEnd(span)) @@ -1397,7 +1367,7 @@ namespace ts.server { return !tree ? undefined : simplifiedResult - ? this.decorateNavigationTree(tree, this.projectService.getScriptInfoForNormalizedPath(file)) + ? this.toLocationNavigationTree(tree, this.projectService.getScriptInfoForNormalizedPath(file)) : tree; } @@ -1416,14 +1386,11 @@ namespace ts.server { return navItems.map((navItem) => { const scriptInfo = project.getScriptInfo(navItem.fileName); - const start = scriptInfo.positionToLineOffset(navItem.textSpan.start); - const end = scriptInfo.positionToLineOffset(textSpanEnd(navItem.textSpan)); const bakedItem: protocol.NavtoItem = { name: navItem.name, kind: navItem.kind, file: navItem.fileName, - start, - end, + ...this.toLocationTextSpan(navItem.textSpan, scriptInfo) }; if (navItem.kindModifiers && (navItem.kindModifiers !== "")) { bakedItem.kindModifiers = navItem.kindModifiers; @@ -1629,7 +1596,7 @@ namespace ts.server { return !spans ? undefined : simplifiedResult - ? spans.map(span => this.decorateSpan(span, scriptInfo)) + ? spans.map(span => this.toLocationTextSpan(span, scriptInfo)) : spans; } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 306f15e9521..9c7d98517e3 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -6868,9 +6868,8 @@ declare namespace ts.server { private getDiagnosticsWorker(args, isSemantic, selector, includeLinePosition); private getDefinition(args, simplifiedResult); private getDefinitionAndBoundSpan(args, simplifiedResult); - private getSimplifiedDefinitions(definitions, project); - private getSimplifiedFileSpan(fileName, textSpan, project); - private getSimplifiedTextSpan(scriptInfo, textSpan); + private mapFileSpan(definitions, project); + private getFileSpan(fileName, textSpan, project); private getTypeDefinition(args); private getImplementation(args, simplifiedResult); private getOccurrences(args); @@ -6920,10 +6919,10 @@ declare namespace ts.server { private reload(args, reqSeq); private saveToTmp(fileName, tempFileName); private closeClientFile(fileName); - private decorateNavigationBarItems(items, scriptInfo); + private mapLocationNavigationBarItems(items, scriptInfo); private getNavigationBarItems(args, simplifiedResult); - private decorateNavigationTree(tree, scriptInfo); - private decorateSpan(span, scriptInfo); + private toLocationNavigationTree(tree, scriptInfo); + private toLocationTextSpan(span, scriptInfo); private getNavigationTree(args, simplifiedResult); private getNavigateToItems(args, simplifiedResult); private getSupportedCodeFixes(); From 71ab810d9d8f07bda255115893bd37cb2ab71e06 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 24 Oct 2017 13:37:16 -0700 Subject: [PATCH 014/235] Clean up outdated string comparison logic --- src/compiler/core.ts | 125 +++++++++++++++++++++++++++++++++---------- 1 file changed, 98 insertions(+), 27 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 12b8dd2f87e..ddcd8c849e7 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -20,12 +20,6 @@ namespace ts { /* @internal */ namespace ts { - - // More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times. - export const collator: { compare(a: string, b: string): number } = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(/*locales*/ undefined, { usage: "sort", sensitivity: "accent" }) : undefined; - // Intl is missing in Safari, and node 0.10 treats "a" as greater than "B". - export const localeCompareIsCorrect = ts.collator && ts.collator.compare("a", "B") < 0; - /** Create a MapLike with good performance. */ function createDictionaryObject(): MapLike { const map = Object.create(/*prototype*/ null); // tslint:disable-line:no-null-keyword @@ -1489,37 +1483,114 @@ namespace ts { return headChain; } - export function compareValues(a: T, b: T): Comparison { - if (a === b) return Comparison.EqualTo; - if (a === undefined) return Comparison.LessThan; - if (b === undefined) return Comparison.GreaterThan; - return a < b ? Comparison.LessThan : Comparison.GreaterThan; + function toComparison(value: number) { + return value < 0 ? Comparison.LessThan : value > 0 ? Comparison.GreaterThan : Comparison.EqualTo; } - export function compareStrings(a: string, b: string, ignoreCase?: boolean): Comparison { + function compareNonNullValues(a: T, b: T): Comparison { + return a < b ? Comparison.LessThan : a > b ? Comparison.GreaterThan : Comparison.EqualTo; + } + + function compareValuesWithCallback(a: T | undefined, b: T | undefined, comparer: (a: T, b: T) => number) { if (a === b) return Comparison.EqualTo; if (a === undefined) return Comparison.LessThan; if (b === undefined) return Comparison.GreaterThan; - if (ignoreCase) { - // Checking if "collator exists indicates that Intl is available. - // We still have to check if "collator.compare" is correct. If it is not, use "String.localeComapre" - if (collator) { - const result = localeCompareIsCorrect ? - collator.compare(a, b) : - a.localeCompare(b, /*locales*/ undefined, { usage: "sort", sensitivity: "accent" }); // accent means a ≠ b, a ≠ á, a = A - return result < 0 ? Comparison.LessThan : result > 0 ? Comparison.GreaterThan : Comparison.EqualTo; - } + return toComparison(comparer(a, b)); + } - a = a.toUpperCase(); - b = b.toUpperCase(); - if (a === b) return Comparison.EqualTo; + export function compareValues(a: T | undefined, b: T | undefined): Comparison { + return compareValuesWithCallback(a, b, compareNonNullValues); + } + + interface StringComparers { + caseSensitive(a: string, b: string): number; + caseInsensitive(a: string, b: string): number; + } + + // Gets string comparers compatible with the current host + function createStringComparers() { + function createIntlComparers(): StringComparers { + // Strings that differ in base, accents/diacritic marks, or case compare as unequal. + // An `undefined` locale uses the default locale of the host. + const caseSensitiveCollator = new Intl.Collator(/*locales*/ undefined, { usage: "sort", sensitivity: "variant" }); + + // Strings that differ in base or accents/diacritic marks compare as unequal. + // An `undefined` locale uses the default locale of the host. + const caseInsensitiveCollator = new Intl.Collator(/*locales*/ undefined, { usage: "sort", sensitivity: "accent" }); + + return { + caseSensitive: (a, b) => caseSensitiveCollator.compare(a, b), + caseInsensitive: (a, b) => caseInsensitiveCollator.compare(a, b) + }; } - return a < b ? Comparison.LessThan : Comparison.GreaterThan; + function createStringLocaleComparers(): StringComparers { + // for case-insensitive comparisons we always map both strings to their + // upper-case form as some unicode characters do not properly round-trip to + // lowercase (such as ẞ). + return { + caseSensitive: (a, b) => a.localeCompare(b), + caseInsensitive: (a, b) => a.toLocaleUpperCase().localeCompare(b.toLocaleUpperCase()) + }; + } + + function createOrdinalComparers(): StringComparers { + // for case-insensitive comparisons we always map both strings to their + // upper-case form as some unicode characters do not properly round-trip to + // lowercase (such as ẞ). + // + // The ordinal comparison cannot properly handle comparison of the Turkish + // (dotted) i and (dotless) ı to the uppercase forms of (dotted) İ and (dotless) I. + // This is best handled by Intl and not supported in the fallback case. + return { + caseSensitive: compareNonNullValues, + caseInsensitive: (a, b) => compareNonNullValues(a.toUpperCase(), b.toUpperCase()) + }; + } + + // If the host supports Intl (ECMA-402), we use Intl for comparisons using the default + // locale. + if (typeof Intl === "object" && typeof Intl.Collator === "function") { + return createIntlComparers(); + } + + // If the host does not support Intl (Safari, Node v0.10), we fall back to localeCompare. + // Node v0.10 provides incorrect results for comparisons using localeCompare, so we must + // verify the implementation. + if (typeof String.prototype.localeCompare === "function" && + typeof String.prototype.toLocaleUpperCase === "function" && + "a".localeCompare("B") < 0) { + return createStringLocaleComparers(); + } + + // fall back to ordinal comparison + return createOrdinalComparers(); } - export function compareStringsCaseInsensitive(a: string, b: string) { - return compareStrings(a, b, /*ignoreCase*/ true); + const stringComparers = createStringComparers(); + + /** + * Performs a case-sensitive comparison between two strings. + * + * If supported by the host, the default locale is used for comparisons. Otherwise, an ordinal + * comparison is used. + */ + export function compareStringsCaseSensitive(a: string | undefined, b: string | undefined) { + return compareValuesWithCallback(a, b, stringComparers.caseSensitive); + } + + /** + * Performs a case-insensitive comparison between two strings. + * + * If supported by the host, the default locale is used for comparisons. Otherwise, an ordinal + * comparison is used. + */ + export function compareStringsCaseInsensitive(a: string | undefined, b: string | undefined) { + return compareValuesWithCallback(a, b, stringComparers.caseInsensitive); + } + + export function compareStrings(a: string | undefined, b: string | undefined, ignoreCase?: boolean): Comparison { + return ignoreCase ? compareStringsCaseInsensitive(a, b) : compareStringsCaseSensitive(a, b); } function getDiagnosticFileName(diagnostic: Diagnostic): string { From 7f577dcef3bc414a5ea9a87aebeedbc7c035100a Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Tue, 24 Oct 2017 14:02:02 -0700 Subject: [PATCH 015/235] Added triple slash support --- src/services/goToDefinition.ts | 14 ++++++++++---- tests/cases/fourslash/goToDefinitionSourceUnit.ts | 2 +- .../goToDefinitionTypeReferenceDirective.ts | 2 +- .../goToDefinitionTypeReferenceDirective.ts | 2 +- .../shims/goToDefinitionTypeReferenceDirective.ts | 2 +- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index eaee0afdd1e..0641c814cac 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -156,10 +156,16 @@ namespace ts.GoToDefinition { return undefined; } - // TODO: Add textSpan for triple slash references (file and type). - const comment = findReferenceInPosition(sourceFile.referencedFiles, position); - if (comment && tryResolveScriptReference(program, sourceFile, comment) || findReferenceInPosition(sourceFile.typeReferenceDirectives, position)) { - return { definitions, textSpan: undefined }; + let comment = findReferenceInPosition(sourceFile.referencedFiles, position); + if (!comment || !tryResolveScriptReference(program, sourceFile, comment)) { + comment = findReferenceInPosition(sourceFile.typeReferenceDirectives, position); + } + + if (comment) { + return { + definitions, + textSpan: createTextSpanFromBounds(comment.pos, comment.end) + }; } const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); diff --git a/tests/cases/fourslash/goToDefinitionSourceUnit.ts b/tests/cases/fourslash/goToDefinitionSourceUnit.ts index e66b5ef7960..d823b366eee 100644 --- a/tests/cases/fourslash/goToDefinitionSourceUnit.ts +++ b/tests/cases/fourslash/goToDefinitionSourceUnit.ts @@ -4,7 +4,7 @@ //// //MyFile Comments //// //more comments //// /// -//// /// +//// /// //// //// class clsInOverload { //// static fnOverload(); diff --git a/tests/cases/fourslash/goToDefinitionTypeReferenceDirective.ts b/tests/cases/fourslash/goToDefinitionTypeReferenceDirective.ts index ad02bb9d851..532390fb35e 100644 --- a/tests/cases/fourslash/goToDefinitionTypeReferenceDirective.ts +++ b/tests/cases/fourslash/goToDefinitionTypeReferenceDirective.ts @@ -5,7 +5,7 @@ /////*0*/declare let $: {x: number}; // @Filename: src/app.ts -//// /// +//// /// //// $.x; verify.goToDefinition("1", "0"); diff --git a/tests/cases/fourslash/shims-pp/goToDefinitionTypeReferenceDirective.ts b/tests/cases/fourslash/shims-pp/goToDefinitionTypeReferenceDirective.ts index ad02bb9d851..532390fb35e 100644 --- a/tests/cases/fourslash/shims-pp/goToDefinitionTypeReferenceDirective.ts +++ b/tests/cases/fourslash/shims-pp/goToDefinitionTypeReferenceDirective.ts @@ -5,7 +5,7 @@ /////*0*/declare let $: {x: number}; // @Filename: src/app.ts -//// /// +//// /// //// $.x; verify.goToDefinition("1", "0"); diff --git a/tests/cases/fourslash/shims/goToDefinitionTypeReferenceDirective.ts b/tests/cases/fourslash/shims/goToDefinitionTypeReferenceDirective.ts index 4669b7f62e9..f318de7c25e 100644 --- a/tests/cases/fourslash/shims/goToDefinitionTypeReferenceDirective.ts +++ b/tests/cases/fourslash/shims/goToDefinitionTypeReferenceDirective.ts @@ -5,7 +5,7 @@ /////*0*/declare let $: {x: number}; // @Filename: src/app.ts -//// /// +//// /// //// $.x; verify.goToDefinition("1", "0"); From 763d17e947fc8bafc66f586e42697128361ae543 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 24 Oct 2017 14:17:29 -0700 Subject: [PATCH 016/235] Manually inline a few cases to reduce repeated 'ignoreCase' conditionals in loops --- src/compiler/core.ts | 10 ++++++---- src/compiler/program.ts | 3 ++- src/services/navigateTo.ts | 5 +---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index ddcd8c849e7..f11ace7f6c4 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1975,8 +1975,9 @@ namespace ts { const aComponents = getNormalizedPathComponents(a, currentDirectory); const bComponents = getNormalizedPathComponents(b, currentDirectory); const sharedLength = Math.min(aComponents.length, bComponents.length); + const stringComparer = ignoreCase ? compareStringsCaseInsensitive : compareStringsCaseSensitive; for (let i = 0; i < sharedLength; i++) { - const result = compareStrings(aComponents[i], bComponents[i], ignoreCase); + const result = stringComparer(aComponents[i], bComponents[i]); if (result !== Comparison.EqualTo) { return result; } @@ -1997,8 +1998,9 @@ namespace ts { return false; } + const stringComparer = ignoreCase ? compareStringsCaseInsensitive : compareStringsCaseSensitive; for (let i = 0; i < parentComponents.length; i++) { - const result = compareStrings(parentComponents[i], childComponents[i], ignoreCase); + const result = stringComparer(parentComponents[i], childComponents[i]); if (result !== Comparison.EqualTo) { return false; } @@ -2255,7 +2257,7 @@ namespace ts { // If there are no "includes", then just put everything in results[0]. const results: string[][] = includeFileRegexes ? includeFileRegexes.map(() => []) : [[]]; - const comparer = useCaseSensitiveFileNames ? compareStrings : compareStringsCaseInsensitive; + const comparer = useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive; for (const basePath of patterns.basePaths) { visitDirectory(basePath, combinePaths(currentDirectory, basePath), depth); } @@ -2320,7 +2322,7 @@ namespace ts { } // Sort the offsets array using either the literal or canonical path representations. - includeBasePaths.sort(useCaseSensitiveFileNames ? compareStrings : compareStringsCaseInsensitive); + includeBasePaths.sort(useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive); // Iterate over each include base path and include unique base paths that are not a // subpath of an existing base path diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 0ff78a77ecd..e87a4997f13 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1105,7 +1105,8 @@ namespace ts { return compareStrings(file.fileName, getDefaultLibraryFileName(), /*ignoreCase*/ !host.useCaseSensitiveFileNames()) === Comparison.EqualTo; } else { - return forEach(options.lib, libFileName => compareStrings(file.fileName, combinePaths(defaultLibraryPath, libFileName), /*ignoreCase*/ !host.useCaseSensitiveFileNames()) === Comparison.EqualTo); + const stringComparer = host.useCaseSensitiveFileNames() ? compareStringsCaseSensitive : compareStringsCaseInsensitive; + return forEach(options.lib, libFileName => stringComparer(file.fileName, combinePaths(defaultLibraryPath, libFileName)) === Comparison.EqualTo); } } diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index 7fa177b6a30..be2c7b61a7e 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -176,11 +176,8 @@ namespace ts.NavigateTo { function compareNavigateToItems(i1: RawNavigateToItem, i2: RawNavigateToItem): number { // TODO(cyrusn): get the gamut of comparisons that VS already uses here. // Right now we just sort by kind first, and then by name of the item. - // We first sort case insensitively. So "Aaa" will come before "bar". - // Then we sort case sensitively, so "aaa" will come before "Aaa". return i1.matchKind - i2.matchKind || - ts.compareStringsCaseInsensitive(i1.name, i2.name) || - ts.compareStrings(i1.name, i2.name); + ts.compareStringsCaseSensitive(i1.name, i2.name); } function createNavigateToItem(rawItem: RawNavigateToItem): NavigateToItem { From 5f8b392f7df76fea985d9f8ab43ae844b7c2ee77 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 24 Oct 2017 15:50:19 -0700 Subject: [PATCH 017/235] Revert use of Intl/localeCompare for CS comparisons --- src/compiler/core.ts | 120 ++++++++++++++++--------------------------- 1 file changed, 44 insertions(+), 76 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index f11ace7f6c4..7c4139e3e07 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1483,101 +1483,58 @@ namespace ts { return headChain; } - function toComparison(value: number) { - return value < 0 ? Comparison.LessThan : value > 0 ? Comparison.GreaterThan : Comparison.EqualTo; - } - - function compareNonNullValues(a: T, b: T): Comparison { - return a < b ? Comparison.LessThan : a > b ? Comparison.GreaterThan : Comparison.EqualTo; - } - - function compareValuesWithCallback(a: T | undefined, b: T | undefined, comparer: (a: T, b: T) => number) { + export function compareValues(a: T | undefined, b: T | undefined) { if (a === b) return Comparison.EqualTo; if (a === undefined) return Comparison.LessThan; if (b === undefined) return Comparison.GreaterThan; - return toComparison(comparer(a, b)); - } - - export function compareValues(a: T | undefined, b: T | undefined): Comparison { - return compareValuesWithCallback(a, b, compareNonNullValues); - } - - interface StringComparers { - caseSensitive(a: string, b: string): number; - caseInsensitive(a: string, b: string): number; + return a < b ? Comparison.LessThan : Comparison.GreaterThan; } // Gets string comparers compatible with the current host - function createStringComparers() { - function createIntlComparers(): StringComparers { - // Strings that differ in base, accents/diacritic marks, or case compare as unequal. - // An `undefined` locale uses the default locale of the host. - const caseSensitiveCollator = new Intl.Collator(/*locales*/ undefined, { usage: "sort", sensitivity: "variant" }); - + function createCaseInsensitiveStringComparer(): (a: string, b: string) => number { + // If the host supports Intl (ECMA-402), we use Intl for comparisons using the default + // locale: + if (typeof Intl === "object" && typeof Intl.Collator === "function") { // Strings that differ in base or accents/diacritic marks compare as unequal. // An `undefined` locale uses the default locale of the host. - const caseInsensitiveCollator = new Intl.Collator(/*locales*/ undefined, { usage: "sort", sensitivity: "accent" }); - - return { - caseSensitive: (a, b) => caseSensitiveCollator.compare(a, b), - caseInsensitive: (a, b) => caseInsensitiveCollator.compare(a, b) - }; - } - - function createStringLocaleComparers(): StringComparers { - // for case-insensitive comparisons we always map both strings to their - // upper-case form as some unicode characters do not properly round-trip to - // lowercase (such as ẞ). - return { - caseSensitive: (a, b) => a.localeCompare(b), - caseInsensitive: (a, b) => a.toLocaleUpperCase().localeCompare(b.toLocaleUpperCase()) - }; - } - - function createOrdinalComparers(): StringComparers { - // for case-insensitive comparisons we always map both strings to their - // upper-case form as some unicode characters do not properly round-trip to - // lowercase (such as ẞ). // - // The ordinal comparison cannot properly handle comparison of the Turkish - // (dotted) i and (dotless) ı to the uppercase forms of (dotted) İ and (dotless) I. - // This is best handled by Intl and not supported in the fallback case. - return { - caseSensitive: compareNonNullValues, - caseInsensitive: (a, b) => compareNonNullValues(a.toUpperCase(), b.toUpperCase()) - }; + // Intl.Collator.prototype.compare is bound to the collator. See NOTE in + // http://www.ecma-international.org/ecma-402/2.0/#sec-Intl.Collator.prototype.compare + return new Intl.Collator(/*locales*/ undefined, { usage: "sort", sensitivity: "accent" }).compare; } - // If the host supports Intl (ECMA-402), we use Intl for comparisons using the default - // locale. - if (typeof Intl === "object" && typeof Intl.Collator === "function") { - return createIntlComparers(); - } - - // If the host does not support Intl (Safari, Node v0.10), we fall back to localeCompare. + // If the host does not support Intl, we fall back to localeCompare: + // // Node v0.10 provides incorrect results for comparisons using localeCompare, so we must // verify the implementation. if (typeof String.prototype.localeCompare === "function" && typeof String.prototype.toLocaleUpperCase === "function" && "a".localeCompare("B") < 0) { - return createStringLocaleComparers(); + // for case-insensitive comparisons we always map both strings to their + // upper-case form as some unicode characters do not properly round-trip to + // lowercase (such as ẞ). + return (a, b) => a.toLocaleUpperCase().localeCompare(b.toLocaleUpperCase()); } - // fall back to ordinal comparison - return createOrdinalComparers(); + // Otherwise, fall back to ordinal comparison: + // + // for case-insensitive comparisons we always map both strings to their + // upper-case form as some unicode characters do not properly round-trip to + // lowercase (such as ẞ). + // + // The ordinal comparison cannot properly handle comparison of the Turkish + // (dotted) i and (dotless) ı to the uppercase forms of (dotted) İ and (dotless) I. + // This is best handled by Intl and not supported in the fallback case. + return (a, b) => { + const upperA = a.toUpperCase(); + const upperB = b.toUpperCase(); + return upperA < upperB ? Comparison.LessThan : + upperA > upperB ? Comparison.GreaterThan : + Comparison.EqualTo; + }; } - const stringComparers = createStringComparers(); - - /** - * Performs a case-sensitive comparison between two strings. - * - * If supported by the host, the default locale is used for comparisons. Otherwise, an ordinal - * comparison is used. - */ - export function compareStringsCaseSensitive(a: string | undefined, b: string | undefined) { - return compareValuesWithCallback(a, b, stringComparers.caseSensitive); - } + const caseInsensitiveComparer = createCaseInsensitiveStringComparer(); /** * Performs a case-insensitive comparison between two strings. @@ -1586,7 +1543,18 @@ namespace ts { * comparison is used. */ export function compareStringsCaseInsensitive(a: string | undefined, b: string | undefined) { - return compareValuesWithCallback(a, b, stringComparers.caseInsensitive); + if (a === b) return Comparison.EqualTo; + if (a === undefined) return Comparison.LessThan; + if (b === undefined) return Comparison.GreaterThan; + const result = caseInsensitiveComparer(a, b); + return result < 0 ? Comparison.LessThan : result > 0 ? Comparison.GreaterThan : Comparison.EqualTo; + } + + /** + * Performs a case-sensitive comparison between two strings. + */ + export function compareStringsCaseSensitive(a: string | undefined, b: string | undefined) { + return compareValues(a, b); } export function compareStrings(a: string | undefined, b: string | undefined, ignoreCase?: boolean): Comparison { From 7fd9fe686b6d40c0f2b8db7b6b384d5c9e2d96b3 Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Tue, 24 Oct 2017 15:58:43 -0700 Subject: [PATCH 018/235] Rollback spread operator changes --- src/server/session.ts | 59 +++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/src/server/session.ts b/src/server/session.ts index f6d21fe8772..a63620252bc 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -609,7 +609,7 @@ namespace ts.server { } if (simplifiedResult) { - return this.mapFileSpan(definitions, project); + return this.mapDefinitionInfo(definitions, project); } else { return definitions; @@ -632,7 +632,7 @@ namespace ts.server { if (simplifiedResult) { return { - definitions: this.mapFileSpan(definitionAndBoundSpan.definitions, project), + definitions: this.mapDefinitionInfo(definitionAndBoundSpan.definitions, project), textSpan: this.toLocationTextSpan(definitionAndBoundSpan.textSpan, scriptInfo) }; } @@ -640,16 +640,17 @@ namespace ts.server { return definitionAndBoundSpan; } - private mapFileSpan(definitions: ReadonlyArray, project: Project): ReadonlyArray { - return definitions.map(def => this.getFileSpan(def.fileName, def.textSpan, project)); + private mapDefinitionInfo(definitions: ReadonlyArray, project: Project): ReadonlyArray { + return definitions.map(def => this.toFileSpan(def.fileName, def.textSpan, project)); } - private getFileSpan(fileName: string, textSpan: TextSpan, project: Project): protocol.FileSpan { + private toFileSpan(fileName: string, textSpan: TextSpan, project: Project): protocol.FileSpan { const scriptInfo = project.getScriptInfo(fileName); return { file: fileName, - ...this.toLocationTextSpan(textSpan, scriptInfo) + start: scriptInfo.positionToLineOffset(textSpan.start), + end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan)) }; } @@ -662,7 +663,7 @@ namespace ts.server { return emptyArray; } - return this.mapFileSpan(definitions, project); + return this.mapDefinitionInfo(definitions, project); } private getImplementation(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): ReadonlyArray | ReadonlyArray { @@ -673,7 +674,7 @@ namespace ts.server { return emptyArray; } if (simplifiedResult) { - return implementations.map(({ fileName, textSpan }) => this.getFileSpan(fileName, textSpan, project)); + return implementations.map(({ fileName, textSpan }) => this.toFileSpan(fileName, textSpan, project)); } else { return implementations; @@ -682,6 +683,7 @@ namespace ts.server { private getOccurrences(args: protocol.FileLocationRequestArgs): ReadonlyArray { const { file, project } = this.getFileAndProject(args); + const position = this.getPositionInFile(args, file); const occurrences = project.getLanguageService().getOccurrencesAtPosition(file, position); @@ -694,9 +696,10 @@ namespace ts.server { const { fileName, isWriteAccess, textSpan, isInString } = occurrence; const scriptInfo = project.getScriptInfo(fileName); const result: protocol.OccurrencesResponseItem = { + start: scriptInfo.positionToLineOffset(textSpan.start), + end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan)), file: fileName, isWriteAccess, - ...this.toLocationTextSpan(textSpan, scriptInfo) }; // no need to serialize the property if it is not true if (isInString) { @@ -734,13 +737,13 @@ namespace ts.server { } if (simplifiedResult) { - return documentHighlights.map(x => convertToDocumentHighlightsItem(x, this.toLocationTextSpan)); + return documentHighlights.map(convertToDocumentHighlightsItem); } else { return documentHighlights; } - function convertToDocumentHighlightsItem(documentHighlights: DocumentHighlights, toLocationSpan: (textSpan: TextSpan, scriptInfo: ScriptInfo) => protocol.TextSpan): protocol.DocumentHighlightsItem { + function convertToDocumentHighlightsItem(documentHighlights: DocumentHighlights): protocol.DocumentHighlightsItem { const { fileName, highlightSpans } = documentHighlights; const scriptInfo = project.getScriptInfo(fileName); @@ -749,10 +752,11 @@ namespace ts.server { highlightSpans: highlightSpans.map(convertHighlightSpan) }; - function convertHighlightSpan(this: Session, highlightSpan: HighlightSpan): protocol.HighlightSpan { + function convertHighlightSpan(highlightSpan: HighlightSpan): protocol.HighlightSpan { const { textSpan, kind } = highlightSpan; - - return { kind, ...toLocationSpan(textSpan, scriptInfo) }; + const start = scriptInfo.positionToLineOffset(textSpan.start); + const end = scriptInfo.positionToLineOffset(textSpanEnd(textSpan)); + return { start, end, kind }; } } } @@ -845,7 +849,8 @@ namespace ts.server { const locationScriptInfo = project.getScriptInfo(location.fileName); return { file: location.fileName, - ...this.toLocationTextSpan(location.textSpan, locationScriptInfo) + start: locationScriptInfo.positionToLineOffset(location.textSpan.start), + end: locationScriptInfo.positionToLineOffset(textSpanEnd(location.textSpan)), }; }); }, @@ -940,15 +945,16 @@ namespace ts.server { return references.map(ref => { const refScriptInfo = project.getScriptInfo(ref.fileName); - const textSpan = this.toLocationTextSpan(ref.textSpan, refScriptInfo); - const refLineSpan = refScriptInfo.lineToTextSpan(textSpan.start.line - 1); + const start = refScriptInfo.positionToLineOffset(ref.textSpan.start); + const refLineSpan = refScriptInfo.lineToTextSpan(start.line - 1); const lineText = refScriptInfo.getSnapshot().getText(refLineSpan.start, textSpanEnd(refLineSpan)).replace(/\r|\n/g, ""); return { file: ref.fileName, + start, lineText, + end: refScriptInfo.positionToLineOffset(textSpanEnd(ref.textSpan)), isWriteAccess: ref.isWriteAccess, - isDefinition: ref.isDefinition, - ...textSpan + isDefinition: ref.isDefinition }; }); }, @@ -1087,10 +1093,11 @@ namespace ts.server { return { kind: quickInfo.kind, kindModifiers: quickInfo.kindModifiers, + start: scriptInfo.positionToLineOffset(quickInfo.textSpan.start), + end: scriptInfo.positionToLineOffset(textSpanEnd(quickInfo.textSpan)), displayString, documentation: docString, - tags: quickInfo.tags || [], - ...this.toLocationTextSpan(quickInfo.textSpan, scriptInfo) + tags: quickInfo.tags || [] }; } else { @@ -1180,8 +1187,9 @@ namespace ts.server { return edits.map((edit) => { return { - newText: edit.newText ? edit.newText : "", - ...this.toLocationTextSpan(edit.span, scriptInfo) + start: scriptInfo.positionToLineOffset(edit.span.start), + end: scriptInfo.positionToLineOffset(textSpanEnd(edit.span)), + newText: edit.newText ? edit.newText : "" }; }); } @@ -1409,7 +1417,8 @@ namespace ts.server { name: navItem.name, kind: navItem.kind, file: navItem.fileName, - ...this.toLocationTextSpan(navItem.textSpan, scriptInfo) + start: scriptInfo.positionToLineOffset(navItem.textSpan.start), + end: scriptInfo.positionToLineOffset(textSpanEnd(navItem.textSpan)) }; if (navItem.kindModifiers && (navItem.kindModifiers !== "")) { bakedItem.kindModifiers = navItem.kindModifiers; @@ -1596,7 +1605,7 @@ namespace ts.server { fileName: change.fileName, textChanges: change.textChanges.map(textChange => this.convertTextChangeToCodeEdit(textChange, scriptInfo)) })); - return { description, changes, commands }; + return { description, changes, commands }; } private mapTextChangesToCodeEdits(project: Project, textChanges: FileTextChanges): protocol.FileCodeEdits { From 5b7abf2425e96489a4d8197d4bbccf0641789b57 Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Tue, 24 Oct 2017 15:59:33 -0700 Subject: [PATCH 019/235] Fixed tsserverlibrary.d.ts tests --- tests/baselines/reference/api/tsserverlibrary.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 289137cbcf7..87d88ba4355 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -6922,8 +6922,8 @@ declare namespace ts.server { private getDiagnosticsWorker(args, isSemantic, selector, includeLinePosition); private getDefinition(args, simplifiedResult); private getDefinitionAndBoundSpan(args, simplifiedResult); - private mapFileSpan(definitions, project); - private getFileSpan(fileName, textSpan, project); + private mapDefinitionInfo(definitions, project); + private toFileSpan(fileName, textSpan, project); private getTypeDefinition(args); private getImplementation(args, simplifiedResult); private getOccurrences(args); From f3059ce698364872d0bb945672c4278803a81f96 Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Tue, 24 Oct 2017 16:08:23 -0700 Subject: [PATCH 020/235] Addressed PR comments. --- src/services/goToDefinition.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 0641c814cac..35f4d079e29 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -156,11 +156,8 @@ namespace ts.GoToDefinition { return undefined; } - let comment = findReferenceInPosition(sourceFile.referencedFiles, position); - if (!comment || !tryResolveScriptReference(program, sourceFile, comment)) { - comment = findReferenceInPosition(sourceFile.typeReferenceDirectives, position); - } - + // Check if position is on triple slash reference. + const comment = findReferenceInPosition(sourceFile.referencedFiles, position) || findReferenceInPosition(sourceFile.typeReferenceDirectives, position); if (comment) { return { definitions, From dee77ced7c3e19ca8bf16ab0b3b0d382512ca9b4 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 24 Oct 2017 16:14:49 -0700 Subject: [PATCH 021/235] Added 'equateStrings' for string equality comparisons (rather than sorting) --- src/compiler/core.ts | 111 +++++++++++++++++++++++++++++----------- src/compiler/parser.ts | 2 +- src/compiler/program.ts | 6 +-- 3 files changed, 84 insertions(+), 35 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 7c4139e3e07..79a9aa8e019 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1490,17 +1490,60 @@ namespace ts { return a < b ? Comparison.LessThan : Comparison.GreaterThan; } + interface StringCollator { + compare(a: string, b: string): number; + equals(a: string, b: string): boolean; + } + // Gets string comparers compatible with the current host - function createCaseInsensitiveStringComparer(): (a: string, b: string) => number { + function createCaseInsensitiveStringComparers() { + function createIntlStringCollator(): StringCollator { + // Strings that differ in base or accents/diacritic marks compare as unequal. + // An `undefined` locale uses the default locale of the host. + const sortCollator = new Intl.Collator(/*locales*/ undefined, { usage: "sort", sensitivity: "accent" }); + const searchCollator = new Intl.Collator(/*locales*/ undefined, { usage: "search", sensitivity: "accent" }); + return { + // Intl.Collator.prototype.compare is bound to the collator. See NOTE in + // http://www.ecma-international.org/ecma-402/2.0/#sec-Intl.Collator.prototype.compare + compare: sortCollator.compare, + equals: (a, b) => searchCollator.compare(a, b) === 0 + }; + } + + function createLocaleCompareStringCollator(): StringCollator { + // for case-insensitive comparisons we always map both strings to their + // upper-case form as some unicode characters do not properly round-trip to + // lowercase (such as ẞ). + return { + compare: (a, b) => a.toLocaleUpperCase().localeCompare(b.toLocaleUpperCase()), + equals: (a, b) => a.toLocaleUpperCase() === b.toLocaleUpperCase() + }; + } + + function createOrdinalStringCollator(): StringCollator { + // for case-insensitive comparisons we always map both strings to their + // upper-case form as some unicode characters do not properly round-trip to + // lowercase (such as ẞ). + // + // The ordinal comparison cannot properly handle comparison of the Turkish + // (dotted) i and (dotless) ı to the uppercase forms of (dotted) İ and (dotless) I. + // This is best handled by Intl and not supported in the fallback case. + return { + compare: (a, b) => { + const upperA = a.toUpperCase(); + const upperB = b.toUpperCase(); + return upperA < upperB ? Comparison.LessThan : + upperA > upperB ? Comparison.GreaterThan : + Comparison.EqualTo; + }, + equals: (a, b) => a.toUpperCase() === b.toUpperCase() + }; + } + // If the host supports Intl (ECMA-402), we use Intl for comparisons using the default // locale: if (typeof Intl === "object" && typeof Intl.Collator === "function") { - // Strings that differ in base or accents/diacritic marks compare as unequal. - // An `undefined` locale uses the default locale of the host. - // - // Intl.Collator.prototype.compare is bound to the collator. See NOTE in - // http://www.ecma-international.org/ecma-402/2.0/#sec-Intl.Collator.prototype.compare - return new Intl.Collator(/*locales*/ undefined, { usage: "sort", sensitivity: "accent" }).compare; + return createIntlStringCollator(); } // If the host does not support Intl, we fall back to localeCompare: @@ -1510,31 +1553,14 @@ namespace ts { if (typeof String.prototype.localeCompare === "function" && typeof String.prototype.toLocaleUpperCase === "function" && "a".localeCompare("B") < 0) { - // for case-insensitive comparisons we always map both strings to their - // upper-case form as some unicode characters do not properly round-trip to - // lowercase (such as ẞ). - return (a, b) => a.toLocaleUpperCase().localeCompare(b.toLocaleUpperCase()); + return createLocaleCompareStringCollator(); } // Otherwise, fall back to ordinal comparison: - // - // for case-insensitive comparisons we always map both strings to their - // upper-case form as some unicode characters do not properly round-trip to - // lowercase (such as ẞ). - // - // The ordinal comparison cannot properly handle comparison of the Turkish - // (dotted) i and (dotless) ı to the uppercase forms of (dotted) İ and (dotless) I. - // This is best handled by Intl and not supported in the fallback case. - return (a, b) => { - const upperA = a.toUpperCase(); - const upperB = b.toUpperCase(); - return upperA < upperB ? Comparison.LessThan : - upperA > upperB ? Comparison.GreaterThan : - Comparison.EqualTo; - }; + return createOrdinalStringCollator(); } - const caseInsensitiveComparer = createCaseInsensitiveStringComparer(); + const caseInsensitiveCollator = createCaseInsensitiveStringComparers(); /** * Performs a case-insensitive comparison between two strings. @@ -1546,7 +1572,7 @@ namespace ts { if (a === b) return Comparison.EqualTo; if (a === undefined) return Comparison.LessThan; if (b === undefined) return Comparison.GreaterThan; - const result = caseInsensitiveComparer(a, b); + const result = caseInsensitiveCollator.compare(a, b); return result < 0 ? Comparison.LessThan : result > 0 ? Comparison.GreaterThan : Comparison.EqualTo; } @@ -1561,6 +1587,30 @@ namespace ts { return ignoreCase ? compareStringsCaseInsensitive(a, b) : compareStringsCaseSensitive(a, b); } + /** + * Performs a case-insensitive equality comparison between two strings. + * + * If supported by the host, the default locale is used for comparisons. Otherwise, an ordinal + * comparison is used. + */ + export function equateStringsCaseInsensitive(a: string | undefined, b: string | undefined) { + return a === b + || a !== undefined + && b !== undefined + && caseInsensitiveCollator.equals(a, b); + } + + /** + * Performs a case-sensitive equality comparison between two strings. + */ + export function equateStringsCaseSensitive(a: string | undefined, b: string | undefined) { + return a === b; + } + + export function equateStrings(a: string | undefined, b: string | undefined, ignoreCase?: boolean) { + return ignoreCase ? equateStringsCaseInsensitive(a, b) : equateStringsCaseSensitive(a, b); + } + function getDiagnosticFileName(diagnostic: Diagnostic): string { return diagnostic.file ? diagnostic.file.fileName : undefined; } @@ -1966,10 +2016,9 @@ namespace ts { return false; } - const stringComparer = ignoreCase ? compareStringsCaseInsensitive : compareStringsCaseSensitive; + const stringEqualityComparer = ignoreCase ? equateStringsCaseInsensitive : equateStringsCaseSensitive; for (let i = 0; i < parentComponents.length; i++) { - const result = stringComparer(parentComponents[i], childComponents[i]); - if (result !== Comparison.EqualTo) { + if (!stringEqualityComparer(parentComponents[i], childComponents[i])) { return false; } } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index b27d4811ecb..ef93dfe7d4f 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6069,7 +6069,7 @@ namespace ts { const checkJsDirectiveMatchResult = checkJsDirectiveRegEx.exec(comment); if (checkJsDirectiveMatchResult) { checkJsDirective = { - enabled: compareStrings(checkJsDirectiveMatchResult[1], "@ts-check", /*ignoreCase*/ true) === Comparison.EqualTo, + enabled: equateStrings(checkJsDirectiveMatchResult[1], "@ts-check", /*ignoreCase*/ true), end: range.end, pos: range.pos }; diff --git a/src/compiler/program.ts b/src/compiler/program.ts index e87a4997f13..394dc2a7669 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1102,11 +1102,11 @@ namespace ts { // If '--lib' is not specified, include default library file according to '--target' // otherwise, using options specified in '--lib' instead of '--target' default library file if (!options.lib) { - return compareStrings(file.fileName, getDefaultLibraryFileName(), /*ignoreCase*/ !host.useCaseSensitiveFileNames()) === Comparison.EqualTo; + return equateStrings(file.fileName, getDefaultLibraryFileName(), /*ignoreCase*/ !host.useCaseSensitiveFileNames()); } else { - const stringComparer = host.useCaseSensitiveFileNames() ? compareStringsCaseSensitive : compareStringsCaseInsensitive; - return forEach(options.lib, libFileName => stringComparer(file.fileName, combinePaths(defaultLibraryPath, libFileName)) === Comparison.EqualTo); + const stringEqualityComparer = host.useCaseSensitiveFileNames() ? equateStringsCaseSensitive : equateStringsCaseInsensitive; + return forEach(options.lib, libFileName => stringEqualityComparer(file.fileName, combinePaths(defaultLibraryPath, libFileName))); } } From 7bc3b73ab974afc34af29ac87782fbb2323d1508 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 24 Oct 2017 16:26:11 -0700 Subject: [PATCH 022/235] Clean up existing equality comparisons --- src/compiler/core.ts | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 79a9aa8e019..5c9f23af19a 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -650,13 +650,13 @@ namespace ts { } // TODO: fixme (N^2) - add optional comparer so collection can be sorted before deduplication. - export function deduplicate(array: ReadonlyArray, areEqual?: (a: T, b: T) => boolean): T[] { + export function deduplicate(array: ReadonlyArray, equalityComparer: (a: T, b: T) => boolean = equateValues): T[] { let result: T[]; if (array) { result = []; loop: for (const item of array) { for (const res of result) { - if (areEqual ? areEqual(res, item) : res === item) { + if (equalityComparer(res, item)) { continue loop; } } @@ -666,7 +666,7 @@ namespace ts { return result; } - export function arrayIsEqualTo(array1: ReadonlyArray, array2: ReadonlyArray, equaler?: (a: T, b: T) => boolean): boolean { + export function arrayIsEqualTo(array1: ReadonlyArray, array2: ReadonlyArray, equalityComparer: (a: T, b: T) => boolean = equateValues): boolean { if (!array1 || !array2) { return array1 === array2; } @@ -676,8 +676,7 @@ namespace ts { } for (let i = 0; i < array1.length; i++) { - const equals = equaler ? equaler(array1[i], array2[i]) : array1[i] === array2[i]; - if (!equals) { + if (!equalityComparer(array1[i], array2[i])) { return false; } } @@ -916,6 +915,7 @@ namespace ts { } export type Comparer = (a: T, b: T) => Comparison; + export type EqualityComparer = (a: T, b: T) => boolean; /** * Performs a binary search, finding the index at which 'value' occurs in 'array'. @@ -1124,13 +1124,13 @@ namespace ts { * @param left A map-like whose properties should be compared. * @param right A map-like whose properties should be compared. */ - export function equalOwnProperties(left: MapLike, right: MapLike, equalityComparer?: (left: T, right: T) => boolean) { + export function equalOwnProperties(left: MapLike, right: MapLike, equalityComparer: EqualityComparer = equateValues) { if (left === right) return true; if (!left || !right) return false; for (const key in left) { if (hasOwnProperty.call(left, key)) { if (!hasOwnProperty.call(right, key) === undefined) return false; - if (equalityComparer ? !equalityComparer(left[key], right[key]) : left[key] !== right[key]) return false; + if (!equalityComparer(left[key], right[key])) return false; } } @@ -1483,6 +1483,9 @@ namespace ts { return headChain; } + /** + * Compare two values for their order relative to each other. + */ export function compareValues(a: T | undefined, b: T | undefined) { if (a === b) return Comparison.EqualTo; if (a === undefined) return Comparison.LessThan; @@ -1490,9 +1493,16 @@ namespace ts { return a < b ? Comparison.LessThan : Comparison.GreaterThan; } + /** + * Compare two values for their equality. + */ + export function equateValues(a: T | undefined, b: T | undefined) { + return a === b; + } + interface StringCollator { compare(a: string, b: string): number; - equals(a: string, b: string): boolean; + equate(a: string, b: string): boolean; } // Gets string comparers compatible with the current host @@ -1506,7 +1516,7 @@ namespace ts { // Intl.Collator.prototype.compare is bound to the collator. See NOTE in // http://www.ecma-international.org/ecma-402/2.0/#sec-Intl.Collator.prototype.compare compare: sortCollator.compare, - equals: (a, b) => searchCollator.compare(a, b) === 0 + equate: (a, b) => searchCollator.compare(a, b) === 0 }; } @@ -1516,7 +1526,7 @@ namespace ts { // lowercase (such as ẞ). return { compare: (a, b) => a.toLocaleUpperCase().localeCompare(b.toLocaleUpperCase()), - equals: (a, b) => a.toLocaleUpperCase() === b.toLocaleUpperCase() + equate: (a, b) => a.toLocaleUpperCase() === b.toLocaleUpperCase() }; } @@ -1536,7 +1546,7 @@ namespace ts { upperA > upperB ? Comparison.GreaterThan : Comparison.EqualTo; }, - equals: (a, b) => a.toUpperCase() === b.toUpperCase() + equate: (a, b) => a.toUpperCase() === b.toUpperCase() }; } @@ -1597,14 +1607,14 @@ namespace ts { return a === b || a !== undefined && b !== undefined - && caseInsensitiveCollator.equals(a, b); + && caseInsensitiveCollator.equate(a, b); } /** * Performs a case-sensitive equality comparison between two strings. */ export function equateStringsCaseSensitive(a: string | undefined, b: string | undefined) { - return a === b; + return equateValues(a, b); } export function equateStrings(a: string | undefined, b: string | undefined, ignoreCase?: boolean) { @@ -1993,9 +2003,9 @@ namespace ts { const aComponents = getNormalizedPathComponents(a, currentDirectory); const bComponents = getNormalizedPathComponents(b, currentDirectory); const sharedLength = Math.min(aComponents.length, bComponents.length); - const stringComparer = ignoreCase ? compareStringsCaseInsensitive : compareStringsCaseSensitive; + const comparer = ignoreCase ? compareStringsCaseInsensitive : compareStringsCaseSensitive; for (let i = 0; i < sharedLength; i++) { - const result = stringComparer(aComponents[i], bComponents[i]); + const result = comparer(aComponents[i], bComponents[i]); if (result !== Comparison.EqualTo) { return result; } @@ -2016,9 +2026,9 @@ namespace ts { return false; } - const stringEqualityComparer = ignoreCase ? equateStringsCaseInsensitive : equateStringsCaseSensitive; + const equalityComparer = ignoreCase ? equateStringsCaseInsensitive : equateStringsCaseSensitive; for (let i = 0; i < parentComponents.length; i++) { - if (!stringEqualityComparer(parentComponents[i], childComponents[i])) { + if (!equalityComparer(parentComponents[i], childComponents[i])) { return false; } } From 27d0b9f4fc927d8fd409a7301f4d295363bb9426 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 24 Oct 2017 16:30:23 -0700 Subject: [PATCH 023/235] Minor name change --- src/compiler/core.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 5c9f23af19a..3aea96ef354 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1506,7 +1506,7 @@ namespace ts { } // Gets string comparers compatible with the current host - function createCaseInsensitiveStringComparers() { + function createCaseInsensitiveStringCollator() { function createIntlStringCollator(): StringCollator { // Strings that differ in base or accents/diacritic marks compare as unequal. // An `undefined` locale uses the default locale of the host. @@ -1570,7 +1570,7 @@ namespace ts { return createOrdinalStringCollator(); } - const caseInsensitiveCollator = createCaseInsensitiveStringComparers(); + const caseInsensitiveCollator = createCaseInsensitiveStringCollator(); /** * Performs a case-insensitive comparison between two strings. From 6d4e2a006ffe44657dc9f917551fd598cd28fd73 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 24 Oct 2017 16:36:35 -0700 Subject: [PATCH 024/235] Revert change in navigateTo --- src/services/navigateTo.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index be2c7b61a7e..2647a87ada7 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -176,8 +176,11 @@ namespace ts.NavigateTo { function compareNavigateToItems(i1: RawNavigateToItem, i2: RawNavigateToItem): number { // TODO(cyrusn): get the gamut of comparisons that VS already uses here. // Right now we just sort by kind first, and then by name of the item. + // We first sort case insensitively. So "Aaa" will come before "bar". + // Then we sort case sensitively, so "aaa" will come before "Aaa". return i1.matchKind - i2.matchKind || - ts.compareStringsCaseSensitive(i1.name, i2.name); + compareStringsCaseInsensitive(i1.name, i2.name) || + compareStringsCaseSensitive(i1.name, i2.name); } function createNavigateToItem(rawItem: RawNavigateToItem): NavigateToItem { From 4d7923af00f09bf6cbd2d79fd3c14dcd39ffe965 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 24 Oct 2017 16:37:41 -0700 Subject: [PATCH 025/235] Consistent naming --- src/compiler/program.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 394dc2a7669..bca10eceb67 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1105,8 +1105,8 @@ namespace ts { return equateStrings(file.fileName, getDefaultLibraryFileName(), /*ignoreCase*/ !host.useCaseSensitiveFileNames()); } else { - const stringEqualityComparer = host.useCaseSensitiveFileNames() ? equateStringsCaseSensitive : equateStringsCaseInsensitive; - return forEach(options.lib, libFileName => stringEqualityComparer(file.fileName, combinePaths(defaultLibraryPath, libFileName))); + const equalityComparer = host.useCaseSensitiveFileNames() ? equateStringsCaseSensitive : equateStringsCaseInsensitive; + return forEach(options.lib, libFileName => equalityComparer(file.fileName, combinePaths(defaultLibraryPath, libFileName))); } } From c4a675ef99d67ac2835ca1756fd4af2c6af86616 Mon Sep 17 00:00:00 2001 From: Armando Aguirre Date: Tue, 24 Oct 2017 16:55:41 -0700 Subject: [PATCH 026/235] Removed double tests of gotoDefinition --- src/harness/fourslash.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index c1f3f36e386..1885fd45989 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -583,7 +583,6 @@ namespace FourSlash { } public verifyGoToDefinition(arg0: any, endMarkerNames?: string | string[]) { - this.verifyGoToX(arg0, endMarkerNames, () => this.getGoToDefinition()); this.verifyGoToX(arg0, endMarkerNames, () => this.getGoToDefinitionAndBoundSpan()); } From 130c407708993304170a2720966cdddd4d907bd5 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 25 Oct 2017 16:30:19 -0700 Subject: [PATCH 027/235] More control over which collator to use in each situation --- src/compiler/core.ts | 394 ++++++++++++++++-------- src/compiler/parser.ts | 2 +- src/compiler/program.ts | 8 +- src/compiler/utilities.ts | 3 + src/harness/harness.ts | 4 +- src/harness/unittests/compileOnSave.ts | 6 +- src/server/session.ts | 3 +- src/services/navigateTo.ts | 6 +- src/services/navigationBar.ts | 9 +- src/services/refactors/extractSymbol.ts | 4 +- 10 files changed, 296 insertions(+), 143 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 3aea96ef354..3a706a9119d 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1486,140 +1486,288 @@ namespace ts { /** * Compare two values for their order relative to each other. */ - export function compareValues(a: T | undefined, b: T | undefined) { - if (a === b) return Comparison.EqualTo; - if (a === undefined) return Comparison.LessThan; - if (b === undefined) return Comparison.GreaterThan; - return a < b ? Comparison.LessThan : Comparison.GreaterThan; + export function compareValues(a: T, b: T) { + return a === b ? Comparison.EqualTo : + a === undefined ? Comparison.LessThan : + b === undefined ? Comparison.GreaterThan : + a < b ? Comparison.LessThan : + Comparison.GreaterThan; } /** * Compare two values for their equality. */ - export function equateValues(a: T | undefined, b: T | undefined) { + export function equateValues(a: T, b: T) { return a === b; } - interface StringCollator { - compare(a: string, b: string): number; - equate(a: string, b: string): boolean; + export interface StringCollator { + compare(a: string | undefined, b: string | undefined): number; + equate(a: string | undefined, b: string | undefined): boolean; } - // Gets string comparers compatible with the current host - function createCaseInsensitiveStringCollator() { - function createIntlStringCollator(): StringCollator { - // Strings that differ in base or accents/diacritic marks compare as unequal. - // An `undefined` locale uses the default locale of the host. - const sortCollator = new Intl.Collator(/*locales*/ undefined, { usage: "sort", sensitivity: "accent" }); - const searchCollator = new Intl.Collator(/*locales*/ undefined, { usage: "search", sensitivity: "accent" }); - return { + export interface StringCollators { + /** + * Gets a string collator for case-insensitive ordinal comparisons of strings. + * + * Ordinal comparisons are based on the difference between the unicode code points of + * both strings. Characters with multiple unicode representations are considered + * unequal. + * + * Case-insensitive comparisons compare both strings after applying `toUpperCase` to + * each string. + */ + readonly ordinalCaseInsensitive: StringCollator; + + /** + * Gets a string collator for case-sensitive ordinal comparisons of strings. + * + * Ordinal comparisons are based on the difference between the unicode code points of + * both strings. Characters with multiple unicode representations are considered + * unequal. They provide predictable ordering, but place "a" after "B". + */ + readonly ordinalCaseSensitive: StringCollator; + + /** + * Gets or sets a string collator for case-insensitive comparisons of strings in the host default locale. + * + * UI comparisons are based on the sort order of the host default locale. Ordering is not + * predictable between different host locales, but is best for displaying ordered data + * for UI presentation. Characters with multiple unicode representations may be considered + * equal. + * + * Case-insensitive comparisons compare strings that differ in only base characters or + * accents/diacritic marks as unequal. + */ + readonly uiCaseInsensitive: StringCollator; + + /** + * Gets a string collator for case-sensitive comparisons of strings in the host default locale. + * + * UI comparisons are based on the sort order of the host default locale. Ordering is not + * predictable between different host locales, but is best for displaying ordered data + * for UI presentation. Characters with multiple unicode representations may be considered + * equal. + */ + readonly uiCaseSensitive: StringCollator; + + /** + * Gets a string collator for case-insensitive comparisons of strings in an invariant locale. + * + * Invariant comparisons are based on the sort order of an invariant locale ('en-US'). + * They provide predictable ordering, placing "a" before "B". Characters with multiple + * unicode representations may be considered equal. Invariant comparisons are best used + * when interacting with the file system. + * + * Case-insensitive comparisons compare strings that differ in only base characters or + * accents/diacritic marks as unequal. + */ + readonly invariantCaseInsensitive: StringCollator; + + /** + * Gets a string collator for case-sensitive comparisons of strings in an invariant locale. + * + * Invariant comparisons are based on the sort order of an invariant locale ('en-US'). + * They provide predictable ordering, placing "a" before "B". Characters with multiple + * unicode representations may be considered equal. Invariant comparisons are best used + * when interacting with the file system. + */ + readonly invariantCaseSensitive: StringCollator; + + /** + * Gets or sets the locale for UI collators + */ + uiLocale: string | undefined; + + /** + * Creates a `StringCollator` for a specific locale and case sensitivity. + */ + create(locale: string | undefined, caseSensitive: boolean): StringCollator; + + /** + * Gets the ordinal `StringCollator` for the provided case sensitivity. + */ + getOrdinalCollator(caseSensitive: boolean): StringCollator; + + /** + * Gets the UI `StringCollator` for the provided case sensitivity. + */ + getUICollator(caseSensitive: boolean): StringCollator; + + /** + * Gets the invariant `StringCollator` for the provided case sensitivity. + */ + getInvariantCollator(caseSensitive: boolean): StringCollator; + + /** + * Gets a `StringCollator` for comparing code fragments for code generation. + */ + getCodeCollator(caseSensitive: boolean): StringCollator; + + /** + * Gets a `StringCollator` for comparing paths. + */ + getPathCollator(caseSensitive: boolean): StringCollator; + } + + export const StringCollator: StringCollators = (function () { + const invariantLocaleName = "en-US"; // we use en-US for the invariant locale + const create = getStringCollatorFactory(); + const ordinalCS: StringCollator = { + compare: compareValues, + equate: equateValues + }; + const ordinalCI: StringCollator = { + compare: (a, b) => compareValues(toUpperCase(a), toUpperCase(b)), + equate: (a, b) => toUpperCase(a) === toUpperCase(b) + }; + let invariantCI: StringCollator | undefined; + let invariantCS: StringCollator | undefined; + let uiCI: StringCollator | undefined; + let uiCS: StringCollator | undefined; + let uiLocale: string | undefined; + + return { + get ordinalCaseInsensitive() { return ordinalCI; }, + get ordinalCaseSensitive() { return ordinalCS; }, + get uiCaseInsensitive() { return uiCI || (uiCI = create(uiLocale, /*caseInsensitive*/ true)); }, + get uiCaseSensitive() { return uiCS || (uiCS = create(uiLocale, /*caseInsensitive*/ false)); }, + get invariantCaseInsensitive() { return invariantCI || (invariantCI = create(invariantLocaleName, /*caseInsensitive*/ true)); }, + get invariantCaseSensitive() { return invariantCS || (invariantCS = create(invariantLocaleName, /*caseInsensitive*/ false)); }, + get uiLocale() { return uiLocale; }, + set uiLocale(value) { + if (uiLocale !== value) { + uiLocale = value; + uiCI = undefined; + uiCS = undefined; + } + }, + create, + getOrdinalCollator, + getUICollator, + getInvariantCollator, + getCodeCollator: getInvariantCollator, + getPathCollator: getInvariantCollator + }; + + function getOrdinalCollator(caseInsensitive: boolean) { + return caseInsensitive ? StringCollator.ordinalCaseInsensitive : StringCollator.ordinalCaseSensitive; + } + + function getUICollator(caseInsensitive: boolean) { + return caseInsensitive ? StringCollator.uiCaseInsensitive : StringCollator.uiCaseSensitive; + } + + function getInvariantCollator(caseInsensitive: boolean) { + return caseInsensitive ? StringCollator.invariantCaseInsensitive : StringCollator.invariantCaseSensitive; + } + + function toUpperCase(value: string | undefined): string | undefined { + return value === undefined ? undefined : value.toUpperCase(); + } + + function compareDefined(a: string, b: string) { + return a < b ? Comparison.LessThan : a > b ? Comparison.GreaterThan : Comparison.EqualTo; + } + + function compareWithCallback(a: string | undefined, b: string | undefined, comparer: (a: string, b: string) => number) { + return a === b ? Comparison.EqualTo : + a === undefined ? Comparison.LessThan : + b === undefined ? Comparison.GreaterThan : + toComparison(comparer(a, b)); + } + + function toComparison(value: number) { + return value < 0 ? Comparison.LessThan : value > 0 ? Comparison.GreaterThan : Comparison.EqualTo; + } + + function createIntlStringCollator(locale: string | undefined, caseInsensitive: boolean): StringCollator { + // Initialize the sort collator on first use + let sortComparer: Comparer = (a, b) => { // Intl.Collator.prototype.compare is bound to the collator. See NOTE in // http://www.ecma-international.org/ecma-402/2.0/#sec-Intl.Collator.prototype.compare - compare: sortCollator.compare, - equate: (a, b) => searchCollator.compare(a, b) === 0 + sortComparer = new Intl.Collator(locale, { usage: "sort", sensitivity: caseInsensitive ? "accent" : "variant" }).compare; + return sortComparer(a, b); + }; + + // Initialize the search collator on first use + let searchComparer: Comparer = (a, b) => { + // Intl.Collator.prototype.compare is bound to the collator. See NOTE in + // http://www.ecma-international.org/ecma-402/2.0/#sec-Intl.Collator.prototype.compare + searchComparer = new Intl.Collator(locale, { usage: "search", sensitivity: caseInsensitive ? "accent" : "variant" }).compare; + return searchComparer(a, b); }; - } - function createLocaleCompareStringCollator(): StringCollator { - // for case-insensitive comparisons we always map both strings to their - // upper-case form as some unicode characters do not properly round-trip to - // lowercase (such as ẞ). return { - compare: (a, b) => a.toLocaleUpperCase().localeCompare(b.toLocaleUpperCase()), - equate: (a, b) => a.toLocaleUpperCase() === b.toLocaleUpperCase() + compare: (a, b) => compareWithCallback(a, b, sortComparer), + equate: (a, b) => compareWithCallback(a, b, searchComparer) === 0 }; } - function createOrdinalStringCollator(): StringCollator { - // for case-insensitive comparisons we always map both strings to their - // upper-case form as some unicode characters do not properly round-trip to - // lowercase (such as ẞ). + function createLocaleCompareStringCollator(locale: string | undefined, caseInsensitive: boolean): StringCollator { + if (locale !== undefined) return getFallbackStringCollator(/*locale*/ undefined, caseInsensitive); + if (caseInsensitive) { + // for case-insensitive comparisons we always map both strings to their + // upper-case form as some unicode characters do not properly round-trip to + // lowercase (such as `ẞ` (German sharp capital s)). + return { + compare: (a, b) => compareWithCallback(a, b, localeCompareCaseInsensitive), + equate: (a, b) => compareWithCallback(a, b, localeCompareCaseInsensitive) === 0 + }; + } + else { + return { + compare: (a, b) => compareWithCallback(a, b, localeCompare), + equate: (a, b) => compareWithCallback(a, b, localeCompare) === 0 + }; + } + + function localeCompareCaseInsensitive(a: string, b: string) { + return a.toLocaleUpperCase().localeCompare(b.toLocaleUpperCase()); + } + + function localeCompare(a: string, b: string) { + return a.localeCompare(b); + } + } + + function getFallbackStringCollator(_locale: string | undefined, caseInsensitive: boolean): StringCollator { + if (caseInsensitive) return ordinalCI; + + function compareLowerCaseFirst(a: string, b: string) { + // An ordinal comparison puts "A" after "b", but for the UI we want "A" before "b". + // We first sort case insensitively. So "Aaa" will come before "baa". + // Then we sort case sensitively, so "aaa" will come before "Aaa". + return compareDefined(a.toUpperCase(), b.toUpperCase()) || compareDefined(a, b); + } + + return { + compare: (a, b) => compareWithCallback(a, b, compareLowerCaseFirst), + equate: ordinalCS.equate + }; + } + + function getStringCollatorFactory() { + // If the host supports Intl (ECMA-402), we use Intl for comparisons using the default + // locale: + if (typeof Intl === "object" && typeof Intl.Collator === "function") { + return createIntlStringCollator; + } + + // If the host does not support Intl, we fall back to localeCompare: // - // The ordinal comparison cannot properly handle comparison of the Turkish - // (dotted) i and (dotless) ı to the uppercase forms of (dotted) İ and (dotless) I. - // This is best handled by Intl and not supported in the fallback case. - return { - compare: (a, b) => { - const upperA = a.toUpperCase(); - const upperB = b.toUpperCase(); - return upperA < upperB ? Comparison.LessThan : - upperA > upperB ? Comparison.GreaterThan : - Comparison.EqualTo; - }, - equate: (a, b) => a.toUpperCase() === b.toUpperCase() - }; + // Node v0.10 provides incorrect results for comparisons using localeCompare, so we must + // verify the implementation. + if (typeof String.prototype.localeCompare === "function" && + typeof String.prototype.toLocaleUpperCase === "function" && + "a".localeCompare("B") < 0) { + return createLocaleCompareStringCollator; + } + + // Otherwise, fall back to ordinal comparison: + return getFallbackStringCollator; } - - // If the host supports Intl (ECMA-402), we use Intl for comparisons using the default - // locale: - if (typeof Intl === "object" && typeof Intl.Collator === "function") { - return createIntlStringCollator(); - } - - // If the host does not support Intl, we fall back to localeCompare: - // - // Node v0.10 provides incorrect results for comparisons using localeCompare, so we must - // verify the implementation. - if (typeof String.prototype.localeCompare === "function" && - typeof String.prototype.toLocaleUpperCase === "function" && - "a".localeCompare("B") < 0) { - return createLocaleCompareStringCollator(); - } - - // Otherwise, fall back to ordinal comparison: - return createOrdinalStringCollator(); - } - - const caseInsensitiveCollator = createCaseInsensitiveStringCollator(); - - /** - * Performs a case-insensitive comparison between two strings. - * - * If supported by the host, the default locale is used for comparisons. Otherwise, an ordinal - * comparison is used. - */ - export function compareStringsCaseInsensitive(a: string | undefined, b: string | undefined) { - if (a === b) return Comparison.EqualTo; - if (a === undefined) return Comparison.LessThan; - if (b === undefined) return Comparison.GreaterThan; - const result = caseInsensitiveCollator.compare(a, b); - return result < 0 ? Comparison.LessThan : result > 0 ? Comparison.GreaterThan : Comparison.EqualTo; - } - - /** - * Performs a case-sensitive comparison between two strings. - */ - export function compareStringsCaseSensitive(a: string | undefined, b: string | undefined) { - return compareValues(a, b); - } - - export function compareStrings(a: string | undefined, b: string | undefined, ignoreCase?: boolean): Comparison { - return ignoreCase ? compareStringsCaseInsensitive(a, b) : compareStringsCaseSensitive(a, b); - } - - /** - * Performs a case-insensitive equality comparison between two strings. - * - * If supported by the host, the default locale is used for comparisons. Otherwise, an ordinal - * comparison is used. - */ - export function equateStringsCaseInsensitive(a: string | undefined, b: string | undefined) { - return a === b - || a !== undefined - && b !== undefined - && caseInsensitiveCollator.equate(a, b); - } - - /** - * Performs a case-sensitive equality comparison between two strings. - */ - export function equateStringsCaseSensitive(a: string | undefined, b: string | undefined) { - return equateValues(a, b); - } - - export function equateStrings(a: string | undefined, b: string | undefined, ignoreCase?: boolean) { - return ignoreCase ? equateStringsCaseInsensitive(a, b) : equateStringsCaseSensitive(a, b); - } + })(); function getDiagnosticFileName(diagnostic: Diagnostic): string { return diagnostic.file ? diagnostic.file.fileName : undefined; @@ -2003,9 +2151,9 @@ namespace ts { const aComponents = getNormalizedPathComponents(a, currentDirectory); const bComponents = getNormalizedPathComponents(b, currentDirectory); const sharedLength = Math.min(aComponents.length, bComponents.length); - const comparer = ignoreCase ? compareStringsCaseInsensitive : compareStringsCaseSensitive; + const collator = StringCollator.getPathCollator(ignoreCase); for (let i = 0; i < sharedLength; i++) { - const result = comparer(aComponents[i], bComponents[i]); + const result = collator.compare(aComponents[i], bComponents[i]); if (result !== Comparison.EqualTo) { return result; } @@ -2026,9 +2174,10 @@ namespace ts { return false; } - const equalityComparer = ignoreCase ? equateStringsCaseInsensitive : equateStringsCaseSensitive; + // File-system comparisons should use predictable ordering + const collator = StringCollator.getPathCollator(ignoreCase); for (let i = 0; i < parentComponents.length; i++) { - if (!equalityComparer(parentComponents[i], childComponents[i])) { + if (!collator.equate(parentComponents[i], childComponents[i])) { return false; } } @@ -2284,7 +2433,7 @@ namespace ts { // If there are no "includes", then just put everything in results[0]. const results: string[][] = includeFileRegexes ? includeFileRegexes.map(() => []) : [[]]; - const comparer = useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive; + const collator = StringCollator.getPathCollator(!useCaseSensitiveFileNames); for (const basePath of patterns.basePaths) { visitDirectory(basePath, combinePaths(currentDirectory, basePath), depth); } @@ -2293,7 +2442,7 @@ namespace ts { function visitDirectory(path: string, absolutePath: string, depth: number | undefined) { let { files, directories } = getFileSystemEntries(path); - files = files.slice().sort(comparer); + files = files.slice().sort(collator.compare); for (const current of files) { const name = combinePaths(path, current); @@ -2318,7 +2467,7 @@ namespace ts { } } - directories = directories.slice().sort(comparer); + directories = directories.slice().sort(collator.compare); for (const current of directories) { const name = combinePaths(path, current); const absoluteName = combinePaths(absolutePath, current); @@ -2349,7 +2498,8 @@ namespace ts { } // Sort the offsets array using either the literal or canonical path representations. - includeBasePaths.sort(useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive); + const collator = StringCollator.getPathCollator(!useCaseSensitiveFileNames); + includeBasePaths.sort(collator.compare); // Iterate over each include base path and include unique base paths that are not a // subpath of an existing base path diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index ef93dfe7d4f..bda31d83d86 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6069,7 +6069,7 @@ namespace ts { const checkJsDirectiveMatchResult = checkJsDirectiveRegEx.exec(comment); if (checkJsDirectiveMatchResult) { checkJsDirective = { - enabled: equateStrings(checkJsDirectiveMatchResult[1], "@ts-check", /*ignoreCase*/ true), + enabled: StringCollator.ordinalCaseInsensitive.equate(checkJsDirectiveMatchResult[1], "@ts-check"), end: range.end, pos: range.pos }; diff --git a/src/compiler/program.ts b/src/compiler/program.ts index bca10eceb67..ff3143f3d96 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1101,12 +1101,14 @@ namespace ts { // If '--lib' is not specified, include default library file according to '--target' // otherwise, using options specified in '--lib' instead of '--target' default library file + + // File-system ordering should use a predictable order + const collator = StringCollator.getPathCollator(!host.useCaseSensitiveFileNames()); if (!options.lib) { - return equateStrings(file.fileName, getDefaultLibraryFileName(), /*ignoreCase*/ !host.useCaseSensitiveFileNames()); + return collator.equate(file.fileName, getDefaultLibraryFileName()); } else { - const equalityComparer = host.useCaseSensitiveFileNames() ? equateStringsCaseSensitive : equateStringsCaseInsensitive; - return forEach(options.lib, libFileName => equalityComparer(file.fileName, combinePaths(defaultLibraryPath, libFileName))); + return forEach(options.lib, libFileName => collator.equate(file.fileName, combinePaths(defaultLibraryPath, libFileName))); } } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 01bb36e9065..7ae7e84ad18 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3949,6 +3949,9 @@ namespace ts { trySetLanguageAndTerritory(language, /*territory*/ undefined, errors); } + // Set the locale for UI collation + StringCollator.uiLocale = locale; + function trySetLanguageAndTerritory(language: string, territory: string, errors?: Push): boolean { const compilerFilePath = normalizePath(sys.getExecutingFilePath()); const containingDirectoryPath = getDirectoryPath(compilerFilePath); diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 9622a6df332..8029c3672af 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1698,7 +1698,9 @@ namespace Harness { export function *iterateOutputs(outputFiles: Harness.Compiler.GeneratedFile[]): IterableIterator<[string, string]> { // Collect, test, and sort the fileNames - outputFiles.sort((a, b) => ts.compareStrings(cleanName(a.fileName), cleanName(b.fileName))); + // As this uses the file system, use a predictable order + const collator = ts.StringCollator.getPathCollator(/*ignoreCase*/ false); + outputFiles.sort((a, b) => collator.compare(cleanName(a.fileName), cleanName(b.fileName))); const dupeCase = ts.createMap(); // Yield them for (const outputFile of outputFiles) { diff --git a/src/harness/unittests/compileOnSave.ts b/src/harness/unittests/compileOnSave.ts index 7be6ab5b323..8c7ae507991 100644 --- a/src/harness/unittests/compileOnSave.ts +++ b/src/harness/unittests/compileOnSave.ts @@ -13,8 +13,10 @@ namespace ts.projectSystem { describe("CompileOnSave affected list", () => { function sendAffectedFileRequestAndCheckResult(session: server.Session, request: server.protocol.Request, expectedFileList: { projectFileName: string, files: FileOrFolder[] }[]) { const response = session.executeCommand(request).response as server.protocol.CompileOnSaveAffectedFileListSingleProject[]; - const actualResult = response.sort((list1, list2) => compareStrings(list1.projectFileName, list2.projectFileName)); - expectedFileList = expectedFileList.sort((list1, list2) => compareStrings(list1.projectFileName, list2.projectFileName)); + // File-system ordering should use a predictable order + const collator = StringCollator.getPathCollator(/*ignoreCase*/ false); + const actualResult = response.sort((list1, list2) => collator.compare(list1.projectFileName, list2.projectFileName)); + expectedFileList = expectedFileList.sort((list1, list2) => collator.compare(list1.projectFileName, list2.projectFileName)); assert.equal(actualResult.length, expectedFileList.length, `Actual result project number is different from the expected project number`); diff --git a/src/server/session.ts b/src/server/session.ts index e8ce752745e..ea09a9720f8 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1186,6 +1186,7 @@ namespace ts.server { const completions = project.getLanguageService().getCompletionsAtPosition(file, position); if (simplifiedResult) { + const comparer = StringCollator.uiCaseSensitive.compare; return mapDefined(completions && completions.entries, entry => { if (completions.isMemberCompletion || (entry.name.toLowerCase().indexOf(prefix.toLowerCase()) === 0)) { const { name, kind, kindModifiers, sortText, replacementSpan, hasAction } = entry; @@ -1193,7 +1194,7 @@ namespace ts.server { // Use `hasAction || undefined` to avoid serializing `false`. return { name, kind, kindModifiers, sortText, replacementSpan: convertedSpan, hasAction: hasAction || undefined }; } - }).sort((a, b) => compareStrings(a.name, b.name)); + }).sort((a, b) => comparer(a.name, b.name)); } else { return completions; diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index 2647a87ada7..3988a88fe78 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -175,12 +175,8 @@ namespace ts.NavigateTo { function compareNavigateToItems(i1: RawNavigateToItem, i2: RawNavigateToItem): number { // TODO(cyrusn): get the gamut of comparisons that VS already uses here. - // Right now we just sort by kind first, and then by name of the item. - // We first sort case insensitively. So "Aaa" will come before "bar". - // Then we sort case sensitively, so "aaa" will come before "Aaa". return i1.matchKind - i2.matchKind || - compareStringsCaseInsensitive(i1.name, i2.name) || - compareStringsCaseSensitive(i1.name, i2.name); + StringCollator.uiCaseSensitive.compare(i1.name, i2.name); } function createNavigateToItem(rawItem: RawNavigateToItem): NavigateToItem { diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index bf34f28fed6..91b7ec78a89 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -368,13 +368,8 @@ namespace ts.NavigationBar { function compareChildren(child1: NavigationBarNode, child2: NavigationBarNode): number { const name1 = tryGetName(child1.node), name2 = tryGetName(child2.node); - if (name1 && name2) { - const cmp = ts.compareStringsCaseInsensitive(name1, name2); - return cmp !== 0 ? cmp : navigationBarNodeKind(child1) - navigationBarNodeKind(child2); - } - else { - return name1 ? 1 : name2 ? -1 : navigationBarNodeKind(child1) - navigationBarNodeKind(child2); - } + return StringCollator.uiCaseInsensitive.compare(name1, name2) + || navigationBarNodeKind(child1) - navigationBarNodeKind(child2); } /** diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 84f6ffb0815..2a5ea4ec53b 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -1154,7 +1154,9 @@ namespace ts.refactor.extractSymbol { const name1 = type1.symbol ? type1.symbol.getName() : ""; const name2 = type2.symbol ? type2.symbol.getName() : ""; - const nameDiff = compareStrings(name1, name2); + + // This is for code generation, use a predictable comparer. + const nameDiff = StringCollator.invariantCaseSensitive.compare(name1, name2); if (nameDiff !== 0) { return nameDiff; } From c0ed26e6058fe7a3c5ab1b86166da13ed4d6b998 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 25 Oct 2017 17:46:39 -0700 Subject: [PATCH 028/235] Simplify comparers --- src/compiler/core.ts | 394 +++++++++--------------- src/compiler/parser.ts | 2 +- src/compiler/program.ts | 6 +- src/compiler/utilities.ts | 2 +- src/harness/harness.ts | 4 +- src/harness/unittests/compileOnSave.ts | 6 +- src/server/session.ts | 3 +- src/services/navigateTo.ts | 2 +- src/services/navigationBar.ts | 2 +- src/services/refactors/extractSymbol.ts | 2 +- 10 files changed, 165 insertions(+), 258 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 3a706a9119d..94ab45a6f6a 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1483,6 +1483,38 @@ namespace ts { return headChain; } + /** + * Compare two values for their equality. + */ + export function equateValues(a: T, b: T) { + return a === b; + } + + export function equateStringsCaseInsensitive(a: string, b: string) { + return a === b + || a !== undefined + && b !== undefined + && a.toUpperCase() === b.toUpperCase(); + } + + export function equateStringsCaseSensitive(a: string, b: string) { + return equateValues(a, b); + } + + /** + * Compare equality between two strings using an ordinal comparison. + * + * Case-insensitive comparisons compare both strings after applying `toUpperCase` to + * each string. + */ + export function equateStrings(a: string, b: string, ignoreCase: boolean) { + return ignoreCase ? equateStringsCaseInsensitive(a, b) : equateStringsCaseSensitive(a, b); + } + + export function getStringEqualityComparer(ignoreCase: boolean) { + return ignoreCase ? equateStringsCaseInsensitive : equateStringsCaseSensitive; + } + /** * Compare two values for their order relative to each other. */ @@ -1495,280 +1527,157 @@ namespace ts { } /** - * Compare two values for their equality. + * Compare two strings using an ordinal comparison. + * + * Ordinal comparisons are based on the difference between the unicode code points of + * both strings. Characters with multiple unicode representations are considered + * unequal. Ordinal comparisons provide predictable ordering, but place "a" after "B". + * + * Case-insensitive comparisons compare both strings after applying `toUpperCase` to + * each string. */ - export function equateValues(a: T, b: T) { - return a === b; + export function compareStrings(a: string, b: string, ignoreCase: boolean) { + return ignoreCase ? compareStringsCaseInsensitive(a, b) : compareStringsCaseSensitive(a, b); } - export interface StringCollator { - compare(a: string | undefined, b: string | undefined): number; - equate(a: string | undefined, b: string | undefined): boolean; + export function compareStringsCaseInsensitive(a: string, b: string) { + if (a === b) return Comparison.EqualTo; + if (a === undefined) return Comparison.LessThan; + if (b === undefined) return Comparison.GreaterThan; + a = a.toUpperCase(); + b = b.toUpperCase(); + return a < b ? Comparison.LessThan : a > b ? Comparison.GreaterThan : Comparison.EqualTo; } - export interface StringCollators { - /** - * Gets a string collator for case-insensitive ordinal comparisons of strings. - * - * Ordinal comparisons are based on the difference between the unicode code points of - * both strings. Characters with multiple unicode representations are considered - * unequal. - * - * Case-insensitive comparisons compare both strings after applying `toUpperCase` to - * each string. - */ - readonly ordinalCaseInsensitive: StringCollator; - - /** - * Gets a string collator for case-sensitive ordinal comparisons of strings. - * - * Ordinal comparisons are based on the difference between the unicode code points of - * both strings. Characters with multiple unicode representations are considered - * unequal. They provide predictable ordering, but place "a" after "B". - */ - readonly ordinalCaseSensitive: StringCollator; - - /** - * Gets or sets a string collator for case-insensitive comparisons of strings in the host default locale. - * - * UI comparisons are based on the sort order of the host default locale. Ordering is not - * predictable between different host locales, but is best for displaying ordered data - * for UI presentation. Characters with multiple unicode representations may be considered - * equal. - * - * Case-insensitive comparisons compare strings that differ in only base characters or - * accents/diacritic marks as unequal. - */ - readonly uiCaseInsensitive: StringCollator; - - /** - * Gets a string collator for case-sensitive comparisons of strings in the host default locale. - * - * UI comparisons are based on the sort order of the host default locale. Ordering is not - * predictable between different host locales, but is best for displaying ordered data - * for UI presentation. Characters with multiple unicode representations may be considered - * equal. - */ - readonly uiCaseSensitive: StringCollator; - - /** - * Gets a string collator for case-insensitive comparisons of strings in an invariant locale. - * - * Invariant comparisons are based on the sort order of an invariant locale ('en-US'). - * They provide predictable ordering, placing "a" before "B". Characters with multiple - * unicode representations may be considered equal. Invariant comparisons are best used - * when interacting with the file system. - * - * Case-insensitive comparisons compare strings that differ in only base characters or - * accents/diacritic marks as unequal. - */ - readonly invariantCaseInsensitive: StringCollator; - - /** - * Gets a string collator for case-sensitive comparisons of strings in an invariant locale. - * - * Invariant comparisons are based on the sort order of an invariant locale ('en-US'). - * They provide predictable ordering, placing "a" before "B". Characters with multiple - * unicode representations may be considered equal. Invariant comparisons are best used - * when interacting with the file system. - */ - readonly invariantCaseSensitive: StringCollator; - - /** - * Gets or sets the locale for UI collators - */ - uiLocale: string | undefined; - - /** - * Creates a `StringCollator` for a specific locale and case sensitivity. - */ - create(locale: string | undefined, caseSensitive: boolean): StringCollator; - - /** - * Gets the ordinal `StringCollator` for the provided case sensitivity. - */ - getOrdinalCollator(caseSensitive: boolean): StringCollator; - - /** - * Gets the UI `StringCollator` for the provided case sensitivity. - */ - getUICollator(caseSensitive: boolean): StringCollator; - - /** - * Gets the invariant `StringCollator` for the provided case sensitivity. - */ - getInvariantCollator(caseSensitive: boolean): StringCollator; - - /** - * Gets a `StringCollator` for comparing code fragments for code generation. - */ - getCodeCollator(caseSensitive: boolean): StringCollator; - - /** - * Gets a `StringCollator` for comparing paths. - */ - getPathCollator(caseSensitive: boolean): StringCollator; + export function compareStringsCaseSensitive(a: string, b: string) { + return compareValues(a, b); } - export const StringCollator: StringCollators = (function () { - const invariantLocaleName = "en-US"; // we use en-US for the invariant locale - const create = getStringCollatorFactory(); - const ordinalCS: StringCollator = { - compare: compareValues, - equate: equateValues - }; - const ordinalCI: StringCollator = { - compare: (a, b) => compareValues(toUpperCase(a), toUpperCase(b)), - equate: (a, b) => toUpperCase(a) === toUpperCase(b) - }; - let invariantCI: StringCollator | undefined; - let invariantCS: StringCollator | undefined; - let uiCI: StringCollator | undefined; - let uiCS: StringCollator | undefined; - let uiLocale: string | undefined; + export function getStringComparer(ignoreCase: boolean) { + return ignoreCase ? compareStringsCaseInsensitive : compareStringsCaseSensitive; + } - return { - get ordinalCaseInsensitive() { return ordinalCI; }, - get ordinalCaseSensitive() { return ordinalCS; }, - get uiCaseInsensitive() { return uiCI || (uiCI = create(uiLocale, /*caseInsensitive*/ true)); }, - get uiCaseSensitive() { return uiCS || (uiCS = create(uiLocale, /*caseInsensitive*/ false)); }, - get invariantCaseInsensitive() { return invariantCI || (invariantCI = create(invariantLocaleName, /*caseInsensitive*/ true)); }, - get invariantCaseSensitive() { return invariantCS || (invariantCS = create(invariantLocaleName, /*caseInsensitive*/ false)); }, - get uiLocale() { return uiLocale; }, - set uiLocale(value) { - if (uiLocale !== value) { - uiLocale = value; - uiCI = undefined; - uiCS = undefined; - } - }, - create, - getOrdinalCollator, - getUICollator, - getInvariantCollator, - getCodeCollator: getInvariantCollator, - getPathCollator: getInvariantCollator - }; - - function getOrdinalCollator(caseInsensitive: boolean) { - return caseInsensitive ? StringCollator.ordinalCaseInsensitive : StringCollator.ordinalCaseSensitive; + /** + * Creates a string comparer for use with string collation in the UI. + */ + const createStringComparer = (function () { + // If the host supports Intl, we use it for comparisons using the default locale. + if (typeof Intl === "object" && typeof Intl.Collator === "function") { + return createIntlCollatorStringComparer; } - function getUICollator(caseInsensitive: boolean) { - return caseInsensitive ? StringCollator.uiCaseInsensitive : StringCollator.uiCaseSensitive; + // If the host does not support Intl, we fall back to localeCompare. + // localeCompare in Node v0.10 is just an ordinal comparison, so don't use it. + if (typeof String.prototype.localeCompare === "function" && + typeof String.prototype.toLocaleUpperCase === "function" && + "a".localeCompare("B") < 0) { + return createLocaleCompareStringComparer; } - function getInvariantCollator(caseInsensitive: boolean) { - return caseInsensitive ? StringCollator.invariantCaseInsensitive : StringCollator.invariantCaseSensitive; - } - - function toUpperCase(value: string | undefined): string | undefined { - return value === undefined ? undefined : value.toUpperCase(); - } - - function compareDefined(a: string, b: string) { - return a < b ? Comparison.LessThan : a > b ? Comparison.GreaterThan : Comparison.EqualTo; - } + // Otherwise, fall back to ordinal comparison: + return createFallbackStringComparer; function compareWithCallback(a: string | undefined, b: string | undefined, comparer: (a: string, b: string) => number) { - return a === b ? Comparison.EqualTo : - a === undefined ? Comparison.LessThan : - b === undefined ? Comparison.GreaterThan : - toComparison(comparer(a, b)); - } - - function toComparison(value: number) { + if (a === b) return Comparison.EqualTo; + if (a === undefined) return Comparison.LessThan; + if (b === undefined) return Comparison.GreaterThan; + const value = comparer(a, b); return value < 0 ? Comparison.LessThan : value > 0 ? Comparison.GreaterThan : Comparison.EqualTo; } - function createIntlStringCollator(locale: string | undefined, caseInsensitive: boolean): StringCollator { + function createIntlCollatorStringComparer(locale: string | undefined, caseInsensitive: boolean): Comparer { // Initialize the sort collator on first use - let sortComparer: Comparer = (a, b) => { + let comparer: Comparer = (a, b) => { // Intl.Collator.prototype.compare is bound to the collator. See NOTE in // http://www.ecma-international.org/ecma-402/2.0/#sec-Intl.Collator.prototype.compare - sortComparer = new Intl.Collator(locale, { usage: "sort", sensitivity: caseInsensitive ? "accent" : "variant" }).compare; - return sortComparer(a, b); - }; - - // Initialize the search collator on first use - let searchComparer: Comparer = (a, b) => { - // Intl.Collator.prototype.compare is bound to the collator. See NOTE in - // http://www.ecma-international.org/ecma-402/2.0/#sec-Intl.Collator.prototype.compare - searchComparer = new Intl.Collator(locale, { usage: "search", sensitivity: caseInsensitive ? "accent" : "variant" }).compare; - return searchComparer(a, b); - }; - - return { - compare: (a, b) => compareWithCallback(a, b, sortComparer), - equate: (a, b) => compareWithCallback(a, b, searchComparer) === 0 + comparer = new Intl.Collator(locale, { usage: "sort", sensitivity: caseInsensitive ? "accent" : "variant" }).compare; + return comparer(a, b); }; + return (a, b) => compareWithCallback(a, b, comparer); } - function createLocaleCompareStringCollator(locale: string | undefined, caseInsensitive: boolean): StringCollator { - if (locale !== undefined) return getFallbackStringCollator(/*locale*/ undefined, caseInsensitive); - if (caseInsensitive) { + function createLocaleCompareStringComparer(locale: string | undefined, caseInsensitive: boolean): Comparer { + // if the locale is not the default locale (`undefined`), use the fallback comparer. + return locale !== undefined ? createFallbackStringComparer(locale, caseInsensitive) : + caseInsensitive ? (a, b) => compareWithCallback(a, b, compareCaseInsensitive) : + (a, b) => compareWithCallback(a, b, compareCaseSensitive); + + function compareCaseInsensitive(a: string, b: string) { // for case-insensitive comparisons we always map both strings to their // upper-case form as some unicode characters do not properly round-trip to // lowercase (such as `ẞ` (German sharp capital s)). - return { - compare: (a, b) => compareWithCallback(a, b, localeCompareCaseInsensitive), - equate: (a, b) => compareWithCallback(a, b, localeCompareCaseInsensitive) === 0 - }; - } - else { - return { - compare: (a, b) => compareWithCallback(a, b, localeCompare), - equate: (a, b) => compareWithCallback(a, b, localeCompare) === 0 - }; + return compareCaseSensitive(a.toLocaleUpperCase(), b.toLocaleUpperCase()); } - function localeCompareCaseInsensitive(a: string, b: string) { - return a.toLocaleUpperCase().localeCompare(b.toLocaleUpperCase()); - } - - function localeCompare(a: string, b: string) { + function compareCaseSensitive(a: string, b: string) { return a.localeCompare(b); } } - function getFallbackStringCollator(_locale: string | undefined, caseInsensitive: boolean): StringCollator { - if (caseInsensitive) return ordinalCI; + function createFallbackStringComparer(_locale: string | undefined, caseInsensitive: boolean): Comparer { + return caseInsensitive ? (a, b) => compareWithCallback(a, b, compareCaseInsensitive) : + (a, b) => compareWithCallback(a, b, compareCaseSensitiveDictionaryOrder); - function compareLowerCaseFirst(a: string, b: string) { + function compareCaseInsensitive(a: string, b: string) { + // for case-insensitive comparisons we always map both strings to their + // upper-case form as some unicode characters do not properly round-trip to + // lowercase (such as `ẞ` (German sharp capital s)). + return compareCaseSensitive(a.toUpperCase(), b.toUpperCase()); + } + + function compareCaseSensitive(a: string, b: string) { + return a < b ? Comparison.LessThan : a > b ? Comparison.GreaterThan : Comparison.EqualTo; + } + + function compareCaseSensitiveDictionaryOrder(a: string, b: string) { // An ordinal comparison puts "A" after "b", but for the UI we want "A" before "b". // We first sort case insensitively. So "Aaa" will come before "baa". // Then we sort case sensitively, so "aaa" will come before "Aaa". - return compareDefined(a.toUpperCase(), b.toUpperCase()) || compareDefined(a, b); + return compareCaseInsensitive(a, b) || compareCaseSensitive(a, b); } - - return { - compare: (a, b) => compareWithCallback(a, b, compareLowerCaseFirst), - equate: ordinalCS.equate - }; - } - - function getStringCollatorFactory() { - // If the host supports Intl (ECMA-402), we use Intl for comparisons using the default - // locale: - if (typeof Intl === "object" && typeof Intl.Collator === "function") { - return createIntlStringCollator; - } - - // If the host does not support Intl, we fall back to localeCompare: - // - // Node v0.10 provides incorrect results for comparisons using localeCompare, so we must - // verify the implementation. - if (typeof String.prototype.localeCompare === "function" && - typeof String.prototype.toLocaleUpperCase === "function" && - "a".localeCompare("B") < 0) { - return createLocaleCompareStringCollator; - } - - // Otherwise, fall back to ordinal comparison: - return getFallbackStringCollator; } })(); + let uiCS: Comparer | undefined; + let uiCI: Comparer | undefined; + let uiLocale: string | undefined; + + export function setUILocale(value: string) { + if (uiLocale !== value) { + uiLocale = value; + uiCS = undefined; + uiCI = undefined; + } + } + + export function compareStringsCaseInsensitiveUI(a: string, b: string) { + const comparer = uiCS || (uiCS = createStringComparer(uiLocale, /*caseInsensitive*/ false)); + return comparer(a, b); + } + + export function compareStringsCaseSensitiveUI(a: string, b: string) { + const comparer = uiCI || (uiCI = createStringComparer(uiLocale, /*caseInsensitive*/ true)); + return comparer(a, b); + } + + /** + * Compare two strings using the sort behavior of the UI locale. + * + * Ordering is not predictable between different host locales, but is best for displaying + * ordered data for UI presentation. Characters with multiple unicode representations may + * be considered equal. + * + * Case-insensitive comparisons compare strings that differ in only base characters or + * accents/diacritic marks as unequal. + */ + export function compareStringsUI(a: string, b: string, ignoreCase: boolean) { + return ignoreCase ? compareStringsCaseInsensitiveUI(a, b) : compareStringsCaseSensitiveUI(a, b); + } + + export function getStringComparerUI(ignoreCase: boolean) { + return ignoreCase ? compareStringsCaseInsensitiveUI : compareStringsCaseSensitiveUI; + } + function getDiagnosticFileName(diagnostic: Diagnostic): string { return diagnostic.file ? diagnostic.file.fileName : undefined; } @@ -2151,9 +2060,9 @@ namespace ts { const aComponents = getNormalizedPathComponents(a, currentDirectory); const bComponents = getNormalizedPathComponents(b, currentDirectory); const sharedLength = Math.min(aComponents.length, bComponents.length); - const collator = StringCollator.getPathCollator(ignoreCase); + const comparer = getStringComparer(ignoreCase); for (let i = 0; i < sharedLength; i++) { - const result = collator.compare(aComponents[i], bComponents[i]); + const result = comparer(aComponents[i], bComponents[i]); if (result !== Comparison.EqualTo) { return result; } @@ -2175,9 +2084,9 @@ namespace ts { } // File-system comparisons should use predictable ordering - const collator = StringCollator.getPathCollator(ignoreCase); + const equalityComparer = getStringEqualityComparer(ignoreCase); for (let i = 0; i < parentComponents.length; i++) { - if (!collator.equate(parentComponents[i], childComponents[i])) { + if (!equalityComparer(parentComponents[i], childComponents[i])) { return false; } } @@ -2433,7 +2342,7 @@ namespace ts { // If there are no "includes", then just put everything in results[0]. const results: string[][] = includeFileRegexes ? includeFileRegexes.map(() => []) : [[]]; - const collator = StringCollator.getPathCollator(!useCaseSensitiveFileNames); + const comparer = getStringComparer(!useCaseSensitiveFileNames); for (const basePath of patterns.basePaths) { visitDirectory(basePath, combinePaths(currentDirectory, basePath), depth); } @@ -2442,7 +2351,7 @@ namespace ts { function visitDirectory(path: string, absolutePath: string, depth: number | undefined) { let { files, directories } = getFileSystemEntries(path); - files = files.slice().sort(collator.compare); + files = files.slice().sort(comparer); for (const current of files) { const name = combinePaths(path, current); @@ -2467,7 +2376,7 @@ namespace ts { } } - directories = directories.slice().sort(collator.compare); + directories = directories.slice().sort(comparer); for (const current of directories) { const name = combinePaths(path, current); const absoluteName = combinePaths(absolutePath, current); @@ -2498,8 +2407,7 @@ namespace ts { } // Sort the offsets array using either the literal or canonical path representations. - const collator = StringCollator.getPathCollator(!useCaseSensitiveFileNames); - includeBasePaths.sort(collator.compare); + includeBasePaths.sort(getStringComparer(!useCaseSensitiveFileNames)); // Iterate over each include base path and include unique base paths that are not a // subpath of an existing base path diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index bda31d83d86..11eabb32b43 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6069,7 +6069,7 @@ namespace ts { const checkJsDirectiveMatchResult = checkJsDirectiveRegEx.exec(comment); if (checkJsDirectiveMatchResult) { checkJsDirective = { - enabled: StringCollator.ordinalCaseInsensitive.equate(checkJsDirectiveMatchResult[1], "@ts-check"), + enabled: equateStringsCaseInsensitive(checkJsDirectiveMatchResult[1], "@ts-check"), end: range.end, pos: range.pos }; diff --git a/src/compiler/program.ts b/src/compiler/program.ts index ff3143f3d96..76d3ce4f58d 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1103,12 +1103,12 @@ namespace ts { // otherwise, using options specified in '--lib' instead of '--target' default library file // File-system ordering should use a predictable order - const collator = StringCollator.getPathCollator(!host.useCaseSensitiveFileNames()); + const equalityComparer = getStringEqualityComparer(!host.useCaseSensitiveFileNames()); if (!options.lib) { - return collator.equate(file.fileName, getDefaultLibraryFileName()); + return equalityComparer(file.fileName, getDefaultLibraryFileName()); } else { - return forEach(options.lib, libFileName => collator.equate(file.fileName, combinePaths(defaultLibraryPath, libFileName))); + return forEach(options.lib, libFileName => equalityComparer(file.fileName, combinePaths(defaultLibraryPath, libFileName))); } } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 7ae7e84ad18..4c75215acb5 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3950,7 +3950,7 @@ namespace ts { } // Set the locale for UI collation - StringCollator.uiLocale = locale; + setUILocale(locale); function trySetLanguageAndTerritory(language: string, territory: string, errors?: Push): boolean { const compilerFilePath = normalizePath(sys.getExecutingFilePath()); diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 8029c3672af..1529b19b47a 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1699,8 +1699,8 @@ namespace Harness { export function *iterateOutputs(outputFiles: Harness.Compiler.GeneratedFile[]): IterableIterator<[string, string]> { // Collect, test, and sort the fileNames // As this uses the file system, use a predictable order - const collator = ts.StringCollator.getPathCollator(/*ignoreCase*/ false); - outputFiles.sort((a, b) => collator.compare(cleanName(a.fileName), cleanName(b.fileName))); + const comparer = ts.getStringComparer(/*ignoreCase*/ false); + outputFiles.sort((a, b) => comparer(cleanName(a.fileName), cleanName(b.fileName))); const dupeCase = ts.createMap(); // Yield them for (const outputFile of outputFiles) { diff --git a/src/harness/unittests/compileOnSave.ts b/src/harness/unittests/compileOnSave.ts index 8c7ae507991..43becc3fdb1 100644 --- a/src/harness/unittests/compileOnSave.ts +++ b/src/harness/unittests/compileOnSave.ts @@ -14,9 +14,9 @@ namespace ts.projectSystem { function sendAffectedFileRequestAndCheckResult(session: server.Session, request: server.protocol.Request, expectedFileList: { projectFileName: string, files: FileOrFolder[] }[]) { const response = session.executeCommand(request).response as server.protocol.CompileOnSaveAffectedFileListSingleProject[]; // File-system ordering should use a predictable order - const collator = StringCollator.getPathCollator(/*ignoreCase*/ false); - const actualResult = response.sort((list1, list2) => collator.compare(list1.projectFileName, list2.projectFileName)); - expectedFileList = expectedFileList.sort((list1, list2) => collator.compare(list1.projectFileName, list2.projectFileName)); + const comparer = getStringComparer(/*ignoreCase*/ false); + const actualResult = response.sort((list1, list2) => comparer(list1.projectFileName, list2.projectFileName)); + expectedFileList = expectedFileList.sort((list1, list2) => comparer(list1.projectFileName, list2.projectFileName)); assert.equal(actualResult.length, expectedFileList.length, `Actual result project number is different from the expected project number`); diff --git a/src/server/session.ts b/src/server/session.ts index ea09a9720f8..d40becbbd16 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1186,7 +1186,6 @@ namespace ts.server { const completions = project.getLanguageService().getCompletionsAtPosition(file, position); if (simplifiedResult) { - const comparer = StringCollator.uiCaseSensitive.compare; return mapDefined(completions && completions.entries, entry => { if (completions.isMemberCompletion || (entry.name.toLowerCase().indexOf(prefix.toLowerCase()) === 0)) { const { name, kind, kindModifiers, sortText, replacementSpan, hasAction } = entry; @@ -1194,7 +1193,7 @@ namespace ts.server { // Use `hasAction || undefined` to avoid serializing `false`. return { name, kind, kindModifiers, sortText, replacementSpan: convertedSpan, hasAction: hasAction || undefined }; } - }).sort((a, b) => comparer(a.name, b.name)); + }).sort((a, b) => compareStringsCaseSensitiveUI(a.name, b.name)); } else { return completions; diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index 3988a88fe78..603342df7a8 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -176,7 +176,7 @@ namespace ts.NavigateTo { function compareNavigateToItems(i1: RawNavigateToItem, i2: RawNavigateToItem): number { // TODO(cyrusn): get the gamut of comparisons that VS already uses here. return i1.matchKind - i2.matchKind || - StringCollator.uiCaseSensitive.compare(i1.name, i2.name); + compareStringsCaseSensitiveUI(i1.name, i2.name); } function createNavigateToItem(rawItem: RawNavigateToItem): NavigateToItem { diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 91b7ec78a89..9f4d37407eb 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -368,7 +368,7 @@ namespace ts.NavigationBar { function compareChildren(child1: NavigationBarNode, child2: NavigationBarNode): number { const name1 = tryGetName(child1.node), name2 = tryGetName(child2.node); - return StringCollator.uiCaseInsensitive.compare(name1, name2) + return compareStringsCaseInsensitiveUI(name1, name2) || navigationBarNodeKind(child1) - navigationBarNodeKind(child2); } diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 2a5ea4ec53b..41b922c2003 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -1156,7 +1156,7 @@ namespace ts.refactor.extractSymbol { const name2 = type2.symbol ? type2.symbol.getName() : ""; // This is for code generation, use a predictable comparer. - const nameDiff = StringCollator.invariantCaseSensitive.compare(name1, name2); + const nameDiff = compareStringsCaseSensitive(name1, name2); if (nameDiff !== 0) { return nameDiff; } From dfa1ffe6500881c74d71a109902478ee5a37a52f Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 25 Oct 2017 18:00:59 -0700 Subject: [PATCH 029/235] Cleanup and reordering --- src/compiler/core.ts | 55 ++++++++++++++----------- src/compiler/utilities.ts | 2 +- src/harness/unittests/compileOnSave.ts | 1 - src/services/navigateTo.ts | 6 +-- src/services/navigationBar.ts | 7 ++-- src/services/refactors/extractSymbol.ts | 31 +++----------- 6 files changed, 43 insertions(+), 59 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 94ab45a6f6a..3457af9d174 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1490,6 +1490,16 @@ namespace ts { return a === b; } + /** + * Compare equality between two strings using an ordinal comparison. + * + * Case-insensitive comparisons compare both strings after applying `toUpperCase` to + * each string. + */ + export function equateStrings(a: string, b: string, ignoreCase: boolean) { + return ignoreCase ? equateStringsCaseInsensitive(a, b) : equateStringsCaseSensitive(a, b); + } + export function equateStringsCaseInsensitive(a: string, b: string) { return a === b || a !== undefined @@ -1501,16 +1511,6 @@ namespace ts { return equateValues(a, b); } - /** - * Compare equality between two strings using an ordinal comparison. - * - * Case-insensitive comparisons compare both strings after applying `toUpperCase` to - * each string. - */ - export function equateStrings(a: string, b: string, ignoreCase: boolean) { - return ignoreCase ? equateStringsCaseInsensitive(a, b) : equateStringsCaseSensitive(a, b); - } - export function getStringEqualityComparer(ignoreCase: boolean) { return ignoreCase ? equateStringsCaseInsensitive : equateStringsCaseSensitive; } @@ -1557,6 +1557,20 @@ namespace ts { return ignoreCase ? compareStringsCaseInsensitive : compareStringsCaseSensitive; } + /** + * Compare two strings using the sort behavior of the UI locale. + * + * Ordering is not predictable between different host locales, but is best for displaying + * ordered data for UI presentation. Characters with multiple unicode representations may + * be considered equal. + * + * Case-insensitive comparisons compare strings that differ in only base characters or + * accents/diacritic marks as unequal. + */ + export function compareStringsUI(a: string, b: string, ignoreCase: boolean) { + return ignoreCase ? compareStringsCaseInsensitiveUI(a, b) : compareStringsCaseSensitiveUI(a, b); + } + /** * Creates a string comparer for use with string collation in the UI. */ @@ -1660,24 +1674,17 @@ namespace ts { return comparer(a, b); } - /** - * Compare two strings using the sort behavior of the UI locale. - * - * Ordering is not predictable between different host locales, but is best for displaying - * ordered data for UI presentation. Characters with multiple unicode representations may - * be considered equal. - * - * Case-insensitive comparisons compare strings that differ in only base characters or - * accents/diacritic marks as unequal. - */ - export function compareStringsUI(a: string, b: string, ignoreCase: boolean) { - return ignoreCase ? compareStringsCaseInsensitiveUI(a, b) : compareStringsCaseSensitiveUI(a, b); - } - export function getStringComparerUI(ignoreCase: boolean) { return ignoreCase ? compareStringsCaseInsensitiveUI : compareStringsCaseSensitiveUI; } + export function compareProperties(a: T, b: T, key: keyof T) { + return a === b ? Comparison.EqualTo : + a === undefined ? Comparison.LessThan : + b === undefined ? Comparison.GreaterThan : + compareValues(a[key], b[key]); + } + function getDiagnosticFileName(diagnostic: Diagnostic): string { return diagnostic.file ? diagnostic.file.fileName : undefined; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 4c75215acb5..a3a8ca3afc7 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3949,7 +3949,7 @@ namespace ts { trySetLanguageAndTerritory(language, /*territory*/ undefined, errors); } - // Set the locale for UI collation + // Set the UI locale for string collation setUILocale(locale); function trySetLanguageAndTerritory(language: string, territory: string, errors?: Push): boolean { diff --git a/src/harness/unittests/compileOnSave.ts b/src/harness/unittests/compileOnSave.ts index 43becc3fdb1..d6d22b162bf 100644 --- a/src/harness/unittests/compileOnSave.ts +++ b/src/harness/unittests/compileOnSave.ts @@ -13,7 +13,6 @@ namespace ts.projectSystem { describe("CompileOnSave affected list", () => { function sendAffectedFileRequestAndCheckResult(session: server.Session, request: server.protocol.Request, expectedFileList: { projectFileName: string, files: FileOrFolder[] }[]) { const response = session.executeCommand(request).response as server.protocol.CompileOnSaveAffectedFileListSingleProject[]; - // File-system ordering should use a predictable order const comparer = getStringComparer(/*ignoreCase*/ false); const actualResult = response.sort((list1, list2) => comparer(list1.projectFileName, list2.projectFileName)); expectedFileList = expectedFileList.sort((list1, list2) => comparer(list1.projectFileName, list2.projectFileName)); diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index 603342df7a8..762726adb77 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -173,10 +173,10 @@ namespace ts.NavigateTo { return bestMatchKind; } - function compareNavigateToItems(i1: RawNavigateToItem, i2: RawNavigateToItem): number { + function compareNavigateToItems(i1: RawNavigateToItem, i2: RawNavigateToItem) { // TODO(cyrusn): get the gamut of comparisons that VS already uses here. - return i1.matchKind - i2.matchKind || - compareStringsCaseSensitiveUI(i1.name, i2.name); + return compareValues(i1.matchKind, i2.matchKind) + || compareStringsCaseSensitiveUI(i1.name, i2.name); } function createNavigateToItem(rawItem: RawNavigateToItem): NavigateToItem { diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 9f4d37407eb..712a315bb41 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -366,10 +366,9 @@ namespace ts.NavigationBar { children.sort(compareChildren); } - function compareChildren(child1: NavigationBarNode, child2: NavigationBarNode): number { - const name1 = tryGetName(child1.node), name2 = tryGetName(child2.node); - return compareStringsCaseInsensitiveUI(name1, name2) - || navigationBarNodeKind(child1) - navigationBarNodeKind(child2); + function compareChildren(child1: NavigationBarNode, child2: NavigationBarNode) { + return compareStringsCaseInsensitiveUI(tryGetName(child1.node), tryGetName(child2.node)) + || compareValues(navigationBarNodeKind(child1), navigationBarNodeKind(child2)); } /** diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 41b922c2003..e26cdd0f74f 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -1137,32 +1137,11 @@ namespace ts.refactor.extractSymbol { {type: type1, declaration: declaration1}: {type: Type, declaration?: Declaration}, {type: type2, declaration: declaration2}: {type: Type, declaration?: Declaration}) { - if (declaration1) { - if (declaration2) { - const positionDiff = declaration1.pos - declaration2.pos; - if (positionDiff !== 0) { - return positionDiff; - } - } - else { - return 1; // Sort undeclared type parameters to the front. - } - } - else if (declaration2) { - return -1; // Sort undeclared type parameters to the front. - } - - const name1 = type1.symbol ? type1.symbol.getName() : ""; - const name2 = type2.symbol ? type2.symbol.getName() : ""; - - // This is for code generation, use a predictable comparer. - const nameDiff = compareStringsCaseSensitive(name1, name2); - if (nameDiff !== 0) { - return nameDiff; - } - - // IDs are guaranteed to be unique, so this ensures a total ordering. - return type1.id - type2.id; + return compareProperties(declaration1, declaration2, "pos") + || compareStringsCaseSensitive( + type1.symbol ? type1.symbol.getName() : "", + type2.symbol ? type2.symbol.getName() : "") + || compareValues(type1.id, type2.id); } function getCalledExpression(scope: Node, range: TargetRange, functionNameText: string): Expression { From 3605e4ef696173fd260a8f5749cd89b34e995f0a Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 25 Oct 2017 18:04:31 -0700 Subject: [PATCH 030/235] Remove unnecessary comment --- src/compiler/program.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 76d3ce4f58d..6a60327371c 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1101,8 +1101,6 @@ namespace ts { // If '--lib' is not specified, include default library file according to '--target' // otherwise, using options specified in '--lib' instead of '--target' default library file - - // File-system ordering should use a predictable order const equalityComparer = getStringEqualityComparer(!host.useCaseSensitiveFileNames()); if (!options.lib) { return equalityComparer(file.fileName, getDefaultLibraryFileName()); From e08f8d263f6f2e715dfe4af58b7b3afd528fb58c Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 25 Oct 2017 18:05:50 -0700 Subject: [PATCH 031/235] Remove unnecessary comment --- src/harness/harness.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 1529b19b47a..d8e12c8e8f7 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1698,7 +1698,6 @@ namespace Harness { export function *iterateOutputs(outputFiles: Harness.Compiler.GeneratedFile[]): IterableIterator<[string, string]> { // Collect, test, and sort the fileNames - // As this uses the file system, use a predictable order const comparer = ts.getStringComparer(/*ignoreCase*/ false); outputFiles.sort((a, b) => comparer(cleanName(a.fileName), cleanName(b.fileName))); const dupeCase = ts.createMap(); From 24437774a8dfdffe7fd49c064e491acd99ace38c Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 26 Oct 2017 11:56:29 -0700 Subject: [PATCH 032/235] Further simplification --- src/compiler/core.ts | 123 +++++++++++++----------- src/compiler/program.ts | 2 +- src/compiler/tsc.ts | 2 +- src/harness/fourslash.ts | 6 ++ src/harness/harness.ts | 3 +- src/harness/unittests/compileOnSave.ts | 5 +- src/services/refactors/extractSymbol.ts | 2 +- 7 files changed, 77 insertions(+), 66 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 3457af9d174..64ab5af67c2 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1483,23 +1483,18 @@ namespace ts { return headChain; } - /** - * Compare two values for their equality. - */ - export function equateValues(a: T, b: T) { + function equateValues(a: T, b: T) { return a === b; } /** - * Compare equality between two strings using an ordinal comparison. + * Compare the equality of two strings using a case-sensitive ordinal comparison. * - * Case-insensitive comparisons compare both strings after applying `toUpperCase` to - * each string. + * Case-sensitive comparisons compare both strings one code-point at a time using the integer + * value of each code-point after applying `toUpperCase` to each string. We always map both + * strings to their upper-case form as some unicode characters do not properly round-trip to + * lowercase (such as `ẞ` (German sharp capital s)). */ - export function equateStrings(a: string, b: string, ignoreCase: boolean) { - return ignoreCase ? equateStringsCaseInsensitive(a, b) : equateStringsCaseSensitive(a, b); - } - export function equateStringsCaseInsensitive(a: string, b: string) { return a === b || a !== undefined @@ -1507,14 +1502,16 @@ namespace ts { && a.toUpperCase() === b.toUpperCase(); } + /** + * Compare the equality of two strings using a case-sensitive ordinal comparison. + * + * Case-sensitive comparisons compare both strings one code-point at a time using the + * integer value of each code-point. + */ export function equateStringsCaseSensitive(a: string, b: string) { return equateValues(a, b); } - export function getStringEqualityComparer(ignoreCase: boolean) { - return ignoreCase ? equateStringsCaseInsensitive : equateStringsCaseSensitive; - } - /** * Compare two values for their order relative to each other. */ @@ -1527,19 +1524,17 @@ namespace ts { } /** - * Compare two strings using an ordinal comparison. + * Compare two strings using a case-insensitive ordinal comparison. * - * Ordinal comparisons are based on the difference between the unicode code points of - * both strings. Characters with multiple unicode representations are considered - * unequal. Ordinal comparisons provide predictable ordering, but place "a" after "B". + * Ordinal comparisons are based on the difference between the unicode code points of both + * strings. Characters with multiple unicode representations are considered unequal. Ordinal + * comparisons provide predictable ordering, but place "a" after "B". * - * Case-insensitive comparisons compare both strings after applying `toUpperCase` to - * each string. + * Case-insensitive comparisons compare both strings one code-point at a time using the integer + * value of each code-point after applying `toUpperCase` to each string. We always map both + * strings to their upper-case form as some unicode characters do not properly round-trip to + * lowercase (such as `ẞ` (German sharp capital s)). */ - export function compareStrings(a: string, b: string, ignoreCase: boolean) { - return ignoreCase ? compareStringsCaseInsensitive(a, b) : compareStringsCaseSensitive(a, b); - } - export function compareStringsCaseInsensitive(a: string, b: string) { if (a === b) return Comparison.EqualTo; if (a === undefined) return Comparison.LessThan; @@ -1549,28 +1544,20 @@ namespace ts { return a < b ? Comparison.LessThan : a > b ? Comparison.GreaterThan : Comparison.EqualTo; } + /** + * Compare two strings using a case-sensitive ordinal comparison. + * + * Ordinal comparisons are based on the difference between the unicode code points of both + * strings. Characters with multiple unicode representations are considered unequal. Ordinal + * comparisons provide predictable ordering, but place "a" after "B". + * + * Case-sensitive comparisons compare both strings one code-point at a time using the integer + * value of each code-point. + */ export function compareStringsCaseSensitive(a: string, b: string) { return compareValues(a, b); } - export function getStringComparer(ignoreCase: boolean) { - return ignoreCase ? compareStringsCaseInsensitive : compareStringsCaseSensitive; - } - - /** - * Compare two strings using the sort behavior of the UI locale. - * - * Ordering is not predictable between different host locales, but is best for displaying - * ordered data for UI presentation. Characters with multiple unicode representations may - * be considered equal. - * - * Case-insensitive comparisons compare strings that differ in only base characters or - * accents/diacritic marks as unequal. - */ - export function compareStringsUI(a: string, b: string, ignoreCase: boolean) { - return ignoreCase ? compareStringsCaseInsensitiveUI(a, b) : compareStringsCaseSensitiveUI(a, b); - } - /** * Creates a string comparer for use with string collation in the UI. */ @@ -1656,6 +1643,10 @@ namespace ts { let uiCI: Comparer | undefined; let uiLocale: string | undefined; + export function getUILocale() { + return uiLocale; + } + export function setUILocale(value: string) { if (uiLocale !== value) { uiLocale = value; @@ -1664,25 +1655,41 @@ namespace ts { } } + /** + * Compare two strings using the case-insensitive sort behavior of the UI locale. + * + * Ordering is not predictable between different host locales, but is best for displaying + * ordered data for UI presentation. Characters with multiple unicode representations may + * be considered equal. + * + * Case-insensitive comparisons compare strings that differ in only base characters or + * accents/diacritic marks as unequal. + */ export function compareStringsCaseInsensitiveUI(a: string, b: string) { - const comparer = uiCS || (uiCS = createStringComparer(uiLocale, /*caseInsensitive*/ false)); - return comparer(a, b); - } - - export function compareStringsCaseSensitiveUI(a: string, b: string) { const comparer = uiCI || (uiCI = createStringComparer(uiLocale, /*caseInsensitive*/ true)); return comparer(a, b); } - export function getStringComparerUI(ignoreCase: boolean) { - return ignoreCase ? compareStringsCaseInsensitiveUI : compareStringsCaseSensitiveUI; + /** + * Compare two strings in a using the case-sensitive sort behavior of the UI locale. + * + * Ordering is not predictable between different host locales, but is best for displaying + * ordered data for UI presentation. Characters with multiple unicode representations may + * be considered equal. + * + * Case-sensitive comparisons compare strings that differ in base characters, or + * accents/diacritic marks, or case as unequal. + */ + export function compareStringsCaseSensitiveUI(a: string, b: string) { + const comparer = uiCS || (uiCS = createStringComparer(uiLocale, /*caseInsensitive*/ false)); + return comparer(a, b); } - export function compareProperties(a: T, b: T, key: keyof T) { + export function compareProperties(a: T, b: T, key: K, comparer: Comparer) { return a === b ? Comparison.EqualTo : a === undefined ? Comparison.LessThan : b === undefined ? Comparison.GreaterThan : - compareValues(a[key], b[key]); + comparer(a[key], b[key]); } function getDiagnosticFileName(diagnostic: Diagnostic): string { @@ -1690,7 +1697,7 @@ namespace ts { } export function compareDiagnostics(d1: Diagnostic, d2: Diagnostic): Comparison { - return compareValues(getDiagnosticFileName(d1), getDiagnosticFileName(d2)) || + return compareStringsCaseSensitive(getDiagnosticFileName(d1), getDiagnosticFileName(d2)) || compareValues(d1.start, d2.start) || compareValues(d1.length, d2.length) || compareValues(d1.code, d2.code) || @@ -1704,7 +1711,7 @@ namespace ts { const string1 = isString(text1) ? text1 : text1.messageText; const string2 = isString(text2) ? text2 : text2.messageText; - const res = compareValues(string1, string2); + const res = compareStringsCaseSensitive(string1, string2); if (res) { return res; } @@ -2067,7 +2074,7 @@ namespace ts { const aComponents = getNormalizedPathComponents(a, currentDirectory); const bComponents = getNormalizedPathComponents(b, currentDirectory); const sharedLength = Math.min(aComponents.length, bComponents.length); - const comparer = getStringComparer(ignoreCase); + const comparer = ignoreCase ? compareStringsCaseInsensitive : compareStringsCaseSensitive; for (let i = 0; i < sharedLength; i++) { const result = comparer(aComponents[i], bComponents[i]); if (result !== Comparison.EqualTo) { @@ -2091,7 +2098,7 @@ namespace ts { } // File-system comparisons should use predictable ordering - const equalityComparer = getStringEqualityComparer(ignoreCase); + const equalityComparer = ignoreCase ? equateStringsCaseInsensitive : equateStringsCaseSensitive; for (let i = 0; i < parentComponents.length; i++) { if (!equalityComparer(parentComponents[i], childComponents[i])) { return false; @@ -2338,6 +2345,7 @@ namespace ts { path = normalizePath(path); currentDirectory = normalizePath(currentDirectory); + const comparer = useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive; const patterns = getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory); const regexFlag = useCaseSensitiveFileNames ? "" : "i"; @@ -2349,7 +2357,6 @@ namespace ts { // If there are no "includes", then just put everything in results[0]. const results: string[][] = includeFileRegexes ? includeFileRegexes.map(() => []) : [[]]; - const comparer = getStringComparer(!useCaseSensitiveFileNames); for (const basePath of patterns.basePaths) { visitDirectory(basePath, combinePaths(currentDirectory, basePath), depth); } @@ -2414,7 +2421,7 @@ namespace ts { } // Sort the offsets array using either the literal or canonical path representations. - includeBasePaths.sort(getStringComparer(!useCaseSensitiveFileNames)); + includeBasePaths.sort(useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive); // Iterate over each include base path and include unique base paths that are not a // subpath of an existing base path diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 6a60327371c..eb2ac9babe5 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1101,7 +1101,7 @@ namespace ts { // If '--lib' is not specified, include default library file according to '--target' // otherwise, using options specified in '--lib' instead of '--target' default library file - const equalityComparer = getStringEqualityComparer(!host.useCaseSensitiveFileNames()); + const equalityComparer = host.useCaseSensitiveFileNames() ? equateStringsCaseSensitive : equateStringsCaseInsensitive; if (!options.lib) { return equalityComparer(file.fileName, getDefaultLibraryFileName()); } diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 680daeeb485..cc3c256827a 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -306,7 +306,7 @@ namespace ts { // Sort our options by their names, (e.g. "--noImplicitAny" comes before "--watch") const optsList = showAllOptions ? - optionDeclarations.slice().sort((a, b) => compareValues(a.name.toLowerCase(), b.name.toLowerCase())) : + optionDeclarations.slice().sort((a, b) => compareStringsCaseInsensitive(a.name, b.name)) : filter(optionDeclarations.slice(), v => v.showInSimplifiedHelpView); // We want our descriptions to align at the same column in our output, diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index d88f0e0854e..105501196b0 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -3128,7 +3128,10 @@ Actual: ${stringify(fullActual)}`); `(function(test, goTo, verify, edit, debug, format, cancellation, classification, verifyOperationIsCancelled) { ${code} })`; + const savedUILocale = ts.getUILocale(); + ts.setUILocale("en-US"); // run tests in en-US by default. try { + const test = new FourSlashInterface.Test(state); const goTo = new FourSlashInterface.GoTo(state); const verify = new FourSlashInterface.Verify(state); @@ -3142,6 +3145,9 @@ ${code} catch (err) { throw err; } + finally { + ts.setUILocale(savedUILocale); + } } function chompLeadingSpace(content: string) { diff --git a/src/harness/harness.ts b/src/harness/harness.ts index d8e12c8e8f7..728d18c59cc 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1698,8 +1698,7 @@ namespace Harness { export function *iterateOutputs(outputFiles: Harness.Compiler.GeneratedFile[]): IterableIterator<[string, string]> { // Collect, test, and sort the fileNames - const comparer = ts.getStringComparer(/*ignoreCase*/ false); - outputFiles.sort((a, b) => comparer(cleanName(a.fileName), cleanName(b.fileName))); + outputFiles.sort((a, b) => ts.compareStringsCaseSensitive(cleanName(a.fileName), cleanName(b.fileName))); const dupeCase = ts.createMap(); // Yield them for (const outputFile of outputFiles) { diff --git a/src/harness/unittests/compileOnSave.ts b/src/harness/unittests/compileOnSave.ts index d6d22b162bf..540c94b9f6d 100644 --- a/src/harness/unittests/compileOnSave.ts +++ b/src/harness/unittests/compileOnSave.ts @@ -13,9 +13,8 @@ namespace ts.projectSystem { describe("CompileOnSave affected list", () => { function sendAffectedFileRequestAndCheckResult(session: server.Session, request: server.protocol.Request, expectedFileList: { projectFileName: string, files: FileOrFolder[] }[]) { const response = session.executeCommand(request).response as server.protocol.CompileOnSaveAffectedFileListSingleProject[]; - const comparer = getStringComparer(/*ignoreCase*/ false); - const actualResult = response.sort((list1, list2) => comparer(list1.projectFileName, list2.projectFileName)); - expectedFileList = expectedFileList.sort((list1, list2) => comparer(list1.projectFileName, list2.projectFileName)); + const actualResult = response.sort((list1, list2) => ts.compareStringsCaseSensitive(list1.projectFileName, list2.projectFileName)); + expectedFileList = expectedFileList.sort((list1, list2) => ts.compareStringsCaseSensitive(list1.projectFileName, list2.projectFileName)); assert.equal(actualResult.length, expectedFileList.length, `Actual result project number is different from the expected project number`); diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index e26cdd0f74f..a790db44ea3 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -1137,7 +1137,7 @@ namespace ts.refactor.extractSymbol { {type: type1, declaration: declaration1}: {type: Type, declaration?: Declaration}, {type: type2, declaration: declaration2}: {type: Type, declaration?: Declaration}) { - return compareProperties(declaration1, declaration2, "pos") + return compareProperties(declaration1, declaration2, "pos", compareValues) || compareStringsCaseSensitive( type1.symbol ? type1.symbol.getName() : "", type2.symbol ? type2.symbol.getName() : "") From bfba32b71df825279a4408756fb7b5dddd1170b1 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 26 Oct 2017 13:49:32 -0700 Subject: [PATCH 033/235] Cleanup, merge #19475 --- src/compiler/core.ts | 147 ++++++++++++++++++++++---------- src/compiler/types.ts | 16 ++++ src/server/project.ts | 3 +- src/server/session.ts | 2 +- src/server/utilities.ts | 5 +- src/services/jsTyping.ts | 5 +- src/services/pathCompletions.ts | 7 +- src/services/services.ts | 2 +- 8 files changed, 132 insertions(+), 55 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 64ab5af67c2..9c52a4481f9 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -159,12 +159,6 @@ namespace ts { return getCanonicalFileName(nonCanonicalizedPath); } - export const enum Comparison { - LessThan = -1, - EqualTo = 0, - GreaterThan = 1 - } - export function length(array: ReadonlyArray) { return array ? array.length : 0; } @@ -301,17 +295,33 @@ namespace ts { Debug.fail(); } - export function contains(array: ReadonlyArray, value: T): boolean { - if (array) { - for (const v of array) { - if (v === value) { - return true; - } + function containsWithoutEqualityComparer(array: ReadonlyArray, value: T) { + for (const v of array) { + if (v === value) { + return true; } } return false; } + function containsWithEqualityComparer(array: ReadonlyArray, value: T, equalityComparer: EqualityComparer) { + for (const v of array) { + if (equalityComparer(v, value)) { + return true; + } + } + return false; + } + + export function contains(array: ReadonlyArray, value: T, equalityComparer?: EqualityComparer): boolean { + if (array) { + return equalityComparer + ? containsWithEqualityComparer(array, value, equalityComparer) + : containsWithoutEqualityComparer(array, value); + } + return false; + } + export function indexOf(array: ReadonlyArray, value: T): number { if (array) { for (let i = 0; i < array.length; i++) { @@ -649,21 +659,36 @@ namespace ts { return [...array1, ...array2]; } - // TODO: fixme (N^2) - add optional comparer so collection can be sorted before deduplication. - export function deduplicate(array: ReadonlyArray, equalityComparer: (a: T, b: T) => boolean = equateValues): T[] { - let result: T[]; - if (array) { - result = []; - loop: for (const item of array) { - for (const res of result) { - if (equalityComparer(res, item)) { - continue loop; - } + /** + * Creates a new array with duplicate entries removed. + * @param equalityComparer An optional `EqualityComparer` used to determine if two values are duplicates. + * @param comparer An optional `Comparer` used to sort entries before comparison. If supplied, + * results are returned in the original order found in `array`. + */ + export function deduplicate(array: ReadonlyArray, equalityComparer?: EqualityComparer, comparer?: Comparer): T[] { + if (!array) return undefined; + if (!comparer) return addRangeIfUnique([], array, equalityComparer); + return deduplicateWorker(array, equalityComparer, comparer); + } + + function deduplicateWorker(array: ReadonlyArray, equalityComparer: EqualityComparer = equateValues, comparer: Comparer) { + // Perform a stable sort of the array. This ensures the first entry in a list of + // duplicates remains the first entry in the result. + const indices = sequence(0, array.length); + stableSortIndices(array, indices, comparer); + + const deduplicated: number[] = []; + loop: for (const sourceIndex of indices) { + for (const targetIndex of deduplicated) { + if (equalityComparer(array[sourceIndex], array[targetIndex])) { + continue loop; } - result.push(item); } + deduplicated.push(sourceIndex); } - return result; + + // return deduplicated items in original order + return deduplicated.sort().map(i => array[i]); } export function arrayIsEqualTo(array1: ReadonlyArray, array2: ReadonlyArray, equalityComparer: (a: T, b: T) => boolean = equateValues): boolean { @@ -731,7 +756,7 @@ namespace ts { * are not present in `arrayA` but are present in `arrayB`. Assumes both arrays are sorted * based on the provided comparer. */ - export function relativeComplement(arrayA: T[] | undefined, arrayB: T[] | undefined, comparer: Comparer = compareValues, offsetA = 0, offsetB = 0): T[] | undefined { + export function relativeComplement(arrayA: T[] | undefined, arrayB: T[] | undefined, comparer: Comparer, offsetA = 0, offsetB = 0): T[] | undefined { if (!arrayB || !arrayA || arrayB.length === 0 || arrayA.length === 0) return arrayB; const result: T[] = []; outer: for (; offsetB < arrayB.length; offsetB++) { @@ -795,19 +820,27 @@ namespace ts { start = start === undefined ? 0 : toOffset(from, start); end = end === undefined ? from.length : toOffset(from, end); for (let i = start; i < end && i < from.length; i++) { - const v = from[i]; - if (v !== undefined) { + if (from[i] !== undefined) { to.push(from[i]); } } return to; } + function addRangeIfUnique(to: T[], from: ReadonlyArray, equalityComparer?: EqualityComparer): T[] | undefined { + for (let i = 0; i < from.length; i++) { + if (from[i] !== undefined) { + pushIfUnique(to, from[i], equalityComparer); + } + } + return to; + } + /** * @return Whether the value was added. */ - export function pushIfUnique(array: T[], toAdd: T): boolean { - if (contains(array, toAdd)) { + export function pushIfUnique(array: T[], toAdd: T, equalityComparer?: EqualityComparer): boolean { + if (contains(array, toAdd, equalityComparer)) { return false; } else { @@ -819,9 +852,9 @@ namespace ts { /** * Unlike `pushIfUnique`, this can take `undefined` as an input, and returns a new array. */ - export function appendIfUnique(array: T[] | undefined, toAdd: T): T[] { + export function appendIfUnique(array: T[] | undefined, toAdd: T, equalityComparer?: EqualityComparer): T[] { if (array) { - pushIfUnique(array, toAdd); + pushIfUnique(array, toAdd, equalityComparer); return array; } else { @@ -829,14 +862,29 @@ namespace ts { } } + /** + * Creates an array of integers starting at `from` (inclusive) and ending at `to` (exclusive). + */ + function sequence(from: number, to: number) { + const numbers: number[] = []; + for (let i = from; i < to; i++) { + numbers.push(i); + } + return numbers; + } + + function stableSortIndices(array: ReadonlyArray, indices: number[], comparer: Comparer) { + // sort indices by value then position + indices.sort((x, y) => comparer(array[x], array[y]) || compareValues(x, y)); + } + /** * Stable sort of an array. Elements equal to each other maintain their relative position in the array. */ - export function stableSort(array: ReadonlyArray, comparer: Comparer = compareValues) { - return array - .map((_, i) => i) // create array of indices - .sort((x, y) => comparer(array[x], array[y]) || compareValues(x, y)) // sort indices by value then position - .map(i => array[i]); // get sorted array + export function stableSort(array: ReadonlyArray, comparer: Comparer) { + const indices = sequence(0, array.length); + stableSortIndices(array, indices, comparer); + return indices.map(i => array[i]); } export function rangeEquals(array1: ReadonlyArray, array2: ReadonlyArray, pos: number, end: number) { @@ -914,9 +962,6 @@ namespace ts { return result; } - export type Comparer = (a: T, b: T) => Comparison; - export type EqualityComparer = (a: T, b: T) => boolean; - /** * Performs a binary search, finding the index at which 'value' occurs in 'array'. * If no such index is found, returns the 2's-complement of first index at which @@ -1483,7 +1528,7 @@ namespace ts { return headChain; } - function equateValues(a: T, b: T) { + export function equateValues(a: T, b: T) { return a === b; } @@ -1512,10 +1557,9 @@ namespace ts { return equateValues(a, b); } - /** - * Compare two values for their order relative to each other. - */ - export function compareValues(a: T, b: T) { + function compareComparableValues(a: string, b: string): Comparison; + function compareComparableValues(a: number, b: number): Comparison; + function compareComparableValues(a: string | number, b: string | number) { return a === b ? Comparison.EqualTo : a === undefined ? Comparison.LessThan : b === undefined ? Comparison.GreaterThan : @@ -1523,6 +1567,13 @@ namespace ts { Comparison.GreaterThan; } + /** + * Compare two values for their order relative to each other. + */ + export function compareValues(a: number, b: number) { + return compareComparableValues(a, b); + } + /** * Compare two strings using a case-insensitive ordinal comparison. * @@ -1555,7 +1606,7 @@ namespace ts { * value of each code-point. */ export function compareStringsCaseSensitive(a: string, b: string) { - return compareValues(a, b); + return compareComparableValues(a, b); } /** @@ -2488,7 +2539,11 @@ namespace ts { if (!extraFileExtensions || extraFileExtensions.length === 0 || !needAllExtensions) { return needAllExtensions ? allSupportedExtensions : supportedTypeScriptExtensions; } - return deduplicate([...allSupportedExtensions, ...extraFileExtensions.map(e => e.extension)]); + return deduplicate( + [...allSupportedExtensions, ...extraFileExtensions.map(e => e.extension)], + equateStringsCaseSensitive, + compareStringsCaseSensitive + ); } export function hasJavaScriptFileExtension(fileName: string) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ff2a33266ed..2f861f2c371 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -36,6 +36,22 @@ namespace ts { push(...values: T[]): void; } + /* @internal */ + export type EqualityComparer = (a: T, b: T) => boolean; + + /* @internal */ + export type Comparer = (a: T, b: T) => Comparison; + + /* @internal */ + export const enum Comparison { + LessThan = -1, + EqualTo = 0, + GreaterThan = 1 + } + + /* @internal */ + export type Selector = (v: T) => U; + // branded string type used to store absolute, normalized and canonicalized paths // arbitrary file name can be converted to Path via toPath function export type Path = string & { __pathBrand: any }; diff --git a/src/server/project.ts b/src/server/project.ts index 7542b30df00..bda4b644e9c 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -860,7 +860,8 @@ namespace ts.server { const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(inserted, this.directoryStructureHost); scriptInfo.attachToProject(this); }, - removed => this.detachScriptInfoFromProject(removed) + removed => this.detachScriptInfoFromProject(removed), + compareStringsCaseSensitive ); const elapsed = timestamp() - start; this.writeLog(`Finishing updateGraphWorker: Project: ${this.getProjectName()} structureChanged: ${hasChanges} Elapsed: ${elapsed}ms`); diff --git a/src/server/session.ts b/src/server/session.ts index d40becbbd16..c8ce00f303c 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -958,7 +958,7 @@ namespace ts.server { projects, project => project.getLanguageService().findReferences(file, position), /*comparer*/ undefined, - /*areEqual (TODO: fixme)*/ undefined + equateValues ); } diff --git a/src/server/utilities.ts b/src/server/utilities.ts index 69399b672b3..0976d3dd1e5 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -288,8 +288,7 @@ namespace ts.server { return index === 0 || value !== array[index - 1]; } - export function enumerateInsertsAndDeletes(newItems: SortedReadonlyArray, oldItems: SortedReadonlyArray, inserted: (newItem: T) => void, deleted: (oldItem: T) => void, compare?: Comparer) { - compare = compare || compareValues; + export function enumerateInsertsAndDeletes(newItems: SortedReadonlyArray, oldItems: SortedReadonlyArray, inserted: (newItem: T) => void, deleted: (oldItem: T) => void, comparer: Comparer) { let newIndex = 0; let oldIndex = 0; const newLen = newItems.length; @@ -297,7 +296,7 @@ namespace ts.server { while (newIndex < newLen && oldIndex < oldLen) { const newItem = newItems[newIndex]; const oldItem = oldItems[oldIndex]; - const compareResult = compare(newItem, oldItem); + const compareResult = comparer(newItem, oldItem); if (compareResult === Comparison.LessThan) { inserted(newItem); newIndex++; diff --git a/src/services/jsTyping.ts b/src/services/jsTyping.ts index 572858dd2fd..6579e21fb27 100644 --- a/src/services/jsTyping.ts +++ b/src/services/jsTyping.ts @@ -115,7 +115,10 @@ namespace ts.JsTyping { // add typings for unresolved imports if (unresolvedImports) { - const module = deduplicate(unresolvedImports.map(moduleId => nodeCoreModules.has(moduleId) ? "node" : moduleId)); + const module = deduplicate( + unresolvedImports.map(moduleId => nodeCoreModules.has(moduleId) ? "node" : moduleId), + equateStringsCaseSensitive, + compareStringsCaseSensitive); addInferredTypings(module, "Inferred typings from unresolved imports"); } // Add the cached typing locations for inferred typings that are already installed diff --git a/src/services/pathCompletions.ts b/src/services/pathCompletions.ts index 780b14db719..79a38c70d3a 100644 --- a/src/services/pathCompletions.ts +++ b/src/services/pathCompletions.ts @@ -44,7 +44,10 @@ namespace ts.Completions.PathCompletions { containsPath(rootDirectory, scriptPath, basePath, ignoreCase) ? scriptPath.substr(rootDirectory.length) : undefined); // Now find a path for each potential directory that is to be merged with the one containing the script - return deduplicate(map(rootDirs, rootDirectory => combinePaths(rootDirectory, relativeDirectory))); + return deduplicate( + map(rootDirs, rootDirectory => combinePaths(rootDirectory, relativeDirectory)), + equateStringsCaseSensitive, + compareStringsCaseSensitive); } function getCompletionEntriesForDirectoryFragmentWithRootDirs(rootDirs: string[], fragment: string, scriptPath: string, extensions: ReadonlyArray, includeExtensions: boolean, span: TextSpan, compilerOptions: CompilerOptions, host: LanguageServiceHost, exclude?: string): CompletionEntry[] { @@ -271,7 +274,7 @@ namespace ts.Completions.PathCompletions { } } - return deduplicate(nonRelativeModuleNames); + return deduplicate(nonRelativeModuleNames, equateStringsCaseSensitive, compareStringsCaseSensitive); } export function getTripleSlashReferenceCompletion(sourceFile: SourceFile, position: number, compilerOptions: CompilerOptions, host: LanguageServiceHost): CompletionInfo { diff --git a/src/services/services.ts b/src/services/services.ts index 3b90a80a387..a5f81edf79d 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1757,7 +1757,7 @@ namespace ts { const newLineCharacter = getNewLineOrDefaultFromHost(host); const rulesProvider = getRuleProvider(formatOptions); - return flatMap(deduplicate(errorCodes), errorCode => { + return flatMap(deduplicate(errorCodes, equateValues, compareValues), errorCode => { cancellationToken.throwIfCancellationRequested(); return codefix.getFixes({ errorCode, sourceFile, span, program, newLineCharacter, host, cancellationToken, rulesProvider }); }); From d9775cd8229ffcecff7cfb194bbcc98945f7554f Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 26 Oct 2017 14:29:03 -0700 Subject: [PATCH 034/235] Ensure explicit default locale before each test --- src/compiler/core.ts | 63 +++++++++++++++++++++++++++++++--------- src/harness/fourslash.ts | 5 ---- src/harness/runner.ts | 5 ++++ 3 files changed, 55 insertions(+), 18 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 9c52a4481f9..bb0aca3e700 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1613,21 +1613,17 @@ namespace ts { * Creates a string comparer for use with string collation in the UI. */ const createStringComparer = (function () { - // If the host supports Intl, we use it for comparisons using the default locale. - if (typeof Intl === "object" && typeof Intl.Collator === "function") { - return createIntlCollatorStringComparer; + type CachedLocale = "en-US" | undefined; + + interface StringComparerCache { + default?: Comparer; + "en-US"?: Comparer; } - // If the host does not support Intl, we fall back to localeCompare. - // localeCompare in Node v0.10 is just an ordinal comparison, so don't use it. - if (typeof String.prototype.localeCompare === "function" && - typeof String.prototype.toLocaleUpperCase === "function" && - "a".localeCompare("B") < 0) { - return createLocaleCompareStringComparer; - } - - // Otherwise, fall back to ordinal comparison: - return createFallbackStringComparer; + let caseInsensitiveCache: StringComparerCache | undefined; + let caseSensitiveCache: StringComparerCache | undefined; + const createStringComparerNoCache = getStringComparerFactory(); + return createStringComparer; function compareWithCallback(a: string | undefined, b: string | undefined, comparer: (a: string, b: string) => number) { if (a === b) return Comparison.EqualTo; @@ -1688,6 +1684,47 @@ namespace ts { return compareCaseInsensitive(a, b) || compareCaseSensitive(a, b); } } + + function getStringComparerFactory() { + // If the host supports Intl, we use it for comparisons using the default locale. + if (typeof Intl === "object" && typeof Intl.Collator === "function") { + return createIntlCollatorStringComparer; + } + + // If the host does not support Intl, we fall back to localeCompare. + // localeCompare in Node v0.10 is just an ordinal comparison, so don't use it. + if (typeof String.prototype.localeCompare === "function" && + typeof String.prototype.toLocaleUpperCase === "function" && + "a".localeCompare("B") < 0) { + return createLocaleCompareStringComparer; + } + + // Otherwise, fall back to ordinal comparison: + return createFallbackStringComparer; + } + + // Hold onto common string comparers. This avoids constantly reallocating comparers during + // tests. + function createStringComparerCached(locale: CachedLocale, caseInsensitive: boolean) { + const cacheKey = locale || "default"; + const cache = caseInsensitive + ? caseInsensitiveCache || (caseInsensitiveCache = {}) + : caseSensitiveCache || (caseSensitiveCache = {}); + + let comparer = cache[cacheKey]; + if (!comparer) { + comparer = createStringComparerNoCache(locale, caseInsensitive); + cache[cacheKey] = comparer; + } + + return comparer; + } + + function createStringComparer(locale: string | undefined, caseInsensitive: boolean) { + return locale === undefined || locale === "en-US" + ? createStringComparerCached(locale as CachedLocale, caseInsensitive) + : createStringComparerNoCache(locale, caseInsensitive); + } })(); let uiCS: Comparer | undefined; diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 105501196b0..b52dbd6932a 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -3128,8 +3128,6 @@ Actual: ${stringify(fullActual)}`); `(function(test, goTo, verify, edit, debug, format, cancellation, classification, verifyOperationIsCancelled) { ${code} })`; - const savedUILocale = ts.getUILocale(); - ts.setUILocale("en-US"); // run tests in en-US by default. try { const test = new FourSlashInterface.Test(state); @@ -3145,9 +3143,6 @@ ${code} catch (err) { throw err; } - finally { - ts.setUILocale(savedUILocale); - } } function chompLeadingSpace(content: string) { diff --git a/src/harness/runner.ts b/src/harness/runner.ts index db807b976bb..57955c9ab43 100644 --- a/src/harness/runner.ts +++ b/src/harness/runner.ts @@ -207,6 +207,11 @@ function beginTests() { ts.Debug.enableDebugInfo(); } + // run tests in en-US by default. + const savedUILocale = ts.getUILocale(); + beforeEach(() => ts.setUILocale("en-US")); + afterEach(() => ts.setUILocale(savedUILocale)); + runTests(runners); if (!runUnitTests) { From 3cb15378d7db79454d7b2dcc1963e3d3badb7ecb Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 26 Oct 2017 17:51:09 -0700 Subject: [PATCH 035/235] Improve performance of deduplication of sorted arrays --- src/compiler/checker.ts | 22 ++----- src/compiler/core.ts | 109 +++++++++++++++++++++++------------ src/compiler/scanner.ts | 2 +- src/compiler/tsc.ts | 2 +- src/compiler/types.ts | 5 ++ src/compiler/utilities.ts | 10 ++-- src/harness/harness.ts | 2 +- src/server/editorServices.ts | 6 +- src/server/utilities.ts | 4 +- src/services/textChanges.ts | 2 +- 10 files changed, 98 insertions(+), 66 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index aaaa0ed50b8..abedf405cde 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7341,24 +7341,12 @@ namespace ts { unionIndex?: number; } + function getTypeId(type: Type) { + return type.id; + } + function binarySearchTypes(types: Type[], type: Type): number { - let low = 0; - let high = types.length - 1; - const typeId = type.id; - while (low <= high) { - const middle = low + ((high - low) >> 1); - const id = types[middle].id; - if (id === typeId) { - return middle; - } - else if (id > typeId) { - high = middle - 1; - } - else { - low = middle + 1; - } - } - return ~low; + return binarySearch(types, type, getTypeId, compareValues); } function containsType(types: Type[], type: Type): boolean { diff --git a/src/compiler/core.ts b/src/compiler/core.ts index bb0aca3e700..605cde05178 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -660,35 +660,77 @@ namespace ts { } /** - * Creates a new array with duplicate entries removed. + * Deduplicates an array that has already been sorted. + */ + export function deduplicateSorted(array: SortedReadonlyArray, comparer: EqualityComparer | Comparer) { + if (!array) return undefined; + if (array.length === 0) return []; + + let last = array[0]; + const deduplicated: T[] = [last]; + for (let i = 1; i < array.length; i++) { + switch (comparer(last, array[i])) { + // equality comparison + case true: + + // relational comparison + case Comparison.LessThan: + case Comparison.EqualTo: + continue; + } + + deduplicated.push(last = array[i]); + } + + return deduplicated; + } + + /** + * Deduplicates an unsorted array. * @param equalityComparer An optional `EqualityComparer` used to determine if two values are duplicates. * @param comparer An optional `Comparer` used to sort entries before comparison. If supplied, * results are returned in the original order found in `array`. */ - export function deduplicate(array: ReadonlyArray, equalityComparer?: EqualityComparer, comparer?: Comparer): T[] { - if (!array) return undefined; - if (!comparer) return addRangeIfUnique([], array, equalityComparer); - return deduplicateWorker(array, equalityComparer, comparer); + export function deduplicate(array: ReadonlyArray, equalityComparer: EqualityComparer, comparer?: Comparer): T[] { + return !array ? undefined : + array.length === 0 ? [] : + array.length === 1 ? array.slice() : + comparer ? deduplicateRelational(array, equalityComparer, comparer) : + deduplicateEquality(array, equalityComparer); } - function deduplicateWorker(array: ReadonlyArray, equalityComparer: EqualityComparer = equateValues, comparer: Comparer) { + function deduplicateRelational(array: ReadonlyArray, equalityComparer: EqualityComparer, comparer: Comparer) { // Perform a stable sort of the array. This ensures the first entry in a list of // duplicates remains the first entry in the result. const indices = sequence(0, array.length); stableSortIndices(array, indices, comparer); - const deduplicated: number[] = []; - loop: for (const sourceIndex of indices) { - for (const targetIndex of deduplicated) { - if (equalityComparer(array[sourceIndex], array[targetIndex])) { - continue loop; - } + let last = array[indices[0]]; + const deduplicated: number[] = [indices[0]]; + for (let i = 1; i < indices.length; i++) { + const index = indices[i]; + const item = array[index]; + if (!equalityComparer(last, item)) { + deduplicated.push(index); + last = item; } - deduplicated.push(sourceIndex); } - // return deduplicated items in original order - return deduplicated.sort().map(i => array[i]); + // restore original order + deduplicated.sort(); + return deduplicated.map(i => array[i]); + } + + function deduplicateEquality(array: ReadonlyArray, equalityComparer: EqualityComparer) { + const result: T[] = []; + for (const item of array) { + pushIfUnique(result, item, equalityComparer); + } + return result; + } + + export function sortAndDeduplicate(array: ReadonlyArray, comparer: Comparer, equalityComparer?: EqualityComparer) { + return deduplicateSorted(sort(array, comparer), equalityComparer || comparer); } export function arrayIsEqualTo(array1: ReadonlyArray, array2: ReadonlyArray, equalityComparer: (a: T, b: T) => boolean = equateValues): boolean { @@ -827,15 +869,6 @@ namespace ts { return to; } - function addRangeIfUnique(to: T[], from: ReadonlyArray, equalityComparer?: EqualityComparer): T[] | undefined { - for (let i = 0; i < from.length; i++) { - if (from[i] !== undefined) { - pushIfUnique(to, from[i], equalityComparer); - } - } - return to; - } - /** * @return Whether the value was added. */ @@ -878,13 +911,20 @@ namespace ts { indices.sort((x, y) => comparer(array[x], array[y]) || compareValues(x, y)); } + /** + * Returns a new sorted array. + */ + export function sort(array: ReadonlyArray, comparer: Comparer) { + return array.slice().sort(comparer) as ReadonlyArray as SortedReadonlyArray; + } + /** * Stable sort of an array. Elements equal to each other maintain their relative position in the array. */ export function stableSort(array: ReadonlyArray, comparer: Comparer) { const indices = sequence(0, array.length); stableSortIndices(array, indices, comparer); - return indices.map(i => array[i]); + return indices.map(i => array[i]) as ReadonlyArray as SortedReadonlyArray; } export function rangeEquals(array1: ReadonlyArray, array2: ReadonlyArray, pos: number, end: number) { @@ -969,25 +1009,22 @@ namespace ts { * @param array A sorted array whose first element must be no larger than number * @param number The value to be searched for in the array. */ - export function binarySearch(array: ReadonlyArray, value: T, comparer?: Comparer, offset?: number): number { + export function binarySearch(array: ReadonlyArray, value: T, keySelector: Selector, keyComparer: Comparer, offset?: number): number { if (!array || array.length === 0) { return -1; } let low = offset || 0; let high = array.length - 1; - comparer = comparer !== undefined - ? comparer - : (v1, v2) => (v1 < v2 ? -1 : (v1 > v2 ? 1 : 0)); - + const key = keySelector(value); while (low <= high) { const middle = low + ((high - low) >> 1); - const midValue = array[middle]; + const midKey = keySelector(array[middle]); - if (comparer(midValue, value) === 0) { + if (keyComparer(midKey, key) === 0) { return middle; } - else if (comparer(midValue, value) > 0) { + else if (keyComparer(midKey, key) > 0) { high = middle - 1; } else { @@ -2452,8 +2489,8 @@ namespace ts { return flatten(results); function visitDirectory(path: string, absolutePath: string, depth: number | undefined) { - let { files, directories } = getFileSystemEntries(path); - files = files.slice().sort(comparer); + const entries = getFileSystemEntries(path); + const files = sort(entries.files, comparer); for (const current of files) { const name = combinePaths(path, current); @@ -2478,7 +2515,7 @@ namespace ts { } } - directories = directories.slice().sort(comparer); + const directories = sort(entries.directories, comparer); for (const current of directories) { const name = combinePaths(path, current); const absoluteName = combinePaths(absolutePath, current); diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 6dab127ca33..5a11cccc8b6 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -352,7 +352,7 @@ namespace ts { * We assume the first line starts at position 0 and 'position' is non-negative. */ export function computeLineAndCharacterOfPosition(lineStarts: ReadonlyArray, position: number): LineAndCharacter { - let lineNumber = binarySearch(lineStarts, position); + let lineNumber = binarySearch(lineStarts, position, identity, compareValues); if (lineNumber < 0) { // If the actual position was not found, // the binary search returns the 2's-complement of the next line start diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index cc3c256827a..e7a73b6d09c 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -306,7 +306,7 @@ namespace ts { // Sort our options by their names, (e.g. "--noImplicitAny" comes before "--watch") const optsList = showAllOptions ? - optionDeclarations.slice().sort((a, b) => compareStringsCaseInsensitive(a.name, b.name)) : + sort(optionDeclarations, (a, b) => compareStringsCaseInsensitive(a.name, b.name)) : filter(optionDeclarations.slice(), v => v.showInSimplifiedHelpView); // We want our descriptions to align at the same column in our output, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 2f861f2c371..3af3b6e022a 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -36,6 +36,11 @@ namespace ts { push(...values: T[]): void; } + /* @internal */ + export interface SortedReadonlyArray extends ReadonlyArray { + " __sortedArrayBrand": any; + } + /* @internal */ export type EqualityComparer = (a: T, b: T) => boolean; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index a3a8ca3afc7..1ade3cc6374 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -321,16 +321,16 @@ namespace ts { return getSourceTextOfNodeFromSourceFile(getSourceFileOfNode(node), node, includeTrivia); } + function getPos(range: Node) { + return range.pos; + } + /** * Note: it is expected that the `nodeArray` and the `node` are within the same file. * For example, searching for a `SourceFile` in a `SourceFile[]` wouldn't work. */ export function indexOfNode(nodeArray: ReadonlyArray, node: Node) { - return binarySearch(nodeArray, node, compareNodePos); - } - - function compareNodePos({ pos: aPos }: Node, { pos: bPos}: Node) { - return aPos < bPos ? Comparison.LessThan : bPos < aPos ? Comparison.GreaterThan : Comparison.EqualTo; + return binarySearch(nodeArray, node, getPos, compareValues); } /** diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 728d18c59cc..4826c30bbfb 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1313,7 +1313,7 @@ namespace Harness { export const diagnosticSummaryMarker = "__diagnosticSummary"; export const globalErrorsMarker = "__globalErrors"; export function *iterateErrorBaseline(inputFiles: ReadonlyArray, diagnostics: ReadonlyArray, pretty?: boolean): IterableIterator<[string, string, number]> { - diagnostics = diagnostics.slice().sort(ts.compareDiagnostics); + diagnostics = ts.sort(diagnostics, ts.compareDiagnostics); let outputLines = ""; // Count up all errors that were found in files other than lib.d.ts so we don't miss any let totalErrorsReportedInNonLibraryFiles = 0; diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index f749c27cbbc..1e3104b08d1 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -203,8 +203,10 @@ namespace ts.server { * This helper function processes a list of projects and return the concatenated, sortd and deduplicated output of processing each project. */ export function combineProjectOutput(projects: ReadonlyArray, action: (project: Project) => ReadonlyArray, comparer?: (a: T, b: T) => number, areEqual?: (a: T, b: T) => boolean) { - const result = flatMap(projects, action).sort(comparer); - return projects.length > 1 ? deduplicate(result, areEqual) : result; + const outputs = flatMap(projects, action); + return comparer + ? sortAndDeduplicate(outputs, comparer, areEqual) + : deduplicate(outputs, areEqual); } export interface HostConfiguration { diff --git a/src/server/utilities.ts b/src/server/utilities.ts index 0976d3dd1e5..2d458c09b82 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -250,7 +250,7 @@ namespace ts.server { return; } - const insertIndex = binarySearch(array, insert, compare); + const insertIndex = binarySearch(array, insert, identity, compare); if (insertIndex < 0) { array.splice(~insertIndex, 0, insert); } @@ -266,7 +266,7 @@ namespace ts.server { return; } - const removeIndex = binarySearch(array, remove, compare); + const removeIndex = binarySearch(array, remove, identity, compare); if (removeIndex >= 0) { array.splice(removeIndex, 1); } diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index bc3a8e27ef0..f84292c5faf 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -581,7 +581,7 @@ namespace ts.textChanges { return applyFormatting(nonformattedText, sourceFile, initialIndentation, delta, this.rulesProvider); } - private static normalize(changes: Change[]): Change[] { + private static normalize(changes: Change[]) { // order changes by start position const normalized = stableSort(changes, (a, b) => a.range.pos - b.range.pos); // verify that change intervals do not overlap, except possibly at end points. From da63c2c57977840cf0b349c84ab139a92e6f4787 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 27 Oct 2017 16:24:12 -0700 Subject: [PATCH 036/235] Exclude legacy safelist files in external projects --- src/compiler/core.ts | 7 ++++ src/server/editorServices.ts | 33 +++++++++++++++---- src/services/jsTyping.ts | 2 +- .../reference/api/tsserverlibrary.d.ts | 7 ++-- 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 12b8dd2f87e..c9b644b22ce 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2413,6 +2413,13 @@ namespace ts { return (removeFileExtension(path) + newExtension); } + /** + * Takes a string like "jquery-min.4.2.3" and returns "jquery" + */ + export function removeMinAndVersionNumbers(fileName: string) { + return fileName.replace(/((?:\.|-)min(?=\.|$))|((?:-|\.)\d+)/g, ""); + } + export interface ObjectAllocator { getNodeConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Node; getTokenConstructor(): new (kind: TKind, pos?: number, end?: number) => Token; diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index b7617e1fa17..eb2ae0f3cd9 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -110,7 +110,7 @@ namespace ts.server { export interface TypesMapFile { typesMap: SafeList; - simpleMap: string[]; + simpleMap: { [libName: string]: string }; } /** @@ -374,6 +374,7 @@ namespace ts.server { private readonly hostConfiguration: HostConfiguration; private safelist: SafeList = defaultTypeSafeList; + private legacySafelist: { [key: string]: string } = {}; private changedFiles: ScriptInfo[]; private pendingProjectUpdates = createMap(); @@ -426,9 +427,12 @@ namespace ts.server { this.toCanonicalFileName = createGetCanonicalFileName(this.host.useCaseSensitiveFileNames); this.throttledOperations = new ThrottledOperations(this.host, this.logger); - if (opts.typesMapLocation) { + if (this.typesMapLocation) { this.loadTypesMap(); } + else { + this.logger.info("No types map provided; using the default"); + } this.typingsInstaller.attach(this); @@ -518,10 +522,12 @@ namespace ts.server { } // raw is now fixed and ready this.safelist = raw.typesMap; + this.legacySafelist = raw.simpleMap; } catch (e) { this.logger.info(`Error loading types map: ${e}`); this.safelist = defaultTypeSafeList; + this.legacySafelist = {}; } } @@ -1393,7 +1399,7 @@ namespace ts.server { return false; } - private createExternalProject(projectFileName: string, files: protocol.ExternalFile[], options: protocol.ExternalProjectCompilerOptions, typeAcquisition: TypeAcquisition) { + private createExternalProject(projectFileName: string, files: protocol.ExternalFile[], options: protocol.ExternalProjectCompilerOptions, typeAcquisition: TypeAcquisition, excludedFiles: NormalizedPath[]) { const compilerOptions = convertCompilerOptions(options); const project = new ExternalProject( projectFileName, @@ -1402,6 +1408,7 @@ namespace ts.server { compilerOptions, /*languageServiceEnabled*/ !this.exceededTotalSizeLimitForNonTsFiles(projectFileName, compilerOptions, files, externalFilePropertyReader), options.compileOnSave === undefined ? true : options.compileOnSave); + project.excludedFiles = excludedFiles; this.addFilesToNonInferredProjectAndUpdateGraph(project, files, externalFilePropertyReader, typeAcquisition); this.externalProjects.push(project); @@ -2204,7 +2211,22 @@ namespace ts.server { excludedFiles.push(normalizedNames[i]); } else { - filesToKeep.push(proj.rootFiles[i]); + let exclude = false; + if (typeAcquisition && (typeAcquisition.enable || typeAcquisition.enableAutoDiscovery)) { + const baseName = getBaseFileName(normalizedNames[i].toLowerCase()); + if (fileExtensionIs(baseName, "js")) { + const inferredTypingName = removeFileExtension(baseName); + const cleanedTypingName = removeMinAndVersionNumbers(inferredTypingName); + if (this.legacySafelist[cleanedTypingName]) { + this.logger.info(`Excluded '${normalizedNames[i]}'`); + excludedFiles.push(normalizedNames[i]); + exclude = true; + } + } + } + if (!exclude) { + filesToKeep.push(proj.rootFiles[i]); + } } } proj.rootFiles = filesToKeep; @@ -2312,8 +2334,7 @@ namespace ts.server { else { // no config files - remove the item from the collection this.externalProjectToConfiguredProjectMap.delete(proj.projectFileName); - const newProj = this.createExternalProject(proj.projectFileName, rootFiles, proj.options, proj.typeAcquisition); - newProj.excludedFiles = excludedFiles; + this.createExternalProject(proj.projectFileName, rootFiles, proj.options, proj.typeAcquisition, excludedFiles); } if (!suppressRefreshOfInferredProjects) { this.ensureProjectStructuresUptoDate(/*refreshInferredProjects*/ true); diff --git a/src/services/jsTyping.ts b/src/services/jsTyping.ts index 572858dd2fd..e31201b951f 100644 --- a/src/services/jsTyping.ts +++ b/src/services/jsTyping.ts @@ -180,7 +180,7 @@ namespace ts.JsTyping { if (!hasJavaScriptFileExtension(j)) return undefined; const inferredTypingName = removeFileExtension(getBaseFileName(j.toLowerCase())); - const cleanedTypingName = inferredTypingName.replace(/((?:\.|-)min(?=\.|$))|((?:-|\.)\d+)/g, ""); + const cleanedTypingName = removeMinAndVersionNumbers(inferredTypingName); return safeList.get(cleanedTypingName); }); if (fromFileNames.length) { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 5d439e840b0..44c8095b9fb 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -7391,7 +7391,9 @@ declare namespace ts.server { } interface TypesMapFile { typesMap: SafeList; - simpleMap: string[]; + simpleMap: { + [libName: string]: string; + }; } function convertFormatOptions(protocolOptions: protocol.FormatCodeSettings): FormatCodeSettings; function convertCompilerOptions(protocolOptions: protocol.ExternalProjectCompilerOptions): CompilerOptions & protocol.CompileOnSaveMixin; @@ -7468,6 +7470,7 @@ declare namespace ts.server { private readonly throttledOperations; private readonly hostConfiguration; private safelist; + private legacySafelist; private changedFiles; private pendingProjectUpdates; private pendingInferredProjectUpdate; @@ -7576,7 +7579,7 @@ declare namespace ts.server { private findExternalProjectByProjectName(projectFileName); private convertConfigFileContentToProjectOptions(configFilename, cachedDirectoryStructureHost); private exceededTotalSizeLimitForNonTsFiles(name, options, fileNames, propertyReader); - private createExternalProject(projectFileName, files, options, typeAcquisition); + private createExternalProject(projectFileName, files, options, typeAcquisition, excludedFiles); private sendProjectTelemetry(projectKey, project, projectOptions?); private addFilesToNonInferredProjectAndUpdateGraph(project, files, propertyReader, typeAcquisition); private createConfiguredProject(configFileName); From 22eb519b0f6c4c06c71a7c2dd351bbec530f5dd9 Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Fri, 27 Oct 2017 15:33:30 -0700 Subject: [PATCH 037/235] Return empty doc comment instead of undefined --- src/services/jsDoc.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 3e9913fc6c7..49f13d0b4c3 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -188,24 +188,26 @@ namespace ts.JsDoc { * be performed. */ export function getDocCommentTemplateAtPosition(newLine: string, sourceFile: SourceFile, position: number): TextInsertion { + const emptyDocComment = { newText: "", caretOffset: 0 }; + // Check if in a context where we don't want to perform any insertion if (isInString(sourceFile, position) || isInComment(sourceFile, position) || hasDocComment(sourceFile, position)) { - return undefined; + return emptyDocComment; } const tokenAtPos = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false); const tokenStart = tokenAtPos.getStart(); if (!tokenAtPos || tokenStart < position) { - return undefined; + return emptyDocComment; } const commentOwnerInfo = getCommentOwnerInfo(tokenAtPos); if (!commentOwnerInfo) { - return undefined; + return emptyDocComment; } const { commentOwner, parameters } = commentOwnerInfo; if (commentOwner.getStart() < position) { - return undefined; + return emptyDocComment; } const posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position); From b566480aaaf92460b37eb0977b5c07c1c0729c85 Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Fri, 27 Oct 2017 16:39:33 -0700 Subject: [PATCH 038/235] Update tests to expect empty doc comment template --- src/harness/fourslash.ts | 4 ++-- tests/cases/fourslash/docCommentTemplateEmptyFile.ts | 2 +- tests/cases/fourslash/docCommentTemplateInMultiLineComment.ts | 2 +- .../cases/fourslash/docCommentTemplateInSingleLineComment.ts | 2 +- .../fourslash/docCommentTemplateInsideFunctionDeclaration.ts | 2 +- .../fourslash/docCommentTemplateNamespacesAndModules02.ts | 4 ++-- tests/cases/fourslash/docCommentTemplateRegex.ts | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 7ba4e94902d..79cd18da839 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -4050,9 +4050,9 @@ namespace FourSlashInterface { this.state.verifyDocCommentTemplate({ newText: expectedText.replace(/\r?\n/g, "\r\n"), caretOffset: expectedOffset }); } - public noDocCommentTemplateAt(marker: string | FourSlash.Marker) { + public emptyDocCommentTemplateAt(marker: string | FourSlash.Marker) { this.state.goToMarker(marker); - this.state.verifyDocCommentTemplate(/*expected*/ undefined); + this.state.verifyDocCommentTemplate({ newText: "", caretOffset: 0 }); } public rangeAfterCodeFix(expectedText: string, includeWhiteSpace?: boolean, errorCode?: number, index?: number): void { diff --git a/tests/cases/fourslash/docCommentTemplateEmptyFile.ts b/tests/cases/fourslash/docCommentTemplateEmptyFile.ts index f04653dc328..6dcb5ef832b 100644 --- a/tests/cases/fourslash/docCommentTemplateEmptyFile.ts +++ b/tests/cases/fourslash/docCommentTemplateEmptyFile.ts @@ -3,4 +3,4 @@ // @Filename: emptyFile.ts /////*0*/ -verify.noDocCommentTemplateAt("0"); +verify.emptyDocCommentTemplateAt("0"); diff --git a/tests/cases/fourslash/docCommentTemplateInMultiLineComment.ts b/tests/cases/fourslash/docCommentTemplateInMultiLineComment.ts index 6e749782c7d..dc3da4e7599 100644 --- a/tests/cases/fourslash/docCommentTemplateInMultiLineComment.ts +++ b/tests/cases/fourslash/docCommentTemplateInMultiLineComment.ts @@ -3,4 +3,4 @@ // @Filename: justAComment.ts //// /* /*0*/ */ -verify.noDocCommentTemplateAt("0"); +verify.emptyDocCommentTemplateAt("0"); diff --git a/tests/cases/fourslash/docCommentTemplateInSingleLineComment.ts b/tests/cases/fourslash/docCommentTemplateInSingleLineComment.ts index b60fff2d590..472d417a9ff 100644 --- a/tests/cases/fourslash/docCommentTemplateInSingleLineComment.ts +++ b/tests/cases/fourslash/docCommentTemplateInSingleLineComment.ts @@ -9,5 +9,5 @@ //// // /*2*/ for (const marker of test.markers()) { - verify.noDocCommentTemplateAt(marker); + verify.emptyDocCommentTemplateAt(marker); } diff --git a/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts b/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts index e0ebc00dc39..13b6ebc0df6 100644 --- a/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts +++ b/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts @@ -4,5 +4,5 @@ ////f/*0*/unction /*1*/foo/*2*/(/*3*/) /*4*/{ /*5*/} for (const marker of test.markers()) { - verify.noDocCommentTemplateAt(marker); + verify.emptyDocCommentTemplateAt(marker); } diff --git a/tests/cases/fourslash/docCommentTemplateNamespacesAndModules02.ts b/tests/cases/fourslash/docCommentTemplateNamespacesAndModules02.ts index dad2e9745a9..8bb14bef5df 100644 --- a/tests/cases/fourslash/docCommentTemplateNamespacesAndModules02.ts +++ b/tests/cases/fourslash/docCommentTemplateNamespacesAndModules02.ts @@ -11,6 +11,6 @@ verify.docCommentTemplateAt("top", /*indentation*/ 8, * */`); -verify.noDocCommentTemplateAt("n2"); +verify.emptyDocCommentTemplateAt("n2"); -verify.noDocCommentTemplateAt("n3"); +verify.emptyDocCommentTemplateAt("n3"); diff --git a/tests/cases/fourslash/docCommentTemplateRegex.ts b/tests/cases/fourslash/docCommentTemplateRegex.ts index 685c1ca5aef..7a6af09aeb5 100644 --- a/tests/cases/fourslash/docCommentTemplateRegex.ts +++ b/tests/cases/fourslash/docCommentTemplateRegex.ts @@ -4,5 +4,5 @@ ////var regex = /*0*///*1*/asdf/*2*/ /*3*///*4*/; for (const marker of test.markers()) { - verify.noDocCommentTemplateAt(marker); + verify.emptyDocCommentTemplateAt(marker); } From 7aeb11b41ea6cdec2fe5994b4a32454876dba8b6 Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Fri, 27 Oct 2017 16:46:39 -0700 Subject: [PATCH 039/235] Return doc comment template for interfaces and method signatures --- src/services/jsDoc.ts | 4 +++- .../fourslash/docCommentTemplateInterfaces.ts | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/docCommentTemplateInterfaces.ts diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 49f13d0b4c3..0443a950e94 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -266,10 +266,12 @@ namespace ts.JsDoc { case SyntaxKind.FunctionDeclaration: case SyntaxKind.MethodDeclaration: case SyntaxKind.Constructor: - const { parameters } = commentOwner as FunctionDeclaration | MethodDeclaration | ConstructorDeclaration; + case SyntaxKind.MethodSignature: + const { parameters } = commentOwner as FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | MethodSignature; return { commentOwner, parameters }; case SyntaxKind.ClassDeclaration: + case SyntaxKind.InterfaceDeclaration: return { commentOwner }; case SyntaxKind.VariableStatement: { diff --git a/tests/cases/fourslash/docCommentTemplateInterfaces.ts b/tests/cases/fourslash/docCommentTemplateInterfaces.ts new file mode 100644 index 00000000000..2faf49351f2 --- /dev/null +++ b/tests/cases/fourslash/docCommentTemplateInterfaces.ts @@ -0,0 +1,23 @@ +/// + +/////*interfaceFoo*/ +////interface Foo { +//// /*propertybar*/ +//// bar: any; +//// +//// /*methodbaz*/ +//// baz(message: any): void; +////} + +verify.docCommentTemplateAt("interfaceFoo", /*expectedOffset*/ 8, +`/** + * + */`); + +verify.emptyDocCommentTemplateAt("propertybar"); + +verify.docCommentTemplateAt("methodbaz", /*expectedOffset*/ 12, + `/** + * + * @param message + */`); \ No newline at end of file From 49772187e51060d0516c0b7644684c13fc05afc7 Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Fri, 27 Oct 2017 16:53:24 -0700 Subject: [PATCH 040/235] Update comments --- src/services/jsDoc.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 0443a950e94..07db4402cbf 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -177,6 +177,8 @@ namespace ts.JsDoc { * - class declarations * - variable statements * - namespace declarations + * - interface declarations + * - method signatures * * Hosts should ideally check that: * - The line is all whitespace up to 'position' before performing the insertion. @@ -258,7 +260,6 @@ namespace ts.JsDoc { function getCommentOwnerInfo(tokenAtPos: Node): CommentOwnerInfo | undefined { // TODO: add support for: // - enums/enum members - // - interfaces // - property declarations // - potentially property assignments for (let commentOwner = tokenAtPos; commentOwner; commentOwner = commentOwner.parent) { From 5830bb9b19f400994f77bdb1df0b5aff888dbdc3 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 27 Oct 2017 17:07:04 -0700 Subject: [PATCH 041/235] Improved logging --- src/server/editorServices.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index eb2ae0f3cd9..0bd02f32d95 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -2152,7 +2152,7 @@ namespace ts.server { const rule = this.safelist[name]; for (const root of normalizedNames) { if (rule.match.test(root)) { - this.logger.info(`Excluding files based on rule ${name}`); + this.logger.info(`Excluding files based on rule ${name} matching file '${root}'`); // If the file matches, collect its types packages and exclude rules if (rule.types) { @@ -2218,7 +2218,7 @@ namespace ts.server { const inferredTypingName = removeFileExtension(baseName); const cleanedTypingName = removeMinAndVersionNumbers(inferredTypingName); if (this.legacySafelist[cleanedTypingName]) { - this.logger.info(`Excluded '${normalizedNames[i]}'`); + this.logger.info(`Excluded '${normalizedNames[i]}' because it matched ${cleanedTypingName} from the legacy safelist`); excludedFiles.push(normalizedNames[i]); exclude = true; } From e6cdd6334b0419bd4c3c9a6b4e924989e448f015 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Sun, 29 Oct 2017 12:35:48 -0700 Subject: [PATCH 042/235] PR Feedback --- src/compiler/core.ts | 29 +++++++++-------------------- src/compiler/types.ts | 3 --- src/harness/fourslash.ts | 1 - src/harness/runner.ts | 7 +++++-- 4 files changed, 14 insertions(+), 26 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 605cde05178..a3910334286 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -702,7 +702,7 @@ namespace ts { function deduplicateRelational(array: ReadonlyArray, equalityComparer: EqualityComparer, comparer: Comparer) { // Perform a stable sort of the array. This ensures the first entry in a list of // duplicates remains the first entry in the result. - const indices = sequence(0, array.length); + const indices = array.map((_, i) => i); stableSortIndices(array, indices, comparer); let last = array[indices[0]]; @@ -895,17 +895,6 @@ namespace ts { } } - /** - * Creates an array of integers starting at `from` (inclusive) and ending at `to` (exclusive). - */ - function sequence(from: number, to: number) { - const numbers: number[] = []; - for (let i = from; i < to; i++) { - numbers.push(i); - } - return numbers; - } - function stableSortIndices(array: ReadonlyArray, indices: number[], comparer: Comparer) { // sort indices by value then position indices.sort((x, y) => comparer(array[x], array[y]) || compareValues(x, y)); @@ -922,7 +911,7 @@ namespace ts { * Stable sort of an array. Elements equal to each other maintain their relative position in the array. */ export function stableSort(array: ReadonlyArray, comparer: Comparer) { - const indices = sequence(0, array.length); + const indices = array.map((_, i) => i); stableSortIndices(array, indices, comparer); return indices.map(i => array[i]) as ReadonlyArray as SortedReadonlyArray; } @@ -1009,7 +998,7 @@ namespace ts { * @param array A sorted array whose first element must be no larger than number * @param number The value to be searched for in the array. */ - export function binarySearch(array: ReadonlyArray, value: T, keySelector: Selector, keyComparer: Comparer, offset?: number): number { + export function binarySearch(array: ReadonlyArray, value: T, keySelector: (v: T) => U, keyComparer: Comparer, offset?: number): number { if (!array || array.length === 0) { return -1; } @@ -1764,8 +1753,8 @@ namespace ts { } })(); - let uiCS: Comparer | undefined; - let uiCI: Comparer | undefined; + let uiComparerCaseSensitive: Comparer | undefined; + let uiComparerCaseInsensitive: Comparer | undefined; let uiLocale: string | undefined; export function getUILocale() { @@ -1775,8 +1764,8 @@ namespace ts { export function setUILocale(value: string) { if (uiLocale !== value) { uiLocale = value; - uiCS = undefined; - uiCI = undefined; + uiComparerCaseSensitive = undefined; + uiComparerCaseInsensitive = undefined; } } @@ -1791,7 +1780,7 @@ namespace ts { * accents/diacritic marks as unequal. */ export function compareStringsCaseInsensitiveUI(a: string, b: string) { - const comparer = uiCI || (uiCI = createStringComparer(uiLocale, /*caseInsensitive*/ true)); + const comparer = uiComparerCaseInsensitive || (uiComparerCaseInsensitive = createStringComparer(uiLocale, /*caseInsensitive*/ true)); return comparer(a, b); } @@ -1806,7 +1795,7 @@ namespace ts { * accents/diacritic marks, or case as unequal. */ export function compareStringsCaseSensitiveUI(a: string, b: string) { - const comparer = uiCS || (uiCS = createStringComparer(uiLocale, /*caseInsensitive*/ false)); + const comparer = uiComparerCaseSensitive || (uiComparerCaseSensitive = createStringComparer(uiLocale, /*caseInsensitive*/ false)); return comparer(a, b); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 3af3b6e022a..84028a23b0a 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -54,9 +54,6 @@ namespace ts { GreaterThan = 1 } - /* @internal */ - export type Selector = (v: T) => U; - // branded string type used to store absolute, normalized and canonicalized paths // arbitrary file name can be converted to Path via toPath function export type Path = string & { __pathBrand: any }; diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index b52dbd6932a..d88f0e0854e 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -3129,7 +3129,6 @@ Actual: ${stringify(fullActual)}`); ${code} })`; try { - const test = new FourSlashInterface.Test(state); const goTo = new FourSlashInterface.GoTo(state); const verify = new FourSlashInterface.Verify(state); diff --git a/src/harness/runner.ts b/src/harness/runner.ts index 57955c9ab43..6ae94790e1b 100644 --- a/src/harness/runner.ts +++ b/src/harness/runner.ts @@ -208,8 +208,11 @@ function beginTests() { } // run tests in en-US by default. - const savedUILocale = ts.getUILocale(); - beforeEach(() => ts.setUILocale("en-US")); + let savedUILocale: string | undefined; + beforeEach(() => { + savedUILocale = ts.getUILocale(); + ts.setUILocale("en-US"); + }); afterEach(() => ts.setUILocale(savedUILocale)); runTests(runners); From fcb8296a05b687cfb9f5a30139bca037e6c2a175 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Sun, 29 Oct 2017 12:40:40 -0700 Subject: [PATCH 043/235] Updated comments --- src/compiler/core.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index a3910334286..7f165a171f8 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -992,11 +992,15 @@ namespace ts { } /** - * Performs a binary search, finding the index at which 'value' occurs in 'array'. + * Performs a binary search, finding the index at which `value` occurs in `array`. * If no such index is found, returns the 2's-complement of first index at which - * number[index] exceeds number. + * `array[index]` exceeds `value`. * @param array A sorted array whose first element must be no larger than number - * @param number The value to be searched for in the array. + * @param value The value to be searched for in the array. + * @param keySelector A callback used to select the search key from `value` and each element of + * `array`. + * @param keyComparer A callback used to compare two keys in a sorted array. + * @param offset An offset into `array` at which to start the search. */ export function binarySearch(array: ReadonlyArray, value: T, keySelector: (v: T) => U, keyComparer: Comparer, offset?: number): number { if (!array || array.length === 0) { From 1f961cda11bcc96ccd01f3fe88cd6e17b8b9c000 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Sun, 29 Oct 2017 13:24:22 -0700 Subject: [PATCH 044/235] PR Feedback, cleanup --- src/compiler/core.ts | 89 ++++++++++++++++++++++--------------------- src/compiler/types.ts | 5 --- 2 files changed, 46 insertions(+), 48 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 7f165a171f8..e66a43e0aeb 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -659,46 +659,6 @@ namespace ts { return [...array1, ...array2]; } - /** - * Deduplicates an array that has already been sorted. - */ - export function deduplicateSorted(array: SortedReadonlyArray, comparer: EqualityComparer | Comparer) { - if (!array) return undefined; - if (array.length === 0) return []; - - let last = array[0]; - const deduplicated: T[] = [last]; - for (let i = 1; i < array.length; i++) { - switch (comparer(last, array[i])) { - // equality comparison - case true: - - // relational comparison - case Comparison.LessThan: - case Comparison.EqualTo: - continue; - } - - deduplicated.push(last = array[i]); - } - - return deduplicated; - } - - /** - * Deduplicates an unsorted array. - * @param equalityComparer An optional `EqualityComparer` used to determine if two values are duplicates. - * @param comparer An optional `Comparer` used to sort entries before comparison. If supplied, - * results are returned in the original order found in `array`. - */ - export function deduplicate(array: ReadonlyArray, equalityComparer: EqualityComparer, comparer?: Comparer): T[] { - return !array ? undefined : - array.length === 0 ? [] : - array.length === 1 ? array.slice() : - comparer ? deduplicateRelational(array, equalityComparer, comparer) : - deduplicateEquality(array, equalityComparer); - } - function deduplicateRelational(array: ReadonlyArray, equalityComparer: EqualityComparer, comparer: Comparer) { // Perform a stable sort of the array. This ensures the first entry in a list of // duplicates remains the first entry in the result. @@ -729,6 +689,50 @@ namespace ts { return result; } + /** + * Deduplicates an unsorted array. + * @param equalityComparer An optional `EqualityComparer` used to determine if two values are duplicates. + * @param comparer An optional `Comparer` used to sort entries before comparison. If supplied, + * results are returned in the original order found in `array`. + */ + export function deduplicate(array: ReadonlyArray, equalityComparer: EqualityComparer, comparer?: Comparer): T[] { + return !array ? undefined : + array.length === 0 ? [] : + array.length === 1 ? array.slice() : + comparer ? deduplicateRelational(array, equalityComparer, comparer) : + deduplicateEquality(array, equalityComparer); + } + + /** + * Deduplicates an array that has already been sorted. + */ + function deduplicateSorted(array: ReadonlyArray, comparer: EqualityComparer | Comparer) { + if (!array) return undefined; + if (array.length === 0) return []; + + let last = array[0]; + const deduplicated: T[] = [last]; + for (let i = 1; i < array.length; i++) { + const next = array[i]; + switch (comparer(next, last)) { + // equality comparison + case true: + + // relational comparison + case Comparison.EqualTo: + continue; + + case Comparison.LessThan: + // If `array` is sorted, `next` should **never** be less than `last`. + return Debug.fail("Array is unsorted."); + } + + deduplicated.push(last = next); + } + + return deduplicated; + } + export function sortAndDeduplicate(array: ReadonlyArray, comparer: Comparer, equalityComparer?: EqualityComparer) { return deduplicateSorted(sort(array, comparer), equalityComparer || comparer); } @@ -904,7 +908,7 @@ namespace ts { * Returns a new sorted array. */ export function sort(array: ReadonlyArray, comparer: Comparer) { - return array.slice().sort(comparer) as ReadonlyArray as SortedReadonlyArray; + return array.slice().sort(comparer); } /** @@ -913,7 +917,7 @@ namespace ts { export function stableSort(array: ReadonlyArray, comparer: Comparer) { const indices = array.map((_, i) => i); stableSortIndices(array, indices, comparer); - return indices.map(i => array[i]) as ReadonlyArray as SortedReadonlyArray; + return indices.map(i => array[i]); } export function rangeEquals(array1: ReadonlyArray, array2: ReadonlyArray, pos: number, end: number) { @@ -2215,7 +2219,6 @@ namespace ts { return false; } - // File-system comparisons should use predictable ordering const equalityComparer = ignoreCase ? equateStringsCaseInsensitive : equateStringsCaseSensitive; for (let i = 0; i < parentComponents.length; i++) { if (!equalityComparer(parentComponents[i], childComponents[i])) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 84028a23b0a..43ed345e220 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -36,11 +36,6 @@ namespace ts { push(...values: T[]): void; } - /* @internal */ - export interface SortedReadonlyArray extends ReadonlyArray { - " __sortedArrayBrand": any; - } - /* @internal */ export type EqualityComparer = (a: T, b: T) => boolean; From c83eeaaac7cc2e1988ea663471e40e33dd22ef32 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Sun, 29 Oct 2017 13:26:51 -0700 Subject: [PATCH 045/235] Added comment --- src/compiler/core.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index e66a43e0aeb..0ccb7253331 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1602,7 +1602,8 @@ namespace ts { } /** - * Compare two values for their order relative to each other. + * Compare two numeric values for their order relative to each other. + * To compare strings, use any of the `compareStrings` functions. */ export function compareValues(a: number, b: number) { return compareComparableValues(a, b); From 5395d0ddb872acb83c2cca3ec31240572082db05 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Mon, 30 Oct 2017 10:44:51 -0700 Subject: [PATCH 046/235] Add test --- .../unittests/tsserverProjectSystem.ts | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index bc8b476ceb9..fb2bbec6741 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -1496,6 +1496,26 @@ namespace ts.projectSystem { } }); + it("ignores files excluded by a legacy safe type list", () => { + const file1 = { + path: "/a/b/bliss.js", + content: "let x = 5" + }; + const file2 = { + path: "/a/b/foo.js", + content: "" + }; + const host = createServerHost([file1, file2, customTypesMap]); + const projectService = createProjectService(host); + try { + projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles([file1.path, file2.path]), typeAcquisition: { enable: true } }); + const proj = projectService.externalProjects[0]; + assert.deepEqual(proj.getFileNames(), [file2.path]); + } finally { + projectService.resetSafeList(); + } + }); + it("open file become a part of configured project if it is referenced from root file", () => { const file1 = { path: "/a/b/f1.ts", From a01df0f20beef355f0902eb54019e7018fde5576 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 30 Oct 2017 12:36:25 -0700 Subject: [PATCH 047/235] Use nominal check in isTypeInstanceOf --- src/compiler/checker.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 72438fa27af..864e78aa0e9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8556,11 +8556,14 @@ namespace ts { return isTypeRelatedTo(source, target, assignableRelation); } - // A type S is considered to be an instance of a type T if S and T are the same type or if S is a - // subtype of T but not structurally identical to T. This specifically means that two distinct but - // structurally identical types (such as two classes) are not considered instances of each other. + // An object type S is considered to be an instance of an object type T if + // S is a union type and every constituent of S is an instance of T, + // T is a union type and S is an instance of at least one constituent of T, or + // T occurs directly or indirectly in an 'extends' clause of S. function isTypeInstanceOf(source: Type, target: Type): boolean { - return getTargetType(source) === getTargetType(target) || isTypeSubtypeOf(source, target) && !isTypeIdenticalTo(source, target); + return source.flags & TypeFlags.Union ? every((source).types, t => isTypeInstanceOf(t, target)) : + target.flags & TypeFlags.Union ? some((target).types, t => isTypeInstanceOf(source, t)) : + hasBaseType(source, getTargetType(target)); } /** From d6697714629b3c204fdbadca1452480b436bd09c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 30 Oct 2017 12:36:34 -0700 Subject: [PATCH 048/235] Accept new baselines --- .../narrowingGenericTypeFromInstanceof01.errors.txt | 10 ++++------ .../narrowingGenericTypeFromInstanceof01.types | 6 +++--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/tests/baselines/reference/narrowingGenericTypeFromInstanceof01.errors.txt b/tests/baselines/reference/narrowingGenericTypeFromInstanceof01.errors.txt index c686cd7a7cf..bb35b351c1b 100644 --- a/tests/baselines/reference/narrowingGenericTypeFromInstanceof01.errors.txt +++ b/tests/baselines/reference/narrowingGenericTypeFromInstanceof01.errors.txt @@ -1,6 +1,5 @@ -tests/cases/conformance/types/typeRelationships/instanceOf/narrowingGenericTypeFromInstanceof01.ts(13,17): error TS2345: Argument of type 'A | B' is not assignable to parameter of type 'A'. - Type 'B' is not assignable to type 'A'. - Property 'a' is missing in type 'B'. +tests/cases/conformance/types/typeRelationships/instanceOf/narrowingGenericTypeFromInstanceof01.ts(13,17): error TS2345: Argument of type 'B' is not assignable to parameter of type 'A<{}>'. + Property 'a' is missing in type 'B'. ==== tests/cases/conformance/types/typeRelationships/instanceOf/narrowingGenericTypeFromInstanceof01.ts (1 errors) ==== @@ -18,9 +17,8 @@ tests/cases/conformance/types/typeRelationships/instanceOf/narrowingGenericTypeF if (x instanceof B) { acceptA(x); ~ -!!! error TS2345: Argument of type 'A | B' is not assignable to parameter of type 'A'. -!!! error TS2345: Type 'B' is not assignable to type 'A'. -!!! error TS2345: Property 'a' is missing in type 'B'. +!!! error TS2345: Argument of type 'B' is not assignable to parameter of type 'A<{}>'. +!!! error TS2345: Property 'a' is missing in type 'B'. } if (x instanceof A) { diff --git a/tests/baselines/reference/narrowingGenericTypeFromInstanceof01.types b/tests/baselines/reference/narrowingGenericTypeFromInstanceof01.types index 22d02d17ce1..964c7920a34 100644 --- a/tests/baselines/reference/narrowingGenericTypeFromInstanceof01.types +++ b/tests/baselines/reference/narrowingGenericTypeFromInstanceof01.types @@ -43,7 +43,7 @@ function test(x: A | B) { acceptA(x); >acceptA(x) : any >acceptA : (a: A) => void ->x : A | B +>x : B } if (x instanceof A) { @@ -65,7 +65,7 @@ function test(x: A | B) { acceptB(x); >acceptB(x) : void >acceptB : (b: B) => void ->x : A | B +>x : B } if (x instanceof B) { @@ -76,6 +76,6 @@ function test(x: A | B) { acceptB(x); >acceptB(x) : void >acceptB : (b: B) => void ->x : A | B +>x : B } } From 976c25c672b9f86129ad1ee549fec7f0b3f0b9fa Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Mon, 30 Oct 2017 15:05:55 -0700 Subject: [PATCH 049/235] Add support for enums and property signatures --- src/services/jsDoc.ts | 5 +- .../fourslash/docCommentTemplateInterfaces.ts | 23 --------- .../docCommentTemplateInterfacesAndEnums.ts | 50 +++++++++++++++++++ 3 files changed, 53 insertions(+), 25 deletions(-) delete mode 100644 tests/cases/fourslash/docCommentTemplateInterfaces.ts create mode 100644 tests/cases/fourslash/docCommentTemplateInterfacesAndEnums.ts diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 07db4402cbf..622463d96fa 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -259,8 +259,6 @@ namespace ts.JsDoc { } function getCommentOwnerInfo(tokenAtPos: Node): CommentOwnerInfo | undefined { // TODO: add support for: - // - enums/enum members - // - property declarations // - potentially property assignments for (let commentOwner = tokenAtPos; commentOwner; commentOwner = commentOwner.parent) { switch (commentOwner.kind) { @@ -273,6 +271,9 @@ namespace ts.JsDoc { case SyntaxKind.ClassDeclaration: case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.PropertySignature: + case SyntaxKind.EnumDeclaration: + case SyntaxKind.EnumMember: return { commentOwner }; case SyntaxKind.VariableStatement: { diff --git a/tests/cases/fourslash/docCommentTemplateInterfaces.ts b/tests/cases/fourslash/docCommentTemplateInterfaces.ts deleted file mode 100644 index 2faf49351f2..00000000000 --- a/tests/cases/fourslash/docCommentTemplateInterfaces.ts +++ /dev/null @@ -1,23 +0,0 @@ -/// - -/////*interfaceFoo*/ -////interface Foo { -//// /*propertybar*/ -//// bar: any; -//// -//// /*methodbaz*/ -//// baz(message: any): void; -////} - -verify.docCommentTemplateAt("interfaceFoo", /*expectedOffset*/ 8, -`/** - * - */`); - -verify.emptyDocCommentTemplateAt("propertybar"); - -verify.docCommentTemplateAt("methodbaz", /*expectedOffset*/ 12, - `/** - * - * @param message - */`); \ No newline at end of file diff --git a/tests/cases/fourslash/docCommentTemplateInterfacesAndEnums.ts b/tests/cases/fourslash/docCommentTemplateInterfacesAndEnums.ts new file mode 100644 index 00000000000..ed10ba86d98 --- /dev/null +++ b/tests/cases/fourslash/docCommentTemplateInterfacesAndEnums.ts @@ -0,0 +1,50 @@ +/// + +/////*interfaceFoo*/ +////interface Foo { +//// /*propertybar*/ +//// bar: any; +//// +//// /*methodbaz*/ +//// baz(message: any): void; +////} +//// +/////*enumStatus*/ +////const enum Status { +//// /*memberOpen*/ +//// Open, +//// +//// /*memberClosed*/ +//// Closed +////} + +verify.docCommentTemplateAt("interfaceFoo", /*expectedOffset*/ 8, +`/** + * + */`); + +verify.docCommentTemplateAt("propertybar", /*expectedOffset*/ 12, + `/** + * + */`); + +verify.docCommentTemplateAt("methodbaz", /*expectedOffset*/ 12, + `/** + * + * @param message + */`); + +verify.docCommentTemplateAt("enumStatus", /*expectedOffset*/ 8, +`/** + * + */`); + +verify.docCommentTemplateAt("memberOpen", /*expectedOffset*/ 12, + `/** + * + */`); + +verify.docCommentTemplateAt("memberClosed", /*expectedOffset*/ 12, + `/** + * + */`); \ No newline at end of file From 3d89837cfa01a25bcf432f1d7f0077932bb9ec11 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 30 Oct 2017 15:35:51 -0700 Subject: [PATCH 050/235] Use nominal checks in union type subtype reduction --- src/compiler/checker.ts | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 864e78aa0e9..058cff4d8b6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7431,9 +7431,12 @@ namespace ts { return false; } - function isSubtypeOfAny(candidate: Type, types: Type[]): boolean { - for (const type of types) { - if (candidate !== type && isTypeSubtypeOf(candidate, type)) { + function isSubtypeOfAny(source: Type, targets: Type[]): boolean { + for (const target of targets) { + if (source !== target && isTypeSubtypeOf(source, target) && ( + !(getObjectFlags(source) & (ObjectFlags.ClassOrInterface | ObjectFlags.Reference)) || + !(getObjectFlags(target) & (ObjectFlags.ClassOrInterface | ObjectFlags.Reference)) || + isTypeDerivedFrom(source, target))) { return true; } } @@ -8556,13 +8559,15 @@ namespace ts { return isTypeRelatedTo(source, target, assignableRelation); } - // An object type S is considered to be an instance of an object type T if - // S is a union type and every constituent of S is an instance of T, - // T is a union type and S is an instance of at least one constituent of T, or + // An object type S is considered to be derived from an object type T if + // S is a union type and every constituent of S is derived from T, + // T is a union type and S is derived from at least one constituent of T, or // T occurs directly or indirectly in an 'extends' clause of S. - function isTypeInstanceOf(source: Type, target: Type): boolean { - return source.flags & TypeFlags.Union ? every((source).types, t => isTypeInstanceOf(t, target)) : - target.flags & TypeFlags.Union ? some((target).types, t => isTypeInstanceOf(source, t)) : + // Note that this check ignores type parameters and only considers the + // inheritance hierarchy. + function isTypeDerivedFrom(source: Type, target: Type): boolean { + return source.flags & TypeFlags.Union ? every((source).types, t => isTypeDerivedFrom(t, target)) : + target.flags & TypeFlags.Union ? some((target).types, t => isTypeDerivedFrom(source, t)) : hasBaseType(source, getTargetType(target)); } @@ -12411,7 +12416,7 @@ namespace ts { } if (targetType) { - return getNarrowedType(type, targetType, assumeTrue, isTypeInstanceOf); + return getNarrowedType(type, targetType, assumeTrue, isTypeDerivedFrom); } return type; From 923e7a0614dc4dae6116508e8a86c9a7df0458fb Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 30 Oct 2017 15:36:08 -0700 Subject: [PATCH 051/235] Accept new baselines --- .../reference/arrayBestCommonTypes.types | 32 +++++++++---------- .../arrayLiteralsWithRecursiveGenerics.types | 4 +-- .../controlFlowBinaryOrExpression.symbols | 4 +-- .../controlFlowBinaryOrExpression.types | 2 +- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/tests/baselines/reference/arrayBestCommonTypes.types b/tests/baselines/reference/arrayBestCommonTypes.types index 864b1adfacb..c146a100d18 100644 --- a/tests/baselines/reference/arrayBestCommonTypes.types +++ b/tests/baselines/reference/arrayBestCommonTypes.types @@ -366,29 +366,29 @@ module EmptyTypes { >base2 : typeof base2 var b1 = [baseObj, base2Obj, ifaceObj]; ->b1 : iface[] ->[baseObj, base2Obj, ifaceObj] : iface[] +>b1 : (iface | base | base2)[] +>[baseObj, base2Obj, ifaceObj] : (iface | base | base2)[] >baseObj : base >base2Obj : base2 >ifaceObj : iface var b2 = [base2Obj, baseObj, ifaceObj]; ->b2 : iface[] ->[base2Obj, baseObj, ifaceObj] : iface[] +>b2 : (iface | base | base2)[] +>[base2Obj, baseObj, ifaceObj] : (iface | base | base2)[] >base2Obj : base2 >baseObj : base >ifaceObj : iface var b3 = [baseObj, ifaceObj, base2Obj]; ->b3 : iface[] ->[baseObj, ifaceObj, base2Obj] : iface[] +>b3 : (iface | base | base2)[] +>[baseObj, ifaceObj, base2Obj] : (iface | base | base2)[] >baseObj : base >ifaceObj : iface >base2Obj : base2 var b4 = [ifaceObj, baseObj, base2Obj]; ->b4 : iface[] ->[ifaceObj, baseObj, base2Obj] : iface[] +>b4 : (iface | base | base2)[] +>[ifaceObj, baseObj, base2Obj] : (iface | base | base2)[] >ifaceObj : iface >baseObj : base >base2Obj : base2 @@ -769,29 +769,29 @@ module NonEmptyTypes { >base2 : typeof base2 var b1 = [baseObj, base2Obj, ifaceObj]; ->b1 : iface[] ->[baseObj, base2Obj, ifaceObj] : iface[] +>b1 : (iface | base | base2)[] +>[baseObj, base2Obj, ifaceObj] : (iface | base | base2)[] >baseObj : base >base2Obj : base2 >ifaceObj : iface var b2 = [base2Obj, baseObj, ifaceObj]; ->b2 : iface[] ->[base2Obj, baseObj, ifaceObj] : iface[] +>b2 : (iface | base | base2)[] +>[base2Obj, baseObj, ifaceObj] : (iface | base | base2)[] >base2Obj : base2 >baseObj : base >ifaceObj : iface var b3 = [baseObj, ifaceObj, base2Obj]; ->b3 : iface[] ->[baseObj, ifaceObj, base2Obj] : iface[] +>b3 : (iface | base | base2)[] +>[baseObj, ifaceObj, base2Obj] : (iface | base | base2)[] >baseObj : base >ifaceObj : iface >base2Obj : base2 var b4 = [ifaceObj, baseObj, base2Obj]; ->b4 : iface[] ->[ifaceObj, baseObj, base2Obj] : iface[] +>b4 : (iface | base | base2)[] +>[ifaceObj, baseObj, base2Obj] : (iface | base | base2)[] >ifaceObj : iface >baseObj : base >base2Obj : base2 diff --git a/tests/baselines/reference/arrayLiteralsWithRecursiveGenerics.types b/tests/baselines/reference/arrayLiteralsWithRecursiveGenerics.types index 9cdbe0a0a61..75013cdef09 100644 --- a/tests/baselines/reference/arrayLiteralsWithRecursiveGenerics.types +++ b/tests/baselines/reference/arrayLiteralsWithRecursiveGenerics.types @@ -55,8 +55,8 @@ var myList: MyList; >MyList : MyList var xs = [list, myList]; // {}[] ->xs : List[] ->[list, myList] : List[] +>xs : (List | MyList)[] +>[list, myList] : (List | MyList)[] >list : List >myList : MyList diff --git a/tests/baselines/reference/controlFlowBinaryOrExpression.symbols b/tests/baselines/reference/controlFlowBinaryOrExpression.symbols index 5251973005f..e76cfbf4cab 100644 --- a/tests/baselines/reference/controlFlowBinaryOrExpression.symbols +++ b/tests/baselines/reference/controlFlowBinaryOrExpression.symbols @@ -86,8 +86,8 @@ if (isNodeList(sourceObj) || isHTMLCollection(sourceObj)) { >sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) sourceObj.length; ->sourceObj.length : Symbol(NodeList.length, Decl(controlFlowBinaryOrExpression.ts, 10, 27)) +>sourceObj.length : Symbol(length, Decl(controlFlowBinaryOrExpression.ts, 10, 27), Decl(controlFlowBinaryOrExpression.ts, 14, 33)) >sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) ->length : Symbol(NodeList.length, Decl(controlFlowBinaryOrExpression.ts, 10, 27)) +>length : Symbol(length, Decl(controlFlowBinaryOrExpression.ts, 10, 27), Decl(controlFlowBinaryOrExpression.ts, 14, 33)) } diff --git a/tests/baselines/reference/controlFlowBinaryOrExpression.types b/tests/baselines/reference/controlFlowBinaryOrExpression.types index e843844ebf1..8a3b8a6d055 100644 --- a/tests/baselines/reference/controlFlowBinaryOrExpression.types +++ b/tests/baselines/reference/controlFlowBinaryOrExpression.types @@ -106,7 +106,7 @@ if (isNodeList(sourceObj) || isHTMLCollection(sourceObj)) { sourceObj.length; >sourceObj.length : number ->sourceObj : NodeList +>sourceObj : NodeList | HTMLCollection >length : number } From 967a426fe1d175a3cbfa0211df96e020a593507e Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 30 Oct 2017 17:19:27 -0700 Subject: [PATCH 052/235] Unify deduplication, fix deferred global diagnostics --- src/compiler/checker.ts | 8 +--- src/compiler/core.ts | 41 +++++-------------- src/compiler/utilities.ts | 8 ++++ src/harness/fourslash.ts | 24 +++++++++-- .../incrementalParsingDynamicImport1.ts | 6 +-- .../incrementalParsingDynamicImport3.ts | 2 +- 6 files changed, 45 insertions(+), 44 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index abedf405cde..39abb68de70 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7345,12 +7345,8 @@ namespace ts { return type.id; } - function binarySearchTypes(types: Type[], type: Type): number { - return binarySearch(types, type, getTypeId, compareValues); - } - function containsType(types: Type[], type: Type): boolean { - return binarySearchTypes(types, type) >= 0; + return binarySearch(types, type, getTypeId, compareValues) >= 0; } // Return true if the given intersection type contains (a) more than one unit type or (b) an object @@ -7391,7 +7387,7 @@ namespace ts { if (flags & TypeFlags.Number) typeSet.containsNumber = true; if (flags & TypeFlags.StringOrNumberLiteral) typeSet.containsStringOrNumberLiteral = true; const len = typeSet.length; - const index = len && type.id > typeSet[len - 1].id ? ~len : binarySearchTypes(typeSet, type); + const index = len && type.id > typeSet[len - 1].id ? ~len : binarySearch(typeSet, type, getTypeId, compareValues); if (index < 0) { if (!(flags & TypeFlags.Object && (type).objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && containsIdenticalType(typeSet, type))) { diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 0ccb7253331..dd30b36470f 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1017,15 +1017,15 @@ namespace ts { while (low <= high) { const middle = low + ((high - low) >> 1); const midKey = keySelector(array[middle]); - - if (keyComparer(midKey, key) === 0) { - return middle; - } - else if (keyComparer(midKey, key) > 0) { - high = middle - 1; - } - else { - low = middle + 1; + switch (keyComparer(midKey, key)) { + case Comparison.LessThan: + low = middle + 1; + break; + case Comparison.EqualTo: + return middle; + case Comparison.GreaterThan: + high = middle - 1; + break; } } @@ -1852,27 +1852,8 @@ namespace ts { return text1 ? Comparison.GreaterThan : Comparison.LessThan; } - export function sortAndDeduplicateDiagnostics(diagnostics: Diagnostic[]): Diagnostic[] { - return deduplicateSortedDiagnostics(diagnostics.sort(compareDiagnostics)); - } - - export function deduplicateSortedDiagnostics(diagnostics: Diagnostic[]): Diagnostic[] { - if (diagnostics.length < 2) { - return diagnostics; - } - - const newDiagnostics = [diagnostics[0]]; - let previousDiagnostic = diagnostics[0]; - for (let i = 1; i < diagnostics.length; i++) { - const currentDiagnostic = diagnostics[i]; - const isDupe = compareDiagnostics(currentDiagnostic, previousDiagnostic) === Comparison.EqualTo; - if (!isDupe) { - newDiagnostics.push(currentDiagnostic); - previousDiagnostic = currentDiagnostic; - } - } - - return newDiagnostics; + export function sortAndDeduplicateDiagnostics(diagnostics: ReadonlyArray): Diagnostic[] { + return sortAndDeduplicate(diagnostics, compareDiagnostics); } export function normalizeSlashes(path: string): string { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 1ade3cc6374..4e55ae04d03 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2291,6 +2291,7 @@ namespace ts { let nonFileDiagnostics: Diagnostic[] = []; const fileDiagnostics = createMap(); + let hasReadNonFileDiagnostics = false; let diagnosticsModified = false; let modificationCount = 0; @@ -2320,6 +2321,12 @@ namespace ts { } } else { + // If we've already read the non-file diagnostics, do not modify the existing array. + if (hasReadNonFileDiagnostics) { + hasReadNonFileDiagnostics = false; + nonFileDiagnostics = nonFileDiagnostics.slice(); + } + diagnostics = nonFileDiagnostics; } @@ -2330,6 +2337,7 @@ namespace ts { function getGlobalDiagnostics(): Diagnostic[] { sortAndDeduplicate(); + hasReadNonFileDiagnostics = true; return nonFileDiagnostics; } diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index d88f0e0854e..7ecf783aee6 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -531,15 +531,31 @@ namespace FourSlash { } for (const { start, length, messageText, file } of errors) { - Harness.IO.log(" from: " + showPosition(file, start) + - ", to: " + showPosition(file, start + length) + + Harness.IO.log(" " + this.formatRange(file, start, length) + ", message: " + ts.flattenDiagnosticMessageText(messageText, Harness.IO.newLine()) + "\n"); } + } - function showPosition(file: ts.SourceFile, pos: number) { + private formatRange(file: ts.SourceFile, start: number, length: number) { + if (file) { + return `from: ${this.formatLineAndCharacterOfPosition(file, start)}, to: ${this.formatLineAndCharacterOfPosition(file, start + length)}`; + } + return "global"; + } + + private formatLineAndCharacterOfPosition(file: ts.SourceFile, pos: number) { + if (file) { const { line, character } = ts.getLineAndCharacterOfPosition(file, pos); return `${line}:${character}`; } + return "global"; + } + + private formatPosition(file: ts.SourceFile, pos: number) { + if (file) { + return file.fileName + "@" + pos; + } + return "global"; } public verifyNoErrors() { @@ -549,7 +565,7 @@ namespace FourSlash { if (errors.length) { this.printErrorLog(/*expectErrors*/ false, errors); const error = errors[0]; - this.raiseError(`Found an error: ${error.file.fileName}@${error.start}: ${error.messageText}`); + this.raiseError(`Found an error: ${this.formatPosition(error.file, error.start)}: ${error.messageText}`); } }); } diff --git a/tests/cases/fourslash/incrementalParsingDynamicImport1.ts b/tests/cases/fourslash/incrementalParsingDynamicImport1.ts index 0f15dcb3b1b..511f3835f5b 100644 --- a/tests/cases/fourslash/incrementalParsingDynamicImport1.ts +++ b/tests/cases/fourslash/incrementalParsingDynamicImport1.ts @@ -7,11 +7,11 @@ //// var x1 = import("./foo"); //// x1.then(foo => { -//// var s: string = foo.bar(); +//// var s: string = foo.bar(); //// }) //// /*1*/ -verify.numberOfErrorsInCurrentFile(1); +verify.numberOfErrorsInCurrentFile(2); goTo.marker("1"); edit.insert(" "); -verify.numberOfErrorsInCurrentFile(1); \ No newline at end of file +verify.numberOfErrorsInCurrentFile(2); \ No newline at end of file diff --git a/tests/cases/fourslash/incrementalParsingDynamicImport3.ts b/tests/cases/fourslash/incrementalParsingDynamicImport3.ts index b3da4c5b538..64aca403ad9 100644 --- a/tests/cases/fourslash/incrementalParsingDynamicImport3.ts +++ b/tests/cases/fourslash/incrementalParsingDynamicImport3.ts @@ -11,4 +11,4 @@ verify.numberOfErrorsInCurrentFile(0); goTo.marker("1"); edit.insert("("); -verify.numberOfErrorsInCurrentFile(2); \ No newline at end of file +verify.numberOfErrorsInCurrentFile(3); \ No newline at end of file From 1d0a9ee453c476b6f8f19041085b23e0af1c3abf Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 31 Oct 2017 10:49:08 -0700 Subject: [PATCH 053/235] PR feedback --- src/compiler/core.ts | 46 +++++++++++-------------------------- src/services/textChanges.ts | 2 +- 2 files changed, 15 insertions(+), 33 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index dd30b36470f..e2e8a0096f5 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -295,29 +295,13 @@ namespace ts { Debug.fail(); } - function containsWithoutEqualityComparer(array: ReadonlyArray, value: T) { - for (const v of array) { - if (v === value) { - return true; - } - } - return false; - } - - function containsWithEqualityComparer(array: ReadonlyArray, value: T, equalityComparer: EqualityComparer) { - for (const v of array) { - if (equalityComparer(v, value)) { - return true; - } - } - return false; - } - - export function contains(array: ReadonlyArray, value: T, equalityComparer?: EqualityComparer): boolean { + export function contains(array: ReadonlyArray, value: T, equalityComparer: EqualityComparer = equateValues): boolean { if (array) { - return equalityComparer - ? containsWithEqualityComparer(array, value, equalityComparer) - : containsWithoutEqualityComparer(array, value); + for (const v of array) { + if (equalityComparer(v, value)) { + return true; + } + } } return false; } @@ -692,8 +676,8 @@ namespace ts { /** * Deduplicates an unsorted array. * @param equalityComparer An optional `EqualityComparer` used to determine if two values are duplicates. - * @param comparer An optional `Comparer` used to sort entries before comparison. If supplied, - * results are returned in the original order found in `array`. + * @param comparer An optional `Comparer` used to sort entries before comparison, though the + * result will remain in the original order in `array`. */ export function deduplicate(array: ReadonlyArray, equalityComparer: EqualityComparer, comparer?: Comparer): T[] { return !array ? undefined : @@ -798,14 +782,14 @@ namespace ts { } /** - * Gets the relative complement of `arrayA` with respect to `b`, returning the elements that + * Gets the relative complement of `arrayA` with respect to `arrayB`, returning the elements that * are not present in `arrayA` but are present in `arrayB`. Assumes both arrays are sorted * based on the provided comparer. */ - export function relativeComplement(arrayA: T[] | undefined, arrayB: T[] | undefined, comparer: Comparer, offsetA = 0, offsetB = 0): T[] | undefined { + export function relativeComplement(arrayA: T[] | undefined, arrayB: T[] | undefined, comparer: Comparer): T[] | undefined { if (!arrayB || !arrayA || arrayB.length === 0 || arrayA.length === 0) return arrayB; const result: T[] = []; - outer: for (; offsetB < arrayB.length; offsetB++) { + outer: for (let offsetA = 0, offsetB = 0; offsetB < arrayB.length; offsetB++) { inner: for (; offsetA < arrayA.length; offsetA++) { switch (comparer(arrayB[offsetB], arrayA[offsetA])) { case Comparison.LessThan: break inner; @@ -2467,10 +2451,9 @@ namespace ts { return flatten(results); function visitDirectory(path: string, absolutePath: string, depth: number | undefined) { - const entries = getFileSystemEntries(path); - const files = sort(entries.files, comparer); + const { files, directories } = getFileSystemEntries(path); - for (const current of files) { + for (const current of sort(files, comparer)) { const name = combinePaths(path, current); const absoluteName = combinePaths(absolutePath, current); if (extensions && !fileExtensionIsOneOf(name, extensions)) continue; @@ -2493,8 +2476,7 @@ namespace ts { } } - const directories = sort(entries.directories, comparer); - for (const current of directories) { + for (const current of sort(directories, comparer)) { const name = combinePaths(path, current); const absoluteName = combinePaths(absolutePath, current); if ((!includeDirectoryRegex || includeDirectoryRegex.test(absoluteName)) && diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index f84292c5faf..bc3a8e27ef0 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -581,7 +581,7 @@ namespace ts.textChanges { return applyFormatting(nonformattedText, sourceFile, initialIndentation, delta, this.rulesProvider); } - private static normalize(changes: Change[]) { + private static normalize(changes: Change[]): Change[] { // order changes by start position const normalized = stableSort(changes, (a, b) => a.range.pos - b.range.pos); // verify that change intervals do not overlap, except possibly at end points. From 88e56f39569196bafa55cddebd884dc256ef582b Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 31 Oct 2017 11:49:52 -0700 Subject: [PATCH 054/235] Assert arrays passed to relativeComplement are sorted --- src/compiler/core.ts | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index e2e8a0096f5..3907231a525 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -789,15 +789,37 @@ namespace ts { export function relativeComplement(arrayA: T[] | undefined, arrayB: T[] | undefined, comparer: Comparer): T[] | undefined { if (!arrayB || !arrayA || arrayB.length === 0 || arrayA.length === 0) return arrayB; const result: T[] = []; - outer: for (let offsetA = 0, offsetB = 0; offsetB < arrayB.length; offsetB++) { - inner: for (; offsetA < arrayA.length; offsetA++) { + loopB: for (let offsetA = 0, offsetB = 0; offsetB < arrayB.length; offsetB++) { + if (offsetB > 0) { + // Ensure `arrayB` is properly sorted. + Debug.assertGreaterThanOrEqual(comparer(arrayB[offsetB], arrayB[offsetB - 1]), Comparison.EqualTo); + } + + loopA: for (const startA = offsetA; offsetA < arrayA.length; offsetA++) { + if (offsetA > startA) { + // Ensure `arrayA` is properly sorted. We only need to perform this check if + // `offsetA` has changed since we entered the loop. + Debug.assertGreaterThanOrEqual(comparer(arrayA[offsetA], arrayA[offsetA - 1]), Comparison.EqualTo); + } + switch (comparer(arrayB[offsetB], arrayA[offsetA])) { - case Comparison.LessThan: break inner; - case Comparison.EqualTo: continue outer; - case Comparison.GreaterThan: continue inner; + case Comparison.LessThan: + // If B is less than A, B does not exist in arrayA. Add B to the result and + // move to the next element in arrayB without changing the current position + // in arrayA. + result.push(arrayB[offsetB]); + continue loopB; + case Comparison.EqualTo: + // If B is equal to A, B exists in arrayA. Move to the next element in + // arrayB without adding B to the result or changing the current position + // in arrayA. + continue loopB; + case Comparison.GreaterThan: + // If B is greater than A, we need to keep looking for B in arrayA. Move to + // the next element in arrayA and recheck. + continue loopA; } } - result.push(arrayB[offsetB]); } return result; } From 542a060875d1913ffa2117a43abec593cba86943 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 31 Oct 2017 12:33:35 -0700 Subject: [PATCH 055/235] Remove case-insensitive UI comparisons for now --- src/compiler/core.ts | 119 ++++++++++------------------------ src/services/navigationBar.ts | 2 +- 2 files changed, 37 insertions(+), 84 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 3907231a525..093653b8fec 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1653,17 +1653,11 @@ namespace ts { /** * Creates a string comparer for use with string collation in the UI. */ - const createStringComparer = (function () { - type CachedLocale = "en-US" | undefined; + const createUIStringComparer = (function () { + let defaultComparer: Comparer | undefined; + let enUSComparer: Comparer | undefined; - interface StringComparerCache { - default?: Comparer; - "en-US"?: Comparer; - } - - let caseInsensitiveCache: StringComparerCache | undefined; - let caseSensitiveCache: StringComparerCache | undefined; - const createStringComparerNoCache = getStringComparerFactory(); + const stringComparerFactory = getStringComparerFactory(); return createStringComparer; function compareWithCallback(a: string | undefined, b: string | undefined, comparer: (a: string, b: string) => number) { @@ -1674,56 +1668,41 @@ namespace ts { return value < 0 ? Comparison.LessThan : value > 0 ? Comparison.GreaterThan : Comparison.EqualTo; } - function createIntlCollatorStringComparer(locale: string | undefined, caseInsensitive: boolean): Comparer { - // Initialize the sort collator on first use - let comparer: Comparer = (a, b) => { - // Intl.Collator.prototype.compare is bound to the collator. See NOTE in - // http://www.ecma-international.org/ecma-402/2.0/#sec-Intl.Collator.prototype.compare - comparer = new Intl.Collator(locale, { usage: "sort", sensitivity: caseInsensitive ? "accent" : "variant" }).compare; - return comparer(a, b); - }; + function createIntlCollatorStringComparer(locale: string | undefined): Comparer { + // Intl.Collator.prototype.compare is bound to the collator. See NOTE in + // http://www.ecma-international.org/ecma-402/2.0/#sec-Intl.Collator.prototype.compare + const comparer = new Intl.Collator(locale, { usage: "sort", sensitivity: "variant" }).compare; return (a, b) => compareWithCallback(a, b, comparer); } - function createLocaleCompareStringComparer(locale: string | undefined, caseInsensitive: boolean): Comparer { + function createLocaleCompareStringComparer(locale: string | undefined): Comparer { // if the locale is not the default locale (`undefined`), use the fallback comparer. - return locale !== undefined ? createFallbackStringComparer(locale, caseInsensitive) : - caseInsensitive ? (a, b) => compareWithCallback(a, b, compareCaseInsensitive) : - (a, b) => compareWithCallback(a, b, compareCaseSensitive); + if (locale !== undefined) return createFallbackStringComparer(); - function compareCaseInsensitive(a: string, b: string) { - // for case-insensitive comparisons we always map both strings to their - // upper-case form as some unicode characters do not properly round-trip to - // lowercase (such as `ẞ` (German sharp capital s)). - return compareCaseSensitive(a.toLocaleUpperCase(), b.toLocaleUpperCase()); - } + return (a, b) => compareWithCallback(a, b, compareStrings); - function compareCaseSensitive(a: string, b: string) { + function compareStrings(a: string, b: string) { return a.localeCompare(b); } } - function createFallbackStringComparer(_locale: string | undefined, caseInsensitive: boolean): Comparer { - return caseInsensitive ? (a, b) => compareWithCallback(a, b, compareCaseInsensitive) : - (a, b) => compareWithCallback(a, b, compareCaseSensitiveDictionaryOrder); + function createFallbackStringComparer(): Comparer { + // An ordinal comparison puts "A" after "b", but for the UI we want "A" before "b". + // We first sort case insensitively. So "Aaa" will come before "baa". + // Then we sort case sensitively, so "aaa" will come before "Aaa". + // + // For case insensitive comparisons we always map both strings to their + // upper-case form as some unicode characters do not properly round-trip to + // lowercase (such as `ẞ` (German sharp capital s)). + return (a, b) => compareWithCallback(a, b, compareDictionaryOrder); - function compareCaseInsensitive(a: string, b: string) { - // for case-insensitive comparisons we always map both strings to their - // upper-case form as some unicode characters do not properly round-trip to - // lowercase (such as `ẞ` (German sharp capital s)). - return compareCaseSensitive(a.toUpperCase(), b.toUpperCase()); + function compareDictionaryOrder(a: string, b: string) { + return compareStrings(a.toUpperCase(), b.toUpperCase()) || compareStrings(a, b); } - function compareCaseSensitive(a: string, b: string) { + function compareStrings(a: string, b: string) { return a < b ? Comparison.LessThan : a > b ? Comparison.GreaterThan : Comparison.EqualTo; } - - function compareCaseSensitiveDictionaryOrder(a: string, b: string) { - // An ordinal comparison puts "A" after "b", but for the UI we want "A" before "b". - // We first sort case insensitively. So "Aaa" will come before "baa". - // Then we sort case sensitively, so "aaa" will come before "Aaa". - return compareCaseInsensitive(a, b) || compareCaseSensitive(a, b); - } } function getStringComparerFactory() { @@ -1744,32 +1723,22 @@ namespace ts { return createFallbackStringComparer; } - // Hold onto common string comparers. This avoids constantly reallocating comparers during - // tests. - function createStringComparerCached(locale: CachedLocale, caseInsensitive: boolean) { - const cacheKey = locale || "default"; - const cache = caseInsensitive - ? caseInsensitiveCache || (caseInsensitiveCache = {}) - : caseSensitiveCache || (caseSensitiveCache = {}); - - let comparer = cache[cacheKey]; - if (!comparer) { - comparer = createStringComparerNoCache(locale, caseInsensitive); - cache[cacheKey] = comparer; + function createStringComparer(locale: string | undefined) { + // Hold onto common string comparers. This avoids constantly reallocating comparers during + // tests. + if (locale === undefined) { + return defaultComparer || (defaultComparer = stringComparerFactory(locale)); + } + else if (locale === "en-US") { + return enUSComparer || (enUSComparer = stringComparerFactory(locale)); + } + else { + return stringComparerFactory(locale); } - - return comparer; - } - - function createStringComparer(locale: string | undefined, caseInsensitive: boolean) { - return locale === undefined || locale === "en-US" - ? createStringComparerCached(locale as CachedLocale, caseInsensitive) - : createStringComparerNoCache(locale, caseInsensitive); } })(); let uiComparerCaseSensitive: Comparer | undefined; - let uiComparerCaseInsensitive: Comparer | undefined; let uiLocale: string | undefined; export function getUILocale() { @@ -1780,25 +1749,9 @@ namespace ts { if (uiLocale !== value) { uiLocale = value; uiComparerCaseSensitive = undefined; - uiComparerCaseInsensitive = undefined; } } - /** - * Compare two strings using the case-insensitive sort behavior of the UI locale. - * - * Ordering is not predictable between different host locales, but is best for displaying - * ordered data for UI presentation. Characters with multiple unicode representations may - * be considered equal. - * - * Case-insensitive comparisons compare strings that differ in only base characters or - * accents/diacritic marks as unequal. - */ - export function compareStringsCaseInsensitiveUI(a: string, b: string) { - const comparer = uiComparerCaseInsensitive || (uiComparerCaseInsensitive = createStringComparer(uiLocale, /*caseInsensitive*/ true)); - return comparer(a, b); - } - /** * Compare two strings in a using the case-sensitive sort behavior of the UI locale. * @@ -1810,7 +1763,7 @@ namespace ts { * accents/diacritic marks, or case as unequal. */ export function compareStringsCaseSensitiveUI(a: string, b: string) { - const comparer = uiComparerCaseSensitive || (uiComparerCaseSensitive = createStringComparer(uiLocale, /*caseInsensitive*/ false)); + const comparer = uiComparerCaseSensitive || (uiComparerCaseSensitive = createUIStringComparer(uiLocale)); return comparer(a, b); } diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 712a315bb41..7d3b8e1845a 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -367,7 +367,7 @@ namespace ts.NavigationBar { } function compareChildren(child1: NavigationBarNode, child2: NavigationBarNode) { - return compareStringsCaseInsensitiveUI(tryGetName(child1.node), tryGetName(child2.node)) + return compareStringsCaseSensitiveUI(tryGetName(child1.node), tryGetName(child2.node)) || compareValues(navigationBarNodeKind(child1), navigationBarNodeKind(child2)); } From 25af351014236059030ed4bc6b1c8aec2eee8978 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 31 Oct 2017 12:50:01 -0700 Subject: [PATCH 056/235] Nix getBestChoiceType, [] subtyping, nominal union reduction for classes --- src/compiler/checker.ts | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 058cff4d8b6..146be93c5d5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7434,8 +7434,8 @@ namespace ts { function isSubtypeOfAny(source: Type, targets: Type[]): boolean { for (const target of targets) { if (source !== target && isTypeSubtypeOf(source, target) && ( - !(getObjectFlags(source) & (ObjectFlags.ClassOrInterface | ObjectFlags.Reference)) || - !(getObjectFlags(target) & (ObjectFlags.ClassOrInterface | ObjectFlags.Reference)) || + !(getObjectFlags(getTargetType(source)) & ObjectFlags.Class) || + !(getObjectFlags(getTargetType(target)) & ObjectFlags.Class) || isTypeDerivedFrom(source, target))) { return true; } @@ -9605,7 +9605,7 @@ namespace ts { if (relation === identityRelation) { return propertiesIdenticalTo(source, target); } - const requireOptionalProperties = relation === subtypeRelation && !isObjectLiteralType(source); + const requireOptionalProperties = relation === subtypeRelation && !isObjectLiteralType(source) && !isEmptyArrayLiteralType(source); const unmatchedProperty = getUnmatchedProperty(source, target, requireOptionalProperties); if (unmatchedProperty) { if (reportErrors) { @@ -10313,6 +10313,11 @@ namespace ts { !(type.flags & TypeFlags.Nullable) && isTypeAssignableTo(type, anyReadonlyArrayType); } + function isEmptyArrayLiteralType(type: Type): boolean { + const elementType = isArrayType(type) ? (type).typeArguments[0] : undefined; + return elementType === undefinedWideningType || elementType === neverType; + } + function isTupleLikeType(type: Type): boolean { return !!getPropertyOfType(type, "0" as __String); } @@ -13878,7 +13883,6 @@ namespace ts { type.pattern = node; return type; } - const contextualType = getApparentTypeOfContextualType(node); if (contextualType && contextualTypeIsTupleLikeType(contextualType)) { const pattern = contextualType.pattern; // If array literal is contextually typed by a binding pattern or an assignment pattern, pad the resulting @@ -18066,14 +18070,6 @@ namespace ts { return (target.flags & TypeFlags.Nullable) !== 0 || isTypeComparableTo(source, target); } - function getBestChoiceType(type1: Type, type2: Type): Type { - const firstAssignableToSecond = isTypeAssignableTo(type1, type2); - const secondAssignableToFirst = isTypeAssignableTo(type2, type1); - return secondAssignableToFirst && !firstAssignableToSecond ? type1 : - firstAssignableToSecond && !secondAssignableToFirst ? type2 : - getUnionType([type1, type2], /*subtypeReduction*/ true); - } - function checkBinaryExpression(node: BinaryExpression, checkMode?: CheckMode) { return checkBinaryLikeExpression(node.left, node.operatorToken, node.right, checkMode, node); } @@ -18210,7 +18206,7 @@ namespace ts { leftType; case SyntaxKind.BarBarToken: return getTypeFacts(leftType) & TypeFacts.Falsy ? - getBestChoiceType(removeDefinitelyFalsyTypes(leftType), rightType) : + getUnionType([removeDefinitelyFalsyTypes(leftType), rightType], /*subtypeReduction*/ true) : leftType; case SyntaxKind.EqualsToken: checkAssignmentOperator(rightType); @@ -18370,7 +18366,7 @@ namespace ts { checkExpression(node.condition); const type1 = checkExpression(node.whenTrue, checkMode); const type2 = checkExpression(node.whenFalse, checkMode); - return getBestChoiceType(type1, type2); + return getUnionType([type1, type2], /*subtypeReduction*/ true); } function checkTemplateExpression(node: TemplateExpression): Type { From 7f35c8fd07c10b7e964e82b4536b5fdc85be4e73 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 31 Oct 2017 13:00:30 -0700 Subject: [PATCH 057/235] Add type annotation --- src/compiler/factory.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 65c1c92f366..de744ca3f00 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -2625,7 +2625,7 @@ namespace ts { /** * Gets a custom text range to use when emitting source maps. */ - export function getSourceMapRange(node: Node) { + export function getSourceMapRange(node: Node): SourceMapRange { const emitNode = node.emitNode; return (emitNode && emitNode.sourceMapRange) || node; } From 412f3735bc03a149dce28da1173ee2b5f8fa70cf Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 31 Oct 2017 13:00:38 -0700 Subject: [PATCH 058/235] Accept new baselines --- .../reference/arrayBestCommonTypes.types | 32 +++++++++---------- .../controlFlowBinaryOrExpression.symbols | 4 +-- .../controlFlowBinaryOrExpression.types | 2 +- .../reference/fixSignatureCaching.types | 4 +-- .../nonContextuallyTypedLogicalOr.symbols | 4 +-- .../nonContextuallyTypedLogicalOr.types | 4 +-- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/tests/baselines/reference/arrayBestCommonTypes.types b/tests/baselines/reference/arrayBestCommonTypes.types index c146a100d18..864b1adfacb 100644 --- a/tests/baselines/reference/arrayBestCommonTypes.types +++ b/tests/baselines/reference/arrayBestCommonTypes.types @@ -366,29 +366,29 @@ module EmptyTypes { >base2 : typeof base2 var b1 = [baseObj, base2Obj, ifaceObj]; ->b1 : (iface | base | base2)[] ->[baseObj, base2Obj, ifaceObj] : (iface | base | base2)[] +>b1 : iface[] +>[baseObj, base2Obj, ifaceObj] : iface[] >baseObj : base >base2Obj : base2 >ifaceObj : iface var b2 = [base2Obj, baseObj, ifaceObj]; ->b2 : (iface | base | base2)[] ->[base2Obj, baseObj, ifaceObj] : (iface | base | base2)[] +>b2 : iface[] +>[base2Obj, baseObj, ifaceObj] : iface[] >base2Obj : base2 >baseObj : base >ifaceObj : iface var b3 = [baseObj, ifaceObj, base2Obj]; ->b3 : (iface | base | base2)[] ->[baseObj, ifaceObj, base2Obj] : (iface | base | base2)[] +>b3 : iface[] +>[baseObj, ifaceObj, base2Obj] : iface[] >baseObj : base >ifaceObj : iface >base2Obj : base2 var b4 = [ifaceObj, baseObj, base2Obj]; ->b4 : (iface | base | base2)[] ->[ifaceObj, baseObj, base2Obj] : (iface | base | base2)[] +>b4 : iface[] +>[ifaceObj, baseObj, base2Obj] : iface[] >ifaceObj : iface >baseObj : base >base2Obj : base2 @@ -769,29 +769,29 @@ module NonEmptyTypes { >base2 : typeof base2 var b1 = [baseObj, base2Obj, ifaceObj]; ->b1 : (iface | base | base2)[] ->[baseObj, base2Obj, ifaceObj] : (iface | base | base2)[] +>b1 : iface[] +>[baseObj, base2Obj, ifaceObj] : iface[] >baseObj : base >base2Obj : base2 >ifaceObj : iface var b2 = [base2Obj, baseObj, ifaceObj]; ->b2 : (iface | base | base2)[] ->[base2Obj, baseObj, ifaceObj] : (iface | base | base2)[] +>b2 : iface[] +>[base2Obj, baseObj, ifaceObj] : iface[] >base2Obj : base2 >baseObj : base >ifaceObj : iface var b3 = [baseObj, ifaceObj, base2Obj]; ->b3 : (iface | base | base2)[] ->[baseObj, ifaceObj, base2Obj] : (iface | base | base2)[] +>b3 : iface[] +>[baseObj, ifaceObj, base2Obj] : iface[] >baseObj : base >ifaceObj : iface >base2Obj : base2 var b4 = [ifaceObj, baseObj, base2Obj]; ->b4 : (iface | base | base2)[] ->[ifaceObj, baseObj, base2Obj] : (iface | base | base2)[] +>b4 : iface[] +>[ifaceObj, baseObj, base2Obj] : iface[] >ifaceObj : iface >baseObj : base >base2Obj : base2 diff --git a/tests/baselines/reference/controlFlowBinaryOrExpression.symbols b/tests/baselines/reference/controlFlowBinaryOrExpression.symbols index e76cfbf4cab..5251973005f 100644 --- a/tests/baselines/reference/controlFlowBinaryOrExpression.symbols +++ b/tests/baselines/reference/controlFlowBinaryOrExpression.symbols @@ -86,8 +86,8 @@ if (isNodeList(sourceObj) || isHTMLCollection(sourceObj)) { >sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) sourceObj.length; ->sourceObj.length : Symbol(length, Decl(controlFlowBinaryOrExpression.ts, 10, 27), Decl(controlFlowBinaryOrExpression.ts, 14, 33)) +>sourceObj.length : Symbol(NodeList.length, Decl(controlFlowBinaryOrExpression.ts, 10, 27)) >sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) ->length : Symbol(length, Decl(controlFlowBinaryOrExpression.ts, 10, 27), Decl(controlFlowBinaryOrExpression.ts, 14, 33)) +>length : Symbol(NodeList.length, Decl(controlFlowBinaryOrExpression.ts, 10, 27)) } diff --git a/tests/baselines/reference/controlFlowBinaryOrExpression.types b/tests/baselines/reference/controlFlowBinaryOrExpression.types index 8a3b8a6d055..e843844ebf1 100644 --- a/tests/baselines/reference/controlFlowBinaryOrExpression.types +++ b/tests/baselines/reference/controlFlowBinaryOrExpression.types @@ -106,7 +106,7 @@ if (isNodeList(sourceObj) || isHTMLCollection(sourceObj)) { sourceObj.length; >sourceObj.length : number ->sourceObj : NodeList | HTMLCollection +>sourceObj : NodeList >length : number } diff --git a/tests/baselines/reference/fixSignatureCaching.types b/tests/baselines/reference/fixSignatureCaching.types index 6f87f563707..781912544e2 100644 --- a/tests/baselines/reference/fixSignatureCaching.types +++ b/tests/baselines/reference/fixSignatureCaching.types @@ -866,9 +866,9 @@ define(function () { >'UnknownMobile' : "UnknownMobile" isArray = ('isArray' in Array) ? ->isArray = ('isArray' in Array) ? Array.isArray : function (value) { return Object.prototype.toString.call(value) === '[object Array]'; } : (value: any) => boolean +>isArray = ('isArray' in Array) ? Array.isArray : function (value) { return Object.prototype.toString.call(value) === '[object Array]'; } : (arg: any) => arg is any[] >isArray : any ->('isArray' in Array) ? Array.isArray : function (value) { return Object.prototype.toString.call(value) === '[object Array]'; } : (value: any) => boolean +>('isArray' in Array) ? Array.isArray : function (value) { return Object.prototype.toString.call(value) === '[object Array]'; } : (arg: any) => arg is any[] >('isArray' in Array) : boolean >'isArray' in Array : boolean >'isArray' : "isArray" diff --git a/tests/baselines/reference/nonContextuallyTypedLogicalOr.symbols b/tests/baselines/reference/nonContextuallyTypedLogicalOr.symbols index 43d7539b6b9..2d921f6631c 100644 --- a/tests/baselines/reference/nonContextuallyTypedLogicalOr.symbols +++ b/tests/baselines/reference/nonContextuallyTypedLogicalOr.symbols @@ -28,8 +28,8 @@ var e: Ellement; >Ellement : Symbol(Ellement, Decl(nonContextuallyTypedLogicalOr.ts, 3, 1)) (c || e).dummy; ->(c || e).dummy : Symbol(Contextual.dummy, Decl(nonContextuallyTypedLogicalOr.ts, 0, 22)) +>(c || e).dummy : Symbol(dummy, Decl(nonContextuallyTypedLogicalOr.ts, 0, 22), Decl(nonContextuallyTypedLogicalOr.ts, 5, 20)) >c : Symbol(c, Decl(nonContextuallyTypedLogicalOr.ts, 10, 3)) >e : Symbol(e, Decl(nonContextuallyTypedLogicalOr.ts, 11, 3)) ->dummy : Symbol(Contextual.dummy, Decl(nonContextuallyTypedLogicalOr.ts, 0, 22)) +>dummy : Symbol(dummy, Decl(nonContextuallyTypedLogicalOr.ts, 0, 22), Decl(nonContextuallyTypedLogicalOr.ts, 5, 20)) diff --git a/tests/baselines/reference/nonContextuallyTypedLogicalOr.types b/tests/baselines/reference/nonContextuallyTypedLogicalOr.types index 5061ad1d975..aeb9d1409c6 100644 --- a/tests/baselines/reference/nonContextuallyTypedLogicalOr.types +++ b/tests/baselines/reference/nonContextuallyTypedLogicalOr.types @@ -29,8 +29,8 @@ var e: Ellement; (c || e).dummy; >(c || e).dummy : any ->(c || e) : Contextual ->c || e : Contextual +>(c || e) : Contextual | Ellement +>c || e : Contextual | Ellement >c : Contextual >e : Ellement >dummy : any From f962aba24abe1d04c36551c193bcd12b0e0161b5 Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Mon, 30 Oct 2017 16:44:44 -0700 Subject: [PATCH 059/235] Indent all lines of single JsxText node --- src/services/formatting/formatting.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 3808cb78940..18f463b9fad 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -714,6 +714,11 @@ namespace ts.formatting { processNode(child, childContextNode, childStartLine, undecoratedChildStartLine, childIndentation.indentation, childIndentation.delta); + if (child.kind === SyntaxKind.JsxText) { + const range = { pos: child.getStart(), end: child.getEnd() }; + indentMultilineCommentOrJsxText(range, childIndentation.indentation, /*firstLineIsIndented*/ true, /*indentFinalLine*/ false); + } + childContextNode = node; if (isFirstListItem && parent.kind === SyntaxKind.ArrayLiteralExpression && inheritedIndentation === Constants.Unknown) { @@ -833,7 +838,7 @@ namespace ts.formatting { switch (triviaItem.kind) { case SyntaxKind.MultiLineCommentTrivia: if (triviaInRange) { - indentMultilineComment(triviaItem, commentIndentation, /*firstLineIsIndented*/ !indentNextTokenOrTrivia); + indentMultilineCommentOrJsxText(triviaItem, commentIndentation, /*firstLineIsIndented*/ !indentNextTokenOrTrivia); } indentNextTokenOrTrivia = false; break; @@ -985,7 +990,7 @@ namespace ts.formatting { return indentationString !== sourceFile.text.substr(startLinePosition, indentationString.length); } - function indentMultilineComment(commentRange: TextRange, indentation: number, firstLineIsIndented: boolean) { + function indentMultilineCommentOrJsxText(commentRange: TextRange, indentation: number, firstLineIsIndented: boolean, indentFinalLine = true) { // split comment in lines let startLine = sourceFile.getLineAndCharacterOfPosition(commentRange.pos).line; const endLine = sourceFile.getLineAndCharacterOfPosition(commentRange.end).line; @@ -1006,7 +1011,9 @@ namespace ts.formatting { startPos = getStartPositionOfLine(line + 1, sourceFile); } - parts.push({ pos: startPos, end: commentRange.end }); + if (indentFinalLine) { + parts.push({ pos: startPos, end: commentRange.end }); + } } const startLinePos = getStartPositionOfLine(startLine, sourceFile); From 9b9032f8c55f87ad3f47f93bb25e4d0b0bc2538d Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Mon, 30 Oct 2017 17:09:20 -0700 Subject: [PATCH 060/235] Add JSXText indentation test --- tests/cases/fourslash/indentationInJsx3.ts | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 tests/cases/fourslash/indentationInJsx3.ts diff --git a/tests/cases/fourslash/indentationInJsx3.ts b/tests/cases/fourslash/indentationInJsx3.ts new file mode 100644 index 00000000000..3c75356a12f --- /dev/null +++ b/tests/cases/fourslash/indentationInJsx3.ts @@ -0,0 +1,31 @@ +/// + +//@Filename: file.tsx +////function foo () { +//// return ( +////
+////hello +////goodbye +////
+//// ) +////} + +goTo.position(21); +verify.textAtCaretIs("return"); +goTo.position(38); +verify.textAtCaretIs("
"); +goTo.position(44); +verify.textAtCaretIs("hello"); +goTo.position(50); +verify.textAtCaretIs("goodbye"); + +format.document(); + +goTo.position(21); +verify.textAtCaretIs("return"); +goTo.position(38); +verify.textAtCaretIs("
"); +goTo.position(56); +verify.textAtCaretIs("hello"); +goTo.position(74); +verify.textAtCaretIs("goodbye"); \ No newline at end of file From deb94886fd5e64251c368620f8bf41f4603a5ed8 Mon Sep 17 00:00:00 2001 From: "wenlu.wang" <805037171@163.com> Date: Tue, 31 Oct 2017 16:10:38 -0500 Subject: [PATCH 061/235] fix completion module path (#19351)(#19367) (#19366) * completion module path with re-export(#19351) * completion module path with dynamic import(#19367) --- src/services/completions.ts | 6 ++- .../completionForStringLiteralExport.ts | 37 +++++++++++++++++++ ...letionForStringLiteralWithDynamicImport.ts | 33 +++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/completionForStringLiteralExport.ts create mode 100644 tests/cases/fourslash/completionForStringLiteralWithDynamicImport.ts diff --git a/src/services/completions.ts b/src/services/completions.ts index f1e7fac2a4e..f4feb8a1c10 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -241,11 +241,15 @@ namespace ts.Completions { // a['/*completion position*/'] return getStringLiteralCompletionEntriesFromElementAccess(node.parent, typeChecker, compilerOptions.target, log); } - else if (node.parent.kind === SyntaxKind.ImportDeclaration || isExpressionOfExternalModuleImportEqualsDeclaration(node) || isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false)) { + else if (node.parent.kind === SyntaxKind.ImportDeclaration || node.parent.kind === SyntaxKind.ExportDeclaration + || isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false) || isImportCall(node.parent) + || isExpressionOfExternalModuleImportEqualsDeclaration(node)) { // Get all known external module names or complete a path to a module // i.e. import * as ns from "/*completion position*/"; + // var y = import("/*completion position*/"); // import x = require("/*completion position*/"); // var y = require("/*completion position*/"); + // export * from "/*completion position*/"; return PathCompletions.getStringLiteralCompletionEntriesFromModuleNames(node, compilerOptions, host, typeChecker); } else if (isEqualityExpression(node.parent)) { diff --git a/tests/cases/fourslash/completionForStringLiteralExport.ts b/tests/cases/fourslash/completionForStringLiteralExport.ts new file mode 100644 index 00000000000..649148bb15d --- /dev/null +++ b/tests/cases/fourslash/completionForStringLiteralExport.ts @@ -0,0 +1,37 @@ +/// + +// Should define spans for replacement that appear after the last directory seperator in export statements + +// @typeRoots: my_typings + +// @Filename: test.ts +//// export * from "./some/*0*/ +//// export * from "./sub/some/*1*/"; +//// export * from "some-/*2*/"; +//// export * from "..//*3*/"; +//// export {} from ".//*4*/"; + + +// @Filename: someFile1.ts +//// /*someFile1*/ + +// @Filename: sub/someFile2.ts +//// /*someFile2*/ + +// @Filename: my_typings/some-module/index.d.ts +//// export var x = 9; + +goTo.marker("0"); +verify.completionListContains("someFile1"); + +goTo.marker("1"); +verify.completionListContains("someFile2"); + +goTo.marker("2"); +verify.completionListContains("some-module"); + +goTo.marker("3"); +verify.completionListContains("fourslash"); + +goTo.marker("4"); +verify.completionListContains("someFile1"); diff --git a/tests/cases/fourslash/completionForStringLiteralWithDynamicImport.ts b/tests/cases/fourslash/completionForStringLiteralWithDynamicImport.ts new file mode 100644 index 00000000000..8e823991c0b --- /dev/null +++ b/tests/cases/fourslash/completionForStringLiteralWithDynamicImport.ts @@ -0,0 +1,33 @@ +/// + +// Should define spans for replacement that appear after the last directory seperator in dynamic import statements + +// @typeRoots: my_typings + +// @Filename: test.ts +//// const a = import("./some/*0*/ +//// const a = import("./sub/some/*1*/"); +//// const a = import("some-/*2*/"); +//// const a = import("..//*3*/"); + + +// @Filename: someFile1.ts +//// /*someFile1*/ + +// @Filename: sub/someFile2.ts +//// /*someFile2*/ + +// @Filename: my_typings/some-module/index.d.ts +//// export var x = 9; + +goTo.marker("0"); +verify.completionListContains("someFile1"); + +goTo.marker("1"); +verify.completionListContains("someFile2"); + +goTo.marker("2"); +verify.completionListContains("some-module"); + +goTo.marker("3"); +verify.completionListContains("fourslash"); From b6ea2f955a90f7e2e45278af040dceb452d7b0e5 Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Tue, 31 Oct 2017 14:52:15 -0700 Subject: [PATCH 062/235] Refactor test and annotate object literal --- src/services/formatting/formatting.ts | 2 +- tests/cases/fourslash/indentationInJsx3.ts | 28 ++++++++-------------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 18f463b9fad..fdd70cda461 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -715,7 +715,7 @@ namespace ts.formatting { processNode(child, childContextNode, childStartLine, undecoratedChildStartLine, childIndentation.indentation, childIndentation.delta); if (child.kind === SyntaxKind.JsxText) { - const range = { pos: child.getStart(), end: child.getEnd() }; + const range: TextRange = { pos: child.getStart(), end: child.getEnd() }; indentMultilineCommentOrJsxText(range, childIndentation.indentation, /*firstLineIsIndented*/ true, /*indentFinalLine*/ false); } diff --git a/tests/cases/fourslash/indentationInJsx3.ts b/tests/cases/fourslash/indentationInJsx3.ts index 3c75356a12f..1c93cbc24bd 100644 --- a/tests/cases/fourslash/indentationInJsx3.ts +++ b/tests/cases/fourslash/indentationInJsx3.ts @@ -4,28 +4,20 @@ ////function foo () { //// return ( ////
-////hello -////goodbye +/////*0*/hello +/////*1*/goodbye ////
//// ) ////} -goTo.position(21); -verify.textAtCaretIs("return"); -goTo.position(38); -verify.textAtCaretIs("
"); -goTo.position(44); -verify.textAtCaretIs("hello"); -goTo.position(50); -verify.textAtCaretIs("goodbye"); +goTo.marker('0'); +verify.currentLineContentIs("hello"); +goTo.marker('1'); +verify.currentLineContentIs("goodbye"); format.document(); -goTo.position(21); -verify.textAtCaretIs("return"); -goTo.position(38); -verify.textAtCaretIs("
"); -goTo.position(56); -verify.textAtCaretIs("hello"); -goTo.position(74); -verify.textAtCaretIs("goodbye"); \ No newline at end of file +goTo.marker('0'); +verify.currentLineContentIs(" hello"); +goTo.marker('1'); +verify.currentLineContentIs(" goodbye"); \ No newline at end of file From 7985e6636f605d5292dd07bd6abd140eb6a2547a Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 31 Oct 2017 15:37:25 -0700 Subject: [PATCH 063/235] Drop node 4, add node 8 for CI (#19617) --- .travis.yml | 2 +- netci.groovy | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d24e155b580..06e912c55f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,8 @@ language: node_js node_js: - 'stable' + - '8' - '6' - - '4' sudo: false diff --git a/netci.groovy b/netci.groovy index fc6d00e4e7f..5fa8b02baf2 100644 --- a/netci.groovy +++ b/netci.groovy @@ -5,7 +5,7 @@ import jobs.generation.Utilities; def project = GithubProject def branch = GithubBranchName -def nodeVersions = ['stable', '6', '4'] +def nodeVersions = ['stable', '8', '6'] nodeVersions.each { nodeVer -> From 20e1f5258b552f62ece82915aa0cef3a92fe90b4 Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Tue, 31 Oct 2017 16:09:30 -0700 Subject: [PATCH 064/235] Update test --- tests/cases/fourslash/indentationInJsx3.ts | 30 +++++++++++++++------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/tests/cases/fourslash/indentationInJsx3.ts b/tests/cases/fourslash/indentationInJsx3.ts index 1c93cbc24bd..b5d5e772213 100644 --- a/tests/cases/fourslash/indentationInJsx3.ts +++ b/tests/cases/fourslash/indentationInJsx3.ts @@ -1,7 +1,7 @@ /// //@Filename: file.tsx -////function foo () { +////function foo() { //// return ( ////
/////*0*/hello @@ -10,14 +10,26 @@ //// ) ////} -goTo.marker('0'); -verify.currentLineContentIs("hello"); -goTo.marker('1'); -verify.currentLineContentIs("goodbye"); +verify.currentFileContentIs( +`function foo() { + return ( +
+hello +goodbye +
+ ) +}` +); format.document(); -goTo.marker('0'); -verify.currentLineContentIs(" hello"); -goTo.marker('1'); -verify.currentLineContentIs(" goodbye"); \ No newline at end of file +verify.currentFileContentIs( +`function foo() { + return ( +
+ hello + goodbye +
+ ) +}` +); \ No newline at end of file From 9f68ff5b0f700084cd02dfe93db56438dfc58bb5 Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Tue, 31 Oct 2017 16:10:17 -0700 Subject: [PATCH 065/235] Remove markers --- tests/cases/fourslash/indentationInJsx3.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cases/fourslash/indentationInJsx3.ts b/tests/cases/fourslash/indentationInJsx3.ts index b5d5e772213..0c57b3b31e4 100644 --- a/tests/cases/fourslash/indentationInJsx3.ts +++ b/tests/cases/fourslash/indentationInJsx3.ts @@ -4,8 +4,8 @@ ////function foo() { //// return ( ////
-/////*0*/hello -/////*1*/goodbye +////hello +////goodbye ////
//// ) ////} From 53ad019ba1c5ced4c0333f19fcd69bd31c07aa85 Mon Sep 17 00:00:00 2001 From: Homa Wong Date: Tue, 31 Oct 2017 16:33:43 -0700 Subject: [PATCH 066/235] Log top 5 largest files when TS language service is disabling. (#19315) * Log top 5 largest files * Show same message on second pass. This second pass seemingly should be avoid. Bug there. * Get all files and sort when error. * Refactor * Push logic to error branch * Update to use array chain. * Update to return string * going functional. --- src/server/editorServices.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index b7617e1fa17..35f888ebc7d 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1373,24 +1373,42 @@ namespace ts.server { this.projectToSizeMap.forEach(val => (availableSpace -= (val || 0))); let totalNonTsFileSize = 0; + for (const f of fileNames) { const fileName = propertyReader.getFileName(f); if (hasTypeScriptFileExtension(fileName)) { continue; } + totalNonTsFileSize += this.host.getFileSize(fileName); + if (totalNonTsFileSize > maxProgramSizeForNonTsFiles) { + this.logger.info(getExceedLimitMessage({ propertyReader, hasTypeScriptFileExtension, host: this.host }, totalNonTsFileSize)); // Keep the size as zero since it's disabled return true; } } if (totalNonTsFileSize > availableSpace) { + this.logger.info(getExceedLimitMessage({ propertyReader, hasTypeScriptFileExtension, host: this.host }, totalNonTsFileSize)); return true; } this.projectToSizeMap.set(name, totalNonTsFileSize); return false; + + function getExceedLimitMessage(context: { propertyReader: FilePropertyReader, hasTypeScriptFileExtension: (filename: string) => boolean, host: ServerHost }, totalNonTsFileSize: number) { + const files = getTop5LargestFiles(context); + + return `Non TS file size exceeded limit (${totalNonTsFileSize}). Largest files: ${files.map(file => `${file.name}:${file.size}`).join(", ")}`; + } + function getTop5LargestFiles({ propertyReader, hasTypeScriptFileExtension, host }: { propertyReader: FilePropertyReader, hasTypeScriptFileExtension: (filename: string) => boolean, host: ServerHost }) { + return fileNames.map(f => propertyReader.getFileName(f)) + .filter(name => hasTypeScriptFileExtension(name)) + .map(name => ({ name, size: host.getFileSize(name) })) + .sort((a, b) => b.size - a.size) + .slice(0, 5); + } } private createExternalProject(projectFileName: string, files: protocol.ExternalFile[], options: protocol.ExternalProjectCompilerOptions, typeAcquisition: TypeAcquisition) { From 5dc02ef5ccf267c0f4a07f4571d0b8d603a9eefa Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 31 Oct 2017 18:38:00 -0700 Subject: [PATCH 067/235] Use a different RegEx --- src/compiler/core.ts | 8 ++++++- .../unittests/tsserverProjectSystem.ts | 22 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index c9b644b22ce..626480035b1 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2417,7 +2417,13 @@ namespace ts { * Takes a string like "jquery-min.4.2.3" and returns "jquery" */ export function removeMinAndVersionNumbers(fileName: string) { - return fileName.replace(/((?:\.|-)min(?=\.|$))|((?:-|\.)\d+)/g, ""); + const match = /((\w|(-(?!min)))+)(\.|-)?.*/.exec(fileName); + if (match) { + return match[1]; + } + else { + return fileName; + } } export interface ObjectAllocator { diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index fb2bbec6741..c72a27e173e 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -1496,6 +1496,28 @@ namespace ts.projectSystem { } }); + it("removes version numbers correctly", () => { + const testData: [string, string][] = [ + ["jquery-max", "jquery-max"], + ["jquery.min", "jquery"], + ["jquery-min.4.2.3", "jquery"], + ["jquery.4.2-test.js", "jquery"], + ["jquery.min.4.2.1", "jquery"], + ["jquery.7.min.js", "jquery"], + ["jquery.7.min-beta", "jquery"], + ["minimum", "minimum"], + ["min", "min"], + ["min.3.2", "min"], + ["jquery", "jquery"] + ]; + const suffixes = [".js", ".jsx", ""]; + for (const t of testData) { + for (const suf of suffixes) { + assert.equal(removeMinAndVersionNumbers(t[0] + suf), t[1]); + } + } + }); + it("ignores files excluded by a legacy safe type list", () => { const file1 = { path: "/a/b/bliss.js", From 81326ac90178a5a481412dab32fc458cb45be4e5 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 1 Nov 2017 09:16:16 -0700 Subject: [PATCH 068/235] Properly handle Object and Function types --- src/compiler/checker.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9cd21263b8d..1fd70a22b67 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8571,14 +8571,16 @@ namespace ts { // An object type S is considered to be derived from an object type T if // S is a union type and every constituent of S is derived from T, // T is a union type and S is derived from at least one constituent of T, or + // T is one of the global types Object and Function and S is a subtype of T, or // T occurs directly or indirectly in an 'extends' clause of S. // Note that this check ignores type parameters and only considers the // inheritance hierarchy. function isTypeDerivedFrom(source: Type, target: Type): boolean { return source.flags & TypeFlags.Union ? every((source).types, t => isTypeDerivedFrom(t, target)) : target.flags & TypeFlags.Union ? some((target).types, t => isTypeDerivedFrom(source, t)) : + target === globalObjectType || target === globalFunctionType ? isTypeSubtypeOf(source, target) : hasBaseType(source, getTargetType(target)); - } + } /** * This is *not* a bi-directional relationship. From a6a5b85b522b89d061aaf0baaaaf39103ba0c346 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 1 Nov 2017 10:33:24 -0700 Subject: [PATCH 069/235] Switch from undefined guard to asserts In both fixSpelling and getSuggestionForNonexistentSymbol --- src/compiler/checker.ts | 9 +++------ src/services/codefixes/fixSpelling.ts | 4 +++- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 738a484d254..b28ecb082a1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15062,12 +15062,9 @@ namespace ts { return suggestion && symbolName(suggestion); } - function getSuggestionForNonexistentSymbol(location: Node, name: __String, meaning: SymbolFlags): string { - const result = resolveNameHelper(location, name, meaning, /*nameNotFoundMessage*/ undefined, name, /*isUse*/ false, (symbols, name, meaning) => { - // NOTE: `name` from the callback is supposed to === the outer `name`, but is undefined in some cases - if (name === undefined) { - return undefined; - } + function getSuggestionForNonexistentSymbol(location: Node, outerName: __String, meaning: SymbolFlags): string { + const result = resolveNameHelper(location, outerName, meaning, /*nameNotFoundMessage*/ undefined, outerName, /*isUse*/ false, (symbols, name, meaning) => { + Debug.assert(name !== undefined, "name should always be defined, and equal to " + outerName); const symbol = getSymbol(symbols, name, meaning); // Sometimes the symbol is found when location is a return type of a function: `typeof x` and `x` is declared in the body of the function // So the table *contains* `x` but `x` isn't actually in scope. diff --git a/src/services/codefixes/fixSpelling.ts b/src/services/codefixes/fixSpelling.ts index ff3bd455291..e5c15ade5a2 100644 --- a/src/services/codefixes/fixSpelling.ts +++ b/src/services/codefixes/fixSpelling.ts @@ -22,7 +22,9 @@ namespace ts.codefix { } else { const meaning = getMeaningFromLocation(node); - suggestion = checker.getSuggestionForNonexistentSymbol(node, getTextOfNode(node), convertSemanticMeaningToSymbolFlags(meaning)); + const name = getTextOfNode(node); + Debug.assert(!!name, "name should be defined"); + suggestion = checker.getSuggestionForNonexistentSymbol(node, name, convertSemanticMeaningToSymbolFlags(meaning)); } if (suggestion) { return [{ From 146addc4d54b4146da359e69d643ea85f39abb55 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 1 Nov 2017 10:35:54 -0700 Subject: [PATCH 070/235] Use explicit undefined checkk --- src/services/codefixes/fixSpelling.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/codefixes/fixSpelling.ts b/src/services/codefixes/fixSpelling.ts index e5c15ade5a2..2546a92a32f 100644 --- a/src/services/codefixes/fixSpelling.ts +++ b/src/services/codefixes/fixSpelling.ts @@ -23,7 +23,7 @@ namespace ts.codefix { else { const meaning = getMeaningFromLocation(node); const name = getTextOfNode(node); - Debug.assert(!!name, "name should be defined"); + Debug.assert(name !== undefined, "name should be defined"); suggestion = checker.getSuggestionForNonexistentSymbol(node, name, convertSemanticMeaningToSymbolFlags(meaning)); } if (suggestion) { From 5d7e87a9c21df96a31925b3bafab2e0267ffe02a Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 1 Nov 2017 11:52:52 -0700 Subject: [PATCH 071/235] Add "strictTuples" to list of strict flags --- src/compiler/core.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 23493b3087d..eed627079b9 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1684,7 +1684,7 @@ namespace ts { return moduleResolution; } - export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "alwaysStrict"; + export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "strictTuples" | "alwaysStrict"; export function getStrictOptionValue(compilerOptions: CompilerOptions, flag: StrictOptionName): boolean { return compilerOptions[flag] === undefined ? compilerOptions.strict : compilerOptions[flag]; From defd32f01580fb85a72593efd15089f98c444c71 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 1 Nov 2017 11:38:14 -0700 Subject: [PATCH 072/235] Move strict tuple test and add a couple of cases --- .../reference/strictTupleLength.errors.txt | 37 +++++++++++ .../{tupleLength.js => strictTupleLength.js} | 17 +++-- .../reference/strictTupleLength.symbols | 66 +++++++++++++++++++ ...leLength.types => strictTupleLength.types} | 23 ++++++- .../reference/tupleLength.errors.txt | 26 -------- tests/baselines/reference/tupleLength.symbols | 51 -------------- .../types/tuple/strictTupleLength.ts} | 7 +- 7 files changed, 139 insertions(+), 88 deletions(-) create mode 100644 tests/baselines/reference/strictTupleLength.errors.txt rename tests/baselines/reference/{tupleLength.js => strictTupleLength.js} (58%) create mode 100644 tests/baselines/reference/strictTupleLength.symbols rename tests/baselines/reference/{tupleLength.types => strictTupleLength.types} (61%) delete mode 100644 tests/baselines/reference/tupleLength.errors.txt delete mode 100644 tests/baselines/reference/tupleLength.symbols rename tests/cases/{compiler/tupleLength.ts => conformance/types/tuple/strictTupleLength.ts} (70%) diff --git a/tests/baselines/reference/strictTupleLength.errors.txt b/tests/baselines/reference/strictTupleLength.errors.txt new file mode 100644 index 00000000000..c31064f6b6b --- /dev/null +++ b/tests/baselines/reference/strictTupleLength.errors.txt @@ -0,0 +1,37 @@ +tests/cases/conformance/types/tuple/strictTupleLength.ts(1,9): error TS1122: A tuple type element list cannot be empty. +tests/cases/conformance/types/tuple/strictTupleLength.ts(11,5): error TS2403: Subsequent variable declarations must have the same type. Variable 't1' has type '[number]' at tests/cases/conformance/types/tuple/strictTupleLength.ts 1:4, but here has type '[number, number]'. +tests/cases/conformance/types/tuple/strictTupleLength.ts(12,5): error TS2403: Subsequent variable declarations must have the same type. Variable 't2' has type '[number, number]' at tests/cases/conformance/types/tuple/strictTupleLength.ts 2:4, but here has type '[number]'. +tests/cases/conformance/types/tuple/strictTupleLength.ts(18,1): error TS2322: Type 'number[]' is not assignable to type '[number]'. + Property '0' is missing in type 'number[]'. + + +==== tests/cases/conformance/types/tuple/strictTupleLength.ts (4 errors) ==== + var t0: []; + ~~ +!!! error TS1122: A tuple type element list cannot be empty. + var t1: [number]; + var t2: [number, number]; + var arr: number[]; + + var len0: 0 = t0.length; + var len1: 1 = t1.length; + var len2: 2 = t2.length; + var lena: number = arr.length; + + var t1 = t2; // error + ~~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 't1' has type '[number]' at tests/cases/conformance/types/tuple/strictTupleLength.ts 1:4, but here has type '[number, number]'. + var t2 = t1; // error + ~~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 't2' has type '[number, number]' at tests/cases/conformance/types/tuple/strictTupleLength.ts 2:4, but here has type '[number]'. + + type A = T['length']; + var b: A<[boolean]>; + var c: 1 = b; + + t1 = arr; // error with or without strict + ~~ +!!! error TS2322: Type 'number[]' is not assignable to type '[number]'. +!!! error TS2322: Property '0' is missing in type 'number[]'. + arr = t1; // ok with or without strict + \ No newline at end of file diff --git a/tests/baselines/reference/tupleLength.js b/tests/baselines/reference/strictTupleLength.js similarity index 58% rename from tests/baselines/reference/tupleLength.js rename to tests/baselines/reference/strictTupleLength.js index 3893305421b..e4ae65f2fde 100644 --- a/tests/baselines/reference/tupleLength.js +++ b/tests/baselines/reference/strictTupleLength.js @@ -1,10 +1,10 @@ -//// [tupleLength.ts] -// var t0: []; +//// [strictTupleLength.ts] +var t0: []; var t1: [number]; var t2: [number, number]; var arr: number[]; -// var len0: 0 = t0.length; +var len0: 0 = t0.length; var len1: 1 = t1.length; var len2: 2 = t2.length; var lena: number = arr.length; @@ -15,14 +15,17 @@ var t2 = t1; // error type A = T['length']; var b: A<[boolean]>; var c: 1 = b; + +t1 = arr; // error with or without strict +arr = t1; // ok with or without strict -//// [tupleLength.js] -// var t0: []; +//// [strictTupleLength.js] +var t0; var t1; var t2; var arr; -// var len0: 0 = t0.length; +var len0 = t0.length; var len1 = t1.length; var len2 = t2.length; var lena = arr.length; @@ -30,3 +33,5 @@ var t1 = t2; // error var t2 = t1; // error var b; var c = b; +t1 = arr; // error with or without strict +arr = t1; // ok with or without strict diff --git a/tests/baselines/reference/strictTupleLength.symbols b/tests/baselines/reference/strictTupleLength.symbols new file mode 100644 index 00000000000..e81697b84bf --- /dev/null +++ b/tests/baselines/reference/strictTupleLength.symbols @@ -0,0 +1,66 @@ +=== tests/cases/conformance/types/tuple/strictTupleLength.ts === +var t0: []; +>t0 : Symbol(t0, Decl(strictTupleLength.ts, 0, 3)) + +var t1: [number]; +>t1 : Symbol(t1, Decl(strictTupleLength.ts, 1, 3), Decl(strictTupleLength.ts, 10, 3)) + +var t2: [number, number]; +>t2 : Symbol(t2, Decl(strictTupleLength.ts, 2, 3), Decl(strictTupleLength.ts, 11, 3)) + +var arr: number[]; +>arr : Symbol(arr, Decl(strictTupleLength.ts, 3, 3)) + +var len0: 0 = t0.length; +>len0 : Symbol(len0, Decl(strictTupleLength.ts, 5, 3)) +>t0.length : Symbol(length) +>t0 : Symbol(t0, Decl(strictTupleLength.ts, 0, 3)) +>length : Symbol(length) + +var len1: 1 = t1.length; +>len1 : Symbol(len1, Decl(strictTupleLength.ts, 6, 3)) +>t1.length : Symbol(length) +>t1 : Symbol(t1, Decl(strictTupleLength.ts, 1, 3), Decl(strictTupleLength.ts, 10, 3)) +>length : Symbol(length) + +var len2: 2 = t2.length; +>len2 : Symbol(len2, Decl(strictTupleLength.ts, 7, 3)) +>t2.length : Symbol(length) +>t2 : Symbol(t2, Decl(strictTupleLength.ts, 2, 3), Decl(strictTupleLength.ts, 11, 3)) +>length : Symbol(length) + +var lena: number = arr.length; +>lena : Symbol(lena, Decl(strictTupleLength.ts, 8, 3)) +>arr.length : Symbol(Array.length, Decl(lib.d.ts, --, --)) +>arr : Symbol(arr, Decl(strictTupleLength.ts, 3, 3)) +>length : Symbol(Array.length, Decl(lib.d.ts, --, --)) + +var t1 = t2; // error +>t1 : Symbol(t1, Decl(strictTupleLength.ts, 1, 3), Decl(strictTupleLength.ts, 10, 3)) +>t2 : Symbol(t2, Decl(strictTupleLength.ts, 2, 3), Decl(strictTupleLength.ts, 11, 3)) + +var t2 = t1; // error +>t2 : Symbol(t2, Decl(strictTupleLength.ts, 2, 3), Decl(strictTupleLength.ts, 11, 3)) +>t1 : Symbol(t1, Decl(strictTupleLength.ts, 1, 3), Decl(strictTupleLength.ts, 10, 3)) + +type A = T['length']; +>A : Symbol(A, Decl(strictTupleLength.ts, 11, 12)) +>T : Symbol(T, Decl(strictTupleLength.ts, 13, 7)) +>T : Symbol(T, Decl(strictTupleLength.ts, 13, 7)) + +var b: A<[boolean]>; +>b : Symbol(b, Decl(strictTupleLength.ts, 14, 3)) +>A : Symbol(A, Decl(strictTupleLength.ts, 11, 12)) + +var c: 1 = b; +>c : Symbol(c, Decl(strictTupleLength.ts, 15, 3)) +>b : Symbol(b, Decl(strictTupleLength.ts, 14, 3)) + +t1 = arr; // error with or without strict +>t1 : Symbol(t1, Decl(strictTupleLength.ts, 1, 3), Decl(strictTupleLength.ts, 10, 3)) +>arr : Symbol(arr, Decl(strictTupleLength.ts, 3, 3)) + +arr = t1; // ok with or without strict +>arr : Symbol(arr, Decl(strictTupleLength.ts, 3, 3)) +>t1 : Symbol(t1, Decl(strictTupleLength.ts, 1, 3), Decl(strictTupleLength.ts, 10, 3)) + diff --git a/tests/baselines/reference/tupleLength.types b/tests/baselines/reference/strictTupleLength.types similarity index 61% rename from tests/baselines/reference/tupleLength.types rename to tests/baselines/reference/strictTupleLength.types index ce1c88d2a70..917c2f7db23 100644 --- a/tests/baselines/reference/tupleLength.types +++ b/tests/baselines/reference/strictTupleLength.types @@ -1,5 +1,7 @@ -=== tests/cases/compiler/tupleLength.ts === -// var t0: []; +=== tests/cases/conformance/types/tuple/strictTupleLength.ts === +var t0: []; +>t0 : [] + var t1: [number]; >t1 : [number] @@ -9,7 +11,12 @@ var t2: [number, number]; var arr: number[]; >arr : number[] -// var len0: 0 = t0.length; +var len0: 0 = t0.length; +>len0 : 0 +>t0.length : 0 +>t0 : [] +>length : 0 + var len1: 1 = t1.length; >len1 : 1 >t1.length : 1 @@ -49,3 +56,13 @@ var c: 1 = b; >c : 1 >b : 1 +t1 = arr; // error with or without strict +>t1 = arr : number[] +>t1 : [number] +>arr : number[] + +arr = t1; // ok with or without strict +>arr = t1 : [number] +>arr : number[] +>t1 : [number] + diff --git a/tests/baselines/reference/tupleLength.errors.txt b/tests/baselines/reference/tupleLength.errors.txt deleted file mode 100644 index 9b4b7fa52bc..00000000000 --- a/tests/baselines/reference/tupleLength.errors.txt +++ /dev/null @@ -1,26 +0,0 @@ -tests/cases/compiler/tupleLength.ts(11,5): error TS2403: Subsequent variable declarations must have the same type. Variable 't1' has type '[number]' at tests/cases/compiler/tupleLength.ts 1:4, but here has type '[number, number]'. -tests/cases/compiler/tupleLength.ts(12,5): error TS2403: Subsequent variable declarations must have the same type. Variable 't2' has type '[number, number]' at tests/cases/compiler/tupleLength.ts 2:4, but here has type '[number]'. - - -==== tests/cases/compiler/tupleLength.ts (2 errors) ==== - // var t0: []; - var t1: [number]; - var t2: [number, number]; - var arr: number[]; - - // var len0: 0 = t0.length; - var len1: 1 = t1.length; - var len2: 2 = t2.length; - var lena: number = arr.length; - - var t1 = t2; // error - ~~ -!!! error TS2403: Subsequent variable declarations must have the same type. Variable 't1' has type '[number]' at tests/cases/compiler/tupleLength.ts 1:4, but here has type '[number, number]'. - var t2 = t1; // error - ~~ -!!! error TS2403: Subsequent variable declarations must have the same type. Variable 't2' has type '[number, number]' at tests/cases/compiler/tupleLength.ts 2:4, but here has type '[number]'. - - type A = T['length']; - var b: A<[boolean]>; - var c: 1 = b; - \ No newline at end of file diff --git a/tests/baselines/reference/tupleLength.symbols b/tests/baselines/reference/tupleLength.symbols deleted file mode 100644 index f488185306d..00000000000 --- a/tests/baselines/reference/tupleLength.symbols +++ /dev/null @@ -1,51 +0,0 @@ -=== tests/cases/compiler/tupleLength.ts === -// var t0: []; -var t1: [number]; ->t1 : Symbol(t1, Decl(tupleLength.ts, 1, 3), Decl(tupleLength.ts, 10, 3)) - -var t2: [number, number]; ->t2 : Symbol(t2, Decl(tupleLength.ts, 2, 3), Decl(tupleLength.ts, 11, 3)) - -var arr: number[]; ->arr : Symbol(arr, Decl(tupleLength.ts, 3, 3)) - -// var len0: 0 = t0.length; -var len1: 1 = t1.length; ->len1 : Symbol(len1, Decl(tupleLength.ts, 6, 3)) ->t1.length : Symbol(length) ->t1 : Symbol(t1, Decl(tupleLength.ts, 1, 3), Decl(tupleLength.ts, 10, 3)) ->length : Symbol(length) - -var len2: 2 = t2.length; ->len2 : Symbol(len2, Decl(tupleLength.ts, 7, 3)) ->t2.length : Symbol(length) ->t2 : Symbol(t2, Decl(tupleLength.ts, 2, 3), Decl(tupleLength.ts, 11, 3)) ->length : Symbol(length) - -var lena: number = arr.length; ->lena : Symbol(lena, Decl(tupleLength.ts, 8, 3)) ->arr.length : Symbol(Array.length, Decl(lib.d.ts, --, --)) ->arr : Symbol(arr, Decl(tupleLength.ts, 3, 3)) ->length : Symbol(Array.length, Decl(lib.d.ts, --, --)) - -var t1 = t2; // error ->t1 : Symbol(t1, Decl(tupleLength.ts, 1, 3), Decl(tupleLength.ts, 10, 3)) ->t2 : Symbol(t2, Decl(tupleLength.ts, 2, 3), Decl(tupleLength.ts, 11, 3)) - -var t2 = t1; // error ->t2 : Symbol(t2, Decl(tupleLength.ts, 2, 3), Decl(tupleLength.ts, 11, 3)) ->t1 : Symbol(t1, Decl(tupleLength.ts, 1, 3), Decl(tupleLength.ts, 10, 3)) - -type A = T['length']; ->A : Symbol(A, Decl(tupleLength.ts, 11, 12)) ->T : Symbol(T, Decl(tupleLength.ts, 13, 7)) ->T : Symbol(T, Decl(tupleLength.ts, 13, 7)) - -var b: A<[boolean]>; ->b : Symbol(b, Decl(tupleLength.ts, 14, 3)) ->A : Symbol(A, Decl(tupleLength.ts, 11, 12)) - -var c: 1 = b; ->c : Symbol(c, Decl(tupleLength.ts, 15, 3)) ->b : Symbol(b, Decl(tupleLength.ts, 14, 3)) - diff --git a/tests/cases/compiler/tupleLength.ts b/tests/cases/conformance/types/tuple/strictTupleLength.ts similarity index 70% rename from tests/cases/compiler/tupleLength.ts rename to tests/cases/conformance/types/tuple/strictTupleLength.ts index 3c6db1a034a..bfae662cd7c 100644 --- a/tests/cases/compiler/tupleLength.ts +++ b/tests/cases/conformance/types/tuple/strictTupleLength.ts @@ -1,11 +1,11 @@ // @strictTuples: true -// var t0: []; +var t0: []; var t1: [number]; var t2: [number, number]; var arr: number[]; -// var len0: 0 = t0.length; +var len0: 0 = t0.length; var len1: 1 = t1.length; var len2: 2 = t2.length; var lena: number = arr.length; @@ -16,3 +16,6 @@ var t2 = t1; // error type A = T['length']; var b: A<[boolean]>; var c: 1 = b; + +t1 = arr; // error with or without strict +arr = t1; // ok with or without strict From 6a382f1436710a6fad7a8fef8f48dff62fad96e4 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 1 Nov 2017 14:20:26 -0700 Subject: [PATCH 073/235] In typings installer, provide mandatory 'package.json' fields (#19663) --- src/server/typingsInstaller/typingsInstaller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/typingsInstaller/typingsInstaller.ts b/src/server/typingsInstaller/typingsInstaller.ts index 26e7781b440..c45275d0b3d 100644 --- a/src/server/typingsInstaller/typingsInstaller.ts +++ b/src/server/typingsInstaller/typingsInstaller.ts @@ -248,7 +248,7 @@ namespace ts.server.typingsInstaller { this.log.writeLine(`Npm config file: '${npmConfigPath}' is missing, creating new one...`); } this.ensureDirectoryExists(directory, this.installTypingHost); - this.installTypingHost.writeFile(npmConfigPath, "{}"); + this.installTypingHost.writeFile(npmConfigPath, '{ "description": "", "repository": "", "license": "" }'); } } From ba98cbbf92ab475eabf90e27d08cc84d060c621e Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 1 Nov 2017 16:22:37 -0700 Subject: [PATCH 074/235] User code runner draft (#19539) * Realworld runner draft * Baseline tsc output instead of just checking exit code * use latest instead of major minor pin * Add 7 more test cases + update gitignore * Update baselines for realworld/user tests * Rename to user * Do not commit lockfiles * Add code to run user tests on CRON * Add rest of most-dependend packages to user tests Turns out levelup doesn't have types! So I removed that one. --- .gitignore | 8 +++ Jakefile.js | 1 + src/harness/runner.ts | 14 ++++- src/harness/runnerbase.ts | 2 +- src/harness/tsconfig.json | 1 + src/harness/userRunner.ts | 51 +++++++++++++++++++ tests/baselines/reference/user/ajv.log | 6 +++ tests/baselines/reference/user/antd.log | 6 +++ tests/baselines/reference/user/axios.log | 6 +++ .../baselines/reference/user/bignumber.js.log | 6 +++ tests/baselines/reference/user/discord.js.log | 6 +++ tests/baselines/reference/user/electron.log | 13 +++++ .../reference/user/eventemitter2.log | 6 +++ .../reference/user/eventemitter3.log | 6 +++ tests/baselines/reference/user/firebase.log | 6 +++ tests/baselines/reference/user/github.log | 6 +++ tests/baselines/reference/user/immutable.log | 6 +++ tests/baselines/reference/user/isobject.log | 6 +++ tests/baselines/reference/user/jimp.log | 6 +++ tests/baselines/reference/user/jsonschema.log | 6 +++ tests/baselines/reference/user/keycode.log | 6 +++ tests/baselines/reference/user/leveldown.log | 20 ++++++++ .../baselines/reference/user/localforage.log | 6 +++ tests/baselines/reference/user/log4js.log | 6 +++ tests/baselines/reference/user/mobx.log | 6 +++ tests/baselines/reference/user/moment.log | 6 +++ tests/baselines/reference/user/mqtt.log | 6 +++ tests/baselines/reference/user/parse5.log | 6 +++ tests/baselines/reference/user/portfinder.log | 6 +++ tests/baselines/reference/user/postcss.log | 6 +++ tests/baselines/reference/user/protobufjs.log | 6 +++ tests/baselines/reference/user/redux.log | 6 +++ tests/baselines/reference/user/reselect.log | 6 +++ tests/baselines/reference/user/rxjs.log | 12 +++++ tests/baselines/reference/user/should.log | 6 +++ tests/baselines/reference/user/sift.log | 6 +++ tests/baselines/reference/user/soap.log | 6 +++ tests/baselines/reference/user/sugar.log | 6 +++ tests/baselines/reference/user/tslint.log | 6 +++ tests/baselines/reference/user/vue.log | 6 +++ tests/baselines/reference/user/vuex.log | 7 +++ tests/baselines/reference/user/xlsx.log | 6 +++ tests/baselines/reference/user/xpath.log | 6 +++ tests/baselines/reference/user/zone.js.log | 6 +++ tests/cases/user/ajv/index.ts | 1 + tests/cases/user/ajv/package.json | 11 ++++ tests/cases/user/ajv/tsconfig.json | 7 +++ tests/cases/user/antd/index.ts | 1 + tests/cases/user/antd/package.json | 12 +++++ tests/cases/user/antd/tsconfig.json | 8 +++ tests/cases/user/axios/index.ts | 1 + tests/cases/user/axios/package.json | 11 ++++ tests/cases/user/axios/tsconfig.json | 7 +++ tests/cases/user/bignumber.js/index.ts | 1 + tests/cases/user/bignumber.js/package.json | 11 ++++ tests/cases/user/bignumber.js/tsconfig.json | 7 +++ tests/cases/user/discord.js/index.ts | 1 + tests/cases/user/discord.js/package.json | 12 +++++ tests/cases/user/discord.js/tsconfig.json | 7 +++ tests/cases/user/electron/index.ts | 1 + tests/cases/user/electron/package.json | 11 ++++ tests/cases/user/electron/tsconfig.json | 7 +++ tests/cases/user/eventemitter2/index.ts | 1 + tests/cases/user/eventemitter2/package.json | 11 ++++ tests/cases/user/eventemitter2/tsconfig.json | 7 +++ tests/cases/user/eventemitter3/index.ts | 1 + tests/cases/user/eventemitter3/package.json | 11 ++++ tests/cases/user/eventemitter3/tsconfig.json | 7 +++ tests/cases/user/firebase/index.ts | 1 + tests/cases/user/firebase/package.json | 11 ++++ tests/cases/user/firebase/tsconfig.json | 7 +++ tests/cases/user/github/index.ts | 1 + tests/cases/user/github/package.json | 11 ++++ tests/cases/user/github/tsconfig.json | 7 +++ tests/cases/user/immutable/index.ts | 1 + tests/cases/user/immutable/package.json | 11 ++++ tests/cases/user/immutable/tsconfig.json | 7 +++ tests/cases/user/isobject/index.ts | 1 + tests/cases/user/isobject/package.json | 11 ++++ tests/cases/user/isobject/tsconfig.json | 7 +++ tests/cases/user/jimp/index.ts | 1 + tests/cases/user/jimp/package.json | 11 ++++ tests/cases/user/jimp/tsconfig.json | 7 +++ tests/cases/user/jsonschema/index.ts | 1 + tests/cases/user/jsonschema/package.json | 11 ++++ tests/cases/user/jsonschema/tsconfig.json | 7 +++ tests/cases/user/keycode/index.ts | 1 + tests/cases/user/keycode/package.json | 12 +++++ tests/cases/user/keycode/tsconfig.json | 7 +++ tests/cases/user/leveldown/index.ts | 1 + tests/cases/user/leveldown/package.json | 12 +++++ tests/cases/user/leveldown/tsconfig.json | 7 +++ tests/cases/user/localforage/index.ts | 1 + tests/cases/user/localforage/package.json | 11 ++++ tests/cases/user/localforage/tsconfig.json | 7 +++ tests/cases/user/log4js/index.ts | 1 + tests/cases/user/log4js/package.json | 11 ++++ tests/cases/user/log4js/tsconfig.json | 7 +++ tests/cases/user/mobx/index.ts | 1 + tests/cases/user/mobx/package.json | 11 ++++ tests/cases/user/mobx/tsconfig.json | 7 +++ tests/cases/user/moment/index.ts | 1 + tests/cases/user/moment/package.json | 11 ++++ tests/cases/user/moment/tsconfig.json | 7 +++ tests/cases/user/mqtt/index.ts | 1 + tests/cases/user/mqtt/package.json | 11 ++++ tests/cases/user/mqtt/tsconfig.json | 7 +++ tests/cases/user/parse5/index.ts | 1 + tests/cases/user/parse5/package.json | 11 ++++ tests/cases/user/parse5/tsconfig.json | 7 +++ tests/cases/user/portfinder/index.ts | 1 + tests/cases/user/portfinder/package.json | 11 ++++ tests/cases/user/portfinder/tsconfig.json | 7 +++ tests/cases/user/postcss/index.ts | 1 + tests/cases/user/postcss/package.json | 11 ++++ tests/cases/user/postcss/tsconfig.json | 7 +++ tests/cases/user/protobufjs/index.ts | 1 + tests/cases/user/protobufjs/package.json | 11 ++++ tests/cases/user/protobufjs/tsconfig.json | 7 +++ tests/cases/user/redux/index.ts | 1 + tests/cases/user/redux/package.json | 11 ++++ tests/cases/user/redux/tsconfig.json | 7 +++ tests/cases/user/reselect/index.ts | 1 + tests/cases/user/reselect/package.json | 11 ++++ tests/cases/user/reselect/tsconfig.json | 7 +++ tests/cases/user/rxjs/index.ts | 1 + tests/cases/user/rxjs/package.json | 11 ++++ tests/cases/user/rxjs/tsconfig.json | 7 +++ tests/cases/user/should/index.ts | 1 + tests/cases/user/should/package.json | 11 ++++ tests/cases/user/should/tsconfig.json | 7 +++ tests/cases/user/sift/index.ts | 1 + tests/cases/user/sift/package.json | 11 ++++ tests/cases/user/sift/tsconfig.json | 7 +++ tests/cases/user/soap/index.ts | 1 + tests/cases/user/soap/package.json | 12 +++++ tests/cases/user/soap/tsconfig.json | 7 +++ tests/cases/user/sugar/index.ts | 1 + tests/cases/user/sugar/package.json | 11 ++++ tests/cases/user/sugar/tsconfig.json | 7 +++ tests/cases/user/tslint/index.ts | 1 + tests/cases/user/tslint/package.json | 27 ++++++++++ tests/cases/user/tslint/tsconfig.json | 7 +++ tests/cases/user/vue/index.ts | 1 + tests/cases/user/vue/package.json | 11 ++++ tests/cases/user/vue/tsconfig.json | 7 +++ tests/cases/user/vuex/index.ts | 1 + tests/cases/user/vuex/package.json | 12 +++++ tests/cases/user/vuex/tsconfig.json | 7 +++ tests/cases/user/xlsx/index.ts | 1 + tests/cases/user/xlsx/package.json | 11 ++++ tests/cases/user/xlsx/tsconfig.json | 7 +++ tests/cases/user/xpath/index.ts | 1 + tests/cases/user/xpath/package.json | 11 ++++ tests/cases/user/xpath/tsconfig.json | 7 +++ tests/cases/user/zone.js/index.ts | 1 + tests/cases/user/zone.js/package.json | 11 ++++ tests/cases/user/zone.js/tsconfig.json | 11 ++++ 158 files changed, 1080 insertions(+), 2 deletions(-) create mode 100644 src/harness/userRunner.ts create mode 100644 tests/baselines/reference/user/ajv.log create mode 100644 tests/baselines/reference/user/antd.log create mode 100644 tests/baselines/reference/user/axios.log create mode 100644 tests/baselines/reference/user/bignumber.js.log create mode 100644 tests/baselines/reference/user/discord.js.log create mode 100644 tests/baselines/reference/user/electron.log create mode 100644 tests/baselines/reference/user/eventemitter2.log create mode 100644 tests/baselines/reference/user/eventemitter3.log create mode 100644 tests/baselines/reference/user/firebase.log create mode 100644 tests/baselines/reference/user/github.log create mode 100644 tests/baselines/reference/user/immutable.log create mode 100644 tests/baselines/reference/user/isobject.log create mode 100644 tests/baselines/reference/user/jimp.log create mode 100644 tests/baselines/reference/user/jsonschema.log create mode 100644 tests/baselines/reference/user/keycode.log create mode 100644 tests/baselines/reference/user/leveldown.log create mode 100644 tests/baselines/reference/user/localforage.log create mode 100644 tests/baselines/reference/user/log4js.log create mode 100644 tests/baselines/reference/user/mobx.log create mode 100644 tests/baselines/reference/user/moment.log create mode 100644 tests/baselines/reference/user/mqtt.log create mode 100644 tests/baselines/reference/user/parse5.log create mode 100644 tests/baselines/reference/user/portfinder.log create mode 100644 tests/baselines/reference/user/postcss.log create mode 100644 tests/baselines/reference/user/protobufjs.log create mode 100644 tests/baselines/reference/user/redux.log create mode 100644 tests/baselines/reference/user/reselect.log create mode 100644 tests/baselines/reference/user/rxjs.log create mode 100644 tests/baselines/reference/user/should.log create mode 100644 tests/baselines/reference/user/sift.log create mode 100644 tests/baselines/reference/user/soap.log create mode 100644 tests/baselines/reference/user/sugar.log create mode 100644 tests/baselines/reference/user/tslint.log create mode 100644 tests/baselines/reference/user/vue.log create mode 100644 tests/baselines/reference/user/vuex.log create mode 100644 tests/baselines/reference/user/xlsx.log create mode 100644 tests/baselines/reference/user/xpath.log create mode 100644 tests/baselines/reference/user/zone.js.log create mode 100644 tests/cases/user/ajv/index.ts create mode 100644 tests/cases/user/ajv/package.json create mode 100644 tests/cases/user/ajv/tsconfig.json create mode 100644 tests/cases/user/antd/index.ts create mode 100644 tests/cases/user/antd/package.json create mode 100644 tests/cases/user/antd/tsconfig.json create mode 100644 tests/cases/user/axios/index.ts create mode 100644 tests/cases/user/axios/package.json create mode 100644 tests/cases/user/axios/tsconfig.json create mode 100644 tests/cases/user/bignumber.js/index.ts create mode 100644 tests/cases/user/bignumber.js/package.json create mode 100644 tests/cases/user/bignumber.js/tsconfig.json create mode 100644 tests/cases/user/discord.js/index.ts create mode 100644 tests/cases/user/discord.js/package.json create mode 100644 tests/cases/user/discord.js/tsconfig.json create mode 100644 tests/cases/user/electron/index.ts create mode 100644 tests/cases/user/electron/package.json create mode 100644 tests/cases/user/electron/tsconfig.json create mode 100644 tests/cases/user/eventemitter2/index.ts create mode 100644 tests/cases/user/eventemitter2/package.json create mode 100644 tests/cases/user/eventemitter2/tsconfig.json create mode 100644 tests/cases/user/eventemitter3/index.ts create mode 100644 tests/cases/user/eventemitter3/package.json create mode 100644 tests/cases/user/eventemitter3/tsconfig.json create mode 100644 tests/cases/user/firebase/index.ts create mode 100644 tests/cases/user/firebase/package.json create mode 100644 tests/cases/user/firebase/tsconfig.json create mode 100644 tests/cases/user/github/index.ts create mode 100644 tests/cases/user/github/package.json create mode 100644 tests/cases/user/github/tsconfig.json create mode 100644 tests/cases/user/immutable/index.ts create mode 100644 tests/cases/user/immutable/package.json create mode 100644 tests/cases/user/immutable/tsconfig.json create mode 100644 tests/cases/user/isobject/index.ts create mode 100644 tests/cases/user/isobject/package.json create mode 100644 tests/cases/user/isobject/tsconfig.json create mode 100644 tests/cases/user/jimp/index.ts create mode 100644 tests/cases/user/jimp/package.json create mode 100644 tests/cases/user/jimp/tsconfig.json create mode 100644 tests/cases/user/jsonschema/index.ts create mode 100644 tests/cases/user/jsonschema/package.json create mode 100644 tests/cases/user/jsonschema/tsconfig.json create mode 100644 tests/cases/user/keycode/index.ts create mode 100644 tests/cases/user/keycode/package.json create mode 100644 tests/cases/user/keycode/tsconfig.json create mode 100644 tests/cases/user/leveldown/index.ts create mode 100644 tests/cases/user/leveldown/package.json create mode 100644 tests/cases/user/leveldown/tsconfig.json create mode 100644 tests/cases/user/localforage/index.ts create mode 100644 tests/cases/user/localforage/package.json create mode 100644 tests/cases/user/localforage/tsconfig.json create mode 100644 tests/cases/user/log4js/index.ts create mode 100644 tests/cases/user/log4js/package.json create mode 100644 tests/cases/user/log4js/tsconfig.json create mode 100644 tests/cases/user/mobx/index.ts create mode 100644 tests/cases/user/mobx/package.json create mode 100644 tests/cases/user/mobx/tsconfig.json create mode 100644 tests/cases/user/moment/index.ts create mode 100644 tests/cases/user/moment/package.json create mode 100644 tests/cases/user/moment/tsconfig.json create mode 100644 tests/cases/user/mqtt/index.ts create mode 100644 tests/cases/user/mqtt/package.json create mode 100644 tests/cases/user/mqtt/tsconfig.json create mode 100644 tests/cases/user/parse5/index.ts create mode 100644 tests/cases/user/parse5/package.json create mode 100644 tests/cases/user/parse5/tsconfig.json create mode 100644 tests/cases/user/portfinder/index.ts create mode 100644 tests/cases/user/portfinder/package.json create mode 100644 tests/cases/user/portfinder/tsconfig.json create mode 100644 tests/cases/user/postcss/index.ts create mode 100644 tests/cases/user/postcss/package.json create mode 100644 tests/cases/user/postcss/tsconfig.json create mode 100644 tests/cases/user/protobufjs/index.ts create mode 100644 tests/cases/user/protobufjs/package.json create mode 100644 tests/cases/user/protobufjs/tsconfig.json create mode 100644 tests/cases/user/redux/index.ts create mode 100644 tests/cases/user/redux/package.json create mode 100644 tests/cases/user/redux/tsconfig.json create mode 100644 tests/cases/user/reselect/index.ts create mode 100644 tests/cases/user/reselect/package.json create mode 100644 tests/cases/user/reselect/tsconfig.json create mode 100644 tests/cases/user/rxjs/index.ts create mode 100644 tests/cases/user/rxjs/package.json create mode 100644 tests/cases/user/rxjs/tsconfig.json create mode 100644 tests/cases/user/should/index.ts create mode 100644 tests/cases/user/should/package.json create mode 100644 tests/cases/user/should/tsconfig.json create mode 100644 tests/cases/user/sift/index.ts create mode 100644 tests/cases/user/sift/package.json create mode 100644 tests/cases/user/sift/tsconfig.json create mode 100644 tests/cases/user/soap/index.ts create mode 100644 tests/cases/user/soap/package.json create mode 100644 tests/cases/user/soap/tsconfig.json create mode 100644 tests/cases/user/sugar/index.ts create mode 100644 tests/cases/user/sugar/package.json create mode 100644 tests/cases/user/sugar/tsconfig.json create mode 100644 tests/cases/user/tslint/index.ts create mode 100644 tests/cases/user/tslint/package.json create mode 100644 tests/cases/user/tslint/tsconfig.json create mode 100644 tests/cases/user/vue/index.ts create mode 100644 tests/cases/user/vue/package.json create mode 100644 tests/cases/user/vue/tsconfig.json create mode 100644 tests/cases/user/vuex/index.ts create mode 100644 tests/cases/user/vuex/package.json create mode 100644 tests/cases/user/vuex/tsconfig.json create mode 100644 tests/cases/user/xlsx/index.ts create mode 100644 tests/cases/user/xlsx/package.json create mode 100644 tests/cases/user/xlsx/tsconfig.json create mode 100644 tests/cases/user/xpath/index.ts create mode 100644 tests/cases/user/xpath/package.json create mode 100644 tests/cases/user/xpath/tsconfig.json create mode 100644 tests/cases/user/zone.js/index.ts create mode 100644 tests/cases/user/zone.js/package.json create mode 100644 tests/cases/user/zone.js/tsconfig.json diff --git a/.gitignore b/.gitignore index 90b078fc94f..40c473d13dd 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,11 @@ internal/ .idea yarn.lock .parallelperf.* +tests/cases/user/*/package-lock.json +tests/cases/user/*/node_modules/ +tests/cases/user/*/**/*.js +tests/cases/user/*/**/*.js.map +tests/cases/user/*/**/*.d.ts +!tests/cases/user/zone.js/ +!tests/cases/user/bignumber.js/ +!tests/cases/user/discord.js/ diff --git a/Jakefile.js b/Jakefile.js index da7d96f0699..b7973c092f2 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -105,6 +105,7 @@ var harnessCoreSources = [ "projectsRunner.ts", "loggedIO.ts", "rwcRunner.ts", + "userRunner.ts", "test262Runner.ts", "./parallel/shared.ts", "./parallel/host.ts", diff --git a/src/harness/runner.ts b/src/harness/runner.ts index db807b976bb..9b8ed41554e 100644 --- a/src/harness/runner.ts +++ b/src/harness/runner.ts @@ -18,6 +18,7 @@ /// /// /// +/// /// /// @@ -59,6 +60,8 @@ function createRunner(kind: TestRunnerKind): RunnerBase { return new RWCRunner(); case "test262": return new Test262BaselineRunner(); + case "user": + return new UserCodeRunner(); } ts.Debug.fail(`Unknown runner kind ${kind}`); } @@ -175,6 +178,9 @@ function handleTestConfig() { case "test262": runners.push(new Test262BaselineRunner()); break; + case "user": + runners.push(new UserCodeRunner()); + break; } } } @@ -196,6 +202,11 @@ function handleTestConfig() { runners.push(new FourSlashRunner(FourSlashTestType.ShimsWithPreprocess)); runners.push(new FourSlashRunner(FourSlashTestType.Server)); // runners.push(new GeneratedFourslashRunner()); + + // CRON-only tests + if (Utils.getExecutionEnvironment() !== Utils.ExecutionEnvironment.Browser && process.env.TRAVIS_EVENT_TYPE === "cron") { + runners.push(new UserCodeRunner()); + } } if (runUnitTests === undefined) { runUnitTests = runners.length !== 1; // Don't run unit tests when running only one runner if unit tests were not explicitly asked for @@ -215,8 +226,9 @@ function beginTests() { } } +let isWorker: boolean; function startTestEnvironment() { - const isWorker = handleTestConfig(); + isWorker = handleTestConfig(); if (Utils.getExecutionEnvironment() !== Utils.ExecutionEnvironment.Browser) { if (isWorker) { return Harness.Parallel.Worker.start(); diff --git a/src/harness/runnerbase.ts b/src/harness/runnerbase.ts index d50604803ed..2fef2264b73 100644 --- a/src/harness/runnerbase.ts +++ b/src/harness/runnerbase.ts @@ -1,7 +1,7 @@ /// -type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project" | "rwc" | "test262"; +type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project" | "rwc" | "test262" | "user"; type CompilerTestKind = "conformance" | "compiler"; type FourslashTestKind = "fourslash" | "fourslash-shims" | "fourslash-shims-pp" | "fourslash-server"; diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json index 18baeb67c82..6e61b7690bc 100644 --- a/src/harness/tsconfig.json +++ b/src/harness/tsconfig.json @@ -92,6 +92,7 @@ "projectsRunner.ts", "loggedIO.ts", "rwcRunner.ts", + "userRunner.ts", "test262Runner.ts", "./parallel/shared.ts", "./parallel/host.ts", diff --git a/src/harness/userRunner.ts b/src/harness/userRunner.ts new file mode 100644 index 00000000000..3802330e10c --- /dev/null +++ b/src/harness/userRunner.ts @@ -0,0 +1,51 @@ +/// +/// +class UserCodeRunner extends RunnerBase { + private static readonly testDir = "tests/cases/user/"; + public enumerateTestFiles() { + return Harness.IO.getDirectories(UserCodeRunner.testDir); + } + + public kind(): TestRunnerKind { + return "user"; + } + + /** Setup the runner's tests so that they are ready to be executed by the harness + * The first test should be a describe/it block that sets up the harness's compiler instance appropriately + */ + public initializeTests(): void { + // Read in and evaluate the test list + const testList = this.tests && this.tests.length ? this.tests : this.enumerateTestFiles(); + + describe(`${this.kind()} code samples`, () => { + for (let i = 0; i < testList.length; i++) { + this.runTest(testList[i]); + } + }); + } + + private runTest(directoryName: string) { + describe(directoryName, () => { + const cp = require("child_process"); + const path = require("path"); + + it("should build successfully", () => { + const cwd = path.join(__dirname, "../../", UserCodeRunner.testDir, directoryName); + const timeout = 600000; // 10 minutes + const stdio = isWorker ? "pipe" : "inherit"; + const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout, shell: true, stdio }); + if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed!`); + Harness.Baseline.runBaseline(`${this.kind()}/${directoryName}.log`, () => { + const result = cp.spawnSync(`node`, ["../../../../built/local/tsc.js"], { cwd, timeout, shell: true }); + return `Exit Code: ${result.status} +Standard output: +${result.stdout.toString().replace(/\r\n/g, "\n")} + + +Standard error: +${result.stderr.toString().replace(/\r\n/g, "\n")}`; + }); + }); + }); + } +} diff --git a/tests/baselines/reference/user/ajv.log b/tests/baselines/reference/user/ajv.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/ajv.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/antd.log b/tests/baselines/reference/user/antd.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/antd.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/axios.log b/tests/baselines/reference/user/axios.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/axios.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/bignumber.js.log b/tests/baselines/reference/user/bignumber.js.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/bignumber.js.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/discord.js.log b/tests/baselines/reference/user/discord.js.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/discord.js.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/electron.log b/tests/baselines/reference/user/electron.log new file mode 100644 index 00000000000..e5eef689d49 --- /dev/null +++ b/tests/baselines/reference/user/electron.log @@ -0,0 +1,13 @@ +Exit Code: 2 +Standard output: +node_modules/electron/electron.d.ts(5390,13): error TS2430: Interface 'WebviewTag' incorrectly extends interface 'HTMLElement'. + Types of property 'addEventListener' are incompatible. + Type '{ (event: "load-commit", listener: (event: LoadCommitEvent) => void, useCapture?: boolean | undef...' is not assignable to type '{ void'. + Type 'EventListenerObject' is not assignable to type '(event: LoadCommitEvent) => void'. + Type 'EventListenerObject' provides no match for the signature '(event: LoadCommitEvent): void'. + + + +Standard error: diff --git a/tests/baselines/reference/user/eventemitter2.log b/tests/baselines/reference/user/eventemitter2.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/eventemitter2.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/eventemitter3.log b/tests/baselines/reference/user/eventemitter3.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/eventemitter3.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/firebase.log b/tests/baselines/reference/user/firebase.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/firebase.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/github.log b/tests/baselines/reference/user/github.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/github.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/immutable.log b/tests/baselines/reference/user/immutable.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/immutable.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/isobject.log b/tests/baselines/reference/user/isobject.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/isobject.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/jimp.log b/tests/baselines/reference/user/jimp.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/jimp.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/jsonschema.log b/tests/baselines/reference/user/jsonschema.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/jsonschema.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/keycode.log b/tests/baselines/reference/user/keycode.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/keycode.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/leveldown.log b/tests/baselines/reference/user/leveldown.log new file mode 100644 index 00000000000..c37a983f73d --- /dev/null +++ b/tests/baselines/reference/user/leveldown.log @@ -0,0 +1,20 @@ +Exit Code: 2 +Standard output: +node_modules/abstract-leveldown/index.d.ts(2,3): error TS7010: 'open', which lacks return-type annotation, implicitly has an 'any' return type. +node_modules/abstract-leveldown/index.d.ts(3,3): error TS7010: 'open', which lacks return-type annotation, implicitly has an 'any' return type. +node_modules/abstract-leveldown/index.d.ts(5,3): error TS7010: 'close', which lacks return-type annotation, implicitly has an 'any' return type. +node_modules/abstract-leveldown/index.d.ts(7,3): error TS7010: 'get', which lacks return-type annotation, implicitly has an 'any' return type. +node_modules/abstract-leveldown/index.d.ts(7,26): error TS7006: Parameter 'err' implicitly has an 'any' type. +node_modules/abstract-leveldown/index.d.ts(8,3): error TS7010: 'get', which lacks return-type annotation, implicitly has an 'any' return type. +node_modules/abstract-leveldown/index.d.ts(8,39): error TS7006: Parameter 'err' implicitly has an 'any' type. +node_modules/abstract-leveldown/index.d.ts(10,3): error TS7010: 'put', which lacks return-type annotation, implicitly has an 'any' return type. +node_modules/abstract-leveldown/index.d.ts(11,3): error TS7010: 'put', which lacks return-type annotation, implicitly has an 'any' return type. +node_modules/abstract-leveldown/index.d.ts(13,3): error TS7010: 'del', which lacks return-type annotation, implicitly has an 'any' return type. +node_modules/abstract-leveldown/index.d.ts(14,3): error TS7010: 'del', which lacks return-type annotation, implicitly has an 'any' return type. +node_modules/abstract-leveldown/index.d.ts(17,3): error TS7010: 'batch', which lacks return-type annotation, implicitly has an 'any' return type. +node_modules/abstract-leveldown/index.d.ts(18,3): error TS7010: 'batch', which lacks return-type annotation, implicitly has an 'any' return type. +node_modules/leveldown/leveldown.d.ts(66,3): error TS7010: 'seek', which lacks return-type annotation, implicitly has an 'any' return type. + + + +Standard error: diff --git a/tests/baselines/reference/user/localforage.log b/tests/baselines/reference/user/localforage.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/localforage.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/log4js.log b/tests/baselines/reference/user/log4js.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/log4js.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/mobx.log b/tests/baselines/reference/user/mobx.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/mobx.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/moment.log b/tests/baselines/reference/user/moment.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/moment.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/mqtt.log b/tests/baselines/reference/user/mqtt.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/mqtt.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/parse5.log b/tests/baselines/reference/user/parse5.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/parse5.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/portfinder.log b/tests/baselines/reference/user/portfinder.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/portfinder.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/postcss.log b/tests/baselines/reference/user/postcss.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/postcss.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/protobufjs.log b/tests/baselines/reference/user/protobufjs.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/protobufjs.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/redux.log b/tests/baselines/reference/user/redux.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/redux.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/reselect.log b/tests/baselines/reference/user/reselect.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/reselect.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/rxjs.log b/tests/baselines/reference/user/rxjs.log new file mode 100644 index 00000000000..73058119ce9 --- /dev/null +++ b/tests/baselines/reference/user/rxjs.log @@ -0,0 +1,12 @@ +Exit Code: 2 +Standard output: +node_modules/rxjs/scheduler/VirtualTimeScheduler.d.ts(22,22): error TS2415: Class 'VirtualAction' incorrectly extends base class 'AsyncAction'. + Types of property 'work' are incompatible. + Type '(this: VirtualAction, state?: T | undefined) => void' is not assignable to type '(this: AsyncAction, state?: T | undefined) => void'. + The 'this' types of each signature are incompatible. + Type 'AsyncAction' is not assignable to type 'VirtualAction'. + Property 'index' is missing in type 'AsyncAction'. + + + +Standard error: diff --git a/tests/baselines/reference/user/should.log b/tests/baselines/reference/user/should.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/should.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/sift.log b/tests/baselines/reference/user/sift.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/sift.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/soap.log b/tests/baselines/reference/user/soap.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/soap.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/sugar.log b/tests/baselines/reference/user/sugar.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/sugar.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/tslint.log b/tests/baselines/reference/user/tslint.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/tslint.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/vue.log b/tests/baselines/reference/user/vue.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/vue.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/vuex.log b/tests/baselines/reference/user/vuex.log new file mode 100644 index 00000000000..47a500804bd --- /dev/null +++ b/tests/baselines/reference/user/vuex.log @@ -0,0 +1,7 @@ +Exit Code: 2 +Standard output: +node_modules/vuex/types/index.d.ts(124,16): error TS2714: The expression of an export assignment must be an identifier or qualified name in an ambient context. + + + +Standard error: diff --git a/tests/baselines/reference/user/xlsx.log b/tests/baselines/reference/user/xlsx.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/xlsx.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/xpath.log b/tests/baselines/reference/user/xpath.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/xpath.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/baselines/reference/user/zone.js.log b/tests/baselines/reference/user/zone.js.log new file mode 100644 index 00000000000..15b10503c1f --- /dev/null +++ b/tests/baselines/reference/user/zone.js.log @@ -0,0 +1,6 @@ +Exit Code: 0 +Standard output: + + + +Standard error: diff --git a/tests/cases/user/ajv/index.ts b/tests/cases/user/ajv/index.ts new file mode 100644 index 00000000000..ffcbd04e944 --- /dev/null +++ b/tests/cases/user/ajv/index.ts @@ -0,0 +1 @@ +import ajv = require("ajv"); diff --git a/tests/cases/user/ajv/package.json b/tests/cases/user/ajv/package.json new file mode 100644 index 00000000000..72782496ab0 --- /dev/null +++ b/tests/cases/user/ajv/package.json @@ -0,0 +1,11 @@ +{ + "name": "ajv-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "ajv": "latest" + } +} diff --git a/tests/cases/user/ajv/tsconfig.json b/tests/cases/user/ajv/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/ajv/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/antd/index.ts b/tests/cases/user/antd/index.ts new file mode 100644 index 00000000000..edc6fcfb52e --- /dev/null +++ b/tests/cases/user/antd/index.ts @@ -0,0 +1 @@ +import antd = require("antd"); diff --git a/tests/cases/user/antd/package.json b/tests/cases/user/antd/package.json new file mode 100644 index 00000000000..a20168dd27b --- /dev/null +++ b/tests/cases/user/antd/package.json @@ -0,0 +1,12 @@ +{ + "name": "antd-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "@types/react": "^16.0.18", + "antd": "latest" + } +} diff --git a/tests/cases/user/antd/tsconfig.json b/tests/cases/user/antd/tsconfig.json new file mode 100644 index 00000000000..adbd65f2d00 --- /dev/null +++ b/tests/cases/user/antd/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015", "dom"], + "types": [], + "allowSyntheticDefaultImports": true + } +} diff --git a/tests/cases/user/axios/index.ts b/tests/cases/user/axios/index.ts new file mode 100644 index 00000000000..43a4bf8d5d0 --- /dev/null +++ b/tests/cases/user/axios/index.ts @@ -0,0 +1 @@ +import axios = require("axios"); diff --git a/tests/cases/user/axios/package.json b/tests/cases/user/axios/package.json new file mode 100644 index 00000000000..b4cc25a9b97 --- /dev/null +++ b/tests/cases/user/axios/package.json @@ -0,0 +1,11 @@ +{ + "name": "axios-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "axios": "latest" + } +} diff --git a/tests/cases/user/axios/tsconfig.json b/tests/cases/user/axios/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/axios/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/bignumber.js/index.ts b/tests/cases/user/bignumber.js/index.ts new file mode 100644 index 00000000000..fbbbc4c0661 --- /dev/null +++ b/tests/cases/user/bignumber.js/index.ts @@ -0,0 +1 @@ +import bignumber_js = require("bignumber.js"); diff --git a/tests/cases/user/bignumber.js/package.json b/tests/cases/user/bignumber.js/package.json new file mode 100644 index 00000000000..8b5fea49297 --- /dev/null +++ b/tests/cases/user/bignumber.js/package.json @@ -0,0 +1,11 @@ +{ + "name": "bignumber.js-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "bignumber.js": "latest" + } +} diff --git a/tests/cases/user/bignumber.js/tsconfig.json b/tests/cases/user/bignumber.js/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/bignumber.js/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/discord.js/index.ts b/tests/cases/user/discord.js/index.ts new file mode 100644 index 00000000000..e86cef98fb0 --- /dev/null +++ b/tests/cases/user/discord.js/index.ts @@ -0,0 +1 @@ +import discord_js = require("discord.js"); diff --git a/tests/cases/user/discord.js/package.json b/tests/cases/user/discord.js/package.json new file mode 100644 index 00000000000..c78d4cd0645 --- /dev/null +++ b/tests/cases/user/discord.js/package.json @@ -0,0 +1,12 @@ +{ + "name": "discord.js-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "@types/node": "^8.0.47", + "discord.js": "latest" + } +} diff --git a/tests/cases/user/discord.js/tsconfig.json b/tests/cases/user/discord.js/tsconfig.json new file mode 100644 index 00000000000..a8a84f5c5fe --- /dev/null +++ b/tests/cases/user/discord.js/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": ["node"] + } +} diff --git a/tests/cases/user/electron/index.ts b/tests/cases/user/electron/index.ts new file mode 100644 index 00000000000..c8af4b993ff --- /dev/null +++ b/tests/cases/user/electron/index.ts @@ -0,0 +1 @@ +import electron = require("electron"); diff --git a/tests/cases/user/electron/package.json b/tests/cases/user/electron/package.json new file mode 100644 index 00000000000..3113f8bd03b --- /dev/null +++ b/tests/cases/user/electron/package.json @@ -0,0 +1,11 @@ +{ + "name": "electron-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "electron": "latest" + } +} diff --git a/tests/cases/user/electron/tsconfig.json b/tests/cases/user/electron/tsconfig.json new file mode 100644 index 00000000000..aa10372d8d1 --- /dev/null +++ b/tests/cases/user/electron/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015", "dom"], + "types": [] + } +} diff --git a/tests/cases/user/eventemitter2/index.ts b/tests/cases/user/eventemitter2/index.ts new file mode 100644 index 00000000000..c68cae71e50 --- /dev/null +++ b/tests/cases/user/eventemitter2/index.ts @@ -0,0 +1 @@ +import eventemitter2 = require("eventemitter2"); diff --git a/tests/cases/user/eventemitter2/package.json b/tests/cases/user/eventemitter2/package.json new file mode 100644 index 00000000000..7a1fb9e04f8 --- /dev/null +++ b/tests/cases/user/eventemitter2/package.json @@ -0,0 +1,11 @@ +{ + "name": "eventemitter2-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "eventemitter2": "latest" + } +} diff --git a/tests/cases/user/eventemitter2/tsconfig.json b/tests/cases/user/eventemitter2/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/eventemitter2/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/eventemitter3/index.ts b/tests/cases/user/eventemitter3/index.ts new file mode 100644 index 00000000000..1ef33830f09 --- /dev/null +++ b/tests/cases/user/eventemitter3/index.ts @@ -0,0 +1 @@ +import eventemitter3 = require("eventemitter3"); diff --git a/tests/cases/user/eventemitter3/package.json b/tests/cases/user/eventemitter3/package.json new file mode 100644 index 00000000000..7b401395c6a --- /dev/null +++ b/tests/cases/user/eventemitter3/package.json @@ -0,0 +1,11 @@ +{ + "name": "eventemitter3-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "eventemitter3": "latest" + } +} diff --git a/tests/cases/user/eventemitter3/tsconfig.json b/tests/cases/user/eventemitter3/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/eventemitter3/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/firebase/index.ts b/tests/cases/user/firebase/index.ts new file mode 100644 index 00000000000..dfd40bf009d --- /dev/null +++ b/tests/cases/user/firebase/index.ts @@ -0,0 +1 @@ +import firebase = require("firebase"); diff --git a/tests/cases/user/firebase/package.json b/tests/cases/user/firebase/package.json new file mode 100644 index 00000000000..11fb1d2ea7e --- /dev/null +++ b/tests/cases/user/firebase/package.json @@ -0,0 +1,11 @@ +{ + "name": "firebase-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "firebase": "latest" + } +} diff --git a/tests/cases/user/firebase/tsconfig.json b/tests/cases/user/firebase/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/firebase/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/github/index.ts b/tests/cases/user/github/index.ts new file mode 100644 index 00000000000..90e2253381c --- /dev/null +++ b/tests/cases/user/github/index.ts @@ -0,0 +1 @@ +import github = require("github"); diff --git a/tests/cases/user/github/package.json b/tests/cases/user/github/package.json new file mode 100644 index 00000000000..37a0181865f --- /dev/null +++ b/tests/cases/user/github/package.json @@ -0,0 +1,11 @@ +{ + "name": "github-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "github": "latest" + } +} diff --git a/tests/cases/user/github/tsconfig.json b/tests/cases/user/github/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/github/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/immutable/index.ts b/tests/cases/user/immutable/index.ts new file mode 100644 index 00000000000..b5fb927e459 --- /dev/null +++ b/tests/cases/user/immutable/index.ts @@ -0,0 +1 @@ +import immutable = require("immutable"); diff --git a/tests/cases/user/immutable/package.json b/tests/cases/user/immutable/package.json new file mode 100644 index 00000000000..fb869e488ea --- /dev/null +++ b/tests/cases/user/immutable/package.json @@ -0,0 +1,11 @@ +{ + "name": "immutable-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "immutable": "latest" + } +} diff --git a/tests/cases/user/immutable/tsconfig.json b/tests/cases/user/immutable/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/immutable/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/isobject/index.ts b/tests/cases/user/isobject/index.ts new file mode 100644 index 00000000000..92b08ff4825 --- /dev/null +++ b/tests/cases/user/isobject/index.ts @@ -0,0 +1 @@ +import isobject = require("isobject"); diff --git a/tests/cases/user/isobject/package.json b/tests/cases/user/isobject/package.json new file mode 100644 index 00000000000..b1501180526 --- /dev/null +++ b/tests/cases/user/isobject/package.json @@ -0,0 +1,11 @@ +{ + "name": "isobject-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "isobject": "latest" + } +} diff --git a/tests/cases/user/isobject/tsconfig.json b/tests/cases/user/isobject/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/isobject/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/jimp/index.ts b/tests/cases/user/jimp/index.ts new file mode 100644 index 00000000000..6a7d51414aa --- /dev/null +++ b/tests/cases/user/jimp/index.ts @@ -0,0 +1 @@ +import jimp = require("jimp"); diff --git a/tests/cases/user/jimp/package.json b/tests/cases/user/jimp/package.json new file mode 100644 index 00000000000..18ebc2933e3 --- /dev/null +++ b/tests/cases/user/jimp/package.json @@ -0,0 +1,11 @@ +{ + "name": "jimp-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "jimp": "latest" + } +} diff --git a/tests/cases/user/jimp/tsconfig.json b/tests/cases/user/jimp/tsconfig.json new file mode 100644 index 00000000000..a8a84f5c5fe --- /dev/null +++ b/tests/cases/user/jimp/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": ["node"] + } +} diff --git a/tests/cases/user/jsonschema/index.ts b/tests/cases/user/jsonschema/index.ts new file mode 100644 index 00000000000..0cab63413a5 --- /dev/null +++ b/tests/cases/user/jsonschema/index.ts @@ -0,0 +1 @@ +import jsonschema = require("jsonschema"); diff --git a/tests/cases/user/jsonschema/package.json b/tests/cases/user/jsonschema/package.json new file mode 100644 index 00000000000..daf42c5c0c7 --- /dev/null +++ b/tests/cases/user/jsonschema/package.json @@ -0,0 +1,11 @@ +{ + "name": "jsonschema-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "jsonschema": "latest" + } +} diff --git a/tests/cases/user/jsonschema/tsconfig.json b/tests/cases/user/jsonschema/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/jsonschema/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/keycode/index.ts b/tests/cases/user/keycode/index.ts new file mode 100644 index 00000000000..cfa11252ecb --- /dev/null +++ b/tests/cases/user/keycode/index.ts @@ -0,0 +1 @@ +import keycode = require("keycode"); diff --git a/tests/cases/user/keycode/package.json b/tests/cases/user/keycode/package.json new file mode 100644 index 00000000000..73280239eb0 --- /dev/null +++ b/tests/cases/user/keycode/package.json @@ -0,0 +1,12 @@ +{ + "name": "keycode-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "@types/node": "^8.0.47", + "keycode": "latest" + } +} diff --git a/tests/cases/user/keycode/tsconfig.json b/tests/cases/user/keycode/tsconfig.json new file mode 100644 index 00000000000..aa10372d8d1 --- /dev/null +++ b/tests/cases/user/keycode/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015", "dom"], + "types": [] + } +} diff --git a/tests/cases/user/leveldown/index.ts b/tests/cases/user/leveldown/index.ts new file mode 100644 index 00000000000..c595cfc3198 --- /dev/null +++ b/tests/cases/user/leveldown/index.ts @@ -0,0 +1 @@ +import leveldown = require("leveldown"); diff --git a/tests/cases/user/leveldown/package.json b/tests/cases/user/leveldown/package.json new file mode 100644 index 00000000000..4ee61ed4ba4 --- /dev/null +++ b/tests/cases/user/leveldown/package.json @@ -0,0 +1,12 @@ +{ + "name": "leveldown-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "@types/node": "^8.0.47", + "leveldown": "latest" + } +} diff --git a/tests/cases/user/leveldown/tsconfig.json b/tests/cases/user/leveldown/tsconfig.json new file mode 100644 index 00000000000..a8a84f5c5fe --- /dev/null +++ b/tests/cases/user/leveldown/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": ["node"] + } +} diff --git a/tests/cases/user/localforage/index.ts b/tests/cases/user/localforage/index.ts new file mode 100644 index 00000000000..dad26db93e3 --- /dev/null +++ b/tests/cases/user/localforage/index.ts @@ -0,0 +1 @@ +import localforage = require("localforage"); diff --git a/tests/cases/user/localforage/package.json b/tests/cases/user/localforage/package.json new file mode 100644 index 00000000000..f02b0e02fb2 --- /dev/null +++ b/tests/cases/user/localforage/package.json @@ -0,0 +1,11 @@ +{ + "name": "localforage-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "localforage": "latest" + } +} diff --git a/tests/cases/user/localforage/tsconfig.json b/tests/cases/user/localforage/tsconfig.json new file mode 100644 index 00000000000..aa10372d8d1 --- /dev/null +++ b/tests/cases/user/localforage/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015", "dom"], + "types": [] + } +} diff --git a/tests/cases/user/log4js/index.ts b/tests/cases/user/log4js/index.ts new file mode 100644 index 00000000000..dbafe63e9dd --- /dev/null +++ b/tests/cases/user/log4js/index.ts @@ -0,0 +1 @@ +import log4js = require("log4js"); diff --git a/tests/cases/user/log4js/package.json b/tests/cases/user/log4js/package.json new file mode 100644 index 00000000000..1c5161081a7 --- /dev/null +++ b/tests/cases/user/log4js/package.json @@ -0,0 +1,11 @@ +{ + "name": "log4js-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "log4js": "latest" + } +} diff --git a/tests/cases/user/log4js/tsconfig.json b/tests/cases/user/log4js/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/log4js/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/mobx/index.ts b/tests/cases/user/mobx/index.ts new file mode 100644 index 00000000000..b1cdddab88e --- /dev/null +++ b/tests/cases/user/mobx/index.ts @@ -0,0 +1 @@ +import mobx = require("mobx"); diff --git a/tests/cases/user/mobx/package.json b/tests/cases/user/mobx/package.json new file mode 100644 index 00000000000..99806321aa5 --- /dev/null +++ b/tests/cases/user/mobx/package.json @@ -0,0 +1,11 @@ +{ + "name": "mobx-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "mobx": "latest" + } +} diff --git a/tests/cases/user/mobx/tsconfig.json b/tests/cases/user/mobx/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/mobx/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/moment/index.ts b/tests/cases/user/moment/index.ts new file mode 100644 index 00000000000..7ea0c0f0abc --- /dev/null +++ b/tests/cases/user/moment/index.ts @@ -0,0 +1 @@ +import moment = require("moment"); diff --git a/tests/cases/user/moment/package.json b/tests/cases/user/moment/package.json new file mode 100644 index 00000000000..fddf99c1c11 --- /dev/null +++ b/tests/cases/user/moment/package.json @@ -0,0 +1,11 @@ +{ + "name": "moment-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "moment": "latest" + } +} diff --git a/tests/cases/user/moment/tsconfig.json b/tests/cases/user/moment/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/moment/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/mqtt/index.ts b/tests/cases/user/mqtt/index.ts new file mode 100644 index 00000000000..322527ef757 --- /dev/null +++ b/tests/cases/user/mqtt/index.ts @@ -0,0 +1 @@ +import mqtt = require("mqtt"); diff --git a/tests/cases/user/mqtt/package.json b/tests/cases/user/mqtt/package.json new file mode 100644 index 00000000000..072c255d571 --- /dev/null +++ b/tests/cases/user/mqtt/package.json @@ -0,0 +1,11 @@ +{ + "name": "mqtt-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "mqtt": "latest" + } +} diff --git a/tests/cases/user/mqtt/tsconfig.json b/tests/cases/user/mqtt/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/mqtt/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/parse5/index.ts b/tests/cases/user/parse5/index.ts new file mode 100644 index 00000000000..c640ea4f9cb --- /dev/null +++ b/tests/cases/user/parse5/index.ts @@ -0,0 +1 @@ +import parse5 = require("parse5"); diff --git a/tests/cases/user/parse5/package.json b/tests/cases/user/parse5/package.json new file mode 100644 index 00000000000..4b0aa84c0f3 --- /dev/null +++ b/tests/cases/user/parse5/package.json @@ -0,0 +1,11 @@ +{ + "name": "parse5-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "parse5": "latest" + } +} diff --git a/tests/cases/user/parse5/tsconfig.json b/tests/cases/user/parse5/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/parse5/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/portfinder/index.ts b/tests/cases/user/portfinder/index.ts new file mode 100644 index 00000000000..9fafbff4adb --- /dev/null +++ b/tests/cases/user/portfinder/index.ts @@ -0,0 +1 @@ +import portfinder = require("portfinder"); diff --git a/tests/cases/user/portfinder/package.json b/tests/cases/user/portfinder/package.json new file mode 100644 index 00000000000..e7431dce9a2 --- /dev/null +++ b/tests/cases/user/portfinder/package.json @@ -0,0 +1,11 @@ +{ + "name": "portfinder-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "portfinder": "latest" + } +} diff --git a/tests/cases/user/portfinder/tsconfig.json b/tests/cases/user/portfinder/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/portfinder/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/postcss/index.ts b/tests/cases/user/postcss/index.ts new file mode 100644 index 00000000000..e1480858fcd --- /dev/null +++ b/tests/cases/user/postcss/index.ts @@ -0,0 +1 @@ +import postcss = require("postcss"); diff --git a/tests/cases/user/postcss/package.json b/tests/cases/user/postcss/package.json new file mode 100644 index 00000000000..3c87e7357cd --- /dev/null +++ b/tests/cases/user/postcss/package.json @@ -0,0 +1,11 @@ +{ + "name": "postcss-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "postcss": "latest" + } +} diff --git a/tests/cases/user/postcss/tsconfig.json b/tests/cases/user/postcss/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/postcss/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/protobufjs/index.ts b/tests/cases/user/protobufjs/index.ts new file mode 100644 index 00000000000..cbbc52231d7 --- /dev/null +++ b/tests/cases/user/protobufjs/index.ts @@ -0,0 +1 @@ +import protobufjs = require("protobufjs"); diff --git a/tests/cases/user/protobufjs/package.json b/tests/cases/user/protobufjs/package.json new file mode 100644 index 00000000000..20201e3728e --- /dev/null +++ b/tests/cases/user/protobufjs/package.json @@ -0,0 +1,11 @@ +{ + "name": "protobufjs-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "protobufjs": "latest" + } +} diff --git a/tests/cases/user/protobufjs/tsconfig.json b/tests/cases/user/protobufjs/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/protobufjs/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/redux/index.ts b/tests/cases/user/redux/index.ts new file mode 100644 index 00000000000..0475efa0567 --- /dev/null +++ b/tests/cases/user/redux/index.ts @@ -0,0 +1 @@ +import redux = require("redux"); diff --git a/tests/cases/user/redux/package.json b/tests/cases/user/redux/package.json new file mode 100644 index 00000000000..c31108bcd95 --- /dev/null +++ b/tests/cases/user/redux/package.json @@ -0,0 +1,11 @@ +{ + "name": "redux-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "redux": "latest" + } +} diff --git a/tests/cases/user/redux/tsconfig.json b/tests/cases/user/redux/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/redux/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/reselect/index.ts b/tests/cases/user/reselect/index.ts new file mode 100644 index 00000000000..ee93d241169 --- /dev/null +++ b/tests/cases/user/reselect/index.ts @@ -0,0 +1 @@ +import reselect = require("reselect"); diff --git a/tests/cases/user/reselect/package.json b/tests/cases/user/reselect/package.json new file mode 100644 index 00000000000..fc335b32cc4 --- /dev/null +++ b/tests/cases/user/reselect/package.json @@ -0,0 +1,11 @@ +{ + "name": "reselect-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "reselect": "latest" + } +} diff --git a/tests/cases/user/reselect/tsconfig.json b/tests/cases/user/reselect/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/reselect/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/rxjs/index.ts b/tests/cases/user/rxjs/index.ts new file mode 100644 index 00000000000..41418158bc5 --- /dev/null +++ b/tests/cases/user/rxjs/index.ts @@ -0,0 +1 @@ +import rxjs = require("rxjs"); diff --git a/tests/cases/user/rxjs/package.json b/tests/cases/user/rxjs/package.json new file mode 100644 index 00000000000..1d006ed3c42 --- /dev/null +++ b/tests/cases/user/rxjs/package.json @@ -0,0 +1,11 @@ +{ + "name": "rxjs-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "rxjs": "latest" + } +} diff --git a/tests/cases/user/rxjs/tsconfig.json b/tests/cases/user/rxjs/tsconfig.json new file mode 100644 index 00000000000..aa10372d8d1 --- /dev/null +++ b/tests/cases/user/rxjs/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015", "dom"], + "types": [] + } +} diff --git a/tests/cases/user/should/index.ts b/tests/cases/user/should/index.ts new file mode 100644 index 00000000000..66e1a7aadfc --- /dev/null +++ b/tests/cases/user/should/index.ts @@ -0,0 +1 @@ +import should = require("should"); diff --git a/tests/cases/user/should/package.json b/tests/cases/user/should/package.json new file mode 100644 index 00000000000..8674a9f4f38 --- /dev/null +++ b/tests/cases/user/should/package.json @@ -0,0 +1,11 @@ +{ + "name": "should-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "should": "latest" + } +} diff --git a/tests/cases/user/should/tsconfig.json b/tests/cases/user/should/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/should/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/sift/index.ts b/tests/cases/user/sift/index.ts new file mode 100644 index 00000000000..383f18d1b7d --- /dev/null +++ b/tests/cases/user/sift/index.ts @@ -0,0 +1 @@ +import sift = require("sift"); diff --git a/tests/cases/user/sift/package.json b/tests/cases/user/sift/package.json new file mode 100644 index 00000000000..344b2d73d11 --- /dev/null +++ b/tests/cases/user/sift/package.json @@ -0,0 +1,11 @@ +{ + "name": "sift-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "sift": "latest" + } +} diff --git a/tests/cases/user/sift/tsconfig.json b/tests/cases/user/sift/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/sift/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/soap/index.ts b/tests/cases/user/soap/index.ts new file mode 100644 index 00000000000..d056570add2 --- /dev/null +++ b/tests/cases/user/soap/index.ts @@ -0,0 +1 @@ +import soap = require("soap"); diff --git a/tests/cases/user/soap/package.json b/tests/cases/user/soap/package.json new file mode 100644 index 00000000000..5882bdeea5c --- /dev/null +++ b/tests/cases/user/soap/package.json @@ -0,0 +1,12 @@ +{ + "name": "soap-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "@types/bluebird": "^3.5.17", + "soap": "latest" + } +} diff --git a/tests/cases/user/soap/tsconfig.json b/tests/cases/user/soap/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/soap/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/sugar/index.ts b/tests/cases/user/sugar/index.ts new file mode 100644 index 00000000000..2f959bdf704 --- /dev/null +++ b/tests/cases/user/sugar/index.ts @@ -0,0 +1 @@ +import sugar = require("sugar"); diff --git a/tests/cases/user/sugar/package.json b/tests/cases/user/sugar/package.json new file mode 100644 index 00000000000..c1708049b62 --- /dev/null +++ b/tests/cases/user/sugar/package.json @@ -0,0 +1,11 @@ +{ + "name": "sugar-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "sugar": "latest" + } +} diff --git a/tests/cases/user/sugar/tsconfig.json b/tests/cases/user/sugar/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/sugar/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/tslint/index.ts b/tests/cases/user/tslint/index.ts new file mode 100644 index 00000000000..249b3a054f6 --- /dev/null +++ b/tests/cases/user/tslint/index.ts @@ -0,0 +1 @@ +import tslint = require("tslint"); \ No newline at end of file diff --git a/tests/cases/user/tslint/package.json b/tests/cases/user/tslint/package.json new file mode 100644 index 00000000000..41a315e5110 --- /dev/null +++ b/tests/cases/user/tslint/package.json @@ -0,0 +1,27 @@ +{ + "name": "tslint-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "tslint": "latest", + "typescript": "latest" + }, + "devDependencies": { + "@types/babel-code-frame": "latest", + "@types/chai": "latest", + "@types/chalk": "latest", + "@types/commander": "latest", + "@types/diff": "latest", + "@types/glob": "latest", + "@types/js-yaml": "latest", + "@types/minimatch": "latest", + "@types/mocha": "latest", + "@types/node": "latest", + "@types/resolve": "latest", + "@types/rimraf": "latest", + "@types/semver": "latest" + } +} diff --git a/tests/cases/user/tslint/tsconfig.json b/tests/cases/user/tslint/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/tslint/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/vue/index.ts b/tests/cases/user/vue/index.ts new file mode 100644 index 00000000000..385522edcd9 --- /dev/null +++ b/tests/cases/user/vue/index.ts @@ -0,0 +1 @@ +import vue = require("vue"); diff --git a/tests/cases/user/vue/package.json b/tests/cases/user/vue/package.json new file mode 100644 index 00000000000..69df82e9e0a --- /dev/null +++ b/tests/cases/user/vue/package.json @@ -0,0 +1,11 @@ +{ + "name": "vue-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "vue": "latest" + } +} diff --git a/tests/cases/user/vue/tsconfig.json b/tests/cases/user/vue/tsconfig.json new file mode 100644 index 00000000000..aa10372d8d1 --- /dev/null +++ b/tests/cases/user/vue/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015", "dom"], + "types": [] + } +} diff --git a/tests/cases/user/vuex/index.ts b/tests/cases/user/vuex/index.ts new file mode 100644 index 00000000000..26e6c2efe19 --- /dev/null +++ b/tests/cases/user/vuex/index.ts @@ -0,0 +1 @@ +import vuex = require("vuex"); diff --git a/tests/cases/user/vuex/package.json b/tests/cases/user/vuex/package.json new file mode 100644 index 00000000000..83d6c53c152 --- /dev/null +++ b/tests/cases/user/vuex/package.json @@ -0,0 +1,12 @@ +{ + "name": "vuex-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "vue": "^2.5.2", + "vuex": "latest" + } +} diff --git a/tests/cases/user/vuex/tsconfig.json b/tests/cases/user/vuex/tsconfig.json new file mode 100644 index 00000000000..aa10372d8d1 --- /dev/null +++ b/tests/cases/user/vuex/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015", "dom"], + "types": [] + } +} diff --git a/tests/cases/user/xlsx/index.ts b/tests/cases/user/xlsx/index.ts new file mode 100644 index 00000000000..bf5e78c75a7 --- /dev/null +++ b/tests/cases/user/xlsx/index.ts @@ -0,0 +1 @@ +import xlsx = require("xlsx"); diff --git a/tests/cases/user/xlsx/package.json b/tests/cases/user/xlsx/package.json new file mode 100644 index 00000000000..398ba78ff69 --- /dev/null +++ b/tests/cases/user/xlsx/package.json @@ -0,0 +1,11 @@ +{ + "name": "xlsx-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "xlsx": "latest" + } +} diff --git a/tests/cases/user/xlsx/tsconfig.json b/tests/cases/user/xlsx/tsconfig.json new file mode 100644 index 00000000000..cd66d349e94 --- /dev/null +++ b/tests/cases/user/xlsx/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + } +} \ No newline at end of file diff --git a/tests/cases/user/xpath/index.ts b/tests/cases/user/xpath/index.ts new file mode 100644 index 00000000000..b747fe100fb --- /dev/null +++ b/tests/cases/user/xpath/index.ts @@ -0,0 +1 @@ +import xpath = require("xpath"); diff --git a/tests/cases/user/xpath/package.json b/tests/cases/user/xpath/package.json new file mode 100644 index 00000000000..c97f1c46656 --- /dev/null +++ b/tests/cases/user/xpath/package.json @@ -0,0 +1,11 @@ +{ + "name": "xpath-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "xpath": "latest" + } +} diff --git a/tests/cases/user/xpath/tsconfig.json b/tests/cases/user/xpath/tsconfig.json new file mode 100644 index 00000000000..aa10372d8d1 --- /dev/null +++ b/tests/cases/user/xpath/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015", "dom"], + "types": [] + } +} diff --git a/tests/cases/user/zone.js/index.ts b/tests/cases/user/zone.js/index.ts new file mode 100644 index 00000000000..533d8a07e1d --- /dev/null +++ b/tests/cases/user/zone.js/index.ts @@ -0,0 +1 @@ +Zone.assertZonePatched diff --git a/tests/cases/user/zone.js/package.json b/tests/cases/user/zone.js/package.json new file mode 100644 index 00000000000..3828f62559e --- /dev/null +++ b/tests/cases/user/zone.js/package.json @@ -0,0 +1,11 @@ +{ + "name": "zone.js-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "zone.js": "latest" + } +} diff --git a/tests/cases/user/zone.js/tsconfig.json b/tests/cases/user/zone.js/tsconfig.json new file mode 100644 index 00000000000..3eff28851c6 --- /dev/null +++ b/tests/cases/user/zone.js/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "strict": true, + "lib": ["es2015"], + "types": [] + }, + "files": [ + "index.ts", + "node_modules/zone.js/dist/zone.js.d.ts" + ] +} From 1a7a587a9ea11371c3748a632ac7613d20d1e5d2 Mon Sep 17 00:00:00 2001 From: Mike Morearty Date: Wed, 1 Nov 2017 16:37:06 -0700 Subject: [PATCH 075/235] Fix TokenOrIdentifierObject.getText() crash (#19673) TokenOrIdentifierObject.getText() needs to pass `sourceFile` as an argument to `getStart()`. Fixes https://github.com/Microsoft/TypeScript/issues/19670 --- src/services/services.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/services/services.ts b/src/services/services.ts index 06edd621e96..cd6fe867711 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -276,7 +276,10 @@ namespace ts { } public getText(sourceFile?: SourceFile): string { - return (sourceFile || this.getSourceFile()).text.substring(this.getStart(), this.getEnd()); + if (!sourceFile) { + sourceFile = this.getSourceFile(); + } + return sourceFile.text.substring(this.getStart(sourceFile), this.getEnd()); } public getChildCount(): number { From 509b9ad087c7368d5c27d3fdd4d6feefeae9e8af Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Thu, 2 Nov 2017 09:55:56 -0700 Subject: [PATCH 076/235] Complete to single line jsdoc comment if no params --- src/services/jsDoc.ts | 31 ++++++------ .../docCommentTemplateClassDecl01.ts | 7 +-- .../docCommentTemplateClassDeclMethods01.ts | 14 ++---- .../docCommentTemplateClassDeclMethods02.ts | 7 ++- .../docCommentTemplateIndentation.ts | 13 ++--- .../docCommentTemplateInterfacesAndEnums.ts | 50 ------------------- ...ntTemplateInterfacesEnumsAndTypeAliases.ts | 49 ++++++++++++++++++ ...ocCommentTemplateNamespacesAndModules01.ts | 18 +++---- ...ocCommentTemplateNamespacesAndModules02.ts | 6 +-- ...ocCommentTemplateObjectLiteralMethods01.ts | 7 ++- .../docCommentTemplateVariableStatements01.ts | 6 +-- .../docCommentTemplateVariableStatements02.ts | 6 +-- .../docCommentTemplateVariableStatements03.ts | 12 ++--- 13 files changed, 99 insertions(+), 127 deletions(-) delete mode 100644 tests/cases/fourslash/docCommentTemplateInterfacesAndEnums.ts create mode 100644 tests/cases/fourslash/docCommentTemplateInterfacesEnumsAndTypeAliases.ts diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 622463d96fa..f1e06a0ffe4 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -212,6 +212,12 @@ namespace ts.JsDoc { return emptyDocComment; } + if (!parameters || parameters.length === 0) { + // if there are no parameters, just complete to a single line JSDoc comment + const singleLineResult = "/** */"; + return { newText: singleLineResult, caretOffset: 3 }; + } + const posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position); const lineStart = sourceFile.getLineStarts()[posLineAndChar.line]; @@ -220,18 +226,16 @@ namespace ts.JsDoc { const isJavaScriptFile = hasJavaScriptFileExtension(sourceFile.fileName); let docParams = ""; - if (parameters) { - for (let i = 0; i < parameters.length; i++) { - const currentName = parameters[i].name; - const paramName = currentName.kind === SyntaxKind.Identifier ? - (currentName).escapedText : - "param" + i; - if (isJavaScriptFile) { - docParams += `${indentationStr} * @param {any} ${paramName}${newLine}`; - } - else { - docParams += `${indentationStr} * @param ${paramName}${newLine}`; - } + for (let i = 0; i < parameters.length; i++) { + const currentName = parameters[i].name; + const paramName = currentName.kind === SyntaxKind.Identifier ? + (currentName).escapedText : + "param" + i; + if (isJavaScriptFile) { + docParams += `${indentationStr} * @param {any} ${paramName}${newLine}`; + } + else { + docParams += `${indentationStr} * @param ${paramName}${newLine}`; } } @@ -258,8 +262,6 @@ namespace ts.JsDoc { readonly parameters?: ReadonlyArray; } function getCommentOwnerInfo(tokenAtPos: Node): CommentOwnerInfo | undefined { - // TODO: add support for: - // - potentially property assignments for (let commentOwner = tokenAtPos; commentOwner; commentOwner = commentOwner.parent) { switch (commentOwner.kind) { case SyntaxKind.FunctionDeclaration: @@ -274,6 +276,7 @@ namespace ts.JsDoc { case SyntaxKind.PropertySignature: case SyntaxKind.EnumDeclaration: case SyntaxKind.EnumMember: + case SyntaxKind.TypeAliasDeclaration: return { commentOwner }; case SyntaxKind.VariableStatement: { diff --git a/tests/cases/fourslash/docCommentTemplateClassDecl01.ts b/tests/cases/fourslash/docCommentTemplateClassDecl01.ts index 5a96f20d2e2..342d35a3b4a 100644 --- a/tests/cases/fourslash/docCommentTemplateClassDecl01.ts +++ b/tests/cases/fourslash/docCommentTemplateClassDecl01.ts @@ -11,8 +11,5 @@ //// } ////} -verify.docCommentTemplateAt("decl", /*newTextOffset*/ 8, -`/** - * - */ -`); +verify.docCommentTemplateAt("decl", /*newTextOffset*/ 3, +"/** */"); diff --git a/tests/cases/fourslash/docCommentTemplateClassDeclMethods01.ts b/tests/cases/fourslash/docCommentTemplateClassDeclMethods01.ts index ef4c82e7df7..34e55875676 100644 --- a/tests/cases/fourslash/docCommentTemplateClassDeclMethods01.ts +++ b/tests/cases/fourslash/docCommentTemplateClassDeclMethods01.ts @@ -1,7 +1,7 @@ /// const enum Indentation { - Standard = 8, + Standard = 3, Indented = 12, } @@ -17,15 +17,11 @@ const enum Indentation { ////} verify.docCommentTemplateAt("0", Indentation.Standard, -`/** - * - */`); +"/** */"); -verify.docCommentTemplateAt("1", Indentation.Indented, - `/** - * - */`); +verify.docCommentTemplateAt("1", Indentation.Standard, +"/** */"); verify.docCommentTemplateAt("2", Indentation.Indented, @@ -51,7 +47,7 @@ verify.docCommentTemplateAt("4", Indentation.Indented, * @param param2 */`); -verify.docCommentTemplateAt("5", Indentation.Indented, +verify.docCommentTemplateAt("5", Indentation.Indented, `/** * * @param a diff --git a/tests/cases/fourslash/docCommentTemplateClassDeclMethods02.ts b/tests/cases/fourslash/docCommentTemplateClassDeclMethods02.ts index 28da24d381a..a16fbd86064 100644 --- a/tests/cases/fourslash/docCommentTemplateClassDeclMethods02.ts +++ b/tests/cases/fourslash/docCommentTemplateClassDeclMethods02.ts @@ -1,6 +1,7 @@ /// const enum Indentation { + Standard = 3, Indented = 12, } @@ -13,10 +14,8 @@ const enum Indentation { //// [1 + 2 + 3 + Math.rand()](x: number, y: string, z = true) { } ////} -verify.docCommentTemplateAt("0", Indentation.Indented, - `/** - * - */`); +verify.docCommentTemplateAt("0", Indentation.Standard, +"/** */"); verify.docCommentTemplateAt("1", Indentation.Indented, `/** diff --git a/tests/cases/fourslash/docCommentTemplateIndentation.ts b/tests/cases/fourslash/docCommentTemplateIndentation.ts index c3015a6d9dd..bc909aa0265 100644 --- a/tests/cases/fourslash/docCommentTemplateIndentation.ts +++ b/tests/cases/fourslash/docCommentTemplateIndentation.ts @@ -5,13 +5,8 @@ //// /*1*/ /////*0*/ function foo() { } -const noIndentEmptyScaffolding = "/**\r\n * \r\n */"; -const oneIndentEmptyScaffolding = "/**\r\n * \r\n */"; -const twoIndentEmptyScaffolding = "/**\r\n * \r\n */"; -const noIndentOffset = 8; -const oneIndentOffset = noIndentOffset + 4; -const twoIndentOffset = oneIndentOffset + 4; +const singleLineComment = "/** */"; -verify.docCommentTemplateAt("0", noIndentOffset, noIndentEmptyScaffolding); -verify.docCommentTemplateAt("1", oneIndentOffset, oneIndentEmptyScaffolding); -verify.docCommentTemplateAt("2", twoIndentOffset, twoIndentEmptyScaffolding); +verify.docCommentTemplateAt("0", 3, singleLineComment); +verify.docCommentTemplateAt("1", 3, singleLineComment); +verify.docCommentTemplateAt("2", 3, singleLineComment); diff --git a/tests/cases/fourslash/docCommentTemplateInterfacesAndEnums.ts b/tests/cases/fourslash/docCommentTemplateInterfacesAndEnums.ts deleted file mode 100644 index ed10ba86d98..00000000000 --- a/tests/cases/fourslash/docCommentTemplateInterfacesAndEnums.ts +++ /dev/null @@ -1,50 +0,0 @@ -/// - -/////*interfaceFoo*/ -////interface Foo { -//// /*propertybar*/ -//// bar: any; -//// -//// /*methodbaz*/ -//// baz(message: any): void; -////} -//// -/////*enumStatus*/ -////const enum Status { -//// /*memberOpen*/ -//// Open, -//// -//// /*memberClosed*/ -//// Closed -////} - -verify.docCommentTemplateAt("interfaceFoo", /*expectedOffset*/ 8, -`/** - * - */`); - -verify.docCommentTemplateAt("propertybar", /*expectedOffset*/ 12, - `/** - * - */`); - -verify.docCommentTemplateAt("methodbaz", /*expectedOffset*/ 12, - `/** - * - * @param message - */`); - -verify.docCommentTemplateAt("enumStatus", /*expectedOffset*/ 8, -`/** - * - */`); - -verify.docCommentTemplateAt("memberOpen", /*expectedOffset*/ 12, - `/** - * - */`); - -verify.docCommentTemplateAt("memberClosed", /*expectedOffset*/ 12, - `/** - * - */`); \ No newline at end of file diff --git a/tests/cases/fourslash/docCommentTemplateInterfacesEnumsAndTypeAliases.ts b/tests/cases/fourslash/docCommentTemplateInterfacesEnumsAndTypeAliases.ts new file mode 100644 index 00000000000..d0805d53255 --- /dev/null +++ b/tests/cases/fourslash/docCommentTemplateInterfacesEnumsAndTypeAliases.ts @@ -0,0 +1,49 @@ +/// + +/////*interfaceFoo*/ +////interface Foo { +//// /*propertybar*/ +//// bar: any; +//// +//// /*methodbaz*/ +//// baz(message: any): void; +//// +//// /*methodUnit*/ +//// unit(): void; +////} +//// +/////*enumStatus*/ +////const enum Status { +//// /*memberOpen*/ +//// Open, +//// +//// /*memberClosed*/ +//// Closed +////} +//// +/////*aliasBar*/ +////type Bar = Foo & any; + +verify.docCommentTemplateAt("interfaceFoo", /*expectedOffset*/ 3, + "/** */"); + +verify.docCommentTemplateAt("propertybar", /*expectedOffset*/ 3, + "/** */"); + +verify.docCommentTemplateAt("methodbaz", /*expectedOffset*/ 12, + `/** + * + * @param message + */`); + +verify.docCommentTemplateAt("methodUnit", /*expectedOffset*/ 3, + "/** */"); + +verify.docCommentTemplateAt("enumStatus", /*expectedOffset*/ 3, + "/** */"); + +verify.docCommentTemplateAt("memberOpen", /*expectedOffset*/ 3, + "/** */"); + +verify.docCommentTemplateAt("memberClosed", /*expectedOffset*/ 3, + "/** */"); \ No newline at end of file diff --git a/tests/cases/fourslash/docCommentTemplateNamespacesAndModules01.ts b/tests/cases/fourslash/docCommentTemplateNamespacesAndModules01.ts index e7e52fd5e94..f3ba46605c4 100644 --- a/tests/cases/fourslash/docCommentTemplateNamespacesAndModules01.ts +++ b/tests/cases/fourslash/docCommentTemplateNamespacesAndModules01.ts @@ -12,17 +12,11 @@ ////module "ambientModule" { ////} -verify.docCommentTemplateAt("namespaceN", /*indentation*/ 8, -`/** - * - */`); +verify.docCommentTemplateAt("namespaceN", /*indentation*/ 3, + "/** */"); -verify.docCommentTemplateAt("namespaceM", /*indentation*/ 8, -`/** - * - */`); +verify.docCommentTemplateAt("namespaceM", /*indentation*/ 3, + "/** */"); -verify.docCommentTemplateAt("namespaceM", /*indentation*/ 8, -`/** - * - */`); +verify.docCommentTemplateAt("namespaceM", /*indentation*/ 3, + "/** */"); \ No newline at end of file diff --git a/tests/cases/fourslash/docCommentTemplateNamespacesAndModules02.ts b/tests/cases/fourslash/docCommentTemplateNamespacesAndModules02.ts index 8bb14bef5df..c1b9ed23ad6 100644 --- a/tests/cases/fourslash/docCommentTemplateNamespacesAndModules02.ts +++ b/tests/cases/fourslash/docCommentTemplateNamespacesAndModules02.ts @@ -6,10 +6,8 @@ //// /*n3*/ n3 { ////} -verify.docCommentTemplateAt("top", /*indentation*/ 8, -`/** - * - */`); +verify.docCommentTemplateAt("top", /*indentation*/ 3, +"/** */"); verify.emptyDocCommentTemplateAt("n2"); diff --git a/tests/cases/fourslash/docCommentTemplateObjectLiteralMethods01.ts b/tests/cases/fourslash/docCommentTemplateObjectLiteralMethods01.ts index 2ae77d4afac..7fb6156be17 100644 --- a/tests/cases/fourslash/docCommentTemplateObjectLiteralMethods01.ts +++ b/tests/cases/fourslash/docCommentTemplateObjectLiteralMethods01.ts @@ -1,6 +1,7 @@ /// const enum Indentation { + Standard = 3, Indented = 12, } @@ -13,10 +14,8 @@ const enum Indentation { //// [1 + 2 + 3 + Math.rand()](x: number, y: string, z = true) { } ////} -verify.docCommentTemplateAt("0", Indentation.Indented, - `/** - * - */`); +verify.docCommentTemplateAt("0", Indentation.Standard, + "/** */"); verify.docCommentTemplateAt("1", Indentation.Indented, `/** diff --git a/tests/cases/fourslash/docCommentTemplateVariableStatements01.ts b/tests/cases/fourslash/docCommentTemplateVariableStatements01.ts index b6243652167..9112c9a8cab 100644 --- a/tests/cases/fourslash/docCommentTemplateVariableStatements01.ts +++ b/tests/cases/fourslash/docCommentTemplateVariableStatements01.ts @@ -29,10 +29,8 @@ ////} for (const varName of ["a", "b", "c", "d"]) { - verify.docCommentTemplateAt(varName, /*newTextOffset*/ 8, -`/** - * - */`); + verify.docCommentTemplateAt(varName, /*newTextOffset*/ 3, + "/** */"); } verify.docCommentTemplateAt("e", /*newTextOffset*/ 8, diff --git a/tests/cases/fourslash/docCommentTemplateVariableStatements02.ts b/tests/cases/fourslash/docCommentTemplateVariableStatements02.ts index f22e361f63f..8e513780aad 100644 --- a/tests/cases/fourslash/docCommentTemplateVariableStatements02.ts +++ b/tests/cases/fourslash/docCommentTemplateVariableStatements02.ts @@ -29,8 +29,6 @@ ////}, f2 = null; for (const varName of ["a", "b", "c", "d", "e", "f"]) { - verify.docCommentTemplateAt(varName, /*newTextOffset*/ 8, -`/** - * - */`); + verify.docCommentTemplateAt(varName, /*newTextOffset*/ 3, + "/** */"); } diff --git a/tests/cases/fourslash/docCommentTemplateVariableStatements03.ts b/tests/cases/fourslash/docCommentTemplateVariableStatements03.ts index 195553098f0..6971b86a312 100644 --- a/tests/cases/fourslash/docCommentTemplateVariableStatements03.ts +++ b/tests/cases/fourslash/docCommentTemplateVariableStatements03.ts @@ -49,10 +49,8 @@ verify.docCommentTemplateAt("c", /*newTextOffset*/ 8, * @param x */`); -verify.docCommentTemplateAt("d", /*newTextOffset*/ 8, -`/** - * - */`); +verify.docCommentTemplateAt("d", /*newTextOffset*/ 3, +"/** */"); verify.docCommentTemplateAt("e", /*newTextOffset*/ 8, `/** @@ -60,10 +58,8 @@ verify.docCommentTemplateAt("e", /*newTextOffset*/ 8, * @param param0 */`); -verify.docCommentTemplateAt("f", /*newTextOffset*/ 8, -`/** - * - */`); +verify.docCommentTemplateAt("f", /*newTextOffset*/ 3, +"/** */"); verify.docCommentTemplateAt("g", /*newTextOffset*/ 8, `/** From 8cfabcaeb4ecf26bec2543b445c9a394e089061d Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 2 Nov 2017 10:07:47 -0700 Subject: [PATCH 077/235] Remove strictTuple flag and Tuple.length readonly --- src/compiler/checker.ts | 10 +++------- src/compiler/commandLineParser.ts | 7 ------- src/compiler/core.ts | 2 +- src/compiler/diagnosticMessages.json | 4 ---- src/compiler/types.ts | 1 - 5 files changed, 4 insertions(+), 20 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 83220ed6c42..8bfd60e5659 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -67,7 +67,6 @@ namespace ts { const allowSyntheticDefaultImports = typeof compilerOptions.allowSyntheticDefaultImports !== "undefined" ? compilerOptions.allowSyntheticDefaultImports : modulekind === ModuleKind.System; const strictNullChecks = getStrictOptionValue(compilerOptions, "strictNullChecks"); const strictFunctionTypes = getStrictOptionValue(compilerOptions, "strictFunctionTypes"); - const strictTuples = getStrictOptionValue(compilerOptions, "strictTuples"); const noImplicitAny = getStrictOptionValue(compilerOptions, "noImplicitAny"); const noImplicitThis = getStrictOptionValue(compilerOptions, "noImplicitThis"); @@ -7303,12 +7302,9 @@ namespace ts { property.type = typeParameter; properties.push(property); } - if (strictTuples) { - const lengthSymbol = createSymbol(SymbolFlags.Property, "length" as __String); - lengthSymbol.type = getLiteralType(arity); - lengthSymbol.checkFlags = CheckFlags.Readonly; - properties.push(lengthSymbol); - } + const lengthSymbol = createSymbol(SymbolFlags.Property, "length" as __String); + lengthSymbol.type = getLiteralType(arity); + properties.push(lengthSymbol); const type = createObjectType(ObjectFlags.Tuple | ObjectFlags.Reference); type.typeParameters = typeParameters; type.outerTypeParameters = undefined; diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 2b6f4c266a1..b7003fbffd9 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -276,13 +276,6 @@ namespace ts { category: Diagnostics.Strict_Type_Checking_Options, description: Diagnostics.Enable_strict_checking_of_function_types }, - { - name: "strictTuples", - type: "boolean", - showInSimplifiedHelpView: true, - category: Diagnostics.Strict_Type_Checking_Options, - description: Diagnostics.Enable_strict_tuple_checks - }, { name: "noImplicitThis", type: "boolean", diff --git a/src/compiler/core.ts b/src/compiler/core.ts index eed627079b9..23493b3087d 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1684,7 +1684,7 @@ namespace ts { return moduleResolution; } - export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "strictTuples" | "alwaysStrict"; + export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "alwaysStrict"; export function getStrictOptionValue(compilerOptions: CompilerOptions, flag: StrictOptionName): boolean { return compilerOptions[flag] === undefined ? compilerOptions.strict : compilerOptions[flag]; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 252ed7f77e7..8f855347bd8 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3326,10 +3326,6 @@ "category": "Message", "code": 6186 }, - "Enable strict tuple checks.": { - "category": "Message", - "code": 6187 - }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", "code": 7005 diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 95b87ab3853..549c0f8d52f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3785,7 +3785,6 @@ namespace ts { strict?: boolean; strictFunctionTypes?: boolean; // Always combine with strict property strictNullChecks?: boolean; // Always combine with strict property - strictTuples?: boolean; /* @internal */ stripInternal?: boolean; suppressExcessPropertyErrors?: boolean; suppressImplicitAnyIndexErrors?: boolean; From 12baae6c843044dd03478d04ea862d62368500c2 Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Thu, 2 Nov 2017 10:59:58 -0700 Subject: [PATCH 078/235] Revert "Return empty doc comment instead of undefined" This reverts commit 22eb519b0f6c4c06c71a7c2dd351bbec530f5dd9. --- src/services/jsDoc.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index f1e06a0ffe4..c88fe261613 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -190,26 +190,24 @@ namespace ts.JsDoc { * be performed. */ export function getDocCommentTemplateAtPosition(newLine: string, sourceFile: SourceFile, position: number): TextInsertion { - const emptyDocComment = { newText: "", caretOffset: 0 }; - // Check if in a context where we don't want to perform any insertion if (isInString(sourceFile, position) || isInComment(sourceFile, position) || hasDocComment(sourceFile, position)) { - return emptyDocComment; + return undefined; } const tokenAtPos = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false); const tokenStart = tokenAtPos.getStart(); if (!tokenAtPos || tokenStart < position) { - return emptyDocComment; + return undefined; } const commentOwnerInfo = getCommentOwnerInfo(tokenAtPos); if (!commentOwnerInfo) { - return emptyDocComment; + return undefined; } const { commentOwner, parameters } = commentOwnerInfo; if (commentOwner.getStart() < position) { - return emptyDocComment; + return undefined; } if (!parameters || parameters.length === 0) { From b17b7b9374cbfb7ac2b344b5363eefbac700ddd0 Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Thu, 2 Nov 2017 11:00:30 -0700 Subject: [PATCH 079/235] Revert "Update tests to expect empty doc comment template" This reverts commit b566480aaaf92460b37eb0977b5c07c1c0729c85. --- src/harness/fourslash.ts | 4 ++-- tests/cases/fourslash/docCommentTemplateEmptyFile.ts | 2 +- tests/cases/fourslash/docCommentTemplateInMultiLineComment.ts | 2 +- .../cases/fourslash/docCommentTemplateInSingleLineComment.ts | 2 +- .../fourslash/docCommentTemplateInsideFunctionDeclaration.ts | 2 +- .../fourslash/docCommentTemplateNamespacesAndModules02.ts | 4 ++-- tests/cases/fourslash/docCommentTemplateRegex.ts | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 79cd18da839..7ba4e94902d 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -4050,9 +4050,9 @@ namespace FourSlashInterface { this.state.verifyDocCommentTemplate({ newText: expectedText.replace(/\r?\n/g, "\r\n"), caretOffset: expectedOffset }); } - public emptyDocCommentTemplateAt(marker: string | FourSlash.Marker) { + public noDocCommentTemplateAt(marker: string | FourSlash.Marker) { this.state.goToMarker(marker); - this.state.verifyDocCommentTemplate({ newText: "", caretOffset: 0 }); + this.state.verifyDocCommentTemplate(/*expected*/ undefined); } public rangeAfterCodeFix(expectedText: string, includeWhiteSpace?: boolean, errorCode?: number, index?: number): void { diff --git a/tests/cases/fourslash/docCommentTemplateEmptyFile.ts b/tests/cases/fourslash/docCommentTemplateEmptyFile.ts index 6dcb5ef832b..f04653dc328 100644 --- a/tests/cases/fourslash/docCommentTemplateEmptyFile.ts +++ b/tests/cases/fourslash/docCommentTemplateEmptyFile.ts @@ -3,4 +3,4 @@ // @Filename: emptyFile.ts /////*0*/ -verify.emptyDocCommentTemplateAt("0"); +verify.noDocCommentTemplateAt("0"); diff --git a/tests/cases/fourslash/docCommentTemplateInMultiLineComment.ts b/tests/cases/fourslash/docCommentTemplateInMultiLineComment.ts index dc3da4e7599..6e749782c7d 100644 --- a/tests/cases/fourslash/docCommentTemplateInMultiLineComment.ts +++ b/tests/cases/fourslash/docCommentTemplateInMultiLineComment.ts @@ -3,4 +3,4 @@ // @Filename: justAComment.ts //// /* /*0*/ */ -verify.emptyDocCommentTemplateAt("0"); +verify.noDocCommentTemplateAt("0"); diff --git a/tests/cases/fourslash/docCommentTemplateInSingleLineComment.ts b/tests/cases/fourslash/docCommentTemplateInSingleLineComment.ts index 472d417a9ff..b60fff2d590 100644 --- a/tests/cases/fourslash/docCommentTemplateInSingleLineComment.ts +++ b/tests/cases/fourslash/docCommentTemplateInSingleLineComment.ts @@ -9,5 +9,5 @@ //// // /*2*/ for (const marker of test.markers()) { - verify.emptyDocCommentTemplateAt(marker); + verify.noDocCommentTemplateAt(marker); } diff --git a/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts b/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts index 13b6ebc0df6..e0ebc00dc39 100644 --- a/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts +++ b/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts @@ -4,5 +4,5 @@ ////f/*0*/unction /*1*/foo/*2*/(/*3*/) /*4*/{ /*5*/} for (const marker of test.markers()) { - verify.emptyDocCommentTemplateAt(marker); + verify.noDocCommentTemplateAt(marker); } diff --git a/tests/cases/fourslash/docCommentTemplateNamespacesAndModules02.ts b/tests/cases/fourslash/docCommentTemplateNamespacesAndModules02.ts index c1b9ed23ad6..787e9f04481 100644 --- a/tests/cases/fourslash/docCommentTemplateNamespacesAndModules02.ts +++ b/tests/cases/fourslash/docCommentTemplateNamespacesAndModules02.ts @@ -9,6 +9,6 @@ verify.docCommentTemplateAt("top", /*indentation*/ 3, "/** */"); -verify.emptyDocCommentTemplateAt("n2"); +verify.noDocCommentTemplateAt("n2"); -verify.emptyDocCommentTemplateAt("n3"); +verify.noDocCommentTemplateAt("n3"); diff --git a/tests/cases/fourslash/docCommentTemplateRegex.ts b/tests/cases/fourslash/docCommentTemplateRegex.ts index 7a6af09aeb5..685c1ca5aef 100644 --- a/tests/cases/fourslash/docCommentTemplateRegex.ts +++ b/tests/cases/fourslash/docCommentTemplateRegex.ts @@ -4,5 +4,5 @@ ////var regex = /*0*///*1*/asdf/*2*/ /*3*///*4*/; for (const marker of test.markers()) { - verify.emptyDocCommentTemplateAt(marker); + verify.noDocCommentTemplateAt(marker); } From b1b611f40adc1ced57f22d9c5ba8abf2569d7502 Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Thu, 2 Nov 2017 11:08:26 -0700 Subject: [PATCH 080/235] Add undefined to return type --- src/harness/harnessLanguageService.ts | 2 +- src/services/jsDoc.ts | 3 ++- src/services/services.ts | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 64ef1b552f5..c074b260a1d 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -492,7 +492,7 @@ namespace Harness.LanguageService { getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: ts.FormatCodeOptions): ts.TextChange[] { return unwrapJSONCallResult(this.shim.getFormattingEditsAfterKeystroke(fileName, position, key, JSON.stringify(options))); } - getDocCommentTemplateAtPosition(fileName: string, position: number): ts.TextInsertion { + getDocCommentTemplateAtPosition(fileName: string, position: number): ts.TextInsertion | undefined { return unwrapJSONCallResult(this.shim.getDocCommentTemplateAtPosition(fileName, position)); } isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean { diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index c88fe261613..78ea0c6b534 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -189,7 +189,8 @@ namespace ts.JsDoc { * @param position The (character-indexed) position in the file where the check should * be performed. */ - export function getDocCommentTemplateAtPosition(newLine: string, sourceFile: SourceFile, position: number): TextInsertion { + + export function getDocCommentTemplateAtPosition(newLine: string, sourceFile: SourceFile, position: number): TextInsertion | undefined { // Check if in a context where we don't want to perform any insertion if (isInString(sourceFile, position) || isInComment(sourceFile, position) || hasDocComment(sourceFile, position)) { return undefined; diff --git a/src/services/services.ts b/src/services/services.ts index d6e75868852..0df273e8fce 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1791,7 +1791,7 @@ namespace ts { } } - function getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion { + function getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion | undefined { return JsDoc.getDocCommentTemplateAtPosition(getNewLineOrDefaultFromHost(host), syntaxTreeCache.getCurrentSourceFile(fileName), position); } From c557131cac4379fc3e685514d44b6b82f1f642fb Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Thu, 2 Nov 2017 13:49:00 -0600 Subject: [PATCH 081/235] Ensure that we continue recursing into TS transforms (#19650) * Ensure that we continue recursing into TS transforms when avoiding export elliding for transformed nodes, fix #19649 * Use more precise fix --- src/compiler/transformers/ts.ts | 7 ++++++ src/harness/unittests/transform.ts | 23 +++++++++++++++++++ ...Correctly.transformTypesInExportDefault.js | 1 + 3 files changed, 31 insertions(+) create mode 100644 tests/baselines/reference/transformApi/transformsCorrectly.transformTypesInExportDefault.js diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index ffaecd77d71..5339f2aaee5 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -225,6 +225,13 @@ namespace ts { if (parsed !== node) { // If the node has been transformed by a `before` transformer, perform no ellision on it // As the type information we would attempt to lookup to perform ellision is potentially unavailable for the synthesized nodes + // We do not reuse `visitorWorker`, as the ellidable statement syntax kinds are technically unrecognized by the switch-case in `visitTypeScript`, + // and will trigger debug failures when debug verbosity is turned up + if (node.transformFlags & TransformFlags.ContainsTypeScript) { + // This node contains TypeScript, so we should visit its children. + return visitEachChild(node, visitor, context); + } + // Otherwise, we can just return the node return node; } switch (node.kind) { diff --git a/src/harness/unittests/transform.ts b/src/harness/unittests/transform.ts index bcdca3e3b60..72f7072535c 100644 --- a/src/harness/unittests/transform.ts +++ b/src/harness/unittests/transform.ts @@ -20,6 +20,15 @@ namespace ts { }; return (file: ts.SourceFile) => file; } + function replaceNumberWith2(context: ts.TransformationContext) { + function visitor(node: Node): Node { + if (isNumericLiteral(node)) { + return createNumericLiteral("2"); + } + return visitEachChild(node, visitor, context); + } + return (file: ts.SourceFile) => visitNode(file, visitor); + } function replaceIdentifiersNamedOldNameWithNewName(context: ts.TransformationContext) { const previousOnSubstituteNode = context.onSubstituteNode; @@ -101,6 +110,20 @@ namespace ts { }).outputText; }); + testBaseline("transformTypesInExportDefault", () => { + return ts.transpileModule(` + export default (foo: string) => { return 1; } + `, { + transformers: { + before: [replaceNumberWith2], + }, + compilerOptions: { + target: ts.ScriptTarget.ESNext, + newLine: NewLineKind.CarriageReturnLineFeed, + } + }).outputText; + }); + testBaseline("synthesizedClassAndNamespaceCombination", () => { return ts.transpileModule("", { transformers: { diff --git a/tests/baselines/reference/transformApi/transformsCorrectly.transformTypesInExportDefault.js b/tests/baselines/reference/transformApi/transformsCorrectly.transformTypesInExportDefault.js new file mode 100644 index 00000000000..82fd539be17 --- /dev/null +++ b/tests/baselines/reference/transformApi/transformsCorrectly.transformTypesInExportDefault.js @@ -0,0 +1 @@ +export default (foo) => { return 2; }; From 96232570a0a1b61581639193cc1045c5dfe84af5 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 2 Nov 2017 13:42:23 -0700 Subject: [PATCH 082/235] Remember to provide source for completionDetails from client.ts (#19664) * Remember to provide source for completionDetails from client.ts * Fix -- add "options" parameter too * Mark "options" as unused --- src/server/client.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/client.ts b/src/server/client.ts index bf46301ff86..b3492cb8ae3 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -192,8 +192,8 @@ namespace ts.server { }; } - getCompletionEntryDetails(fileName: string, position: number, entryName: string): CompletionEntryDetails { - const args: protocol.CompletionDetailsRequestArgs = { ...this.createFileLocationRequestArgs(fileName, position), entryNames: [entryName] }; + getCompletionEntryDetails(fileName: string, position: number, entryName: string, _options: FormatCodeOptions | FormatCodeSettings | undefined, source: string | undefined): CompletionEntryDetails { + const args: protocol.CompletionDetailsRequestArgs = { ...this.createFileLocationRequestArgs(fileName, position), entryNames: [{ name: entryName, source }] }; const request = this.processRequest(CommandNames.CompletionDetails, args); const response = this.processResponse(request); From 2d5331edde612eb3c4936fa5e5dad143cde0bea0 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 2 Nov 2017 13:45:50 -0700 Subject: [PATCH 083/235] Handle cases when npm install doesnt get triggered with the actual file added Fixes #19597 --- src/compiler/resolutionCache.ts | 22 +++- src/harness/unittests/tscWatchMode.ts | 2 +- .../unittests/tsserverProjectSystem.ts | 111 ++++++++++++++++++ src/harness/virtualFileSystemWithWatch.ts | 20 +++- 4 files changed, 144 insertions(+), 11 deletions(-) diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index b988da0fd5f..edc66df8fa3 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -320,6 +320,10 @@ namespace ts { return endsWith(dirPath, "/node_modules"); } + function isNodeModulesAtTypesDirectory(dirPath: Path) { + return endsWith(dirPath, "/node_modules/@types"); + } + function isDirectoryAtleastAtLevelFromFSRoot(dirPath: Path, minLevels: number) { for (let searchIndex = getRootLength(dirPath); minLevels > 0; minLevels--) { searchIndex = dirPath.indexOf(directorySeparator, searchIndex) + 1; @@ -560,11 +564,21 @@ namespace ts { else { // Some file or directory in the watching directory is created // Return early if it does not have any of the watching extension or not the custom failed lookup path - if (!isPathWithDefaultFailedLookupExtension(fileOrDirectoryPath) && !customFailedLookupPaths.has(fileOrDirectoryPath)) { - return false; + const dirOfFileOrDirectory = getDirectoryPath(fileOrDirectoryPath); + if (isNodeModulesAtTypesDirectory(dirOfFileOrDirectory) || isNodeModulesDirectory(dirOfFileOrDirectory)) { + // Invalidate any resolution from this directory + isChangedFailedLookupLocation = location => { + const locationPath = resolutionHost.toPath(location); + return locationPath === fileOrDirectoryPath || startsWith(resolutionHost.toPath(location), fileOrDirectoryPath); + }; + } + else { + if (!isPathWithDefaultFailedLookupExtension(fileOrDirectoryPath) && !customFailedLookupPaths.has(fileOrDirectoryPath)) { + return false; + } + // Resolution need to be invalidated if failed lookup location is same as the file or directory getting created + isChangedFailedLookupLocation = location => resolutionHost.toPath(location) === fileOrDirectoryPath; } - // Resolution need to be invalidated if failed lookup location is same as the file or directory getting created - isChangedFailedLookupLocation = location => resolutionHost.toPath(location) === fileOrDirectoryPath; } const hasChangedFailedLookupLocation = (resolution: ResolutionWithFailedLookupLocations) => some(resolution.failedLookupLocations, isChangedFailedLookupLocation); const invalidatedFilesCount = filesWithInvalidatedResolutions && filesWithInvalidatedResolutions.size; diff --git a/src/harness/unittests/tscWatchMode.ts b/src/harness/unittests/tscWatchMode.ts index c5aba73f2ac..cddbfba9dc0 100644 --- a/src/harness/unittests/tscWatchMode.ts +++ b/src/harness/unittests/tscWatchMode.ts @@ -1988,7 +1988,7 @@ declare module "fs" { checkProgramActualFiles(watch(), mapDefined(files, f => f === configFile ? undefined : f.path)); file1.content = "var zz30 = 100;"; - host.reloadFS(files, /*invokeDirectoryWatcherInsteadOfFileChanged*/ true); + host.reloadFS(files, { invokeDirectoryWatcherInsteadOfFileChanged: true }); host.runQueuedTimeoutCallbacks(); checkProgramActualFiles(watch(), mapDefined(files, f => f === configFile ? undefined : f.path)); diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index bc8b476ceb9..be38176fb15 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -3445,6 +3445,117 @@ namespace ts.projectSystem { diags = session.executeCommand(getErrRequest).response as server.protocol.Diagnostic[]; verifyNoDiagnostics(diags); }); + + function assertEvent(actualOutput: string, expectedEvent: protocol.Event, host: TestServerHost) { + assert.equal(actualOutput, server.formatMessage(expectedEvent, nullLogger, Utils.byteLength, host.newLine)); + } + + function checkErrorMessage(host: TestServerHost, eventName: "syntaxDiag" | "semanticDiag", diagnostics: protocol.DiagnosticEventBody) { + const outputs = host.getOutput(); + assert.isTrue(outputs.length >= 1, outputs.toString()); + const event: protocol.Event = { + seq: 0, + type: "event", + event: eventName, + body: diagnostics + }; + assertEvent(outputs[0], event, host); + } + + function checkCompleteEvent(host: TestServerHost, numberOfCurrentEvents: number, expectedSequenceId: number) { + const outputs = host.getOutput(); + assert.equal(outputs.length, numberOfCurrentEvents, outputs.toString()); + const event: protocol.RequestCompletedEvent = { + seq: 0, + type: "event", + event: "requestCompleted", + body: { + request_seq: expectedSequenceId + } + }; + assertEvent(outputs[numberOfCurrentEvents - 1], event, host); + } + + function checkProjectUpdatedInBackgroundEvent(host: TestServerHost, openFiles: string[]) { + const outputs = host.getOutput(); + assert.equal(outputs.length, 1, outputs.toString()); + const event: protocol.ProjectsUpdatedInBackgroundEvent = { + seq: 0, + type: "event", + event: "projectsUpdatedInBackground", + body: { + openFiles + } + }; + assertEvent(outputs[0], event, host); + } + + it("npm install @types works", () => { + const folderPath = "/a/b/projects/temp"; + const file1: FileOrFolder = { + path: `${folderPath}/a.ts`, + content: 'import f = require("pad")' + }; + const files = [file1, libFile]; + const host = createServerHost(files); + const session = createSession(host, { canUseEvents: true }); + const service = session.getProjectService(); + session.executeCommandSeq({ + command: server.CommandNames.Open, + arguments: { + file: file1.path, + fileContent: file1.content, + scriptKindName: "TS", + projectRootPath: folderPath + } + }); + checkNumberOfProjects(service, { inferredProjects: 1 }); + host.clearOutput(); + const expectedSequenceId = session.getNextSeq(); + session.executeCommandSeq({ + command: server.CommandNames.Geterr, + arguments: { + delay: 0, + files: [file1.path] + } + }); + + host.checkTimeoutQueueLengthAndRun(1); + checkErrorMessage(host, "syntaxDiag", { file: file1.path, diagnostics: [] }); + host.clearOutput(); + + host.runQueuedImmediateCallbacks(); + const moduleNotFound = Diagnostics.Cannot_find_module_0; + const startOffset = file1.content.indexOf('"') + 1; + checkErrorMessage(host, "semanticDiag", { + file: file1.path, diagnostics: [{ + start: { line: 1, offset: startOffset }, + end: { line: 1, offset: startOffset + '"pad"'.length }, + text: formatStringFromArgs(moduleNotFound.message, ["pad"]), + code: moduleNotFound.code, + category: DiagnosticCategory[moduleNotFound.category].toLowerCase() + }] + }); + checkCompleteEvent(host, 2, expectedSequenceId); + host.clearOutput(); + + const padIndex: FileOrFolder = { + path: `${folderPath}/node_modules/@types/pad/index.d.ts`, + content: "export = pad;declare function pad(length: number, text: string, char ?: string): string;" + }; + files.push(padIndex); + host.reloadFS(files, { ignoreWatchInvokedWithTriggerAsFileCreate: true }); + host.runQueuedTimeoutCallbacks(); + checkProjectUpdatedInBackgroundEvent(host, [file1.path]); + host.clearOutput(); + + host.runQueuedTimeoutCallbacks(); + checkErrorMessage(host, "syntaxDiag", { file: file1.path, diagnostics: [] }); + host.clearOutput(); + + host.runQueuedImmediateCallbacks(); + checkErrorMessage(host, "semanticDiag", { file: file1.path, diagnostics: [] }); + }); }); describe("Configure file diagnostics events", () => { diff --git a/src/harness/virtualFileSystemWithWatch.ts b/src/harness/virtualFileSystemWithWatch.ts index d6b1fc1a771..fe40cb42844 100644 --- a/src/harness/virtualFileSystemWithWatch.ts +++ b/src/harness/virtualFileSystemWithWatch.ts @@ -226,6 +226,11 @@ interface Array {}` directoryName: string; } + export interface ReloadWatchInvokeOptions { + invokeDirectoryWatcherInsteadOfFileChanged: boolean; + ignoreWatchInvokedWithTriggerAsFileCreate: boolean; + } + export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost { args: string[] = []; @@ -270,7 +275,7 @@ interface Array {}` return s; } - reloadFS(fileOrFolderList: ReadonlyArray, invokeDirectoryWatcherInsteadOfFileChanged?: boolean) { + reloadFS(fileOrFolderList: ReadonlyArray, options?: Partial) { const mapNewLeaves = createMap(); const isNewFs = this.fs.size === 0; fileOrFolderList = fileOrFolderList.concat(this.withSafeList ? safeList : []); @@ -291,7 +296,7 @@ interface Array {}` // Update file if (currentEntry.content !== fileOrDirectory.content) { currentEntry.content = fileOrDirectory.content; - if (invokeDirectoryWatcherInsteadOfFileChanged) { + if (options && options.invokeDirectoryWatcherInsteadOfFileChanged) { this.invokeDirectoryWatcher(getDirectoryPath(currentEntry.fullPath), currentEntry.fullPath); } else { @@ -314,7 +319,7 @@ interface Array {}` } } else { - this.ensureFileOrFolder(fileOrDirectory); + this.ensureFileOrFolder(fileOrDirectory, options && options.ignoreWatchInvokedWithTriggerAsFileCreate); } } @@ -331,12 +336,12 @@ interface Array {}` } } - ensureFileOrFolder(fileOrDirectory: FileOrFolder) { + ensureFileOrFolder(fileOrDirectory: FileOrFolder, ignoreWatchInvokedWithTriggerAsFileCreate?: boolean) { if (isString(fileOrDirectory.content)) { const file = this.toFile(fileOrDirectory); Debug.assert(!this.fs.get(file.path)); const baseFolder = this.ensureFolder(getDirectoryPath(file.fullPath)); - this.addFileOrFolderInFolder(baseFolder, file); + this.addFileOrFolderInFolder(baseFolder, file, ignoreWatchInvokedWithTriggerAsFileCreate); } else { const fullPath = getNormalizedAbsolutePath(fileOrDirectory.path, this.currentDirectory); @@ -365,10 +370,13 @@ interface Array {}` return folder; } - private addFileOrFolderInFolder(folder: Folder, fileOrDirectory: File | Folder) { + private addFileOrFolderInFolder(folder: Folder, fileOrDirectory: File | Folder, ignoreWatch?: boolean) { folder.entries.push(fileOrDirectory); this.fs.set(fileOrDirectory.path, fileOrDirectory); + if (ignoreWatch) { + return; + } if (isFile(fileOrDirectory)) { this.invokeFileWatcher(fileOrDirectory.fullPath, FileWatcherEventKind.Created); } From 6911acf80b712051db3833162eb68c3d3f79d13c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 2 Nov 2017 14:28:46 -0700 Subject: [PATCH 084/235] Remove freshness from literal types in intersections --- src/compiler/checker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 09354d957a3..7c8386e5580 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7589,11 +7589,11 @@ namespace ts { } } - // Add the given types to the given type set. Order is preserved, duplicates are removed, - // and nested types of the given kind are flattened into the set. + // Add the given types to the given type set. Order is preserved, freshness is removed from literal + // types, duplicates are removed, and nested types of the given kind are flattened into the set. function addTypesToIntersection(typeSet: TypeSet, types: Type[]) { for (const type of types) { - addTypeToIntersection(typeSet, type); + addTypeToIntersection(typeSet, getRegularTypeOfLiteralType(type)); } } From 01ad4f7dfb663e47990e959fb91bb979be175f81 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 2 Nov 2017 14:47:23 -0700 Subject: [PATCH 085/235] Support quick info at `function` and `=>` locations (#19669) * Support quick info at `function` and `=>` locations * Fixes --- src/compiler/checker.ts | 2 ++ src/services/symbolDisplay.ts | 6 +++-- .../fourslash/quickInfoFunctionKeyword.ts | 7 +++++ .../fourslash/quickInfoInvalidLocations.ts | 26 +++++++++---------- 4 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 tests/cases/fourslash/quickInfoFunctionKeyword.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 09354d957a3..7a402dce46b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -23638,6 +23638,8 @@ namespace ts { return objectType && getPropertyOfType(objectType, escapeLeadingUnderscores((node as StringLiteral | NumericLiteral).text)); case SyntaxKind.DefaultKeyword: + case SyntaxKind.FunctionKeyword: + case SyntaxKind.EqualsGreaterThanToken: return getSymbolOfNode(node.parent); default: diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index d210a045513..0465ec2aa70 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -489,8 +489,10 @@ namespace ts.SymbolDisplay { addNewLineIfDisplayPartsExist(); if (symbolKind) { pushTypePart(symbolKind); - displayParts.push(spacePart()); - addFullSymbolName(symbol); + if (!some(symbol.declarations, d => isArrowFunction(d) || (isFunctionExpression(d) || isClassExpression(d)) && !d.name)) { + displayParts.push(spacePart()); + addFullSymbolName(symbol); + } } } diff --git a/tests/cases/fourslash/quickInfoFunctionKeyword.ts b/tests/cases/fourslash/quickInfoFunctionKeyword.ts new file mode 100644 index 00000000000..d593aa679d4 --- /dev/null +++ b/tests/cases/fourslash/quickInfoFunctionKeyword.ts @@ -0,0 +1,7 @@ +/// + +////[1].forEach(fu/*1*/nction() {}); +////[1].map(x =/*2*/> x + 1); + +verify.quickInfoAt("1", "(local function)(): void"); +verify.quickInfoAt("2", "function(x: number): number"); diff --git a/tests/cases/fourslash/quickInfoInvalidLocations.ts b/tests/cases/fourslash/quickInfoInvalidLocations.ts index c70be23f387..396fac67c97 100644 --- a/tests/cases/fourslash/quickInfoInvalidLocations.ts +++ b/tests/cases/fourslash/quickInfoInvalidLocations.ts @@ -1,35 +1,35 @@ /// -////inter/*invlaid1*/face IFoo { +////inter/*invalid1*/face IFoo { //// new(): IFoo; //// [indexer: string]: number; //// method(value: number): string; //// property: string; -/////*invlaid2*/} +/////*invalid2*/} //// -////cl/*invlaid3*/ass bar imple/*invlaid4*/ments IFoo { -//// constructor( /*invlaid5*/ ) { +////cl/*invalid3*/ass bar imple/*invalid4*/ments IFoo { +//// constructor( /*invalid5*/ ) { //// //// } //// -//// pu/*invlaid6*/blic method(value: string): string { -//// retu/*invlaid7*/rn null; +//// pu/*invalid6*/blic method(value: string): string { +//// retu/*invalid7*/rn null; //// } //// -//// public property: string /*invlaid8*/= "string"; +//// public property: string /*invalid8*/= "string"; //// -//// public ge/*invlaid9*/t value() { +//// public ge/*invalid9*/t value() { //// return 0; //// } ////} //// //// -////mod/*invlaid10*/ule m1 { -//// va/*invlaid11*/r varibale = 0; +////mod/*invalid10*/ule m1 { +//// va/*invalid11*/r varibale = 0; //// -//// func/*invlaid12*/tion foo(arg1: number) { -//// ret/*invlaid13*/urn string; +//// function foo(arg1: number) { +//// ret/*invalid13*/urn string; //// } //// //// class foo { @@ -40,7 +40,7 @@ //// value1: "string", //// value2: { //// value21: number -//// /*invlaid14*/} +//// /*invalid14*/} //// }; ////} From 18b5ade05d8ddfb9cce0d9d750a1da394337c904 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 2 Nov 2017 14:48:34 -0700 Subject: [PATCH 086/235] Add regression test --- .../freshLiteralTypesInIntersections.js | 13 ++++++++ .../freshLiteralTypesInIntersections.symbols | 23 ++++++++++++++ .../freshLiteralTypesInIntersections.types | 30 +++++++++++++++++++ .../freshLiteralTypesInIntersections.ts | 7 +++++ 4 files changed, 73 insertions(+) create mode 100644 tests/baselines/reference/freshLiteralTypesInIntersections.js create mode 100644 tests/baselines/reference/freshLiteralTypesInIntersections.symbols create mode 100644 tests/baselines/reference/freshLiteralTypesInIntersections.types create mode 100644 tests/cases/compiler/freshLiteralTypesInIntersections.ts diff --git a/tests/baselines/reference/freshLiteralTypesInIntersections.js b/tests/baselines/reference/freshLiteralTypesInIntersections.js new file mode 100644 index 00000000000..633a2200380 --- /dev/null +++ b/tests/baselines/reference/freshLiteralTypesInIntersections.js @@ -0,0 +1,13 @@ +//// [freshLiteralTypesInIntersections.ts] +// Repro from #19657 + +declare function func(a: A, b: B[]): (ab: A & B) => void; +const q = func("x" as "x" | "y", ["x"]); +q("x"); + + +//// [freshLiteralTypesInIntersections.js] +"use strict"; +// Repro from #19657 +var q = func("x", ["x"]); +q("x"); diff --git a/tests/baselines/reference/freshLiteralTypesInIntersections.symbols b/tests/baselines/reference/freshLiteralTypesInIntersections.symbols new file mode 100644 index 00000000000..b16f90407b4 --- /dev/null +++ b/tests/baselines/reference/freshLiteralTypesInIntersections.symbols @@ -0,0 +1,23 @@ +=== tests/cases/compiler/freshLiteralTypesInIntersections.ts === +// Repro from #19657 + +declare function func(a: A, b: B[]): (ab: A & B) => void; +>func : Symbol(func, Decl(freshLiteralTypesInIntersections.ts, 0, 0)) +>A : Symbol(A, Decl(freshLiteralTypesInIntersections.ts, 2, 22)) +>B : Symbol(B, Decl(freshLiteralTypesInIntersections.ts, 2, 39)) +>A : Symbol(A, Decl(freshLiteralTypesInIntersections.ts, 2, 22)) +>a : Symbol(a, Decl(freshLiteralTypesInIntersections.ts, 2, 53)) +>A : Symbol(A, Decl(freshLiteralTypesInIntersections.ts, 2, 22)) +>b : Symbol(b, Decl(freshLiteralTypesInIntersections.ts, 2, 58)) +>B : Symbol(B, Decl(freshLiteralTypesInIntersections.ts, 2, 39)) +>ab : Symbol(ab, Decl(freshLiteralTypesInIntersections.ts, 2, 69)) +>A : Symbol(A, Decl(freshLiteralTypesInIntersections.ts, 2, 22)) +>B : Symbol(B, Decl(freshLiteralTypesInIntersections.ts, 2, 39)) + +const q = func("x" as "x" | "y", ["x"]); +>q : Symbol(q, Decl(freshLiteralTypesInIntersections.ts, 3, 5)) +>func : Symbol(func, Decl(freshLiteralTypesInIntersections.ts, 0, 0)) + +q("x"); +>q : Symbol(q, Decl(freshLiteralTypesInIntersections.ts, 3, 5)) + diff --git a/tests/baselines/reference/freshLiteralTypesInIntersections.types b/tests/baselines/reference/freshLiteralTypesInIntersections.types new file mode 100644 index 00000000000..b693a8c2c3f --- /dev/null +++ b/tests/baselines/reference/freshLiteralTypesInIntersections.types @@ -0,0 +1,30 @@ +=== tests/cases/compiler/freshLiteralTypesInIntersections.ts === +// Repro from #19657 + +declare function func(a: A, b: B[]): (ab: A & B) => void; +>func : (a: A, b: B[]) => (ab: A & B) => void +>A : A +>B : B +>A : A +>a : A +>A : A +>b : B[] +>B : B +>ab : A & B +>A : A +>B : B + +const q = func("x" as "x" | "y", ["x"]); +>q : (ab: "x") => void +>func("x" as "x" | "y", ["x"]) : (ab: "x") => void +>func : (a: A, b: B[]) => (ab: A & B) => void +>"x" as "x" | "y" : "x" | "y" +>"x" : "x" +>["x"] : "x"[] +>"x" : "x" + +q("x"); +>q("x") : void +>q : (ab: "x") => void +>"x" : "x" + diff --git a/tests/cases/compiler/freshLiteralTypesInIntersections.ts b/tests/cases/compiler/freshLiteralTypesInIntersections.ts new file mode 100644 index 00000000000..b1e73974426 --- /dev/null +++ b/tests/cases/compiler/freshLiteralTypesInIntersections.ts @@ -0,0 +1,7 @@ +// @strict: true + +// Repro from #19657 + +declare function func(a: A, b: B[]): (ab: A & B) => void; +const q = func("x" as "x" | "y", ["x"]); +q("x"); From 5979c9a20669bff11d232c1fe5c134c38005d042 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 2 Nov 2017 15:11:38 -0700 Subject: [PATCH 087/235] Port generated lib files (#19690) --- src/lib/dom.generated.d.ts | 1555 +++++++++++++++--------------- src/lib/webworker.generated.d.ts | 178 ++-- 2 files changed, 870 insertions(+), 863 deletions(-) diff --git a/src/lib/dom.generated.d.ts b/src/lib/dom.generated.d.ts index e4104715446..5c7600624e8 100644 --- a/src/lib/dom.generated.d.ts +++ b/src/lib/dom.generated.d.ts @@ -203,7 +203,7 @@ interface IDBIndexParameters { interface IDBObjectStoreParameters { autoIncrement?: boolean; - keyPath?: IDBKeyPath | null; + keyPath?: string | string[]; } interface IntersectionObserverEntryInit { @@ -773,7 +773,7 @@ interface RequestInit { body?: any; cache?: RequestCache; credentials?: RequestCredentials; - headers?: Headers | string[][]; + headers?: HeadersInit; integrity?: string; keepalive?: boolean; method?: string; @@ -785,7 +785,7 @@ interface RequestInit { } interface ResponseInit { - headers?: Headers | string[][]; + headers?: HeadersInit; status?: number; statusText?: string; } @@ -1255,10 +1255,10 @@ interface ApplicationCache extends EventTarget { readonly OBSOLETE: number; readonly UNCACHED: number; readonly UPDATEREADY: number; - addEventListener(type: K, listener: (this: ApplicationCache, ev: ApplicationCacheEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: ApplicationCache, ev: ApplicationCacheEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: ApplicationCache, ev: ApplicationCacheEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: ApplicationCache, ev: ApplicationCacheEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var ApplicationCache: { @@ -1314,10 +1314,10 @@ interface AudioBufferSourceNode extends AudioNode { readonly playbackRate: AudioParam; start(when?: number, offset?: number, duration?: number): void; stop(when?: number): void; - addEventListener(type: K, listener: (this: AudioBufferSourceNode, ev: AudioBufferSourceNodeEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: AudioBufferSourceNode, ev: AudioBufferSourceNodeEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: AudioBufferSourceNode, ev: AudioBufferSourceNodeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: AudioBufferSourceNode, ev: AudioBufferSourceNodeEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var AudioBufferSourceNode: { @@ -1358,10 +1358,10 @@ interface AudioContextBase extends EventTarget { createWaveShaper(): WaveShaperNode; decodeAudioData(audioData: ArrayBuffer, successCallback?: DecodeSuccessCallback, errorCallback?: DecodeErrorCallback): Promise; resume(): Promise; - addEventListener(type: K, listener: (this: AudioContext, ev: AudioContextEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: AudioContext, ev: AudioContextEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: AudioContext, ev: AudioContextEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: AudioContext, ev: AudioContextEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } interface AudioContext extends AudioContextBase { @@ -1468,10 +1468,10 @@ interface AudioTrackList extends EventTarget { onremovetrack: (this: AudioTrackList, ev: TrackEvent) => any; getTrackById(id: string): AudioTrack | null; item(index: number): AudioTrack; - addEventListener(type: K, listener: (this: AudioTrackList, ev: AudioTrackListEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: AudioTrackList, ev: AudioTrackListEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: AudioTrackList, ev: AudioTrackListEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: AudioTrackList, ev: AudioTrackListEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; [index: number]: AudioTrack; } @@ -2386,10 +2386,10 @@ declare var CustomEvent: { interface DataCue extends TextTrackCue { data: ArrayBuffer; - addEventListener(type: K, listener: (this: DataCue, ev: TextTrackCueEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: DataCue, ev: TextTrackCueEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: DataCue, ev: TextTrackCueEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: DataCue, ev: TextTrackCueEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var DataCue: { @@ -3311,10 +3311,10 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven * @param content The text and HTML tags to write. */ writeln(...content: string[]): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var Document: { @@ -3638,10 +3638,10 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec insertAdjacentHTML(where: InsertPosition, html: string): void; insertAdjacentText(where: InsertPosition, text: string): void; attachShadow(shadowRootInitDict: ShadowRootInit): ShadowRoot; - addEventListener(type: K, listener: (this: Element, ev: ElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: Element, ev: ElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: Element, ev: ElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: Element, ev: ElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var Element: { @@ -3777,10 +3777,10 @@ interface FileReader extends EventTarget, MSBaseReader { readAsBinaryString(blob: Blob): void; readAsDataURL(blob: Blob): void; readAsText(blob: Blob, encoding?: string): void; - addEventListener(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var FileReader: { @@ -3901,7 +3901,7 @@ interface Headers { declare var Headers: { prototype: Headers; - new(init?: Headers | string[][] | object): Headers; + new(init?: HeadersInit): Headers; }; interface History { @@ -4012,10 +4012,10 @@ interface HTMLAnchorElement extends HTMLElement { * Returns a string representation of an object. */ toString(): string; - addEventListener(type: K, listener: (this: HTMLAnchorElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLAnchorElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLAnchorElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLAnchorElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLAnchorElement: { @@ -4088,10 +4088,10 @@ interface HTMLAppletElement extends HTMLElement { useMap: string; vspace: number; width: number; - addEventListener(type: K, listener: (this: HTMLAppletElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLAppletElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLAppletElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLAppletElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLAppletElement: { @@ -4158,10 +4158,10 @@ interface HTMLAreaElement extends HTMLElement { * Returns a string representation of an object. */ toString(): string; - addEventListener(type: K, listener: (this: HTMLAreaElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLAreaElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLAreaElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLAreaElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLAreaElement: { @@ -4178,10 +4178,10 @@ declare var HTMLAreasCollection: { }; interface HTMLAudioElement extends HTMLMediaElement { - addEventListener(type: K, listener: (this: HTMLAudioElement, ev: HTMLMediaElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLAudioElement, ev: HTMLMediaElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLAudioElement, ev: HTMLMediaElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLAudioElement, ev: HTMLMediaElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLAudioElement: { @@ -4198,10 +4198,10 @@ interface HTMLBaseElement extends HTMLElement { * Sets or retrieves the window or frame at which to target content. */ target: string; - addEventListener(type: K, listener: (this: HTMLBaseElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLBaseElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLBaseElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLBaseElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLBaseElement: { @@ -4218,10 +4218,10 @@ interface HTMLBaseFontElement extends HTMLElement, DOML2DeprecatedColorProperty * Sets or retrieves the font size of the object. */ size: number; - addEventListener(type: K, listener: (this: HTMLBaseFontElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLBaseFontElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLBaseFontElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLBaseFontElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLBaseFontElement: { @@ -4274,10 +4274,10 @@ interface HTMLBodyElement extends HTMLElement { onunload: (this: HTMLBodyElement, ev: Event) => any; text: any; vLink: any; - addEventListener(type: K, listener: (this: HTMLBodyElement, ev: HTMLBodyElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLBodyElement, ev: HTMLBodyElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLBodyElement, ev: HTMLBodyElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLBodyElement, ev: HTMLBodyElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLBodyElement: { @@ -4290,10 +4290,10 @@ interface HTMLBRElement extends HTMLElement { * Sets or retrieves the side on which floating objects are not to be positioned when any IHTMLBlockElement is inserted into the document. */ clear: string; - addEventListener(type: K, listener: (this: HTMLBRElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLBRElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLBRElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLBRElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLBRElement: { @@ -4365,10 +4365,10 @@ interface HTMLButtonElement extends HTMLElement { * @param error Sets a custom error message that is displayed when a form is submitted. */ setCustomValidity(error: string): void; - addEventListener(type: K, listener: (this: HTMLButtonElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLButtonElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLButtonElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLButtonElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLButtonElement: { @@ -4402,10 +4402,10 @@ interface HTMLCanvasElement extends HTMLElement { */ toDataURL(type?: string, ...args: any[]): string; toBlob(callback: (result: Blob | null) => void, type?: string, ...arguments: any[]): void; - addEventListener(type: K, listener: (this: HTMLCanvasElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLCanvasElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLCanvasElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLCanvasElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLCanvasElement: { @@ -4439,10 +4439,10 @@ declare var HTMLCollection: { interface HTMLDataElement extends HTMLElement { value: string; - addEventListener(type: K, listener: (this: HTMLDataElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLDataElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLDataElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLDataElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLDataElement: { @@ -4452,10 +4452,10 @@ declare var HTMLDataElement: { interface HTMLDataListElement extends HTMLElement { options: HTMLCollectionOf; - addEventListener(type: K, listener: (this: HTMLDataListElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLDataListElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLDataListElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLDataListElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLDataListElement: { @@ -4465,10 +4465,10 @@ declare var HTMLDataListElement: { interface HTMLDirectoryElement extends HTMLElement { compact: boolean; - addEventListener(type: K, listener: (this: HTMLDirectoryElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLDirectoryElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLDirectoryElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLDirectoryElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLDirectoryElement: { @@ -4485,10 +4485,10 @@ interface HTMLDivElement extends HTMLElement { * Sets or retrieves whether the browser automatically performs wordwrap. */ noWrap: boolean; - addEventListener(type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLDivElement: { @@ -4498,10 +4498,10 @@ declare var HTMLDivElement: { interface HTMLDListElement extends HTMLElement { compact: boolean; - addEventListener(type: K, listener: (this: HTMLDListElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLDListElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLDListElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLDListElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLDListElement: { @@ -4510,10 +4510,10 @@ declare var HTMLDListElement: { }; interface HTMLDocument extends Document { - addEventListener(type: K, listener: (this: HTMLDocument, ev: DocumentEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLDocument, ev: DocumentEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLDocument, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLDocument, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLDocument: { @@ -4685,10 +4685,10 @@ interface HTMLElement extends Element { dragDrop(): boolean; focus(): void; msGetInputContext(): MSInputMethodContext; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLElement: { @@ -4743,10 +4743,10 @@ interface HTMLEmbedElement extends HTMLElement, GetSVGDocument { * Sets or retrieves the width of the object. */ width: string; - addEventListener(type: K, listener: (this: HTMLEmbedElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLEmbedElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLEmbedElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLEmbedElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLEmbedElement: { @@ -4786,10 +4786,10 @@ interface HTMLFieldSetElement extends HTMLElement { * @param error Sets a custom error message that is displayed when a form is submitted. */ setCustomValidity(error: string): void; - addEventListener(type: K, listener: (this: HTMLFieldSetElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLFieldSetElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLFieldSetElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLFieldSetElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLFieldSetElement: { @@ -4802,10 +4802,10 @@ interface HTMLFontElement extends HTMLElement, DOML2DeprecatedColorProperty, DOM * Sets or retrieves the current typeface family. */ face: string; - addEventListener(type: K, listener: (this: HTMLFontElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLFontElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLFontElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLFontElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLFontElement: { @@ -4890,10 +4890,10 @@ interface HTMLFormElement extends HTMLElement { */ submit(): void; reportValidity(): boolean; - addEventListener(type: K, listener: (this: HTMLFormElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLFormElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLFormElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLFormElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; [name: string]: any; } @@ -4967,10 +4967,10 @@ interface HTMLFrameElement extends HTMLElement, GetSVGDocument { * Sets or retrieves the width of the object. */ width: string | number; - addEventListener(type: K, listener: (this: HTMLFrameElement, ev: HTMLFrameElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLFrameElement, ev: HTMLFrameElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLFrameElement, ev: HTMLFrameElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLFrameElement, ev: HTMLFrameElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLFrameElement: { @@ -5037,10 +5037,10 @@ interface HTMLFrameSetElement extends HTMLElement { * Sets or retrieves the frame heights of the object. */ rows: string; - addEventListener(type: K, listener: (this: HTMLFrameSetElement, ev: HTMLFrameSetElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLFrameSetElement, ev: HTMLFrameSetElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLFrameSetElement, ev: HTMLFrameSetElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLFrameSetElement, ev: HTMLFrameSetElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLFrameSetElement: { @@ -5050,10 +5050,10 @@ declare var HTMLFrameSetElement: { interface HTMLHeadElement extends HTMLElement { profile: string; - addEventListener(type: K, listener: (this: HTMLHeadElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLHeadElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLHeadElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLHeadElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLHeadElement: { @@ -5066,10 +5066,10 @@ interface HTMLHeadingElement extends HTMLElement { * Sets or retrieves a value that indicates the table alignment. */ align: string; - addEventListener(type: K, listener: (this: HTMLHeadingElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLHeadingElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLHeadingElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLHeadingElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLHeadingElement: { @@ -5090,10 +5090,10 @@ interface HTMLHRElement extends HTMLElement, DOML2DeprecatedColorProperty, DOML2 * Sets or retrieves the width of the object. */ width: number; - addEventListener(type: K, listener: (this: HTMLHRElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLHRElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLHRElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLHRElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLHRElement: { @@ -5106,10 +5106,10 @@ interface HTMLHtmlElement extends HTMLElement { * Sets or retrieves the DTD version that governs the current document. */ version: string; - addEventListener(type: K, listener: (this: HTMLHtmlElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLHtmlElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLHtmlElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLHtmlElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLHtmlElement: { @@ -5193,10 +5193,10 @@ interface HTMLIFrameElement extends HTMLElement, GetSVGDocument { * Sets or retrieves the width of the object. */ width: string; - addEventListener(type: K, listener: (this: HTMLIFrameElement, ev: HTMLIFrameElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLIFrameElement, ev: HTMLIFrameElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLIFrameElement, ev: HTMLIFrameElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIFrameElement, ev: HTMLIFrameElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLIFrameElement: { @@ -5286,10 +5286,10 @@ interface HTMLImageElement extends HTMLElement { readonly x: number; readonly y: number; msGetAsCastingSource(): any; - addEventListener(type: K, listener: (this: HTMLImageElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLImageElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLImageElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLImageElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLImageElement: { @@ -5500,10 +5500,10 @@ interface HTMLInputElement extends HTMLElement { * @param n Value to increment the value by. */ stepUp(n?: number): void; - addEventListener(type: K, listener: (this: HTMLInputElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLInputElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLInputElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLInputElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLInputElement: { @@ -5520,10 +5520,10 @@ interface HTMLLabelElement extends HTMLElement { * Sets or retrieves the object to which the given label object is assigned. */ htmlFor: string; - addEventListener(type: K, listener: (this: HTMLLabelElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLLabelElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLLabelElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLLabelElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLLabelElement: { @@ -5540,10 +5540,10 @@ interface HTMLLegendElement extends HTMLElement { * Retrieves a reference to the form that the object is embedded in. */ readonly form: HTMLFormElement | null; - addEventListener(type: K, listener: (this: HTMLLegendElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLLegendElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLLegendElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLLegendElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLLegendElement: { @@ -5557,10 +5557,10 @@ interface HTMLLIElement extends HTMLElement { * Sets or retrieves the value of a list item. */ value: number; - addEventListener(type: K, listener: (this: HTMLLIElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLLIElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLLIElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLLIElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLLIElement: { @@ -5604,10 +5604,10 @@ interface HTMLLinkElement extends HTMLElement, LinkStyle { type: string; import?: Document; integrity: string; - addEventListener(type: K, listener: (this: HTMLLinkElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLLinkElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLLinkElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLLinkElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLLinkElement: { @@ -5624,10 +5624,10 @@ interface HTMLMapElement extends HTMLElement { * Sets or retrieves the name of the object. */ name: string; - addEventListener(type: K, listener: (this: HTMLMapElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLMapElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLMapElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLMapElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLMapElement: { @@ -5658,10 +5658,10 @@ interface HTMLMarqueeElement extends HTMLElement { width: string; start(): void; stop(): void; - addEventListener(type: K, listener: (this: HTMLMarqueeElement, ev: HTMLMarqueeElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLMarqueeElement, ev: HTMLMarqueeElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLMarqueeElement, ev: HTMLMarqueeElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLMarqueeElement, ev: HTMLMarqueeElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLMarqueeElement: { @@ -5842,10 +5842,10 @@ interface HTMLMediaElement extends HTMLElement { readonly NETWORK_IDLE: number; readonly NETWORK_LOADING: number; readonly NETWORK_NO_SOURCE: number; - addEventListener(type: K, listener: (this: HTMLMediaElement, ev: HTMLMediaElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLMediaElement, ev: HTMLMediaElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLMediaElement, ev: HTMLMediaElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLMediaElement, ev: HTMLMediaElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLMediaElement: { @@ -5865,10 +5865,10 @@ declare var HTMLMediaElement: { interface HTMLMenuElement extends HTMLElement { compact: boolean; type: string; - addEventListener(type: K, listener: (this: HTMLMenuElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLMenuElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLMenuElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLMenuElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLMenuElement: { @@ -5901,10 +5901,10 @@ interface HTMLMetaElement extends HTMLElement { * Sets or retrieves the URL property that will be loaded after the specified time has elapsed. */ url: string; - addEventListener(type: K, listener: (this: HTMLMetaElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLMetaElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLMetaElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLMetaElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLMetaElement: { @@ -5919,10 +5919,10 @@ interface HTMLMeterElement extends HTMLElement { min: number; optimum: number; value: number; - addEventListener(type: K, listener: (this: HTMLMeterElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLMeterElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLMeterElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLMeterElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLMeterElement: { @@ -5939,10 +5939,10 @@ interface HTMLModElement extends HTMLElement { * Sets or retrieves the date and time of a modification to the object. */ dateTime: string; - addEventListener(type: K, listener: (this: HTMLModElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLModElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLModElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLModElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLModElement: { @@ -6058,10 +6058,10 @@ interface HTMLObjectElement extends HTMLElement, GetSVGDocument { * @param error Sets a custom error message that is displayed when a form is submitted. */ setCustomValidity(error: string): void; - addEventListener(type: K, listener: (this: HTMLObjectElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLObjectElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLObjectElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLObjectElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLObjectElement: { @@ -6076,10 +6076,10 @@ interface HTMLOListElement extends HTMLElement { */ start: number; type: string; - addEventListener(type: K, listener: (this: HTMLOListElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLOListElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLOListElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLOListElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLOListElement: { @@ -6117,10 +6117,10 @@ interface HTMLOptGroupElement extends HTMLElement { * Sets or retrieves the value which is returned to the server when the form control is submitted. */ value: string; - addEventListener(type: K, listener: (this: HTMLOptGroupElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLOptGroupElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLOptGroupElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLOptGroupElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLOptGroupElement: { @@ -6158,10 +6158,10 @@ interface HTMLOptionElement extends HTMLElement { * Sets or retrieves the value which is returned to the server when the form control is submitted. */ value: string; - addEventListener(type: K, listener: (this: HTMLOptionElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLOptionElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLOptionElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLOptionElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLOptionElement: { @@ -6194,10 +6194,10 @@ interface HTMLOutputElement extends HTMLElement { checkValidity(): boolean; reportValidity(): boolean; setCustomValidity(error: string): void; - addEventListener(type: K, listener: (this: HTMLOutputElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLOutputElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLOutputElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLOutputElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLOutputElement: { @@ -6211,10 +6211,10 @@ interface HTMLParagraphElement extends HTMLElement { */ align: string; clear: string; - addEventListener(type: K, listener: (this: HTMLParagraphElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLParagraphElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLParagraphElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLParagraphElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLParagraphElement: { @@ -6239,10 +6239,10 @@ interface HTMLParamElement extends HTMLElement { * Sets or retrieves the data type of the value attribute. */ valueType: string; - addEventListener(type: K, listener: (this: HTMLParamElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLParamElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLParamElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLParamElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLParamElement: { @@ -6251,10 +6251,10 @@ declare var HTMLParamElement: { }; interface HTMLPictureElement extends HTMLElement { - addEventListener(type: K, listener: (this: HTMLPictureElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLPictureElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLPictureElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLPictureElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLPictureElement: { @@ -6267,10 +6267,10 @@ interface HTMLPreElement extends HTMLElement { * Sets or gets a value that you can use to implement your own width functionality for the object. */ width: number; - addEventListener(type: K, listener: (this: HTMLPreElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLPreElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLPreElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLPreElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLPreElement: { @@ -6295,10 +6295,10 @@ interface HTMLProgressElement extends HTMLElement { * Sets or gets the current value of a progress element. The value must be a non-negative number between 0 and the max value. */ value: number; - addEventListener(type: K, listener: (this: HTMLProgressElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLProgressElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLProgressElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLProgressElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLProgressElement: { @@ -6311,10 +6311,10 @@ interface HTMLQuoteElement extends HTMLElement { * Sets or retrieves reference information about the object. */ cite: string; - addEventListener(type: K, listener: (this: HTMLQuoteElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLQuoteElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLQuoteElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLQuoteElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLQuoteElement: { @@ -6354,10 +6354,10 @@ interface HTMLScriptElement extends HTMLElement { */ type: string; integrity: string; - addEventListener(type: K, listener: (this: HTMLScriptElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLScriptElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLScriptElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLScriptElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLScriptElement: { @@ -6452,10 +6452,10 @@ interface HTMLSelectElement extends HTMLElement { * @param error Sets a custom error message that is displayed when a form is submitted. */ setCustomValidity(error: string): void; - addEventListener(type: K, listener: (this: HTMLSelectElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLSelectElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLSelectElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLSelectElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; [name: string]: any; } @@ -6480,10 +6480,10 @@ interface HTMLSourceElement extends HTMLElement { * Gets or sets the MIME type of a media resource. */ type: string; - addEventListener(type: K, listener: (this: HTMLSourceElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLSourceElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLSourceElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLSourceElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLSourceElement: { @@ -6492,10 +6492,10 @@ declare var HTMLSourceElement: { }; interface HTMLSpanElement extends HTMLElement { - addEventListener(type: K, listener: (this: HTMLSpanElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLSpanElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLSpanElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLSpanElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLSpanElement: { @@ -6513,10 +6513,10 @@ interface HTMLStyleElement extends HTMLElement, LinkStyle { * Retrieves the CSS language in which the style sheet is written. */ type: string; - addEventListener(type: K, listener: (this: HTMLStyleElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLStyleElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLStyleElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLStyleElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLStyleElement: { @@ -6533,10 +6533,10 @@ interface HTMLTableCaptionElement extends HTMLElement { * Sets or retrieves whether the caption appears at the top or bottom of the table. */ vAlign: string; - addEventListener(type: K, listener: (this: HTMLTableCaptionElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLTableCaptionElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTableCaptionElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLTableCaptionElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTableCaptionElement: { @@ -6590,10 +6590,10 @@ interface HTMLTableCellElement extends HTMLElement, HTMLTableAlignment { * Sets or retrieves the width of the object. */ width: string; - addEventListener(type: K, listener: (this: HTMLTableCellElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLTableCellElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTableCellElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLTableCellElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTableCellElement: { @@ -6614,10 +6614,10 @@ interface HTMLTableColElement extends HTMLElement, HTMLTableAlignment { * Sets or retrieves the width of the object. */ width: any; - addEventListener(type: K, listener: (this: HTMLTableColElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLTableColElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTableColElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLTableColElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTableColElement: { @@ -6626,10 +6626,10 @@ declare var HTMLTableColElement: { }; interface HTMLTableDataCellElement extends HTMLTableCellElement { - addEventListener(type: K, listener: (this: HTMLTableDataCellElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLTableDataCellElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTableDataCellElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLTableDataCellElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTableDataCellElement: { @@ -6741,10 +6741,10 @@ interface HTMLTableElement extends HTMLElement { * @param index Number that specifies where to insert the row in the rows collection. The default value is -1, which appends the new row to the end of the rows collection. */ insertRow(index?: number): HTMLTableRowElement; - addEventListener(type: K, listener: (this: HTMLTableElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLTableElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTableElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLTableElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTableElement: { @@ -6757,10 +6757,10 @@ interface HTMLTableHeaderCellElement extends HTMLTableCellElement { * Sets or retrieves the group of cells in a table to which the object's information applies. */ scope: string; - addEventListener(type: K, listener: (this: HTMLTableHeaderCellElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLTableHeaderCellElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTableHeaderCellElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLTableHeaderCellElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTableHeaderCellElement: { @@ -6800,10 +6800,10 @@ interface HTMLTableRowElement extends HTMLElement, HTMLTableAlignment { * @param index Number that specifies where to insert the cell in the tr. The default value is -1, which appends the new cell to the end of the cells collection. */ insertCell(index?: number): HTMLTableDataCellElement; - addEventListener(type: K, listener: (this: HTMLTableRowElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLTableRowElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTableRowElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLTableRowElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTableRowElement: { @@ -6830,10 +6830,10 @@ interface HTMLTableSectionElement extends HTMLElement, HTMLTableAlignment { * @param index Number that specifies where to insert the row in the rows collection. The default value is -1, which appends the new row to the end of the rows collection. */ insertRow(index?: number): HTMLTableRowElement; - addEventListener(type: K, listener: (this: HTMLTableSectionElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLTableSectionElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTableSectionElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLTableSectionElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTableSectionElement: { @@ -6843,10 +6843,10 @@ declare var HTMLTableSectionElement: { interface HTMLTemplateElement extends HTMLElement { readonly content: DocumentFragment; - addEventListener(type: K, listener: (this: HTMLTemplateElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLTemplateElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTemplateElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLTemplateElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTemplateElement: { @@ -6952,10 +6952,10 @@ interface HTMLTextAreaElement extends HTMLElement { * @param end The offset into the text field for the end of the selection. */ setSelectionRange(start: number, end: number): void; - addEventListener(type: K, listener: (this: HTMLTextAreaElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLTextAreaElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTextAreaElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLTextAreaElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTextAreaElement: { @@ -6965,10 +6965,10 @@ declare var HTMLTextAreaElement: { interface HTMLTimeElement extends HTMLElement { dateTime: string; - addEventListener(type: K, listener: (this: HTMLTimeElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLTimeElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTimeElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLTimeElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTimeElement: { @@ -6981,10 +6981,10 @@ interface HTMLTitleElement extends HTMLElement { * Retrieves or sets the text of the object as a string. */ text: string; - addEventListener(type: K, listener: (this: HTMLTitleElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLTitleElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTitleElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLTitleElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTitleElement: { @@ -7004,10 +7004,10 @@ interface HTMLTrackElement extends HTMLElement { readonly LOADED: number; readonly LOADING: number; readonly NONE: number; - addEventListener(type: K, listener: (this: HTMLTrackElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLTrackElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTrackElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLTrackElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTrackElement: { @@ -7022,10 +7022,10 @@ declare var HTMLTrackElement: { interface HTMLUListElement extends HTMLElement { compact: boolean; type: string; - addEventListener(type: K, listener: (this: HTMLUListElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLUListElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLUListElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLUListElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLUListElement: { @@ -7034,10 +7034,10 @@ declare var HTMLUListElement: { }; interface HTMLUnknownElement extends HTMLElement { - addEventListener(type: K, listener: (this: HTMLUnknownElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLUnknownElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLUnknownElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLUnknownElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLUnknownElement: { @@ -7091,10 +7091,10 @@ interface HTMLVideoElement extends HTMLMediaElement { webkitEnterFullScreen(): void; webkitExitFullscreen(): void; webkitExitFullScreen(): void; - addEventListener(type: K, listener: (this: HTMLVideoElement, ev: HTMLVideoElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: HTMLVideoElement, ev: HTMLVideoElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLVideoElement, ev: HTMLVideoElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLVideoElement, ev: HTMLVideoElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLVideoElement: { @@ -7151,11 +7151,12 @@ interface IDBDatabase extends EventTarget { createObjectStore(name: string, optionalParameters?: IDBObjectStoreParameters): IDBObjectStore; deleteObjectStore(name: string): void; transaction(storeNames: string | string[], mode?: IDBTransactionMode): IDBTransaction; - addEventListener(type: "versionchange", listener: (ev: IDBVersionChangeEvent) => any, useCapture?: boolean): void; - addEventListener(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: "versionchange", listener: (this: IDBDatabase, ev: IDBVersionChangeEvent) => any, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: "versionchange", listener: (this: IDBDatabase, ev: IDBVersionChangeEvent) => any, options?: boolean | EventListenerOptions): void; + addEventListener(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var IDBDatabase: { @@ -7239,10 +7240,10 @@ interface IDBOpenDBRequestEventMap extends IDBRequestEventMap { interface IDBOpenDBRequest extends IDBRequest { onblocked: (this: IDBOpenDBRequest, ev: Event) => any; onupgradeneeded: (this: IDBOpenDBRequest, ev: IDBVersionChangeEvent) => any; - addEventListener(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var IDBOpenDBRequest: { @@ -7263,10 +7264,10 @@ interface IDBRequest extends EventTarget { readonly result: any; source: IDBObjectStore | IDBIndex | IDBCursor; readonly transaction: IDBTransaction; - addEventListener(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var IDBRequest: { @@ -7292,10 +7293,10 @@ interface IDBTransaction extends EventTarget { readonly READ_ONLY: string; readonly READ_WRITE: string; readonly VERSION_CHANGE: string; - addEventListener(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var IDBTransaction: { @@ -7464,10 +7465,10 @@ interface MediaDevices extends EventTarget { enumerateDevices(): Promise; getSupportedConstraints(): MediaTrackSupportedConstraints; getUserMedia(constraints: MediaStreamConstraints): Promise; - addEventListener(type: K, listener: (this: MediaDevices, ev: MediaDevicesEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: MediaDevices, ev: MediaDevicesEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: MediaDevices, ev: MediaDevicesEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: MediaDevices, ev: MediaDevicesEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var MediaDevices: { @@ -7638,10 +7639,10 @@ interface MediaStream extends EventTarget { getVideoTracks(): MediaStreamTrack[]; removeTrack(track: MediaStreamTrack): void; stop(): void; - addEventListener(type: K, listener: (this: MediaStream, ev: MediaStreamEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: MediaStream, ev: MediaStreamEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: MediaStream, ev: MediaStreamEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: MediaStream, ev: MediaStreamEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var MediaStream: { @@ -7712,10 +7713,10 @@ interface MediaStreamTrack extends EventTarget { getConstraints(): MediaTrackConstraints; getSettings(): MediaTrackSettings; stop(): void; - addEventListener(type: K, listener: (this: MediaStreamTrack, ev: MediaStreamTrackEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: MediaStreamTrack, ev: MediaStreamTrackEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: MediaStreamTrack, ev: MediaStreamTrackEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: MediaStreamTrack, ev: MediaStreamTrackEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var MediaStreamTrack: { @@ -7764,10 +7765,10 @@ interface MessagePort extends EventTarget { close(): void; postMessage(message?: any, transfer?: any[]): void; start(): void; - addEventListener(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var MessagePort: { @@ -7871,10 +7872,10 @@ interface MSAppAsyncOperation extends EventTarget { readonly COMPLETED: number; readonly ERROR: number; readonly STARTED: number; - addEventListener(type: K, listener: (this: MSAppAsyncOperation, ev: MSAppAsyncOperationEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: MSAppAsyncOperation, ev: MSAppAsyncOperationEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: MSAppAsyncOperation, ev: MSAppAsyncOperationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: MSAppAsyncOperation, ev: MSAppAsyncOperationEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var MSAppAsyncOperation: { @@ -8029,10 +8030,10 @@ interface MSHTMLWebViewElement extends HTMLElement { navigateWithHttpRequestMessage(requestMessage: any): void; refresh(): void; stop(): void; - addEventListener(type: K, listener: (this: MSHTMLWebViewElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: MSHTMLWebViewElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: MSHTMLWebViewElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: MSHTMLWebViewElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var MSHTMLWebViewElement: { @@ -8057,10 +8058,10 @@ interface MSInputMethodContext extends EventTarget { getCompositionAlternatives(): string[]; hasComposition(): boolean; isCandidateWindowVisible(): boolean; - addEventListener(type: K, listener: (this: MSInputMethodContext, ev: MSInputMethodContextEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: MSInputMethodContext, ev: MSInputMethodContextEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: MSInputMethodContext, ev: MSInputMethodContextEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: MSInputMethodContext, ev: MSInputMethodContextEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var MSInputMethodContext: { @@ -8225,10 +8226,10 @@ interface MSStreamReader extends EventTarget, MSBaseReader { readAsBlob(stream: MSStream, size?: number): void; readAsDataURL(stream: MSStream, size?: number): void; readAsText(stream: MSStream, encoding?: string, size?: number): void; - addEventListener(type: K, listener: (this: MSStreamReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: MSStreamReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: MSStreamReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: MSStreamReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var MSStreamReader: { @@ -8256,10 +8257,10 @@ interface MSWebViewAsyncOperation extends EventTarget { readonly TYPE_CAPTURE_PREVIEW_TO_RANDOM_ACCESS_STREAM: number; readonly TYPE_CREATE_DATA_PACKAGE_FROM_SELECTION: number; readonly TYPE_INVOKE_SCRIPT: number; - addEventListener(type: K, listener: (this: MSWebViewAsyncOperation, ev: MSWebViewAsyncOperationEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: MSWebViewAsyncOperation, ev: MSWebViewAsyncOperationEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: MSWebViewAsyncOperation, ev: MSWebViewAsyncOperationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: MSWebViewAsyncOperation, ev: MSWebViewAsyncOperationEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var MSWebViewAsyncOperation: { @@ -8549,10 +8550,10 @@ interface Notification extends EventTarget { readonly tag: string; readonly title: string; close(): void; - addEventListener(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var Notification: { @@ -8631,10 +8632,10 @@ interface OfflineAudioContext extends AudioContextBase { oncomplete: (this: OfflineAudioContext, ev: OfflineAudioCompletionEvent) => any; startRendering(): Promise; suspend(suspendTime: number): Promise; - addEventListener(type: K, listener: (this: OfflineAudioContext, ev: OfflineAudioContextEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: OfflineAudioContext, ev: OfflineAudioContextEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: OfflineAudioContext, ev: OfflineAudioContextEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: OfflineAudioContext, ev: OfflineAudioContextEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var OfflineAudioContext: { @@ -8654,10 +8655,10 @@ interface OscillatorNode extends AudioNode { setPeriodicWave(periodicWave: PeriodicWave): void; start(when?: number): void; stop(when?: number): void; - addEventListener(type: K, listener: (this: OscillatorNode, ev: OscillatorNodeEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: OscillatorNode, ev: OscillatorNodeEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: OscillatorNode, ev: OscillatorNodeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: OscillatorNode, ev: OscillatorNodeEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var OscillatorNode: { @@ -8751,10 +8752,10 @@ interface PaymentRequest extends EventTarget { readonly shippingType: PaymentShippingType | null; abort(): Promise; show(): Promise; - addEventListener(type: K, listener: (this: PaymentRequest, ev: PaymentRequestEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: PaymentRequest, ev: PaymentRequestEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: PaymentRequest, ev: PaymentRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: PaymentRequest, ev: PaymentRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var PaymentRequest: { @@ -9260,10 +9261,10 @@ interface RTCDtlsTransport extends RTCStatsProvider { getRemoteParameters(): RTCDtlsParameters | null; start(remoteParameters: RTCDtlsParameters): void; stop(): void; - addEventListener(type: K, listener: (this: RTCDtlsTransport, ev: RTCDtlsTransportEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: RTCDtlsTransport, ev: RTCDtlsTransportEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: RTCDtlsTransport, ev: RTCDtlsTransportEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: RTCDtlsTransport, ev: RTCDtlsTransportEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var RTCDtlsTransport: { @@ -9292,10 +9293,10 @@ interface RTCDtmfSender extends EventTarget { readonly sender: RTCRtpSender; readonly toneBuffer: string; insertDTMF(tones: string, duration?: number, interToneGap?: number): void; - addEventListener(type: K, listener: (this: RTCDtmfSender, ev: RTCDtmfSenderEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: RTCDtmfSender, ev: RTCDtmfSenderEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: RTCDtmfSender, ev: RTCDtmfSenderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: RTCDtmfSender, ev: RTCDtmfSenderEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var RTCDtmfSender: { @@ -9345,10 +9346,10 @@ interface RTCIceGatherer extends RTCStatsProvider { createAssociatedGatherer(): RTCIceGatherer; getLocalCandidates(): RTCIceCandidateDictionary[]; getLocalParameters(): RTCIceParameters; - addEventListener(type: K, listener: (this: RTCIceGatherer, ev: RTCIceGathererEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: RTCIceGatherer, ev: RTCIceGathererEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: RTCIceGatherer, ev: RTCIceGathererEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: RTCIceGatherer, ev: RTCIceGathererEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var RTCIceGatherer: { @@ -9385,10 +9386,10 @@ interface RTCIceTransport extends RTCStatsProvider { setRemoteCandidates(remoteCandidates: RTCIceCandidateDictionary[]): void; start(gatherer: RTCIceGatherer, remoteParameters: RTCIceParameters, role?: RTCIceRole): void; stop(): void; - addEventListener(type: K, listener: (this: RTCIceTransport, ev: RTCIceTransportEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: RTCIceTransport, ev: RTCIceTransportEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: RTCIceTransport, ev: RTCIceTransportEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: RTCIceTransport, ev: RTCIceTransportEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var RTCIceTransport: { @@ -9442,10 +9443,10 @@ interface RTCPeerConnection extends EventTarget { removeStream(stream: MediaStream): void; setLocalDescription(description: RTCSessionDescription, successCallback?: VoidFunction, failureCallback?: RTCPeerConnectionErrorCallback): Promise; setRemoteDescription(description: RTCSessionDescription, successCallback?: VoidFunction, failureCallback?: RTCPeerConnectionErrorCallback): Promise; - addEventListener(type: K, listener: (this: RTCPeerConnection, ev: RTCPeerConnectionEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: RTCPeerConnection, ev: RTCPeerConnectionEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: RTCPeerConnection, ev: RTCPeerConnectionEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: RTCPeerConnection, ev: RTCPeerConnectionEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var RTCPeerConnection: { @@ -9476,10 +9477,10 @@ interface RTCRtpReceiver extends RTCStatsProvider { requestSendCSRC(csrc: number): void; setTransport(transport: RTCDtlsTransport | RTCSrtpSdesTransport, rtcpTransport?: RTCDtlsTransport): void; stop(): void; - addEventListener(type: K, listener: (this: RTCRtpReceiver, ev: RTCRtpReceiverEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: RTCRtpReceiver, ev: RTCRtpReceiverEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: RTCRtpReceiver, ev: RTCRtpReceiverEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: RTCRtpReceiver, ev: RTCRtpReceiverEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var RTCRtpReceiver: { @@ -9503,10 +9504,10 @@ interface RTCRtpSender extends RTCStatsProvider { setTrack(track: MediaStreamTrack): void; setTransport(transport: RTCDtlsTransport | RTCSrtpSdesTransport, rtcpTransport?: RTCDtlsTransport): void; stop(): void; - addEventListener(type: K, listener: (this: RTCRtpSender, ev: RTCRtpSenderEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: RTCRtpSender, ev: RTCRtpSenderEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: RTCRtpSender, ev: RTCRtpSenderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: RTCRtpSender, ev: RTCRtpSenderEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var RTCRtpSender: { @@ -9533,10 +9534,10 @@ interface RTCSrtpSdesTransportEventMap { interface RTCSrtpSdesTransport extends EventTarget { onerror: ((this: RTCSrtpSdesTransport, ev: Event) => any) | null; readonly transport: RTCIceTransport; - addEventListener(type: K, listener: (this: RTCSrtpSdesTransport, ev: RTCSrtpSdesTransportEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: RTCSrtpSdesTransport, ev: RTCSrtpSdesTransportEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: RTCSrtpSdesTransport, ev: RTCSrtpSdesTransportEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: RTCSrtpSdesTransport, ev: RTCSrtpSdesTransportEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var RTCSrtpSdesTransport: { @@ -9607,10 +9608,10 @@ interface Screen extends EventTarget { readonly width: number; msLockOrientation(orientations: string | string[]): boolean; msUnlockOrientation(): void; - addEventListener(type: K, listener: (this: Screen, ev: ScreenEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: Screen, ev: ScreenEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: Screen, ev: ScreenEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: Screen, ev: ScreenEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var Screen: { @@ -9635,10 +9636,10 @@ interface ScriptProcessorNodeEventMap { interface ScriptProcessorNode extends AudioNode { readonly bufferSize: number; onaudioprocess: (this: ScriptProcessorNode, ev: AudioProcessingEvent) => any; - addEventListener(type: K, listener: (this: ScriptProcessorNode, ev: ScriptProcessorNodeEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: ScriptProcessorNode, ev: ScriptProcessorNodeEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: ScriptProcessorNode, ev: ScriptProcessorNodeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: ScriptProcessorNode, ev: ScriptProcessorNodeEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var ScriptProcessorNode: { @@ -9689,10 +9690,10 @@ interface ServiceWorker extends EventTarget, AbstractWorker { readonly scriptURL: USVString; readonly state: ServiceWorkerState; postMessage(message: any, transfer?: any[]): void; - addEventListener(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var ServiceWorker: { @@ -9713,10 +9714,10 @@ interface ServiceWorkerContainer extends EventTarget { getRegistration(): Promise; getRegistrations(): Promise; register(scriptURL: USVString, options?: RegistrationOptions): Promise; - addEventListener(type: K, listener: (this: ServiceWorkerContainer, ev: ServiceWorkerContainerEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: ServiceWorkerContainer, ev: ServiceWorkerContainerEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: ServiceWorkerContainer, ev: ServiceWorkerContainerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: ServiceWorkerContainer, ev: ServiceWorkerContainerEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var ServiceWorkerContainer: { @@ -9753,10 +9754,10 @@ interface ServiceWorkerRegistration extends EventTarget { showNotification(title: string, options?: NotificationOptions): Promise; unregister(): Promise; update(): Promise; - addEventListener(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var ServiceWorkerRegistration: { @@ -9809,10 +9810,10 @@ interface SpeechSynthesis extends EventTarget { pause(): void; resume(): void; speak(utterance: SpeechSynthesisUtterance): void; - addEventListener(type: K, listener: (this: SpeechSynthesis, ev: SpeechSynthesisEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SpeechSynthesis, ev: SpeechSynthesisEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SpeechSynthesis, ev: SpeechSynthesisEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SpeechSynthesis, ev: SpeechSynthesisEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SpeechSynthesis: { @@ -9856,10 +9857,10 @@ interface SpeechSynthesisUtterance extends EventTarget { text: string; voice: SpeechSynthesisVoice; volume: number; - addEventListener(type: K, listener: (this: SpeechSynthesisUtterance, ev: SpeechSynthesisUtteranceEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SpeechSynthesisUtterance, ev: SpeechSynthesisUtteranceEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SpeechSynthesisUtterance, ev: SpeechSynthesisUtteranceEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SpeechSynthesisUtterance, ev: SpeechSynthesisUtteranceEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SpeechSynthesisUtterance: { @@ -9993,10 +9994,10 @@ declare var SubtleCrypto: { interface SVGAElement extends SVGGraphicsElement, SVGURIReference { readonly target: SVGAnimatedString; - addEventListener(type: K, listener: (this: SVGAElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGAElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGAElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGAElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGAElement: { @@ -10152,10 +10153,10 @@ interface SVGCircleElement extends SVGGraphicsElement { readonly cx: SVGAnimatedLength; readonly cy: SVGAnimatedLength; readonly r: SVGAnimatedLength; - addEventListener(type: K, listener: (this: SVGCircleElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGCircleElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGCircleElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGCircleElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGCircleElement: { @@ -10165,10 +10166,10 @@ declare var SVGCircleElement: { interface SVGClipPathElement extends SVGGraphicsElement, SVGUnitTypes { readonly clipPathUnits: SVGAnimatedEnumeration; - addEventListener(type: K, listener: (this: SVGClipPathElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGClipPathElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGClipPathElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGClipPathElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGClipPathElement: { @@ -10190,10 +10191,10 @@ interface SVGComponentTransferFunctionElement extends SVGElement { readonly SVG_FECOMPONENTTRANSFER_TYPE_LINEAR: number; readonly SVG_FECOMPONENTTRANSFER_TYPE_TABLE: number; readonly SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN: number; - addEventListener(type: K, listener: (this: SVGComponentTransferFunctionElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGComponentTransferFunctionElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGComponentTransferFunctionElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGComponentTransferFunctionElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGComponentTransferFunctionElement: { @@ -10208,10 +10209,10 @@ declare var SVGComponentTransferFunctionElement: { }; interface SVGDefsElement extends SVGGraphicsElement { - addEventListener(type: K, listener: (this: SVGDefsElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGDefsElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGDefsElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGDefsElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGDefsElement: { @@ -10220,10 +10221,10 @@ declare var SVGDefsElement: { }; interface SVGDescElement extends SVGElement { - addEventListener(type: K, listener: (this: SVGDescElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGDescElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGDescElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGDescElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGDescElement: { @@ -10260,10 +10261,10 @@ interface SVGElement extends Element { readonly style: CSSStyleDeclaration; readonly viewportElement: SVGElement; xmlbase: string; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGElement: { @@ -10302,10 +10303,10 @@ interface SVGEllipseElement extends SVGGraphicsElement { readonly cy: SVGAnimatedLength; readonly rx: SVGAnimatedLength; readonly ry: SVGAnimatedLength; - addEventListener(type: K, listener: (this: SVGEllipseElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGEllipseElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGEllipseElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGEllipseElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGEllipseElement: { @@ -10334,10 +10335,10 @@ interface SVGFEBlendElement extends SVGElement, SVGFilterPrimitiveStandardAttrib readonly SVG_FEBLEND_MODE_SCREEN: number; readonly SVG_FEBLEND_MODE_SOFT_LIGHT: number; readonly SVG_FEBLEND_MODE_UNKNOWN: number; - addEventListener(type: K, listener: (this: SVGFEBlendElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFEBlendElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEBlendElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFEBlendElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEBlendElement: { @@ -10371,10 +10372,10 @@ interface SVGFEColorMatrixElement extends SVGElement, SVGFilterPrimitiveStandard readonly SVG_FECOLORMATRIX_TYPE_MATRIX: number; readonly SVG_FECOLORMATRIX_TYPE_SATURATE: number; readonly SVG_FECOLORMATRIX_TYPE_UNKNOWN: number; - addEventListener(type: K, listener: (this: SVGFEColorMatrixElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFEColorMatrixElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEColorMatrixElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFEColorMatrixElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEColorMatrixElement: { @@ -10389,10 +10390,10 @@ declare var SVGFEColorMatrixElement: { interface SVGFEComponentTransferElement extends SVGElement, SVGFilterPrimitiveStandardAttributes { readonly in1: SVGAnimatedString; - addEventListener(type: K, listener: (this: SVGFEComponentTransferElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFEComponentTransferElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEComponentTransferElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFEComponentTransferElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEComponentTransferElement: { @@ -10415,10 +10416,10 @@ interface SVGFECompositeElement extends SVGElement, SVGFilterPrimitiveStandardAt readonly SVG_FECOMPOSITE_OPERATOR_OVER: number; readonly SVG_FECOMPOSITE_OPERATOR_UNKNOWN: number; readonly SVG_FECOMPOSITE_OPERATOR_XOR: number; - addEventListener(type: K, listener: (this: SVGFECompositeElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFECompositeElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFECompositeElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFECompositeElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFECompositeElement: { @@ -10450,10 +10451,10 @@ interface SVGFEConvolveMatrixElement extends SVGElement, SVGFilterPrimitiveStand readonly SVG_EDGEMODE_NONE: number; readonly SVG_EDGEMODE_UNKNOWN: number; readonly SVG_EDGEMODE_WRAP: number; - addEventListener(type: K, listener: (this: SVGFEConvolveMatrixElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFEConvolveMatrixElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEConvolveMatrixElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFEConvolveMatrixElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEConvolveMatrixElement: { @@ -10471,10 +10472,10 @@ interface SVGFEDiffuseLightingElement extends SVGElement, SVGFilterPrimitiveStan readonly kernelUnitLengthX: SVGAnimatedNumber; readonly kernelUnitLengthY: SVGAnimatedNumber; readonly surfaceScale: SVGAnimatedNumber; - addEventListener(type: K, listener: (this: SVGFEDiffuseLightingElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFEDiffuseLightingElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEDiffuseLightingElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFEDiffuseLightingElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEDiffuseLightingElement: { @@ -10493,10 +10494,10 @@ interface SVGFEDisplacementMapElement extends SVGElement, SVGFilterPrimitiveStan readonly SVG_CHANNEL_G: number; readonly SVG_CHANNEL_R: number; readonly SVG_CHANNEL_UNKNOWN: number; - addEventListener(type: K, listener: (this: SVGFEDisplacementMapElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFEDisplacementMapElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEDisplacementMapElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFEDisplacementMapElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEDisplacementMapElement: { @@ -10512,10 +10513,10 @@ declare var SVGFEDisplacementMapElement: { interface SVGFEDistantLightElement extends SVGElement { readonly azimuth: SVGAnimatedNumber; readonly elevation: SVGAnimatedNumber; - addEventListener(type: K, listener: (this: SVGFEDistantLightElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFEDistantLightElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEDistantLightElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFEDistantLightElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEDistantLightElement: { @@ -10524,10 +10525,10 @@ declare var SVGFEDistantLightElement: { }; interface SVGFEFloodElement extends SVGElement, SVGFilterPrimitiveStandardAttributes { - addEventListener(type: K, listener: (this: SVGFEFloodElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFEFloodElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEFloodElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFEFloodElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEFloodElement: { @@ -10536,10 +10537,10 @@ declare var SVGFEFloodElement: { }; interface SVGFEFuncAElement extends SVGComponentTransferFunctionElement { - addEventListener(type: K, listener: (this: SVGFEFuncAElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFEFuncAElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEFuncAElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFEFuncAElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEFuncAElement: { @@ -10548,10 +10549,10 @@ declare var SVGFEFuncAElement: { }; interface SVGFEFuncBElement extends SVGComponentTransferFunctionElement { - addEventListener(type: K, listener: (this: SVGFEFuncBElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFEFuncBElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEFuncBElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFEFuncBElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEFuncBElement: { @@ -10560,10 +10561,10 @@ declare var SVGFEFuncBElement: { }; interface SVGFEFuncGElement extends SVGComponentTransferFunctionElement { - addEventListener(type: K, listener: (this: SVGFEFuncGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFEFuncGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEFuncGElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFEFuncGElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEFuncGElement: { @@ -10572,10 +10573,10 @@ declare var SVGFEFuncGElement: { }; interface SVGFEFuncRElement extends SVGComponentTransferFunctionElement { - addEventListener(type: K, listener: (this: SVGFEFuncRElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFEFuncRElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEFuncRElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFEFuncRElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEFuncRElement: { @@ -10588,10 +10589,10 @@ interface SVGFEGaussianBlurElement extends SVGElement, SVGFilterPrimitiveStandar readonly stdDeviationX: SVGAnimatedNumber; readonly stdDeviationY: SVGAnimatedNumber; setStdDeviation(stdDeviationX: number, stdDeviationY: number): void; - addEventListener(type: K, listener: (this: SVGFEGaussianBlurElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFEGaussianBlurElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEGaussianBlurElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFEGaussianBlurElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEGaussianBlurElement: { @@ -10601,10 +10602,10 @@ declare var SVGFEGaussianBlurElement: { interface SVGFEImageElement extends SVGElement, SVGFilterPrimitiveStandardAttributes, SVGURIReference { readonly preserveAspectRatio: SVGAnimatedPreserveAspectRatio; - addEventListener(type: K, listener: (this: SVGFEImageElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFEImageElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEImageElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFEImageElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEImageElement: { @@ -10613,10 +10614,10 @@ declare var SVGFEImageElement: { }; interface SVGFEMergeElement extends SVGElement, SVGFilterPrimitiveStandardAttributes { - addEventListener(type: K, listener: (this: SVGFEMergeElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFEMergeElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEMergeElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFEMergeElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEMergeElement: { @@ -10626,10 +10627,10 @@ declare var SVGFEMergeElement: { interface SVGFEMergeNodeElement extends SVGElement { readonly in1: SVGAnimatedString; - addEventListener(type: K, listener: (this: SVGFEMergeNodeElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFEMergeNodeElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEMergeNodeElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFEMergeNodeElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEMergeNodeElement: { @@ -10645,10 +10646,10 @@ interface SVGFEMorphologyElement extends SVGElement, SVGFilterPrimitiveStandardA readonly SVG_MORPHOLOGY_OPERATOR_DILATE: number; readonly SVG_MORPHOLOGY_OPERATOR_ERODE: number; readonly SVG_MORPHOLOGY_OPERATOR_UNKNOWN: number; - addEventListener(type: K, listener: (this: SVGFEMorphologyElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFEMorphologyElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEMorphologyElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFEMorphologyElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEMorphologyElement: { @@ -10663,10 +10664,10 @@ interface SVGFEOffsetElement extends SVGElement, SVGFilterPrimitiveStandardAttri readonly dx: SVGAnimatedNumber; readonly dy: SVGAnimatedNumber; readonly in1: SVGAnimatedString; - addEventListener(type: K, listener: (this: SVGFEOffsetElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFEOffsetElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEOffsetElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFEOffsetElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEOffsetElement: { @@ -10678,10 +10679,10 @@ interface SVGFEPointLightElement extends SVGElement { readonly x: SVGAnimatedNumber; readonly y: SVGAnimatedNumber; readonly z: SVGAnimatedNumber; - addEventListener(type: K, listener: (this: SVGFEPointLightElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFEPointLightElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEPointLightElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFEPointLightElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEPointLightElement: { @@ -10696,10 +10697,10 @@ interface SVGFESpecularLightingElement extends SVGElement, SVGFilterPrimitiveSta readonly specularConstant: SVGAnimatedNumber; readonly specularExponent: SVGAnimatedNumber; readonly surfaceScale: SVGAnimatedNumber; - addEventListener(type: K, listener: (this: SVGFESpecularLightingElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFESpecularLightingElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFESpecularLightingElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFESpecularLightingElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFESpecularLightingElement: { @@ -10716,10 +10717,10 @@ interface SVGFESpotLightElement extends SVGElement { readonly x: SVGAnimatedNumber; readonly y: SVGAnimatedNumber; readonly z: SVGAnimatedNumber; - addEventListener(type: K, listener: (this: SVGFESpotLightElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFESpotLightElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFESpotLightElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFESpotLightElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFESpotLightElement: { @@ -10729,10 +10730,10 @@ declare var SVGFESpotLightElement: { interface SVGFETileElement extends SVGElement, SVGFilterPrimitiveStandardAttributes { readonly in1: SVGAnimatedString; - addEventListener(type: K, listener: (this: SVGFETileElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFETileElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFETileElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFETileElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFETileElement: { @@ -10753,10 +10754,10 @@ interface SVGFETurbulenceElement extends SVGElement, SVGFilterPrimitiveStandardA readonly SVG_TURBULENCE_TYPE_FRACTALNOISE: number; readonly SVG_TURBULENCE_TYPE_TURBULENCE: number; readonly SVG_TURBULENCE_TYPE_UNKNOWN: number; - addEventListener(type: K, listener: (this: SVGFETurbulenceElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFETurbulenceElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFETurbulenceElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFETurbulenceElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFETurbulenceElement: { @@ -10780,10 +10781,10 @@ interface SVGFilterElement extends SVGElement, SVGUnitTypes, SVGURIReference { readonly x: SVGAnimatedLength; readonly y: SVGAnimatedLength; setFilterRes(filterResX: number, filterResY: number): void; - addEventListener(type: K, listener: (this: SVGFilterElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGFilterElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFilterElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGFilterElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFilterElement: { @@ -10796,10 +10797,10 @@ interface SVGForeignObjectElement extends SVGGraphicsElement { readonly width: SVGAnimatedLength; readonly x: SVGAnimatedLength; readonly y: SVGAnimatedLength; - addEventListener(type: K, listener: (this: SVGForeignObjectElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGForeignObjectElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGForeignObjectElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGForeignObjectElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGForeignObjectElement: { @@ -10808,10 +10809,10 @@ declare var SVGForeignObjectElement: { }; interface SVGGElement extends SVGGraphicsElement { - addEventListener(type: K, listener: (this: SVGGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGGElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGGElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGGElement: { @@ -10827,10 +10828,10 @@ interface SVGGradientElement extends SVGElement, SVGUnitTypes, SVGURIReference { readonly SVG_SPREADMETHOD_REFLECT: number; readonly SVG_SPREADMETHOD_REPEAT: number; readonly SVG_SPREADMETHOD_UNKNOWN: number; - addEventListener(type: K, listener: (this: SVGGradientElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGGradientElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGGradientElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGGradientElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGGradientElement: { @@ -10850,10 +10851,10 @@ interface SVGGraphicsElement extends SVGElement, SVGTests { getCTM(): SVGMatrix; getScreenCTM(): SVGMatrix; getTransformToElement(element: SVGElement): SVGMatrix; - addEventListener(type: K, listener: (this: SVGGraphicsElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGGraphicsElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGGraphicsElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGGraphicsElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGGraphicsElement: { @@ -10867,10 +10868,10 @@ interface SVGImageElement extends SVGGraphicsElement, SVGURIReference { readonly width: SVGAnimatedLength; readonly x: SVGAnimatedLength; readonly y: SVGAnimatedLength; - addEventListener(type: K, listener: (this: SVGImageElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGImageElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGImageElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGImageElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGImageElement: { @@ -10935,10 +10936,10 @@ interface SVGLinearGradientElement extends SVGGradientElement { readonly x2: SVGAnimatedLength; readonly y1: SVGAnimatedLength; readonly y2: SVGAnimatedLength; - addEventListener(type: K, listener: (this: SVGLinearGradientElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGLinearGradientElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGLinearGradientElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGLinearGradientElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGLinearGradientElement: { @@ -10951,10 +10952,10 @@ interface SVGLineElement extends SVGGraphicsElement { readonly x2: SVGAnimatedLength; readonly y1: SVGAnimatedLength; readonly y2: SVGAnimatedLength; - addEventListener(type: K, listener: (this: SVGLineElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGLineElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGLineElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGLineElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGLineElement: { @@ -10978,10 +10979,10 @@ interface SVGMarkerElement extends SVGElement, SVGFitToViewBox { readonly SVG_MARKERUNITS_STROKEWIDTH: number; readonly SVG_MARKERUNITS_UNKNOWN: number; readonly SVG_MARKERUNITS_USERSPACEONUSE: number; - addEventListener(type: K, listener: (this: SVGMarkerElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGMarkerElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGMarkerElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGMarkerElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGMarkerElement: { @@ -11002,10 +11003,10 @@ interface SVGMaskElement extends SVGElement, SVGTests, SVGUnitTypes { readonly width: SVGAnimatedLength; readonly x: SVGAnimatedLength; readonly y: SVGAnimatedLength; - addEventListener(type: K, listener: (this: SVGMaskElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGMaskElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGMaskElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGMaskElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGMaskElement: { @@ -11039,10 +11040,10 @@ declare var SVGMatrix: { }; interface SVGMetadataElement extends SVGElement { - addEventListener(type: K, listener: (this: SVGMetadataElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGMetadataElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGMetadataElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGMetadataElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGMetadataElement: { @@ -11099,10 +11100,10 @@ interface SVGPathElement extends SVGGraphicsElement { getPathSegAtLength(distance: number): number; getPointAtLength(distance: number): SVGPoint; getTotalLength(): number; - addEventListener(type: K, listener: (this: SVGPathElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGPathElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGPathElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGPathElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGPathElement: { @@ -11394,10 +11395,10 @@ interface SVGPatternElement extends SVGElement, SVGTests, SVGUnitTypes, SVGFitTo readonly width: SVGAnimatedLength; readonly x: SVGAnimatedLength; readonly y: SVGAnimatedLength; - addEventListener(type: K, listener: (this: SVGPatternElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGPatternElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGPatternElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGPatternElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGPatternElement: { @@ -11433,10 +11434,10 @@ declare var SVGPointList: { }; interface SVGPolygonElement extends SVGGraphicsElement, SVGAnimatedPoints { - addEventListener(type: K, listener: (this: SVGPolygonElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGPolygonElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGPolygonElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGPolygonElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGPolygonElement: { @@ -11445,10 +11446,10 @@ declare var SVGPolygonElement: { }; interface SVGPolylineElement extends SVGGraphicsElement, SVGAnimatedPoints { - addEventListener(type: K, listener: (this: SVGPolylineElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGPolylineElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGPolylineElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGPolylineElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGPolylineElement: { @@ -11500,10 +11501,10 @@ interface SVGRadialGradientElement extends SVGGradientElement { readonly fx: SVGAnimatedLength; readonly fy: SVGAnimatedLength; readonly r: SVGAnimatedLength; - addEventListener(type: K, listener: (this: SVGRadialGradientElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGRadialGradientElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGRadialGradientElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGRadialGradientElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGRadialGradientElement: { @@ -11530,10 +11531,10 @@ interface SVGRectElement extends SVGGraphicsElement { readonly width: SVGAnimatedLength; readonly x: SVGAnimatedLength; readonly y: SVGAnimatedLength; - addEventListener(type: K, listener: (this: SVGRectElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGRectElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGRectElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGRectElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGRectElement: { @@ -11543,10 +11544,10 @@ declare var SVGRectElement: { interface SVGScriptElement extends SVGElement, SVGURIReference { type: string; - addEventListener(type: K, listener: (this: SVGScriptElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGScriptElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGScriptElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGScriptElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGScriptElement: { @@ -11556,10 +11557,10 @@ declare var SVGScriptElement: { interface SVGStopElement extends SVGElement { readonly offset: SVGAnimatedNumber; - addEventListener(type: K, listener: (this: SVGStopElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGStopElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGStopElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGStopElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGStopElement: { @@ -11588,10 +11589,10 @@ interface SVGStyleElement extends SVGElement { media: string; title: string; type: string; - addEventListener(type: K, listener: (this: SVGStyleElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGStyleElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGStyleElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGStyleElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGStyleElement: { @@ -11651,10 +11652,10 @@ interface SVGSVGElement extends SVGGraphicsElement, DocumentEvent, SVGFitToViewB unpauseAnimations(): void; unsuspendRedraw(suspendHandleID: number): void; unsuspendRedrawAll(): void; - addEventListener(type: K, listener: (this: SVGSVGElement, ev: SVGSVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGSVGElement, ev: SVGSVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGSVGElement, ev: SVGSVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGSVGElement, ev: SVGSVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGSVGElement: { @@ -11663,10 +11664,10 @@ declare var SVGSVGElement: { }; interface SVGSwitchElement extends SVGGraphicsElement { - addEventListener(type: K, listener: (this: SVGSwitchElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGSwitchElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGSwitchElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGSwitchElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGSwitchElement: { @@ -11675,10 +11676,10 @@ declare var SVGSwitchElement: { }; interface SVGSymbolElement extends SVGElement, SVGFitToViewBox { - addEventListener(type: K, listener: (this: SVGSymbolElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGSymbolElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGSymbolElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGSymbolElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGSymbolElement: { @@ -11701,10 +11702,10 @@ interface SVGTextContentElement extends SVGGraphicsElement { readonly LENGTHADJUST_SPACING: number; readonly LENGTHADJUST_SPACINGANDGLYPHS: number; readonly LENGTHADJUST_UNKNOWN: number; - addEventListener(type: K, listener: (this: SVGTextContentElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGTextContentElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGTextContentElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGTextContentElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGTextContentElement: { @@ -11716,10 +11717,10 @@ declare var SVGTextContentElement: { }; interface SVGTextElement extends SVGTextPositioningElement { - addEventListener(type: K, listener: (this: SVGTextElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGTextElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGTextElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGTextElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGTextElement: { @@ -11737,10 +11738,10 @@ interface SVGTextPathElement extends SVGTextContentElement, SVGURIReference { readonly TEXTPATH_SPACINGTYPE_AUTO: number; readonly TEXTPATH_SPACINGTYPE_EXACT: number; readonly TEXTPATH_SPACINGTYPE_UNKNOWN: number; - addEventListener(type: K, listener: (this: SVGTextPathElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGTextPathElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGTextPathElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGTextPathElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGTextPathElement: { @@ -11760,10 +11761,10 @@ interface SVGTextPositioningElement extends SVGTextContentElement { readonly rotate: SVGAnimatedNumberList; readonly x: SVGAnimatedLengthList; readonly y: SVGAnimatedLengthList; - addEventListener(type: K, listener: (this: SVGTextPositioningElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGTextPositioningElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGTextPositioningElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGTextPositioningElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGTextPositioningElement: { @@ -11772,10 +11773,10 @@ declare var SVGTextPositioningElement: { }; interface SVGTitleElement extends SVGElement { - addEventListener(type: K, listener: (this: SVGTitleElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGTitleElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGTitleElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGTitleElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGTitleElement: { @@ -11833,10 +11834,10 @@ declare var SVGTransformList: { }; interface SVGTSpanElement extends SVGTextPositioningElement { - addEventListener(type: K, listener: (this: SVGTSpanElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGTSpanElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGTSpanElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGTSpanElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGTSpanElement: { @@ -11858,10 +11859,10 @@ interface SVGUseElement extends SVGGraphicsElement, SVGURIReference { readonly width: SVGAnimatedLength; readonly x: SVGAnimatedLength; readonly y: SVGAnimatedLength; - addEventListener(type: K, listener: (this: SVGUseElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGUseElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGUseElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGUseElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGUseElement: { @@ -11871,10 +11872,10 @@ declare var SVGUseElement: { interface SVGViewElement extends SVGElement, SVGZoomAndPan, SVGFitToViewBox { readonly viewTarget: SVGStringList; - addEventListener(type: K, listener: (this: SVGViewElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: SVGViewElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGViewElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: SVGViewElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGViewElement: { @@ -11994,10 +11995,10 @@ interface TextTrack extends EventTarget { readonly LOADING: number; readonly NONE: number; readonly SHOWING: number; - addEventListener(type: K, listener: (this: TextTrack, ev: TextTrackEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: TextTrack, ev: TextTrackEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: TextTrack, ev: TextTrackEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: TextTrack, ev: TextTrackEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var TextTrack: { @@ -12027,10 +12028,10 @@ interface TextTrackCue extends EventTarget { text: string; readonly track: TextTrack; getCueAsHTML(): DocumentFragment; - addEventListener(type: K, listener: (this: TextTrackCue, ev: TextTrackCueEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: TextTrackCue, ev: TextTrackCueEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: TextTrackCue, ev: TextTrackCueEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: TextTrackCue, ev: TextTrackCueEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var TextTrackCue: { @@ -12058,10 +12059,10 @@ interface TextTrackList extends EventTarget { readonly length: number; onaddtrack: ((this: TextTrackList, ev: TrackEvent) => any) | null; item(index: number): TextTrack; - addEventListener(type: K, listener: (this: TextTrackList, ev: TextTrackListEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: TextTrackList, ev: TextTrackListEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: TextTrackList, ev: TextTrackListEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: TextTrackList, ev: TextTrackListEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; [index: number]: TextTrack; } @@ -12269,10 +12270,10 @@ interface VideoTrackList extends EventTarget { readonly selectedIndex: number; getTrackById(id: string): VideoTrack | null; item(index: number): VideoTrack; - addEventListener(type: K, listener: (this: VideoTrackList, ev: VideoTrackListEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: VideoTrackList, ev: VideoTrackListEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: VideoTrackList, ev: VideoTrackListEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: VideoTrackList, ev: VideoTrackListEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; [index: number]: VideoTrack; } @@ -13290,10 +13291,10 @@ declare var WebKitPoint: { }; interface webkitRTCPeerConnection extends RTCPeerConnection { - addEventListener(type: K, listener: (this: webkitRTCPeerConnection, ev: RTCPeerConnectionEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: webkitRTCPeerConnection, ev: RTCPeerConnectionEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: webkitRTCPeerConnection, ev: RTCPeerConnectionEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: webkitRTCPeerConnection, ev: RTCPeerConnectionEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var webkitRTCPeerConnection: { @@ -13325,10 +13326,10 @@ interface WebSocket extends EventTarget { readonly CLOSING: number; readonly CONNECTING: number; readonly OPEN: number; - addEventListener(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var WebSocket: { @@ -13640,10 +13641,10 @@ interface Window extends EventTarget, WindowTimers, WindowSessionStorage, Window scroll(options?: ScrollToOptions): void; scrollTo(options?: ScrollToOptions): void; scrollBy(options?: ScrollToOptions): void; - addEventListener(type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var Window: { @@ -13659,10 +13660,10 @@ interface Worker extends EventTarget, AbstractWorker { onmessage: (this: Worker, ev: MessageEvent) => any; postMessage(message: any, transfer?: any[]): void; terminate(): void; - addEventListener(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var Worker: { @@ -13671,10 +13672,10 @@ declare var Worker: { }; interface XMLDocument extends Document { - addEventListener(type: K, listener: (this: XMLDocument, ev: DocumentEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: XMLDocument, ev: DocumentEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: XMLDocument, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: XMLDocument, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var XMLDocument: { @@ -13715,10 +13716,10 @@ interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget { readonly LOADING: number; readonly OPENED: number; readonly UNSENT: number; - addEventListener(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var XMLHttpRequest: { @@ -13732,10 +13733,10 @@ declare var XMLHttpRequest: { }; interface XMLHttpRequestUpload extends EventTarget, XMLHttpRequestEventTarget { - addEventListener(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var XMLHttpRequestUpload: { @@ -13840,10 +13841,10 @@ interface AbstractWorkerEventMap { interface AbstractWorker { onerror: (this: AbstractWorker, ev: ErrorEvent) => any; - addEventListener(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } interface Body { @@ -13988,10 +13989,10 @@ interface GlobalEventHandlers { onpointerover: (this: GlobalEventHandlers, ev: PointerEvent) => any; onpointerup: (this: GlobalEventHandlers, ev: PointerEvent) => any; onwheel: (this: GlobalEventHandlers, ev: WheelEvent) => any; - addEventListener(type: K, listener: (this: GlobalEventHandlers, ev: GlobalEventHandlersEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: GlobalEventHandlers, ev: GlobalEventHandlersEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: GlobalEventHandlers, ev: GlobalEventHandlersEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: GlobalEventHandlers, ev: GlobalEventHandlersEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } interface GlobalFetch { @@ -14043,10 +14044,10 @@ interface MSBaseReader { readonly DONE: number; readonly EMPTY: number; readonly LOADING: number; - addEventListener(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } interface MSFileSaver { @@ -14192,10 +14193,10 @@ interface XMLHttpRequestEventTarget { onloadstart: (this: XMLHttpRequest, ev: Event) => any; onprogress: (this: XMLHttpRequest, ev: ProgressEvent) => any; ontimeout: (this: XMLHttpRequest, ev: ProgressEvent) => any; - addEventListener(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } interface BroadcastChannel extends EventTarget { @@ -14204,8 +14205,10 @@ interface BroadcastChannel extends EventTarget { onmessageerror: (ev: MessageEvent) => any; close(): void; postMessage(message: any): void; - addEventListener(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var BroadcastChannel: { @@ -15085,10 +15088,10 @@ declare var indexedDB: IDBFactory; declare function atob(encodedString: string): string; declare function btoa(rawString: string): string; declare function fetch(input: RequestInfo, init?: RequestInit): Promise; -declare function addEventListener(type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, useCapture?: boolean): void; -declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; -declare function removeEventListener(type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, useCapture?: boolean): void; -declare function removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +declare function addEventListener(type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; +declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; +declare function removeEventListener(type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | EventListenerOptions): void; +declare function removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; type AAGUID = string; type AlgorithmIdentifier = string | Algorithm; type BodyInit = any; @@ -15112,7 +15115,6 @@ type GLsizeiptr = number; type GLubyte = number; type GLuint = number; type GLushort = number; -type HeadersInit = Headers | string[][]; type IDBKeyPath = string; type KeyFormat = string; type KeyType = string; @@ -15133,6 +15135,7 @@ type MouseWheelEvent = WheelEvent; type ScrollRestoration = "auto" | "manual"; type FormDataEntryValue = string | File; type InsertPosition = "beforebegin" | "afterbegin" | "beforeend" | "afterend"; +type HeadersInit = string[][] | { [key: string]: string }; type AppendMode = "segments" | "sequence"; type AudioContextState = "suspended" | "running" | "closed"; type BiquadFilterType = "lowpass" | "highpass" | "bandpass" | "lowshelf" | "highshelf" | "peaking" | "notch" | "allpass"; diff --git a/src/lib/webworker.generated.d.ts b/src/lib/webworker.generated.d.ts index 2651d1664ff..509c4b776c9 100644 --- a/src/lib/webworker.generated.d.ts +++ b/src/lib/webworker.generated.d.ts @@ -37,7 +37,7 @@ interface IDBIndexParameters { interface IDBObjectStoreParameters { autoIncrement?: boolean; - keyPath?: IDBKeyPath | null; + keyPath?: string | string[]; } interface KeyAlgorithm { @@ -74,7 +74,7 @@ interface RequestInit { body?: any; cache?: RequestCache; credentials?: RequestCredentials; - headers?: Headers | string[][]; + headers?: HeadersInit; integrity?: string; keepalive?: boolean; method?: string; @@ -86,7 +86,7 @@ interface RequestInit { } interface ResponseInit { - headers?: Headers | string[][]; + headers?: HeadersInit; status?: number; statusText?: string; } @@ -441,10 +441,10 @@ interface FileReader extends EventTarget, MSBaseReader { readAsBinaryString(blob: Blob): void; readAsDataURL(blob: Blob): void; readAsText(blob: Blob, encoding?: string): void; - addEventListener(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var FileReader: { @@ -472,7 +472,7 @@ interface Headers { declare var Headers: { prototype: Headers; - new(init?: Headers | string[][] | object): Headers; + new(init?: HeadersInit): Headers; }; interface IDBCursor { @@ -524,11 +524,12 @@ interface IDBDatabase extends EventTarget { createObjectStore(name: string, optionalParameters?: IDBObjectStoreParameters): IDBObjectStore; deleteObjectStore(name: string): void; transaction(storeNames: string | string[], mode?: IDBTransactionMode): IDBTransaction; - addEventListener(type: "versionchange", listener: (ev: IDBVersionChangeEvent) => any, useCapture?: boolean): void; - addEventListener(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: "versionchange", listener: (this: IDBDatabase, ev: IDBVersionChangeEvent) => any, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: "versionchange", listener: (this: IDBDatabase, ev: IDBVersionChangeEvent) => any, options?: boolean | EventListenerOptions): void; + addEventListener(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var IDBDatabase: { @@ -612,10 +613,10 @@ interface IDBOpenDBRequestEventMap extends IDBRequestEventMap { interface IDBOpenDBRequest extends IDBRequest { onblocked: (this: IDBOpenDBRequest, ev: Event) => any; onupgradeneeded: (this: IDBOpenDBRequest, ev: IDBVersionChangeEvent) => any; - addEventListener(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var IDBOpenDBRequest: { @@ -636,10 +637,10 @@ interface IDBRequest extends EventTarget { readonly result: any; source: IDBObjectStore | IDBIndex | IDBCursor; readonly transaction: IDBTransaction; - addEventListener(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var IDBRequest: { @@ -665,10 +666,10 @@ interface IDBTransaction extends EventTarget { readonly READ_ONLY: string; readonly READ_WRITE: string; readonly VERSION_CHANGE: string; - addEventListener(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var IDBTransaction: { @@ -733,10 +734,10 @@ interface MessagePort extends EventTarget { close(): void; postMessage(message?: any, transfer?: any[]): void; start(): void; - addEventListener(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var MessagePort: { @@ -764,10 +765,10 @@ interface Notification extends EventTarget { readonly tag: string; readonly title: string; close(): void; - addEventListener(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var Notification: { @@ -994,10 +995,10 @@ interface ServiceWorker extends EventTarget, AbstractWorker { readonly scriptURL: USVString; readonly state: ServiceWorkerState; postMessage(message: any, transfer?: any[]): void; - addEventListener(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var ServiceWorker: { @@ -1021,10 +1022,10 @@ interface ServiceWorkerRegistration extends EventTarget { showNotification(title: string, options?: NotificationOptions): Promise; unregister(): Promise; update(): Promise; - addEventListener(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var ServiceWorkerRegistration: { @@ -1089,10 +1090,10 @@ interface WebSocket extends EventTarget { readonly CLOSING: number; readonly CONNECTING: number; readonly OPEN: number; - addEventListener(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var WebSocket: { @@ -1112,10 +1113,10 @@ interface Worker extends EventTarget, AbstractWorker { onmessage: (this: Worker, ev: MessageEvent) => any; postMessage(message: any, transfer?: any[]): void; terminate(): void; - addEventListener(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var Worker: { @@ -1155,10 +1156,10 @@ interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget { readonly LOADING: number; readonly OPENED: number; readonly UNSENT: number; - addEventListener(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var XMLHttpRequest: { @@ -1172,10 +1173,10 @@ declare var XMLHttpRequest: { }; interface XMLHttpRequestUpload extends EventTarget, XMLHttpRequestEventTarget { - addEventListener(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var XMLHttpRequestUpload: { @@ -1189,10 +1190,10 @@ interface AbstractWorkerEventMap { interface AbstractWorker { onerror: (this: AbstractWorker, ev: ErrorEvent) => any; - addEventListener(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } interface Body { @@ -1229,10 +1230,10 @@ interface MSBaseReader { readonly DONE: number; readonly EMPTY: number; readonly LOADING: number; - addEventListener(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } interface NavigatorBeacon { @@ -1286,10 +1287,10 @@ interface XMLHttpRequestEventTarget { onloadstart: (this: XMLHttpRequest, ev: Event) => any; onprogress: (this: XMLHttpRequest, ev: ProgressEvent) => any; ontimeout: (this: XMLHttpRequest, ev: ProgressEvent) => any; - addEventListener(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } interface Client { @@ -1324,10 +1325,10 @@ interface DedicatedWorkerGlobalScope extends WorkerGlobalScope { onmessage: (this: DedicatedWorkerGlobalScope, ev: MessageEvent) => any; close(): void; postMessage(message: any, transfer?: any[]): void; - addEventListener(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var DedicatedWorkerGlobalScope: { @@ -1437,10 +1438,10 @@ interface ServiceWorkerGlobalScope extends WorkerGlobalScope { onsync: (this: ServiceWorkerGlobalScope, ev: SyncEvent) => any; readonly registration: ServiceWorkerRegistration; skipWaiting(): Promise; - addEventListener(type: K, listener: (this: ServiceWorkerGlobalScope, ev: ServiceWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: ServiceWorkerGlobalScope, ev: ServiceWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: ServiceWorkerGlobalScope, ev: ServiceWorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: ServiceWorkerGlobalScope, ev: ServiceWorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var ServiceWorkerGlobalScope: { @@ -1484,10 +1485,10 @@ interface WorkerGlobalScope extends EventTarget, WorkerUtils, WindowConsole, Glo msWriteProfilerMark(profilerMarkName: string): void; createImageBitmap(image: ImageBitmap | ImageData | Blob, options?: ImageBitmapOptions): Promise; createImageBitmap(image: ImageBitmap | ImageData | Blob, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise; - addEventListener(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; - removeEventListener(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var WorkerGlobalScope: { @@ -1544,8 +1545,10 @@ interface BroadcastChannel extends EventTarget { onmessageerror: (ev: MessageEvent) => any; close(): void; postMessage(message: any): void; - addEventListener(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var BroadcastChannel: { @@ -1875,10 +1878,10 @@ declare function btoa(rawString: string): string; declare var console: Console; declare function fetch(input: RequestInfo, init?: RequestInit): Promise; declare function dispatchEvent(evt: Event): boolean; -declare function addEventListener(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void; -declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; -declare function removeEventListener(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void; -declare function removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +declare function addEventListener(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; +declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; +declare function removeEventListener(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void; +declare function removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; type AlgorithmIdentifier = string | Algorithm; type BodyInit = any; type IDBKeyPath = string; @@ -1887,6 +1890,7 @@ type USVString = string; type IDBValidKey = number | string | Date | IDBArrayKey; type BufferSource = ArrayBuffer | ArrayBufferView; type FormDataEntryValue = string | File; +type HeadersInit = string[][] | { [key: string]: string }; type IDBCursorDirection = "next" | "nextunique" | "prev" | "prevunique"; type IDBRequestReadyState = "pending" | "done"; type IDBTransactionMode = "readonly" | "readwrite" | "versionchange"; From c3e19ab1319322241b9d55f6baa22cf617bc2819 Mon Sep 17 00:00:00 2001 From: Eugene Timokhov Date: Fri, 3 Nov 2017 02:17:10 +0300 Subject: [PATCH 088/235] Split ArrayConstructor.from method into 2 overloads #19682 (#19693) --- src/lib/es2015.core.d.ts | 8 +++++++- src/lib/es2015.iterable.d.ts | 8 +++++++- ...ingWellknownSymbolWithOutES6WellknownSymbolLib.symbols | 4 ++-- ...UsingWellknownSymbolWithOutES6WellknownSymbolLib.types | 4 ++-- .../modularizeLibrary_NoErrorDuplicateLibOptions1.symbols | 4 ++-- .../modularizeLibrary_NoErrorDuplicateLibOptions1.types | 4 ++-- .../modularizeLibrary_NoErrorDuplicateLibOptions2.symbols | 4 ++-- .../modularizeLibrary_NoErrorDuplicateLibOptions2.types | 4 ++-- .../modularizeLibrary_TargetES5UsingES6Lib.symbols | 4 ++-- .../modularizeLibrary_TargetES5UsingES6Lib.types | 4 ++-- .../modularizeLibrary_TargetES6UsingES6Lib.symbols | 4 ++-- .../modularizeLibrary_TargetES6UsingES6Lib.types | 4 ++-- .../modularizeLibrary_UsingES5LibAndES6ArrayLib.symbols | 4 ++-- .../modularizeLibrary_UsingES5LibAndES6ArrayLib.types | 4 ++-- ...ry_UsingES5LibES6ArrayLibES6WellknownSymbolLib.symbols | 4 ++-- ...rary_UsingES5LibES6ArrayLibES6WellknownSymbolLib.types | 4 ++-- 16 files changed, 42 insertions(+), 30 deletions(-) diff --git a/src/lib/es2015.core.d.ts b/src/lib/es2015.core.d.ts index 9ea773e3eef..0e1b46f2eb0 100644 --- a/src/lib/es2015.core.d.ts +++ b/src/lib/es2015.core.d.ts @@ -50,10 +50,16 @@ interface ArrayConstructor { /** * Creates an array from an array-like object. * @param arrayLike An array-like object to convert to an array. + */ + from(arrayLike: ArrayLike): T[]; + + /** + * Creates an array from an iterable object. + * @param arrayLike An array-like object to convert to an array. * @param mapfn A mapping function to call on every element of the array. * @param thisArg Value of 'this' used to invoke the mapfn. */ - from(arrayLike: ArrayLike, mapfn?: (v: T, k: number) => U, thisArg?: any): U[]; + from(arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; /** * Returns a new array from a set of elements. diff --git a/src/lib/es2015.iterable.d.ts b/src/lib/es2015.iterable.d.ts index 7b84c3e04c4..f3024bc334f 100644 --- a/src/lib/es2015.iterable.d.ts +++ b/src/lib/es2015.iterable.d.ts @@ -48,13 +48,19 @@ interface Array { } interface ArrayConstructor { + /** + * Creates an array from an iterable object. + * @param iterable An iterable object to convert to an array. + */ + from(iterable: Iterable): T[]; + /** * Creates an array from an iterable object. * @param iterable An iterable object to convert to an array. * @param mapfn A mapping function to call on every element of the array. * @param thisArg Value of 'this' used to invoke the mapfn. */ - from(iterable: Iterable, mapfn?: (v: T, k: number) => U, thisArg?: any): U[]; + from(iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } interface ReadonlyArray { diff --git a/tests/baselines/reference/modularizeLibrary_ErrorFromUsingWellknownSymbolWithOutES6WellknownSymbolLib.symbols b/tests/baselines/reference/modularizeLibrary_ErrorFromUsingWellknownSymbolWithOutES6WellknownSymbolLib.symbols index 917c5bbc654..4c51c416f3c 100644 --- a/tests/baselines/reference/modularizeLibrary_ErrorFromUsingWellknownSymbolWithOutES6WellknownSymbolLib.symbols +++ b/tests/baselines/reference/modularizeLibrary_ErrorFromUsingWellknownSymbolWithOutES6WellknownSymbolLib.symbols @@ -6,9 +6,9 @@ function f(x: number, y: number, z: number) { >z : Symbol(z, Decl(modularizeLibrary_ErrorFromUsingWellknownSymbolWithOutES6WellknownSymbolLib.ts, 0, 32)) return Array.from(arguments); ->Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.core.d.ts, --, --)) +>Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >Array : Symbol(Array, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->from : Symbol(ArrayConstructor.from, Decl(lib.es2015.core.d.ts, --, --)) +>from : Symbol(ArrayConstructor.from, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >arguments : Symbol(arguments) } diff --git a/tests/baselines/reference/modularizeLibrary_ErrorFromUsingWellknownSymbolWithOutES6WellknownSymbolLib.types b/tests/baselines/reference/modularizeLibrary_ErrorFromUsingWellknownSymbolWithOutES6WellknownSymbolLib.types index 73dad44343b..1f8f0c5cb63 100644 --- a/tests/baselines/reference/modularizeLibrary_ErrorFromUsingWellknownSymbolWithOutES6WellknownSymbolLib.types +++ b/tests/baselines/reference/modularizeLibrary_ErrorFromUsingWellknownSymbolWithOutES6WellknownSymbolLib.types @@ -7,9 +7,9 @@ function f(x: number, y: number, z: number) { return Array.from(arguments); >Array.from(arguments) : any[] ->Array.from : (arrayLike: ArrayLike, mapfn?: (v: T, k: number) => U, thisArg?: any) => U[] +>Array.from : { (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >Array : ArrayConstructor ->from : (arrayLike: ArrayLike, mapfn?: (v: T, k: number) => U, thisArg?: any) => U[] +>from : { (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >arguments : IArguments } diff --git a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.symbols b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.symbols index 6842ec9ae25..1f55a3890ff 100644 --- a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.symbols +++ b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.symbols @@ -7,9 +7,9 @@ function f(x: number, y: number, z: number) { >z : Symbol(z, Decl(modularizeLibrary_NoErrorDuplicateLibOptions1.ts, 1, 32)) return Array.from(arguments); ->Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >Array : Symbol(Array, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >arguments : Symbol(arguments) } diff --git a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.types b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.types index 4743391fcf1..afc286ca708 100644 --- a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.types +++ b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.types @@ -8,9 +8,9 @@ function f(x: number, y: number, z: number) { return Array.from(arguments); >Array.from(arguments) : any[] ->Array.from : { (iterable: Iterable, mapfn?: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike, mapfn?: (v: T, k: number) => U, thisArg?: any): U[]; } +>Array.from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >Array : ArrayConstructor ->from : { (iterable: Iterable, mapfn?: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike, mapfn?: (v: T, k: number) => U, thisArg?: any): U[]; } +>from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >arguments : IArguments } diff --git a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.symbols b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.symbols index d9af41e6027..d6eb97d3673 100644 --- a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.symbols +++ b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.symbols @@ -7,9 +7,9 @@ function f(x: number, y: number, z: number) { >z : Symbol(z, Decl(modularizeLibrary_NoErrorDuplicateLibOptions2.ts, 1, 32)) return Array.from(arguments); ->Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >Array : Symbol(Array, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >arguments : Symbol(arguments) } diff --git a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.types b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.types index a700c1c03f6..d394c411c4d 100644 --- a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.types +++ b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.types @@ -8,9 +8,9 @@ function f(x: number, y: number, z: number) { return Array.from(arguments); >Array.from(arguments) : any[] ->Array.from : { (iterable: Iterable, mapfn?: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike, mapfn?: (v: T, k: number) => U, thisArg?: any): U[]; } +>Array.from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >Array : ArrayConstructor ->from : { (iterable: Iterable, mapfn?: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike, mapfn?: (v: T, k: number) => U, thisArg?: any): U[]; } +>from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >arguments : IArguments } diff --git a/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.symbols b/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.symbols index 2ae943ab81d..08e90ead0ea 100644 --- a/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.symbols +++ b/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.symbols @@ -7,9 +7,9 @@ function f(x: number, y: number, z: number) { >z : Symbol(z, Decl(modularizeLibrary_TargetES5UsingES6Lib.ts, 1, 32)) return Array.from(arguments); ->Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >Array : Symbol(Array, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >arguments : Symbol(arguments) } diff --git a/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.types b/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.types index d51e87c8b9d..479747d3e0e 100644 --- a/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.types +++ b/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.types @@ -8,9 +8,9 @@ function f(x: number, y: number, z: number) { return Array.from(arguments); >Array.from(arguments) : any[] ->Array.from : { (iterable: Iterable, mapfn?: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike, mapfn?: (v: T, k: number) => U, thisArg?: any): U[]; } +>Array.from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >Array : ArrayConstructor ->from : { (iterable: Iterable, mapfn?: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike, mapfn?: (v: T, k: number) => U, thisArg?: any): U[]; } +>from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >arguments : IArguments } diff --git a/tests/baselines/reference/modularizeLibrary_TargetES6UsingES6Lib.symbols b/tests/baselines/reference/modularizeLibrary_TargetES6UsingES6Lib.symbols index 182daeefd1a..1d3f903f880 100644 --- a/tests/baselines/reference/modularizeLibrary_TargetES6UsingES6Lib.symbols +++ b/tests/baselines/reference/modularizeLibrary_TargetES6UsingES6Lib.symbols @@ -7,9 +7,9 @@ function f(x: number, y: number, z: number) { >z : Symbol(z, Decl(modularizeLibrary_TargetES6UsingES6Lib.ts, 1, 32)) return Array.from(arguments); ->Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) ->from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >arguments : Symbol(arguments) } diff --git a/tests/baselines/reference/modularizeLibrary_TargetES6UsingES6Lib.types b/tests/baselines/reference/modularizeLibrary_TargetES6UsingES6Lib.types index 8296220b36e..efb2beddb4f 100644 --- a/tests/baselines/reference/modularizeLibrary_TargetES6UsingES6Lib.types +++ b/tests/baselines/reference/modularizeLibrary_TargetES6UsingES6Lib.types @@ -8,9 +8,9 @@ function f(x: number, y: number, z: number) { return Array.from(arguments); >Array.from(arguments) : any[] ->Array.from : { (iterable: Iterable, mapfn?: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike, mapfn?: (v: T, k: number) => U, thisArg?: any): U[]; } +>Array.from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >Array : ArrayConstructor ->from : { (iterable: Iterable, mapfn?: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike, mapfn?: (v: T, k: number) => U, thisArg?: any): U[]; } +>from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >arguments : IArguments } diff --git a/tests/baselines/reference/modularizeLibrary_UsingES5LibAndES6ArrayLib.symbols b/tests/baselines/reference/modularizeLibrary_UsingES5LibAndES6ArrayLib.symbols index a9f94d2e1ca..489d23c4d48 100644 --- a/tests/baselines/reference/modularizeLibrary_UsingES5LibAndES6ArrayLib.symbols +++ b/tests/baselines/reference/modularizeLibrary_UsingES5LibAndES6ArrayLib.symbols @@ -7,9 +7,9 @@ function f(x: number, y: number, z: number) { >z : Symbol(z, Decl(modularizeLibrary_UsingES5LibAndES6ArrayLib.ts, 1, 32)) return Array.from(arguments); ->Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.core.d.ts, --, --)) +>Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >Array : Symbol(Array, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->from : Symbol(ArrayConstructor.from, Decl(lib.es2015.core.d.ts, --, --)) +>from : Symbol(ArrayConstructor.from, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >arguments : Symbol(arguments) } diff --git a/tests/baselines/reference/modularizeLibrary_UsingES5LibAndES6ArrayLib.types b/tests/baselines/reference/modularizeLibrary_UsingES5LibAndES6ArrayLib.types index 7a3d1a8c7c3..d624c1ac259 100644 --- a/tests/baselines/reference/modularizeLibrary_UsingES5LibAndES6ArrayLib.types +++ b/tests/baselines/reference/modularizeLibrary_UsingES5LibAndES6ArrayLib.types @@ -8,9 +8,9 @@ function f(x: number, y: number, z: number) { return Array.from(arguments); >Array.from(arguments) : any[] ->Array.from : (arrayLike: ArrayLike, mapfn?: (v: T, k: number) => U, thisArg?: any) => U[] +>Array.from : { (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >Array : ArrayConstructor ->from : (arrayLike: ArrayLike, mapfn?: (v: T, k: number) => U, thisArg?: any) => U[] +>from : { (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >arguments : IArguments } diff --git a/tests/baselines/reference/modularizeLibrary_UsingES5LibES6ArrayLibES6WellknownSymbolLib.symbols b/tests/baselines/reference/modularizeLibrary_UsingES5LibES6ArrayLibES6WellknownSymbolLib.symbols index 7870c6362d3..b00d1aba743 100644 --- a/tests/baselines/reference/modularizeLibrary_UsingES5LibES6ArrayLibES6WellknownSymbolLib.symbols +++ b/tests/baselines/reference/modularizeLibrary_UsingES5LibES6ArrayLibES6WellknownSymbolLib.symbols @@ -6,9 +6,9 @@ function f(x: number, y: number, z: number) { >z : Symbol(z, Decl(modularizeLibrary_UsingES5LibES6ArrayLibES6WellknownSymbolLib.ts, 0, 32)) return Array.from(arguments); ->Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.core.d.ts, --, --)) +>Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >Array : Symbol(Array, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->from : Symbol(ArrayConstructor.from, Decl(lib.es2015.core.d.ts, --, --)) +>from : Symbol(ArrayConstructor.from, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >arguments : Symbol(arguments) } diff --git a/tests/baselines/reference/modularizeLibrary_UsingES5LibES6ArrayLibES6WellknownSymbolLib.types b/tests/baselines/reference/modularizeLibrary_UsingES5LibES6ArrayLibES6WellknownSymbolLib.types index 1012cbad340..caca4cf8759 100644 --- a/tests/baselines/reference/modularizeLibrary_UsingES5LibES6ArrayLibES6WellknownSymbolLib.types +++ b/tests/baselines/reference/modularizeLibrary_UsingES5LibES6ArrayLibES6WellknownSymbolLib.types @@ -7,9 +7,9 @@ function f(x: number, y: number, z: number) { return Array.from(arguments); >Array.from(arguments) : any[] ->Array.from : (arrayLike: ArrayLike, mapfn?: (v: T, k: number) => U, thisArg?: any) => U[] +>Array.from : { (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >Array : ArrayConstructor ->from : (arrayLike: ArrayLike, mapfn?: (v: T, k: number) => U, thisArg?: any) => U[] +>from : { (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >arguments : IArguments } From 2ea723f3156b0e224d438330951e2bf1edf8c065 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 2 Nov 2017 16:36:57 -0700 Subject: [PATCH 089/235] Accept user test baselines --- tests/baselines/reference/user/vuex.log | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/baselines/reference/user/vuex.log b/tests/baselines/reference/user/vuex.log index 47a500804bd..15b10503c1f 100644 --- a/tests/baselines/reference/user/vuex.log +++ b/tests/baselines/reference/user/vuex.log @@ -1,6 +1,5 @@ -Exit Code: 2 +Exit Code: 0 Standard output: -node_modules/vuex/types/index.d.ts(124,16): error TS2714: The expression of an export assignment must be an identifier or qualified name in an ambient context. From 5b0bcecfae0d7b3dc8f5f0a00e48847610767d79 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 2 Nov 2017 16:58:41 -0700 Subject: [PATCH 090/235] Properly handle intersection types in getUnmatchedProperty --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 09354d957a3..840a6351a2f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10792,7 +10792,7 @@ namespace ts { } function getUnmatchedProperty(source: Type, target: Type, requireOptionalProperties: boolean) { - const properties = getPropertiesOfObjectType(target); + const properties = target.flags & TypeFlags.Intersection ? getPropertiesOfUnionOrIntersectionType(target) : getPropertiesOfObjectType(target); for (const targetProp of properties) { if (requireOptionalProperties || !(targetProp.flags & SymbolFlags.Optional)) { const sourceProp = getPropertyOfType(source, targetProp.escapedName); From 2191b75fc70ea5ae6b4bde1d61228980f9e7bca5 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 2 Nov 2017 17:07:31 -0700 Subject: [PATCH 091/235] Accept new baselines --- ...ssFunctionComponentsWithTypeArguments4.errors.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments4.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments4.errors.txt index 2feed16ac0a..d692364d264 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments4.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments4.errors.txt @@ -1,9 +1,9 @@ tests/cases/conformance/jsx/file.tsx(9,33): error TS2322: Type '{ a: number; }' is not assignable to type 'IntrinsicAttributes & { b: {}; a: number; }'. Type '{ a: number; }' is not assignable to type '{ b: {}; a: number; }'. Property 'b' is missing in type '{ a: number; }'. -tests/cases/conformance/jsx/file.tsx(10,33): error TS2322: Type 'T' is not assignable to type 'IntrinsicAttributes & { b: number; a: {}; }'. - Type '{ b: number; }' is not assignable to type 'IntrinsicAttributes & { b: number; a: {}; }'. - Type '{ b: number; }' is not assignable to type '{ b: number; a: {}; }'. +tests/cases/conformance/jsx/file.tsx(10,33): error TS2322: Type 'T' is not assignable to type 'IntrinsicAttributes & { b: {}; a: {}; }'. + Type '{ b: number; }' is not assignable to type 'IntrinsicAttributes & { b: {}; a: {}; }'. + Type '{ b: number; }' is not assignable to type '{ b: {}; a: {}; }'. Property 'a' is missing in type '{ b: number; }'. Type 'T' is not assignable to type 'IntrinsicAttributes'. Type '{ b: number; }' has no properties in common with type 'IntrinsicAttributes'. @@ -25,9 +25,9 @@ tests/cases/conformance/jsx/file.tsx(10,33): error TS2322: Type 'T' is not assig !!! error TS2322: Property 'b' is missing in type '{ a: number; }'. let a2 = // missing a ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2322: Type 'T' is not assignable to type 'IntrinsicAttributes & { b: number; a: {}; }'. -!!! error TS2322: Type '{ b: number; }' is not assignable to type 'IntrinsicAttributes & { b: number; a: {}; }'. -!!! error TS2322: Type '{ b: number; }' is not assignable to type '{ b: number; a: {}; }'. +!!! error TS2322: Type 'T' is not assignable to type 'IntrinsicAttributes & { b: {}; a: {}; }'. +!!! error TS2322: Type '{ b: number; }' is not assignable to type 'IntrinsicAttributes & { b: {}; a: {}; }'. +!!! error TS2322: Type '{ b: number; }' is not assignable to type '{ b: {}; a: {}; }'. !!! error TS2322: Property 'a' is missing in type '{ b: number; }'. !!! error TS2322: Type 'T' is not assignable to type 'IntrinsicAttributes'. !!! error TS2322: Type '{ b: number; }' has no properties in common with type 'IntrinsicAttributes'. From fd415214219476754bd89c2f707b0e794451a076 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 2 Nov 2017 17:16:09 -0700 Subject: [PATCH 092/235] Enable 'callable-types' tslint rule (#19654) --- src/compiler/resolutionCache.ts | 5 ++--- src/compiler/scanner.ts | 4 +--- src/compiler/types.ts | 18 ++++++++--------- src/harness/harness.ts | 12 ++++++++--- src/server/editorServices.ts | 4 +--- src/server/project.ts | 4 +--- .../formatting/ruleOperationContext.ts | 4 ++-- .../reference/api/tsserverlibrary.d.ts | 20 ++++++------------- tests/baselines/reference/api/typescript.d.ts | 8 ++------ tslint.json | 1 - 10 files changed, 33 insertions(+), 47 deletions(-) diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index edc66df8fa3..e21e81a2e88 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -69,9 +69,8 @@ namespace ts { export const maxNumberOfFilesToIterateForInvalidation = 256; - interface GetResolutionWithResolvedFileName { - (resolution: T): R; - } + type GetResolutionWithResolvedFileName = + (resolution: T) => R; export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootDirForResolution: string): ResolutionCache { let filesWithChangedSetOfUnresolvedImports: Path[] | undefined; diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 521a1983254..fa6a50ec51d 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -2,9 +2,7 @@ /// namespace ts { - export interface ErrorCallback { - (message: DiagnosticMessage, length: number): void; - } + export type ErrorCallback = (message: DiagnosticMessage, length: number) => void; /* @internal */ export function tokenIsIdentifierOrKeyword(token: SyntaxKind): boolean { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 549c0f8d52f..1fda7d8f49d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2471,9 +2471,13 @@ namespace ts { readFile(path: string): string | undefined; } - export interface WriteFileCallback { - (fileName: string, data: string, writeByteOrderMark: boolean, onError: ((message: string) => void) | undefined, sourceFiles: ReadonlyArray): void; - } + export type WriteFileCallback = ( + fileName: string, + data: string, + writeByteOrderMark: boolean, + onError: ((message: string) => void) | undefined, + sourceFiles: ReadonlyArray, + ) => void; export class OperationCanceledException { } @@ -3582,9 +3586,7 @@ namespace ts { } /* @internal */ - export interface TypeMapper { - (t: TypeParameter): Type; - } + export type TypeMapper = (t: TypeParameter) => Type; export const enum InferencePriority { Contravariant = 1 << 0, // Inference from contravariant position @@ -4192,9 +4194,7 @@ namespace ts { } /* @internal */ - export interface HasInvalidatedResolution { - (sourceFile: Path): boolean; - } + export type HasInvalidatedResolution = (sourceFile: Path) => boolean; export interface CompilerHost extends ModuleResolutionHost { getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void, shouldCreateNewSourceFile?: boolean): SourceFile | undefined; diff --git a/src/harness/harness.ts b/src/harness/harness.ts index c6caeff0dd9..d5159b5c5f5 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -784,9 +784,15 @@ namespace Harness { ? IO.newLine() + `//# sourceURL=${IO.resolvePath(tcServicesFileName)}` : ""); - export interface SourceMapEmitterCallback { - (emittedFile: string, emittedLine: number, emittedColumn: number, sourceFile: string, sourceLine: number, sourceColumn: number, sourceName: string): void; - } + export type SourceMapEmitterCallback = ( + emittedFile: string, + emittedLine: number, + emittedColumn: number, + sourceFile: string, + sourceLine: number, + sourceColumn: number, + sourceName: string, + ) => void; // Settings export let userSpecifiedRoot = ""; diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 35f888ebc7d..9ec190c152f 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -78,9 +78,7 @@ namespace ts.server { export type ProjectServiceEvent = ProjectsUpdatedInBackgroundEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent; - export interface ProjectServiceEventHandler { - (event: ProjectServiceEvent): void; - } + export type ProjectServiceEventHandler = (event: ProjectServiceEvent) => void; export interface SafeList { [name: string]: { match: RegExp, exclude?: (string | number)[][], types?: string[] }; diff --git a/src/server/project.ts b/src/server/project.ts index 0e1e7ac2cab..0444e9304b5 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -98,9 +98,7 @@ namespace ts.server { getExternalFiles?(proj: Project): string[]; } - export interface PluginModuleFactory { - (mod: { typescript: typeof ts }): PluginModule; - } + export type PluginModuleFactory = (mod: { typescript: typeof ts }) => PluginModule; /** * The project root can be script info - if root is present, diff --git a/src/services/formatting/ruleOperationContext.ts b/src/services/formatting/ruleOperationContext.ts index bf96363ad7d..f03b19516d5 100644 --- a/src/services/formatting/ruleOperationContext.ts +++ b/src/services/formatting/ruleOperationContext.ts @@ -4,9 +4,9 @@ namespace ts.formatting { export class RuleOperationContext { - private readonly customContextChecks: { (context: FormattingContext): boolean; }[]; + private readonly customContextChecks: ((context: FormattingContext) => boolean)[]; - constructor(...funcs: { (context: FormattingContext): boolean; }[]) { + constructor(...funcs: ((context: FormattingContext) => boolean)[]) { this.customContextChecks = funcs; } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 7fbff83009f..2bce9cbf49a 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1623,9 +1623,7 @@ declare namespace ts { fileExists(path: string): boolean; readFile(path: string): string | undefined; } - interface WriteFileCallback { - (fileName: string, data: string, writeByteOrderMark: boolean, onError: ((message: string) => void) | undefined, sourceFiles: ReadonlyArray): void; - } + type WriteFileCallback = (fileName: string, data: string, writeByteOrderMark: boolean, onError: ((message: string) => void) | undefined, sourceFiles: ReadonlyArray) => void; class OperationCanceledException { } interface CancellationToken { @@ -3095,9 +3093,7 @@ declare namespace ts { function isGetAccessor(node: Node): node is GetAccessorDeclaration; } declare namespace ts { - interface ErrorCallback { - (message: DiagnosticMessage, length: number): void; - } + type ErrorCallback = (message: DiagnosticMessage, length: number) => void; interface Scanner { getStartPos(): number; getToken(): SyntaxKind; @@ -7144,11 +7140,9 @@ declare namespace ts.server { create(createInfo: PluginCreateInfo): LanguageService; getExternalFiles?(proj: Project): string[]; } - interface PluginModuleFactory { - (mod: { - typescript: typeof ts; - }): PluginModule; - } + type PluginModuleFactory = (mod: { + typescript: typeof ts; + }) => PluginModule; /** * The project root can be script info - if root is present, * or it could be just normalized path if root wasnt present on the host(only for non inferred project) @@ -7418,9 +7412,7 @@ declare namespace ts.server { readonly dts: number; } type ProjectServiceEvent = ProjectsUpdatedInBackgroundEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent; - interface ProjectServiceEventHandler { - (event: ProjectServiceEvent): void; - } + type ProjectServiceEventHandler = (event: ProjectServiceEvent) => void; interface SafeList { [name: string]: { match: RegExp; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 73d069757df..48105ea7d12 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1623,9 +1623,7 @@ declare namespace ts { fileExists(path: string): boolean; readFile(path: string): string | undefined; } - interface WriteFileCallback { - (fileName: string, data: string, writeByteOrderMark: boolean, onError: ((message: string) => void) | undefined, sourceFiles: ReadonlyArray): void; - } + type WriteFileCallback = (fileName: string, data: string, writeByteOrderMark: boolean, onError: ((message: string) => void) | undefined, sourceFiles: ReadonlyArray) => void; class OperationCanceledException { } interface CancellationToken { @@ -2758,9 +2756,7 @@ declare namespace ts { let sys: System; } declare namespace ts { - interface ErrorCallback { - (message: DiagnosticMessage, length: number): void; - } + type ErrorCallback = (message: DiagnosticMessage, length: number) => void; interface Scanner { getStartPos(): number; getToken(): SyntaxKind; diff --git a/tslint.json b/tslint.json index 13c9e161958..197dc43729d 100644 --- a/tslint.json +++ b/tslint.json @@ -76,7 +76,6 @@ "arrow-return-shorthand": false, "ban-comma-operator": false, "ban-types": false, - "callable-types": false, "forin": false, "member-access": false, // [true, "no-public"] "no-conditional-assignment": false, From c70eae49933eac79a1f761b15cf2bbdb381a5805 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 2 Nov 2017 17:19:50 -0700 Subject: [PATCH 093/235] Enable 'no-this-assignment' lint rule (#19696) --- src/harness/fourslash.ts | 41 +++++++++++++++++++--------------------- tslint.json | 1 - 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 652737f9b57..2b535b223ab 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -873,37 +873,34 @@ namespace FourSlash { * @param spanIndex the index of the range that the completion item's replacement text span should match */ public verifyCompletionListDoesNotContain(entryId: ts.Completions.CompletionEntryIdentifier, expectedText?: string, expectedDocumentation?: string, expectedKind?: string, spanIndex?: number) { - const that = this; let replacementSpan: ts.TextSpan; if (spanIndex !== undefined) { replacementSpan = this.getTextSpanForRangeAtIndex(spanIndex); } - function filterByTextOrDocumentation(entry: ts.CompletionEntry) { - const details = that.getCompletionEntryDetails(entry.name); - const documentation = details && ts.displayPartsToString(details.documentation); - const text = details && ts.displayPartsToString(details.displayParts); - - // If any of the expected values are undefined, assume that users don't - // care about them. - if (replacementSpan && !TestState.textSpansEqual(replacementSpan, entry.replacementSpan)) { - return false; - } - else if (expectedText && text !== expectedText) { - return false; - } - else if (expectedDocumentation && documentation !== expectedDocumentation) { - return false; - } - - return true; - } - const completions = this.getCompletionListAtCaret(); if (completions) { let filterCompletions = completions.entries.filter(e => e.name === entryId.name && e.source === entryId.source); filterCompletions = expectedKind ? filterCompletions.filter(e => e.kind === expectedKind) : filterCompletions; - filterCompletions = filterCompletions.filter(filterByTextOrDocumentation); + filterCompletions = filterCompletions.filter(entry => { + const details = this.getCompletionEntryDetails(entry.name); + const documentation = details && ts.displayPartsToString(details.documentation); + const text = details && ts.displayPartsToString(details.displayParts); + + // If any of the expected values are undefined, assume that users don't + // care about them. + if (replacementSpan && !TestState.textSpansEqual(replacementSpan, entry.replacementSpan)) { + return false; + } + else if (expectedText && text !== expectedText) { + return false; + } + else if (expectedDocumentation && documentation !== expectedDocumentation) { + return false; + } + + return true; + }); if (filterCompletions.length !== 0) { // After filtered using all present criterion, if there are still symbol left in the list // then these symbols must meet the criterion for Not supposed to be in the list. So we diff --git a/tslint.json b/tslint.json index 197dc43729d..fa89fea6f49 100644 --- a/tslint.json +++ b/tslint.json @@ -89,7 +89,6 @@ "no-object-literal-type-assertion": false, "no-shadowed-variable": false, "no-submodule-imports": false, - "no-this-assignment": false, "no-unused-expression": false, "no-unnecessary-initializer": false, "no-var-requires": false, From f67a9ba96e26c0d142934dc73d55d727bd238ae8 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 2 Nov 2017 17:20:18 -0700 Subject: [PATCH 094/235] Apply 'interface-name' lint rule (#19695) --- Gulpfile.ts | 2 +- Jakefile.js | 2 +- src/harness/harness.ts | 6 +++--- src/harness/harnessLanguageService.ts | 6 +++--- src/harness/loggedIO.ts | 30 +++++++++++++-------------- src/harness/rwcRunner.ts | 4 ++-- src/server/scriptVersionCache.ts | 18 ++++++++-------- src/server/server.ts | 6 +++--- src/server/typingsCache.ts | 1 + src/services/shims.ts | 6 +++--- src/services/types.ts | 1 + tslint.json | 2 +- 12 files changed, 43 insertions(+), 41 deletions(-) diff --git a/Gulpfile.ts b/Gulpfile.ts index 283535208ed..58aa9b9329f 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -1106,7 +1106,7 @@ gulp.task("lint", "Runs tslint on the compiler sources. Optional arguments are: const fileMatcher = cmdLineOptions.files; const files = fileMatcher ? `src/**/${fileMatcher}` - : "Gulpfile.ts 'scripts/generateLocalizedDiagnosticMessages.ts' 'scripts/tslint/**/*.ts' 'src/**/*.ts' --exclude src/lib/es5.d.ts --exclude 'src/lib/*.generated.d.ts'"; + : "Gulpfile.ts 'scripts/generateLocalizedDiagnosticMessages.ts' 'scripts/tslint/**/*.ts' 'src/**/*.ts' --exclude 'src/lib/*.d.ts'"; const cmd = `node node_modules/tslint/bin/tslint ${files} --formatters-dir ./built/local/tslint/formatters --format autolinkableStylish`; console.log("Linting: " + cmd); child_process.execSync(cmd, { stdio: [0, 1, 2] }); diff --git a/Jakefile.js b/Jakefile.js index b7973c092f2..13607f7b40f 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -1283,7 +1283,7 @@ task("lint", ["build-rules"], () => { const fileMatcher = process.env.f || process.env.file || process.env.files; const files = fileMatcher ? `src/**/${fileMatcher}` - : "Gulpfile.ts 'scripts/generateLocalizedDiagnosticMessages.ts' 'scripts/tslint/**/*.ts' 'src/**/*.ts' --exclude src/lib/es5.d.ts --exclude 'src/lib/*.generated.d.ts'"; + : "Gulpfile.ts 'scripts/generateLocalizedDiagnosticMessages.ts' 'scripts/tslint/**/*.ts' 'src/**/*.ts' --exclude 'src/lib/*.d.ts'"; const cmd = `node node_modules/tslint/bin/tslint ${files} --formatters-dir ./built/local/tslint/formatters --format autolinkableStylish`; console.log("Linting: " + cmd); jake.exec([cmd], { interactive: true }, () => { diff --git a/src/harness/harness.ts b/src/harness/harness.ts index d5159b5c5f5..ada7f06f3b3 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -479,7 +479,7 @@ namespace Utils { } namespace Harness { - export interface IO { + export interface Io { newLine(): string; getCurrentDirectory(): string; useCaseSensitiveFileNames(): boolean; @@ -502,7 +502,7 @@ namespace Harness { tryEnableSourceMapsForHost?(): void; getEnvironmentVariable?(name: string): string; } - export let IO: IO; + export let IO: Io; // harness always uses one kind of new line // But note that `parseTestData` in `fourslash.ts` uses "\n" @@ -2151,7 +2151,7 @@ namespace Harness { return filePath.indexOf(Harness.libFolder) === 0; } - export function getDefaultLibraryFile(io: Harness.IO): Harness.Compiler.TestFile { + export function getDefaultLibraryFile(io: Harness.Io): Harness.Compiler.TestFile { const libFile = Harness.userSpecifiedRoot + Harness.libFolder + Harness.Compiler.defaultLibFileName; return { unitName: libFile, content: io.readFile(libFile) }; } diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 55d43758734..d1b3c197471 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -544,9 +544,9 @@ namespace Harness.LanguageService { getClassifier(): ts.Classifier { return new ClassifierShimProxy(this.factory.createClassifierShim(this.host)); } getPreProcessedFileInfo(fileName: string, fileContents: string): ts.PreProcessedFileInfo { let shimResult: { - referencedFiles: ts.IFileReference[]; - typeReferenceDirectives: ts.IFileReference[]; - importedFiles: ts.IFileReference[]; + referencedFiles: ts.ShimsFileReference[]; + typeReferenceDirectives: ts.ShimsFileReference[]; + importedFiles: ts.ShimsFileReference[]; isLibFile: boolean; }; diff --git a/src/harness/loggedIO.ts b/src/harness/loggedIO.ts index 55be4068e83..29e9dba7fc5 100644 --- a/src/harness/loggedIO.ts +++ b/src/harness/loggedIO.ts @@ -14,19 +14,19 @@ interface FileInformation { interface FindFileResult { } -interface IOLogFile { +interface IoLogFile { path: string; codepage: number; result?: FileInformation; } -interface IOLog { +interface IoLog { timestamp: string; arguments: string[]; executingPath: string; currentDirectory: string; useCustomLibraryFile?: boolean; - filesRead: IOLogFile[]; + filesRead: IoLogFile[]; filesWritten: { path: string; contents?: string; @@ -80,16 +80,16 @@ interface IOLog { interface PlaybackControl { startReplayFromFile(logFileName: string): void; startReplayFromString(logContents: string): void; - startReplayFromData(log: IOLog): void; + startReplayFromData(log: IoLog): void; endReplay(): void; startRecord(logFileName: string): void; endRecord(): void; } namespace Playback { - let recordLog: IOLog = undefined; - let replayLog: IOLog = undefined; - let replayFilesRead: ts.Map | undefined = undefined; + let recordLog: IoLog = undefined; + let replayLog: IoLog = undefined; + let replayFilesRead: ts.Map | undefined = undefined; let recordLogFileNameBase = ""; interface Memoized { @@ -110,11 +110,11 @@ namespace Playback { return run; } - export interface PlaybackIO extends Harness.IO, PlaybackControl { } + export interface PlaybackIO extends Harness.Io, PlaybackControl { } export interface PlaybackSystem extends ts.System, PlaybackControl { } - function createEmptyLog(): IOLog { + function createEmptyLog(): IoLog { return { timestamp: (new Date()).toString(), arguments: [], @@ -134,7 +134,7 @@ namespace Playback { }; } - export function newStyleLogIntoOldStyleLog(log: IOLog, host: ts.System | Harness.IO, baseName: string) { + export function newStyleLogIntoOldStyleLog(log: IoLog, host: ts.System | Harness.Io, baseName: string) { for (const file of log.filesAppended) { if (file.contentsPath) { file.contents = host.readFile(ts.combinePaths(baseName, file.contentsPath)); @@ -167,7 +167,7 @@ namespace Playback { return path; } - export function oldStyleLogIntoNewStyleLog(log: IOLog, writeFile: typeof Harness.IO.writeFile, baseTestName: string) { + export function oldStyleLogIntoNewStyleLog(log: IoLog, writeFile: typeof Harness.IO.writeFile, baseTestName: string) { if (log.filesAppended) { for (const file of log.filesAppended) { if (file.contents !== undefined) { @@ -210,8 +210,8 @@ namespace Playback { } function initWrapper(wrapper: PlaybackSystem, underlying: ts.System): void; - function initWrapper(wrapper: PlaybackIO, underlying: Harness.IO): void; - function initWrapper(wrapper: PlaybackSystem | PlaybackIO, underlying: ts.System | Harness.IO): void { + function initWrapper(wrapper: PlaybackIO, underlying: Harness.Io): void; + function initWrapper(wrapper: PlaybackSystem | PlaybackIO, underlying: ts.System | Harness.Io): void { ts.forEach(Object.keys(underlying), prop => { (wrapper)[prop] = (underlying)[prop]; }); @@ -261,7 +261,7 @@ namespace Playback { } }; - function generateTsconfig(newLog: IOLog): undefined | { compilerOptions: ts.CompilerOptions, files: string[] } { + function generateTsconfig(newLog: IoLog): undefined | { compilerOptions: ts.CompilerOptions, files: string[] } { if (newLog.filesRead.some(file => /tsconfig.+json$/.test(file.path))) { return; } @@ -426,7 +426,7 @@ namespace Playback { // console.log("Swallowed write operation during replay: " + name); } - export function wrapIO(underlying: Harness.IO): PlaybackIO { + export function wrapIO(underlying: Harness.Io): PlaybackIO { const wrapper: PlaybackIO = {}; initWrapper(wrapper, underlying); diff --git a/src/harness/rwcRunner.ts b/src/harness/rwcRunner.ts index 2b4fc7b24e4..21cc38cb8b8 100644 --- a/src/harness/rwcRunner.ts +++ b/src/harness/rwcRunner.ts @@ -6,7 +6,7 @@ /* tslint:disable:no-null-keyword */ namespace RWC { - function runWithIOLog(ioLog: IOLog, fn: (oldIO: Harness.IO) => void) { + function runWithIOLog(ioLog: IoLog, fn: (oldIO: Harness.Io) => void) { const oldIO = Harness.IO; const wrappedIO = Playback.wrapIO(oldIO); @@ -58,7 +58,7 @@ namespace RWC { this.timeout(800000); // Allow long timeouts for RWC compilations let opts: ts.ParsedCommandLine; - const ioLog: IOLog = Playback.newStyleLogIntoOldStyleLog(JSON.parse(Harness.IO.readFile(`internal/cases/rwc/${jsonPath}/test.json`)), Harness.IO, `internal/cases/rwc/${baseName}`); + const ioLog: IoLog = Playback.newStyleLogIntoOldStyleLog(JSON.parse(Harness.IO.readFile(`internal/cases/rwc/${jsonPath}/test.json`)), Harness.IO, `internal/cases/rwc/${baseName}`); currentDirectory = ioLog.currentDirectory; useCustomLibraryFile = ioLog.useCustomLibraryFile; runWithIOLog(ioLog, () => { diff --git a/src/server/scriptVersionCache.ts b/src/server/scriptVersionCache.ts index 7c25e4cc3cb..fe71040b4f6 100644 --- a/src/server/scriptVersionCache.ts +++ b/src/server/scriptVersionCache.ts @@ -10,7 +10,7 @@ namespace ts.server { charCount(): number; lineCount(): number; isLeaf(): this is LineLeaf; - walk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker): void; + walk(rangeStart: number, rangeLength: number, walkFns: LineIndexWalker): void; } export interface AbsolutePositionAndLineText { @@ -27,7 +27,7 @@ namespace ts.server { PostEnd } - interface ILineIndexWalker { + interface LineIndexWalker { goSubtree: boolean; done: boolean; leaf(relativeStart: number, relativeLength: number, lineCollection: LineLeaf): void; @@ -37,7 +37,7 @@ namespace ts.server { parent: LineNode, nodeType: CharRangeSection): void; } - class EditWalker implements ILineIndexWalker { + class EditWalker implements LineIndexWalker { goSubtree = true; get done() { return false; } @@ -429,7 +429,7 @@ namespace ts.server { } } - walk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker) { + walk(rangeStart: number, rangeLength: number, walkFns: LineIndexWalker) { this.root.walk(rangeStart, rangeLength, walkFns); } @@ -458,7 +458,7 @@ namespace ts.server { const walkFns = { goSubtree: true, done: false, - leaf(this: ILineIndexWalker, relativeStart: number, relativeLength: number, ll: LineLeaf) { + leaf(this: LineIndexWalker, relativeStart: number, relativeLength: number, ll: LineLeaf) { if (!f(ll, relativeStart, relativeLength)) { this.done = true; } @@ -580,7 +580,7 @@ namespace ts.server { } } - private execWalk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker, childIndex: number, nodeType: CharRangeSection) { + private execWalk(rangeStart: number, rangeLength: number, walkFns: LineIndexWalker, childIndex: number, nodeType: CharRangeSection) { if (walkFns.pre) { walkFns.pre(rangeStart, rangeLength, this.children[childIndex], this, nodeType); } @@ -596,14 +596,14 @@ namespace ts.server { return walkFns.done; } - private skipChild(relativeStart: number, relativeLength: number, childIndex: number, walkFns: ILineIndexWalker, nodeType: CharRangeSection) { + private skipChild(relativeStart: number, relativeLength: number, childIndex: number, walkFns: LineIndexWalker, nodeType: CharRangeSection) { if (walkFns.pre && (!walkFns.done)) { walkFns.pre(relativeStart, relativeLength, this.children[childIndex], this, nodeType); walkFns.goSubtree = true; } } - walk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker) { + walk(rangeStart: number, rangeLength: number, walkFns: LineIndexWalker) { // assume (rangeStart < this.totalChars) && (rangeLength <= this.totalChars) let childIndex = 0; let childCharCount = this.children[childIndex].charCount(); @@ -814,7 +814,7 @@ namespace ts.server { return true; } - walk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker) { + walk(rangeStart: number, rangeLength: number, walkFns: LineIndexWalker) { walkFns.leaf(rangeStart, rangeLength, this); } diff --git a/src/server/server.ts b/src/server/server.ts index 01dba98a503..8706df32e67 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -3,7 +3,7 @@ /// namespace ts.server { - interface IOSessionOptions { + interface IoSessionOptions { host: ServerHost; cancellationToken: ServerCancellationToken; canUseEvents: boolean; @@ -529,7 +529,7 @@ namespace ts.server { } class IOSession extends Session { - constructor(options: IOSessionOptions) { + constructor(options: IoSessionOptions) { const { host, installerEventPort, globalTypingsCacheLocation, typingSafeListLocation, typesMapLocation, npmLocation, canUseEvents } = options; const typingsInstaller = disableAutomaticTypingAcquisition ? undefined @@ -933,7 +933,7 @@ namespace ts.server { const disableAutomaticTypingAcquisition = hasArgument("--disableAutomaticTypingAcquisition"); const telemetryEnabled = hasArgument(Arguments.EnableTelemetry); - const options: IOSessionOptions = { + const options: IoSessionOptions = { host: sys, cancellationToken, installerEventPort: eventPort, diff --git a/src/server/typingsCache.ts b/src/server/typingsCache.ts index d6eeaa2cbcf..cde303bfd39 100644 --- a/src/server/typingsCache.ts +++ b/src/server/typingsCache.ts @@ -5,6 +5,7 @@ namespace ts.server { projectRootPath: Path; } + // tslint:disable-next-line interface-name (for backwards-compatibility) export interface ITypingsInstaller { isKnownTypesPackageName(name: string): boolean; installPackage(options: InstallPackageOptionsWithProjectRootPath): Promise; diff --git a/src/services/shims.ts b/src/services/shims.ts index 9048d68c828..d3cdbe13524 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -106,7 +106,7 @@ namespace ts { /// // Note: This is being using by the host (VS) and is marshaled back and forth. // When changing this make sure the changes are reflected in the managed side as well - export interface IFileReference { + export interface ShimsFileReference { path: string; position: number; length: number; @@ -1104,11 +1104,11 @@ namespace ts { ); } - private convertFileReferences(refs: FileReference[]): IFileReference[] { + private convertFileReferences(refs: FileReference[]): ShimsFileReference[] { if (!refs) { return undefined; } - const result: IFileReference[] = []; + const result: ShimsFileReference[] = []; for (const ref of refs) { result.push({ path: normalizeSlashes(ref.fileName), diff --git a/src/services/types.ts b/src/services/types.ts index 2d629041d1f..671823b86bc 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -86,6 +86,7 @@ namespace ts { * snapshot is observably immutable. i.e. the same calls with the same parameters will return * the same values. */ + // tslint:disable-next-line interface-name export interface IScriptSnapshot { /** Gets a portion of the script snapshot specified by [start, end). */ getText(start: number, end: number): string; diff --git a/tslint.json b/tslint.json index fa89fea6f49..a990d08a2bb 100644 --- a/tslint.json +++ b/tslint.json @@ -13,6 +13,7 @@ "indent": [true, "spaces" ], + "interface-name": [true, "never-prefix"], "interface-over-type-literal": true, "jsdoc-format": true, "linebreak-style": [true, "CRLF"], @@ -110,7 +111,6 @@ "no-consecutive-blank-lines": false, // Not doing - "interface-name": false, "max-classes-per-file": false, "member-ordering": false, "no-angle-bracket-type-assertion": false, From 63f7029b9a8751f96acf72ff3ae29fcf196c32e5 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 2 Nov 2017 17:31:17 -0700 Subject: [PATCH 095/235] Add regression tests --- .../reference/intersectionTypeInference3.js | 25 ++++++++ .../intersectionTypeInference3.symbols | 57 +++++++++++++++++ .../intersectionTypeInference3.types | 61 +++++++++++++++++++ .../intersectionTypeInference3.ts | 20 ++++++ 4 files changed, 163 insertions(+) create mode 100644 tests/baselines/reference/intersectionTypeInference3.js create mode 100644 tests/baselines/reference/intersectionTypeInference3.symbols create mode 100644 tests/baselines/reference/intersectionTypeInference3.types create mode 100644 tests/cases/conformance/types/intersection/intersectionTypeInference3.ts diff --git a/tests/baselines/reference/intersectionTypeInference3.js b/tests/baselines/reference/intersectionTypeInference3.js new file mode 100644 index 00000000000..8a7db286ca2 --- /dev/null +++ b/tests/baselines/reference/intersectionTypeInference3.js @@ -0,0 +1,25 @@ +//// [intersectionTypeInference3.ts] +// Repro from #19682 + +type Nominal = Type & { + [Symbol.species]: Kind; +}; + +type A = Nominal<'A', string>; + +declare const a: Set; +declare const b: Set; + +const c1 = Array.from(a).concat(Array.from(b)); + +// Simpler repro + +declare function from(): T[]; +const c2: ReadonlyArray = from(); + + +//// [intersectionTypeInference3.js] +"use strict"; +// Repro from #19682 +const c1 = Array.from(a).concat(Array.from(b)); +const c2 = from(); diff --git a/tests/baselines/reference/intersectionTypeInference3.symbols b/tests/baselines/reference/intersectionTypeInference3.symbols new file mode 100644 index 00000000000..5b717508319 --- /dev/null +++ b/tests/baselines/reference/intersectionTypeInference3.symbols @@ -0,0 +1,57 @@ +=== tests/cases/conformance/types/intersection/intersectionTypeInference3.ts === +// Repro from #19682 + +type Nominal = Type & { +>Nominal : Symbol(Nominal, Decl(intersectionTypeInference3.ts, 0, 0)) +>Kind : Symbol(Kind, Decl(intersectionTypeInference3.ts, 2, 13)) +>Type : Symbol(Type, Decl(intersectionTypeInference3.ts, 2, 33)) +>Type : Symbol(Type, Decl(intersectionTypeInference3.ts, 2, 33)) + + [Symbol.species]: Kind; +>Symbol.species : Symbol(SymbolConstructor.species, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>species : Symbol(SymbolConstructor.species, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Kind : Symbol(Kind, Decl(intersectionTypeInference3.ts, 2, 13)) + +}; + +type A = Nominal<'A', string>; +>A : Symbol(A, Decl(intersectionTypeInference3.ts, 4, 2)) +>Nominal : Symbol(Nominal, Decl(intersectionTypeInference3.ts, 0, 0)) + +declare const a: Set; +>a : Symbol(a, Decl(intersectionTypeInference3.ts, 8, 13)) +>Set : Symbol(Set, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --)) +>A : Symbol(A, Decl(intersectionTypeInference3.ts, 4, 2)) + +declare const b: Set; +>b : Symbol(b, Decl(intersectionTypeInference3.ts, 9, 13)) +>Set : Symbol(Set, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --)) +>A : Symbol(A, Decl(intersectionTypeInference3.ts, 4, 2)) + +const c1 = Array.from(a).concat(Array.from(b)); +>c1 : Symbol(c1, Decl(intersectionTypeInference3.ts, 11, 5)) +>Array.from(a).concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>a : Symbol(a, Decl(intersectionTypeInference3.ts, 8, 13)) +>concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>b : Symbol(b, Decl(intersectionTypeInference3.ts, 9, 13)) + +// Simpler repro + +declare function from(): T[]; +>from : Symbol(from, Decl(intersectionTypeInference3.ts, 11, 47)) +>T : Symbol(T, Decl(intersectionTypeInference3.ts, 15, 22)) +>T : Symbol(T, Decl(intersectionTypeInference3.ts, 15, 22)) + +const c2: ReadonlyArray = from(); +>c2 : Symbol(c2, Decl(intersectionTypeInference3.ts, 16, 5)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>A : Symbol(A, Decl(intersectionTypeInference3.ts, 4, 2)) +>from : Symbol(from, Decl(intersectionTypeInference3.ts, 11, 47)) + diff --git a/tests/baselines/reference/intersectionTypeInference3.types b/tests/baselines/reference/intersectionTypeInference3.types new file mode 100644 index 00000000000..4d474c84d54 --- /dev/null +++ b/tests/baselines/reference/intersectionTypeInference3.types @@ -0,0 +1,61 @@ +=== tests/cases/conformance/types/intersection/intersectionTypeInference3.ts === +// Repro from #19682 + +type Nominal = Type & { +>Nominal : Nominal +>Kind : Kind +>Type : Type +>Type : Type + + [Symbol.species]: Kind; +>Symbol.species : symbol +>Symbol : SymbolConstructor +>species : symbol +>Kind : Kind + +}; + +type A = Nominal<'A', string>; +>A : Nominal<"A", string> +>Nominal : Nominal + +declare const a: Set; +>a : Set> +>Set : Set +>A : Nominal<"A", string> + +declare const b: Set; +>b : Set> +>Set : Set +>A : Nominal<"A", string> + +const c1 = Array.from(a).concat(Array.from(b)); +>c1 : Nominal<"A", string>[] +>Array.from(a).concat(Array.from(b)) : Nominal<"A", string>[] +>Array.from(a).concat : { (...items: ReadonlyArray>[]): Nominal<"A", string>[]; (...items: (Nominal<"A", string> | ReadonlyArray>)[]): Nominal<"A", string>[]; } +>Array.from(a) : Nominal<"A", string>[] +>Array.from : { (iterable: Iterable, mapfn?: ((v: T, k: number) => U) | undefined, thisArg?: any): U[]; (arrayLike: ArrayLike, mapfn?: ((v: T, k: number) => U) | undefined, thisArg?: any): U[]; } +>Array : ArrayConstructor +>from : { (iterable: Iterable, mapfn?: ((v: T, k: number) => U) | undefined, thisArg?: any): U[]; (arrayLike: ArrayLike, mapfn?: ((v: T, k: number) => U) | undefined, thisArg?: any): U[]; } +>a : Set> +>concat : { (...items: ReadonlyArray>[]): Nominal<"A", string>[]; (...items: (Nominal<"A", string> | ReadonlyArray>)[]): Nominal<"A", string>[]; } +>Array.from(b) : Nominal<"A", string>[] +>Array.from : { (iterable: Iterable, mapfn?: ((v: T, k: number) => U) | undefined, thisArg?: any): U[]; (arrayLike: ArrayLike, mapfn?: ((v: T, k: number) => U) | undefined, thisArg?: any): U[]; } +>Array : ArrayConstructor +>from : { (iterable: Iterable, mapfn?: ((v: T, k: number) => U) | undefined, thisArg?: any): U[]; (arrayLike: ArrayLike, mapfn?: ((v: T, k: number) => U) | undefined, thisArg?: any): U[]; } +>b : Set> + +// Simpler repro + +declare function from(): T[]; +>from : () => T[] +>T : T +>T : T + +const c2: ReadonlyArray = from(); +>c2 : ReadonlyArray> +>ReadonlyArray : ReadonlyArray +>A : Nominal<"A", string> +>from() : Nominal<"A", string>[] +>from : () => T[] + diff --git a/tests/cases/conformance/types/intersection/intersectionTypeInference3.ts b/tests/cases/conformance/types/intersection/intersectionTypeInference3.ts new file mode 100644 index 00000000000..ceaff10f7f1 --- /dev/null +++ b/tests/cases/conformance/types/intersection/intersectionTypeInference3.ts @@ -0,0 +1,20 @@ +// @strict: true +// @target: es2015 + +// Repro from #19682 + +type Nominal = Type & { + [Symbol.species]: Kind; +}; + +type A = Nominal<'A', string>; + +declare const a: Set; +declare const b: Set; + +const c1 = Array.from(a).concat(Array.from(b)); + +// Simpler repro + +declare function from(): T[]; +const c2: ReadonlyArray = from(); From 9bb6a527712022c5d0237eedac875cae4f9603e3 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 2 Nov 2017 20:13:25 -0700 Subject: [PATCH 096/235] Accept new baselines --- .../reference/intersectionTypeInference3.symbols | 8 ++++---- .../baselines/reference/intersectionTypeInference3.types | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/baselines/reference/intersectionTypeInference3.symbols b/tests/baselines/reference/intersectionTypeInference3.symbols index 5b717508319..3945cf64fb6 100644 --- a/tests/baselines/reference/intersectionTypeInference3.symbols +++ b/tests/baselines/reference/intersectionTypeInference3.symbols @@ -32,14 +32,14 @@ declare const b: Set; const c1 = Array.from(a).concat(Array.from(b)); >c1 : Symbol(c1, Decl(intersectionTypeInference3.ts, 11, 5)) >Array.from(a).concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) ->from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >a : Symbol(a, Decl(intersectionTypeInference3.ts, 8, 13)) >concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) ->from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >b : Symbol(b, Decl(intersectionTypeInference3.ts, 9, 13)) // Simpler repro diff --git a/tests/baselines/reference/intersectionTypeInference3.types b/tests/baselines/reference/intersectionTypeInference3.types index 4d474c84d54..9fca37af8c1 100644 --- a/tests/baselines/reference/intersectionTypeInference3.types +++ b/tests/baselines/reference/intersectionTypeInference3.types @@ -34,15 +34,15 @@ const c1 = Array.from(a).concat(Array.from(b)); >Array.from(a).concat(Array.from(b)) : Nominal<"A", string>[] >Array.from(a).concat : { (...items: ReadonlyArray>[]): Nominal<"A", string>[]; (...items: (Nominal<"A", string> | ReadonlyArray>)[]): Nominal<"A", string>[]; } >Array.from(a) : Nominal<"A", string>[] ->Array.from : { (iterable: Iterable, mapfn?: ((v: T, k: number) => U) | undefined, thisArg?: any): U[]; (arrayLike: ArrayLike, mapfn?: ((v: T, k: number) => U) | undefined, thisArg?: any): U[]; } +>Array.from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >Array : ArrayConstructor ->from : { (iterable: Iterable, mapfn?: ((v: T, k: number) => U) | undefined, thisArg?: any): U[]; (arrayLike: ArrayLike, mapfn?: ((v: T, k: number) => U) | undefined, thisArg?: any): U[]; } +>from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >a : Set> >concat : { (...items: ReadonlyArray>[]): Nominal<"A", string>[]; (...items: (Nominal<"A", string> | ReadonlyArray>)[]): Nominal<"A", string>[]; } >Array.from(b) : Nominal<"A", string>[] ->Array.from : { (iterable: Iterable, mapfn?: ((v: T, k: number) => U) | undefined, thisArg?: any): U[]; (arrayLike: ArrayLike, mapfn?: ((v: T, k: number) => U) | undefined, thisArg?: any): U[]; } +>Array.from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >Array : ArrayConstructor ->from : { (iterable: Iterable, mapfn?: ((v: T, k: number) => U) | undefined, thisArg?: any): U[]; (arrayLike: ArrayLike, mapfn?: ((v: T, k: number) => U) | undefined, thisArg?: any): U[]; } +>from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >b : Set> // Simpler repro From cc2a2a79b5b342a11e8e034f2f917c2c357db3d4 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 3 Nov 2017 08:08:48 -0700 Subject: [PATCH 097/235] Use NodeFlags to detect nodes in ambient contexts instead of climbing ancestors (#17831) * Use NodeFlags to detect nodes in ambient contexts instead of climbing ancestors * Set context flags on tokens * Remove 'isDeclarationFile' parameter to 'initializeState' and move to 'parseSourceFileWorker' * Changes based on code review * Update API baselines --- src/compiler/binder.ts | 14 +-- src/compiler/checker.ts | 88 +++++++++---------- src/compiler/parser.ts | 47 ++++++++-- src/compiler/types.ts | 5 +- src/compiler/utilities.ts | 10 --- src/harness/unittests/incrementalParser.ts | 6 +- src/services/breakpoints.ts | 2 +- src/services/refactors/extractSymbol.ts | 2 +- src/services/services.ts | 1 + src/services/utilities.ts | 2 +- .../reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- .../parserConstructorDeclaration4.errors.txt | 5 +- ...rserMemberAccessorDeclaration11.errors.txt | 5 +- ...arserMemberFunctionDeclaration5.errors.txt | 5 +- 15 files changed, 108 insertions(+), 88 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 602a9c505ad..85ca2435974 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1550,7 +1550,7 @@ namespace ts { function setExportContextFlag(node: ModuleDeclaration | SourceFile) { // A declaration source file or ambient module declaration that contains no export declarations (but possibly regular // declarations with export modifiers) is an export context in which declarations are implicitly exported. - if (isInAmbientContext(node) && !hasExportDeclarations(node)) { + if (node.flags & NodeFlags.Ambient && !hasExportDeclarations(node)) { node.flags |= NodeFlags.ExportContext; } else { @@ -1726,7 +1726,7 @@ namespace ts { node.originalKeywordKind >= SyntaxKind.FirstFutureReservedWord && node.originalKeywordKind <= SyntaxKind.LastFutureReservedWord && !isIdentifierName(node) && - !isInAmbientContext(node)) { + !(node.flags & NodeFlags.Ambient)) { // Report error only if there are no parse errors in file if (!file.parseDiagnostics.length) { @@ -2481,7 +2481,7 @@ namespace ts { } function bindParameter(node: ParameterDeclaration) { - if (inStrictMode && !isInAmbientContext(node)) { + if (inStrictMode && !(node.flags & NodeFlags.Ambient)) { // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a // strict mode FunctionLikeDeclaration or FunctionExpression(13.1) checkStrictModeEvalOrArguments(node, node.name); @@ -2503,7 +2503,7 @@ namespace ts { } function bindFunctionDeclaration(node: FunctionDeclaration) { - if (!file.isDeclarationFile && !isInAmbientContext(node)) { + if (!file.isDeclarationFile && !(node.flags & NodeFlags.Ambient)) { if (isAsyncFunction(node)) { emitFlags |= NodeFlags.HasAsyncFunctions; } @@ -2520,7 +2520,7 @@ namespace ts { } function bindFunctionExpression(node: FunctionExpression) { - if (!file.isDeclarationFile && !isInAmbientContext(node)) { + if (!file.isDeclarationFile && !(node.flags & NodeFlags.Ambient)) { if (isAsyncFunction(node)) { emitFlags |= NodeFlags.HasAsyncFunctions; } @@ -2534,7 +2534,7 @@ namespace ts { } function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { - if (!file.isDeclarationFile && !isInAmbientContext(node) && isAsyncFunction(node)) { + if (!file.isDeclarationFile && !(node.flags & NodeFlags.Ambient) && isAsyncFunction(node)) { emitFlags |= NodeFlags.HasAsyncFunctions; } @@ -2583,7 +2583,7 @@ namespace ts { // On the other side we do want to report errors on non-initialized 'lets' because of TDZ const reportUnreachableCode = !options.allowUnreachableCode && - !isInAmbientContext(node) && + !(node.flags & NodeFlags.Ambient) && ( node.kind !== SyntaxKind.VariableStatement || getCombinedNodeFlags((node).declarationList) & NodeFlags.BlockScoped || diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index af8bd6f7c98..b540f92b525 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -691,7 +691,7 @@ namespace ts { else { // find a module that about to be augmented // do not validate names of augmentations that are defined in ambient context - const moduleNotFoundError = !isInAmbientContext(moduleName.parent.parent) + const moduleNotFoundError = !(moduleName.parent.parent.flags & NodeFlags.Ambient) ? Diagnostics.Invalid_module_name_in_augmentation_module_0_cannot_be_found : undefined; let mainModule = resolveExternalModuleNameWorker(moduleName, moduleName, moduleNotFoundError, /*isForAugmentation*/ true); @@ -796,7 +796,7 @@ namespace ts { if ((modulekind && (declarationFile.externalModuleIndicator || useFile.externalModuleIndicator)) || (!compilerOptions.outFile && !compilerOptions.out) || isInTypeQuery(usage) || - isInAmbientContext(declaration)) { + declaration.flags & NodeFlags.Ambient) { // nodes are in different files and order cannot be determined return true; } @@ -1384,7 +1384,7 @@ namespace ts { Debug.assert(declaration !== undefined, "Declaration to checkResolvedBlockScopedVariable is undefined"); - if (!isInAmbientContext(declaration) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) { + if (!(declaration.flags & NodeFlags.Ambient) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) { if (result.flags & SymbolFlags.BlockScopedVariable) { error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, declarationNameToString(getNameOfDeclaration(declaration))); } @@ -3949,7 +3949,7 @@ namespace ts { const parent = getDeclarationContainer(node); // If the node is not exported or it is not ambient module element (except import declaration) if (!(getCombinedModifierFlags(node) & ModifierFlags.Export) && - !(node.kind !== SyntaxKind.ImportEqualsDeclaration && parent.kind !== SyntaxKind.SourceFile && isInAmbientContext(parent))) { + !(node.kind !== SyntaxKind.ImportEqualsDeclaration && parent.kind !== SyntaxKind.SourceFile && parent.flags & NodeFlags.Ambient)) { return isGlobalSourceFile(parent); } // Exported members/ambient module elements (exception import declaration) are visible if parent is visible @@ -4327,7 +4327,7 @@ namespace ts { if ((noImplicitAny || isInJavaScriptFile(declaration)) && declaration.kind === SyntaxKind.VariableDeclaration && !isBindingPattern(declaration.name) && - !(getCombinedModifierFlags(declaration) & ModifierFlags.Export) && !isInAmbientContext(declaration)) { + !(getCombinedModifierFlags(declaration) & ModifierFlags.Export) && !(declaration.flags & NodeFlags.Ambient)) { // If --noImplicitAny is on or the declaration is in a Javascript file, // use control flow tracked 'any' type for non-ambient, non-exported var or let variables with no // initializer or a 'null' or 'undefined' initializer. @@ -5200,7 +5200,7 @@ namespace ts { function isLiteralEnumMember(member: EnumMember) { const expr = member.initializer; if (!expr) { - return !isInAmbientContext(member); + return !(member.flags & NodeFlags.Ambient); } switch (expr.kind) { case SyntaxKind.StringLiteral: @@ -12760,7 +12760,7 @@ namespace ts { const assumeInitialized = isParameter || isAlias || isOuterVariable || type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0 || isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) || node.parent.kind === SyntaxKind.NonNullExpression || - isInAmbientContext(declaration); + declaration.flags & NodeFlags.Ambient; const initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, getRootDeclaration(declaration) as VariableLikeDeclaration) : type) : type === autoType || type === autoArrayType ? undefinedType : getNullableType(type, TypeFlags.Undefined); @@ -15232,7 +15232,7 @@ namespace ts { } else if (valueDeclaration.kind === SyntaxKind.ClassDeclaration && node.parent.kind !== SyntaxKind.TypeReference && - !isInAmbientContext(valueDeclaration) && + !(valueDeclaration.flags & NodeFlags.Ambient) && !isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right)) { error(right, Diagnostics.Class_0_used_before_its_declaration, idText(right)); } @@ -17100,7 +17100,7 @@ namespace ts { return type; } - function isCommonJsRequire(node: Node) { + function isCommonJsRequire(node: Node): boolean { if (!isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) { return false; } @@ -17124,7 +17124,7 @@ namespace ts { if (targetDeclarationKind !== SyntaxKind.Unknown) { const decl = getDeclarationOfKind(resolvedRequire, targetDeclarationKind); // function/variable declaration should be ambient - return isInAmbientContext(decl); + return !!(decl.flags & NodeFlags.Ambient); } return false; } @@ -19242,7 +19242,7 @@ namespace ts { checkDecorators(node); checkSignatureDeclaration(node); if (node.kind === SyntaxKind.GetAccessor) { - if (!isInAmbientContext(node) && nodeIsPresent(node.body) && (node.flags & NodeFlags.HasImplicitReturn)) { + if (!(node.flags & NodeFlags.Ambient) && nodeIsPresent(node.body) && (node.flags & NodeFlags.HasImplicitReturn)) { if (!(node.flags & NodeFlags.HasExplicitReturn)) { error(node.name, Diagnostics.A_get_accessor_must_return_a_value); } @@ -19425,7 +19425,7 @@ namespace ts { } function isPrivateWithinAmbient(node: Node): boolean { - return hasModifier(node, ModifierFlags.Private) && isInAmbientContext(node); + return hasModifier(node, ModifierFlags.Private) && !!(node.flags & NodeFlags.Ambient); } function getEffectiveDeclarationFlags(n: Node, flagsToCheck: ModifierFlags): ModifierFlags { @@ -19436,7 +19436,7 @@ namespace ts { if (n.parent.kind !== SyntaxKind.InterfaceDeclaration && n.parent.kind !== SyntaxKind.ClassDeclaration && n.parent.kind !== SyntaxKind.ClassExpression && - isInAmbientContext(n)) { + n.flags & NodeFlags.Ambient) { if (!(flags & ModifierFlags.Ambient)) { // It is nested in an ambient context, which means it is automatically exported flags |= ModifierFlags.Export; @@ -19575,7 +19575,7 @@ namespace ts { let multipleConstructorImplementation = false; for (const current of declarations) { const node = current; - const inAmbientContext = isInAmbientContext(node); + const inAmbientContext = node.flags & NodeFlags.Ambient; const inAmbientContextOrInterface = node.parent.kind === SyntaxKind.InterfaceDeclaration || node.parent.kind === SyntaxKind.TypeLiteral || inAmbientContext; if (inAmbientContextOrInterface) { // check if declarations are consecutive only if they are non-ambient @@ -20430,7 +20430,7 @@ namespace ts { } function checkUnusedLocalsAndParameters(node: Node): void { - if (node.parent.kind !== SyntaxKind.InterfaceDeclaration && noUnusedIdentifiers && !isInAmbientContext(node)) { + if (node.parent.kind !== SyntaxKind.InterfaceDeclaration && noUnusedIdentifiers && !(node.flags & NodeFlags.Ambient)) { node.locals.forEach(local => { if (!local.isReferenced) { if (local.valueDeclaration && getRootDeclaration(local.valueDeclaration).kind === SyntaxKind.Parameter) { @@ -20483,7 +20483,7 @@ namespace ts { } function checkUnusedClassMembers(node: ClassDeclaration | ClassExpression): void { - if (compilerOptions.noUnusedLocals && !isInAmbientContext(node)) { + if (compilerOptions.noUnusedLocals && !(node.flags & NodeFlags.Ambient)) { if (node.members) { for (const member of node.members) { if (member.kind === SyntaxKind.MethodDeclaration || member.kind === SyntaxKind.PropertyDeclaration) { @@ -20504,7 +20504,7 @@ namespace ts { } function checkUnusedTypeParameters(node: ClassDeclaration | ClassExpression | FunctionDeclaration | MethodDeclaration | FunctionExpression | ArrowFunction | ConstructorDeclaration | SignatureDeclaration | InterfaceDeclaration | TypeAliasDeclaration) { - if (compilerOptions.noUnusedLocals && !isInAmbientContext(node)) { + if (compilerOptions.noUnusedLocals && !(node.flags & NodeFlags.Ambient)) { if (node.typeParameters) { // Only report errors on the last declaration for the type parameter container; // this ensures that all uses have been accounted for. @@ -20523,7 +20523,7 @@ namespace ts { } function checkUnusedModuleMembers(node: ModuleDeclaration | SourceFile): void { - if (compilerOptions.noUnusedLocals && !isInAmbientContext(node)) { + if (compilerOptions.noUnusedLocals && !(node.flags & NodeFlags.Ambient)) { node.locals.forEach(local => { if (!local.isReferenced && !local.exportSymbol) { for (const declaration of local.declarations) { @@ -20556,7 +20556,7 @@ namespace ts { function checkCollisionWithArgumentsInGeneratedCode(node: SignatureDeclaration) { // no rest parameters \ declaration context \ overload - no codegen impact - if (!hasRestParameter(node) || isInAmbientContext(node) || nodeIsMissing((node).body)) { + if (!hasRestParameter(node) || node.flags & NodeFlags.Ambient || nodeIsMissing((node).body)) { return; } @@ -20582,7 +20582,7 @@ namespace ts { return false; } - if (isInAmbientContext(node)) { + if (node.flags & NodeFlags.Ambient) { // ambient context - no codegen impact return false; } @@ -20647,7 +20647,7 @@ namespace ts { // bubble up and find containing type const enclosingClass = getContainingClass(node); // if containing type was not found or it is ambient - exit (no codegen) - if (!enclosingClass || isInAmbientContext(enclosingClass)) { + if (!enclosingClass || enclosingClass.flags & NodeFlags.Ambient) { return; } @@ -21962,7 +21962,7 @@ namespace ts { checkClassForDuplicateDeclarations(node); // Only check for reserved static identifiers on non-ambient context. - if (!isInAmbientContext(node)) { + if (!(node.flags & NodeFlags.Ambient)) { checkClassForStaticPropertyNameConflicts(node); } @@ -22268,7 +22268,7 @@ namespace ts { } // In ambient enum declarations that specify no const modifier, enum member declarations that omit // a value are considered computed members (as opposed to having auto-incremented values). - if (isInAmbientContext(member.parent) && !isConst(member.parent)) { + if (member.parent.flags & NodeFlags.Ambient && !isConst(member.parent)) { return undefined; } // If the member declaration specifies no value, the member is considered a constant enum member. @@ -22301,7 +22301,7 @@ namespace ts { else if (isConstEnum) { error(initializer, Diagnostics.In_const_enum_declarations_member_initializer_must_be_constant_expression); } - else if (isInAmbientContext(member.parent)) { + else if (member.parent.flags & NodeFlags.Ambient) { error(initializer, Diagnostics.In_ambient_enum_declarations_member_initializer_must_be_constant_expression); } else { @@ -22414,7 +22414,7 @@ namespace ts { computeEnumMemberValues(node); const enumIsConst = isConst(node); - if (compilerOptions.isolatedModules && enumIsConst && isInAmbientContext(node)) { + if (compilerOptions.isolatedModules && enumIsConst && node.flags & NodeFlags.Ambient) { error(node.name, Diagnostics.Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided); } @@ -22466,7 +22466,7 @@ namespace ts { for (const declaration of declarations) { if ((declaration.kind === SyntaxKind.ClassDeclaration || (declaration.kind === SyntaxKind.FunctionDeclaration && nodeIsPresent((declaration).body))) && - !isInAmbientContext(declaration)) { + !(declaration.flags & NodeFlags.Ambient)) { return declaration; } } @@ -22491,7 +22491,7 @@ namespace ts { if (produceDiagnostics) { // Grammar checking const isGlobalAugmentation = isGlobalScopeAugmentation(node); - const inAmbientContext = isInAmbientContext(node); + const inAmbientContext = node.flags & NodeFlags.Ambient; if (isGlobalAugmentation && !inAmbientContext) { error(node.name, Diagnostics.Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambient_context); } @@ -22710,7 +22710,7 @@ namespace ts { if (compilerOptions.isolatedModules && node.kind === SyntaxKind.ExportSpecifier && !(target.flags & SymbolFlags.Value) - && !isInAmbientContext(node)) { + && !(node.flags & NodeFlags.Ambient)) { error(node, Diagnostics.Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided); } } @@ -22761,7 +22761,7 @@ namespace ts { if (hasModifier(node, ModifierFlags.Export)) { markExportAsReferenced(node); } - if (isInternalModuleImportEqualsDeclaration(node)) { + if (node.moduleReference.kind !== SyntaxKind.ExternalModuleReference) { const target = resolveAlias(getSymbolOfNode(node)); if (target !== unknownSymbol) { if (target.flags & SymbolFlags.Value) { @@ -22777,7 +22777,7 @@ namespace ts { } } else { - if (modulekind >= ModuleKind.ES2015 && !isInAmbientContext(node)) { + if (modulekind >= ModuleKind.ES2015 && !(node.flags & NodeFlags.Ambient)) { // Import equals declaration is deprecated in es6 or above grammarErrorOnNode(node, Diagnostics.Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead); } @@ -22803,7 +22803,7 @@ namespace ts { const inAmbientExternalModule = node.parent.kind === SyntaxKind.ModuleBlock && isAmbientModule(node.parent.parent); const inAmbientNamespaceDeclaration = !inAmbientExternalModule && node.parent.kind === SyntaxKind.ModuleBlock && - !node.moduleSpecifier && isInAmbientContext(node); + !node.moduleSpecifier && node.flags & NodeFlags.Ambient; if (node.parent.kind !== SyntaxKind.SourceFile && !inAmbientExternalModule && !inAmbientNamespaceDeclaration) { error(node, Diagnostics.Export_declarations_are_not_permitted_in_a_namespace); } @@ -22876,11 +22876,11 @@ namespace ts { checkExternalModuleExports(container); - if (isInAmbientContext(node) && !isEntityNameExpression(node.expression)) { + if ((node.flags & NodeFlags.Ambient) && !isEntityNameExpression(node.expression)) { grammarErrorOnNode(node.expression, Diagnostics.The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context); } - if (node.isExportEquals && !isInAmbientContext(node)) { + if (node.isExportEquals && !(node.flags & NodeFlags.Ambient)) { if (modulekind >= ModuleKind.ES2015) { // export assignment is not supported in es6 modules grammarErrorOnNode(node, Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or_another_module_format_instead); @@ -24514,7 +24514,7 @@ namespace ts { function checkExternalEmitHelpers(location: Node, helpers: ExternalEmitHelpers) { if ((requestedExternalEmitHelpers & helpers) !== helpers && compilerOptions.importHelpers) { const sourceFile = getSourceFileOfNode(location); - if (isEffectiveExternalModule(sourceFile, compilerOptions) && !isInAmbientContext(location)) { + if (isEffectiveExternalModule(sourceFile, compilerOptions) && !(location.flags & NodeFlags.Ambient)) { const helpersModule = resolveHelpersModule(sourceFile, location); if (helpersModule !== unknownSymbol) { const uncheckedHelpers = helpers & ~requestedExternalEmitHelpers; @@ -24716,7 +24716,7 @@ namespace ts { else if (node.kind === SyntaxKind.Parameter) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "declare"); } - else if (isInAmbientContext(node.parent) && node.parent.kind === SyntaxKind.ModuleBlock) { + else if ((node.parent.flags & NodeFlags.Ambient) && node.parent.kind === SyntaxKind.ModuleBlock) { return grammarErrorOnNode(modifier, Diagnostics.A_declare_modifier_cannot_be_used_in_an_already_ambient_context); } flags |= ModifierFlags.Ambient; @@ -24752,7 +24752,7 @@ namespace ts { if (flags & ModifierFlags.Async) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "async"); } - else if (flags & ModifierFlags.Ambient || isInAmbientContext(node.parent)) { + else if (flags & ModifierFlags.Ambient || node.parent.flags & NodeFlags.Ambient) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async"); } else if (node.kind === SyntaxKind.Parameter) { @@ -25100,7 +25100,7 @@ namespace ts { node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.MethodDeclaration); - if (isInAmbientContext(node)) { + if (node.flags & NodeFlags.Ambient) { return grammarErrorOnNode(node.asteriskToken, Diagnostics.Generators_are_not_allowed_in_an_ambient_context); } if (!node.body) { @@ -25287,7 +25287,7 @@ namespace ts { if (languageVersion < ScriptTarget.ES5) { return grammarErrorOnNode(accessor.name, Diagnostics.Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher); } - else if (isInAmbientContext(accessor)) { + else if (accessor.flags & NodeFlags.Ambient) { return grammarErrorOnNode(accessor.name, Diagnostics.An_accessor_cannot_be_declared_in_an_ambient_context); } else if (accessor.body === undefined && !hasModifier(accessor, ModifierFlags.Abstract)) { @@ -25366,7 +25366,7 @@ namespace ts { // However, property declarations disallow computed names in general, // and accessors are not allowed in ambient contexts in general, // so this error only really matters for methods. - if (isInAmbientContext(node)) { + if (node.flags & NodeFlags.Ambient) { return checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_an_ambient_context_must_directly_refer_to_a_built_in_symbol); } else if (!node.body) { @@ -25461,7 +25461,7 @@ namespace ts { function checkGrammarVariableDeclaration(node: VariableDeclaration) { if (node.parent.parent.kind !== SyntaxKind.ForInStatement && node.parent.parent.kind !== SyntaxKind.ForOfStatement) { - if (isInAmbientContext(node)) { + if (node.flags & NodeFlags.Ambient) { if (node.initializer) { if (isConst(node) && !node.type) { if (!isStringOrNumberLiteralExpression(node.initializer)) { @@ -25491,7 +25491,7 @@ namespace ts { } if (compilerOptions.module !== ModuleKind.ES2015 && compilerOptions.module !== ModuleKind.ESNext && compilerOptions.module !== ModuleKind.System && !compilerOptions.noEmit && - !isInAmbientContext(node.parent.parent) && hasModifier(node.parent.parent, ModifierFlags.Export)) { + !(node.parent.parent.flags & NodeFlags.Ambient) && hasModifier(node.parent.parent, ModifierFlags.Export)) { checkESModuleMarker(node.name); } @@ -25650,7 +25650,7 @@ namespace ts { } } - if (isInAmbientContext(node) && node.initializer) { + if (node.flags & NodeFlags.Ambient && node.initializer) { return grammarErrorOnFirstToken(node.initializer, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); } } @@ -25693,11 +25693,11 @@ namespace ts { } function checkGrammarSourceFile(node: SourceFile): boolean { - return isInAmbientContext(node) && checkGrammarTopLevelElementsForRequiredDeclareModifier(node); + return !!(node.flags & NodeFlags.Ambient) && checkGrammarTopLevelElementsForRequiredDeclareModifier(node); } function checkGrammarStatementInAmbientContext(node: Node): boolean { - if (isInAmbientContext(node)) { + if (node.flags & NodeFlags.Ambient) { // An accessors is already reported about the ambient context if (isAccessor(node.parent)) { return getNodeLinks(node).hasReportedStatementInAmbientContext = true; diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 648f3e30d1c..c2b35bd25c4 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -631,6 +631,7 @@ namespace ts { } export function parseIsolatedEntityName(content: string, languageVersion: ScriptTarget): EntityName { + // Choice of `isDeclarationFile` should be arbitrary initializeState(content, languageVersion, /*syntaxCursor*/ undefined, ScriptKind.JS); // Prime the scanner. nextToken(); @@ -643,7 +644,7 @@ namespace ts { export function parseJsonText(fileName: string, sourceText: string): JsonSourceFile { initializeState(sourceText, ScriptTarget.ES2015, /*syntaxCursor*/ undefined, ScriptKind.JSON); // Set source file so that errors will be reported with this file name - sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON); + sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON, /*isDeclaration*/ false); const result = sourceFile; // Prime the scanner. @@ -685,7 +686,16 @@ namespace ts { identifierCount = 0; nodeCount = 0; - contextFlags = scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JSON ? NodeFlags.JavaScriptFile : NodeFlags.None; + switch (scriptKind) { + case ScriptKind.JS: + case ScriptKind.JSX: + case ScriptKind.JSON: + contextFlags = NodeFlags.JavaScriptFile; + break; + default: + contextFlags = NodeFlags.None; + break; + } parseErrorBeforeNextFinishedNode = false; // Initialize and prime the scanner before parsing the source elements. @@ -709,7 +719,12 @@ namespace ts { } function parseSourceFileWorker(fileName: string, languageVersion: ScriptTarget, setParentNodes: boolean, scriptKind: ScriptKind): SourceFile { - sourceFile = createSourceFile(fileName, languageVersion, scriptKind); + const isDeclarationFile = isDeclarationFileName(fileName); + if (isDeclarationFile) { + contextFlags |= NodeFlags.Ambient; + } + + sourceFile = createSourceFile(fileName, languageVersion, scriptKind, isDeclarationFile); sourceFile.flags = contextFlags; // Prime the scanner. @@ -786,7 +801,7 @@ namespace ts { } } - function createSourceFile(fileName: string, languageVersion: ScriptTarget, scriptKind: ScriptKind): SourceFile { + function createSourceFile(fileName: string, languageVersion: ScriptTarget, scriptKind: ScriptKind, isDeclarationFile: boolean): SourceFile { // code from createNode is inlined here so createNode won't have to deal with special case of creating source files // this is quite rare comparing to other nodes and createNode should be as fast as possible const sourceFile = new SourceFileConstructor(SyntaxKind.SourceFile, /*pos*/ 0, /* end */ sourceText.length); @@ -797,7 +812,7 @@ namespace ts { sourceFile.languageVersion = languageVersion; sourceFile.fileName = normalizePath(fileName); sourceFile.languageVariant = getLanguageVariant(scriptKind); - sourceFile.isDeclarationFile = fileExtensionIs(sourceFile.fileName, Extension.Dts); + sourceFile.isDeclarationFile = isDeclarationFile; sourceFile.scriptKind = scriptKind; return sourceFile; @@ -5135,6 +5150,18 @@ namespace ts { const fullStart = getNodePos(); const decorators = parseDecorators(); const modifiers = parseModifiers(); + if (some(modifiers, m => m.kind === SyntaxKind.DeclareKeyword)) { + for (const m of modifiers) { + m.flags |= NodeFlags.Ambient; + } + return doInsideOfContext(NodeFlags.Ambient, () => parseDeclarationWorker(fullStart, decorators, modifiers)); + } + else { + return parseDeclarationWorker(fullStart, decorators, modifiers); + } + } + + function parseDeclarationWorker(fullStart: number, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): Statement { switch (token()) { case SyntaxKind.VarKeyword: case SyntaxKind.LetKeyword: @@ -5492,8 +5519,8 @@ namespace ts { return false; } - function parseDecorators(): NodeArray { - let list: Decorator[]; + function parseDecorators(): NodeArray | undefined { + let list: Decorator[] | undefined; const listPos = getNodePos(); while (true) { const decoratorStart = getNodePos(); @@ -6177,7 +6204,7 @@ namespace ts { export namespace JSDocParser { export function parseJSDocTypeExpressionForTests(content: string, start: number, length: number): { jsDocTypeExpression: JSDocTypeExpression, diagnostics: Diagnostic[] } | undefined { initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS); - sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS); + sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS, /*isDeclarationFile*/ false); scanner.setText(content, start, length); currentToken = scanner.scan(); const jsDocTypeExpression = parseJSDocTypeExpression(); @@ -7507,4 +7534,8 @@ namespace ts { Value = -1 } } + + function isDeclarationFileName(fileName: string): boolean { + return fileExtensionIs(fileName, Extension.Dts); + } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 1fda7d8f49d..b4e84ae6a75 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -454,7 +454,8 @@ namespace ts { /* @internal */ PossiblyContainsDynamicImport = 1 << 19, JSDoc = 1 << 20, // If node was parsed inside jsdoc - /* @internal */ InWithStatement = 1 << 21, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`) + /* @internal */ Ambient = 1 << 21, // If node was inside an ambient context -- a declaration file, or inside something with the `declare` modifier. + /* @internal */ InWithStatement = 1 << 22, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`) BlockScoped = Let | Const, @@ -462,7 +463,7 @@ namespace ts { ReachabilityAndEmitFlags = ReachabilityCheckFlags | HasAsyncFunctions, // Parsing context flags - ContextFlags = DisallowInContext | YieldContext | DecoratorContext | AwaitContext | JavaScriptFile | InWithStatement, + ContextFlags = DisallowInContext | YieldContext | DecoratorContext | AwaitContext | JavaScriptFile | InWithStatement | Ambient, // Exclude these flags when parsing a Type TypeExcludesFlags = YieldContext | AwaitContext, diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 080172b8106..e15b81db8e1 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1728,16 +1728,6 @@ namespace ts { return false; } - export function isInAmbientContext(node: Node): boolean { - while (node) { - if (hasModifier(node, ModifierFlags.Ambient) || (node.kind === SyntaxKind.SourceFile && (node as SourceFile).isDeclarationFile)) { - return true; - } - node = node.parent; - } - return false; - } - // True if the given identifier, string literal, or number literal is the name of a declaration node export function isDeclarationName(name: Node): boolean { switch (name.kind) { diff --git a/src/harness/unittests/incrementalParser.ts b/src/harness/unittests/incrementalParser.ts index fbd8a60da92..c71b89d3da6 100644 --- a/src/harness/unittests/incrementalParser.ts +++ b/src/harness/unittests/incrementalParser.ts @@ -591,7 +591,7 @@ module m3 { }\ const index = 0; const newTextAndChange = withInsert(oldText, index, "declare "); - compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 3); + compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); }); it("Insert function above arrow function with comment", () => { @@ -674,7 +674,7 @@ module m3 { }\ const oldText = ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, 0, "{"); - compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9); + compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4); }); it("Removing block around function declarations", () => { @@ -683,7 +683,7 @@ module m3 { }\ const oldText = ScriptSnapshot.fromString(source); const newTextAndChange = withDelete(oldText, 0, "{".length); - compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9); + compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4); }); it("Moving methods from class to object literal", () => { diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index 73176aa4b5f..73732ce87e8 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -31,7 +31,7 @@ namespace ts.BreakpointResolver { } // Cannot set breakpoint in ambient declarations - if (isInAmbientContext(tokenAtLocation)) { + if (tokenAtLocation.flags & NodeFlags.Ambient) { return undefined; } diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 3106ea9576c..58e57675459 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -335,7 +335,7 @@ namespace ts.refactor.extractSymbol { return [createDiagnosticForNode(nodeToCheck, Messages.StatementOrExpressionExpected)]; } - if (isInAmbientContext(nodeToCheck)) { + if (nodeToCheck.flags & NodeFlags.Ambient) { return [createDiagnosticForNode(nodeToCheck, Messages.CannotExtractAmbientBlock)]; } diff --git a/src/services/services.ts b/src/services/services.ts index cd6fe867711..e4a6e556f79 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -41,6 +41,7 @@ namespace ts { kind === SyntaxKind.Identifier ? new IdentifierObject(SyntaxKind.Identifier, pos, end) : new TokenObject(kind, pos, end); node.parent = parent; + node.flags = parent.flags & NodeFlags.ContextFlags; return node; } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 2580ff18410..9397c40ff8a 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -947,7 +947,7 @@ namespace ts { if (flags & ModifierFlags.Static) result.push(ScriptElementKindModifier.staticModifier); if (flags & ModifierFlags.Abstract) result.push(ScriptElementKindModifier.abstractModifier); if (flags & ModifierFlags.Export) result.push(ScriptElementKindModifier.exportedModifier); - if (isInAmbientContext(node)) result.push(ScriptElementKindModifier.ambientModifier); + if (node.flags & NodeFlags.Ambient) result.push(ScriptElementKindModifier.ambientModifier); return result.length > 0 ? result.join(",") : ScriptElementKindModifier.none; } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 2bce9cbf49a..cffa1375608 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -411,7 +411,7 @@ declare namespace ts { BlockScoped = 3, ReachabilityCheckFlags = 384, ReachabilityAndEmitFlags = 1408, - ContextFlags = 2193408, + ContextFlags = 6387712, TypeExcludesFlags = 20480, } enum ModifierFlags { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 48105ea7d12..666cc34162b 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -411,7 +411,7 @@ declare namespace ts { BlockScoped = 3, ReachabilityCheckFlags = 384, ReachabilityAndEmitFlags = 1408, - ContextFlags = 2193408, + ContextFlags = 6387712, TypeExcludesFlags = 20480, } enum ModifierFlags { diff --git a/tests/baselines/reference/parserConstructorDeclaration4.errors.txt b/tests/baselines/reference/parserConstructorDeclaration4.errors.txt index b5329a1cb47..bd27ccbb255 100644 --- a/tests/baselines/reference/parserConstructorDeclaration4.errors.txt +++ b/tests/baselines/reference/parserConstructorDeclaration4.errors.txt @@ -1,12 +1,9 @@ tests/cases/conformance/parser/ecmascript5/ConstructorDeclarations/parserConstructorDeclaration4.ts(2,3): error TS1031: 'declare' modifier cannot appear on a class element. -tests/cases/conformance/parser/ecmascript5/ConstructorDeclarations/parserConstructorDeclaration4.ts(2,25): error TS1183: An implementation cannot be declared in ambient contexts. -==== tests/cases/conformance/parser/ecmascript5/ConstructorDeclarations/parserConstructorDeclaration4.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ConstructorDeclarations/parserConstructorDeclaration4.ts (1 errors) ==== class C { declare constructor() { } ~~~~~~~ !!! error TS1031: 'declare' modifier cannot appear on a class element. - ~ -!!! error TS1183: An implementation cannot be declared in ambient contexts. } \ No newline at end of file diff --git a/tests/baselines/reference/parserMemberAccessorDeclaration11.errors.txt b/tests/baselines/reference/parserMemberAccessorDeclaration11.errors.txt index 5da5e536e06..3a04bfbbd02 100644 --- a/tests/baselines/reference/parserMemberAccessorDeclaration11.errors.txt +++ b/tests/baselines/reference/parserMemberAccessorDeclaration11.errors.txt @@ -1,9 +1,12 @@ tests/cases/conformance/parser/ecmascript5/MemberAccessorDeclarations/parserMemberAccessorDeclaration11.ts(2,5): error TS1031: 'declare' modifier cannot appear on a class element. +tests/cases/conformance/parser/ecmascript5/MemberAccessorDeclarations/parserMemberAccessorDeclaration11.ts(2,17): error TS2378: A 'get' accessor must return a value. -==== tests/cases/conformance/parser/ecmascript5/MemberAccessorDeclarations/parserMemberAccessorDeclaration11.ts (1 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/MemberAccessorDeclarations/parserMemberAccessorDeclaration11.ts (2 errors) ==== class C { declare get Foo() { } ~~~~~~~ !!! error TS1031: 'declare' modifier cannot appear on a class element. + ~~~ +!!! error TS2378: A 'get' accessor must return a value. } \ No newline at end of file diff --git a/tests/baselines/reference/parserMemberFunctionDeclaration5.errors.txt b/tests/baselines/reference/parserMemberFunctionDeclaration5.errors.txt index 402355919a0..dc19cb0f855 100644 --- a/tests/baselines/reference/parserMemberFunctionDeclaration5.errors.txt +++ b/tests/baselines/reference/parserMemberFunctionDeclaration5.errors.txt @@ -1,12 +1,9 @@ tests/cases/conformance/parser/ecmascript5/MemberFunctionDeclarations/parserMemberFunctionDeclaration5.ts(2,5): error TS1031: 'declare' modifier cannot appear on a class element. -tests/cases/conformance/parser/ecmascript5/MemberFunctionDeclarations/parserMemberFunctionDeclaration5.ts(2,19): error TS1183: An implementation cannot be declared in ambient contexts. -==== tests/cases/conformance/parser/ecmascript5/MemberFunctionDeclarations/parserMemberFunctionDeclaration5.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/MemberFunctionDeclarations/parserMemberFunctionDeclaration5.ts (1 errors) ==== class C { declare Foo() { } ~~~~~~~ !!! error TS1031: 'declare' modifier cannot appear on a class element. - ~ -!!! error TS1183: An implementation cannot be declared in ambient contexts. } \ No newline at end of file From d54ad4b01ac63d92de6dea44702ac4c4c18cdf49 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 3 Nov 2017 08:31:13 -0700 Subject: [PATCH 098/235] Add refactoring to use default import (#19659) * Add refactoring to use default import * Add localizable description --- src/compiler/diagnosticMessages.json | 4 + src/harness/fourslash.ts | 4 + src/services/refactors/refactors.ts | 1 + src/services/refactors/useDefaultImport.ts | 96 +++++++++++++++++++ .../fourslash/refactorUseDefaultImport.ts | 29 ++++++ 5 files changed, 134 insertions(+) create mode 100644 src/services/refactors/useDefaultImport.ts create mode 100644 tests/cases/fourslash/refactorUseDefaultImport.ts diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 8f855347bd8..2309977539c 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3793,5 +3793,9 @@ "Infer parameter types from usage.": { "category": "Message", "code": 95012 + }, + "Convert to default import": { + "category": "Message", + "code": 95013 } } diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 2b535b223ab..ba8c11462e4 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -470,6 +470,10 @@ namespace FourSlash { public select(startMarker: string, endMarker: string) { const start = this.getMarkerByName(startMarker), end = this.getMarkerByName(endMarker); + ts.Debug.assert(start.fileName === end.fileName); + if (this.activeFile.fileName !== start.fileName) { + this.openFile(start.fileName); + } this.goToPosition(start.position); this.selectionEnd = end.position; } diff --git a/src/services/refactors/refactors.ts b/src/services/refactors/refactors.ts index f4b56422a89..3858b198743 100644 --- a/src/services/refactors/refactors.ts +++ b/src/services/refactors/refactors.ts @@ -2,3 +2,4 @@ /// /// /// +/// diff --git a/src/services/refactors/useDefaultImport.ts b/src/services/refactors/useDefaultImport.ts new file mode 100644 index 00000000000..56faf082a49 --- /dev/null +++ b/src/services/refactors/useDefaultImport.ts @@ -0,0 +1,96 @@ +/* @internal */ +namespace ts.refactor.installTypesForPackage { + const actionName = "Convert to default import"; + + const useDefaultImport: Refactor = { + name: actionName, + description: getLocaleSpecificMessage(Diagnostics.Convert_to_default_import), + getEditsForAction, + getAvailableActions, + }; + + registerRefactor(useDefaultImport); + + function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined { + const { file, startPosition, program } = context; + + if (!program.getCompilerOptions().allowSyntheticDefaultImports) { + return undefined; + } + + const importInfo = getConvertibleImportAtPosition(file, startPosition); + if (!importInfo) { + return undefined; + } + + const module = ts.getResolvedModule(file, importInfo.moduleSpecifier.text); + const resolvedFile = program.getSourceFile(module.resolvedFileName); + if (!(resolvedFile.externalModuleIndicator && isExportAssignment(resolvedFile.externalModuleIndicator) && resolvedFile.externalModuleIndicator.isExportEquals)) { + return undefined; + } + + return [ + { + name: useDefaultImport.name, + description: useDefaultImport.description, + actions: [ + { + description: useDefaultImport.description, + name: actionName, + }, + ], + }, + ]; + } + + function getEditsForAction(context: RefactorContext, _actionName: string): RefactorEditInfo | undefined { + const { file, startPosition } = context; + Debug.assertEqual(actionName, _actionName); + const importInfo = getConvertibleImportAtPosition(file, startPosition); + if (!importInfo) { + return undefined; + } + const { importStatement, name, moduleSpecifier } = importInfo; + const newImportClause = createImportClause(name, /*namedBindings*/ undefined); + const newImportStatement = ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, newImportClause, moduleSpecifier); + return { + edits: textChanges.ChangeTracker.with(context, t => t.replaceNode(file, importStatement, newImportStatement)), + renameFilename: undefined, + renameLocation: undefined, + }; + } + + function getConvertibleImportAtPosition( + file: SourceFile, + startPosition: number, + ): { importStatement: AnyImportSyntax, name: Identifier, moduleSpecifier: StringLiteral } | undefined { + let node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false); + while (true) { + switch (node.kind) { + case SyntaxKind.ImportEqualsDeclaration: + const eq = node as ImportEqualsDeclaration; + const { moduleReference } = eq; + return moduleReference.kind === SyntaxKind.ExternalModuleReference && isStringLiteral(moduleReference.expression) + ? { importStatement: eq, name: eq.name, moduleSpecifier: moduleReference.expression } + : undefined; + case SyntaxKind.ImportDeclaration: + const d = node as ImportDeclaration; + const { importClause } = d; + return !importClause.name && importClause.namedBindings.kind === SyntaxKind.NamespaceImport && isStringLiteral(d.moduleSpecifier) + ? { importStatement: d, name: importClause.namedBindings.name, moduleSpecifier: d.moduleSpecifier } + : undefined; + // For known child node kinds of convertible imports, try again with parent node. + case SyntaxKind.NamespaceImport: + case SyntaxKind.ExternalModuleReference: + case SyntaxKind.ImportKeyword: + case SyntaxKind.Identifier: + case SyntaxKind.StringLiteral: + case SyntaxKind.AsteriskToken: + break; + default: + return undefined; + } + node = node.parent; + } + } +} diff --git a/tests/cases/fourslash/refactorUseDefaultImport.ts b/tests/cases/fourslash/refactorUseDefaultImport.ts new file mode 100644 index 00000000000..8834b70f85e --- /dev/null +++ b/tests/cases/fourslash/refactorUseDefaultImport.ts @@ -0,0 +1,29 @@ +/// + +// @allowSyntheticDefaultImports: true + +// @Filename: /a.d.ts +////declare const x: number; +////export = x; + +// @Filename: /b.ts +/////*b0*/import * as a from "./a";/*b1*/ + +// @Filename: /c.ts +/////*c0*/import a = require("./a");/*c1*/ + +goTo.select("b0", "b1"); +edit.applyRefactor({ + refactorName: "Convert to default import", + actionName: "Convert to default import", + actionDescription: "Convert to default import", + newContent: 'import a from "./a";', +}); + +goTo.select("c0", "c1"); +edit.applyRefactor({ + refactorName: "Convert to default import", + actionName: "Convert to default import", + actionDescription: "Convert to default import", + newContent: 'import a from "./a";', +}); From 1e89e78dd213ee24036895508484d8ae9e18a657 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 3 Nov 2017 08:59:19 -0700 Subject: [PATCH 099/235] Fix incorrect relative module name detection (#19702) --- scripts/ior.ts | 1 - src/compiler/core.ts | 1 - .../declarationEmitRelativeModuleError.errors.txt | 13 +++++++++++++ .../reference/declarationEmitRelativeModuleError.js | 10 ++++++++++ .../declarationEmitRelativeModuleError.symbols | 9 +++++++++ .../declarationEmitRelativeModuleError.types | 9 +++++++++ .../compiler/declarationEmitRelativeModuleError.ts | 7 +++++++ tests/webTestServer.ts | 1 - 8 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/declarationEmitRelativeModuleError.errors.txt create mode 100644 tests/baselines/reference/declarationEmitRelativeModuleError.js create mode 100644 tests/baselines/reference/declarationEmitRelativeModuleError.symbols create mode 100644 tests/baselines/reference/declarationEmitRelativeModuleError.types create mode 100644 tests/cases/compiler/declarationEmitRelativeModuleError.ts diff --git a/scripts/ior.ts b/scripts/ior.ts index 91580203350..374747d8439 100644 --- a/scripts/ior.ts +++ b/scripts/ior.ts @@ -64,7 +64,6 @@ module Commands { } if (path.charAt(1) === ":") { if (path.charAt(2) === directorySeparator) return 3; - return 2; } return 0; } diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 23493b3087d..157a0c7fd1d 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1574,7 +1574,6 @@ namespace ts { } if (path.charCodeAt(1) === CharacterCodes.colon) { if (path.charCodeAt(2) === CharacterCodes.slash) return 3; - return 2; } // Per RFC 1738 'file' URI schema has the shape file:/// // if is omitted then it is assumed that host value is 'localhost', diff --git a/tests/baselines/reference/declarationEmitRelativeModuleError.errors.txt b/tests/baselines/reference/declarationEmitRelativeModuleError.errors.txt new file mode 100644 index 00000000000..32aea83b5e4 --- /dev/null +++ b/tests/baselines/reference/declarationEmitRelativeModuleError.errors.txt @@ -0,0 +1,13 @@ +tests/cases/compiler/declarationEmitRelativeModuleError.ts(5,16): error TS2436: Ambient module declaration cannot specify relative module name. + + +==== tests/cases/compiler/declarationEmitRelativeModuleError.ts (1 errors) ==== + declare module "b:block" { // <-- no error anymore + + } + + declare module "b:/block" { // <-- still an error + ~~~~~~~~~~ +!!! error TS2436: Ambient module declaration cannot specify relative module name. + + } \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitRelativeModuleError.js b/tests/baselines/reference/declarationEmitRelativeModuleError.js new file mode 100644 index 00000000000..e1d78ba5c03 --- /dev/null +++ b/tests/baselines/reference/declarationEmitRelativeModuleError.js @@ -0,0 +1,10 @@ +//// [declarationEmitRelativeModuleError.ts] +declare module "b:block" { // <-- no error anymore + +} + +declare module "b:/block" { // <-- still an error + +} + +//// [declarationEmitRelativeModuleError.js] diff --git a/tests/baselines/reference/declarationEmitRelativeModuleError.symbols b/tests/baselines/reference/declarationEmitRelativeModuleError.symbols new file mode 100644 index 00000000000..d07a145116a --- /dev/null +++ b/tests/baselines/reference/declarationEmitRelativeModuleError.symbols @@ -0,0 +1,9 @@ +=== tests/cases/compiler/declarationEmitRelativeModuleError.ts === +declare module "b:block" { // <-- no error anymore +No type information for this code. +No type information for this code.} +No type information for this code. +No type information for this code.declare module "b:/block" { // <-- still an error +No type information for this code. +No type information for this code.} +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitRelativeModuleError.types b/tests/baselines/reference/declarationEmitRelativeModuleError.types new file mode 100644 index 00000000000..d07a145116a --- /dev/null +++ b/tests/baselines/reference/declarationEmitRelativeModuleError.types @@ -0,0 +1,9 @@ +=== tests/cases/compiler/declarationEmitRelativeModuleError.ts === +declare module "b:block" { // <-- no error anymore +No type information for this code. +No type information for this code.} +No type information for this code. +No type information for this code.declare module "b:/block" { // <-- still an error +No type information for this code. +No type information for this code.} +No type information for this code. \ No newline at end of file diff --git a/tests/cases/compiler/declarationEmitRelativeModuleError.ts b/tests/cases/compiler/declarationEmitRelativeModuleError.ts new file mode 100644 index 00000000000..f358e81da43 --- /dev/null +++ b/tests/cases/compiler/declarationEmitRelativeModuleError.ts @@ -0,0 +1,7 @@ +declare module "b:block" { // <-- no error anymore + +} + +declare module "b:/block" { // <-- still an error + +} \ No newline at end of file diff --git a/tests/webTestServer.ts b/tests/webTestServer.ts index 5a3b4cc5048..aff2ba0752a 100644 --- a/tests/webTestServer.ts +++ b/tests/webTestServer.ts @@ -61,7 +61,6 @@ function getRootLength(path: string): number { } if (path.charAt(1) === ":") { if (path.charAt(2) === directorySeparator) return 3; - return 2; } // Per RFC 1738 'file' URI schema has the shape file:/// // if is omitted then it is assumed that host value is 'localhost', From adac1f398c79e07c4271825c34c11068852267d6 Mon Sep 17 00:00:00 2001 From: csigs Date: Fri, 3 Nov 2017 16:10:16 +0000 Subject: [PATCH 100/235] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl index dddb873d73e..6c74cb8ca90 100644 --- a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2961,6 +2961,12 @@ + + + + + + @@ -3184,7 +3190,7 @@ - + @@ -3193,7 +3199,7 @@ - + @@ -3202,7 +3208,7 @@ - + @@ -4200,6 +4206,18 @@ + + + + + + + + + + + + From 612616a1058d7aa9fc181126f83041549bfbe295 Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Fri, 3 Nov 2017 09:53:56 -0700 Subject: [PATCH 101/235] Loosen restrictions on jsdoc completion locations --- src/services/jsDoc.ts | 54 ++++++++----------- .../fourslash/docCommentTemplateEmptyFile.ts | 2 +- ...ommentTemplateInsideFunctionDeclaration.ts | 10 ++-- .../fourslash/docCommentTemplateJSXText.ts | 12 +++++ ...ocCommentTemplateNamespacesAndModules02.ts | 4 +- .../fourslash/docCommentTemplateRegex.ts | 8 +-- 6 files changed, 50 insertions(+), 40 deletions(-) create mode 100644 tests/cases/fourslash/docCommentTemplateJSXText.ts diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 78ea0c6b534..109330c177c 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -1,5 +1,6 @@ /* @internal */ namespace ts.JsDoc { + const singleLineTemplate = { newText: "/** */", caretOffset: 3 }; const jsDocTagNames = [ "augments", "author", @@ -170,15 +171,9 @@ namespace ts.JsDoc { /** * Checks if position points to a valid position to add JSDoc comments, and if so, * returns the appropriate template. Otherwise returns an empty string. - * Valid positions are - * - outside of comments, statements, and expressions, and - * - preceding a: - * - function/constructor/method declaration - * - class declarations - * - variable statements - * - namespace declarations - * - interface declarations - * - method signatures + * Invalid positions are + * - within comments, strings (including template literals and regex), and JSXText + * - within a token * * Hosts should ideally check that: * - The line is all whitespace up to 'position' before performing the insertion. @@ -204,17 +199,23 @@ namespace ts.JsDoc { const commentOwnerInfo = getCommentOwnerInfo(tokenAtPos); if (!commentOwnerInfo) { - return undefined; + // if climbing the tree did not find a declaration with parameters, complete to a single line comment + return singleLineTemplate; } const { commentOwner, parameters } = commentOwnerInfo; - if (commentOwner.getStart() < position) { + + if (commentOwner.kind === SyntaxKind.JsxText) { return undefined; } - if (!parameters || parameters.length === 0) { - // if there are no parameters, just complete to a single line JSDoc comment - const singleLineResult = "/** */"; - return { newText: singleLineResult, caretOffset: 3 }; + if (commentOwner.getStart() < position) { + // if climbing the tree found a declaration with parameters but the request was made inside it, complete to a single line comment + return singleLineTemplate; + } + + if (parameters.length === 0) { + // if there are no parameters, complete to a single line comment + return singleLineTemplate; } const posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position); @@ -258,7 +259,7 @@ namespace ts.JsDoc { interface CommentOwnerInfo { readonly commentOwner: Node; - readonly parameters?: ReadonlyArray; + readonly parameters: ReadonlyArray; } function getCommentOwnerInfo(tokenAtPos: Node): CommentOwnerInfo | undefined { for (let commentOwner = tokenAtPos; commentOwner; commentOwner = commentOwner.parent) { @@ -270,32 +271,18 @@ namespace ts.JsDoc { const { parameters } = commentOwner as FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | MethodSignature; return { commentOwner, parameters }; - case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.PropertySignature: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.EnumMember: - case SyntaxKind.TypeAliasDeclaration: - return { commentOwner }; - case SyntaxKind.VariableStatement: { const varStatement = commentOwner; const varDeclarations = varStatement.declarationList.declarations; const parameters = varDeclarations.length === 1 && varDeclarations[0].initializer ? getParametersFromRightHandSideOfAssignment(varDeclarations[0].initializer) : undefined; - return { commentOwner, parameters }; + return parameters ? { commentOwner, parameters } : undefined; } case SyntaxKind.SourceFile: return undefined; - case SyntaxKind.ModuleDeclaration: - // If in walking up the tree, we hit a a nested namespace declaration, - // then we must be somewhere within a dotted namespace name; however we don't - // want to give back a JSDoc template for the 'b' or 'c' in 'namespace a.b.c { }'. - return commentOwner.parent.kind === SyntaxKind.ModuleDeclaration ? undefined : { commentOwner }; - case SyntaxKind.BinaryExpression: { const be = commentOwner as BinaryExpression; if (getSpecialPropertyAssignmentKind(be) === ts.SpecialPropertyAssignmentKind.None) { @@ -304,6 +291,11 @@ namespace ts.JsDoc { const parameters = isFunctionLike(be.right) ? be.right.parameters : emptyArray; return { commentOwner, parameters }; } + + case SyntaxKind.JsxText: { + const parameters: ReadonlyArray = emptyArray; + return { commentOwner, parameters }; + } } } } diff --git a/tests/cases/fourslash/docCommentTemplateEmptyFile.ts b/tests/cases/fourslash/docCommentTemplateEmptyFile.ts index f04653dc328..064306e3fbd 100644 --- a/tests/cases/fourslash/docCommentTemplateEmptyFile.ts +++ b/tests/cases/fourslash/docCommentTemplateEmptyFile.ts @@ -3,4 +3,4 @@ // @Filename: emptyFile.ts /////*0*/ -verify.noDocCommentTemplateAt("0"); +verify.docCommentTemplateAt("0", 3, "/** */"); diff --git a/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts b/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts index e0ebc00dc39..67a11a27133 100644 --- a/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts +++ b/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts @@ -3,6 +3,10 @@ // @Filename: functionDecl.ts ////f/*0*/unction /*1*/foo/*2*/(/*3*/) /*4*/{ /*5*/} -for (const marker of test.markers()) { - verify.noDocCommentTemplateAt(marker); -} +verify.noDocCommentTemplateAt("0"); + +verify.docCommentTemplateAt("1", 3, "/** */"); +verify.docCommentTemplateAt("2", 3, "/** */"); +verify.docCommentTemplateAt("3", 3, "/** */"); +verify.docCommentTemplateAt("4", 3, "/** */"); +verify.docCommentTemplateAt("5", 3, "/** */"); diff --git a/tests/cases/fourslash/docCommentTemplateJSXText.ts b/tests/cases/fourslash/docCommentTemplateJSXText.ts new file mode 100644 index 00000000000..845f969f4e3 --- /dev/null +++ b/tests/cases/fourslash/docCommentTemplateJSXText.ts @@ -0,0 +1,12 @@ +/// + +//@Filename: file.tsx +//// +//// var x =
+//// /*0*/hello/*1*/ +//// /*2*/goodbye/*3*/ +////
; + +for (const marker in test.markers()) { + verify.noDocCommentTemplateAt(marker); +} \ No newline at end of file diff --git a/tests/cases/fourslash/docCommentTemplateNamespacesAndModules02.ts b/tests/cases/fourslash/docCommentTemplateNamespacesAndModules02.ts index 787e9f04481..3beb9368661 100644 --- a/tests/cases/fourslash/docCommentTemplateNamespacesAndModules02.ts +++ b/tests/cases/fourslash/docCommentTemplateNamespacesAndModules02.ts @@ -9,6 +9,6 @@ verify.docCommentTemplateAt("top", /*indentation*/ 3, "/** */"); -verify.noDocCommentTemplateAt("n2"); +verify.docCommentTemplateAt("n2", 3, "/** */"); -verify.noDocCommentTemplateAt("n3"); +verify.docCommentTemplateAt("n3", 3, "/** */"); diff --git a/tests/cases/fourslash/docCommentTemplateRegex.ts b/tests/cases/fourslash/docCommentTemplateRegex.ts index 685c1ca5aef..c1368190ca2 100644 --- a/tests/cases/fourslash/docCommentTemplateRegex.ts +++ b/tests/cases/fourslash/docCommentTemplateRegex.ts @@ -3,6 +3,8 @@ // @Filename: regex.ts ////var regex = /*0*///*1*/asdf/*2*/ /*3*///*4*/; -for (const marker of test.markers()) { - verify.noDocCommentTemplateAt(marker); -} +verify.docCommentTemplateAt("0", 3, "/** */"); +verify.noDocCommentTemplateAt("1"); +verify.noDocCommentTemplateAt("2"); +verify.noDocCommentTemplateAt("3"); +verify.docCommentTemplateAt("4", 3, "/** */"); \ No newline at end of file From a980d61f86c4df8f90c11f4ae47000232b2f19a0 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 3 Nov 2017 09:56:39 -0700 Subject: [PATCH 102/235] Add a few tuple tests and update baselines --- .../reference/api/tsserverlibrary.d.ts | 1 - tests/baselines/reference/api/typescript.d.ts | 1 - .../arityAndOrderCompatibility01.errors.txt | 98 ++++++++-------- .../reference/arityAndOrderCompatibility01.js | 2 + .../arityAndOrderCompatibility01.symbols | 106 +++++++++--------- .../arityAndOrderCompatibility01.types | 18 +-- ...teralExpressionContextualTyping.errors.txt | 28 +++-- .../reference/arrayLiterals3.errors.txt | 12 +- .../reference/castingTuple.errors.txt | 34 +++++- tests/baselines/reference/castingTuple.js | 4 + .../baselines/reference/castingTuple.symbols | 52 +++++---- tests/baselines/reference/castingTuple.types | 10 ++ .../contextualTypeWithTuple.errors.txt | 33 +++--- ...cturingParameterDeclaration1ES5.errors.txt | 16 ++- ...estructuringParameterDeclaration1ES5.types | 8 +- ...arameterDeclaration1ES5iterable.errors.txt | 16 ++- ...ringParameterDeclaration1ES5iterable.types | 8 +- ...cturingParameterDeclaration1ES6.errors.txt | 16 ++- ...estructuringParameterDeclaration1ES6.types | 8 +- ...tructuringParameterDeclaration2.errors.txt | 12 +- ...cturingParameterDeclaration3ES5.errors.txt | 55 +++++++++ ...estructuringParameterDeclaration3ES5.types | 6 +- ...arameterDeclaration3ES5iterable.errors.txt | 55 +++++++++ ...ringParameterDeclaration3ES5iterable.types | 6 +- ...cturingParameterDeclaration3ES6.errors.txt | 55 +++++++++ ...estructuringParameterDeclaration3ES6.types | 6 +- .../genericCallWithTupleType.errors.txt | 12 +- .../reference/keyofAndIndexedAccess.types | 4 +- .../promiseEmptyTupleNoException.errors.txt | 10 +- .../tsconfig.json | 1 - .../tsconfig.json | 1 - .../tsconfig.json | 1 - .../tsconfig.json | 1 - .../tsconfig.json | 1 - .../tsconfig.json | 1 - .../tsconfig.json | 1 - .../tsconfig.json | 1 - .../baselines/reference/tupleTypes.errors.txt | 11 +- tests/baselines/reference/tupleTypes.js | 4 +- tests/baselines/reference/tupleTypes.symbols | 2 +- tests/baselines/reference/tupleTypes.types | 2 +- .../unionTypeFromArrayLiteral.errors.txt | 33 ++++++ .../reference/wideningTuples3.errors.txt | 11 +- .../reference/wideningTuples4.errors.txt | 14 +++ tests/cases/compiler/tupleTypes.ts | 2 +- .../tuple/arityAndOrderCompatibility01.ts | 2 + .../conformance/types/tuple/castingTuple.ts | 2 + .../types/tuple/strictTupleLength.ts | 2 - 48 files changed, 544 insertions(+), 241 deletions(-) create mode 100644 tests/baselines/reference/destructuringParameterDeclaration3ES5.errors.txt create mode 100644 tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.errors.txt create mode 100644 tests/baselines/reference/destructuringParameterDeclaration3ES6.errors.txt create mode 100644 tests/baselines/reference/unionTypeFromArrayLiteral.errors.txt create mode 100644 tests/baselines/reference/wideningTuples4.errors.txt diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index f8593cc76e3..08e7ef8fe50 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2278,7 +2278,6 @@ declare namespace ts { strict?: boolean; strictFunctionTypes?: boolean; strictNullChecks?: boolean; - strictTuples?: boolean; suppressExcessPropertyErrors?: boolean; suppressImplicitAnyIndexErrors?: boolean; target?: ScriptTarget; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 15269f4d7af..666cc34162b 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2278,7 +2278,6 @@ declare namespace ts { strict?: boolean; strictFunctionTypes?: boolean; strictNullChecks?: boolean; - strictTuples?: boolean; suppressExcessPropertyErrors?: boolean; suppressImplicitAnyIndexErrors?: boolean; target?: ScriptTarget; diff --git a/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt b/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt index 5a367a4122f..4d6fbd063ae 100644 --- a/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt +++ b/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt @@ -1,52 +1,49 @@ -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(13,12): error TS2493: Tuple type '[string, number]' with length '2' cannot be assigned to tuple with length '3'. -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(14,12): error TS2460: Type 'StrNum' has no property '2'. -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(15,5): error TS2461: Type '{ 0: string; 1: number; }' is not an array type. -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(15,12): error TS2460: Type '{ 0: string; 1: number; }' has no property '2'. -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(16,5): error TS2322: Type '[string, number]' is not assignable to type '[number, number, number]'. +tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(15,12): error TS2493: Tuple type '[string, number]' with length '2' cannot be assigned to tuple with length '3'. +tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(16,12): error TS2460: Type 'StrNum' has no property '2'. +tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(17,5): error TS2461: Type '{ 0: string; 1: number; length: 2; }' is not an array type. +tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(17,12): error TS2460: Type '{ 0: string; 1: number; length: 2; }' has no property '2'. +tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(18,5): error TS2322: Type '[string, number]' is not assignable to type '[number, number, number]'. Property '2' is missing in type '[string, number]'. -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(17,5): error TS2322: Type 'StrNum' is not assignable to type '[number, number, number]'. +tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(19,5): error TS2322: Type 'StrNum' is not assignable to type '[number, number, number]'. Property '2' is missing in type 'StrNum'. -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(18,5): error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[number, number, number]'. - Property '2' is missing in type '{ 0: string; 1: number; }'. -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(19,5): error TS2322: Type '[string, number]' is not assignable to type '[string, number, number]'. +tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(20,5): error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number, number, number]'. + Property '2' is missing in type '{ 0: string; 1: number; length: 2; }'. +tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(21,5): error TS2322: Type '[string, number]' is not assignable to type '[string, number, number]'. Property '2' is missing in type '[string, number]'. -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(20,5): error TS2322: Type 'StrNum' is not assignable to type '[string, number, number]'. +tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(22,5): error TS2322: Type 'StrNum' is not assignable to type '[string, number, number]'. Property '2' is missing in type 'StrNum'. -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(21,5): error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[string, number, number]'. - Property '2' is missing in type '{ 0: string; 1: number; }'. -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(22,5): error TS2322: Type '[string, number]' is not assignable to type '[number]'. +tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(23,5): error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[string, number, number]'. + Property '2' is missing in type '{ 0: string; 1: number; length: 2; }'. +tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(24,5): error TS2322: Type '[string, number]' is not assignable to type '[number]'. Types of property '0' are incompatible. Type 'string' is not assignable to type 'number'. -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(23,5): error TS2322: Type 'StrNum' is not assignable to type '[number]'. +tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(25,5): error TS2322: Type 'StrNum' is not assignable to type '[number]'. Types of property '0' are incompatible. Type 'string' is not assignable to type 'number'. -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(24,5): error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[number]'. - Property 'length' is missing in type '{ 0: string; 1: number; }'. -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(25,5): error TS2322: Type '[string, number]' is not assignable to type '[string]'. - Types of property 'pop' are incompatible. - Type '() => string | number' is not assignable to type '() => string'. - Type 'string | number' is not assignable to type 'string'. - Type 'number' is not assignable to type 'string'. -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(26,5): error TS2322: Type 'StrNum' is not assignable to type '[string]'. - Types of property 'pop' are incompatible. - Type '() => string | number' is not assignable to type '() => string'. - Type 'string | number' is not assignable to type 'string'. - Type 'number' is not assignable to type 'string'. -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(27,5): error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[string]'. - Property 'length' is missing in type '{ 0: string; 1: number; }'. -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(28,5): error TS2322: Type '[string, number]' is not assignable to type '[number, string]'. +tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(26,5): error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number]'. + Property 'push' is missing in type '{ 0: string; 1: number; length: 2; }'. +tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(27,5): error TS2322: Type '[string, number]' is not assignable to type '[string]'. + Types of property 'length' are incompatible. + Type '2' is not assignable to type '1'. +tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(28,5): error TS2322: Type 'StrNum' is not assignable to type '[string]'. + Types of property 'length' are incompatible. + Type '2' is not assignable to type '1'. +tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(29,5): error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[string]'. + Property 'push' is missing in type '{ 0: string; 1: number; length: 2; }'. +tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(30,5): error TS2322: Type '[string, number]' is not assignable to type '[number, string]'. Type 'string' is not assignable to type 'number'. -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(29,5): error TS2322: Type 'StrNum' is not assignable to type '[number, string]'. +tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(31,5): error TS2322: Type 'StrNum' is not assignable to type '[number, string]'. Types of property '0' are incompatible. Type 'string' is not assignable to type 'number'. -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(30,5): error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[number, string]'. - Property 'length' is missing in type '{ 0: string; 1: number; }'. +tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(32,5): error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number, string]'. + Property 'push' is missing in type '{ 0: string; 1: number; length: 2; }'. ==== tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts (19 errors) ==== interface StrNum extends Array { 0: string; 1: number; + length: 2; } var x: [string, number]; @@ -54,6 +51,7 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(30,5): error var z: { 0: string; 1: number; + length: 2; } var [a, b, c] = x; @@ -64,9 +62,9 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(30,5): error !!! error TS2460: Type 'StrNum' has no property '2'. var [g, h, i] = z; ~~~~~~~~~ -!!! error TS2461: Type '{ 0: string; 1: number; }' is not an array type. +!!! error TS2461: Type '{ 0: string; 1: number; length: 2; }' is not an array type. ~ -!!! error TS2460: Type '{ 0: string; 1: number; }' has no property '2'. +!!! error TS2460: Type '{ 0: string; 1: number; length: 2; }' has no property '2'. var j1: [number, number, number] = x; ~~ !!! error TS2322: Type '[string, number]' is not assignable to type '[number, number, number]'. @@ -77,8 +75,8 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(30,5): error !!! error TS2322: Property '2' is missing in type 'StrNum'. var j3: [number, number, number] = z; ~~ -!!! error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[number, number, number]'. -!!! error TS2322: Property '2' is missing in type '{ 0: string; 1: number; }'. +!!! error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number, number, number]'. +!!! error TS2322: Property '2' is missing in type '{ 0: string; 1: number; length: 2; }'. var k1: [string, number, number] = x; ~~ !!! error TS2322: Type '[string, number]' is not assignable to type '[string, number, number]'. @@ -89,8 +87,8 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(30,5): error !!! error TS2322: Property '2' is missing in type 'StrNum'. var k3: [string, number, number] = z; ~~ -!!! error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[string, number, number]'. -!!! error TS2322: Property '2' is missing in type '{ 0: string; 1: number; }'. +!!! error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[string, number, number]'. +!!! error TS2322: Property '2' is missing in type '{ 0: string; 1: number; length: 2; }'. var l1: [number] = x; ~~ !!! error TS2322: Type '[string, number]' is not assignable to type '[number]'. @@ -103,26 +101,22 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(30,5): error !!! error TS2322: Type 'string' is not assignable to type 'number'. var l3: [number] = z; ~~ -!!! error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[number]'. -!!! error TS2322: Property 'length' is missing in type '{ 0: string; 1: number; }'. +!!! error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number]'. +!!! error TS2322: Property 'push' is missing in type '{ 0: string; 1: number; length: 2; }'. var m1: [string] = x; ~~ !!! error TS2322: Type '[string, number]' is not assignable to type '[string]'. -!!! error TS2322: Types of property 'pop' are incompatible. -!!! error TS2322: Type '() => string | number' is not assignable to type '() => string'. -!!! error TS2322: Type 'string | number' is not assignable to type 'string'. -!!! error TS2322: Type 'number' is not assignable to type 'string'. +!!! error TS2322: Types of property 'length' are incompatible. +!!! error TS2322: Type '2' is not assignable to type '1'. var m2: [string] = y; ~~ !!! error TS2322: Type 'StrNum' is not assignable to type '[string]'. -!!! error TS2322: Types of property 'pop' are incompatible. -!!! error TS2322: Type '() => string | number' is not assignable to type '() => string'. -!!! error TS2322: Type 'string | number' is not assignable to type 'string'. -!!! error TS2322: Type 'number' is not assignable to type 'string'. +!!! error TS2322: Types of property 'length' are incompatible. +!!! error TS2322: Type '2' is not assignable to type '1'. var m3: [string] = z; ~~ -!!! error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[string]'. -!!! error TS2322: Property 'length' is missing in type '{ 0: string; 1: number; }'. +!!! error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[string]'. +!!! error TS2322: Property 'push' is missing in type '{ 0: string; 1: number; length: 2; }'. var n1: [number, string] = x; ~~ !!! error TS2322: Type '[string, number]' is not assignable to type '[number, string]'. @@ -134,8 +128,8 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(30,5): error !!! error TS2322: Type 'string' is not assignable to type 'number'. var n3: [number, string] = z; ~~ -!!! error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[number, string]'. -!!! error TS2322: Property 'length' is missing in type '{ 0: string; 1: number; }'. +!!! error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number, string]'. +!!! error TS2322: Property 'push' is missing in type '{ 0: string; 1: number; length: 2; }'. var o1: [string, number] = x; var o2: [string, number] = y; var o3: [string, number] = y; diff --git a/tests/baselines/reference/arityAndOrderCompatibility01.js b/tests/baselines/reference/arityAndOrderCompatibility01.js index 2eb1bcf8bd8..bf7736a80c9 100644 --- a/tests/baselines/reference/arityAndOrderCompatibility01.js +++ b/tests/baselines/reference/arityAndOrderCompatibility01.js @@ -2,6 +2,7 @@ interface StrNum extends Array { 0: string; 1: number; + length: 2; } var x: [string, number]; @@ -9,6 +10,7 @@ var y: StrNum var z: { 0: string; 1: number; + length: 2; } var [a, b, c] = x; diff --git a/tests/baselines/reference/arityAndOrderCompatibility01.symbols b/tests/baselines/reference/arityAndOrderCompatibility01.symbols index c6ef08a845b..3a5d55dc1e6 100644 --- a/tests/baselines/reference/arityAndOrderCompatibility01.symbols +++ b/tests/baselines/reference/arityAndOrderCompatibility01.symbols @@ -5,109 +5,113 @@ interface StrNum extends Array { 0: string; 1: number; + length: 2; +>length : Symbol(StrNum.length, Decl(arityAndOrderCompatibility01.ts, 2, 14)) } var x: [string, number]; ->x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 5, 3)) +>x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 6, 3)) var y: StrNum ->y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 6, 3)) +>y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 7, 3)) >StrNum : Symbol(StrNum, Decl(arityAndOrderCompatibility01.ts, 0, 0)) var z: { ->z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 7, 3)) +>z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 8, 3)) 0: string; 1: number; + length: 2; +>length : Symbol(length, Decl(arityAndOrderCompatibility01.ts, 10, 14)) } var [a, b, c] = x; ->a : Symbol(a, Decl(arityAndOrderCompatibility01.ts, 12, 5)) ->b : Symbol(b, Decl(arityAndOrderCompatibility01.ts, 12, 7)) ->c : Symbol(c, Decl(arityAndOrderCompatibility01.ts, 12, 10)) ->x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 5, 3)) +>a : Symbol(a, Decl(arityAndOrderCompatibility01.ts, 14, 5)) +>b : Symbol(b, Decl(arityAndOrderCompatibility01.ts, 14, 7)) +>c : Symbol(c, Decl(arityAndOrderCompatibility01.ts, 14, 10)) +>x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 6, 3)) var [d, e, f] = y; ->d : Symbol(d, Decl(arityAndOrderCompatibility01.ts, 13, 5)) ->e : Symbol(e, Decl(arityAndOrderCompatibility01.ts, 13, 7)) ->f : Symbol(f, Decl(arityAndOrderCompatibility01.ts, 13, 10)) ->y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 6, 3)) +>d : Symbol(d, Decl(arityAndOrderCompatibility01.ts, 15, 5)) +>e : Symbol(e, Decl(arityAndOrderCompatibility01.ts, 15, 7)) +>f : Symbol(f, Decl(arityAndOrderCompatibility01.ts, 15, 10)) +>y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 7, 3)) var [g, h, i] = z; ->g : Symbol(g, Decl(arityAndOrderCompatibility01.ts, 14, 5)) ->h : Symbol(h, Decl(arityAndOrderCompatibility01.ts, 14, 7)) ->i : Symbol(i, Decl(arityAndOrderCompatibility01.ts, 14, 10)) ->z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 7, 3)) +>g : Symbol(g, Decl(arityAndOrderCompatibility01.ts, 16, 5)) +>h : Symbol(h, Decl(arityAndOrderCompatibility01.ts, 16, 7)) +>i : Symbol(i, Decl(arityAndOrderCompatibility01.ts, 16, 10)) +>z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 8, 3)) var j1: [number, number, number] = x; ->j1 : Symbol(j1, Decl(arityAndOrderCompatibility01.ts, 15, 3)) ->x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 5, 3)) +>j1 : Symbol(j1, Decl(arityAndOrderCompatibility01.ts, 17, 3)) +>x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 6, 3)) var j2: [number, number, number] = y; ->j2 : Symbol(j2, Decl(arityAndOrderCompatibility01.ts, 16, 3)) ->y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 6, 3)) +>j2 : Symbol(j2, Decl(arityAndOrderCompatibility01.ts, 18, 3)) +>y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 7, 3)) var j3: [number, number, number] = z; ->j3 : Symbol(j3, Decl(arityAndOrderCompatibility01.ts, 17, 3)) ->z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 7, 3)) +>j3 : Symbol(j3, Decl(arityAndOrderCompatibility01.ts, 19, 3)) +>z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 8, 3)) var k1: [string, number, number] = x; ->k1 : Symbol(k1, Decl(arityAndOrderCompatibility01.ts, 18, 3)) ->x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 5, 3)) +>k1 : Symbol(k1, Decl(arityAndOrderCompatibility01.ts, 20, 3)) +>x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 6, 3)) var k2: [string, number, number] = y; ->k2 : Symbol(k2, Decl(arityAndOrderCompatibility01.ts, 19, 3)) ->y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 6, 3)) +>k2 : Symbol(k2, Decl(arityAndOrderCompatibility01.ts, 21, 3)) +>y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 7, 3)) var k3: [string, number, number] = z; ->k3 : Symbol(k3, Decl(arityAndOrderCompatibility01.ts, 20, 3)) ->z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 7, 3)) +>k3 : Symbol(k3, Decl(arityAndOrderCompatibility01.ts, 22, 3)) +>z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 8, 3)) var l1: [number] = x; ->l1 : Symbol(l1, Decl(arityAndOrderCompatibility01.ts, 21, 3)) ->x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 5, 3)) +>l1 : Symbol(l1, Decl(arityAndOrderCompatibility01.ts, 23, 3)) +>x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 6, 3)) var l2: [number] = y; ->l2 : Symbol(l2, Decl(arityAndOrderCompatibility01.ts, 22, 3)) ->y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 6, 3)) +>l2 : Symbol(l2, Decl(arityAndOrderCompatibility01.ts, 24, 3)) +>y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 7, 3)) var l3: [number] = z; ->l3 : Symbol(l3, Decl(arityAndOrderCompatibility01.ts, 23, 3)) ->z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 7, 3)) +>l3 : Symbol(l3, Decl(arityAndOrderCompatibility01.ts, 25, 3)) +>z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 8, 3)) var m1: [string] = x; ->m1 : Symbol(m1, Decl(arityAndOrderCompatibility01.ts, 24, 3)) ->x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 5, 3)) +>m1 : Symbol(m1, Decl(arityAndOrderCompatibility01.ts, 26, 3)) +>x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 6, 3)) var m2: [string] = y; ->m2 : Symbol(m2, Decl(arityAndOrderCompatibility01.ts, 25, 3)) ->y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 6, 3)) +>m2 : Symbol(m2, Decl(arityAndOrderCompatibility01.ts, 27, 3)) +>y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 7, 3)) var m3: [string] = z; ->m3 : Symbol(m3, Decl(arityAndOrderCompatibility01.ts, 26, 3)) ->z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 7, 3)) +>m3 : Symbol(m3, Decl(arityAndOrderCompatibility01.ts, 28, 3)) +>z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 8, 3)) var n1: [number, string] = x; ->n1 : Symbol(n1, Decl(arityAndOrderCompatibility01.ts, 27, 3)) ->x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 5, 3)) +>n1 : Symbol(n1, Decl(arityAndOrderCompatibility01.ts, 29, 3)) +>x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 6, 3)) var n2: [number, string] = y; ->n2 : Symbol(n2, Decl(arityAndOrderCompatibility01.ts, 28, 3)) ->y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 6, 3)) +>n2 : Symbol(n2, Decl(arityAndOrderCompatibility01.ts, 30, 3)) +>y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 7, 3)) var n3: [number, string] = z; ->n3 : Symbol(n3, Decl(arityAndOrderCompatibility01.ts, 29, 3)) ->z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 7, 3)) +>n3 : Symbol(n3, Decl(arityAndOrderCompatibility01.ts, 31, 3)) +>z : Symbol(z, Decl(arityAndOrderCompatibility01.ts, 8, 3)) var o1: [string, number] = x; ->o1 : Symbol(o1, Decl(arityAndOrderCompatibility01.ts, 30, 3)) ->x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 5, 3)) +>o1 : Symbol(o1, Decl(arityAndOrderCompatibility01.ts, 32, 3)) +>x : Symbol(x, Decl(arityAndOrderCompatibility01.ts, 6, 3)) var o2: [string, number] = y; ->o2 : Symbol(o2, Decl(arityAndOrderCompatibility01.ts, 31, 3)) ->y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 6, 3)) +>o2 : Symbol(o2, Decl(arityAndOrderCompatibility01.ts, 33, 3)) +>y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 7, 3)) var o3: [string, number] = y; ->o3 : Symbol(o3, Decl(arityAndOrderCompatibility01.ts, 32, 3)) ->y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 6, 3)) +>o3 : Symbol(o3, Decl(arityAndOrderCompatibility01.ts, 34, 3)) +>y : Symbol(y, Decl(arityAndOrderCompatibility01.ts, 7, 3)) diff --git a/tests/baselines/reference/arityAndOrderCompatibility01.types b/tests/baselines/reference/arityAndOrderCompatibility01.types index 934c5c6966d..80e91fbd2e7 100644 --- a/tests/baselines/reference/arityAndOrderCompatibility01.types +++ b/tests/baselines/reference/arityAndOrderCompatibility01.types @@ -5,6 +5,8 @@ interface StrNum extends Array { 0: string; 1: number; + length: 2; +>length : 2 } var x: [string, number]; @@ -15,10 +17,12 @@ var y: StrNum >StrNum : StrNum var z: { ->z : { 0: string; 1: number; } +>z : { 0: string; 1: number; length: 2; } 0: string; 1: number; + length: 2; +>length : 2 } var [a, b, c] = x; @@ -37,7 +41,7 @@ var [g, h, i] = z; >g : string >h : number >i : any ->z : { 0: string; 1: number; } +>z : { 0: string; 1: number; length: 2; } var j1: [number, number, number] = x; >j1 : [number, number, number] @@ -49,7 +53,7 @@ var j2: [number, number, number] = y; var j3: [number, number, number] = z; >j3 : [number, number, number] ->z : { 0: string; 1: number; } +>z : { 0: string; 1: number; length: 2; } var k1: [string, number, number] = x; >k1 : [string, number, number] @@ -61,7 +65,7 @@ var k2: [string, number, number] = y; var k3: [string, number, number] = z; >k3 : [string, number, number] ->z : { 0: string; 1: number; } +>z : { 0: string; 1: number; length: 2; } var l1: [number] = x; >l1 : [number] @@ -73,7 +77,7 @@ var l2: [number] = y; var l3: [number] = z; >l3 : [number] ->z : { 0: string; 1: number; } +>z : { 0: string; 1: number; length: 2; } var m1: [string] = x; >m1 : [string] @@ -85,7 +89,7 @@ var m2: [string] = y; var m3: [string] = z; >m3 : [string] ->z : { 0: string; 1: number; } +>z : { 0: string; 1: number; length: 2; } var n1: [number, string] = x; >n1 : [number, string] @@ -97,7 +101,7 @@ var n2: [number, string] = y; var n3: [number, string] = z; >n3 : [number, string] ->z : { 0: string; 1: number; } +>z : { 0: string; 1: number; length: 2; } var o1: [string, number] = x; >o1 : [string, number] diff --git a/tests/baselines/reference/arrayLiteralExpressionContextualTyping.errors.txt b/tests/baselines/reference/arrayLiteralExpressionContextualTyping.errors.txt index 3e9777aea7c..8cb36b113a7 100644 --- a/tests/baselines/reference/arrayLiteralExpressionContextualTyping.errors.txt +++ b/tests/baselines/reference/arrayLiteralExpressionContextualTyping.errors.txt @@ -1,27 +1,37 @@ +tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionContextualTyping.ts(6,5): error TS2322: Type '[number, number, number, number]' is not assignable to type '[number, number, number]'. + Types of property 'length' are incompatible. + Type '4' is not assignable to type '3'. +tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionContextualTyping.ts(7,5): error TS2322: Type '[number, number, number, string]' is not assignable to type '[string | number, string | number, string | number]'. + Types of property 'length' are incompatible. + Type '4' is not assignable to type '3'. tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionContextualTyping.ts(8,5): error TS2322: Type '[number, number, number, string]' is not assignable to type '[number, number, number]'. - Types of property 'pop' are incompatible. - Type '() => string | number' is not assignable to type '() => number'. - Type 'string | number' is not assignable to type 'number'. - Type 'string' is not assignable to type 'number'. + Types of property 'length' are incompatible. + Type '4' is not assignable to type '3'. tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionContextualTyping.ts(14,5): error TS2322: Type 'number[]' is not assignable to type '[number, number, number]'. Property '0' is missing in type 'number[]'. -==== tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionContextualTyping.ts (2 errors) ==== +==== tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionContextualTyping.ts (4 errors) ==== // In a contextually typed array literal expression containing no spread elements, an element expression at index N is contextually typed by // the type of the property with the numeric name N in the contextual type, if any, or otherwise // the numeric index type of the contextual type, if any. var array = [1, 2, 3]; var array1 = [true, 2, 3]; // Contextual type by the numeric index type of the contextual type var tup: [number, number, number] = [1, 2, 3, 4]; + ~~~ +!!! error TS2322: Type '[number, number, number, number]' is not assignable to type '[number, number, number]'. +!!! error TS2322: Types of property 'length' are incompatible. +!!! error TS2322: Type '4' is not assignable to type '3'. var tup1: [number|string, number|string, number|string] = [1, 2, 3, "string"]; + ~~~~ +!!! error TS2322: Type '[number, number, number, string]' is not assignable to type '[string | number, string | number, string | number]'. +!!! error TS2322: Types of property 'length' are incompatible. +!!! error TS2322: Type '4' is not assignable to type '3'. var tup2: [number, number, number] = [1, 2, 3, "string"]; // Error ~~~~ !!! error TS2322: Type '[number, number, number, string]' is not assignable to type '[number, number, number]'. -!!! error TS2322: Types of property 'pop' are incompatible. -!!! error TS2322: Type '() => string | number' is not assignable to type '() => number'. -!!! error TS2322: Type 'string | number' is not assignable to type 'number'. -!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! error TS2322: Types of property 'length' are incompatible. +!!! error TS2322: Type '4' is not assignable to type '3'. // In a contextually typed array literal expression containing one or more spread elements, // an element expression at index N is contextually typed by the numeric index type of the contextual type, if any. diff --git a/tests/baselines/reference/arrayLiterals3.errors.txt b/tests/baselines/reference/arrayLiterals3.errors.txt index 3ebf4174f51..8c36d7d59c1 100644 --- a/tests/baselines/reference/arrayLiterals3.errors.txt +++ b/tests/baselines/reference/arrayLiterals3.errors.txt @@ -3,10 +3,8 @@ tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(10,5): error tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(11,5): error TS2322: Type '["string", number, boolean]' is not assignable to type '[boolean, string, number]'. Type '"string"' is not assignable to type 'boolean'. tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(17,5): error TS2322: Type '[number, number, string, boolean]' is not assignable to type '[number, number]'. - Types of property 'pop' are incompatible. - Type '() => string | number | boolean' is not assignable to type '() => number'. - Type 'string | number | boolean' is not assignable to type 'number'. - Type 'string' is not assignable to type 'number'. + Types of property 'length' are incompatible. + Type '4' is not assignable to type '2'. tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(32,5): error TS2322: Type '(number[] | string[])[]' is not assignable to type 'tup'. Property '0' is missing in type '(number[] | string[])[]'. tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(33,5): error TS2322: Type 'number[]' is not assignable to type '[number, number, number]'. @@ -46,10 +44,8 @@ tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(34,5): error var [b1, b2]: [number, number] = [1, 2, "string", true]; ~~~~~~~~ !!! error TS2322: Type '[number, number, string, boolean]' is not assignable to type '[number, number]'. -!!! error TS2322: Types of property 'pop' are incompatible. -!!! error TS2322: Type '() => string | number | boolean' is not assignable to type '() => number'. -!!! error TS2322: Type 'string | number | boolean' is not assignable to type 'number'. -!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! error TS2322: Types of property 'length' are incompatible. +!!! error TS2322: Type '4' is not assignable to type '2'. // The resulting type an array literal expression is determined as follows: // - the resulting type is an array type with an element type that is the union of the types of the diff --git a/tests/baselines/reference/castingTuple.errors.txt b/tests/baselines/reference/castingTuple.errors.txt index eb6aac5f463..a17f8c2b082 100644 --- a/tests/baselines/reference/castingTuple.errors.txt +++ b/tests/baselines/reference/castingTuple.errors.txt @@ -1,13 +1,21 @@ -tests/cases/conformance/types/tuple/castingTuple.ts(28,10): error TS2352: Type '[number, string]' cannot be converted to type '[number, number]'. +tests/cases/conformance/types/tuple/castingTuple.ts(13,23): error TS2352: Type '[number, string]' cannot be converted to type '[number, string, boolean]'. + Property '2' is missing in type '[number, string]'. +tests/cases/conformance/types/tuple/castingTuple.ts(14,15): error TS2352: Type '[number, string, boolean]' cannot be converted to type '[number, string]'. + Types of property 'length' are incompatible. + Type '3' is not comparable to type '2'. +tests/cases/conformance/types/tuple/castingTuple.ts(15,14): error TS2352: Type '[number, string]' cannot be converted to type '[number, string, boolean]'. +tests/cases/conformance/types/tuple/castingTuple.ts(18,21): error TS2352: Type '[C, D]' cannot be converted to type '[C, D, A]'. + Property '2' is missing in type '[C, D]'. +tests/cases/conformance/types/tuple/castingTuple.ts(30,10): error TS2352: Type '[number, string]' cannot be converted to type '[number, number]'. Type 'string' is not comparable to type 'number'. -tests/cases/conformance/types/tuple/castingTuple.ts(29,10): error TS2352: Type '[C, D]' cannot be converted to type '[A, I]'. +tests/cases/conformance/types/tuple/castingTuple.ts(31,10): error TS2352: Type '[C, D]' cannot be converted to type '[A, I]'. Type 'C' is not comparable to type 'A'. Property 'a' is missing in type 'C'. -tests/cases/conformance/types/tuple/castingTuple.ts(30,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'array1' has type '{}[]' at tests/cases/conformance/types/tuple/castingTuple.ts 20:4, but here has type 'number[]'. -tests/cases/conformance/types/tuple/castingTuple.ts(31,1): error TS2304: Cannot find name 't4'. +tests/cases/conformance/types/tuple/castingTuple.ts(32,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'array1' has type '{}[]' at tests/cases/conformance/types/tuple/castingTuple.ts 22:4, but here has type 'number[]'. +tests/cases/conformance/types/tuple/castingTuple.ts(33,1): error TS2304: Cannot find name 't4'. -==== tests/cases/conformance/types/tuple/castingTuple.ts (4 errors) ==== +==== tests/cases/conformance/types/tuple/castingTuple.ts (8 errors) ==== interface I { } class A { a = 10; } class C implements I { c }; @@ -21,9 +29,23 @@ tests/cases/conformance/types/tuple/castingTuple.ts(31,1): error TS2304: Cannot var numStrTuple: [number, string] = [5, "foo"]; var emptyObjTuple = <[{}, {}]>numStrTuple; var numStrBoolTuple = <[number, string, boolean]>numStrTuple; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2352: Type '[number, string]' cannot be converted to type '[number, string, boolean]'. +!!! error TS2352: Property '2' is missing in type '[number, string]'. + var shorter = numStrBoolTuple as [number, string] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2352: Type '[number, string, boolean]' cannot be converted to type '[number, string]'. +!!! error TS2352: Types of property 'length' are incompatible. +!!! error TS2352: Type '3' is not comparable to type '2'. + var longer = numStrTuple as [number, string, boolean] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2352: Type '[number, string]' cannot be converted to type '[number, string, boolean]'. var classCDTuple: [C, D] = [new C(), new D()]; var interfaceIITuple = <[I, I]>classCDTuple; var classCDATuple = <[C, D, A]>classCDTuple; + ~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2352: Type '[C, D]' cannot be converted to type '[C, D, A]'. +!!! error TS2352: Property '2' is missing in type '[C, D]'. var eleFromCDA1 = classCDATuple[2]; // A var eleFromCDA2 = classCDATuple[5]; // C | D | A var t10: [E1, E2] = [E1.one, E2.one]; @@ -46,7 +68,7 @@ tests/cases/conformance/types/tuple/castingTuple.ts(31,1): error TS2304: Cannot !!! error TS2352: Property 'a' is missing in type 'C'. var array1 = numStrTuple; ~~~~~~ -!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'array1' has type '{}[]' at tests/cases/conformance/types/tuple/castingTuple.ts 20:4, but here has type 'number[]'. +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'array1' has type '{}[]' at tests/cases/conformance/types/tuple/castingTuple.ts 22:4, but here has type 'number[]'. t4[2] = 10; ~~ !!! error TS2304: Cannot find name 't4'. diff --git a/tests/baselines/reference/castingTuple.js b/tests/baselines/reference/castingTuple.js index 3744d40d8a5..a94246a19b8 100644 --- a/tests/baselines/reference/castingTuple.js +++ b/tests/baselines/reference/castingTuple.js @@ -12,6 +12,8 @@ enum E2 { one } var numStrTuple: [number, string] = [5, "foo"]; var emptyObjTuple = <[{}, {}]>numStrTuple; var numStrBoolTuple = <[number, string, boolean]>numStrTuple; +var shorter = numStrBoolTuple as [number, string] +var longer = numStrTuple as [number, string, boolean] var classCDTuple: [C, D] = [new C(), new D()]; var interfaceIITuple = <[I, I]>classCDTuple; var classCDATuple = <[C, D, A]>classCDTuple; @@ -89,6 +91,8 @@ var E2; var numStrTuple = [5, "foo"]; var emptyObjTuple = numStrTuple; var numStrBoolTuple = numStrTuple; +var shorter = numStrBoolTuple; +var longer = numStrTuple; var classCDTuple = [new C(), new D()]; var interfaceIITuple = classCDTuple; var classCDATuple = classCDTuple; diff --git a/tests/baselines/reference/castingTuple.symbols b/tests/baselines/reference/castingTuple.symbols index 61edfb4b376..3cf5face2a6 100644 --- a/tests/baselines/reference/castingTuple.symbols +++ b/tests/baselines/reference/castingTuple.symbols @@ -46,37 +46,45 @@ var numStrBoolTuple = <[number, string, boolean]>numStrTuple; >numStrBoolTuple : Symbol(numStrBoolTuple, Decl(castingTuple.ts, 12, 3)) >numStrTuple : Symbol(numStrTuple, Decl(castingTuple.ts, 10, 3)) +var shorter = numStrBoolTuple as [number, string] +>shorter : Symbol(shorter, Decl(castingTuple.ts, 13, 3)) +>numStrBoolTuple : Symbol(numStrBoolTuple, Decl(castingTuple.ts, 12, 3)) + +var longer = numStrTuple as [number, string, boolean] +>longer : Symbol(longer, Decl(castingTuple.ts, 14, 3)) +>numStrTuple : Symbol(numStrTuple, Decl(castingTuple.ts, 10, 3)) + var classCDTuple: [C, D] = [new C(), new D()]; ->classCDTuple : Symbol(classCDTuple, Decl(castingTuple.ts, 13, 3)) +>classCDTuple : Symbol(classCDTuple, Decl(castingTuple.ts, 15, 3)) >C : Symbol(C, Decl(castingTuple.ts, 1, 19)) >D : Symbol(D, Decl(castingTuple.ts, 2, 27)) >C : Symbol(C, Decl(castingTuple.ts, 1, 19)) >D : Symbol(D, Decl(castingTuple.ts, 2, 27)) var interfaceIITuple = <[I, I]>classCDTuple; ->interfaceIITuple : Symbol(interfaceIITuple, Decl(castingTuple.ts, 14, 3)) +>interfaceIITuple : Symbol(interfaceIITuple, Decl(castingTuple.ts, 16, 3)) >I : Symbol(I, Decl(castingTuple.ts, 0, 0)) >I : Symbol(I, Decl(castingTuple.ts, 0, 0)) ->classCDTuple : Symbol(classCDTuple, Decl(castingTuple.ts, 13, 3)) +>classCDTuple : Symbol(classCDTuple, Decl(castingTuple.ts, 15, 3)) var classCDATuple = <[C, D, A]>classCDTuple; ->classCDATuple : Symbol(classCDATuple, Decl(castingTuple.ts, 15, 3)) +>classCDATuple : Symbol(classCDATuple, Decl(castingTuple.ts, 17, 3)) >C : Symbol(C, Decl(castingTuple.ts, 1, 19)) >D : Symbol(D, Decl(castingTuple.ts, 2, 27)) >A : Symbol(A, Decl(castingTuple.ts, 0, 15)) ->classCDTuple : Symbol(classCDTuple, Decl(castingTuple.ts, 13, 3)) +>classCDTuple : Symbol(classCDTuple, Decl(castingTuple.ts, 15, 3)) var eleFromCDA1 = classCDATuple[2]; // A ->eleFromCDA1 : Symbol(eleFromCDA1, Decl(castingTuple.ts, 16, 3)) ->classCDATuple : Symbol(classCDATuple, Decl(castingTuple.ts, 15, 3)) +>eleFromCDA1 : Symbol(eleFromCDA1, Decl(castingTuple.ts, 18, 3)) +>classCDATuple : Symbol(classCDATuple, Decl(castingTuple.ts, 17, 3)) >2 : Symbol(2) var eleFromCDA2 = classCDATuple[5]; // C | D | A ->eleFromCDA2 : Symbol(eleFromCDA2, Decl(castingTuple.ts, 17, 3)) ->classCDATuple : Symbol(classCDATuple, Decl(castingTuple.ts, 15, 3)) +>eleFromCDA2 : Symbol(eleFromCDA2, Decl(castingTuple.ts, 19, 3)) +>classCDATuple : Symbol(classCDATuple, Decl(castingTuple.ts, 17, 3)) var t10: [E1, E2] = [E1.one, E2.one]; ->t10 : Symbol(t10, Decl(castingTuple.ts, 18, 3)) +>t10 : Symbol(t10, Decl(castingTuple.ts, 20, 3)) >E1 : Symbol(E1, Decl(castingTuple.ts, 5, 24)) >E2 : Symbol(E2, Decl(castingTuple.ts, 6, 15)) >E1.one : Symbol(E1.one, Decl(castingTuple.ts, 6, 9)) @@ -87,45 +95,45 @@ var t10: [E1, E2] = [E1.one, E2.one]; >one : Symbol(E2.one, Decl(castingTuple.ts, 7, 9)) var t11 = <[number, number]>t10; ->t11 : Symbol(t11, Decl(castingTuple.ts, 19, 3)) ->t10 : Symbol(t10, Decl(castingTuple.ts, 18, 3)) +>t11 : Symbol(t11, Decl(castingTuple.ts, 21, 3)) +>t10 : Symbol(t10, Decl(castingTuple.ts, 20, 3)) var array1 = <{}[]>emptyObjTuple; ->array1 : Symbol(array1, Decl(castingTuple.ts, 20, 3), Decl(castingTuple.ts, 29, 3)) +>array1 : Symbol(array1, Decl(castingTuple.ts, 22, 3), Decl(castingTuple.ts, 31, 3)) >emptyObjTuple : Symbol(emptyObjTuple, Decl(castingTuple.ts, 11, 3)) var unionTuple: [C, string | number] = [new C(), "foo"]; ->unionTuple : Symbol(unionTuple, Decl(castingTuple.ts, 21, 3)) +>unionTuple : Symbol(unionTuple, Decl(castingTuple.ts, 23, 3)) >C : Symbol(C, Decl(castingTuple.ts, 1, 19)) >C : Symbol(C, Decl(castingTuple.ts, 1, 19)) var unionTuple2: [C, string | number, D] = [new C(), "foo", new D()]; ->unionTuple2 : Symbol(unionTuple2, Decl(castingTuple.ts, 22, 3)) +>unionTuple2 : Symbol(unionTuple2, Decl(castingTuple.ts, 24, 3)) >C : Symbol(C, Decl(castingTuple.ts, 1, 19)) >D : Symbol(D, Decl(castingTuple.ts, 2, 27)) >C : Symbol(C, Decl(castingTuple.ts, 1, 19)) >D : Symbol(D, Decl(castingTuple.ts, 2, 27)) var unionTuple3: [number, string| number] = [10, "foo"]; ->unionTuple3 : Symbol(unionTuple3, Decl(castingTuple.ts, 23, 3)) +>unionTuple3 : Symbol(unionTuple3, Decl(castingTuple.ts, 25, 3)) var unionTuple4 = <[number, number]>unionTuple3; ->unionTuple4 : Symbol(unionTuple4, Decl(castingTuple.ts, 24, 3)) ->unionTuple3 : Symbol(unionTuple3, Decl(castingTuple.ts, 23, 3)) +>unionTuple4 : Symbol(unionTuple4, Decl(castingTuple.ts, 26, 3)) +>unionTuple3 : Symbol(unionTuple3, Decl(castingTuple.ts, 25, 3)) // error var t3 = <[number, number]>numStrTuple; ->t3 : Symbol(t3, Decl(castingTuple.ts, 27, 3)) +>t3 : Symbol(t3, Decl(castingTuple.ts, 29, 3)) >numStrTuple : Symbol(numStrTuple, Decl(castingTuple.ts, 10, 3)) var t9 = <[A, I]>classCDTuple; ->t9 : Symbol(t9, Decl(castingTuple.ts, 28, 3)) +>t9 : Symbol(t9, Decl(castingTuple.ts, 30, 3)) >A : Symbol(A, Decl(castingTuple.ts, 0, 15)) >I : Symbol(I, Decl(castingTuple.ts, 0, 0)) ->classCDTuple : Symbol(classCDTuple, Decl(castingTuple.ts, 13, 3)) +>classCDTuple : Symbol(classCDTuple, Decl(castingTuple.ts, 15, 3)) var array1 = numStrTuple; ->array1 : Symbol(array1, Decl(castingTuple.ts, 20, 3), Decl(castingTuple.ts, 29, 3)) +>array1 : Symbol(array1, Decl(castingTuple.ts, 22, 3), Decl(castingTuple.ts, 31, 3)) >numStrTuple : Symbol(numStrTuple, Decl(castingTuple.ts, 10, 3)) t4[2] = 10; diff --git a/tests/baselines/reference/castingTuple.types b/tests/baselines/reference/castingTuple.types index 23d2e51a576..0b9aa0a1487 100644 --- a/tests/baselines/reference/castingTuple.types +++ b/tests/baselines/reference/castingTuple.types @@ -52,6 +52,16 @@ var numStrBoolTuple = <[number, string, boolean]>numStrTuple; ><[number, string, boolean]>numStrTuple : [number, string, boolean] >numStrTuple : [number, string] +var shorter = numStrBoolTuple as [number, string] +>shorter : [number, string] +>numStrBoolTuple as [number, string] : [number, string] +>numStrBoolTuple : [number, string, boolean] + +var longer = numStrTuple as [number, string, boolean] +>longer : [number, string, boolean] +>numStrTuple as [number, string, boolean] : [number, string, boolean] +>numStrTuple : [number, string] + var classCDTuple: [C, D] = [new C(), new D()]; >classCDTuple : [C, D] >C : C diff --git a/tests/baselines/reference/contextualTypeWithTuple.errors.txt b/tests/baselines/reference/contextualTypeWithTuple.errors.txt index a488d8c7648..58a90919c5b 100644 --- a/tests/baselines/reference/contextualTypeWithTuple.errors.txt +++ b/tests/baselines/reference/contextualTypeWithTuple.errors.txt @@ -1,8 +1,6 @@ tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(3,5): error TS2322: Type '[number, string, boolean]' is not assignable to type '[number, string]'. - Types of property 'pop' are incompatible. - Type '() => string | number | boolean' is not assignable to type '() => string | number'. - Type 'string | number | boolean' is not assignable to type 'string | number'. - Type 'true' is not assignable to type 'string | number'. + Types of property 'length' are incompatible. + Type '3' is not assignable to type '2'. tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(15,1): error TS2322: Type '[number, string, boolean]' is not assignable to type '[number, string]'. tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(18,1): error TS2322: Type '[{}, number]' is not assignable to type '[{ a: string; }, number]'. Type '{}' is not assignable to type '{ a: string; }'. @@ -10,10 +8,11 @@ tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(18,1): error TS23 tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(19,1): error TS2322: Type '[number, string]' is not assignable to type '[number, string, boolean]'. Property '2' is missing in type '[number, string]'. tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(20,5): error TS2322: Type '[string, string, number]' is not assignable to type '[string, string]'. - Types of property 'pop' are incompatible. - Type '() => string | number' is not assignable to type '() => string'. - Type 'string | number' is not assignable to type 'string'. - Type 'number' is not assignable to type 'string'. + Types of property 'length' are incompatible. + Type '3' is not assignable to type '2'. +tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(23,1): error TS2322: Type '[C, string | number, D]' is not assignable to type '[C, string | number]'. + Types of property 'length' are incompatible. + Type '3' is not assignable to type '2'. tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(24,1): error TS2322: Type '[C, string | number]' is not assignable to type '[C, string | number, D]'. Property '2' is missing in type '[C, string | number]'. tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(25,1): error TS2322: Type '[number, string | number]' is not assignable to type '[number, string]'. @@ -21,16 +20,14 @@ tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(25,1): error TS23 Type 'number' is not assignable to type 'string'. -==== tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts (7 errors) ==== +==== tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts (8 errors) ==== // no error var numStrTuple: [number, string] = [5, "hello"]; var numStrTuple2: [number, string] = [5, "foo", true]; ~~~~~~~~~~~~ !!! error TS2322: Type '[number, string, boolean]' is not assignable to type '[number, string]'. -!!! error TS2322: Types of property 'pop' are incompatible. -!!! error TS2322: Type '() => string | number | boolean' is not assignable to type '() => string | number'. -!!! error TS2322: Type 'string | number | boolean' is not assignable to type 'string | number'. -!!! error TS2322: Type 'true' is not assignable to type 'string | number'. +!!! error TS2322: Types of property 'length' are incompatible. +!!! error TS2322: Type '3' is not assignable to type '2'. var numStrBoolTuple: [number, string, boolean] = [5, "foo", true]; var objNumTuple: [{ a: string }, number] = [{ a: "world" }, 5]; var strTupleTuple: [string, [number, {}]] = ["bar", [5, { x: 1, y: 1 }]]; @@ -59,13 +56,15 @@ tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(25,1): error TS23 var strStrTuple: [string, string] = ["foo", "bar", 5]; ~~~~~~~~~~~ !!! error TS2322: Type '[string, string, number]' is not assignable to type '[string, string]'. -!!! error TS2322: Types of property 'pop' are incompatible. -!!! error TS2322: Type '() => string | number' is not assignable to type '() => string'. -!!! error TS2322: Type 'string | number' is not assignable to type 'string'. -!!! error TS2322: Type 'number' is not assignable to type 'string'. +!!! error TS2322: Types of property 'length' are incompatible. +!!! error TS2322: Type '3' is not assignable to type '2'. unionTuple = unionTuple1; unionTuple = unionTuple2; + ~~~~~~~~~~ +!!! error TS2322: Type '[C, string | number, D]' is not assignable to type '[C, string | number]'. +!!! error TS2322: Types of property 'length' are incompatible. +!!! error TS2322: Type '3' is not assignable to type '2'. unionTuple2 = unionTuple; ~~~~~~~~~~~ !!! error TS2322: Type '[C, string | number]' is not assignable to type '[C, string | number, D]'. diff --git a/tests/baselines/reference/destructuringParameterDeclaration1ES5.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration1ES5.errors.txt index 8e51c2b6111..fbbfc3b0d21 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration1ES5.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration1ES5.errors.txt @@ -1,8 +1,14 @@ +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(12,4): error TS2345: Argument of type '[number, number, string[][], number]' is not assignable to parameter of type '[number, number, string[][]]'. + Types of property 'length' are incompatible. + Type '4' is not assignable to type '3'. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(57,4): error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. + Types of property 'length' are incompatible. + Type '5' is not assignable to type '3'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(62,10): error TS2393: Duplicate function implementation. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(63,10): error TS2393: Duplicate function implementation. -==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts (2 errors) ==== +==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts (4 errors) ==== // A parameter declaration may specify either an identifier or a binding pattern. // The identifiers specified in parameter declarations and binding patterns // in a parameter list must be unique within that parameter list. @@ -15,6 +21,10 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5. a1([1, 2, [["world"]]]); a1([1, 2, [["world"]], 3]); + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '[number, number, string[][], number]' is not assignable to parameter of type '[number, number, string[][]]'. +!!! error TS2345: Types of property 'length' are incompatible. +!!! error TS2345: Type '4' is not assignable to type '3'. // If the declaration includes an initializer expression (which is permitted only // when the parameter list occurs in conjunction with a function body), @@ -60,6 +70,10 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5. c5([1, 2, [["string"]]]); // Implied type is is [any, any, [[any]]] c5([1, 2, [["string"]], false, true]); // Implied type is is [any, any, [[any]]] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. +!!! error TS2345: Types of property 'length' are incompatible. +!!! error TS2345: Type '5' is not assignable to type '3'. // A parameter can be marked optional by following its name or binding pattern with a question mark (?) // or by including an initializer. diff --git a/tests/baselines/reference/destructuringParameterDeclaration1ES5.types b/tests/baselines/reference/destructuringParameterDeclaration1ES5.types index a4b7e882298..c7a5c44f1d4 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration1ES5.types +++ b/tests/baselines/reference/destructuringParameterDeclaration1ES5.types @@ -54,7 +54,7 @@ a1([1, 2, [["world"]]]); a1([1, 2, [["world"]], 3]); >a1([1, 2, [["world"]], 3]) : void >a1 : ([a, b, [[c]]]: [number, number, string[][]]) => void ->[1, 2, [["world"]], 3] : [number, number, string[][], number] +>[1, 2, [["world"]], 3] : (number | string[][])[] >1 : 1 >2 : 2 >[["world"]] : string[][] @@ -304,11 +304,11 @@ c5([1, 2, [["string"]]]); // Implied type is is [any, any, [[any]] c5([1, 2, [["string"]], false, true]); // Implied type is is [any, any, [[any]]] >c5([1, 2, [["string"]], false, true]) : void >c5 : ([a, b, [[c]]]: [any, any, [[any]]]) => void ->[1, 2, [["string"]], false, true] : [number, number, [[string]], boolean, boolean] +>[1, 2, [["string"]], false, true] : (number | boolean | string[][])[] >1 : 1 >2 : 2 ->[["string"]] : [[string]] ->["string"] : [string] +>[["string"]] : string[][] +>["string"] : string[] >"string" : "string" >false : false >true : true diff --git a/tests/baselines/reference/destructuringParameterDeclaration1ES5iterable.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration1ES5iterable.errors.txt index 101a37fc84a..1dc3c61bb3a 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration1ES5iterable.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration1ES5iterable.errors.txt @@ -1,8 +1,14 @@ +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5iterable.ts(12,4): error TS2345: Argument of type '[number, number, string[][], number]' is not assignable to parameter of type '[number, number, string[][]]'. + Types of property 'length' are incompatible. + Type '4' is not assignable to type '3'. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5iterable.ts(57,4): error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. + Types of property 'length' are incompatible. + Type '5' is not assignable to type '3'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5iterable.ts(62,10): error TS2393: Duplicate function implementation. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5iterable.ts(63,10): error TS2393: Duplicate function implementation. -==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5iterable.ts (2 errors) ==== +==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5iterable.ts (4 errors) ==== // A parameter declaration may specify either an identifier or a binding pattern. // The identifiers specified in parameter declarations and binding patterns // in a parameter list must be unique within that parameter list. @@ -15,6 +21,10 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5i a1([1, 2, [["world"]]]); a1([1, 2, [["world"]], 3]); + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '[number, number, string[][], number]' is not assignable to parameter of type '[number, number, string[][]]'. +!!! error TS2345: Types of property 'length' are incompatible. +!!! error TS2345: Type '4' is not assignable to type '3'. // If the declaration includes an initializer expression (which is permitted only // when the parameter list occurs in conjunction with a function body), @@ -60,6 +70,10 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5i c5([1, 2, [["string"]]]); // Implied type is is [any, any, [[any]]] c5([1, 2, [["string"]], false, true]); // Implied type is is [any, any, [[any]]] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. +!!! error TS2345: Types of property 'length' are incompatible. +!!! error TS2345: Type '5' is not assignable to type '3'. // A parameter can be marked optional by following its name or binding pattern with a question mark (?) // or by including an initializer. diff --git a/tests/baselines/reference/destructuringParameterDeclaration1ES5iterable.types b/tests/baselines/reference/destructuringParameterDeclaration1ES5iterable.types index 9d72faf55b6..b41a2027586 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration1ES5iterable.types +++ b/tests/baselines/reference/destructuringParameterDeclaration1ES5iterable.types @@ -54,7 +54,7 @@ a1([1, 2, [["world"]]]); a1([1, 2, [["world"]], 3]); >a1([1, 2, [["world"]], 3]) : void >a1 : ([a, b, [[c]]]: [number, number, string[][]]) => void ->[1, 2, [["world"]], 3] : [number, number, string[][], number] +>[1, 2, [["world"]], 3] : (number | string[][])[] >1 : 1 >2 : 2 >[["world"]] : string[][] @@ -304,11 +304,11 @@ c5([1, 2, [["string"]]]); // Implied type is is [any, any, [[any]] c5([1, 2, [["string"]], false, true]); // Implied type is is [any, any, [[any]]] >c5([1, 2, [["string"]], false, true]) : void >c5 : ([a, b, [[c]]]: [any, any, [[any]]]) => void ->[1, 2, [["string"]], false, true] : [number, number, [[string]], boolean, boolean] +>[1, 2, [["string"]], false, true] : (number | boolean | string[][])[] >1 : 1 >2 : 2 ->[["string"]] : [[string]] ->["string"] : [string] +>[["string"]] : string[][] +>["string"] : string[] >"string" : "string" >false : false >true : true diff --git a/tests/baselines/reference/destructuringParameterDeclaration1ES6.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration1ES6.errors.txt index e900b9be393..f6c17a5c0ea 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration1ES6.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration1ES6.errors.txt @@ -1,9 +1,15 @@ +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6.ts(14,4): error TS2345: Argument of type '[number, number, string[][], number]' is not assignable to parameter of type '[number, number, string[][]]'. + Types of property 'length' are incompatible. + Type '4' is not assignable to type '3'. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6.ts(58,4): error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. + Types of property 'length' are incompatible. + Type '5' is not assignable to type '3'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6.ts(96,18): error TS2300: Duplicate identifier 'number'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6.ts(96,26): error TS2300: Duplicate identifier 'number'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6.ts(96,34): error TS2300: Duplicate identifier 'number'. -==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6.ts (3 errors) ==== +==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6.ts (5 errors) ==== // Conformance for emitting ES6 // A parameter declaration may specify either an identifier or a binding pattern. @@ -18,6 +24,10 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6. a1([1, 2, [["world"]]]); a1([1, 2, [["world"]], 3]); + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '[number, number, string[][], number]' is not assignable to parameter of type '[number, number, string[][]]'. +!!! error TS2345: Types of property 'length' are incompatible. +!!! error TS2345: Type '4' is not assignable to type '3'. // If the declaration includes an initializer expression (which is permitted only @@ -62,6 +72,10 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6. c5([1, 2, [["string"]]]); // Implied type is is [any, any, [[any]]] c5([1, 2, [["string"]], false, true]); // Implied type is is [any, any, [[any]]] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. +!!! error TS2345: Types of property 'length' are incompatible. +!!! error TS2345: Type '5' is not assignable to type '3'. // A parameter can be marked optional by following its name or binding pattern with a question mark (?) diff --git a/tests/baselines/reference/destructuringParameterDeclaration1ES6.types b/tests/baselines/reference/destructuringParameterDeclaration1ES6.types index b997dcf6017..9de904efdec 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration1ES6.types +++ b/tests/baselines/reference/destructuringParameterDeclaration1ES6.types @@ -56,7 +56,7 @@ a1([1, 2, [["world"]]]); a1([1, 2, [["world"]], 3]); >a1([1, 2, [["world"]], 3]) : void >a1 : ([a, b, [[c]]]: [number, number, string[][]]) => void ->[1, 2, [["world"]], 3] : [number, number, string[][], number] +>[1, 2, [["world"]], 3] : (number | string[][])[] >1 : 1 >2 : 2 >[["world"]] : string[][] @@ -287,11 +287,11 @@ c5([1, 2, [["string"]]]); // Implied type is is [any, any, [[any]] c5([1, 2, [["string"]], false, true]); // Implied type is is [any, any, [[any]]] >c5([1, 2, [["string"]], false, true]) : void >c5 : ([a, b, [[c]]]: [any, any, [[any]]]) => void ->[1, 2, [["string"]], false, true] : [number, number, [[string]], boolean, boolean] +>[1, 2, [["string"]], false, true] : (number | boolean | string[][])[] >1 : 1 >2 : 2 ->[["string"]] : [[string]] ->["string"] : [string] +>[["string"]] : string[][] +>["string"] : string[] >"string" : "string" >false : false >true : true diff --git a/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt index 81c85f7c42b..96b93423660 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt @@ -2,10 +2,8 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts( Type 'string' is not assignable to type 'number'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(7,29): error TS1005: ',' expected. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(8,4): error TS2345: Argument of type '[number, number, string[][], string]' is not assignable to parameter of type '[number, number, string[][]]'. - Types of property 'pop' are incompatible. - Type '() => string | number | string[][]' is not assignable to type '() => number | string[][]'. - Type 'string | number | string[][]' is not assignable to type 'number | string[][]'. - Type 'string' is not assignable to type 'number | string[][]'. + Types of property 'length' are incompatible. + Type '4' is not assignable to type '3'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(16,8): error TS2371: A parameter initializer is only allowed in a function or constructor implementation. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(16,16): error TS2371: A parameter initializer is only allowed in a function or constructor implementation. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(23,14): error TS2345: Argument of type '{ x: string; y: boolean; }' is not assignable to parameter of type '{ x: number; y: any; }'. @@ -64,10 +62,8 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts( a0([1, 2, [["world"]], "string"]); // Error ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '[number, number, string[][], string]' is not assignable to parameter of type '[number, number, string[][]]'. -!!! error TS2345: Types of property 'pop' are incompatible. -!!! error TS2345: Type '() => string | number | string[][]' is not assignable to type '() => number | string[][]'. -!!! error TS2345: Type 'string | number | string[][]' is not assignable to type 'number | string[][]'. -!!! error TS2345: Type 'string' is not assignable to type 'number | string[][]'. +!!! error TS2345: Types of property 'length' are incompatible. +!!! error TS2345: Type '4' is not assignable to type '3'. // If the declaration includes an initializer expression (which is permitted only diff --git a/tests/baselines/reference/destructuringParameterDeclaration3ES5.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration3ES5.errors.txt new file mode 100644 index 00000000000..3b16993a047 --- /dev/null +++ b/tests/baselines/reference/destructuringParameterDeclaration3ES5.errors.txt @@ -0,0 +1,55 @@ +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5.ts(26,4): error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. + Types of property 'length' are incompatible. + Type '5' is not assignable to type '3'. + + +==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5.ts (1 errors) ==== + // If the parameter is a rest parameter, the parameter type is any[] + // A type annotation for a rest parameter must denote an array type. + + // RestParameter: + // ... Identifier TypeAnnotation(opt) + + type arrayString = Array + type someArray = Array | number[]; + type stringOrNumArray = Array; + + function a1(...x: (number|string)[]) { } + function a2(...a) { } + function a3(...a: Array) { } + function a4(...a: arrayString) { } + function a5(...a: stringOrNumArray) { } + function a9([a, b, [[c]]]) { } + function a10([a, b, [[c]], ...x]) { } + function a11([a, b, c, ...x]: number[]) { } + + + var array = [1, 2, 3]; + var array2 = [true, false, "hello"]; + a2([...array]); + a1(...array); + + a9([1, 2, [["string"]], false, true]); // Parameter type is [any, any, [[any]]] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. +!!! error TS2345: Types of property 'length' are incompatible. +!!! error TS2345: Type '5' is not assignable to type '3'. + + a10([1, 2, [["string"]], false, true]); // Parameter type is any[] + a10([1, 2, 3, false, true]); // Parameter type is any[] + a10([1, 2]); // Parameter type is any[] + a11([1, 2]); // Parameter type is number[] + + // Rest parameter with generic + function foo(...a: T[]) { } + foo("hello", 1, 2); + foo("hello", "world"); + + enum E { a, b } + const enum E1 { a, b } + function foo1(...a: T[]) { } + foo1(1, 2, 3, E.a); + foo1(1, 2, 3, E1.a, E.b); + + + \ No newline at end of file diff --git a/tests/baselines/reference/destructuringParameterDeclaration3ES5.types b/tests/baselines/reference/destructuringParameterDeclaration3ES5.types index a91d54d5284..33e0d3b6bd8 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration3ES5.types +++ b/tests/baselines/reference/destructuringParameterDeclaration3ES5.types @@ -96,11 +96,11 @@ a1(...array); a9([1, 2, [["string"]], false, true]); // Parameter type is [any, any, [[any]]] >a9([1, 2, [["string"]], false, true]) : void >a9 : ([a, b, [[c]]]: [any, any, [[any]]]) => void ->[1, 2, [["string"]], false, true] : [number, number, [[string]], boolean, boolean] +>[1, 2, [["string"]], false, true] : (number | boolean | string[][])[] >1 : 1 >2 : 2 ->[["string"]] : [[string]] ->["string"] : [string] +>[["string"]] : string[][] +>["string"] : string[] >"string" : "string" >false : false >true : true diff --git a/tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.errors.txt new file mode 100644 index 00000000000..f0dbf325ed4 --- /dev/null +++ b/tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.errors.txt @@ -0,0 +1,55 @@ +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5iterable.ts(26,4): error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. + Types of property 'length' are incompatible. + Type '5' is not assignable to type '3'. + + +==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5iterable.ts (1 errors) ==== + // If the parameter is a rest parameter, the parameter type is any[] + // A type annotation for a rest parameter must denote an array type. + + // RestParameter: + // ... Identifier TypeAnnotation(opt) + + type arrayString = Array + type someArray = Array | number[]; + type stringOrNumArray = Array; + + function a1(...x: (number|string)[]) { } + function a2(...a) { } + function a3(...a: Array) { } + function a4(...a: arrayString) { } + function a5(...a: stringOrNumArray) { } + function a9([a, b, [[c]]]) { } + function a10([a, b, [[c]], ...x]) { } + function a11([a, b, c, ...x]: number[]) { } + + + var array = [1, 2, 3]; + var array2 = [true, false, "hello"]; + a2([...array]); + a1(...array); + + a9([1, 2, [["string"]], false, true]); // Parameter type is [any, any, [[any]]] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. +!!! error TS2345: Types of property 'length' are incompatible. +!!! error TS2345: Type '5' is not assignable to type '3'. + + a10([1, 2, [["string"]], false, true]); // Parameter type is any[] + a10([1, 2, 3, false, true]); // Parameter type is any[] + a10([1, 2]); // Parameter type is any[] + a11([1, 2]); // Parameter type is number[] + + // Rest parameter with generic + function foo(...a: T[]) { } + foo("hello", 1, 2); + foo("hello", "world"); + + enum E { a, b } + const enum E1 { a, b } + function foo1(...a: T[]) { } + foo1(1, 2, 3, E.a); + foo1(1, 2, 3, E1.a, E.b); + + + \ No newline at end of file diff --git a/tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.types b/tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.types index 5f2963abe87..931e149ffe2 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.types +++ b/tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.types @@ -96,11 +96,11 @@ a1(...array); a9([1, 2, [["string"]], false, true]); // Parameter type is [any, any, [[any]]] >a9([1, 2, [["string"]], false, true]) : void >a9 : ([a, b, [[c]]]: [any, any, [[any]]]) => void ->[1, 2, [["string"]], false, true] : [number, number, [[string]], boolean, boolean] +>[1, 2, [["string"]], false, true] : (number | boolean | string[][])[] >1 : 1 >2 : 2 ->[["string"]] : [[string]] ->["string"] : [string] +>[["string"]] : string[][] +>["string"] : string[] >"string" : "string" >false : false >true : true diff --git a/tests/baselines/reference/destructuringParameterDeclaration3ES6.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration3ES6.errors.txt new file mode 100644 index 00000000000..67a5c1bf87f --- /dev/null +++ b/tests/baselines/reference/destructuringParameterDeclaration3ES6.errors.txt @@ -0,0 +1,55 @@ +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES6.ts(26,4): error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. + Types of property 'length' are incompatible. + Type '5' is not assignable to type '3'. + + +==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES6.ts (1 errors) ==== + // If the parameter is a rest parameter, the parameter type is any[] + // A type annotation for a rest parameter must denote an array type. + + // RestParameter: + // ... Identifier TypeAnnotation(opt) + + type arrayString = Array + type someArray = Array | number[]; + type stringOrNumArray = Array; + + function a1(...x: (number|string)[]) { } + function a2(...a) { } + function a3(...a: Array) { } + function a4(...a: arrayString) { } + function a5(...a: stringOrNumArray) { } + function a9([a, b, [[c]]]) { } + function a10([a, b, [[c]], ...x]) { } + function a11([a, b, c, ...x]: number[]) { } + + + var array = [1, 2, 3]; + var array2 = [true, false, "hello"]; + a2([...array]); + a1(...array); + + a9([1, 2, [["string"]], false, true]); // Parameter type is [any, any, [[any]]] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. +!!! error TS2345: Types of property 'length' are incompatible. +!!! error TS2345: Type '5' is not assignable to type '3'. + + a10([1, 2, [["string"]], false, true]); // Parameter type is any[] + a10([1, 2, 3, false, true]); // Parameter type is any[] + a10([1, 2]); // Parameter type is any[] + a11([1, 2]); // Parameter type is number[] + + // Rest parameter with generic + function foo(...a: T[]) { } + foo("hello", 1, 2); + foo("hello", "world"); + + enum E { a, b } + const enum E1 { a, b } + function foo1(...a: T[]) { } + foo1(1, 2, 3, E.a); + foo1(1, 2, 3, E1.a, E.b); + + + \ No newline at end of file diff --git a/tests/baselines/reference/destructuringParameterDeclaration3ES6.types b/tests/baselines/reference/destructuringParameterDeclaration3ES6.types index 397ec934a2f..dc5e64d2c2c 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration3ES6.types +++ b/tests/baselines/reference/destructuringParameterDeclaration3ES6.types @@ -96,11 +96,11 @@ a1(...array); a9([1, 2, [["string"]], false, true]); // Parameter type is [any, any, [[any]]] >a9([1, 2, [["string"]], false, true]) : void >a9 : ([a, b, [[c]]]: [any, any, [[any]]]) => void ->[1, 2, [["string"]], false, true] : [number, number, [[string]], boolean, boolean] +>[1, 2, [["string"]], false, true] : (number | boolean | string[][])[] >1 : 1 >2 : 2 ->[["string"]] : [[string]] ->["string"] : [string] +>[["string"]] : string[][] +>["string"] : string[] >"string" : "string" >false : false >true : true diff --git a/tests/baselines/reference/genericCallWithTupleType.errors.txt b/tests/baselines/reference/genericCallWithTupleType.errors.txt index 617c4f7159b..65920596c45 100644 --- a/tests/baselines/reference/genericCallWithTupleType.errors.txt +++ b/tests/baselines/reference/genericCallWithTupleType.errors.txt @@ -1,8 +1,6 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(12,1): error TS2322: Type '[string, number, boolean, boolean]' is not assignable to type '[string, number]'. - Types of property 'pop' are incompatible. - Type '() => string | number | boolean' is not assignable to type '() => string | number'. - Type 'string | number | boolean' is not assignable to type 'string | number'. - Type 'true' is not assignable to type 'string | number'. + Types of property 'length' are incompatible. + Type '4' is not assignable to type '2'. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(14,1): error TS2322: Type '{ a: string; }' is not assignable to type 'string | number'. Type '{ a: string; }' is not assignable to type 'number'. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(22,1): error TS2322: Type '[number, string]' is not assignable to type '[string, number]'. @@ -28,10 +26,8 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTup i1.tuple1 = ["foo", 5, false, true]; ~~~~~~~~~ !!! error TS2322: Type '[string, number, boolean, boolean]' is not assignable to type '[string, number]'. -!!! error TS2322: Types of property 'pop' are incompatible. -!!! error TS2322: Type '() => string | number | boolean' is not assignable to type '() => string | number'. -!!! error TS2322: Type 'string | number | boolean' is not assignable to type 'string | number'. -!!! error TS2322: Type 'true' is not assignable to type 'string | number'. +!!! error TS2322: Types of property 'length' are incompatible. +!!! error TS2322: Type '4' is not assignable to type '2'. var e3 = i1.tuple1[2]; // {} i1.tuple1[3] = { a: "string" }; ~~~~~~~~~~~~ diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index 9ae7b793ce2..302cefabf90 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -352,8 +352,8 @@ function f12(t: [Shape, boolean]) { >Shape : Shape let len = getProperty(t, "length"); ->len : number ->getProperty(t, "length") : number +>len : 2 +>getProperty(t, "length") : 2 >getProperty : (obj: T, key: K) => T[K] >t : [Shape, boolean] >"length" : "length" diff --git a/tests/baselines/reference/promiseEmptyTupleNoException.errors.txt b/tests/baselines/reference/promiseEmptyTupleNoException.errors.txt index 0237d658da5..73d768ddfeb 100644 --- a/tests/baselines/reference/promiseEmptyTupleNoException.errors.txt +++ b/tests/baselines/reference/promiseEmptyTupleNoException.errors.txt @@ -1,8 +1,7 @@ tests/cases/compiler/promiseEmptyTupleNoException.ts(1,38): error TS1122: A tuple type element list cannot be empty. tests/cases/compiler/promiseEmptyTupleNoException.ts(3,3): error TS2322: Type 'any[]' is not assignable to type '[]'. - Types of property 'pop' are incompatible. - Type '() => any' is not assignable to type '() => never'. - Type 'any' is not assignable to type 'never'. + Types of property 'length' are incompatible. + Type 'number' is not assignable to type '0'. ==== tests/cases/compiler/promiseEmptyTupleNoException.ts (2 errors) ==== @@ -13,8 +12,7 @@ tests/cases/compiler/promiseEmptyTupleNoException.ts(3,3): error TS2322: Type 'a return emails; ~~~~~~~~~~~~~~ !!! error TS2322: Type 'any[]' is not assignable to type '[]'. -!!! error TS2322: Types of property 'pop' are incompatible. -!!! error TS2322: Type '() => any' is not assignable to type '() => never'. -!!! error TS2322: Type 'any' is not assignable to type 'never'. +!!! error TS2322: Types of property 'length' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type '0'. } \ No newline at end of file diff --git a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json index 5ddfd890cc5..08887fc6c94 100644 --- a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json @@ -23,7 +23,6 @@ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictTuples": true, /* Enable strict tuple checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json index 854d7da20ae..ca2b4aa4087 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json @@ -23,7 +23,6 @@ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictTuples": true, /* Enable strict tuple checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json index 386e240f9b4..9437685c295 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json @@ -23,7 +23,6 @@ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictTuples": true, /* Enable strict tuple checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json index 235377d03e9..d2e7e85ad55 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json @@ -23,7 +23,6 @@ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictTuples": true, /* Enable strict tuple checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json index e64ea6fc432..3f4100033d0 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json @@ -23,7 +23,6 @@ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictTuples": true, /* Enable strict tuple checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json index 5ddfd890cc5..08887fc6c94 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json @@ -23,7 +23,6 @@ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictTuples": true, /* Enable strict tuple checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json index 112e47b09d4..22cb0444209 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json @@ -23,7 +23,6 @@ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictTuples": true, /* Enable strict tuple checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json index 1e942b5c9b8..fc3321600fe 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json @@ -23,7 +23,6 @@ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictTuples": true, /* Enable strict tuple checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tupleTypes.errors.txt b/tests/baselines/reference/tupleTypes.errors.txt index 3b55476e4b1..16a8f66ba79 100644 --- a/tests/baselines/reference/tupleTypes.errors.txt +++ b/tests/baselines/reference/tupleTypes.errors.txt @@ -5,6 +5,9 @@ tests/cases/compiler/tupleTypes.ts(15,1): error TS2322: Type '[number]' is not a Property '1' is missing in type '[number]'. tests/cases/compiler/tupleTypes.ts(17,1): error TS2322: Type '[string, number]' is not assignable to type '[number, string]'. Type 'string' is not assignable to type 'number'. +tests/cases/compiler/tupleTypes.ts(18,1): error TS2322: Type '[number, string, number]' is not assignable to type '[number, string]'. + Types of property 'length' are incompatible. + Type '3' is not assignable to type '2'. tests/cases/compiler/tupleTypes.ts(41,1): error TS2322: Type 'undefined[]' is not assignable to type '[number, string]'. tests/cases/compiler/tupleTypes.ts(47,1): error TS2322: Type '[number, string]' is not assignable to type 'number[]'. Types of property 'pop' are incompatible. @@ -22,7 +25,7 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n Type '{}' is not assignable to type 'string'. -==== tests/cases/compiler/tupleTypes.ts (9 errors) ==== +==== tests/cases/compiler/tupleTypes.ts (10 errors) ==== var v1: []; // Error ~~ !!! error TS1122: A tuple type element list cannot be empty. @@ -51,7 +54,11 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n ~ !!! error TS2322: Type '[string, number]' is not assignable to type '[number, string]'. !!! error TS2322: Type 'string' is not assignable to type 'number'. - t = [1, "hello", 2]; // Ok + t = [1, "hello", 2]; // Error + ~ +!!! error TS2322: Type '[number, string, number]' is not assignable to type '[number, string]'. +!!! error TS2322: Types of property 'length' are incompatible. +!!! error TS2322: Type '3' is not assignable to type '2'. var tf: [string, (x: string) => number] = ["hello", x => x.length]; diff --git a/tests/baselines/reference/tupleTypes.js b/tests/baselines/reference/tupleTypes.js index 451aeb5eb09..947b7bba30b 100644 --- a/tests/baselines/reference/tupleTypes.js +++ b/tests/baselines/reference/tupleTypes.js @@ -16,7 +16,7 @@ t = []; // Error t = [1]; // Error t = [1, "hello"]; // Ok t = ["hello", 1]; // Error -t = [1, "hello", 2]; // Ok +t = [1, "hello", 2]; // Error var tf: [string, (x: string) => number] = ["hello", x => x.length]; @@ -70,7 +70,7 @@ t = []; // Error t = [1]; // Error t = [1, "hello"]; // Ok t = ["hello", 1]; // Error -t = [1, "hello", 2]; // Ok +t = [1, "hello", 2]; // Error var tf = ["hello", function (x) { return x.length; }]; var ff1 = ff("hello", ["foo", function (x) { return x.length; }]); var ff1; diff --git a/tests/baselines/reference/tupleTypes.symbols b/tests/baselines/reference/tupleTypes.symbols index 1f14b269ca9..cf60cea8534 100644 --- a/tests/baselines/reference/tupleTypes.symbols +++ b/tests/baselines/reference/tupleTypes.symbols @@ -49,7 +49,7 @@ t = [1, "hello"]; // Ok t = ["hello", 1]; // Error >t : Symbol(t, Decl(tupleTypes.ts, 5, 3)) -t = [1, "hello", 2]; // Ok +t = [1, "hello", 2]; // Error >t : Symbol(t, Decl(tupleTypes.ts, 5, 3)) var tf: [string, (x: string) => number] = ["hello", x => x.length]; diff --git a/tests/baselines/reference/tupleTypes.types b/tests/baselines/reference/tupleTypes.types index 3bbf48bdb29..3f68d4c7e2d 100644 --- a/tests/baselines/reference/tupleTypes.types +++ b/tests/baselines/reference/tupleTypes.types @@ -66,7 +66,7 @@ t = ["hello", 1]; // Error >"hello" : "hello" >1 : 1 -t = [1, "hello", 2]; // Ok +t = [1, "hello", 2]; // Error >t = [1, "hello", 2] : [number, string, number] >t : [number, string] >[1, "hello", 2] : [number, string, number] diff --git a/tests/baselines/reference/unionTypeFromArrayLiteral.errors.txt b/tests/baselines/reference/unionTypeFromArrayLiteral.errors.txt new file mode 100644 index 00000000000..2ecce8a802e --- /dev/null +++ b/tests/baselines/reference/unionTypeFromArrayLiteral.errors.txt @@ -0,0 +1,33 @@ +tests/cases/conformance/types/union/unionTypeFromArrayLiteral.ts(9,5): error TS2322: Type '[number, string, string]' is not assignable to type '[number, string]'. + Types of property 'length' are incompatible. + Type '3' is not assignable to type '2'. + + +==== tests/cases/conformance/types/union/unionTypeFromArrayLiteral.ts (1 errors) ==== + // The resulting type an array literal expression is determined as follows: + // If the array literal is empty, the resulting type is an array type with the element type Undefined. + // Otherwise, if the array literal is contextually typed by a type that has a property with the numeric name ‘0’, the resulting type is a tuple type constructed from the types of the element expressions. + // Otherwise, the resulting type is an array type with an element type that is the union of the types of the element expressions. + + var arr1 = [1, 2]; // number[] + var arr2 = ["hello", true]; // (string | number)[] + var arr3Tuple: [number, string] = [3, "three"]; // [number, string] + var arr4Tuple: [number, string] = [3, "three", "hello"]; // [number, string, string] + ~~~~~~~~~ +!!! error TS2322: Type '[number, string, string]' is not assignable to type '[number, string]'. +!!! error TS2322: Types of property 'length' are incompatible. +!!! error TS2322: Type '3' is not assignable to type '2'. + var arrEmpty = []; + var arr5Tuple: { + 0: string; + 5: number; + } = ["hello", true, false, " hello", true, 10, "any"]; // Tuple + class C { foo() { } } + class D { foo2() { } } + class E extends C { foo3() { } } + class F extends C { foo4() { } } + var c: C, d: D, e: E, f: F; + var arr6 = [c, d]; // (C | D)[] + var arr7 = [c, d, e]; // (C | D)[] + var arr8 = [c, e]; // C[] + var arr9 = [e, f]; // (E|F)[] \ No newline at end of file diff --git a/tests/baselines/reference/wideningTuples3.errors.txt b/tests/baselines/reference/wideningTuples3.errors.txt index 43c7e349a0c..15e02cfb559 100644 --- a/tests/baselines/reference/wideningTuples3.errors.txt +++ b/tests/baselines/reference/wideningTuples3.errors.txt @@ -1,9 +1,16 @@ tests/cases/conformance/types/tuple/wideningTuples3.ts(3,5): error TS7005: Variable 'b' implicitly has an '[any, any]' type. +tests/cases/conformance/types/tuple/wideningTuples3.ts(3,9): error TS2322: Type '[undefined, null]' is not assignable to type '[any]'. + Types of property 'length' are incompatible. + Type '2' is not assignable to type '1'. -==== tests/cases/conformance/types/tuple/wideningTuples3.ts (1 errors) ==== +==== tests/cases/conformance/types/tuple/wideningTuples3.ts (2 errors) ==== var a: [any]; var b = a = [undefined, null]; ~ -!!! error TS7005: Variable 'b' implicitly has an '[any, any]' type. \ No newline at end of file +!!! error TS7005: Variable 'b' implicitly has an '[any, any]' type. + ~ +!!! error TS2322: Type '[undefined, null]' is not assignable to type '[any]'. +!!! error TS2322: Types of property 'length' are incompatible. +!!! error TS2322: Type '2' is not assignable to type '1'. \ No newline at end of file diff --git a/tests/baselines/reference/wideningTuples4.errors.txt b/tests/baselines/reference/wideningTuples4.errors.txt new file mode 100644 index 00000000000..e38035e7041 --- /dev/null +++ b/tests/baselines/reference/wideningTuples4.errors.txt @@ -0,0 +1,14 @@ +tests/cases/conformance/types/tuple/wideningTuples4.ts(3,9): error TS2322: Type '[undefined, null]' is not assignable to type '[any]'. + Types of property 'length' are incompatible. + Type '2' is not assignable to type '1'. + + +==== tests/cases/conformance/types/tuple/wideningTuples4.ts (1 errors) ==== + var a: [any]; + + var b = a = [undefined, null]; + ~ +!!! error TS2322: Type '[undefined, null]' is not assignable to type '[any]'. +!!! error TS2322: Types of property 'length' are incompatible. +!!! error TS2322: Type '2' is not assignable to type '1'. + b = ["", ""]; \ No newline at end of file diff --git a/tests/cases/compiler/tupleTypes.ts b/tests/cases/compiler/tupleTypes.ts index 80181f8b332..53e5b584b7a 100644 --- a/tests/cases/compiler/tupleTypes.ts +++ b/tests/cases/compiler/tupleTypes.ts @@ -15,7 +15,7 @@ t = []; // Error t = [1]; // Error t = [1, "hello"]; // Ok t = ["hello", 1]; // Error -t = [1, "hello", 2]; // Ok +t = [1, "hello", 2]; // Error var tf: [string, (x: string) => number] = ["hello", x => x.length]; diff --git a/tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts b/tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts index 0f486d843ea..85a035d472b 100644 --- a/tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts +++ b/tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts @@ -1,6 +1,7 @@ interface StrNum extends Array { 0: string; 1: number; + length: 2; } var x: [string, number]; @@ -8,6 +9,7 @@ var y: StrNum var z: { 0: string; 1: number; + length: 2; } var [a, b, c] = x; diff --git a/tests/cases/conformance/types/tuple/castingTuple.ts b/tests/cases/conformance/types/tuple/castingTuple.ts index cf5c58af346..2ffc22ff34c 100644 --- a/tests/cases/conformance/types/tuple/castingTuple.ts +++ b/tests/cases/conformance/types/tuple/castingTuple.ts @@ -11,6 +11,8 @@ enum E2 { one } var numStrTuple: [number, string] = [5, "foo"]; var emptyObjTuple = <[{}, {}]>numStrTuple; var numStrBoolTuple = <[number, string, boolean]>numStrTuple; +var shorter = numStrBoolTuple as [number, string] +var longer = numStrTuple as [number, string, boolean] var classCDTuple: [C, D] = [new C(), new D()]; var interfaceIITuple = <[I, I]>classCDTuple; var classCDATuple = <[C, D, A]>classCDTuple; diff --git a/tests/cases/conformance/types/tuple/strictTupleLength.ts b/tests/cases/conformance/types/tuple/strictTupleLength.ts index bfae662cd7c..eaa9111e557 100644 --- a/tests/cases/conformance/types/tuple/strictTupleLength.ts +++ b/tests/cases/conformance/types/tuple/strictTupleLength.ts @@ -1,5 +1,3 @@ -// @strictTuples: true - var t0: []; var t1: [number]; var t2: [number, number]; From 21093503a8f0fab321c85e9f830219c2bfc4d451 Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Fri, 3 Nov 2017 11:19:53 -0700 Subject: [PATCH 103/235] Respond to CR --- src/services/jsDoc.ts | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 109330c177c..bb2cfb03e47 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -208,13 +208,9 @@ namespace ts.JsDoc { return undefined; } - if (commentOwner.getStart() < position) { - // if climbing the tree found a declaration with parameters but the request was made inside it, complete to a single line comment - return singleLineTemplate; - } - - if (parameters.length === 0) { - // if there are no parameters, complete to a single line comment + if (commentOwner.getStart() < position || parameters.length === 0) { + // if climbing the tree found a declaration with parameters but the request was made inside it + // or if there are no parameters, complete to a single line comment return singleLineTemplate; } @@ -225,19 +221,11 @@ namespace ts.JsDoc { const indentationStr = sourceFile.text.substr(lineStart, posLineAndChar.character).replace(/\S/i, () => " "); const isJavaScriptFile = hasJavaScriptFileExtension(sourceFile.fileName); - let docParams = ""; - for (let i = 0; i < parameters.length; i++) { - const currentName = parameters[i].name; - const paramName = currentName.kind === SyntaxKind.Identifier ? - (currentName).escapedText : - "param" + i; - if (isJavaScriptFile) { - docParams += `${indentationStr} * @param {any} ${paramName}${newLine}`; - } - else { - docParams += `${indentationStr} * @param ${paramName}${newLine}`; - } - } + const docParams = parameters.map(({name}, i) => { + const nameText = isIdentifier(name) ? name.text : `param${i}`; + const type = isJavaScriptFile ? "{any} " : ""; + return `${indentationStr} * @param ${type}${nameText}${newLine}`; + }).join(""); // A doc comment consists of the following // * The opening comment line From 668ac108902fc6f7fd3d55b0fd50aed70f64d998 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 3 Nov 2017 11:51:16 -0700 Subject: [PATCH 104/235] Test where script info path and program path differ because of current directory --- .../unittests/tsserverProjectSystem.ts | 148 ++++++++++++------ src/harness/virtualFileSystemWithWatch.ts | 20 ++- 2 files changed, 121 insertions(+), 47 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index be38176fb15..5df045335cb 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -437,6 +437,50 @@ namespace ts.projectSystem { verifyDiagnostics(actual, []); } + function assertEvent(actualOutput: string, expectedEvent: protocol.Event, host: TestServerHost) { + assert.equal(actualOutput, server.formatMessage(expectedEvent, nullLogger, Utils.byteLength, host.newLine)); + } + + function checkErrorMessage(host: TestServerHost, eventName: "syntaxDiag" | "semanticDiag", diagnostics: protocol.DiagnosticEventBody) { + const outputs = host.getOutput(); + assert.isTrue(outputs.length >= 1, outputs.toString()); + const event: protocol.Event = { + seq: 0, + type: "event", + event: eventName, + body: diagnostics + }; + assertEvent(outputs[0], event, host); + } + + function checkCompleteEvent(host: TestServerHost, numberOfCurrentEvents: number, expectedSequenceId: number) { + const outputs = host.getOutput(); + assert.equal(outputs.length, numberOfCurrentEvents, outputs.toString()); + const event: protocol.RequestCompletedEvent = { + seq: 0, + type: "event", + event: "requestCompleted", + body: { + request_seq: expectedSequenceId + } + }; + assertEvent(outputs[numberOfCurrentEvents - 1], event, host); + } + + function checkProjectUpdatedInBackgroundEvent(host: TestServerHost, openFiles: string[]) { + const outputs = host.getOutput(); + assert.equal(outputs.length, 1, outputs.toString()); + const event: protocol.ProjectsUpdatedInBackgroundEvent = { + seq: 0, + type: "event", + event: "projectsUpdatedInBackground", + body: { + openFiles + } + }; + assertEvent(outputs[0], event, host); + } + describe("tsserverProjectSystem", () => { const commonFile1: FileOrFolder = { path: "/a/b/commonFile1.ts", @@ -2744,6 +2788,66 @@ namespace ts.projectSystem { const project = projectService.findProject(corruptedConfig.path); checkProjectRootFiles(project, [file1.path]); }); + + it("when opening new file that doesnt exist on disk yet", () => { + const host = createServerHost([libFile]); + let hasError = false; + const errLogger: server.Logger = { + close: noop, + hasLevel: () => true, + loggingEnabled: () => true, + perftrc: noop, + info: noop, + msg: (_s, type) => { + if (type === server.Msg.Err) { + hasError = true; + } + }, + startGroup: noop, + endGroup: noop, + getLogFileName: (): string => undefined + }; + const session = createSession(host, { canUseEvents: true, logger: errLogger, useInferredProjectPerProjectRoot: true }); + + const folderPath = "/user/someuser/projects/someFolder"; + const projectService = session.getProjectService(); + const untitledFile = "untitled:Untitled-1"; + session.executeCommandSeq({ + command: server.CommandNames.Open, + arguments: { + file: untitledFile, + fileContent: "", + scriptKindName: "JS", + projectRootPath: folderPath + } + }); + checkNumberOfProjects(projectService, { inferredProjects: 1 }); + host.checkTimeoutQueueLength(2); + + const newTimeoutId = host.getNextTimeoutId(); + const expectedSequenceId = session.getNextSeq(); + session.executeCommandSeq({ + command: server.CommandNames.Geterr, + arguments: { + delay: 0, + files: [untitledFile] + } + }); + host.checkTimeoutQueueLength(3); + + // Run the last one = get error request + host.runQueuedTimeoutCallbacks(newTimeoutId); + host.checkTimeoutQueueLength(2); + + checkErrorMessage(host, "syntaxDiag", { file: untitledFile, diagnostics: [] }); + host.clearOutput(); + + host.runQueuedImmediateCallbacks(); + assert.isFalse(hasError); + checkErrorMessage(host, "semanticDiag", { file: untitledFile, diagnostics: [] }); + + checkCompleteEvent(host, 2, expectedSequenceId); + }); }); describe("autoDiscovery", () => { @@ -3446,50 +3550,6 @@ namespace ts.projectSystem { verifyNoDiagnostics(diags); }); - function assertEvent(actualOutput: string, expectedEvent: protocol.Event, host: TestServerHost) { - assert.equal(actualOutput, server.formatMessage(expectedEvent, nullLogger, Utils.byteLength, host.newLine)); - } - - function checkErrorMessage(host: TestServerHost, eventName: "syntaxDiag" | "semanticDiag", diagnostics: protocol.DiagnosticEventBody) { - const outputs = host.getOutput(); - assert.isTrue(outputs.length >= 1, outputs.toString()); - const event: protocol.Event = { - seq: 0, - type: "event", - event: eventName, - body: diagnostics - }; - assertEvent(outputs[0], event, host); - } - - function checkCompleteEvent(host: TestServerHost, numberOfCurrentEvents: number, expectedSequenceId: number) { - const outputs = host.getOutput(); - assert.equal(outputs.length, numberOfCurrentEvents, outputs.toString()); - const event: protocol.RequestCompletedEvent = { - seq: 0, - type: "event", - event: "requestCompleted", - body: { - request_seq: expectedSequenceId - } - }; - assertEvent(outputs[numberOfCurrentEvents - 1], event, host); - } - - function checkProjectUpdatedInBackgroundEvent(host: TestServerHost, openFiles: string[]) { - const outputs = host.getOutput(); - assert.equal(outputs.length, 1, outputs.toString()); - const event: protocol.ProjectsUpdatedInBackgroundEvent = { - seq: 0, - type: "event", - event: "projectsUpdatedInBackground", - body: { - openFiles - } - }; - assertEvent(outputs[0], event, host); - } - it("npm install @types works", () => { const folderPath = "/a/b/projects/temp"; const file1: FileOrFolder = { diff --git a/src/harness/virtualFileSystemWithWatch.ts b/src/harness/virtualFileSystemWithWatch.ts index fe40cb42844..6c3bd8a635a 100644 --- a/src/harness/virtualFileSystemWithWatch.ts +++ b/src/harness/virtualFileSystemWithWatch.ts @@ -182,6 +182,10 @@ interface Array {}` private map: TimeOutCallback[] = []; private nextId = 1; + getNextId() { + return this.nextId; + } + register(cb: (...args: any[]) => void, args: any[]) { const timeoutId = this.nextId; this.nextId++; @@ -203,7 +207,13 @@ interface Array {}` return n; } - invoke() { + invoke(invokeKey?: number) { + if (invokeKey) { + this.map[invokeKey](); + delete this.map[invokeKey]; + return; + } + // Note: invoking a callback may result in new callbacks been queued, // so do not clear the entire callback list regardless. Only remove the // ones we have invoked. @@ -553,6 +563,10 @@ interface Array {}` return this.timeoutCallbacks.register(callback, args); } + getNextTimeoutId() { + return this.timeoutCallbacks.getNextId(); + } + clearTimeout(timeoutId: any): void { this.timeoutCallbacks.unregister(timeoutId); } @@ -567,9 +581,9 @@ interface Array {}` assert.equal(callbacksCount, expected, `expected ${expected} timeout callbacks queued but found ${callbacksCount}.`); } - runQueuedTimeoutCallbacks() { + runQueuedTimeoutCallbacks(timeoutId?: number) { try { - this.timeoutCallbacks.invoke(); + this.timeoutCallbacks.invoke(timeoutId); } catch (e) { if (e.message === this.existMessage) { From 9fb06c60a8aa236eb9fdb916e251d9439b21076c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 3 Nov 2017 14:32:34 -0700 Subject: [PATCH 105/235] Call on never type is not an untyped function call --- src/compiler/checker.ts | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index af8bd6f7c98..eaf1b885544 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16631,21 +16631,9 @@ namespace ts { * but is a subtype of the Function interface, the call is an untyped function call. */ function isUntypedFunctionCall(funcType: Type, apparentFuncType: Type, numCallSignatures: number, numConstructSignatures: number) { - if (isTypeAny(funcType)) { - return true; - } - if (isTypeAny(apparentFuncType) && funcType.flags & TypeFlags.TypeParameter) { - return true; - } - if (!numCallSignatures && !numConstructSignatures) { - // We exclude union types because we may have a union of function types that happen to have - // no common signatures. - if (funcType.flags & TypeFlags.Union) { - return false; - } - return isTypeAssignableTo(funcType, globalFunctionType); - } - return false; + // We exclude union types because we may have a union of function types that happen to have no common signatures. + return isTypeAny(funcType) || isTypeAny(apparentFuncType) && funcType.flags & TypeFlags.TypeParameter || + !numCallSignatures && !numConstructSignatures && !(funcType.flags & (TypeFlags.Union | TypeFlags.Never)) && isTypeAssignableTo(funcType, globalFunctionType); } function resolveNewExpression(node: NewExpression, candidatesOutArray: Signature[]): Signature { From f701b1300f16b3e16b89ba98e815711431fb168c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 3 Nov 2017 14:40:06 -0700 Subject: [PATCH 106/235] Add tests --- tests/cases/conformance/types/never/neverTypeErrors1.ts | 1 + tests/cases/conformance/types/never/neverTypeErrors2.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/cases/conformance/types/never/neverTypeErrors1.ts b/tests/cases/conformance/types/never/neverTypeErrors1.ts index 8d78e863098..deab74c6690 100644 --- a/tests/cases/conformance/types/never/neverTypeErrors1.ts +++ b/tests/cases/conformance/types/never/neverTypeErrors1.ts @@ -6,6 +6,7 @@ function f1() { x = undefined; x = null; x = {}; + x(); } function f2(): never { diff --git a/tests/cases/conformance/types/never/neverTypeErrors2.ts b/tests/cases/conformance/types/never/neverTypeErrors2.ts index 635d1c9c6ad..2c637580d00 100644 --- a/tests/cases/conformance/types/never/neverTypeErrors2.ts +++ b/tests/cases/conformance/types/never/neverTypeErrors2.ts @@ -8,6 +8,7 @@ function f1() { x = undefined; x = null; x = {}; + x(); } function f2(): never { From fc40a3fdcf7857f55ee1916d38da8e04917142d4 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 3 Nov 2017 14:40:12 -0700 Subject: [PATCH 107/235] Accept new baselines --- .../baselines/reference/neverTypeErrors1.errors.txt | 12 ++++++++---- tests/baselines/reference/neverTypeErrors1.js | 2 ++ tests/baselines/reference/neverTypeErrors1.symbols | 9 ++++++--- tests/baselines/reference/neverTypeErrors1.types | 4 ++++ .../baselines/reference/neverTypeErrors2.errors.txt | 12 ++++++++---- tests/baselines/reference/neverTypeErrors2.js | 2 ++ tests/baselines/reference/neverTypeErrors2.symbols | 9 ++++++--- tests/baselines/reference/neverTypeErrors2.types | 4 ++++ 8 files changed, 40 insertions(+), 14 deletions(-) diff --git a/tests/baselines/reference/neverTypeErrors1.errors.txt b/tests/baselines/reference/neverTypeErrors1.errors.txt index a27c6fba065..56233fb6101 100644 --- a/tests/baselines/reference/neverTypeErrors1.errors.txt +++ b/tests/baselines/reference/neverTypeErrors1.errors.txt @@ -4,12 +4,13 @@ tests/cases/conformance/types/never/neverTypeErrors1.ts(5,5): error TS2322: Type tests/cases/conformance/types/never/neverTypeErrors1.ts(6,5): error TS2322: Type 'undefined' is not assignable to type 'never'. tests/cases/conformance/types/never/neverTypeErrors1.ts(7,5): error TS2322: Type 'null' is not assignable to type 'never'. tests/cases/conformance/types/never/neverTypeErrors1.ts(8,5): error TS2322: Type '{}' is not assignable to type 'never'. -tests/cases/conformance/types/never/neverTypeErrors1.ts(12,5): error TS2322: Type 'undefined' is not assignable to type 'never'. -tests/cases/conformance/types/never/neverTypeErrors1.ts(16,5): error TS2322: Type '1' is not assignable to type 'never'. -tests/cases/conformance/types/never/neverTypeErrors1.ts(19,16): error TS2534: A function returning 'never' cannot have a reachable end point. +tests/cases/conformance/types/never/neverTypeErrors1.ts(9,5): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'never' has no compatible call signatures. +tests/cases/conformance/types/never/neverTypeErrors1.ts(13,5): error TS2322: Type 'undefined' is not assignable to type 'never'. +tests/cases/conformance/types/never/neverTypeErrors1.ts(17,5): error TS2322: Type '1' is not assignable to type 'never'. +tests/cases/conformance/types/never/neverTypeErrors1.ts(20,16): error TS2534: A function returning 'never' cannot have a reachable end point. -==== tests/cases/conformance/types/never/neverTypeErrors1.ts (9 errors) ==== +==== tests/cases/conformance/types/never/neverTypeErrors1.ts (10 errors) ==== function f1() { let x: never; x = 1; @@ -30,6 +31,9 @@ tests/cases/conformance/types/never/neverTypeErrors1.ts(19,16): error TS2534: A x = {}; ~ !!! error TS2322: Type '{}' is not assignable to type 'never'. + x(); + ~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'never' has no compatible call signatures. } function f2(): never { diff --git a/tests/baselines/reference/neverTypeErrors1.js b/tests/baselines/reference/neverTypeErrors1.js index 81b3f8f9cdb..4bbe131cd05 100644 --- a/tests/baselines/reference/neverTypeErrors1.js +++ b/tests/baselines/reference/neverTypeErrors1.js @@ -7,6 +7,7 @@ function f1() { x = undefined; x = null; x = {}; + x(); } function f2(): never { @@ -29,6 +30,7 @@ function f1() { x = undefined; x = null; x = {}; + x(); } function f2() { return; diff --git a/tests/baselines/reference/neverTypeErrors1.symbols b/tests/baselines/reference/neverTypeErrors1.symbols index c9525226aab..eee8e493144 100644 --- a/tests/baselines/reference/neverTypeErrors1.symbols +++ b/tests/baselines/reference/neverTypeErrors1.symbols @@ -23,20 +23,23 @@ function f1() { x = {}; >x : Symbol(x, Decl(neverTypeErrors1.ts, 1, 7)) + + x(); +>x : Symbol(x, Decl(neverTypeErrors1.ts, 1, 7)) } function f2(): never { ->f2 : Symbol(f2, Decl(neverTypeErrors1.ts, 8, 1)) +>f2 : Symbol(f2, Decl(neverTypeErrors1.ts, 9, 1)) return; } function f3(): never { ->f3 : Symbol(f3, Decl(neverTypeErrors1.ts, 12, 1)) +>f3 : Symbol(f3, Decl(neverTypeErrors1.ts, 13, 1)) return 1; } function f4(): never { ->f4 : Symbol(f4, Decl(neverTypeErrors1.ts, 16, 1)) +>f4 : Symbol(f4, Decl(neverTypeErrors1.ts, 17, 1)) } diff --git a/tests/baselines/reference/neverTypeErrors1.types b/tests/baselines/reference/neverTypeErrors1.types index 150459b32b3..fe21a8c5ba2 100644 --- a/tests/baselines/reference/neverTypeErrors1.types +++ b/tests/baselines/reference/neverTypeErrors1.types @@ -34,6 +34,10 @@ function f1() { >x = {} : {} >x : never >{} : {} + + x(); +>x() : any +>x : never } function f2(): never { diff --git a/tests/baselines/reference/neverTypeErrors2.errors.txt b/tests/baselines/reference/neverTypeErrors2.errors.txt index 5f9bb26344f..eb24ac8251c 100644 --- a/tests/baselines/reference/neverTypeErrors2.errors.txt +++ b/tests/baselines/reference/neverTypeErrors2.errors.txt @@ -4,12 +4,13 @@ tests/cases/conformance/types/never/neverTypeErrors2.ts(5,5): error TS2322: Type tests/cases/conformance/types/never/neverTypeErrors2.ts(6,5): error TS2322: Type 'undefined' is not assignable to type 'never'. tests/cases/conformance/types/never/neverTypeErrors2.ts(7,5): error TS2322: Type 'null' is not assignable to type 'never'. tests/cases/conformance/types/never/neverTypeErrors2.ts(8,5): error TS2322: Type '{}' is not assignable to type 'never'. -tests/cases/conformance/types/never/neverTypeErrors2.ts(12,5): error TS2322: Type 'undefined' is not assignable to type 'never'. -tests/cases/conformance/types/never/neverTypeErrors2.ts(16,5): error TS2322: Type '1' is not assignable to type 'never'. -tests/cases/conformance/types/never/neverTypeErrors2.ts(19,16): error TS2534: A function returning 'never' cannot have a reachable end point. +tests/cases/conformance/types/never/neverTypeErrors2.ts(9,5): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'never' has no compatible call signatures. +tests/cases/conformance/types/never/neverTypeErrors2.ts(13,5): error TS2322: Type 'undefined' is not assignable to type 'never'. +tests/cases/conformance/types/never/neverTypeErrors2.ts(17,5): error TS2322: Type '1' is not assignable to type 'never'. +tests/cases/conformance/types/never/neverTypeErrors2.ts(20,16): error TS2534: A function returning 'never' cannot have a reachable end point. -==== tests/cases/conformance/types/never/neverTypeErrors2.ts (9 errors) ==== +==== tests/cases/conformance/types/never/neverTypeErrors2.ts (10 errors) ==== function f1() { let x: never; x = 1; @@ -30,6 +31,9 @@ tests/cases/conformance/types/never/neverTypeErrors2.ts(19,16): error TS2534: A x = {}; ~ !!! error TS2322: Type '{}' is not assignable to type 'never'. + x(); + ~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'never' has no compatible call signatures. } function f2(): never { diff --git a/tests/baselines/reference/neverTypeErrors2.js b/tests/baselines/reference/neverTypeErrors2.js index 70bdb4673ca..940c4df5556 100644 --- a/tests/baselines/reference/neverTypeErrors2.js +++ b/tests/baselines/reference/neverTypeErrors2.js @@ -7,6 +7,7 @@ function f1() { x = undefined; x = null; x = {}; + x(); } function f2(): never { @@ -29,6 +30,7 @@ function f1() { x = undefined; x = null; x = {}; + x(); } function f2() { return; diff --git a/tests/baselines/reference/neverTypeErrors2.symbols b/tests/baselines/reference/neverTypeErrors2.symbols index 683751fe663..17433391576 100644 --- a/tests/baselines/reference/neverTypeErrors2.symbols +++ b/tests/baselines/reference/neverTypeErrors2.symbols @@ -23,20 +23,23 @@ function f1() { x = {}; >x : Symbol(x, Decl(neverTypeErrors2.ts, 1, 7)) + + x(); +>x : Symbol(x, Decl(neverTypeErrors2.ts, 1, 7)) } function f2(): never { ->f2 : Symbol(f2, Decl(neverTypeErrors2.ts, 8, 1)) +>f2 : Symbol(f2, Decl(neverTypeErrors2.ts, 9, 1)) return; } function f3(): never { ->f3 : Symbol(f3, Decl(neverTypeErrors2.ts, 12, 1)) +>f3 : Symbol(f3, Decl(neverTypeErrors2.ts, 13, 1)) return 1; } function f4(): never { ->f4 : Symbol(f4, Decl(neverTypeErrors2.ts, 16, 1)) +>f4 : Symbol(f4, Decl(neverTypeErrors2.ts, 17, 1)) } diff --git a/tests/baselines/reference/neverTypeErrors2.types b/tests/baselines/reference/neverTypeErrors2.types index 071f1779a43..9e45bf1aeba 100644 --- a/tests/baselines/reference/neverTypeErrors2.types +++ b/tests/baselines/reference/neverTypeErrors2.types @@ -34,6 +34,10 @@ function f1() { >x = {} : {} >x : never >{} : {} + + x(); +>x() : any +>x : never } function f2(): never { From 749e151c2393fada05edc93d1c35f12f0388744a Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 3 Nov 2017 15:05:44 -0700 Subject: [PATCH 108/235] Support path completions inside node_modules (#19692) * Support path completions inside node_modules * Fix: Start searching from current file's directory, not host.getCurrentDirectory() * Add test for nested node_modules * Also test in /src/folder/b.ts --- src/services/pathCompletions.ts | 11 ++++++++++- tests/cases/fourslash/completionsPaths.ts | 21 +++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/completionsPaths.ts diff --git a/src/services/pathCompletions.ts b/src/services/pathCompletions.ts index 780b14db719..190e980c936 100644 --- a/src/services/pathCompletions.ts +++ b/src/services/pathCompletions.ts @@ -144,8 +144,8 @@ namespace ts.Completions.PathCompletions { let result: CompletionEntry[]; + const fileExtensions = getSupportedExtensions(compilerOptions); if (baseUrl) { - const fileExtensions = getSupportedExtensions(compilerOptions); const projectDir = compilerOptions.project || host.getCurrentDirectory(); const absolute = isRootedDiskPath(baseUrl) ? baseUrl : combinePaths(projectDir, baseUrl); result = getCompletionEntriesForDirectoryFragment(fragment, normalizePath(absolute), fileExtensions, /*includeExtensions*/ false, span, host); @@ -176,6 +176,15 @@ namespace ts.Completions.PathCompletions { result = []; } + if (compilerOptions.moduleResolution === ts.ModuleResolutionKind.NodeJs) { + forEachAncestorDirectory(scriptPath, ancestor => { + const nodeModules = combinePaths(ancestor, "node_modules"); + if (host.directoryExists(nodeModules)) { + getCompletionEntriesForDirectoryFragment(fragment, nodeModules, fileExtensions, /*includeExtensions*/ false, span, host, /*exclude*/ undefined, result); + } + }); + } + getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span, result); for (const moduleName of enumeratePotentialNonRelativeModules(fragment, scriptPath, compilerOptions, typeChecker, host)) { diff --git a/tests/cases/fourslash/completionsPaths.ts b/tests/cases/fourslash/completionsPaths.ts new file mode 100644 index 00000000000..9473ae54b25 --- /dev/null +++ b/tests/cases/fourslash/completionsPaths.ts @@ -0,0 +1,21 @@ +/// + +// @moduleResolution: node + +// @Filename: /node_modules/x/foo.d.ts +////not read + +// @Filename: /node_modules/x/bar.d.ts +////not read + +// @Filename: /src/node_modules/y/index.d.ts +////not read + +// @Filename: /src/a.ts +////import {} from "/*1*/"; + +// @Filename: /src/folder/b.ts +////import {} from "x//*2*/"; + +verify.completionsAt("1", ["y", "x"]); +verify.completionsAt("2", ["bar", "foo"]); From 1d7f449a871cd497016340cbe9cfb93ea62f3534 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 3 Nov 2017 15:06:22 -0700 Subject: [PATCH 109/235] Minor cleanups in pathCompletions.ts (#19685) * Minor cleanups in pathCompletions.ts * Update name --- src/compiler/program.ts | 16 ++--- src/compiler/utilities.ts | 2 +- src/services/completions.ts | 18 ++++- src/services/pathCompletions.ts | 116 ++++++++++---------------------- 4 files changed, 57 insertions(+), 95 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index e00e803b489..49f9cb98835 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -7,18 +7,10 @@ namespace ts { const ignoreDiagnosticCommentRegEx = /(^\s*$)|(^\s*\/\/\/?\s*(@ts-ignore)?)/; export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string { - while (true) { - const fileName = combinePaths(searchPath, configName); - if (fileExists(fileName)) { - return fileName; - } - const parentPath = getDirectoryPath(searchPath); - if (parentPath === searchPath) { - break; - } - searchPath = parentPath; - } - return undefined; + return forEachAncestorDirectory(searchPath, ancestor => { + const fileName = combinePaths(ancestor, configName); + return fileExists(fileName) ? fileName : undefined; + }); } export function resolveTripleslashReference(moduleName: string, containingFile: string): string { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index e15b81db8e1..10b93ad59cf 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3592,7 +3592,7 @@ namespace ts { } /** Calls `callback` on `directory` and every ancestor directory it has, returning the first defined result. */ - export function forEachAncestorDirectory(directory: string, callback: (directory: string) => T): T { + export function forEachAncestorDirectory(directory: string, callback: (directory: string) => T | undefined): T | undefined { while (true) { const result = callback(directory); if (result !== undefined) { diff --git a/src/services/completions.ts b/src/services/completions.ts index f4feb8a1c10..6462788d5ae 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -30,7 +30,8 @@ namespace ts.Completions { allSourceFiles: ReadonlyArray, ): CompletionInfo | undefined { if (isInReferenceComment(sourceFile, position)) { - return PathCompletions.getTripleSlashReferenceCompletion(sourceFile, position, compilerOptions, host); + const entries = PathCompletions.getTripleSlashReferenceCompletion(sourceFile, position, compilerOptions, host); + return entries && pathCompletionsInfo(entries); } if (isInString(sourceFile, position)) { @@ -250,7 +251,8 @@ namespace ts.Completions { // import x = require("/*completion position*/"); // var y = require("/*completion position*/"); // export * from "/*completion position*/"; - return PathCompletions.getStringLiteralCompletionEntriesFromModuleNames(node, compilerOptions, host, typeChecker); + const entries = PathCompletions.getStringLiteralCompletionsFromModuleNames(node, compilerOptions, host, typeChecker); + return pathCompletionsInfo(entries); } else if (isEqualityExpression(node.parent)) { // Get completions from the type of the other operand @@ -279,6 +281,18 @@ namespace ts.Completions { } } + function pathCompletionsInfo(entries: CompletionEntry[]): CompletionInfo { + return { + // We don't want the editor to offer any other completions, such as snippets, inside a comment. + isGlobalCompletion: false, + isMemberCompletion: false, + // The user may type in a path that doesn't yet exist, creating a "new identifier" + // with respect to the collection of identifiers the server is aware of. + isNewIdentifierLocation: true, + entries, + }; + } + function getStringLiteralCompletionEntriesFromPropertyAssignment(element: ObjectLiteralElement, typeChecker: TypeChecker, target: ScriptTarget, log: Log): CompletionInfo | undefined { const type = typeChecker.getContextualType((element.parent)); const entries: CompletionEntry[] = []; diff --git a/src/services/pathCompletions.ts b/src/services/pathCompletions.ts index 190e980c936..921c4a14d93 100644 --- a/src/services/pathCompletions.ts +++ b/src/services/pathCompletions.ts @@ -1,34 +1,27 @@ /* @internal */ namespace ts.Completions.PathCompletions { - export function getStringLiteralCompletionEntriesFromModuleNames(node: StringLiteral, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker): CompletionInfo { + export function getStringLiteralCompletionsFromModuleNames(node: StringLiteral, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker): CompletionEntry[] { const literalValue = normalizeSlashes(node.text); const scriptPath = node.getSourceFile().path; const scriptDirectory = getDirectoryPath(scriptPath); const span = getDirectoryFragmentTextSpan((node).text, node.getStart() + 1); - let entries: CompletionEntry[]; if (isPathRelativeToScript(literalValue) || isRootedDiskPath(literalValue)) { const extensions = getSupportedExtensions(compilerOptions); if (compilerOptions.rootDirs) { - entries = getCompletionEntriesForDirectoryFragmentWithRootDirs( + return getCompletionEntriesForDirectoryFragmentWithRootDirs( compilerOptions.rootDirs, literalValue, scriptDirectory, extensions, /*includeExtensions*/ false, span, compilerOptions, host, scriptPath); } else { - entries = getCompletionEntriesForDirectoryFragment( + return getCompletionEntriesForDirectoryFragment( literalValue, scriptDirectory, extensions, /*includeExtensions*/ false, span, host, scriptPath); } } else { // Check for node modules - entries = getCompletionEntriesForNonRelativeModules(literalValue, scriptDirectory, span, compilerOptions, host, typeChecker); + return getCompletionEntriesForNonRelativeModules(literalValue, scriptDirectory, span, compilerOptions, host, typeChecker); } - return { - isGlobalCompletion: false, - isMemberCompletion: false, - isNewIdentifierLocation: true, - entries - }; } /** @@ -37,14 +30,14 @@ namespace ts.Completions.PathCompletions { */ function getBaseDirectoriesFromRootDirs(rootDirs: string[], basePath: string, scriptPath: string, ignoreCase: boolean): string[] { // Make all paths absolute/normalized if they are not already - rootDirs = map(rootDirs, rootDirectory => normalizePath(isRootedDiskPath(rootDirectory) ? rootDirectory : combinePaths(basePath, rootDirectory))); + rootDirs = rootDirs.map(rootDirectory => normalizePath(isRootedDiskPath(rootDirectory) ? rootDirectory : combinePaths(basePath, rootDirectory))); // Determine the path to the directory containing the script relative to the root directory it is contained within - const relativeDirectory = forEach(rootDirs, rootDirectory => + const relativeDirectory = firstDefined(rootDirs, rootDirectory => containsPath(rootDirectory, scriptPath, basePath, ignoreCase) ? scriptPath.substr(rootDirectory.length) : undefined); // Now find a path for each potential directory that is to be merged with the one containing the script - return deduplicate(map(rootDirs, rootDirectory => combinePaths(rootDirectory, relativeDirectory))); + return deduplicate(rootDirs.map(rootDirectory => combinePaths(rootDirectory, relativeDirectory))); } function getCompletionEntriesForDirectoryFragmentWithRootDirs(rootDirs: string[], fragment: string, scriptPath: string, extensions: ReadonlyArray, includeExtensions: boolean, span: TextSpan, compilerOptions: CompilerOptions, host: LanguageServiceHost, exclude?: string): CompletionEntry[] { @@ -283,61 +276,35 @@ namespace ts.Completions.PathCompletions { return deduplicate(nonRelativeModuleNames); } - export function getTripleSlashReferenceCompletion(sourceFile: SourceFile, position: number, compilerOptions: CompilerOptions, host: LanguageServiceHost): CompletionInfo { + export function getTripleSlashReferenceCompletion(sourceFile: SourceFile, position: number, compilerOptions: CompilerOptions, host: LanguageServiceHost): CompletionEntry[] | undefined { const token = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false); - if (!token) { - return undefined; - } - const commentRanges: CommentRange[] = getLeadingCommentRanges(sourceFile.text, token.pos); - - if (!commentRanges || !commentRanges.length) { - return undefined; - } - - const range = forEach(commentRanges, commentRange => position >= commentRange.pos && position <= commentRange.end && commentRange); - + const commentRanges = getLeadingCommentRanges(sourceFile.text, token.pos); + const range = commentRanges && find(commentRanges, commentRange => position >= commentRange.pos && position <= commentRange.end); if (!range) { return undefined; } - - const completionInfo: CompletionInfo = { - /** - * We don't want the editor to offer any other completions, such as snippets, inside a comment. - */ - isGlobalCompletion: false, - isMemberCompletion: false, - /** - * The user may type in a path that doesn't yet exist, creating a "new identifier" - * with respect to the collection of identifiers the server is aware of. - */ - isNewIdentifierLocation: true, - - entries: [] - }; - - const text = sourceFile.text.substr(range.pos, position - range.pos); - + const text = sourceFile.text.slice(range.pos, position); const match = tripleSlashDirectiveFragmentRegex.exec(text); - - if (match) { - const prefix = match[1]; - const kind = match[2]; - const toComplete = match[3]; - - const scriptPath = getDirectoryPath(sourceFile.path); - if (kind === "path") { - // Give completions for a relative path - const span: TextSpan = getDirectoryFragmentTextSpan(toComplete, range.pos + prefix.length); - completionInfo.entries = getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(compilerOptions), /*includeExtensions*/ true, span, host, sourceFile.path); - } - else { - // Give completions based on the typings available - const span: TextSpan = { start: range.pos + prefix.length, length: match[0].length - prefix.length }; - completionInfo.entries = getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span); - } + if (!match) { + return undefined; } - return completionInfo; + const [, prefix, kind, toComplete] = match; + const scriptPath = getDirectoryPath(sourceFile.path); + switch (kind) { + case "path": { + // Give completions for a relative path + const span = getDirectoryFragmentTextSpan(toComplete, range.pos + prefix.length); + return getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(compilerOptions), /*includeExtensions*/ true, span, host, sourceFile.path); + } + case "types": { + // Give completions based on the typings available + const span = createTextSpan(range.pos + prefix.length, match[0].length - prefix.length); + return getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span); + } + default: + return undefined; + } } function getCompletionEntriesFromTypings(host: LanguageServiceHost, options: CompilerOptions, scriptPath: string, span: TextSpan, result: CompletionEntry[] = []): CompletionEntry[] { @@ -385,26 +352,15 @@ namespace ts.Completions.PathCompletions { } } - function findPackageJsons(currentDir: string, host: LanguageServiceHost): string[] { + function findPackageJsons(directory: string, host: LanguageServiceHost): string[] { const paths: string[] = []; - let currentConfigPath: string; - while (true) { - currentConfigPath = findConfigFile(currentDir, (f) => tryFileExists(host, f), "package.json"); - if (currentConfigPath) { - paths.push(currentConfigPath); - - currentDir = getDirectoryPath(currentConfigPath); - const parent = getDirectoryPath(currentDir); - if (currentDir === parent) { - break; - } - currentDir = parent; + forEachAncestorDirectory(directory, ancestor => { + const currentConfigPath = findConfigFile(ancestor, (f) => tryFileExists(host, f), "package.json"); + if (!currentConfigPath) { + return true; // break out } - else { - break; - } - } - + paths.push(currentConfigPath); + }); return paths; } From ae87cd2fa9e166c862f557159dbbe2113f424d0b Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 3 Nov 2017 15:08:19 -0700 Subject: [PATCH 110/235] Enable 'no-implicit-dependencies' lint rule (#19716) --- package.json | 2 ++ tslint.json | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index e76d480937c..e329db05d85 100644 --- a/package.json +++ b/package.json @@ -74,10 +74,12 @@ "q": "latest", "run-sequence": "latest", "sorcery": "latest", + "source-map-support": "latest", "through2": "latest", "travis-fold": "latest", "ts-node": "latest", "tslint": "latest", + "vinyl": "latest", "colors": "latest", "typescript": "next" }, diff --git a/tslint.json b/tslint.json index a990d08a2bb..873b08eaf31 100644 --- a/tslint.json +++ b/tslint.json @@ -72,6 +72,9 @@ "check-type" ], + // Config different from tslint:latest + "no-implicit-dependencies": [true, "dev"], + // TODO "arrow-parens": false, // [true, "ban-single-arg-parens"] "arrow-return-shorthand": false, @@ -85,7 +88,6 @@ "no-empty": false, "no-empty-interface": false, "no-eval": false, - "no-implicit-dependencies": false, "no-invalid-template-strings": false, "no-object-literal-type-assertion": false, "no-shadowed-variable": false, From cd9dbe694f5511cfe3b1c0b93a7d42d89450b14a Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 3 Nov 2017 15:08:50 -0700 Subject: [PATCH 111/235] Enable 'only-arrow-functions' lint rule (#19717) --- Gulpfile.ts | 56 +++++++----------- src/compiler/sys.ts | 4 +- src/harness/harnessLanguageService.ts | 6 +- src/harness/loggedIO.ts | 1 + .../unittests/services/colorization.ts | 58 +++++++++---------- .../unittests/services/patternMatcher.ts | 6 +- .../unittests/services/preProcessFile.ts | 30 +++++----- src/server/server.ts | 4 +- tslint.json | 1 - 9 files changed, 77 insertions(+), 89 deletions(-) diff --git a/Gulpfile.ts b/Gulpfile.ts index 58aa9b9329f..5b35b9f672f 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -123,15 +123,13 @@ const es2015LibrarySources = [ "es2015.symbol.wellknown.d.ts" ]; -const es2015LibrarySourceMap = es2015LibrarySources.map(function(source) { - return { target: "lib." + source, sources: ["header.d.ts", source] }; -}); +const es2015LibrarySourceMap = es2015LibrarySources.map(source => + ({ target: "lib." + source, sources: ["header.d.ts", source] })); const es2016LibrarySource = ["es2016.array.include.d.ts"]; -const es2016LibrarySourceMap = es2016LibrarySource.map(function(source) { - return { target: "lib." + source, sources: ["header.d.ts", source] }; -}); +const es2016LibrarySourceMap = es2016LibrarySource.map(source => + ({ target: "lib." + source, sources: ["header.d.ts", source] })); const es2017LibrarySource = [ "es2017.object.d.ts", @@ -140,17 +138,15 @@ const es2017LibrarySource = [ "es2017.intl.d.ts", ]; -const es2017LibrarySourceMap = es2017LibrarySource.map(function(source) { - return { target: "lib." + source, sources: ["header.d.ts", source] }; -}); +const es2017LibrarySourceMap = es2017LibrarySource.map(source => + ({ target: "lib." + source, sources: ["header.d.ts", source] })); const esnextLibrarySource = [ "esnext.asynciterable.d.ts" ]; -const esnextLibrarySourceMap = esnextLibrarySource.map(function (source) { - return { target: "lib." + source, sources: ["header.d.ts", source] }; -}); +const esnextLibrarySourceMap = esnextLibrarySource.map(source => + ({ target: "lib." + source, sources: ["header.d.ts", source] })); const hostsLibrarySources = ["dom.generated.d.ts", "webworker.importscripts.d.ts", "scripthost.d.ts"]; @@ -176,9 +172,8 @@ const librarySourceMap = [ { target: "lib.esnext.full.d.ts", sources: ["header.d.ts", "esnext.d.ts"].concat(hostsLibrarySources, "dom.iterable.d.ts") }, ].concat(es2015LibrarySourceMap, es2016LibrarySourceMap, es2017LibrarySourceMap, esnextLibrarySourceMap); -const libraryTargets = librarySourceMap.map(function(f) { - return path.join(builtLocalDirectory, f.target); -}); +const libraryTargets = librarySourceMap.map(f => + path.join(builtLocalDirectory, f.target)); /** * .lcg file is what localization team uses to know what messages to localize. @@ -193,22 +188,19 @@ const generatedLCGFile = path.join(builtLocalDirectory, "enu", "diagnosticMessag * 2. 'src\compiler\diagnosticMessages.generated.json' => 'built\local\ENU\diagnosticMessages.generated.json.lcg' * generate the lcg file (source of messages to localize) from the diagnosticMessages.generated.json */ -const localizationTargets = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"].map(function (f) { - return path.join(builtLocalDirectory, f, "diagnosticMessages.generated.json"); -}).concat(generatedLCGFile); +const localizationTargets = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"] + .map(f => path.join(builtLocalDirectory, f, "diagnosticMessages.generated.json")) + .concat(generatedLCGFile); for (const i in libraryTargets) { const entry = librarySourceMap[i]; const target = libraryTargets[i]; - const sources = [copyright].concat(entry.sources.map(function(s) { - return path.join(libraryDirectory, s); - })); - gulp.task(target, /*help*/ false, [], function() { - return gulp.src(sources) + const sources = [copyright].concat(entry.sources.map(s => path.join(libraryDirectory, s))); + gulp.task(target, /*help*/ false, [], () => + gulp.src(sources) .pipe(newer(target)) .pipe(concat(target, { newLine: "\n\n" })) - .pipe(gulp.dest(".")); - }); + .pipe(gulp.dest("."))); } const configureNightlyJs = path.join(scriptsDirectory, "configureNightly.js"); @@ -575,9 +567,7 @@ gulp.task(specMd, /*help*/ false, [word2mdJs], (done) => { const specMDFullPath = path.resolve(specMd); const cmd = "cscript //nologo " + word2mdJs + " \"" + specWordFullPath + "\" " + "\"" + specMDFullPath + "\""; console.log(cmd); - cp.exec(cmd, function() { - done(); - }); + cp.exec(cmd, done); }); gulp.task("generate-spec", "Generates a Markdown version of the Language Specification", [specMd]); @@ -714,17 +704,13 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done: } args.push(run); setNodeEnvToDevelopment(); - exec(mocha, args, lintThenFinish, function(e, status) { - finish(e, status); - }); + exec(mocha, args, lintThenFinish, finish); } else { // run task to load all tests and partition them between workers setNodeEnvToDevelopment(); - exec(host, [run], lintThenFinish, function(e, status) { - finish(e, status); - }); + exec(host, [run], lintThenFinish, finish); } }); @@ -1082,7 +1068,7 @@ function sendNextFile(files: {path: string}[], child: cp.ChildProcess, callback: function spawnLintWorker(files: {path: string}[], callback: (failures: number) => void) { const child = cp.fork("./scripts/parallel-lint"); let failures = 0; - child.on("message", function(data) { + child.on("message", data => { switch (data.kind) { case "result": if (data.failures > 0) { diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 1169af191b8..2400266f9c7 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -124,7 +124,7 @@ namespace ts { getEnvironmentVariable?(name: string): string; }; - export let sys: System = (function() { + export let sys: System = (() => { function getNodeSystem(): System { const _fs = require("fs"); const _path = require("path"); @@ -594,7 +594,7 @@ namespace ts { if (sys) { // patch writefile to create folder before writing the file const originalWriteFile = sys.writeFile; - sys.writeFile = function(path, data, writeBom) { + sys.writeFile = (path, data, writeBom) => { const directoryPath = getDirectoryPath(normalizeSlashes(path)); if (directoryPath && !sys.directoryExists(directoryPath)) { recursiveCreateDirectory(directoryPath, sys); diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index d1b3c197471..97445900d34 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -757,6 +757,7 @@ namespace Harness.LanguageService { create(info: ts.server.PluginCreateInfo) { const proxy = makeDefaultProxy(info); const langSvc: any = info.languageService; + // tslint:disable-next-line only-arrow-functions proxy.getQuickInfoAtPosition = function () { const parts = langSvc.getQuickInfoAtPosition.apply(langSvc, arguments); if (parts.displayParts.length > 0) { @@ -789,7 +790,7 @@ namespace Harness.LanguageService { module: () => ({ create(info: ts.server.PluginCreateInfo) { const proxy = makeDefaultProxy(info); - proxy.getSemanticDiagnostics = function (filename: string) { + proxy.getSemanticDiagnostics = filename => { const prev = info.languageService.getSemanticDiagnostics(filename); const sourceFile: ts.SourceFile = info.languageService.getSourceFile(filename); prev.push({ @@ -815,11 +816,12 @@ namespace Harness.LanguageService { }; } - function makeDefaultProxy(info: ts.server.PluginCreateInfo) { + function makeDefaultProxy(info: ts.server.PluginCreateInfo): ts.LanguageService { // tslint:disable-next-line:no-null-keyword const proxy = Object.create(/*prototype*/ null); const langSvc: any = info.languageService; for (const k of Object.keys(langSvc)) { + // tslint:disable-next-line only-arrow-functions proxy[k] = function () { return langSvc[k].apply(langSvc, arguments); }; diff --git a/src/harness/loggedIO.ts b/src/harness/loggedIO.ts index 29e9dba7fc5..2be09abcf91 100644 --- a/src/harness/loggedIO.ts +++ b/src/harness/loggedIO.ts @@ -366,6 +366,7 @@ namespace Playback { function recordReplay(original: T, underlying: any) { function createWrapper(record: T, replay: T): T { + // tslint:disable-next-line only-arrow-functions return (function () { if (replayLog !== undefined) { return replay.apply(undefined, arguments); diff --git a/src/harness/unittests/services/colorization.ts b/src/harness/unittests/services/colorization.ts index eb2606bb08e..6dbc7732a00 100644 --- a/src/harness/unittests/services/colorization.ts +++ b/src/harness/unittests/services/colorization.ts @@ -6,7 +6,7 @@ interface ClassificationEntry { position?: number; } -describe("Colorization", function () { +describe("Colorization", () => { // Use the shim adapter to ensure test coverage of the shim layer for the classifier const languageServiceAdapter = new Harness.LanguageService.ShimLanguageServiceAdapter(/*preprocessToResolve*/ false); const classifier = languageServiceAdapter.getClassifier(); @@ -55,8 +55,8 @@ describe("Colorization", function () { } } - describe("test getClassifications", function () { - it("Returns correct token classes", function () { + describe("test getClassifications", () => { + it("Returns correct token classes", () => { testLexicalClassification("var x: string = \"foo\"; //Hello", ts.EndOfLineState.None, keyword("var"), @@ -70,7 +70,7 @@ describe("Colorization", function () { punctuation(";")); }); - it("correctly classifies a comment after a divide operator", function () { + it("correctly classifies a comment after a divide operator", () => { testLexicalClassification("1 / 2 // comment", ts.EndOfLineState.None, numberLiteral("1"), @@ -80,7 +80,7 @@ describe("Colorization", function () { comment("// comment")); }); - it("correctly classifies a literal after a divide operator", function () { + it("correctly classifies a literal after a divide operator", () => { testLexicalClassification("1 / 2, 3 / 4", ts.EndOfLineState.None, numberLiteral("1"), @@ -92,131 +92,131 @@ describe("Colorization", function () { operator(",")); }); - it("correctly classifies a multi-line string with one backslash", function () { + it("correctly classifies a multi-line string with one backslash", () => { testLexicalClassification("'line1\\", ts.EndOfLineState.None, stringLiteral("'line1\\"), finalEndOfLineState(ts.EndOfLineState.InSingleQuoteStringLiteral)); }); - it("correctly classifies a multi-line string with three backslashes", function () { + it("correctly classifies a multi-line string with three backslashes", () => { testLexicalClassification("'line1\\\\\\", ts.EndOfLineState.None, stringLiteral("'line1\\\\\\"), finalEndOfLineState(ts.EndOfLineState.InSingleQuoteStringLiteral)); }); - it("correctly classifies an unterminated single-line string with no backslashes", function () { + it("correctly classifies an unterminated single-line string with no backslashes", () => { testLexicalClassification("'line1", ts.EndOfLineState.None, stringLiteral("'line1"), finalEndOfLineState(ts.EndOfLineState.None)); }); - it("correctly classifies an unterminated single-line string with two backslashes", function () { + it("correctly classifies an unterminated single-line string with two backslashes", () => { testLexicalClassification("'line1\\\\", ts.EndOfLineState.None, stringLiteral("'line1\\\\"), finalEndOfLineState(ts.EndOfLineState.None)); }); - it("correctly classifies an unterminated single-line string with four backslashes", function () { + it("correctly classifies an unterminated single-line string with four backslashes", () => { testLexicalClassification("'line1\\\\\\\\", ts.EndOfLineState.None, stringLiteral("'line1\\\\\\\\"), finalEndOfLineState(ts.EndOfLineState.None)); }); - it("correctly classifies the continuing line of a multi-line string ending in one backslash", function () { + it("correctly classifies the continuing line of a multi-line string ending in one backslash", () => { testLexicalClassification("\\", ts.EndOfLineState.InDoubleQuoteStringLiteral, stringLiteral("\\"), finalEndOfLineState(ts.EndOfLineState.InDoubleQuoteStringLiteral)); }); - it("correctly classifies the continuing line of a multi-line string ending in three backslashes", function () { + it("correctly classifies the continuing line of a multi-line string ending in three backslashes", () => { testLexicalClassification("\\", ts.EndOfLineState.InDoubleQuoteStringLiteral, stringLiteral("\\"), finalEndOfLineState(ts.EndOfLineState.InDoubleQuoteStringLiteral)); }); - it("correctly classifies the last line of an unterminated multi-line string ending in no backslashes", function () { + it("correctly classifies the last line of an unterminated multi-line string ending in no backslashes", () => { testLexicalClassification(" ", ts.EndOfLineState.InDoubleQuoteStringLiteral, stringLiteral(" "), finalEndOfLineState(ts.EndOfLineState.None)); }); - it("correctly classifies the last line of an unterminated multi-line string ending in two backslashes", function () { + it("correctly classifies the last line of an unterminated multi-line string ending in two backslashes", () => { testLexicalClassification("\\\\", ts.EndOfLineState.InDoubleQuoteStringLiteral, stringLiteral("\\\\"), finalEndOfLineState(ts.EndOfLineState.None)); }); - it("correctly classifies the last line of an unterminated multi-line string ending in four backslashes", function () { + it("correctly classifies the last line of an unterminated multi-line string ending in four backslashes", () => { testLexicalClassification("\\\\\\\\", ts.EndOfLineState.InDoubleQuoteStringLiteral, stringLiteral("\\\\\\\\"), finalEndOfLineState(ts.EndOfLineState.None)); }); - it("correctly classifies the last line of a multi-line string", function () { + it("correctly classifies the last line of a multi-line string", () => { testLexicalClassification("'", ts.EndOfLineState.InSingleQuoteStringLiteral, stringLiteral("'"), finalEndOfLineState(ts.EndOfLineState.None)); }); - it("correctly classifies an unterminated multiline comment", function () { + it("correctly classifies an unterminated multiline comment", () => { testLexicalClassification("/*", ts.EndOfLineState.None, comment("/*"), finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia)); }); - it("correctly classifies the termination of a multiline comment", function () { + it("correctly classifies the termination of a multiline comment", () => { testLexicalClassification(" */ ", ts.EndOfLineState.InMultiLineCommentTrivia, comment(" */"), finalEndOfLineState(ts.EndOfLineState.None)); }); - it("correctly classifies the continuation of a multiline comment", function () { + it("correctly classifies the continuation of a multiline comment", () => { testLexicalClassification("LOREM IPSUM DOLOR ", ts.EndOfLineState.InMultiLineCommentTrivia, comment("LOREM IPSUM DOLOR "), finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia)); }); - it("correctly classifies an unterminated multiline comment on a line ending in '/*/'", function () { + it("correctly classifies an unterminated multiline comment on a line ending in '/*/'", () => { testLexicalClassification(" /*/", ts.EndOfLineState.None, comment("/*/"), finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia)); }); - it("correctly classifies an unterminated multiline comment with trailing space", function () { + it("correctly classifies an unterminated multiline comment with trailing space", () => { testLexicalClassification("/* ", ts.EndOfLineState.None, comment("/* "), finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia)); }); - it("correctly classifies a keyword after a dot", function () { + it("correctly classifies a keyword after a dot", () => { testLexicalClassification("a.var", ts.EndOfLineState.None, identifier("var")); }); - it("correctly classifies a string literal after a dot", function () { + it("correctly classifies a string literal after a dot", () => { testLexicalClassification("a.\"var\"", ts.EndOfLineState.None, stringLiteral("\"var\"")); }); - it("correctly classifies a keyword after a dot separated by comment trivia", function () { + it("correctly classifies a keyword after a dot separated by comment trivia", () => { testLexicalClassification("a./*hello world*/ var", ts.EndOfLineState.None, identifier("a"), @@ -225,21 +225,21 @@ describe("Colorization", function () { identifier("var")); }); - it("classifies a property access with whitespace around the dot", function () { + it("classifies a property access with whitespace around the dot", () => { testLexicalClassification(" x .\tfoo ()", ts.EndOfLineState.None, identifier("x"), identifier("foo")); }); - it("classifies a keyword after a dot on previous line", function () { + it("classifies a keyword after a dot on previous line", () => { testLexicalClassification("var", ts.EndOfLineState.None, keyword("var"), finalEndOfLineState(ts.EndOfLineState.None)); }); - it("classifies multiple keywords properly", function () { + it("classifies multiple keywords properly", () => { testLexicalClassification("public static", ts.EndOfLineState.None, keyword("public"), @@ -353,7 +353,7 @@ describe("Colorization", function () { } }); - it("classifies partially written generics correctly.", function () { + it("classifies partially written generics correctly.", () => { testLexicalClassification("Foo { testLexicalClassification("for (var of of of) { }", ts.EndOfLineState.None, keyword("for"), diff --git a/src/harness/unittests/services/patternMatcher.ts b/src/harness/unittests/services/patternMatcher.ts index 728636e9af2..fef382e8a3b 100644 --- a/src/harness/unittests/services/patternMatcher.ts +++ b/src/harness/unittests/services/patternMatcher.ts @@ -1,7 +1,7 @@ /// -describe("PatternMatcher", function () { - describe("BreakIntoCharacterSpans", function () { +describe("PatternMatcher", () => { + describe("BreakIntoCharacterSpans", () => { it("EmptyIdentifier", () => { verifyBreakIntoCharacterSpans(""); }); @@ -55,7 +55,7 @@ describe("PatternMatcher", function () { }); }); - describe("BreakIntoWordSpans", function () { + describe("BreakIntoWordSpans", () => { it("VarbatimIdentifier", () => { verifyBreakIntoWordSpans("@int:", "int"); }); diff --git a/src/harness/unittests/services/preProcessFile.ts b/src/harness/unittests/services/preProcessFile.ts index 6e77c27e4a8..d4195573cba 100644 --- a/src/harness/unittests/services/preProcessFile.ts +++ b/src/harness/unittests/services/preProcessFile.ts @@ -1,6 +1,6 @@ /// -describe("PreProcessFile:", function () { +describe("PreProcessFile:", () => { function test(sourceText: string, readImportFile: boolean, detectJavaScriptImports: boolean, expectedPreProcess: ts.PreProcessedFileInfo): void { const resultPreProcess = ts.preProcessFile(sourceText, readImportFile, detectJavaScriptImports); @@ -31,8 +31,8 @@ describe("PreProcessFile:", function () { } } - describe("Test preProcessFiles,", function () { - it("Correctly return referenced files from triple slash", function () { + describe("Test preProcessFiles,", () => { + it("Correctly return referenced files from triple slash", () => { test("///" + "\n" + "///" + "\n" + "///" + "\n" + "///", /*readImportFile*/ true, /*detectJavaScriptImports*/ false, @@ -46,7 +46,7 @@ describe("PreProcessFile:", function () { }); }), - it("Do not return reference path because of invalid triple-slash syntax", function () { + it("Do not return reference path because of invalid triple-slash syntax", () => { test("///" + "\n" + "///" + "\n" + "///" + "\n" + "///", /*readImportFile*/ true, /*detectJavaScriptImports*/ false, @@ -59,7 +59,7 @@ describe("PreProcessFile:", function () { }); }), - it("Correctly return imported files", function () { + it("Correctly return imported files", () => { test("import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\"); import i3= require(\"r3.ts\"); import i4=require(\"r4.ts\"); import i5 = require (\"r5.ts\");", /*readImportFile*/ true, /*detectJavaScriptImports*/ false, @@ -73,7 +73,7 @@ describe("PreProcessFile:", function () { }); }), - it("Do not return imported files if readImportFiles argument is false", function () { + it("Do not return imported files if readImportFiles argument is false", () => { test("import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\"); import i3= require(\"r3.ts\"); import i4=require(\"r4.ts\"); import i5 = require (\"r5.ts\");", /*readImportFile*/ false, /*detectJavaScriptImports*/ false, @@ -86,7 +86,7 @@ describe("PreProcessFile:", function () { }); }), - it("Do not return import path because of invalid import syntax", function () { + it("Do not return import path because of invalid import syntax", () => { test("import i1 require(\"r1.ts\"); import = require(\"r2.ts\") import i3= require(\"r3.ts\"); import i5", /*readImportFile*/ true, /*detectJavaScriptImports*/ false, @@ -99,7 +99,7 @@ describe("PreProcessFile:", function () { }); }), - it("Correctly return referenced files and import files", function () { + it("Correctly return referenced files and import files", () => { test("///" + "\n" + "///" + "\n" + "import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\");", /*readImportFile*/ true, /*detectJavaScriptImports*/ false, @@ -112,7 +112,7 @@ describe("PreProcessFile:", function () { }); }), - it("Correctly return referenced files and import files even with some invalid syntax", function () { + it("Correctly return referenced files and import files even with some invalid syntax", () => { test("///" + "\n" + "///" + "\n" + "import i1 = require(\"r1.ts\"); import = require(\"r2.ts\"); import i2 = require(\"r3.ts\");", /*readImportFile*/ true, /*detectJavaScriptImports*/ false, @@ -125,7 +125,7 @@ describe("PreProcessFile:", function () { }); }); - it("Correctly return ES6 imports", function () { + it("Correctly return ES6 imports", () => { test("import * as ns from \"m1\";" + "\n" + "import def, * as ns from \"m2\";" + "\n" + "import def from \"m3\";" + "\n" + @@ -152,7 +152,7 @@ describe("PreProcessFile:", function () { }); }); - it("Correctly return ES6 exports", function () { + it("Correctly return ES6 exports", () => { test("export * from \"m1\";" + "\n" + "export {a} from \"m2\";" + "\n" + "export {a as A} from \"m3\";" + "\n" + @@ -192,7 +192,7 @@ describe("PreProcessFile:", function () { }); }); - it("Correctly handles export import declarations", function () { + it("Correctly handles export import declarations", () => { test("export import a = require(\"m1\");", /*readImportFile*/ true, /*detectJavaScriptImports*/ false, @@ -206,7 +206,7 @@ describe("PreProcessFile:", function () { isLibFile: false }); }); - it("Correctly handles export require calls in JavaScript files", function () { + it("Correctly handles export require calls in JavaScript files", () => { test(` export import a = require("m1"); var x = require('m2'); @@ -228,7 +228,7 @@ describe("PreProcessFile:", function () { isLibFile: false }); }); - it("Correctly handles dependency lists in define([deplist]) calls in JavaScript files", function () { + it("Correctly handles dependency lists in define([deplist]) calls in JavaScript files", () => { test(` define(["mod1", "mod2"], (m1, m2) => { }); @@ -246,7 +246,7 @@ describe("PreProcessFile:", function () { isLibFile: false }); }); - it("Correctly handles dependency lists in define(modName, [deplist]) calls in JavaScript files", function () { + it("Correctly handles dependency lists in define(modName, [deplist]) calls in JavaScript files", () => { test(` define("mod", ["mod1", "mod2"], (m1, m2) => { }); diff --git a/src/server/server.ts b/src/server/server.ts index 8706df32e67..457be4a9b9a 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -816,7 +816,7 @@ namespace ts.server { if (useWatchGuard) { const currentDrive = extractWatchDirectoryCacheKey(sys.resolvePath(sys.getCurrentDirectory()), /*currentDriveKey*/ undefined); const statusCache = createMap(); - sys.watchDirectory = function (path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher { + sys.watchDirectory = (path, callback, recursive) => { const cacheKey = extractWatchDirectoryCacheKey(path, currentDrive); let status = cacheKey && statusCache.get(cacheKey); if (status === undefined) { @@ -953,7 +953,7 @@ namespace ts.server { }; const ioSession = new IOSession(options); - process.on("uncaughtException", function (err: Error) { + process.on("uncaughtException", err => { ioSession.logError(err, "unknown"); }); // See https://github.com/Microsoft/TypeScript/issues/11348 diff --git a/tslint.json b/tslint.json index 873b08eaf31..bdd783e2868 100644 --- a/tslint.json +++ b/tslint.json @@ -96,7 +96,6 @@ "no-unnecessary-initializer": false, "no-var-requires": false, "object-literal-key-quotes": false, - "only-arrow-functions": false, "ordered-imports": false, "prefer-conditional-expression": false, "prefer-for-of": false, From 8b5d8565cf9339226cb17045790a67993edc71cf Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 3 Nov 2017 15:11:36 -0700 Subject: [PATCH 112/235] Add CompletionDetailsFull request (#19689) * Add CompletionDetailsFull request * Update API baselines * Make internal --- src/server/protocol.ts | 2 ++ src/server/session.ts | 21 +++++++++---------- .../reference/api/tsserverlibrary.d.ts | 2 +- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 9a94c265f5d..18a5ad2ce10 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -15,6 +15,8 @@ namespace ts.server.protocol { /* @internal */ CompletionsFull = "completions-full", CompletionDetails = "completionEntryDetails", + /* @internal */ + CompletionDetailsFull = "completionEntryDetailsFull", CompileOnSaveAffectedFileList = "compileOnSaveAffectedFileList", CompileOnSaveEmitFile = "compileOnSaveEmitFile", Configure = "configure", diff --git a/src/server/session.ts b/src/server/session.ts index f02e1c620b9..f6983f48b54 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1216,23 +1216,19 @@ namespace ts.server { } } - private getCompletionEntryDetails(args: protocol.CompletionDetailsRequestArgs): ReadonlyArray { + private getCompletionEntryDetails(args: protocol.CompletionDetailsRequestArgs, simplifiedResult: boolean): ReadonlyArray | ReadonlyArray { const { file, project } = this.getFileAndProject(args); const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); const position = this.getPosition(args, scriptInfo); const formattingOptions = project.projectService.getFormatCodeOptions(file); - return mapDefined(args.entryNames, entryName => { + const result = mapDefined(args.entryNames, entryName => { const { name, source } = typeof entryName === "string" ? { name: entryName, source: undefined } : entryName; - const details = project.getLanguageService().getCompletionEntryDetails(file, position, name, formattingOptions, source); - if (details) { - const mappedCodeActions = map(details.codeActions, action => this.mapCodeAction(action, scriptInfo)); - return { ...details, codeActions: mappedCodeActions }; - } - else { - return undefined; - } + return project.getLanguageService().getCompletionEntryDetails(file, position, name, formattingOptions, source); }); + return simplifiedResult + ? result.map(details => ({ ...details, codeActions: map(details.codeActions, action => this.mapCodeAction(action, scriptInfo)) })) + : result; } private getCompileOnSaveAffectedFileList(args: protocol.FileRequestArgs): ReadonlyArray { @@ -1842,7 +1838,10 @@ namespace ts.server { return this.requiredResponse(this.getCompletions(request.arguments, /*simplifiedResult*/ false)); }, [CommandNames.CompletionDetails]: (request: protocol.CompletionDetailsRequest) => { - return this.requiredResponse(this.getCompletionEntryDetails(request.arguments)); + return this.requiredResponse(this.getCompletionEntryDetails(request.arguments, /*simplifiedResult*/ true)); + }, + [CommandNames.CompletionDetailsFull]: (request: protocol.CompletionDetailsRequest) => { + return this.requiredResponse(this.getCompletionEntryDetails(request.arguments, /*simplifiedResult*/ false)); }, [CommandNames.CompileOnSaveAffectedFileList]: (request: protocol.CompileOnSaveAffectedFileListRequest) => { return this.requiredResponse(this.getCompileOnSaveAffectedFileList(request.arguments)); diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index cffa1375608..aacd4f1276d 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -6996,7 +6996,7 @@ declare namespace ts.server { private getFormattingEditsAfterKeystrokeFull(args); private getFormattingEditsAfterKeystroke(args); private getCompletions(args, simplifiedResult); - private getCompletionEntryDetails(args); + private getCompletionEntryDetails(args, simplifiedResult); private getCompileOnSaveAffectedFileList(args); private emitFile(args); private getSignatureHelpItems(args, simplifiedResult); From d998e97d8c64acf1ed4b8cd508a4589c110bd3aa Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 3 Nov 2017 15:20:35 -0700 Subject: [PATCH 113/235] Apply 'prefer-for-of' tslint rule (#19721) --- src/compiler/checker.ts | 3 +-- src/compiler/emitter.ts | 4 ++-- src/compiler/transformers/module/system.ts | 3 +-- src/compiler/tsc.ts | 4 +--- src/harness/compilerRunner.ts | 4 ++-- src/harness/harness.ts | 16 ++++++---------- src/harness/parallel/host.ts | 3 +-- src/harness/projectsRunner.ts | 10 +++++----- src/harness/runner.ts | 4 ++-- src/harness/rwcRunner.ts | 6 ++---- src/harness/sourceMapRecorder.ts | 7 +++---- src/harness/userRunner.ts | 4 ++-- .../fixClassSuperMustPrecedeThisAccess.ts | 4 ++-- src/services/codefixes/helpers.ts | 6 ++---- tslint.json | 1 - 15 files changed, 32 insertions(+), 47 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b540f92b525..2b3bc631ebc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2854,8 +2854,7 @@ namespace ts { function mapToTypeNodes(types: Type[], context: NodeBuilderContext): TypeNode[] { if (some(types)) { const result = []; - for (let i = 0; i < types.length; ++i) { - const type = types[i]; + for (const type of types) { const typeNode = typeToTypeNodeHelper(type, context); if (typeNode) { result.push(typeNode); diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 8c41eda192a..74e5d4d5539 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2661,8 +2661,8 @@ namespace ts { function writeLines(text: string): void { const lines = text.split(/\r\n?|\n/g); const indentation = guessIndentation(lines); - for (let i = 0; i < lines.length; i++) { - const line = indentation ? lines[i].slice(indentation) : lines[i]; + for (const lineText of lines) { + const line = indentation ? lineText.slice(indentation) : lineText; if (line.length) { writeLine(); write(line); diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index a481f0c1d40..e5d638cf04d 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -146,8 +146,7 @@ namespace ts { function collectDependencyGroups(externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[]) { const groupIndices = createMap(); const dependencyGroups: DependencyGroup[] = []; - for (let i = 0; i < externalImports.length; i++) { - const externalImport = externalImports[i]; + for (const externalImport of externalImports) { const externalModuleName = getExternalModuleNameLiteral(externalImport, currentSourceFile, host, resolver, compilerOptions); if (externalModuleName) { const text = externalModuleName.text; diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 827dfa152c7..fe4365de265 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -305,9 +305,7 @@ namespace ts { const optionsDescriptionMap = createMap(); // Map between option.description and list of option.type if it is a kind - for (let i = 0; i < optsList.length; i++) { - const option = optsList[i]; - + for (const option of optsList) { // If an option lacks a description, // it is not officially supported. if (!option.description) { diff --git a/src/harness/compilerRunner.ts b/src/harness/compilerRunner.ts index c58accb657c..30c5e47949f 100644 --- a/src/harness/compilerRunner.ts +++ b/src/harness/compilerRunner.ts @@ -211,8 +211,8 @@ class CompilerBaselineRunner extends RunnerBase { this.emit = false; const opts = this.options.split(","); - for (let i = 0; i < opts.length; i++) { - switch (opts[i]) { + for (const opt of opts) { + switch (opt) { case "emit": this.emit = true; break; diff --git a/src/harness/harness.ts b/src/harness/harness.ts index ada7f06f3b3..e698839168a 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -575,14 +575,13 @@ namespace Harness { function filesInFolder(folder: string): string[] { let paths: string[] = []; - const files = fs.readdirSync(folder); - for (let i = 0; i < files.length; i++) { - const pathToFile = pathModule.join(folder, files[i]); + for (const file of fs.readdirSync(folder)) { + const pathToFile = pathModule.join(folder, file); const stat = fs.statSync(pathToFile); if (options.recursive && stat.isDirectory()) { paths = paths.concat(filesInFolder(pathToFile)); } - else if (stat.isFile() && (!spec || files[i].match(spec))) { + else if (stat.isFile() && (!spec || file.match(spec))) { paths.push(pathToFile); } } @@ -1581,10 +1580,8 @@ namespace Harness { // Preserve legacy behavior if (lastIndexWritten === undefined) { - for (let i = 0; i < codeLines.length; i++) { - const currentCodeLine = codeLines[i]; - typeLines += currentCodeLine + "\r\n"; - typeLines += "No type information for this code."; + for (const codeLine of codeLines) { + typeLines += codeLine + "\r\nNo type information for this code."; } } else { @@ -1870,8 +1867,7 @@ namespace Harness { let currentFileName: any = undefined; let refs: string[] = []; - for (let i = 0; i < lines.length; i++) { - const line = lines[i]; + for (const line of lines) { const testMetaData = optionRegex.exec(line); if (testMetaData) { // Comment line, check for global/file @options and record them diff --git a/src/harness/parallel/host.ts b/src/harness/parallel/host.ts index bf218c1b3a1..40dee0da872 100644 --- a/src/harness/parallel/host.ts +++ b/src/harness/parallel/host.ts @@ -314,8 +314,7 @@ namespace Harness.Parallel.Host { stats.failures = errorResults.length; stats.tests = totalPassing + errorResults.length; stats.duration = duration; - for (let j = 0; j < errorResults.length; j++) { - const failure = errorResults[j]; + for (const failure of errorResults) { failures.push(makeMochaTest(failure)); } if (noColors) { diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index cc68f8625f4..fccbba88ff6 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -140,12 +140,12 @@ class ProjectRunner extends RunnerBase { // Clean up source map data that will be used in baselining if (sourceMapData) { - for (let i = 0; i < sourceMapData.length; i++) { - for (let j = 0; j < sourceMapData[i].sourceMapSources.length; j++) { - sourceMapData[i].sourceMapSources[j] = cleanProjectUrl(sourceMapData[i].sourceMapSources[j]); + for (const data of sourceMapData) { + for (let j = 0; j < data.sourceMapSources.length; j++) { + data.sourceMapSources[j] = cleanProjectUrl(data.sourceMapSources[j]); } - sourceMapData[i].jsSourceMappingURL = cleanProjectUrl(sourceMapData[i].jsSourceMappingURL); - sourceMapData[i].sourceMapSourceRoot = cleanProjectUrl(sourceMapData[i].sourceMapSourceRoot); + data.jsSourceMappingURL = cleanProjectUrl(data.jsSourceMappingURL); + data.sourceMapSourceRoot = cleanProjectUrl(data.sourceMapSourceRoot); } } diff --git a/src/harness/runner.ts b/src/harness/runner.ts index 9b8ed41554e..b538f90bc39 100644 --- a/src/harness/runner.ts +++ b/src/harness/runner.ts @@ -27,8 +27,8 @@ let iterations = 1; function runTests(runners: RunnerBase[]) { for (let i = iterations; i > 0; i--) { - for (let j = 0; j < runners.length; j++) { - runners[j].initializeTests(); + for (const runner of runners) { + runner.initializeTests(); } } } diff --git a/src/harness/rwcRunner.ts b/src/harness/rwcRunner.ts index 21cc38cb8b8..af6e8c95c5c 100644 --- a/src/harness/rwcRunner.ts +++ b/src/harness/rwcRunner.ts @@ -245,10 +245,8 @@ class RWCRunner extends RunnerBase { */ public initializeTests(): void { // Read in and evaluate the test list - const testList = this.tests && this.tests.length ? this.tests : this.enumerateTestFiles(); - - for (let i = 0; i < testList.length; i++) { - this.runTest(testList[i]); + for (const test of this.tests && this.tests.length ? this.tests : this.enumerateTestFiles()) { + this.runTest(test); } } diff --git a/src/harness/sourceMapRecorder.ts b/src/harness/sourceMapRecorder.ts index de068706fbe..606d4e67acd 100644 --- a/src/harness/sourceMapRecorder.ts +++ b/src/harness/sourceMapRecorder.ts @@ -386,9 +386,9 @@ namespace Harness.SourceMapRecorder { if (currentSpan.decodeErrors) { // If there are decode errors, write - for (let i = 0; i < currentSpan.decodeErrors.length; i++) { + for (const decodeError of currentSpan.decodeErrors) { writeSourceMapIndent(prevEmittedCol, markerIds[index]); - sourceMapRecorder.WriteLine(currentSpan.decodeErrors[i]); + sourceMapRecorder.WriteLine(decodeError); } } @@ -442,8 +442,7 @@ namespace Harness.SourceMapRecorder { let prevSourceFile: ts.SourceFile; SourceMapSpanWriter.initializeSourceMapSpanWriter(sourceMapRecorder, sourceMapData, jsFiles[i]); - for (let j = 0; j < sourceMapData.sourceMapDecodedMappings.length; j++) { - const decodedSourceMapping = sourceMapData.sourceMapDecodedMappings[j]; + for (const decodedSourceMapping of sourceMapData.sourceMapDecodedMappings) { const currentSourceFile = program.getSourceFile(sourceMapData.inputSourceFileNames[decodedSourceMapping.sourceIndex]); if (currentSourceFile !== prevSourceFile) { SourceMapSpanWriter.recordNewSourceFileSpan(decodedSourceMapping, currentSourceFile.text); diff --git a/src/harness/userRunner.ts b/src/harness/userRunner.ts index 3802330e10c..9be652aebf8 100644 --- a/src/harness/userRunner.ts +++ b/src/harness/userRunner.ts @@ -18,8 +18,8 @@ class UserCodeRunner extends RunnerBase { const testList = this.tests && this.tests.length ? this.tests : this.enumerateTestFiles(); describe(`${this.kind()} code samples`, () => { - for (let i = 0; i < testList.length; i++) { - this.runTest(testList[i]); + for (const test of testList) { + this.runTest(test); } }); } diff --git a/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts b/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts index bc92cd8e0d1..e5c4266684d 100644 --- a/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts +++ b/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts @@ -20,8 +20,8 @@ namespace ts.codefix { // i.e. super(this.a), since in that case we won't suggest a fix if (superCall.expression && superCall.expression.kind === SyntaxKind.CallExpression) { const expressionArguments = (superCall.expression).arguments; - for (let i = 0; i < expressionArguments.length; i++) { - if ((expressionArguments[i]).expression === token) { + for (const arg of expressionArguments) { + if ((arg).expression === token) { return undefined; } } diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 685c6832f13..206a3864ac0 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -104,8 +104,7 @@ namespace ts.codefix { } const signatureDeclarations: MethodDeclaration[] = []; - for (let i = 0; i < signatures.length; i++) { - const signature = signatures[i]; + for (const signature of signatures) { const methodDeclaration = signatureToMethodDeclaration(signature, enclosingDeclaration); if (methodDeclaration) { signatureDeclarations.push(methodDeclaration); @@ -194,8 +193,7 @@ namespace ts.codefix { let maxArgsSignature = signatures[0]; let minArgumentCount = signatures[0].minArgumentCount; let someSigHasRestParameter = false; - for (let i = 0; i < signatures.length; i++) { - const sig = signatures[i]; + for (const sig of signatures) { minArgumentCount = Math.min(sig.minArgumentCount, minArgumentCount); if (sig.hasRestParameter) { someSigHasRestParameter = true; diff --git a/tslint.json b/tslint.json index bdd783e2868..299a1049e4c 100644 --- a/tslint.json +++ b/tslint.json @@ -98,7 +98,6 @@ "object-literal-key-quotes": false, "ordered-imports": false, "prefer-conditional-expression": false, - "prefer-for-of": false, "radix": false, "space-before-function-paren": false, "trailing-comma": false, From 373510c4d9f1673fde5f3e17d9a4b63728acb4e7 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 3 Nov 2017 15:28:28 -0700 Subject: [PATCH 114/235] Handle the script infos that are opened with non rooted disk path Fixes #19588 --- .../unittests/tsserverProjectSystem.ts | 3 +- src/server/editorServices.ts | 46 ++++++++++++++----- src/server/project.ts | 10 ++-- src/server/scriptInfo.ts | 4 +- .../reference/api/tsserverlibrary.d.ts | 10 +++- 5 files changed, 52 insertions(+), 21 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 5df045335cb..ae90ec7d741 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -2837,8 +2837,9 @@ namespace ts.projectSystem { // Run the last one = get error request host.runQueuedTimeoutCallbacks(newTimeoutId); - host.checkTimeoutQueueLength(2); + assert.isFalse(hasError); + host.checkTimeoutQueueLength(2); checkErrorMessage(host, "syntaxDiag", { file: untitledFile, diagnostics: [] }); host.clearOutput(); diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 9ec190c152f..1730e545257 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -353,6 +353,10 @@ namespace ts.server { * Open files: with value being project root path, and key being Path of the file that is open */ readonly openFiles = createMap(); + /** + * Map of open files that are opened without complete path but have projectRoot as current directory + */ + private readonly openFilesWithNonRootedDiskPath = createMap(); private compilerOptionsForInferredProjects: CompilerOptions; private compilerOptionsForInferredProjectsPerProjectRoot = createMap(); @@ -930,12 +934,16 @@ namespace ts.server { // Closing file should trigger re-reading the file content from disk. This is // because the user may chose to discard the buffer content before saving // to the disk, and the server's version of the file can be out of sync. - info.close(); + const fileExists = this.host.fileExists(info.fileName); + info.close(fileExists); this.stopWatchingConfigFilesForClosedScriptInfo(info); this.openFiles.delete(info.path); + const canonicalFileName = this.toCanonicalFileName(info.fileName); + if (this.openFilesWithNonRootedDiskPath.get(canonicalFileName) === info) { + this.openFilesWithNonRootedDiskPath.delete(canonicalFileName); + } - const fileExists = this.host.fileExists(info.fileName); // collect all projects that should be removed let projectsToRemove: Project[]; @@ -1535,7 +1543,7 @@ namespace ts.server { else { const scriptKind = propertyReader.getScriptKind(f, this.hostConfiguration.extraFileExtensions); const hasMixedContent = propertyReader.hasMixedContent(f, this.hostConfiguration.extraFileExtensions); - scriptInfo = this.getOrCreateScriptInfoNotOpenedByClientForNormalizedPath(normalizedPath, scriptKind, hasMixedContent, project.directoryStructureHost); + scriptInfo = this.getOrCreateScriptInfoNotOpenedByClientForNormalizedPath(normalizedPath, project.currentDirectory, scriptKind, hasMixedContent, project.directoryStructureHost); path = scriptInfo.path; // If this script info is not already a root add it if (!project.isRoot(scriptInfo)) { @@ -1689,9 +1697,9 @@ namespace ts.server { } /*@internal*/ - getOrCreateScriptInfoNotOpenedByClient(uncheckedFileName: string, hostToQueryFileExistsOn: DirectoryStructureHost) { + getOrCreateScriptInfoNotOpenedByClient(uncheckedFileName: string, currentDirectory: string, hostToQueryFileExistsOn: DirectoryStructureHost) { return this.getOrCreateScriptInfoNotOpenedByClientForNormalizedPath( - toNormalizedPath(uncheckedFileName), /*scriptKind*/ undefined, + toNormalizedPath(uncheckedFileName), currentDirectory, /*scriptKind*/ undefined, /*hasMixedContent*/ undefined, hostToQueryFileExistsOn ); } @@ -1722,20 +1730,26 @@ namespace ts.server { } /*@internal*/ - getOrCreateScriptInfoNotOpenedByClientForNormalizedPath(fileName: NormalizedPath, scriptKind?: ScriptKind, hasMixedContent?: boolean, hostToQueryFileExistsOn?: DirectoryStructureHost) { - return this.getOrCreateScriptInfoForNormalizedPath(fileName, /*openedByClient*/ false, /*fileContent*/ undefined, scriptKind, hasMixedContent, hostToQueryFileExistsOn); + getOrCreateScriptInfoNotOpenedByClientForNormalizedPath(fileName: NormalizedPath, currentDirectory: string, scriptKind: ScriptKind | undefined, hasMixedContent: boolean | undefined, hostToQueryFileExistsOn: DirectoryStructureHost | undefined) { + return this.getOrCreateScriptInfoWorker(fileName, currentDirectory, /*openedByClient*/ false, /*fileContent*/ undefined, scriptKind, hasMixedContent, hostToQueryFileExistsOn); } /*@internal*/ - getOrCreateScriptInfoOpenedByClientForNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, hostToQueryFileExistsOn?: DirectoryStructureHost) { - return this.getOrCreateScriptInfoForNormalizedPath(fileName, /*openedByClient*/ true, fileContent, scriptKind, hasMixedContent, hostToQueryFileExistsOn); + getOrCreateScriptInfoOpenedByClientForNormalizedPath(fileName: NormalizedPath, currentDirectory: string, fileContent: string | undefined, scriptKind: ScriptKind | undefined, hasMixedContent: boolean | undefined) { + return this.getOrCreateScriptInfoWorker(fileName, currentDirectory, /*openedByClient*/ true, fileContent, scriptKind, hasMixedContent); } getOrCreateScriptInfoForNormalizedPath(fileName: NormalizedPath, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, hostToQueryFileExistsOn?: DirectoryStructureHost) { + return this.getOrCreateScriptInfoWorker(fileName, this.currentDirectory, openedByClient, fileContent, scriptKind, hasMixedContent, hostToQueryFileExistsOn); + } + + private getOrCreateScriptInfoWorker(fileName: NormalizedPath, currentDirectory: string, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, hostToQueryFileExistsOn?: DirectoryStructureHost) { Debug.assert(fileContent === undefined || openedByClient, "ScriptInfo needs to be opened by client to be able to set its user defined content"); - const path = normalizedPathToPath(fileName, this.currentDirectory, this.toCanonicalFileName); + const path = normalizedPathToPath(fileName, currentDirectory, this.toCanonicalFileName); let info = this.getScriptInfoForPath(path); if (!info) { + Debug.assert(isRootedDiskPath(fileName) || openedByClient, "Script info with relative file name can only be open script info"); + Debug.assert(!isRootedDiskPath(fileName) || this.currentDirectory === currentDirectory || !this.openFilesWithNonRootedDiskPath.has(this.toCanonicalFileName(fileName)), "Open script files with non rooted disk path opened with current directory context cannot have same canonical names"); const isDynamic = isDynamicFileName(fileName); // If the file is not opened by client and the file doesnot exist on the disk, return if (!openedByClient && !isDynamic && !(hostToQueryFileExistsOn || this.host).fileExists(fileName)) { @@ -1746,6 +1760,10 @@ namespace ts.server { if (!openedByClient) { this.watchClosedScriptInfo(info); } + else if (!isRootedDiskPath(fileName) && currentDirectory !== this.currentDirectory) { + // File that is opened by user but isn't rooted disk path + this.openFilesWithNonRootedDiskPath.set(this.toCanonicalFileName(fileName), info); + } } if (openedByClient && !info.isScriptOpen()) { // Opening closed script info @@ -1762,8 +1780,12 @@ namespace ts.server { return info; } + /** + * This gets the script info for the normalized path. If the path is not rooted disk path then the open script info with project root context is preferred + */ getScriptInfoForNormalizedPath(fileName: NormalizedPath) { - return this.getScriptInfoForPath(normalizedPathToPath(fileName, this.currentDirectory, this.toCanonicalFileName)); + return !isRootedDiskPath(fileName) && this.openFilesWithNonRootedDiskPath.get(this.toCanonicalFileName(fileName)) || + this.getScriptInfoForPath(normalizedPathToPath(fileName, this.currentDirectory, this.toCanonicalFileName)); } getScriptInfoForPath(fileName: Path) { @@ -1948,7 +1970,7 @@ namespace ts.server { let sendConfigFileDiagEvent = false; let configFileErrors: ReadonlyArray; - const info = this.getOrCreateScriptInfoOpenedByClientForNormalizedPath(fileName, fileContent, scriptKind, hasMixedContent); + const info = this.getOrCreateScriptInfoOpenedByClientForNormalizedPath(fileName, projectRootPath ? this.getNormalizedAbsolutePath(projectRootPath) : this.currentDirectory, fileContent, scriptKind, hasMixedContent); let project: ConfiguredProject | ExternalProject = this.findContainingExternalProject(fileName); if (!project) { configFileName = this.getConfigFileNameForFile(info, projectRootPath); diff --git a/src/server/project.ts b/src/server/project.ts index 0444e9304b5..edb1d6730e9 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -285,7 +285,7 @@ namespace ts.server { } private getOrCreateScriptInfoAndAttachToProject(fileName: string) { - const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(fileName, this.directoryStructureHost); + const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(fileName, this.currentDirectory, this.directoryStructureHost); if (scriptInfo) { const existingValue = this.rootFilesMap.get(scriptInfo.path); if (existingValue !== scriptInfo && existingValue !== undefined) { @@ -365,7 +365,7 @@ namespace ts.server { /*@internal*/ toPath(fileName: string) { - return this.projectService.toPath(fileName); + return toPath(fileName, this.currentDirectory, this.projectService.toCanonicalFileName); } /*@internal*/ @@ -658,7 +658,7 @@ namespace ts.server { } containsFile(filename: NormalizedPath, requireOpen?: boolean) { - const info = this.projectService.getScriptInfoForNormalizedPath(filename); + const info = this.projectService.getScriptInfoForPath(this.toPath(filename)); if (info && (info.isScriptOpen() || !requireOpen)) { return this.containsScriptInfo(info); } @@ -855,7 +855,7 @@ namespace ts.server { // by the LSHost for files in the program when the program is retrieved above but // the program doesn't contain external files so this must be done explicitly. inserted => { - const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(inserted, this.directoryStructureHost); + const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(inserted, this.currentDirectory, this.directoryStructureHost); scriptInfo.attachToProject(this); }, removed => this.detachScriptInfoFromProject(removed) @@ -901,7 +901,7 @@ namespace ts.server { } getScriptInfoForNormalizedPath(fileName: NormalizedPath) { - const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(fileName); + const scriptInfo = this.projectService.getScriptInfoForPath(this.toPath(fileName)); if (scriptInfo && !scriptInfo.isAttached(this)) { return Errors.ThrowProjectDoesNotContainDocument(fileName, this); } diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index 9f029c00f0a..f800a1117d0 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -248,9 +248,9 @@ namespace ts.server { } } - public close() { + public close(fileExists = true) { this.textStorage.isOpen = false; - if (this.isDynamicOrHasMixedContent()) { + if (this.isDynamicOrHasMixedContent() || !fileExists) { if (this.textStorage.reload("")) { this.markContainingProjectsAsDirty(); } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index cffa1375608..64bbdd60c7c 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -7058,7 +7058,7 @@ declare namespace ts.server { constructor(host: ServerHost, fileName: NormalizedPath, scriptKind: ScriptKind, hasMixedContent: boolean, path: Path); isScriptOpen(): boolean; open(newText: string): void; - close(): void; + close(fileExists?: boolean): void; getSnapshot(): IScriptSnapshot; getFormatCodeSettings(): FormatCodeSettings; attachToProject(project: Project): boolean; @@ -7482,6 +7482,10 @@ declare namespace ts.server { * Open files: with value being project root path, and key being Path of the file that is open */ readonly openFiles: Map; + /** + * Map of open files that are opened without complete path but have projectRoot as current directory + */ + private readonly openFilesWithNonRootedDiskPath; private compilerOptionsForInferredProjects; private compilerOptionsForInferredProjectsPerProjectRoot; /** @@ -7621,6 +7625,10 @@ declare namespace ts.server { private watchClosedScriptInfo(info); private stopWatchingScriptInfo(info); getOrCreateScriptInfoForNormalizedPath(fileName: NormalizedPath, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, hostToQueryFileExistsOn?: DirectoryStructureHost): ScriptInfo; + private getOrCreateScriptInfoWorker(fileName, currentDirectory, openedByClient, fileContent?, scriptKind?, hasMixedContent?, hostToQueryFileExistsOn?); + /** + * This gets the script info for the normalized path. If the path is not rooted disk path then the open script info with project root context is preferred + */ getScriptInfoForNormalizedPath(fileName: NormalizedPath): ScriptInfo; getScriptInfoForPath(fileName: Path): ScriptInfo; setHostConfiguration(args: protocol.ConfigureRequestArguments): void; From bb7fb7dda945550ec17b7490e3b725f45142c847 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 3 Nov 2017 15:55:31 -0700 Subject: [PATCH 115/235] For getCompletionsAtPosition, require a flag to provide completions with code actions (#19687) * For getCompletionsAtPosition, require a flag to provide completions with code actions * Change name * Increase API version * Update API baselines * Add comment * Update API baseline --- src/harness/fourslash.ts | 24 +++++++++---------- src/harness/harnessLanguageService.ts | 4 ++-- .../unittests/tsserverProjectSystem.ts | 12 +++++----- src/server/client.ts | 4 ++-- src/server/protocol.ts | 5 ++++ src/server/session.ts | 8 +++---- src/services/completions.ts | 10 +++++--- src/services/services.ts | 14 ++++++++--- src/services/shims.ts | 8 +++---- src/services/types.ts | 6 ++++- .../reference/api/tsserverlibrary.d.ts | 12 ++++++++-- tests/baselines/reference/api/typescript.d.ts | 7 ++++-- ...letionsImport_default_addToNamedImports.ts | 2 +- ...ionsImport_default_addToNamespaceImport.ts | 2 +- ...Import_default_alreadyExistedWithRename.ts | 2 +- ...letionsImport_default_didNotExistBefore.ts | 2 +- .../fourslash/completionsImport_matching.ts | 11 +++++---- .../completionsImport_multipleWithSameName.ts | 7 +++--- ...mpletionsImport_named_addToNamedImports.ts | 2 +- ...mpletionsImport_named_didNotExistBefore.ts | 7 +++--- ...tionsImport_named_namespaceImportExists.ts | 2 +- .../fourslash/completionsImport_ofAlias.ts | 7 +++--- ...pletionsImport_previousTokenIsSemicolon.ts | 2 +- .../completionsImport_shadowedByLocal.ts | 5 ++-- tests/cases/fourslash/fourslash.ts | 1 + 25 files changed, 102 insertions(+), 64 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index ba8c11462e4..7852aba28f1 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -855,8 +855,8 @@ namespace FourSlash { }); } - public verifyCompletionListContains(entryId: ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string, spanIndex?: number, hasAction?: boolean) { - const completions = this.getCompletionListAtCaret(); + public verifyCompletionListContains(entryId: ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string, spanIndex?: number, hasAction?: boolean, options?: ts.GetCompletionsAtPositionOptions) { + const completions = this.getCompletionListAtCaret(options); if (completions) { this.assertItemInCompletionList(completions.entries, entryId, text, documentation, kind, spanIndex, hasAction); } @@ -876,13 +876,13 @@ namespace FourSlash { * @param expectedKind the kind of symbol (see ScriptElementKind) * @param spanIndex the index of the range that the completion item's replacement text span should match */ - public verifyCompletionListDoesNotContain(entryId: ts.Completions.CompletionEntryIdentifier, expectedText?: string, expectedDocumentation?: string, expectedKind?: string, spanIndex?: number) { + public verifyCompletionListDoesNotContain(entryId: ts.Completions.CompletionEntryIdentifier, expectedText?: string, expectedDocumentation?: string, expectedKind?: string, spanIndex?: number, options?: ts.GetCompletionsAtPositionOptions) { let replacementSpan: ts.TextSpan; if (spanIndex !== undefined) { replacementSpan = this.getTextSpanForRangeAtIndex(spanIndex); } - const completions = this.getCompletionListAtCaret(); + const completions = this.getCompletionListAtCaret(options); if (completions) { let filterCompletions = completions.entries.filter(e => e.name === entryId.name && e.source === entryId.source); filterCompletions = expectedKind ? filterCompletions.filter(e => e.kind === expectedKind) : filterCompletions; @@ -1195,11 +1195,11 @@ Actual: ${stringify(fullActual)}`); this.raiseError(`verifyReferencesAtPositionListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(references)})`); } - private getCompletionListAtCaret() { - return this.languageService.getCompletionsAtPosition(this.activeFile.fileName, this.currentCaretPosition); + private getCompletionListAtCaret(options?: ts.GetCompletionsAtPositionOptions): ts.CompletionInfo { + return this.languageService.getCompletionsAtPosition(this.activeFile.fileName, this.currentCaretPosition, options); } - private getCompletionEntryDetails(entryName: string, source?: string) { + private getCompletionEntryDetails(entryName: string, source?: string): ts.CompletionEntryDetails { return this.languageService.getCompletionEntryDetails(this.activeFile.fileName, this.currentCaretPosition, entryName, this.formatCodeSettings, source); } @@ -1790,7 +1790,7 @@ Actual: ${stringify(fullActual)}`); } else if (prevChar === " " && /A-Za-z_/.test(ch)) { /* Completions */ - this.languageService.getCompletionsAtPosition(this.activeFile.fileName, offset); + this.languageService.getCompletionsAtPosition(this.activeFile.fileName, offset, { includeExternalModuleExports: false }); } if (i % checkCadence === 0) { @@ -2365,7 +2365,7 @@ Actual: ${stringify(fullActual)}`); public applyCodeActionFromCompletion(markerName: string, options: FourSlashInterface.VerifyCompletionActionOptions) { this.goToMarker(markerName); - const actualCompletion = this.getCompletionListAtCaret().entries.find(e => e.name === options.name && e.source === options.source); + const actualCompletion = this.getCompletionListAtCaret({ includeExternalModuleExports: true }).entries.find(e => e.name === options.name && e.source === options.source); if (!actualCompletion.hasAction) { this.raiseError(`Completion for ${options.name} does not have an associated action.`); @@ -3803,15 +3803,15 @@ namespace FourSlashInterface { // Verifies the completion list contains the specified symbol. The // completion list is brought up if necessary - public completionListContains(entryId: string | ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string, spanIndex?: number, hasAction?: boolean) { + public completionListContains(entryId: string | ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string, spanIndex?: number, hasAction?: boolean, options?: ts.GetCompletionsAtPositionOptions) { if (typeof entryId === "string") { entryId = { name: entryId, source: undefined }; } if (this.negative) { - this.state.verifyCompletionListDoesNotContain(entryId, text, documentation, kind, spanIndex); + this.state.verifyCompletionListDoesNotContain(entryId, text, documentation, kind, spanIndex, options); } else { - this.state.verifyCompletionListContains(entryId, text, documentation, kind, spanIndex, hasAction); + this.state.verifyCompletionListContains(entryId, text, documentation, kind, spanIndex, hasAction, options); } } diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 97445900d34..185c22db72d 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -413,8 +413,8 @@ namespace Harness.LanguageService { getEncodedSemanticClassifications(fileName: string, span: ts.TextSpan): ts.Classifications { return unwrapJSONCallResult(this.shim.getEncodedSemanticClassifications(fileName, span.start, span.length)); } - getCompletionsAtPosition(fileName: string, position: number): ts.CompletionInfo { - return unwrapJSONCallResult(this.shim.getCompletionsAtPosition(fileName, position)); + getCompletionsAtPosition(fileName: string, position: number, options: ts.GetCompletionsAtPositionOptions | undefined): ts.CompletionInfo { + return unwrapJSONCallResult(this.shim.getCompletionsAtPosition(fileName, position, options)); } getCompletionEntryDetails(fileName: string, position: number, entryName: string, options: ts.FormatCodeOptions | undefined, source: string | undefined): ts.CompletionEntryDetails { return unwrapJSONCallResult(this.shim.getCompletionEntryDetails(fileName, position, entryName, JSON.stringify(options), source)); diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index be38176fb15..112809b5683 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -1248,13 +1248,13 @@ namespace ts.projectSystem { service.checkNumberOfProjects({ externalProjects: 1 }); checkProjectActualFiles(service.externalProjects[0], [f1.path, f2.path, libFile.path]); - const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2); + const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, { includeExternalModuleExports: false }); // should contain completions for string assert.isTrue(completions1.entries.some(e => e.name === "charAt"), "should contain 'charAt'"); assert.isFalse(completions1.entries.some(e => e.name === "toExponential"), "should not contain 'toExponential'"); service.closeClientFile(f2.path); - const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2); + const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, { includeExternalModuleExports: false }); // should contain completions for string assert.isFalse(completions2.entries.some(e => e.name === "charAt"), "should not contain 'charAt'"); assert.isTrue(completions2.entries.some(e => e.name === "toExponential"), "should contain 'toExponential'"); @@ -1280,11 +1280,11 @@ namespace ts.projectSystem { service.checkNumberOfProjects({ externalProjects: 1 }); checkProjectActualFiles(service.externalProjects[0], [f1.path, f2.path, libFile.path]); - const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0); + const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, { includeExternalModuleExports: false }); assert.isTrue(completions1.entries.some(e => e.name === "somelongname"), "should contain 'somelongname'"); service.closeClientFile(f2.path); - const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0); + const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, { includeExternalModuleExports: false }); assert.isFalse(completions2.entries.some(e => e.name === "somelongname"), "should not contain 'somelongname'"); const sf2 = service.externalProjects[0].getLanguageService().getProgram().getSourceFile(f2.path); assert.equal(sf2.text, ""); @@ -1845,7 +1845,7 @@ namespace ts.projectSystem { // Check identifiers defined in HTML content are available in .ts file const project = configuredProjectAt(projectService, 0); - let completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 1); + let completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 1, { includeExternalModuleExports: false }); assert(completions && completions.entries[0].name === "hello", `expected entry hello to be in completion list`); // Close HTML file @@ -1859,7 +1859,7 @@ namespace ts.projectSystem { checkProjectActualFiles(configuredProjectAt(projectService, 0), [file1.path, file2.path, config.path]); // Check identifiers defined in HTML content are not available in .ts file - completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 5); + completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 5, { includeExternalModuleExports: false }); assert(completions && completions.entries[0].name !== "hello", `unexpected hello entry in completion list`); }); diff --git a/src/server/client.ts b/src/server/client.ts index b3492cb8ae3..8286119e828 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -170,8 +170,8 @@ namespace ts.server { }; } - getCompletionsAtPosition(fileName: string, position: number): CompletionInfo { - const args: protocol.CompletionsRequestArgs = this.createFileLocationRequestArgs(fileName, position); + getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions | undefined): CompletionInfo { + const args: protocol.CompletionsRequestArgs = { ...this.createFileLocationRequestArgs(fileName, position), ...options }; const request = this.processRequest(CommandNames.Completions, args); const response = this.processResponse(request); diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 18a5ad2ce10..93d5c69d361 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -1619,6 +1619,11 @@ namespace ts.server.protocol { * Optional prefix to apply to possible completions. */ prefix?: string; + /** + * If enabled, TypeScript will search through all external modules' exports and add them to the completions list. + * This affects lone identifier completions but not completions on the right hand side of `obj.`. + */ + includeExternalModuleExports: boolean; } /** diff --git a/src/server/session.ts b/src/server/session.ts index f6983f48b54..3f223b13963 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1200,10 +1200,10 @@ namespace ts.server { const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); const position = this.getPosition(args, scriptInfo); - const completions = project.getLanguageService().getCompletionsAtPosition(file, position); + const completions = project.getLanguageService().getCompletionsAtPosition(file, position, args); if (simplifiedResult) { return mapDefined(completions && completions.entries, entry => { - if (completions.isMemberCompletion || (entry.name.toLowerCase().indexOf(prefix.toLowerCase()) === 0)) { + if (completions.isMemberCompletion || startsWith(entry.name.toLowerCase(), prefix.toLowerCase())) { const { name, kind, kindModifiers, sortText, replacementSpan, hasAction, source } = entry; const convertedSpan = replacementSpan ? this.toLocationTextSpan(replacementSpan, scriptInfo) : undefined; // Use `hasAction || undefined` to avoid serializing `false`. @@ -1831,10 +1831,10 @@ namespace ts.server { [CommandNames.FormatRangeFull]: (request: protocol.FormatRequest) => { return this.requiredResponse(this.getFormattingEditsForRangeFull(request.arguments)); }, - [CommandNames.Completions]: (request: protocol.CompletionDetailsRequest) => { + [CommandNames.Completions]: (request: protocol.CompletionsRequest) => { return this.requiredResponse(this.getCompletions(request.arguments, /*simplifiedResult*/ true)); }, - [CommandNames.CompletionsFull]: (request: protocol.CompletionDetailsRequest) => { + [CommandNames.CompletionsFull]: (request: protocol.CompletionsRequest) => { return this.requiredResponse(this.getCompletions(request.arguments, /*simplifiedResult*/ false)); }, [CommandNames.CompletionDetails]: (request: protocol.CompletionDetailsRequest) => { diff --git a/src/services/completions.ts b/src/services/completions.ts index 6462788d5ae..3c233f4dbe8 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -28,6 +28,7 @@ namespace ts.Completions { sourceFile: SourceFile, position: number, allSourceFiles: ReadonlyArray, + options: GetCompletionsAtPositionOptions, ): CompletionInfo | undefined { if (isInReferenceComment(sourceFile, position)) { const entries = PathCompletions.getTripleSlashReferenceCompletion(sourceFile, position, compilerOptions, host); @@ -38,7 +39,7 @@ namespace ts.Completions { return getStringLiteralCompletionEntries(sourceFile, position, typeChecker, compilerOptions, host, log); } - const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles); + const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, options); if (!completionData) { return undefined; } @@ -380,7 +381,7 @@ namespace ts.Completions { { name, source }: CompletionEntryIdentifier, allSourceFiles: ReadonlyArray, ): { type: "symbol", symbol: Symbol, location: Node, symbolToOriginInfoMap: SymbolOriginInfoMap } | { type: "request", request: Request } | { type: "none" } { - const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles); + const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, { includeExternalModuleExports: true }); if (!completionData) { return { type: "none" }; } @@ -521,6 +522,7 @@ namespace ts.Completions { sourceFile: SourceFile, position: number, allSourceFiles: ReadonlyArray, + options: GetCompletionsAtPositionOptions, ): CompletionData | undefined { const isJavaScriptFile = isSourceFileJavaScript(sourceFile); @@ -918,7 +920,9 @@ namespace ts.Completions { const symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias; symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings); - getSymbolsFromOtherSourceFileExports(symbols, previousToken && isIdentifier(previousToken) ? previousToken.text : ""); + if (options.includeExternalModuleExports) { + getSymbolsFromOtherSourceFileExports(symbols, previousToken && isIdentifier(previousToken) ? previousToken.text : ""); + } filterGlobalCompletion(symbols); return true; diff --git a/src/services/services.ts b/src/services/services.ts index e4a6e556f79..178d949990d 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -31,7 +31,7 @@ namespace ts { /** The version of the language service API */ - export const servicesVersion = "0.6"; + export const servicesVersion = "0.7"; /* @internal */ let ruleProvider: formatting.RulesProvider; @@ -1326,9 +1326,17 @@ namespace ts { return [...program.getOptionsDiagnostics(cancellationToken), ...program.getGlobalDiagnostics(cancellationToken)]; } - function getCompletionsAtPosition(fileName: string, position: number): CompletionInfo { + function getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions = { includeExternalModuleExports: false }): CompletionInfo { synchronizeHostData(); - return Completions.getCompletionsAtPosition(host, program.getTypeChecker(), log, program.getCompilerOptions(), getValidSourceFile(fileName), position, program.getSourceFiles()); + return Completions.getCompletionsAtPosition( + host, + program.getTypeChecker(), + log, + program.getCompilerOptions(), + getValidSourceFile(fileName), + position, + program.getSourceFiles(), + options); } function getCompletionEntryDetails(fileName: string, position: number, name: string, formattingOptions?: FormatCodeSettings, source?: string): CompletionEntryDetails { diff --git a/src/services/shims.ts b/src/services/shims.ts index d3cdbe13524..7c932361c10 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -140,7 +140,7 @@ namespace ts { getEncodedSyntacticClassifications(fileName: string, start: number, length: number): string; getEncodedSemanticClassifications(fileName: string, start: number, length: number): string; - getCompletionsAtPosition(fileName: string, position: number): string; + getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions | undefined): string; getCompletionEntryDetails(fileName: string, position: number, entryName: string, options: string/*Services.FormatCodeOptions*/, source: string | undefined): string; getQuickInfoAtPosition(fileName: string, position: number): string; @@ -898,10 +898,10 @@ namespace ts { * to provide at the given source position and providing a member completion * list if requested. */ - public getCompletionsAtPosition(fileName: string, position: number) { + public getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions | undefined) { return this.forwardJSONCall( - `getCompletionsAtPosition('${fileName}', ${position})`, - () => this.languageService.getCompletionsAtPosition(fileName, position) + `getCompletionsAtPosition('${fileName}', ${position}, ${options})`, + () => this.languageService.getCompletionsAtPosition(fileName, position, options) ); } diff --git a/src/services/types.ts b/src/services/types.ts index 671823b86bc..a3af3dbdf63 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -237,7 +237,7 @@ namespace ts { getEncodedSyntacticClassifications(fileName: string, span: TextSpan): Classifications; getEncodedSemanticClassifications(fileName: string, span: TextSpan): Classifications; - getCompletionsAtPosition(fileName: string, position: number): CompletionInfo; + getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions | undefined): CompletionInfo; // "options" and "source" are optional only for backwards-compatibility getCompletionEntryDetails( fileName: string, @@ -310,6 +310,10 @@ namespace ts { dispose(): void; } + export interface GetCompletionsAtPositionOptions { + includeExternalModuleExports: boolean; + } + export interface ApplyCodeActionCommandResult { successMessage: string; } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index aacd4f1276d..95800d82c2e 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3933,7 +3933,7 @@ declare namespace ts { getSemanticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[]; getEncodedSyntacticClassifications(fileName: string, span: TextSpan): Classifications; getEncodedSemanticClassifications(fileName: string, span: TextSpan): Classifications; - getCompletionsAtPosition(fileName: string, position: number): CompletionInfo; + getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions | undefined): CompletionInfo; getCompletionEntryDetails(fileName: string, position: number, name: string, options: FormatCodeOptions | FormatCodeSettings | undefined, source: string | undefined): CompletionEntryDetails; getCompletionEntrySymbol(fileName: string, position: number, name: string, source: string | undefined): Symbol; getQuickInfoAtPosition(fileName: string, position: number): QuickInfo; @@ -3972,6 +3972,9 @@ declare namespace ts { getProgram(): Program; dispose(): void; } + interface GetCompletionsAtPositionOptions { + includeExternalModuleExports: boolean; + } interface ApplyCodeActionCommandResult { successMessage: string; } @@ -4622,7 +4625,7 @@ declare namespace ts { } declare namespace ts { /** The version of the language service API */ - const servicesVersion = "0.6"; + const servicesVersion = "0.7"; interface DisplayPartsSymbolWriter extends SymbolWriter { displayParts(): SymbolDisplayPart[]; } @@ -6047,6 +6050,11 @@ declare namespace ts.server.protocol { * Optional prefix to apply to possible completions. */ prefix?: string; + /** + * If enabled, TypeScript will search through all external modules' exports and add them to the completions list. + * This affects lone identifier completions but not completions on the right hand side of `obj.`. + */ + includeExternalModuleExports: boolean; } /** * Completions request; value of command field is "completions". diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 666cc34162b..62b7d4e885b 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3933,7 +3933,7 @@ declare namespace ts { getSemanticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[]; getEncodedSyntacticClassifications(fileName: string, span: TextSpan): Classifications; getEncodedSemanticClassifications(fileName: string, span: TextSpan): Classifications; - getCompletionsAtPosition(fileName: string, position: number): CompletionInfo; + getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions | undefined): CompletionInfo; getCompletionEntryDetails(fileName: string, position: number, name: string, options: FormatCodeOptions | FormatCodeSettings | undefined, source: string | undefined): CompletionEntryDetails; getCompletionEntrySymbol(fileName: string, position: number, name: string, source: string | undefined): Symbol; getQuickInfoAtPosition(fileName: string, position: number): QuickInfo; @@ -3972,6 +3972,9 @@ declare namespace ts { getProgram(): Program; dispose(): void; } + interface GetCompletionsAtPositionOptions { + includeExternalModuleExports: boolean; + } interface ApplyCodeActionCommandResult { successMessage: string; } @@ -4622,7 +4625,7 @@ declare namespace ts { } declare namespace ts { /** The version of the language service API */ - const servicesVersion = "0.6"; + const servicesVersion = "0.7"; interface DisplayPartsSymbolWriter extends SymbolWriter { displayParts(): SymbolDisplayPart[]; } diff --git a/tests/cases/fourslash/completionsImport_default_addToNamedImports.ts b/tests/cases/fourslash/completionsImport_default_addToNamedImports.ts index 734b3ff0f66..7a7a220ca77 100644 --- a/tests/cases/fourslash/completionsImport_default_addToNamedImports.ts +++ b/tests/cases/fourslash/completionsImport_default_addToNamedImports.ts @@ -9,7 +9,7 @@ ////f/**/; goTo.marker(""); -verify.completionListContains({ name: "foo", source: "/a" }, "function foo(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true); +verify.completionListContains({ name: "foo", source: "/a" }, "function foo(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true, { includeExternalModuleExports: true }); verify.applyCodeActionFromCompletion("", { name: "foo", diff --git a/tests/cases/fourslash/completionsImport_default_addToNamespaceImport.ts b/tests/cases/fourslash/completionsImport_default_addToNamespaceImport.ts index d4a81bc5272..43e3854c5e3 100644 --- a/tests/cases/fourslash/completionsImport_default_addToNamespaceImport.ts +++ b/tests/cases/fourslash/completionsImport_default_addToNamespaceImport.ts @@ -8,7 +8,7 @@ ////f/**/; goTo.marker(""); -verify.completionListContains({ name: "foo", source: "/a" }, "function foo(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true); +verify.completionListContains({ name: "foo", source: "/a" }, "function foo(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true, { includeExternalModuleExports: true }); verify.applyCodeActionFromCompletion("", { name: "foo", diff --git a/tests/cases/fourslash/completionsImport_default_alreadyExistedWithRename.ts b/tests/cases/fourslash/completionsImport_default_alreadyExistedWithRename.ts index f49f5850043..ed34d5e4e9c 100644 --- a/tests/cases/fourslash/completionsImport_default_alreadyExistedWithRename.ts +++ b/tests/cases/fourslash/completionsImport_default_alreadyExistedWithRename.ts @@ -8,7 +8,7 @@ ////f/**/; goTo.marker(""); -verify.completionListContains({ name: "foo", source: "/a" }, "function foo(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true); +verify.completionListContains({ name: "foo", source: "/a" }, "function foo(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true, { includeExternalModuleExports: true }); verify.applyCodeActionFromCompletion("", { name: "foo", diff --git a/tests/cases/fourslash/completionsImport_default_didNotExistBefore.ts b/tests/cases/fourslash/completionsImport_default_didNotExistBefore.ts index fb4d65a1c52..82b8e92a570 100644 --- a/tests/cases/fourslash/completionsImport_default_didNotExistBefore.ts +++ b/tests/cases/fourslash/completionsImport_default_didNotExistBefore.ts @@ -7,7 +7,7 @@ ////f/**/; goTo.marker(""); -verify.completionListContains({ name: "foo", source: "/a" }, "function foo(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true); +verify.completionListContains({ name: "foo", source: "/a" }, "function foo(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true, { includeExternalModuleExports: true }); verify.applyCodeActionFromCompletion("", { name: "foo", diff --git a/tests/cases/fourslash/completionsImport_matching.ts b/tests/cases/fourslash/completionsImport_matching.ts index edecf3592cd..f5f9108fa6c 100644 --- a/tests/cases/fourslash/completionsImport_matching.ts +++ b/tests/cases/fourslash/completionsImport_matching.ts @@ -14,9 +14,10 @@ goTo.marker(""); -verify.not.completionListContains({ name: "abcde", source: "/a" }); -verify.not.completionListContains({ name: "dbf", source: "/a" }); +const options = { includeExternalModuleExports: true }; +verify.not.completionListContains({ name: "abcde", source: "/a" }, undefined, undefined, undefined, undefined, undefined, options); +verify.not.completionListContains({ name: "dbf", source: "/a" }, undefined, undefined, undefined, undefined, undefined, options); -verify.completionListContains({ name: "bdf", source: "/a" }, "function bdf(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true); -verify.completionListContains({ name: "abcdef", source: "/a" }, "function abcdef(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true); -verify.completionListContains({ name: "BDF", source: "/a" }, "function BDF(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true); +verify.completionListContains({ name: "bdf", source: "/a" }, "function bdf(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true, options); +verify.completionListContains({ name: "abcdef", source: "/a" }, "function abcdef(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true, options); +verify.completionListContains({ name: "BDF", source: "/a" }, "function BDF(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true, options); diff --git a/tests/cases/fourslash/completionsImport_multipleWithSameName.ts b/tests/cases/fourslash/completionsImport_multipleWithSameName.ts index 825a4ca0a97..c9bb33d6c79 100644 --- a/tests/cases/fourslash/completionsImport_multipleWithSameName.ts +++ b/tests/cases/fourslash/completionsImport_multipleWithSameName.ts @@ -14,9 +14,10 @@ ////fo/**/ goTo.marker(""); -verify.completionListContains("foo", "var foo: number", "", "var"); -verify.completionListContains({ name: "foo", source: "/a" }, "const foo: 0", "", "const", /*spanIndex*/ undefined, /*hasAction*/ true); -verify.completionListContains({ name: "foo", source: "/b" }, "const foo: 1", "", "const", /*spanIndex*/ undefined, /*hasAction*/ true); +const options = { includeExternalModuleExports: true }; +verify.completionListContains("foo", "var foo: number", "", "var", undefined, undefined, options); +verify.completionListContains({ name: "foo", source: "/a" }, "const foo: 0", "", "const", /*spanIndex*/ undefined, /*hasAction*/ true, options); +verify.completionListContains({ name: "foo", source: "/b" }, "const foo: 1", "", "const", /*spanIndex*/ undefined, /*hasAction*/ true, options); verify.applyCodeActionFromCompletion("", { name: "foo", diff --git a/tests/cases/fourslash/completionsImport_named_addToNamedImports.ts b/tests/cases/fourslash/completionsImport_named_addToNamedImports.ts index 5444b25692a..b11552d0327 100644 --- a/tests/cases/fourslash/completionsImport_named_addToNamedImports.ts +++ b/tests/cases/fourslash/completionsImport_named_addToNamedImports.ts @@ -9,7 +9,7 @@ ////f/**/; goTo.marker(""); -verify.completionListContains({ name: "foo", source: "/a" }, "function foo(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true); +verify.completionListContains({ name: "foo", source: "/a" }, "function foo(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true, { includeExternalModuleExports: true }); verify.applyCodeActionFromCompletion("", { name: "foo", diff --git a/tests/cases/fourslash/completionsImport_named_didNotExistBefore.ts b/tests/cases/fourslash/completionsImport_named_didNotExistBefore.ts index 809e40e7cf2..9397ee004c2 100644 --- a/tests/cases/fourslash/completionsImport_named_didNotExistBefore.ts +++ b/tests/cases/fourslash/completionsImport_named_didNotExistBefore.ts @@ -9,9 +9,10 @@ ////t/**/ goTo.marker(""); -verify.completionListContains({ name: "Test1", source: "/a" }, "function Test1(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true); -verify.completionListContains("Test2", "import Test2", "", "alias", /*spanIndex*/ undefined, /*hasAction*/ undefined); -verify.not.completionListContains({ name: "Test2", source: "/a" }); +const options = { includeExternalModuleExports: true }; +verify.completionListContains({ name: "Test1", source: "/a" }, "function Test1(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true, options); +verify.completionListContains("Test2", "import Test2", "", "alias", /*spanIndex*/ undefined, /*hasAction*/ undefined, options); +verify.not.completionListContains({ name: "Test2", source: "/a" }, undefined, undefined, undefined, undefined, undefined, options); verify.applyCodeActionFromCompletion("", { name: "Test1", diff --git a/tests/cases/fourslash/completionsImport_named_namespaceImportExists.ts b/tests/cases/fourslash/completionsImport_named_namespaceImportExists.ts index 70cd75a4e41..d4602795280 100644 --- a/tests/cases/fourslash/completionsImport_named_namespaceImportExists.ts +++ b/tests/cases/fourslash/completionsImport_named_namespaceImportExists.ts @@ -8,7 +8,7 @@ ////f/**/; goTo.marker(""); -verify.completionListContains({ name: "foo", source: "/a" }, "function foo(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true); +verify.completionListContains({ name: "foo", source: "/a" }, "function foo(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true, { includeExternalModuleExports: true }); verify.applyCodeActionFromCompletion("", { name: "foo", diff --git a/tests/cases/fourslash/completionsImport_ofAlias.ts b/tests/cases/fourslash/completionsImport_ofAlias.ts index 27bc29fa210..e7cdb366497 100644 --- a/tests/cases/fourslash/completionsImport_ofAlias.ts +++ b/tests/cases/fourslash/completionsImport_ofAlias.ts @@ -15,9 +15,10 @@ ////fo/**/ goTo.marker(""); -// https://github.com/Microsoft/TypeScript/issues/14003 -verify.completionListContains({ name: "foo", source: "/a" }, "import foo", "", "alias", /*spanIndex*/ undefined, /*hasAction*/ true); -verify.not.completionListContains({ name: "foo", source: "/a_reexport" }); +const options = { includeExternalModuleExports: true }; +// TODO: https://github.com/Microsoft/TypeScript/issues/14003 +verify.completionListContains({ name: "foo", source: "/a" }, "import foo", "", "alias", /*spanIndex*/ undefined, /*hasAction*/ true, options); +verify.not.completionListContains({ name: "foo", source: "/a_reexport" }, undefined, undefined, undefined, undefined, undefined, options); verify.applyCodeActionFromCompletion("", { name: "foo", diff --git a/tests/cases/fourslash/completionsImport_previousTokenIsSemicolon.ts b/tests/cases/fourslash/completionsImport_previousTokenIsSemicolon.ts index 5eddb5037c1..93c2cc01b0b 100644 --- a/tests/cases/fourslash/completionsImport_previousTokenIsSemicolon.ts +++ b/tests/cases/fourslash/completionsImport_previousTokenIsSemicolon.ts @@ -8,4 +8,4 @@ /////**/ goTo.marker(""); -verify.completionListContains({ name: "foo", source: "/a" }, "function foo(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true); +verify.completionListContains({ name: "foo", source: "/a" }, "function foo(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true, { includeExternalModuleExports: true }); diff --git a/tests/cases/fourslash/completionsImport_shadowedByLocal.ts b/tests/cases/fourslash/completionsImport_shadowedByLocal.ts index d35a021acc7..20e8c4a4bc8 100644 --- a/tests/cases/fourslash/completionsImport_shadowedByLocal.ts +++ b/tests/cases/fourslash/completionsImport_shadowedByLocal.ts @@ -8,5 +8,6 @@ ////fo/**/ goTo.marker(""); -verify.completionListContains("foo", "const foo: 1", "", "const"); -verify.not.completionListContains({ name: "foo", source: "/a" }); +const options = { includeExternalModuleExports: true }; +verify.completionListContains("foo", "const foo: 1", "", "const", undefined, undefined, options); +verify.not.completionListContains({ name: "foo", source: "/a" }, undefined, undefined, undefined, undefined, undefined, options); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 9eca1d64565..a0ee392a82e 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -148,6 +148,7 @@ declare namespace FourSlashInterface { kind?: string, spanIndex?: number, hasAction?: boolean, + options?: { includeExternalModuleExports: boolean }, ): void; completionListItemsCountIsGreaterThan(count: number): void; completionListIsEmpty(): void; From d2114e1b9eb8cfc6fabeb6b775b1aa3e29625027 Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Fri, 3 Nov 2017 16:14:47 -0700 Subject: [PATCH 116/235] Rename offsets in tests --- .../docCommentTemplateClassDeclMethods01.ts | 18 ++++++++---------- .../docCommentTemplateClassDeclMethods02.ts | 10 ++++------ ...docCommentTemplateObjectLiteralMethods01.ts | 10 ++++------ 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/tests/cases/fourslash/docCommentTemplateClassDeclMethods01.ts b/tests/cases/fourslash/docCommentTemplateClassDeclMethods01.ts index 34e55875676..2e729243497 100644 --- a/tests/cases/fourslash/docCommentTemplateClassDeclMethods01.ts +++ b/tests/cases/fourslash/docCommentTemplateClassDeclMethods01.ts @@ -1,9 +1,7 @@ /// -const enum Indentation { - Standard = 3, - Indented = 12, -} +const singleLineOffset = 3; +const multiLineOffset = 12; ////class C { @@ -16,22 +14,22 @@ const enum Indentation { //// } ////} -verify.docCommentTemplateAt("0", Indentation.Standard, +verify.docCommentTemplateAt("0", singleLineOffset, "/** */"); -verify.docCommentTemplateAt("1", Indentation.Standard, +verify.docCommentTemplateAt("1", singleLineOffset, "/** */"); -verify.docCommentTemplateAt("2", Indentation.Indented, +verify.docCommentTemplateAt("2", multiLineOffset, `/** * * @param a */ `); -verify.docCommentTemplateAt("3", Indentation.Indented, +verify.docCommentTemplateAt("3", multiLineOffset, `/** * * @param a @@ -39,7 +37,7 @@ verify.docCommentTemplateAt("3", Indentation.Indented, */ `); -verify.docCommentTemplateAt("4", Indentation.Indented, +verify.docCommentTemplateAt("4", multiLineOffset, `/** * * @param a @@ -47,7 +45,7 @@ verify.docCommentTemplateAt("4", Indentation.Indented, * @param param2 */`); -verify.docCommentTemplateAt("5", Indentation.Indented, +verify.docCommentTemplateAt("5", multiLineOffset, `/** * * @param a diff --git a/tests/cases/fourslash/docCommentTemplateClassDeclMethods02.ts b/tests/cases/fourslash/docCommentTemplateClassDeclMethods02.ts index a16fbd86064..7a35e60ae9e 100644 --- a/tests/cases/fourslash/docCommentTemplateClassDeclMethods02.ts +++ b/tests/cases/fourslash/docCommentTemplateClassDeclMethods02.ts @@ -1,9 +1,7 @@ /// -const enum Indentation { - Standard = 3, - Indented = 12, -} +const singleLineOffset = 3; +const multiLineOffset = 12; ////class C { //// /*0*/ @@ -14,10 +12,10 @@ const enum Indentation { //// [1 + 2 + 3 + Math.rand()](x: number, y: string, z = true) { } ////} -verify.docCommentTemplateAt("0", Indentation.Standard, +verify.docCommentTemplateAt("0", singleLineOffset, "/** */"); -verify.docCommentTemplateAt("1", Indentation.Indented, +verify.docCommentTemplateAt("1", multiLineOffset, `/** * * @param x diff --git a/tests/cases/fourslash/docCommentTemplateObjectLiteralMethods01.ts b/tests/cases/fourslash/docCommentTemplateObjectLiteralMethods01.ts index 7fb6156be17..5121957a718 100644 --- a/tests/cases/fourslash/docCommentTemplateObjectLiteralMethods01.ts +++ b/tests/cases/fourslash/docCommentTemplateObjectLiteralMethods01.ts @@ -1,9 +1,7 @@ /// -const enum Indentation { - Standard = 3, - Indented = 12, -} +const singleLineOffset = 3; +const multiLineOffset = 12; ////var x = { //// /*0*/ @@ -14,10 +12,10 @@ const enum Indentation { //// [1 + 2 + 3 + Math.rand()](x: number, y: string, z = true) { } ////} -verify.docCommentTemplateAt("0", Indentation.Standard, +verify.docCommentTemplateAt("0", singleLineOffset, "/** */"); -verify.docCommentTemplateAt("1", Indentation.Indented, +verify.docCommentTemplateAt("1", multiLineOffset, `/** * * @param x From 845c06692394ea828f24b0264c9a3958d4f6b577 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 3 Nov 2017 17:46:19 -0700 Subject: [PATCH 117/235] Check for unused locals in commonjs modules (#19612) --- src/compiler/checker.ts | 2 +- .../reference/commonJsUnusedLocals.errors.txt | 9 +++++++++ .../baselines/reference/commonJsUnusedLocals.symbols | 9 +++++++++ tests/baselines/reference/commonJsUnusedLocals.types | 12 ++++++++++++ tests/cases/compiler/commonJsUnusedLocals.ts | 8 ++++++++ 5 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/commonJsUnusedLocals.errors.txt create mode 100644 tests/baselines/reference/commonJsUnusedLocals.symbols create mode 100644 tests/baselines/reference/commonJsUnusedLocals.types create mode 100644 tests/cases/compiler/commonJsUnusedLocals.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b598be408c1..e2e45b2ccb0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -23158,7 +23158,7 @@ namespace ts { checkDeferredNodes(); - if (isExternalModule(node)) { + if (isExternalOrCommonJsModule(node)) { registerForUnusedIdentifiersCheck(node); } diff --git a/tests/baselines/reference/commonJsUnusedLocals.errors.txt b/tests/baselines/reference/commonJsUnusedLocals.errors.txt new file mode 100644 index 00000000000..b8e2159d432 --- /dev/null +++ b/tests/baselines/reference/commonJsUnusedLocals.errors.txt @@ -0,0 +1,9 @@ +/a.js(1,7): error TS6133: 'x' is declared but its value is never read. + + +==== /a.js (1 errors) ==== + const x = 0; + ~ +!!! error TS6133: 'x' is declared but its value is never read. + exports.y = 1; + \ No newline at end of file diff --git a/tests/baselines/reference/commonJsUnusedLocals.symbols b/tests/baselines/reference/commonJsUnusedLocals.symbols new file mode 100644 index 00000000000..08155bc4d26 --- /dev/null +++ b/tests/baselines/reference/commonJsUnusedLocals.symbols @@ -0,0 +1,9 @@ +=== /a.js === +const x = 0; +>x : Symbol(x, Decl(a.js, 0, 5)) + +exports.y = 1; +>exports.y : Symbol(y, Decl(a.js, 0, 12)) +>exports : Symbol(y, Decl(a.js, 0, 12)) +>y : Symbol(y, Decl(a.js, 0, 12)) + diff --git a/tests/baselines/reference/commonJsUnusedLocals.types b/tests/baselines/reference/commonJsUnusedLocals.types new file mode 100644 index 00000000000..e792ad8e782 --- /dev/null +++ b/tests/baselines/reference/commonJsUnusedLocals.types @@ -0,0 +1,12 @@ +=== /a.js === +const x = 0; +>x : 0 +>0 : 0 + +exports.y = 1; +>exports.y = 1 : 1 +>exports.y : number +>exports : typeof "/a" +>y : number +>1 : 1 + diff --git a/tests/cases/compiler/commonJsUnusedLocals.ts b/tests/cases/compiler/commonJsUnusedLocals.ts new file mode 100644 index 00000000000..d1b51aa245b --- /dev/null +++ b/tests/cases/compiler/commonJsUnusedLocals.ts @@ -0,0 +1,8 @@ +// @noUnusedLocals: true +// @allowJs: true +// @checkJs: true +// @noEmit: true + +// @Filename: /a.js +const x = 0; +exports.y = 1; From 8d5b0529b2bb7650d471b4d64fd88061cde4707d Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 3 Nov 2017 18:14:21 -0700 Subject: [PATCH 118/235] Add localizable diagnostic for "Install '{0}'" (#19651) --- src/compiler/diagnosticMessages.json | 4 ++++ src/services/codefixes/fixCannotFindModule.ts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 2309977539c..d3669ce397d 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3797,5 +3797,9 @@ "Convert to default import": { "category": "Message", "code": 95013 + }, + "Install '{0}'": { + "category": "Message", + "code": 95014 } } diff --git a/src/services/codefixes/fixCannotFindModule.ts b/src/services/codefixes/fixCannotFindModule.ts index c15ca341cb4..29f2475f21d 100644 --- a/src/services/codefixes/fixCannotFindModule.ts +++ b/src/services/codefixes/fixCannotFindModule.ts @@ -26,7 +26,7 @@ namespace ts.codefix { const typesPackageName = getTypesPackageName(packageName); return { - description: `Install '${typesPackageName}'`, + description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Install_0), [typesPackageName]), changes: [], commands: [{ type: "install package", packageName: typesPackageName }], }; From ed914a8d4755d8152040648faf25f8c65e01f1b9 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 3 Nov 2017 23:53:13 -0700 Subject: [PATCH 119/235] Fix new lint error --- src/compiler/core.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 296a203a704..2113256346d 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1627,7 +1627,7 @@ namespace ts { /** * Creates a string comparer for use with string collation in the UI. */ - const createUIStringComparer = (function () { + const createUIStringComparer = (() => { let defaultComparer: Comparer | undefined; let enUSComparer: Comparer | undefined; From 45c53e0dccdd20ba181111bcdd4491b3e37779fa Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 4 Nov 2017 08:08:05 -0700 Subject: [PATCH 120/235] Check combined modifiers in mappedTypeRelatedTo --- src/compiler/checker.ts | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b598be408c1..1229a0dcf43 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -529,6 +529,11 @@ namespace ts { Strict, } + const enum MappedTypeModifiers { + Readonly = 1 << 0, + Optional = 1 << 1, + } + const builtinGlobals = createSymbolTable(); builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol); @@ -5875,6 +5880,17 @@ namespace ts { return type.modifiersType; } + function getMappedTypeModifiers(type: MappedType): MappedTypeModifiers { + return (type.declaration.readonlyToken ? MappedTypeModifiers.Readonly : 0) | + (type.declaration.questionToken ? MappedTypeModifiers.Optional : 0); + } + + function getCombinedMappedTypeModifiers(type: MappedType): MappedTypeModifiers { + const modifiersType = getModifiersTypeFromMappedType(type); + return getMappedTypeModifiers(type) | + (isGenericMappedType(modifiersType) ? getMappedTypeModifiers(modifiersType) : 0); + } + function isPartialMappedType(type: Type) { return getObjectFlags(type) & ObjectFlags.Mapped && !!(type).declaration.questionToken; } @@ -9592,13 +9608,10 @@ namespace ts { // related to Y, where X' is an instantiation of X in which P is replaced with Q. Notice // that S and T are contra-variant whereas X and Y are co-variant. function mappedTypeRelatedTo(source: MappedType, target: MappedType, reportErrors: boolean): Ternary { - const sourceReadonly = !!source.declaration.readonlyToken; - const sourceOptional = !!source.declaration.questionToken; - const targetReadonly = !!target.declaration.readonlyToken; - const targetOptional = !!target.declaration.questionToken; - const modifiersRelated = relation === identityRelation ? - sourceReadonly === targetReadonly && sourceOptional === targetOptional : - relation === comparableRelation || !sourceOptional || targetOptional; + const modifiersRelated = relation === comparableRelation || ( + relation === identityRelation ? getMappedTypeModifiers(source) === getMappedTypeModifiers(target) : + !(getCombinedMappedTypeModifiers(source) & MappedTypeModifiers.Optional) || + getCombinedMappedTypeModifiers(target) & MappedTypeModifiers.Optional); if (modifiersRelated) { let result: Ternary; if (result = isRelatedTo(getConstraintTypeFromMappedType(target), getConstraintTypeFromMappedType(source), reportErrors)) { From 9619dc14f963ba48b1e867230809a8233a9dcab5 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 4 Nov 2017 08:08:28 -0700 Subject: [PATCH 121/235] Add tests --- .../reference/mappedTypes5.errors.txt | 73 +++++ tests/baselines/reference/mappedTypes5.js | 95 ++++++ .../baselines/reference/mappedTypes5.symbols | 279 +++++++++++++++++ tests/baselines/reference/mappedTypes5.types | 292 ++++++++++++++++++ .../conformance/types/mapped/mappedTypes5.ts | 62 ++++ 5 files changed, 801 insertions(+) create mode 100644 tests/baselines/reference/mappedTypes5.errors.txt create mode 100644 tests/baselines/reference/mappedTypes5.js create mode 100644 tests/baselines/reference/mappedTypes5.symbols create mode 100644 tests/baselines/reference/mappedTypes5.types create mode 100644 tests/cases/conformance/types/mapped/mappedTypes5.ts diff --git a/tests/baselines/reference/mappedTypes5.errors.txt b/tests/baselines/reference/mappedTypes5.errors.txt new file mode 100644 index 00000000000..d0c32cd1dd9 --- /dev/null +++ b/tests/baselines/reference/mappedTypes5.errors.txt @@ -0,0 +1,73 @@ +tests/cases/conformance/types/mapped/mappedTypes5.ts(6,9): error TS2322: Type 'Partial' is not assignable to type 'Readonly'. +tests/cases/conformance/types/mapped/mappedTypes5.ts(8,9): error TS2322: Type 'Partial>' is not assignable to type 'Readonly'. +tests/cases/conformance/types/mapped/mappedTypes5.ts(9,9): error TS2322: Type 'Readonly>' is not assignable to type 'Readonly'. + + +==== tests/cases/conformance/types/mapped/mappedTypes5.ts (3 errors) ==== + function f(p: Partial, r: Readonly, pr: Partial>, rp: Readonly>) { + let a1: Partial = p; + let a2: Partial = r; + let a3: Partial = pr; + let a4: Partial = rp; + let b1: Readonly = p; // Error + ~~ +!!! error TS2322: Type 'Partial' is not assignable to type 'Readonly'. + let b2: Readonly = r; + let b3: Readonly = pr; // Error + ~~ +!!! error TS2322: Type 'Partial>' is not assignable to type 'Readonly'. + let b4: Readonly = rp; // Error + ~~ +!!! error TS2322: Type 'Readonly>' is not assignable to type 'Readonly'. + let c1: Partial> = p; + let c2: Partial> = r; + let c3: Partial> = pr; + let c4: Partial> = rp; + let d1: Readonly> = p; + let d2: Readonly> = r; + let d3: Readonly> = pr; + let d4: Readonly> = rp; + } + + // Repro from #17682 + + type State = { + [key: string]: string | boolean | number | null; + }; + + type Args1 = { + readonly previous: Readonly>; + readonly current: Readonly>; + }; + + type Args2 = { + readonly previous: Partial>; + readonly current: Partial>; + }; + + function doit() { + let previous: Partial = Object.create(null); + let current: Partial = Object.create(null); + let args1: Args1 = { previous, current }; + let args2: Args2 = { previous, current }; + } + + type State2 = { foo: number, bar: string }; + + type Args3 = { + readonly previous: Readonly>; + readonly current: Readonly>; + }; + + type Args4 = { + readonly previous: Partial>; + readonly current: Partial>; + }; + + function doit2() { + let previous: Partial = Object.create(null); + let current: Partial = Object.create(null); + let args1: Args3 = { previous, current }; + let args2: Args4 = { previous, current }; + } + \ No newline at end of file diff --git a/tests/baselines/reference/mappedTypes5.js b/tests/baselines/reference/mappedTypes5.js new file mode 100644 index 00000000000..6f20b71ed7b --- /dev/null +++ b/tests/baselines/reference/mappedTypes5.js @@ -0,0 +1,95 @@ +//// [mappedTypes5.ts] +function f(p: Partial, r: Readonly, pr: Partial>, rp: Readonly>) { + let a1: Partial = p; + let a2: Partial = r; + let a3: Partial = pr; + let a4: Partial = rp; + let b1: Readonly = p; // Error + let b2: Readonly = r; + let b3: Readonly = pr; // Error + let b4: Readonly = rp; // Error + let c1: Partial> = p; + let c2: Partial> = r; + let c3: Partial> = pr; + let c4: Partial> = rp; + let d1: Readonly> = p; + let d2: Readonly> = r; + let d3: Readonly> = pr; + let d4: Readonly> = rp; +} + +// Repro from #17682 + +type State = { + [key: string]: string | boolean | number | null; +}; + +type Args1 = { + readonly previous: Readonly>; + readonly current: Readonly>; +}; + +type Args2 = { + readonly previous: Partial>; + readonly current: Partial>; +}; + +function doit() { + let previous: Partial = Object.create(null); + let current: Partial = Object.create(null); + let args1: Args1 = { previous, current }; + let args2: Args2 = { previous, current }; +} + +type State2 = { foo: number, bar: string }; + +type Args3 = { + readonly previous: Readonly>; + readonly current: Readonly>; +}; + +type Args4 = { + readonly previous: Partial>; + readonly current: Partial>; +}; + +function doit2() { + let previous: Partial = Object.create(null); + let current: Partial = Object.create(null); + let args1: Args3 = { previous, current }; + let args2: Args4 = { previous, current }; +} + + +//// [mappedTypes5.js] +"use strict"; +function f(p, r, pr, rp) { + var a1 = p; + var a2 = r; + var a3 = pr; + var a4 = rp; + var b1 = p; // Error + var b2 = r; + var b3 = pr; // Error + var b4 = rp; // Error + var c1 = p; + var c2 = r; + var c3 = pr; + var c4 = rp; + var d1 = p; + var d2 = r; + var d3 = pr; + var d4 = rp; +} +function doit() { + var previous = Object.create(null); + var current = Object.create(null); + var args1 = { previous: previous, current: current }; + var args2 = { previous: previous, current: current }; +} +function doit2() { + var previous = Object.create(null); + var current = Object.create(null); + var args1 = { previous: previous, current: current }; + var args2 = { previous: previous, current: current }; +} diff --git a/tests/baselines/reference/mappedTypes5.symbols b/tests/baselines/reference/mappedTypes5.symbols new file mode 100644 index 00000000000..7a499c4c4e9 --- /dev/null +++ b/tests/baselines/reference/mappedTypes5.symbols @@ -0,0 +1,279 @@ +=== tests/cases/conformance/types/mapped/mappedTypes5.ts === +function f(p: Partial, r: Readonly, pr: Partial>, rp: Readonly>) { +>f : Symbol(f, Decl(mappedTypes5.ts, 0, 0)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>p : Symbol(p, Decl(mappedTypes5.ts, 0, 14)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>r : Symbol(r, Decl(mappedTypes5.ts, 0, 28)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>pr : Symbol(pr, Decl(mappedTypes5.ts, 0, 44)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>rp : Symbol(rp, Decl(mappedTypes5.ts, 0, 70)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) + + let a1: Partial = p; +>a1 : Symbol(a1, Decl(mappedTypes5.ts, 1, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>p : Symbol(p, Decl(mappedTypes5.ts, 0, 14)) + + let a2: Partial = r; +>a2 : Symbol(a2, Decl(mappedTypes5.ts, 2, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>r : Symbol(r, Decl(mappedTypes5.ts, 0, 28)) + + let a3: Partial = pr; +>a3 : Symbol(a3, Decl(mappedTypes5.ts, 3, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>pr : Symbol(pr, Decl(mappedTypes5.ts, 0, 44)) + + let a4: Partial = rp; +>a4 : Symbol(a4, Decl(mappedTypes5.ts, 4, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>rp : Symbol(rp, Decl(mappedTypes5.ts, 0, 70)) + + let b1: Readonly = p; // Error +>b1 : Symbol(b1, Decl(mappedTypes5.ts, 5, 7)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>p : Symbol(p, Decl(mappedTypes5.ts, 0, 14)) + + let b2: Readonly = r; +>b2 : Symbol(b2, Decl(mappedTypes5.ts, 6, 7)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>r : Symbol(r, Decl(mappedTypes5.ts, 0, 28)) + + let b3: Readonly = pr; // Error +>b3 : Symbol(b3, Decl(mappedTypes5.ts, 7, 7)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>pr : Symbol(pr, Decl(mappedTypes5.ts, 0, 44)) + + let b4: Readonly = rp; // Error +>b4 : Symbol(b4, Decl(mappedTypes5.ts, 8, 7)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>rp : Symbol(rp, Decl(mappedTypes5.ts, 0, 70)) + + let c1: Partial> = p; +>c1 : Symbol(c1, Decl(mappedTypes5.ts, 9, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>p : Symbol(p, Decl(mappedTypes5.ts, 0, 14)) + + let c2: Partial> = r; +>c2 : Symbol(c2, Decl(mappedTypes5.ts, 10, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>r : Symbol(r, Decl(mappedTypes5.ts, 0, 28)) + + let c3: Partial> = pr; +>c3 : Symbol(c3, Decl(mappedTypes5.ts, 11, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>pr : Symbol(pr, Decl(mappedTypes5.ts, 0, 44)) + + let c4: Partial> = rp; +>c4 : Symbol(c4, Decl(mappedTypes5.ts, 12, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>rp : Symbol(rp, Decl(mappedTypes5.ts, 0, 70)) + + let d1: Readonly> = p; +>d1 : Symbol(d1, Decl(mappedTypes5.ts, 13, 7)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>p : Symbol(p, Decl(mappedTypes5.ts, 0, 14)) + + let d2: Readonly> = r; +>d2 : Symbol(d2, Decl(mappedTypes5.ts, 14, 7)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>r : Symbol(r, Decl(mappedTypes5.ts, 0, 28)) + + let d3: Readonly> = pr; +>d3 : Symbol(d3, Decl(mappedTypes5.ts, 15, 7)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>pr : Symbol(pr, Decl(mappedTypes5.ts, 0, 44)) + + let d4: Readonly> = rp; +>d4 : Symbol(d4, Decl(mappedTypes5.ts, 16, 7)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>rp : Symbol(rp, Decl(mappedTypes5.ts, 0, 70)) +} + +// Repro from #17682 + +type State = { +>State : Symbol(State, Decl(mappedTypes5.ts, 17, 1)) + + [key: string]: string | boolean | number | null; +>key : Symbol(key, Decl(mappedTypes5.ts, 22, 5)) + +}; + +type Args1 = { +>Args1 : Symbol(Args1, Decl(mappedTypes5.ts, 23, 2)) +>T : Symbol(T, Decl(mappedTypes5.ts, 25, 11)) +>State : Symbol(State, Decl(mappedTypes5.ts, 17, 1)) + + readonly previous: Readonly>; +>previous : Symbol(previous, Decl(mappedTypes5.ts, 25, 31)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 25, 11)) + + readonly current: Readonly>; +>current : Symbol(current, Decl(mappedTypes5.ts, 26, 44)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 25, 11)) + +}; + +type Args2 = { +>Args2 : Symbol(Args2, Decl(mappedTypes5.ts, 28, 2)) +>T : Symbol(T, Decl(mappedTypes5.ts, 30, 11)) +>State : Symbol(State, Decl(mappedTypes5.ts, 17, 1)) + + readonly previous: Partial>; +>previous : Symbol(previous, Decl(mappedTypes5.ts, 30, 31)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 30, 11)) + + readonly current: Partial>; +>current : Symbol(current, Decl(mappedTypes5.ts, 31, 44)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 30, 11)) + +}; + +function doit() { +>doit : Symbol(doit, Decl(mappedTypes5.ts, 33, 2)) +>T : Symbol(T, Decl(mappedTypes5.ts, 35, 14)) +>State : Symbol(State, Decl(mappedTypes5.ts, 17, 1)) + + let previous: Partial = Object.create(null); +>previous : Symbol(previous, Decl(mappedTypes5.ts, 36, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 35, 14)) +>Object.create : Symbol(ObjectConstructor.create, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>create : Symbol(ObjectConstructor.create, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + let current: Partial = Object.create(null); +>current : Symbol(current, Decl(mappedTypes5.ts, 37, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 35, 14)) +>Object.create : Symbol(ObjectConstructor.create, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>create : Symbol(ObjectConstructor.create, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + let args1: Args1 = { previous, current }; +>args1 : Symbol(args1, Decl(mappedTypes5.ts, 38, 7)) +>Args1 : Symbol(Args1, Decl(mappedTypes5.ts, 23, 2)) +>T : Symbol(T, Decl(mappedTypes5.ts, 35, 14)) +>previous : Symbol(previous, Decl(mappedTypes5.ts, 38, 27)) +>current : Symbol(current, Decl(mappedTypes5.ts, 38, 37)) + + let args2: Args2 = { previous, current }; +>args2 : Symbol(args2, Decl(mappedTypes5.ts, 39, 7)) +>Args2 : Symbol(Args2, Decl(mappedTypes5.ts, 28, 2)) +>T : Symbol(T, Decl(mappedTypes5.ts, 35, 14)) +>previous : Symbol(previous, Decl(mappedTypes5.ts, 39, 27)) +>current : Symbol(current, Decl(mappedTypes5.ts, 39, 37)) +} + +type State2 = { foo: number, bar: string }; +>State2 : Symbol(State2, Decl(mappedTypes5.ts, 40, 1)) +>foo : Symbol(foo, Decl(mappedTypes5.ts, 42, 15)) +>bar : Symbol(bar, Decl(mappedTypes5.ts, 42, 28)) + +type Args3 = { +>Args3 : Symbol(Args3, Decl(mappedTypes5.ts, 42, 43)) + + readonly previous: Readonly>; +>previous : Symbol(previous, Decl(mappedTypes5.ts, 44, 14)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>State2 : Symbol(State2, Decl(mappedTypes5.ts, 40, 1)) + + readonly current: Readonly>; +>current : Symbol(current, Decl(mappedTypes5.ts, 45, 49)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>State2 : Symbol(State2, Decl(mappedTypes5.ts, 40, 1)) + +}; + +type Args4 = { +>Args4 : Symbol(Args4, Decl(mappedTypes5.ts, 47, 2)) + + readonly previous: Partial>; +>previous : Symbol(previous, Decl(mappedTypes5.ts, 49, 14)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>State2 : Symbol(State2, Decl(mappedTypes5.ts, 40, 1)) + + readonly current: Partial>; +>current : Symbol(current, Decl(mappedTypes5.ts, 50, 49)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>State2 : Symbol(State2, Decl(mappedTypes5.ts, 40, 1)) + +}; + +function doit2() { +>doit2 : Symbol(doit2, Decl(mappedTypes5.ts, 52, 2)) + + let previous: Partial = Object.create(null); +>previous : Symbol(previous, Decl(mappedTypes5.ts, 55, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>State2 : Symbol(State2, Decl(mappedTypes5.ts, 40, 1)) +>Object.create : Symbol(ObjectConstructor.create, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>create : Symbol(ObjectConstructor.create, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + let current: Partial = Object.create(null); +>current : Symbol(current, Decl(mappedTypes5.ts, 56, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>State2 : Symbol(State2, Decl(mappedTypes5.ts, 40, 1)) +>Object.create : Symbol(ObjectConstructor.create, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>create : Symbol(ObjectConstructor.create, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + let args1: Args3 = { previous, current }; +>args1 : Symbol(args1, Decl(mappedTypes5.ts, 57, 7)) +>Args3 : Symbol(Args3, Decl(mappedTypes5.ts, 42, 43)) +>previous : Symbol(previous, Decl(mappedTypes5.ts, 57, 24)) +>current : Symbol(current, Decl(mappedTypes5.ts, 57, 34)) + + let args2: Args4 = { previous, current }; +>args2 : Symbol(args2, Decl(mappedTypes5.ts, 58, 7)) +>Args4 : Symbol(Args4, Decl(mappedTypes5.ts, 47, 2)) +>previous : Symbol(previous, Decl(mappedTypes5.ts, 58, 24)) +>current : Symbol(current, Decl(mappedTypes5.ts, 58, 34)) +} + diff --git a/tests/baselines/reference/mappedTypes5.types b/tests/baselines/reference/mappedTypes5.types new file mode 100644 index 00000000000..2cbc66523e2 --- /dev/null +++ b/tests/baselines/reference/mappedTypes5.types @@ -0,0 +1,292 @@ +=== tests/cases/conformance/types/mapped/mappedTypes5.ts === +function f(p: Partial, r: Readonly, pr: Partial>, rp: Readonly>) { +>f : (p: Partial, r: Readonly, pr: Partial>, rp: Readonly>) => void +>T : T +>p : Partial +>Partial : Partial +>T : T +>r : Readonly +>Readonly : Readonly +>T : T +>pr : Partial> +>Partial : Partial +>Readonly : Readonly +>T : T +>rp : Readonly> +>Readonly : Readonly +>Partial : Partial +>T : T + + let a1: Partial = p; +>a1 : Partial +>Partial : Partial +>T : T +>p : Partial + + let a2: Partial = r; +>a2 : Partial +>Partial : Partial +>T : T +>r : Readonly + + let a3: Partial = pr; +>a3 : Partial +>Partial : Partial +>T : T +>pr : Partial> + + let a4: Partial = rp; +>a4 : Partial +>Partial : Partial +>T : T +>rp : Readonly> + + let b1: Readonly = p; // Error +>b1 : Readonly +>Readonly : Readonly +>T : T +>p : Partial + + let b2: Readonly = r; +>b2 : Readonly +>Readonly : Readonly +>T : T +>r : Readonly + + let b3: Readonly = pr; // Error +>b3 : Readonly +>Readonly : Readonly +>T : T +>pr : Partial> + + let b4: Readonly = rp; // Error +>b4 : Readonly +>Readonly : Readonly +>T : T +>rp : Readonly> + + let c1: Partial> = p; +>c1 : Partial> +>Partial : Partial +>Readonly : Readonly +>T : T +>p : Partial + + let c2: Partial> = r; +>c2 : Partial> +>Partial : Partial +>Readonly : Readonly +>T : T +>r : Readonly + + let c3: Partial> = pr; +>c3 : Partial> +>Partial : Partial +>Readonly : Readonly +>T : T +>pr : Partial> + + let c4: Partial> = rp; +>c4 : Partial> +>Partial : Partial +>Readonly : Readonly +>T : T +>rp : Readonly> + + let d1: Readonly> = p; +>d1 : Readonly> +>Readonly : Readonly +>Partial : Partial +>T : T +>p : Partial + + let d2: Readonly> = r; +>d2 : Readonly> +>Readonly : Readonly +>Partial : Partial +>T : T +>r : Readonly + + let d3: Readonly> = pr; +>d3 : Readonly> +>Readonly : Readonly +>Partial : Partial +>T : T +>pr : Partial> + + let d4: Readonly> = rp; +>d4 : Readonly> +>Readonly : Readonly +>Partial : Partial +>T : T +>rp : Readonly> +} + +// Repro from #17682 + +type State = { +>State : State + + [key: string]: string | boolean | number | null; +>key : string +>null : null + +}; + +type Args1 = { +>Args1 : Args1 +>T : T +>State : State + + readonly previous: Readonly>; +>previous : Readonly> +>Readonly : Readonly +>Partial : Partial +>T : T + + readonly current: Readonly>; +>current : Readonly> +>Readonly : Readonly +>Partial : Partial +>T : T + +}; + +type Args2 = { +>Args2 : Args2 +>T : T +>State : State + + readonly previous: Partial>; +>previous : Partial> +>Partial : Partial +>Readonly : Readonly +>T : T + + readonly current: Partial>; +>current : Partial> +>Partial : Partial +>Readonly : Readonly +>T : T + +}; + +function doit() { +>doit : () => void +>T : T +>State : State + + let previous: Partial = Object.create(null); +>previous : Partial +>Partial : Partial +>T : T +>Object.create(null) : any +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } +>Object : ObjectConstructor +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } +>null : null + + let current: Partial = Object.create(null); +>current : Partial +>Partial : Partial +>T : T +>Object.create(null) : any +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } +>Object : ObjectConstructor +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } +>null : null + + let args1: Args1 = { previous, current }; +>args1 : Args1 +>Args1 : Args1 +>T : T +>{ previous, current } : { previous: Partial; current: Partial; } +>previous : Partial +>current : Partial + + let args2: Args2 = { previous, current }; +>args2 : Args2 +>Args2 : Args2 +>T : T +>{ previous, current } : { previous: Partial; current: Partial; } +>previous : Partial +>current : Partial +} + +type State2 = { foo: number, bar: string }; +>State2 : State2 +>foo : number +>bar : string + +type Args3 = { +>Args3 : Args3 + + readonly previous: Readonly>; +>previous : Readonly> +>Readonly : Readonly +>Partial : Partial +>State2 : State2 + + readonly current: Readonly>; +>current : Readonly> +>Readonly : Readonly +>Partial : Partial +>State2 : State2 + +}; + +type Args4 = { +>Args4 : Args4 + + readonly previous: Partial>; +>previous : Partial> +>Partial : Partial +>Readonly : Readonly +>State2 : State2 + + readonly current: Partial>; +>current : Partial> +>Partial : Partial +>Readonly : Readonly +>State2 : State2 + +}; + +function doit2() { +>doit2 : () => void + + let previous: Partial = Object.create(null); +>previous : Partial +>Partial : Partial +>State2 : State2 +>Object.create(null) : any +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } +>Object : ObjectConstructor +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } +>null : null + + let current: Partial = Object.create(null); +>current : Partial +>Partial : Partial +>State2 : State2 +>Object.create(null) : any +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } +>Object : ObjectConstructor +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } +>null : null + + let args1: Args3 = { previous, current }; +>args1 : Args3 +>Args3 : Args3 +>{ previous, current } : { previous: Partial; current: Partial; } +>previous : Partial +>current : Partial + + let args2: Args4 = { previous, current }; +>args2 : Args4 +>Args4 : Args4 +>{ previous, current } : { previous: Partial; current: Partial; } +>previous : Partial +>current : Partial +} + diff --git a/tests/cases/conformance/types/mapped/mappedTypes5.ts b/tests/cases/conformance/types/mapped/mappedTypes5.ts new file mode 100644 index 00000000000..38a010da0f5 --- /dev/null +++ b/tests/cases/conformance/types/mapped/mappedTypes5.ts @@ -0,0 +1,62 @@ +// @strict: true + +function f(p: Partial, r: Readonly, pr: Partial>, rp: Readonly>) { + let a1: Partial = p; + let a2: Partial = r; + let a3: Partial = pr; + let a4: Partial = rp; + let b1: Readonly = p; // Error + let b2: Readonly = r; + let b3: Readonly = pr; // Error + let b4: Readonly = rp; // Error + let c1: Partial> = p; + let c2: Partial> = r; + let c3: Partial> = pr; + let c4: Partial> = rp; + let d1: Readonly> = p; + let d2: Readonly> = r; + let d3: Readonly> = pr; + let d4: Readonly> = rp; +} + +// Repro from #17682 + +type State = { + [key: string]: string | boolean | number | null; +}; + +type Args1 = { + readonly previous: Readonly>; + readonly current: Readonly>; +}; + +type Args2 = { + readonly previous: Partial>; + readonly current: Partial>; +}; + +function doit() { + let previous: Partial = Object.create(null); + let current: Partial = Object.create(null); + let args1: Args1 = { previous, current }; + let args2: Args2 = { previous, current }; +} + +type State2 = { foo: number, bar: string }; + +type Args3 = { + readonly previous: Readonly>; + readonly current: Readonly>; +}; + +type Args4 = { + readonly previous: Partial>; + readonly current: Partial>; +}; + +function doit2() { + let previous: Partial = Object.create(null); + let current: Partial = Object.create(null); + let args1: Args3 = { previous, current }; + let args2: Args4 = { previous, current }; +} From a8160de49c9b74fe536705a1edd35618c1e855e6 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 4 Nov 2017 17:26:02 -0700 Subject: [PATCH 122/235] Empty array literal has a non-inferrable element type --- src/compiler/checker.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e2e45b2ccb0..5b5bc92350b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -281,6 +281,7 @@ namespace ts { const voidType = createIntrinsicType(TypeFlags.Void, "void"); const neverType = createIntrinsicType(TypeFlags.Never, "never"); const silentNeverType = createIntrinsicType(TypeFlags.Never, "never"); + const implicitNeverType = createIntrinsicType(TypeFlags.Never, "never"); const nonPrimitiveType = createIntrinsicType(TypeFlags.NonPrimitive, "object"); const emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); @@ -7684,7 +7685,7 @@ namespace ts { function getIndexTypeOrString(type: Type): Type { const indexType = getIndexType(type); - return indexType !== neverType ? indexType : stringType; + return indexType.flags & TypeFlags.Never ? stringType : indexType; } function getTypeFromTypeOperatorNode(node: TypeOperatorNode) { @@ -8861,8 +8862,8 @@ namespace ts { function isSimpleTypeRelatedTo(source: Type, target: Type, relation: Map, errorReporter?: ErrorReporter) { const s = source.flags; const t = target.flags; - if (t & TypeFlags.Never) return false; if (t & TypeFlags.Any || s & TypeFlags.Never) return true; + if (t & TypeFlags.Never) return false; if (s & TypeFlags.StringLike && t & TypeFlags.String) return true; if (s & TypeFlags.StringLiteral && s & TypeFlags.EnumLiteral && t & TypeFlags.StringLiteral && !(t & TypeFlags.EnumLiteral) && @@ -10323,7 +10324,7 @@ namespace ts { function isEmptyArrayLiteralType(type: Type): boolean { const elementType = isArrayType(type) ? (type).typeArguments[0] : undefined; - return elementType === undefinedWideningType || elementType === neverType; + return elementType === undefinedWideningType || elementType === implicitNeverType; } function isTupleLikeType(type: Type): boolean { @@ -10880,9 +10881,10 @@ namespace ts { // Because the anyFunctionType is internal, it should not be exposed to the user by adding // it as an inference candidate. Hopefully, a better candidate will come along that does // not contain anyFunctionType when we come back to this argument for its second round - // of inference. Also, we exclude inferences for silentNeverType which is used as a wildcard - // when constructing types from type parameters that had no inference candidates. - if (source.flags & TypeFlags.ContainsAnyFunctionType || source === silentNeverType) { + // of inference. Also, we exclude inferences for silentNeverType (which is used as a wildcard + // when constructing types from type parameters that had no inference candidates) and + // implicitNeverType (which is used as the element type for empty array literals). + if (source.flags & TypeFlags.ContainsAnyFunctionType || source === silentNeverType || source === implicitNeverType) { return; } const inference = getInferenceInfoForType(target); @@ -13923,7 +13925,7 @@ namespace ts { } return createArrayType(elementTypes.length ? getUnionType(elementTypes, /*subtypeReduction*/ true) : - strictNullChecks ? neverType : undefinedWideningType); + strictNullChecks ? implicitNeverType : undefinedWideningType); } function isNumericName(name: DeclarationName): boolean { From 0a4f60e87b030dfe58a067c671177dad40c89944 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 4 Nov 2017 17:26:12 -0700 Subject: [PATCH 123/235] Add tests --- tests/baselines/reference/neverInference.js | 31 +++++++ .../reference/neverInference.symbols | 76 +++++++++++++++++ .../baselines/reference/neverInference.types | 83 +++++++++++++++++++ .../conformance/types/never/neverInference.ts | 24 ++++++ 4 files changed, 214 insertions(+) create mode 100644 tests/baselines/reference/neverInference.js create mode 100644 tests/baselines/reference/neverInference.symbols create mode 100644 tests/baselines/reference/neverInference.types create mode 100644 tests/cases/conformance/types/never/neverInference.ts diff --git a/tests/baselines/reference/neverInference.js b/tests/baselines/reference/neverInference.js new file mode 100644 index 00000000000..d13e537eba4 --- /dev/null +++ b/tests/baselines/reference/neverInference.js @@ -0,0 +1,31 @@ +//// [neverInference.ts] +declare function f(x: T[]): T; + +let neverArray: never[] = []; + +let a1 = f([]); // {} +let a2 = f(neverArray); // never + +// Repro from #19576 + +type Comparator = (x: T, y: T) => number; + +interface LinkedList { + comparator: Comparator, + nodes: Node +} + +type Node = { value: T, next: Node } | null + +declare function compareNumbers(x: number, y: number): number; +declare function mkList(items: T[], comparator: Comparator): LinkedList; + +const list: LinkedList = mkList([], compareNumbers); + + +//// [neverInference.js] +"use strict"; +var neverArray = []; +var a1 = f([]); // {} +var a2 = f(neverArray); // never +var list = mkList([], compareNumbers); diff --git a/tests/baselines/reference/neverInference.symbols b/tests/baselines/reference/neverInference.symbols new file mode 100644 index 00000000000..683e079b2f8 --- /dev/null +++ b/tests/baselines/reference/neverInference.symbols @@ -0,0 +1,76 @@ +=== tests/cases/conformance/types/never/neverInference.ts === +declare function f(x: T[]): T; +>f : Symbol(f, Decl(neverInference.ts, 0, 0)) +>T : Symbol(T, Decl(neverInference.ts, 0, 19)) +>x : Symbol(x, Decl(neverInference.ts, 0, 22)) +>T : Symbol(T, Decl(neverInference.ts, 0, 19)) +>T : Symbol(T, Decl(neverInference.ts, 0, 19)) + +let neverArray: never[] = []; +>neverArray : Symbol(neverArray, Decl(neverInference.ts, 2, 3)) + +let a1 = f([]); // {} +>a1 : Symbol(a1, Decl(neverInference.ts, 4, 3)) +>f : Symbol(f, Decl(neverInference.ts, 0, 0)) + +let a2 = f(neverArray); // never +>a2 : Symbol(a2, Decl(neverInference.ts, 5, 3)) +>f : Symbol(f, Decl(neverInference.ts, 0, 0)) +>neverArray : Symbol(neverArray, Decl(neverInference.ts, 2, 3)) + +// Repro from #19576 + +type Comparator = (x: T, y: T) => number; +>Comparator : Symbol(Comparator, Decl(neverInference.ts, 5, 23)) +>T : Symbol(T, Decl(neverInference.ts, 9, 16)) +>x : Symbol(x, Decl(neverInference.ts, 9, 22)) +>T : Symbol(T, Decl(neverInference.ts, 9, 16)) +>y : Symbol(y, Decl(neverInference.ts, 9, 27)) +>T : Symbol(T, Decl(neverInference.ts, 9, 16)) + +interface LinkedList { +>LinkedList : Symbol(LinkedList, Decl(neverInference.ts, 9, 44)) +>T : Symbol(T, Decl(neverInference.ts, 11, 21)) + + comparator: Comparator, +>comparator : Symbol(LinkedList.comparator, Decl(neverInference.ts, 11, 25)) +>Comparator : Symbol(Comparator, Decl(neverInference.ts, 5, 23)) +>T : Symbol(T, Decl(neverInference.ts, 11, 21)) + + nodes: Node +>nodes : Symbol(LinkedList.nodes, Decl(neverInference.ts, 12, 30)) +>Node : Symbol(Node, Decl(neverInference.ts, 14, 1)) +>T : Symbol(T, Decl(neverInference.ts, 11, 21)) +} + +type Node = { value: T, next: Node } | null +>Node : Symbol(Node, Decl(neverInference.ts, 14, 1)) +>T : Symbol(T, Decl(neverInference.ts, 16, 10)) +>value : Symbol(value, Decl(neverInference.ts, 16, 16)) +>T : Symbol(T, Decl(neverInference.ts, 16, 10)) +>next : Symbol(next, Decl(neverInference.ts, 16, 26)) +>Node : Symbol(Node, Decl(neverInference.ts, 14, 1)) +>T : Symbol(T, Decl(neverInference.ts, 16, 10)) + +declare function compareNumbers(x: number, y: number): number; +>compareNumbers : Symbol(compareNumbers, Decl(neverInference.ts, 16, 49)) +>x : Symbol(x, Decl(neverInference.ts, 18, 32)) +>y : Symbol(y, Decl(neverInference.ts, 18, 42)) + +declare function mkList(items: T[], comparator: Comparator): LinkedList; +>mkList : Symbol(mkList, Decl(neverInference.ts, 18, 62)) +>T : Symbol(T, Decl(neverInference.ts, 19, 24)) +>items : Symbol(items, Decl(neverInference.ts, 19, 27)) +>T : Symbol(T, Decl(neverInference.ts, 19, 24)) +>comparator : Symbol(comparator, Decl(neverInference.ts, 19, 38)) +>Comparator : Symbol(Comparator, Decl(neverInference.ts, 5, 23)) +>T : Symbol(T, Decl(neverInference.ts, 19, 24)) +>LinkedList : Symbol(LinkedList, Decl(neverInference.ts, 9, 44)) +>T : Symbol(T, Decl(neverInference.ts, 19, 24)) + +const list: LinkedList = mkList([], compareNumbers); +>list : Symbol(list, Decl(neverInference.ts, 21, 5)) +>LinkedList : Symbol(LinkedList, Decl(neverInference.ts, 9, 44)) +>mkList : Symbol(mkList, Decl(neverInference.ts, 18, 62)) +>compareNumbers : Symbol(compareNumbers, Decl(neverInference.ts, 16, 49)) + diff --git a/tests/baselines/reference/neverInference.types b/tests/baselines/reference/neverInference.types new file mode 100644 index 00000000000..a7dd05a3f8b --- /dev/null +++ b/tests/baselines/reference/neverInference.types @@ -0,0 +1,83 @@ +=== tests/cases/conformance/types/never/neverInference.ts === +declare function f(x: T[]): T; +>f : (x: T[]) => T +>T : T +>x : T[] +>T : T +>T : T + +let neverArray: never[] = []; +>neverArray : never[] +>[] : never[] + +let a1 = f([]); // {} +>a1 : {} +>f([]) : {} +>f : (x: T[]) => T +>[] : never[] + +let a2 = f(neverArray); // never +>a2 : never +>f(neverArray) : never +>f : (x: T[]) => T +>neverArray : never[] + +// Repro from #19576 + +type Comparator = (x: T, y: T) => number; +>Comparator : Comparator +>T : T +>x : T +>T : T +>y : T +>T : T + +interface LinkedList { +>LinkedList : LinkedList +>T : T + + comparator: Comparator, +>comparator : Comparator +>Comparator : Comparator +>T : T + + nodes: Node +>nodes : Node +>Node : Node +>T : T +} + +type Node = { value: T, next: Node } | null +>Node : Node +>T : T +>value : T +>T : T +>next : Node +>Node : Node +>T : T +>null : null + +declare function compareNumbers(x: number, y: number): number; +>compareNumbers : (x: number, y: number) => number +>x : number +>y : number + +declare function mkList(items: T[], comparator: Comparator): LinkedList; +>mkList : (items: T[], comparator: Comparator) => LinkedList +>T : T +>items : T[] +>T : T +>comparator : Comparator +>Comparator : Comparator +>T : T +>LinkedList : LinkedList +>T : T + +const list: LinkedList = mkList([], compareNumbers); +>list : LinkedList +>LinkedList : LinkedList +>mkList([], compareNumbers) : LinkedList +>mkList : (items: T[], comparator: Comparator) => LinkedList +>[] : never[] +>compareNumbers : (x: number, y: number) => number + diff --git a/tests/cases/conformance/types/never/neverInference.ts b/tests/cases/conformance/types/never/neverInference.ts new file mode 100644 index 00000000000..1258a35e3d3 --- /dev/null +++ b/tests/cases/conformance/types/never/neverInference.ts @@ -0,0 +1,24 @@ +// @strict: true + +declare function f(x: T[]): T; + +let neverArray: never[] = []; + +let a1 = f([]); // {} +let a2 = f(neverArray); // never + +// Repro from #19576 + +type Comparator = (x: T, y: T) => number; + +interface LinkedList { + comparator: Comparator, + nodes: Node +} + +type Node = { value: T, next: Node } | null + +declare function compareNumbers(x: number, y: number): number; +declare function mkList(items: T[], comparator: Comparator): LinkedList; + +const list: LinkedList = mkList([], compareNumbers); From db9ed00a0f131585fa1ee74118e3ba75328e3024 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 6 Nov 2017 07:48:09 -0800 Subject: [PATCH 124/235] Remove readonly from index signatures of a spread --- src/compiler/checker.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e2e45b2ccb0..59964f388bb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7993,11 +7993,16 @@ namespace ts { } } - const spread = createAnonymousType(undefined, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo); + const spread = createAnonymousType( + symbol, + members, + emptyArray, + emptyArray, + getNonReadonlyIndexSignature(stringIndexInfo), + getNonReadonlyIndexSignature(numberIndexInfo)); spread.flags |= propagatedFlags; spread.flags |= TypeFlags.FreshLiteral | TypeFlags.ContainsObjectLiteral; (spread as ObjectType).objectFlags |= (ObjectFlags.ObjectLiteral | ObjectFlags.ContainsSpread); - spread.symbol = symbol; return spread; } @@ -8013,6 +8018,13 @@ namespace ts { return result; } + function getNonReadonlyIndexSignature(index: IndexInfo) { + if (index && index.isReadonly) { + return createIndexInfo(index.type, /*isReadonly*/ false, index.declaration); + } + return index; + } + function isClassMethod(prop: Symbol) { return prop.flags & SymbolFlags.Method && find(prop.declarations, decl => isClassLike(decl.parent)); } From 7788d293c4d65103f8fef81128d77a44cbb6df09 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 6 Nov 2017 07:53:43 -0800 Subject: [PATCH 125/235] Test:spread removes readonly from index signatures --- .../objectSpreadIndexSignature.errors.txt | 4 ++++ .../reference/objectSpreadIndexSignature.js | 6 ++++++ .../reference/objectSpreadIndexSignature.symbols | 11 +++++++++++ .../reference/objectSpreadIndexSignature.types | 16 ++++++++++++++++ .../types/spread/objectSpreadIndexSignature.ts | 4 ++++ 5 files changed, 41 insertions(+) diff --git a/tests/baselines/reference/objectSpreadIndexSignature.errors.txt b/tests/baselines/reference/objectSpreadIndexSignature.errors.txt index ee7425909c2..dede126d063 100644 --- a/tests/baselines/reference/objectSpreadIndexSignature.errors.txt +++ b/tests/baselines/reference/objectSpreadIndexSignature.errors.txt @@ -16,4 +16,8 @@ tests/cases/conformance/types/spread/objectSpreadIndexSignature.ts(6,1): error T declare const b: boolean; indexed3 = { ...b ? indexed3 : undefined }; + + declare var roindex: { readonly [x:string]: number }; + var writable = { ...roindex }; + writable.a = 0; // should be ok. \ No newline at end of file diff --git a/tests/baselines/reference/objectSpreadIndexSignature.js b/tests/baselines/reference/objectSpreadIndexSignature.js index 283129036da..f8663fd836f 100644 --- a/tests/baselines/reference/objectSpreadIndexSignature.js +++ b/tests/baselines/reference/objectSpreadIndexSignature.js @@ -11,6 +11,10 @@ ii[1001]; declare const b: boolean; indexed3 = { ...b ? indexed3 : undefined }; + +declare var roindex: { readonly [x:string]: number }; +var writable = { ...roindex }; +writable.a = 0; // should be ok. //// [objectSpreadIndexSignature.js] @@ -30,3 +34,5 @@ var ii = __assign({}, indexed1, indexed2); // both have indexer, so i[1001]: number | boolean ii[1001]; indexed3 = __assign({}, b ? indexed3 : undefined); +var writable = __assign({}, roindex); +writable.a = 0; // should be ok. diff --git a/tests/baselines/reference/objectSpreadIndexSignature.symbols b/tests/baselines/reference/objectSpreadIndexSignature.symbols index d08cfff53ff..439463c4131 100644 --- a/tests/baselines/reference/objectSpreadIndexSignature.symbols +++ b/tests/baselines/reference/objectSpreadIndexSignature.symbols @@ -40,3 +40,14 @@ indexed3 = { ...b ? indexed3 : undefined }; >indexed3 : Symbol(indexed3, Decl(objectSpreadIndexSignature.ts, 2, 11)) >undefined : Symbol(undefined) +declare var roindex: { readonly [x:string]: number }; +>roindex : Symbol(roindex, Decl(objectSpreadIndexSignature.ts, 13, 11)) +>x : Symbol(x, Decl(objectSpreadIndexSignature.ts, 13, 33)) + +var writable = { ...roindex }; +>writable : Symbol(writable, Decl(objectSpreadIndexSignature.ts, 14, 3)) +>roindex : Symbol(roindex, Decl(objectSpreadIndexSignature.ts, 13, 11)) + +writable.a = 0; // should be ok. +>writable : Symbol(writable, Decl(objectSpreadIndexSignature.ts, 14, 3)) + diff --git a/tests/baselines/reference/objectSpreadIndexSignature.types b/tests/baselines/reference/objectSpreadIndexSignature.types index eff3b04b8f6..3ce4d00584b 100644 --- a/tests/baselines/reference/objectSpreadIndexSignature.types +++ b/tests/baselines/reference/objectSpreadIndexSignature.types @@ -50,3 +50,19 @@ indexed3 = { ...b ? indexed3 : undefined }; >indexed3 : { [n: string]: number; } >undefined : undefined +declare var roindex: { readonly [x:string]: number }; +>roindex : { readonly [x: string]: number; } +>x : string + +var writable = { ...roindex }; +>writable : { [x: string]: number; } +>{ ...roindex } : { [x: string]: number; } +>roindex : { readonly [x: string]: number; } + +writable.a = 0; // should be ok. +>writable.a = 0 : 0 +>writable.a : number +>writable : { [x: string]: number; } +>a : number +>0 : 0 + diff --git a/tests/cases/conformance/types/spread/objectSpreadIndexSignature.ts b/tests/cases/conformance/types/spread/objectSpreadIndexSignature.ts index 83649d465f1..13ddc4f71d3 100644 --- a/tests/cases/conformance/types/spread/objectSpreadIndexSignature.ts +++ b/tests/cases/conformance/types/spread/objectSpreadIndexSignature.ts @@ -11,3 +11,7 @@ ii[1001]; declare const b: boolean; indexed3 = { ...b ? indexed3 : undefined }; + +declare var roindex: { readonly [x:string]: number }; +var writable = { ...roindex }; +writable.a = 0; // should be ok. From 0a7b7e07ee9cfae804baaf2bc2435b02e58964ce Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 6 Nov 2017 09:23:47 -0800 Subject: [PATCH 126/235] Apply 'variable-name' tslint rule (#19743) --- Gulpfile.ts | 8 +- .../generateLocalizedDiagnosticMessages.ts | 8 +- scripts/processDiagnosticMessages.ts | 3 +- src/compiler/binder.ts | 2 +- src/compiler/checker.ts | 85 +++--- src/compiler/core.ts | 2 +- src/compiler/factory.ts | 1 + src/compiler/parser.ts | 4 + src/compiler/utilities.ts | 4 +- src/harness/fourslash.ts | 6 +- src/harness/harness.ts | 18 +- src/harness/harnessLanguageService.ts | 4 +- src/harness/loggedIO.ts | 2 +- src/harness/parallel/host.ts | 32 +-- src/harness/unittests/compileOnSave.ts | 4 +- src/harness/unittests/extractRanges.ts | 28 +- src/harness/unittests/moduleResolution.ts | 2 +- .../unittests/reuseProgramStructure.ts | 244 +++++++++--------- src/server/editorServices.ts | 4 +- src/server/session.ts | 2 +- src/server/shared.ts | 1 + .../typingsInstaller/nodeTypingsInstaller.ts | 16 +- src/server/utilities.ts | 6 +- src/services/formatting/formatting.ts | 12 +- src/services/formatting/rule.ts | 6 +- src/services/formatting/ruleDescriptor.ts | 6 +- src/services/formatting/ruleOperation.ts | 8 +- .../formatting/ruleOperationContext.ts | 4 +- src/services/formatting/rules.ts | 1 + src/services/formatting/rulesMap.ts | 38 +-- src/services/formatting/tokenRange.ts | 1 + src/services/jsTyping.ts | 6 +- src/services/patternMatcher.ts | 10 +- src/services/refactors/extractSymbol.ts | 96 +++---- src/services/services.ts | 4 +- tslint.json | 2 +- 36 files changed, 349 insertions(+), 331 deletions(-) diff --git a/Gulpfile.ts b/Gulpfile.ts index 5b35b9f672f..4d6dfdf2862 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -99,12 +99,12 @@ const lclDirectory = "src/loc/lcl"; const builtDirectory = "built/"; const builtLocalDirectory = "built/local/"; -const LKGDirectory = "lib/"; +const lkgDirectory = "lib/"; const copyright = "CopyrightNotice.txt"; const compilerFilename = "tsc.js"; -const LKGCompiler = path.join(LKGDirectory, compilerFilename); +const lkgCompiler = path.join(lkgDirectory, compilerFilename); const builtLocalCompiler = path.join(builtLocalDirectory, compilerFilename); const nodeModulesPathPrefix = path.resolve("./node_modules/.bin/"); @@ -589,7 +589,7 @@ gulp.task("VerifyLKG", /*help*/ false, [], () => { ". The following files are missing:\n" + missingFiles.join("\n")); } // Copy all the targets into the LKG directory - return gulp.src([...expectedFiles, path.join(builtLocalDirectory, "**"), `!${path.join(builtLocalDirectory, "tslint")}`, `!${path.join(builtLocalDirectory, "*.*")}`]).pipe(gulp.dest(LKGDirectory)); + return gulp.src([...expectedFiles, path.join(builtLocalDirectory, "**"), `!${path.join(builtLocalDirectory, "tslint")}`, `!${path.join(builtLocalDirectory, "*.*")}`]).pipe(gulp.dest(lkgDirectory)); }); gulp.task("LKGInternal", /*help*/ false, ["lib", "local"]); @@ -992,7 +992,7 @@ gulp.task(loggedIOJsPath, /*help*/ false, [], (done) => { const temp = path.join(builtLocalDirectory, "temp"); mkdirP(temp, (err) => { if (err) { console.error(err); done(err); process.exit(1); } - exec(host, [LKGCompiler, "--types", "--target es5", "--lib es5", "--outdir", temp, loggedIOpath], () => { + exec(host, [lkgCompiler, "--types", "--target es5", "--lib es5", "--outdir", temp, loggedIOpath], () => { fs.renameSync(path.join(temp, "/harness/loggedIO.js"), loggedIOJsPath); del(temp).then(() => done(), done); }, done); diff --git a/scripts/generateLocalizedDiagnosticMessages.ts b/scripts/generateLocalizedDiagnosticMessages.ts index 00bd8314a9b..566eb557fd5 100644 --- a/scripts/generateLocalizedDiagnosticMessages.ts +++ b/scripts/generateLocalizedDiagnosticMessages.ts @@ -87,9 +87,9 @@ function main(): void { const out: any = {}; for (const item of o.LCX.Item[0].Item[0].Item) { let ItemId = item.$.ItemId; - let Val = item.Str[0].Tgt ? item.Str[0].Tgt[0].Val[0] : item.Str[0].Val[0]; + let val = item.Str[0].Tgt ? item.Str[0].Tgt[0].Val[0] : item.Str[0].Val[0]; - if (typeof ItemId !== "string" || typeof Val !== "string") { + if (typeof ItemId !== "string" || typeof val !== "string") { console.error("Unexpected XML file structure"); process.exit(1); } @@ -98,8 +98,8 @@ function main(): void { ItemId = ItemId.slice(1); // remove leading semicolon } - Val = Val.replace(/]5D;/, "]"); // unescape `]` - out[ItemId] = Val; + val = val.replace(/]5D;/, "]"); // unescape `]` + out[ItemId] = val; } return JSON.stringify(out, undefined, 2); } diff --git a/scripts/processDiagnosticMessages.ts b/scripts/processDiagnosticMessages.ts index ff4047d310d..20085022c04 100644 --- a/scripts/processDiagnosticMessages.ts +++ b/scripts/processDiagnosticMessages.ts @@ -63,7 +63,8 @@ function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable): string " function diag(code: number, category: DiagnosticCategory, key: string, message: string): DiagnosticMessage {\r\n" + " return { code, category, key, message };\r\n" + " }\r\n" + - ' export const Diagnostics = {\r\n'; + " // tslint:disable-next-line variable-name\r\n" + + " export const Diagnostics = {\r\n"; messageTable.forEach(({ code, category }, name) => { const propName = convertPropertyName(name); result += ` ${propName}: diag(${code}, DiagnosticCategory.${category}, "${createKey(propName, code)}", ${JSON.stringify(name)}),\r\n`; diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 85ca2435974..72cff733b0c 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -133,7 +133,7 @@ namespace ts { let symbolCount = 0; - let Symbol: { new (flags: SymbolFlags, name: __String): Symbol }; + let Symbol: { new (flags: SymbolFlags, name: __String): Symbol }; // tslint:disable-line variable-name let classifiableNames: UnderscoreEscapedMap; const unreachableFlow: FlowNode = { flags: FlowFlags.Unreachable }; diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e2e45b2ccb0..b0b014d598a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -48,9 +48,11 @@ namespace ts { let requestedExternalEmitHelpers: ExternalEmitHelpers; let externalHelpersModule: Symbol; + // tslint:disable variable-name const Symbol = objectAllocator.getSymbolConstructor(); const Type = objectAllocator.getTypeConstructor(); const Signature = objectAllocator.getSignatureConstructor(); + // tslint:enable variable-name let typeCount = 0; let symbolCount = 0; @@ -488,17 +490,6 @@ namespace ts { /** Things we lazy load from the JSX namespace */ const jsxTypes = createUnderscoreEscapedMap(); - const JsxNames = { - JSX: "JSX" as __String, - IntrinsicElements: "IntrinsicElements" as __String, - ElementClass: "ElementClass" as __String, - ElementAttributesPropertyNameContainer: "ElementAttributesProperty" as __String, - ElementChildrenAttributeNameContainer: "ElementChildrenAttribute" as __String, - Element: "Element" as __String, - IntrinsicAttributes: "IntrinsicAttributes" as __String, - IntrinsicClassAttributes: "IntrinsicClassAttributes" as __String - }; - const subtypeRelation = createMap(); const assignableRelation = createMap(); const comparableRelation = createMap(); @@ -25103,11 +25094,13 @@ namespace ts { } function checkGrammarObjectLiteralExpression(node: ObjectLiteralExpression, inDestructuring: boolean) { - const seen = createUnderscoreEscapedMap(); - const Property = 1; - const GetAccessor = 2; - const SetAccessor = 4; - const GetOrSetAccessor = GetAccessor | SetAccessor; + const enum Flags { + Property = 1, + GetAccessor = 2, + SetAccessor = 4, + GetOrSetAccessor = GetAccessor | SetAccessor, + } + const seen = createUnderscoreEscapedMap(); for (const prop of node.properties) { if (prop.kind === SyntaxKind.SpreadAssignment) { @@ -25142,26 +25135,27 @@ namespace ts { // c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true. // d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true // and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields - let currentKind: number; - if (prop.kind === SyntaxKind.PropertyAssignment || prop.kind === SyntaxKind.ShorthandPropertyAssignment) { - // Grammar checking for computedPropertyName and shorthandPropertyAssignment - checkGrammarForInvalidQuestionMark((prop).questionToken, Diagnostics.An_object_member_cannot_be_declared_optional); - if (name.kind === SyntaxKind.NumericLiteral) { - checkGrammarNumericLiteral(name); - } - currentKind = Property; - } - else if (prop.kind === SyntaxKind.MethodDeclaration) { - currentKind = Property; - } - else if (prop.kind === SyntaxKind.GetAccessor) { - currentKind = GetAccessor; - } - else if (prop.kind === SyntaxKind.SetAccessor) { - currentKind = SetAccessor; - } - else { - Debug.assertNever(prop, "Unexpected syntax kind:" + (prop).kind); + let currentKind: Flags; + switch (prop.kind) { + case SyntaxKind.PropertyAssignment: + case SyntaxKind.ShorthandPropertyAssignment: + // Grammar checking for computedPropertyName and shorthandPropertyAssignment + checkGrammarForInvalidQuestionMark((prop).questionToken, Diagnostics.An_object_member_cannot_be_declared_optional); + if (name.kind === SyntaxKind.NumericLiteral) { + checkGrammarNumericLiteral(name); + } + // falls through + case SyntaxKind.MethodDeclaration: + currentKind = Flags.Property; + break; + case SyntaxKind.GetAccessor: + currentKind = Flags.GetAccessor; + break; + case SyntaxKind.SetAccessor: + currentKind = Flags.SetAccessor; + break; + default: + Debug.assertNever(prop, "Unexpected syntax kind:" + (prop).kind); } const effectiveName = getPropertyNameForPropertyNameNode(name); @@ -25174,11 +25168,11 @@ namespace ts { seen.set(effectiveName, currentKind); } else { - if (currentKind === Property && existingKind === Property) { + if (currentKind === Flags.Property && existingKind === Flags.Property) { grammarErrorOnNode(name, Diagnostics.Duplicate_identifier_0, getTextOfNode(name)); } - else if ((currentKind & GetOrSetAccessor) && (existingKind & GetOrSetAccessor)) { - if (existingKind !== GetOrSetAccessor && currentKind !== existingKind) { + else if ((currentKind & Flags.GetOrSetAccessor) && (existingKind & Flags.GetOrSetAccessor)) { + if (existingKind !== Flags.GetOrSetAccessor && currentKind !== existingKind) { seen.set(effectiveName, currentKind | existingKind); } else { @@ -25806,4 +25800,17 @@ namespace ts { return false; } } + + namespace JsxNames { + // tslint:disable variable-name + export const JSX = "JSX" as __String; + export const IntrinsicElements = "IntrinsicElements" as __String; + export const ElementClass = "ElementClass" as __String; + export const ElementAttributesPropertyNameContainer = "ElementAttributesProperty" as __String; + export const ElementChildrenAttributeNameContainer = "ElementChildrenAttribute" as __String; + export const Element = "Element" as __String; + export const IntrinsicAttributes = "IntrinsicAttributes" as __String; + export const IntrinsicClassAttributes = "IntrinsicClassAttributes" as __String; + // tslint:enable variable-name + } } diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 157a0c7fd1d..f2249641ff4 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -76,7 +76,7 @@ namespace ts { // The global Map object. This may not be available, so we must test for it. declare const Map: { new(): Map } | undefined; // Internet Explorer's Map doesn't support iteration, so don't use it. - // tslint:disable-next-line:no-in-operator + // tslint:disable-next-line no-in-operator variable-name const MapCtr = typeof Map !== "undefined" && "entries" in Map.prototype ? Map : shimMap(); // Keep the class inside a function so it doesn't get compiled if it's not used. diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index d16903bc300..053672d19df 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -2654,6 +2654,7 @@ namespace ts { return node; } + // tslint:disable-next-line variable-name let SourceMapSource: new (fileName: string, text: string, skipTrivia?: (pos: number) => number) => SourceMapSource; /** diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index c2b35bd25c4..9b43a3c991b 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -12,10 +12,12 @@ namespace ts { JSDoc = 1 << 5, } + // tslint:disable variable-name let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let IdentifierConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; + // tslint:enable variable-name export function createNode(kind: SyntaxKind, pos?: number, end?: number): Node { if (kind === SyntaxKind.SourceFile) { @@ -524,10 +526,12 @@ namespace ts { const disallowInAndDecoratorContext = NodeFlags.DisallowInContext | NodeFlags.DecoratorContext; // capture constructors in 'initializeState' to avoid null checks + // tslint:disable variable-name let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let IdentifierConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; + // tslint:enable variable-name let sourceFile: SourceFile; let parseDiagnostics: Diagnostic[]; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 10b93ad59cf..456f02c09c6 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1404,8 +1404,8 @@ namespace ts { return charCode === CharacterCodes.singleQuote || charCode === CharacterCodes.doubleQuote; } - export function isStringDoubleQuoted(string: StringLiteral, sourceFile: SourceFile): boolean { - return getSourceTextOfNodeFromSourceFile(sourceFile, string).charCodeAt(0) === CharacterCodes.doubleQuote; + export function isStringDoubleQuoted(str: StringLiteral, sourceFile: SourceFile): boolean { + return getSourceTextOfNodeFromSourceFile(sourceFile, str).charCodeAt(0) === CharacterCodes.doubleQuote; } /** diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 7852aba28f1..dac8f7b8413 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -126,8 +126,8 @@ namespace FourSlash { // 0 - cancelled // >0 - not cancelled // <0 - not cancelled and value denotes number of isCancellationRequested after which token become cancelled - private static readonly NotCanceled: number = -1; - private numberOfCallsBeforeCancellation: number = TestCancellationToken.NotCanceled; + private static readonly notCanceled = -1; + private numberOfCallsBeforeCancellation = TestCancellationToken.notCanceled; public isCancellationRequested(): boolean { if (this.numberOfCallsBeforeCancellation < 0) { @@ -148,7 +148,7 @@ namespace FourSlash { } public resetCancelled(): void { - this.numberOfCallsBeforeCancellation = TestCancellationToken.NotCanceled; + this.numberOfCallsBeforeCancellation = TestCancellationToken.notCanceled; } } diff --git a/src/harness/harness.ts b/src/harness/harness.ts index e698839168a..61ea4508363 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1113,11 +1113,11 @@ namespace Harness { case "string": return value; case "number": { - const number = parseInt(value, 10); - if (isNaN(number)) { + const numverValue = parseInt(value, 10); + if (isNaN(numverValue)) { throw new Error(`Value must be a number, got: ${JSON.stringify(value)}`); } - return number; + return numverValue; } // If not a primitive, the possible types are specified in what is effectively a map of options. case "list": @@ -1964,7 +1964,7 @@ namespace Harness { /** Support class for baseline files */ export namespace Baseline { - const NoContent = ""; + const noContent = ""; export interface BaselineOptions { Subfolder?: string; @@ -2023,7 +2023,7 @@ namespace Harness { /* tslint:disable:no-null-keyword */ if (actual === null) { /* tslint:enable:no-null-keyword */ - actual = NoContent; + actual = noContent; } let expected = ""; @@ -2060,13 +2060,13 @@ namespace Harness { IO.deleteFile(actualFileName); } - const encoded_actual = Utils.encodeString(actual); - if (expected !== encoded_actual) { - if (actual === NoContent) { + const encodedActual = Utils.encodeString(actual); + if (expected !== encodedActual) { + if (actual === noContent) { IO.writeFile(actualFileName + ".delete", ""); } else { - IO.writeFile(actualFileName, encoded_actual); + IO.writeFile(actualFileName, encodedActual); } throw new Error(`The baseline file ${relativeFileName} has changed.`); } diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 185c22db72d..b745a0bfd4f 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -108,7 +108,7 @@ namespace Harness.LanguageService { } class DefaultHostCancellationToken implements ts.HostCancellationToken { - public static readonly Instance = new DefaultHostCancellationToken(); + public static readonly instance = new DefaultHostCancellationToken(); public isCancellationRequested() { return false; @@ -126,7 +126,7 @@ namespace Harness.LanguageService { public typesRegistry: ts.Map | undefined; protected virtualFileSystem: Utils.VirtualFileSystem = new Utils.VirtualFileSystem(virtualFileSystemRoot, /*useCaseSensitiveFilenames*/false); - constructor(protected cancellationToken = DefaultHostCancellationToken.Instance, + constructor(protected cancellationToken = DefaultHostCancellationToken.instance, protected settings = ts.getDefaultCompilerOptions()) { } diff --git a/src/harness/loggedIO.ts b/src/harness/loggedIO.ts index 2be09abcf91..37e8dddb3d7 100644 --- a/src/harness/loggedIO.ts +++ b/src/harness/loggedIO.ts @@ -251,7 +251,7 @@ namespace Playback { let i = 0; const getBase = () => recordLogFileNameBase + i; while (underlying.fileExists(ts.combinePaths(getBase(), "test.json"))) i++; - const newLog = oldStyleLogIntoNewStyleLog(recordLog, (path, string) => underlying.writeFile(path, string), getBase()); + const newLog = oldStyleLogIntoNewStyleLog(recordLog, (path, str) => underlying.writeFile(path, str), getBase()); underlying.writeFile(ts.combinePaths(getBase(), "test.json"), JSON.stringify(newLog, null, 4)); // tslint:disable-line:no-null-keyword const syntheticTsconfig = generateTsconfig(newLog); if (syntheticTsconfig) { diff --git a/src/harness/parallel/host.ts b/src/harness/parallel/host.ts index 40dee0da872..f37a3b1099e 100644 --- a/src/harness/parallel/host.ts +++ b/src/harness/parallel/host.ts @@ -274,15 +274,15 @@ namespace Harness.Parallel.Host { function completeBar() { const isPartitionFail = failingFiles !== 0; const summaryColor = isPartitionFail ? "fail" : "green"; - const summarySymbol = isPartitionFail ? Base.symbols.err : Base.symbols.ok; + const summarySymbol = isPartitionFail ? base.symbols.err : base.symbols.ok; const summaryTests = (isPartitionFail ? totalPassing + "/" + (errorResults.length + totalPassing) : totalPassing) + " passing"; const summaryDuration = "(" + ms(duration) + ")"; - const savedUseColors = Base.useColors; - Base.useColors = !noColors; + const savedUseColors = base.useColors; + base.useColors = !noColors; const summary = color(summaryColor, summarySymbol + " " + summaryTests) + " " + color("light", summaryDuration); - Base.useColors = savedUseColors; + base.useColors = savedUseColors; updateProgress(1, summary); } @@ -307,7 +307,7 @@ namespace Harness.Parallel.Host { completeBar(); progressBars.disable(); - const reporter = new Base(); + const reporter = new base(); const stats = reporter.stats; const failures = reporter.failures; stats.passes = totalPassing; @@ -318,10 +318,10 @@ namespace Harness.Parallel.Host { failures.push(makeMochaTest(failure)); } if (noColors) { - const savedUseColors = Base.useColors; - Base.useColors = false; + const savedUseColors = base.useColors; + base.useColors = false; reporter.epilogue(); - Base.useColors = savedUseColors; + base.useColors = savedUseColors; } else { reporter.epilogue(); @@ -352,8 +352,8 @@ namespace Harness.Parallel.Host { return; } - let Mocha: any; - let Base: any; + let mocha: any; + let base: any; let color: any; let cursor: any; let readline: any; @@ -394,10 +394,10 @@ namespace Harness.Parallel.Host { } function initializeProgressBarsDependencies() { - Mocha = require("mocha"); - Base = Mocha.reporters.Base; - color = Base.color; - cursor = Base.cursor; + mocha = require("mocha"); + base = mocha.reporters.Base; + color = base.color; + cursor = base.cursor; readline = require("readline"); os = require("os"); tty = require("tty"); @@ -414,8 +414,8 @@ namespace Harness.Parallel.Host { const open = options.open || "["; const close = options.close || "]"; const complete = options.complete || "▬"; - const incomplete = options.incomplete || Base.symbols.dot; - const maxWidth = Base.window.width - open.length - close.length - 34; + const incomplete = options.incomplete || base.symbols.dot; + const maxWidth = base.window.width - open.length - close.length - 34; const width = minMax(options.width || maxWidth, 10, maxWidth); this._options = { open, diff --git a/src/harness/unittests/compileOnSave.ts b/src/harness/unittests/compileOnSave.ts index 7be6ab5b323..0a3b5f46f0f 100644 --- a/src/harness/unittests/compileOnSave.ts +++ b/src/harness/unittests/compileOnSave.ts @@ -627,8 +627,8 @@ namespace ts.projectSystem { const mapFileContent = host.readFile(expectedMapFileName); verifyContentHasString(mapFileContent, `"sources":["${inputFileName}"]`); - function verifyContentHasString(content: string, string: string) { - assert.isTrue(content.indexOf(string) !== -1, `Expected "${content}" to have "${string}"`); + function verifyContentHasString(content: string, str: string) { + assert.isTrue(stringContains(content, str), `Expected "${content}" to have "${str}"`); } }); }); diff --git a/src/harness/unittests/extractRanges.ts b/src/harness/unittests/extractRanges.ts index e8e9a918f0d..493c9639c3d 100644 --- a/src/harness/unittests/extractRanges.ts +++ b/src/harness/unittests/extractRanges.ts @@ -191,7 +191,7 @@ function f() { } `, [ - refactor.extractSymbol.Messages.CannotExtractRangeContainingConditionalReturnStatement.message + refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalReturnStatement.message ]); testExtractRangeFailed("extractRangeFailed2", @@ -210,7 +210,7 @@ function f() { } `, [ - refactor.extractSymbol.Messages.CannotExtractRangeContainingConditionalBreakOrContinueStatements.message + refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements.message ]); testExtractRangeFailed("extractRangeFailed3", @@ -229,7 +229,7 @@ function f() { } `, [ - refactor.extractSymbol.Messages.CannotExtractRangeContainingConditionalBreakOrContinueStatements.message + refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements.message ]); testExtractRangeFailed("extractRangeFailed4", @@ -248,7 +248,7 @@ function f() { } `, [ - refactor.extractSymbol.Messages.CannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange.message + refactor.extractSymbol.Messages.cannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange.message ]); testExtractRangeFailed("extractRangeFailed5", @@ -269,7 +269,7 @@ function f2() { } `, [ - refactor.extractSymbol.Messages.CannotExtractRangeContainingConditionalReturnStatement.message + refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalReturnStatement.message ]); testExtractRangeFailed("extractRangeFailed6", @@ -290,7 +290,7 @@ function f2() { } `, [ - refactor.extractSymbol.Messages.CannotExtractRangeContainingConditionalReturnStatement.message + refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalReturnStatement.message ]); testExtractRangeFailed("extractRangeFailed7", @@ -303,7 +303,7 @@ while (x) { } `, [ - refactor.extractSymbol.Messages.CannotExtractRangeContainingConditionalBreakOrContinueStatements.message + refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements.message ]); testExtractRangeFailed("extractRangeFailed8", @@ -316,13 +316,13 @@ switch (x) { } `, [ - refactor.extractSymbol.Messages.CannotExtractRangeContainingConditionalBreakOrContinueStatements.message + refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements.message ]); testExtractRangeFailed("extractRangeFailed9", `var x = ([#||]1 + 2);`, [ - refactor.extractSymbol.Messages.CannotExtractEmpty.message + refactor.extractSymbol.Messages.cannotExtractEmpty.message ]); testExtractRangeFailed("extractRangeFailed10", @@ -333,7 +333,7 @@ switch (x) { } `, [ - refactor.extractSymbol.Messages.CannotExtractRange.message + refactor.extractSymbol.Messages.cannotExtractRange.message ]); testExtractRangeFailed("extractRangeFailed11", @@ -350,21 +350,21 @@ switch (x) { } `, [ - refactor.extractSymbol.Messages.CannotExtractRangeContainingConditionalBreakOrContinueStatements.message + refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements.message ]); testExtractRangeFailed("extractRangeFailed12", `let [#|x|];`, [ - refactor.extractSymbol.Messages.StatementOrExpressionExpected.message + refactor.extractSymbol.Messages.statementOrExpressionExpected.message ]); testExtractRangeFailed("extractRangeFailed13", `[#|return;|]`, [ - refactor.extractSymbol.Messages.CannotExtractRange.message + refactor.extractSymbol.Messages.cannotExtractRange.message ]); - testExtractRangeFailed("extract-method-not-for-token-expression-statement", `[#|a|]`, [refactor.extractSymbol.Messages.CannotExtractIdentifier.message]); + testExtractRangeFailed("extract-method-not-for-token-expression-statement", `[#|a|]`, [refactor.extractSymbol.Messages.cannotExtractIdentifier.message]); }); } \ No newline at end of file diff --git a/src/harness/unittests/moduleResolution.ts b/src/harness/unittests/moduleResolution.ts index 32301d6dccf..6f62c78208f 100644 --- a/src/harness/unittests/moduleResolution.ts +++ b/src/harness/unittests/moduleResolution.ts @@ -803,7 +803,7 @@ import b = require("./moduleB"); function test(hasDirectoryExists: boolean) { const file1: File = { name: "/root/folder1/file1.ts" }; - const file1_1: File = { name: "/root/folder1/file1_1/index.d.ts" }; + const file1_1: File = { name: "/root/folder1/file1_1/index.d.ts" }; // tslint:disable-line variable-name const file2: File = { name: "/root/generated/folder1/file2.ts" }; const file3: File = { name: "/root/generated/folder2/file3.ts" }; const host = createModuleResolutionHost(hasDirectoryExists, file1, file1_1, file2, file3); diff --git a/src/harness/unittests/reuseProgramStructure.ts b/src/harness/unittests/reuseProgramStructure.ts index e0c0e6f80a8..6278742a0bd 100644 --- a/src/harness/unittests/reuseProgramStructure.ts +++ b/src/harness/unittests/reuseProgramStructure.ts @@ -243,111 +243,111 @@ namespace ts { ]; it("successful if change does not affect imports", () => { - const program_1 = newProgram(files, ["a.ts"], { target }); - const program_2 = updateProgram(program_1, ["a.ts"], { target }, files => { + const program1 = newProgram(files, ["a.ts"], { target }); + const program2 = updateProgram(program1, ["a.ts"], { target }, files => { files[0].text = files[0].text.updateProgram("var x = 100"); }); - assert.equal(program_1.structureIsReused, StructureIsReused.Completely); - const program1Diagnostics = program_1.getSemanticDiagnostics(program_1.getSourceFile("a.ts")); - const program2Diagnostics = program_2.getSemanticDiagnostics(program_1.getSourceFile("a.ts")); + assert.equal(program1.structureIsReused, StructureIsReused.Completely); + const program1Diagnostics = program1.getSemanticDiagnostics(program1.getSourceFile("a.ts")); + const program2Diagnostics = program2.getSemanticDiagnostics(program1.getSourceFile("a.ts")); assert.equal(program1Diagnostics.length, program2Diagnostics.length); }); it("successful if change does not affect type reference directives", () => { - const program_1 = newProgram(files, ["a.ts"], { target }); - const program_2 = updateProgram(program_1, ["a.ts"], { target }, files => { + const program1 = newProgram(files, ["a.ts"], { target }); + const program2 = updateProgram(program1, ["a.ts"], { target }, files => { files[0].text = files[0].text.updateProgram("var x = 100"); }); - assert.equal(program_1.structureIsReused, StructureIsReused.Completely); - const program1Diagnostics = program_1.getSemanticDiagnostics(program_1.getSourceFile("a.ts")); - const program2Diagnostics = program_2.getSemanticDiagnostics(program_1.getSourceFile("a.ts")); + assert.equal(program1.structureIsReused, StructureIsReused.Completely); + const program1Diagnostics = program1.getSemanticDiagnostics(program1.getSourceFile("a.ts")); + const program2Diagnostics = program2.getSemanticDiagnostics(program1.getSourceFile("a.ts")); assert.equal(program1Diagnostics.length, program2Diagnostics.length); }); it("fails if change affects tripleslash references", () => { - const program_1 = newProgram(files, ["a.ts"], { target }); - updateProgram(program_1, ["a.ts"], { target }, files => { + const program1 = newProgram(files, ["a.ts"], { target }); + updateProgram(program1, ["a.ts"], { target }, files => { const newReferences = `/// /// `; files[0].text = files[0].text.updateReferences(newReferences); }); - assert.equal(program_1.structureIsReused, StructureIsReused.SafeModules); + assert.equal(program1.structureIsReused, StructureIsReused.SafeModules); }); it("fails if change affects type references", () => { - const program_1 = newProgram(files, ["a.ts"], { types: ["a"] }); - updateProgram(program_1, ["a.ts"], { types: ["b"] }, noop); - assert.equal(program_1.structureIsReused, StructureIsReused.Not); + const program1 = newProgram(files, ["a.ts"], { types: ["a"] }); + updateProgram(program1, ["a.ts"], { types: ["b"] }, noop); + assert.equal(program1.structureIsReused, StructureIsReused.Not); }); it("succeeds if change doesn't affect type references", () => { - const program_1 = newProgram(files, ["a.ts"], { types: ["a"] }); - updateProgram(program_1, ["a.ts"], { types: ["a"] }, noop); - assert.equal(program_1.structureIsReused, StructureIsReused.Completely); + const program1 = newProgram(files, ["a.ts"], { types: ["a"] }); + updateProgram(program1, ["a.ts"], { types: ["a"] }, noop); + assert.equal(program1.structureIsReused, StructureIsReused.Completely); }); it("fails if change affects imports", () => { - const program_1 = newProgram(files, ["a.ts"], { target }); - updateProgram(program_1, ["a.ts"], { target }, files => { + const program1 = newProgram(files, ["a.ts"], { target }); + updateProgram(program1, ["a.ts"], { target }, files => { files[2].text = files[2].text.updateImportsAndExports("import x from 'b'"); }); - assert.equal(program_1.structureIsReused, StructureIsReused.SafeModules); + assert.equal(program1.structureIsReused, StructureIsReused.SafeModules); }); it("fails if change affects type directives", () => { - const program_1 = newProgram(files, ["a.ts"], { target }); - updateProgram(program_1, ["a.ts"], { target }, files => { + const program1 = newProgram(files, ["a.ts"], { target }); + updateProgram(program1, ["a.ts"], { target }, files => { const newReferences = ` /// /// /// `; files[0].text = files[0].text.updateReferences(newReferences); }); - assert.equal(program_1.structureIsReused, StructureIsReused.SafeModules); + assert.equal(program1.structureIsReused, StructureIsReused.SafeModules); }); it("fails if module kind changes", () => { - const program_1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS }); - updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.AMD }, noop); - assert.equal(program_1.structureIsReused, StructureIsReused.Not); + const program1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS }); + updateProgram(program1, ["a.ts"], { target, module: ModuleKind.AMD }, noop); + assert.equal(program1.structureIsReused, StructureIsReused.Not); }); it("fails if rootdir changes", () => { - const program_1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS, rootDir: "/a/b" }); - updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.CommonJS, rootDir: "/a/c" }, noop); - assert.equal(program_1.structureIsReused, StructureIsReused.Not); + const program1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS, rootDir: "/a/b" }); + updateProgram(program1, ["a.ts"], { target, module: ModuleKind.CommonJS, rootDir: "/a/c" }, noop); + assert.equal(program1.structureIsReused, StructureIsReused.Not); }); it("fails if config path changes", () => { - const program_1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS, configFilePath: "/a/b/tsconfig.json" }); - updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.CommonJS, configFilePath: "/a/c/tsconfig.json" }, noop); - assert.equal(program_1.structureIsReused, StructureIsReused.Not); + const program1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS, configFilePath: "/a/b/tsconfig.json" }); + updateProgram(program1, ["a.ts"], { target, module: ModuleKind.CommonJS, configFilePath: "/a/c/tsconfig.json" }, noop); + assert.equal(program1.structureIsReused, StructureIsReused.Not); }); it("succeeds if missing files remain missing", () => { const options: CompilerOptions = { target, noLib: true }; - const program_1 = newProgram(files, ["a.ts"], options); - assert.notDeepEqual(emptyArray, program_1.getMissingFilePaths()); + const program1 = newProgram(files, ["a.ts"], options); + assert.notDeepEqual(emptyArray, program1.getMissingFilePaths()); - const program_2 = updateProgram(program_1, ["a.ts"], options, noop); - assert.deepEqual(program_1.getMissingFilePaths(), program_2.getMissingFilePaths()); + const program2 = updateProgram(program1, ["a.ts"], options, noop); + assert.deepEqual(program1.getMissingFilePaths(), program2.getMissingFilePaths()); - assert.equal(StructureIsReused.Completely, program_1.structureIsReused); + assert.equal(StructureIsReused.Completely, program1.structureIsReused); }); it("fails if missing file is created", () => { const options: CompilerOptions = { target, noLib: true }; - const program_1 = newProgram(files, ["a.ts"], options); - assert.notDeepEqual(emptyArray, program_1.getMissingFilePaths()); + const program1 = newProgram(files, ["a.ts"], options); + assert.notDeepEqual(emptyArray, program1.getMissingFilePaths()); const newTexts: NamedSourceText[] = files.concat([{ name: "non-existing-file.ts", text: SourceText.New("", "", `var x = 1`) }]); - const program_2 = updateProgram(program_1, ["a.ts"], options, noop, newTexts); - assert.deepEqual(emptyArray, program_2.getMissingFilePaths()); + const program2 = updateProgram(program1, ["a.ts"], options, noop, newTexts); + assert.deepEqual(emptyArray, program2.getMissingFilePaths()); - assert.equal(StructureIsReused.Not, program_1.structureIsReused); + assert.equal(StructureIsReused.Not, program1.structureIsReused); }); it("resolution cache follows imports", () => { @@ -359,34 +359,34 @@ namespace ts { ]; const options: CompilerOptions = { target }; - const program_1 = newProgram(files, ["a.ts"], options); - checkResolvedModulesCache(program_1, "a.ts", createMapFromTemplate({ "b": createResolvedModule("b.ts") })); - checkResolvedModulesCache(program_1, "b.ts", /*expectedContent*/ undefined); + const program1 = newProgram(files, ["a.ts"], options); + checkResolvedModulesCache(program1, "a.ts", createMapFromTemplate({ "b": createResolvedModule("b.ts") })); + checkResolvedModulesCache(program1, "b.ts", /*expectedContent*/ undefined); - const program_2 = updateProgram(program_1, ["a.ts"], options, files => { + const program2 = updateProgram(program1, ["a.ts"], options, files => { files[0].text = files[0].text.updateProgram("var x = 2"); }); - assert.equal(program_1.structureIsReused, StructureIsReused.Completely); + assert.equal(program1.structureIsReused, StructureIsReused.Completely); // content of resolution cache should not change - checkResolvedModulesCache(program_1, "a.ts", createMapFromTemplate({ "b": createResolvedModule("b.ts") })); - checkResolvedModulesCache(program_1, "b.ts", /*expectedContent*/ undefined); + checkResolvedModulesCache(program1, "a.ts", createMapFromTemplate({ "b": createResolvedModule("b.ts") })); + checkResolvedModulesCache(program1, "b.ts", /*expectedContent*/ undefined); // imports has changed - program is not reused - const program_3 = updateProgram(program_2, ["a.ts"], options, files => { + const program3 = updateProgram(program2, ["a.ts"], options, files => { files[0].text = files[0].text.updateImportsAndExports(""); }); - assert.equal(program_2.structureIsReused, StructureIsReused.SafeModules); - checkResolvedModulesCache(program_3, "a.ts", /*expectedContent*/ undefined); + assert.equal(program2.structureIsReused, StructureIsReused.SafeModules); + checkResolvedModulesCache(program3, "a.ts", /*expectedContent*/ undefined); - const program_4 = updateProgram(program_3, ["a.ts"], options, files => { + const program4 = updateProgram(program3, ["a.ts"], options, files => { const newImports = `import x from 'b' import y from 'c' `; files[0].text = files[0].text.updateImportsAndExports(newImports); }); - assert.equal(program_3.structureIsReused, StructureIsReused.SafeModules); - checkResolvedModulesCache(program_4, "a.ts", createMapFromTemplate({ "b": createResolvedModule("b.ts"), "c": undefined })); + assert.equal(program3.structureIsReused, StructureIsReused.SafeModules); + checkResolvedModulesCache(program4, "a.ts", createMapFromTemplate({ "b": createResolvedModule("b.ts"), "c": undefined })); }); it("resolved type directives cache follows type directives", () => { @@ -396,35 +396,35 @@ namespace ts { ]; const options: CompilerOptions = { target, typeRoots: ["/types"] }; - const program_1 = newProgram(files, ["/a.ts"], options); - checkResolvedTypeDirectivesCache(program_1, "/a.ts", createMapFromTemplate({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); - checkResolvedTypeDirectivesCache(program_1, "/types/typedefs/index.d.ts", /*expectedContent*/ undefined); + const program1 = newProgram(files, ["/a.ts"], options); + checkResolvedTypeDirectivesCache(program1, "/a.ts", createMapFromTemplate({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); + checkResolvedTypeDirectivesCache(program1, "/types/typedefs/index.d.ts", /*expectedContent*/ undefined); - const program_2 = updateProgram(program_1, ["/a.ts"], options, files => { + const program2 = updateProgram(program1, ["/a.ts"], options, files => { files[0].text = files[0].text.updateProgram("var x = 2"); }); - assert.equal(program_1.structureIsReused, StructureIsReused.Completely); + assert.equal(program1.structureIsReused, StructureIsReused.Completely); // content of resolution cache should not change - checkResolvedTypeDirectivesCache(program_1, "/a.ts", createMapFromTemplate({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); - checkResolvedTypeDirectivesCache(program_1, "/types/typedefs/index.d.ts", /*expectedContent*/ undefined); + checkResolvedTypeDirectivesCache(program1, "/a.ts", createMapFromTemplate({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); + checkResolvedTypeDirectivesCache(program1, "/types/typedefs/index.d.ts", /*expectedContent*/ undefined); // type reference directives has changed - program is not reused - const program_3 = updateProgram(program_2, ["/a.ts"], options, files => { + const program3 = updateProgram(program2, ["/a.ts"], options, files => { files[0].text = files[0].text.updateReferences(""); }); - assert.equal(program_2.structureIsReused, StructureIsReused.SafeModules); - checkResolvedTypeDirectivesCache(program_3, "/a.ts", /*expectedContent*/ undefined); + assert.equal(program2.structureIsReused, StructureIsReused.SafeModules); + checkResolvedTypeDirectivesCache(program3, "/a.ts", /*expectedContent*/ undefined); - updateProgram(program_3, ["/a.ts"], options, files => { + updateProgram(program3, ["/a.ts"], options, files => { const newReferences = `/// /// `; files[0].text = files[0].text.updateReferences(newReferences); }); - assert.equal(program_3.structureIsReused, StructureIsReused.SafeModules); - checkResolvedTypeDirectivesCache(program_1, "/a.ts", createMapFromTemplate({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); + assert.equal(program3.structureIsReused, StructureIsReused.SafeModules); + checkResolvedTypeDirectivesCache(program1, "/a.ts", createMapFromTemplate({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); }); it("fetches imports after npm install", () => { @@ -529,18 +529,18 @@ namespace ts { "======== Module name 'fs' was not resolved. ========", ], "should look for 'fs'"); - const program_2 = updateProgram(program, program.getRootFileNames(), options, f => { + const program2 = updateProgram(program, program.getRootFileNames(), options, f => { f[0].text = f[0].text.updateProgram("var x = 1;"); }); - assert.deepEqual(program_2.host.getTrace(), [ + assert.deepEqual(program2.host.getTrace(), [ "Module 'fs' was resolved as ambient module declared in '/a/b/node.d.ts' since this file was not modified." ], "should reuse 'fs' since node.d.ts was not changed"); - const program_3 = updateProgram(program_2, program_2.getRootFileNames(), options, f => { + const program3 = updateProgram(program2, program2.getRootFileNames(), options, f => { f[0].text = f[0].text.updateProgram("var y = 1;"); f[1].text = f[1].text.updateProgram("declare var process: any"); }); - assert.deepEqual(program_3.host.getTrace(), + assert.deepEqual(program3.host.getTrace(), [ "======== Resolving module 'fs' from '/a/b/app.ts'. ========", "Module resolution kind is not specified, using 'Classic'.", @@ -598,10 +598,10 @@ namespace ts { ]; const options: CompilerOptions = { target: ScriptTarget.ES2015, traceResolution: true, moduleResolution: ModuleResolutionKind.Classic }; - const program_1 = newProgram(files, files.map(f => f.name), options); + const program1 = newProgram(files, files.map(f => f.name), options); let expectedErrors = 0; { - assert.deepEqual(program_1.host.getTrace(), + assert.deepEqual(program1.host.getTrace(), [ "======== Resolving type reference directive 'typerefs1', containing file 'f1.ts', root directory 'node_modules/@types'. ========", "Resolving with primary search path 'node_modules/@types'.", @@ -626,22 +626,22 @@ namespace ts { "File 'f1.ts' exist - use it as a name resolution result.", "======== Module name './f1' was successfully resolved to 'f1.ts'. ========" ], - "program_1: execute module resolution normally."); + "program1: execute module resolution normally."); - const program_1Diagnostics = program_1.getSemanticDiagnostics(program_1.getSourceFile("f2.ts")); - assert.lengthOf(program_1Diagnostics, expectedErrors, `initial program should be well-formed`); + const program1Diagnostics = program1.getSemanticDiagnostics(program1.getSourceFile("f2.ts")); + assert.lengthOf(program1Diagnostics, expectedErrors, `initial program should be well-formed`); } const indexOfF1 = 6; - const program_2 = updateProgram(program_1, program_1.getRootFileNames(), options, f => { + const program2 = updateProgram(program1, program1.getRootFileNames(), options, f => { const newSourceText = f[indexOfF1].text.updateReferences(`/// ${newLine}/// `); f[indexOfF1] = { name: "f1.ts", text: newSourceText }; }); { - const program_2Diagnostics = program_2.getSemanticDiagnostics(program_2.getSourceFile("f2.ts")); - assert.lengthOf(program_2Diagnostics, expectedErrors, `removing no-default-lib shouldn't affect any types used.`); + const program2Diagnostics = program2.getSemanticDiagnostics(program2.getSourceFile("f2.ts")); + assert.lengthOf(program2Diagnostics, expectedErrors, `removing no-default-lib shouldn't affect any types used.`); - assert.deepEqual(program_2.host.getTrace(), [ + assert.deepEqual(program2.host.getTrace(), [ "======== Resolving type reference directive 'typerefs1', containing file 'f1.ts', root directory 'node_modules/@types'. ========", "Resolving with primary search path 'node_modules/@types'.", "File 'node_modules/@types/typerefs1/package.json' does not exist.", @@ -658,19 +658,19 @@ namespace ts { "======== Type reference directive 'typerefs2' was successfully resolved to 'node_modules/@types/typerefs2/index.d.ts', primary: true. ========", "Reusing resolution of module './b2' to file 'f2.ts' from old program.", "Reusing resolution of module './f1' to file 'f2.ts' from old program." - ], "program_2: reuse module resolutions in f2 since it is unchanged"); + ], "program2: reuse module resolutions in f2 since it is unchanged"); } - const program_3 = updateProgram(program_2, program_2.getRootFileNames(), options, f => { + const program3 = updateProgram(program2, program2.getRootFileNames(), options, f => { const newSourceText = f[indexOfF1].text.updateReferences(`/// `); f[indexOfF1] = { name: "f1.ts", text: newSourceText }; }); { - const program_3Diagnostics = program_3.getSemanticDiagnostics(program_3.getSourceFile("f2.ts")); - assert.lengthOf(program_3Diagnostics, expectedErrors, `typerefs2 was unused, so diagnostics should be unaffected.`); + const program3Diagnostics = program3.getSemanticDiagnostics(program3.getSourceFile("f2.ts")); + assert.lengthOf(program3Diagnostics, expectedErrors, `typerefs2 was unused, so diagnostics should be unaffected.`); - assert.deepEqual(program_3.host.getTrace(), [ + assert.deepEqual(program3.host.getTrace(), [ "======== Resolving module './b1' from 'f1.ts'. ========", "Explicitly specified module resolution kind: 'Classic'.", "File 'b1.ts' exist - use it as a name resolution result.", @@ -682,20 +682,20 @@ namespace ts { "======== Type reference directive 'typerefs2' was successfully resolved to 'node_modules/@types/typerefs2/index.d.ts', primary: true. ========", "Reusing resolution of module './b2' to file 'f2.ts' from old program.", "Reusing resolution of module './f1' to file 'f2.ts' from old program." - ], "program_3: reuse module resolutions in f2 since it is unchanged"); + ], "program3: reuse module resolutions in f2 since it is unchanged"); } - const program_4 = updateProgram(program_3, program_3.getRootFileNames(), options, f => { + const program4 = updateProgram(program3, program3.getRootFileNames(), options, f => { const newSourceText = f[indexOfF1].text.updateReferences(""); f[indexOfF1] = { name: "f1.ts", text: newSourceText }; }); { - const program_4Diagnostics = program_4.getSemanticDiagnostics(program_4.getSourceFile("f2.ts")); - assert.lengthOf(program_4Diagnostics, expectedErrors, `a1.ts was unused, so diagnostics should be unaffected.`); + const program4Diagnostics = program4.getSemanticDiagnostics(program4.getSourceFile("f2.ts")); + assert.lengthOf(program4Diagnostics, expectedErrors, `a1.ts was unused, so diagnostics should be unaffected.`); - assert.deepEqual(program_4.host.getTrace(), [ + assert.deepEqual(program4.host.getTrace(), [ "======== Resolving module './b1' from 'f1.ts'. ========", "Explicitly specified module resolution kind: 'Classic'.", "File 'b1.ts' exist - use it as a name resolution result.", @@ -710,16 +710,16 @@ namespace ts { ], "program_4: reuse module resolutions in f2 since it is unchanged"); } - const program_5 = updateProgram(program_4, program_4.getRootFileNames(), options, f => { + const program5 = updateProgram(program4, program4.getRootFileNames(), options, f => { const newSourceText = f[indexOfF1].text.updateImportsAndExports(`import { B } from './b1';`); f[indexOfF1] = { name: "f1.ts", text: newSourceText }; }); { - const program_5Diagnostics = program_5.getSemanticDiagnostics(program_5.getSourceFile("f2.ts")); - assert.lengthOf(program_5Diagnostics, ++expectedErrors, `import of BB in f1 fails. BB is of type any. Add one error`); + const program5Diagnostics = program5.getSemanticDiagnostics(program5.getSourceFile("f2.ts")); + assert.lengthOf(program5Diagnostics, ++expectedErrors, `import of BB in f1 fails. BB is of type any. Add one error`); - assert.deepEqual(program_5.host.getTrace(), [ + assert.deepEqual(program5.host.getTrace(), [ "======== Resolving module './b1' from 'f1.ts'. ========", "Explicitly specified module resolution kind: 'Classic'.", "File 'b1.ts' exist - use it as a name resolution result.", @@ -727,16 +727,16 @@ namespace ts { ], "program_5: exports do not affect program structure, so f2's resolutions are silently reused."); } - const program_6 = updateProgram(program_5, program_5.getRootFileNames(), options, f => { + const program6 = updateProgram(program5, program5.getRootFileNames(), options, f => { const newSourceText = f[indexOfF1].text.updateProgram(""); f[indexOfF1] = { name: "f1.ts", text: newSourceText }; }); { - const program_6Diagnostics = program_6.getSemanticDiagnostics(program_6.getSourceFile("f2.ts")); - assert.lengthOf(program_6Diagnostics, expectedErrors, `import of BB in f1 fails.`); + const program6Diagnostics = program6.getSemanticDiagnostics(program6.getSourceFile("f2.ts")); + assert.lengthOf(program6Diagnostics, expectedErrors, `import of BB in f1 fails.`); - assert.deepEqual(program_6.host.getTrace(), [ + assert.deepEqual(program6.host.getTrace(), [ "======== Resolving module './b1' from 'f1.ts'. ========", "Explicitly specified module resolution kind: 'Classic'.", "File 'b1.ts' exist - use it as a name resolution result.", @@ -751,16 +751,16 @@ namespace ts { ], "program_6: reuse module resolutions in f2 since it is unchanged"); } - const program_7 = updateProgram(program_6, program_6.getRootFileNames(), options, f => { + const program7 = updateProgram(program6, program6.getRootFileNames(), options, f => { const newSourceText = f[indexOfF1].text.updateImportsAndExports(""); f[indexOfF1] = { name: "f1.ts", text: newSourceText }; }); { - const program_7Diagnostics = program_7.getSemanticDiagnostics(program_7.getSourceFile("f2.ts")); - assert.lengthOf(program_7Diagnostics, expectedErrors, `removing import is noop with respect to program, so no change in diagnostics.`); + const program7Diagnostics = program7.getSemanticDiagnostics(program7.getSourceFile("f2.ts")); + assert.lengthOf(program7Diagnostics, expectedErrors, `removing import is noop with respect to program, so no change in diagnostics.`); - assert.deepEqual(program_7.host.getTrace(), [ + assert.deepEqual(program7.host.getTrace(), [ "======== Resolving type reference directive 'typerefs2', containing file 'f2.ts', root directory 'node_modules/@types'. ========", "Resolving with primary search path 'node_modules/@types'.", "File 'node_modules/@types/typerefs2/package.json' does not exist.", @@ -820,47 +820,47 @@ namespace ts { } it("No changes -> redirect not broken", () => { - const program_1 = createRedirectProgram(); + const program1 = createRedirectProgram(); - const program_2 = updateRedirectProgram(program_1, files => { + const program2 = updateRedirectProgram(program1, files => { updateProgramText(files, root, "const x = 1;"); }); - assert.equal(program_1.structureIsReused, StructureIsReused.Completely); - assert.deepEqual(program_2.getSemanticDiagnostics(), emptyArray); + assert.equal(program1.structureIsReused, StructureIsReused.Completely); + assert.deepEqual(program2.getSemanticDiagnostics(), emptyArray); }); it("Target changes -> redirect broken", () => { - const program_1 = createRedirectProgram(); - assert.deepEqual(program_1.getSemanticDiagnostics(), emptyArray); + const program1 = createRedirectProgram(); + assert.deepEqual(program1.getSemanticDiagnostics(), emptyArray); - const program_2 = updateRedirectProgram(program_1, files => { + const program2 = updateRedirectProgram(program1, files => { updateProgramText(files, axIndex, "export default class X { private x: number; private y: number; }"); updateProgramText(files, axPackage, JSON.stringify('{ name: "x", version: "1.2.4" }')); }); - assert.equal(program_1.structureIsReused, StructureIsReused.Not); - assert.lengthOf(program_2.getSemanticDiagnostics(), 1); + assert.equal(program1.structureIsReused, StructureIsReused.Not); + assert.lengthOf(program2.getSemanticDiagnostics(), 1); }); it("Underlying changes -> redirect broken", () => { - const program_1 = createRedirectProgram(); + const program1 = createRedirectProgram(); - const program_2 = updateRedirectProgram(program_1, files => { + const program2 = updateRedirectProgram(program1, files => { updateProgramText(files, bxIndex, "export default class X { private x: number; private y: number; }"); updateProgramText(files, bxPackage, JSON.stringify({ name: "x", version: "1.2.4" })); }); - assert.equal(program_1.structureIsReused, StructureIsReused.Not); - assert.lengthOf(program_2.getSemanticDiagnostics(), 1); + assert.equal(program1.structureIsReused, StructureIsReused.Not); + assert.lengthOf(program2.getSemanticDiagnostics(), 1); }); it("Previously duplicate packages -> program structure not reused", () => { - const program_1 = createRedirectProgram({ bVersion: "1.2.4", bText: "export = class X { private x: number; }" }); + const program1 = createRedirectProgram({ bVersion: "1.2.4", bText: "export = class X { private x: number; }" }); - const program_2 = updateRedirectProgram(program_1, files => { + const program2 = updateRedirectProgram(program1, files => { updateProgramText(files, bxIndex, "export default class X { private x: number; }"); updateProgramText(files, bxPackage, JSON.stringify({ name: "x", version: "1.2.3" })); }); - assert.equal(program_1.structureIsReused, StructureIsReused.Not); - assert.deepEqual(program_2.getSemanticDiagnostics(), []); + assert.equal(program1.structureIsReused, StructureIsReused.Not); + assert.deepEqual(program2.getSemanticDiagnostics(), []); }); }); }); diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 9ec190c152f..2511c6c30c3 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -9,10 +9,12 @@ namespace ts.server { export const maxProgramSizeForNonTsFiles = 20 * 1024 * 1024; + // tslint:disable variable-name export const ProjectsUpdatedInBackgroundEvent = "projectsUpdatedInBackground"; export const ConfigFileDiagEvent = "configFileDiag"; export const ProjectLanguageServiceStateEvent = "projectLanguageServiceState"; export const ProjectInfoTelemetryEvent = "projectInfo"; + // tslint:enable variable-name export interface ProjectsUpdatedInBackgroundEvent { eventName: typeof ProjectsUpdatedInBackgroundEvent; @@ -1061,7 +1063,7 @@ namespace ts.server { * Returns true if the configFileExistenceInfo is needed/impacted by open files that are root of inferred project */ private configFileExistenceImpactsRootOfInferredProject(configFileExistenceInfo: ConfigFileExistenceInfo) { - return forEachEntry(configFileExistenceInfo.openFilesImpactedByConfigFile, (isRootOfInferredProject, __key) => isRootOfInferredProject); + return forEachEntry(configFileExistenceInfo.openFilesImpactedByConfigFile, (isRootOfInferredProject) => isRootOfInferredProject); } private setConfigFileExistenceInfoByClosedConfiguredProject(closedProject: ConfiguredProject) { diff --git a/src/server/session.ts b/src/server/session.ts index 3f223b13963..dc9ddab7ae1 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -124,7 +124,7 @@ namespace ts.server { // we want to ensure the value is maintained in the out since the file is // built using --preseveConstEnum. export type CommandNames = protocol.CommandTypes; - export const CommandNames = (protocol).CommandTypes; + export const CommandNames = (protocol).CommandTypes; // tslint:disable-line variable-name export function formatMessage(msg: T, logger: server.Logger, byteLength: (s: string, encoding: string) => number, newLine: string): string { const verboseLogging = logger.hasLevel(LogLevel.verbose); diff --git a/src/server/shared.ts b/src/server/shared.ts index a8a122c3327..99a38eba389 100644 --- a/src/server/shared.ts +++ b/src/server/shared.ts @@ -1,6 +1,7 @@ /// namespace ts.server { + // tslint:disable variable-name export const ActionSet: ActionSet = "action::set"; export const ActionInvalidate: ActionInvalidate = "action::invalidate"; export const EventTypesRegistry: EventTypesRegistry = "event::typesRegistry"; diff --git a/src/server/typingsInstaller/nodeTypingsInstaller.ts b/src/server/typingsInstaller/nodeTypingsInstaller.ts index 2a1036010a7..da16d5dde82 100644 --- a/src/server/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/server/typingsInstaller/nodeTypingsInstaller.ts @@ -63,9 +63,9 @@ namespace ts.server.typingsInstaller { } } - const TypesRegistryPackageName = "types-registry"; + const typesRegistryPackageName = "types-registry"; function getTypesRegistryFileLocation(globalTypingsCacheLocation: string): string { - return combinePaths(normalizeSlashes(globalTypingsCacheLocation), `node_modules/${TypesRegistryPackageName}/index.json`); + return combinePaths(normalizeSlashes(globalTypingsCacheLocation), `node_modules/${typesRegistryPackageName}/index.json`); } interface ExecSyncOptions { @@ -105,16 +105,16 @@ namespace ts.server.typingsInstaller { try { if (this.log.isEnabled()) { - this.log.writeLine(`Updating ${TypesRegistryPackageName} npm package...`); + this.log.writeLine(`Updating ${typesRegistryPackageName} npm package...`); } - this.execSyncAndLog(`${this.npmPath} install --ignore-scripts ${TypesRegistryPackageName}`, { cwd: globalTypingsCacheLocation }); + this.execSyncAndLog(`${this.npmPath} install --ignore-scripts ${typesRegistryPackageName}`, { cwd: globalTypingsCacheLocation }); if (this.log.isEnabled()) { - this.log.writeLine(`Updated ${TypesRegistryPackageName} npm package`); + this.log.writeLine(`Updated ${typesRegistryPackageName} npm package`); } } catch (e) { if (this.log.isEnabled()) { - this.log.writeLine(`Error updating ${TypesRegistryPackageName} package: ${(e).message}`); + this.log.writeLine(`Error updating ${typesRegistryPackageName} package: ${(e).message}`); } // store error info to report it later when it is known that server is already listening to events from typings installer this.delayedInitializationError = { @@ -243,7 +243,7 @@ namespace ts.server.typingsInstaller { const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, typingSafeListLocation, typesMapLocation, npmLocation, /*throttleLimit*/5, log); installer.listen(); - function indent(newline: string, string: string): string { - return `${newline} ` + string.replace(/\r?\n/, `${newline} `); + function indent(newline: string, str: string): string { + return `${newline} ` + str.replace(/\r?\n/, `${newline} `); } } diff --git a/src/server/utilities.ts b/src/server/utilities.ts index 69399b672b3..096d4484154 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -24,6 +24,7 @@ namespace ts.server { } export namespace Msg { + // tslint:disable variable-name export type Err = "Err"; export const Err: Err = "Err"; export type Info = "Info"; @@ -31,6 +32,7 @@ namespace ts.server { export type Perf = "Perf"; export const Perf: Perf = "Perf"; export type Types = Err | Info | Perf; + // tslint:enable variable-name } function getProjectRootPath(project: Project): Path { @@ -320,8 +322,8 @@ namespace ts.server { } /* @internal */ - export function indent(string: string): string { - return "\n " + string; + export function indent(str: string): string { + return "\n " + str; } /** Put stringified JSON on the next line, indented. */ diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index fdd70cda461..529fdae0545 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -924,7 +924,7 @@ namespace ts.formatting { if (rule) { applyRuleEdits(rule, previousItem, previousStartLine, currentItem, currentStartLine); - if (rule.Operation.Action & (RuleAction.Space | RuleAction.Delete) && currentStartLine !== previousStartLine) { + if (rule.operation.action & (RuleAction.Space | RuleAction.Delete) && currentStartLine !== previousStartLine) { lineAdded = false; // Handle the case where the next line is moved to be the end of this line. // In this case we don't indent the next line in the next pass. @@ -932,7 +932,7 @@ namespace ts.formatting { dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ false); } } - else if (rule.Operation.Action & RuleAction.NewLine && currentStartLine === previousStartLine) { + else if (rule.operation.action & RuleAction.NewLine && currentStartLine === previousStartLine) { lineAdded = true; // Handle the case where token2 is moved to the new line. // In this case we indent token2 in the next pass but we set @@ -943,7 +943,7 @@ namespace ts.formatting { } // We need to trim trailing whitespace between the tokens if they were on different lines, and no rule was applied to put them on the same line - trimTrailingWhitespaces = !(rule.Operation.Action & RuleAction.Delete) && rule.Flag !== RuleFlags.CanDeleteNewLines; + trimTrailingWhitespaces = !(rule.operation.action & RuleAction.Delete) && rule.flag !== RuleFlags.CanDeleteNewLines; } else { trimTrailingWhitespaces = true; @@ -1118,7 +1118,7 @@ namespace ts.formatting { currentRange: TextRangeWithKind, currentStartLine: number): void { - switch (rule.Operation.Action) { + switch (rule.operation.action) { case RuleAction.Ignore: // no action required return; @@ -1132,7 +1132,7 @@ namespace ts.formatting { // exit early if we on different lines and rule cannot change number of newlines // if line1 and line2 are on subsequent lines then no edits are required - ok to exit // if line1 and line2 are separated with more than one newline - ok to exit since we cannot delete extra new lines - if (rule.Flag !== RuleFlags.CanDeleteNewLines && previousStartLine !== currentStartLine) { + if (rule.flag !== RuleFlags.CanDeleteNewLines && previousStartLine !== currentStartLine) { return; } @@ -1144,7 +1144,7 @@ namespace ts.formatting { break; case RuleAction.Space: // exit early if we on different lines and rule cannot change number of newlines - if (rule.Flag !== RuleFlags.CanDeleteNewLines && previousStartLine !== currentStartLine) { + if (rule.flag !== RuleFlags.CanDeleteNewLines && previousStartLine !== currentStartLine) { return; } diff --git a/src/services/formatting/rule.ts b/src/services/formatting/rule.ts index 10987c745c2..8fd432586b4 100644 --- a/src/services/formatting/rule.ts +++ b/src/services/formatting/rule.ts @@ -6,9 +6,9 @@ namespace ts.formatting { // Used for debugging to identify each rule based on the property name it's assigned to. public debugName?: string; constructor( - readonly Descriptor: RuleDescriptor, - readonly Operation: RuleOperation, - readonly Flag: RuleFlags = RuleFlags.None) { + readonly descriptor: RuleDescriptor, + readonly operation: RuleOperation, + readonly flag: RuleFlags = RuleFlags.None) { } } } \ No newline at end of file diff --git a/src/services/formatting/ruleDescriptor.ts b/src/services/formatting/ruleDescriptor.ts index 96506adc3dc..b8529496956 100644 --- a/src/services/formatting/ruleDescriptor.ts +++ b/src/services/formatting/ruleDescriptor.ts @@ -3,12 +3,12 @@ /* @internal */ namespace ts.formatting { export class RuleDescriptor { - constructor(public LeftTokenRange: Shared.TokenRange, public RightTokenRange: Shared.TokenRange) { + constructor(public leftTokenRange: Shared.TokenRange, public rightTokenRange: Shared.TokenRange) { } public toString(): string { - return "[leftRange=" + this.LeftTokenRange + "," + - "rightRange=" + this.RightTokenRange + "]"; + return "[leftRange=" + this.leftTokenRange + "," + + "rightRange=" + this.rightTokenRange + "]"; } static create1(left: SyntaxKind, right: SyntaxKind): RuleDescriptor { diff --git a/src/services/formatting/ruleOperation.ts b/src/services/formatting/ruleOperation.ts index 8ad83b11653..462c27352d8 100644 --- a/src/services/formatting/ruleOperation.ts +++ b/src/services/formatting/ruleOperation.ts @@ -3,15 +3,15 @@ /* @internal */ namespace ts.formatting { export class RuleOperation { - constructor(public Context: RuleOperationContext, public Action: RuleAction) {} + constructor(readonly context: RuleOperationContext, readonly action: RuleAction) {} public toString(): string { - return "[context=" + this.Context + "," + - "action=" + this.Action + "]"; + return "[context=" + this.context + "," + + "action=" + this.action + "]"; } static create1(action: RuleAction) { - return RuleOperation.create2(RuleOperationContext.Any, action); + return RuleOperation.create2(RuleOperationContext.any, action); } static create2(context: RuleOperationContext, action: RuleAction) { diff --git a/src/services/formatting/ruleOperationContext.ts b/src/services/formatting/ruleOperationContext.ts index f03b19516d5..c433d106372 100644 --- a/src/services/formatting/ruleOperationContext.ts +++ b/src/services/formatting/ruleOperationContext.ts @@ -10,10 +10,10 @@ namespace ts.formatting { this.customContextChecks = funcs; } - static readonly Any: RuleOperationContext = new RuleOperationContext(); + static readonly any: RuleOperationContext = new RuleOperationContext(); public IsAny(): boolean { - return this === RuleOperationContext.Any; + return this === RuleOperationContext.any; } public InContext(context: FormattingContext): boolean { diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 32d01eb1a16..c5b59e818eb 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -2,6 +2,7 @@ /* @internal */ namespace ts.formatting { + // tslint:disable variable-name (TODO) export class Rules { public IgnoreBeforeComment: Rule; public IgnoreAfterLineComment: Rule; diff --git a/src/services/formatting/rulesMap.ts b/src/services/formatting/rulesMap.ts index d1f6e4724f7..3b04308ebe8 100644 --- a/src/services/formatting/rulesMap.ts +++ b/src/services/formatting/rulesMap.ts @@ -23,10 +23,10 @@ namespace ts.formatting { } private FillRule(rule: Rule, rulesBucketConstructionStateList: RulesBucketConstructionState[]): void { - const specificRule = rule.Descriptor.LeftTokenRange.isSpecific() && rule.Descriptor.RightTokenRange.isSpecific(); + const specificRule = rule.descriptor.leftTokenRange.isSpecific() && rule.descriptor.rightTokenRange.isSpecific(); - rule.Descriptor.LeftTokenRange.GetTokens().forEach((left) => { - rule.Descriptor.RightTokenRange.GetTokens().forEach((right) => { + rule.descriptor.leftTokenRange.GetTokens().forEach((left) => { + rule.descriptor.rightTokenRange.GetTokens().forEach((right) => { const rulesBucketIndex = this.GetRuleBucketIndex(left, right); let rulesBucket = this.map[rulesBucketIndex]; @@ -44,7 +44,7 @@ namespace ts.formatting { const bucket = this.map[bucketIndex]; if (bucket) { for (const rule of bucket.Rules()) { - if (rule.Operation.Context.InContext(context)) { + if (rule.operation.context.InContext(context)) { return rule; } } @@ -53,16 +53,16 @@ namespace ts.formatting { } } - const MaskBitSize = 5; - const Mask = 0x1f; + const maskBitSize = 5; + const mask = 0x1f; enum RulesPosition { IgnoreRulesSpecific = 0, - IgnoreRulesAny = MaskBitSize * 1, - ContextRulesSpecific = MaskBitSize * 2, - ContextRulesAny = MaskBitSize * 3, - NoContextRulesSpecific = MaskBitSize * 4, - NoContextRulesAny = MaskBitSize * 5 + IgnoreRulesAny = maskBitSize * 1, + ContextRulesSpecific = maskBitSize * 2, + ContextRulesAny = maskBitSize * 3, + NoContextRulesSpecific = maskBitSize * 4, + NoContextRulesAny = maskBitSize * 5 } export class RulesBucketConstructionState { @@ -94,20 +94,20 @@ namespace ts.formatting { let indexBitmap = this.rulesInsertionIndexBitmap; while (pos <= maskPosition) { - index += (indexBitmap & Mask); - indexBitmap >>= MaskBitSize; - pos += MaskBitSize; + index += (indexBitmap & mask); + indexBitmap >>= maskBitSize; + pos += maskBitSize; } return index; } public IncreaseInsertionIndex(maskPosition: RulesPosition): void { - let value = (this.rulesInsertionIndexBitmap >> maskPosition) & Mask; + let value = (this.rulesInsertionIndexBitmap >> maskPosition) & mask; value++; - Debug.assert((value & Mask) === value, "Adding more rules into the sub-bucket than allowed. Maximum allowed is 32 rules."); + Debug.assert((value & mask) === value, "Adding more rules into the sub-bucket than allowed. Maximum allowed is 32 rules."); - let temp = this.rulesInsertionIndexBitmap & ~(Mask << maskPosition); + let temp = this.rulesInsertionIndexBitmap & ~(mask << maskPosition); temp |= value << maskPosition; this.rulesInsertionIndexBitmap = temp; @@ -128,12 +128,12 @@ namespace ts.formatting { public AddRule(rule: Rule, specificTokens: boolean, constructionState: RulesBucketConstructionState[], rulesBucketIndex: number): void { let position: RulesPosition; - if (rule.Operation.Action === RuleAction.Ignore) { + if (rule.operation.action === RuleAction.Ignore) { position = specificTokens ? RulesPosition.IgnoreRulesSpecific : RulesPosition.IgnoreRulesAny; } - else if (!rule.Operation.Context.IsAny()) { + else if (!rule.operation.context.IsAny()) { position = specificTokens ? RulesPosition.ContextRulesSpecific : RulesPosition.ContextRulesAny; diff --git a/src/services/formatting/tokenRange.ts b/src/services/formatting/tokenRange.ts index 29855279e25..31e15bc738d 100644 --- a/src/services/formatting/tokenRange.ts +++ b/src/services/formatting/tokenRange.ts @@ -95,6 +95,7 @@ namespace ts.formatting { return new TokenAllExceptAccess(token); } + // tslint:disable variable-name (TODO) export const Any: TokenRange = new TokenAllAccess(); export const AnyIncludingMultilineComments = TokenRange.FromTokens([...allTokens, SyntaxKind.MultiLineCommentTrivia]); export const Keywords = TokenRange.FromRange(SyntaxKind.FirstKeyword, SyntaxKind.LastKeyword); diff --git a/src/services/jsTyping.ts b/src/services/jsTyping.ts index 572858dd2fd..0c250d75f92 100644 --- a/src/services/jsTyping.ts +++ b/src/services/jsTyping.ts @@ -257,7 +257,7 @@ namespace ts.JsTyping { NameContainsNonURISafeCharacters } - const MaxPackageNameLength = 214; + const maxPackageNameLength = 214; /** * Validates package name using rules defined at https://docs.npmjs.com/files/package.json @@ -266,7 +266,7 @@ namespace ts.JsTyping { if (!packageName) { return PackageNameValidationResult.EmptyName; } - if (packageName.length > MaxPackageNameLength) { + if (packageName.length > maxPackageNameLength) { return PackageNameValidationResult.NameTooLong; } if (packageName.charCodeAt(0) === CharacterCodes.dot) { @@ -292,7 +292,7 @@ namespace ts.JsTyping { case PackageNameValidationResult.EmptyName: return `Package name '${typing}' cannot be empty`; case PackageNameValidationResult.NameTooLong: - return `Package name '${typing}' should be less than ${MaxPackageNameLength} characters`; + return `Package name '${typing}' should be less than ${maxPackageNameLength} characters`; case PackageNameValidationResult.NameStartsWithDot: return `Package name '${typing}' cannot start with '.'`; case PackageNameValidationResult.NameStartsWithUnderscore: diff --git a/src/services/patternMatcher.ts b/src/services/patternMatcher.ts index 04f9d906d35..db957816146 100644 --- a/src/services/patternMatcher.ts +++ b/src/services/patternMatcher.ts @@ -515,10 +515,10 @@ namespace ts { } // Assumes 'value' is already lowercase. - function indexOfIgnoringCase(string: string, value: string): number { - const n = string.length - value.length; + function indexOfIgnoringCase(str: string, value: string): number { + const n = str.length - value.length; for (let i = 0; i <= n; i++) { - if (startsWithIgnoringCase(string, value, i)) { + if (startsWithIgnoringCase(str, value, i)) { return i; } } @@ -527,9 +527,9 @@ namespace ts { } // Assumes 'value' is already lowercase. - function startsWithIgnoringCase(string: string, value: string, start: number): boolean { + function startsWithIgnoringCase(str: string, value: string, start: number): boolean { for (let i = 0; i < value.length; i++) { - const ch1 = toLowerCase(string.charCodeAt(i + start)); + const ch1 = toLowerCase(str.charCodeAt(i + start)); const ch2 = value.charCodeAt(i); if (ch1 !== ch2) { diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 58e57675459..11f659a8b43 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -122,28 +122,28 @@ namespace ts.refactor.extractSymbol { return { message, code: 0, category: DiagnosticCategory.Message, key: message }; } - export const CannotExtractRange: DiagnosticMessage = createMessage("Cannot extract range."); - export const CannotExtractImport: DiagnosticMessage = createMessage("Cannot extract import statement."); - export const CannotExtractSuper: DiagnosticMessage = createMessage("Cannot extract super call."); - export const CannotExtractEmpty: DiagnosticMessage = createMessage("Cannot extract empty range."); - export const ExpressionExpected: DiagnosticMessage = createMessage("expression expected."); - export const UselessConstantType: DiagnosticMessage = createMessage("No reason to extract constant of type."); - export const StatementOrExpressionExpected: DiagnosticMessage = createMessage("Statement or expression expected."); - export const CannotExtractRangeContainingConditionalBreakOrContinueStatements: DiagnosticMessage = createMessage("Cannot extract range containing conditional break or continue statements."); - export const CannotExtractRangeContainingConditionalReturnStatement: DiagnosticMessage = createMessage("Cannot extract range containing conditional return statement."); - export const CannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange: DiagnosticMessage = createMessage("Cannot extract range containing labeled break or continue with target outside of the range."); - export const CannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators: DiagnosticMessage = createMessage("Cannot extract range containing writes to references located outside of the target range in generators."); - export const TypeWillNotBeVisibleInTheNewScope = createMessage("Type will not visible in the new scope."); - export const FunctionWillNotBeVisibleInTheNewScope = createMessage("Function will not visible in the new scope."); - export const CannotExtractIdentifier = createMessage("Select more than a single identifier."); - export const CannotExtractExportedEntity = createMessage("Cannot extract exported declaration"); - export const CannotWriteInExpression = createMessage("Cannot write back side-effects when extracting an expression"); - export const CannotExtractReadonlyPropertyInitializerOutsideConstructor = createMessage("Cannot move initialization of read-only class property outside of the constructor"); - export const CannotExtractAmbientBlock = createMessage("Cannot extract code from ambient contexts"); - export const CannotAccessVariablesFromNestedScopes = createMessage("Cannot access variables from nested scopes"); - export const CannotExtractToOtherFunctionLike = createMessage("Cannot extract method to a function-like scope that is not a function"); - export const CannotExtractToJSClass = createMessage("Cannot extract constant to a class scope in JS"); - export const CannotExtractToExpressionArrowFunction = createMessage("Cannot extract constant to an arrow function without a block"); + export const cannotExtractRange: DiagnosticMessage = createMessage("Cannot extract range."); + export const cannotExtractImport: DiagnosticMessage = createMessage("Cannot extract import statement."); + export const cannotExtractSuper: DiagnosticMessage = createMessage("Cannot extract super call."); + export const cannotExtractEmpty: DiagnosticMessage = createMessage("Cannot extract empty range."); + export const expressionExpected: DiagnosticMessage = createMessage("expression expected."); + export const uselessConstantType: DiagnosticMessage = createMessage("No reason to extract constant of type."); + export const statementOrExpressionExpected: DiagnosticMessage = createMessage("Statement or expression expected."); + export const cannotExtractRangeContainingConditionalBreakOrContinueStatements: DiagnosticMessage = createMessage("Cannot extract range containing conditional break or continue statements."); + export const cannotExtractRangeContainingConditionalReturnStatement: DiagnosticMessage = createMessage("Cannot extract range containing conditional return statement."); + export const cannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange: DiagnosticMessage = createMessage("Cannot extract range containing labeled break or continue with target outside of the range."); + export const cannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators: DiagnosticMessage = createMessage("Cannot extract range containing writes to references located outside of the target range in generators."); + export const typeWillNotBeVisibleInTheNewScope = createMessage("Type will not visible in the new scope."); + export const functionWillNotBeVisibleInTheNewScope = createMessage("Function will not visible in the new scope."); + export const cannotExtractIdentifier = createMessage("Select more than a single identifier."); + export const cannotExtractExportedEntity = createMessage("Cannot extract exported declaration"); + export const cannotWriteInExpression = createMessage("Cannot write back side-effects when extracting an expression"); + export const cannotExtractReadonlyPropertyInitializerOutsideConstructor = createMessage("Cannot move initialization of read-only class property outside of the constructor"); + export const cannotExtractAmbientBlock = createMessage("Cannot extract code from ambient contexts"); + export const cannotAccessVariablesFromNestedScopes = createMessage("Cannot access variables from nested scopes"); + export const cannotExtractToOtherFunctionLike = createMessage("Cannot extract method to a function-like scope that is not a function"); + export const cannotExtractToJSClass = createMessage("Cannot extract constant to a class scope in JS"); + export const cannotExtractToExpressionArrowFunction = createMessage("Cannot extract constant to an arrow function without a block"); } enum RangeFacts { @@ -198,7 +198,7 @@ namespace ts.refactor.extractSymbol { const { length } = span; if (length === 0) { - return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractEmpty)] }; + return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractEmpty)] }; } // Walk up starting from the the start position until we find a non-SourceFile node that subsumes the selected span. @@ -215,18 +215,18 @@ namespace ts.refactor.extractSymbol { if (!start || !end) { // cannot find either start or end node - return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractRange)] }; + return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] }; } if (start.parent !== end.parent) { // start and end nodes belong to different subtrees - return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractRange)] }; + return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] }; } if (start !== end) { // start and end should be statements and parent should be either block or a source file if (!isBlockLike(start.parent)) { - return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractRange)] }; + return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] }; } const statements: Statement[] = []; for (const statement of (start.parent).statements) { @@ -246,7 +246,7 @@ namespace ts.refactor.extractSymbol { if (isReturnStatement(start) && !start.expression) { // Makes no sense to extract an expression-less return statement. - return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractRange)] }; + return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] }; } // We have a single node (start) @@ -293,7 +293,7 @@ namespace ts.refactor.extractSymbol { function checkRootNode(node: Node): Diagnostic[] | undefined { if (isIdentifier(isExpressionStatement(node) ? node.expression : node)) { - return [createDiagnosticForNode(node, Messages.CannotExtractIdentifier)]; + return [createDiagnosticForNode(node, Messages.cannotExtractIdentifier)]; } return undefined; } @@ -332,11 +332,11 @@ namespace ts.refactor.extractSymbol { Return = 1 << 2 } if (!isStatement(nodeToCheck) && !(isExpressionNode(nodeToCheck) && isExtractableExpression(nodeToCheck))) { - return [createDiagnosticForNode(nodeToCheck, Messages.StatementOrExpressionExpected)]; + return [createDiagnosticForNode(nodeToCheck, Messages.statementOrExpressionExpected)]; } if (nodeToCheck.flags & NodeFlags.Ambient) { - return [createDiagnosticForNode(nodeToCheck, Messages.CannotExtractAmbientBlock)]; + return [createDiagnosticForNode(nodeToCheck, Messages.cannotExtractAmbientBlock)]; } // If we're in a class, see whether we're in a static region (static property initializer, static method, class constructor parameter default) @@ -362,7 +362,7 @@ namespace ts.refactor.extractSymbol { if (isDeclaration(node)) { const declaringNode = (node.kind === SyntaxKind.VariableDeclaration) ? node.parent.parent : node; if (hasModifier(declaringNode, ModifierFlags.Export)) { - (errors || (errors = [])).push(createDiagnosticForNode(node, Messages.CannotExtractExportedEntity)); + (errors || (errors = [])).push(createDiagnosticForNode(node, Messages.cannotExtractExportedEntity)); return true; } declarations.push(node.symbol); @@ -371,7 +371,7 @@ namespace ts.refactor.extractSymbol { // Some things can't be extracted in certain situations switch (node.kind) { case SyntaxKind.ImportDeclaration: - (errors || (errors = [])).push(createDiagnosticForNode(node, Messages.CannotExtractImport)); + (errors || (errors = [])).push(createDiagnosticForNode(node, Messages.cannotExtractImport)); return true; case SyntaxKind.SuperKeyword: // For a super *constructor call*, we have to be extracting the entire class, @@ -380,7 +380,7 @@ namespace ts.refactor.extractSymbol { // Super constructor call const containingClass = getContainingClass(node); if (containingClass.pos < span.start || containingClass.end >= (span.start + span.length)) { - (errors || (errors = [])).push(createDiagnosticForNode(node, Messages.CannotExtractSuper)); + (errors || (errors = [])).push(createDiagnosticForNode(node, Messages.cannotExtractSuper)); return true; } } @@ -396,7 +396,7 @@ namespace ts.refactor.extractSymbol { case SyntaxKind.ClassDeclaration: if (node.parent.kind === SyntaxKind.SourceFile && (node.parent as ts.SourceFile).externalModuleIndicator === undefined) { // You cannot extract global declarations - (errors || (errors = [])).push(createDiagnosticForNode(node, Messages.FunctionWillNotBeVisibleInTheNewScope)); + (errors || (errors = [])).push(createDiagnosticForNode(node, Messages.functionWillNotBeVisibleInTheNewScope)); } break; } @@ -452,13 +452,13 @@ namespace ts.refactor.extractSymbol { if (label) { if (!contains(seenLabels, label.escapedText)) { // attempts to jump to label that is not in range to be extracted - (errors || (errors = [])).push(createDiagnosticForNode(node, Messages.CannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange)); + (errors || (errors = [])).push(createDiagnosticForNode(node, Messages.cannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange)); } } else { if (!(permittedJumps & (node.kind === SyntaxKind.BreakStatement ? PermittedJumps.Break : PermittedJumps.Continue))) { // attempt to break or continue in a forbidden context - (errors || (errors = [])).push(createDiagnosticForNode(node, Messages.CannotExtractRangeContainingConditionalBreakOrContinueStatements)); + (errors || (errors = [])).push(createDiagnosticForNode(node, Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements)); } } break; @@ -474,7 +474,7 @@ namespace ts.refactor.extractSymbol { rangeFacts |= RangeFacts.HasReturn; } else { - (errors || (errors = [])).push(createDiagnosticForNode(node, Messages.CannotExtractRangeContainingConditionalReturnStatement)); + (errors || (errors = [])).push(createDiagnosticForNode(node, Messages.cannotExtractRangeContainingConditionalReturnStatement)); } break; default: @@ -1455,10 +1455,10 @@ namespace ts.refactor.extractSymbol { const statements = targetRange.range as ReadonlyArray; const start = first(statements).getStart(); const end = last(statements).end; - expressionDiagnostic = createFileDiagnostic(sourceFile, start, end - start, Messages.ExpressionExpected); + expressionDiagnostic = createFileDiagnostic(sourceFile, start, end - start, Messages.expressionExpected); } else if (checker.getTypeAtLocation(expression).flags & (TypeFlags.Void | TypeFlags.Never)) { - expressionDiagnostic = createDiagnosticForNode(expression, Messages.UselessConstantType); + expressionDiagnostic = createDiagnosticForNode(expression, Messages.uselessConstantType); } // initialize results @@ -1468,7 +1468,7 @@ namespace ts.refactor.extractSymbol { functionErrorsPerScope.push( isFunctionLikeDeclaration(scope) && scope.kind !== SyntaxKind.FunctionDeclaration - ? [createDiagnosticForNode(scope, Messages.CannotExtractToOtherFunctionLike)] + ? [createDiagnosticForNode(scope, Messages.cannotExtractToOtherFunctionLike)] : []); const constantErrors = []; @@ -1476,11 +1476,11 @@ namespace ts.refactor.extractSymbol { constantErrors.push(expressionDiagnostic); } if (isClassLike(scope) && isInJavaScriptFile(scope)) { - constantErrors.push(createDiagnosticForNode(scope, Messages.CannotExtractToJSClass)); + constantErrors.push(createDiagnosticForNode(scope, Messages.cannotExtractToJSClass)); } if (isArrowFunction(scope) && !isBlock(scope.body)) { // TODO (https://github.com/Microsoft/TypeScript/issues/18924): allow this - constantErrors.push(createDiagnosticForNode(scope, Messages.CannotExtractToExpressionArrowFunction)); + constantErrors.push(createDiagnosticForNode(scope, Messages.cannotExtractToExpressionArrowFunction)); } constantErrorsPerScope.push(constantErrors); } @@ -1548,7 +1548,7 @@ namespace ts.refactor.extractSymbol { // local will actually be declared at the same level as the extracted expression). if (i > 0 && (scopeUsages.usages.size > 0 || scopeUsages.typeParameterUsages.size > 0)) { const errorNode = isReadonlyArray(targetRange.range) ? targetRange.range[0] : targetRange.range; - constantErrorsPerScope[i].push(createDiagnosticForNode(errorNode, Messages.CannotAccessVariablesFromNestedScopes)); + constantErrorsPerScope[i].push(createDiagnosticForNode(errorNode, Messages.cannotAccessVariablesFromNestedScopes)); } let hasWrite = false; @@ -1568,17 +1568,17 @@ namespace ts.refactor.extractSymbol { Debug.assert(isReadonlyArray(targetRange.range) || exposedVariableDeclarations.length === 0); if (hasWrite && !isReadonlyArray(targetRange.range)) { - const diag = createDiagnosticForNode(targetRange.range, Messages.CannotWriteInExpression); + const diag = createDiagnosticForNode(targetRange.range, Messages.cannotWriteInExpression); functionErrorsPerScope[i].push(diag); constantErrorsPerScope[i].push(diag); } else if (readonlyClassPropertyWrite && i > 0) { - const diag = createDiagnosticForNode(readonlyClassPropertyWrite, Messages.CannotExtractReadonlyPropertyInitializerOutsideConstructor); + const diag = createDiagnosticForNode(readonlyClassPropertyWrite, Messages.cannotExtractReadonlyPropertyInitializerOutsideConstructor); functionErrorsPerScope[i].push(diag); constantErrorsPerScope[i].push(diag); } else if (firstExposedNonVariableDeclaration) { - const diag = createDiagnosticForNode(firstExposedNonVariableDeclaration, Messages.CannotExtractExportedEntity); + const diag = createDiagnosticForNode(firstExposedNonVariableDeclaration, Messages.cannotExtractExportedEntity); functionErrorsPerScope[i].push(diag); constantErrorsPerScope[i].push(diag); } @@ -1710,7 +1710,7 @@ namespace ts.refactor.extractSymbol { if (targetRange.facts & RangeFacts.IsGenerator && usage === Usage.Write) { // this is write to a reference located outside of the target scope and range is extracted into generator // currently this is unsupported scenario - const diag = createDiagnosticForNode(identifier, Messages.CannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators); + const diag = createDiagnosticForNode(identifier, Messages.cannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators); for (const errors of functionErrorsPerScope) { errors.push(diag); } @@ -1733,7 +1733,7 @@ namespace ts.refactor.extractSymbol { // If the symbol is a type parameter that won't be in scope, we'll pass it as a type argument // so there's no problem. if (!(symbol.flags & SymbolFlags.TypeParameter)) { - const diag = createDiagnosticForNode(identifier, Messages.TypeWillNotBeVisibleInTheNewScope); + const diag = createDiagnosticForNode(identifier, Messages.typeWillNotBeVisibleInTheNewScope); functionErrorsPerScope[i].push(diag); constantErrorsPerScope[i].push(diag); } diff --git a/src/services/services.ts b/src/services/services.ts index 178d949990d..6345dae2d1f 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1997,9 +1997,7 @@ namespace ts { } function isNodeModulesFile(path: string): boolean { - const node_modulesFolderName = "/node_modules/"; - - return stringContains(path, node_modulesFolderName); + return stringContains(path, "/node_modules/"); } } diff --git a/tslint.json b/tslint.json index 299a1049e4c..9ad752e6094 100644 --- a/tslint.json +++ b/tslint.json @@ -74,6 +74,7 @@ // Config different from tslint:latest "no-implicit-dependencies": [true, "dev"], + "variable-name": [true, "ban-keywords", "check-format", "allow-leading-underscore"], // TODO "arrow-parens": false, // [true, "ban-single-arg-parens"] @@ -102,7 +103,6 @@ "space-before-function-paren": false, "trailing-comma": false, "unified-signatures": false, - "variable-name": false, // These should be done automatically by a formatter. https://github.com/Microsoft/TypeScript/issues/18340 "align": false, From a287ddc93bda8043ca4c6b5f1cbf15f25c50791c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 6 Nov 2017 09:25:41 -0800 Subject: [PATCH 127/235] Fix invariant generic error elaboration logic --- src/compiler/checker.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e2e45b2ccb0..4d5449a9526 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9432,6 +9432,7 @@ namespace ts { function structuredTypeRelatedTo(source: Type, target: Type, reportErrors: boolean): Ternary { let result: Ternary; + let originalErrorInfo: DiagnosticMessageChain; const saveErrorInfo = errorInfo; if (target.flags & TypeFlags.TypeParameter) { // A source type { [P in keyof T]: X } is related to a target type T if X is related to T[P]. @@ -9511,6 +9512,7 @@ namespace ts { // if we have indexed access types with identical index types, see if relationship holds for // the two object types. if (result = isRelatedTo((source).objectType, (target).objectType, reportErrors)) { + errorInfo = saveErrorInfo; return result; } } @@ -9542,6 +9544,10 @@ namespace ts { if (!(reportErrors && some(variances, v => v === Variance.Invariant))) { return Ternary.False; } + // We remember the original error information so we can restore it in case the structural + // comparison unexpectedly succeeds. This can happen when the structural comparison result + // is a Ternary.Maybe for example caused by the recursion depth limiter. + originalErrorInfo = errorInfo; errorInfo = saveErrorInfo; } } @@ -9580,8 +9586,11 @@ namespace ts { } } if (result) { - errorInfo = saveErrorInfo; - return result; + if (!originalErrorInfo) { + errorInfo = saveErrorInfo; + return result; + } + errorInfo = originalErrorInfo; } } } From baafe5157eb273d1c87d71ff9e270e25e15d7b05 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 6 Nov 2017 09:25:51 -0800 Subject: [PATCH 128/235] Add regression test --- ...nvariantGenericErrorElaboration.errors.txt | 54 +++++++++++++ .../invariantGenericErrorElaboration.js | 30 +++++++ .../invariantGenericErrorElaboration.symbols | 76 ++++++++++++++++++ .../invariantGenericErrorElaboration.types | 78 +++++++++++++++++++ .../invariantGenericErrorElaboration.ts | 24 ++++++ 5 files changed, 262 insertions(+) create mode 100644 tests/baselines/reference/invariantGenericErrorElaboration.errors.txt create mode 100644 tests/baselines/reference/invariantGenericErrorElaboration.js create mode 100644 tests/baselines/reference/invariantGenericErrorElaboration.symbols create mode 100644 tests/baselines/reference/invariantGenericErrorElaboration.types create mode 100644 tests/cases/compiler/invariantGenericErrorElaboration.ts diff --git a/tests/baselines/reference/invariantGenericErrorElaboration.errors.txt b/tests/baselines/reference/invariantGenericErrorElaboration.errors.txt new file mode 100644 index 00000000000..5142b665d71 --- /dev/null +++ b/tests/baselines/reference/invariantGenericErrorElaboration.errors.txt @@ -0,0 +1,54 @@ +tests/cases/compiler/invariantGenericErrorElaboration.ts(3,7): error TS2322: Type 'Num' is not assignable to type 'Runtype'. + Types of property 'constraint' are incompatible. + Type 'Constraint' is not assignable to type 'Constraint>'. + Types of property 'constraint' are incompatible. + Type 'Constraint>' is not assignable to type 'Constraint>>'. + Types of property 'constraint' are incompatible. + Type 'Constraint>>' is not assignable to type 'Constraint>>>'. + Type 'Constraint>>' is not assignable to type 'Constraint>'. + Types of property 'underlying' are incompatible. + Type 'Constraint>' is not assignable to type 'Constraint'. +tests/cases/compiler/invariantGenericErrorElaboration.ts(4,17): error TS2345: Argument of type '{ foo: Num; }' is not assignable to parameter of type '{ [_: string]: Runtype; }'. + Property 'foo' is incompatible with index signature. + Type 'Num' is not assignable to type 'Runtype'. + + +==== tests/cases/compiler/invariantGenericErrorElaboration.ts (2 errors) ==== + // Repro from #19746 + + const wat: Runtype = Num; + ~~~ +!!! error TS2322: Type 'Num' is not assignable to type 'Runtype'. +!!! error TS2322: Types of property 'constraint' are incompatible. +!!! error TS2322: Type 'Constraint' is not assignable to type 'Constraint>'. +!!! error TS2322: Types of property 'constraint' are incompatible. +!!! error TS2322: Type 'Constraint>' is not assignable to type 'Constraint>>'. +!!! error TS2322: Types of property 'constraint' are incompatible. +!!! error TS2322: Type 'Constraint>>' is not assignable to type 'Constraint>>>'. +!!! error TS2322: Type 'Constraint>>' is not assignable to type 'Constraint>'. +!!! error TS2322: Types of property 'underlying' are incompatible. +!!! error TS2322: Type 'Constraint>' is not assignable to type 'Constraint'. + const Foo = Obj({ foo: Num }) + ~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ foo: Num; }' is not assignable to parameter of type '{ [_: string]: Runtype; }'. +!!! error TS2345: Property 'foo' is incompatible with index signature. +!!! error TS2345: Type 'Num' is not assignable to type 'Runtype'. + + interface Runtype
{ + constraint: Constraint + witness: A + } + + interface Num extends Runtype { + tag: 'number' + } + declare const Num: Num + + interface Obj }> extends Runtype<{[K in keyof O]: O[K]['witness'] }> {} + declare function Obj }>(fields: O): Obj; + + interface Constraint> extends Runtype { + underlying: A, + check: (x: A['witness']) => void, + } + \ No newline at end of file diff --git a/tests/baselines/reference/invariantGenericErrorElaboration.js b/tests/baselines/reference/invariantGenericErrorElaboration.js new file mode 100644 index 00000000000..253c4ab03b7 --- /dev/null +++ b/tests/baselines/reference/invariantGenericErrorElaboration.js @@ -0,0 +1,30 @@ +//// [invariantGenericErrorElaboration.ts] +// Repro from #19746 + +const wat: Runtype = Num; +const Foo = Obj({ foo: Num }) + +interface Runtype { + constraint: Constraint + witness: A +} + +interface Num extends Runtype { + tag: 'number' +} +declare const Num: Num + +interface Obj }> extends Runtype<{[K in keyof O]: O[K]['witness'] }> {} +declare function Obj }>(fields: O): Obj; + +interface Constraint> extends Runtype { + underlying: A, + check: (x: A['witness']) => void, +} + + +//// [invariantGenericErrorElaboration.js] +"use strict"; +// Repro from #19746 +var wat = Num; +var Foo = Obj({ foo: Num }); diff --git a/tests/baselines/reference/invariantGenericErrorElaboration.symbols b/tests/baselines/reference/invariantGenericErrorElaboration.symbols new file mode 100644 index 00000000000..9c141e5c27f --- /dev/null +++ b/tests/baselines/reference/invariantGenericErrorElaboration.symbols @@ -0,0 +1,76 @@ +=== tests/cases/compiler/invariantGenericErrorElaboration.ts === +// Repro from #19746 + +const wat: Runtype = Num; +>wat : Symbol(wat, Decl(invariantGenericErrorElaboration.ts, 2, 5)) +>Runtype : Symbol(Runtype, Decl(invariantGenericErrorElaboration.ts, 3, 29)) +>Num : Symbol(Num, Decl(invariantGenericErrorElaboration.ts, 8, 1), Decl(invariantGenericErrorElaboration.ts, 13, 13)) + +const Foo = Obj({ foo: Num }) +>Foo : Symbol(Foo, Decl(invariantGenericErrorElaboration.ts, 3, 5)) +>Obj : Symbol(Obj, Decl(invariantGenericErrorElaboration.ts, 13, 22), Decl(invariantGenericErrorElaboration.ts, 15, 111)) +>foo : Symbol(foo, Decl(invariantGenericErrorElaboration.ts, 3, 17)) +>Num : Symbol(Num, Decl(invariantGenericErrorElaboration.ts, 8, 1), Decl(invariantGenericErrorElaboration.ts, 13, 13)) + +interface Runtype { +>Runtype : Symbol(Runtype, Decl(invariantGenericErrorElaboration.ts, 3, 29)) +>A : Symbol(A, Decl(invariantGenericErrorElaboration.ts, 5, 18)) + + constraint: Constraint +>constraint : Symbol(Runtype.constraint, Decl(invariantGenericErrorElaboration.ts, 5, 22)) +>Constraint : Symbol(Constraint, Decl(invariantGenericErrorElaboration.ts, 16, 81)) + + witness: A +>witness : Symbol(Runtype.witness, Decl(invariantGenericErrorElaboration.ts, 6, 30)) +>A : Symbol(A, Decl(invariantGenericErrorElaboration.ts, 5, 18)) +} + +interface Num extends Runtype { +>Num : Symbol(Num, Decl(invariantGenericErrorElaboration.ts, 8, 1), Decl(invariantGenericErrorElaboration.ts, 13, 13)) +>Runtype : Symbol(Runtype, Decl(invariantGenericErrorElaboration.ts, 3, 29)) + + tag: 'number' +>tag : Symbol(Num.tag, Decl(invariantGenericErrorElaboration.ts, 10, 39)) +} +declare const Num: Num +>Num : Symbol(Num, Decl(invariantGenericErrorElaboration.ts, 8, 1), Decl(invariantGenericErrorElaboration.ts, 13, 13)) +>Num : Symbol(Num, Decl(invariantGenericErrorElaboration.ts, 8, 1), Decl(invariantGenericErrorElaboration.ts, 13, 13)) + +interface Obj }> extends Runtype<{[K in keyof O]: O[K]['witness'] }> {} +>Obj : Symbol(Obj, Decl(invariantGenericErrorElaboration.ts, 13, 22), Decl(invariantGenericErrorElaboration.ts, 15, 111)) +>O : Symbol(O, Decl(invariantGenericErrorElaboration.ts, 15, 14)) +>_ : Symbol(_, Decl(invariantGenericErrorElaboration.ts, 15, 27)) +>Runtype : Symbol(Runtype, Decl(invariantGenericErrorElaboration.ts, 3, 29)) +>Runtype : Symbol(Runtype, Decl(invariantGenericErrorElaboration.ts, 3, 29)) +>K : Symbol(K, Decl(invariantGenericErrorElaboration.ts, 15, 75)) +>O : Symbol(O, Decl(invariantGenericErrorElaboration.ts, 15, 14)) +>O : Symbol(O, Decl(invariantGenericErrorElaboration.ts, 15, 14)) +>K : Symbol(K, Decl(invariantGenericErrorElaboration.ts, 15, 75)) + +declare function Obj }>(fields: O): Obj; +>Obj : Symbol(Obj, Decl(invariantGenericErrorElaboration.ts, 13, 22), Decl(invariantGenericErrorElaboration.ts, 15, 111)) +>O : Symbol(O, Decl(invariantGenericErrorElaboration.ts, 16, 21)) +>_ : Symbol(_, Decl(invariantGenericErrorElaboration.ts, 16, 34)) +>Runtype : Symbol(Runtype, Decl(invariantGenericErrorElaboration.ts, 3, 29)) +>fields : Symbol(fields, Decl(invariantGenericErrorElaboration.ts, 16, 62)) +>O : Symbol(O, Decl(invariantGenericErrorElaboration.ts, 16, 21)) +>Obj : Symbol(Obj, Decl(invariantGenericErrorElaboration.ts, 13, 22), Decl(invariantGenericErrorElaboration.ts, 15, 111)) +>O : Symbol(O, Decl(invariantGenericErrorElaboration.ts, 16, 21)) + +interface Constraint> extends Runtype { +>Constraint : Symbol(Constraint, Decl(invariantGenericErrorElaboration.ts, 16, 81)) +>A : Symbol(A, Decl(invariantGenericErrorElaboration.ts, 18, 21)) +>Runtype : Symbol(Runtype, Decl(invariantGenericErrorElaboration.ts, 3, 29)) +>Runtype : Symbol(Runtype, Decl(invariantGenericErrorElaboration.ts, 3, 29)) +>A : Symbol(A, Decl(invariantGenericErrorElaboration.ts, 18, 21)) + + underlying: A, +>underlying : Symbol(Constraint.underlying, Decl(invariantGenericErrorElaboration.ts, 18, 76)) +>A : Symbol(A, Decl(invariantGenericErrorElaboration.ts, 18, 21)) + + check: (x: A['witness']) => void, +>check : Symbol(Constraint.check, Decl(invariantGenericErrorElaboration.ts, 19, 16)) +>x : Symbol(x, Decl(invariantGenericErrorElaboration.ts, 20, 10)) +>A : Symbol(A, Decl(invariantGenericErrorElaboration.ts, 18, 21)) +} + diff --git a/tests/baselines/reference/invariantGenericErrorElaboration.types b/tests/baselines/reference/invariantGenericErrorElaboration.types new file mode 100644 index 00000000000..2120c06d5fa --- /dev/null +++ b/tests/baselines/reference/invariantGenericErrorElaboration.types @@ -0,0 +1,78 @@ +=== tests/cases/compiler/invariantGenericErrorElaboration.ts === +// Repro from #19746 + +const wat: Runtype = Num; +>wat : Runtype +>Runtype : Runtype +>Num : Num + +const Foo = Obj({ foo: Num }) +>Foo : any +>Obj({ foo: Num }) : any +>Obj : ; }>(fields: O) => Obj +>{ foo: Num } : { foo: Num; } +>foo : Num +>Num : Num + +interface Runtype { +>Runtype : Runtype +>A : A + + constraint: Constraint +>constraint : Constraint +>Constraint : Constraint + + witness: A +>witness : A +>A : A +} + +interface Num extends Runtype { +>Num : Num +>Runtype : Runtype + + tag: 'number' +>tag : "number" +} +declare const Num: Num +>Num : Num +>Num : Num + +interface Obj }> extends Runtype<{[K in keyof O]: O[K]['witness'] }> {} +>Obj : Obj +>O : O +>_ : _ +>Runtype : Runtype +>Runtype : Runtype +>K : K +>O : O +>O : O +>K : K + +declare function Obj }>(fields: O): Obj; +>Obj : ; }>(fields: O) => Obj +>O : O +>_ : string +>Runtype : Runtype +>fields : O +>O : O +>Obj : Obj +>O : O + +interface Constraint> extends Runtype { +>Constraint : Constraint +>A : A +>Runtype : Runtype +>Runtype : Runtype +>A : A + + underlying: A, +>underlying : A +>A : A + + check: (x: A['witness']) => void, +>check : (x: A["witness"]) => void +>x : A["witness"] +>A : A +} + diff --git a/tests/cases/compiler/invariantGenericErrorElaboration.ts b/tests/cases/compiler/invariantGenericErrorElaboration.ts new file mode 100644 index 00000000000..6191949dd8c --- /dev/null +++ b/tests/cases/compiler/invariantGenericErrorElaboration.ts @@ -0,0 +1,24 @@ +// @strict: true + +// Repro from #19746 + +const wat: Runtype = Num; +const Foo = Obj({ foo: Num }) + +interface Runtype { + constraint: Constraint + witness: A +} + +interface Num extends Runtype { + tag: 'number' +} +declare const Num: Num + +interface Obj }> extends Runtype<{[K in keyof O]: O[K]['witness'] }> {} +declare function Obj }>(fields: O): Obj; + +interface Constraint> extends Runtype { + underlying: A, + check: (x: A['witness']) => void, +} From d97335e4e719c28d8e80431a42aad4e772454916 Mon Sep 17 00:00:00 2001 From: micbou Date: Mon, 6 Nov 2017 18:45:52 +0100 Subject: [PATCH 129/235] Silence NPM warnings when installing typings (#19749) --- src/server/typingsInstaller/typingsInstaller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/typingsInstaller/typingsInstaller.ts b/src/server/typingsInstaller/typingsInstaller.ts index c45275d0b3d..eacbebbf4ab 100644 --- a/src/server/typingsInstaller/typingsInstaller.ts +++ b/src/server/typingsInstaller/typingsInstaller.ts @@ -248,7 +248,7 @@ namespace ts.server.typingsInstaller { this.log.writeLine(`Npm config file: '${npmConfigPath}' is missing, creating new one...`); } this.ensureDirectoryExists(directory, this.installTypingHost); - this.installTypingHost.writeFile(npmConfigPath, '{ "description": "", "repository": "", "license": "" }'); + this.installTypingHost.writeFile(npmConfigPath, '{ "private": true }'); } } From 445001e1717f201255277dc48dcaf890577de86b Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 6 Nov 2017 10:24:21 -0800 Subject: [PATCH 130/235] Port generated lib files (#19772) --- src/lib/dom.generated.d.ts | 2 +- src/lib/webworker.generated.d.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/dom.generated.d.ts b/src/lib/dom.generated.d.ts index 5c7600624e8..ec488bb069e 100644 --- a/src/lib/dom.generated.d.ts +++ b/src/lib/dom.generated.d.ts @@ -15135,7 +15135,7 @@ type MouseWheelEvent = WheelEvent; type ScrollRestoration = "auto" | "manual"; type FormDataEntryValue = string | File; type InsertPosition = "beforebegin" | "afterbegin" | "beforeend" | "afterend"; -type HeadersInit = string[][] | { [key: string]: string }; +type HeadersInit = Headers | string[][] | { [key: string]: string }; type AppendMode = "segments" | "sequence"; type AudioContextState = "suspended" | "running" | "closed"; type BiquadFilterType = "lowpass" | "highpass" | "bandpass" | "lowshelf" | "highshelf" | "peaking" | "notch" | "allpass"; diff --git a/src/lib/webworker.generated.d.ts b/src/lib/webworker.generated.d.ts index 509c4b776c9..6eb17c33c5e 100644 --- a/src/lib/webworker.generated.d.ts +++ b/src/lib/webworker.generated.d.ts @@ -1890,7 +1890,7 @@ type USVString = string; type IDBValidKey = number | string | Date | IDBArrayKey; type BufferSource = ArrayBuffer | ArrayBufferView; type FormDataEntryValue = string | File; -type HeadersInit = string[][] | { [key: string]: string }; +type HeadersInit = Headers | string[][] | { [key: string]: string }; type IDBCursorDirection = "next" | "nextunique" | "prev" | "prevunique"; type IDBRequestReadyState = "pending" | "done"; type IDBTransactionMode = "readonly" | "readwrite" | "versionchange"; From 4385444c4488f7d0fe802e58b7de303e088e0a01 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 6 Nov 2017 10:35:53 -0800 Subject: [PATCH 131/235] Add TupleBase with unusable mutating Array methods --- src/compiler/checker.ts | 13 ++++++++----- src/lib/es5.d.ts | 12 ++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8a214e39c19..83ffce7b21f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -327,6 +327,7 @@ namespace ts { let globalFunctionType: ObjectType; let globalArrayType: GenericType; let globalReadonlyArrayType: GenericType; + let globalTupleBaseType: GenericType; let globalStringType: ObjectType; let globalNumberType: ObjectType; let globalBooleanType: ObjectType; @@ -775,7 +776,7 @@ namespace ts { * @param parameterName a name of the parameter to get the symbols for. * @return a tuple of two symbols */ - function getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: __String): [Symbol, Symbol] { + function getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: __String): Symbol[] { const constructorDeclaration = parameter.parent; const classDeclaration = parameter.parent.parent; @@ -4996,7 +4997,7 @@ namespace ts { function getBaseTypes(type: InterfaceType): BaseType[] { if (!type.resolvedBaseTypes) { if (type.objectFlags & ObjectFlags.Tuple) { - type.resolvedBaseTypes = [createArrayType(getUnionType(type.typeParameters))]; + type.resolvedBaseTypes = [createTypeFromGenericGlobalType(globalTupleBaseType, [getUnionType(type.typeParameters)])]; } else if (type.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { if (type.symbol.flags & SymbolFlags.Class) { @@ -9992,7 +9993,7 @@ namespace ts { const typeParameters = type.typeParameters || emptyArray; let variances = type.variances; if (!variances) { - if (type === globalArrayType || type === globalReadonlyArrayType) { + if (type === globalArrayType || type === globalReadonlyArrayType || type === globalTupleBaseType) { // Arrays are known to be covariant, no need to spend time computing this variances = [Variance.Covariant]; } @@ -10321,7 +10322,7 @@ namespace ts { function isArrayLikeType(type: Type): boolean { // A type is array-like if it is a reference to the global Array or global ReadonlyArray type, // or if it is not the undefined or null type and if it is assignable to ReadonlyArray - return getObjectFlags(type) & ObjectFlags.Reference && ((type).target === globalArrayType || (type).target === globalReadonlyArrayType) || + return getObjectFlags(type) & ObjectFlags.Reference && ((type).target === globalArrayType || (type).target === globalReadonlyArrayType || (type as TypeReference).target === globalTupleBaseType) || !(type.flags & TypeFlags.Nullable) && isTypeAssignableTo(type, anyReadonlyArrayType); } @@ -24509,7 +24510,9 @@ namespace ts { anyArrayType = createArrayType(anyType); autoArrayType = createArrayType(autoType); - globalReadonlyArrayType = getGlobalTypeOrUndefined("ReadonlyArray" as __String, /*arity*/ 1); + // TODO: ReadonlyArray and TupleBase should always be available, but haven't been required previously + globalReadonlyArrayType = getGlobalType("ReadonlyArray" as __String, /*arity*/ 1, /*reportErrors*/ true); + globalTupleBaseType = getGlobalType("TupleBase" as __String, /*arity*/ 1, /*reportErrors*/ true); anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType; globalThisType = getGlobalTypeOrUndefined("ThisType" as __String, /*arity*/ 1); } diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index fd2ae5b3fdf..4694fae4868 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1240,6 +1240,18 @@ interface ArrayConstructor { declare const Array: ArrayConstructor; +interface TupleBase extends Array { + // TODO: Add jsdoc here warning not to call this + push(...items: never[]): never; + pop(): never | undefined; + reverse(): never[]; + sort(compareFn?: (a: never, b: never) => number): never; + shift(): never | undefined; + unshift(...items: never[]): never; + splice(start: number, deleteCount?: number): never[]; + splice(start: number, deleteCount: number, ...items: never[]): never[]; +} + interface TypedPropertyDescriptor { enumerable?: boolean; configurable?: boolean; From 2399d58266087aef119250e5e53a5526d245762b Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 6 Nov 2017 10:50:57 -0800 Subject: [PATCH 132/235] Improve TupleBase docs and backward compatibility --- src/compiler/checker.ts | 6 +++--- src/lib/es5.d.ts | 23 ++++++++++++++--------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 83ffce7b21f..5cddb7d411e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4997,7 +4997,7 @@ namespace ts { function getBaseTypes(type: InterfaceType): BaseType[] { if (!type.resolvedBaseTypes) { if (type.objectFlags & ObjectFlags.Tuple) { - type.resolvedBaseTypes = [createTypeFromGenericGlobalType(globalTupleBaseType, [getUnionType(type.typeParameters)])]; + type.resolvedBaseTypes = [createTypeFromGenericGlobalType(globalTupleBaseType || globalArrayType, [getUnionType(type.typeParameters)])]; } else if (type.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { if (type.symbol.flags & SymbolFlags.Class) { @@ -24511,8 +24511,8 @@ namespace ts { autoArrayType = createArrayType(autoType); // TODO: ReadonlyArray and TupleBase should always be available, but haven't been required previously - globalReadonlyArrayType = getGlobalType("ReadonlyArray" as __String, /*arity*/ 1, /*reportErrors*/ true); - globalTupleBaseType = getGlobalType("TupleBase" as __String, /*arity*/ 1, /*reportErrors*/ true); + globalReadonlyArrayType = getGlobalTypeOrUndefined("ReadonlyArray" as __String, /*arity*/ 1); + globalTupleBaseType = getGlobalTypeOrUndefined("TupleBase" as __String, /*arity*/ 1); anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType; globalThisType = getGlobalTypeOrUndefined("ThisType" as __String, /*arity*/ 1); } diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 4694fae4868..d3760e3a310 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1241,15 +1241,20 @@ interface ArrayConstructor { declare const Array: ArrayConstructor; interface TupleBase extends Array { - // TODO: Add jsdoc here warning not to call this - push(...items: never[]): never; - pop(): never | undefined; - reverse(): never[]; - sort(compareFn?: (a: never, b: never) => number): never; - shift(): never | undefined; - unshift(...items: never[]): never; - splice(start: number, deleteCount?: number): never[]; - splice(start: number, deleteCount: number, ...items: never[]): never[]; + /** Mutation is not allowed on tuples. Do not use this method. */ + push: never; + /** Mutation is not allowed on tuples. Do not use this method. */ + pop: never; + /** Mutation is not allowed on tuples. Do not use this method. */ + reverse: never; + /** Mutation is not allowed on tuples. Do not use this method. */ + sort: never; + /** Mutation is not allowed on tuples. Do not use this method. */ + shift: never; + /** Mutation is not allowed on tuples. Do not use this method. */ + unshift: never; + /** Mutation is not allowed on tuples. Do not use this method. */ + splice: never; } interface TypedPropertyDescriptor { From 163e40cde68d945dda726a93b748fa900e0b782e Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 6 Nov 2017 10:56:52 -0800 Subject: [PATCH 133/235] Add testcase for non existent file without absolute path when opened with/without projectRoot --- .../unittests/tsserverProjectSystem.ts | 128 ++++++++++-------- 1 file changed, 74 insertions(+), 54 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index ae90ec7d741..a0a5995a1f0 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -2789,65 +2789,85 @@ namespace ts.projectSystem { checkProjectRootFiles(project, [file1.path]); }); - it("when opening new file that doesnt exist on disk yet", () => { - const host = createServerHost([libFile]); - let hasError = false; - const errLogger: server.Logger = { - close: noop, - hasLevel: () => true, - loggingEnabled: () => true, - perftrc: noop, - info: noop, - msg: (_s, type) => { - if (type === server.Msg.Err) { - hasError = true; + describe("when opening new file that doesnt exist on disk yet", () => { + function verifyNonExistentFile(useProjectRoot: boolean) { + const host = createServerHost([libFile]); + let hasError = false; + const errLogger: server.Logger = { + close: noop, + hasLevel: () => true, + loggingEnabled: () => true, + perftrc: noop, + info: noop, + msg: (_s, type) => { + if (type === server.Msg.Err) { + hasError = true; + } + }, + startGroup: noop, + endGroup: noop, + getLogFileName: (): string => undefined + }; + const session = createSession(host, { canUseEvents: true, logger: errLogger, useInferredProjectPerProjectRoot: true }); + + const folderPath = "/user/someuser/projects/someFolder"; + const projectService = session.getProjectService(); + const untitledFile = "untitled:Untitled-1"; + session.executeCommandSeq({ + command: server.CommandNames.Open, + arguments: { + file: untitledFile, + fileContent: "", + scriptKindName: "JS", + projectRootPath: useProjectRoot ? folderPath : undefined } - }, - startGroup: noop, - endGroup: noop, - getLogFileName: (): string => undefined - }; - const session = createSession(host, { canUseEvents: true, logger: errLogger, useInferredProjectPerProjectRoot: true }); - - const folderPath = "/user/someuser/projects/someFolder"; - const projectService = session.getProjectService(); - const untitledFile = "untitled:Untitled-1"; - session.executeCommandSeq({ - command: server.CommandNames.Open, - arguments: { - file: untitledFile, - fileContent: "", - scriptKindName: "JS", - projectRootPath: folderPath + }); + checkNumberOfProjects(projectService, { inferredProjects: 1 }); + const infoForUntitledAtProjectRoot = projectService.getScriptInfoForPath(`${folderPath.toLowerCase()}/${untitledFile.toLowerCase()}` as Path); + const infoForUnitiledAtRoot = projectService.getScriptInfoForPath(`/${untitledFile.toLowerCase()}` as Path); + if (useProjectRoot) { + assert.isDefined(infoForUntitledAtProjectRoot); + assert.isUndefined(infoForUnitiledAtRoot); } - }); - checkNumberOfProjects(projectService, { inferredProjects: 1 }); - host.checkTimeoutQueueLength(2); - - const newTimeoutId = host.getNextTimeoutId(); - const expectedSequenceId = session.getNextSeq(); - session.executeCommandSeq({ - command: server.CommandNames.Geterr, - arguments: { - delay: 0, - files: [untitledFile] + else { + assert.isDefined(infoForUnitiledAtRoot); + assert.isUndefined(infoForUntitledAtProjectRoot); } + host.checkTimeoutQueueLength(2); + + const newTimeoutId = host.getNextTimeoutId(); + const expectedSequenceId = session.getNextSeq(); + session.executeCommandSeq({ + command: server.CommandNames.Geterr, + arguments: { + delay: 0, + files: [untitledFile] + } + }); + host.checkTimeoutQueueLength(3); + + // Run the last one = get error request + host.runQueuedTimeoutCallbacks(newTimeoutId); + + assert.isFalse(hasError); + host.checkTimeoutQueueLength(2); + checkErrorMessage(host, "syntaxDiag", { file: untitledFile, diagnostics: [] }); + host.clearOutput(); + + host.runQueuedImmediateCallbacks(); + assert.isFalse(hasError); + checkErrorMessage(host, "semanticDiag", { file: untitledFile, diagnostics: [] }); + + checkCompleteEvent(host, 2, expectedSequenceId); + } + + it("has projectRoot", () => { + verifyNonExistentFile(/*useProjectRoot*/ true); }); - host.checkTimeoutQueueLength(3); - // Run the last one = get error request - host.runQueuedTimeoutCallbacks(newTimeoutId); - - assert.isFalse(hasError); - host.checkTimeoutQueueLength(2); - checkErrorMessage(host, "syntaxDiag", { file: untitledFile, diagnostics: [] }); - host.clearOutput(); - - host.runQueuedImmediateCallbacks(); - assert.isFalse(hasError); - checkErrorMessage(host, "semanticDiag", { file: untitledFile, diagnostics: [] }); - - checkCompleteEvent(host, 2, expectedSequenceId); + it("does not have projectRoot", () => { + verifyNonExistentFile(/*useProjectRoot*/ false); + }); }); }); From c4bf21b9cb26c8936bf51636ac14cabf2cc44fe6 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 6 Nov 2017 10:59:39 -0800 Subject: [PATCH 134/235] Improvements to checkUnusedIdentifiers (#19607) --- src/compiler/checker.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 532eee363d7..eb5442a7996 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20430,21 +20430,20 @@ namespace ts { case SyntaxKind.MethodSignature: case SyntaxKind.CallSignature: case SyntaxKind.ConstructSignature: - case SyntaxKind.IndexSignature: case SyntaxKind.FunctionType: case SyntaxKind.ConstructorType: - checkUnusedTypeParameters(node); - break; case SyntaxKind.TypeAliasDeclaration: - checkUnusedTypeParameters(node); + checkUnusedTypeParameters(node); break; + default: + Debug.fail("Node should not have been registered for unused identifiers check"); } } } } function checkUnusedLocalsAndParameters(node: Node): void { - if (node.parent.kind !== SyntaxKind.InterfaceDeclaration && noUnusedIdentifiers && !(node.flags & NodeFlags.Ambient)) { + if (noUnusedIdentifiers && !(node.flags & NodeFlags.Ambient)) { node.locals.forEach(local => { if (!local.isReferenced) { if (local.valueDeclaration && getRootDeclaration(local.valueDeclaration).kind === SyntaxKind.Parameter) { From c016f5b9b0713d727ba3c07e59a2c97d3d148137 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 6 Nov 2017 11:24:17 -0800 Subject: [PATCH 135/235] Split runner selection from test selection (#19729) * Split runner selection from test selection * Continue to support old behavior --- Gulpfile.ts | 16 ++++++++++------ Jakefile.js | 13 ++++++++----- src/harness/runner.ts | 6 ++++-- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/Gulpfile.ts b/Gulpfile.ts index 4d6dfdf2862..fd353083433 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -50,6 +50,7 @@ const cmdLineOptions = minimist(process.argv.slice(2), { d: "debug", "debug-brk": "debug", i: "inspect", "inspect-brk": "inspect", t: "tests", test: "tests", + ru: "runners", runner: "runners", r: "reporter", c: "colors", color: "colors", f: "files", file: "files", @@ -64,6 +65,7 @@ const cmdLineOptions = minimist(process.argv.slice(2), { browser: process.env.browser || process.env.b || "IE", timeout: process.env.timeout || 40000, tests: process.env.test || process.env.tests || process.env.t, + runners: process.env.runners || process.env.runner || process.env.ru, light: process.env.light === undefined || process.env.light !== "false", reporter: process.env.reporter || process.env.r, lint: process.env.lint || true, @@ -648,6 +650,7 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done: const debug = cmdLineOptions.debug; const inspect = cmdLineOptions.inspect; const tests = cmdLineOptions.tests; + const runners = cmdLineOptions.runners; const light = cmdLineOptions.light; const stackTraceLimit = cmdLineOptions.stackTraceLimit; const testConfigFile = "test.config"; @@ -668,8 +671,8 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done: workerCount = cmdLineOptions.workers; } - if (tests || light || taskConfigsFolder) { - writeTestConfigFile(tests, light, taskConfigsFolder, workerCount, stackTraceLimit); + if (tests || runners || light || taskConfigsFolder) { + writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit); } if (tests && tests.toLocaleLowerCase() === "rwc") { @@ -860,8 +863,8 @@ function cleanTestDirs(done: (e?: any) => void) { } // used to pass data from jake command line directly to run.js -function writeTestConfigFile(tests: string, light: boolean, taskConfigsFolder?: string, workerCount?: number, stackTraceLimit?: string) { - const testConfigContents = JSON.stringify({ test: tests ? [tests] : undefined, light, workerCount, stackTraceLimit, taskConfigsFolder, noColor: !cmdLineOptions.colors }); +function writeTestConfigFile(tests: string, runners: string, light: boolean, taskConfigsFolder?: string, workerCount?: number, stackTraceLimit?: string) { + const testConfigContents = JSON.stringify({ test: tests ? [tests] : undefined, runner: runners ? runners.split(",") : undefined, light, workerCount, stackTraceLimit, taskConfigsFolder, noColor: !cmdLineOptions.colors }); console.log("Running tests with config: " + testConfigContents); fs.writeFileSync("test.config", testConfigContents); } @@ -872,13 +875,14 @@ gulp.task("runtests-browser", "Runs the tests using the built run.js file like ' if (err) { console.error(err); done(err); process.exit(1); } host = "node"; const tests = cmdLineOptions.tests; + const runners = cmdLineOptions.runners; const light = cmdLineOptions.light; const testConfigFile = "test.config"; if (fs.existsSync(testConfigFile)) { fs.unlinkSync(testConfigFile); } - if (tests || light) { - writeTestConfigFile(tests, light); + if (tests || runners || light) { + writeTestConfigFile(tests, runners, light); } const args = [nodeServerOutFile]; diff --git a/Jakefile.js b/Jakefile.js index 13607f7b40f..7f0915ad7e9 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -844,8 +844,9 @@ function cleanTestDirs() { } // used to pass data from jake command line directly to run.js -function writeTestConfigFile(tests, light, taskConfigsFolder, workerCount, stackTraceLimit, colors) { +function writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, colors) { var testConfigContents = JSON.stringify({ + runners: runners ? runners.split(",") : undefined, test: tests ? [tests] : undefined, light: light, workerCount: workerCount, @@ -871,6 +872,7 @@ function runConsoleTests(defaultReporter, runInParallel) { var debug = process.env.debug || process.env["debug-brk"] || process.env.d; var inspect = process.env.inspect || process.env["inspect-brk"] || process.env.i; var testTimeout = process.env.timeout || defaultTestTimeout; + var runners = process.env.runners || process.env.runner || process.env.ru; var tests = process.env.test || process.env.tests || process.env.t; var light = process.env.light === undefined || process.env.light !== "false"; var stackTraceLimit = process.env.stackTraceLimit; @@ -892,8 +894,8 @@ function runConsoleTests(defaultReporter, runInParallel) { workerCount = process.env.workerCount || process.env.p || os.cpus().length; } - if (tests || light || taskConfigsFolder) { - writeTestConfigFile(tests, light, taskConfigsFolder, workerCount, stackTraceLimit, colors); + if (tests || runners || light || taskConfigsFolder) { + writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, colors); } if (tests && tests.toLocaleLowerCase() === "rwc") { @@ -1028,14 +1030,15 @@ task("runtests-browser", ["browserify", nodeServerOutFile], function () { cleanTestDirs(); host = "node"; var browser = process.env.browser || process.env.b || (os.platform() === "linux" ? "chrome" : "IE"); + var runners = process.env.runners || process.env.runner || process.env.ru; var tests = process.env.test || process.env.tests || process.env.t; var light = process.env.light || false; var testConfigFile = 'test.config'; if (fs.existsSync(testConfigFile)) { fs.unlinkSync(testConfigFile); } - if (tests || light) { - writeTestConfigFile(tests, light); + if (tests || runners || light) { + writeTestConfigFile(tests, runners, light); } tests = tests ? tests : ''; diff --git a/src/harness/runner.ts b/src/harness/runner.ts index b538f90bc39..70954e9e853 100644 --- a/src/harness/runner.ts +++ b/src/harness/runner.ts @@ -95,6 +95,7 @@ interface TestConfig { workerCount?: number; stackTraceLimit?: number | "full"; test?: string[]; + runners?: string[]; runUnitTests?: boolean; noColors?: boolean; } @@ -132,8 +133,9 @@ function handleTestConfig() { return true; } - if (testConfig.test && testConfig.test.length > 0) { - for (const option of testConfig.test) { + const runnerConfig = testConfig.runners || testConfig.test; + if (runnerConfig && runnerConfig.length > 0) { + for (const option of runnerConfig) { if (!option) { continue; } From 4f48bf80fe2780741cbeb91dbaae2f2142a67995 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 6 Nov 2017 12:51:34 -0800 Subject: [PATCH 136/235] Revised emit for computed property names, including with decorators (#19430) * Revised emit for computed property names * Fix downlevel name generation scopes * Accept slightly more conservative baseline * First feedback pass * Reduce number of nonrequired variable declarations and assignments * Remove side-effect-free identifier references * skip partially emitted expressions * Comments, move starsOnNewLine to emitNode * Put expressions on newlines when inlined in class expressions for consistency * Update new ref * Fix typo in comment --- src/compiler/binder.ts | 2 + src/compiler/emitter.ts | 64 +- src/compiler/factory.ts | 41 +- src/compiler/transformers/es2015.ts | 17 +- src/compiler/transformers/generators.ts | 5 +- src/compiler/transformers/ts.ts | 96 ++- src/compiler/types.ts | 3 +- .../capturedParametersInInitializers2.js | 15 +- .../reference/computedPropertyNames12_ES5.js | 8 +- .../reference/computedPropertyNames12_ES6.js | 8 +- .../reference/decoratorOnClassMethod13.js | 9 +- .../reference/decoratorOnClassMethod4.js | 5 +- .../reference/decoratorOnClassMethod5.js | 5 +- .../reference/decoratorOnClassMethod6.js | 5 +- .../reference/decoratorOnClassMethod7.js | 5 +- .../decoratorsOnComputedProperties.errors.txt | 435 ++++++++++ .../decoratorsOnComputedProperties.js | 457 ++++++++++ .../decoratorsOnComputedProperties.symbols | 664 ++++++++++++++ .../decoratorsOnComputedProperties.types | 816 ++++++++++++++++++ tests/baselines/reference/newTarget.es5.js | 6 +- .../reference/parserComputedPropertyName10.js | 4 +- .../reference/parserComputedPropertyName25.js | 4 +- .../reference/parserComputedPropertyName27.js | 4 +- .../reference/parserComputedPropertyName28.js | 4 +- .../reference/parserComputedPropertyName29.js | 4 +- .../reference/parserComputedPropertyName33.js | 4 +- .../parserES5ComputedPropertyName10.js | 4 +- tests/baselines/reference/symbolProperty7.js | 5 +- .../decoratorsOnComputedProperties.ts | 191 ++++ 29 files changed, 2777 insertions(+), 113 deletions(-) create mode 100644 tests/baselines/reference/decoratorsOnComputedProperties.errors.txt create mode 100644 tests/baselines/reference/decoratorsOnComputedProperties.js create mode 100644 tests/baselines/reference/decoratorsOnComputedProperties.symbols create mode 100644 tests/baselines/reference/decoratorsOnComputedProperties.types create mode 100644 tests/cases/compiler/decoratorsOnComputedProperties.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 72cff733b0c..cf8b3eefde8 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2963,6 +2963,7 @@ namespace ts { || hasModifier(node, ModifierFlags.TypeScriptModifier) || node.typeParameters || node.type + || (node.name && isComputedPropertyName(node.name)) // While computed method names aren't typescript, the TS transform must visit them to emit property declarations correctly || !node.body) { transformFlags |= TransformFlags.AssertTypeScript; } @@ -2993,6 +2994,7 @@ namespace ts { if (node.decorators || hasModifier(node, ModifierFlags.TypeScriptModifier) || node.type + || (node.name && isComputedPropertyName(node.name)) // While computed accessor names aren't typescript, the TS transform must visit them to emit property declarations correctly || !node.body) { transformFlags |= TransformFlags.AssertTypeScript; } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 74e5d4d5539..7a1d88d3bfd 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1733,26 +1733,15 @@ namespace ts { increaseIndent(); } - if (getEmitFlags(node) & EmitFlags.ReuseTempVariableScope) { - emitSignatureHead(node); - if (onEmitNode) { - onEmitNode(EmitHint.Unspecified, body, emitBlockCallback); - } - else { - emitBlockFunctionBody(body); - } + pushNameGenerationScope(node); + emitSignatureHead(node); + if (onEmitNode) { + onEmitNode(EmitHint.Unspecified, body, emitBlockCallback); } else { - pushNameGenerationScope(); - emitSignatureHead(node); - if (onEmitNode) { - onEmitNode(EmitHint.Unspecified, body, emitBlockCallback); - } - else { - emitBlockFunctionBody(body); - } - popNameGenerationScope(); + emitBlockFunctionBody(body); } + popNameGenerationScope(node); if (indentedFlag) { decreaseIndent(); @@ -1871,11 +1860,9 @@ namespace ts { emitTypeParameters(node, node.typeParameters); emitList(node, node.heritageClauses, ListFormat.ClassHeritageClauses); - pushNameGenerationScope(); write(" {"); emitList(node, node.members, ListFormat.ClassMembers); write("}"); - popNameGenerationScope(); if (indentedFlag) { decreaseIndent(); @@ -1909,11 +1896,9 @@ namespace ts { emitModifiers(node, node.modifiers); write("enum "); emit(node.name); - pushNameGenerationScope(); write(" {"); emitList(node, node.members, ListFormat.EnumMembers); write("}"); - popNameGenerationScope(); } function emitModuleDeclaration(node: ModuleDeclaration) { @@ -1935,11 +1920,11 @@ namespace ts { } function emitModuleBlock(node: ModuleBlock) { - pushNameGenerationScope(); + pushNameGenerationScope(node); write("{"); emitBlockStatements(node, /*forceSingleLine*/ isEmptyBlock(node)); write("}"); - popNameGenerationScope(); + popNameGenerationScope(node); } function emitCaseBlock(node: CaseBlock) { @@ -2284,11 +2269,11 @@ namespace ts { function emitSourceFileWorker(node: SourceFile) { const statements = node.statements; - pushNameGenerationScope(); + pushNameGenerationScope(node); emitHelpersIndirect(node); const index = findIndex(statements, statement => !isPrologueDirective(statement)); emitList(node, statements, ListFormat.MultiLine, index === -1 ? statements.length : index); - popNameGenerationScope(); + popNameGenerationScope(node); } // Transformation nodes @@ -2751,7 +2736,7 @@ namespace ts { } } else { - return nextNode.startsOnNewLine; + return getStartsOnNewLine(nextNode); } } @@ -2782,7 +2767,7 @@ namespace ts { function synthesizedNodeStartsOnNewLine(node: Node, format?: ListFormat) { if (nodeIsSynthesized(node)) { - const startsOnNewLine = node.startsOnNewLine; + const startsOnNewLine = getStartsOnNewLine(node); if (startsOnNewLine === undefined) { return (format & ListFormat.PreferNewLine) !== 0; } @@ -2799,7 +2784,7 @@ namespace ts { node2 = skipSynthesizedParentheses(node2); // Always use a newline for synthesized code if the synthesizer desires it. - if (node2.startsOnNewLine) { + if (getStartsOnNewLine(node2)) { return true; } @@ -2858,7 +2843,10 @@ namespace ts { /** * Push a new name generation scope. */ - function pushNameGenerationScope() { + function pushNameGenerationScope(node: Node | undefined) { + if (node && getEmitFlags(node) & EmitFlags.ReuseTempVariableScope) { + return; + } tempFlagsStack.push(tempFlags); tempFlags = 0; } @@ -2866,7 +2854,10 @@ namespace ts { /** * Pop the current name generation scope. */ - function popNameGenerationScope() { + function popNameGenerationScope(node: Node | undefined) { + if (node && getEmitFlags(node) & EmitFlags.ReuseTempVariableScope) { + return; + } tempFlags = tempFlagsStack.pop(); } @@ -2877,8 +2868,17 @@ namespace ts { if (name.autoGenerateKind === GeneratedIdentifierKind.Node) { // Node names generate unique names based on their original node // and are cached based on that node's id. - const node = getNodeForGeneratedName(name); - return generateNameCached(node); + if (name.skipNameGenerationScope) { + const savedTempFlags = tempFlags; + popNameGenerationScope(/*node*/ undefined); + const result = generateNameCached(getNodeForGeneratedName(name)); + pushNameGenerationScope(/*node*/ undefined); + tempFlags = savedTempFlags; + return result; + } + else { + return generateNameCached(getNodeForGeneratedName(name)); + } } else { // Auto, Loop, and Unique names are cached based on their unique diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 053672d19df..c9e0fec5927 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -13,9 +13,6 @@ namespace ts { if (updated !== original) { setOriginalNode(updated, original); setTextRange(updated, original); - if (original.startsOnNewLine) { - updated.startsOnNewLine = true; - } aggregateTransformFlags(updated); } return updated; @@ -168,11 +165,14 @@ namespace ts { } /** Create a unique name generated for a node. */ - export function getGeneratedNameForNode(node: Node): Identifier { + export function getGeneratedNameForNode(node: Node): Identifier; + /*@internal*/ export function getGeneratedNameForNode(node: Node, shouldSkipNameGenerationScope?: boolean): Identifier; + export function getGeneratedNameForNode(node: Node, shouldSkipNameGenerationScope?: boolean): Identifier { const name = createIdentifier(""); name.autoGenerateKind = GeneratedIdentifierKind.Node; name.autoGenerateId = nextAutoGenerateId; name.original = node; + name.skipNameGenerationScope = !!shouldSkipNameGenerationScope; nextAutoGenerateId++; return name; } @@ -2683,6 +2683,24 @@ namespace ts { return node; } + /** + * Gets a custom text range to use when emitting comments. + */ + /*@internal*/ + export function getStartsOnNewLine(node: Node) { + const emitNode = node.emitNode; + return emitNode && emitNode.startsOnNewLine; + } + + /** + * Sets a custom text range to use when emitting comments. + */ + /*@internal*/ + export function setStartsOnNewLine(node: T, newLine: boolean) { + getOrCreateEmitNode(node).startsOnNewLine = newLine; + return node; + } + /** * Gets a custom text range to use when emitting comments. */ @@ -2841,7 +2859,8 @@ namespace ts { sourceMapRange, tokenSourceMapRanges, constantValue, - helpers + helpers, + startsOnNewLine, } = sourceEmitNode; if (!destEmitNode) destEmitNode = {}; // We are using `.slice()` here in case `destEmitNode.leadingComments` is pushed to later. @@ -2853,6 +2872,7 @@ namespace ts { if (tokenSourceMapRanges) destEmitNode.tokenSourceMapRanges = mergeTokenSourceMapRanges(tokenSourceMapRanges, destEmitNode.tokenSourceMapRanges); if (constantValue !== undefined) destEmitNode.constantValue = constantValue; if (helpers) destEmitNode.helpers = addRange(destEmitNode.helpers, helpers); + if (startsOnNewLine !== undefined) destEmitNode.startsOnNewLine = startsOnNewLine; return destEmitNode; } @@ -3014,7 +3034,7 @@ namespace ts { if (children.length > 1) { for (const child of children) { - child.startsOnNewLine = true; + startOnNewLine(child); argumentsList.push(child); } } @@ -3045,7 +3065,7 @@ namespace ts { if (children && children.length > 0) { if (children.length > 1) { for (const child of children) { - child.startsOnNewLine = true; + startOnNewLine(child); argumentsList.push(child); } } @@ -3620,8 +3640,8 @@ namespace ts { ); setOriginalNode(updated, node); setTextRange(updated, node); - if (node.startsOnNewLine) { - updated.startsOnNewLine = true; + if (getStartsOnNewLine(node)) { + setStartsOnNewLine(updated, /*newLine*/ true); } aggregateTransformFlags(updated); return updated; @@ -4250,8 +4270,7 @@ namespace ts { } export function startOnNewLine(node: T): T { - node.startsOnNewLine = true; - return node; + return setStartsOnNewLine(node, /*newLine*/ true); } export function getExternalHelpersModuleName(node: SourceFile) { diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index a1e52480172..989b0827570 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -787,9 +787,7 @@ namespace ts { // To preserve the behavior of the old emitter, we explicitly indent // the body of the function here if it was requested in an earlier // transformation. - if (getEmitFlags(node) & EmitFlags.Indented) { - setEmitFlags(classFunction, EmitFlags.Indented); - } + setEmitFlags(classFunction, (getEmitFlags(node) & EmitFlags.Indented) | EmitFlags.ReuseTempVariableScope); // "inner" and "outer" below are added purely to preserve source map locations from // the old emitter @@ -1327,7 +1325,8 @@ namespace ts { EmitFlags.SingleLine | EmitFlags.NoTrailingSourceMap | EmitFlags.NoTokenSourceMaps ) ); - statement.startsOnNewLine = true; + + startOnNewLine(statement); setTextRange(statement, parameter); setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoTrailingSourceMap | EmitFlags.CustomPrologue); statements.push(statement); @@ -1683,7 +1682,7 @@ namespace ts { ] ); if (startsOnNewLine) { - call.startsOnNewLine = true; + startOnNewLine(call); } exitSubtree(ancestorFacts, HierarchyFacts.PropagateNewTargetMask, hierarchyFacts & HierarchyFacts.PropagateNewTargetMask ? HierarchyFacts.NewTarget : HierarchyFacts.None); @@ -2602,7 +2601,7 @@ namespace ts { ); if (node.multiLine) { - assignment.startsOnNewLine = true; + startOnNewLine(assignment); } expressions.push(assignment); @@ -3083,7 +3082,7 @@ namespace ts { ); setTextRange(expression, property); if (startsOnNewLine) { - expression.startsOnNewLine = true; + startOnNewLine(expression); } return expression; } @@ -3105,7 +3104,7 @@ namespace ts { ); setTextRange(expression, property); if (startsOnNewLine) { - expression.startsOnNewLine = true; + startOnNewLine(expression); } return expression; } @@ -3128,7 +3127,7 @@ namespace ts { ); setTextRange(expression, method); if (startsOnNewLine) { - expression.startsOnNewLine = true; + startOnNewLine(expression); } exitSubtree(ancestorFacts, HierarchyFacts.PropagateNewTargetMask, hierarchyFacts & HierarchyFacts.PropagateNewTargetMask ? HierarchyFacts.NewTarget : HierarchyFacts.None); return expression; diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 7ede62b1540..bd2a4ef554d 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -1077,7 +1077,7 @@ namespace ts { const visited = visitNode(expression, visitor, isExpression); if (visited) { if (multiLine) { - visited.startsOnNewLine = true; + startOnNewLine(visited); } expressions.push(visited); } @@ -2683,8 +2683,7 @@ namespace ts { if (clauses) { const labelExpression = createPropertyAccess(state, "label"); const switchStatement = createSwitch(labelExpression, createCaseBlock(clauses)); - switchStatement.startsOnNewLine = true; - return [switchStatement]; + return [startOnNewLine(switchStatement)]; } if (statements) { diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 5339f2aaee5..39a4cc83bda 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -86,6 +86,12 @@ namespace ts { */ let applicableSubstitutions: TypeScriptSubstitutionFlags; + /** + * Tracks what computed name expressions originating from elided names must be inlined + * at the next execution site, in document order + */ + let pendingExpressions: Expression[] | undefined; + return transformSourceFile; /** @@ -395,9 +401,11 @@ namespace ts { case SyntaxKind.TypeAliasDeclaration: // TypeScript type-only declarations are elided. + return undefined; case SyntaxKind.PropertyDeclaration: - // TypeScript property declarations are elided. + // TypeScript property declarations are elided. However their names are still visited, and can potentially be retained if they could have sideeffects + return visitPropertyDeclaration(node as PropertyDeclaration); case SyntaxKind.NamespaceExportDeclaration: // TypeScript namespace export declarations are elided. @@ -584,6 +592,9 @@ namespace ts { * @param node The node to transform. */ function visitClassDeclaration(node: ClassDeclaration): VisitResult { + const savedPendingExpressions = pendingExpressions; + pendingExpressions = undefined; + const staticProperties = getInitializedProperties(node, /*isStatic*/ true); const facts = getClassFacts(node, staticProperties); @@ -598,6 +609,12 @@ namespace ts { let statements: Statement[] = [classStatement]; + // Write any pending expressions from elided or moved computed property names + if (some(pendingExpressions)) { + statements.push(createStatement(inlineExpressions(pendingExpressions))); + } + pendingExpressions = savedPendingExpressions; + // Emit static property assignment. Because classDeclaration is lexically evaluated, // it is safe to emit static property assignment after classDeclaration // From ES6 specification: @@ -856,6 +873,9 @@ namespace ts { * @param node The node to transform. */ function visitClassExpression(node: ClassExpression): Expression { + const savedPendingExpressions = pendingExpressions; + pendingExpressions = undefined; + const staticProperties = getInitializedProperties(node, /*isStatic*/ true); const heritageClauses = visitNodes(node.heritageClauses, visitor, isHeritageClause); const members = transformClassMembers(node, some(heritageClauses, c => c.token === SyntaxKind.ExtendsKeyword)); @@ -871,7 +891,7 @@ namespace ts { setOriginalNode(classExpression, node); setTextRange(classExpression, node); - if (staticProperties.length > 0) { + if (some(staticProperties) || some(pendingExpressions)) { const expressions: Expression[] = []; const temp = createTempVariable(hoistVariableDeclaration); if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference) { @@ -884,11 +904,15 @@ namespace ts { // the body of a class with static initializers. setEmitFlags(classExpression, EmitFlags.Indented | getEmitFlags(classExpression)); expressions.push(startOnNewLine(createAssignment(temp, classExpression))); + // Add any pending expressions leftover from elided or relocated computed property names + addRange(expressions, map(pendingExpressions, startOnNewLine)); + pendingExpressions = savedPendingExpressions; addRange(expressions, generateInitializedPropertyExpressions(staticProperties, temp)); expressions.push(startOnNewLine(temp)); return inlineExpressions(expressions); } + pendingExpressions = savedPendingExpressions; return classExpression; } @@ -1202,7 +1226,7 @@ namespace ts { const expressions: Expression[] = []; for (const property of properties) { const expression = transformInitializedProperty(property, receiver); - expression.startsOnNewLine = true; + startOnNewLine(expression); setSourceMapRange(expression, moveRangePastModifiers(property)); setCommentRange(expression, property); expressions.push(expression); @@ -1218,7 +1242,10 @@ namespace ts { * @param receiver The object receiving the property assignment. */ function transformInitializedProperty(property: PropertyDeclaration, receiver: LeftHandSideExpression) { - const propertyName = visitPropertyNameOfClassElement(property); + // We generate a name here in order to reuse the value cached by the relocated computed name expression (which uses the same generated name) + const propertyName = isComputedPropertyName(property.name) && !isSimpleInlineableExpression(property.name.expression) + ? updateComputedPropertyName(property.name, getGeneratedNameForNode(property.name, !hasModifier(property, ModifierFlags.Static))) + : property.name; const initializer = visitNode(property.initializer, visitor, isExpression); const memberAccess = createMemberAccessForPropertyName(receiver, propertyName, /*location*/ propertyName); @@ -2041,6 +2068,16 @@ namespace ts { ); } + /** + * A simple inlinable expression is an expression which can be copied into multiple locations + * without risk of repeating any sideeffects and whose value could not possibly change between + * any such locations + */ + function isSimpleInlineableExpression(expression: Expression) { + return !isIdentifier(expression) && isSimpleCopiableExpression(expression) || + isWellKnownSymbolSyntactically(expression); + } + /** * Gets an expression that represents a property name. For a computed property, a * name is generated for the node. @@ -2050,7 +2087,7 @@ namespace ts { function getExpressionForPropertyName(member: ClassElement | EnumMember, generateNameForComputedPropertyName: boolean): Expression { const name = member.name; if (isComputedPropertyName(name)) { - return generateNameForComputedPropertyName + return generateNameForComputedPropertyName && !isSimpleInlineableExpression((name).expression) ? getGeneratedNameForNode(name) : (name).expression; } @@ -2062,6 +2099,26 @@ namespace ts { } } + /** + * If the name is a computed property, this function transforms it, then either returns an expression which caches the + * value of the result or the expression itself if the value is either unused or safe to inline into multiple locations + * @param shouldHoist Does the expression need to be reused? (ie, for an initializer or a decorator) + * @param omitSimple Should expressions with no observable side-effects be elided? (ie, the expression is not hoisted for a decorator or initializer and is a literal) + */ + function getPropertyNameExpressionIfNeeded(name: PropertyName, shouldHoist: boolean, omitSimple: boolean): Expression { + if (isComputedPropertyName(name)) { + const expression = visitNode(name.expression, visitor, isExpression); + const innerExpression = skipPartiallyEmittedExpressions(expression); + const inlinable = isSimpleInlineableExpression(innerExpression); + if (!inlinable && shouldHoist) { + const generatedName = getGeneratedNameForNode(name); + hoistVariableDeclaration(generatedName); + return createAssignment(generatedName, expression); + } + return (omitSimple && (inlinable || isIdentifier(innerExpression))) ? undefined : expression; + } + } + /** * Visits the property name of a class element, for use when emitting property * initializers. For a computed property on a node with decorators, a temporary @@ -2071,15 +2128,14 @@ namespace ts { */ function visitPropertyNameOfClassElement(member: ClassElement): PropertyName { const name = member.name; - if (isComputedPropertyName(name)) { - let expression = visitNode(name.expression, visitor, isExpression); - if (member.decorators) { - const generatedName = getGeneratedNameForNode(name); - hoistVariableDeclaration(generatedName); - expression = createAssignment(generatedName, expression); + let expr = getPropertyNameExpressionIfNeeded(name, some(member.decorators), /*omitSimple*/ false); + if (expr) { // expr only exists if `name` is a computed property name + // Inline any pending expressions from previous elided or relocated computed property name expressions in order to preserve execution order + if (some(pendingExpressions)) { + expr = inlineExpressions([...pendingExpressions, expr]); + pendingExpressions.length = 0; } - - return updateComputedPropertyName(name, expression); + return updateComputedPropertyName(name as ComputedPropertyName, expr); } else { return name; @@ -2136,6 +2192,14 @@ namespace ts { return !nodeIsMissing(node.body); } + function visitPropertyDeclaration(node: PropertyDeclaration): undefined { + const expr = getPropertyNameExpressionIfNeeded(node.name, some(node.decorators) || !!node.initializer, /*omitSimple*/ true); + if (expr && !isSimpleInlineableExpression(expr)) { + (pendingExpressions || (pendingExpressions = [])).push(expr); + } + return undefined; + } + function visitConstructor(node: ConstructorDeclaration) { if (!shouldEmitFunctionLikeDeclaration(node)) { return undefined; @@ -2156,7 +2220,7 @@ namespace ts { * This function will be called when one of the following conditions are met: * - The node is an overload * - The node is marked as abstract, public, private, protected, or readonly - * - The node has both a decorator and a computed property name + * - The node has a computed property name * * @param node The method node. */ @@ -2200,7 +2264,7 @@ namespace ts { * * This function will be called when one of the following conditions are met: * - The node is marked as abstract, public, private, or protected - * - The node has both a decorator and a computed property name + * - The node has a computed property name * * @param node The get accessor node. */ @@ -2231,7 +2295,7 @@ namespace ts { * * This function will be called when one of the following conditions are met: * - The node is marked as abstract, public, private, or protected - * - The node has both a decorator and a computed property name + * - The node has a computed property name * * @param node The set accessor node. */ diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b4e84ae6a75..adab1f32492 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -520,7 +520,6 @@ namespace ts { /* @internal */ id?: number; // Unique id (used to look up NodeLinks) parent?: Node; // Parent node (initialized by binding) /* @internal */ original?: Node; // The original node if this is an updated node. - /* @internal */ startsOnNewLine?: boolean; // Whether a synthesized node should start on a new line (used by transforms). /* @internal */ symbol?: Symbol; // Symbol declared by node (initialized by binding) /* @internal */ locals?: SymbolTable; // Locals associated with node (initialized by binding) /* @internal */ nextContainer?: Node; // Next container in declaration order (initialized by binding) @@ -630,6 +629,7 @@ namespace ts { isInJSDocNamespace?: boolean; // if the node is a member in a JSDoc namespace /*@internal*/ typeArguments?: NodeArray; // Only defined on synthesized nodes. Though not syntactically valid, used in emitting diagnostics. /*@internal*/ jsdocDotPos?: number; // Identifier occurs in JSDoc-style generic: Id. + /*@internal*/ skipNameGenerationScope?: boolean; // Should skip a name generation scope when generating the name for this identifier } // Transient identifier node (marked by id === -1) @@ -4330,6 +4330,7 @@ namespace ts { constantValue?: string | number; // The constant value of an expression externalHelpersModuleName?: Identifier; // The local name for an imported helpers module helpers?: EmitHelper[]; // Emit helpers for the node + startsOnNewLine?: boolean; // If the node should begin on a new line } export const enum EmitFlags { diff --git a/tests/baselines/reference/capturedParametersInInitializers2.js b/tests/baselines/reference/capturedParametersInInitializers2.js index 2e833cac003..8982862af4f 100644 --- a/tests/baselines/reference/capturedParametersInInitializers2.js +++ b/tests/baselines/reference/capturedParametersInInitializers2.js @@ -19,11 +19,14 @@ function foo(y, x) { var _a; } function foo2(y, x) { - if (y === void 0) { y = /** @class */ (function () { - function class_2() { - this[x] = x; - } - return class_2; - }()); } + if (y === void 0) { y = (_a = /** @class */ (function () { + function class_2() { + this[_b] = x; + } + return class_2; + }()), + _b = x, + _a); } if (x === void 0) { x = 1; } + var _b, _a; } diff --git a/tests/baselines/reference/computedPropertyNames12_ES5.js b/tests/baselines/reference/computedPropertyNames12_ES5.js index b3743a36b2b..e8bcf325c34 100644 --- a/tests/baselines/reference/computedPropertyNames12_ES5.js +++ b/tests/baselines/reference/computedPropertyNames12_ES5.js @@ -22,10 +22,12 @@ var n; var a; var C = /** @class */ (function () { function C() { - this[n] = n; - this[s + n] = 2; + this[_a] = n; + this[_b] = 2; this["hello bye"] = 0; } - C["hello " + a + " bye"] = 0; + _a = n, s + s, _b = s + n, +s, _c = "hello " + a + " bye"; + C[_c] = 0; return C; + var _a, _b, _c; }()); diff --git a/tests/baselines/reference/computedPropertyNames12_ES6.js b/tests/baselines/reference/computedPropertyNames12_ES6.js index fd6ccb6e486..6f91ec92cc9 100644 --- a/tests/baselines/reference/computedPropertyNames12_ES6.js +++ b/tests/baselines/reference/computedPropertyNames12_ES6.js @@ -22,9 +22,11 @@ var n; var a; class C { constructor() { - this[n] = n; - this[s + n] = 2; + this[_a] = n; + this[_b] = 2; this[`hello bye`] = 0; } } -C[`hello ${a} bye`] = 0; +_a = n, s + s, _b = s + n, +s, _c = `hello ${a} bye`; +C[_c] = 0; +var _a, _b, _c; diff --git a/tests/baselines/reference/decoratorOnClassMethod13.js b/tests/baselines/reference/decoratorOnClassMethod13.js index adf21f733eb..e8a913070fc 100644 --- a/tests/baselines/reference/decoratorOnClassMethod13.js +++ b/tests/baselines/reference/decoratorOnClassMethod13.js @@ -14,13 +14,12 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, return c > 3 && r && Object.defineProperty(target, key, r), r; }; class C { - [_a = "1"]() { } - [_b = "b"]() { } + ["1"]() { } + ["b"]() { } } __decorate([ dec -], C.prototype, _a, null); +], C.prototype, "1", null); __decorate([ dec -], C.prototype, _b, null); -var _a, _b; +], C.prototype, "b", null); diff --git a/tests/baselines/reference/decoratorOnClassMethod4.js b/tests/baselines/reference/decoratorOnClassMethod4.js index 5c7b91c1c83..c68cca5d3a0 100644 --- a/tests/baselines/reference/decoratorOnClassMethod4.js +++ b/tests/baselines/reference/decoratorOnClassMethod4.js @@ -13,9 +13,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, return c > 3 && r && Object.defineProperty(target, key, r), r; }; class C { - [_a = "method"]() { } + ["method"]() { } } __decorate([ dec -], C.prototype, _a, null); -var _a; +], C.prototype, "method", null); diff --git a/tests/baselines/reference/decoratorOnClassMethod5.js b/tests/baselines/reference/decoratorOnClassMethod5.js index 2fedbaaf764..c89ebc6bb38 100644 --- a/tests/baselines/reference/decoratorOnClassMethod5.js +++ b/tests/baselines/reference/decoratorOnClassMethod5.js @@ -13,9 +13,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, return c > 3 && r && Object.defineProperty(target, key, r), r; }; class C { - [_a = "method"]() { } + ["method"]() { } } __decorate([ dec() -], C.prototype, _a, null); -var _a; +], C.prototype, "method", null); diff --git a/tests/baselines/reference/decoratorOnClassMethod6.js b/tests/baselines/reference/decoratorOnClassMethod6.js index 7966225e221..45f5eeddb81 100644 --- a/tests/baselines/reference/decoratorOnClassMethod6.js +++ b/tests/baselines/reference/decoratorOnClassMethod6.js @@ -13,9 +13,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, return c > 3 && r && Object.defineProperty(target, key, r), r; }; class C { - [_a = "method"]() { } + ["method"]() { } } __decorate([ dec -], C.prototype, _a, null); -var _a; +], C.prototype, "method", null); diff --git a/tests/baselines/reference/decoratorOnClassMethod7.js b/tests/baselines/reference/decoratorOnClassMethod7.js index 3ec509e17f0..dc92364cd89 100644 --- a/tests/baselines/reference/decoratorOnClassMethod7.js +++ b/tests/baselines/reference/decoratorOnClassMethod7.js @@ -13,9 +13,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, return c > 3 && r && Object.defineProperty(target, key, r), r; }; class C { - [_a = "method"]() { } + ["method"]() { } } __decorate([ dec -], C.prototype, _a, null); -var _a; +], C.prototype, "method", null); diff --git a/tests/baselines/reference/decoratorsOnComputedProperties.errors.txt b/tests/baselines/reference/decoratorsOnComputedProperties.errors.txt new file mode 100644 index 00000000000..2aef827d4f5 --- /dev/null +++ b/tests/baselines/reference/decoratorsOnComputedProperties.errors.txt @@ -0,0 +1,435 @@ +tests/cases/compiler/decoratorsOnComputedProperties.ts(18,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(19,8): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(20,8): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(21,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(22,8): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(23,8): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(27,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(28,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(29,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(30,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(35,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(36,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(37,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(38,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(39,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(40,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(52,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(53,8): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(54,8): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(55,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(56,8): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(57,8): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(62,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(63,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(64,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(65,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(70,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(71,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(72,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(73,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(74,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(75,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(88,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(89,8): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(90,8): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(92,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(93,8): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(94,8): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(98,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(99,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(100,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(101,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(106,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(107,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(108,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(110,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(111,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(112,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(124,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(125,8): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(126,8): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(128,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(129,8): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(131,8): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(135,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(136,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(137,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(138,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(143,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(144,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(145,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(147,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(148,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(150,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(162,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(163,8): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(164,8): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(166,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(167,8): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(169,8): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(173,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(174,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(175,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(176,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(181,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(182,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(183,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(184,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(185,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. +tests/cases/compiler/decoratorsOnComputedProperties.ts(186,5): error TS1206: Decorators are not valid here. +tests/cases/compiler/decoratorsOnComputedProperties.ts(188,5): error TS1206: Decorators are not valid here. + + +==== tests/cases/compiler/decoratorsOnComputedProperties.ts (81 errors) ==== + function x(o: object, k: PropertyKey) { } + let i = 0; + function foo(): string { return ++i + ""; } + + const fieldNameA: string = "fieldName1"; + const fieldNameB: string = "fieldName2"; + const fieldNameC: string = "fieldName3"; + + class A { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + ~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [foo()]: any; + ~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [foo()]: any = null; + ~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + [fieldNameA]: any; + ~~~~~~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [fieldNameB]: any; + ~~~~~~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [fieldNameC]: any = null; + ~~~~~~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + } + + void class B { + @x ["property"]: any; + ~ +!!! error TS1206: Decorators are not valid here. + @x [Symbol.toStringTag]: any; + ~ +!!! error TS1206: Decorators are not valid here. + @x ["property2"]: any = 2; + ~ +!!! error TS1206: Decorators are not valid here. + @x [Symbol.iterator]: any = null; + ~ +!!! error TS1206: Decorators are not valid here. + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + ~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [foo()]: any; + ~ +!!! error TS1206: Decorators are not valid here. + @x [foo()]: any = null; + ~ +!!! error TS1206: Decorators are not valid here. + [fieldNameA]: any; + ~~~~~~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [fieldNameB]: any; + ~ +!!! error TS1206: Decorators are not valid here. + @x [fieldNameC]: any = null; + ~ +!!! error TS1206: Decorators are not valid here. + }; + + class C { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + ~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [foo()]: any; + ~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [foo()]: any = null; + ~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + [fieldNameA]: any; + ~~~~~~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [fieldNameB]: any; + ~~~~~~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [fieldNameC]: any = null; + ~~~~~~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + ["some" + "method"]() {} + } + + void class D { + @x ["property"]: any; + ~ +!!! error TS1206: Decorators are not valid here. + @x [Symbol.toStringTag]: any; + ~ +!!! error TS1206: Decorators are not valid here. + @x ["property2"]: any = 2; + ~ +!!! error TS1206: Decorators are not valid here. + @x [Symbol.iterator]: any = null; + ~ +!!! error TS1206: Decorators are not valid here. + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + ~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [foo()]: any; + ~ +!!! error TS1206: Decorators are not valid here. + @x [foo()]: any = null; + ~ +!!! error TS1206: Decorators are not valid here. + [fieldNameA]: any; + ~~~~~~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [fieldNameB]: any; + ~ +!!! error TS1206: Decorators are not valid here. + @x [fieldNameC]: any = null; + ~ +!!! error TS1206: Decorators are not valid here. + ["some" + "method"]() {} + }; + + class E { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + ~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [foo()]: any; + ~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [foo()]: any = null; + ~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + ["some" + "method"]() {} + [fieldNameA]: any; + ~~~~~~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [fieldNameB]: any; + ~~~~~~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [fieldNameC]: any = null; + ~~~~~~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + } + + void class F { + @x ["property"]: any; + ~ +!!! error TS1206: Decorators are not valid here. + @x [Symbol.toStringTag]: any; + ~ +!!! error TS1206: Decorators are not valid here. + @x ["property2"]: any = 2; + ~ +!!! error TS1206: Decorators are not valid here. + @x [Symbol.iterator]: any = null; + ~ +!!! error TS1206: Decorators are not valid here. + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + ~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [foo()]: any; + ~ +!!! error TS1206: Decorators are not valid here. + @x [foo()]: any = null; + ~ +!!! error TS1206: Decorators are not valid here. + ["some" + "method"]() {} + [fieldNameA]: any; + ~~~~~~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [fieldNameB]: any; + ~ +!!! error TS1206: Decorators are not valid here. + @x [fieldNameC]: any = null; + ~ +!!! error TS1206: Decorators are not valid here. + }; + + class G { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + ~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [foo()]: any; + ~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [foo()]: any = null; + ~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + ["some" + "method"]() {} + [fieldNameA]: any; + ~~~~~~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [fieldNameB]: any; + ~~~~~~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + ["some" + "method2"]() {} + @x [fieldNameC]: any = null; + ~~~~~~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + } + + void class H { + @x ["property"]: any; + ~ +!!! error TS1206: Decorators are not valid here. + @x [Symbol.toStringTag]: any; + ~ +!!! error TS1206: Decorators are not valid here. + @x ["property2"]: any = 2; + ~ +!!! error TS1206: Decorators are not valid here. + @x [Symbol.iterator]: any = null; + ~ +!!! error TS1206: Decorators are not valid here. + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + ~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [foo()]: any; + ~ +!!! error TS1206: Decorators are not valid here. + @x [foo()]: any = null; + ~ +!!! error TS1206: Decorators are not valid here. + ["some" + "method"]() {} + [fieldNameA]: any; + ~~~~~~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [fieldNameB]: any; + ~ +!!! error TS1206: Decorators are not valid here. + ["some" + "method2"]() {} + @x [fieldNameC]: any = null; + ~ +!!! error TS1206: Decorators are not valid here. + }; + + class I { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + ~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [foo()]: any; + ~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [foo()]: any = null; + ~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x ["some" + "method"]() {} + [fieldNameA]: any; + ~~~~~~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [fieldNameB]: any; + ~~~~~~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + ["some" + "method2"]() {} + @x [fieldNameC]: any = null; + ~~~~~~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + } + + void class J { + @x ["property"]: any; + ~ +!!! error TS1206: Decorators are not valid here. + @x [Symbol.toStringTag]: any; + ~ +!!! error TS1206: Decorators are not valid here. + @x ["property2"]: any = 2; + ~ +!!! error TS1206: Decorators are not valid here. + @x [Symbol.iterator]: any = null; + ~ +!!! error TS1206: Decorators are not valid here. + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + ~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [foo()]: any; + ~ +!!! error TS1206: Decorators are not valid here. + @x [foo()]: any = null; + ~ +!!! error TS1206: Decorators are not valid here. + @x ["some" + "method"]() {} + ~ +!!! error TS1206: Decorators are not valid here. + [fieldNameA]: any; + ~~~~~~~~~~~~ +!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. + @x [fieldNameB]: any; + ~ +!!! error TS1206: Decorators are not valid here. + ["some" + "method2"]() {} + @x [fieldNameC]: any = null; + ~ +!!! error TS1206: Decorators are not valid here. + }; \ No newline at end of file diff --git a/tests/baselines/reference/decoratorsOnComputedProperties.js b/tests/baselines/reference/decoratorsOnComputedProperties.js new file mode 100644 index 00000000000..0083bc8b9a1 --- /dev/null +++ b/tests/baselines/reference/decoratorsOnComputedProperties.js @@ -0,0 +1,457 @@ +//// [decoratorsOnComputedProperties.ts] +function x(o: object, k: PropertyKey) { } +let i = 0; +function foo(): string { return ++i + ""; } + +const fieldNameA: string = "fieldName1"; +const fieldNameB: string = "fieldName2"; +const fieldNameC: string = "fieldName3"; + +class A { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + @x [foo()]: any; + @x [foo()]: any = null; + [fieldNameA]: any; + @x [fieldNameB]: any; + @x [fieldNameC]: any = null; +} + +void class B { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + @x [foo()]: any; + @x [foo()]: any = null; + [fieldNameA]: any; + @x [fieldNameB]: any; + @x [fieldNameC]: any = null; +}; + +class C { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + @x [foo()]: any; + @x [foo()]: any = null; + [fieldNameA]: any; + @x [fieldNameB]: any; + @x [fieldNameC]: any = null; + ["some" + "method"]() {} +} + +void class D { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + @x [foo()]: any; + @x [foo()]: any = null; + [fieldNameA]: any; + @x [fieldNameB]: any; + @x [fieldNameC]: any = null; + ["some" + "method"]() {} +}; + +class E { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + @x [foo()]: any; + @x [foo()]: any = null; + ["some" + "method"]() {} + [fieldNameA]: any; + @x [fieldNameB]: any; + @x [fieldNameC]: any = null; +} + +void class F { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + @x [foo()]: any; + @x [foo()]: any = null; + ["some" + "method"]() {} + [fieldNameA]: any; + @x [fieldNameB]: any; + @x [fieldNameC]: any = null; +}; + +class G { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + @x [foo()]: any; + @x [foo()]: any = null; + ["some" + "method"]() {} + [fieldNameA]: any; + @x [fieldNameB]: any; + ["some" + "method2"]() {} + @x [fieldNameC]: any = null; +} + +void class H { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + @x [foo()]: any; + @x [foo()]: any = null; + ["some" + "method"]() {} + [fieldNameA]: any; + @x [fieldNameB]: any; + ["some" + "method2"]() {} + @x [fieldNameC]: any = null; +}; + +class I { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + @x [foo()]: any; + @x [foo()]: any = null; + @x ["some" + "method"]() {} + [fieldNameA]: any; + @x [fieldNameB]: any; + ["some" + "method2"]() {} + @x [fieldNameC]: any = null; +} + +void class J { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + @x [foo()]: any; + @x [foo()]: any = null; + @x ["some" + "method"]() {} + [fieldNameA]: any; + @x [fieldNameB]: any; + ["some" + "method2"]() {} + @x [fieldNameC]: any = null; +}; + +//// [decoratorsOnComputedProperties.js] +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +function x(o, k) { } +let i = 0; +function foo() { return ++i + ""; } +const fieldNameA = "fieldName1"; +const fieldNameB = "fieldName2"; +const fieldNameC = "fieldName3"; +class A { + constructor() { + this["property2"] = 2; + this[Symbol.iterator] = null; + this["property4"] = 2; + this[Symbol.match] = null; + this[_a] = null; + this[_b] = null; + } +} +foo(), _c = foo(), _a = foo(), _d = fieldNameB, _b = fieldNameC; +__decorate([ + x +], A.prototype, "property", void 0); +__decorate([ + x +], A.prototype, Symbol.toStringTag, void 0); +__decorate([ + x +], A.prototype, "property2", void 0); +__decorate([ + x +], A.prototype, Symbol.iterator, void 0); +__decorate([ + x +], A.prototype, _c, void 0); +__decorate([ + x +], A.prototype, _a, void 0); +__decorate([ + x +], A.prototype, _d, void 0); +__decorate([ + x +], A.prototype, _b, void 0); +void (_e = class B { + constructor() { + this["property2"] = 2; + this[Symbol.iterator] = null; + this["property4"] = 2; + this[Symbol.match] = null; + this[_f] = null; + this[_g] = null; + } + }, + foo(), + _h = foo(), + _f = foo(), + _j = fieldNameB, + _g = fieldNameC, + _e); +class C { + constructor() { + this["property2"] = 2; + this[Symbol.iterator] = null; + this["property4"] = 2; + this[Symbol.match] = null; + this[_k] = null; + this[_l] = null; + } + [foo(), _m = foo(), _k = foo(), _o = fieldNameB, _l = fieldNameC, "some" + "method"]() { } +} +__decorate([ + x +], C.prototype, "property", void 0); +__decorate([ + x +], C.prototype, Symbol.toStringTag, void 0); +__decorate([ + x +], C.prototype, "property2", void 0); +__decorate([ + x +], C.prototype, Symbol.iterator, void 0); +__decorate([ + x +], C.prototype, _m, void 0); +__decorate([ + x +], C.prototype, _k, void 0); +__decorate([ + x +], C.prototype, _o, void 0); +__decorate([ + x +], C.prototype, _l, void 0); +void class D { + constructor() { + this["property2"] = 2; + this[Symbol.iterator] = null; + this["property4"] = 2; + this[Symbol.match] = null; + this[_p] = null; + this[_q] = null; + } + [foo(), _r = foo(), _p = foo(), _s = fieldNameB, _q = fieldNameC, "some" + "method"]() { } +}; +class E { + constructor() { + this["property2"] = 2; + this[Symbol.iterator] = null; + this["property4"] = 2; + this[Symbol.match] = null; + this[_t] = null; + this[_u] = null; + } + [foo(), _v = foo(), _t = foo(), "some" + "method"]() { } +} +_w = fieldNameB, _u = fieldNameC; +__decorate([ + x +], E.prototype, "property", void 0); +__decorate([ + x +], E.prototype, Symbol.toStringTag, void 0); +__decorate([ + x +], E.prototype, "property2", void 0); +__decorate([ + x +], E.prototype, Symbol.iterator, void 0); +__decorate([ + x +], E.prototype, _v, void 0); +__decorate([ + x +], E.prototype, _t, void 0); +__decorate([ + x +], E.prototype, _w, void 0); +__decorate([ + x +], E.prototype, _u, void 0); +void (_x = class F { + constructor() { + this["property2"] = 2; + this[Symbol.iterator] = null; + this["property4"] = 2; + this[Symbol.match] = null; + this[_y] = null; + this[_z] = null; + } + [foo(), _0 = foo(), _y = foo(), "some" + "method"]() { } + }, + _1 = fieldNameB, + _z = fieldNameC, + _x); +class G { + constructor() { + this["property2"] = 2; + this[Symbol.iterator] = null; + this["property4"] = 2; + this[Symbol.match] = null; + this[_2] = null; + this[_3] = null; + } + [foo(), _4 = foo(), _2 = foo(), "some" + "method"]() { } + [_5 = fieldNameB, "some" + "method2"]() { } +} +_3 = fieldNameC; +__decorate([ + x +], G.prototype, "property", void 0); +__decorate([ + x +], G.prototype, Symbol.toStringTag, void 0); +__decorate([ + x +], G.prototype, "property2", void 0); +__decorate([ + x +], G.prototype, Symbol.iterator, void 0); +__decorate([ + x +], G.prototype, _4, void 0); +__decorate([ + x +], G.prototype, _2, void 0); +__decorate([ + x +], G.prototype, _5, void 0); +__decorate([ + x +], G.prototype, _3, void 0); +void (_6 = class H { + constructor() { + this["property2"] = 2; + this[Symbol.iterator] = null; + this["property4"] = 2; + this[Symbol.match] = null; + this[_7] = null; + this[_8] = null; + } + [foo(), _9 = foo(), _7 = foo(), "some" + "method"]() { } + [_10 = fieldNameB, "some" + "method2"]() { } + }, + _8 = fieldNameC, + _6); +class I { + constructor() { + this["property2"] = 2; + this[Symbol.iterator] = null; + this["property4"] = 2; + this[Symbol.match] = null; + this[_11] = null; + this[_12] = null; + } + [foo(), _13 = foo(), _11 = foo(), _14 = "some" + "method"]() { } + [_15 = fieldNameB, "some" + "method2"]() { } +} +_12 = fieldNameC; +__decorate([ + x +], I.prototype, "property", void 0); +__decorate([ + x +], I.prototype, Symbol.toStringTag, void 0); +__decorate([ + x +], I.prototype, "property2", void 0); +__decorate([ + x +], I.prototype, Symbol.iterator, void 0); +__decorate([ + x +], I.prototype, _13, void 0); +__decorate([ + x +], I.prototype, _11, void 0); +__decorate([ + x +], I.prototype, _14, null); +__decorate([ + x +], I.prototype, _15, void 0); +__decorate([ + x +], I.prototype, _12, void 0); +void (_16 = class J { + constructor() { + this["property2"] = 2; + this[Symbol.iterator] = null; + this["property4"] = 2; + this[Symbol.match] = null; + this[_17] = null; + this[_18] = null; + } + [foo(), _19 = foo(), _17 = foo(), _20 = "some" + "method"]() { } + [_21 = fieldNameB, "some" + "method2"]() { } + }, + _18 = fieldNameC, + _16); +var _c, _a, _d, _b, _h, _f, _j, _g, _e, _m, _k, _o, _l, _r, _p, _s, _q, _v, _t, _w, _u, _0, _y, _1, _z, _x, _4, _2, _5, _3, _9, _7, _10, _8, _6, _13, _11, _14, _15, _12, _19, _17, _20, _21, _18, _16; diff --git a/tests/baselines/reference/decoratorsOnComputedProperties.symbols b/tests/baselines/reference/decoratorsOnComputedProperties.symbols new file mode 100644 index 00000000000..a9fb280f96e --- /dev/null +++ b/tests/baselines/reference/decoratorsOnComputedProperties.symbols @@ -0,0 +1,664 @@ +=== tests/cases/compiler/decoratorsOnComputedProperties.ts === +function x(o: object, k: PropertyKey) { } +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>o : Symbol(o, Decl(decoratorsOnComputedProperties.ts, 0, 11)) +>k : Symbol(k, Decl(decoratorsOnComputedProperties.ts, 0, 21)) +>PropertyKey : Symbol(PropertyKey, Decl(lib.es2015.core.d.ts, --, --)) + +let i = 0; +>i : Symbol(i, Decl(decoratorsOnComputedProperties.ts, 1, 3)) + +function foo(): string { return ++i + ""; } +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) +>i : Symbol(i, Decl(decoratorsOnComputedProperties.ts, 1, 3)) + +const fieldNameA: string = "fieldName1"; +>fieldNameA : Symbol(fieldNameA, Decl(decoratorsOnComputedProperties.ts, 4, 5)) + +const fieldNameB: string = "fieldName2"; +>fieldNameB : Symbol(fieldNameB, Decl(decoratorsOnComputedProperties.ts, 5, 5)) + +const fieldNameC: string = "fieldName3"; +>fieldNameC : Symbol(fieldNameC, Decl(decoratorsOnComputedProperties.ts, 6, 5)) + +class A { +>A : Symbol(A, Decl(decoratorsOnComputedProperties.ts, 6, 40)) + + @x ["property"]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>"property" : Symbol(A[["property"]], Decl(decoratorsOnComputedProperties.ts, 8, 9)) + + @x [Symbol.toStringTag]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>Symbol.toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + @x ["property2"]: any = 2; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>"property2" : Symbol(A[["property2"]], Decl(decoratorsOnComputedProperties.ts, 10, 33)) + + @x [Symbol.iterator]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) + + ["property3"]: any; +>"property3" : Symbol(A[["property3"]], Decl(decoratorsOnComputedProperties.ts, 12, 37)) + + [Symbol.isConcatSpreadable]: any; +>Symbol.isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + ["property4"]: any = 2; +>"property4" : Symbol(A[["property4"]], Decl(decoratorsOnComputedProperties.ts, 14, 37)) + + [Symbol.match]: any = null; +>Symbol.match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + [foo()]: any; +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + @x [foo()]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + @x [foo()]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + [fieldNameA]: any; +>fieldNameA : Symbol(fieldNameA, Decl(decoratorsOnComputedProperties.ts, 4, 5)) + + @x [fieldNameB]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>fieldNameB : Symbol(fieldNameB, Decl(decoratorsOnComputedProperties.ts, 5, 5)) + + @x [fieldNameC]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>fieldNameC : Symbol(fieldNameC, Decl(decoratorsOnComputedProperties.ts, 6, 5)) +} + +void class B { +>B : Symbol(B, Decl(decoratorsOnComputedProperties.ts, 25, 4)) + + @x ["property"]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>"property" : Symbol(B[["property"]], Decl(decoratorsOnComputedProperties.ts, 25, 14)) + + @x [Symbol.toStringTag]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>Symbol.toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + @x ["property2"]: any = 2; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>"property2" : Symbol(B[["property2"]], Decl(decoratorsOnComputedProperties.ts, 27, 33)) + + @x [Symbol.iterator]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) + + ["property3"]: any; +>"property3" : Symbol(B[["property3"]], Decl(decoratorsOnComputedProperties.ts, 29, 37)) + + [Symbol.isConcatSpreadable]: any; +>Symbol.isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + ["property4"]: any = 2; +>"property4" : Symbol(B[["property4"]], Decl(decoratorsOnComputedProperties.ts, 31, 37)) + + [Symbol.match]: any = null; +>Symbol.match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + [foo()]: any; +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + @x [foo()]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + @x [foo()]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + [fieldNameA]: any; +>fieldNameA : Symbol(fieldNameA, Decl(decoratorsOnComputedProperties.ts, 4, 5)) + + @x [fieldNameB]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>fieldNameB : Symbol(fieldNameB, Decl(decoratorsOnComputedProperties.ts, 5, 5)) + + @x [fieldNameC]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>fieldNameC : Symbol(fieldNameC, Decl(decoratorsOnComputedProperties.ts, 6, 5)) + +}; + +class C { +>C : Symbol(C, Decl(decoratorsOnComputedProperties.ts, 40, 2)) + + @x ["property"]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>"property" : Symbol(C[["property"]], Decl(decoratorsOnComputedProperties.ts, 42, 9)) + + @x [Symbol.toStringTag]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>Symbol.toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + @x ["property2"]: any = 2; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>"property2" : Symbol(C[["property2"]], Decl(decoratorsOnComputedProperties.ts, 44, 33)) + + @x [Symbol.iterator]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) + + ["property3"]: any; +>"property3" : Symbol(C[["property3"]], Decl(decoratorsOnComputedProperties.ts, 46, 37)) + + [Symbol.isConcatSpreadable]: any; +>Symbol.isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + ["property4"]: any = 2; +>"property4" : Symbol(C[["property4"]], Decl(decoratorsOnComputedProperties.ts, 48, 37)) + + [Symbol.match]: any = null; +>Symbol.match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + [foo()]: any; +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + @x [foo()]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + @x [foo()]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + [fieldNameA]: any; +>fieldNameA : Symbol(fieldNameA, Decl(decoratorsOnComputedProperties.ts, 4, 5)) + + @x [fieldNameB]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>fieldNameB : Symbol(fieldNameB, Decl(decoratorsOnComputedProperties.ts, 5, 5)) + + @x [fieldNameC]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>fieldNameC : Symbol(fieldNameC, Decl(decoratorsOnComputedProperties.ts, 6, 5)) + + ["some" + "method"]() {} +} + +void class D { +>D : Symbol(D, Decl(decoratorsOnComputedProperties.ts, 60, 4)) + + @x ["property"]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>"property" : Symbol(D[["property"]], Decl(decoratorsOnComputedProperties.ts, 60, 14)) + + @x [Symbol.toStringTag]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>Symbol.toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + @x ["property2"]: any = 2; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>"property2" : Symbol(D[["property2"]], Decl(decoratorsOnComputedProperties.ts, 62, 33)) + + @x [Symbol.iterator]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) + + ["property3"]: any; +>"property3" : Symbol(D[["property3"]], Decl(decoratorsOnComputedProperties.ts, 64, 37)) + + [Symbol.isConcatSpreadable]: any; +>Symbol.isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + ["property4"]: any = 2; +>"property4" : Symbol(D[["property4"]], Decl(decoratorsOnComputedProperties.ts, 66, 37)) + + [Symbol.match]: any = null; +>Symbol.match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + [foo()]: any; +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + @x [foo()]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + @x [foo()]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + [fieldNameA]: any; +>fieldNameA : Symbol(fieldNameA, Decl(decoratorsOnComputedProperties.ts, 4, 5)) + + @x [fieldNameB]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>fieldNameB : Symbol(fieldNameB, Decl(decoratorsOnComputedProperties.ts, 5, 5)) + + @x [fieldNameC]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>fieldNameC : Symbol(fieldNameC, Decl(decoratorsOnComputedProperties.ts, 6, 5)) + + ["some" + "method"]() {} +}; + +class E { +>E : Symbol(E, Decl(decoratorsOnComputedProperties.ts, 76, 2)) + + @x ["property"]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>"property" : Symbol(E[["property"]], Decl(decoratorsOnComputedProperties.ts, 78, 9)) + + @x [Symbol.toStringTag]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>Symbol.toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + @x ["property2"]: any = 2; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>"property2" : Symbol(E[["property2"]], Decl(decoratorsOnComputedProperties.ts, 80, 33)) + + @x [Symbol.iterator]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) + + ["property3"]: any; +>"property3" : Symbol(E[["property3"]], Decl(decoratorsOnComputedProperties.ts, 82, 37)) + + [Symbol.isConcatSpreadable]: any; +>Symbol.isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + ["property4"]: any = 2; +>"property4" : Symbol(E[["property4"]], Decl(decoratorsOnComputedProperties.ts, 84, 37)) + + [Symbol.match]: any = null; +>Symbol.match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + [foo()]: any; +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + @x [foo()]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + @x [foo()]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + ["some" + "method"]() {} + [fieldNameA]: any; +>fieldNameA : Symbol(fieldNameA, Decl(decoratorsOnComputedProperties.ts, 4, 5)) + + @x [fieldNameB]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>fieldNameB : Symbol(fieldNameB, Decl(decoratorsOnComputedProperties.ts, 5, 5)) + + @x [fieldNameC]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>fieldNameC : Symbol(fieldNameC, Decl(decoratorsOnComputedProperties.ts, 6, 5)) +} + +void class F { +>F : Symbol(F, Decl(decoratorsOnComputedProperties.ts, 96, 4)) + + @x ["property"]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>"property" : Symbol(F[["property"]], Decl(decoratorsOnComputedProperties.ts, 96, 14)) + + @x [Symbol.toStringTag]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>Symbol.toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + @x ["property2"]: any = 2; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>"property2" : Symbol(F[["property2"]], Decl(decoratorsOnComputedProperties.ts, 98, 33)) + + @x [Symbol.iterator]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) + + ["property3"]: any; +>"property3" : Symbol(F[["property3"]], Decl(decoratorsOnComputedProperties.ts, 100, 37)) + + [Symbol.isConcatSpreadable]: any; +>Symbol.isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + ["property4"]: any = 2; +>"property4" : Symbol(F[["property4"]], Decl(decoratorsOnComputedProperties.ts, 102, 37)) + + [Symbol.match]: any = null; +>Symbol.match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + [foo()]: any; +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + @x [foo()]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + @x [foo()]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + ["some" + "method"]() {} + [fieldNameA]: any; +>fieldNameA : Symbol(fieldNameA, Decl(decoratorsOnComputedProperties.ts, 4, 5)) + + @x [fieldNameB]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>fieldNameB : Symbol(fieldNameB, Decl(decoratorsOnComputedProperties.ts, 5, 5)) + + @x [fieldNameC]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>fieldNameC : Symbol(fieldNameC, Decl(decoratorsOnComputedProperties.ts, 6, 5)) + +}; + +class G { +>G : Symbol(G, Decl(decoratorsOnComputedProperties.ts, 112, 2)) + + @x ["property"]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>"property" : Symbol(G[["property"]], Decl(decoratorsOnComputedProperties.ts, 114, 9)) + + @x [Symbol.toStringTag]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>Symbol.toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + @x ["property2"]: any = 2; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>"property2" : Symbol(G[["property2"]], Decl(decoratorsOnComputedProperties.ts, 116, 33)) + + @x [Symbol.iterator]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) + + ["property3"]: any; +>"property3" : Symbol(G[["property3"]], Decl(decoratorsOnComputedProperties.ts, 118, 37)) + + [Symbol.isConcatSpreadable]: any; +>Symbol.isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + ["property4"]: any = 2; +>"property4" : Symbol(G[["property4"]], Decl(decoratorsOnComputedProperties.ts, 120, 37)) + + [Symbol.match]: any = null; +>Symbol.match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + [foo()]: any; +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + @x [foo()]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + @x [foo()]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + ["some" + "method"]() {} + [fieldNameA]: any; +>fieldNameA : Symbol(fieldNameA, Decl(decoratorsOnComputedProperties.ts, 4, 5)) + + @x [fieldNameB]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>fieldNameB : Symbol(fieldNameB, Decl(decoratorsOnComputedProperties.ts, 5, 5)) + + ["some" + "method2"]() {} + @x [fieldNameC]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>fieldNameC : Symbol(fieldNameC, Decl(decoratorsOnComputedProperties.ts, 6, 5)) +} + +void class H { +>H : Symbol(H, Decl(decoratorsOnComputedProperties.ts, 133, 4)) + + @x ["property"]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>"property" : Symbol(H[["property"]], Decl(decoratorsOnComputedProperties.ts, 133, 14)) + + @x [Symbol.toStringTag]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>Symbol.toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + @x ["property2"]: any = 2; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>"property2" : Symbol(H[["property2"]], Decl(decoratorsOnComputedProperties.ts, 135, 33)) + + @x [Symbol.iterator]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) + + ["property3"]: any; +>"property3" : Symbol(H[["property3"]], Decl(decoratorsOnComputedProperties.ts, 137, 37)) + + [Symbol.isConcatSpreadable]: any; +>Symbol.isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + ["property4"]: any = 2; +>"property4" : Symbol(H[["property4"]], Decl(decoratorsOnComputedProperties.ts, 139, 37)) + + [Symbol.match]: any = null; +>Symbol.match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + [foo()]: any; +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + @x [foo()]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + @x [foo()]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + ["some" + "method"]() {} + [fieldNameA]: any; +>fieldNameA : Symbol(fieldNameA, Decl(decoratorsOnComputedProperties.ts, 4, 5)) + + @x [fieldNameB]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>fieldNameB : Symbol(fieldNameB, Decl(decoratorsOnComputedProperties.ts, 5, 5)) + + ["some" + "method2"]() {} + @x [fieldNameC]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>fieldNameC : Symbol(fieldNameC, Decl(decoratorsOnComputedProperties.ts, 6, 5)) + +}; + +class I { +>I : Symbol(I, Decl(decoratorsOnComputedProperties.ts, 150, 2)) + + @x ["property"]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>"property" : Symbol(I[["property"]], Decl(decoratorsOnComputedProperties.ts, 152, 9)) + + @x [Symbol.toStringTag]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>Symbol.toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + @x ["property2"]: any = 2; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>"property2" : Symbol(I[["property2"]], Decl(decoratorsOnComputedProperties.ts, 154, 33)) + + @x [Symbol.iterator]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) + + ["property3"]: any; +>"property3" : Symbol(I[["property3"]], Decl(decoratorsOnComputedProperties.ts, 156, 37)) + + [Symbol.isConcatSpreadable]: any; +>Symbol.isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + ["property4"]: any = 2; +>"property4" : Symbol(I[["property4"]], Decl(decoratorsOnComputedProperties.ts, 158, 37)) + + [Symbol.match]: any = null; +>Symbol.match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + [foo()]: any; +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + @x [foo()]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + @x [foo()]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + @x ["some" + "method"]() {} +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) + + [fieldNameA]: any; +>fieldNameA : Symbol(fieldNameA, Decl(decoratorsOnComputedProperties.ts, 4, 5)) + + @x [fieldNameB]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>fieldNameB : Symbol(fieldNameB, Decl(decoratorsOnComputedProperties.ts, 5, 5)) + + ["some" + "method2"]() {} + @x [fieldNameC]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>fieldNameC : Symbol(fieldNameC, Decl(decoratorsOnComputedProperties.ts, 6, 5)) +} + +void class J { +>J : Symbol(J, Decl(decoratorsOnComputedProperties.ts, 171, 4)) + + @x ["property"]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>"property" : Symbol(J[["property"]], Decl(decoratorsOnComputedProperties.ts, 171, 14)) + + @x [Symbol.toStringTag]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>Symbol.toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + @x ["property2"]: any = 2; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>"property2" : Symbol(J[["property2"]], Decl(decoratorsOnComputedProperties.ts, 173, 33)) + + @x [Symbol.iterator]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) + + ["property3"]: any; +>"property3" : Symbol(J[["property3"]], Decl(decoratorsOnComputedProperties.ts, 175, 37)) + + [Symbol.isConcatSpreadable]: any; +>Symbol.isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + ["property4"]: any = 2; +>"property4" : Symbol(J[["property4"]], Decl(decoratorsOnComputedProperties.ts, 177, 37)) + + [Symbol.match]: any = null; +>Symbol.match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>match : Symbol(SymbolConstructor.match, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + [foo()]: any; +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + @x [foo()]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + @x [foo()]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>foo : Symbol(foo, Decl(decoratorsOnComputedProperties.ts, 1, 10)) + + @x ["some" + "method"]() {} +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) + + [fieldNameA]: any; +>fieldNameA : Symbol(fieldNameA, Decl(decoratorsOnComputedProperties.ts, 4, 5)) + + @x [fieldNameB]: any; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>fieldNameB : Symbol(fieldNameB, Decl(decoratorsOnComputedProperties.ts, 5, 5)) + + ["some" + "method2"]() {} + @x [fieldNameC]: any = null; +>x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) +>fieldNameC : Symbol(fieldNameC, Decl(decoratorsOnComputedProperties.ts, 6, 5)) + +}; diff --git a/tests/baselines/reference/decoratorsOnComputedProperties.types b/tests/baselines/reference/decoratorsOnComputedProperties.types new file mode 100644 index 00000000000..4976812b8d4 --- /dev/null +++ b/tests/baselines/reference/decoratorsOnComputedProperties.types @@ -0,0 +1,816 @@ +=== tests/cases/compiler/decoratorsOnComputedProperties.ts === +function x(o: object, k: PropertyKey) { } +>x : (o: object, k: PropertyKey) => void +>o : object +>k : PropertyKey +>PropertyKey : PropertyKey + +let i = 0; +>i : number +>0 : 0 + +function foo(): string { return ++i + ""; } +>foo : () => string +>++i + "" : string +>++i : number +>i : number +>"" : "" + +const fieldNameA: string = "fieldName1"; +>fieldNameA : string +>"fieldName1" : "fieldName1" + +const fieldNameB: string = "fieldName2"; +>fieldNameB : string +>"fieldName2" : "fieldName2" + +const fieldNameC: string = "fieldName3"; +>fieldNameC : string +>"fieldName3" : "fieldName3" + +class A { +>A : A + + @x ["property"]: any; +>x : (o: object, k: PropertyKey) => void +>"property" : "property" + + @x [Symbol.toStringTag]: any; +>x : (o: object, k: PropertyKey) => void +>Symbol.toStringTag : symbol +>Symbol : SymbolConstructor +>toStringTag : symbol + + @x ["property2"]: any = 2; +>x : (o: object, k: PropertyKey) => void +>"property2" : "property2" +>2 : 2 + + @x [Symbol.iterator]: any = null; +>x : (o: object, k: PropertyKey) => void +>Symbol.iterator : symbol +>Symbol : SymbolConstructor +>iterator : symbol +>null : null + + ["property3"]: any; +>"property3" : "property3" + + [Symbol.isConcatSpreadable]: any; +>Symbol.isConcatSpreadable : symbol +>Symbol : SymbolConstructor +>isConcatSpreadable : symbol + + ["property4"]: any = 2; +>"property4" : "property4" +>2 : 2 + + [Symbol.match]: any = null; +>Symbol.match : symbol +>Symbol : SymbolConstructor +>match : symbol +>null : null + + [foo()]: any; +>foo() : string +>foo : () => string + + @x [foo()]: any; +>x : (o: object, k: PropertyKey) => void +>foo() : string +>foo : () => string + + @x [foo()]: any = null; +>x : (o: object, k: PropertyKey) => void +>foo() : string +>foo : () => string +>null : null + + [fieldNameA]: any; +>fieldNameA : string + + @x [fieldNameB]: any; +>x : (o: object, k: PropertyKey) => void +>fieldNameB : string + + @x [fieldNameC]: any = null; +>x : (o: object, k: PropertyKey) => void +>fieldNameC : string +>null : null +} + +void class B { +>void class B { @x ["property"]: any; @x [Symbol.toStringTag]: any; @x ["property2"]: any = 2; @x [Symbol.iterator]: any = null; ["property3"]: any; [Symbol.isConcatSpreadable]: any; ["property4"]: any = 2; [Symbol.match]: any = null; [foo()]: any; @x [foo()]: any; @x [foo()]: any = null; [fieldNameA]: any; @x [fieldNameB]: any; @x [fieldNameC]: any = null;} : undefined +>class B { @x ["property"]: any; @x [Symbol.toStringTag]: any; @x ["property2"]: any = 2; @x [Symbol.iterator]: any = null; ["property3"]: any; [Symbol.isConcatSpreadable]: any; ["property4"]: any = 2; [Symbol.match]: any = null; [foo()]: any; @x [foo()]: any; @x [foo()]: any = null; [fieldNameA]: any; @x [fieldNameB]: any; @x [fieldNameC]: any = null;} : typeof B +>B : typeof B + + @x ["property"]: any; +>x : (o: object, k: PropertyKey) => void +>"property" : "property" + + @x [Symbol.toStringTag]: any; +>x : (o: object, k: PropertyKey) => void +>Symbol.toStringTag : symbol +>Symbol : SymbolConstructor +>toStringTag : symbol + + @x ["property2"]: any = 2; +>x : (o: object, k: PropertyKey) => void +>"property2" : "property2" +>2 : 2 + + @x [Symbol.iterator]: any = null; +>x : (o: object, k: PropertyKey) => void +>Symbol.iterator : symbol +>Symbol : SymbolConstructor +>iterator : symbol +>null : null + + ["property3"]: any; +>"property3" : "property3" + + [Symbol.isConcatSpreadable]: any; +>Symbol.isConcatSpreadable : symbol +>Symbol : SymbolConstructor +>isConcatSpreadable : symbol + + ["property4"]: any = 2; +>"property4" : "property4" +>2 : 2 + + [Symbol.match]: any = null; +>Symbol.match : symbol +>Symbol : SymbolConstructor +>match : symbol +>null : null + + [foo()]: any; +>foo() : string +>foo : () => string + + @x [foo()]: any; +>x : (o: object, k: PropertyKey) => void +>foo() : string +>foo : () => string + + @x [foo()]: any = null; +>x : (o: object, k: PropertyKey) => void +>foo() : string +>foo : () => string +>null : null + + [fieldNameA]: any; +>fieldNameA : string + + @x [fieldNameB]: any; +>x : (o: object, k: PropertyKey) => void +>fieldNameB : string + + @x [fieldNameC]: any = null; +>x : (o: object, k: PropertyKey) => void +>fieldNameC : string +>null : null + +}; + +class C { +>C : C + + @x ["property"]: any; +>x : (o: object, k: PropertyKey) => void +>"property" : "property" + + @x [Symbol.toStringTag]: any; +>x : (o: object, k: PropertyKey) => void +>Symbol.toStringTag : symbol +>Symbol : SymbolConstructor +>toStringTag : symbol + + @x ["property2"]: any = 2; +>x : (o: object, k: PropertyKey) => void +>"property2" : "property2" +>2 : 2 + + @x [Symbol.iterator]: any = null; +>x : (o: object, k: PropertyKey) => void +>Symbol.iterator : symbol +>Symbol : SymbolConstructor +>iterator : symbol +>null : null + + ["property3"]: any; +>"property3" : "property3" + + [Symbol.isConcatSpreadable]: any; +>Symbol.isConcatSpreadable : symbol +>Symbol : SymbolConstructor +>isConcatSpreadable : symbol + + ["property4"]: any = 2; +>"property4" : "property4" +>2 : 2 + + [Symbol.match]: any = null; +>Symbol.match : symbol +>Symbol : SymbolConstructor +>match : symbol +>null : null + + [foo()]: any; +>foo() : string +>foo : () => string + + @x [foo()]: any; +>x : (o: object, k: PropertyKey) => void +>foo() : string +>foo : () => string + + @x [foo()]: any = null; +>x : (o: object, k: PropertyKey) => void +>foo() : string +>foo : () => string +>null : null + + [fieldNameA]: any; +>fieldNameA : string + + @x [fieldNameB]: any; +>x : (o: object, k: PropertyKey) => void +>fieldNameB : string + + @x [fieldNameC]: any = null; +>x : (o: object, k: PropertyKey) => void +>fieldNameC : string +>null : null + + ["some" + "method"]() {} +>"some" + "method" : string +>"some" : "some" +>"method" : "method" +} + +void class D { +>void class D { @x ["property"]: any; @x [Symbol.toStringTag]: any; @x ["property2"]: any = 2; @x [Symbol.iterator]: any = null; ["property3"]: any; [Symbol.isConcatSpreadable]: any; ["property4"]: any = 2; [Symbol.match]: any = null; [foo()]: any; @x [foo()]: any; @x [foo()]: any = null; [fieldNameA]: any; @x [fieldNameB]: any; @x [fieldNameC]: any = null; ["some" + "method"]() {}} : undefined +>class D { @x ["property"]: any; @x [Symbol.toStringTag]: any; @x ["property2"]: any = 2; @x [Symbol.iterator]: any = null; ["property3"]: any; [Symbol.isConcatSpreadable]: any; ["property4"]: any = 2; [Symbol.match]: any = null; [foo()]: any; @x [foo()]: any; @x [foo()]: any = null; [fieldNameA]: any; @x [fieldNameB]: any; @x [fieldNameC]: any = null; ["some" + "method"]() {}} : typeof D +>D : typeof D + + @x ["property"]: any; +>x : (o: object, k: PropertyKey) => void +>"property" : "property" + + @x [Symbol.toStringTag]: any; +>x : (o: object, k: PropertyKey) => void +>Symbol.toStringTag : symbol +>Symbol : SymbolConstructor +>toStringTag : symbol + + @x ["property2"]: any = 2; +>x : (o: object, k: PropertyKey) => void +>"property2" : "property2" +>2 : 2 + + @x [Symbol.iterator]: any = null; +>x : (o: object, k: PropertyKey) => void +>Symbol.iterator : symbol +>Symbol : SymbolConstructor +>iterator : symbol +>null : null + + ["property3"]: any; +>"property3" : "property3" + + [Symbol.isConcatSpreadable]: any; +>Symbol.isConcatSpreadable : symbol +>Symbol : SymbolConstructor +>isConcatSpreadable : symbol + + ["property4"]: any = 2; +>"property4" : "property4" +>2 : 2 + + [Symbol.match]: any = null; +>Symbol.match : symbol +>Symbol : SymbolConstructor +>match : symbol +>null : null + + [foo()]: any; +>foo() : string +>foo : () => string + + @x [foo()]: any; +>x : (o: object, k: PropertyKey) => void +>foo() : string +>foo : () => string + + @x [foo()]: any = null; +>x : (o: object, k: PropertyKey) => void +>foo() : string +>foo : () => string +>null : null + + [fieldNameA]: any; +>fieldNameA : string + + @x [fieldNameB]: any; +>x : (o: object, k: PropertyKey) => void +>fieldNameB : string + + @x [fieldNameC]: any = null; +>x : (o: object, k: PropertyKey) => void +>fieldNameC : string +>null : null + + ["some" + "method"]() {} +>"some" + "method" : string +>"some" : "some" +>"method" : "method" + +}; + +class E { +>E : E + + @x ["property"]: any; +>x : (o: object, k: PropertyKey) => void +>"property" : "property" + + @x [Symbol.toStringTag]: any; +>x : (o: object, k: PropertyKey) => void +>Symbol.toStringTag : symbol +>Symbol : SymbolConstructor +>toStringTag : symbol + + @x ["property2"]: any = 2; +>x : (o: object, k: PropertyKey) => void +>"property2" : "property2" +>2 : 2 + + @x [Symbol.iterator]: any = null; +>x : (o: object, k: PropertyKey) => void +>Symbol.iterator : symbol +>Symbol : SymbolConstructor +>iterator : symbol +>null : null + + ["property3"]: any; +>"property3" : "property3" + + [Symbol.isConcatSpreadable]: any; +>Symbol.isConcatSpreadable : symbol +>Symbol : SymbolConstructor +>isConcatSpreadable : symbol + + ["property4"]: any = 2; +>"property4" : "property4" +>2 : 2 + + [Symbol.match]: any = null; +>Symbol.match : symbol +>Symbol : SymbolConstructor +>match : symbol +>null : null + + [foo()]: any; +>foo() : string +>foo : () => string + + @x [foo()]: any; +>x : (o: object, k: PropertyKey) => void +>foo() : string +>foo : () => string + + @x [foo()]: any = null; +>x : (o: object, k: PropertyKey) => void +>foo() : string +>foo : () => string +>null : null + + ["some" + "method"]() {} +>"some" + "method" : string +>"some" : "some" +>"method" : "method" + + [fieldNameA]: any; +>fieldNameA : string + + @x [fieldNameB]: any; +>x : (o: object, k: PropertyKey) => void +>fieldNameB : string + + @x [fieldNameC]: any = null; +>x : (o: object, k: PropertyKey) => void +>fieldNameC : string +>null : null +} + +void class F { +>void class F { @x ["property"]: any; @x [Symbol.toStringTag]: any; @x ["property2"]: any = 2; @x [Symbol.iterator]: any = null; ["property3"]: any; [Symbol.isConcatSpreadable]: any; ["property4"]: any = 2; [Symbol.match]: any = null; [foo()]: any; @x [foo()]: any; @x [foo()]: any = null; ["some" + "method"]() {} [fieldNameA]: any; @x [fieldNameB]: any; @x [fieldNameC]: any = null;} : undefined +>class F { @x ["property"]: any; @x [Symbol.toStringTag]: any; @x ["property2"]: any = 2; @x [Symbol.iterator]: any = null; ["property3"]: any; [Symbol.isConcatSpreadable]: any; ["property4"]: any = 2; [Symbol.match]: any = null; [foo()]: any; @x [foo()]: any; @x [foo()]: any = null; ["some" + "method"]() {} [fieldNameA]: any; @x [fieldNameB]: any; @x [fieldNameC]: any = null;} : typeof F +>F : typeof F + + @x ["property"]: any; +>x : (o: object, k: PropertyKey) => void +>"property" : "property" + + @x [Symbol.toStringTag]: any; +>x : (o: object, k: PropertyKey) => void +>Symbol.toStringTag : symbol +>Symbol : SymbolConstructor +>toStringTag : symbol + + @x ["property2"]: any = 2; +>x : (o: object, k: PropertyKey) => void +>"property2" : "property2" +>2 : 2 + + @x [Symbol.iterator]: any = null; +>x : (o: object, k: PropertyKey) => void +>Symbol.iterator : symbol +>Symbol : SymbolConstructor +>iterator : symbol +>null : null + + ["property3"]: any; +>"property3" : "property3" + + [Symbol.isConcatSpreadable]: any; +>Symbol.isConcatSpreadable : symbol +>Symbol : SymbolConstructor +>isConcatSpreadable : symbol + + ["property4"]: any = 2; +>"property4" : "property4" +>2 : 2 + + [Symbol.match]: any = null; +>Symbol.match : symbol +>Symbol : SymbolConstructor +>match : symbol +>null : null + + [foo()]: any; +>foo() : string +>foo : () => string + + @x [foo()]: any; +>x : (o: object, k: PropertyKey) => void +>foo() : string +>foo : () => string + + @x [foo()]: any = null; +>x : (o: object, k: PropertyKey) => void +>foo() : string +>foo : () => string +>null : null + + ["some" + "method"]() {} +>"some" + "method" : string +>"some" : "some" +>"method" : "method" + + [fieldNameA]: any; +>fieldNameA : string + + @x [fieldNameB]: any; +>x : (o: object, k: PropertyKey) => void +>fieldNameB : string + + @x [fieldNameC]: any = null; +>x : (o: object, k: PropertyKey) => void +>fieldNameC : string +>null : null + +}; + +class G { +>G : G + + @x ["property"]: any; +>x : (o: object, k: PropertyKey) => void +>"property" : "property" + + @x [Symbol.toStringTag]: any; +>x : (o: object, k: PropertyKey) => void +>Symbol.toStringTag : symbol +>Symbol : SymbolConstructor +>toStringTag : symbol + + @x ["property2"]: any = 2; +>x : (o: object, k: PropertyKey) => void +>"property2" : "property2" +>2 : 2 + + @x [Symbol.iterator]: any = null; +>x : (o: object, k: PropertyKey) => void +>Symbol.iterator : symbol +>Symbol : SymbolConstructor +>iterator : symbol +>null : null + + ["property3"]: any; +>"property3" : "property3" + + [Symbol.isConcatSpreadable]: any; +>Symbol.isConcatSpreadable : symbol +>Symbol : SymbolConstructor +>isConcatSpreadable : symbol + + ["property4"]: any = 2; +>"property4" : "property4" +>2 : 2 + + [Symbol.match]: any = null; +>Symbol.match : symbol +>Symbol : SymbolConstructor +>match : symbol +>null : null + + [foo()]: any; +>foo() : string +>foo : () => string + + @x [foo()]: any; +>x : (o: object, k: PropertyKey) => void +>foo() : string +>foo : () => string + + @x [foo()]: any = null; +>x : (o: object, k: PropertyKey) => void +>foo() : string +>foo : () => string +>null : null + + ["some" + "method"]() {} +>"some" + "method" : string +>"some" : "some" +>"method" : "method" + + [fieldNameA]: any; +>fieldNameA : string + + @x [fieldNameB]: any; +>x : (o: object, k: PropertyKey) => void +>fieldNameB : string + + ["some" + "method2"]() {} +>"some" + "method2" : string +>"some" : "some" +>"method2" : "method2" + + @x [fieldNameC]: any = null; +>x : (o: object, k: PropertyKey) => void +>fieldNameC : string +>null : null +} + +void class H { +>void class H { @x ["property"]: any; @x [Symbol.toStringTag]: any; @x ["property2"]: any = 2; @x [Symbol.iterator]: any = null; ["property3"]: any; [Symbol.isConcatSpreadable]: any; ["property4"]: any = 2; [Symbol.match]: any = null; [foo()]: any; @x [foo()]: any; @x [foo()]: any = null; ["some" + "method"]() {} [fieldNameA]: any; @x [fieldNameB]: any; ["some" + "method2"]() {} @x [fieldNameC]: any = null;} : undefined +>class H { @x ["property"]: any; @x [Symbol.toStringTag]: any; @x ["property2"]: any = 2; @x [Symbol.iterator]: any = null; ["property3"]: any; [Symbol.isConcatSpreadable]: any; ["property4"]: any = 2; [Symbol.match]: any = null; [foo()]: any; @x [foo()]: any; @x [foo()]: any = null; ["some" + "method"]() {} [fieldNameA]: any; @x [fieldNameB]: any; ["some" + "method2"]() {} @x [fieldNameC]: any = null;} : typeof H +>H : typeof H + + @x ["property"]: any; +>x : (o: object, k: PropertyKey) => void +>"property" : "property" + + @x [Symbol.toStringTag]: any; +>x : (o: object, k: PropertyKey) => void +>Symbol.toStringTag : symbol +>Symbol : SymbolConstructor +>toStringTag : symbol + + @x ["property2"]: any = 2; +>x : (o: object, k: PropertyKey) => void +>"property2" : "property2" +>2 : 2 + + @x [Symbol.iterator]: any = null; +>x : (o: object, k: PropertyKey) => void +>Symbol.iterator : symbol +>Symbol : SymbolConstructor +>iterator : symbol +>null : null + + ["property3"]: any; +>"property3" : "property3" + + [Symbol.isConcatSpreadable]: any; +>Symbol.isConcatSpreadable : symbol +>Symbol : SymbolConstructor +>isConcatSpreadable : symbol + + ["property4"]: any = 2; +>"property4" : "property4" +>2 : 2 + + [Symbol.match]: any = null; +>Symbol.match : symbol +>Symbol : SymbolConstructor +>match : symbol +>null : null + + [foo()]: any; +>foo() : string +>foo : () => string + + @x [foo()]: any; +>x : (o: object, k: PropertyKey) => void +>foo() : string +>foo : () => string + + @x [foo()]: any = null; +>x : (o: object, k: PropertyKey) => void +>foo() : string +>foo : () => string +>null : null + + ["some" + "method"]() {} +>"some" + "method" : string +>"some" : "some" +>"method" : "method" + + [fieldNameA]: any; +>fieldNameA : string + + @x [fieldNameB]: any; +>x : (o: object, k: PropertyKey) => void +>fieldNameB : string + + ["some" + "method2"]() {} +>"some" + "method2" : string +>"some" : "some" +>"method2" : "method2" + + @x [fieldNameC]: any = null; +>x : (o: object, k: PropertyKey) => void +>fieldNameC : string +>null : null + +}; + +class I { +>I : I + + @x ["property"]: any; +>x : (o: object, k: PropertyKey) => void +>"property" : "property" + + @x [Symbol.toStringTag]: any; +>x : (o: object, k: PropertyKey) => void +>Symbol.toStringTag : symbol +>Symbol : SymbolConstructor +>toStringTag : symbol + + @x ["property2"]: any = 2; +>x : (o: object, k: PropertyKey) => void +>"property2" : "property2" +>2 : 2 + + @x [Symbol.iterator]: any = null; +>x : (o: object, k: PropertyKey) => void +>Symbol.iterator : symbol +>Symbol : SymbolConstructor +>iterator : symbol +>null : null + + ["property3"]: any; +>"property3" : "property3" + + [Symbol.isConcatSpreadable]: any; +>Symbol.isConcatSpreadable : symbol +>Symbol : SymbolConstructor +>isConcatSpreadable : symbol + + ["property4"]: any = 2; +>"property4" : "property4" +>2 : 2 + + [Symbol.match]: any = null; +>Symbol.match : symbol +>Symbol : SymbolConstructor +>match : symbol +>null : null + + [foo()]: any; +>foo() : string +>foo : () => string + + @x [foo()]: any; +>x : (o: object, k: PropertyKey) => void +>foo() : string +>foo : () => string + + @x [foo()]: any = null; +>x : (o: object, k: PropertyKey) => void +>foo() : string +>foo : () => string +>null : null + + @x ["some" + "method"]() {} +>x : (o: object, k: PropertyKey) => void +>"some" + "method" : string +>"some" : "some" +>"method" : "method" + + [fieldNameA]: any; +>fieldNameA : string + + @x [fieldNameB]: any; +>x : (o: object, k: PropertyKey) => void +>fieldNameB : string + + ["some" + "method2"]() {} +>"some" + "method2" : string +>"some" : "some" +>"method2" : "method2" + + @x [fieldNameC]: any = null; +>x : (o: object, k: PropertyKey) => void +>fieldNameC : string +>null : null +} + +void class J { +>void class J { @x ["property"]: any; @x [Symbol.toStringTag]: any; @x ["property2"]: any = 2; @x [Symbol.iterator]: any = null; ["property3"]: any; [Symbol.isConcatSpreadable]: any; ["property4"]: any = 2; [Symbol.match]: any = null; [foo()]: any; @x [foo()]: any; @x [foo()]: any = null; @x ["some" + "method"]() {} [fieldNameA]: any; @x [fieldNameB]: any; ["some" + "method2"]() {} @x [fieldNameC]: any = null;} : undefined +>class J { @x ["property"]: any; @x [Symbol.toStringTag]: any; @x ["property2"]: any = 2; @x [Symbol.iterator]: any = null; ["property3"]: any; [Symbol.isConcatSpreadable]: any; ["property4"]: any = 2; [Symbol.match]: any = null; [foo()]: any; @x [foo()]: any; @x [foo()]: any = null; @x ["some" + "method"]() {} [fieldNameA]: any; @x [fieldNameB]: any; ["some" + "method2"]() {} @x [fieldNameC]: any = null;} : typeof J +>J : typeof J + + @x ["property"]: any; +>x : (o: object, k: PropertyKey) => void +>"property" : "property" + + @x [Symbol.toStringTag]: any; +>x : (o: object, k: PropertyKey) => void +>Symbol.toStringTag : symbol +>Symbol : SymbolConstructor +>toStringTag : symbol + + @x ["property2"]: any = 2; +>x : (o: object, k: PropertyKey) => void +>"property2" : "property2" +>2 : 2 + + @x [Symbol.iterator]: any = null; +>x : (o: object, k: PropertyKey) => void +>Symbol.iterator : symbol +>Symbol : SymbolConstructor +>iterator : symbol +>null : null + + ["property3"]: any; +>"property3" : "property3" + + [Symbol.isConcatSpreadable]: any; +>Symbol.isConcatSpreadable : symbol +>Symbol : SymbolConstructor +>isConcatSpreadable : symbol + + ["property4"]: any = 2; +>"property4" : "property4" +>2 : 2 + + [Symbol.match]: any = null; +>Symbol.match : symbol +>Symbol : SymbolConstructor +>match : symbol +>null : null + + [foo()]: any; +>foo() : string +>foo : () => string + + @x [foo()]: any; +>x : (o: object, k: PropertyKey) => void +>foo() : string +>foo : () => string + + @x [foo()]: any = null; +>x : (o: object, k: PropertyKey) => void +>foo() : string +>foo : () => string +>null : null + + @x ["some" + "method"]() {} +>x : (o: object, k: PropertyKey) => void +>"some" + "method" : string +>"some" : "some" +>"method" : "method" + + [fieldNameA]: any; +>fieldNameA : string + + @x [fieldNameB]: any; +>x : (o: object, k: PropertyKey) => void +>fieldNameB : string + + ["some" + "method2"]() {} +>"some" + "method2" : string +>"some" : "some" +>"method2" : "method2" + + @x [fieldNameC]: any = null; +>x : (o: object, k: PropertyKey) => void +>fieldNameC : string +>null : null + +}; diff --git a/tests/baselines/reference/newTarget.es5.js b/tests/baselines/reference/newTarget.es5.js index 61b3f73a9b4..0ee9a7e339e 100644 --- a/tests/baselines/reference/newTarget.es5.js +++ b/tests/baselines/reference/newTarget.es5.js @@ -69,11 +69,11 @@ function f1() { var g = _newTarget; var h = function () { return _newTarget; }; } -var f2 = function _a() { - var _newTarget = this && this instanceof _a ? this.constructor : void 0; +var f2 = function _b() { + var _newTarget = this && this instanceof _b ? this.constructor : void 0; var i = _newTarget; var j = function () { return _newTarget; }; }; var O = { - k: function _b() { var _newTarget = this && this instanceof _b ? this.constructor : void 0; return _newTarget; } + k: function _c() { var _newTarget = this && this instanceof _c ? this.constructor : void 0; return _newTarget; } }; diff --git a/tests/baselines/reference/parserComputedPropertyName10.js b/tests/baselines/reference/parserComputedPropertyName10.js index eba480ba810..b6efaf3f5a7 100644 --- a/tests/baselines/reference/parserComputedPropertyName10.js +++ b/tests/baselines/reference/parserComputedPropertyName10.js @@ -6,6 +6,8 @@ class C { //// [parserComputedPropertyName10.js] class C { constructor() { - this[e] = 1; + this[_a] = 1; } } +_a = e; +var _a; diff --git a/tests/baselines/reference/parserComputedPropertyName25.js b/tests/baselines/reference/parserComputedPropertyName25.js index 47670fe14b8..f914d7de8ee 100644 --- a/tests/baselines/reference/parserComputedPropertyName25.js +++ b/tests/baselines/reference/parserComputedPropertyName25.js @@ -9,6 +9,8 @@ class C { class C { constructor() { // No ASI - this[e] = 0[e2] = 1; + this[_a] = 0[e2] = 1; } } +_a = e; +var _a; diff --git a/tests/baselines/reference/parserComputedPropertyName27.js b/tests/baselines/reference/parserComputedPropertyName27.js index f872e95e7e6..7f60ec97b5e 100644 --- a/tests/baselines/reference/parserComputedPropertyName27.js +++ b/tests/baselines/reference/parserComputedPropertyName27.js @@ -9,6 +9,8 @@ class C { class C { constructor() { // No ASI - this[e] = 0[e2]; + this[_a] = 0[e2]; } } +_a = e; +var _a; diff --git a/tests/baselines/reference/parserComputedPropertyName28.js b/tests/baselines/reference/parserComputedPropertyName28.js index 998f60db914..d01ed38069f 100644 --- a/tests/baselines/reference/parserComputedPropertyName28.js +++ b/tests/baselines/reference/parserComputedPropertyName28.js @@ -7,6 +7,8 @@ class C { //// [parserComputedPropertyName28.js] class C { constructor() { - this[e] = 0; + this[_a] = 0; } } +_a = e; +var _a; diff --git a/tests/baselines/reference/parserComputedPropertyName29.js b/tests/baselines/reference/parserComputedPropertyName29.js index a100cbf1791..d5a00df2256 100644 --- a/tests/baselines/reference/parserComputedPropertyName29.js +++ b/tests/baselines/reference/parserComputedPropertyName29.js @@ -9,6 +9,8 @@ class C { class C { constructor() { // yes ASI - this[e] = id++; + this[_a] = id++; } } +_a = e; +var _a; diff --git a/tests/baselines/reference/parserComputedPropertyName33.js b/tests/baselines/reference/parserComputedPropertyName33.js index ab80967c21a..84520a8eb51 100644 --- a/tests/baselines/reference/parserComputedPropertyName33.js +++ b/tests/baselines/reference/parserComputedPropertyName33.js @@ -9,7 +9,9 @@ class C { class C { constructor() { // No ASI - this[e] = 0[e2](); + this[_a] = 0[e2](); } } +_a = e; { } +var _a; diff --git a/tests/baselines/reference/parserES5ComputedPropertyName10.js b/tests/baselines/reference/parserES5ComputedPropertyName10.js index 78f819af375..72902c30db9 100644 --- a/tests/baselines/reference/parserES5ComputedPropertyName10.js +++ b/tests/baselines/reference/parserES5ComputedPropertyName10.js @@ -6,7 +6,9 @@ class C { //// [parserES5ComputedPropertyName10.js] var C = /** @class */ (function () { function C() { - this[e] = 1; + this[_a] = 1; } return C; }()); +_a = e; +var _a; diff --git a/tests/baselines/reference/symbolProperty7.js b/tests/baselines/reference/symbolProperty7.js index 51f3511f332..9dbe5a1abb1 100644 --- a/tests/baselines/reference/symbolProperty7.js +++ b/tests/baselines/reference/symbolProperty7.js @@ -11,10 +11,11 @@ class C { //// [symbolProperty7.js] class C { constructor() { - this[Symbol()] = 0; + this[_a] = 0; } - [Symbol()]() { } + [_a = Symbol(), Symbol(), Symbol()]() { } get [Symbol()]() { return 0; } } +var _a; diff --git a/tests/cases/compiler/decoratorsOnComputedProperties.ts b/tests/cases/compiler/decoratorsOnComputedProperties.ts new file mode 100644 index 00000000000..cb9cfe5f997 --- /dev/null +++ b/tests/cases/compiler/decoratorsOnComputedProperties.ts @@ -0,0 +1,191 @@ +// @target: es6 +// @experimentalDecorators: true +function x(o: object, k: PropertyKey) { } +let i = 0; +function foo(): string { return ++i + ""; } + +const fieldNameA: string = "fieldName1"; +const fieldNameB: string = "fieldName2"; +const fieldNameC: string = "fieldName3"; + +class A { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + @x [foo()]: any; + @x [foo()]: any = null; + [fieldNameA]: any; + @x [fieldNameB]: any; + @x [fieldNameC]: any = null; +} + +void class B { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + @x [foo()]: any; + @x [foo()]: any = null; + [fieldNameA]: any; + @x [fieldNameB]: any; + @x [fieldNameC]: any = null; +}; + +class C { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + @x [foo()]: any; + @x [foo()]: any = null; + [fieldNameA]: any; + @x [fieldNameB]: any; + @x [fieldNameC]: any = null; + ["some" + "method"]() {} +} + +void class D { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + @x [foo()]: any; + @x [foo()]: any = null; + [fieldNameA]: any; + @x [fieldNameB]: any; + @x [fieldNameC]: any = null; + ["some" + "method"]() {} +}; + +class E { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + @x [foo()]: any; + @x [foo()]: any = null; + ["some" + "method"]() {} + [fieldNameA]: any; + @x [fieldNameB]: any; + @x [fieldNameC]: any = null; +} + +void class F { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + @x [foo()]: any; + @x [foo()]: any = null; + ["some" + "method"]() {} + [fieldNameA]: any; + @x [fieldNameB]: any; + @x [fieldNameC]: any = null; +}; + +class G { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + @x [foo()]: any; + @x [foo()]: any = null; + ["some" + "method"]() {} + [fieldNameA]: any; + @x [fieldNameB]: any; + ["some" + "method2"]() {} + @x [fieldNameC]: any = null; +} + +void class H { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + @x [foo()]: any; + @x [foo()]: any = null; + ["some" + "method"]() {} + [fieldNameA]: any; + @x [fieldNameB]: any; + ["some" + "method2"]() {} + @x [fieldNameC]: any = null; +}; + +class I { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + @x [foo()]: any; + @x [foo()]: any = null; + @x ["some" + "method"]() {} + [fieldNameA]: any; + @x [fieldNameB]: any; + ["some" + "method2"]() {} + @x [fieldNameC]: any = null; +} + +void class J { + @x ["property"]: any; + @x [Symbol.toStringTag]: any; + @x ["property2"]: any = 2; + @x [Symbol.iterator]: any = null; + ["property3"]: any; + [Symbol.isConcatSpreadable]: any; + ["property4"]: any = 2; + [Symbol.match]: any = null; + [foo()]: any; + @x [foo()]: any; + @x [foo()]: any = null; + @x ["some" + "method"]() {} + [fieldNameA]: any; + @x [fieldNameB]: any; + ["some" + "method2"]() {} + @x [fieldNameC]: any = null; +}; \ No newline at end of file From 0593ba27d8ccc8fac551aade40985f086d264954 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 6 Nov 2017 12:52:33 -0800 Subject: [PATCH 137/235] Make getContextualTypeOfApparentType mapType over unions (#17668) * Instantiate contextual types while in an inferrential context * Limit scope of instantiation to only when likely needed * Still get aparent type * Expand test * Fix nit * Handle JSX and array * Tests for the JSX and Array cases * After much deliberation and inspection, much simpler fix After much deliberation and inspection, much simpler fix Undo Redo --- src/compiler/checker.ts | 2 +- ...ntextualTypingOfOptionalMembers.errors.txt | 80 ++++++ .../contextualTypingOfOptionalMembers.js | 103 +++++++ .../contextualTypingOfOptionalMembers.symbols | 235 ++++++++++++++++ .../contextualTypingOfOptionalMembers.types | 261 ++++++++++++++++++ .../contextualTypingOfOptionalMembers.tsx | 77 ++++++ 6 files changed, 757 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/contextualTypingOfOptionalMembers.errors.txt create mode 100644 tests/baselines/reference/contextualTypingOfOptionalMembers.js create mode 100644 tests/baselines/reference/contextualTypingOfOptionalMembers.symbols create mode 100644 tests/baselines/reference/contextualTypingOfOptionalMembers.types create mode 100644 tests/cases/compiler/contextualTypingOfOptionalMembers.tsx diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index eb5442a7996..39b0dc18569 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13691,7 +13691,7 @@ namespace ts { // be "pushed" onto a node using the contextualType property. function getApparentTypeOfContextualType(node: Expression): Type { const type = getContextualType(node); - return type && getApparentType(type); + return type && mapType(type, getApparentType); } /** diff --git a/tests/baselines/reference/contextualTypingOfOptionalMembers.errors.txt b/tests/baselines/reference/contextualTypingOfOptionalMembers.errors.txt new file mode 100644 index 00000000000..02c94400e21 --- /dev/null +++ b/tests/baselines/reference/contextualTypingOfOptionalMembers.errors.txt @@ -0,0 +1,80 @@ +tests/cases/compiler/index.tsx(73,34): error TS7006: Parameter 's' implicitly has an 'any' type. + + +==== tests/cases/compiler/index.tsx (1 errors) ==== + interface ActionsObject { + [prop: string]: (state: State) => State; + } + + interface Options { + state?: State; + view?: (state: State, actions: Actions) => any; + actions: string | Actions; + } + + declare function app>(obj: Options): void; + + app({ + state: 100, + actions: { + foo: s => s // Should be typed number => number + }, + view: (s, a) => undefined as any, + }); + + + interface Bar { + bar: (a: number) => void; + } + + declare function foo(x: string | T): T; + + const y = foo({ + bar(x) { // Should be typed number => void + } + }); + + interface Options2 { + state?: State; + view?: (state: State, actions: Actions) => any; + actions?: Actions; + } + + declare function app2>(obj: Options2): void; + + app2({ + state: 100, + actions: { + foo: s => s // Should be typed number => number + }, + view: (s, a) => undefined as any, + }); + + + type ActionsArray = ((state: State) => State)[]; + + declare function app3>(obj: Options): void; + + app3({ + state: 100, + actions: [ + s => s // Should be typed number => number + ], + view: (s, a) => undefined as any, + }); + + namespace JSX { + export interface Element {} + export interface IntrinsicElements {} + } + + interface ActionsObjectOr { + [prop: string]: ((state: State) => State) | State; + } + + declare function App4>(props: Options["actions"] & { state: State }): JSX.Element; + + const a = s} />; // TODO: should be number => number, but JSX resolution is missing an inferential pass + ~ +!!! error TS7006: Parameter 's' implicitly has an 'any' type. + \ No newline at end of file diff --git a/tests/baselines/reference/contextualTypingOfOptionalMembers.js b/tests/baselines/reference/contextualTypingOfOptionalMembers.js new file mode 100644 index 00000000000..289d64546e8 --- /dev/null +++ b/tests/baselines/reference/contextualTypingOfOptionalMembers.js @@ -0,0 +1,103 @@ +//// [index.tsx] +interface ActionsObject { + [prop: string]: (state: State) => State; +} + +interface Options { + state?: State; + view?: (state: State, actions: Actions) => any; + actions: string | Actions; +} + +declare function app>(obj: Options): void; + +app({ + state: 100, + actions: { + foo: s => s // Should be typed number => number + }, + view: (s, a) => undefined as any, +}); + + +interface Bar { + bar: (a: number) => void; +} + +declare function foo(x: string | T): T; + +const y = foo({ + bar(x) { // Should be typed number => void + } +}); + +interface Options2 { + state?: State; + view?: (state: State, actions: Actions) => any; + actions?: Actions; +} + +declare function app2>(obj: Options2): void; + +app2({ + state: 100, + actions: { + foo: s => s // Should be typed number => number + }, + view: (s, a) => undefined as any, +}); + + +type ActionsArray = ((state: State) => State)[]; + +declare function app3>(obj: Options): void; + +app3({ + state: 100, + actions: [ + s => s // Should be typed number => number + ], + view: (s, a) => undefined as any, +}); + +namespace JSX { + export interface Element {} + export interface IntrinsicElements {} +} + +interface ActionsObjectOr { + [prop: string]: ((state: State) => State) | State; +} + +declare function App4>(props: Options["actions"] & { state: State }): JSX.Element; + +const a = s} />; // TODO: should be number => number, but JSX resolution is missing an inferential pass + + +//// [index.jsx] +app({ + state: 100, + actions: { + foo: function (s) { return s; } // Should be typed number => number + }, + view: function (s, a) { return undefined; } +}); +var y = foo({ + bar: function (x) { + } +}); +app2({ + state: 100, + actions: { + foo: function (s) { return s; } // Should be typed number => number + }, + view: function (s, a) { return undefined; } +}); +app3({ + state: 100, + actions: [ + function (s) { return s; } // Should be typed number => number + ], + view: function (s, a) { return undefined; } +}); +var a = ; // TODO: should be number => number, but JSX resolution is missing an inferential pass diff --git a/tests/baselines/reference/contextualTypingOfOptionalMembers.symbols b/tests/baselines/reference/contextualTypingOfOptionalMembers.symbols new file mode 100644 index 00000000000..14d8ef41b3a --- /dev/null +++ b/tests/baselines/reference/contextualTypingOfOptionalMembers.symbols @@ -0,0 +1,235 @@ +=== tests/cases/compiler/index.tsx === +interface ActionsObject { +>ActionsObject : Symbol(ActionsObject, Decl(index.tsx, 0, 0)) +>State : Symbol(State, Decl(index.tsx, 0, 24)) + + [prop: string]: (state: State) => State; +>prop : Symbol(prop, Decl(index.tsx, 1, 5)) +>state : Symbol(state, Decl(index.tsx, 1, 21)) +>State : Symbol(State, Decl(index.tsx, 0, 24)) +>State : Symbol(State, Decl(index.tsx, 0, 24)) +} + +interface Options { +>Options : Symbol(Options, Decl(index.tsx, 2, 1)) +>State : Symbol(State, Decl(index.tsx, 4, 18)) +>Actions : Symbol(Actions, Decl(index.tsx, 4, 24)) + + state?: State; +>state : Symbol(Options.state, Decl(index.tsx, 4, 35)) +>State : Symbol(State, Decl(index.tsx, 4, 18)) + + view?: (state: State, actions: Actions) => any; +>view : Symbol(Options.view, Decl(index.tsx, 5, 18)) +>state : Symbol(state, Decl(index.tsx, 6, 12)) +>State : Symbol(State, Decl(index.tsx, 4, 18)) +>actions : Symbol(actions, Decl(index.tsx, 6, 25)) +>Actions : Symbol(Actions, Decl(index.tsx, 4, 24)) + + actions: string | Actions; +>actions : Symbol(Options.actions, Decl(index.tsx, 6, 51)) +>Actions : Symbol(Actions, Decl(index.tsx, 4, 24)) +} + +declare function app>(obj: Options): void; +>app : Symbol(app, Decl(index.tsx, 8, 1)) +>State : Symbol(State, Decl(index.tsx, 10, 21)) +>Actions : Symbol(Actions, Decl(index.tsx, 10, 27)) +>ActionsObject : Symbol(ActionsObject, Decl(index.tsx, 0, 0)) +>State : Symbol(State, Decl(index.tsx, 10, 21)) +>obj : Symbol(obj, Decl(index.tsx, 10, 66)) +>Options : Symbol(Options, Decl(index.tsx, 2, 1)) +>State : Symbol(State, Decl(index.tsx, 10, 21)) +>Actions : Symbol(Actions, Decl(index.tsx, 10, 27)) + +app({ +>app : Symbol(app, Decl(index.tsx, 8, 1)) + + state: 100, +>state : Symbol(state, Decl(index.tsx, 12, 5)) + + actions: { +>actions : Symbol(actions, Decl(index.tsx, 13, 15)) + + foo: s => s // Should be typed number => number +>foo : Symbol(foo, Decl(index.tsx, 14, 14)) +>s : Symbol(s, Decl(index.tsx, 15, 12)) +>s : Symbol(s, Decl(index.tsx, 15, 12)) + + }, + view: (s, a) => undefined as any, +>view : Symbol(view, Decl(index.tsx, 16, 6)) +>s : Symbol(s, Decl(index.tsx, 17, 11)) +>a : Symbol(a, Decl(index.tsx, 17, 13)) +>undefined : Symbol(undefined) + +}); + + +interface Bar { +>Bar : Symbol(Bar, Decl(index.tsx, 18, 3)) + + bar: (a: number) => void; +>bar : Symbol(Bar.bar, Decl(index.tsx, 21, 15)) +>a : Symbol(a, Decl(index.tsx, 22, 10)) +} + +declare function foo(x: string | T): T; +>foo : Symbol(foo, Decl(index.tsx, 23, 1)) +>T : Symbol(T, Decl(index.tsx, 25, 21)) +>Bar : Symbol(Bar, Decl(index.tsx, 18, 3)) +>x : Symbol(x, Decl(index.tsx, 25, 36)) +>T : Symbol(T, Decl(index.tsx, 25, 21)) +>T : Symbol(T, Decl(index.tsx, 25, 21)) + +const y = foo({ +>y : Symbol(y, Decl(index.tsx, 27, 5)) +>foo : Symbol(foo, Decl(index.tsx, 23, 1)) + + bar(x) { // Should be typed number => void +>bar : Symbol(bar, Decl(index.tsx, 27, 15)) +>x : Symbol(x, Decl(index.tsx, 28, 8)) + } +}); + +interface Options2 { +>Options2 : Symbol(Options2, Decl(index.tsx, 30, 3)) +>State : Symbol(State, Decl(index.tsx, 32, 19)) +>Actions : Symbol(Actions, Decl(index.tsx, 32, 25)) + + state?: State; +>state : Symbol(Options2.state, Decl(index.tsx, 32, 36)) +>State : Symbol(State, Decl(index.tsx, 32, 19)) + + view?: (state: State, actions: Actions) => any; +>view : Symbol(Options2.view, Decl(index.tsx, 33, 18)) +>state : Symbol(state, Decl(index.tsx, 34, 12)) +>State : Symbol(State, Decl(index.tsx, 32, 19)) +>actions : Symbol(actions, Decl(index.tsx, 34, 25)) +>Actions : Symbol(Actions, Decl(index.tsx, 32, 25)) + + actions?: Actions; +>actions : Symbol(Options2.actions, Decl(index.tsx, 34, 51)) +>Actions : Symbol(Actions, Decl(index.tsx, 32, 25)) +} + +declare function app2>(obj: Options2): void; +>app2 : Symbol(app2, Decl(index.tsx, 36, 1)) +>State : Symbol(State, Decl(index.tsx, 38, 22)) +>Actions : Symbol(Actions, Decl(index.tsx, 38, 28)) +>ActionsObject : Symbol(ActionsObject, Decl(index.tsx, 0, 0)) +>State : Symbol(State, Decl(index.tsx, 38, 22)) +>obj : Symbol(obj, Decl(index.tsx, 38, 67)) +>Options2 : Symbol(Options2, Decl(index.tsx, 30, 3)) +>State : Symbol(State, Decl(index.tsx, 38, 22)) +>Actions : Symbol(Actions, Decl(index.tsx, 38, 28)) + +app2({ +>app2 : Symbol(app2, Decl(index.tsx, 36, 1)) + + state: 100, +>state : Symbol(state, Decl(index.tsx, 40, 6)) + + actions: { +>actions : Symbol(actions, Decl(index.tsx, 41, 15)) + + foo: s => s // Should be typed number => number +>foo : Symbol(foo, Decl(index.tsx, 42, 14)) +>s : Symbol(s, Decl(index.tsx, 43, 12)) +>s : Symbol(s, Decl(index.tsx, 43, 12)) + + }, + view: (s, a) => undefined as any, +>view : Symbol(view, Decl(index.tsx, 44, 6)) +>s : Symbol(s, Decl(index.tsx, 45, 11)) +>a : Symbol(a, Decl(index.tsx, 45, 13)) +>undefined : Symbol(undefined) + +}); + + +type ActionsArray = ((state: State) => State)[]; +>ActionsArray : Symbol(ActionsArray, Decl(index.tsx, 46, 3)) +>State : Symbol(State, Decl(index.tsx, 49, 18)) +>state : Symbol(state, Decl(index.tsx, 49, 29)) +>State : Symbol(State, Decl(index.tsx, 49, 18)) +>State : Symbol(State, Decl(index.tsx, 49, 18)) + +declare function app3>(obj: Options): void; +>app3 : Symbol(app3, Decl(index.tsx, 49, 55)) +>State : Symbol(State, Decl(index.tsx, 51, 22)) +>Actions : Symbol(Actions, Decl(index.tsx, 51, 28)) +>ActionsArray : Symbol(ActionsArray, Decl(index.tsx, 46, 3)) +>State : Symbol(State, Decl(index.tsx, 51, 22)) +>obj : Symbol(obj, Decl(index.tsx, 51, 66)) +>Options : Symbol(Options, Decl(index.tsx, 2, 1)) +>State : Symbol(State, Decl(index.tsx, 51, 22)) +>Actions : Symbol(Actions, Decl(index.tsx, 51, 28)) + +app3({ +>app3 : Symbol(app3, Decl(index.tsx, 49, 55)) + + state: 100, +>state : Symbol(state, Decl(index.tsx, 53, 6)) + + actions: [ +>actions : Symbol(actions, Decl(index.tsx, 54, 15)) + + s => s // Should be typed number => number +>s : Symbol(s, Decl(index.tsx, 55, 14)) +>s : Symbol(s, Decl(index.tsx, 55, 14)) + + ], + view: (s, a) => undefined as any, +>view : Symbol(view, Decl(index.tsx, 57, 6)) +>s : Symbol(s, Decl(index.tsx, 58, 11)) +>a : Symbol(a, Decl(index.tsx, 58, 13)) +>undefined : Symbol(undefined) + +}); + +namespace JSX { +>JSX : Symbol(JSX, Decl(index.tsx, 59, 3)) + + export interface Element {} +>Element : Symbol(Element, Decl(index.tsx, 61, 15)) + + export interface IntrinsicElements {} +>IntrinsicElements : Symbol(IntrinsicElements, Decl(index.tsx, 62, 31)) +} + +interface ActionsObjectOr { +>ActionsObjectOr : Symbol(ActionsObjectOr, Decl(index.tsx, 64, 1)) +>State : Symbol(State, Decl(index.tsx, 66, 26)) + + [prop: string]: ((state: State) => State) | State; +>prop : Symbol(prop, Decl(index.tsx, 67, 5)) +>state : Symbol(state, Decl(index.tsx, 67, 22)) +>State : Symbol(State, Decl(index.tsx, 66, 26)) +>State : Symbol(State, Decl(index.tsx, 66, 26)) +>State : Symbol(State, Decl(index.tsx, 66, 26)) +} + +declare function App4>(props: Options["actions"] & { state: State }): JSX.Element; +>App4 : Symbol(App4, Decl(index.tsx, 68, 1)) +>State : Symbol(State, Decl(index.tsx, 70, 22)) +>Actions : Symbol(Actions, Decl(index.tsx, 70, 28)) +>ActionsObjectOr : Symbol(ActionsObjectOr, Decl(index.tsx, 64, 1)) +>State : Symbol(State, Decl(index.tsx, 70, 22)) +>props : Symbol(props, Decl(index.tsx, 70, 69)) +>Options : Symbol(Options, Decl(index.tsx, 2, 1)) +>State : Symbol(State, Decl(index.tsx, 70, 22)) +>Actions : Symbol(Actions, Decl(index.tsx, 70, 28)) +>state : Symbol(state, Decl(index.tsx, 70, 114)) +>State : Symbol(State, Decl(index.tsx, 70, 22)) +>JSX : Symbol(JSX, Decl(index.tsx, 59, 3)) +>Element : Symbol(JSX.Element, Decl(index.tsx, 61, 15)) + +const a = s} />; // TODO: should be number => number, but JSX resolution is missing an inferential pass +>a : Symbol(a, Decl(index.tsx, 72, 5)) +>App4 : Symbol(App4, Decl(index.tsx, 68, 1)) +>state : Symbol(state, Decl(index.tsx, 72, 15)) +>foo : Symbol(foo, Decl(index.tsx, 72, 27)) +>s : Symbol(s, Decl(index.tsx, 72, 33)) +>s : Symbol(s, Decl(index.tsx, 72, 33)) + diff --git a/tests/baselines/reference/contextualTypingOfOptionalMembers.types b/tests/baselines/reference/contextualTypingOfOptionalMembers.types new file mode 100644 index 00000000000..515685f5c53 --- /dev/null +++ b/tests/baselines/reference/contextualTypingOfOptionalMembers.types @@ -0,0 +1,261 @@ +=== tests/cases/compiler/index.tsx === +interface ActionsObject { +>ActionsObject : ActionsObject +>State : State + + [prop: string]: (state: State) => State; +>prop : string +>state : State +>State : State +>State : State +} + +interface Options { +>Options : Options +>State : State +>Actions : Actions + + state?: State; +>state : State | undefined +>State : State + + view?: (state: State, actions: Actions) => any; +>view : ((state: State, actions: Actions) => any) | undefined +>state : State +>State : State +>actions : Actions +>Actions : Actions + + actions: string | Actions; +>actions : string | Actions +>Actions : Actions +} + +declare function app>(obj: Options): void; +>app : >(obj: Options) => void +>State : State +>Actions : Actions +>ActionsObject : ActionsObject +>State : State +>obj : Options +>Options : Options +>State : State +>Actions : Actions + +app({ +>app({ state: 100, actions: { foo: s => s // Should be typed number => number }, view: (s, a) => undefined as any,}) : void +>app : >(obj: Options) => void +>{ state: 100, actions: { foo: s => s // Should be typed number => number }, view: (s, a) => undefined as any,} : { state: number; actions: { foo: (s: number) => number; }; view: (s: number, a: ActionsObject) => any; } + + state: 100, +>state : number +>100 : 100 + + actions: { +>actions : { foo: (s: number) => number; } +>{ foo: s => s // Should be typed number => number } : { foo: (s: number) => number; } + + foo: s => s // Should be typed number => number +>foo : (s: number) => number +>s => s : (s: number) => number +>s : number +>s : number + + }, + view: (s, a) => undefined as any, +>view : (s: number, a: ActionsObject) => any +>(s, a) => undefined as any : (s: number, a: ActionsObject) => any +>s : number +>a : ActionsObject +>undefined as any : any +>undefined : undefined + +}); + + +interface Bar { +>Bar : Bar + + bar: (a: number) => void; +>bar : (a: number) => void +>a : number +} + +declare function foo(x: string | T): T; +>foo : (x: string | T) => T +>T : T +>Bar : Bar +>x : string | T +>T : T +>T : T + +const y = foo({ +>y : { bar(x: number): void; } +>foo({ bar(x) { // Should be typed number => void }}) : { bar(x: number): void; } +>foo : (x: string | T) => T +>{ bar(x) { // Should be typed number => void }} : { bar(x: number): void; } + + bar(x) { // Should be typed number => void +>bar : (x: number) => void +>x : number + } +}); + +interface Options2 { +>Options2 : Options2 +>State : State +>Actions : Actions + + state?: State; +>state : State | undefined +>State : State + + view?: (state: State, actions: Actions) => any; +>view : ((state: State, actions: Actions) => any) | undefined +>state : State +>State : State +>actions : Actions +>Actions : Actions + + actions?: Actions; +>actions : Actions | undefined +>Actions : Actions +} + +declare function app2>(obj: Options2): void; +>app2 : >(obj: Options2) => void +>State : State +>Actions : Actions +>ActionsObject : ActionsObject +>State : State +>obj : Options2 +>Options2 : Options2 +>State : State +>Actions : Actions + +app2({ +>app2({ state: 100, actions: { foo: s => s // Should be typed number => number }, view: (s, a) => undefined as any,}) : void +>app2 : >(obj: Options2) => void +>{ state: 100, actions: { foo: s => s // Should be typed number => number }, view: (s, a) => undefined as any,} : { state: number; actions: { foo: (s: number) => number; }; view: (s: number, a: ActionsObject) => any; } + + state: 100, +>state : number +>100 : 100 + + actions: { +>actions : { foo: (s: number) => number; } +>{ foo: s => s // Should be typed number => number } : { foo: (s: number) => number; } + + foo: s => s // Should be typed number => number +>foo : (s: number) => number +>s => s : (s: number) => number +>s : number +>s : number + + }, + view: (s, a) => undefined as any, +>view : (s: number, a: ActionsObject) => any +>(s, a) => undefined as any : (s: number, a: ActionsObject) => any +>s : number +>a : ActionsObject +>undefined as any : any +>undefined : undefined + +}); + + +type ActionsArray = ((state: State) => State)[]; +>ActionsArray : ((state: State) => State)[] +>State : State +>state : State +>State : State +>State : State + +declare function app3>(obj: Options): void; +>app3 : State)[]>(obj: Options) => void +>State : State +>Actions : Actions +>ActionsArray : ((state: State) => State)[] +>State : State +>obj : Options +>Options : Options +>State : State +>Actions : Actions + +app3({ +>app3({ state: 100, actions: [ s => s // Should be typed number => number ], view: (s, a) => undefined as any,}) : void +>app3 : State)[]>(obj: Options) => void +>{ state: 100, actions: [ s => s // Should be typed number => number ], view: (s, a) => undefined as any,} : { state: number; actions: ((s: number) => number)[]; view: (s: number, a: ((state: number) => number)[]) => any; } + + state: 100, +>state : number +>100 : 100 + + actions: [ +>actions : ((s: number) => number)[] +>[ s => s // Should be typed number => number ] : ((s: number) => number)[] + + s => s // Should be typed number => number +>s => s : (s: number) => number +>s : number +>s : number + + ], + view: (s, a) => undefined as any, +>view : (s: number, a: ((state: number) => number)[]) => any +>(s, a) => undefined as any : (s: number, a: ((state: number) => number)[]) => any +>s : number +>a : ((state: number) => number)[] +>undefined as any : any +>undefined : undefined + +}); + +namespace JSX { +>JSX : any + + export interface Element {} +>Element : Element + + export interface IntrinsicElements {} +>IntrinsicElements : IntrinsicElements +} + +interface ActionsObjectOr { +>ActionsObjectOr : ActionsObjectOr +>State : State + + [prop: string]: ((state: State) => State) | State; +>prop : string +>state : State +>State : State +>State : State +>State : State +} + +declare function App4>(props: Options["actions"] & { state: State }): JSX.Element; +>App4 : >(props: (string & { state: State; }) | (Actions & { state: State; })) => JSX.Element +>State : State +>Actions : Actions +>ActionsObjectOr : ActionsObjectOr +>State : State +>props : (string & { state: State; }) | (Actions & { state: State; }) +>Options : Options +>State : State +>Actions : Actions +>state : State +>State : State +>JSX : any +>Element : JSX.Element + +const a = s} />; // TODO: should be number => number, but JSX resolution is missing an inferential pass +>a : JSX.Element +> s} /> : JSX.Element +>App4 : >(props: (string & { state: State; }) | (Actions & { state: State; })) => JSX.Element +>state : number +>100 : 100 +>foo : (s: any) => any +>s => s : (s: any) => any +>s : any +>s : any + diff --git a/tests/cases/compiler/contextualTypingOfOptionalMembers.tsx b/tests/cases/compiler/contextualTypingOfOptionalMembers.tsx new file mode 100644 index 00000000000..5e5a9c70c9b --- /dev/null +++ b/tests/cases/compiler/contextualTypingOfOptionalMembers.tsx @@ -0,0 +1,77 @@ +// @noImplicitAny: true +// @strictNullChecks: true +// @jsx: preserve +// @filename: index.tsx +interface ActionsObject { + [prop: string]: (state: State) => State; +} + +interface Options { + state?: State; + view?: (state: State, actions: Actions) => any; + actions: string | Actions; +} + +declare function app>(obj: Options): void; + +app({ + state: 100, + actions: { + foo: s => s // Should be typed number => number + }, + view: (s, a) => undefined as any, +}); + + +interface Bar { + bar: (a: number) => void; +} + +declare function foo(x: string | T): T; + +const y = foo({ + bar(x) { // Should be typed number => void + } +}); + +interface Options2 { + state?: State; + view?: (state: State, actions: Actions) => any; + actions?: Actions; +} + +declare function app2>(obj: Options2): void; + +app2({ + state: 100, + actions: { + foo: s => s // Should be typed number => number + }, + view: (s, a) => undefined as any, +}); + + +type ActionsArray = ((state: State) => State)[]; + +declare function app3>(obj: Options): void; + +app3({ + state: 100, + actions: [ + s => s // Should be typed number => number + ], + view: (s, a) => undefined as any, +}); + +namespace JSX { + export interface Element {} + export interface IntrinsicElements {} +} + +interface ActionsObjectOr { + [prop: string]: ((state: State) => State) | State; +} + +declare function App4>(props: Options["actions"] & { state: State }): JSX.Element; + +const a = s} />; // TODO: should be number => number, but JSX resolution is missing an inferential pass From 5b9905d5a41a55e49d2a8ca585dc936949ead71d Mon Sep 17 00:00:00 2001 From: Eugene Timokhov Date: Sat, 4 Nov 2017 11:08:00 +0300 Subject: [PATCH 138/235] Added empty constructors to TypedArrays from es2017 (#19680) --- Gulpfile.ts | 1 + Jakefile.js | 3 +- src/compiler/commandLineParser.ts | 1 + src/harness/unittests/commandLineParsing.ts | 6 +-- .../convertCompilerOptionsFromJson.ts | 8 ++-- src/lib/es2017.d.ts | 1 + src/lib/es2017.typedarrays.d.ts | 35 ++++++++++++++ tests/baselines/reference/useTypedArrays1.js | 22 +++++++++ .../reference/useTypedArrays1.symbols | 37 +++++++++++++++ .../baselines/reference/useTypedArrays1.types | 46 +++++++++++++++++++ .../conformance/es2017/useTypedArrays1.ts | 12 +++++ 11 files changed, 164 insertions(+), 8 deletions(-) create mode 100644 src/lib/es2017.typedarrays.d.ts create mode 100644 tests/baselines/reference/useTypedArrays1.js create mode 100644 tests/baselines/reference/useTypedArrays1.symbols create mode 100644 tests/baselines/reference/useTypedArrays1.types create mode 100644 tests/cases/conformance/es2017/useTypedArrays1.ts diff --git a/Gulpfile.ts b/Gulpfile.ts index fd353083433..a75882c5f46 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -138,6 +138,7 @@ const es2017LibrarySource = [ "es2017.sharedmemory.d.ts", "es2017.string.d.ts", "es2017.intl.d.ts", + "es2017.typedarrays.d.ts", ]; const es2017LibrarySourceMap = es2017LibrarySource.map(source => diff --git a/Jakefile.js b/Jakefile.js index 7f0915ad7e9..89fcb6500dd 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -197,7 +197,8 @@ var es2017LibrarySource = [ "es2017.object.d.ts", "es2017.sharedmemory.d.ts", "es2017.string.d.ts", - "es2017.intl.d.ts" + "es2017.intl.d.ts", + "es2017.typedarrays.d.ts", ]; var es2017LibrarySourceMap = es2017LibrarySource.map(function (source) { diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index b7003fbffd9..7ba9bd80843 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -141,6 +141,7 @@ namespace ts { "es2017.sharedmemory": "lib.es2017.sharedmemory.d.ts", "es2017.string": "lib.es2017.string.d.ts", "es2017.intl": "lib.es2017.intl.d.ts", + "es2017.typedarrays": "lib.es2017.typedarrays.d.ts", "esnext.asynciterable": "lib.esnext.asynciterable.d.ts", }), }, diff --git a/src/harness/unittests/commandLineParsing.ts b/src/harness/unittests/commandLineParsing.ts index 01a208aa330..18e867cb9ea 100644 --- a/src/harness/unittests/commandLineParsing.ts +++ b/src/harness/unittests/commandLineParsing.ts @@ -60,7 +60,7 @@ namespace ts { assertParseResult(["--lib", "es5,invalidOption", "0.ts"], { errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, @@ -263,7 +263,7 @@ namespace ts { assertParseResult(["--lib", "es5,", "es7", "0.ts"], { errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, @@ -283,7 +283,7 @@ namespace ts { assertParseResult(["--lib", "es5, ", "es7", "0.ts"], { errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, diff --git a/src/harness/unittests/convertCompilerOptionsFromJson.ts b/src/harness/unittests/convertCompilerOptionsFromJson.ts index 09659762288..cbbe41ceadf 100644 --- a/src/harness/unittests/convertCompilerOptionsFromJson.ts +++ b/src/harness/unittests/convertCompilerOptionsFromJson.ts @@ -266,7 +266,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -297,7 +297,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -328,7 +328,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -359,7 +359,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] diff --git a/src/lib/es2017.d.ts b/src/lib/es2017.d.ts index 80282355a45..87aa273140b 100644 --- a/src/lib/es2017.d.ts +++ b/src/lib/es2017.d.ts @@ -3,3 +3,4 @@ /// /// /// +/// diff --git a/src/lib/es2017.typedarrays.d.ts b/src/lib/es2017.typedarrays.d.ts new file mode 100644 index 00000000000..a0b64135a30 --- /dev/null +++ b/src/lib/es2017.typedarrays.d.ts @@ -0,0 +1,35 @@ +interface Int8ArrayConstructor { + new (): Int8Array; +} + +interface Uint8ArrayConstructor { + new (): Uint8Array; +} + +interface Uint8ClampedArrayConstructor { + new (): Uint8ClampedArray; +} + +interface Int16ArrayConstructor { + new (): Int16Array; +} + +interface Uint16ArrayConstructor { + new (): Uint16Array; +} + +interface Int32ArrayConstructor { + new (): Int32Array; +} + +interface Uint32ArrayConstructor { + new (): Uint32Array; +} + +interface Float32ArrayConstructor { + new (): Float32Array; +} + +interface Float64ArrayConstructor { + new (): Float64Array; +} diff --git a/tests/baselines/reference/useTypedArrays1.js b/tests/baselines/reference/useTypedArrays1.js new file mode 100644 index 00000000000..bbfcccec836 --- /dev/null +++ b/tests/baselines/reference/useTypedArrays1.js @@ -0,0 +1,22 @@ +//// [useTypedArrays1.ts] +var int8Array = new Int8Array(); +var uint8Array = new Uint8Array(); +var uint8ClampedArray = new Uint8ClampedArray(); +var int16Array = new Int16Array(); +var uint16Array = new Uint16Array(); +var int32Array = new Int32Array(); +var uint32Array = new Uint32Array(); +var float32Array = new Float32Array(); +var float64Array = new Float64Array(); + + +//// [useTypedArrays1.js] +var int8Array = new Int8Array(); +var uint8Array = new Uint8Array(); +var uint8ClampedArray = new Uint8ClampedArray(); +var int16Array = new Int16Array(); +var uint16Array = new Uint16Array(); +var int32Array = new Int32Array(); +var uint32Array = new Uint32Array(); +var float32Array = new Float32Array(); +var float64Array = new Float64Array(); diff --git a/tests/baselines/reference/useTypedArrays1.symbols b/tests/baselines/reference/useTypedArrays1.symbols new file mode 100644 index 00000000000..ed41b0c24bd --- /dev/null +++ b/tests/baselines/reference/useTypedArrays1.symbols @@ -0,0 +1,37 @@ +=== tests/cases/conformance/es2017/useTypedArrays1.ts === +var int8Array = new Int8Array(); +>int8Array : Symbol(int8Array, Decl(useTypedArrays1.ts, 0, 3)) +>Int8Array : Symbol(Int8Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +var uint8Array = new Uint8Array(); +>uint8Array : Symbol(uint8Array, Decl(useTypedArrays1.ts, 1, 3)) +>Uint8Array : Symbol(Uint8Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +var uint8ClampedArray = new Uint8ClampedArray(); +>uint8ClampedArray : Symbol(uint8ClampedArray, Decl(useTypedArrays1.ts, 2, 3)) +>Uint8ClampedArray : Symbol(Uint8ClampedArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +var int16Array = new Int16Array(); +>int16Array : Symbol(int16Array, Decl(useTypedArrays1.ts, 3, 3)) +>Int16Array : Symbol(Int16Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +var uint16Array = new Uint16Array(); +>uint16Array : Symbol(uint16Array, Decl(useTypedArrays1.ts, 4, 3)) +>Uint16Array : Symbol(Uint16Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +var int32Array = new Int32Array(); +>int32Array : Symbol(int32Array, Decl(useTypedArrays1.ts, 5, 3)) +>Int32Array : Symbol(Int32Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +var uint32Array = new Uint32Array(); +>uint32Array : Symbol(uint32Array, Decl(useTypedArrays1.ts, 6, 3)) +>Uint32Array : Symbol(Uint32Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +var float32Array = new Float32Array(); +>float32Array : Symbol(float32Array, Decl(useTypedArrays1.ts, 7, 3)) +>Float32Array : Symbol(Float32Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +var float64Array = new Float64Array(); +>float64Array : Symbol(float64Array, Decl(useTypedArrays1.ts, 8, 3)) +>Float64Array : Symbol(Float64Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + diff --git a/tests/baselines/reference/useTypedArrays1.types b/tests/baselines/reference/useTypedArrays1.types new file mode 100644 index 00000000000..f3f27383a3e --- /dev/null +++ b/tests/baselines/reference/useTypedArrays1.types @@ -0,0 +1,46 @@ +=== tests/cases/conformance/es2017/useTypedArrays1.ts === +var int8Array = new Int8Array(); +>int8Array : Int8Array +>new Int8Array() : Int8Array +>Int8Array : Int8ArrayConstructor + +var uint8Array = new Uint8Array(); +>uint8Array : Uint8Array +>new Uint8Array() : Uint8Array +>Uint8Array : Uint8ArrayConstructor + +var uint8ClampedArray = new Uint8ClampedArray(); +>uint8ClampedArray : Uint8ClampedArray +>new Uint8ClampedArray() : Uint8ClampedArray +>Uint8ClampedArray : Uint8ClampedArrayConstructor + +var int16Array = new Int16Array(); +>int16Array : Int16Array +>new Int16Array() : Int16Array +>Int16Array : Int16ArrayConstructor + +var uint16Array = new Uint16Array(); +>uint16Array : Uint16Array +>new Uint16Array() : Uint16Array +>Uint16Array : Uint16ArrayConstructor + +var int32Array = new Int32Array(); +>int32Array : Int32Array +>new Int32Array() : Int32Array +>Int32Array : Int32ArrayConstructor + +var uint32Array = new Uint32Array(); +>uint32Array : Uint32Array +>new Uint32Array() : Uint32Array +>Uint32Array : Uint32ArrayConstructor + +var float32Array = new Float32Array(); +>float32Array : Float32Array +>new Float32Array() : Float32Array +>Float32Array : Float32ArrayConstructor + +var float64Array = new Float64Array(); +>float64Array : Float64Array +>new Float64Array() : Float64Array +>Float64Array : Float64ArrayConstructor + diff --git a/tests/cases/conformance/es2017/useTypedArrays1.ts b/tests/cases/conformance/es2017/useTypedArrays1.ts new file mode 100644 index 00000000000..e06bf91f317 --- /dev/null +++ b/tests/cases/conformance/es2017/useTypedArrays1.ts @@ -0,0 +1,12 @@ +// @target: es5 +// @lib: es5,es2017.typedarrays + +var int8Array = new Int8Array(); +var uint8Array = new Uint8Array(); +var uint8ClampedArray = new Uint8ClampedArray(); +var int16Array = new Int16Array(); +var uint16Array = new Uint16Array(); +var int32Array = new Int32Array(); +var uint32Array = new Uint32Array(); +var float32Array = new Float32Array(); +var float64Array = new Float64Array(); From 5c173f4436703aa6a75ac2fb93d3785905cb72fa Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 6 Nov 2017 12:51:52 -0800 Subject: [PATCH 139/235] Remove test --- tests/baselines/reference/useTypedArrays1.js | 22 --------- .../reference/useTypedArrays1.symbols | 37 --------------- .../baselines/reference/useTypedArrays1.types | 46 ------------------- .../conformance/es2017/useTypedArrays1.ts | 12 ----- 4 files changed, 117 deletions(-) delete mode 100644 tests/baselines/reference/useTypedArrays1.js delete mode 100644 tests/baselines/reference/useTypedArrays1.symbols delete mode 100644 tests/baselines/reference/useTypedArrays1.types delete mode 100644 tests/cases/conformance/es2017/useTypedArrays1.ts diff --git a/tests/baselines/reference/useTypedArrays1.js b/tests/baselines/reference/useTypedArrays1.js deleted file mode 100644 index bbfcccec836..00000000000 --- a/tests/baselines/reference/useTypedArrays1.js +++ /dev/null @@ -1,22 +0,0 @@ -//// [useTypedArrays1.ts] -var int8Array = new Int8Array(); -var uint8Array = new Uint8Array(); -var uint8ClampedArray = new Uint8ClampedArray(); -var int16Array = new Int16Array(); -var uint16Array = new Uint16Array(); -var int32Array = new Int32Array(); -var uint32Array = new Uint32Array(); -var float32Array = new Float32Array(); -var float64Array = new Float64Array(); - - -//// [useTypedArrays1.js] -var int8Array = new Int8Array(); -var uint8Array = new Uint8Array(); -var uint8ClampedArray = new Uint8ClampedArray(); -var int16Array = new Int16Array(); -var uint16Array = new Uint16Array(); -var int32Array = new Int32Array(); -var uint32Array = new Uint32Array(); -var float32Array = new Float32Array(); -var float64Array = new Float64Array(); diff --git a/tests/baselines/reference/useTypedArrays1.symbols b/tests/baselines/reference/useTypedArrays1.symbols deleted file mode 100644 index ed41b0c24bd..00000000000 --- a/tests/baselines/reference/useTypedArrays1.symbols +++ /dev/null @@ -1,37 +0,0 @@ -=== tests/cases/conformance/es2017/useTypedArrays1.ts === -var int8Array = new Int8Array(); ->int8Array : Symbol(int8Array, Decl(useTypedArrays1.ts, 0, 3)) ->Int8Array : Symbol(Int8Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) - -var uint8Array = new Uint8Array(); ->uint8Array : Symbol(uint8Array, Decl(useTypedArrays1.ts, 1, 3)) ->Uint8Array : Symbol(Uint8Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) - -var uint8ClampedArray = new Uint8ClampedArray(); ->uint8ClampedArray : Symbol(uint8ClampedArray, Decl(useTypedArrays1.ts, 2, 3)) ->Uint8ClampedArray : Symbol(Uint8ClampedArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) - -var int16Array = new Int16Array(); ->int16Array : Symbol(int16Array, Decl(useTypedArrays1.ts, 3, 3)) ->Int16Array : Symbol(Int16Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) - -var uint16Array = new Uint16Array(); ->uint16Array : Symbol(uint16Array, Decl(useTypedArrays1.ts, 4, 3)) ->Uint16Array : Symbol(Uint16Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) - -var int32Array = new Int32Array(); ->int32Array : Symbol(int32Array, Decl(useTypedArrays1.ts, 5, 3)) ->Int32Array : Symbol(Int32Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) - -var uint32Array = new Uint32Array(); ->uint32Array : Symbol(uint32Array, Decl(useTypedArrays1.ts, 6, 3)) ->Uint32Array : Symbol(Uint32Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) - -var float32Array = new Float32Array(); ->float32Array : Symbol(float32Array, Decl(useTypedArrays1.ts, 7, 3)) ->Float32Array : Symbol(Float32Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) - -var float64Array = new Float64Array(); ->float64Array : Symbol(float64Array, Decl(useTypedArrays1.ts, 8, 3)) ->Float64Array : Symbol(Float64Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) - diff --git a/tests/baselines/reference/useTypedArrays1.types b/tests/baselines/reference/useTypedArrays1.types deleted file mode 100644 index f3f27383a3e..00000000000 --- a/tests/baselines/reference/useTypedArrays1.types +++ /dev/null @@ -1,46 +0,0 @@ -=== tests/cases/conformance/es2017/useTypedArrays1.ts === -var int8Array = new Int8Array(); ->int8Array : Int8Array ->new Int8Array() : Int8Array ->Int8Array : Int8ArrayConstructor - -var uint8Array = new Uint8Array(); ->uint8Array : Uint8Array ->new Uint8Array() : Uint8Array ->Uint8Array : Uint8ArrayConstructor - -var uint8ClampedArray = new Uint8ClampedArray(); ->uint8ClampedArray : Uint8ClampedArray ->new Uint8ClampedArray() : Uint8ClampedArray ->Uint8ClampedArray : Uint8ClampedArrayConstructor - -var int16Array = new Int16Array(); ->int16Array : Int16Array ->new Int16Array() : Int16Array ->Int16Array : Int16ArrayConstructor - -var uint16Array = new Uint16Array(); ->uint16Array : Uint16Array ->new Uint16Array() : Uint16Array ->Uint16Array : Uint16ArrayConstructor - -var int32Array = new Int32Array(); ->int32Array : Int32Array ->new Int32Array() : Int32Array ->Int32Array : Int32ArrayConstructor - -var uint32Array = new Uint32Array(); ->uint32Array : Uint32Array ->new Uint32Array() : Uint32Array ->Uint32Array : Uint32ArrayConstructor - -var float32Array = new Float32Array(); ->float32Array : Float32Array ->new Float32Array() : Float32Array ->Float32Array : Float32ArrayConstructor - -var float64Array = new Float64Array(); ->float64Array : Float64Array ->new Float64Array() : Float64Array ->Float64Array : Float64ArrayConstructor - diff --git a/tests/cases/conformance/es2017/useTypedArrays1.ts b/tests/cases/conformance/es2017/useTypedArrays1.ts deleted file mode 100644 index e06bf91f317..00000000000 --- a/tests/cases/conformance/es2017/useTypedArrays1.ts +++ /dev/null @@ -1,12 +0,0 @@ -// @target: es5 -// @lib: es5,es2017.typedarrays - -var int8Array = new Int8Array(); -var uint8Array = new Uint8Array(); -var uint8ClampedArray = new Uint8ClampedArray(); -var int16Array = new Int16Array(); -var uint16Array = new Uint16Array(); -var int32Array = new Int32Array(); -var uint32Array = new Uint32Array(); -var float32Array = new Float32Array(); -var float64Array = new Float64Array(); From ed38889ca66991d02728c3ed60ba3bf9d914d55e Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 6 Nov 2017 13:01:07 -0800 Subject: [PATCH 140/235] Enable 'no-unused-expression' tslint rule (#19734) --- src/compiler/checker.ts | 100 +++++++++--------- src/harness/fourslash.ts | 8 +- src/harness/parallel/worker.ts | 8 +- src/harness/unittests/languageService.ts | 2 +- src/harness/unittests/session.ts | 8 +- .../unittests/tsserverProjectSystem.ts | 12 +-- src/services/utilities.ts | 8 +- tslint.json | 1 - 8 files changed, 77 insertions(+), 70 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 39b0dc18569..649deef7e3a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1904,8 +1904,9 @@ namespace ts { * Extends one symbol table with another while collecting information on name collisions for error message generation into the `lookupTable` argument * Not passing `lookupTable` and `exportNode` disables this collection, and just extends the tables */ - function extendExportSymbols(target: SymbolTable, source: SymbolTable, lookupTable?: ExportCollisionTrackerTable, exportNode?: ExportDeclaration) { - source && source.forEach((sourceSymbol, id) => { + function extendExportSymbols(target: SymbolTable, source: SymbolTable | undefined, lookupTable?: ExportCollisionTrackerTable, exportNode?: ExportDeclaration) { + if (!source) return; + source.forEach((sourceSymbol, id) => { if (id === "default") return; const targetSymbol = target.get(id); @@ -17016,8 +17017,7 @@ namespace ts { * @returns On success, the expression's signature's return type. On failure, anyType. */ function checkCallExpression(node: CallExpression | NewExpression): Type { - // Grammar checking; stop grammar-checking if checkGrammarTypeArguments return true - checkGrammarTypeArguments(node, node.typeArguments) || checkGrammarArguments(node.arguments); + if (!checkGrammarTypeArguments(node, node.typeArguments)) checkGrammarArguments(node.arguments); const signature = getResolvedSignature(node); @@ -17064,7 +17064,7 @@ namespace ts { function checkImportCallExpression(node: ImportCall): Type { // Check grammar of dynamic import - checkGrammarArguments(node.arguments) || checkGrammarImportCallExpression(node); + if (!checkGrammarArguments(node.arguments)) checkGrammarImportCallExpression(node); if (node.arguments.length === 0) { return createPromiseReturnType(node, anyType); @@ -18739,9 +18739,7 @@ namespace ts { // It is a SyntaxError if the Identifier "eval" or the Identifier "arguments" occurs as the // Identifier in a PropertySetParameterList of a PropertyAssignment that is contained in strict code // or if its FunctionBody is strict code(11.1.5). - - // Grammar checking - checkGrammarDecorators(node) || checkGrammarModifiers(node); + checkGrammarDecoratorsAndModifiers(node); checkVariableLikeDeclaration(node); const func = getContainingFunction(node); @@ -19131,14 +19129,13 @@ namespace ts { function checkPropertyDeclaration(node: PropertyDeclaration) { // Grammar checking - checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarProperty(node) || checkGrammarComputedPropertyName(node.name); - + if (!checkGrammarDecoratorsAndModifiers(node) && !checkGrammarProperty(node)) checkGrammarComputedPropertyName(node.name); checkVariableLikeDeclaration(node); } function checkMethodDeclaration(node: MethodDeclaration) { // Grammar checking - checkGrammarMethod(node) || checkGrammarComputedPropertyName(node.name); + if (!checkGrammarMethod(node)) checkGrammarComputedPropertyName(node.name); // Grammar checking for modifiers is done inside the function checkGrammarFunctionLikeDeclaration checkFunctionOrMethodDeclaration(node); @@ -19154,7 +19151,7 @@ namespace ts { // Grammar check on signature of constructor and modifier of the constructor is done in checkSignatureDeclaration function. checkSignatureDeclaration(node); // Grammar check for checking only related to constructorDeclaration - checkGrammarConstructorTypeParameters(node) || checkGrammarConstructorTypeAnnotation(node); + if (!checkGrammarConstructorTypeParameters(node)) checkGrammarConstructorTypeAnnotation(node); checkSourceElement(node.body); registerForUnusedIdentifiersCheck(node); @@ -19251,7 +19248,7 @@ namespace ts { function checkAccessorDeclaration(node: AccessorDeclaration) { if (produceDiagnostics) { // Grammar checking accessors - checkGrammarFunctionLikeDeclaration(node) || checkGrammarAccessor(node) || checkGrammarComputedPropertyName(node.name); + if (!checkGrammarFunctionLikeDeclaration(node) && !checkGrammarAccessor(node)) checkGrammarComputedPropertyName(node.name); checkDecorators(node); checkSignatureDeclaration(node); @@ -21013,8 +21010,7 @@ namespace ts { function checkVariableStatement(node: VariableStatement) { // Grammar checking - checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarVariableDeclarationList(node.declarationList) || checkGrammarForDisallowedLetOrConstStatement(node); - + if (!checkGrammarDecoratorsAndModifiers(node) && !checkGrammarVariableDeclarationList(node.declarationList)) checkGrammarForDisallowedLetOrConstStatement(node); forEach(node.declarationList.declarations, checkSourceElement); } @@ -21522,7 +21518,7 @@ namespace ts { function checkBreakOrContinueStatement(node: BreakOrContinueStatement) { // Grammar checking - checkGrammarStatementInAmbientContext(node) || checkGrammarBreakOrContinueStatement(node); + if (!checkGrammarStatementInAmbientContext(node)) checkGrammarBreakOrContinueStatement(node); // TODO: Check that target label is valid } @@ -22203,7 +22199,7 @@ namespace ts { function checkInterfaceDeclaration(node: InterfaceDeclaration) { // Grammar checking - checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarInterfaceDeclaration(node); + if (!checkGrammarDecoratorsAndModifiers(node)) checkGrammarInterfaceDeclaration(node); checkTypeParameters(node.typeParameters); if (produceDiagnostics) { @@ -22245,7 +22241,7 @@ namespace ts { function checkTypeAliasDeclaration(node: TypeAliasDeclaration) { // Grammar checking - checkGrammarDecorators(node) || checkGrammarModifiers(node); + checkGrammarDecoratorsAndModifiers(node); checkTypeNameIsReserved(node.name, Diagnostics.Type_alias_name_cannot_be_0); checkTypeParameters(node.typeParameters); @@ -22415,7 +22411,7 @@ namespace ts { } // Grammar checking - checkGrammarDecorators(node) || checkGrammarModifiers(node); + checkGrammarDecoratorsAndModifiers(node); checkTypeNameIsReserved(node.name, Diagnostics.Enum_name_cannot_be_0); checkCollisionWithCapturedThisVariable(node, node.name); @@ -22518,7 +22514,7 @@ namespace ts { return; } - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node)) { + if (!checkGrammarDecoratorsAndModifiers(node)) { if (!inAmbientContext && node.name.kind === SyntaxKind.StringLiteral) { grammarErrorOnNode(node.name, Diagnostics.Only_ambient_modules_can_use_quoted_names); } @@ -22741,7 +22737,7 @@ namespace ts { // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors. return; } - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && hasModifiers(node)) { + if (!checkGrammarDecoratorsAndModifiers(node) && hasModifiers(node)) { grammarErrorOnFirstToken(node, Diagnostics.An_import_declaration_cannot_have_modifiers); } if (checkExternalImportOrExportDeclaration(node)) { @@ -22768,7 +22764,7 @@ namespace ts { return; } - checkGrammarDecorators(node) || checkGrammarModifiers(node); + checkGrammarDecoratorsAndModifiers(node); if (isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) { checkImportBinding(node); if (hasModifier(node, ModifierFlags.Export)) { @@ -22804,7 +22800,7 @@ namespace ts { return; } - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && hasModifiers(node)) { + if (!checkGrammarDecoratorsAndModifiers(node) && hasModifiers(node)) { grammarErrorOnFirstToken(node, Diagnostics.An_export_declaration_cannot_have_modifiers); } @@ -22877,7 +22873,7 @@ namespace ts { return; } // Grammar checking - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && hasModifiers(node)) { + if (!checkGrammarDecoratorsAndModifiers(node) && hasModifiers(node)) { grammarErrorOnFirstToken(node, Diagnostics.An_export_assignment_cannot_have_modifiers); } if (node.expression.kind === SyntaxKind.Identifier) { @@ -22922,29 +22918,31 @@ namespace ts { } // Checks for export * conflicts const exports = getExportsOfModule(moduleSymbol); - exports && exports.forEach(({ declarations, flags }, id) => { - if (id === "__export") { - return; - } - // ECMA262: 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries. - // (TS Exceptions: namespaces, function overloads, enums, and interfaces) - if (flags & (SymbolFlags.Namespace | SymbolFlags.Interface | SymbolFlags.Enum)) { - return; - } - const exportedDeclarationsCount = countWhere(declarations, isNotOverloadAndNotAccessor); - if (flags & SymbolFlags.TypeAlias && exportedDeclarationsCount <= 2) { - // it is legal to merge type alias with other values - // so count should be either 1 (just type alias) or 2 (type alias + merged value) - return; - } - if (exportedDeclarationsCount > 1) { - for (const declaration of declarations) { - if (isNotOverload(declaration)) { - diagnostics.add(createDiagnosticForNode(declaration, Diagnostics.Cannot_redeclare_exported_variable_0, unescapeLeadingUnderscores(id))); + if (exports) { + exports.forEach(({ declarations, flags }, id) => { + if (id === "__export") { + return; + } + // ECMA262: 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries. + // (TS Exceptions: namespaces, function overloads, enums, and interfaces) + if (flags & (SymbolFlags.Namespace | SymbolFlags.Interface | SymbolFlags.Enum)) { + return; + } + const exportedDeclarationsCount = countWhere(declarations, isNotOverloadAndNotAccessor); + if (flags & SymbolFlags.TypeAlias && exportedDeclarationsCount <= 2) { + // it is legal to merge type alias with other values + // so count should be either 1 (just type alias) or 2 (type alias + merged value) + return; + } + if (exportedDeclarationsCount > 1) { + for (const declaration of declarations) { + if (isNotOverload(declaration)) { + diagnostics.add(createDiagnosticForNode(declaration, Diagnostics.Cannot_redeclare_exported_variable_0, unescapeLeadingUnderscores(id))); + } } } - } - }); + }); + } links.exportsChecked = true; } } @@ -24577,12 +24575,16 @@ namespace ts { } // GRAMMAR CHECKING + function checkGrammarDecoratorsAndModifiers(node: Node): boolean { + return checkGrammarDecorators(node) || checkGrammarModifiers(node); + } + function checkGrammarDecorators(node: Node): boolean { if (!node.decorators) { return false; } if (!nodeCanBeDecorated(node)) { - if (node.kind === SyntaxKind.MethodDeclaration && !ts.nodeIsPresent((node).body)) { + if (node.kind === SyntaxKind.MethodDeclaration && !nodeIsPresent((node).body)) { return grammarErrorOnFirstToken(node, Diagnostics.A_decorator_can_only_decorate_a_method_implementation_not_an_overload); } else { @@ -24932,7 +24934,7 @@ namespace ts { function checkGrammarFunctionLikeDeclaration(node: FunctionLikeDeclaration): boolean { // Prevent cascading error by short-circuit const file = getSourceFileOfNode(node); - return checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarTypeParameterList(node.typeParameters, file) || + return checkGrammarDecoratorsAndModifiers(node) || checkGrammarTypeParameterList(node.typeParameters, file) || checkGrammarParameterList(node.parameters) || checkGrammarArrowFunction(node, file); } @@ -24988,7 +24990,7 @@ namespace ts { function checkGrammarIndexSignature(node: SignatureDeclaration) { // Prevent cascading error by short-circuit - return checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarIndexSignatureParameters(node); + return checkGrammarDecoratorsAndModifiers(node) || checkGrammarIndexSignatureParameters(node); } function checkGrammarForAtLeastOneTypeArgument(node: Node, typeArguments: NodeArray): boolean { @@ -25039,7 +25041,7 @@ namespace ts { let seenExtendsClause = false; let seenImplementsClause = false; - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && node.heritageClauses) { + if (!checkGrammarDecoratorsAndModifiers(node) && node.heritageClauses) { for (const heritageClause of node.heritageClauses) { if (heritageClause.token === SyntaxKind.ExtendsKeyword) { if (seenExtendsClause) { diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index dac8f7b8413..85011525d52 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -221,11 +221,9 @@ namespace FourSlash { private addMatchedInputFile(referenceFilePath: string, extensions: ReadonlyArray) { const inputFiles = this.inputFiles; const languageServiceAdapterHost = this.languageServiceAdapterHost; - if (!extensions) { - tryAdd(referenceFilePath); - } - else { - tryAdd(referenceFilePath) || ts.forEach(extensions, ext => tryAdd(referenceFilePath + ext)); + const didAdd = tryAdd(referenceFilePath); + if (extensions && !didAdd) { + ts.forEach(extensions, ext => tryAdd(referenceFilePath + ext)); } function tryAdd(path: string) { diff --git a/src/harness/parallel/worker.ts b/src/harness/parallel/worker.ts index c32b9660a39..953ed5aeb21 100644 --- a/src/harness/parallel/worker.ts +++ b/src/harness/parallel/worker.ts @@ -57,7 +57,9 @@ namespace Harness.Parallel.Worker { return cleanup(); } try { - beforeFunc && beforeFunc(); + if (beforeFunc) { + beforeFunc(); + } } catch (e) { errors.push({ error: `Error executing before function: ${e.message}`, stack: e.stack, name: [...namestack] }); @@ -69,7 +71,9 @@ namespace Harness.Parallel.Worker { testList.forEach(({ name, callback, kind }) => executeCallback(name, callback, kind)); try { - afterFunc && afterFunc(); + if (afterFunc) { + afterFunc(); + } } catch (e) { errors.push({ error: `Error executing after function: ${e.message}`, stack: e.stack, name: [...namestack] }); diff --git a/src/harness/unittests/languageService.ts b/src/harness/unittests/languageService.ts index fd0a95c167f..1407a518617 100644 --- a/src/harness/unittests/languageService.ts +++ b/src/harness/unittests/languageService.ts @@ -45,7 +45,7 @@ export function Component(x: Config): any;` readDirectory: noop as any, }); const definitions = languageService.getDefinitionAtPosition("foo.ts", 160); // 160 is the latter `vueTemplateHtml` position - expect(definitions).to.exist; + expect(definitions).to.exist; // tslint:disable-line no-unused-expression }); }); } \ No newline at end of file diff --git a/src/harness/unittests/session.ts b/src/harness/unittests/session.ts index e40e7d11b1a..871d4a37b9a 100644 --- a/src/harness/unittests/session.ts +++ b/src/harness/unittests/session.ts @@ -317,7 +317,7 @@ namespace ts.server { session.send = Session.prototype.send; assert(session.send); - expect(session.send(msg)).to.not.exist; + expect(session.send(msg)).to.not.exist; // tslint:disable-line no-unused-expression expect(lastWrittenToHost).to.equal(resultMsg); }); }); @@ -524,14 +524,14 @@ namespace ts.server { }); }); it("has access to the project service", () => { - class ServiceSession extends TestSession { + // tslint:disable-next-line no-unused-expression + new class extends TestSession { constructor() { super(); assert(this.projectService); expect(this.projectService).to.be.instanceOf(ProjectService); } - } - new ServiceSession(); + }(); }); }); diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index c09a1bcb5da..55d767d24a7 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -1870,7 +1870,7 @@ namespace ts.projectSystem { // Specify .html extension as mixed content const extraFileExtensions = [{ extension: ".html", scriptKind: ScriptKind.JS, isMixedContent: true }]; const configureHostRequest = makeSessionRequest(CommandNames.Configure, { extraFileExtensions }); - session.executeCommand(configureHostRequest).response; + session.executeCommand(configureHostRequest); // The configured project should now be updated to include html file checkNumberOfProjects(projectService, { configuredProjects: 1 }); @@ -1929,7 +1929,7 @@ namespace ts.projectSystem { // Specify .html extension as mixed content in a configure host request const extraFileExtensions = [{ extension: ".html", scriptKind: ScriptKind.JS, isMixedContent: true }]; const configureHostRequest = makeSessionRequest(CommandNames.Configure, { extraFileExtensions }); - session.executeCommand(configureHostRequest).response; + session.executeCommand(configureHostRequest); openFilesForSession([file1], session); let projectService = session.getProjectService(); @@ -1948,7 +1948,7 @@ namespace ts.projectSystem { host = createServerHost([file1, file2, config2, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") }); session = createSession(host); - session.executeCommand(configureHostRequest).response; + session.executeCommand(configureHostRequest); openFilesForSession([file1], session); projectService = session.getProjectService(); @@ -1967,7 +1967,7 @@ namespace ts.projectSystem { host = createServerHost([file1, file2, config3, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") }); session = createSession(host); - session.executeCommand(configureHostRequest).response; + session.executeCommand(configureHostRequest); openFilesForSession([file1], session); projectService = session.getProjectService(); @@ -1986,7 +1986,7 @@ namespace ts.projectSystem { host = createServerHost([file1, file2, config4, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") }); session = createSession(host); - session.executeCommand(configureHostRequest).response; + session.executeCommand(configureHostRequest); openFilesForSession([file1], session); projectService = session.getProjectService(); @@ -2005,7 +2005,7 @@ namespace ts.projectSystem { host = createServerHost([file1, file2, config5, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") }); session = createSession(host); - session.executeCommand(configureHostRequest).response; + session.executeCommand(configureHostRequest); openFilesForSession([file1], session); projectService = session.getProjectService(); diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 9397c40ff8a..36089f94f73 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1398,7 +1398,9 @@ namespace ts { addEmitFlags(node, EmitFlags.NoLeadingComments); const firstChild = forEachChild(node, child => child); - firstChild && suppressLeading(firstChild); + if (firstChild) { + suppressLeading(firstChild); + } } function suppressTrailing(node: Node) { @@ -1415,7 +1417,9 @@ namespace ts { } return undefined; }); - lastChild && suppressTrailing(lastChild); + if (lastChild) { + suppressTrailing(lastChild); + } } } } diff --git a/tslint.json b/tslint.json index 9ad752e6094..497bd5e787a 100644 --- a/tslint.json +++ b/tslint.json @@ -93,7 +93,6 @@ "no-object-literal-type-assertion": false, "no-shadowed-variable": false, "no-submodule-imports": false, - "no-unused-expression": false, "no-unnecessary-initializer": false, "no-var-requires": false, "object-literal-key-quotes": false, From 28ed9b307b06bdf09dcad4cb10b31d82b19fc7c7 Mon Sep 17 00:00:00 2001 From: falsandtru Date: Tue, 7 Nov 2017 06:12:47 +0900 Subject: [PATCH 141/235] Update DOM iterable interfaces (#19752) * Make HTMLCollections Iterable * Sort definitions --- src/lib/dom.iterable.d.ts | 42 +++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/src/lib/dom.iterable.d.ts b/src/lib/dom.iterable.d.ts index e89a22f2c14..6ca728444f2 100644 --- a/src/lib/dom.iterable.d.ts +++ b/src/lib/dom.iterable.d.ts @@ -4,23 +4,6 @@ interface DOMTokenList { [Symbol.iterator](): IterableIterator; } -interface FormData { - /** - * Returns an array of key, value pairs for every entry in the list - */ - entries(): IterableIterator<[string, string | File]>; - /** - * Returns a list of keys in the list - */ - keys(): IterableIterator; - /** - * Returns a list of values in the list - */ - values(): IterableIterator; - - [Symbol.iterator](): IterableIterator; -} - interface Headers { [Symbol.iterator](): IterableIterator<[string, string]>; /** @@ -87,6 +70,31 @@ interface NodeListOf { [Symbol.iterator](): IterableIterator; } +interface HTMLCollectionBase { + [Symbol.iterator](): IterableIterator; +} + +interface HTMLCollectionOf { + [Symbol.iterator](): IterableIterator; +} + +interface FormData { + /** + * Returns an array of key, value pairs for every entry in the list + */ + entries(): IterableIterator<[string, string | File]>; + /** + * Returns a list of keys in the list + */ + keys(): IterableIterator; + /** + * Returns a list of values in the list + */ + values(): IterableIterator; + + [Symbol.iterator](): IterableIterator; +} + interface URLSearchParams { /** * Returns an array of key, value pairs for every entry in the search params From a46d2705ef872a1c4f86a9dc5d7384b412e8ba5a Mon Sep 17 00:00:00 2001 From: Sean Barag Date: Mon, 6 Nov 2017 13:18:21 -0800 Subject: [PATCH 142/235] Use documentation comments from inherited properties when @inheritDoc is present (#18804) * Use documentation comments from inherited properties when @inheritDoc is present The JSDoc `@ineheritDoc` [tag](http://usejsdoc.org/tags-inheritdoc.html) "indicates that a symbol should inherit its documentation from its parent class". In the case of a TypeScript file, this also includes implemented interfaces and parent interfaces. With this change, a class method or property (or an interface property) with the `@inheritDoc` tag in its JSDoc comment will automatically use the comments from its nearest ancestor that has no `@inheritDoc` tag. To prevent breaking backwards compatibility, `Symbol.getDocumentationComment` now accepts an optional `TypeChecker` instance to support this feature. fixes #8912 * Use ts.getJSDocTags as per @andy-ms 's recommendation * Convert @inheritDoc tests to verify.quickInfoAt * Concatenate inherited and local docs when @inheritDoc is present * Make typeChecker param explicitly `TypeChecker | undefined` * Re-accept baseline after switch to explicit `| undefined` * Update APISample_jsodc.ts to match new getDocumentationComment signature * Re-accept baselines after rebasing --- src/services/jsDoc.ts | 1 + src/services/services.ts | 96 ++++++++++++++++++- src/services/signatureHelp.ts | 6 +- src/services/symbolDisplay.ts | 6 +- src/services/types.ts | 4 +- tests/baselines/reference/APISample_jsdoc.js | 4 +- .../reference/api/tsserverlibrary.d.ts | 4 +- tests/baselines/reference/api/typescript.d.ts | 4 +- tests/cases/compiler/APISample_jsdoc.ts | 2 +- tests/cases/fourslash/commentsInheritance.ts | 10 +- tests/cases/fourslash/jsDocInheritDoc.ts | 57 +++++++++++ 11 files changed, 170 insertions(+), 24 deletions(-) create mode 100644 tests/cases/fourslash/jsDocInheritDoc.ts diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index b8e94857aa7..79b08780226 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -20,6 +20,7 @@ namespace ts.JsDoc { "fileOverview", "function", "ignore", + "inheritDoc", "inner", "lends", "link", diff --git a/src/services/services.ts b/src/services/services.ts index 0dbdb57f309..237a9ce8d5b 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -346,9 +346,29 @@ namespace ts { return this.declarations; } - getDocumentationComment(): SymbolDisplayPart[] { + getDocumentationComment(checker: TypeChecker | undefined): SymbolDisplayPart[] { if (this.documentationComment === undefined) { - this.documentationComment = JsDoc.getJsDocCommentsFromDeclarations(this.declarations); + if (this.declarations) { + this.documentationComment = JsDoc.getJsDocCommentsFromDeclarations(this.declarations); + + if (this.documentationComment.length === 0 || this.declarations.some(hasJSDocInheritDocTag)) { + if (checker) { + for (const declaration of this.declarations) { + const inheritedDocs = findInheritedJSDocComments(declaration, this.getName(), checker); + if (inheritedDocs.length > 0) { + if (this.documentationComment.length > 0) { + inheritedDocs.push(ts.lineBreakPart()); + } + this.documentationComment = concatenate(inheritedDocs, this.documentationComment); + break; + } + } + } + } + } + else { + this.documentationComment = []; + } } return this.documentationComment; @@ -477,7 +497,23 @@ namespace ts { getDocumentationComment(): SymbolDisplayPart[] { if (this.documentationComment === undefined) { - this.documentationComment = this.declaration ? JsDoc.getJsDocCommentsFromDeclarations([this.declaration]) : []; + if (this.declaration) { + this.documentationComment = JsDoc.getJsDocCommentsFromDeclarations([this.declaration]); + + if (this.documentationComment.length === 0 || hasJSDocInheritDocTag(this.declaration)) { + const inheritedDocs = findInheritedJSDocComments(this.declaration, this.declaration.symbol.getName(), this.checker); + if (this.documentationComment.length > 0) { + inheritedDocs.push(ts.lineBreakPart()); + } + this.documentationComment = concatenate( + inheritedDocs, + this.documentationComment + ); + } + } + else { + this.documentationComment = []; + } } return this.documentationComment; @@ -492,6 +528,58 @@ namespace ts { } } + /** + * Returns whether or not the given node has a JSDoc "inheritDoc" tag on it. + * @param node the Node in question. + * @returns `true` if `node` has a JSDoc "inheritDoc" tag on it, otherwise `false`. + */ + function hasJSDocInheritDocTag(node: Node) { + return ts.getJSDocTags(node).some(tag => tag.tagName.text === "inheritDoc"); + } + + /** + * Attempts to find JSDoc comments for possibly-inherited properties. Checks superclasses then traverses + * implemented interfaces until a symbol is found with the same name and with documentation. + * @param declaration The possibly-inherited declaration to find comments for. + * @param propertyName The name of the possibly-inherited property. + * @param typeChecker A TypeChecker, used to find inherited properties. + * @returns A filled array of documentation comments if any were found, otherwise an empty array. + */ + function findInheritedJSDocComments(declaration: Declaration, propertyName: string, typeChecker: TypeChecker): SymbolDisplayPart[] { + let foundDocs = false; + return flatMap(getAllSuperTypeNodes(declaration), superTypeNode => { + if (foundDocs) { + return emptyArray; + } + const superType = typeChecker.getTypeAtLocation(superTypeNode); + if (!superType) { + return emptyArray; + } + const baseProperty = typeChecker.getPropertyOfType(superType, propertyName); + if (!baseProperty) { + return emptyArray; + } + const inheritedDocs = baseProperty.getDocumentationComment(typeChecker); + foundDocs = inheritedDocs.length > 0; + return inheritedDocs; + }); + } + + /** + * Finds and returns the `TypeNode` for all super classes and implemented interfaces given a declaration. + * @param declaration The possibly-inherited declaration. + * @returns A filled array of `TypeNode`s containing all super classes and implemented interfaces if any exist, otherwise an empty array. + */ + function getAllSuperTypeNodes(declaration: Declaration): ReadonlyArray { + const container = declaration.parent; + if (!container || (!isClassDeclaration(container) && !isInterfaceDeclaration(container))) { + return emptyArray; + } + const extended = getClassExtendsHeritageClauseElement(container); + const types = extended ? [extended] : emptyArray; + return isClassLike(container) ? concatenate(types, getClassImplementsHeritageClauseElements(container)) : types; + } + class SourceFileObject extends NodeObject implements SourceFile { public kind: SyntaxKind.SourceFile; public _declarationBrand: any; @@ -1399,7 +1487,7 @@ namespace ts { kindModifiers: ScriptElementKindModifier.none, textSpan: createTextSpan(node.getStart(), node.getWidth()), displayParts: typeToDisplayParts(typeChecker, type, getContainerNode(node)), - documentation: type.symbol ? type.symbol.getDocumentationComment() : undefined, + documentation: type.symbol ? type.symbol.getDocumentationComment(typeChecker) : undefined, tags: type.symbol ? type.symbol.getJsDocTags() : undefined }; } diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 7e8e748bb17..36c83f5f4af 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -400,7 +400,7 @@ namespace ts.SignatureHelp { suffixDisplayParts, separatorDisplayParts: [punctuationPart(SyntaxKind.CommaToken), spacePart()], parameters: signatureHelpParameters, - documentation: candidateSignature.getDocumentationComment(), + documentation: candidateSignature.getDocumentationComment(typeChecker), tags: candidateSignature.getJsDocTags() }; }); @@ -420,7 +420,7 @@ namespace ts.SignatureHelp { return { name: parameter.name, - documentation: parameter.getDocumentationComment(), + documentation: parameter.getDocumentationComment(typeChecker), displayParts, isOptional: typeChecker.isOptionalParameter(parameter.valueDeclaration) }; @@ -438,4 +438,4 @@ namespace ts.SignatureHelp { }; } } -} \ No newline at end of file +} diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index 0465ec2aa70..e3ef4d3e495 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -438,7 +438,7 @@ namespace ts.SymbolDisplay { } if (!documentation) { - documentation = symbol.getDocumentationComment(); + documentation = symbol.getDocumentationComment(typeChecker); tags = symbol.getJsDocTags(); if (documentation.length === 0 && symbolFlags & SymbolFlags.Property) { // For some special property access expressions like `exports.foo = foo` or `module.exports.foo = foo` @@ -455,7 +455,7 @@ namespace ts.SymbolDisplay { continue; } - documentation = rhsSymbol.getDocumentationComment(); + documentation = rhsSymbol.getDocumentationComment(typeChecker); tags = rhsSymbol.getJsDocTags(); if (documentation.length > 0) { break; @@ -524,7 +524,7 @@ namespace ts.SymbolDisplay { displayParts.push(textPart(allSignatures.length === 2 ? "overload" : "overloads")); displayParts.push(punctuationPart(SyntaxKind.CloseParenToken)); } - documentation = signature.getDocumentationComment(); + documentation = signature.getDocumentationComment(typeChecker); tags = signature.getJsDocTags(); } diff --git a/src/services/types.ts b/src/services/types.ts index a3af3dbdf63..e93ae9686d7 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -32,7 +32,7 @@ namespace ts { getEscapedName(): __String; getName(): string; getDeclarations(): Declaration[] | undefined; - getDocumentationComment(): SymbolDisplayPart[]; + getDocumentationComment(typeChecker: TypeChecker | undefined): SymbolDisplayPart[]; getJsDocTags(): JSDocTagInfo[]; } @@ -55,7 +55,7 @@ namespace ts { getTypeParameters(): TypeParameter[] | undefined; getParameters(): Symbol[]; getReturnType(): Type; - getDocumentationComment(): SymbolDisplayPart[]; + getDocumentationComment(typeChecker: TypeChecker | undefined): SymbolDisplayPart[]; getJsDocTags(): JSDocTagInfo[]; } diff --git a/tests/baselines/reference/APISample_jsdoc.js b/tests/baselines/reference/APISample_jsdoc.js index c74e188f38b..f28b16d88b6 100644 --- a/tests/baselines/reference/APISample_jsdoc.js +++ b/tests/baselines/reference/APISample_jsdoc.js @@ -21,7 +21,7 @@ function parseCommentsIntoDefinition(this: any, } // the comments for a symbol - let comments = symbol.getDocumentationComment(); + let comments = symbol.getDocumentationComment(undefined); if (comments.length) { definition.description = comments.map(comment => comment.kind === "lineBreak" ? comment.text : comment.text.trim().replace(/\r\n/g, "\n")).join(""); @@ -131,7 +131,7 @@ function parseCommentsIntoDefinition(symbol, definition, otherAnnotations) { return; } // the comments for a symbol - var comments = symbol.getDocumentationComment(); + var comments = symbol.getDocumentationComment(undefined); if (comments.length) { definition.description = comments.map(function (comment) { return comment.kind === "lineBreak" ? comment.text : comment.text.trim().replace(/\r\n/g, "\n"); }).join(""); } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 663aa27a1b6..85895ffbce4 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3813,7 +3813,7 @@ declare namespace ts { getEscapedName(): __String; getName(): string; getDeclarations(): Declaration[] | undefined; - getDocumentationComment(): SymbolDisplayPart[]; + getDocumentationComment(typeChecker: TypeChecker | undefined): SymbolDisplayPart[]; getJsDocTags(): JSDocTagInfo[]; } interface Type { @@ -3834,7 +3834,7 @@ declare namespace ts { getTypeParameters(): TypeParameter[] | undefined; getParameters(): Symbol[]; getReturnType(): Type; - getDocumentationComment(): SymbolDisplayPart[]; + getDocumentationComment(typeChecker: TypeChecker | undefined): SymbolDisplayPart[]; getJsDocTags(): JSDocTagInfo[]; } interface SourceFile { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 62b7d4e885b..fd58e72181a 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3813,7 +3813,7 @@ declare namespace ts { getEscapedName(): __String; getName(): string; getDeclarations(): Declaration[] | undefined; - getDocumentationComment(): SymbolDisplayPart[]; + getDocumentationComment(typeChecker: TypeChecker | undefined): SymbolDisplayPart[]; getJsDocTags(): JSDocTagInfo[]; } interface Type { @@ -3834,7 +3834,7 @@ declare namespace ts { getTypeParameters(): TypeParameter[] | undefined; getParameters(): Symbol[]; getReturnType(): Type; - getDocumentationComment(): SymbolDisplayPart[]; + getDocumentationComment(typeChecker: TypeChecker | undefined): SymbolDisplayPart[]; getJsDocTags(): JSDocTagInfo[]; } interface SourceFile { diff --git a/tests/cases/compiler/APISample_jsdoc.ts b/tests/cases/compiler/APISample_jsdoc.ts index 2f4e08931d6..d40673f1d9e 100644 --- a/tests/cases/compiler/APISample_jsdoc.ts +++ b/tests/cases/compiler/APISample_jsdoc.ts @@ -25,7 +25,7 @@ function parseCommentsIntoDefinition(this: any, } // the comments for a symbol - let comments = symbol.getDocumentationComment(); + let comments = symbol.getDocumentationComment(undefined); if (comments.length) { definition.description = comments.map(comment => comment.kind === "lineBreak" ? comment.text : comment.text.trim().replace(/\r\n/g, "\n")).join(""); diff --git a/tests/cases/fourslash/commentsInheritance.ts b/tests/cases/fourslash/commentsInheritance.ts index 7afe18f400c..985c55c7947 100644 --- a/tests/cases/fourslash/commentsInheritance.ts +++ b/tests/cases/fourslash/commentsInheritance.ts @@ -263,8 +263,8 @@ verify.quickInfos({ }); goTo.marker('6'); -verify.completionListContains("i1_p1", "(property) c1.i1_p1: number", ""); -verify.completionListContains("i1_f1", "(method) c1.i1_f1(): void", ""); +verify.completionListContains("i1_p1", "(property) c1.i1_p1: number", "i1_p1"); +verify.completionListContains("i1_f1", "(method) c1.i1_f1(): void", "i1_f1"); verify.completionListContains("i1_l1", "(property) c1.i1_l1: () => void", ""); verify.completionListContains("i1_nc_p1", "(property) c1.i1_nc_p1: number", ""); verify.completionListContains("i1_nc_f1", "(method) c1.i1_nc_f1(): void", ""); @@ -276,7 +276,7 @@ verify.completionListContains("nc_p1", "(property) c1.nc_p1: number", "c1_nc_p1" verify.completionListContains("nc_f1", "(method) c1.nc_f1(): void", "c1_nc_f1"); verify.completionListContains("nc_l1", "(property) c1.nc_l1: () => void", ""); goTo.marker('7'); -verify.currentSignatureHelpDocCommentIs(""); +verify.currentSignatureHelpDocCommentIs("i1_f1"); goTo.marker('8'); verify.currentSignatureHelpDocCommentIs(""); goTo.marker('9'); @@ -294,7 +294,7 @@ verify.currentSignatureHelpDocCommentIs(""); verify.quickInfos({ "6iq": "var c1_i: c1", - "7q": "(method) c1.i1_f1(): void", + "7q": ["(method) c1.i1_f1(): void", "i1_f1"], "8q": "(method) c1.i1_nc_f1(): void", "9q": ["(method) c1.f1(): void", "c1_f1"], "10q": ["(method) c1.nc_f1(): void", "c1_nc_f1"], @@ -515,7 +515,7 @@ verify.quickInfos({ "39q": ["(method) i2.f1(): void", "i2 f1"], "40q": "(method) i2.nc_f1(): void", "l37q": "(property) i2.i2_l1: () => void", - "l38q": "(property) i2.i2_nc_l1: () => void", + "l38q": "(property) i2.i2_nc_l1: () => void", "l39q": "(property) i2.l1: () => void", "l40q": "(property) i2.nc_l1: () => void", }); diff --git a/tests/cases/fourslash/jsDocInheritDoc.ts b/tests/cases/fourslash/jsDocInheritDoc.ts new file mode 100644 index 00000000000..8a19bd0c14e --- /dev/null +++ b/tests/cases/fourslash/jsDocInheritDoc.ts @@ -0,0 +1,57 @@ +/// +// @Filename: inheritDoc.ts +////class Foo { +//// /** +//// * Foo constructor documentation +//// */ +//// constructor(value: number) {} +//// /** +//// * Foo#method1 documentation +//// */ +//// static method1() {} +//// /** +//// * Foo#method2 documentation +//// */ +//// method2() {} +//// /** +//// * Foo#property1 documentation +//// */ +//// property1: string; +////} +////interface Baz { +//// /** Baz#property1 documentation */ +//// property1: string; +//// /** +//// * Baz#property2 documentation +//// */ +//// property2: object; +////} +////class Bar extends Foo implements Baz { +//// ctorValue: number; +//// /** @inheritDoc */ +//// constructor(value: number) { +//// super(value); +//// this.ctorValue = value; +//// } +//// /** @inheritDoc */ +//// static method1() {} +//// method2() {} +//// /** @inheritDoc */ +//// property1: string; +//// /** +//// * Bar#property2 +//// * @inheritDoc +//// */ +//// property2: object; +////} +////const b = new Bar/*1*/(5); +////b.method2/*2*/(); +////Bar.method1/*3*/(); +////const p1 = b.property1/*4*/; +////const p2 = b.property2/*5*/; + +verify.quickInfoAt("1", "constructor Bar(value: number): Bar", undefined); // constructors aren't actually inherited +verify.quickInfoAt("2", "(method) Bar.method2(): void", "Foo#method2 documentation"); // use inherited docs only +verify.quickInfoAt("3", "(method) Bar.method1(): void", undefined); // statics aren't actually inherited +verify.quickInfoAt("4", "(property) Bar.property1: string", "Foo#property1 documentation"); // use inherited docs only +verify.quickInfoAt("5", "(property) Bar.property2: object", "Baz#property2 documentation\nBar#property2"); // include local and inherited docs From 57be7ff3f646391d0d3f825d2705100d86a17101 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 6 Nov 2017 12:21:45 -0800 Subject: [PATCH 143/235] Add test case when inside wild card watched directory folder is renamed --- .../unittests/tsserverProjectSystem.ts | 53 +++++++++++++++++++ src/harness/virtualFileSystemWithWatch.ts | 37 ++++++++++++- 2 files changed, 88 insertions(+), 2 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index c09a1bcb5da..b281f8763a0 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -2767,6 +2767,7 @@ namespace ts.projectSystem { watchedRecursiveDirectories.push(`${root}/a/b/src`, `${root}/a/b/node_modules`); checkWatchedDirectories(host, watchedRecursiveDirectories, /*recursive*/ true); }); + }); describe("Proper errors", () => { @@ -2869,6 +2870,58 @@ namespace ts.projectSystem { verifyNonExistentFile(/*useProjectRoot*/ false); }); }); + + it("folder rename updates project structure and reports no errors", () => { + const projectDir = "/a/b/projects/myproject"; + const app: FileOrFolder = { + path: `${projectDir}/bar/app.ts`, + content: "class Bar implements foo.Foo { getFoo() { return ''; } get2() { return 1; } }" + }; + const foo: FileOrFolder = { + path: `${projectDir}/foo/foo.ts`, + content: "declare namespace foo { interface Foo { get2(): number; getFoo(): string; } }" + }; + const configFile: FileOrFolder = { + path: `${projectDir}/tsconfig.json`, + content: JSON.stringify({ compilerOptions: { module: "none", targer: "es5" }, exclude: ["node_modules"] }) + }; + const host = createServerHost([app, foo, configFile]); + const session = createSession(host, { canUseEvents: true, }); + const projectService = session.getProjectService(); + + session.executeCommandSeq({ + command: server.CommandNames.Open, + arguments: { file: app.path, } + }); + checkNumberOfProjects(projectService, { configuredProjects: 1 }); + assert.isDefined(projectService.configuredProjects.get(configFile.path)); + verifyErrorsInApp(); + + host.renameFolder(`${projectDir}/foo`, `${projectDir}/foo2`); + host.runQueuedTimeoutCallbacks(); + host.runQueuedTimeoutCallbacks(); + verifyErrorsInApp(); + + function verifyErrorsInApp() { + host.clearOutput(); + const expectedSequenceId = session.getNextSeq(); + session.executeCommandSeq({ + command: server.CommandNames.Geterr, + arguments: { + delay: 0, + files: [app.path] + } + }); + host.checkTimeoutQueueLengthAndRun(1); + checkErrorMessage(host, "syntaxDiag", { file: app.path, diagnostics: [] }); + host.clearOutput(); + + host.runQueuedImmediateCallbacks(); + checkErrorMessage(host, "semanticDiag", { file: app.path, diagnostics: [] }); + checkCompleteEvent(host, 2, expectedSequenceId); + host.clearOutput(); + } + }); }); describe("autoDiscovery", () => { diff --git a/src/harness/virtualFileSystemWithWatch.ts b/src/harness/virtualFileSystemWithWatch.ts index 6c3bd8a635a..25581093f3d 100644 --- a/src/harness/virtualFileSystemWithWatch.ts +++ b/src/harness/virtualFileSystemWithWatch.ts @@ -346,6 +346,39 @@ interface Array {}` } } + renameFolder(folderName: string, newFolderName: string) { + const fullPath = getNormalizedAbsolutePath(folderName, this.currentDirectory); + const path = this.toPath(fullPath); + const folder = this.fs.get(path) as Folder; + Debug.assert(!!folder); + + // Only remove the folder + this.removeFileOrFolder(folder, returnFalse, /*isRenaming*/ true); + + // Add updated folder with new folder name + const newFullPath = getNormalizedAbsolutePath(newFolderName, this.currentDirectory); + const newFolder = this.toFolder(newFullPath); + const newPath = newFolder.path; + const basePath = getDirectoryPath(path); + Debug.assert(basePath !== path); + Debug.assert(basePath === getDirectoryPath(newPath)); + const baseFolder = this.fs.get(basePath) as Folder; + this.addFileOrFolderInFolder(baseFolder, newFolder); + + // Invoke watches for files in the folder as deleted (from old path) + for (const entry of folder.entries) { + Debug.assert(isFile(entry)); + this.fs.delete(entry.path); + this.invokeFileWatcher(entry.fullPath, FileWatcherEventKind.Deleted); + + entry.fullPath = combinePaths(newFullPath, getBaseFileName(entry.fullPath)); + entry.path = this.toPath(entry.fullPath); + newFolder.entries.push(entry); + this.fs.set(entry.path, entry); + this.invokeFileWatcher(entry.fullPath, FileWatcherEventKind.Created); + } + } + ensureFileOrFolder(fileOrDirectory: FileOrFolder, ignoreWatchInvokedWithTriggerAsFileCreate?: boolean) { if (isString(fileOrDirectory.content)) { const file = this.toFile(fileOrDirectory); @@ -393,7 +426,7 @@ interface Array {}` this.invokeDirectoryWatcher(folder.fullPath, fileOrDirectory.fullPath); } - private removeFileOrFolder(fileOrDirectory: File | Folder, isRemovableLeafFolder: (folder: Folder) => boolean) { + private removeFileOrFolder(fileOrDirectory: File | Folder, isRemovableLeafFolder: (folder: Folder) => boolean, isRenaming?: boolean) { const basePath = getDirectoryPath(fileOrDirectory.path); const baseFolder = this.fs.get(basePath) as Folder; if (basePath !== fileOrDirectory.path) { @@ -406,7 +439,7 @@ interface Array {}` this.invokeFileWatcher(fileOrDirectory.fullPath, FileWatcherEventKind.Deleted); } else { - Debug.assert(fileOrDirectory.entries.length === 0); + Debug.assert(fileOrDirectory.entries.length === 0 || isRenaming); const relativePath = this.getRelativePathToDirectory(fileOrDirectory.fullPath, fileOrDirectory.fullPath); // Invoke directory and recursive directory watcher for the folder // Here we arent invoking recursive directory watchers for the base folders From fd64322a6372b17d442c95aadce95ff6115883fd Mon Sep 17 00:00:00 2001 From: csigs Date: Mon, 6 Nov 2017 23:10:47 +0000 Subject: [PATCH 144/235] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 36 +++++++++++++++++++ .../diagnosticMessages.generated.json.lcl | 36 +++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl index 94bbc474495..c59e9c20060 100644 --- a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2241,6 +2241,15 @@ + + + + + + + + + @@ -2970,6 +2979,15 @@ + + + + + + + + + @@ -4212,6 +4230,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl index 83a8d7cace7..31f3bfdefd5 100644 --- a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2241,6 +2241,15 @@ + + + + + + + + + @@ -2970,6 +2979,15 @@ + + + + + + + + + @@ -4212,6 +4230,24 @@ + + + + + + + + + + + + + + + + + + From e6c38bf67b451794471245b4a9f4909d02f66320 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 6 Nov 2017 15:16:33 -0800 Subject: [PATCH 145/235] Add DefinitelyTyped test runner Assumes that ../DefinitelyTyped holds the DefinitelyTyped repo. --- src/harness/definitelyRunner.ts | 51 +++++++++++++++++++++++++++++++++ src/harness/runner.ts | 6 ++++ src/harness/runnerbase.ts | 2 +- src/harness/tsconfig.json | 1 + src/harness/userRunner.ts | 2 +- 5 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 src/harness/definitelyRunner.ts diff --git a/src/harness/definitelyRunner.ts b/src/harness/definitelyRunner.ts new file mode 100644 index 00000000000..afd39b72424 --- /dev/null +++ b/src/harness/definitelyRunner.ts @@ -0,0 +1,51 @@ +/// +/// +class DefinitelyTypedRunner extends RunnerBase { + private static readonly testDir = "../DefinitelyTyped/types/"; + public enumerateTestFiles() { + return Harness.IO.getDirectories(DefinitelyTypedRunner.testDir).map(dir => DefinitelyTypedRunner.testDir + dir); + } + + public kind(): TestRunnerKind { + return "definitely"; + } + + /** Setup the runner's tests so that they are ready to be executed by the harness + * The first test should be a describe/it block that sets up the harness's compiler instance appropriately + */ + public initializeTests(): void { + // Read in and evaluate the test list + const testList = this.tests && this.tests.length ? this.tests : this.enumerateTestFiles(); + + describe(`${this.kind()} code samples`, () => { + for (const test of testList) { + this.runTest(test); + } + }); + } + + private runTest(directoryName: string) { + describe(directoryName, () => { + const cp = require("child_process"); + const path = require("path"); + + it("should build successfully", () => { + const cwd = path.join(__dirname, "../../", directoryName); + const timeout = 600000; // 600s = 10 minutes + const stdio = isWorker ? "pipe" : "inherit"; + const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout, shell: true, stdio }); + if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed!`); + Harness.Baseline.runBaseline(`${this.kind()}/${directoryName}.log`, () => { + const result = cp.spawnSync(`node`, [path.join(__dirname, "tsc.js"), "--lib dom,es6", "--strict"], { cwd, timeout, shell: true }); + return `Exit Code: ${result.status} +Standard output: +${result.stdout.toString().replace(/\r\n/g, "\n")} + + +Standard error: +${result.stderr.toString().replace(/\r\n/g, "\n")}`; + }); + }); + }); + } +} diff --git a/src/harness/runner.ts b/src/harness/runner.ts index 70954e9e853..fb66e74b958 100644 --- a/src/harness/runner.ts +++ b/src/harness/runner.ts @@ -19,6 +19,7 @@ /// /// /// +/// /// /// @@ -62,6 +63,8 @@ function createRunner(kind: TestRunnerKind): RunnerBase { return new Test262BaselineRunner(); case "user": return new UserCodeRunner(); + case "definitely": + return new DefinitelyTypedRunner(); } ts.Debug.fail(`Unknown runner kind ${kind}`); } @@ -183,6 +186,9 @@ function handleTestConfig() { case "user": runners.push(new UserCodeRunner()); break; + case "definitely": + runners.push(new DefinitelyTypedRunner()); + break; } } } diff --git a/src/harness/runnerbase.ts b/src/harness/runnerbase.ts index 2fef2264b73..42e625a897d 100644 --- a/src/harness/runnerbase.ts +++ b/src/harness/runnerbase.ts @@ -1,7 +1,7 @@ /// -type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project" | "rwc" | "test262" | "user"; +type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project" | "rwc" | "test262" | "user" | "definitely"; type CompilerTestKind = "conformance" | "compiler"; type FourslashTestKind = "fourslash" | "fourslash-shims" | "fourslash-shims-pp" | "fourslash-server"; diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json index 6e61b7690bc..96f1999e9e8 100644 --- a/src/harness/tsconfig.json +++ b/src/harness/tsconfig.json @@ -93,6 +93,7 @@ "loggedIO.ts", "rwcRunner.ts", "userRunner.ts", + "definitelyRunner.ts", "test262Runner.ts", "./parallel/shared.ts", "./parallel/host.ts", diff --git a/src/harness/userRunner.ts b/src/harness/userRunner.ts index 9be652aebf8..61a46d7e84f 100644 --- a/src/harness/userRunner.ts +++ b/src/harness/userRunner.ts @@ -36,7 +36,7 @@ class UserCodeRunner extends RunnerBase { const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout, shell: true, stdio }); if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed!`); Harness.Baseline.runBaseline(`${this.kind()}/${directoryName}.log`, () => { - const result = cp.spawnSync(`node`, ["../../../../built/local/tsc.js"], { cwd, timeout, shell: true }); + const result = cp.spawnSync(`node`, [path.join(__dirname, "tsc.js")], { cwd, timeout, shell: true }); return `Exit Code: ${result.status} Standard output: ${result.stdout.toString().replace(/\r\n/g, "\n")} From f2d4b36a49df7e7fb7a828b68d88a86f41f58717 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 6 Nov 2017 15:17:21 -0800 Subject: [PATCH 146/235] Update Jakefile with definitelyRunner.ts --- Jakefile.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Jakefile.js b/Jakefile.js index 7f0915ad7e9..40520e79a4a 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -106,6 +106,7 @@ var harnessCoreSources = [ "loggedIO.ts", "rwcRunner.ts", "userRunner.ts", + "definitelyRunner.ts", "test262Runner.ts", "./parallel/shared.ts", "./parallel/host.ts", From 3f34525c81143e9b3d8fe728afa30eeaf0eb5bc4 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 6 Nov 2017 14:39:23 -0800 Subject: [PATCH 147/235] Handle the folder create/delete in the configured project --- src/compiler/core.ts | 17 ++++++--- src/compiler/watch.ts | 37 ++++++++++++------- src/compiler/watchUtilities.ts | 8 ++++ .../unittests/tsserverProjectSystem.ts | 6 +-- src/server/editorServices.ts | 26 +++++++++---- src/server/project.ts | 17 ++++++--- 6 files changed, 74 insertions(+), 37 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index f2249641ff4..8709d39aa8c 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2855,10 +2855,9 @@ namespace ts { function addOrDeleteFileOrDirectory(fileOrDirectory: string, fileOrDirectoryPath: Path) { const existingResult = getCachedFileSystemEntries(fileOrDirectoryPath); if (existingResult) { - // This was a folder already present, remove it if this doesnt exist any more - if (!host.directoryExists(fileOrDirectory)) { - cachedReadDirectoryResult.delete(fileOrDirectoryPath); - } + // Just clear the cache for now + // For now just clear the cache, since this could mean that multiple level entries might need to be re-evaluated + clearCache(); } else { // This was earlier a file (hence not in cached directory contents) @@ -2871,8 +2870,14 @@ namespace ts { fileExists: host.fileExists(fileOrDirectoryPath), directoryExists: host.directoryExists(fileOrDirectoryPath) }; - updateFilesOfFileSystemEntry(parentResult, baseName, fsQueryResult.fileExists); - updateFileSystemEntry(parentResult.directories, baseName, fsQueryResult.directoryExists); + if (fsQueryResult.directoryExists || hasEntry(parentResult.directories, baseName)) { + // Folder added or removed, clear the cache instead of updating the folder and its structure + clearCache(); + } + else { + // No need to update the directory structure, just files + updateFilesOfFileSystemEntry(parentResult, baseName, fsQueryResult.fileExists); + } return fsQueryResult; } } diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 53692fe1e04..8e49bb71a15 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -230,7 +230,7 @@ namespace ts { function createWatchMode(rootFileNames: string[], compilerOptions: CompilerOptions, watchingHost?: WatchingSystemHost, configFileName?: string, configFileSpecs?: ConfigFileSpecs, configFileWildCardDirectories?: MapLike, optionsToExtendForConfigFile?: CompilerOptions) { let program: Program; - let needsReload: boolean; // true if the config file changed and needs to reload it from the disk + let reloadLevel: ConfigFileProgramReloadLevel; // level to indicate if the program needs to be reloaded from config file/just filenames etc let missingFilesMap: Map; // Map of file watchers for the missing files let watchedWildcardDirectories: Map; // map of watchers for the wild card directories in the config file let timerToUpdateProgram: any; // timer callback to recompile the program @@ -488,7 +488,7 @@ namespace ts { function scheduleProgramReload() { Debug.assert(!!configFileName); - needsReload = true; + reloadLevel = ConfigFileProgramReloadLevel.Full; scheduleProgramUpdate(); } @@ -496,17 +496,30 @@ namespace ts { timerToUpdateProgram = undefined; reportWatchDiagnostic(createCompilerDiagnostic(Diagnostics.File_change_detected_Starting_incremental_compilation)); - if (needsReload) { - reloadConfigFile(); + switch (reloadLevel) { + case ConfigFileProgramReloadLevel.Partial: + return reloadFileNamesFromConfigFile(); + case ConfigFileProgramReloadLevel.Full: + return reloadConfigFile(); + default: + return synchronizeProgram(); } - else { - synchronizeProgram(); + } + + function reloadFileNamesFromConfigFile() { + const result = getFileNamesFromConfigSpecs(configFileSpecs, getDirectoryPath(configFileName), compilerOptions, directoryStructureHost); + if (!configFileSpecs.filesSpecs && result.fileNames.length === 0) { + reportDiagnostic(getErrorForNoInputFiles(configFileSpecs, configFileName)); } + rootFileNames = result.fileNames; + + // Update the program + synchronizeProgram(); } function reloadConfigFile() { writeLog(`Reloading config file: ${configFileName}`); - needsReload = false; + reloadLevel = ConfigFileProgramReloadLevel.None; const cachedHost = directoryStructureHost as CachedDirectoryStructureHost; cachedHost.clearCache(); @@ -611,18 +624,14 @@ namespace ts { // If the the added or created file or directory is not supported file name, ignore the file // But when watched directory is added/removed, we need to reload the file list - if (fileOrDirectoryPath !== directory && !isSupportedSourceFileName(fileOrDirectory, compilerOptions)) { + if (fileOrDirectoryPath !== directory && hasExtension(fileOrDirectoryPath) && !isSupportedSourceFileName(fileOrDirectory, compilerOptions)) { writeLog(`Project: ${configFileName} Detected file add/remove of non supported extension: ${fileOrDirectory}`); return; } // Reload is pending, do the reload - if (!needsReload) { - const result = getFileNamesFromConfigSpecs(configFileSpecs, getDirectoryPath(configFileName), compilerOptions, directoryStructureHost); - if (!configFileSpecs.filesSpecs && result.fileNames.length === 0) { - reportDiagnostic(getErrorForNoInputFiles(configFileSpecs, configFileName)); - } - rootFileNames = result.fileNames; + if (reloadLevel !== ConfigFileProgramReloadLevel.Full) { + reloadLevel = ConfigFileProgramReloadLevel.Partial; // Schedule Update the program scheduleProgramUpdate(); diff --git a/src/compiler/watchUtilities.ts b/src/compiler/watchUtilities.ts index f39024d5a7c..0cf38f372d9 100644 --- a/src/compiler/watchUtilities.ts +++ b/src/compiler/watchUtilities.ts @@ -2,6 +2,14 @@ /* @internal */ namespace ts { + export enum ConfigFileProgramReloadLevel { + None, + /** Update the file name list from the disk */ + Partial, + /** Reload completely by re-reading contents of config file from disk and updating program */ + Full + } + /** * Updates the existing missing file watches with the new set of missing files after new program is created */ diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index b281f8763a0..fc38b2d7870 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -5710,8 +5710,8 @@ namespace ts.projectSystem { { "path": "/a/b/node_modules/.staging/lodash-b0733faa/index.js", "content": "module.exports = require('./lodash');" }, { "path": "/a/b/node_modules/.staging/typescript-8493ea5d/package.json.3017591594" } ].map(getRootedFileOrFolder)); - // Since we didnt add any supported extension file, there wont be any timeout scheduled - verifyAfterPartialOrCompleteNpmInstall(0); + // Since we added/removed folder, scheduled project update + verifyAfterPartialOrCompleteNpmInstall(2); // Remove file "/a/b/node_modules/.staging/typescript-8493ea5d/package.json.3017591594" filesAndFoldersToAdd.length--; @@ -5732,7 +5732,7 @@ namespace ts.projectSystem { { "path": "/a/b/node_modules/.staging/rxjs-22375c61/testing" }, { "path": "/a/b/node_modules/.staging/rxjs-22375c61/package.json.2252192041", "content": "{\n \"_args\": [\n [\n {\n \"raw\": \"rxjs@^5.4.2\",\n \"scope\": null,\n \"escapedName\": \"rxjs\",\n \"name\": \"rxjs\",\n \"rawSpec\": \"^5.4.2\",\n \"spec\": \">=5.4.2 <6.0.0\",\n \"type\": \"range\"\n },\n \"C:\\\\Users\\\\shkamat\\\\Desktop\\\\app\"\n ]\n ],\n \"_from\": \"rxjs@>=5.4.2 <6.0.0\",\n \"_id\": \"rxjs@5.4.3\",\n \"_inCache\": true,\n \"_location\": \"/rxjs\",\n \"_nodeVersion\": \"7.7.2\",\n \"_npmOperationalInternal\": {\n \"host\": \"s3://npm-registry-packages\",\n \"tmp\": \"tmp/rxjs-5.4.3.tgz_1502407898166_0.6800217325799167\"\n },\n \"_npmUser\": {\n \"name\": \"blesh\",\n \"email\": \"ben@benlesh.com\"\n },\n \"_npmVersion\": \"5.3.0\",\n \"_phantomChildren\": {},\n \"_requested\": {\n \"raw\": \"rxjs@^5.4.2\",\n \"scope\": null,\n \"escapedName\": \"rxjs\",\n \"name\": \"rxjs\",\n \"rawSpec\": \"^5.4.2\",\n \"spec\": \">=5.4.2 <6.0.0\",\n \"type\": \"range\"\n },\n \"_requiredBy\": [\n \"/\"\n ],\n \"_resolved\": \"https://registry.npmjs.org/rxjs/-/rxjs-5.4.3.tgz\",\n \"_shasum\": \"0758cddee6033d68e0fd53676f0f3596ce3d483f\",\n \"_shrinkwrap\": null,\n \"_spec\": \"rxjs@^5.4.2\",\n \"_where\": \"C:\\\\Users\\\\shkamat\\\\Desktop\\\\app\",\n \"author\": {\n \"name\": \"Ben Lesh\",\n \"email\": \"ben@benlesh.com\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/ReactiveX/RxJS/issues\"\n },\n \"config\": {\n \"commitizen\": {\n \"path\": \"cz-conventional-changelog\"\n }\n },\n \"contributors\": [\n {\n \"name\": \"Ben Lesh\",\n \"email\": \"ben@benlesh.com\"\n },\n {\n \"name\": \"Paul Taylor\",\n \"email\": \"paul.e.taylor@me.com\"\n },\n {\n \"name\": \"Jeff Cross\",\n \"email\": \"crossj@google.com\"\n },\n {\n \"name\": \"Matthew Podwysocki\",\n \"email\": \"matthewp@microsoft.com\"\n },\n {\n \"name\": \"OJ Kwon\",\n \"email\": \"kwon.ohjoong@gmail.com\"\n },\n {\n \"name\": \"Andre Staltz\",\n \"email\": \"andre@staltz.com\"\n }\n ],\n \"dependencies\": {\n \"symbol-observable\": \"^1.0.1\"\n },\n \"description\": \"Reactive Extensions for modern JavaScript\",\n \"devDependencies\": {\n \"babel-polyfill\": \"^6.23.0\",\n \"benchmark\": \"^2.1.0\",\n \"benchpress\": \"2.0.0-beta.1\",\n \"chai\": \"^3.5.0\",\n \"color\": \"^0.11.1\",\n \"colors\": \"1.1.2\",\n \"commitizen\": \"^2.8.6\",\n \"coveralls\": \"^2.11.13\",\n \"cz-conventional-changelog\": \"^1.2.0\",\n \"danger\": \"^1.1.0\",\n \"doctoc\": \"^1.0.0\",\n \"escape-string-regexp\": \"^1.0.5 \",\n \"esdoc\": \"^0.4.7\",\n \"eslint\": \"^3.8.0\",\n \"fs-extra\": \"^2.1.2\",\n \"get-folder-size\": \"^1.0.0\",\n \"glob\": \"^7.0.3\",\n \"gm\": \"^1.22.0\",\n \"google-closure-compiler-js\": \"^20170218.0.0\",\n \"gzip-size\": \"^3.0.0\",\n \"http-server\": \"^0.9.0\",\n \"husky\": \"^0.13.3\",\n \"lint-staged\": \"3.2.5\",\n \"lodash\": \"^4.15.0\",\n \"madge\": \"^1.4.3\",\n \"markdown-doctest\": \"^0.9.1\",\n \"minimist\": \"^1.2.0\",\n \"mkdirp\": \"^0.5.1\",\n \"mocha\": \"^3.0.2\",\n \"mocha-in-sauce\": \"0.0.1\",\n \"npm-run-all\": \"^4.0.2\",\n \"npm-scripts-info\": \"^0.3.4\",\n \"nyc\": \"^10.2.0\",\n \"opn-cli\": \"^3.1.0\",\n \"platform\": \"^1.3.1\",\n \"promise\": \"^7.1.1\",\n \"protractor\": \"^3.1.1\",\n \"rollup\": \"0.36.3\",\n \"rollup-plugin-inject\": \"^2.0.0\",\n \"rollup-plugin-node-resolve\": \"^2.0.0\",\n \"rx\": \"latest\",\n \"rxjs\": \"latest\",\n \"shx\": \"^0.2.2\",\n \"sinon\": \"^2.1.0\",\n \"sinon-chai\": \"^2.9.0\",\n \"source-map-support\": \"^0.4.0\",\n \"tslib\": \"^1.5.0\",\n \"tslint\": \"^4.4.2\",\n \"typescript\": \"~2.0.6\",\n \"typings\": \"^2.0.0\",\n \"validate-commit-msg\": \"^2.14.0\",\n \"watch\": \"^1.0.1\",\n \"webpack\": \"^1.13.1\",\n \"xmlhttprequest\": \"1.8.0\"\n },\n \"directories\": {},\n \"dist\": {\n \"integrity\": \"sha512-fSNi+y+P9ss+EZuV0GcIIqPUK07DEaMRUtLJvdcvMyFjc9dizuDjere+A4V7JrLGnm9iCc+nagV/4QdMTkqC4A==\",\n \"shasum\": \"0758cddee6033d68e0fd53676f0f3596ce3d483f\",\n \"tarball\": \"https://registry.npmjs.org/rxjs/-/rxjs-5.4.3.tgz\"\n },\n \"engines\": {\n \"npm\": \">=2.0.0\"\n },\n \"homepage\": \"https://github.com/ReactiveX/RxJS\",\n \"keywords\": [\n \"Rx\",\n \"RxJS\",\n \"ReactiveX\",\n \"ReactiveExtensions\",\n \"Streams\",\n \"Observables\",\n \"Observable\",\n \"Stream\",\n \"ES6\",\n \"ES2015\"\n ],\n \"license\": \"Apache-2.0\",\n \"lint-staged\": {\n \"*.@(js)\": [\n \"eslint --fix\",\n \"git add\"\n ],\n \"*.@(ts)\": [\n \"tslint --fix\",\n \"git add\"\n ]\n },\n \"main\": \"Rx.js\",\n \"maintainers\": [\n {\n \"name\": \"blesh\",\n \"email\": \"ben@benlesh.com\"\n }\n ],\n \"name\": \"rxjs\",\n \"optionalDependencies\": {},\n \"readme\": \"ERROR: No README data found!\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+ssh://git@github.com/ReactiveX/RxJS.git\"\n },\n \"scripts-info\": {\n \"info\": \"List available script\",\n \"build_all\": \"Build all packages (ES6, CJS, UMD) and generate packages\",\n \"build_cjs\": \"Build CJS package with clean up existing build, copy source into dist\",\n \"build_es6\": \"Build ES6 package with clean up existing build, copy source into dist\",\n \"build_closure_core\": \"Minify Global core build using closure compiler\",\n \"build_global\": \"Build Global package, then minify build\",\n \"build_perf\": \"Build CJS & Global build, run macro performance test\",\n \"build_test\": \"Build CJS package & test spec, execute mocha test runner\",\n \"build_cover\": \"Run lint to current code, build CJS & test spec, execute test coverage\",\n \"build_docs\": \"Build ES6 & global package, create documentation using it\",\n \"build_spec\": \"Build test specs\",\n \"check_circular_dependencies\": \"Check codebase has circular dependencies\",\n \"clean_spec\": \"Clean up existing test spec build output\",\n \"clean_dist_cjs\": \"Clean up existing CJS package output\",\n \"clean_dist_es6\": \"Clean up existing ES6 package output\",\n \"clean_dist_global\": \"Clean up existing Global package output\",\n \"commit\": \"Run git commit wizard\",\n \"compile_dist_cjs\": \"Compile codebase into CJS module\",\n \"compile_module_es6\": \"Compile codebase into ES6\",\n \"cover\": \"Execute test coverage\",\n \"lint_perf\": \"Run lint against performance test suite\",\n \"lint_spec\": \"Run lint against test spec\",\n \"lint_src\": \"Run lint against source\",\n \"lint\": \"Run lint against everything\",\n \"perf\": \"Run macro performance benchmark\",\n \"perf_micro\": \"Run micro performance benchmark\",\n \"test_mocha\": \"Execute mocha test runner against existing test spec build\",\n \"test_browser\": \"Execute mocha test runner on browser against existing test spec build\",\n \"test\": \"Clean up existing test spec build, build test spec and execute mocha test runner\",\n \"tests2png\": \"Generate marble diagram image from test spec\",\n \"watch\": \"Watch codebase, trigger compile when source code changes\"\n },\n \"typings\": \"Rx.d.ts\",\n \"version\": \"5.4.3\"\n}\n" } ].map(getRootedFileOrFolder)); - verifyAfterPartialOrCompleteNpmInstall(0); + verifyAfterPartialOrCompleteNpmInstall(2); // remove /a/b/node_modules/.staging/rxjs-22375c61/package.json.2252192041 filesAndFoldersToAdd.length--; diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 086bb6b38d8..b7c0ba2bc21 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -799,17 +799,14 @@ namespace ts.server { // If the the added or created file or directory is not supported file name, ignore the file // But when watched directory is added/removed, we need to reload the file list - if (fileOrDirectoryPath !== directory && !isSupportedSourceFileName(fileOrDirectory, project.getCompilationSettings(), this.hostConfiguration.extraFileExtensions)) { + if (fileOrDirectoryPath !== directory && hasExtension(fileOrDirectoryPath) && !isSupportedSourceFileName(fileOrDirectory, project.getCompilationSettings(), this.hostConfiguration.extraFileExtensions)) { this.logger.info(`Project: ${configFilename} Detected file add/remove of non supported extension: ${fileOrDirectory}`); return; } // Reload is pending, do the reload - if (!project.pendingReload) { - const configFileSpecs = project.configFileSpecs; - const result = getFileNamesFromConfigSpecs(configFileSpecs, getDirectoryPath(configFilename), project.getCompilationSettings(), project.getCachedDirectoryStructureHost(), this.hostConfiguration.extraFileExtensions); - project.updateErrorOnNoInputFiles(result.fileNames.length !== 0); - this.updateNonInferredProjectFiles(project, result.fileNames, fileNamePropertyReader); + if (project.pendingReload !== ConfigFileProgramReloadLevel.Full) { + project.pendingReload = ConfigFileProgramReloadLevel.Partial; this.delayUpdateProjectGraphAndInferredProjectsRefresh(project); } }, @@ -842,7 +839,7 @@ namespace ts.server { } else { this.logConfigFileWatchUpdate(project.getConfigFilePath(), project.canonicalConfigFilePath, configFileExistenceInfo, ConfigFileWatcherStatus.ReloadingInferredRootFiles); - project.pendingReload = true; + project.pendingReload = ConfigFileProgramReloadLevel.Full; this.delayUpdateProjectGraph(project); // As we scheduled the update on configured project graph, // we would need to schedule the project reload for only the root of inferred projects @@ -1590,6 +1587,19 @@ namespace ts.server { this.addFilesToNonInferredProjectAndUpdateGraph(project, newUncheckedFiles, propertyReader, newTypeAcquisition); } + /** + * Reload the file names from config file specs and update the project graph + */ + /*@internal*/ + reloadFileNamesOfConfiguredProject(project: ConfiguredProject): boolean { + const configFileSpecs = project.configFileSpecs; + const configFileName = project.getConfigFilePath(); + const fileNamesResult = getFileNamesFromConfigSpecs(configFileSpecs, getDirectoryPath(configFileName), project.getCompilationSettings(), project.getCachedDirectoryStructureHost(), this.hostConfiguration.extraFileExtensions); + project.updateErrorOnNoInputFiles(fileNamesResult.fileNames.length !== 0); + this.updateNonInferredProjectFiles(project, fileNamesResult.fileNames, fileNamePropertyReader); + return project.updateGraph(); + } + /** * Read the config file of the project again and update the project */ @@ -1884,7 +1894,7 @@ namespace ts.server { } else if (!updatedProjects.has(configFileName)) { if (delayReload) { - project.pendingReload = true; + project.pendingReload = ConfigFileProgramReloadLevel.Full; this.delayUpdateProjectGraph(project); } else { diff --git a/src/server/project.ts b/src/server/project.ts index edb1d6730e9..edb05205df3 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1121,7 +1121,7 @@ namespace ts.server { readonly canonicalConfigFilePath: NormalizedPath; /* @internal */ - pendingReload: boolean; + pendingReload: ConfigFileProgramReloadLevel; /*@internal*/ configFileSpecs: ConfigFileSpecs; @@ -1161,12 +1161,17 @@ namespace ts.server { * @returns: true if set of files in the project stays the same and false - otherwise. */ updateGraph(): boolean { - if (this.pendingReload) { - this.pendingReload = false; - this.projectService.reloadConfiguredProject(this); - return true; + const reloadLevel = this.pendingReload; + this.pendingReload = ConfigFileProgramReloadLevel.None; + switch (reloadLevel) { + case ConfigFileProgramReloadLevel.Partial: + return this.projectService.reloadFileNamesOfConfiguredProject(this); + case ConfigFileProgramReloadLevel.Full: + this.projectService.reloadConfiguredProject(this); + return true; + default: + return super.updateGraph(); } - return super.updateGraph(); } /*@internal*/ From ea55de3e988cbc291f88adfd1eae48619a7cfcc6 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 6 Nov 2017 15:44:16 -0800 Subject: [PATCH 148/235] Eagerly fall back to TupleBase --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7aedfa43a5d..264b5dad105 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4993,7 +4993,7 @@ namespace ts { function getBaseTypes(type: InterfaceType): BaseType[] { if (!type.resolvedBaseTypes) { if (type.objectFlags & ObjectFlags.Tuple) { - type.resolvedBaseTypes = [createTypeFromGenericGlobalType(globalTupleBaseType || globalArrayType, [getUnionType(type.typeParameters)])]; + type.resolvedBaseTypes = [createTypeFromGenericGlobalType(globalTupleBaseType, [getUnionType(type.typeParameters)])]; } else if (type.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { if (type.symbol.flags & SymbolFlags.Class) { @@ -24526,7 +24526,7 @@ namespace ts { // TODO: ReadonlyArray and TupleBase should always be available, but haven't been required previously globalReadonlyArrayType = getGlobalTypeOrUndefined("ReadonlyArray" as __String, /*arity*/ 1); - globalTupleBaseType = getGlobalTypeOrUndefined("TupleBase" as __String, /*arity*/ 1); + globalTupleBaseType = getGlobalTypeOrUndefined("TupleBase" as __String, /*arity*/ 1) || globalArrayType; anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType; globalThisType = getGlobalTypeOrUndefined("ThisType" as __String, /*arity*/ 1); } From 888da3c3da54042acc96ac270289159730f56396 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 6 Nov 2017 15:55:16 -0800 Subject: [PATCH 149/235] Update baselines --- .../arityAndOrderCompatibility01.errors.txt | 2 +- .../reference/arityAndOrderCompatibility01.js | 2 +- .../arityAndOrderCompatibility01.symbols | 4 +-- .../arityAndOrderCompatibility01.types | 4 +-- ...nmentCompatBetweenTupleAndArray.errors.txt | 18 +++++----- .../baselines/reference/tupleTypes.errors.txt | 36 ++++++++++--------- .../typeInferenceWithTupleType.errors.txt | 31 ++++++++++++++++ .../typeInferenceWithTupleType.symbols | 4 +-- .../typeInferenceWithTupleType.types | 8 ++--- .../tuple/arityAndOrderCompatibility01.ts | 2 +- 10 files changed, 74 insertions(+), 37 deletions(-) create mode 100644 tests/baselines/reference/typeInferenceWithTupleType.errors.txt diff --git a/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt b/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt index 4d6fbd063ae..273d1f3b318 100644 --- a/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt +++ b/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt @@ -40,7 +40,7 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(32,5): error ==== tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts (19 errors) ==== - interface StrNum extends Array { + interface StrNum extends TupleBase { 0: string; 1: number; length: 2; diff --git a/tests/baselines/reference/arityAndOrderCompatibility01.js b/tests/baselines/reference/arityAndOrderCompatibility01.js index bf7736a80c9..e097b72594e 100644 --- a/tests/baselines/reference/arityAndOrderCompatibility01.js +++ b/tests/baselines/reference/arityAndOrderCompatibility01.js @@ -1,5 +1,5 @@ //// [arityAndOrderCompatibility01.ts] -interface StrNum extends Array { +interface StrNum extends TupleBase { 0: string; 1: number; length: 2; diff --git a/tests/baselines/reference/arityAndOrderCompatibility01.symbols b/tests/baselines/reference/arityAndOrderCompatibility01.symbols index 3a5d55dc1e6..8305819f593 100644 --- a/tests/baselines/reference/arityAndOrderCompatibility01.symbols +++ b/tests/baselines/reference/arityAndOrderCompatibility01.symbols @@ -1,7 +1,7 @@ === tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts === -interface StrNum extends Array { +interface StrNum extends TupleBase { >StrNum : Symbol(StrNum, Decl(arityAndOrderCompatibility01.ts, 0, 0)) ->Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>TupleBase : Symbol(TupleBase, Decl(lib.d.ts, --, --)) 0: string; 1: number; diff --git a/tests/baselines/reference/arityAndOrderCompatibility01.types b/tests/baselines/reference/arityAndOrderCompatibility01.types index 80e91fbd2e7..67a02599c40 100644 --- a/tests/baselines/reference/arityAndOrderCompatibility01.types +++ b/tests/baselines/reference/arityAndOrderCompatibility01.types @@ -1,7 +1,7 @@ === tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts === -interface StrNum extends Array { +interface StrNum extends TupleBase { >StrNum : StrNum ->Array : T[] +>TupleBase : TupleBase 0: string; 1: number; diff --git a/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt b/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt index 03dcee9baf3..53073a5300a 100644 --- a/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt +++ b/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt @@ -1,8 +1,9 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatBetweenTupleAndArray.ts(17,1): error TS2322: Type '[number, string]' is not assignable to type 'number[]'. - Types of property 'pop' are incompatible. - Type '() => string | number' is not assignable to type '() => number'. - Type 'string | number' is not assignable to type 'number'. - Type 'string' is not assignable to type 'number'. + Types of property 'concat' are incompatible. + Type '{ (...items: ReadonlyArray[]): (string | number)[]; (...items: (string | number | ReadonlyArray)[]): (string | number)[]; }' is not assignable to type '{ (...items: ReadonlyArray[]): number[]; (...items: (number | ReadonlyArray)[]): number[]; }'. + Type '(string | number)[]' is not assignable to type 'number[]'. + Type 'string | number' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatBetweenTupleAndArray.ts(18,1): error TS2322: Type '{}[]' is not assignable to type '[{}]'. Property '0' is missing in type '{}[]'. @@ -27,10 +28,11 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme numArray = numStrTuple; ~~~~~~~~ !!! error TS2322: Type '[number, string]' is not assignable to type 'number[]'. -!!! error TS2322: Types of property 'pop' are incompatible. -!!! error TS2322: Type '() => string | number' is not assignable to type '() => number'. -!!! error TS2322: Type 'string | number' is not assignable to type 'number'. -!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! error TS2322: Types of property 'concat' are incompatible. +!!! error TS2322: Type '{ (...items: ReadonlyArray[]): (string | number)[]; (...items: (string | number | ReadonlyArray)[]): (string | number)[]; }' is not assignable to type '{ (...items: ReadonlyArray[]): number[]; (...items: (number | ReadonlyArray)[]): number[]; }'. +!!! error TS2322: Type '(string | number)[]' is not assignable to type 'number[]'. +!!! error TS2322: Type 'string | number' is not assignable to type 'number'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. emptyObjTuple = emptyObjArray; ~~~~~~~~~~~~~ !!! error TS2322: Type '{}[]' is not assignable to type '[{}]'. diff --git a/tests/baselines/reference/tupleTypes.errors.txt b/tests/baselines/reference/tupleTypes.errors.txt index 16a8f66ba79..750df3f5092 100644 --- a/tests/baselines/reference/tupleTypes.errors.txt +++ b/tests/baselines/reference/tupleTypes.errors.txt @@ -10,15 +10,17 @@ tests/cases/compiler/tupleTypes.ts(18,1): error TS2322: Type '[number, string, n Type '3' is not assignable to type '2'. tests/cases/compiler/tupleTypes.ts(41,1): error TS2322: Type 'undefined[]' is not assignable to type '[number, string]'. tests/cases/compiler/tupleTypes.ts(47,1): error TS2322: Type '[number, string]' is not assignable to type 'number[]'. - Types of property 'pop' are incompatible. - Type '() => string | number' is not assignable to type '() => number'. - Type 'string | number' is not assignable to type 'number'. - Type 'string' is not assignable to type 'number'. + Types of property 'concat' are incompatible. + Type '{ (...items: ReadonlyArray[]): (string | number)[]; (...items: (string | number | ReadonlyArray)[]): (string | number)[]; }' is not assignable to type '{ (...items: ReadonlyArray[]): number[]; (...items: (number | ReadonlyArray)[]): number[]; }'. + Type '(string | number)[]' is not assignable to type 'number[]'. + Type 'string | number' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. tests/cases/compiler/tupleTypes.ts(49,1): error TS2322: Type '[number, {}]' is not assignable to type 'number[]'. - Types of property 'pop' are incompatible. - Type '() => number | {}' is not assignable to type '() => number'. - Type 'number | {}' is not assignable to type 'number'. - Type '{}' is not assignable to type 'number'. + Types of property 'concat' are incompatible. + Type '{ (...items: ReadonlyArray[]): (number | {})[]; (...items: (number | {} | ReadonlyArray)[]): (number | {})[]; }' is not assignable to type '{ (...items: ReadonlyArray[]): number[]; (...items: (number | ReadonlyArray)[]): number[]; }'. + Type '(number | {})[]' is not assignable to type 'number[]'. + Type 'number | {}' is not assignable to type 'number'. + Type '{}' is not assignable to type 'number'. tests/cases/compiler/tupleTypes.ts(50,1): error TS2322: Type '[number, number]' is not assignable to type '[number, string]'. Type 'number' is not assignable to type 'string'. tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is not assignable to type '[number, string]'. @@ -92,18 +94,20 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n a = a1; // Error ~ !!! error TS2322: Type '[number, string]' is not assignable to type 'number[]'. -!!! error TS2322: Types of property 'pop' are incompatible. -!!! error TS2322: Type '() => string | number' is not assignable to type '() => number'. -!!! error TS2322: Type 'string | number' is not assignable to type 'number'. -!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! error TS2322: Types of property 'concat' are incompatible. +!!! error TS2322: Type '{ (...items: ReadonlyArray[]): (string | number)[]; (...items: (string | number | ReadonlyArray)[]): (string | number)[]; }' is not assignable to type '{ (...items: ReadonlyArray[]): number[]; (...items: (number | ReadonlyArray)[]): number[]; }'. +!!! error TS2322: Type '(string | number)[]' is not assignable to type 'number[]'. +!!! error TS2322: Type 'string | number' is not assignable to type 'number'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. a = a2; a = a3; // Error ~ !!! error TS2322: Type '[number, {}]' is not assignable to type 'number[]'. -!!! error TS2322: Types of property 'pop' are incompatible. -!!! error TS2322: Type '() => number | {}' is not assignable to type '() => number'. -!!! error TS2322: Type 'number | {}' is not assignable to type 'number'. -!!! error TS2322: Type '{}' is not assignable to type 'number'. +!!! error TS2322: Types of property 'concat' are incompatible. +!!! error TS2322: Type '{ (...items: ReadonlyArray[]): (number | {})[]; (...items: (number | {} | ReadonlyArray)[]): (number | {})[]; }' is not assignable to type '{ (...items: ReadonlyArray[]): number[]; (...items: (number | ReadonlyArray)[]): number[]; }'. +!!! error TS2322: Type '(number | {})[]' is not assignable to type 'number[]'. +!!! error TS2322: Type 'number | {}' is not assignable to type 'number'. +!!! error TS2322: Type '{}' is not assignable to type 'number'. a1 = a2; // Error ~~ !!! error TS2322: Type '[number, number]' is not assignable to type '[number, string]'. diff --git a/tests/baselines/reference/typeInferenceWithTupleType.errors.txt b/tests/baselines/reference/typeInferenceWithTupleType.errors.txt new file mode 100644 index 00000000000..9fba99de278 --- /dev/null +++ b/tests/baselines/reference/typeInferenceWithTupleType.errors.txt @@ -0,0 +1,31 @@ +tests/cases/conformance/types/tuple/typeInferenceWithTupleType.ts(16,9): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'never' has no compatible call signatures. + + +==== tests/cases/conformance/types/tuple/typeInferenceWithTupleType.ts (1 errors) ==== + function combine(x: T, y: U): [T, U] { + return [x, y]; + } + + var combineResult = combine("string", 10); + var combineEle1 = combineResult[0]; // string + var combineEle2 = combineResult[1]; // number + + function zip(array1: T[], array2: U[]): [[T, U]] { + if (array1.length != array2.length) { + return [[undefined, undefined]]; + } + var length = array1.length; + var zipResult: [[T, U]]; + for (var i = 0; i < length; ++i) { + zipResult.push([array1[i], array2[i]]); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'never' has no compatible call signatures. + } + return zipResult; + } + + var zipResult = zip(["foo", "bar"], [5, 6]); + var zipResultEle = zipResult[0]; // [string, number] + var zipResultEleEle = zipResult[0][0]; // string + + \ No newline at end of file diff --git a/tests/baselines/reference/typeInferenceWithTupleType.symbols b/tests/baselines/reference/typeInferenceWithTupleType.symbols index 6f3279db8c2..e28ea2571dd 100644 --- a/tests/baselines/reference/typeInferenceWithTupleType.symbols +++ b/tests/baselines/reference/typeInferenceWithTupleType.symbols @@ -70,9 +70,9 @@ function zip(array1: T[], array2: U[]): [[T, U]] { >i : Symbol(i, Decl(typeInferenceWithTupleType.ts, 14, 12)) zipResult.push([array1[i], array2[i]]); ->zipResult.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>zipResult.push : Symbol(TupleBase.push, Decl(lib.d.ts, --, --)) >zipResult : Symbol(zipResult, Decl(typeInferenceWithTupleType.ts, 13, 7)) ->push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>push : Symbol(TupleBase.push, Decl(lib.d.ts, --, --)) >array1 : Symbol(array1, Decl(typeInferenceWithTupleType.ts, 8, 19)) >i : Symbol(i, Decl(typeInferenceWithTupleType.ts, 14, 12)) >array2 : Symbol(array2, Decl(typeInferenceWithTupleType.ts, 8, 31)) diff --git a/tests/baselines/reference/typeInferenceWithTupleType.types b/tests/baselines/reference/typeInferenceWithTupleType.types index a7f8bff6798..e546a127758 100644 --- a/tests/baselines/reference/typeInferenceWithTupleType.types +++ b/tests/baselines/reference/typeInferenceWithTupleType.types @@ -82,11 +82,11 @@ function zip(array1: T[], array2: U[]): [[T, U]] { >i : number zipResult.push([array1[i], array2[i]]); ->zipResult.push([array1[i], array2[i]]) : number ->zipResult.push : (...items: [T, U][]) => number +>zipResult.push([array1[i], array2[i]]) : any +>zipResult.push : never >zipResult : [[T, U]] ->push : (...items: [T, U][]) => number ->[array1[i], array2[i]] : [T, U] +>push : never +>[array1[i], array2[i]] : (T | U)[] >array1[i] : T >array1 : T[] >i : number diff --git a/tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts b/tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts index 85a035d472b..ebd7738125e 100644 --- a/tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts +++ b/tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts @@ -1,4 +1,4 @@ -interface StrNum extends Array { +interface StrNum extends TupleBase { 0: string; 1: number; length: 2; From d79c37cd191a5d10ad678f2a1379c6267e914bf2 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 6 Nov 2017 16:09:35 -0800 Subject: [PATCH 150/235] Discriminate contextual types (#19733) * Discriminate contextual types * Invert conditional * Update findMatchingDiscriminantType and baselines --- src/compiler/checker.ts | 59 ++++++++++++---- .../contextuallyTypedByDiscriminableUnion.js | 42 +++++++++++ ...textuallyTypedByDiscriminableUnion.symbols | 60 ++++++++++++++++ ...ontextuallyTypedByDiscriminableUnion.types | 70 +++++++++++++++++++ .../excessPropertyCheckWithUnions.errors.txt | 18 +++-- .../excessPropertyCheckWithUnions.js | 4 +- .../excessPropertyCheckWithUnions.symbols | 2 +- .../excessPropertyCheckWithUnions.types | 6 +- .../contextuallyTypedByDiscriminableUnion.ts | 25 +++++++ .../compiler/excessPropertyCheckWithUnions.ts | 2 +- 10 files changed, 262 insertions(+), 26 deletions(-) create mode 100644 tests/baselines/reference/contextuallyTypedByDiscriminableUnion.js create mode 100644 tests/baselines/reference/contextuallyTypedByDiscriminableUnion.symbols create mode 100644 tests/baselines/reference/contextuallyTypedByDiscriminableUnion.types create mode 100644 tests/cases/compiler/contextuallyTypedByDiscriminableUnion.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 649deef7e3a..7d9a32a8f92 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9269,20 +9269,24 @@ namespace ts { return Ternary.False; } + // Keep this up-to-date with the same logic within `getApparentTypeOfContextualType`, since they should behave similarly function findMatchingDiscriminantType(source: Type, target: UnionOrIntersectionType) { let match: Type; const sourceProperties = getPropertiesOfObjectType(source); if (sourceProperties) { - const sourceProperty = findSingleDiscriminantProperty(sourceProperties, target); - if (sourceProperty) { - const sourceType = getTypeOfSymbol(sourceProperty); - for (const type of target.types) { - const targetType = getTypeOfPropertyOfType(type, sourceProperty.escapedName); - if (targetType && isRelatedTo(sourceType, targetType)) { - if (match) { - return undefined; + const sourcePropertiesFiltered = findDiscriminantProperties(sourceProperties, target); + if (sourcePropertiesFiltered) { + for (const sourceProperty of sourcePropertiesFiltered) { + const sourceType = getTypeOfSymbol(sourceProperty); + for (const type of target.types) { + const targetType = getTypeOfPropertyOfType(type, sourceProperty.escapedName); + if (targetType && isRelatedTo(sourceType, targetType)) { + if (type === match) continue; // Finding multiple fields which discriminate to the same type is fine + if (match) { + return undefined; + } + match = type; } - match = type; } } } @@ -11396,14 +11400,15 @@ namespace ts { return false; } - function findSingleDiscriminantProperty(sourceProperties: Symbol[], target: Type): Symbol | undefined { - let result: Symbol; + function findDiscriminantProperties(sourceProperties: Symbol[], target: Type): Symbol[] | undefined { + let result: Symbol[]; for (const sourceProperty of sourceProperties) { if (isDiscriminantProperty(target, sourceProperty.escapedName)) { if (result) { - return undefined; + result.push(sourceProperty); + continue; } - result = sourceProperty; + result = [sourceProperty]; } } return result; @@ -13691,8 +13696,32 @@ namespace ts { // Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily // be "pushed" onto a node using the contextualType property. function getApparentTypeOfContextualType(node: Expression): Type { - const type = getContextualType(node); - return type && mapType(type, getApparentType); + let contextualType = getContextualType(node); + contextualType = contextualType && mapType(contextualType, getApparentType); + if (!(contextualType && contextualType.flags & TypeFlags.Union && isObjectLiteralExpression(node))) { + return contextualType; + } + // Keep the below up-to-date with the work done within `isRelatedTo` by `findMatchingDiscriminantType` + let match: Type | undefined; + propLoop: for (const prop of node.properties) { + if (!prop.symbol) continue; + if (prop.kind !== SyntaxKind.PropertyAssignment) continue; + if (isDiscriminantProperty(contextualType, prop.symbol.escapedName)) { + const discriminatingType = getTypeOfNode(prop.initializer); + for (const type of (contextualType as UnionType).types) { + const targetType = getTypeOfPropertyOfType(type, prop.symbol.escapedName); + if (targetType && checkTypeAssignableTo(discriminatingType, targetType, /*errorNode*/ undefined)) { + if (match) { + if (type === match) continue; // Finding multiple fields which discriminate to the same type is fine + match = undefined; + break propLoop; + } + match = type; + } + } + } + } + return match || contextualType; } /** diff --git a/tests/baselines/reference/contextuallyTypedByDiscriminableUnion.js b/tests/baselines/reference/contextuallyTypedByDiscriminableUnion.js new file mode 100644 index 00000000000..b61c235dee9 --- /dev/null +++ b/tests/baselines/reference/contextuallyTypedByDiscriminableUnion.js @@ -0,0 +1,42 @@ +//// [contextuallyTypedByDiscriminableUnion.ts] +type ADT = { + kind: "a", + method(x: string): number; +} | { + kind: "b", + method(x: number): string; +}; + + +function invoke(item: ADT) { + if (item.kind === "a") { + item.method(""); + } + else { + item.method(42); + } +} + +invoke({ + kind: "a", + method(a) { + return +a; + } +}); + + +//// [contextuallyTypedByDiscriminableUnion.js] +function invoke(item) { + if (item.kind === "a") { + item.method(""); + } + else { + item.method(42); + } +} +invoke({ + kind: "a", + method: function (a) { + return +a; + } +}); diff --git a/tests/baselines/reference/contextuallyTypedByDiscriminableUnion.symbols b/tests/baselines/reference/contextuallyTypedByDiscriminableUnion.symbols new file mode 100644 index 00000000000..e4ef8ee73e7 --- /dev/null +++ b/tests/baselines/reference/contextuallyTypedByDiscriminableUnion.symbols @@ -0,0 +1,60 @@ +=== tests/cases/compiler/contextuallyTypedByDiscriminableUnion.ts === +type ADT = { +>ADT : Symbol(ADT, Decl(contextuallyTypedByDiscriminableUnion.ts, 0, 0)) + + kind: "a", +>kind : Symbol(kind, Decl(contextuallyTypedByDiscriminableUnion.ts, 0, 12)) + + method(x: string): number; +>method : Symbol(method, Decl(contextuallyTypedByDiscriminableUnion.ts, 1, 14)) +>x : Symbol(x, Decl(contextuallyTypedByDiscriminableUnion.ts, 2, 11)) + +} | { + kind: "b", +>kind : Symbol(kind, Decl(contextuallyTypedByDiscriminableUnion.ts, 3, 5)) + + method(x: number): string; +>method : Symbol(method, Decl(contextuallyTypedByDiscriminableUnion.ts, 4, 14)) +>x : Symbol(x, Decl(contextuallyTypedByDiscriminableUnion.ts, 5, 11)) + +}; + + +function invoke(item: ADT) { +>invoke : Symbol(invoke, Decl(contextuallyTypedByDiscriminableUnion.ts, 6, 2)) +>item : Symbol(item, Decl(contextuallyTypedByDiscriminableUnion.ts, 9, 16)) +>ADT : Symbol(ADT, Decl(contextuallyTypedByDiscriminableUnion.ts, 0, 0)) + + if (item.kind === "a") { +>item.kind : Symbol(kind, Decl(contextuallyTypedByDiscriminableUnion.ts, 0, 12), Decl(contextuallyTypedByDiscriminableUnion.ts, 3, 5)) +>item : Symbol(item, Decl(contextuallyTypedByDiscriminableUnion.ts, 9, 16)) +>kind : Symbol(kind, Decl(contextuallyTypedByDiscriminableUnion.ts, 0, 12), Decl(contextuallyTypedByDiscriminableUnion.ts, 3, 5)) + + item.method(""); +>item.method : Symbol(method, Decl(contextuallyTypedByDiscriminableUnion.ts, 1, 14)) +>item : Symbol(item, Decl(contextuallyTypedByDiscriminableUnion.ts, 9, 16)) +>method : Symbol(method, Decl(contextuallyTypedByDiscriminableUnion.ts, 1, 14)) + } + else { + item.method(42); +>item.method : Symbol(method, Decl(contextuallyTypedByDiscriminableUnion.ts, 4, 14)) +>item : Symbol(item, Decl(contextuallyTypedByDiscriminableUnion.ts, 9, 16)) +>method : Symbol(method, Decl(contextuallyTypedByDiscriminableUnion.ts, 4, 14)) + } +} + +invoke({ +>invoke : Symbol(invoke, Decl(contextuallyTypedByDiscriminableUnion.ts, 6, 2)) + + kind: "a", +>kind : Symbol(kind, Decl(contextuallyTypedByDiscriminableUnion.ts, 18, 8)) + + method(a) { +>method : Symbol(method, Decl(contextuallyTypedByDiscriminableUnion.ts, 19, 14)) +>a : Symbol(a, Decl(contextuallyTypedByDiscriminableUnion.ts, 20, 11)) + + return +a; +>a : Symbol(a, Decl(contextuallyTypedByDiscriminableUnion.ts, 20, 11)) + } +}); + diff --git a/tests/baselines/reference/contextuallyTypedByDiscriminableUnion.types b/tests/baselines/reference/contextuallyTypedByDiscriminableUnion.types new file mode 100644 index 00000000000..d62dc4b5e0c --- /dev/null +++ b/tests/baselines/reference/contextuallyTypedByDiscriminableUnion.types @@ -0,0 +1,70 @@ +=== tests/cases/compiler/contextuallyTypedByDiscriminableUnion.ts === +type ADT = { +>ADT : ADT + + kind: "a", +>kind : "a" + + method(x: string): number; +>method : (x: string) => number +>x : string + +} | { + kind: "b", +>kind : "b" + + method(x: number): string; +>method : (x: number) => string +>x : number + +}; + + +function invoke(item: ADT) { +>invoke : (item: ADT) => void +>item : ADT +>ADT : ADT + + if (item.kind === "a") { +>item.kind === "a" : boolean +>item.kind : "a" | "b" +>item : ADT +>kind : "a" | "b" +>"a" : "a" + + item.method(""); +>item.method("") : number +>item.method : (x: string) => number +>item : { kind: "a"; method(x: string): number; } +>method : (x: string) => number +>"" : "" + } + else { + item.method(42); +>item.method(42) : string +>item.method : (x: number) => string +>item : { kind: "b"; method(x: number): string; } +>method : (x: number) => string +>42 : 42 + } +} + +invoke({ +>invoke({ kind: "a", method(a) { return +a; }}) : void +>invoke : (item: ADT) => void +>{ kind: "a", method(a) { return +a; }} : { kind: "a"; method(a: string): number; } + + kind: "a", +>kind : string +>"a" : "a" + + method(a) { +>method : (a: string) => number +>a : string + + return +a; +>+a : number +>a : string + } +}); + diff --git a/tests/baselines/reference/excessPropertyCheckWithUnions.errors.txt b/tests/baselines/reference/excessPropertyCheckWithUnions.errors.txt index 9fbbb001605..d802733354e 100644 --- a/tests/baselines/reference/excessPropertyCheckWithUnions.errors.txt +++ b/tests/baselines/reference/excessPropertyCheckWithUnions.errors.txt @@ -1,6 +1,6 @@ tests/cases/compiler/excessPropertyCheckWithUnions.ts(10,30): error TS2322: Type '{ tag: "T"; a1: string; }' is not assignable to type 'ADT'. Object literal may only specify known properties, and 'a1' does not exist in type '{ tag: "T"; }'. -tests/cases/compiler/excessPropertyCheckWithUnions.ts(11,21): error TS2322: Type '{ tag: "A"; d20: 12; }' is not assignable to type 'ADT'. +tests/cases/compiler/excessPropertyCheckWithUnions.ts(11,21): error TS2322: Type '{ tag: "A"; d20: number; }' is not assignable to type 'ADT'. Object literal may only specify known properties, and 'd20' does not exist in type '{ tag: "A"; a1: string; }'. tests/cases/compiler/excessPropertyCheckWithUnions.ts(12,1): error TS2322: Type '{ tag: "D"; }' is not assignable to type 'ADT'. Type '{ tag: "D"; }' is not assignable to type '{ tag: "D"; d20: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20; }'. @@ -17,9 +17,13 @@ tests/cases/compiler/excessPropertyCheckWithUnions.ts(40,1): error TS2322: Type Type '{ tag: "A"; z: true; }' is not assignable to type '{ tag: "C"; }'. Types of property 'tag' are incompatible. Type '"A"' is not assignable to type '"C"'. +tests/cases/compiler/excessPropertyCheckWithUnions.ts(49,35): error TS2322: Type '{ a: 1; b: 1; first: string; second: string; }' is not assignable to type 'Overlapping'. + Object literal may only specify known properties, and 'second' does not exist in type '{ a: 1; b: 1; first: string; }'. +tests/cases/compiler/excessPropertyCheckWithUnions.ts(50,35): error TS2322: Type '{ a: 1; b: 1; first: string; third: string; }' is not assignable to type 'Overlapping'. + Object literal may only specify known properties, and 'third' does not exist in type '{ a: 1; b: 1; first: string; }'. -==== tests/cases/compiler/excessPropertyCheckWithUnions.ts (7 errors) ==== +==== tests/cases/compiler/excessPropertyCheckWithUnions.ts (9 errors) ==== type ADT = { tag: "A", a1: string @@ -35,7 +39,7 @@ tests/cases/compiler/excessPropertyCheckWithUnions.ts(40,1): error TS2322: Type !!! error TS2322: Object literal may only specify known properties, and 'a1' does not exist in type '{ tag: "T"; }'. wrong = { tag: "A", d20: 12 } ~~~~~~~ -!!! error TS2322: Type '{ tag: "A"; d20: 12; }' is not assignable to type 'ADT'. +!!! error TS2322: Type '{ tag: "A"; d20: number; }' is not assignable to type 'ADT'. !!! error TS2322: Object literal may only specify known properties, and 'd20' does not exist in type '{ tag: "A"; a1: string; }'. wrong = { tag: "D" } ~~~~~ @@ -93,9 +97,15 @@ tests/cases/compiler/excessPropertyCheckWithUnions.ts(40,1): error TS2322: Type | { b: 3, third: string } let over: Overlapping - // these two are not reported because there are two discriminant properties + // these two are still errors despite their doubled up discriminants over = { a: 1, b: 1, first: "ok", second: "error" } + ~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ a: 1; b: 1; first: string; second: string; }' is not assignable to type 'Overlapping'. +!!! error TS2322: Object literal may only specify known properties, and 'second' does not exist in type '{ a: 1; b: 1; first: string; }'. over = { a: 1, b: 1, first: "ok", third: "error" } + ~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ a: 1; b: 1; first: string; third: string; }' is not assignable to type 'Overlapping'. +!!! error TS2322: Object literal may only specify known properties, and 'third' does not exist in type '{ a: 1; b: 1; first: string; }'. // Freshness disappears after spreading a union declare let t0: { a: any, b: any } | { d: any, e: any } diff --git a/tests/baselines/reference/excessPropertyCheckWithUnions.js b/tests/baselines/reference/excessPropertyCheckWithUnions.js index c6b45123cce..a20983e4b08 100644 --- a/tests/baselines/reference/excessPropertyCheckWithUnions.js +++ b/tests/baselines/reference/excessPropertyCheckWithUnions.js @@ -46,7 +46,7 @@ type Overlapping = | { b: 3, third: string } let over: Overlapping -// these two are not reported because there are two discriminant properties +// these two are still errors despite their doubled up discriminants over = { a: 1, b: 1, first: "ok", second: "error" } over = { a: 1, b: 1, first: "ok", third: "error" } @@ -84,7 +84,7 @@ amb = { tag: "A", y: 12, extra: 12 }; amb = { tag: "A" }; amb = { tag: "A", z: true }; var over; -// these two are not reported because there are two discriminant properties +// these two are still errors despite their doubled up discriminants over = { a: 1, b: 1, first: "ok", second: "error" }; over = { a: 1, b: 1, first: "ok", third: "error" }; var t2 = __assign({}, t1); diff --git a/tests/baselines/reference/excessPropertyCheckWithUnions.symbols b/tests/baselines/reference/excessPropertyCheckWithUnions.symbols index 7778c6bf216..381681de384 100644 --- a/tests/baselines/reference/excessPropertyCheckWithUnions.symbols +++ b/tests/baselines/reference/excessPropertyCheckWithUnions.symbols @@ -127,7 +127,7 @@ let over: Overlapping >over : Symbol(over, Decl(excessPropertyCheckWithUnions.ts, 45, 3)) >Overlapping : Symbol(Overlapping, Decl(excessPropertyCheckWithUnions.ts, 39, 27)) -// these two are not reported because there are two discriminant properties +// these two are still errors despite their doubled up discriminants over = { a: 1, b: 1, first: "ok", second: "error" } >over : Symbol(over, Decl(excessPropertyCheckWithUnions.ts, 45, 3)) >a : Symbol(a, Decl(excessPropertyCheckWithUnions.ts, 48, 8)) diff --git a/tests/baselines/reference/excessPropertyCheckWithUnions.types b/tests/baselines/reference/excessPropertyCheckWithUnions.types index 78f5c025b38..212eccbe2ff 100644 --- a/tests/baselines/reference/excessPropertyCheckWithUnions.types +++ b/tests/baselines/reference/excessPropertyCheckWithUnions.types @@ -29,9 +29,9 @@ let wrong: ADT = { tag: "T", a1: "extra" } >"extra" : "extra" wrong = { tag: "A", d20: 12 } ->wrong = { tag: "A", d20: 12 } : { tag: "A"; d20: 12; } +>wrong = { tag: "A", d20: 12 } : { tag: "A"; d20: number; } >wrong : ADT ->{ tag: "A", d20: 12 } : { tag: "A"; d20: 12; } +>{ tag: "A", d20: 12 } : { tag: "A"; d20: number; } >tag : string >"A" : "A" >d20 : number @@ -167,7 +167,7 @@ let over: Overlapping >over : Overlapping >Overlapping : Overlapping -// these two are not reported because there are two discriminant properties +// these two are still errors despite their doubled up discriminants over = { a: 1, b: 1, first: "ok", second: "error" } >over = { a: 1, b: 1, first: "ok", second: "error" } : { a: 1; b: 1; first: string; second: string; } >over : Overlapping diff --git a/tests/cases/compiler/contextuallyTypedByDiscriminableUnion.ts b/tests/cases/compiler/contextuallyTypedByDiscriminableUnion.ts new file mode 100644 index 00000000000..5fbcd2dbbc5 --- /dev/null +++ b/tests/cases/compiler/contextuallyTypedByDiscriminableUnion.ts @@ -0,0 +1,25 @@ +// @noImplicitAny: true +type ADT = { + kind: "a", + method(x: string): number; +} | { + kind: "b", + method(x: number): string; +}; + + +function invoke(item: ADT) { + if (item.kind === "a") { + item.method(""); + } + else { + item.method(42); + } +} + +invoke({ + kind: "a", + method(a) { + return +a; + } +}); diff --git a/tests/cases/compiler/excessPropertyCheckWithUnions.ts b/tests/cases/compiler/excessPropertyCheckWithUnions.ts index d5a2327380e..240af391cf5 100644 --- a/tests/cases/compiler/excessPropertyCheckWithUnions.ts +++ b/tests/cases/compiler/excessPropertyCheckWithUnions.ts @@ -46,7 +46,7 @@ type Overlapping = | { b: 3, third: string } let over: Overlapping -// these two are not reported because there are two discriminant properties +// these two are still errors despite their doubled up discriminants over = { a: 1, b: 1, first: "ok", second: "error" } over = { a: 1, b: 1, first: "ok", third: "error" } From 2a4519eb0f276763b3c01d78c09fc69da609f4ff Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 6 Nov 2017 16:22:30 -0800 Subject: [PATCH 151/235] Remove last bits of strictTuples flag --- src/harness/unittests/configurationExtension.ts | 6 ------ src/harness/unittests/transpile.ts | 4 ---- src/server/protocol.ts | 1 - tests/baselines/reference/api/tsserverlibrary.d.ts | 1 - 4 files changed, 12 deletions(-) diff --git a/src/harness/unittests/configurationExtension.ts b/src/harness/unittests/configurationExtension.ts index b5a9d105cc3..0032505aba1 100644 --- a/src/harness/unittests/configurationExtension.ts +++ b/src/harness/unittests/configurationExtension.ts @@ -16,12 +16,6 @@ namespace ts { strictNullChecks: false } }, - "/dev/tsconfig.strictTuples.json": { - extends: "./tsconfig", - compilerOptions: { - strictTuples: false - } - }, "/dev/configs/base.json": { compilerOptions: { allowJs: true, diff --git a/src/harness/unittests/transpile.ts b/src/harness/unittests/transpile.ts index dbad72a71a0..16bef6500f2 100644 --- a/src/harness/unittests/transpile.ts +++ b/src/harness/unittests/transpile.ts @@ -410,10 +410,6 @@ var x = 0;`, { options: { compilerOptions: { strictNullChecks: true }, fileName: "input.js", reportDiagnostics: true } }); - transpilesCorrectly("Supports setting 'strictTuples'", "x;", { - options: { compilerOptions: { strictTuples: true }, fileName: "input.js", reportDiagnostics: true } - }); - transpilesCorrectly("Supports setting 'stripInternal'", "x;", { options: { compilerOptions: { stripInternal: true }, fileName: "input.js", reportDiagnostics: true } }); diff --git a/src/server/protocol.ts b/src/server/protocol.ts index a55aea9eaa7..93d5c69d361 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -2542,7 +2542,6 @@ namespace ts.server.protocol { sourceRoot?: string; strict?: boolean; strictNullChecks?: boolean; - strictTuples?: boolean; suppressExcessPropertyErrors?: boolean; suppressImplicitAnyIndexErrors?: boolean; target?: ScriptTarget | ts.ScriptTarget; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index eb25861eb68..95800d82c2e 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -6850,7 +6850,6 @@ declare namespace ts.server.protocol { sourceRoot?: string; strict?: boolean; strictNullChecks?: boolean; - strictTuples?: boolean; suppressExcessPropertyErrors?: boolean; suppressImplicitAnyIndexErrors?: boolean; target?: ScriptTarget | ts.ScriptTarget; From 381ca45787a5fc65c5655537251c5dce7a156fe0 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 6 Nov 2017 18:10:02 -0800 Subject: [PATCH 152/235] Use an enum for Msg (#19773) --- src/server/server.ts | 2 +- src/server/utilities.ts | 19 +++++++++---------- .../reference/api/tsserverlibrary.d.ts | 16 ++++++++-------- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/server/server.ts b/src/server/server.ts index 457be4a9b9a..4902983ad45 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -200,7 +200,7 @@ namespace ts.server { return this.loggingEnabled() && this.level >= level; } - msg(s: string, type: Msg.Types = Msg.Err) { + msg(s: string, type: Msg = Msg.Err) { if (!this.canWrite) return; s = `[${nowString()}] ${s}\n`; diff --git a/src/server/utilities.ts b/src/server/utilities.ts index 096d4484154..72aae2f714b 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -19,20 +19,19 @@ namespace ts.server { info(s: string): void; startGroup(): void; endGroup(): void; - msg(s: string, type?: Msg.Types): void; + msg(s: string, type?: Msg): void; getLogFileName(): string; } + // TODO: Use a const enum (https://github.com/Microsoft/TypeScript/issues/16804) + export enum Msg { + Err = "Err", + Info = "Info", + Perf = "Perf", + } export namespace Msg { - // tslint:disable variable-name - export type Err = "Err"; - export const Err: Err = "Err"; - export type Info = "Info"; - export const Info: Info = "Info"; - export type Perf = "Perf"; - export const Perf: Perf = "Perf"; - export type Types = Err | Info | Perf; - // tslint:enable variable-name + /** @deprecated Only here for backwards-compatibility. Prefer just `Msg`. */ + export type Types = Msg; } function getProjectRootPath(project: Project): Path { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 85895ffbce4..415565a6fa1 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4779,17 +4779,17 @@ declare namespace ts.server { info(s: string): void; startGroup(): void; endGroup(): void; - msg(s: string, type?: Msg.Types): void; + msg(s: string, type?: Msg): void; getLogFileName(): string; } + enum Msg { + Err = "Err", + Info = "Info", + Perf = "Perf", + } namespace Msg { - type Err = "Err"; - const Err: Err; - type Info = "Info"; - const Info: Info; - type Perf = "Perf"; - const Perf: Perf; - type Types = Err | Info | Perf; + /** @deprecated Only here for backwards-compatibility. Prefer just `Msg`. */ + type Types = Msg; } function createInstallTypingsRequest(project: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray, cachePath?: string): DiscoverTypings; namespace Errors { From 3e7af1cf1240894f6232b5b9e0f30837177f3f64 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 6 Nov 2017 18:10:14 -0800 Subject: [PATCH 153/235] Move "ban-comma-operator" to tslint rules that we won't use (#19780) --- tslint.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tslint.json b/tslint.json index 497bd5e787a..98033b92265 100644 --- a/tslint.json +++ b/tslint.json @@ -79,7 +79,6 @@ // TODO "arrow-parens": false, // [true, "ban-single-arg-parens"] "arrow-return-shorthand": false, - "ban-comma-operator": false, "ban-types": false, "forin": false, "member-access": false, // [true, "no-public"] @@ -110,6 +109,7 @@ "no-consecutive-blank-lines": false, // Not doing + "ban-comma-operator": false, "max-classes-per-file": false, "member-ordering": false, "no-angle-bracket-type-assertion": false, From 40efd1b3bd14e7e15b98053e30e2e317e2344458 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 6 Nov 2017 18:13:20 -0800 Subject: [PATCH 154/235] Apply 'object-literal-key-quotes' tslint rule (#19737) * Apply 'object-literal-key-quotes' tslint rule * Convert to "consistent-as-needed" --- Gulpfile.ts | 20 +- src/compiler/checker.ts | 38 +- src/compiler/commandLineParser.ts | 38 +- src/compiler/transformers/jsx.ts | 506 +++++++++--------- src/compiler/visitor.ts | 18 +- .../unittests/configurationExtension.ts | 8 +- .../convertCompilerOptionsFromJson.ts | 174 +++--- .../convertTypeAcquisitionFromJson.ts | 40 +- src/harness/unittests/moduleResolution.ts | 6 +- .../unittests/reuseProgramStructure.ts | 12 +- .../unittests/services/preProcessFile.ts | 32 +- src/harness/unittests/transpile.ts | 6 +- src/harness/unittests/tscWatchMode.ts | 34 +- .../unittests/tsserverProjectSystem.ts | 130 ++--- src/harness/unittests/typingsInstaller.ts | 14 +- src/server/editorServices.ts | 32 +- src/server/server.ts | 2 +- tslint.json | 2 +- 18 files changed, 556 insertions(+), 556 deletions(-) diff --git a/Gulpfile.ts b/Gulpfile.ts index a75882c5f46..84770f7edbc 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -46,15 +46,15 @@ const cmdLineOptions = minimist(process.argv.slice(2), { boolean: ["debug", "inspect", "light", "colors", "lint", "soft"], string: ["browser", "tests", "host", "reporter", "stackTraceLimit", "timeout"], alias: { - b: "browser", - d: "debug", "debug-brk": "debug", - i: "inspect", "inspect-brk": "inspect", - t: "tests", test: "tests", - ru: "runners", runner: "runners", - r: "reporter", - c: "colors", color: "colors", - f: "files", file: "files", - w: "workers", + "b": "browser", + "d": "debug", "debug-brk": "debug", + "i": "inspect", "inspect-brk": "inspect", + "t": "tests", "test": "tests", + "ru": "runners", "runner": "runners", + "r": "reporter", + "c": "colors", "color": "colors", + "f": "files", "file": "files", + "w": "workers", }, default: { soft: false, @@ -1034,7 +1034,7 @@ gulp.task("update-sublime", "Updates the sublime plugin's tsserver", ["local", s }); gulp.task("build-rules", "Compiles tslint rules to js", () => { - const settings: tsc.Settings = getCompilerSettings({ module: "commonjs", "lib": ["es6"] }, /*useBuiltCompiler*/ false); + const settings: tsc.Settings = getCompilerSettings({ module: "commonjs", lib: ["es6"] }, /*useBuiltCompiler*/ false); const dest = path.join(builtLocalDirectory, "tslint"); return gulp.src("scripts/tslint/**/*.ts") .pipe(newer({ diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7d9a32a8f92..545f38461cb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -455,29 +455,29 @@ namespace ts { } const typeofEQFacts = createMapFromTemplate({ - "string": TypeFacts.TypeofEQString, - "number": TypeFacts.TypeofEQNumber, - "boolean": TypeFacts.TypeofEQBoolean, - "symbol": TypeFacts.TypeofEQSymbol, - "undefined": TypeFacts.EQUndefined, - "object": TypeFacts.TypeofEQObject, - "function": TypeFacts.TypeofEQFunction + string: TypeFacts.TypeofEQString, + number: TypeFacts.TypeofEQNumber, + boolean: TypeFacts.TypeofEQBoolean, + symbol: TypeFacts.TypeofEQSymbol, + undefined: TypeFacts.EQUndefined, + object: TypeFacts.TypeofEQObject, + function: TypeFacts.TypeofEQFunction }); const typeofNEFacts = createMapFromTemplate({ - "string": TypeFacts.TypeofNEString, - "number": TypeFacts.TypeofNENumber, - "boolean": TypeFacts.TypeofNEBoolean, - "symbol": TypeFacts.TypeofNESymbol, - "undefined": TypeFacts.NEUndefined, - "object": TypeFacts.TypeofNEObject, - "function": TypeFacts.TypeofNEFunction + string: TypeFacts.TypeofNEString, + number: TypeFacts.TypeofNENumber, + boolean: TypeFacts.TypeofNEBoolean, + symbol: TypeFacts.TypeofNESymbol, + undefined: TypeFacts.NEUndefined, + object: TypeFacts.TypeofNEObject, + function: TypeFacts.TypeofNEFunction }); const typeofTypesByName = createMapFromTemplate({ - "string": stringType, - "number": numberType, - "boolean": booleanType, - "symbol": esSymbolType, - "undefined": undefinedType + string: stringType, + number: numberType, + boolean: booleanType, + symbol: esSymbolType, + undefined: undefinedType }); const typeofType = createTypeofType(); diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 7ba9bd80843..43ea77c8020 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -76,13 +76,13 @@ namespace ts { name: "target", shortName: "t", type: createMapFromTemplate({ - "es3": ScriptTarget.ES3, - "es5": ScriptTarget.ES5, - "es6": ScriptTarget.ES2015, - "es2015": ScriptTarget.ES2015, - "es2016": ScriptTarget.ES2016, - "es2017": ScriptTarget.ES2017, - "esnext": ScriptTarget.ESNext, + es3: ScriptTarget.ES3, + es5: ScriptTarget.ES5, + es6: ScriptTarget.ES2015, + es2015: ScriptTarget.ES2015, + es2016: ScriptTarget.ES2016, + es2017: ScriptTarget.ES2017, + esnext: ScriptTarget.ESNext, }), paramType: Diagnostics.VERSION, showInSimplifiedHelpView: true, @@ -93,14 +93,14 @@ namespace ts { name: "module", shortName: "m", type: createMapFromTemplate({ - "none": ModuleKind.None, - "commonjs": ModuleKind.CommonJS, - "amd": ModuleKind.AMD, - "system": ModuleKind.System, - "umd": ModuleKind.UMD, - "es6": ModuleKind.ES2015, - "es2015": ModuleKind.ES2015, - "esnext": ModuleKind.ESNext + none: ModuleKind.None, + commonjs: ModuleKind.CommonJS, + amd: ModuleKind.AMD, + system: ModuleKind.System, + umd: ModuleKind.UMD, + es6: ModuleKind.ES2015, + es2015: ModuleKind.ES2015, + esnext: ModuleKind.ESNext }), paramType: Diagnostics.KIND, showInSimplifiedHelpView: true, @@ -326,8 +326,8 @@ namespace ts { { name: "moduleResolution", type: createMapFromTemplate({ - "node": ModuleResolutionKind.NodeJs, - "classic": ModuleResolutionKind.Classic, + node: ModuleResolutionKind.NodeJs, + classic: ModuleResolutionKind.Classic, }), paramType: Diagnostics.STRATEGY, category: Diagnostics.Module_Resolution_Options, @@ -522,8 +522,8 @@ namespace ts { { name: "newLine", type: createMapFromTemplate({ - "crlf": NewLineKind.CarriageReturnLineFeed, - "lf": NewLineKind.LineFeed + crlf: NewLineKind.CarriageReturnLineFeed, + lf: NewLineKind.LineFeed }), paramType: Diagnostics.NEWLINE, category: Diagnostics.Advanced_Options, diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index 2be6cdef0bc..ab44db8ef4b 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -309,258 +309,258 @@ namespace ts { } const entities = createMapFromTemplate({ - "quot": 0x0022, - "amp": 0x0026, - "apos": 0x0027, - "lt": 0x003C, - "gt": 0x003E, - "nbsp": 0x00A0, - "iexcl": 0x00A1, - "cent": 0x00A2, - "pound": 0x00A3, - "curren": 0x00A4, - "yen": 0x00A5, - "brvbar": 0x00A6, - "sect": 0x00A7, - "uml": 0x00A8, - "copy": 0x00A9, - "ordf": 0x00AA, - "laquo": 0x00AB, - "not": 0x00AC, - "shy": 0x00AD, - "reg": 0x00AE, - "macr": 0x00AF, - "deg": 0x00B0, - "plusmn": 0x00B1, - "sup2": 0x00B2, - "sup3": 0x00B3, - "acute": 0x00B4, - "micro": 0x00B5, - "para": 0x00B6, - "middot": 0x00B7, - "cedil": 0x00B8, - "sup1": 0x00B9, - "ordm": 0x00BA, - "raquo": 0x00BB, - "frac14": 0x00BC, - "frac12": 0x00BD, - "frac34": 0x00BE, - "iquest": 0x00BF, - "Agrave": 0x00C0, - "Aacute": 0x00C1, - "Acirc": 0x00C2, - "Atilde": 0x00C3, - "Auml": 0x00C4, - "Aring": 0x00C5, - "AElig": 0x00C6, - "Ccedil": 0x00C7, - "Egrave": 0x00C8, - "Eacute": 0x00C9, - "Ecirc": 0x00CA, - "Euml": 0x00CB, - "Igrave": 0x00CC, - "Iacute": 0x00CD, - "Icirc": 0x00CE, - "Iuml": 0x00CF, - "ETH": 0x00D0, - "Ntilde": 0x00D1, - "Ograve": 0x00D2, - "Oacute": 0x00D3, - "Ocirc": 0x00D4, - "Otilde": 0x00D5, - "Ouml": 0x00D6, - "times": 0x00D7, - "Oslash": 0x00D8, - "Ugrave": 0x00D9, - "Uacute": 0x00DA, - "Ucirc": 0x00DB, - "Uuml": 0x00DC, - "Yacute": 0x00DD, - "THORN": 0x00DE, - "szlig": 0x00DF, - "agrave": 0x00E0, - "aacute": 0x00E1, - "acirc": 0x00E2, - "atilde": 0x00E3, - "auml": 0x00E4, - "aring": 0x00E5, - "aelig": 0x00E6, - "ccedil": 0x00E7, - "egrave": 0x00E8, - "eacute": 0x00E9, - "ecirc": 0x00EA, - "euml": 0x00EB, - "igrave": 0x00EC, - "iacute": 0x00ED, - "icirc": 0x00EE, - "iuml": 0x00EF, - "eth": 0x00F0, - "ntilde": 0x00F1, - "ograve": 0x00F2, - "oacute": 0x00F3, - "ocirc": 0x00F4, - "otilde": 0x00F5, - "ouml": 0x00F6, - "divide": 0x00F7, - "oslash": 0x00F8, - "ugrave": 0x00F9, - "uacute": 0x00FA, - "ucirc": 0x00FB, - "uuml": 0x00FC, - "yacute": 0x00FD, - "thorn": 0x00FE, - "yuml": 0x00FF, - "OElig": 0x0152, - "oelig": 0x0153, - "Scaron": 0x0160, - "scaron": 0x0161, - "Yuml": 0x0178, - "fnof": 0x0192, - "circ": 0x02C6, - "tilde": 0x02DC, - "Alpha": 0x0391, - "Beta": 0x0392, - "Gamma": 0x0393, - "Delta": 0x0394, - "Epsilon": 0x0395, - "Zeta": 0x0396, - "Eta": 0x0397, - "Theta": 0x0398, - "Iota": 0x0399, - "Kappa": 0x039A, - "Lambda": 0x039B, - "Mu": 0x039C, - "Nu": 0x039D, - "Xi": 0x039E, - "Omicron": 0x039F, - "Pi": 0x03A0, - "Rho": 0x03A1, - "Sigma": 0x03A3, - "Tau": 0x03A4, - "Upsilon": 0x03A5, - "Phi": 0x03A6, - "Chi": 0x03A7, - "Psi": 0x03A8, - "Omega": 0x03A9, - "alpha": 0x03B1, - "beta": 0x03B2, - "gamma": 0x03B3, - "delta": 0x03B4, - "epsilon": 0x03B5, - "zeta": 0x03B6, - "eta": 0x03B7, - "theta": 0x03B8, - "iota": 0x03B9, - "kappa": 0x03BA, - "lambda": 0x03BB, - "mu": 0x03BC, - "nu": 0x03BD, - "xi": 0x03BE, - "omicron": 0x03BF, - "pi": 0x03C0, - "rho": 0x03C1, - "sigmaf": 0x03C2, - "sigma": 0x03C3, - "tau": 0x03C4, - "upsilon": 0x03C5, - "phi": 0x03C6, - "chi": 0x03C7, - "psi": 0x03C8, - "omega": 0x03C9, - "thetasym": 0x03D1, - "upsih": 0x03D2, - "piv": 0x03D6, - "ensp": 0x2002, - "emsp": 0x2003, - "thinsp": 0x2009, - "zwnj": 0x200C, - "zwj": 0x200D, - "lrm": 0x200E, - "rlm": 0x200F, - "ndash": 0x2013, - "mdash": 0x2014, - "lsquo": 0x2018, - "rsquo": 0x2019, - "sbquo": 0x201A, - "ldquo": 0x201C, - "rdquo": 0x201D, - "bdquo": 0x201E, - "dagger": 0x2020, - "Dagger": 0x2021, - "bull": 0x2022, - "hellip": 0x2026, - "permil": 0x2030, - "prime": 0x2032, - "Prime": 0x2033, - "lsaquo": 0x2039, - "rsaquo": 0x203A, - "oline": 0x203E, - "frasl": 0x2044, - "euro": 0x20AC, - "image": 0x2111, - "weierp": 0x2118, - "real": 0x211C, - "trade": 0x2122, - "alefsym": 0x2135, - "larr": 0x2190, - "uarr": 0x2191, - "rarr": 0x2192, - "darr": 0x2193, - "harr": 0x2194, - "crarr": 0x21B5, - "lArr": 0x21D0, - "uArr": 0x21D1, - "rArr": 0x21D2, - "dArr": 0x21D3, - "hArr": 0x21D4, - "forall": 0x2200, - "part": 0x2202, - "exist": 0x2203, - "empty": 0x2205, - "nabla": 0x2207, - "isin": 0x2208, - "notin": 0x2209, - "ni": 0x220B, - "prod": 0x220F, - "sum": 0x2211, - "minus": 0x2212, - "lowast": 0x2217, - "radic": 0x221A, - "prop": 0x221D, - "infin": 0x221E, - "ang": 0x2220, - "and": 0x2227, - "or": 0x2228, - "cap": 0x2229, - "cup": 0x222A, - "int": 0x222B, - "there4": 0x2234, - "sim": 0x223C, - "cong": 0x2245, - "asymp": 0x2248, - "ne": 0x2260, - "equiv": 0x2261, - "le": 0x2264, - "ge": 0x2265, - "sub": 0x2282, - "sup": 0x2283, - "nsub": 0x2284, - "sube": 0x2286, - "supe": 0x2287, - "oplus": 0x2295, - "otimes": 0x2297, - "perp": 0x22A5, - "sdot": 0x22C5, - "lceil": 0x2308, - "rceil": 0x2309, - "lfloor": 0x230A, - "rfloor": 0x230B, - "lang": 0x2329, - "rang": 0x232A, - "loz": 0x25CA, - "spades": 0x2660, - "clubs": 0x2663, - "hearts": 0x2665, - "diams": 0x2666 + quot: 0x0022, + amp: 0x0026, + apos: 0x0027, + lt: 0x003C, + gt: 0x003E, + nbsp: 0x00A0, + iexcl: 0x00A1, + cent: 0x00A2, + pound: 0x00A3, + curren: 0x00A4, + yen: 0x00A5, + brvbar: 0x00A6, + sect: 0x00A7, + uml: 0x00A8, + copy: 0x00A9, + ordf: 0x00AA, + laquo: 0x00AB, + not: 0x00AC, + shy: 0x00AD, + reg: 0x00AE, + macr: 0x00AF, + deg: 0x00B0, + plusmn: 0x00B1, + sup2: 0x00B2, + sup3: 0x00B3, + acute: 0x00B4, + micro: 0x00B5, + para: 0x00B6, + middot: 0x00B7, + cedil: 0x00B8, + sup1: 0x00B9, + ordm: 0x00BA, + raquo: 0x00BB, + frac14: 0x00BC, + frac12: 0x00BD, + frac34: 0x00BE, + iquest: 0x00BF, + Agrave: 0x00C0, + Aacute: 0x00C1, + Acirc: 0x00C2, + Atilde: 0x00C3, + Auml: 0x00C4, + Aring: 0x00C5, + AElig: 0x00C6, + Ccedil: 0x00C7, + Egrave: 0x00C8, + Eacute: 0x00C9, + Ecirc: 0x00CA, + Euml: 0x00CB, + Igrave: 0x00CC, + Iacute: 0x00CD, + Icirc: 0x00CE, + Iuml: 0x00CF, + ETH: 0x00D0, + Ntilde: 0x00D1, + Ograve: 0x00D2, + Oacute: 0x00D3, + Ocirc: 0x00D4, + Otilde: 0x00D5, + Ouml: 0x00D6, + times: 0x00D7, + Oslash: 0x00D8, + Ugrave: 0x00D9, + Uacute: 0x00DA, + Ucirc: 0x00DB, + Uuml: 0x00DC, + Yacute: 0x00DD, + THORN: 0x00DE, + szlig: 0x00DF, + agrave: 0x00E0, + aacute: 0x00E1, + acirc: 0x00E2, + atilde: 0x00E3, + auml: 0x00E4, + aring: 0x00E5, + aelig: 0x00E6, + ccedil: 0x00E7, + egrave: 0x00E8, + eacute: 0x00E9, + ecirc: 0x00EA, + euml: 0x00EB, + igrave: 0x00EC, + iacute: 0x00ED, + icirc: 0x00EE, + iuml: 0x00EF, + eth: 0x00F0, + ntilde: 0x00F1, + ograve: 0x00F2, + oacute: 0x00F3, + ocirc: 0x00F4, + otilde: 0x00F5, + ouml: 0x00F6, + divide: 0x00F7, + oslash: 0x00F8, + ugrave: 0x00F9, + uacute: 0x00FA, + ucirc: 0x00FB, + uuml: 0x00FC, + yacute: 0x00FD, + thorn: 0x00FE, + yuml: 0x00FF, + OElig: 0x0152, + oelig: 0x0153, + Scaron: 0x0160, + scaron: 0x0161, + Yuml: 0x0178, + fnof: 0x0192, + circ: 0x02C6, + tilde: 0x02DC, + Alpha: 0x0391, + Beta: 0x0392, + Gamma: 0x0393, + Delta: 0x0394, + Epsilon: 0x0395, + Zeta: 0x0396, + Eta: 0x0397, + Theta: 0x0398, + Iota: 0x0399, + Kappa: 0x039A, + Lambda: 0x039B, + Mu: 0x039C, + Nu: 0x039D, + Xi: 0x039E, + Omicron: 0x039F, + Pi: 0x03A0, + Rho: 0x03A1, + Sigma: 0x03A3, + Tau: 0x03A4, + Upsilon: 0x03A5, + Phi: 0x03A6, + Chi: 0x03A7, + Psi: 0x03A8, + Omega: 0x03A9, + alpha: 0x03B1, + beta: 0x03B2, + gamma: 0x03B3, + delta: 0x03B4, + epsilon: 0x03B5, + zeta: 0x03B6, + eta: 0x03B7, + theta: 0x03B8, + iota: 0x03B9, + kappa: 0x03BA, + lambda: 0x03BB, + mu: 0x03BC, + nu: 0x03BD, + xi: 0x03BE, + omicron: 0x03BF, + pi: 0x03C0, + rho: 0x03C1, + sigmaf: 0x03C2, + sigma: 0x03C3, + tau: 0x03C4, + upsilon: 0x03C5, + phi: 0x03C6, + chi: 0x03C7, + psi: 0x03C8, + omega: 0x03C9, + thetasym: 0x03D1, + upsih: 0x03D2, + piv: 0x03D6, + ensp: 0x2002, + emsp: 0x2003, + thinsp: 0x2009, + zwnj: 0x200C, + zwj: 0x200D, + lrm: 0x200E, + rlm: 0x200F, + ndash: 0x2013, + mdash: 0x2014, + lsquo: 0x2018, + rsquo: 0x2019, + sbquo: 0x201A, + ldquo: 0x201C, + rdquo: 0x201D, + bdquo: 0x201E, + dagger: 0x2020, + Dagger: 0x2021, + bull: 0x2022, + hellip: 0x2026, + permil: 0x2030, + prime: 0x2032, + Prime: 0x2033, + lsaquo: 0x2039, + rsaquo: 0x203A, + oline: 0x203E, + frasl: 0x2044, + euro: 0x20AC, + image: 0x2111, + weierp: 0x2118, + real: 0x211C, + trade: 0x2122, + alefsym: 0x2135, + larr: 0x2190, + uarr: 0x2191, + rarr: 0x2192, + darr: 0x2193, + harr: 0x2194, + crarr: 0x21B5, + lArr: 0x21D0, + uArr: 0x21D1, + rArr: 0x21D2, + dArr: 0x21D3, + hArr: 0x21D4, + forall: 0x2200, + part: 0x2202, + exist: 0x2203, + empty: 0x2205, + nabla: 0x2207, + isin: 0x2208, + notin: 0x2209, + ni: 0x220B, + prod: 0x220F, + sum: 0x2211, + minus: 0x2212, + lowast: 0x2217, + radic: 0x221A, + prop: 0x221D, + infin: 0x221E, + ang: 0x2220, + and: 0x2227, + or: 0x2228, + cap: 0x2229, + cup: 0x222A, + int: 0x222B, + there4: 0x2234, + sim: 0x223C, + cong: 0x2245, + asymp: 0x2248, + ne: 0x2260, + equiv: 0x2261, + le: 0x2264, + ge: 0x2265, + sub: 0x2282, + sup: 0x2283, + nsub: 0x2284, + sube: 0x2286, + supe: 0x2287, + oplus: 0x2295, + otimes: 0x2297, + perp: 0x22A5, + sdot: 0x22C5, + lceil: 0x2308, + rceil: 0x2309, + lfloor: 0x230A, + rfloor: 0x230B, + lang: 0x2329, + rang: 0x232A, + loz: 0x25CA, + spades: 0x2660, + clubs: 0x2663, + hearts: 0x2665, + diams: 0x2666 }); } \ No newline at end of file diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 0428d2d2d2e..0b40e20a7b7 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -1585,13 +1585,13 @@ namespace ts { // Add additional properties in debug mode to assist with debugging. Object.defineProperties(objectAllocator.getSymbolConstructor().prototype, { - "__debugFlags": { get(this: Symbol) { return formatSymbolFlags(this.flags); } } + __debugFlags: { get(this: Symbol) { return formatSymbolFlags(this.flags); } } }); Object.defineProperties(objectAllocator.getTypeConstructor().prototype, { - "__debugFlags": { get(this: Type) { return formatTypeFlags(this.flags); } }, - "__debugObjectFlags": { get(this: Type) { return this.flags & TypeFlags.Object ? formatObjectFlags((this).objectFlags) : ""; } }, - "__debugTypeToString": { value(this: Type) { return this.checker.typeToString(this); } }, + __debugFlags: { get(this: Type) { return formatTypeFlags(this.flags); } }, + __debugObjectFlags: { get(this: Type) { return this.flags & TypeFlags.Object ? formatObjectFlags((this).objectFlags) : ""; } }, + __debugTypeToString: { value(this: Type) { return this.checker.typeToString(this); } }, }); const nodeConstructors = [ @@ -1604,11 +1604,11 @@ namespace ts { for (const ctor of nodeConstructors) { if (!ctor.prototype.hasOwnProperty("__debugKind")) { Object.defineProperties(ctor.prototype, { - "__debugKind": { get(this: Node) { return formatSyntaxKind(this.kind); } }, - "__debugModifierFlags": { get(this: Node) { return formatModifierFlags(getModifierFlagsNoCache(this)); } }, - "__debugTransformFlags": { get(this: Node) { return formatTransformFlags(this.transformFlags); } }, - "__debugEmitFlags": { get(this: Node) { return formatEmitFlags(getEmitFlags(this)); } }, - "__debugGetText": { + __debugKind: { get(this: Node) { return formatSyntaxKind(this.kind); } }, + __debugModifierFlags: { get(this: Node) { return formatModifierFlags(getModifierFlagsNoCache(this)); } }, + __debugTransformFlags: { get(this: Node) { return formatTransformFlags(this.transformFlags); } }, + __debugEmitFlags: { get(this: Node) { return formatEmitFlags(getEmitFlags(this)); } }, + __debugGetText: { value(this: Node, includeTrivia?: boolean) { if (nodeIsSynthesized(this)) return ""; const parseNode = getParseTreeNode(this); diff --git a/src/harness/unittests/configurationExtension.ts b/src/harness/unittests/configurationExtension.ts index 0032505aba1..5a1b155fbcf 100644 --- a/src/harness/unittests/configurationExtension.ts +++ b/src/harness/unittests/configurationExtension.ts @@ -25,9 +25,9 @@ namespace ts { }, "/dev/configs/tests.json": { compilerOptions: { - "preserveConstEnums": true, - "removeComments": false, - "sourceMap": true + preserveConstEnums: true, + removeComments: false, + sourceMap: true }, exclude: [ "../tests/baselines", @@ -52,7 +52,7 @@ namespace ts { "/dev/missing.json": { extends: "./missing2", compilerOptions: { - "types": [] + types: [] } }, "/dev/failure.json": { diff --git a/src/harness/unittests/convertCompilerOptionsFromJson.ts b/src/harness/unittests/convertCompilerOptionsFromJson.ts index cbbe41ceadf..3a73971d7a3 100644 --- a/src/harness/unittests/convertCompilerOptionsFromJson.ts +++ b/src/harness/unittests/convertCompilerOptionsFromJson.ts @@ -58,12 +58,12 @@ namespace ts { it("Convert correctly format tsconfig.json to compiler-options ", () => { assertCompilerOptions( { - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "noImplicitAny": false, - "sourceMap": false, - "lib": ["es5", "es2015.core", "es2015.symbol"] + compilerOptions: { + module: "commonjs", + target: "es5", + noImplicitAny: false, + sourceMap: false, + lib: ["es5", "es2015.core", "es2015.symbol"] } }, "tsconfig.json", { @@ -82,13 +82,13 @@ namespace ts { it("Convert correctly format tsconfig.json with allowJs is false to compiler-options ", () => { assertCompilerOptions( { - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "noImplicitAny": false, - "sourceMap": false, - "allowJs": false, - "lib": ["es5", "es2015.core", "es2015.symbol"] + compilerOptions: { + module: "commonjs", + target: "es5", + noImplicitAny: false, + sourceMap: false, + allowJs: false, + lib: ["es5", "es2015.core", "es2015.symbol"] } }, "tsconfig.json", { @@ -108,12 +108,12 @@ namespace ts { it("Convert incorrect option of jsx to compiler-options ", () => { assertCompilerOptions( { - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "noImplicitAny": false, - "sourceMap": false, - "jsx": "" + compilerOptions: { + module: "commonjs", + target: "es5", + noImplicitAny: false, + sourceMap: false, + jsx: "" } }, "tsconfig.json", { @@ -138,11 +138,11 @@ namespace ts { it("Convert incorrect option of module to compiler-options ", () => { assertCompilerOptions( { - "compilerOptions": { - "module": "", - "target": "es5", - "noImplicitAny": false, - "sourceMap": false, + compilerOptions: { + module: "", + target: "es5", + noImplicitAny: false, + sourceMap: false, } }, "tsconfig.json", { @@ -166,11 +166,11 @@ namespace ts { it("Convert incorrect option of newLine to compiler-options ", () => { assertCompilerOptions( { - "compilerOptions": { - "newLine": "", - "target": "es5", - "noImplicitAny": false, - "sourceMap": false, + compilerOptions: { + newLine: "", + target: "es5", + noImplicitAny: false, + sourceMap: false, } }, "tsconfig.json", { @@ -194,10 +194,10 @@ namespace ts { it("Convert incorrect option of target to compiler-options ", () => { assertCompilerOptions( { - "compilerOptions": { - "target": "", - "noImplicitAny": false, - "sourceMap": false, + compilerOptions: { + target: "", + noImplicitAny: false, + sourceMap: false, } }, "tsconfig.json", { @@ -220,10 +220,10 @@ namespace ts { it("Convert incorrect option of module-resolution to compiler-options ", () => { assertCompilerOptions( { - "compilerOptions": { - "moduleResolution": "", - "noImplicitAny": false, - "sourceMap": false, + compilerOptions: { + moduleResolution: "", + noImplicitAny: false, + sourceMap: false, } }, "tsconfig.json", { @@ -246,12 +246,12 @@ namespace ts { it("Convert incorrect option of libs to compiler-options ", () => { assertCompilerOptions( { - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "noImplicitAny": false, - "sourceMap": false, - "lib": ["es5", "es2015.core", "incorrectLib"] + compilerOptions: { + module: "commonjs", + target: "es5", + noImplicitAny: false, + sourceMap: false, + lib: ["es5", "es2015.core", "incorrectLib"] } }, "tsconfig.json", { @@ -277,12 +277,12 @@ namespace ts { it("Convert empty string option of libs to compiler-options ", () => { assertCompilerOptions( { - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "noImplicitAny": false, - "sourceMap": false, - "lib": ["es5", ""] + compilerOptions: { + module: "commonjs", + target: "es5", + noImplicitAny: false, + sourceMap: false, + lib: ["es5", ""] } }, "tsconfig.json", { @@ -308,12 +308,12 @@ namespace ts { it("Convert empty string option of libs to compiler-options ", () => { assertCompilerOptions( { - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "noImplicitAny": false, - "sourceMap": false, - "lib": [""] + compilerOptions: { + module: "commonjs", + target: "es5", + noImplicitAny: false, + sourceMap: false, + lib: [""] } }, "tsconfig.json", { @@ -339,12 +339,12 @@ namespace ts { it("Convert trailing-whitespace string option of libs to compiler-options ", () => { assertCompilerOptions( { - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "noImplicitAny": false, - "sourceMap": false, - "lib": [" "] + compilerOptions: { + module: "commonjs", + target: "es5", + noImplicitAny: false, + sourceMap: false, + lib: [" "] } }, "tsconfig.json", { @@ -370,12 +370,12 @@ namespace ts { it("Convert empty option of libs to compiler-options ", () => { assertCompilerOptions( { - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "noImplicitAny": false, - "sourceMap": false, - "lib": [] + compilerOptions: { + module: "commonjs", + target: "es5", + noImplicitAny: false, + sourceMap: false, + lib: [] } }, "tsconfig.json", { @@ -394,8 +394,8 @@ namespace ts { it("Convert incorrectly format tsconfig.json to compiler-options ", () => { assertCompilerOptions( { - "compilerOptions": { - "modu": "commonjs", + compilerOptions: { + modu: "commonjs", } }, "tsconfig.json", { @@ -424,9 +424,9 @@ namespace ts { it("Convert negative numbers in tsconfig.json ", () => { assertCompilerOptions( { - "compilerOptions": { - "allowJs": true, - "maxNodeModuleJsDepth": -1 + compilerOptions: { + allowJs: true, + maxNodeModuleJsDepth: -1 } }, "tsconfig.json", { @@ -443,12 +443,12 @@ namespace ts { it("Convert correctly format jsconfig.json to compiler-options ", () => { assertCompilerOptions( { - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "noImplicitAny": false, - "sourceMap": false, - "lib": ["es5", "es2015.core", "es2015.symbol"] + compilerOptions: { + module: "commonjs", + target: "es5", + noImplicitAny: false, + sourceMap: false, + lib: ["es5", "es2015.core", "es2015.symbol"] } }, "jsconfig.json", { @@ -471,13 +471,13 @@ namespace ts { it("Convert correctly format jsconfig.json with allowJs is false to compiler-options ", () => { assertCompilerOptions( { - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "noImplicitAny": false, - "sourceMap": false, - "allowJs": false, - "lib": ["es5", "es2015.core", "es2015.symbol"] + compilerOptions: { + module: "commonjs", + target: "es5", + noImplicitAny: false, + sourceMap: false, + allowJs: false, + lib: ["es5", "es2015.core", "es2015.symbol"] } }, "jsconfig.json", { @@ -500,8 +500,8 @@ namespace ts { it("Convert incorrectly format jsconfig.json to compiler-options ", () => { assertCompilerOptions( { - "compilerOptions": { - "modu": "commonjs", + compilerOptions: { + modu: "commonjs", } }, "jsconfig.json", { diff --git a/src/harness/unittests/convertTypeAcquisitionFromJson.ts b/src/harness/unittests/convertTypeAcquisitionFromJson.ts index 5a367edebbb..be1ada10a97 100644 --- a/src/harness/unittests/convertTypeAcquisitionFromJson.ts +++ b/src/harness/unittests/convertTypeAcquisitionFromJson.ts @@ -55,11 +55,11 @@ namespace ts { it("Convert deprecated typingOptions.enableAutoDiscovery format tsconfig.json to typeAcquisition ", () => { assertTypeAcquisition( { - "typingOptions": + typingOptions: { - "enableAutoDiscovery": true, - "include": ["0.d.ts", "1.d.ts"], - "exclude": ["0.js", "1.js"] + enableAutoDiscovery: true, + include: ["0.d.ts", "1.d.ts"], + exclude: ["0.js", "1.js"] } }, "tsconfig.json", @@ -77,11 +77,11 @@ namespace ts { it("Convert correctly format tsconfig.json to typeAcquisition ", () => { assertTypeAcquisition( { - "typeAcquisition": + typeAcquisition: { - "enable": true, - "include": ["0.d.ts", "1.d.ts"], - "exclude": ["0.js", "1.js"] + enable: true, + include: ["0.d.ts", "1.d.ts"], + exclude: ["0.js", "1.js"] } }, "tsconfig.json", @@ -99,9 +99,9 @@ namespace ts { it("Convert incorrect format tsconfig.json to typeAcquisition ", () => { assertTypeAcquisition( { - "typeAcquisition": + typeAcquisition: { - "enableAutoDiscovy": true, + enableAutoDiscovy: true, } }, "tsconfig.json", { @@ -140,9 +140,9 @@ namespace ts { it("Convert tsconfig.json with only enable property to typeAcquisition ", () => { assertTypeAcquisition( { - "typeAcquisition": + typeAcquisition: { - "enable": true + enable: true } }, "tsconfig.json", { @@ -160,11 +160,11 @@ namespace ts { it("Convert jsconfig.json to typeAcquisition ", () => { assertTypeAcquisition( { - "typeAcquisition": + typeAcquisition: { - "enable": false, - "include": ["0.d.ts"], - "exclude": ["0.js"] + enable: false, + include: ["0.d.ts"], + exclude: ["0.js"] } }, "jsconfig.json", { @@ -194,9 +194,9 @@ namespace ts { it("Convert incorrect format jsconfig.json to typeAcquisition ", () => { assertTypeAcquisition( { - "typeAcquisition": + typeAcquisition: { - "enableAutoDiscovy": true, + enableAutoDiscovy: true, } }, "jsconfig.json", { @@ -222,9 +222,9 @@ namespace ts { it("Convert jsconfig.json with only enable property to typeAcquisition ", () => { assertTypeAcquisition( { - "typeAcquisition": + typeAcquisition: { - "enable": false + enable: false } }, "jsconfig.json", { diff --git a/src/harness/unittests/moduleResolution.ts b/src/harness/unittests/moduleResolution.ts index 6f62c78208f..de79ba06cf9 100644 --- a/src/harness/unittests/moduleResolution.ts +++ b/src/harness/unittests/moduleResolution.ts @@ -127,7 +127,7 @@ namespace ts { function test(hasDirectoryExists: boolean) { const containingFile = { name: containingFileName }; - const packageJson = { name: packageJsonFileName, content: JSON.stringify({ "typings": fieldRef }) }; + const packageJson = { name: packageJsonFileName, content: JSON.stringify({ typings: fieldRef }) }; const moduleFile = { name: moduleFileName }; const resolution = nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, moduleFile)); checkResolvedModule(resolution.resolvedModule, createResolvedModule(moduleFile.name)); @@ -149,7 +149,7 @@ namespace ts { function test(hasDirectoryExists: boolean) { const containingFile = { name: "/a/b.ts" }; - const packageJson = { name: "/node_modules/b/package.json", content: JSON.stringify({ "typings": typings }) }; + const packageJson = { name: "/node_modules/b/package.json", content: JSON.stringify({ typings }) }; const moduleFile = { name: "/a/b.d.ts" }; const indexPath = "/node_modules/b/index.d.ts"; @@ -163,7 +163,7 @@ namespace ts { it("module name as directory - handle invalid 'typings'", () => { testTypingsIgnored(["a", "b"]); - testTypingsIgnored({ "a": "b" }); + testTypingsIgnored({ a: "b" }); testTypingsIgnored(/*typings*/ true); testTypingsIgnored(/*typings*/ null); // tslint:disable-line no-null-keyword testTypingsIgnored(/*typings*/ undefined); diff --git a/src/harness/unittests/reuseProgramStructure.ts b/src/harness/unittests/reuseProgramStructure.ts index 6278742a0bd..fdccc8a7795 100644 --- a/src/harness/unittests/reuseProgramStructure.ts +++ b/src/harness/unittests/reuseProgramStructure.ts @@ -360,7 +360,7 @@ namespace ts { const options: CompilerOptions = { target }; const program1 = newProgram(files, ["a.ts"], options); - checkResolvedModulesCache(program1, "a.ts", createMapFromTemplate({ "b": createResolvedModule("b.ts") })); + checkResolvedModulesCache(program1, "a.ts", createMapFromTemplate({ b: createResolvedModule("b.ts") })); checkResolvedModulesCache(program1, "b.ts", /*expectedContent*/ undefined); const program2 = updateProgram(program1, ["a.ts"], options, files => { @@ -369,7 +369,7 @@ namespace ts { assert.equal(program1.structureIsReused, StructureIsReused.Completely); // content of resolution cache should not change - checkResolvedModulesCache(program1, "a.ts", createMapFromTemplate({ "b": createResolvedModule("b.ts") })); + checkResolvedModulesCache(program1, "a.ts", createMapFromTemplate({ b: createResolvedModule("b.ts") })); checkResolvedModulesCache(program1, "b.ts", /*expectedContent*/ undefined); // imports has changed - program is not reused @@ -386,7 +386,7 @@ namespace ts { files[0].text = files[0].text.updateImportsAndExports(newImports); }); assert.equal(program3.structureIsReused, StructureIsReused.SafeModules); - checkResolvedModulesCache(program4, "a.ts", createMapFromTemplate({ "b": createResolvedModule("b.ts"), "c": undefined })); + checkResolvedModulesCache(program4, "a.ts", createMapFromTemplate({ b: createResolvedModule("b.ts"), c: undefined })); }); it("resolved type directives cache follows type directives", () => { @@ -397,7 +397,7 @@ namespace ts { const options: CompilerOptions = { target, typeRoots: ["/types"] }; const program1 = newProgram(files, ["/a.ts"], options); - checkResolvedTypeDirectivesCache(program1, "/a.ts", createMapFromTemplate({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); + checkResolvedTypeDirectivesCache(program1, "/a.ts", createMapFromTemplate({ typedefs: { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); checkResolvedTypeDirectivesCache(program1, "/types/typedefs/index.d.ts", /*expectedContent*/ undefined); const program2 = updateProgram(program1, ["/a.ts"], options, files => { @@ -406,7 +406,7 @@ namespace ts { assert.equal(program1.structureIsReused, StructureIsReused.Completely); // content of resolution cache should not change - checkResolvedTypeDirectivesCache(program1, "/a.ts", createMapFromTemplate({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); + checkResolvedTypeDirectivesCache(program1, "/a.ts", createMapFromTemplate({ typedefs: { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); checkResolvedTypeDirectivesCache(program1, "/types/typedefs/index.d.ts", /*expectedContent*/ undefined); // type reference directives has changed - program is not reused @@ -424,7 +424,7 @@ namespace ts { files[0].text = files[0].text.updateReferences(newReferences); }); assert.equal(program3.structureIsReused, StructureIsReused.SafeModules); - checkResolvedTypeDirectivesCache(program1, "/a.ts", createMapFromTemplate({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); + checkResolvedTypeDirectivesCache(program1, "/a.ts", createMapFromTemplate({ typedefs: { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); }); it("fetches imports after npm install", () => { diff --git a/src/harness/unittests/services/preProcessFile.ts b/src/harness/unittests/services/preProcessFile.ts index d4195573cba..1e13bc3e345 100644 --- a/src/harness/unittests/services/preProcessFile.ts +++ b/src/harness/unittests/services/preProcessFile.ts @@ -278,7 +278,7 @@ describe("PreProcessFile:", () => { referencedFiles: [], typeReferenceDirectives: [], importedFiles: [ - { "fileName": "../Observable", "pos": 28, "end": 41 } + { fileName: "../Observable", pos: 28, end: 41 } ], ambientExternalModules: undefined, isLibFile: false @@ -298,8 +298,8 @@ describe("PreProcessFile:", () => { referencedFiles: [], typeReferenceDirectives: [], importedFiles: [ - { "fileName": "m", "pos": 123, "end": 124 }, - { "fileName": "../Observable", "pos": 28, "end": 41 } + { fileName: "m", pos: 123, end: 124 }, + { fileName: "../Observable", pos: 28, end: 41 } ], ambientExternalModules: undefined, isLibFile: false @@ -319,8 +319,8 @@ describe("PreProcessFile:", () => { referencedFiles: [], typeReferenceDirectives: [], importedFiles: [ - { "fileName": "m", "pos": 123, "end": 124 }, - { "fileName": "../Observable", "pos": 28, "end": 41 } + { fileName: "m", pos: 123, end: 124 }, + { fileName: "../Observable", pos: 28, end: 41 } ], ambientExternalModules: undefined, isLibFile: false @@ -340,7 +340,7 @@ describe("PreProcessFile:", () => { referencedFiles: [], typeReferenceDirectives: [], importedFiles: [ - { "fileName": "../Observable", "pos": 28, "end": 41 } + { fileName: "../Observable", pos: 28, end: 41 } ], ambientExternalModules: undefined, isLibFile: false @@ -360,7 +360,7 @@ describe("PreProcessFile:", () => { referencedFiles: [], typeReferenceDirectives: [], importedFiles: [ - { "fileName": "../Observable", "pos": 28, "end": 41 } + { fileName: "../Observable", pos: 28, end: 41 } ], ambientExternalModules: undefined, isLibFile: false @@ -379,7 +379,7 @@ describe("PreProcessFile:", () => { referencedFiles: [], typeReferenceDirectives: [], importedFiles: [ - { "fileName": "../Observable", "pos": 28, "end": 41 } + { fileName: "../Observable", pos: 28, end: 41 } ], ambientExternalModules: undefined, isLibFile: false @@ -400,8 +400,8 @@ describe("PreProcessFile:", () => { referencedFiles: [], typeReferenceDirectives: [], importedFiles: [ - { "fileName": "m2", "pos": 65, "end": 67 }, - { "fileName": "augmentation", "pos": 102, "end": 114 } + { fileName: "m2", pos: 65, end: 67 }, + { fileName: "augmentation", pos: 102, end: 114 } ], ambientExternalModules: ["m1"], isLibFile: false @@ -424,8 +424,8 @@ describe("PreProcessFile:", () => { referencedFiles: [], typeReferenceDirectives: [], importedFiles: [ - { "fileName": "m2", "pos": 127, "end": 129 }, - { "fileName": "augmentation", "pos": 164, "end": 176 } + { fileName: "m2", pos: 127, end: 129 }, + { fileName: "augmentation", pos: 164, end: 176 } ], ambientExternalModules: ["m1"], isLibFile: false @@ -442,12 +442,12 @@ describe("PreProcessFile:", () => { /*detectJavaScriptImports*/ false, { referencedFiles: [ - { "pos": 34, "end": 35, "fileName": "a" }, - { "pos": 112, "end": 114, "fileName": "a2" } + { pos: 34, end: 35, fileName: "a" }, + { pos: 112, end: 114, fileName: "a2" } ], typeReferenceDirectives: [ - { "pos": 73, "end": 75, "fileName": "a1" }, - { "pos": 152, "end": 154, "fileName": "a3" } + { pos: 73, end: 75, fileName: "a1" }, + { pos: 152, end: 154, fileName: "a3" } ], importedFiles: [], ambientExternalModules: undefined, diff --git a/src/harness/unittests/transpile.ts b/src/harness/unittests/transpile.ts index 16bef6500f2..7c4af8be167 100644 --- a/src/harness/unittests/transpile.ts +++ b/src/harness/unittests/transpile.ts @@ -149,21 +149,21 @@ var x = 0;`, { `import {foo} from "SomeName";\n` + `declare function use(a: any);\n` + `use(foo);`, { - options: { compilerOptions: { module: ModuleKind.System, newLine: NewLineKind.LineFeed }, renamedDependencies: { "SomeName": "SomeOtherName" } } + options: { compilerOptions: { module: ModuleKind.System, newLine: NewLineKind.LineFeed }, renamedDependencies: { SomeName: "SomeOtherName" } } }); transpilesCorrectly("Rename dependencies - AMD", `import {foo} from "SomeName";\n` + `declare function use(a: any);\n` + `use(foo);`, { - options: { compilerOptions: { module: ModuleKind.AMD, newLine: NewLineKind.LineFeed }, renamedDependencies: { "SomeName": "SomeOtherName" } } + options: { compilerOptions: { module: ModuleKind.AMD, newLine: NewLineKind.LineFeed }, renamedDependencies: { SomeName: "SomeOtherName" } } }); transpilesCorrectly("Rename dependencies - UMD", `import {foo} from "SomeName";\n` + `declare function use(a: any);\n` + `use(foo);`, { - options: { compilerOptions: { module: ModuleKind.UMD, newLine: NewLineKind.LineFeed }, renamedDependencies: { "SomeName": "SomeOtherName" } } + options: { compilerOptions: { module: ModuleKind.UMD, newLine: NewLineKind.LineFeed }, renamedDependencies: { SomeName: "SomeOtherName" } } }); transpilesCorrectly("Transpile with emit decorators and emit metadata", diff --git a/src/harness/unittests/tscWatchMode.ts b/src/harness/unittests/tscWatchMode.ts index cddbfba9dc0..fc80a6f39ef 100644 --- a/src/harness/unittests/tscWatchMode.ts +++ b/src/harness/unittests/tscWatchMode.ts @@ -710,12 +710,12 @@ namespace ts.tscWatch { path: "/src/tsconfig.json", content: JSON.stringify( { - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "noImplicitAny": true, - "sourceMap": false, - "lib": [ + compilerOptions: { + module: "commonjs", + target: "es5", + noImplicitAny: true, + sourceMap: false, + lib: [ "es5" ] } @@ -725,12 +725,12 @@ namespace ts.tscWatch { path: config1.path, content: JSON.stringify( { - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "noImplicitAny": true, - "sourceMap": false, - "lib": [ + compilerOptions: { + module: "commonjs", + target: "es5", + noImplicitAny: true, + sourceMap: false, + lib: [ "es5", "es2015.promise" ] @@ -1963,12 +1963,12 @@ declare module "fs" { const configFile: FileOrFolder = { path: "/a/rootFolder/project/tsconfig.json", content: JSON.stringify({ - "compilerOptions": { - "module": "none", - "allowJs": true, - "outDir": "Static/scripts/" + compilerOptions: { + module: "none", + allowJs: true, + outDir: "Static/scripts/" }, - "include": [ + include: [ "Scripts/**/*" ], }) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 55d767d24a7..ffb811dddba 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -2607,7 +2607,7 @@ namespace ts.projectSystem { projectFileName, rootFiles: [toExternalFile(site.path), toExternalFile(configFile.path)], options: { allowJs: false }, - typeAcquisition: { "include": [] } + typeAcquisition: { include: [] } }; projectService.openExternalProjects([externalProject]); @@ -3114,12 +3114,12 @@ namespace ts.projectSystem { path: "/src/tsconfig.json", content: JSON.stringify( { - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "noImplicitAny": true, - "sourceMap": false, - "lib": [ + compilerOptions: { + module: "commonjs", + target: "es5", + noImplicitAny: true, + sourceMap: false, + lib: [ "es5" ] } @@ -3129,12 +3129,12 @@ namespace ts.projectSystem { path: config1.path, content: JSON.stringify( { - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "noImplicitAny": true, - "sourceMap": false, - "lib": [ + compilerOptions: { + module: "commonjs", + target: "es5", + noImplicitAny: true, + sourceMap: false, + lib: [ "es5", "es2015.promise" ] @@ -5483,31 +5483,31 @@ namespace ts.projectSystem { const tsconfigFile: FileOrFolder = { path: `${frontendDir}/tsconfig.json`, content: JSON.stringify({ - "compilerOptions": { - "strict": true, - "strictNullChecks": true, - "target": "es2016", - "module": "commonjs", - "moduleResolution": "node", - "sourceMap": true, - "noEmitOnError": true, - "experimentalDecorators": true, - "emitDecoratorMetadata": true, + compilerOptions: { + strict: true, + strictNullChecks: true, + target: "es2016", + module: "commonjs", + moduleResolution: "node", + sourceMap: true, + noEmitOnError: true, + experimentalDecorators: true, + emitDecoratorMetadata: true, types, - "noUnusedLocals": true, - "outDir": "./compiled", + noUnusedLocals: true, + outDir: "./compiled", typeRoots, - "baseUrl": ".", - "paths": { + baseUrl: ".", + paths: { "*": [ "types/*" ] } }, - "include": [ + include: [ "src/**/*" ], - "exclude": [ + exclude: [ "node_modules", "compiled" ] @@ -5632,30 +5632,30 @@ namespace ts.projectSystem { // Simulate npm install const filesAndFoldersToAdd: FileOrFolder[] = [ - { "path": "/a/b/node_modules" }, - { "path": "/a/b/node_modules/.staging/@types" }, - { "path": "/a/b/node_modules/.staging/lodash-b0733faa" }, - { "path": "/a/b/node_modules/.staging/@types/lodash-e56c4fe7" }, - { "path": "/a/b/node_modules/.staging/symbol-observable-24bcbbff" }, - { "path": "/a/b/node_modules/.staging/rxjs-22375c61" }, - { "path": "/a/b/node_modules/.staging/typescript-8493ea5d" }, - { "path": "/a/b/node_modules/.staging/symbol-observable-24bcbbff/package.json", "content": "{\n \"name\": \"symbol-observable\",\n \"version\": \"1.0.4\",\n \"description\": \"Symbol.observable ponyfill\",\n \"license\": \"MIT\",\n \"repository\": \"blesh/symbol-observable\",\n \"author\": {\n \"name\": \"Ben Lesh\",\n \"email\": \"ben@benlesh.com\"\n },\n \"engines\": {\n \"node\": \">=0.10.0\"\n },\n \"scripts\": {\n \"test\": \"npm run build && mocha && tsc ./ts-test/test.ts && node ./ts-test/test.js && check-es3-syntax -p lib/ --kill\",\n \"build\": \"babel es --out-dir lib\",\n \"prepublish\": \"npm test\"\n },\n \"files\": [\n \"" }, - { "path": "/a/b/node_modules/.staging/lodash-b0733faa/package.json", "content": "{\n \"name\": \"lodash\",\n \"version\": \"4.17.4\",\n \"description\": \"Lodash modular utilities.\",\n \"keywords\": \"modules, stdlib, util\",\n \"homepage\": \"https://lodash.com/\",\n \"repository\": \"lodash/lodash\",\n \"icon\": \"https://lodash.com/icon.svg\",\n \"license\": \"MIT\",\n \"main\": \"lodash.js\",\n \"author\": \"John-David Dalton (http://allyoucanleet.com/)\",\n \"contributors\": [\n \"John-David Dalton (http://allyoucanleet.com/)\",\n \"Mathias Bynens \",\n \"contributors\": [\n {\n \"name\": \"Ben Lesh\",\n \"email\": \"ben@benlesh.com\"\n },\n {\n \"name\": \"Paul Taylor\",\n \"email\": \"paul.e.taylor@me.com\"\n },\n {\n \"name\": \"Jeff Cross\",\n \"email\": \"crossj@google.com\"\n },\n {\n \"name\": \"Matthew Podwysocki\",\n \"email\": \"matthewp@microsoft.com\"\n },\n {\n \"name\": \"OJ Kwon\",\n \"email\": \"kwon.ohjoong@gmail.com\"\n },\n {\n \"name\": \"Andre Staltz\",\n \"email\": \"andre@staltz.com\"\n }\n ],\n \"license\": \"Apache-2.0\",\n \"bugs\": {\n \"url\": \"https://github.com/ReactiveX/RxJS/issues\"\n },\n \"homepage\": \"https://github.com/ReactiveX/RxJS\",\n \"devDependencies\": {\n \"babel-polyfill\": \"^6.23.0\",\n \"benchmark\": \"^2.1.0\",\n \"benchpress\": \"2.0.0-beta.1\",\n \"chai\": \"^3.5.0\",\n \"color\": \"^0.11.1\",\n \"colors\": \"1.1.2\",\n \"commitizen\": \"^2.8.6\",\n \"coveralls\": \"^2.11.13\",\n \"cz-conventional-changelog\": \"^1.2.0\",\n \"danger\": \"^1.1.0\",\n \"doctoc\": \"^1.0.0\",\n \"escape-string-regexp\": \"^1.0.5 \",\n \"esdoc\": \"^0.4.7\",\n \"eslint\": \"^3.8.0\",\n \"fs-extra\": \"^2.1.2\",\n \"get-folder-size\": \"^1.0.0\",\n \"glob\": \"^7.0.3\",\n \"gm\": \"^1.22.0\",\n \"google-closure-compiler-js\": \"^20170218.0.0\",\n \"gzip-size\": \"^3.0.0\",\n \"http-server\": \"^0.9.0\",\n \"husky\": \"^0.13.3\",\n \"lint-staged\": \"3.2.5\",\n \"lodash\": \"^4.15.0\",\n \"madge\": \"^1.4.3\",\n \"markdown-doctest\": \"^0.9.1\",\n \"minimist\": \"^1.2.0\",\n \"mkdirp\": \"^0.5.1\",\n \"mocha\": \"^3.0.2\",\n \"mocha-in-sauce\": \"0.0.1\",\n \"npm-run-all\": \"^4.0.2\",\n \"npm-scripts-info\": \"^0.3.4\",\n \"nyc\": \"^10.2.0\",\n \"opn-cli\": \"^3.1.0\",\n \"platform\": \"^1.3.1\",\n \"promise\": \"^7.1.1\",\n \"protractor\": \"^3.1.1\",\n \"rollup\": \"0.36.3\",\n \"rollup-plugin-inject\": \"^2.0.0\",\n \"rollup-plugin-node-resolve\": \"^2.0.0\",\n \"rx\": \"latest\",\n \"rxjs\": \"latest\",\n \"shx\": \"^0.2.2\",\n \"sinon\": \"^2.1.0\",\n \"sinon-chai\": \"^2.9.0\",\n \"source-map-support\": \"^0.4.0\",\n \"tslib\": \"^1.5.0\",\n \"tslint\": \"^4.4.2\",\n \"typescript\": \"~2.0.6\",\n \"typings\": \"^2.0.0\",\n \"validate-commit-msg\": \"^2.14.0\",\n \"watch\": \"^1.0.1\",\n \"webpack\": \"^1.13.1\",\n \"xmlhttprequest\": \"1.8.0\"\n },\n \"engines\": {\n \"npm\": \">=2.0.0\"\n },\n \"typings\": \"Rx.d.ts\",\n \"dependencies\": {\n \"symbol-observable\": \"^1.0.1\"\n }\n}" }, - { "path": "/a/b/node_modules/.staging/typescript-8493ea5d/package.json", "content": "{\n \"name\": \"typescript\",\n \"author\": \"Microsoft Corp.\",\n \"homepage\": \"http://typescriptlang.org/\",\n \"version\": \"2.4.2\",\n \"license\": \"Apache-2.0\",\n \"description\": \"TypeScript is a language for application scale JavaScript development\",\n \"keywords\": [\n \"TypeScript\",\n \"Microsoft\",\n \"compiler\",\n \"language\",\n \"javascript\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/Microsoft/TypeScript/issues\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/Microsoft/TypeScript.git\"\n },\n \"main\": \"./lib/typescript.js\",\n \"typings\": \"./lib/typescript.d.ts\",\n \"bin\": {\n \"tsc\": \"./bin/tsc\",\n \"tsserver\": \"./bin/tsserver\"\n },\n \"engines\": {\n \"node\": \">=4.2.0\"\n },\n \"devDependencies\": {\n \"@types/browserify\": \"latest\",\n \"@types/chai\": \"latest\",\n \"@types/convert-source-map\": \"latest\",\n \"@types/del\": \"latest\",\n \"@types/glob\": \"latest\",\n \"@types/gulp\": \"latest\",\n \"@types/gulp-concat\": \"latest\",\n \"@types/gulp-help\": \"latest\",\n \"@types/gulp-newer\": \"latest\",\n \"@types/gulp-sourcemaps\": \"latest\",\n \"@types/merge2\": \"latest\",\n \"@types/minimatch\": \"latest\",\n \"@types/minimist\": \"latest\",\n \"@types/mkdirp\": \"latest\",\n \"@types/mocha\": \"latest\",\n \"@types/node\": \"latest\",\n \"@types/q\": \"latest\",\n \"@types/run-sequence\": \"latest\",\n \"@types/through2\": \"latest\",\n \"browserify\": \"latest\",\n \"chai\": \"latest\",\n \"convert-source-map\": \"latest\",\n \"del\": \"latest\",\n \"gulp\": \"latest\",\n \"gulp-clone\": \"latest\",\n \"gulp-concat\": \"latest\",\n \"gulp-help\": \"latest\",\n \"gulp-insert\": \"latest\",\n \"gulp-newer\": \"latest\",\n \"gulp-sourcemaps\": \"latest\",\n \"gulp-typescript\": \"latest\",\n \"into-stream\": \"latest\",\n \"istanbul\": \"latest\",\n \"jake\": \"latest\",\n \"merge2\": \"latest\",\n \"minimist\": \"latest\",\n \"mkdirp\": \"latest\",\n \"mocha\": \"latest\",\n \"mocha-fivemat-progress-reporter\": \"latest\",\n \"q\": \"latest\",\n \"run-sequence\": \"latest\",\n \"sorcery\": \"latest\",\n \"through2\": \"latest\",\n \"travis-fold\": \"latest\",\n \"ts-node\": \"latest\",\n \"tslint\": \"latest\",\n \"typescript\": \"^2.4\"\n },\n \"scripts\": {\n \"pretest\": \"jake tests\",\n \"test\": \"jake runtests-parallel\",\n \"build\": \"npm run build:compiler && npm run build:tests\",\n \"build:compiler\": \"jake local\",\n \"build:tests\": \"jake tests\",\n \"start\": \"node lib/tsc\",\n \"clean\": \"jake clean\",\n \"gulp\": \"gulp\",\n \"jake\": \"jake\",\n \"lint\": \"jake lint\",\n \"setup-hooks\": \"node scripts/link-hooks.js\"\n },\n \"browser\": {\n \"buffer\": false,\n \"fs\": false,\n \"os\": false,\n \"path\": false\n }\n}" }, - { "path": "/a/b/node_modules/.staging/symbol-observable-24bcbbff/index.js", "content": "module.exports = require('./lib/index');\n" }, - { "path": "/a/b/node_modules/.staging/symbol-observable-24bcbbff/index.d.ts", "content": "declare const observableSymbol: symbol;\nexport default observableSymbol;\n" }, - { "path": "/a/b/node_modules/.staging/symbol-observable-24bcbbff/lib" }, - { "path": "/a/b/node_modules/.staging/symbol-observable-24bcbbff/lib/index.js", "content": "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _ponyfill = require('./ponyfill');\n\nvar _ponyfill2 = _interopRequireDefault(_ponyfill);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar root; /* global window */\n\n\nif (typeof self !== 'undefined') {\n root = self;\n} else if (typeof window !== 'undefined') {\n root = window;\n} else if (typeof global !== 'undefined') {\n root = global;\n} else if (typeof module !== 'undefined') {\n root = module;\n} else {\n root = Function('return this')();\n}\n\nvar result = (0, _ponyfill2['default'])(root);\nexports['default'] = result;" }, + { path: "/a/b/node_modules" }, + { path: "/a/b/node_modules/.staging/@types" }, + { path: "/a/b/node_modules/.staging/lodash-b0733faa" }, + { path: "/a/b/node_modules/.staging/@types/lodash-e56c4fe7" }, + { path: "/a/b/node_modules/.staging/symbol-observable-24bcbbff" }, + { path: "/a/b/node_modules/.staging/rxjs-22375c61" }, + { path: "/a/b/node_modules/.staging/typescript-8493ea5d" }, + { path: "/a/b/node_modules/.staging/symbol-observable-24bcbbff/package.json", content: "{\n \"name\": \"symbol-observable\",\n \"version\": \"1.0.4\",\n \"description\": \"Symbol.observable ponyfill\",\n \"license\": \"MIT\",\n \"repository\": \"blesh/symbol-observable\",\n \"author\": {\n \"name\": \"Ben Lesh\",\n \"email\": \"ben@benlesh.com\"\n },\n \"engines\": {\n \"node\": \">=0.10.0\"\n },\n \"scripts\": {\n \"test\": \"npm run build && mocha && tsc ./ts-test/test.ts && node ./ts-test/test.js && check-es3-syntax -p lib/ --kill\",\n \"build\": \"babel es --out-dir lib\",\n \"prepublish\": \"npm test\"\n },\n \"files\": [\n \"" }, + { path: "/a/b/node_modules/.staging/lodash-b0733faa/package.json", content: "{\n \"name\": \"lodash\",\n \"version\": \"4.17.4\",\n \"description\": \"Lodash modular utilities.\",\n \"keywords\": \"modules, stdlib, util\",\n \"homepage\": \"https://lodash.com/\",\n \"repository\": \"lodash/lodash\",\n \"icon\": \"https://lodash.com/icon.svg\",\n \"license\": \"MIT\",\n \"main\": \"lodash.js\",\n \"author\": \"John-David Dalton (http://allyoucanleet.com/)\",\n \"contributors\": [\n \"John-David Dalton (http://allyoucanleet.com/)\",\n \"Mathias Bynens \",\n \"contributors\": [\n {\n \"name\": \"Ben Lesh\",\n \"email\": \"ben@benlesh.com\"\n },\n {\n \"name\": \"Paul Taylor\",\n \"email\": \"paul.e.taylor@me.com\"\n },\n {\n \"name\": \"Jeff Cross\",\n \"email\": \"crossj@google.com\"\n },\n {\n \"name\": \"Matthew Podwysocki\",\n \"email\": \"matthewp@microsoft.com\"\n },\n {\n \"name\": \"OJ Kwon\",\n \"email\": \"kwon.ohjoong@gmail.com\"\n },\n {\n \"name\": \"Andre Staltz\",\n \"email\": \"andre@staltz.com\"\n }\n ],\n \"license\": \"Apache-2.0\",\n \"bugs\": {\n \"url\": \"https://github.com/ReactiveX/RxJS/issues\"\n },\n \"homepage\": \"https://github.com/ReactiveX/RxJS\",\n \"devDependencies\": {\n \"babel-polyfill\": \"^6.23.0\",\n \"benchmark\": \"^2.1.0\",\n \"benchpress\": \"2.0.0-beta.1\",\n \"chai\": \"^3.5.0\",\n \"color\": \"^0.11.1\",\n \"colors\": \"1.1.2\",\n \"commitizen\": \"^2.8.6\",\n \"coveralls\": \"^2.11.13\",\n \"cz-conventional-changelog\": \"^1.2.0\",\n \"danger\": \"^1.1.0\",\n \"doctoc\": \"^1.0.0\",\n \"escape-string-regexp\": \"^1.0.5 \",\n \"esdoc\": \"^0.4.7\",\n \"eslint\": \"^3.8.0\",\n \"fs-extra\": \"^2.1.2\",\n \"get-folder-size\": \"^1.0.0\",\n \"glob\": \"^7.0.3\",\n \"gm\": \"^1.22.0\",\n \"google-closure-compiler-js\": \"^20170218.0.0\",\n \"gzip-size\": \"^3.0.0\",\n \"http-server\": \"^0.9.0\",\n \"husky\": \"^0.13.3\",\n \"lint-staged\": \"3.2.5\",\n \"lodash\": \"^4.15.0\",\n \"madge\": \"^1.4.3\",\n \"markdown-doctest\": \"^0.9.1\",\n \"minimist\": \"^1.2.0\",\n \"mkdirp\": \"^0.5.1\",\n \"mocha\": \"^3.0.2\",\n \"mocha-in-sauce\": \"0.0.1\",\n \"npm-run-all\": \"^4.0.2\",\n \"npm-scripts-info\": \"^0.3.4\",\n \"nyc\": \"^10.2.0\",\n \"opn-cli\": \"^3.1.0\",\n \"platform\": \"^1.3.1\",\n \"promise\": \"^7.1.1\",\n \"protractor\": \"^3.1.1\",\n \"rollup\": \"0.36.3\",\n \"rollup-plugin-inject\": \"^2.0.0\",\n \"rollup-plugin-node-resolve\": \"^2.0.0\",\n \"rx\": \"latest\",\n \"rxjs\": \"latest\",\n \"shx\": \"^0.2.2\",\n \"sinon\": \"^2.1.0\",\n \"sinon-chai\": \"^2.9.0\",\n \"source-map-support\": \"^0.4.0\",\n \"tslib\": \"^1.5.0\",\n \"tslint\": \"^4.4.2\",\n \"typescript\": \"~2.0.6\",\n \"typings\": \"^2.0.0\",\n \"validate-commit-msg\": \"^2.14.0\",\n \"watch\": \"^1.0.1\",\n \"webpack\": \"^1.13.1\",\n \"xmlhttprequest\": \"1.8.0\"\n },\n \"engines\": {\n \"npm\": \">=2.0.0\"\n },\n \"typings\": \"Rx.d.ts\",\n \"dependencies\": {\n \"symbol-observable\": \"^1.0.1\"\n }\n}" }, + { path: "/a/b/node_modules/.staging/typescript-8493ea5d/package.json", content: "{\n \"name\": \"typescript\",\n \"author\": \"Microsoft Corp.\",\n \"homepage\": \"http://typescriptlang.org/\",\n \"version\": \"2.4.2\",\n \"license\": \"Apache-2.0\",\n \"description\": \"TypeScript is a language for application scale JavaScript development\",\n \"keywords\": [\n \"TypeScript\",\n \"Microsoft\",\n \"compiler\",\n \"language\",\n \"javascript\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/Microsoft/TypeScript/issues\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/Microsoft/TypeScript.git\"\n },\n \"main\": \"./lib/typescript.js\",\n \"typings\": \"./lib/typescript.d.ts\",\n \"bin\": {\n \"tsc\": \"./bin/tsc\",\n \"tsserver\": \"./bin/tsserver\"\n },\n \"engines\": {\n \"node\": \">=4.2.0\"\n },\n \"devDependencies\": {\n \"@types/browserify\": \"latest\",\n \"@types/chai\": \"latest\",\n \"@types/convert-source-map\": \"latest\",\n \"@types/del\": \"latest\",\n \"@types/glob\": \"latest\",\n \"@types/gulp\": \"latest\",\n \"@types/gulp-concat\": \"latest\",\n \"@types/gulp-help\": \"latest\",\n \"@types/gulp-newer\": \"latest\",\n \"@types/gulp-sourcemaps\": \"latest\",\n \"@types/merge2\": \"latest\",\n \"@types/minimatch\": \"latest\",\n \"@types/minimist\": \"latest\",\n \"@types/mkdirp\": \"latest\",\n \"@types/mocha\": \"latest\",\n \"@types/node\": \"latest\",\n \"@types/q\": \"latest\",\n \"@types/run-sequence\": \"latest\",\n \"@types/through2\": \"latest\",\n \"browserify\": \"latest\",\n \"chai\": \"latest\",\n \"convert-source-map\": \"latest\",\n \"del\": \"latest\",\n \"gulp\": \"latest\",\n \"gulp-clone\": \"latest\",\n \"gulp-concat\": \"latest\",\n \"gulp-help\": \"latest\",\n \"gulp-insert\": \"latest\",\n \"gulp-newer\": \"latest\",\n \"gulp-sourcemaps\": \"latest\",\n \"gulp-typescript\": \"latest\",\n \"into-stream\": \"latest\",\n \"istanbul\": \"latest\",\n \"jake\": \"latest\",\n \"merge2\": \"latest\",\n \"minimist\": \"latest\",\n \"mkdirp\": \"latest\",\n \"mocha\": \"latest\",\n \"mocha-fivemat-progress-reporter\": \"latest\",\n \"q\": \"latest\",\n \"run-sequence\": \"latest\",\n \"sorcery\": \"latest\",\n \"through2\": \"latest\",\n \"travis-fold\": \"latest\",\n \"ts-node\": \"latest\",\n \"tslint\": \"latest\",\n \"typescript\": \"^2.4\"\n },\n \"scripts\": {\n \"pretest\": \"jake tests\",\n \"test\": \"jake runtests-parallel\",\n \"build\": \"npm run build:compiler && npm run build:tests\",\n \"build:compiler\": \"jake local\",\n \"build:tests\": \"jake tests\",\n \"start\": \"node lib/tsc\",\n \"clean\": \"jake clean\",\n \"gulp\": \"gulp\",\n \"jake\": \"jake\",\n \"lint\": \"jake lint\",\n \"setup-hooks\": \"node scripts/link-hooks.js\"\n },\n \"browser\": {\n \"buffer\": false,\n \"fs\": false,\n \"os\": false,\n \"path\": false\n }\n}" }, + { path: "/a/b/node_modules/.staging/symbol-observable-24bcbbff/index.js", content: "module.exports = require('./lib/index');\n" }, + { path: "/a/b/node_modules/.staging/symbol-observable-24bcbbff/index.d.ts", content: "declare const observableSymbol: symbol;\nexport default observableSymbol;\n" }, + { path: "/a/b/node_modules/.staging/symbol-observable-24bcbbff/lib" }, + { path: "/a/b/node_modules/.staging/symbol-observable-24bcbbff/lib/index.js", content: "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _ponyfill = require('./ponyfill');\n\nvar _ponyfill2 = _interopRequireDefault(_ponyfill);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar root; /* global window */\n\n\nif (typeof self !== 'undefined') {\n root = self;\n} else if (typeof window !== 'undefined') {\n root = window;\n} else if (typeof global !== 'undefined') {\n root = global;\n} else if (typeof module !== 'undefined') {\n root = module;\n} else {\n root = Function('return this')();\n}\n\nvar result = (0, _ponyfill2['default'])(root);\nexports['default'] = result;" }, ].map(getRootedFileOrFolder); verifyAfterPartialOrCompleteNpmInstall(2); filesAndFoldersToAdd.push(...[ - { "path": "/a/b/node_modules/.staging/typescript-8493ea5d/lib" }, - { "path": "/a/b/node_modules/.staging/rxjs-22375c61/add/operator" }, - { "path": "/a/b/node_modules/.staging/@types/lodash-e56c4fe7/package.json", "content": "{\n \"name\": \"@types/lodash\",\n \"version\": \"4.14.74\",\n \"description\": \"TypeScript definitions for Lo-Dash\",\n \"license\": \"MIT\",\n \"contributors\": [\n {\n \"name\": \"Brian Zengel\",\n \"url\": \"https://github.com/bczengel\"\n },\n {\n \"name\": \"Ilya Mochalov\",\n \"url\": \"https://github.com/chrootsu\"\n },\n {\n \"name\": \"Stepan Mikhaylyuk\",\n \"url\": \"https://github.com/stepancar\"\n },\n {\n \"name\": \"Eric L Anderson\",\n \"url\": \"https://github.com/ericanderson\"\n },\n {\n \"name\": \"AJ Richardson\",\n \"url\": \"https://github.com/aj-r\"\n },\n {\n \"name\": \"Junyoung Clare Jang\",\n \"url\": \"https://github.com/ailrun\"\n }\n ],\n \"main\": \"\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://www.github.com/DefinitelyTyped/DefinitelyTyped.git\"\n },\n \"scripts\": {},\n \"dependencies\": {},\n \"typesPublisherContentHash\": \"12af578ffaf8d86d2df37e591857906a86b983fa9258414326544a0fe6af0de8\",\n \"typeScriptVersion\": \"2.2\"\n}" }, - { "path": "/a/b/node_modules/.staging/lodash-b0733faa/index.js", "content": "module.exports = require('./lodash');" }, - { "path": "/a/b/node_modules/.staging/typescript-8493ea5d/package.json.3017591594" } + { path: "/a/b/node_modules/.staging/typescript-8493ea5d/lib" }, + { path: "/a/b/node_modules/.staging/rxjs-22375c61/add/operator" }, + { path: "/a/b/node_modules/.staging/@types/lodash-e56c4fe7/package.json", content: "{\n \"name\": \"@types/lodash\",\n \"version\": \"4.14.74\",\n \"description\": \"TypeScript definitions for Lo-Dash\",\n \"license\": \"MIT\",\n \"contributors\": [\n {\n \"name\": \"Brian Zengel\",\n \"url\": \"https://github.com/bczengel\"\n },\n {\n \"name\": \"Ilya Mochalov\",\n \"url\": \"https://github.com/chrootsu\"\n },\n {\n \"name\": \"Stepan Mikhaylyuk\",\n \"url\": \"https://github.com/stepancar\"\n },\n {\n \"name\": \"Eric L Anderson\",\n \"url\": \"https://github.com/ericanderson\"\n },\n {\n \"name\": \"AJ Richardson\",\n \"url\": \"https://github.com/aj-r\"\n },\n {\n \"name\": \"Junyoung Clare Jang\",\n \"url\": \"https://github.com/ailrun\"\n }\n ],\n \"main\": \"\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://www.github.com/DefinitelyTyped/DefinitelyTyped.git\"\n },\n \"scripts\": {},\n \"dependencies\": {},\n \"typesPublisherContentHash\": \"12af578ffaf8d86d2df37e591857906a86b983fa9258414326544a0fe6af0de8\",\n \"typeScriptVersion\": \"2.2\"\n}" }, + { path: "/a/b/node_modules/.staging/lodash-b0733faa/index.js", content: "module.exports = require('./lodash');" }, + { path: "/a/b/node_modules/.staging/typescript-8493ea5d/package.json.3017591594" } ].map(getRootedFileOrFolder)); // Since we didnt add any supported extension file, there wont be any timeout scheduled verifyAfterPartialOrCompleteNpmInstall(0); @@ -5665,19 +5665,19 @@ namespace ts.projectSystem { verifyAfterPartialOrCompleteNpmInstall(0); filesAndFoldersToAdd.push(...[ - { "path": "/a/b/node_modules/.staging/rxjs-22375c61/bundles" }, - { "path": "/a/b/node_modules/.staging/rxjs-22375c61/operator" }, - { "path": "/a/b/node_modules/.staging/rxjs-22375c61/src/add/observable/dom" }, - { "path": "/a/b/node_modules/.staging/@types/lodash-e56c4fe7/index.d.ts", "content": "\n// Stub for lodash\nexport = _;\nexport as namespace _;\ndeclare var _: _.LoDashStatic;\ndeclare namespace _ {\n interface LoDashStatic {\n someProp: string;\n }\n class SomeClass {\n someMethod(): void;\n }\n}" } + { path: "/a/b/node_modules/.staging/rxjs-22375c61/bundles" }, + { path: "/a/b/node_modules/.staging/rxjs-22375c61/operator" }, + { path: "/a/b/node_modules/.staging/rxjs-22375c61/src/add/observable/dom" }, + { path: "/a/b/node_modules/.staging/@types/lodash-e56c4fe7/index.d.ts", content: "\n// Stub for lodash\nexport = _;\nexport as namespace _;\ndeclare var _: _.LoDashStatic;\ndeclare namespace _ {\n interface LoDashStatic {\n someProp: string;\n }\n class SomeClass {\n someMethod(): void;\n }\n}" } ].map(getRootedFileOrFolder)); verifyAfterPartialOrCompleteNpmInstall(2); filesAndFoldersToAdd.push(...[ - { "path": "/a/b/node_modules/.staging/rxjs-22375c61/src/scheduler" }, - { "path": "/a/b/node_modules/.staging/rxjs-22375c61/src/util" }, - { "path": "/a/b/node_modules/.staging/rxjs-22375c61/symbol" }, - { "path": "/a/b/node_modules/.staging/rxjs-22375c61/testing" }, - { "path": "/a/b/node_modules/.staging/rxjs-22375c61/package.json.2252192041", "content": "{\n \"_args\": [\n [\n {\n \"raw\": \"rxjs@^5.4.2\",\n \"scope\": null,\n \"escapedName\": \"rxjs\",\n \"name\": \"rxjs\",\n \"rawSpec\": \"^5.4.2\",\n \"spec\": \">=5.4.2 <6.0.0\",\n \"type\": \"range\"\n },\n \"C:\\\\Users\\\\shkamat\\\\Desktop\\\\app\"\n ]\n ],\n \"_from\": \"rxjs@>=5.4.2 <6.0.0\",\n \"_id\": \"rxjs@5.4.3\",\n \"_inCache\": true,\n \"_location\": \"/rxjs\",\n \"_nodeVersion\": \"7.7.2\",\n \"_npmOperationalInternal\": {\n \"host\": \"s3://npm-registry-packages\",\n \"tmp\": \"tmp/rxjs-5.4.3.tgz_1502407898166_0.6800217325799167\"\n },\n \"_npmUser\": {\n \"name\": \"blesh\",\n \"email\": \"ben@benlesh.com\"\n },\n \"_npmVersion\": \"5.3.0\",\n \"_phantomChildren\": {},\n \"_requested\": {\n \"raw\": \"rxjs@^5.4.2\",\n \"scope\": null,\n \"escapedName\": \"rxjs\",\n \"name\": \"rxjs\",\n \"rawSpec\": \"^5.4.2\",\n \"spec\": \">=5.4.2 <6.0.0\",\n \"type\": \"range\"\n },\n \"_requiredBy\": [\n \"/\"\n ],\n \"_resolved\": \"https://registry.npmjs.org/rxjs/-/rxjs-5.4.3.tgz\",\n \"_shasum\": \"0758cddee6033d68e0fd53676f0f3596ce3d483f\",\n \"_shrinkwrap\": null,\n \"_spec\": \"rxjs@^5.4.2\",\n \"_where\": \"C:\\\\Users\\\\shkamat\\\\Desktop\\\\app\",\n \"author\": {\n \"name\": \"Ben Lesh\",\n \"email\": \"ben@benlesh.com\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/ReactiveX/RxJS/issues\"\n },\n \"config\": {\n \"commitizen\": {\n \"path\": \"cz-conventional-changelog\"\n }\n },\n \"contributors\": [\n {\n \"name\": \"Ben Lesh\",\n \"email\": \"ben@benlesh.com\"\n },\n {\n \"name\": \"Paul Taylor\",\n \"email\": \"paul.e.taylor@me.com\"\n },\n {\n \"name\": \"Jeff Cross\",\n \"email\": \"crossj@google.com\"\n },\n {\n \"name\": \"Matthew Podwysocki\",\n \"email\": \"matthewp@microsoft.com\"\n },\n {\n \"name\": \"OJ Kwon\",\n \"email\": \"kwon.ohjoong@gmail.com\"\n },\n {\n \"name\": \"Andre Staltz\",\n \"email\": \"andre@staltz.com\"\n }\n ],\n \"dependencies\": {\n \"symbol-observable\": \"^1.0.1\"\n },\n \"description\": \"Reactive Extensions for modern JavaScript\",\n \"devDependencies\": {\n \"babel-polyfill\": \"^6.23.0\",\n \"benchmark\": \"^2.1.0\",\n \"benchpress\": \"2.0.0-beta.1\",\n \"chai\": \"^3.5.0\",\n \"color\": \"^0.11.1\",\n \"colors\": \"1.1.2\",\n \"commitizen\": \"^2.8.6\",\n \"coveralls\": \"^2.11.13\",\n \"cz-conventional-changelog\": \"^1.2.0\",\n \"danger\": \"^1.1.0\",\n \"doctoc\": \"^1.0.0\",\n \"escape-string-regexp\": \"^1.0.5 \",\n \"esdoc\": \"^0.4.7\",\n \"eslint\": \"^3.8.0\",\n \"fs-extra\": \"^2.1.2\",\n \"get-folder-size\": \"^1.0.0\",\n \"glob\": \"^7.0.3\",\n \"gm\": \"^1.22.0\",\n \"google-closure-compiler-js\": \"^20170218.0.0\",\n \"gzip-size\": \"^3.0.0\",\n \"http-server\": \"^0.9.0\",\n \"husky\": \"^0.13.3\",\n \"lint-staged\": \"3.2.5\",\n \"lodash\": \"^4.15.0\",\n \"madge\": \"^1.4.3\",\n \"markdown-doctest\": \"^0.9.1\",\n \"minimist\": \"^1.2.0\",\n \"mkdirp\": \"^0.5.1\",\n \"mocha\": \"^3.0.2\",\n \"mocha-in-sauce\": \"0.0.1\",\n \"npm-run-all\": \"^4.0.2\",\n \"npm-scripts-info\": \"^0.3.4\",\n \"nyc\": \"^10.2.0\",\n \"opn-cli\": \"^3.1.0\",\n \"platform\": \"^1.3.1\",\n \"promise\": \"^7.1.1\",\n \"protractor\": \"^3.1.1\",\n \"rollup\": \"0.36.3\",\n \"rollup-plugin-inject\": \"^2.0.0\",\n \"rollup-plugin-node-resolve\": \"^2.0.0\",\n \"rx\": \"latest\",\n \"rxjs\": \"latest\",\n \"shx\": \"^0.2.2\",\n \"sinon\": \"^2.1.0\",\n \"sinon-chai\": \"^2.9.0\",\n \"source-map-support\": \"^0.4.0\",\n \"tslib\": \"^1.5.0\",\n \"tslint\": \"^4.4.2\",\n \"typescript\": \"~2.0.6\",\n \"typings\": \"^2.0.0\",\n \"validate-commit-msg\": \"^2.14.0\",\n \"watch\": \"^1.0.1\",\n \"webpack\": \"^1.13.1\",\n \"xmlhttprequest\": \"1.8.0\"\n },\n \"directories\": {},\n \"dist\": {\n \"integrity\": \"sha512-fSNi+y+P9ss+EZuV0GcIIqPUK07DEaMRUtLJvdcvMyFjc9dizuDjere+A4V7JrLGnm9iCc+nagV/4QdMTkqC4A==\",\n \"shasum\": \"0758cddee6033d68e0fd53676f0f3596ce3d483f\",\n \"tarball\": \"https://registry.npmjs.org/rxjs/-/rxjs-5.4.3.tgz\"\n },\n \"engines\": {\n \"npm\": \">=2.0.0\"\n },\n \"homepage\": \"https://github.com/ReactiveX/RxJS\",\n \"keywords\": [\n \"Rx\",\n \"RxJS\",\n \"ReactiveX\",\n \"ReactiveExtensions\",\n \"Streams\",\n \"Observables\",\n \"Observable\",\n \"Stream\",\n \"ES6\",\n \"ES2015\"\n ],\n \"license\": \"Apache-2.0\",\n \"lint-staged\": {\n \"*.@(js)\": [\n \"eslint --fix\",\n \"git add\"\n ],\n \"*.@(ts)\": [\n \"tslint --fix\",\n \"git add\"\n ]\n },\n \"main\": \"Rx.js\",\n \"maintainers\": [\n {\n \"name\": \"blesh\",\n \"email\": \"ben@benlesh.com\"\n }\n ],\n \"name\": \"rxjs\",\n \"optionalDependencies\": {},\n \"readme\": \"ERROR: No README data found!\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+ssh://git@github.com/ReactiveX/RxJS.git\"\n },\n \"scripts-info\": {\n \"info\": \"List available script\",\n \"build_all\": \"Build all packages (ES6, CJS, UMD) and generate packages\",\n \"build_cjs\": \"Build CJS package with clean up existing build, copy source into dist\",\n \"build_es6\": \"Build ES6 package with clean up existing build, copy source into dist\",\n \"build_closure_core\": \"Minify Global core build using closure compiler\",\n \"build_global\": \"Build Global package, then minify build\",\n \"build_perf\": \"Build CJS & Global build, run macro performance test\",\n \"build_test\": \"Build CJS package & test spec, execute mocha test runner\",\n \"build_cover\": \"Run lint to current code, build CJS & test spec, execute test coverage\",\n \"build_docs\": \"Build ES6 & global package, create documentation using it\",\n \"build_spec\": \"Build test specs\",\n \"check_circular_dependencies\": \"Check codebase has circular dependencies\",\n \"clean_spec\": \"Clean up existing test spec build output\",\n \"clean_dist_cjs\": \"Clean up existing CJS package output\",\n \"clean_dist_es6\": \"Clean up existing ES6 package output\",\n \"clean_dist_global\": \"Clean up existing Global package output\",\n \"commit\": \"Run git commit wizard\",\n \"compile_dist_cjs\": \"Compile codebase into CJS module\",\n \"compile_module_es6\": \"Compile codebase into ES6\",\n \"cover\": \"Execute test coverage\",\n \"lint_perf\": \"Run lint against performance test suite\",\n \"lint_spec\": \"Run lint against test spec\",\n \"lint_src\": \"Run lint against source\",\n \"lint\": \"Run lint against everything\",\n \"perf\": \"Run macro performance benchmark\",\n \"perf_micro\": \"Run micro performance benchmark\",\n \"test_mocha\": \"Execute mocha test runner against existing test spec build\",\n \"test_browser\": \"Execute mocha test runner on browser against existing test spec build\",\n \"test\": \"Clean up existing test spec build, build test spec and execute mocha test runner\",\n \"tests2png\": \"Generate marble diagram image from test spec\",\n \"watch\": \"Watch codebase, trigger compile when source code changes\"\n },\n \"typings\": \"Rx.d.ts\",\n \"version\": \"5.4.3\"\n}\n" } + { path: "/a/b/node_modules/.staging/rxjs-22375c61/src/scheduler" }, + { path: "/a/b/node_modules/.staging/rxjs-22375c61/src/util" }, + { path: "/a/b/node_modules/.staging/rxjs-22375c61/symbol" }, + { path: "/a/b/node_modules/.staging/rxjs-22375c61/testing" }, + { path: "/a/b/node_modules/.staging/rxjs-22375c61/package.json.2252192041", content: "{\n \"_args\": [\n [\n {\n \"raw\": \"rxjs@^5.4.2\",\n \"scope\": null,\n \"escapedName\": \"rxjs\",\n \"name\": \"rxjs\",\n \"rawSpec\": \"^5.4.2\",\n \"spec\": \">=5.4.2 <6.0.0\",\n \"type\": \"range\"\n },\n \"C:\\\\Users\\\\shkamat\\\\Desktop\\\\app\"\n ]\n ],\n \"_from\": \"rxjs@>=5.4.2 <6.0.0\",\n \"_id\": \"rxjs@5.4.3\",\n \"_inCache\": true,\n \"_location\": \"/rxjs\",\n \"_nodeVersion\": \"7.7.2\",\n \"_npmOperationalInternal\": {\n \"host\": \"s3://npm-registry-packages\",\n \"tmp\": \"tmp/rxjs-5.4.3.tgz_1502407898166_0.6800217325799167\"\n },\n \"_npmUser\": {\n \"name\": \"blesh\",\n \"email\": \"ben@benlesh.com\"\n },\n \"_npmVersion\": \"5.3.0\",\n \"_phantomChildren\": {},\n \"_requested\": {\n \"raw\": \"rxjs@^5.4.2\",\n \"scope\": null,\n \"escapedName\": \"rxjs\",\n \"name\": \"rxjs\",\n \"rawSpec\": \"^5.4.2\",\n \"spec\": \">=5.4.2 <6.0.0\",\n \"type\": \"range\"\n },\n \"_requiredBy\": [\n \"/\"\n ],\n \"_resolved\": \"https://registry.npmjs.org/rxjs/-/rxjs-5.4.3.tgz\",\n \"_shasum\": \"0758cddee6033d68e0fd53676f0f3596ce3d483f\",\n \"_shrinkwrap\": null,\n \"_spec\": \"rxjs@^5.4.2\",\n \"_where\": \"C:\\\\Users\\\\shkamat\\\\Desktop\\\\app\",\n \"author\": {\n \"name\": \"Ben Lesh\",\n \"email\": \"ben@benlesh.com\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/ReactiveX/RxJS/issues\"\n },\n \"config\": {\n \"commitizen\": {\n \"path\": \"cz-conventional-changelog\"\n }\n },\n \"contributors\": [\n {\n \"name\": \"Ben Lesh\",\n \"email\": \"ben@benlesh.com\"\n },\n {\n \"name\": \"Paul Taylor\",\n \"email\": \"paul.e.taylor@me.com\"\n },\n {\n \"name\": \"Jeff Cross\",\n \"email\": \"crossj@google.com\"\n },\n {\n \"name\": \"Matthew Podwysocki\",\n \"email\": \"matthewp@microsoft.com\"\n },\n {\n \"name\": \"OJ Kwon\",\n \"email\": \"kwon.ohjoong@gmail.com\"\n },\n {\n \"name\": \"Andre Staltz\",\n \"email\": \"andre@staltz.com\"\n }\n ],\n \"dependencies\": {\n \"symbol-observable\": \"^1.0.1\"\n },\n \"description\": \"Reactive Extensions for modern JavaScript\",\n \"devDependencies\": {\n \"babel-polyfill\": \"^6.23.0\",\n \"benchmark\": \"^2.1.0\",\n \"benchpress\": \"2.0.0-beta.1\",\n \"chai\": \"^3.5.0\",\n \"color\": \"^0.11.1\",\n \"colors\": \"1.1.2\",\n \"commitizen\": \"^2.8.6\",\n \"coveralls\": \"^2.11.13\",\n \"cz-conventional-changelog\": \"^1.2.0\",\n \"danger\": \"^1.1.0\",\n \"doctoc\": \"^1.0.0\",\n \"escape-string-regexp\": \"^1.0.5 \",\n \"esdoc\": \"^0.4.7\",\n \"eslint\": \"^3.8.0\",\n \"fs-extra\": \"^2.1.2\",\n \"get-folder-size\": \"^1.0.0\",\n \"glob\": \"^7.0.3\",\n \"gm\": \"^1.22.0\",\n \"google-closure-compiler-js\": \"^20170218.0.0\",\n \"gzip-size\": \"^3.0.0\",\n \"http-server\": \"^0.9.0\",\n \"husky\": \"^0.13.3\",\n \"lint-staged\": \"3.2.5\",\n \"lodash\": \"^4.15.0\",\n \"madge\": \"^1.4.3\",\n \"markdown-doctest\": \"^0.9.1\",\n \"minimist\": \"^1.2.0\",\n \"mkdirp\": \"^0.5.1\",\n \"mocha\": \"^3.0.2\",\n \"mocha-in-sauce\": \"0.0.1\",\n \"npm-run-all\": \"^4.0.2\",\n \"npm-scripts-info\": \"^0.3.4\",\n \"nyc\": \"^10.2.0\",\n \"opn-cli\": \"^3.1.0\",\n \"platform\": \"^1.3.1\",\n \"promise\": \"^7.1.1\",\n \"protractor\": \"^3.1.1\",\n \"rollup\": \"0.36.3\",\n \"rollup-plugin-inject\": \"^2.0.0\",\n \"rollup-plugin-node-resolve\": \"^2.0.0\",\n \"rx\": \"latest\",\n \"rxjs\": \"latest\",\n \"shx\": \"^0.2.2\",\n \"sinon\": \"^2.1.0\",\n \"sinon-chai\": \"^2.9.0\",\n \"source-map-support\": \"^0.4.0\",\n \"tslib\": \"^1.5.0\",\n \"tslint\": \"^4.4.2\",\n \"typescript\": \"~2.0.6\",\n \"typings\": \"^2.0.0\",\n \"validate-commit-msg\": \"^2.14.0\",\n \"watch\": \"^1.0.1\",\n \"webpack\": \"^1.13.1\",\n \"xmlhttprequest\": \"1.8.0\"\n },\n \"directories\": {},\n \"dist\": {\n \"integrity\": \"sha512-fSNi+y+P9ss+EZuV0GcIIqPUK07DEaMRUtLJvdcvMyFjc9dizuDjere+A4V7JrLGnm9iCc+nagV/4QdMTkqC4A==\",\n \"shasum\": \"0758cddee6033d68e0fd53676f0f3596ce3d483f\",\n \"tarball\": \"https://registry.npmjs.org/rxjs/-/rxjs-5.4.3.tgz\"\n },\n \"engines\": {\n \"npm\": \">=2.0.0\"\n },\n \"homepage\": \"https://github.com/ReactiveX/RxJS\",\n \"keywords\": [\n \"Rx\",\n \"RxJS\",\n \"ReactiveX\",\n \"ReactiveExtensions\",\n \"Streams\",\n \"Observables\",\n \"Observable\",\n \"Stream\",\n \"ES6\",\n \"ES2015\"\n ],\n \"license\": \"Apache-2.0\",\n \"lint-staged\": {\n \"*.@(js)\": [\n \"eslint --fix\",\n \"git add\"\n ],\n \"*.@(ts)\": [\n \"tslint --fix\",\n \"git add\"\n ]\n },\n \"main\": \"Rx.js\",\n \"maintainers\": [\n {\n \"name\": \"blesh\",\n \"email\": \"ben@benlesh.com\"\n }\n ],\n \"name\": \"rxjs\",\n \"optionalDependencies\": {},\n \"readme\": \"ERROR: No README data found!\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+ssh://git@github.com/ReactiveX/RxJS.git\"\n },\n \"scripts-info\": {\n \"info\": \"List available script\",\n \"build_all\": \"Build all packages (ES6, CJS, UMD) and generate packages\",\n \"build_cjs\": \"Build CJS package with clean up existing build, copy source into dist\",\n \"build_es6\": \"Build ES6 package with clean up existing build, copy source into dist\",\n \"build_closure_core\": \"Minify Global core build using closure compiler\",\n \"build_global\": \"Build Global package, then minify build\",\n \"build_perf\": \"Build CJS & Global build, run macro performance test\",\n \"build_test\": \"Build CJS package & test spec, execute mocha test runner\",\n \"build_cover\": \"Run lint to current code, build CJS & test spec, execute test coverage\",\n \"build_docs\": \"Build ES6 & global package, create documentation using it\",\n \"build_spec\": \"Build test specs\",\n \"check_circular_dependencies\": \"Check codebase has circular dependencies\",\n \"clean_spec\": \"Clean up existing test spec build output\",\n \"clean_dist_cjs\": \"Clean up existing CJS package output\",\n \"clean_dist_es6\": \"Clean up existing ES6 package output\",\n \"clean_dist_global\": \"Clean up existing Global package output\",\n \"commit\": \"Run git commit wizard\",\n \"compile_dist_cjs\": \"Compile codebase into CJS module\",\n \"compile_module_es6\": \"Compile codebase into ES6\",\n \"cover\": \"Execute test coverage\",\n \"lint_perf\": \"Run lint against performance test suite\",\n \"lint_spec\": \"Run lint against test spec\",\n \"lint_src\": \"Run lint against source\",\n \"lint\": \"Run lint against everything\",\n \"perf\": \"Run macro performance benchmark\",\n \"perf_micro\": \"Run micro performance benchmark\",\n \"test_mocha\": \"Execute mocha test runner against existing test spec build\",\n \"test_browser\": \"Execute mocha test runner on browser against existing test spec build\",\n \"test\": \"Clean up existing test spec build, build test spec and execute mocha test runner\",\n \"tests2png\": \"Generate marble diagram image from test spec\",\n \"watch\": \"Watch codebase, trigger compile when source code changes\"\n },\n \"typings\": \"Rx.d.ts\",\n \"version\": \"5.4.3\"\n}\n" } ].map(getRootedFileOrFolder)); verifyAfterPartialOrCompleteNpmInstall(0); @@ -5685,13 +5685,13 @@ namespace ts.projectSystem { filesAndFoldersToAdd.length--; // and add few more folders/files filesAndFoldersToAdd.push(...[ - { "path": "/a/b/node_modules/symbol-observable" }, - { "path": "/a/b/node_modules/@types" }, - { "path": "/a/b/node_modules/@types/lodash" }, - { "path": "/a/b/node_modules/lodash" }, - { "path": "/a/b/node_modules/rxjs" }, - { "path": "/a/b/node_modules/typescript" }, - { "path": "/a/b/node_modules/.bin" } + { path: "/a/b/node_modules/symbol-observable" }, + { path: "/a/b/node_modules/@types" }, + { path: "/a/b/node_modules/@types/lodash" }, + { path: "/a/b/node_modules/lodash" }, + { path: "/a/b/node_modules/rxjs" }, + { path: "/a/b/node_modules/typescript" }, + { path: "/a/b/node_modules/.bin" } ].map(getRootedFileOrFolder)); // From the type root update verifyAfterPartialOrCompleteNpmInstall(2); diff --git a/src/harness/unittests/typingsInstaller.ts b/src/harness/unittests/typingsInstaller.ts index fb1a7a26a7a..2ae9587b78e 100644 --- a/src/harness/unittests/typingsInstaller.ts +++ b/src/harness/unittests/typingsInstaller.ts @@ -776,8 +776,8 @@ namespace ts.projectSystem { const bowerJson = { path: "/bower.json", content: JSON.stringify({ - "dependencies": { - "jquery": "^3.1.0" + dependencies: { + jquery: "^3.1.0" } }) }; @@ -1012,7 +1012,7 @@ namespace ts.projectSystem { const packageJson = { path: "/a/b/package.json", content: JSON.stringify({ - "dependencies": { + dependencies: { "; say ‘Hello from TypeScript!’ #": "0.0.x" } }) @@ -1094,7 +1094,7 @@ namespace ts.projectSystem { content: "" }; const host = createServerHost([f, node]); - const cache = createMapFromTemplate({ "node": node.path }); + const cache = createMapFromTemplate({ node: node.path }); const logger = trackingLogger(); const result = JsTyping.discoverTypings(host, logger.log, [f.path], getDirectoryPath(f.path), emptySafeList, cache, { enable: true }, ["fs", "bar"]); assert.deepEqual(logger.finish(), [ @@ -1144,7 +1144,7 @@ namespace ts.projectSystem { }; const packageFile = { path: "/a/package.json", - content: JSON.stringify({ dependencies: { "commander": "1.0.0" } }) + content: JSON.stringify({ dependencies: { commander: "1.0.0" } }) }; const cachePath = "/a/cache/"; const commander = { @@ -1194,7 +1194,7 @@ namespace ts.projectSystem { }; const packageFile = { path: "/a/package.json", - content: JSON.stringify({ dependencies: { "commander": "1.0.0" } }) + content: JSON.stringify({ dependencies: { commander: "1.0.0" } }) }; const cachePath = "/a/cache/"; const commander = { @@ -1246,7 +1246,7 @@ namespace ts.projectSystem { }; const packageFile = { path: "/a/package.json", - content: JSON.stringify({ dependencies: { "commander": "1.0.0" } }) + content: JSON.stringify({ dependencies: { commander: "1.0.0" } }) }; const cachePath = "/a/cache/"; const host = createServerHost([f1, packageFile]); diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 086bb6b38d8..0627f3038bb 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -103,9 +103,9 @@ namespace ts.server { const compilerOptionConverters = prepareConvertersForEnumLikeCompilerOptions(optionDeclarations); const indentStyle = createMapFromTemplate({ - "none": IndentStyle.None, - "block": IndentStyle.Block, - "smart": IndentStyle.Smart + none: IndentStyle.None, + block: IndentStyle.Block, + smart: IndentStyle.Smart }); export interface TypesMapFile { @@ -134,31 +134,31 @@ namespace ts.server { const defaultTypeSafeList: SafeList = { "jquery": { // jquery files can have names like "jquery-1.10.2.min.js" (or "jquery.intellisense.js") - "match": /jquery(-(\.?\d+)+)?(\.intellisense)?(\.min)?\.js$/i, - "types": ["jquery"] + match: /jquery(-(\.?\d+)+)?(\.intellisense)?(\.min)?\.js$/i, + types: ["jquery"] }, "WinJS": { // e.g. c:/temp/UWApp1/lib/winjs-4.0.1/js/base.js - "match": /^(.*\/winjs-[.\d]+)\/js\/base\.js$/i, // If the winjs/base.js file is found.. - "exclude": [["^", 1, "/.*"]], // ..then exclude all files under the winjs folder - "types": ["winjs"] // And fetch the @types package for WinJS + match: /^(.*\/winjs-[.\d]+)\/js\/base\.js$/i, // If the winjs/base.js file is found.. + exclude: [["^", 1, "/.*"]], // ..then exclude all files under the winjs folder + types: ["winjs"] // And fetch the @types package for WinJS }, "Kendo": { // e.g. /Kendo3/wwwroot/lib/kendo/kendo.all.min.js - "match": /^(.*\/kendo)\/kendo\.all\.min\.js$/i, - "exclude": [["^", 1, "/.*"]], - "types": ["kendo-ui"] + match: /^(.*\/kendo)\/kendo\.all\.min\.js$/i, + exclude: [["^", 1, "/.*"]], + types: ["kendo-ui"] }, "Office Nuget": { // e.g. /scripts/Office/1/excel-15.debug.js - "match": /^(.*\/office\/1)\/excel-\d+\.debug\.js$/i, // Office NuGet package is installed under a "1/office" folder - "exclude": [["^", 1, "/.*"]], // Exclude that whole folder if the file indicated above is found in it - "types": ["office"] // @types package to fetch instead + match: /^(.*\/office\/1)\/excel-\d+\.debug\.js$/i, // Office NuGet package is installed under a "1/office" folder + exclude: [["^", 1, "/.*"]], // Exclude that whole folder if the file indicated above is found in it + types: ["office"] // @types package to fetch instead }, "Minified files": { // e.g. /whatever/blah.min.js - "match": /^(.+\.min\.js)$/i, - "exclude": [["^", 1, "$"]] + match: /^(.+\.min\.js)$/i, + exclude: [["^", 1, "$"]] } }; diff --git a/src/server/server.ts b/src/server/server.ts index 4902983ad45..f4faa0d3c77 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -828,7 +828,7 @@ namespace ts.server { if (logger.hasLevel(LogLevel.verbose)) { logger.info(`Starting ${process.execPath} with args:${stringifyIndented(args)}`); } - childProcess.execFileSync(process.execPath, args, { stdio: "ignore", env: { "ELECTRON_RUN_AS_NODE": "1" } }); + childProcess.execFileSync(process.execPath, args, { stdio: "ignore", env: { ELECTRON_RUN_AS_NODE: "1" } }); status = true; if (logger.hasLevel(LogLevel.verbose)) { logger.info(`WatchGuard for path ${path} returned: OK`); diff --git a/tslint.json b/tslint.json index 98033b92265..2d7c702b8aa 100644 --- a/tslint.json +++ b/tslint.json @@ -74,6 +74,7 @@ // Config different from tslint:latest "no-implicit-dependencies": [true, "dev"], + "object-literal-key-quotes": [true, "consistent-as-needed"], "variable-name": [true, "ban-keywords", "check-format", "allow-leading-underscore"], // TODO @@ -94,7 +95,6 @@ "no-submodule-imports": false, "no-unnecessary-initializer": false, "no-var-requires": false, - "object-literal-key-quotes": false, "ordered-imports": false, "prefer-conditional-expression": false, "radix": false, From 2f13222180dee1cbfac550955d98f2da556b7c8a Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Mon, 6 Nov 2017 18:29:38 -0800 Subject: [PATCH 155/235] Handle windows linebreaks in getSourceFileImportLocation --- src/services/utilities.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 36089f94f73..643aae2bae1 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1335,18 +1335,30 @@ namespace ts { let position = 0; // However we should still skip a pinned comment at the top if (ranges.length && ranges[0].kind === SyntaxKind.MultiLineCommentTrivia && isPinnedComment(text, ranges[0])) { - position = ranges[0].end + 1; + position = ranges[0].end; + AdvancePastLineBreak(); ranges = ranges.slice(1); } // As well as any triple slash references for (const range of ranges) { if (range.kind === SyntaxKind.SingleLineCommentTrivia && isRecognizedTripleSlashComment(node.text, range.pos, range.end)) { - position = range.end + 1; + position = range.end; + AdvancePastLineBreak(); continue; } break; } return position; + + function AdvancePastLineBreak() { + if (text.charCodeAt(position) === 0xD) { + position++; + } + + if (text.charCodeAt(position) === 0xA) { + position++; + } + } } /** From 77b24aec839501c709d3c37be6626e399cb7fd97 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 6 Nov 2017 18:38:03 -0800 Subject: [PATCH 156/235] Apply 'unified-signatures' tslint rule (#19738) * Apply 'unified-signatures' tslint rule * Fix new failure --- src/compiler/factory.ts | 7 +++--- src/harness/fourslash.ts | 23 ++++++------------- src/services/types.ts | 2 ++ .../reference/api/tsserverlibrary.d.ts | 5 ++-- tests/baselines/reference/api/typescript.d.ts | 5 ++-- tslint.json | 1 - 6 files changed, 17 insertions(+), 26 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index c9e0fec5927..6a56b6da049 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -70,11 +70,10 @@ namespace ts { // Literals - export function createLiteral(value: string): StringLiteral; + /** If a node is passed, creates a string literal whose source text is read from a source node during emit. */ + export function createLiteral(value: string | StringLiteral | NumericLiteral | Identifier): StringLiteral; export function createLiteral(value: number): NumericLiteral; export function createLiteral(value: boolean): BooleanLiteral; - /** Create a string literal whose source text is read from a source node during emit. */ - export function createLiteral(sourceNode: StringLiteral | NumericLiteral | Identifier): StringLiteral; export function createLiteral(value: string | number | boolean): PrimaryExpression; export function createLiteral(value: string | number | boolean | StringLiteral | NumericLiteral | Identifier): PrimaryExpression { if (typeof value === "number") { @@ -113,6 +112,7 @@ namespace ts { export function createIdentifier(text: string): Identifier; /* @internal */ + // tslint:disable-next-line unified-signatures export function createIdentifier(text: string, typeArguments: ReadonlyArray): Identifier; export function createIdentifier(text: string, typeArguments?: ReadonlyArray): Identifier { const node = createSynthesizedNode(SyntaxKind.Identifier); @@ -166,6 +166,7 @@ namespace ts { /** Create a unique name generated for a node. */ export function getGeneratedNameForNode(node: Node): Identifier; + // tslint:disable-next-line unified-signatures /*@internal*/ export function getGeneratedNameForNode(node: Node, shouldSkipNameGenerationScope?: boolean): Identifier; export function getGeneratedNameForNode(node: Node, shouldSkipNameGenerationScope?: boolean): Identifier { const name = createIdentifier(""); diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 85011525d52..91e22689fcf 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -483,9 +483,7 @@ namespace FourSlash { } // Opens a file given its 0-based index or fileName - public openFile(index: number, content?: string, scriptKindName?: string): void; - public openFile(name: string, content?: string, scriptKindName?: string): void; - public openFile(indexOrName: any, content?: string, scriptKindName?: string) { + public openFile(indexOrName: number | string, content?: string, scriptKindName?: string): void { const fileToOpen: FourSlashFile = this.findFile(indexOrName); fileToOpen.fileName = ts.normalizeSlashes(fileToOpen.fileName); this.activeFile = fileToOpen; @@ -3093,7 +3091,7 @@ Actual: ${stringify(fullActual)}`); this.raiseError(`Expected "${stringify({ entryId, text, documentation, kind })}" to be in list [${itemsString}]`); } - private findFile(indexOrName: any) { + private findFile(indexOrName: string | number) { let result: FourSlashFile; if (typeof indexOrName === "number") { const index = indexOrName; @@ -3745,9 +3743,7 @@ namespace FourSlashInterface { this.state.goToImplementation(); } - public position(position: number, fileIndex?: number): void; - public position(position: number, fileName?: string): void; - public position(position: number, fileNameOrIndex?: any): void { + public position(position: number, fileNameOrIndex?: string | number): void { if (fileNameOrIndex !== undefined) { this.file(fileNameOrIndex); } @@ -3757,9 +3753,7 @@ namespace FourSlashInterface { // Opens a file, given either its index as it // appears in the test source, or its filename // as specified in the test metadata - public file(index: number, content?: string, scriptKindName?: string): void; - public file(name: string, content?: string, scriptKindName?: string): void; - public file(indexOrName: any, content?: string, scriptKindName?: string): void { + public file(indexOrName: number | string, content?: string, scriptKindName?: string): void { this.state.openFile(indexOrName, content, scriptKindName); } @@ -3966,17 +3960,14 @@ namespace FourSlashInterface { this.state.verifyGoToDefinitionIs(endMarkers); } - public goToDefinition(startMarkerName: string | string[], endMarkerName: string | string[]): void; - public goToDefinition(startMarkerName: string | string[], endMarkerName: string | string[], range: FourSlash.Range): void; - public goToDefinition(startsAndEnds: [string | string[], string | string[]][]): void; - public goToDefinition(startsAndEnds: { [startMarkerName: string]: string | string[] }): void; + public goToDefinition(startMarkerName: string | string[], endMarkerName: string | string[], range?: FourSlash.Range): void; + public goToDefinition(startsAndEnds: [string | string[], string | string[]][] | { [startMarkerName: string]: string | string[] }): void; public goToDefinition(arg0: any, endMarkerName?: string | string[]) { this.state.verifyGoToDefinition(arg0, endMarkerName); } public goToType(startMarkerName: string | string[], endMarkerName: string | string[]): void; - public goToType(startsAndEnds: [string | string[], string | string[]][]): void; - public goToType(startsAndEnds: { [startMarkerName: string]: string | string[] }): void; + public goToType(startsAndEnds: [string | string[], string | string[]][] | { [startMarkerName: string]: string | string[] }): void; public goToType(arg0: any, endMarkerName?: string | string[]) { this.state.verifyGoToType(arg0, endMarkerName); } diff --git a/src/services/types.ts b/src/services/types.ts index e93ae9686d7..a9244982fbb 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -5,9 +5,11 @@ namespace ts { getChildAt(index: number, sourceFile?: SourceFile): Node; getChildren(sourceFile?: SourceFile): Node[]; /* @internal */ + // tslint:disable-next-line unified-signatures getChildren(sourceFile?: SourceFileLike): Node[]; getStart(sourceFile?: SourceFile, includeJsDocComment?: boolean): number; /* @internal */ + // tslint:disable-next-line unified-signatures getStart(sourceFile?: SourceFileLike, includeJsDocComment?: boolean): number; getFullStart(): number; getEnd(): number; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 415565a6fa1..9b2270d29e5 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3271,11 +3271,10 @@ declare namespace ts { } declare namespace ts { function createNodeArray(elements?: ReadonlyArray, hasTrailingComma?: boolean): NodeArray; - function createLiteral(value: string): StringLiteral; + /** If a node is passed, creates a string literal whose source text is read from a source node during emit. */ + function createLiteral(value: string | StringLiteral | NumericLiteral | Identifier): StringLiteral; function createLiteral(value: number): NumericLiteral; function createLiteral(value: boolean): BooleanLiteral; - /** Create a string literal whose source text is read from a source node during emit. */ - function createLiteral(sourceNode: StringLiteral | NumericLiteral | Identifier): StringLiteral; function createLiteral(value: string | number | boolean): PrimaryExpression; function createNumericLiteral(value: string): NumericLiteral; function createIdentifier(text: string): Identifier; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index fd58e72181a..6ef259ddc8f 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3218,11 +3218,10 @@ declare namespace ts { } declare namespace ts { function createNodeArray(elements?: ReadonlyArray, hasTrailingComma?: boolean): NodeArray; - function createLiteral(value: string): StringLiteral; + /** If a node is passed, creates a string literal whose source text is read from a source node during emit. */ + function createLiteral(value: string | StringLiteral | NumericLiteral | Identifier): StringLiteral; function createLiteral(value: number): NumericLiteral; function createLiteral(value: boolean): BooleanLiteral; - /** Create a string literal whose source text is read from a source node during emit. */ - function createLiteral(sourceNode: StringLiteral | NumericLiteral | Identifier): StringLiteral; function createLiteral(value: string | number | boolean): PrimaryExpression; function createNumericLiteral(value: string): NumericLiteral; function createIdentifier(text: string): Identifier; diff --git a/tslint.json b/tslint.json index 2d7c702b8aa..658beb14d16 100644 --- a/tslint.json +++ b/tslint.json @@ -100,7 +100,6 @@ "radix": false, "space-before-function-paren": false, "trailing-comma": false, - "unified-signatures": false, // These should be done automatically by a formatter. https://github.com/Microsoft/TypeScript/issues/18340 "align": false, From 6d273cfb33dfebe0dcd9b0314b0e1c6a571edfde Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 6 Nov 2017 19:14:24 -0800 Subject: [PATCH 157/235] Consistently use "JSX Attribute" completion kind (#19781) * Consistently use "JSX Attribute" completion kind * Update tests and fix bug * Fix bug: In a JsxOpeningElement, if at an Identifier we are not at an attribute but at the tag itself. If at a GreaterThanToken, we are about to fill in an attribute. --- src/services/symbolDisplay.ts | 12 +++++++--- .../fourslash/completionsJsxAttribute.ts | 22 +++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 tests/cases/fourslash/completionsJsxAttribute.ts diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index e3ef4d3e495..ad9ac88bdfc 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -75,10 +75,16 @@ namespace ts.SymbolDisplay { } return unionPropertyKind; } - if (location.parent && isJsxAttribute(location.parent)) { - return ScriptElementKind.jsxAttribute; + // If we requested completions after `x.` at the top-level, we may be at a source file location. + switch (location.parent && location.parent.kind) { + // If we've typed a character of the attribute name, will be 'JsxAttribute', else will be 'JsxOpeningElement'. + case SyntaxKind.JsxOpeningElement: + return location.kind === SyntaxKind.Identifier ? ScriptElementKind.memberVariableElement : ScriptElementKind.jsxAttribute; + case SyntaxKind.JsxAttribute: + return ScriptElementKind.jsxAttribute; + default: + return ScriptElementKind.memberVariableElement; } - return ScriptElementKind.memberVariableElement; } return ScriptElementKind.unknown; diff --git a/tests/cases/fourslash/completionsJsxAttribute.ts b/tests/cases/fourslash/completionsJsxAttribute.ts new file mode 100644 index 00000000000..29e6122ef18 --- /dev/null +++ b/tests/cases/fourslash/completionsJsxAttribute.ts @@ -0,0 +1,22 @@ +/// + +// @jsx: preserve + +// @Filename: /a.tsx +////declare namespace JSX { +//// interface Element {} +//// interface IntrinsicElements { +//// div: { +//// /** Doc */ +//// foo: string +//// } +//// } +////} +//// +////
; + +goTo.marker(); +verify.completionEntryDetailIs("foo", "(JSX attribute) foo: string", "Doc ", "JSX attribute", []); +edit.insert("f"); +verify.completionEntryDetailIs("foo", "(JSX attribute) foo: string", "Doc ", "JSX attribute", []); + From ed335a66fa685077452dd6059bfff21b9742889d Mon Sep 17 00:00:00 2001 From: csigs Date: Tue, 7 Nov 2017 05:10:13 +0000 Subject: [PATCH 158/235] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 36 +++++++++++++++++++ .../diagnosticMessages.generated.json.lcl | 36 +++++++++++++++++++ .../diagnosticMessages.generated.json.lcl | 36 +++++++++++++++++++ 3 files changed, 108 insertions(+) diff --git a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl index d96fb42d4ea..4865cf6c508 100644 --- a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2250,6 +2250,15 @@
+ + + + + + + + + @@ -2979,6 +2988,15 @@ + + + + + + + + + @@ -4221,6 +4239,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl index 326158fcca0..2bf61430d60 100644 --- a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2250,6 +2250,15 @@ + + + + + + + + + @@ -2979,6 +2988,15 @@ + + + + + + + + + @@ -4221,6 +4239,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl index b0897a56d25..1e480ff2a08 100644 --- a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2225,6 +2225,15 @@ + + + + + + + + + @@ -2954,6 +2963,15 @@ + + + + + + + + + @@ -4193,6 +4211,24 @@ + + + + + + + + + + + + + + + + + + From 70cabdda419748c0ce10d0cd15e025cbb5bc0fae Mon Sep 17 00:00:00 2001 From: Aluan Haddad Date: Tue, 7 Nov 2017 01:55:37 -0500 Subject: [PATCH 159/235] fix inconsistencies in import UMD code fixes adapting to module format (#19572) * improve import code fixes for UMD modules - use default import under --allowSyntheticDefaultImports - import..require support - make make quick fix info match resulting import - make diagnostics * Address PR feedback: - extract test for synethetic default imports into getAllowSyntheticDefaultImports in core.ts - use getAllowSyntheticDefaultImports in checker.ts and importFixes.ts - move compilerOptions to top level destructuring * add tests * remove `import =` quick fix and supporting code. * update feature tests * remove errant whitespace --- src/compiler/checker.ts | 2 +- src/compiler/core.ts | 7 ++++ src/compiler/diagnosticMessages.json | 8 ++++ src/services/codefixes/importFixes.ts | 39 +++++++++++++------ ...xNewImportAllowSyntheticDefaultImports0.ts | 18 +++++++++ ...xNewImportAllowSyntheticDefaultImports1.ts | 18 +++++++++ ...xNewImportAllowSyntheticDefaultImports2.ts | 18 +++++++++ 7 files changed, 98 insertions(+), 12 deletions(-) create mode 100644 tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports0.ts create mode 100644 tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports1.ts create mode 100644 tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 556046f3d76..7bce66892de 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -66,7 +66,7 @@ namespace ts { const languageVersion = getEmitScriptTarget(compilerOptions); const modulekind = getEmitModuleKind(compilerOptions); const noUnusedIdentifiers = !!compilerOptions.noUnusedLocals || !!compilerOptions.noUnusedParameters; - const allowSyntheticDefaultImports = typeof compilerOptions.allowSyntheticDefaultImports !== "undefined" ? compilerOptions.allowSyntheticDefaultImports : modulekind === ModuleKind.System; + const allowSyntheticDefaultImports = getAllowSyntheticDefaultImports(compilerOptions); const strictNullChecks = getStrictOptionValue(compilerOptions, "strictNullChecks"); const strictFunctionTypes = getStrictOptionValue(compilerOptions, "strictFunctionTypes"); const noImplicitAny = getStrictOptionValue(compilerOptions, "noImplicitAny"); diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 5fb7019dfb2..4fb072b1112 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1916,6 +1916,13 @@ namespace ts { return moduleResolution; } + export function getAllowSyntheticDefaultImports(compilerOptions: CompilerOptions) { + const moduleKind = getEmitModuleKind(compilerOptions); + return compilerOptions.allowSyntheticDefaultImports !== undefined + ? compilerOptions.allowSyntheticDefaultImports + : moduleKind === ModuleKind.System; + } + export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "alwaysStrict"; export function getStrictOptionValue(compilerOptions: CompilerOptions, flag: StrictOptionName): boolean { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index d3669ce397d..60e3d6c4c4f 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3801,5 +3801,13 @@ "Install '{0}'": { "category": "Message", "code": 95014 + }, + "Import '{0}' = require(\"{1}\").": { + "category": "Message", + "code": 95015 + }, + "Import * as '{0}' from \"{1}\".": { + "category": "Message", + "code": 95016 } } diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 3f0d27e5b07..73cedc883be 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -180,7 +180,7 @@ namespace ts.codefix { export const enum ImportKind { Named, Default, - Namespace, + Namespace } export function getCodeActionForImport(moduleSymbol: Symbol, context: ImportCodeFixOptions): ImportCodeAction[] { @@ -212,7 +212,7 @@ namespace ts.codefix { function getNamespaceImportName(declaration: AnyImportSyntax): Identifier { if (declaration.kind === SyntaxKind.ImportDeclaration) { - const namedBindings = declaration.importClause && declaration.importClause.namedBindings; + const namedBindings = declaration.importClause && isImportClause(declaration.importClause) && declaration.importClause.namedBindings; return namedBindings && namedBindings.kind === SyntaxKind.NamespaceImport ? namedBindings.name : undefined; } else { @@ -237,6 +237,8 @@ namespace ts.codefix { return parent as ImportDeclaration; case SyntaxKind.ExternalModuleReference: return (parent as ExternalModuleReference).parent; + case SyntaxKind.ImportEqualsDeclaration: + return parent as ImportEqualsDeclaration; default: Debug.assert(parent.kind === SyntaxKind.ExportDeclaration); // Ignore these, can't add imports to them. @@ -249,11 +251,13 @@ namespace ts.codefix { const lastImportDeclaration = findLast(sourceFile.statements, isAnyImportSyntax); const moduleSpecifierWithoutQuotes = stripQuotes(moduleSpecifier); + const quotedModuleSpecifier = createStringLiteralWithQuoteStyle(sourceFile, moduleSpecifierWithoutQuotes); const importDecl = createImportDeclaration( - /*decorators*/ undefined, - /*modifiers*/ undefined, + /*decorators*/ undefined, + /*modifiers*/ undefined, createImportClauseOfKind(kind, symbolName), - createStringLiteralWithQuoteStyle(sourceFile, moduleSpecifierWithoutQuotes)); + quotedModuleSpecifier); + const changes = ChangeTracker.with(context, changeTracker => { if (lastImportDeclaration) { changeTracker.insertNodeAfter(sourceFile, lastImportDeclaration, importDecl, { suffix: newLineCharacter }); @@ -263,11 +267,15 @@ namespace ts.codefix { } }); + const actionFormat = kind === ImportKind.Namespace + ? Diagnostics.Import_Asterisk_as_0_from_1 + : Diagnostics.Import_0_from_1; + // if this file doesn't have any import statements, insert an import statement and then insert a new line // between the only import statement and user code. Otherwise just insert the statement because chances // are there are already a new line seperating code and import statements. return createCodeAction( - Diagnostics.Import_0_from_1, + actionFormat, [symbolName, moduleSpecifierWithoutQuotes], changes, "NewImport", @@ -282,7 +290,7 @@ namespace ts.codefix { return literal; } - function createImportClauseOfKind(kind: ImportKind, symbolName: string) { + function createImportClauseOfKind(kind: ImportKind.Default | ImportKind.Named | ImportKind.Namespace, symbolName: string) { const id = createIdentifier(symbolName); switch (kind) { case ImportKind.Default: @@ -534,7 +542,7 @@ namespace ts.codefix { declarations: ReadonlyArray): ImportCodeAction { const fromExistingImport = firstDefined(declarations, declaration => { if (declaration.kind === SyntaxKind.ImportDeclaration && declaration.importClause) { - const changes = tryUpdateExistingImport(ctx, declaration.importClause); + const changes = tryUpdateExistingImport(ctx, isImportClause(declaration.importClause) && declaration.importClause || undefined); if (changes) { const moduleSpecifierWithoutQuotes = stripQuotes(declaration.moduleSpecifier.getText()); return createCodeAction( @@ -564,9 +572,10 @@ namespace ts.codefix { return expression && isStringLiteral(expression) ? expression.text : undefined; } - function tryUpdateExistingImport(context: SymbolContext & { kind: ImportKind }, importClause: ImportClause): FileTextChanges[] | undefined { + function tryUpdateExistingImport(context: SymbolContext & { kind: ImportKind }, importClause: ImportClause | ImportEqualsDeclaration): FileTextChanges[] | undefined { const { symbolName, sourceFile, kind } = context; - const { name, namedBindings } = importClause; + const { name } = importClause; + const { namedBindings } = importClause.kind !== SyntaxKind.ImportEqualsDeclaration && importClause; switch (kind) { case ImportKind.Default: return name ? undefined : ChangeTracker.with(context, t => @@ -627,7 +636,7 @@ namespace ts.codefix { } function getActionsForUMDImport(context: ImportCodeFixContext): ImportCodeAction[] { - const { checker, symbolToken } = context; + const { checker, symbolToken, compilerOptions } = context; const umdSymbol = checker.getSymbolAtLocation(symbolToken); let symbol: ts.Symbol; let symbolName: string; @@ -644,6 +653,14 @@ namespace ts.codefix { Debug.fail("Either the symbol or the JSX namespace should be a UMD global if we got here"); } + const allowSyntheticDefaultImports = getAllowSyntheticDefaultImports(compilerOptions); + + // Import a synthetic `default` if enabled. + if (allowSyntheticDefaultImports) { + return getCodeActionForImport(symbol, { ...context, symbolName, kind: ImportKind.Default }); + } + + // Fall back to the `import * as ns` style import. return getCodeActionForImport(symbol, { ...context, symbolName, kind: ImportKind.Namespace }); } diff --git a/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports0.ts b/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports0.ts new file mode 100644 index 00000000000..3b62e0e9d5f --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports0.ts @@ -0,0 +1,18 @@ +/// +// @AllowSyntheticDefaultImports: true + +// @Filename: a/f1.ts +//// [|export var x = 0; +//// bar/*0*/();|] + +// @Filename: a/foo.d.ts +//// declare function bar(): number; +//// export = bar; +//// export as namespace bar; + +verify.importFixAtPosition([ +`import bar from "./foo"; + +export var x = 0; +bar();` + ]); \ No newline at end of file diff --git a/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports1.ts b/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports1.ts new file mode 100644 index 00000000000..c6c2a554874 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports1.ts @@ -0,0 +1,18 @@ +/// +// @Module: system + +// @Filename: a/f1.ts +//// [|export var x = 0; +//// bar/*0*/();|] + +// @Filename: a/foo.d.ts +//// declare function bar(): number; +//// export = bar; +//// export as namespace bar; + +verify.importFixAtPosition([ +`import bar from "./foo"; + +export var x = 0; +bar();` +]); \ No newline at end of file diff --git a/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports2.ts b/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports2.ts new file mode 100644 index 00000000000..3421d603297 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports2.ts @@ -0,0 +1,18 @@ +/// +// @AllowSyntheticDefaultImports: false + +// @Filename: a/f1.ts +//// [|export var x = 0; +//// bar/*0*/();|] + +// @Filename: a/foo.d.ts +//// declare function bar(): number; +//// export = bar; +//// export as namespace bar; + +verify.importFixAtPosition([ +`import * as bar from "./foo"; + +export var x = 0; +bar();` +]); \ No newline at end of file From 9ba9a893cc7f8fa3ab2bb40cbe5559147f081018 Mon Sep 17 00:00:00 2001 From: csigs Date: Tue, 7 Nov 2017 11:10:13 +0000 Subject: [PATCH 160/235] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl index 2653d211440..2693d7cce27 100644 --- a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2241,6 +2241,15 @@ + + + + + + + + + @@ -2970,6 +2979,15 @@ + + + + + + + + + @@ -4212,6 +4230,24 @@ + + + + + + + + + + + + + + + + + + From 9c8129eeac9747f953f95c82f7bd05fd8d45d579 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 7 Nov 2017 06:51:35 -0800 Subject: [PATCH 161/235] Enable 'no-invalid-template-strings' lint rule (#19790) --- src/compiler/utilities.ts | 2 ++ src/harness/unittests/printer.ts | 1 + src/harness/unittests/services/colorization.ts | 2 ++ tslint.json | 1 - 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index dffadda45b2..41a5512cb2a 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -363,8 +363,10 @@ namespace ts { case SyntaxKind.NoSubstitutionTemplateLiteral: return "`" + escapeText(node.text, CharacterCodes.backtick) + "`"; case SyntaxKind.TemplateHead: + // tslint:disable-next-line no-invalid-template-strings return "`" + escapeText(node.text, CharacterCodes.backtick) + "${"; case SyntaxKind.TemplateMiddle: + // tslint:disable-next-line no-invalid-template-strings return "}" + escapeText(node.text, CharacterCodes.backtick) + "${"; case SyntaxKind.TemplateTail: return "}" + escapeText(node.text, CharacterCodes.backtick) + "`"; diff --git a/src/harness/unittests/printer.ts b/src/harness/unittests/printer.ts index 4aaddce5c00..ad60484d963 100644 --- a/src/harness/unittests/printer.ts +++ b/src/harness/unittests/printer.ts @@ -55,6 +55,7 @@ namespace ts { printsCorrectly("removeComments", { removeComments: true }, printer => printer.printFile(sourceFile)); // github #14948 + // tslint:disable-next-line no-invalid-template-strings printsCorrectly("templateLiteral", {}, printer => printer.printFile(createSourceFile("source.ts", "let greeting = `Hi ${name}, how are you?`;", ScriptTarget.ES2017))); // github #18071 diff --git a/src/harness/unittests/services/colorization.ts b/src/harness/unittests/services/colorization.ts index 6dbc7732a00..17d4132e9e5 100644 --- a/src/harness/unittests/services/colorization.ts +++ b/src/harness/unittests/services/colorization.ts @@ -1,5 +1,7 @@ /// +// tslint:disable no-invalid-template-strings (lots of tests use quoted code) + interface ClassificationEntry { value: any; classification: ts.TokenClass; diff --git a/tslint.json b/tslint.json index 658beb14d16..914681329ec 100644 --- a/tslint.json +++ b/tslint.json @@ -89,7 +89,6 @@ "no-empty": false, "no-empty-interface": false, "no-eval": false, - "no-invalid-template-strings": false, "no-object-literal-type-assertion": false, "no-shadowed-variable": false, "no-submodule-imports": false, From 2fcf8b7068b5cf2ef1bd5c1929b1fb9a241f9a1f Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 7 Nov 2017 07:41:21 -0800 Subject: [PATCH 162/235] Fix assertion -- an import may come from a require() call (#19667) * Fix assertion -- an import may come from a require() call * Add test for `import("./a")` --- src/services/codefixes/importFixes.ts | 8 ++-- .../fourslash/completionsImport_require.ts | 42 +++++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 tests/cases/fourslash/completionsImport_require.ts diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 73cedc883be..a7f0e2e0814 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -237,12 +237,12 @@ namespace ts.codefix { return parent as ImportDeclaration; case SyntaxKind.ExternalModuleReference: return (parent as ExternalModuleReference).parent; - case SyntaxKind.ImportEqualsDeclaration: - return parent as ImportEqualsDeclaration; - default: - Debug.assert(parent.kind === SyntaxKind.ExportDeclaration); + case SyntaxKind.ExportDeclaration: + case SyntaxKind.CallExpression: // For "require()" calls // Ignore these, can't add imports to them. return undefined; + default: + Debug.fail(); } } diff --git a/tests/cases/fourslash/completionsImport_require.ts b/tests/cases/fourslash/completionsImport_require.ts new file mode 100644 index 00000000000..e0a6b00d462 --- /dev/null +++ b/tests/cases/fourslash/completionsImport_require.ts @@ -0,0 +1,42 @@ +/// + +// @allowJs: true + +// @Filename: /a.ts +////export const foo = 0; + +// @Filename: /b.js +////const a = require("./a"); +////fo/*b*/ + +// @Filename: /c.js +////const a = import("./a"); +////fo/*c*/ + +goTo.marker("b"); +verify.completionListContains({ name: "foo", source: "/a" }, "const foo: 0", "", "const", /*spanIndex*/ undefined, /*hasAction*/ true, { includeExternalModuleExports: true }); + +verify.applyCodeActionFromCompletion("b", { + name: "foo", + source: "/a", + description: `Import 'foo' from "./a".`, + // TODO: GH#18445 + newFileContent: `import { foo } from "./a";\r +\r +const a = require("./a"); +fo`, +}); + +goTo.marker("c"); +verify.completionListContains({ name: "foo", source: "/a" }, "const foo: 0", "", "const", /*spanIndex*/ undefined, /*hasAction*/ true, { includeExternalModuleExports: true }); + +verify.applyCodeActionFromCompletion("c", { + name: "foo", + source: "/a", + description: `Import 'foo' from "./a".`, + // TODO: GH#18445 + newFileContent: `import { foo } from "./a";\r +\r +const a = import("./a"); +fo`, +}); From 6a0779333212ea4156481d369752d8f66269424f Mon Sep 17 00:00:00 2001 From: Jing Ma Date: Wed, 8 Nov 2017 01:02:26 +0800 Subject: [PATCH 163/235] Fixed minor syntactics error (#19801) --- src/lib/es2015.core.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/es2015.core.d.ts b/src/lib/es2015.core.d.ts index 0e1b46f2eb0..ccff68968f1 100644 --- a/src/lib/es2015.core.d.ts +++ b/src/lib/es2015.core.d.ts @@ -449,7 +449,7 @@ interface String { /** * Returns a String value that is made from count copies appended together. If count is 0, - * T is the empty String is returned. + * the empty string is returned. * @param count number of copies to append */ repeat(count: number): string; From b50fb3ef3ff120efe37eb3ac094093893f3ceb88 Mon Sep 17 00:00:00 2001 From: csigs Date: Tue, 7 Nov 2017 17:10:19 +0000 Subject: [PATCH 164/235] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 36 ++++++++++++++++++ .../diagnosticMessages.generated.json.lcl | 38 ++++++++++++++++++- .../diagnosticMessages.generated.json.lcl | 18 +++++++++ .../diagnosticMessages.generated.json.lcl | 36 ++++++++++++++++++ .../diagnosticMessages.generated.json.lcl | 36 ++++++++++++++++++ .../diagnosticMessages.generated.json.lcl | 36 ++++++++++++++++++ 6 files changed, 199 insertions(+), 1 deletion(-) diff --git a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl index 3ea6148617a..929b7edf058 100644 --- a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2241,6 +2241,15 @@ + + + + + + + + + @@ -2970,6 +2979,15 @@ + + + + + + + + + @@ -4212,6 +4230,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl index 078b17179a4..8dab90a1ba2 100644 --- a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2250,6 +2250,15 @@ + + + + + + + + + @@ -2979,6 +2988,15 @@ + + + + + + + + + @@ -4221,6 +4239,24 @@ + + + + + + + + + + + + + + + + + + @@ -8320,7 +8356,7 @@ - + diff --git a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl index 6c74cb8ca90..c00e5a2a2e7 100644 --- a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2232,6 +2232,15 @@ + + + + + + + + + @@ -2964,6 +2973,9 @@ + + + @@ -4209,12 +4221,18 @@ + + + + + + diff --git a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl index 34a98237a2a..b2ae023f5a4 100644 --- a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2241,6 +2241,15 @@ + + + + + + + + + @@ -2970,6 +2979,15 @@ + + + + + + + + + @@ -4212,6 +4230,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 3b132575e58..b9d115872b6 100644 --- a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2225,6 +2225,15 @@ + + + + + + + + + @@ -2954,6 +2963,15 @@ + + + + + + + + + @@ -4193,6 +4211,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 34f080a97cc..0eafa4da0b2 100644 --- a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2234,6 +2234,15 @@ + + + + + + + + + @@ -2963,6 +2972,15 @@ + + + + + + + + + @@ -4205,6 +4223,24 @@ + + + + + + + + + + + + + + + + + + From bd2e97597d731635a44866569b1b4f6095b4a946 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 7 Nov 2017 09:22:28 -0800 Subject: [PATCH 165/235] Enable 'no-empty' tslint rule (#19769) * Enable 'no-empty' tslint rule * Fix bug --- Gulpfile.ts | 3 +- src/compiler/core.ts | 7 ++-- src/compiler/performance.ts | 4 +-- src/compiler/sys.ts | 4 +-- src/harness/harness.ts | 5 ++- src/harness/harnessLanguageService.ts | 36 ++++++------------- src/harness/projectsRunner.ts | 5 +-- src/harness/runnerbase.ts | 2 -- src/harness/unittests/extractTestHelpers.ts | 4 +-- src/harness/unittests/hostNewLineSupport.ts | 6 ++-- .../unittests/tsserverProjectSystem.ts | 7 ++-- src/server/session.ts | 3 +- src/server/watchGuard/watchGuard.ts | 3 +- src/services/pathCompletions.ts | 7 ++-- tslint.json | 1 - 15 files changed, 35 insertions(+), 62 deletions(-) diff --git a/Gulpfile.ts b/Gulpfile.ts index 84770f7edbc..aedde5c33d9 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -74,7 +74,8 @@ const cmdLineOptions = minimist(process.argv.slice(2), { } }); -function exec(cmd: string, args: string[], complete: () => void = (() => { }), error: (e: any, status: number) => void = (() => { })) { +const noop = () => {}; // tslint:disable-line no-empty +function exec(cmd: string, args: string[], complete: () => void = noop, error: (e: any, status: number) => void = noop) { console.log(`${cmd} ${args.join(" ")}`); // TODO (weswig): Update child_process types to add windowsVerbatimArguments to the type definition const subshellFlag = isWin ? "/c" : "-c"; diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 4fb072b1112..d9e0faf3aed 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1341,7 +1341,7 @@ namespace ts { } /** Does nothing. */ - export function noop(): void { } + export function noop(_?: {} | null | undefined): void { } // tslint:disable-line no-empty /** Do nothing and return false */ export function returnFalse(): false { return false; } @@ -2659,8 +2659,7 @@ namespace ts { } } - function Signature() { - } + function Signature() {} // tslint:disable-line no-empty function Node(this: Node, kind: SyntaxKind, pos: number, end: number) { this.id = 0; @@ -2931,7 +2930,7 @@ namespace ts { return (arg: T) => f(arg) && g(arg); } - export function assertTypeIsNever(_: never): void { } + export function assertTypeIsNever(_: never): void { } // tslint:disable-line no-empty export interface FileAndDirectoryExistence { fileExists: boolean; diff --git a/src/compiler/performance.ts b/src/compiler/performance.ts index 8c24b3b9f1b..225b34de9cf 100644 --- a/src/compiler/performance.ts +++ b/src/compiler/performance.ts @@ -10,9 +10,7 @@ namespace ts { namespace ts.performance { declare const onProfilerEvent: { (markName: string): void; profiler: boolean; }; - const profilerEvent = typeof onProfilerEvent === "function" && onProfilerEvent.profiler === true - ? onProfilerEvent - : (_markName: string) => { }; + const profilerEvent: (markName: string) => void = typeof onProfilerEvent === "function" && onProfilerEvent.profiler === true ? onProfilerEvent : noop; let enabled = false; let profilerStart = 0; diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 2400266f9c7..529ece36fa6 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -511,7 +511,7 @@ namespace ts { return stat.size; } } - catch (e) { } + catch { /*ignore*/ } return 0; }, exit(exitCode?: number): void { @@ -525,7 +525,7 @@ namespace ts { try { require("source-map-support").install(); } - catch (e) { + catch { // Could not enable source maps. } }, diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 737e444835c..abec41ea4a4 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -555,8 +555,7 @@ namespace Harness { try { fs.unlinkSync(path); } - catch (e) { - } + catch { /*ignore*/ } } export function directoryExists(path: string): boolean { @@ -615,7 +614,7 @@ namespace Harness { namespace Http { function waitForXHR(xhr: XMLHttpRequest) { - while (xhr.readyState !== 4) { } + while (xhr.readyState !== 4) { } // tslint:disable-line no-empty return { status: xhr.status, responseText: xhr.responseText }; } diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index f8f09049d4d..d4b5a9c2a16 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -166,8 +166,7 @@ namespace Harness.LanguageService { throw new Error("No script with name '" + fileName + "'"); } - public openFile(_fileName: string, _content?: string, _scriptKindName?: string): void { - } + public openFile(_fileName: string, _content?: string, _scriptKindName?: string): void { /*overridden*/ } /** * @param line 0 based index @@ -237,9 +236,9 @@ namespace Harness.LanguageService { } - log(_: string): void { } - trace(_: string): void { } - error(_: string): void { } + log = ts.noop; + trace = ts.noop; + error = ts.noop; } export class NativeLanguageServiceAdapter implements LanguageServiceAdapter { @@ -596,13 +595,8 @@ namespace Harness.LanguageService { super(cancellationToken, settings); } - onMessage(): void { - - } - - writeMessage(): void { - - } + onMessage = ts.noop; + writeMessage = ts.noop; setClient(client: ts.server.SessionClient) { this.client = client; @@ -628,13 +622,8 @@ namespace Harness.LanguageService { this.newLine = this.host.getNewLine(); } - onMessage(): void { - - } - - writeMessage(_message: string): void { - } - + onMessage = ts.noop; + writeMessage = ts.noop; // overridden write(message: string): void { this.writeMessage(message); } @@ -648,8 +637,7 @@ namespace Harness.LanguageService { return snapshot && snapshot.getText(0, snapshot.getLength()); } - writeFile(): void { - } + writeFile = ts.noop; resolvePath(path: string): string { return path; @@ -668,8 +656,7 @@ namespace Harness.LanguageService { return ""; } - exit(): void { - } + exit = ts.noop; createDirectory(_directoryName: string): void { return ts.notImplemented(); @@ -697,8 +684,7 @@ namespace Harness.LanguageService { return { close: ts.noop }; } - close(): void { - } + close = ts.noop; info(message: string): void { this.host.log(message); diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index fccbba88ff6..c617cc7a0a3 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -396,7 +396,7 @@ class ProjectRunner extends RunnerBase { }); // Dont allow config files since we are compiling existing source options - return compileProjectFiles(compilerResult.moduleKind, compilerResult.configFileSourceFiles, getInputFiles, getSourceFileText, writeFile, compilerResult.compilerOptions); + return compileProjectFiles(compilerResult.moduleKind, compilerResult.configFileSourceFiles, getInputFiles, getSourceFileText, /*writeFile*/ ts.noop, compilerResult.compilerOptions); function findOutputDtsFile(fileName: string) { return ts.forEach(compilerResult.outputFiles, outputFile => outputFile.emittedFileName === fileName ? outputFile : undefined); @@ -416,9 +416,6 @@ class ProjectRunner extends RunnerBase { } return undefined; } - - function writeFile() { - } } function getErrorsBaseline(compilerResult: CompileProjectFilesResult) { diff --git a/src/harness/runnerbase.ts b/src/harness/runnerbase.ts index 2fef2264b73..14be5e0682a 100644 --- a/src/harness/runnerbase.ts +++ b/src/harness/runnerbase.ts @@ -6,8 +6,6 @@ type CompilerTestKind = "conformance" | "compiler"; type FourslashTestKind = "fourslash" | "fourslash-shims" | "fourslash-shims-pp" | "fourslash-server"; abstract class RunnerBase { - constructor() { } - // contains the tests to run public tests: string[] = []; diff --git a/src/harness/unittests/extractTestHelpers.ts b/src/harness/unittests/extractTestHelpers.ts index b8974694cfe..ae3f663aa51 100644 --- a/src/harness/unittests/extractTestHelpers.ts +++ b/src/harness/unittests/extractTestHelpers.ts @@ -126,7 +126,7 @@ namespace ts { const sourceFile = program.getSourceFile(path); const context: RefactorContext = { - cancellationToken: { throwIfCancellationRequested() { }, isCancellationRequested() { return false; } }, + cancellationToken: { throwIfCancellationRequested: noop, isCancellationRequested: returnFalse }, newLineCharacter, program, file: sourceFile, @@ -190,7 +190,7 @@ namespace ts { const program = projectService.inferredProjects[0].getLanguageService().getProgram(); const sourceFile = program.getSourceFile(f.path); const context: RefactorContext = { - cancellationToken: { throwIfCancellationRequested() { }, isCancellationRequested() { return false; } }, + cancellationToken: { throwIfCancellationRequested: noop, isCancellationRequested: returnFalse }, newLineCharacter, program, file: sourceFile, diff --git a/src/harness/unittests/hostNewLineSupport.ts b/src/harness/unittests/hostNewLineSupport.ts index 9f6b09dfb72..95a05f101f7 100644 --- a/src/harness/unittests/hostNewLineSupport.ts +++ b/src/harness/unittests/hostNewLineSupport.ts @@ -5,10 +5,10 @@ namespace ts { function snapFor(path: string): IScriptSnapshot { if (path === "lib.d.ts") { return { - dispose() {}, + dispose: noop, getChangeRange() { return undefined; }, getLength() { return 0; }, - getText(_start, _end) { + getText() { return ""; } }; @@ -16,7 +16,7 @@ namespace ts { const result = forEach(files, f => f.unitName === path ? f : undefined); if (result) { return { - dispose() {}, + dispose: noop, getChangeRange() { return undefined; }, getLength() { return result.content.length; }, getText(start, end) { diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index ffb811dddba..432a6e7a5c5 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -85,8 +85,7 @@ namespace ts.projectSystem { assert.equal(this.postExecActions.length, expectedCount, `Expected ${expectedCount} post install actions`); } - onProjectClosed() { - } + onProjectClosed = noop; attach(projectService: server.ProjectService) { this.projectService = projectService; @@ -4717,7 +4716,7 @@ namespace ts.projectSystem { const host = createServerHost([f1, config]); const session = createSession(host, { canUseEvents: true, - eventHandler: () => { }, + eventHandler: noop, cancellationToken }); { @@ -4854,7 +4853,7 @@ namespace ts.projectSystem { const host = createServerHost([f1, config]); const session = createSession(host, { canUseEvents: true, - eventHandler: () => { }, + eventHandler: noop, cancellationToken, throttleWaitMilliseconds: 0 }); diff --git a/src/server/session.ts b/src/server/session.ts index 07fcc49d1b2..6c97c3c8bd4 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1687,8 +1687,7 @@ namespace ts.server { return normalizePath(name); } - exit() { - } + exit() { /*overridden*/ } private notRequired(): HandlerResponse { return { responseRequired: false }; diff --git a/src/server/watchGuard/watchGuard.ts b/src/server/watchGuard/watchGuard.ts index f57369aecb9..8ec248ebb87 100644 --- a/src/server/watchGuard/watchGuard.ts +++ b/src/server/watchGuard/watchGuard.ts @@ -14,6 +14,5 @@ try { const watcher = fs.watch(directoryName, { recursive: true }, () => ({})); watcher.close(); } -catch (_e) { -} +catch { /*ignore*/ } process.exit(0); \ No newline at end of file diff --git a/src/services/pathCompletions.ts b/src/services/pathCompletions.ts index 977b43899c9..a6dfb53da80 100644 --- a/src/services/pathCompletions.ts +++ b/src/services/pathCompletions.ts @@ -320,10 +320,9 @@ namespace ts.Completions.PathCompletions { else if (host.getDirectories) { let typeRoots: ReadonlyArray; try { - // Wrap in try catch because getEffectiveTypeRoots touches the filesystem typeRoots = getEffectiveTypeRoots(options, host); } - catch (e) {} + catch { /* Wrap in try catch because getEffectiveTypeRoots touches the filesystem */ } if (typeRoots) { for (const root of typeRoots) { @@ -484,7 +483,7 @@ namespace ts.Completions.PathCompletions { try { return directoryProbablyExists(path, host); } - catch (e) {} + catch { /*ignore*/ } return undefined; } @@ -492,7 +491,7 @@ namespace ts.Completions.PathCompletions { try { return toApply && toApply.apply(host, args); } - catch (e) {} + catch { /*ignore*/ } return undefined; } } diff --git a/tslint.json b/tslint.json index 914681329ec..f4403d48f19 100644 --- a/tslint.json +++ b/tslint.json @@ -86,7 +86,6 @@ "no-conditional-assignment": false, "no-console": false, "no-debugger": false, - "no-empty": false, "no-empty-interface": false, "no-eval": false, "no-object-literal-type-assertion": false, From b2b54cbf5c41397135a2642510fa4af12af95fd4 Mon Sep 17 00:00:00 2001 From: Aluan Haddad Date: Tue, 7 Nov 2017 12:45:30 -0500 Subject: [PATCH 166/235] Import fix add import require support (#19802) * import fix: suggest import..require where supported if synthetic defaults are unavailable * Add tests for import..require fix when targeting CommonJS, AMD, and UMD modules * fix failing tests --- src/services/codefixes/importFixes.ts | 30 +++++++++++++++---- ...xNewImportAllowSyntheticDefaultImports2.ts | 1 + ...xNewImportAllowSyntheticDefaultImports3.ts | 19 ++++++++++++ ...xNewImportAllowSyntheticDefaultImports4.ts | 19 ++++++++++++ ...xNewImportAllowSyntheticDefaultImports5.ts | 19 ++++++++++++ .../fourslash/importNameCodeFixUMDGlobal0.ts | 3 ++ .../fourslash/importNameCodeFixUMDGlobal1.ts | 3 ++ .../importNameCodeFixUMDGlobalReact0.ts | 2 ++ .../importNameCodeFixUMDGlobalReact1.ts | 2 ++ 9 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports3.ts create mode 100644 tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports4.ts create mode 100644 tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports5.ts diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index a7f0e2e0814..e0e57801cf8 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -180,7 +180,8 @@ namespace ts.codefix { export const enum ImportKind { Named, Default, - Namespace + Namespace, + Equals } export function getCodeActionForImport(moduleSymbol: Symbol, context: ImportCodeFixOptions): ImportCodeAction[] { @@ -252,11 +253,17 @@ namespace ts.codefix { const moduleSpecifierWithoutQuotes = stripQuotes(moduleSpecifier); const quotedModuleSpecifier = createStringLiteralWithQuoteStyle(sourceFile, moduleSpecifierWithoutQuotes); - const importDecl = createImportDeclaration( + const importDecl = kind !== ImportKind.Equals + ? createImportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createImportClauseOfKind(kind, symbolName), - quotedModuleSpecifier); + createImportClauseOfKind(kind, symbolName), + quotedModuleSpecifier) + : createImportEqualsDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + createIdentifier(symbolName), + createExternalModuleReference(quotedModuleSpecifier)); const changes = ChangeTracker.with(context, changeTracker => { if (lastImportDeclaration) { @@ -267,8 +274,10 @@ namespace ts.codefix { } }); - const actionFormat = kind === ImportKind.Namespace - ? Diagnostics.Import_Asterisk_as_0_from_1 + const actionFormat = kind === ImportKind.Equals + ? Diagnostics.Import_0_require_1 + : kind === ImportKind.Namespace + ? Diagnostics.Import_Asterisk_as_0_from_1 : Diagnostics.Import_0_from_1; // if this file doesn't have any import statements, insert an import statement and then insert a new line @@ -601,6 +610,9 @@ namespace ts.codefix { return namedBindings ? undefined : ChangeTracker.with(context, t => t.replaceNode(sourceFile, importClause, createImportClause(name, createNamespaceImport(createIdentifier(symbolName))))); + case ImportKind.Equals: + return undefined; + default: Debug.assertNever(kind); } @@ -659,6 +671,12 @@ namespace ts.codefix { if (allowSyntheticDefaultImports) { return getCodeActionForImport(symbol, { ...context, symbolName, kind: ImportKind.Default }); } + const moduleKind = getEmitModuleKind(compilerOptions); + + // When a synthetic `default` is unavailable, use `import..require` if the module kind supports it. + if (moduleKind === ModuleKind.AMD || moduleKind === ModuleKind.CommonJS || moduleKind === ModuleKind.UMD) { + return getCodeActionForImport(symbol, { ...context, symbolName, kind: ImportKind.Equals }); + } // Fall back to the `import * as ns` style import. return getCodeActionForImport(symbol, { ...context, symbolName, kind: ImportKind.Namespace }); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports2.ts b/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports2.ts index 3421d603297..f6ba985715e 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports2.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports2.ts @@ -1,5 +1,6 @@ /// // @AllowSyntheticDefaultImports: false +// @Module: system // @Filename: a/f1.ts //// [|export var x = 0; diff --git a/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports3.ts b/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports3.ts new file mode 100644 index 00000000000..bc0ba6d8163 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports3.ts @@ -0,0 +1,19 @@ +/// +// @AllowSyntheticDefaultImports: false +// @Module: commonjs + +// @Filename: a/f1.ts +//// [|export var x = 0; +//// bar/*0*/();|] + +// @Filename: a/foo.d.ts +//// declare function bar(): number; +//// export = bar; +//// export as namespace bar; + +verify.importFixAtPosition([ +`import bar = require("./foo"); + +export var x = 0; +bar();` +]); \ No newline at end of file diff --git a/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports4.ts b/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports4.ts new file mode 100644 index 00000000000..c8ce87db71a --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports4.ts @@ -0,0 +1,19 @@ +/// +// @AllowSyntheticDefaultImports: false +// @Module: amd + +// @Filename: a/f1.ts +//// [|export var x = 0; +//// bar/*0*/();|] + +// @Filename: a/foo.d.ts +//// declare function bar(): number; +//// export = bar; +//// export as namespace bar; + +verify.importFixAtPosition([ +`import bar = require("./foo"); + +export var x = 0; +bar();` +]); \ No newline at end of file diff --git a/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports5.ts b/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports5.ts new file mode 100644 index 00000000000..7830faaacc8 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixNewImportAllowSyntheticDefaultImports5.ts @@ -0,0 +1,19 @@ +/// +// @AllowSyntheticDefaultImports: false +// @Module: umd + +// @Filename: a/f1.ts +//// [|export var x = 0; +//// bar/*0*/();|] + +// @Filename: a/foo.d.ts +//// declare function bar(): number; +//// export = bar; +//// export as namespace bar; + +verify.importFixAtPosition([ +`import bar = require("./foo"); + +export var x = 0; +bar();` +]); \ No newline at end of file diff --git a/tests/cases/fourslash/importNameCodeFixUMDGlobal0.ts b/tests/cases/fourslash/importNameCodeFixUMDGlobal0.ts index 3c780dc0af6..3208a41bba1 100644 --- a/tests/cases/fourslash/importNameCodeFixUMDGlobal0.ts +++ b/tests/cases/fourslash/importNameCodeFixUMDGlobal0.ts @@ -1,5 +1,8 @@ /// +// @AllowSyntheticDefaultImports: false +// @Module: es2015 + // @Filename: a/f1.ts //// [|export function test() { }; //// bar1/*0*/.bar;|] diff --git a/tests/cases/fourslash/importNameCodeFixUMDGlobal1.ts b/tests/cases/fourslash/importNameCodeFixUMDGlobal1.ts index 96671ad6f91..1beebb0477c 100644 --- a/tests/cases/fourslash/importNameCodeFixUMDGlobal1.ts +++ b/tests/cases/fourslash/importNameCodeFixUMDGlobal1.ts @@ -1,5 +1,8 @@ /// +// @AllowSyntheticDefaultImports: false +// @Module: esnext + // @Filename: a/f1.ts //// [|import { bar } from "./foo"; //// diff --git a/tests/cases/fourslash/importNameCodeFixUMDGlobalReact0.ts b/tests/cases/fourslash/importNameCodeFixUMDGlobalReact0.ts index 260c34d10a6..5b6df7a5173 100644 --- a/tests/cases/fourslash/importNameCodeFixUMDGlobalReact0.ts +++ b/tests/cases/fourslash/importNameCodeFixUMDGlobalReact0.ts @@ -1,6 +1,8 @@ /// // @jsx: react +// @allowSyntheticDefaultImports: false +// @module: es2015 // @Filename: /node_modules/@types/react/index.d.ts ////export = React; diff --git a/tests/cases/fourslash/importNameCodeFixUMDGlobalReact1.ts b/tests/cases/fourslash/importNameCodeFixUMDGlobalReact1.ts index ccd69c50199..669db55342b 100644 --- a/tests/cases/fourslash/importNameCodeFixUMDGlobalReact1.ts +++ b/tests/cases/fourslash/importNameCodeFixUMDGlobalReact1.ts @@ -1,6 +1,8 @@ /// // @jsx: react +// @allowSyntheticDefaultImports: false +// @module: es2015 // @Filename: /node_modules/@types/react/index.d.ts ////export = React; From 2f2a82b91dd1286723308b9af0505560491af700 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 7 Nov 2017 09:45:58 -0800 Subject: [PATCH 167/235] Move "space-before-function-paren" lint rule to list of rules waiting on a formatter (#19807) --- tslint.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tslint.json b/tslint.json index f4403d48f19..718c437b372 100644 --- a/tslint.json +++ b/tslint.json @@ -96,7 +96,6 @@ "ordered-imports": false, "prefer-conditional-expression": false, "radix": false, - "space-before-function-paren": false, "trailing-comma": false, // These should be done automatically by a formatter. https://github.com/Microsoft/TypeScript/issues/18340 @@ -104,6 +103,7 @@ "eofline": false, "max-line-length": false, "no-consecutive-blank-lines": false, + "space-before-function-paren": false, // Not doing "ban-comma-operator": false, From 57f247eff490d804ff047e7d8b88b64b294ea13f Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 7 Nov 2017 09:46:40 -0800 Subject: [PATCH 168/235] Add hyphen in completionEntryDetails-full (#19808) --- src/server/protocol.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 93d5c69d361..f44efa0db21 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -16,7 +16,7 @@ namespace ts.server.protocol { CompletionsFull = "completions-full", CompletionDetails = "completionEntryDetails", /* @internal */ - CompletionDetailsFull = "completionEntryDetailsFull", + CompletionDetailsFull = "completionEntryDetails-full", CompileOnSaveAffectedFileList = "compileOnSaveAffectedFileList", CompileOnSaveEmitFile = "compileOnSaveEmitFile", Configure = "configure", From 9a415a2b23fa26e1f997580718ea41948b51f7ce Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 7 Nov 2017 09:50:17 -0800 Subject: [PATCH 169/235] DefinitelyRunner cleanup and speedup 1. Only `npm install` packages with a package.json 2. Add `workingDirectory` to runnerBase to differentiate input directory from output directory (which should be different for definitelyRunner). 3. Don't output anything on success. --- src/harness/definitelyRunner.ts | 20 +++++++++++++------- src/harness/parallel/host.ts | 8 ++++---- src/harness/runnerbase.ts | 3 +++ 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/harness/definitelyRunner.ts b/src/harness/definitelyRunner.ts index afd39b72424..c2f7a04d3e7 100644 --- a/src/harness/definitelyRunner.ts +++ b/src/harness/definitelyRunner.ts @@ -2,8 +2,11 @@ /// class DefinitelyTypedRunner extends RunnerBase { private static readonly testDir = "../DefinitelyTyped/types/"; + + public workingDirectory = DefinitelyTypedRunner.testDir; + public enumerateTestFiles() { - return Harness.IO.getDirectories(DefinitelyTypedRunner.testDir).map(dir => DefinitelyTypedRunner.testDir + dir); + return Harness.IO.getDirectories(DefinitelyTypedRunner.testDir); } public kind(): TestRunnerKind { @@ -28,16 +31,19 @@ class DefinitelyTypedRunner extends RunnerBase { describe(directoryName, () => { const cp = require("child_process"); const path = require("path"); + const fs = require("fs"); it("should build successfully", () => { - const cwd = path.join(__dirname, "../../", directoryName); + const cwd = path.join(__dirname, "../../", DefinitelyTypedRunner.testDir, directoryName); const timeout = 600000; // 600s = 10 minutes - const stdio = isWorker ? "pipe" : "inherit"; - const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout, shell: true, stdio }); - if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed!`); + if (fs.existsSync(path.join(cwd, 'package.json'))) { + const stdio = isWorker ? "pipe" : "inherit"; + const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout, shell: true, stdio }); + if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed!`); + } Harness.Baseline.runBaseline(`${this.kind()}/${directoryName}.log`, () => { - const result = cp.spawnSync(`node`, [path.join(__dirname, "tsc.js"), "--lib dom,es6", "--strict"], { cwd, timeout, shell: true }); - return `Exit Code: ${result.status} + const result = cp.spawnSync(`node`, [path.join(__dirname, "tsc.js")], { cwd, timeout, shell: true }); + return result.status === 0 ? null : `Exit Code: ${result.status} Standard output: ${result.stdout.toString().replace(/\r\n/g, "\n")} diff --git a/src/harness/parallel/host.ts b/src/harness/parallel/host.ts index f37a3b1099e..e278d267e1f 100644 --- a/src/harness/parallel/host.ts +++ b/src/harness/parallel/host.ts @@ -77,18 +77,18 @@ namespace Harness.Parallel.Host { console.log("Discovering runner-based tests..."); const discoverStart = +(new Date()); const { statSync }: { statSync(path: string): { size: number }; } = require("fs"); + const path: { join: (...args: string[]) => string } = require("path"); for (const runner of runners) { - const files = runner.enumerateTestFiles(); - for (const file of files) { + for (const file of runner.enumerateTestFiles()) { let size: number; if (!perfData) { try { - size = statSync(file).size; + size = statSync(path.join(runner.workingDirectory, file)).size; } catch { // May be a directory try { - size = Harness.IO.listFiles(file, /.*/g, { recursive: true }).reduce((acc, elem) => acc + statSync(elem).size, 0); + size = Harness.IO.listFiles(path.join(runner.workingDirectory, file), /.*/g, { recursive: true }).reduce((acc, elem) => acc + statSync(elem).size, 0); } catch { // Unknown test kind, just return 0 and let the historical analysis take over after one run diff --git a/src/harness/runnerbase.ts b/src/harness/runnerbase.ts index 42e625a897d..1f5b31db2d6 100644 --- a/src/harness/runnerbase.ts +++ b/src/harness/runnerbase.ts @@ -24,6 +24,9 @@ abstract class RunnerBase { abstract enumerateTestFiles(): string[]; + /** The working directory where tests are found. Needed for batch testing where the input path will differ from the output path inside baselines */ + public workingDirectory = ""; + /** Setup the runner's tests so that they are ready to be executed by the harness * The first test should be a describe/it block that sets up the harness's compiler instance appropriately */ From d1fa006a1e1761e39430f9363768356a5b8f360a Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Tue, 7 Nov 2017 10:10:34 -0800 Subject: [PATCH 170/235] Use CharacterCode enum --- src/services/utilities.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 643aae2bae1..4f95682d949 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1351,11 +1351,11 @@ namespace ts { return position; function AdvancePastLineBreak() { - if (text.charCodeAt(position) === 0xD) { + if (text.charCodeAt(position) === CharacterCodes.carriageReturn) { position++; } - if (text.charCodeAt(position) === 0xA) { + if (text.charCodeAt(position) === CharacterCodes.lineFeed) { position++; } } From 3e339d88a1b192e86a448ed26643e1351f80afb9 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Tue, 7 Nov 2017 10:33:35 -0800 Subject: [PATCH 171/235] Handle other linebreak characters and add boundary checks --- src/services/utilities.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 4f95682d949..179e5edde52 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1330,6 +1330,7 @@ namespace ts { export function getSourceFileImportLocation(node: SourceFile) { // For a source file, it is possible there are detached comments we should not skip const text = node.text; + const textLength = text.length; let ranges = getLeadingCommentRanges(text, 0); if (!ranges) return 0; let position = 0; @@ -1351,12 +1352,15 @@ namespace ts { return position; function AdvancePastLineBreak() { - if (text.charCodeAt(position) === CharacterCodes.carriageReturn) { - position++; - } + if (position < textLength) { + const charCode = text.charCodeAt(position); + if (isLineBreak(charCode)) { + position++; - if (text.charCodeAt(position) === CharacterCodes.lineFeed) { - position++; + if (position < textLength && charCode === CharacterCodes.carriageReturn && text.charCodeAt(position) === CharacterCodes.lineFeed) { + position++; + } + } } } } From 2378ff32b1164388ec8c7d74872f3f8dee8d764a Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 7 Nov 2017 10:45:42 -0800 Subject: [PATCH 172/235] Fix lint and allow null keyword --- src/harness/definitelyRunner.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/harness/definitelyRunner.ts b/src/harness/definitelyRunner.ts index c2f7a04d3e7..ca9f9137ca4 100644 --- a/src/harness/definitelyRunner.ts +++ b/src/harness/definitelyRunner.ts @@ -36,13 +36,14 @@ class DefinitelyTypedRunner extends RunnerBase { it("should build successfully", () => { const cwd = path.join(__dirname, "../../", DefinitelyTypedRunner.testDir, directoryName); const timeout = 600000; // 600s = 10 minutes - if (fs.existsSync(path.join(cwd, 'package.json'))) { + if (fs.existsSync(path.join(cwd, "package.json"))) { const stdio = isWorker ? "pipe" : "inherit"; const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout, shell: true, stdio }); if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed!`); } Harness.Baseline.runBaseline(`${this.kind()}/${directoryName}.log`, () => { const result = cp.spawnSync(`node`, [path.join(__dirname, "tsc.js")], { cwd, timeout, shell: true }); + // tslint:disable:no-null-keyword return result.status === 0 ? null : `Exit Code: ${result.status} Standard output: ${result.stdout.toString().replace(/\r\n/g, "\n")} @@ -50,6 +51,7 @@ ${result.stdout.toString().replace(/\r\n/g, "\n")} Standard error: ${result.stderr.toString().replace(/\r\n/g, "\n")}`; + // tslint:enable:no-null-keyword }); }); }); From 2715f890b4993a94ca75b7ba1453aa5982dc1803 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Tue, 7 Nov 2017 10:47:36 -0800 Subject: [PATCH 173/235] PascalCase -> camelCase --- src/services/utilities.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 179e5edde52..f59f6e56e91 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1337,21 +1337,21 @@ namespace ts { // However we should still skip a pinned comment at the top if (ranges.length && ranges[0].kind === SyntaxKind.MultiLineCommentTrivia && isPinnedComment(text, ranges[0])) { position = ranges[0].end; - AdvancePastLineBreak(); + advancePastLineBreak(); ranges = ranges.slice(1); } // As well as any triple slash references for (const range of ranges) { if (range.kind === SyntaxKind.SingleLineCommentTrivia && isRecognizedTripleSlashComment(node.text, range.pos, range.end)) { position = range.end; - AdvancePastLineBreak(); + advancePastLineBreak(); continue; } break; } return position; - function AdvancePastLineBreak() { + function advancePastLineBreak() { if (position < textLength) { const charCode = text.charCodeAt(position); if (isLineBreak(charCode)) { From 88a31d60967d86fd8107f630e4575b5d75048661 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 7 Nov 2017 10:57:54 -0800 Subject: [PATCH 174/235] Change runner name from 'definitely' to 'dt' --- Jakefile.js | 2 +- src/harness/{definitelyRunner.ts => dtRunner.ts} | 2 +- src/harness/runner.ts | 6 +++--- src/harness/runnerbase.ts | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) rename src/harness/{definitelyRunner.ts => dtRunner.ts} (96%) diff --git a/Jakefile.js b/Jakefile.js index 40520e79a4a..a133d0dba32 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -106,7 +106,7 @@ var harnessCoreSources = [ "loggedIO.ts", "rwcRunner.ts", "userRunner.ts", - "definitelyRunner.ts", + "dtRunner.ts", "test262Runner.ts", "./parallel/shared.ts", "./parallel/host.ts", diff --git a/src/harness/definitelyRunner.ts b/src/harness/dtRunner.ts similarity index 96% rename from src/harness/definitelyRunner.ts rename to src/harness/dtRunner.ts index ca9f9137ca4..1da07b92d86 100644 --- a/src/harness/definitelyRunner.ts +++ b/src/harness/dtRunner.ts @@ -10,7 +10,7 @@ class DefinitelyTypedRunner extends RunnerBase { } public kind(): TestRunnerKind { - return "definitely"; + return "dt"; } /** Setup the runner's tests so that they are ready to be executed by the harness diff --git a/src/harness/runner.ts b/src/harness/runner.ts index fb66e74b958..0a9a7d3428d 100644 --- a/src/harness/runner.ts +++ b/src/harness/runner.ts @@ -19,7 +19,7 @@ /// /// /// -/// +/// /// /// @@ -63,7 +63,7 @@ function createRunner(kind: TestRunnerKind): RunnerBase { return new Test262BaselineRunner(); case "user": return new UserCodeRunner(); - case "definitely": + case "dt": return new DefinitelyTypedRunner(); } ts.Debug.fail(`Unknown runner kind ${kind}`); @@ -186,7 +186,7 @@ function handleTestConfig() { case "user": runners.push(new UserCodeRunner()); break; - case "definitely": + case "dt": runners.push(new DefinitelyTypedRunner()); break; } diff --git a/src/harness/runnerbase.ts b/src/harness/runnerbase.ts index 1f5b31db2d6..2858738f4b5 100644 --- a/src/harness/runnerbase.ts +++ b/src/harness/runnerbase.ts @@ -1,7 +1,7 @@ /// -type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project" | "rwc" | "test262" | "user" | "definitely"; +type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project" | "rwc" | "test262" | "user" | "dt"; type CompilerTestKind = "conformance" | "compiler"; type FourslashTestKind = "fourslash" | "fourslash-shims" | "fourslash-shims-pp" | "fourslash-server"; From 5e5b5652ed8437eac908f40a1ac91e2f55a04761 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 7 Nov 2017 11:10:24 -0800 Subject: [PATCH 175/235] Remove package-lock.json before `npm install` --- src/harness/dtRunner.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/harness/dtRunner.ts b/src/harness/dtRunner.ts index 1da07b92d86..3b739b28f1c 100644 --- a/src/harness/dtRunner.ts +++ b/src/harness/dtRunner.ts @@ -37,6 +37,9 @@ class DefinitelyTypedRunner extends RunnerBase { const cwd = path.join(__dirname, "../../", DefinitelyTypedRunner.testDir, directoryName); const timeout = 600000; // 600s = 10 minutes if (fs.existsSync(path.join(cwd, "package.json"))) { + if (fs.existsSync(path.join(cwd, "package-lock.json"))) { + fs.unlinkSync(path.join(cwd, "package-lock.json")); + } const stdio = isWorker ? "pipe" : "inherit"; const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout, shell: true, stdio }); if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed!`); From c6f343e266f2ffd3c69711dbf3ea02fdde2d3485 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 7 Nov 2017 14:47:08 -0800 Subject: [PATCH 176/235] Improve asserts in getSuggestionForNonexistentSymbol --- src/compiler/checker.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4c88bce12f2..2990f0cc3f8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15291,8 +15291,9 @@ namespace ts { } function getSuggestionForNonexistentSymbol(location: Node, outerName: __String, meaning: SymbolFlags): string { + Debug.assert(outerName !== undefined, "outername should always be defined"); const result = resolveNameHelper(location, outerName, meaning, /*nameNotFoundMessage*/ undefined, outerName, /*isUse*/ false, (symbols, name, meaning) => { - Debug.assert(name !== undefined, "name should always be defined, and equal to " + outerName); + Debug.assertEqual(outerName, name, "name should equal outerName"); const symbol = getSymbol(symbols, name, meaning); // Sometimes the symbol is found when location is a return type of a function: `typeof x` and `x` is declared in the body of the function // So the table *contains* `x` but `x` isn't actually in scope. From ad18bde92bbe4307f0a2b245cc0ecd0f89fcf671 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 7 Nov 2017 15:43:55 -0800 Subject: [PATCH 177/235] RWC:Handle lib entries in tsconfig --- src/harness/harness.ts | 4 ++-- src/harness/rwcRunner.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index abec41ea4a4..338ca6bb087 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -2146,8 +2146,8 @@ namespace Harness { return filePath.indexOf(Harness.libFolder) === 0; } - export function getDefaultLibraryFile(io: Harness.Io): Harness.Compiler.TestFile { - const libFile = Harness.userSpecifiedRoot + Harness.libFolder + Harness.Compiler.defaultLibFileName; + export function getDefaultLibraryFile(libPath: string, io: Harness.Io): Harness.Compiler.TestFile { + const libFile = Harness.userSpecifiedRoot + Harness.libFolder + libPath.slice(io.directoryName(libPath).length + 1); return { unitName: libFile, content: io.readFile(libFile) }; } diff --git a/src/harness/rwcRunner.ts b/src/harness/rwcRunner.ts index af6e8c95c5c..5613848b8e0 100644 --- a/src/harness/rwcRunner.ts +++ b/src/harness/rwcRunner.ts @@ -131,7 +131,7 @@ namespace RWC { } else { // set the flag to put default library to the beginning of the list - inputFiles.unshift(Harness.getDefaultLibraryFile(oldIO)); + inputFiles.unshift(Harness.getDefaultLibraryFile(fileRead.path, oldIO)); } } } From 4e4f7507d09699f26b3884254e208d1e7966442f Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 7 Nov 2017 16:08:57 -0800 Subject: [PATCH 178/235] Fix getDefaultLibraryFile + turn off lib 1. getDefaultLibraryFile should use ts to normalise the file and find the filename. 2. lib should be turned off at the same time that noLib is turned on to avoid a pointless error. --- src/harness/harness.ts | 4 ++-- src/harness/rwcRunner.ts | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 338ca6bb087..8a3202b88be 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -2146,8 +2146,8 @@ namespace Harness { return filePath.indexOf(Harness.libFolder) === 0; } - export function getDefaultLibraryFile(libPath: string, io: Harness.Io): Harness.Compiler.TestFile { - const libFile = Harness.userSpecifiedRoot + Harness.libFolder + libPath.slice(io.directoryName(libPath).length + 1); + export function getDefaultLibraryFile(filePath: string, io: Harness.Io): Harness.Compiler.TestFile { + const libFile = Harness.userSpecifiedRoot + Harness.libFolder + ts.getBaseFileName(ts.normalizeSlashes(filePath)); return { unitName: libFile, content: io.readFile(libFile) }; } diff --git a/src/harness/rwcRunner.ts b/src/harness/rwcRunner.ts index 5613848b8e0..ef7a371b0c4 100644 --- a/src/harness/rwcRunner.ts +++ b/src/harness/rwcRunner.ts @@ -138,6 +138,7 @@ namespace RWC { } // do not use lib since we already read it in above + opts.options.lib = undefined; opts.options.noLib = true; // Emit the results From ef6f9351b5ec2fb5c2a2664e60ba35903b51bd43 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 8 Nov 2017 09:40:53 -0800 Subject: [PATCH 179/235] Fix undefined error for diagnostic for instantiating an abstract class (#19809) * Fix undefined error for diagnostic for instantiating an abstract class * Only use the name-less diagnostic --- src/compiler/checker.ts | 2 +- src/compiler/diagnosticMessages.json | 2 +- ...ractClassInLocalScopeIsAbstract.errors.txt | 4 +-- ...bstractConstructorAssignability.errors.txt | 4 +-- .../classAbstractFactoryFunction.errors.txt | 4 +-- ...lassAbstractImportInstantiation.errors.txt | 8 ++--- .../classAbstractInAModule.errors.txt | 4 +-- .../classAbstractInstantiations1.errors.txt | 12 +++---- .../classAbstractInstantiations2.errors.txt | 12 +++---- .../classAbstractMergedDeclaration.errors.txt | 32 +++++++++---------- .../classAbstractSingleLineDecl.errors.txt | 4 +-- ...assAbstractUsingAbstractMethod1.errors.txt | 4 +-- .../reference/newAbstractInstance2.errors.txt | 12 +++++++ .../reference/newAbstractInstance2.js | 24 ++++++++++++++ .../reference/newAbstractInstance2.symbols | 10 ++++++ .../reference/newAbstractInstance2.types | 11 +++++++ tests/cases/compiler/newAbstractInstance2.ts | 6 ++++ 17 files changed, 109 insertions(+), 46 deletions(-) create mode 100644 tests/baselines/reference/newAbstractInstance2.errors.txt create mode 100644 tests/baselines/reference/newAbstractInstance2.js create mode 100644 tests/baselines/reference/newAbstractInstance2.symbols create mode 100644 tests/baselines/reference/newAbstractInstance2.types create mode 100644 tests/cases/compiler/newAbstractInstance2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8fa4429f7fd..21ae2369a41 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16726,7 +16726,7 @@ namespace ts { // only the class declaration node will have the Abstract flag set. const valueDecl = expressionType.symbol && getClassLikeDeclarationOfSymbol(expressionType.symbol); if (valueDecl && hasModifier(valueDecl, ModifierFlags.Abstract)) { - error(node, Diagnostics.Cannot_create_an_instance_of_the_abstract_class_0, declarationNameToString(getNameOfDeclaration(valueDecl))); + error(node, Diagnostics.Cannot_create_an_instance_of_an_abstract_class); return resolveErrorCall(node); } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 60e3d6c4c4f..0eb3959fd3c 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1716,7 +1716,7 @@ "category": "Error", "code": 2510 }, - "Cannot create an instance of the abstract class '{0}'.": { + "Cannot create an instance of an abstract class.": { "category": "Error", "code": 2511 }, diff --git a/tests/baselines/reference/abstractClassInLocalScopeIsAbstract.errors.txt b/tests/baselines/reference/abstractClassInLocalScopeIsAbstract.errors.txt index f5c5b417ea3..fa02cb21d34 100644 --- a/tests/baselines/reference/abstractClassInLocalScopeIsAbstract.errors.txt +++ b/tests/baselines/reference/abstractClassInLocalScopeIsAbstract.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/abstractClassInLocalScopeIsAbstract.ts(4,5): error TS2511: Cannot create an instance of the abstract class 'A'. +tests/cases/compiler/abstractClassInLocalScopeIsAbstract.ts(4,5): error TS2511: Cannot create an instance of an abstract class. ==== tests/cases/compiler/abstractClassInLocalScopeIsAbstract.ts (1 errors) ==== @@ -7,7 +7,7 @@ tests/cases/compiler/abstractClassInLocalScopeIsAbstract.ts(4,5): error TS2511: class B extends A {} new A(); ~~~~~~~ -!!! error TS2511: Cannot create an instance of the abstract class 'A'. +!!! error TS2511: Cannot create an instance of an abstract class. new B(); })() \ No newline at end of file diff --git a/tests/baselines/reference/classAbstractConstructorAssignability.errors.txt b/tests/baselines/reference/classAbstractConstructorAssignability.errors.txt index 0f834665346..3ad45cc2b04 100644 --- a/tests/baselines/reference/classAbstractConstructorAssignability.errors.txt +++ b/tests/baselines/reference/classAbstractConstructorAssignability.errors.txt @@ -2,7 +2,7 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst Cannot assign an abstract constructor type to a non-abstract constructor type. tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractConstructorAssignability.ts(9,5): error TS2322: Type 'typeof B' is not assignable to type 'typeof C'. Cannot assign an abstract constructor type to a non-abstract constructor type. -tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractConstructorAssignability.ts(12,1): error TS2511: Cannot create an instance of the abstract class 'B'. +tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractConstructorAssignability.ts(12,1): error TS2511: Cannot create an instance of an abstract class. ==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractConstructorAssignability.ts (3 errors) ==== @@ -25,5 +25,5 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst new AA; new BB; ~~~~~~ -!!! error TS2511: Cannot create an instance of the abstract class 'B'. +!!! error TS2511: Cannot create an instance of an abstract class. new CC; \ No newline at end of file diff --git a/tests/baselines/reference/classAbstractFactoryFunction.errors.txt b/tests/baselines/reference/classAbstractFactoryFunction.errors.txt index 1b281f35260..2e7b3ad8f46 100644 --- a/tests/baselines/reference/classAbstractFactoryFunction.errors.txt +++ b/tests/baselines/reference/classAbstractFactoryFunction.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractFactoryFunction.ts(9,12): error TS2511: Cannot create an instance of the abstract class 'B'. +tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractFactoryFunction.ts(9,12): error TS2511: Cannot create an instance of an abstract class. tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractFactoryFunction.ts(13,6): error TS2345: Argument of type 'typeof B' is not assignable to parameter of type 'typeof A'. Cannot assign an abstract constructor type to a non-abstract constructor type. @@ -14,7 +14,7 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst function NewB(Factory: typeof B) { return new B; ~~~~~ -!!! error TS2511: Cannot create an instance of the abstract class 'B'. +!!! error TS2511: Cannot create an instance of an abstract class. } NewA(A); diff --git a/tests/baselines/reference/classAbstractImportInstantiation.errors.txt b/tests/baselines/reference/classAbstractImportInstantiation.errors.txt index 76110afa4ff..a01c75b6dae 100644 --- a/tests/baselines/reference/classAbstractImportInstantiation.errors.txt +++ b/tests/baselines/reference/classAbstractImportInstantiation.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractImportInstantiation.ts(4,5): error TS2511: Cannot create an instance of the abstract class 'A'. -tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractImportInstantiation.ts(9,1): error TS2511: Cannot create an instance of the abstract class 'A'. +tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractImportInstantiation.ts(4,5): error TS2511: Cannot create an instance of an abstract class. +tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractImportInstantiation.ts(9,1): error TS2511: Cannot create an instance of an abstract class. ==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractImportInstantiation.ts (2 errors) ==== @@ -8,12 +8,12 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst new A; ~~~~~ -!!! error TS2511: Cannot create an instance of the abstract class 'A'. +!!! error TS2511: Cannot create an instance of an abstract class. } import myA = M.A; new myA; ~~~~~~~ -!!! error TS2511: Cannot create an instance of the abstract class 'A'. +!!! error TS2511: Cannot create an instance of an abstract class. \ No newline at end of file diff --git a/tests/baselines/reference/classAbstractInAModule.errors.txt b/tests/baselines/reference/classAbstractInAModule.errors.txt index 426da866087..18bb6d4391e 100644 --- a/tests/baselines/reference/classAbstractInAModule.errors.txt +++ b/tests/baselines/reference/classAbstractInAModule.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInAModule.ts(6,1): error TS2511: Cannot create an instance of the abstract class 'A'. +tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInAModule.ts(6,1): error TS2511: Cannot create an instance of an abstract class. ==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInAModule.ts (1 errors) ==== @@ -9,5 +9,5 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst new M.A; ~~~~~~~ -!!! error TS2511: Cannot create an instance of the abstract class 'A'. +!!! error TS2511: Cannot create an instance of an abstract class. new M.B; \ No newline at end of file diff --git a/tests/baselines/reference/classAbstractInstantiations1.errors.txt b/tests/baselines/reference/classAbstractInstantiations1.errors.txt index d1c159858a4..bc696ce19db 100644 --- a/tests/baselines/reference/classAbstractInstantiations1.errors.txt +++ b/tests/baselines/reference/classAbstractInstantiations1.errors.txt @@ -1,6 +1,6 @@ -tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations1.ts(11,1): error TS2511: Cannot create an instance of the abstract class 'A'. -tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations1.ts(12,1): error TS2511: Cannot create an instance of the abstract class 'A'. -tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations1.ts(14,1): error TS2511: Cannot create an instance of the abstract class 'C'. +tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations1.ts(11,1): error TS2511: Cannot create an instance of an abstract class. +tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations1.ts(12,1): error TS2511: Cannot create an instance of an abstract class. +tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations1.ts(14,1): error TS2511: Cannot create an instance of an abstract class. ==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations1.ts (3 errors) ==== @@ -16,14 +16,14 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst new A; ~~~~~ -!!! error TS2511: Cannot create an instance of the abstract class 'A'. +!!! error TS2511: Cannot create an instance of an abstract class. new A(1); // should report 1 error ~~~~~~~~ -!!! error TS2511: Cannot create an instance of the abstract class 'A'. +!!! error TS2511: Cannot create an instance of an abstract class. new B; new C; ~~~~~ -!!! error TS2511: Cannot create an instance of the abstract class 'C'. +!!! error TS2511: Cannot create an instance of an abstract class. var a : A; var b : B; diff --git a/tests/baselines/reference/classAbstractInstantiations2.errors.txt b/tests/baselines/reference/classAbstractInstantiations2.errors.txt index 15b63a6d3e8..d05e05517b2 100644 --- a/tests/baselines/reference/classAbstractInstantiations2.errors.txt +++ b/tests/baselines/reference/classAbstractInstantiations2.errors.txt @@ -1,8 +1,8 @@ -tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(10,1): error TS2511: Cannot create an instance of the abstract class 'B'. +tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(10,1): error TS2511: Cannot create an instance of an abstract class. tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(13,5): error TS2322: Type 'typeof B' is not assignable to type 'typeof A'. Cannot assign an abstract constructor type to a non-abstract constructor type. -tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(17,5): error TS2511: Cannot create an instance of the abstract class 'B'. -tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(21,1): error TS2511: Cannot create an instance of the abstract class 'B'. +tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(17,5): error TS2511: Cannot create an instance of an abstract class. +tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(21,1): error TS2511: Cannot create an instance of an abstract class. tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(23,15): error TS2449: Class 'C' used before its declaration. tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(26,7): error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'bar' from class 'B'. tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(46,5): error TS2391: Function implementation is missing or not immediately following the declaration. @@ -22,7 +22,7 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst new B; // error ~~~~~ -!!! error TS2511: Cannot create an instance of the abstract class 'B'. +!!! error TS2511: Cannot create an instance of an abstract class. var BB: typeof B = B; var AA: typeof A = BB; // error, AA is not of abstract type. @@ -34,13 +34,13 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst function constructB(Factory : typeof B) { new Factory; // error -- Factory is of type typeof B. ~~~~~~~~~~~ -!!! error TS2511: Cannot create an instance of the abstract class 'B'. +!!! error TS2511: Cannot create an instance of an abstract class. } var BB = B; new BB; // error -- BB is of type typeof B. ~~~~~~ -!!! error TS2511: Cannot create an instance of the abstract class 'B'. +!!! error TS2511: Cannot create an instance of an abstract class. var x : any = C; ~ diff --git a/tests/baselines/reference/classAbstractMergedDeclaration.errors.txt b/tests/baselines/reference/classAbstractMergedDeclaration.errors.txt index 3e18d8796fb..fc15ca410e8 100644 --- a/tests/baselines/reference/classAbstractMergedDeclaration.errors.txt +++ b/tests/baselines/reference/classAbstractMergedDeclaration.errors.txt @@ -6,14 +6,14 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(26,15): error TS2300: Duplicate identifier 'DCC1'. tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(28,15): error TS2300: Duplicate identifier 'DCC2'. tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(29,24): error TS2300: Duplicate identifier 'DCC2'. -tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(31,1): error TS2511: Cannot create an instance of the abstract class 'CM'. -tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(32,1): error TS2511: Cannot create an instance of the abstract class 'MC'. -tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(33,1): error TS2511: Cannot create an instance of the abstract class 'CI'. -tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(34,1): error TS2511: Cannot create an instance of the abstract class 'IC'. -tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(35,1): error TS2511: Cannot create an instance of the abstract class 'CC1'. -tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(37,1): error TS2511: Cannot create an instance of the abstract class 'DCI'. -tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(38,1): error TS2511: Cannot create an instance of the abstract class 'DIC'. -tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(39,1): error TS2511: Cannot create an instance of the abstract class 'DCC1'. +tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(31,1): error TS2511: Cannot create an instance of an abstract class. +tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(32,1): error TS2511: Cannot create an instance of an abstract class. +tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(33,1): error TS2511: Cannot create an instance of an abstract class. +tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(34,1): error TS2511: Cannot create an instance of an abstract class. +tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(35,1): error TS2511: Cannot create an instance of an abstract class. +tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(37,1): error TS2511: Cannot create an instance of an abstract class. +tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(38,1): error TS2511: Cannot create an instance of an abstract class. +tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts(39,1): error TS2511: Cannot create an instance of an abstract class. ==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMergedDeclaration.ts (16 errors) ==== @@ -65,27 +65,27 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst new CM; ~~~~~~ -!!! error TS2511: Cannot create an instance of the abstract class 'CM'. +!!! error TS2511: Cannot create an instance of an abstract class. new MC; ~~~~~~ -!!! error TS2511: Cannot create an instance of the abstract class 'MC'. +!!! error TS2511: Cannot create an instance of an abstract class. new CI; ~~~~~~ -!!! error TS2511: Cannot create an instance of the abstract class 'CI'. +!!! error TS2511: Cannot create an instance of an abstract class. new IC; ~~~~~~ -!!! error TS2511: Cannot create an instance of the abstract class 'IC'. +!!! error TS2511: Cannot create an instance of an abstract class. new CC1; ~~~~~~~ -!!! error TS2511: Cannot create an instance of the abstract class 'CC1'. +!!! error TS2511: Cannot create an instance of an abstract class. new CC2; new DCI; ~~~~~~~ -!!! error TS2511: Cannot create an instance of the abstract class 'DCI'. +!!! error TS2511: Cannot create an instance of an abstract class. new DIC; ~~~~~~~ -!!! error TS2511: Cannot create an instance of the abstract class 'DIC'. +!!! error TS2511: Cannot create an instance of an abstract class. new DCC1; ~~~~~~~~ -!!! error TS2511: Cannot create an instance of the abstract class 'DCC1'. +!!! error TS2511: Cannot create an instance of an abstract class. new DCC2; \ No newline at end of file diff --git a/tests/baselines/reference/classAbstractSingleLineDecl.errors.txt b/tests/baselines/reference/classAbstractSingleLineDecl.errors.txt index 0670ea108ea..1bdabfefe6d 100644 --- a/tests/baselines/reference/classAbstractSingleLineDecl.errors.txt +++ b/tests/baselines/reference/classAbstractSingleLineDecl.errors.txt @@ -1,6 +1,6 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractSingleLineDecl.ts(3,1): error TS2304: Cannot find name 'abstract'. tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractSingleLineDecl.ts(6,1): error TS2304: Cannot find name 'abstract'. -tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractSingleLineDecl.ts(10,1): error TS2511: Cannot create an instance of the abstract class 'A'. +tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractSingleLineDecl.ts(10,1): error TS2511: Cannot create an instance of an abstract class. ==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractSingleLineDecl.ts (3 errors) ==== @@ -19,6 +19,6 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst new A; ~~~~~ -!!! error TS2511: Cannot create an instance of the abstract class 'A'. +!!! error TS2511: Cannot create an instance of an abstract class. new B; new C; \ No newline at end of file diff --git a/tests/baselines/reference/classAbstractUsingAbstractMethod1.errors.txt b/tests/baselines/reference/classAbstractUsingAbstractMethod1.errors.txt index df3682a36af..282fa3a53aa 100644 --- a/tests/baselines/reference/classAbstractUsingAbstractMethod1.errors.txt +++ b/tests/baselines/reference/classAbstractUsingAbstractMethod1.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractUsingAbstractMethod1.ts(16,5): error TS2511: Cannot create an instance of the abstract class 'C'. +tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractUsingAbstractMethod1.ts(16,5): error TS2511: Cannot create an instance of an abstract class. ==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractUsingAbstractMethod1.ts (1 errors) ==== @@ -19,5 +19,5 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst a = new C; // error, cannot instantiate abstract class. ~~~~~ -!!! error TS2511: Cannot create an instance of the abstract class 'C'. +!!! error TS2511: Cannot create an instance of an abstract class. a.foo(); \ No newline at end of file diff --git a/tests/baselines/reference/newAbstractInstance2.errors.txt b/tests/baselines/reference/newAbstractInstance2.errors.txt new file mode 100644 index 00000000000..2b2559cc932 --- /dev/null +++ b/tests/baselines/reference/newAbstractInstance2.errors.txt @@ -0,0 +1,12 @@ +/b.ts(2,1): error TS2511: Cannot create an instance of an abstract class. + + +==== /a.ts (0 errors) ==== + export default abstract class {} + +==== /b.ts (1 errors) ==== + import A from "./a"; + new A(); + ~~~~~~~ +!!! error TS2511: Cannot create an instance of an abstract class. + \ No newline at end of file diff --git a/tests/baselines/reference/newAbstractInstance2.js b/tests/baselines/reference/newAbstractInstance2.js new file mode 100644 index 00000000000..2be1012fcd5 --- /dev/null +++ b/tests/baselines/reference/newAbstractInstance2.js @@ -0,0 +1,24 @@ +//// [tests/cases/compiler/newAbstractInstance2.ts] //// + +//// [a.ts] +export default abstract class {} + +//// [b.ts] +import A from "./a"; +new A(); + + +//// [a.js] +"use strict"; +exports.__esModule = true; +var default_1 = /** @class */ (function () { + function default_1() { + } + return default_1; +}()); +exports["default"] = default_1; +//// [b.js] +"use strict"; +exports.__esModule = true; +var a_1 = require("./a"); +new a_1["default"](); diff --git a/tests/baselines/reference/newAbstractInstance2.symbols b/tests/baselines/reference/newAbstractInstance2.symbols new file mode 100644 index 00000000000..2ce91130095 --- /dev/null +++ b/tests/baselines/reference/newAbstractInstance2.symbols @@ -0,0 +1,10 @@ +=== /a.ts === +export default abstract class {} +No type information for this code. +No type information for this code.=== /b.ts === +import A from "./a"; +>A : Symbol(A, Decl(b.ts, 0, 6)) + +new A(); +>A : Symbol(A, Decl(b.ts, 0, 6)) + diff --git a/tests/baselines/reference/newAbstractInstance2.types b/tests/baselines/reference/newAbstractInstance2.types new file mode 100644 index 00000000000..8e980d90300 --- /dev/null +++ b/tests/baselines/reference/newAbstractInstance2.types @@ -0,0 +1,11 @@ +=== /a.ts === +export default abstract class {} +No type information for this code. +No type information for this code.=== /b.ts === +import A from "./a"; +>A : typeof A + +new A(); +>new A() : any +>A : typeof A + diff --git a/tests/cases/compiler/newAbstractInstance2.ts b/tests/cases/compiler/newAbstractInstance2.ts new file mode 100644 index 00000000000..a035ccabdcf --- /dev/null +++ b/tests/cases/compiler/newAbstractInstance2.ts @@ -0,0 +1,6 @@ +// @Filename: /a.ts +export default abstract class {} + +// @Filename: /b.ts +import A from "./a"; +new A(); From d73fb3acdd33712b7d6267e8fc11173596c3e07a Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 8 Nov 2017 09:48:36 -0800 Subject: [PATCH 180/235] Narrow property access from string index signatures Previously these accesses did not use control flow to narrow property accesses of undefined properties that are resolved from a string index signature. Now the use control flow to narrow these just like normal properties. --- src/compiler/checker.ts | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7bce66892de..e2a419900c7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15221,7 +15221,7 @@ namespace ts { if (indexInfo.isReadonly && (isAssignmentTarget(node) || isDeleteTarget(node))) { error(node, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(apparentType)); } - return indexInfo.type; + return getFlowTypeOfPropertyAccess(node, /*prop*/ undefined, indexInfo.type, getAssignmentTargetKind(node)); } if (right.escapedText && !checkAndReportErrorForExtendingInterface(node)) { reportNonexistentProperty(right, type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType ? apparentType : type); @@ -15246,16 +15246,21 @@ namespace ts { return unknownType; } } + return getFlowTypeOfPropertyAccess(node, prop, propType, assignmentKind); + } - // Only compute control flow type if this is a property access expression that isn't an - // assignment target, and the referenced property was declared as a variable, property, - // accessor, or optional method. - if (node.kind !== SyntaxKind.PropertyAccessExpression || assignmentKind === AssignmentKind.Definite || - !(prop.flags & (SymbolFlags.Variable | SymbolFlags.Property | SymbolFlags.Accessor)) && - !(prop.flags & SymbolFlags.Method && propType.flags & TypeFlags.Union)) { - return propType; + /** + * Only compute control flow type if this is a property access expression that isn't an + * assignment target, and the referenced property was declared as a variable, property, + * accessor, or optional method. + */ + function getFlowTypeOfPropertyAccess(node: PropertyAccessExpression | QualifiedName, prop: Symbol | undefined, type: Type, assignmentKind: AssignmentKind) { + if (node.kind !== SyntaxKind.PropertyAccessExpression || + assignmentKind === AssignmentKind.Definite || + prop && !(prop.flags & (SymbolFlags.Variable | SymbolFlags.Property | SymbolFlags.Accessor)) && !(prop.flags & SymbolFlags.Method && type.flags & TypeFlags.Union)) { + return type; } - const flowType = getFlowTypeOfReference(node, propType); + const flowType = getFlowTypeOfReference(node, type); return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType; } From 6c74b81d7eeb67abf3f17cdcc9f1c858916bdd1f Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 8 Nov 2017 09:50:39 -0800 Subject: [PATCH 181/235] Test:narrow properties from string index signatures --- .../reference/controlFlowStringIndex.js | 13 ++++++++++ .../reference/controlFlowStringIndex.symbols | 18 +++++++++++++ .../reference/controlFlowStringIndex.types | 26 +++++++++++++++++++ .../controlFlow/controlFlowStringIndex.ts | 6 +++++ 4 files changed, 63 insertions(+) create mode 100644 tests/baselines/reference/controlFlowStringIndex.js create mode 100644 tests/baselines/reference/controlFlowStringIndex.symbols create mode 100644 tests/baselines/reference/controlFlowStringIndex.types create mode 100644 tests/cases/conformance/controlFlow/controlFlowStringIndex.ts diff --git a/tests/baselines/reference/controlFlowStringIndex.js b/tests/baselines/reference/controlFlowStringIndex.js new file mode 100644 index 00000000000..456ae6afcd4 --- /dev/null +++ b/tests/baselines/reference/controlFlowStringIndex.js @@ -0,0 +1,13 @@ +//// [controlFlowStringIndex.ts] +type A = { [index: string]: number | null }; +declare const value: A; +if (value.foo !== null) { + value.foo.toExponential() +} + + +//// [controlFlowStringIndex.js] +"use strict"; +if (value.foo !== null) { + value.foo.toExponential(); +} diff --git a/tests/baselines/reference/controlFlowStringIndex.symbols b/tests/baselines/reference/controlFlowStringIndex.symbols new file mode 100644 index 00000000000..aad08e48a9b --- /dev/null +++ b/tests/baselines/reference/controlFlowStringIndex.symbols @@ -0,0 +1,18 @@ +=== tests/cases/conformance/controlFlow/controlFlowStringIndex.ts === +type A = { [index: string]: number | null }; +>A : Symbol(A, Decl(controlFlowStringIndex.ts, 0, 0)) +>index : Symbol(index, Decl(controlFlowStringIndex.ts, 0, 12)) + +declare const value: A; +>value : Symbol(value, Decl(controlFlowStringIndex.ts, 1, 13)) +>A : Symbol(A, Decl(controlFlowStringIndex.ts, 0, 0)) + +if (value.foo !== null) { +>value : Symbol(value, Decl(controlFlowStringIndex.ts, 1, 13)) + + value.foo.toExponential() +>value.foo.toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --)) +>value : Symbol(value, Decl(controlFlowStringIndex.ts, 1, 13)) +>toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --)) +} + diff --git a/tests/baselines/reference/controlFlowStringIndex.types b/tests/baselines/reference/controlFlowStringIndex.types new file mode 100644 index 00000000000..d1722dd6925 --- /dev/null +++ b/tests/baselines/reference/controlFlowStringIndex.types @@ -0,0 +1,26 @@ +=== tests/cases/conformance/controlFlow/controlFlowStringIndex.ts === +type A = { [index: string]: number | null }; +>A : A +>index : string +>null : null + +declare const value: A; +>value : A +>A : A + +if (value.foo !== null) { +>value.foo !== null : boolean +>value.foo : number | null +>value : A +>foo : number | null +>null : null + + value.foo.toExponential() +>value.foo.toExponential() : string +>value.foo.toExponential : (fractionDigits?: number | undefined) => string +>value.foo : number +>value : A +>foo : number +>toExponential : (fractionDigits?: number | undefined) => string +} + diff --git a/tests/cases/conformance/controlFlow/controlFlowStringIndex.ts b/tests/cases/conformance/controlFlow/controlFlowStringIndex.ts new file mode 100644 index 00000000000..78acf6d654e --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowStringIndex.ts @@ -0,0 +1,6 @@ +// @strict: true +type A = { [index: string]: number | null }; +declare const value: A; +if (value.foo !== null) { + value.foo.toExponential() +} From 1a0ec81488b4fb4236f9bbfa25448eaf4e26d8db Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 8 Nov 2017 09:56:50 -0800 Subject: [PATCH 182/235] quickInfo: Display info for signature on a separate line from variable info (#18698) --- src/services/symbolDisplay.ts | 7 ++-- ...kInfoDisplayPartsInterfaceMembers.baseline | 16 ++++++-- ...playPartsTypeParameterInInterface.baseline | 32 +++++++++++---- tests/cases/fourslash/commentsInterface.ts | 4 +- tests/cases/fourslash/commentsOverloads.ts | 40 +++++++++---------- .../externalModuleWithExportAssignment.ts | 8 ++-- 6 files changed, 66 insertions(+), 41 deletions(-) diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index ad9ac88bdfc..fe04342b8f7 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -191,13 +191,14 @@ namespace ts.SymbolDisplay { // If it is call or construct signature of lambda's write type name displayParts.push(punctuationPart(SyntaxKind.ColonToken)); displayParts.push(spacePart()); + if (!(type.flags & TypeFlags.Object && (type).objectFlags & ObjectFlags.Anonymous) && type.symbol) { + addRange(displayParts, symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, SymbolFormatFlags.WriteTypeParametersOrArguments)); + displayParts.push(lineBreakPart()); + } if (useConstructSignatures) { displayParts.push(keywordPart(SyntaxKind.NewKeyword)); displayParts.push(spacePart()); } - if (!(type.flags & TypeFlags.Object && (type).objectFlags & ObjectFlags.Anonymous) && type.symbol) { - addRange(displayParts, symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, SymbolFormatFlags.WriteTypeParametersOrArguments)); - } addSignatureDisplayParts(signature, allSignatures, TypeFormatFlags.WriteArrowStyleSignature); break; diff --git a/tests/baselines/reference/quickInfoDisplayPartsInterfaceMembers.baseline b/tests/baselines/reference/quickInfoDisplayPartsInterfaceMembers.baseline index 732582d9190..fa1e5977dd5 100644 --- a/tests/baselines/reference/quickInfoDisplayPartsInterfaceMembers.baseline +++ b/tests/baselines/reference/quickInfoDisplayPartsInterfaceMembers.baseline @@ -368,6 +368,10 @@ "text": "I", "kind": "interfaceName" }, + { + "text": "\n", + "kind": "lineBreak" + }, { "text": "(", "kind": "punctuation" @@ -472,6 +476,14 @@ "text": " ", "kind": "space" }, + { + "text": "I", + "kind": "interfaceName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, { "text": "new", "kind": "keyword" @@ -480,10 +492,6 @@ "text": " ", "kind": "space" }, - { - "text": "I", - "kind": "interfaceName" - }, { "text": "(", "kind": "punctuation" diff --git a/tests/baselines/reference/quickInfoDisplayPartsTypeParameterInInterface.baseline b/tests/baselines/reference/quickInfoDisplayPartsTypeParameterInInterface.baseline index d48bb70f8ff..80da1f19ef9 100644 --- a/tests/baselines/reference/quickInfoDisplayPartsTypeParameterInInterface.baseline +++ b/tests/baselines/reference/quickInfoDisplayPartsTypeParameterInInterface.baseline @@ -2058,6 +2058,14 @@ "text": " ", "kind": "space" }, + { + "text": "I", + "kind": "interfaceName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, { "text": "new", "kind": "keyword" @@ -2066,10 +2074,6 @@ "text": " ", "kind": "space" }, - { - "text": "I", - "kind": "interfaceName" - }, { "text": "<", "kind": "punctuation" @@ -2188,6 +2192,10 @@ "text": "I", "kind": "interfaceName" }, + { + "text": "\n", + "kind": "lineBreak" + }, { "text": "<", "kind": "punctuation" @@ -5462,6 +5470,14 @@ "text": " ", "kind": "space" }, + { + "text": "I1", + "kind": "interfaceName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, { "text": "new", "kind": "keyword" @@ -5470,10 +5486,6 @@ "text": " ", "kind": "space" }, - { - "text": "I1", - "kind": "interfaceName" - }, { "text": "<", "kind": "punctuation" @@ -5748,6 +5760,10 @@ "text": "I1", "kind": "interfaceName" }, + { + "text": "\n", + "kind": "lineBreak" + }, { "text": "<", "kind": "punctuation" diff --git a/tests/cases/fourslash/commentsInterface.ts b/tests/cases/fourslash/commentsInterface.ts index 7a09329a0fd..e2223326274 100644 --- a/tests/cases/fourslash/commentsInterface.ts +++ b/tests/cases/fourslash/commentsInterface.ts @@ -113,7 +113,7 @@ goTo.marker('16'); verify.currentSignatureHelpDocCommentIs("new method"); verify.currentParameterHelpArgumentDocCommentIs("param"); verify.quickInfos({ - "16q": ["var i2_i: new i2(i: i1) => any", "new method"], + "16q": ["var i2_i: i2\nnew (i: i1) => any", "new method"], 17: "var i2_i_nc_x: number", 18: "(property) i2.nc_x: number", @@ -133,7 +133,7 @@ verify.quickInfos({ goTo.marker('24'); verify.currentSignatureHelpDocCommentIs("this is call signature"); verify.currentParameterHelpArgumentDocCommentIs("paramhelp a"); -verify.quickInfoAt("24q", "var i2_i: i2(a: number, b: number) => number", "this is call signature"); +verify.quickInfoAt("24q", "var i2_i: i2\n(a: number, b: number) => number", "this is call signature"); goTo.marker('25'); verify.currentSignatureHelpDocCommentIs("this is call signature"); diff --git a/tests/cases/fourslash/commentsOverloads.ts b/tests/cases/fourslash/commentsOverloads.ts index 6add2609897..1068e1e6fe1 100644 --- a/tests/cases/fourslash/commentsOverloads.ts +++ b/tests/cases/fourslash/commentsOverloads.ts @@ -296,34 +296,34 @@ verify.completionListContains('f4', 'function f4(a: number): number (+1 overload goTo.marker('18'); verify.not.completionListContains('i1', 'interface i1', ''); -verify.completionListContains('i1_i', 'var i1_i: new i1(b: number) => any (+1 overload)', ''); +verify.completionListContains('i1_i', 'var i1_i: i1\nnew (b: number) => any (+1 overload)', ''); verify.not.completionListContains('i2', 'interface i2', ''); -verify.completionListContains('i2_i', 'var i2_i: new i2(a: string) => any (+1 overload)', ''); +verify.completionListContains('i2_i', 'var i2_i: i2\nnew (a: string) => any (+1 overload)', ''); verify.not.completionListContains('i3', 'interface i3', ''); -verify.completionListContains('i3_i', 'var i3_i: new i3(a: string) => any (+1 overload)', 'new 1'); +verify.completionListContains('i3_i', 'var i3_i: i3\nnew (a: string) => any (+1 overload)', 'new 1'); verify.not.completionListContains('i4', 'interface i4', ''); -verify.completionListContains('i4_i', 'var i4_i: new i4(a: string) => any (+1 overload)', ''); +verify.completionListContains('i4_i', 'var i4_i: i4\nnew (a: string) => any (+1 overload)', ''); goTo.marker('19'); verify.currentSignatureHelpDocCommentIs(""); verify.currentParameterHelpArgumentDocCommentIs(""); -verify.quickInfoAt("19q", "var i1_i: new i1(b: number) => any (+1 overload)"); +verify.quickInfoAt("19q", "var i1_i: i1\nnew (b: number) => any (+1 overload)"); goTo.marker('20'); verify.currentSignatureHelpDocCommentIs("new 1"); verify.currentParameterHelpArgumentDocCommentIs(""); -verify.quickInfoAt("20q", "var i1_i: new i1(a: string) => any (+1 overload)", "new 1"); +verify.quickInfoAt("20q", "var i1_i: i1\nnew (a: string) => any (+1 overload)", "new 1"); goTo.marker('21'); verify.currentSignatureHelpDocCommentIs("this signature 1"); verify.currentParameterHelpArgumentDocCommentIs("param a"); -verify.quickInfoAt("21q", "var i1_i: i1(a: number) => number (+1 overload)", "this signature 1"); +verify.quickInfoAt("21q", "var i1_i: i1\n(a: number) => number (+1 overload)", "this signature 1"); goTo.marker('22'); verify.currentSignatureHelpDocCommentIs("this is signature 2"); verify.currentParameterHelpArgumentDocCommentIs(""); goTo.marker('22q'); -verify.quickInfoAt("22q", "var i1_i: i1(b: string) => number (+1 overload)", "this is signature 2"); +verify.quickInfoAt("22q", "var i1_i: i1\n(b: string) => number (+1 overload)", "this is signature 2"); goTo.marker('23'); verify.completionListContains('foo', '(method) i1.foo(a: number): number (+1 overload)', 'foo 1'); @@ -374,62 +374,62 @@ verify.quickInfoAt("31q", "(method) i1.foo4(b: string): number (+1 overload)"); goTo.marker('32'); verify.currentSignatureHelpDocCommentIs("new 2"); verify.currentParameterHelpArgumentDocCommentIs(""); -verify.quickInfoAt("32q", "var i2_i: new i2(b: number) => any (+1 overload)", "new 2"); +verify.quickInfoAt("32q", "var i2_i: i2\nnew (b: number) => any (+1 overload)", "new 2"); goTo.marker('33'); verify.currentSignatureHelpDocCommentIs(""); verify.currentParameterHelpArgumentDocCommentIs(""); -verify.quickInfoAt("33q", "var i2_i: new i2(a: string) => any (+1 overload)"); +verify.quickInfoAt("33q", "var i2_i: i2\nnew (a: string) => any (+1 overload)"); goTo.marker('34'); verify.currentSignatureHelpDocCommentIs(""); verify.currentParameterHelpArgumentDocCommentIs(""); -verify.quickInfoAt("34q", "var i2_i: i2(a: number) => number (+1 overload)"); +verify.quickInfoAt("34q", "var i2_i: i2\n(a: number) => number (+1 overload)"); goTo.marker('35'); verify.currentSignatureHelpDocCommentIs("this is signature 2"); verify.currentParameterHelpArgumentDocCommentIs(""); -verify.quickInfoAt("35q", "var i2_i: i2(b: string) => number (+1 overload)", "this is signature 2"); +verify.quickInfoAt("35q", "var i2_i: i2\n(b: string) => number (+1 overload)", "this is signature 2"); goTo.marker('36'); verify.currentSignatureHelpDocCommentIs("new 2"); verify.currentParameterHelpArgumentDocCommentIs(""); -verify.quickInfoAt("36q", "var i3_i: new i3(b: number) => any (+1 overload)", "new 2"); +verify.quickInfoAt("36q", "var i3_i: i3\nnew (b: number) => any (+1 overload)", "new 2"); goTo.marker('37'); verify.currentSignatureHelpDocCommentIs("new 1"); verify.currentParameterHelpArgumentDocCommentIs(""); -verify.quickInfoAt("37q", "var i3_i: new i3(a: string) => any (+1 overload)", "new 1"); +verify.quickInfoAt("37q", "var i3_i: i3\nnew (a: string) => any (+1 overload)", "new 1"); goTo.marker('38'); verify.currentSignatureHelpDocCommentIs("this is signature 1"); verify.currentParameterHelpArgumentDocCommentIs(""); -verify.quickInfoAt("38q", "var i3_i: i3(a: number) => number (+1 overload)", "this is signature 1"); +verify.quickInfoAt("38q", "var i3_i: i3\n(a: number) => number (+1 overload)", "this is signature 1"); goTo.marker('39'); verify.currentSignatureHelpDocCommentIs(""); verify.currentParameterHelpArgumentDocCommentIs(""); -verify.quickInfoAt("39q", "var i3_i: i3(b: string) => number (+1 overload)"); +verify.quickInfoAt("39q", "var i3_i: i3\n(b: string) => number (+1 overload)"); goTo.marker('40'); verify.currentSignatureHelpDocCommentIs(""); verify.currentParameterHelpArgumentDocCommentIs(""); -verify.quickInfoAt("40q", "var i4_i: new i4(b: number) => any (+1 overload)"); +verify.quickInfoAt("40q", "var i4_i: i4\nnew (b: number) => any (+1 overload)"); goTo.marker('41'); verify.currentSignatureHelpDocCommentIs(""); verify.currentParameterHelpArgumentDocCommentIs(""); -verify.quickInfoAt("41q", "var i4_i: new i4(a: string) => any (+1 overload)"); +verify.quickInfoAt("41q", "var i4_i: i4\nnew (a: string) => any (+1 overload)"); goTo.marker('42'); verify.currentSignatureHelpDocCommentIs(""); verify.currentParameterHelpArgumentDocCommentIs(""); -verify.quickInfoAt("42q", "var i4_i: i4(a: number) => number (+1 overload)"); +verify.quickInfoAt("42q", "var i4_i: i4\n(a: number) => number (+1 overload)"); goTo.marker('43'); verify.currentSignatureHelpDocCommentIs(""); verify.currentParameterHelpArgumentDocCommentIs(""); -verify.quickInfoAt("43q", "var i4_i: i4(b: string) => number (+1 overload)"); +verify.quickInfoAt("43q", "var i4_i: i4\n(b: string) => number (+1 overload)"); goTo.marker('44'); verify.completionListContains('prop1', '(method) c.prop1(a: number): number (+1 overload)', ''); diff --git a/tests/cases/fourslash/externalModuleWithExportAssignment.ts b/tests/cases/fourslash/externalModuleWithExportAssignment.ts index 90009fe9d46..5b392623690 100644 --- a/tests/cases/fourslash/externalModuleWithExportAssignment.ts +++ b/tests/cases/fourslash/externalModuleWithExportAssignment.ts @@ -33,8 +33,8 @@ verify.quickInfoAt("1", 'import a1 = require("./externalModuleWithExportAssignme verify.quickInfoAt("2", "var a: {\n (): a1.connectExport;\n test1: a1.connectModule;\n test2(): a1.connectModule;\n}", undefined); goTo.marker('3'); -verify.quickInfoIs("(property) test1: a1.connectModule(res: any, req: any, next: any) => void", undefined); -verify.completionListContains("test1", "(property) test1: a1.connectModule(res: any, req: any, next: any) => void", undefined); +verify.quickInfoIs("(property) test1: a1.connectModule\n(res: any, req: any, next: any) => void", undefined); +verify.completionListContains("test1", "(property) test1: a1.connectModule\n(res: any, req: any, next: any) => void", undefined); verify.completionListContains("test2", "(method) test2(): a1.connectModule", undefined); verify.not.completionListContains("connectModule"); verify.not.completionListContains("connectExport"); @@ -53,8 +53,8 @@ verify.currentSignatureHelpIs("a(): a1.connectExport"); verify.quickInfoAt("8", "var r2: a1.connectExport", undefined); goTo.marker('9'); -verify.quickInfoIs("(property) test1: a1.connectModule(res: any, req: any, next: any) => void", undefined); -verify.completionListContains("test1", "(property) test1: a1.connectModule(res: any, req: any, next: any) => void", undefined); +verify.quickInfoIs("(property) test1: a1.connectModule\n(res: any, req: any, next: any) => void", undefined); +verify.completionListContains("test1", "(property) test1: a1.connectModule\n(res: any, req: any, next: any) => void", undefined); verify.completionListContains("test2", "(method) test2(): a1.connectModule", undefined); verify.not.completionListContains("connectModule"); verify.not.completionListContains("connectExport"); From a1da5bd5af7ab16c6a1910f2f20b9f3f72a2d888 Mon Sep 17 00:00:00 2001 From: Adrian Leonhard Date: Wed, 8 Nov 2017 19:02:39 +0100 Subject: [PATCH 183/235] Changed error for setter when emitting declaration with private param type (#18593) so that error message refers to prop name instead of param name. Changed getter errors for similar case so they also refer to prop name. Fixed bug where static getters wouldn't output their specific error. Fixes #1976 --- src/compiler/declarationEmitter.ts | 41 +++-- src/compiler/diagnosticMessages.json | 20 +-- ...otationVisibilityErrorAccessors.errors.txt | 44 +++--- ...eTypeAnnotationVisibilityErrorAccessors.js | 4 +- .../privacyAccessorDeclFile.errors.txt | 144 +++++++++--------- ...ivacyCannotNameAccessorDeclFile.errors.txt | 32 ++-- .../symbolDeclarationEmit12.errors.txt | 4 +- ...eTypeAnnotationVisibilityErrorAccessors.ts | 4 +- 8 files changed, 144 insertions(+), 149 deletions(-) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 48b97b048e9..3276e68b2ac 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -1429,45 +1429,40 @@ namespace ts { function getAccessorDeclarationTypeVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic { let diagnosticMessage: DiagnosticMessage; if (accessorWithTypeAnnotation.kind === SyntaxKind.SetAccessor) { - // Setters have to have type named and cannot infer it so, the type should always be named - if (hasModifier(accessorWithTypeAnnotation.parent, ModifierFlags.Static)) { + // Getters can infer the return type from the returned expression, but setters cannot, so the + // "_from_external_module_1_but_cannot_be_named" case cannot occur. + if (hasModifier(accessorWithTypeAnnotation, ModifierFlags.Static)) { diagnosticMessage = symbolAccessibilityResult.errorModuleName ? - Diagnostics.Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_private_name_1; + Diagnostics.Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 : + Diagnostics.Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1; } else { diagnosticMessage = symbolAccessibilityResult.errorModuleName ? - Diagnostics.Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_private_name_1; + Diagnostics.Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 : + Diagnostics.Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1; } - return { - diagnosticMessage, - errorNode: accessorWithTypeAnnotation.parameters[0], - // TODO(jfreeman): Investigate why we are passing node.name instead of node.parameters[0].name - typeName: accessorWithTypeAnnotation.name - }; } else { if (hasModifier(accessorWithTypeAnnotation, ModifierFlags.Static)) { diagnosticMessage = symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? - Diagnostics.Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : - Diagnostics.Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_1 : - Diagnostics.Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_private_name_0; + Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : + Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 : + Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1; } else { diagnosticMessage = symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? - Diagnostics.Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : - Diagnostics.Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_1 : - Diagnostics.Return_type_of_public_property_getter_from_exported_class_has_or_is_using_private_name_0; + Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : + Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 : + Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1; } - return { - diagnosticMessage, - errorNode: accessorWithTypeAnnotation.name, - typeName: undefined - }; } + return { + diagnosticMessage, + errorNode: accessorWithTypeAnnotation.name, + typeName: accessorWithTypeAnnotation.name + }; } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 0eb3959fd3c..964264ff6e8 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2321,43 +2321,43 @@ "category": "Error", "code": 4033 }, - "Parameter '{0}' of public static property setter from exported class has or is using name '{1}' from private module '{2}'.": { + "Parameter type of public static setter '{0}' from exported class has or is using name '{1}' from private module '{2}'.": { "category": "Error", "code": 4034 }, - "Parameter '{0}' of public static property setter from exported class has or is using private name '{1}'.": { + "Parameter type of public static setter '{0}' from exported class has or is using private name '{1}'.": { "category": "Error", "code": 4035 }, - "Parameter '{0}' of public property setter from exported class has or is using name '{1}' from private module '{2}'.": { + "Parameter type of public setter '{0}' from exported class has or is using name '{1}' from private module '{2}'.": { "category": "Error", "code": 4036 }, - "Parameter '{0}' of public property setter from exported class has or is using private name '{1}'.": { + "Parameter type of public setter '{0}' from exported class has or is using private name '{1}'.": { "category": "Error", "code": 4037 }, - "Return type of public static property getter from exported class has or is using name '{0}' from external module {1} but cannot be named.": { + "Return type of public static getter '{0}' from exported class has or is using name '{1}' from external module {2} but cannot be named.": { "category": "Error", "code": 4038 }, - "Return type of public static property getter from exported class has or is using name '{0}' from private module '{1}'.": { + "Return type of public static getter '{0}' from exported class has or is using name '{1}' from private module '{2}'.": { "category": "Error", "code": 4039 }, - "Return type of public static property getter from exported class has or is using private name '{0}'.": { + "Return type of public static getter '{0}' from exported class has or is using private name '{1}'.": { "category": "Error", "code": 4040 }, - "Return type of public property getter from exported class has or is using name '{0}' from external module {1} but cannot be named.": { + "Return type of public getter '{0}' from exported class has or is using name '{1}' from external module {2} but cannot be named.": { "category": "Error", "code": 4041 }, - "Return type of public property getter from exported class has or is using name '{0}' from private module '{1}'.": { + "Return type of public getter '{0}' from exported class has or is using name '{1}' from private module '{2}'.": { "category": "Error", "code": 4042 }, - "Return type of public property getter from exported class has or is using private name '{0}'.": { + "Return type of public getter '{0}' from exported class has or is using private name '{1}'.": { "category": "Error", "code": 4043 }, diff --git a/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.errors.txt b/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.errors.txt index 771960ba788..4ea18c15901 100644 --- a/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.errors.txt +++ b/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.errors.txt @@ -1,13 +1,13 @@ -tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(15,21): error TS4043: Return type of public property getter from exported class has or is using private name 'private1'. -tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(20,13): error TS4043: Return type of public property getter from exported class has or is using private name 'private1'. -tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(25,25): error TS4037: Parameter 'foo3' of public property setter from exported class has or is using private name 'private1'. -tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(32,25): error TS4037: Parameter 'foo4' of public property setter from exported class has or is using private name 'private1'. -tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(36,21): error TS4043: Return type of public property getter from exported class has or is using private name 'private1'. -tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(71,23): error TS4043: Return type of public property getter from exported class has or is using private name 'm2'. -tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(76,13): error TS4042: Return type of public property getter from exported class has or is using name 'm2.public2' from private module 'm2'. -tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(81,27): error TS4037: Parameter 'foo113' of public property setter from exported class has or is using private name 'm2'. -tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(88,27): error TS4037: Parameter 'foo114' of public property setter from exported class has or is using private name 'm2'. -tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(92,23): error TS4043: Return type of public property getter from exported class has or is using private name 'm2'. +tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(15,21): error TS4043: Return type of public getter 'foo1' from exported class has or is using private name 'private1'. +tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(20,13): error TS4043: Return type of public getter 'foo2' from exported class has or is using private name 'private1'. +tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(25,25): error TS4037: Parameter type of public setter 'foo3' from exported class has or is using private name 'private1'. +tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(32,25): error TS4037: Parameter type of public setter 'foo4' from exported class has or is using private name 'private1'. +tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(36,21): error TS4043: Return type of public getter 'foo5' from exported class has or is using private name 'private1'. +tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(71,23): error TS4043: Return type of public getter 'foo111' from exported class has or is using private name 'm2'. +tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(76,13): error TS4042: Return type of public getter 'foo112' from exported class has or is using name 'm2.public2' from private module 'm2'. +tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(81,27): error TS4037: Parameter type of public setter 'foo113' from exported class has or is using private name 'm2'. +tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(88,27): error TS4037: Parameter type of public setter 'foo114' from exported class has or is using private name 'm2'. +tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(92,23): error TS4043: Return type of public getter 'foo115' from exported class has or is using private name 'm2'. ==== tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts (10 errors) ==== @@ -22,26 +22,26 @@ tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(92,23): e export class public2 { } } - + export class c { // getter with annotation get foo1(): private1 { ~~~~~~~~ -!!! error TS4043: Return type of public property getter from exported class has or is using private name 'private1'. +!!! error TS4043: Return type of public getter 'foo1' from exported class has or is using private name 'private1'. return; } // getter without annotation get foo2() { ~~~~ -!!! error TS4043: Return type of public property getter from exported class has or is using private name 'private1'. +!!! error TS4043: Return type of public getter 'foo2' from exported class has or is using private name 'private1'. return new private1(); } // setter with annotation set foo3(param: private1) { ~~~~~~~~ -!!! error TS4037: Parameter 'foo3' of public property setter from exported class has or is using private name 'private1'. +!!! error TS4037: Parameter type of public setter 'foo3' from exported class has or is using private name 'private1'. } // Both - getter without annotation, setter with annotation @@ -50,18 +50,18 @@ tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(92,23): e } set foo4(param: private1) { ~~~~~~~~ -!!! error TS4037: Parameter 'foo4' of public property setter from exported class has or is using private name 'private1'. +!!! error TS4037: Parameter type of public setter 'foo4' from exported class has or is using private name 'private1'. } // Both - with annotation get foo5(): private1 { ~~~~~~~~ -!!! error TS4043: Return type of public property getter from exported class has or is using private name 'private1'. +!!! error TS4043: Return type of public getter 'foo5' from exported class has or is using private name 'private1'. return; } set foo5(param: private1) { } - + // getter with annotation get foo11(): public1 { return; @@ -93,21 +93,21 @@ tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(92,23): e // getter with annotation get foo111(): m2.public2 { ~~ -!!! error TS4043: Return type of public property getter from exported class has or is using private name 'm2'. +!!! error TS4043: Return type of public getter 'foo111' from exported class has or is using private name 'm2'. return; } // getter without annotation get foo112() { ~~~~~~ -!!! error TS4042: Return type of public property getter from exported class has or is using name 'm2.public2' from private module 'm2'. +!!! error TS4042: Return type of public getter 'foo112' from exported class has or is using name 'm2.public2' from private module 'm2'. return new m2.public2(); } // setter with annotation set foo113(param: m2.public2) { ~~ -!!! error TS4037: Parameter 'foo113' of public property setter from exported class has or is using private name 'm2'. +!!! error TS4037: Parameter type of public setter 'foo113' from exported class has or is using private name 'm2'. } // Both - getter without annotation, setter with annotation @@ -116,13 +116,13 @@ tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts(92,23): e } set foo114(param: m2.public2) { ~~ -!!! error TS4037: Parameter 'foo114' of public property setter from exported class has or is using private name 'm2'. +!!! error TS4037: Parameter type of public setter 'foo114' from exported class has or is using private name 'm2'. } // Both - with annotation get foo115(): m2.public2 { ~~ -!!! error TS4043: Return type of public property getter from exported class has or is using private name 'm2'. +!!! error TS4043: Return type of public getter 'foo115' from exported class has or is using private name 'm2'. return; } set foo115(param: m2.public2) { diff --git a/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.js b/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.js index 2d4d948668a..c02807207ca 100644 --- a/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.js +++ b/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.js @@ -10,7 +10,7 @@ module m { export class public2 { } } - + export class c { // getter with annotation get foo1(): private1 { @@ -39,7 +39,7 @@ module m { } set foo5(param: private1) { } - + // getter with annotation get foo11(): public1 { return; diff --git a/tests/baselines/reference/privacyAccessorDeclFile.errors.txt b/tests/baselines/reference/privacyAccessorDeclFile.errors.txt index 67a62a2269c..92ce3d5c535 100644 --- a/tests/baselines/reference/privacyAccessorDeclFile.errors.txt +++ b/tests/baselines/reference/privacyAccessorDeclFile.errors.txt @@ -1,39 +1,39 @@ -tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(253,44): error TS4040: Return type of public static property getter from exported class has or is using private name 'privateClass'. -tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(259,31): error TS4043: Return type of public property getter from exported class has or is using private name 'privateClass'. -tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(265,20): error TS4040: Return type of public static property getter from exported class has or is using private name 'privateClass'. -tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(271,13): error TS4043: Return type of public property getter from exported class has or is using private name 'privateClass'. -tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(361,48): error TS4037: Parameter 'myPublicStaticMethod' of public property setter from exported class has or is using private name 'privateClass'. -tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(365,35): error TS4037: Parameter 'myPublicMethod' of public property setter from exported class has or is using private name 'privateClass'. -tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(405,44): error TS4040: Return type of public static property getter from exported class has or is using private name 'privateModule'. -tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(408,31): error TS4043: Return type of public property getter from exported class has or is using private name 'privateModule'. -tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(411,20): error TS4039: Return type of public static property getter from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. -tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(414,13): error TS4042: Return type of public property getter from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. -tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(420,48): error TS4037: Parameter 'myPublicStaticMethod' of public property setter from exported class has or is using private name 'privateModule'. -tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(422,35): error TS4037: Parameter 'myPublicMethod' of public property setter from exported class has or is using private name 'privateModule'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(8,40): error TS4040: Return type of public static property getter from exported class has or is using private name 'privateClass'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(14,27): error TS4043: Return type of public property getter from exported class has or is using private name 'privateClass'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(20,16): error TS4040: Return type of public static property getter from exported class has or is using private name 'privateClass'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(26,9): error TS4043: Return type of public property getter from exported class has or is using private name 'privateClass'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(116,44): error TS4037: Parameter 'myPublicStaticMethod' of public property setter from exported class has or is using private name 'privateClass'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(120,31): error TS4037: Parameter 'myPublicMethod' of public property setter from exported class has or is using private name 'privateClass'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(160,40): error TS4040: Return type of public static property getter from exported class has or is using private name 'privateModule'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(163,27): error TS4043: Return type of public property getter from exported class has or is using private name 'privateModule'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(166,16): error TS4039: Return type of public static property getter from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(169,9): error TS4042: Return type of public property getter from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(175,44): error TS4037: Parameter 'myPublicStaticMethod' of public property setter from exported class has or is using private name 'privateModule'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(177,31): error TS4037: Parameter 'myPublicMethod' of public property setter from exported class has or is using private name 'privateModule'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(210,44): error TS4040: Return type of public static property getter from exported class has or is using private name 'privateClass'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(216,31): error TS4043: Return type of public property getter from exported class has or is using private name 'privateClass'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(222,20): error TS4040: Return type of public static property getter from exported class has or is using private name 'privateClass'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(228,13): error TS4043: Return type of public property getter from exported class has or is using private name 'privateClass'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(318,48): error TS4037: Parameter 'myPublicStaticMethod' of public property setter from exported class has or is using private name 'privateClass'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(322,35): error TS4037: Parameter 'myPublicMethod' of public property setter from exported class has or is using private name 'privateClass'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(362,44): error TS4040: Return type of public static property getter from exported class has or is using private name 'privateModule'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(365,31): error TS4043: Return type of public property getter from exported class has or is using private name 'privateModule'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(368,20): error TS4039: Return type of public static property getter from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(371,13): error TS4042: Return type of public property getter from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(377,48): error TS4037: Parameter 'myPublicStaticMethod' of public property setter from exported class has or is using private name 'privateModule'. -tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS4037: Parameter 'myPublicMethod' of public property setter from exported class has or is using private name 'privateModule'. +tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(253,44): error TS4040: Return type of public static getter 'myPublicStaticMethod' from exported class has or is using private name 'privateClass'. +tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(259,31): error TS4043: Return type of public getter 'myPublicMethod' from exported class has or is using private name 'privateClass'. +tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(265,20): error TS4040: Return type of public static getter 'myPublicStaticMethod1' from exported class has or is using private name 'privateClass'. +tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(271,13): error TS4043: Return type of public getter 'myPublicMethod1' from exported class has or is using private name 'privateClass'. +tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(361,48): error TS4035: Parameter type of public static setter 'myPublicStaticMethod' from exported class has or is using private name 'privateClass'. +tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(365,35): error TS4037: Parameter type of public setter 'myPublicMethod' from exported class has or is using private name 'privateClass'. +tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(405,44): error TS4040: Return type of public static getter 'myPublicStaticMethod' from exported class has or is using private name 'privateModule'. +tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(408,31): error TS4043: Return type of public getter 'myPublicMethod' from exported class has or is using private name 'privateModule'. +tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(411,20): error TS4039: Return type of public static getter 'myPublicStaticMethod1' from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. +tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(414,13): error TS4042: Return type of public getter 'myPublicMethod1' from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. +tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(420,48): error TS4035: Parameter type of public static setter 'myPublicStaticMethod' from exported class has or is using private name 'privateModule'. +tests/cases/compiler/privacyAccessorDeclFile_GlobalFile.ts(422,35): error TS4037: Parameter type of public setter 'myPublicMethod' from exported class has or is using private name 'privateModule'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(8,40): error TS4040: Return type of public static getter 'myPublicStaticMethod' from exported class has or is using private name 'privateClass'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(14,27): error TS4043: Return type of public getter 'myPublicMethod' from exported class has or is using private name 'privateClass'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(20,16): error TS4040: Return type of public static getter 'myPublicStaticMethod1' from exported class has or is using private name 'privateClass'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(26,9): error TS4043: Return type of public getter 'myPublicMethod1' from exported class has or is using private name 'privateClass'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(116,44): error TS4035: Parameter type of public static setter 'myPublicStaticMethod' from exported class has or is using private name 'privateClass'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(120,31): error TS4037: Parameter type of public setter 'myPublicMethod' from exported class has or is using private name 'privateClass'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(160,40): error TS4040: Return type of public static getter 'myPublicStaticMethod' from exported class has or is using private name 'privateModule'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(163,27): error TS4043: Return type of public getter 'myPublicMethod' from exported class has or is using private name 'privateModule'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(166,16): error TS4039: Return type of public static getter 'myPublicStaticMethod1' from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(169,9): error TS4042: Return type of public getter 'myPublicMethod1' from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(175,44): error TS4035: Parameter type of public static setter 'myPublicStaticMethod' from exported class has or is using private name 'privateModule'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(177,31): error TS4037: Parameter type of public setter 'myPublicMethod' from exported class has or is using private name 'privateModule'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(210,44): error TS4040: Return type of public static getter 'myPublicStaticMethod' from exported class has or is using private name 'privateClass'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(216,31): error TS4043: Return type of public getter 'myPublicMethod' from exported class has or is using private name 'privateClass'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(222,20): error TS4040: Return type of public static getter 'myPublicStaticMethod1' from exported class has or is using private name 'privateClass'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(228,13): error TS4043: Return type of public getter 'myPublicMethod1' from exported class has or is using private name 'privateClass'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(318,48): error TS4035: Parameter type of public static setter 'myPublicStaticMethod' from exported class has or is using private name 'privateClass'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(322,35): error TS4037: Parameter type of public setter 'myPublicMethod' from exported class has or is using private name 'privateClass'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(362,44): error TS4040: Return type of public static getter 'myPublicStaticMethod' from exported class has or is using private name 'privateModule'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(365,31): error TS4043: Return type of public getter 'myPublicMethod' from exported class has or is using private name 'privateModule'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(368,20): error TS4039: Return type of public static getter 'myPublicStaticMethod1' from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(371,13): error TS4042: Return type of public getter 'myPublicMethod1' from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(377,48): error TS4035: Parameter type of public static setter 'myPublicStaticMethod' from exported class has or is using private name 'privateModule'. +tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS4037: Parameter type of public setter 'myPublicMethod' from exported class has or is using private name 'privateModule'. ==== tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts (24 errors) ==== @@ -46,7 +46,7 @@ tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS export class publicClassWithWithPrivateGetAccessorTypes { static get myPublicStaticMethod(): privateClass { // Error ~~~~~~~~~~~~ -!!! error TS4040: Return type of public static property getter from exported class has or is using private name 'privateClass'. +!!! error TS4040: Return type of public static getter 'myPublicStaticMethod' from exported class has or is using private name 'privateClass'. return null; } private static get myPrivateStaticMethod(): privateClass { @@ -54,7 +54,7 @@ tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS } get myPublicMethod(): privateClass { // Error ~~~~~~~~~~~~ -!!! error TS4043: Return type of public property getter from exported class has or is using private name 'privateClass'. +!!! error TS4043: Return type of public getter 'myPublicMethod' from exported class has or is using private name 'privateClass'. return null; } private get myPrivateMethod(): privateClass { @@ -62,7 +62,7 @@ tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS } static get myPublicStaticMethod1() { // Error ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS4040: Return type of public static property getter from exported class has or is using private name 'privateClass'. +!!! error TS4040: Return type of public static getter 'myPublicStaticMethod1' from exported class has or is using private name 'privateClass'. return new privateClass(); } private static get myPrivateStaticMethod1() { @@ -70,7 +70,7 @@ tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS } get myPublicMethod1() { // Error ~~~~~~~~~~~~~~~ -!!! error TS4043: Return type of public property getter from exported class has or is using private name 'privateClass'. +!!! error TS4043: Return type of public getter 'myPublicMethod1' from exported class has or is using private name 'privateClass'. return new privateClass(); } private get myPrivateMethod1() { @@ -162,13 +162,13 @@ tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS export class publicClassWithWithPrivateSetAccessorTypes { static set myPublicStaticMethod(param: privateClass) { // Error ~~~~~~~~~~~~ -!!! error TS4037: Parameter 'myPublicStaticMethod' of public property setter from exported class has or is using private name 'privateClass'. +!!! error TS4035: Parameter type of public static setter 'myPublicStaticMethod' from exported class has or is using private name 'privateClass'. } private static set myPrivateStaticMethod(param: privateClass) { } set myPublicMethod(param: privateClass) { // Error ~~~~~~~~~~~~ -!!! error TS4037: Parameter 'myPublicMethod' of public property setter from exported class has or is using private name 'privateClass'. +!!! error TS4037: Parameter type of public setter 'myPublicMethod' from exported class has or is using private name 'privateClass'. } private set myPrivateMethod(param: privateClass) { } @@ -210,22 +210,22 @@ tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS export class publicClassWithPrivateModuleGetAccessorTypes { static get myPublicStaticMethod(): privateModule.publicClass { // Error ~~~~~~~~~~~~~ -!!! error TS4040: Return type of public static property getter from exported class has or is using private name 'privateModule'. +!!! error TS4040: Return type of public static getter 'myPublicStaticMethod' from exported class has or is using private name 'privateModule'. return null; } get myPublicMethod(): privateModule.publicClass { // Error ~~~~~~~~~~~~~ -!!! error TS4043: Return type of public property getter from exported class has or is using private name 'privateModule'. +!!! error TS4043: Return type of public getter 'myPublicMethod' from exported class has or is using private name 'privateModule'. return null; } static get myPublicStaticMethod1() { // Error ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS4039: Return type of public static property getter from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. +!!! error TS4039: Return type of public static getter 'myPublicStaticMethod1' from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. return new privateModule.publicClass(); } get myPublicMethod1() { // Error ~~~~~~~~~~~~~~~ -!!! error TS4042: Return type of public property getter from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. +!!! error TS4042: Return type of public getter 'myPublicMethod1' from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. return new privateModule.publicClass(); } } @@ -233,11 +233,11 @@ tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS export class publicClassWithPrivateModuleSetAccessorTypes { static set myPublicStaticMethod(param: privateModule.publicClass) { // Error ~~~~~~~~~~~~~ -!!! error TS4037: Parameter 'myPublicStaticMethod' of public property setter from exported class has or is using private name 'privateModule'. +!!! error TS4035: Parameter type of public static setter 'myPublicStaticMethod' from exported class has or is using private name 'privateModule'. } set myPublicMethod(param: privateModule.publicClass) { // Error ~~~~~~~~~~~~~ -!!! error TS4037: Parameter 'myPublicMethod' of public property setter from exported class has or is using private name 'privateModule'. +!!! error TS4037: Parameter type of public setter 'myPublicMethod' from exported class has or is using private name 'privateModule'. } } @@ -272,7 +272,7 @@ tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS export class publicClassWithWithPrivateGetAccessorTypes { static get myPublicStaticMethod(): privateClass { // Error ~~~~~~~~~~~~ -!!! error TS4040: Return type of public static property getter from exported class has or is using private name 'privateClass'. +!!! error TS4040: Return type of public static getter 'myPublicStaticMethod' from exported class has or is using private name 'privateClass'. return null; } private static get myPrivateStaticMethod(): privateClass { @@ -280,7 +280,7 @@ tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS } get myPublicMethod(): privateClass { // Error ~~~~~~~~~~~~ -!!! error TS4043: Return type of public property getter from exported class has or is using private name 'privateClass'. +!!! error TS4043: Return type of public getter 'myPublicMethod' from exported class has or is using private name 'privateClass'. return null; } private get myPrivateMethod(): privateClass { @@ -288,7 +288,7 @@ tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS } static get myPublicStaticMethod1() { // Error ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS4040: Return type of public static property getter from exported class has or is using private name 'privateClass'. +!!! error TS4040: Return type of public static getter 'myPublicStaticMethod1' from exported class has or is using private name 'privateClass'. return new privateClass(); } private static get myPrivateStaticMethod1() { @@ -296,7 +296,7 @@ tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS } get myPublicMethod1() { // Error ~~~~~~~~~~~~~~~ -!!! error TS4043: Return type of public property getter from exported class has or is using private name 'privateClass'. +!!! error TS4043: Return type of public getter 'myPublicMethod1' from exported class has or is using private name 'privateClass'. return new privateClass(); } private get myPrivateMethod1() { @@ -388,13 +388,13 @@ tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS export class publicClassWithWithPrivateSetAccessorTypes { static set myPublicStaticMethod(param: privateClass) { // Error ~~~~~~~~~~~~ -!!! error TS4037: Parameter 'myPublicStaticMethod' of public property setter from exported class has or is using private name 'privateClass'. +!!! error TS4035: Parameter type of public static setter 'myPublicStaticMethod' from exported class has or is using private name 'privateClass'. } private static set myPrivateStaticMethod(param: privateClass) { } set myPublicMethod(param: privateClass) { // Error ~~~~~~~~~~~~ -!!! error TS4037: Parameter 'myPublicMethod' of public property setter from exported class has or is using private name 'privateClass'. +!!! error TS4037: Parameter type of public setter 'myPublicMethod' from exported class has or is using private name 'privateClass'. } private set myPrivateMethod(param: privateClass) { } @@ -436,22 +436,22 @@ tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS export class publicClassWithPrivateModuleGetAccessorTypes { static get myPublicStaticMethod(): privateModule.publicClass { // Error ~~~~~~~~~~~~~ -!!! error TS4040: Return type of public static property getter from exported class has or is using private name 'privateModule'. +!!! error TS4040: Return type of public static getter 'myPublicStaticMethod' from exported class has or is using private name 'privateModule'. return null; } get myPublicMethod(): privateModule.publicClass { // Error ~~~~~~~~~~~~~ -!!! error TS4043: Return type of public property getter from exported class has or is using private name 'privateModule'. +!!! error TS4043: Return type of public getter 'myPublicMethod' from exported class has or is using private name 'privateModule'. return null; } static get myPublicStaticMethod1() { // Error ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS4039: Return type of public static property getter from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. +!!! error TS4039: Return type of public static getter 'myPublicStaticMethod1' from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. return new privateModule.publicClass(); } get myPublicMethod1() { // Error ~~~~~~~~~~~~~~~ -!!! error TS4042: Return type of public property getter from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. +!!! error TS4042: Return type of public getter 'myPublicMethod1' from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. return new privateModule.publicClass(); } } @@ -459,11 +459,11 @@ tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS export class publicClassWithPrivateModuleSetAccessorTypes { static set myPublicStaticMethod(param: privateModule.publicClass) { // Error ~~~~~~~~~~~~~ -!!! error TS4037: Parameter 'myPublicStaticMethod' of public property setter from exported class has or is using private name 'privateModule'. +!!! error TS4035: Parameter type of public static setter 'myPublicStaticMethod' from exported class has or is using private name 'privateModule'. } set myPublicMethod(param: privateModule.publicClass) { // Error ~~~~~~~~~~~~~ -!!! error TS4037: Parameter 'myPublicMethod' of public property setter from exported class has or is using private name 'privateModule'. +!!! error TS4037: Parameter type of public setter 'myPublicMethod' from exported class has or is using private name 'privateModule'. } } @@ -948,7 +948,7 @@ tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS export class publicClassWithWithPrivateGetAccessorTypes { static get myPublicStaticMethod(): privateClass { // Error ~~~~~~~~~~~~ -!!! error TS4040: Return type of public static property getter from exported class has or is using private name 'privateClass'. +!!! error TS4040: Return type of public static getter 'myPublicStaticMethod' from exported class has or is using private name 'privateClass'. return null; } private static get myPrivateStaticMethod(): privateClass { @@ -956,7 +956,7 @@ tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS } get myPublicMethod(): privateClass { // Error ~~~~~~~~~~~~ -!!! error TS4043: Return type of public property getter from exported class has or is using private name 'privateClass'. +!!! error TS4043: Return type of public getter 'myPublicMethod' from exported class has or is using private name 'privateClass'. return null; } private get myPrivateMethod(): privateClass { @@ -964,7 +964,7 @@ tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS } static get myPublicStaticMethod1() { // Error ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS4040: Return type of public static property getter from exported class has or is using private name 'privateClass'. +!!! error TS4040: Return type of public static getter 'myPublicStaticMethod1' from exported class has or is using private name 'privateClass'. return new privateClass(); } private static get myPrivateStaticMethod1() { @@ -972,7 +972,7 @@ tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS } get myPublicMethod1() { // Error ~~~~~~~~~~~~~~~ -!!! error TS4043: Return type of public property getter from exported class has or is using private name 'privateClass'. +!!! error TS4043: Return type of public getter 'myPublicMethod1' from exported class has or is using private name 'privateClass'. return new privateClass(); } private get myPrivateMethod1() { @@ -1064,13 +1064,13 @@ tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS export class publicClassWithWithPrivateSetAccessorTypes { static set myPublicStaticMethod(param: privateClass) { // Error ~~~~~~~~~~~~ -!!! error TS4037: Parameter 'myPublicStaticMethod' of public property setter from exported class has or is using private name 'privateClass'. +!!! error TS4035: Parameter type of public static setter 'myPublicStaticMethod' from exported class has or is using private name 'privateClass'. } private static set myPrivateStaticMethod(param: privateClass) { } set myPublicMethod(param: privateClass) { // Error ~~~~~~~~~~~~ -!!! error TS4037: Parameter 'myPublicMethod' of public property setter from exported class has or is using private name 'privateClass'. +!!! error TS4037: Parameter type of public setter 'myPublicMethod' from exported class has or is using private name 'privateClass'. } private set myPrivateMethod(param: privateClass) { } @@ -1112,22 +1112,22 @@ tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS export class publicClassWithPrivateModuleGetAccessorTypes { static get myPublicStaticMethod(): privateModule.publicClass { // Error ~~~~~~~~~~~~~ -!!! error TS4040: Return type of public static property getter from exported class has or is using private name 'privateModule'. +!!! error TS4040: Return type of public static getter 'myPublicStaticMethod' from exported class has or is using private name 'privateModule'. return null; } get myPublicMethod(): privateModule.publicClass { // Error ~~~~~~~~~~~~~ -!!! error TS4043: Return type of public property getter from exported class has or is using private name 'privateModule'. +!!! error TS4043: Return type of public getter 'myPublicMethod' from exported class has or is using private name 'privateModule'. return null; } static get myPublicStaticMethod1() { // Error ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS4039: Return type of public static property getter from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. +!!! error TS4039: Return type of public static getter 'myPublicStaticMethod1' from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. return new privateModule.publicClass(); } get myPublicMethod1() { // Error ~~~~~~~~~~~~~~~ -!!! error TS4042: Return type of public property getter from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. +!!! error TS4042: Return type of public getter 'myPublicMethod1' from exported class has or is using name 'privateModule.publicClass' from private module 'privateModule'. return new privateModule.publicClass(); } } @@ -1135,11 +1135,11 @@ tests/cases/compiler/privacyAccessorDeclFile_externalModule.ts(379,35): error TS export class publicClassWithPrivateModuleSetAccessorTypes { static set myPublicStaticMethod(param: privateModule.publicClass) { // Error ~~~~~~~~~~~~~ -!!! error TS4037: Parameter 'myPublicStaticMethod' of public property setter from exported class has or is using private name 'privateModule'. +!!! error TS4035: Parameter type of public static setter 'myPublicStaticMethod' from exported class has or is using private name 'privateModule'. } set myPublicMethod(param: privateModule.publicClass) { // Error ~~~~~~~~~~~~~ -!!! error TS4037: Parameter 'myPublicMethod' of public property setter from exported class has or is using private name 'privateModule'. +!!! error TS4037: Parameter type of public setter 'myPublicMethod' from exported class has or is using private name 'privateModule'. } } diff --git a/tests/baselines/reference/privacyCannotNameAccessorDeclFile.errors.txt b/tests/baselines/reference/privacyCannotNameAccessorDeclFile.errors.txt index 6c1763f293e..f2419b360d6 100644 --- a/tests/baselines/reference/privacyCannotNameAccessorDeclFile.errors.txt +++ b/tests/baselines/reference/privacyCannotNameAccessorDeclFile.errors.txt @@ -1,11 +1,11 @@ -tests/cases/compiler/privacyCannotNameAccessorDeclFile_consumer.ts(3,16): error TS4038: Return type of public static property getter from exported class has or is using name 'Widget1' from external module "tests/cases/compiler/privacyCannotNameAccessorDeclFile_Widgets" but cannot be named. -tests/cases/compiler/privacyCannotNameAccessorDeclFile_consumer.ts(9,9): error TS4041: Return type of public property getter from exported class has or is using name 'Widget1' from external module "tests/cases/compiler/privacyCannotNameAccessorDeclFile_Widgets" but cannot be named. -tests/cases/compiler/privacyCannotNameAccessorDeclFile_consumer.ts(15,16): error TS4038: Return type of public static property getter from exported class has or is using name 'Widget3' from external module "GlobalWidgets" but cannot be named. -tests/cases/compiler/privacyCannotNameAccessorDeclFile_consumer.ts(21,9): error TS4041: Return type of public property getter from exported class has or is using name 'Widget3' from external module "GlobalWidgets" but cannot be named. -tests/cases/compiler/privacyCannotNameAccessorDeclFile_consumer.ts(57,16): error TS4038: Return type of public static property getter from exported class has or is using name 'SpecializedWidget.Widget2' from external module "tests/cases/compiler/privacyCannotNameAccessorDeclFile_Widgets" but cannot be named. -tests/cases/compiler/privacyCannotNameAccessorDeclFile_consumer.ts(60,9): error TS4041: Return type of public property getter from exported class has or is using name 'SpecializedWidget.Widget2' from external module "tests/cases/compiler/privacyCannotNameAccessorDeclFile_Widgets" but cannot be named. -tests/cases/compiler/privacyCannotNameAccessorDeclFile_consumer.ts(63,16): error TS4038: Return type of public static property getter from exported class has or is using name 'SpecializedGlobalWidget.Widget4' from external module "GlobalWidgets" but cannot be named. -tests/cases/compiler/privacyCannotNameAccessorDeclFile_consumer.ts(66,9): error TS4041: Return type of public property getter from exported class has or is using name 'SpecializedGlobalWidget.Widget4' from external module "GlobalWidgets" but cannot be named. +tests/cases/compiler/privacyCannotNameAccessorDeclFile_consumer.ts(3,16): error TS4038: Return type of public static getter 'myPublicStaticMethod' from exported class has or is using name 'Widget1' from external module "tests/cases/compiler/privacyCannotNameAccessorDeclFile_Widgets" but cannot be named. +tests/cases/compiler/privacyCannotNameAccessorDeclFile_consumer.ts(9,9): error TS4041: Return type of public getter 'myPublicMethod' from exported class has or is using name 'Widget1' from external module "tests/cases/compiler/privacyCannotNameAccessorDeclFile_Widgets" but cannot be named. +tests/cases/compiler/privacyCannotNameAccessorDeclFile_consumer.ts(15,16): error TS4038: Return type of public static getter 'myPublicStaticMethod1' from exported class has or is using name 'Widget3' from external module "GlobalWidgets" but cannot be named. +tests/cases/compiler/privacyCannotNameAccessorDeclFile_consumer.ts(21,9): error TS4041: Return type of public getter 'myPublicMethod1' from exported class has or is using name 'Widget3' from external module "GlobalWidgets" but cannot be named. +tests/cases/compiler/privacyCannotNameAccessorDeclFile_consumer.ts(57,16): error TS4038: Return type of public static getter 'myPublicStaticMethod' from exported class has or is using name 'SpecializedWidget.Widget2' from external module "tests/cases/compiler/privacyCannotNameAccessorDeclFile_Widgets" but cannot be named. +tests/cases/compiler/privacyCannotNameAccessorDeclFile_consumer.ts(60,9): error TS4041: Return type of public getter 'myPublicMethod' from exported class has or is using name 'SpecializedWidget.Widget2' from external module "tests/cases/compiler/privacyCannotNameAccessorDeclFile_Widgets" but cannot be named. +tests/cases/compiler/privacyCannotNameAccessorDeclFile_consumer.ts(63,16): error TS4038: Return type of public static getter 'myPublicStaticMethod1' from exported class has or is using name 'SpecializedGlobalWidget.Widget4' from external module "GlobalWidgets" but cannot be named. +tests/cases/compiler/privacyCannotNameAccessorDeclFile_consumer.ts(66,9): error TS4041: Return type of public getter 'myPublicMethod1' from exported class has or is using name 'SpecializedGlobalWidget.Widget4' from external module "GlobalWidgets" but cannot be named. ==== tests/cases/compiler/privacyCannotNameAccessorDeclFile_consumer.ts (8 errors) ==== @@ -13,7 +13,7 @@ tests/cases/compiler/privacyCannotNameAccessorDeclFile_consumer.ts(66,9): error export class publicClassWithWithPrivateGetAccessorTypes { static get myPublicStaticMethod() { // Error ~~~~~~~~~~~~~~~~~~~~ -!!! error TS4038: Return type of public static property getter from exported class has or is using name 'Widget1' from external module "tests/cases/compiler/privacyCannotNameAccessorDeclFile_Widgets" but cannot be named. +!!! error TS4038: Return type of public static getter 'myPublicStaticMethod' from exported class has or is using name 'Widget1' from external module "tests/cases/compiler/privacyCannotNameAccessorDeclFile_Widgets" but cannot be named. return exporter.createExportedWidget1(); } private static get myPrivateStaticMethod() { @@ -21,7 +21,7 @@ tests/cases/compiler/privacyCannotNameAccessorDeclFile_consumer.ts(66,9): error } get myPublicMethod() { // Error ~~~~~~~~~~~~~~ -!!! error TS4041: Return type of public property getter from exported class has or is using name 'Widget1' from external module "tests/cases/compiler/privacyCannotNameAccessorDeclFile_Widgets" but cannot be named. +!!! error TS4041: Return type of public getter 'myPublicMethod' from exported class has or is using name 'Widget1' from external module "tests/cases/compiler/privacyCannotNameAccessorDeclFile_Widgets" but cannot be named. return exporter.createExportedWidget1(); } private get myPrivateMethod() { @@ -29,7 +29,7 @@ tests/cases/compiler/privacyCannotNameAccessorDeclFile_consumer.ts(66,9): error } static get myPublicStaticMethod1() { // Error ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS4038: Return type of public static property getter from exported class has or is using name 'Widget3' from external module "GlobalWidgets" but cannot be named. +!!! error TS4038: Return type of public static getter 'myPublicStaticMethod1' from exported class has or is using name 'Widget3' from external module "GlobalWidgets" but cannot be named. return exporter.createExportedWidget3(); } private static get myPrivateStaticMethod1() { @@ -37,7 +37,7 @@ tests/cases/compiler/privacyCannotNameAccessorDeclFile_consumer.ts(66,9): error } get myPublicMethod1() { // Error ~~~~~~~~~~~~~~~ -!!! error TS4041: Return type of public property getter from exported class has or is using name 'Widget3' from external module "GlobalWidgets" but cannot be named. +!!! error TS4041: Return type of public getter 'myPublicMethod1' from exported class has or is using name 'Widget3' from external module "GlobalWidgets" but cannot be named. return exporter.createExportedWidget3(); } private get myPrivateMethod1() { @@ -75,22 +75,22 @@ tests/cases/compiler/privacyCannotNameAccessorDeclFile_consumer.ts(66,9): error export class publicClassWithPrivateModuleGetAccessorTypes { static get myPublicStaticMethod() { // Error ~~~~~~~~~~~~~~~~~~~~ -!!! error TS4038: Return type of public static property getter from exported class has or is using name 'SpecializedWidget.Widget2' from external module "tests/cases/compiler/privacyCannotNameAccessorDeclFile_Widgets" but cannot be named. +!!! error TS4038: Return type of public static getter 'myPublicStaticMethod' from exported class has or is using name 'SpecializedWidget.Widget2' from external module "tests/cases/compiler/privacyCannotNameAccessorDeclFile_Widgets" but cannot be named. return exporter.createExportedWidget2(); } get myPublicMethod() { // Error ~~~~~~~~~~~~~~ -!!! error TS4041: Return type of public property getter from exported class has or is using name 'SpecializedWidget.Widget2' from external module "tests/cases/compiler/privacyCannotNameAccessorDeclFile_Widgets" but cannot be named. +!!! error TS4041: Return type of public getter 'myPublicMethod' from exported class has or is using name 'SpecializedWidget.Widget2' from external module "tests/cases/compiler/privacyCannotNameAccessorDeclFile_Widgets" but cannot be named. return exporter.createExportedWidget2(); } static get myPublicStaticMethod1() { // Error ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS4038: Return type of public static property getter from exported class has or is using name 'SpecializedGlobalWidget.Widget4' from external module "GlobalWidgets" but cannot be named. +!!! error TS4038: Return type of public static getter 'myPublicStaticMethod1' from exported class has or is using name 'SpecializedGlobalWidget.Widget4' from external module "GlobalWidgets" but cannot be named. return exporter.createExportedWidget4(); } get myPublicMethod1() { // Error ~~~~~~~~~~~~~~~ -!!! error TS4041: Return type of public property getter from exported class has or is using name 'SpecializedGlobalWidget.Widget4' from external module "GlobalWidgets" but cannot be named. +!!! error TS4041: Return type of public getter 'myPublicMethod1' from exported class has or is using name 'SpecializedGlobalWidget.Widget4' from external module "GlobalWidgets" but cannot be named. return exporter.createExportedWidget4(); } } diff --git a/tests/baselines/reference/symbolDeclarationEmit12.errors.txt b/tests/baselines/reference/symbolDeclarationEmit12.errors.txt index cdc712f698d..3052065ebe6 100644 --- a/tests/baselines/reference/symbolDeclarationEmit12.errors.txt +++ b/tests/baselines/reference/symbolDeclarationEmit12.errors.txt @@ -4,7 +4,7 @@ tests/cases/conformance/es6/Symbols/symbolDeclarationEmit12.ts(5,33): error TS40 tests/cases/conformance/es6/Symbols/symbolDeclarationEmit12.ts(6,40): error TS4055: Return type of public method from exported class has or is using private name 'I'. tests/cases/conformance/es6/Symbols/symbolDeclarationEmit12.ts(9,13): error TS2300: Duplicate identifier '[Symbol.toPrimitive]'. tests/cases/conformance/es6/Symbols/symbolDeclarationEmit12.ts(10,13): error TS2300: Duplicate identifier '[Symbol.toPrimitive]'. -tests/cases/conformance/es6/Symbols/symbolDeclarationEmit12.ts(10,37): error TS4037: Parameter '[Symbol.toPrimitive]' of public property setter from exported class has or is using private name 'I'. +tests/cases/conformance/es6/Symbols/symbolDeclarationEmit12.ts(10,37): error TS4037: Parameter type of public setter '[Symbol.toPrimitive]' from exported class has or is using private name 'I'. ==== tests/cases/conformance/es6/Symbols/symbolDeclarationEmit12.ts (7 errors) ==== @@ -31,6 +31,6 @@ tests/cases/conformance/es6/Symbols/symbolDeclarationEmit12.ts(10,37): error TS4 ~~~~~~~~~~~~~~~~~~~~ !!! error TS2300: Duplicate identifier '[Symbol.toPrimitive]'. ~ -!!! error TS4037: Parameter '[Symbol.toPrimitive]' of public property setter from exported class has or is using private name 'I'. +!!! error TS4037: Parameter type of public setter '[Symbol.toPrimitive]' from exported class has or is using private name 'I'. } } \ No newline at end of file diff --git a/tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts b/tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts index 8dced33083b..6625973717f 100644 --- a/tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts +++ b/tests/cases/compiler/declFileTypeAnnotationVisibilityErrorAccessors.ts @@ -13,7 +13,7 @@ module m { export class public2 { } } - + export class c { // getter with annotation get foo1(): private1 { @@ -42,7 +42,7 @@ module m { } set foo5(param: private1) { } - + // getter with annotation get foo11(): public1 { return; From ca181a7952a5f51d6f1fff2b4ffe5e236bf81cec Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 8 Nov 2017 10:47:34 -0800 Subject: [PATCH 184/235] Accept baselines --- .../declFileTypeAnnotationVisibilityErrorAccessors.symbols | 4 ++-- .../declFileTypeAnnotationVisibilityErrorAccessors.types | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.symbols b/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.symbols index 503fa75ff97..25b8adca4ac 100644 --- a/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.symbols +++ b/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.symbols @@ -17,7 +17,7 @@ module m { >public2 : Symbol(public2, Decl(declFileTypeAnnotationVisibilityErrorAccessors.ts, 7, 15)) } } - + export class c { >c : Symbol(c, Decl(declFileTypeAnnotationVisibilityErrorAccessors.ts, 10, 5)) @@ -69,7 +69,7 @@ module m { >param : Symbol(param, Decl(declFileTypeAnnotationVisibilityErrorAccessors.ts, 38, 17)) >private1 : Symbol(private1, Decl(declFileTypeAnnotationVisibilityErrorAccessors.ts, 0, 10)) } - + // getter with annotation get foo11(): public1 { >foo11 : Symbol(c.foo11, Decl(declFileTypeAnnotationVisibilityErrorAccessors.ts, 39, 9)) diff --git a/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.types b/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.types index c82794f2764..a05a00908d2 100644 --- a/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.types +++ b/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorAccessors.types @@ -17,7 +17,7 @@ module m { >public2 : public2 } } - + export class c { >c : c @@ -71,7 +71,7 @@ module m { >param : private1 >private1 : private1 } - + // getter with annotation get foo11(): public1 { >foo11 : public1 From 2548aced3f0482c579ef8e00f25d8f370974fb3c Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 8 Nov 2017 10:56:30 -0800 Subject: [PATCH 185/235] Add a couple of test cases --- .../reference/controlFlowStringIndex.js | 9 ++++++- .../reference/controlFlowStringIndex.symbols | 24 +++++++++++++++---- .../reference/controlFlowStringIndex.types | 19 ++++++++++++++- .../controlFlow/controlFlowStringIndex.ts | 7 +++++- 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/tests/baselines/reference/controlFlowStringIndex.js b/tests/baselines/reference/controlFlowStringIndex.js index 456ae6afcd4..db4d4a30ab9 100644 --- a/tests/baselines/reference/controlFlowStringIndex.js +++ b/tests/baselines/reference/controlFlowStringIndex.js @@ -1,8 +1,13 @@ //// [controlFlowStringIndex.ts] -type A = { [index: string]: number | null }; +type A = { + other: number | null; + [index: string]: number | null +}; declare const value: A; if (value.foo !== null) { value.foo.toExponential() + value.other // should still be number | null + value.bar // should still be number | null } @@ -10,4 +15,6 @@ if (value.foo !== null) { "use strict"; if (value.foo !== null) { value.foo.toExponential(); + value.other; // should still be number | null + value.bar; // should still be number | null } diff --git a/tests/baselines/reference/controlFlowStringIndex.symbols b/tests/baselines/reference/controlFlowStringIndex.symbols index aad08e48a9b..5c7d626d4a7 100644 --- a/tests/baselines/reference/controlFlowStringIndex.symbols +++ b/tests/baselines/reference/controlFlowStringIndex.symbols @@ -1,18 +1,32 @@ === tests/cases/conformance/controlFlow/controlFlowStringIndex.ts === -type A = { [index: string]: number | null }; +type A = { >A : Symbol(A, Decl(controlFlowStringIndex.ts, 0, 0)) ->index : Symbol(index, Decl(controlFlowStringIndex.ts, 0, 12)) + other: number | null; +>other : Symbol(other, Decl(controlFlowStringIndex.ts, 0, 10)) + + [index: string]: number | null +>index : Symbol(index, Decl(controlFlowStringIndex.ts, 2, 5)) + +}; declare const value: A; ->value : Symbol(value, Decl(controlFlowStringIndex.ts, 1, 13)) +>value : Symbol(value, Decl(controlFlowStringIndex.ts, 4, 13)) >A : Symbol(A, Decl(controlFlowStringIndex.ts, 0, 0)) if (value.foo !== null) { ->value : Symbol(value, Decl(controlFlowStringIndex.ts, 1, 13)) +>value : Symbol(value, Decl(controlFlowStringIndex.ts, 4, 13)) value.foo.toExponential() >value.foo.toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --)) ->value : Symbol(value, Decl(controlFlowStringIndex.ts, 1, 13)) +>value : Symbol(value, Decl(controlFlowStringIndex.ts, 4, 13)) >toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --)) + + value.other // should still be number | null +>value.other : Symbol(other, Decl(controlFlowStringIndex.ts, 0, 10)) +>value : Symbol(value, Decl(controlFlowStringIndex.ts, 4, 13)) +>other : Symbol(other, Decl(controlFlowStringIndex.ts, 0, 10)) + + value.bar // should still be number | null +>value : Symbol(value, Decl(controlFlowStringIndex.ts, 4, 13)) } diff --git a/tests/baselines/reference/controlFlowStringIndex.types b/tests/baselines/reference/controlFlowStringIndex.types index d1722dd6925..8c5f82cbf80 100644 --- a/tests/baselines/reference/controlFlowStringIndex.types +++ b/tests/baselines/reference/controlFlowStringIndex.types @@ -1,9 +1,16 @@ === tests/cases/conformance/controlFlow/controlFlowStringIndex.ts === -type A = { [index: string]: number | null }; +type A = { >A : A + + other: number | null; +>other : number | null +>null : null + + [index: string]: number | null >index : string >null : null +}; declare const value: A; >value : A >A : A @@ -22,5 +29,15 @@ if (value.foo !== null) { >value : A >foo : number >toExponential : (fractionDigits?: number | undefined) => string + + value.other // should still be number | null +>value.other : number | null +>value : A +>other : number | null + + value.bar // should still be number | null +>value.bar : number | null +>value : A +>bar : number | null } diff --git a/tests/cases/conformance/controlFlow/controlFlowStringIndex.ts b/tests/cases/conformance/controlFlow/controlFlowStringIndex.ts index 78acf6d654e..28b75eaba70 100644 --- a/tests/cases/conformance/controlFlow/controlFlowStringIndex.ts +++ b/tests/cases/conformance/controlFlow/controlFlowStringIndex.ts @@ -1,6 +1,11 @@ // @strict: true -type A = { [index: string]: number | null }; +type A = { + other: number | null; + [index: string]: number | null +}; declare const value: A; if (value.foo !== null) { value.foo.toExponential() + value.other // should still be number | null + value.bar // should still be number | null } From 80d1aa0b4f4d19a3d799afb877260902c13ad24e Mon Sep 17 00:00:00 2001 From: Adrian Leonhard Date: Wed, 8 Nov 2017 21:56:39 +0100 Subject: [PATCH 186/235] processDiagnosticMessages.ts: linted, removed unused code (#18697) Added following line to generated output: "// generated from 'src/diagnosticMessages.json' by 'scripts/processDiagnosticMessages.ts'\r\n" + Fixes https://github.com/Microsoft/TypeScript/issues/3591 --- scripts/processDiagnosticMessages.ts | 67 ++++++++++++++-------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/scripts/processDiagnosticMessages.ts b/scripts/processDiagnosticMessages.ts index 20085022c04..dd66564b134 100644 --- a/scripts/processDiagnosticMessages.ts +++ b/scripts/processDiagnosticMessages.ts @@ -1,4 +1,5 @@ /// +/// interface DiagnosticDetails { category: string; @@ -9,57 +10,55 @@ interface DiagnosticDetails { type InputDiagnosticMessageTable = ts.Map; function main(): void { - var sys = ts.sys; + const sys = ts.sys; if (sys.args.length < 1) { - sys.write("Usage:" + sys.newLine) + sys.write("Usage:" + sys.newLine); sys.write("\tnode processDiagnosticMessages.js " + sys.newLine); return; } function writeFile(fileName: string, contents: string) { - // TODO: Fix path joining - var inputDirectory = inputFilePath.substr(0,inputFilePath.lastIndexOf("/")); - var fileOutputPath = inputDirectory + "/" + fileName; + const inputDirectory = ts.getDirectoryPath(inputFilePath); + const fileOutputPath = ts.combinePaths(inputDirectory, fileName); sys.writeFile(fileOutputPath, contents); } - var inputFilePath = sys.args[0].replace(/\\/g, "/"); - var inputStr = sys.readFile(inputFilePath); + const inputFilePath = sys.args[0].replace(/\\/g, "/"); + const inputStr = sys.readFile(inputFilePath); - var diagnosticMessagesJson: { [key: string]: DiagnosticDetails } = JSON.parse(inputStr); - // Check that there are no duplicates. - const seenNames = ts.createMap(); - for (const name of Object.keys(diagnosticMessagesJson)) { - if (seenNames.has(name)) - throw new Error(`Name ${name} appears twice`); - seenNames.set(name, true); - } + const diagnosticMessagesJson: { [key: string]: DiagnosticDetails } = JSON.parse(inputStr); const diagnosticMessages: InputDiagnosticMessageTable = ts.createMapFromTemplate(diagnosticMessagesJson); - var infoFileOutput = buildInfoFileOutput(diagnosticMessages); + const outputFilesDir = ts.getDirectoryPath(inputFilePath); + const thisFilePathRel = ts.getRelativePathToDirectoryOrUrl(outputFilesDir, sys.getExecutingFilePath(), + sys.getCurrentDirectory(), ts.createGetCanonicalFileName(sys.useCaseSensitiveFileNames), /* isAbsolutePathAnUrl */ false); + + const infoFileOutput = buildInfoFileOutput(diagnosticMessages, "./diagnosticInformationMap.generated.ts", thisFilePathRel); checkForUniqueCodes(diagnosticMessages); writeFile("diagnosticInformationMap.generated.ts", infoFileOutput); - var messageOutput = buildDiagnosticMessageOutput(diagnosticMessages); + const messageOutput = buildDiagnosticMessageOutput(diagnosticMessages); writeFile("diagnosticMessages.generated.json", messageOutput); } function checkForUniqueCodes(diagnosticTable: InputDiagnosticMessageTable) { const allCodes: { [key: number]: true | undefined } = []; diagnosticTable.forEach(({ code }) => { - if (allCodes[code]) + if (allCodes[code]) { throw new Error(`Diagnostic code ${code} appears more than once.`); + } allCodes[code] = true; }); } -function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable): string { - var result = - '// \r\n' + - '/// \r\n' + - '/* @internal */\r\n' + - 'namespace ts {\r\n' + +function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable, inputFilePathRel: string, thisFilePathRel: string): string { + let result = + "// \r\n" + + "// generated from '" + inputFilePathRel + "' by '" + thisFilePathRel + "'\r\n" + + "/// \r\n" + + "/* @internal */\r\n" + + "namespace ts {\r\n" + " function diag(code: number, category: DiagnosticCategory, key: string, message: string): DiagnosticMessage {\r\n" + " return { code, category, key, message };\r\n" + " }\r\n" + @@ -70,20 +69,20 @@ function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable): string result += ` ${propName}: diag(${code}, DiagnosticCategory.${category}, "${createKey(propName, code)}", ${JSON.stringify(name)}),\r\n`; }); - result += ' };\r\n}'; + result += " };\r\n}"; return result; } function buildDiagnosticMessageOutput(messageTable: InputDiagnosticMessageTable): string { - let result = '{'; + let result = "{"; messageTable.forEach(({ code }, name) => { const propName = convertPropertyName(name); result += `\r\n "${createKey(propName, code)}" : "${name.replace(/[\"]/g, '\\"')}",`; }); // Shave trailing comma, then add newline and ending brace - result = result.slice(0, result.length - 1) + '\r\n}'; + result = result.slice(0, result.length - 1) + "\r\n}"; // Assert that we generated valid JSON JSON.parse(result); @@ -91,15 +90,15 @@ function buildDiagnosticMessageOutput(messageTable: InputDiagnosticMessageTable) return result; } -function createKey(name: string, code: number) : string { - return name.slice(0, 100) + '_' + code; +function createKey(name: string, code: number): string { + return name.slice(0, 100) + "_" + code; } function convertPropertyName(origName: string): string { - var result = origName.split("").map(char => { - if (char === '*') { return "_Asterisk"; } - if (char === '/') { return "_Slash"; } - if (char === ':') { return "_Colon"; } + let result = origName.split("").map(char => { + if (char === "*") { return "_Asterisk"; } + if (char === "/") { return "_Slash"; } + if (char === ":") { return "_Colon"; } return /\w/.test(char) ? char : "_"; }).join(""); @@ -107,7 +106,7 @@ function convertPropertyName(origName: string): string { result = result.replace(/_+/g, "_"); // remove any leading underscore, unless it is followed by a number. - result = result.replace(/^_([^\d])/, "$1") + result = result.replace(/^_([^\d])/, "$1"); // get rid of all trailing underscores. result = result.replace(/_$/, ""); From 20e36dba53262e8efee437f52c7af673bc0a4e93 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 8 Nov 2017 13:18:23 -0800 Subject: [PATCH 187/235] Remove trailing whitespace from unit tests (#19836) --- src/harness/unittests/textChanges.ts | 8 ++++---- .../baselines/reference/textChanges/extractMethodLike.js | 8 ++++---- .../reference/textChanges/insertNodeInListAfter6.js | 6 +++--- .../reference/textChanges/insertNodeInListAfter7.js | 4 ++-- .../reference/textChanges/insertNodeInListAfter8.js | 6 +++--- .../reference/textChanges/insertNodeInListAfter9.js | 4 ++-- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/harness/unittests/textChanges.ts b/src/harness/unittests/textChanges.ts index c37e50a2565..aa0bbb253fa 100644 --- a/src/harness/unittests/textChanges.ts +++ b/src/harness/unittests/textChanges.ts @@ -122,9 +122,9 @@ namespace ts { { const text = ` -namespace M +namespace M { - namespace M2 + namespace M2 { function foo() { // comment 1 @@ -572,7 +572,7 @@ const x = 1;`; } { const text = ` -const x = 1, +const x = 1, y = 2;`; runSingleFileTest("insertNodeInListAfter6", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1))); @@ -583,7 +583,7 @@ const x = 1, } { const text = ` -const /*x*/ x = 1, +const /*x*/ x = 1, /*y*/ y = 2;`; runSingleFileTest("insertNodeInListAfter8", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1))); diff --git a/tests/baselines/reference/textChanges/extractMethodLike.js b/tests/baselines/reference/textChanges/extractMethodLike.js index fa1d625dc4d..a566f76b8ed 100644 --- a/tests/baselines/reference/textChanges/extractMethodLike.js +++ b/tests/baselines/reference/textChanges/extractMethodLike.js @@ -1,8 +1,8 @@ ===ORIGINAL=== -namespace M +namespace M { - namespace M2 + namespace M2 { function foo() { // comment 1 @@ -22,7 +22,7 @@ namespace M } ===MODIFIED=== -namespace M +namespace M { function bar(): any { @@ -37,7 +37,7 @@ namespace M const y = 2; // comment 3 return 1; } - namespace M2 + namespace M2 { function foo() { // comment 1 diff --git a/tests/baselines/reference/textChanges/insertNodeInListAfter6.js b/tests/baselines/reference/textChanges/insertNodeInListAfter6.js index 06eae7372a9..4cffc3f1244 100644 --- a/tests/baselines/reference/textChanges/insertNodeInListAfter6.js +++ b/tests/baselines/reference/textChanges/insertNodeInListAfter6.js @@ -1,9 +1,9 @@ ===ORIGINAL=== -const x = 1, +const x = 1, y = 2; ===MODIFIED=== -const x = 1, - z = 1, +const x = 1, + z = 1, y = 2; \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeInListAfter7.js b/tests/baselines/reference/textChanges/insertNodeInListAfter7.js index bef01503683..afc1d97e155 100644 --- a/tests/baselines/reference/textChanges/insertNodeInListAfter7.js +++ b/tests/baselines/reference/textChanges/insertNodeInListAfter7.js @@ -1,9 +1,9 @@ ===ORIGINAL=== -const x = 1, +const x = 1, y = 2; ===MODIFIED=== -const x = 1, +const x = 1, y = 2, z = 1; \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeInListAfter8.js b/tests/baselines/reference/textChanges/insertNodeInListAfter8.js index e3c44b14274..fd325a4469a 100644 --- a/tests/baselines/reference/textChanges/insertNodeInListAfter8.js +++ b/tests/baselines/reference/textChanges/insertNodeInListAfter8.js @@ -1,9 +1,9 @@ ===ORIGINAL=== -const /*x*/ x = 1, +const /*x*/ x = 1, /*y*/ y = 2; ===MODIFIED=== -const /*x*/ x = 1, - z = 1, +const /*x*/ x = 1, + z = 1, /*y*/ y = 2; \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeInListAfter9.js b/tests/baselines/reference/textChanges/insertNodeInListAfter9.js index 510984b7574..951fcea64bf 100644 --- a/tests/baselines/reference/textChanges/insertNodeInListAfter9.js +++ b/tests/baselines/reference/textChanges/insertNodeInListAfter9.js @@ -1,9 +1,9 @@ ===ORIGINAL=== -const /*x*/ x = 1, +const /*x*/ x = 1, /*y*/ y = 2; ===MODIFIED=== -const /*x*/ x = 1, +const /*x*/ x = 1, /*y*/ y = 2, z = 1; \ No newline at end of file From d64a8f62f28e0f77fb8b5b681494e76cb35b3373 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 8 Nov 2017 13:28:35 -0800 Subject: [PATCH 188/235] Refactor user+dt runners into externalCompilerRunner --- Jakefile.js | 3 +- .../{dtRunner.ts => externalCompileRunner.ts} | 129 +++++++++--------- src/harness/runner.ts | 3 +- src/harness/tsconfig.json | 3 +- src/harness/userRunner.ts | 51 ------- 5 files changed, 70 insertions(+), 119 deletions(-) rename src/harness/{dtRunner.ts => externalCompileRunner.ts} (76%) delete mode 100644 src/harness/userRunner.ts diff --git a/Jakefile.js b/Jakefile.js index a133d0dba32..147270e0a59 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -105,8 +105,7 @@ var harnessCoreSources = [ "projectsRunner.ts", "loggedIO.ts", "rwcRunner.ts", - "userRunner.ts", - "dtRunner.ts", + "externalCompileRunner.ts", "test262Runner.ts", "./parallel/shared.ts", "./parallel/host.ts", diff --git a/src/harness/dtRunner.ts b/src/harness/externalCompileRunner.ts similarity index 76% rename from src/harness/dtRunner.ts rename to src/harness/externalCompileRunner.ts index 3b739b28f1c..8ca0be807bf 100644 --- a/src/harness/dtRunner.ts +++ b/src/harness/externalCompileRunner.ts @@ -1,62 +1,67 @@ -/// -/// -class DefinitelyTypedRunner extends RunnerBase { - private static readonly testDir = "../DefinitelyTyped/types/"; - - public workingDirectory = DefinitelyTypedRunner.testDir; - - public enumerateTestFiles() { - return Harness.IO.getDirectories(DefinitelyTypedRunner.testDir); - } - - public kind(): TestRunnerKind { - return "dt"; - } - - /** Setup the runner's tests so that they are ready to be executed by the harness - * The first test should be a describe/it block that sets up the harness's compiler instance appropriately - */ - public initializeTests(): void { - // Read in and evaluate the test list - const testList = this.tests && this.tests.length ? this.tests : this.enumerateTestFiles(); - - describe(`${this.kind()} code samples`, () => { - for (const test of testList) { - this.runTest(test); - } - }); - } - - private runTest(directoryName: string) { - describe(directoryName, () => { - const cp = require("child_process"); - const path = require("path"); - const fs = require("fs"); - - it("should build successfully", () => { - const cwd = path.join(__dirname, "../../", DefinitelyTypedRunner.testDir, directoryName); - const timeout = 600000; // 600s = 10 minutes - if (fs.existsSync(path.join(cwd, "package.json"))) { - if (fs.existsSync(path.join(cwd, "package-lock.json"))) { - fs.unlinkSync(path.join(cwd, "package-lock.json")); - } - const stdio = isWorker ? "pipe" : "inherit"; - const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout, shell: true, stdio }); - if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed!`); - } - Harness.Baseline.runBaseline(`${this.kind()}/${directoryName}.log`, () => { - const result = cp.spawnSync(`node`, [path.join(__dirname, "tsc.js")], { cwd, timeout, shell: true }); - // tslint:disable:no-null-keyword - return result.status === 0 ? null : `Exit Code: ${result.status} -Standard output: -${result.stdout.toString().replace(/\r\n/g, "\n")} - - -Standard error: -${result.stderr.toString().replace(/\r\n/g, "\n")}`; - // tslint:enable:no-null-keyword - }); - }); - }); - } -} +/// +/// +abstract class ExternalCompileRunnerBase extends RunnerBase { + abstract testDir: string; + public enumerateTestFiles() { + return Harness.IO.getDirectories(this.testDir); + } + /** Setup the runner's tests so that they are ready to be executed by the harness + * The first test should be a describe/it block that sets up the harness's compiler instance appropriately + */ + public initializeTests(): void { + // Read in and evaluate the test list + const testList = this.tests && this.tests.length ? this.tests : this.enumerateTestFiles(); + + describe(`${this.kind()} code samples`, () => { + for (const test of testList) { + this.runTest(test); + } + }); + } + private runTest(directoryName: string) { + describe(directoryName, () => { + const cp = require("child_process"); + const path = require("path"); + const fs = require("fs"); + + it("should build successfully", () => { + const cwd = path.join(__dirname, "../../", this.testDir, directoryName); + const timeout = 600000; // 600s = 10 minutes + if (fs.existsSync(path.join(cwd, "package.json"))) { + if (fs.existsSync(path.join(cwd, "package-lock.json"))) { + fs.unlinkSync(path.join(cwd, "package-lock.json")); + } + const stdio = isWorker ? "pipe" : "inherit"; + const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout, shell: true, stdio }); + if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed!`); + } + Harness.Baseline.runBaseline(`${this.kind()}/${directoryName}.log`, () => { + const result = cp.spawnSync(`node`, [path.join(__dirname, "tsc.js")], { cwd, timeout, shell: true }); + // tslint:disable-next-line:no-null-keyword + return result.status === 0 ? null : `Exit Code: ${result.status} +Standard output: +${result.stdout.toString().replace(/\r\n/g, "\n")} + + +Standard error: +${result.stderr.toString().replace(/\r\n/g, "\n")}`; + }); + }); + }); + } +} + +class UserCodeRunner extends ExternalCompileRunnerBase { + public readonly testDir = "tests/cases/user/"; + public kind(): TestRunnerKind { + return "user"; + } +} + +class DefinitelyTypedRunner extends ExternalCompileRunnerBase { + public readonly testDir = "../DefinitelyTyped/types/"; + public workingDirectory = this.testDir; + public kind(): TestRunnerKind { + return "dt"; + } +} diff --git a/src/harness/runner.ts b/src/harness/runner.ts index 0a9a7d3428d..a1210591090 100644 --- a/src/harness/runner.ts +++ b/src/harness/runner.ts @@ -18,8 +18,7 @@ /// /// /// -/// -/// +/// /// /// diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json index 96f1999e9e8..1ab2cb955c8 100644 --- a/src/harness/tsconfig.json +++ b/src/harness/tsconfig.json @@ -92,8 +92,7 @@ "projectsRunner.ts", "loggedIO.ts", "rwcRunner.ts", - "userRunner.ts", - "definitelyRunner.ts", + "externalCompileRunner.ts", "test262Runner.ts", "./parallel/shared.ts", "./parallel/host.ts", diff --git a/src/harness/userRunner.ts b/src/harness/userRunner.ts deleted file mode 100644 index 61a46d7e84f..00000000000 --- a/src/harness/userRunner.ts +++ /dev/null @@ -1,51 +0,0 @@ -/// -/// -class UserCodeRunner extends RunnerBase { - private static readonly testDir = "tests/cases/user/"; - public enumerateTestFiles() { - return Harness.IO.getDirectories(UserCodeRunner.testDir); - } - - public kind(): TestRunnerKind { - return "user"; - } - - /** Setup the runner's tests so that they are ready to be executed by the harness - * The first test should be a describe/it block that sets up the harness's compiler instance appropriately - */ - public initializeTests(): void { - // Read in and evaluate the test list - const testList = this.tests && this.tests.length ? this.tests : this.enumerateTestFiles(); - - describe(`${this.kind()} code samples`, () => { - for (const test of testList) { - this.runTest(test); - } - }); - } - - private runTest(directoryName: string) { - describe(directoryName, () => { - const cp = require("child_process"); - const path = require("path"); - - it("should build successfully", () => { - const cwd = path.join(__dirname, "../../", UserCodeRunner.testDir, directoryName); - const timeout = 600000; // 10 minutes - const stdio = isWorker ? "pipe" : "inherit"; - const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout, shell: true, stdio }); - if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed!`); - Harness.Baseline.runBaseline(`${this.kind()}/${directoryName}.log`, () => { - const result = cp.spawnSync(`node`, [path.join(__dirname, "tsc.js")], { cwd, timeout, shell: true }); - return `Exit Code: ${result.status} -Standard output: -${result.stdout.toString().replace(/\r\n/g, "\n")} - - -Standard error: -${result.stderr.toString().replace(/\r\n/g, "\n")}`; - }); - }); - }); - } -} From 397b5497a33ce30be6d86ecd86576287e42073a3 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 8 Nov 2017 13:29:28 -0800 Subject: [PATCH 189/235] Remove positive baselines for user tests --- tests/baselines/reference/user/ajv.log | 6 ------ tests/baselines/reference/user/antd.log | 6 ------ tests/baselines/reference/user/axios.log | 6 ------ tests/baselines/reference/user/bignumber.js.log | 6 ------ tests/baselines/reference/user/discord.js.log | 6 ------ tests/baselines/reference/user/eventemitter2.log | 6 ------ tests/baselines/reference/user/eventemitter3.log | 6 ------ tests/baselines/reference/user/firebase.log | 6 ------ tests/baselines/reference/user/github.log | 6 ------ tests/baselines/reference/user/immutable.log | 6 ------ tests/baselines/reference/user/isobject.log | 6 ------ tests/baselines/reference/user/jimp.log | 6 ------ tests/baselines/reference/user/jsonschema.log | 6 ------ tests/baselines/reference/user/keycode.log | 6 ------ tests/baselines/reference/user/localforage.log | 6 ------ tests/baselines/reference/user/log4js.log | 6 ------ tests/baselines/reference/user/mobx.log | 6 ------ tests/baselines/reference/user/moment.log | 6 ------ tests/baselines/reference/user/mqtt.log | 6 ------ tests/baselines/reference/user/parse5.log | 6 ------ tests/baselines/reference/user/portfinder.log | 6 ------ tests/baselines/reference/user/postcss.log | 6 ------ tests/baselines/reference/user/protobufjs.log | 6 ------ tests/baselines/reference/user/redux.log | 6 ------ tests/baselines/reference/user/reselect.log | 6 ------ tests/baselines/reference/user/should.log | 6 ------ tests/baselines/reference/user/sift.log | 6 ------ tests/baselines/reference/user/soap.log | 6 ------ tests/baselines/reference/user/sugar.log | 6 ------ tests/baselines/reference/user/tslint.log | 6 ------ tests/baselines/reference/user/vue.log | 6 ------ tests/baselines/reference/user/vuex.log | 6 ------ tests/baselines/reference/user/xlsx.log | 6 ------ tests/baselines/reference/user/xpath.log | 6 ------ tests/baselines/reference/user/zone.js.log | 6 ------ 35 files changed, 210 deletions(-) delete mode 100644 tests/baselines/reference/user/ajv.log delete mode 100644 tests/baselines/reference/user/antd.log delete mode 100644 tests/baselines/reference/user/axios.log delete mode 100644 tests/baselines/reference/user/bignumber.js.log delete mode 100644 tests/baselines/reference/user/discord.js.log delete mode 100644 tests/baselines/reference/user/eventemitter2.log delete mode 100644 tests/baselines/reference/user/eventemitter3.log delete mode 100644 tests/baselines/reference/user/firebase.log delete mode 100644 tests/baselines/reference/user/github.log delete mode 100644 tests/baselines/reference/user/immutable.log delete mode 100644 tests/baselines/reference/user/isobject.log delete mode 100644 tests/baselines/reference/user/jimp.log delete mode 100644 tests/baselines/reference/user/jsonschema.log delete mode 100644 tests/baselines/reference/user/keycode.log delete mode 100644 tests/baselines/reference/user/localforage.log delete mode 100644 tests/baselines/reference/user/log4js.log delete mode 100644 tests/baselines/reference/user/mobx.log delete mode 100644 tests/baselines/reference/user/moment.log delete mode 100644 tests/baselines/reference/user/mqtt.log delete mode 100644 tests/baselines/reference/user/parse5.log delete mode 100644 tests/baselines/reference/user/portfinder.log delete mode 100644 tests/baselines/reference/user/postcss.log delete mode 100644 tests/baselines/reference/user/protobufjs.log delete mode 100644 tests/baselines/reference/user/redux.log delete mode 100644 tests/baselines/reference/user/reselect.log delete mode 100644 tests/baselines/reference/user/should.log delete mode 100644 tests/baselines/reference/user/sift.log delete mode 100644 tests/baselines/reference/user/soap.log delete mode 100644 tests/baselines/reference/user/sugar.log delete mode 100644 tests/baselines/reference/user/tslint.log delete mode 100644 tests/baselines/reference/user/vue.log delete mode 100644 tests/baselines/reference/user/vuex.log delete mode 100644 tests/baselines/reference/user/xlsx.log delete mode 100644 tests/baselines/reference/user/xpath.log delete mode 100644 tests/baselines/reference/user/zone.js.log diff --git a/tests/baselines/reference/user/ajv.log b/tests/baselines/reference/user/ajv.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/ajv.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/antd.log b/tests/baselines/reference/user/antd.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/antd.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/axios.log b/tests/baselines/reference/user/axios.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/axios.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/bignumber.js.log b/tests/baselines/reference/user/bignumber.js.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/bignumber.js.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/discord.js.log b/tests/baselines/reference/user/discord.js.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/discord.js.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/eventemitter2.log b/tests/baselines/reference/user/eventemitter2.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/eventemitter2.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/eventemitter3.log b/tests/baselines/reference/user/eventemitter3.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/eventemitter3.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/firebase.log b/tests/baselines/reference/user/firebase.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/firebase.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/github.log b/tests/baselines/reference/user/github.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/github.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/immutable.log b/tests/baselines/reference/user/immutable.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/immutable.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/isobject.log b/tests/baselines/reference/user/isobject.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/isobject.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/jimp.log b/tests/baselines/reference/user/jimp.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/jimp.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/jsonschema.log b/tests/baselines/reference/user/jsonschema.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/jsonschema.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/keycode.log b/tests/baselines/reference/user/keycode.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/keycode.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/localforage.log b/tests/baselines/reference/user/localforage.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/localforage.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/log4js.log b/tests/baselines/reference/user/log4js.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/log4js.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/mobx.log b/tests/baselines/reference/user/mobx.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/mobx.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/moment.log b/tests/baselines/reference/user/moment.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/moment.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/mqtt.log b/tests/baselines/reference/user/mqtt.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/mqtt.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/parse5.log b/tests/baselines/reference/user/parse5.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/parse5.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/portfinder.log b/tests/baselines/reference/user/portfinder.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/portfinder.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/postcss.log b/tests/baselines/reference/user/postcss.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/postcss.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/protobufjs.log b/tests/baselines/reference/user/protobufjs.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/protobufjs.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/redux.log b/tests/baselines/reference/user/redux.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/redux.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/reselect.log b/tests/baselines/reference/user/reselect.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/reselect.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/should.log b/tests/baselines/reference/user/should.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/should.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/sift.log b/tests/baselines/reference/user/sift.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/sift.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/soap.log b/tests/baselines/reference/user/soap.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/soap.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/sugar.log b/tests/baselines/reference/user/sugar.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/sugar.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/tslint.log b/tests/baselines/reference/user/tslint.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/tslint.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/vue.log b/tests/baselines/reference/user/vue.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/vue.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/vuex.log b/tests/baselines/reference/user/vuex.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/vuex.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/xlsx.log b/tests/baselines/reference/user/xlsx.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/xlsx.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/xpath.log b/tests/baselines/reference/user/xpath.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/xpath.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: diff --git a/tests/baselines/reference/user/zone.js.log b/tests/baselines/reference/user/zone.js.log deleted file mode 100644 index 15b10503c1f..00000000000 --- a/tests/baselines/reference/user/zone.js.log +++ /dev/null @@ -1,6 +0,0 @@ -Exit Code: 0 -Standard output: - - - -Standard error: From 5ad7e9516b1e1b3cf644497dfc8f66f6b9bbaed6 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 8 Nov 2017 13:39:03 -0800 Subject: [PATCH 190/235] Remove unnecessary wrapper classes in ts.formatting.Rule (#19744) * Remove unnecessary wrapper classes in ts.formatting.Rule * RulesProvider -> immutable FormatContext * Remove Rules class, just use a list of rules * Remove Shared namespace, replace Shared.TokenRange with TokenRange * Simplify TokenRange * Separate Rule and RuleSpec * Move FormattingRequestKind to formattingContext.ts * Simplify references * Fix lint * Revert removal of trailing newlines --- src/harness/tsconfig.json | 9 - src/harness/unittests/extractTestHelpers.ts | 52 +- src/harness/unittests/textChanges.ts | 56 +- src/services/codefixes/importFixes.ts | 2 +- src/services/completions.ts | 8 +- src/services/formatting/formatting.ts | 75 +- src/services/formatting/formattingContext.ts | 11 +- .../formatting/formattingRequestKind.ts | 13 - src/services/formatting/references.ts | 12 - src/services/formatting/rule.ts | 34 +- src/services/formatting/ruleAction.ts | 11 - src/services/formatting/ruleDescriptor.ts | 30 - src/services/formatting/ruleFlag.ts | 10 - src/services/formatting/ruleOperation.ts | 21 - .../formatting/ruleOperationContext.ts | 32 - src/services/formatting/rules.ts | 1490 +++++++---------- src/services/formatting/rulesMap.ts | 197 +-- src/services/formatting/rulesProvider.ts | 30 - src/services/formatting/smartIndenter.ts | 2 - src/services/formatting/tokenRange.ts | 124 -- .../refactors/convertFunctionToEs6Class.ts | 2 +- src/services/services.ts | 47 +- src/services/textChanges.ts | 16 +- src/services/utilities.ts | 25 +- 24 files changed, 853 insertions(+), 1456 deletions(-) delete mode 100644 src/services/formatting/formattingRequestKind.ts delete mode 100644 src/services/formatting/references.ts delete mode 100644 src/services/formatting/ruleAction.ts delete mode 100644 src/services/formatting/ruleDescriptor.ts delete mode 100644 src/services/formatting/ruleFlag.ts delete mode 100644 src/services/formatting/ruleOperation.ts delete mode 100644 src/services/formatting/ruleOperationContext.ts delete mode 100644 src/services/formatting/rulesProvider.ts delete mode 100644 src/services/formatting/tokenRange.ts diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json index 6e61b7690bc..45430b5c506 100644 --- a/src/harness/tsconfig.json +++ b/src/harness/tsconfig.json @@ -60,20 +60,11 @@ "../services/jsTyping.ts", "../services/formatting/formatting.ts", "../services/formatting/formattingContext.ts", - "../services/formatting/formattingRequestKind.ts", "../services/formatting/formattingScanner.ts", - "../services/formatting/references.ts", "../services/formatting/rule.ts", - "../services/formatting/ruleAction.ts", - "../services/formatting/ruleDescriptor.ts", - "../services/formatting/ruleFlag.ts", - "../services/formatting/ruleOperation.ts", - "../services/formatting/ruleOperationContext.ts", "../services/formatting/rules.ts", "../services/formatting/rulesMap.ts", - "../services/formatting/rulesProvider.ts", "../services/formatting/smartIndenter.ts", - "../services/formatting/tokenRange.ts", "../services/codeFixProvider.ts", "../services/codefixes/fixes.ts", "../services/codefixes/helpers.ts", diff --git a/src/harness/unittests/extractTestHelpers.ts b/src/harness/unittests/extractTestHelpers.ts index ae3f663aa51..a04f443c3c9 100644 --- a/src/harness/unittests/extractTestHelpers.ts +++ b/src/harness/unittests/extractTestHelpers.ts @@ -67,33 +67,27 @@ namespace ts { } export const newLineCharacter = "\n"; - export const getRuleProvider = memoize(getRuleProviderInternal); - function getRuleProviderInternal() { - const options = { - indentSize: 4, - tabSize: 4, - newLineCharacter, - convertTabsToSpaces: true, - indentStyle: ts.IndentStyle.Smart, - insertSpaceAfterConstructor: false, - insertSpaceAfterCommaDelimiter: true, - insertSpaceAfterSemicolonInForStatements: true, - insertSpaceBeforeAndAfterBinaryOperators: true, - insertSpaceAfterKeywordsInControlFlowStatements: true, - insertSpaceAfterFunctionKeywordForAnonymousFunctions: false, - insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, - insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, - insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true, - insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, - insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false, - insertSpaceBeforeFunctionParenthesis: false, - placeOpenBraceOnNewLineForFunctions: false, - placeOpenBraceOnNewLineForControlBlocks: false, - }; - const rulesProvider = new formatting.RulesProvider(); - rulesProvider.ensureUpToDate(options); - return rulesProvider; - } + export const testFormatOptions: ts.FormatCodeSettings = { + indentSize: 4, + tabSize: 4, + newLineCharacter, + convertTabsToSpaces: true, + indentStyle: ts.IndentStyle.Smart, + insertSpaceAfterConstructor: false, + insertSpaceAfterCommaDelimiter: true, + insertSpaceAfterSemicolonInForStatements: true, + insertSpaceBeforeAndAfterBinaryOperators: true, + insertSpaceAfterKeywordsInControlFlowStatements: true, + insertSpaceAfterFunctionKeywordForAnonymousFunctions: false, + insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, + insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, + insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true, + insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, + insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false, + insertSpaceBeforeFunctionParenthesis: false, + placeOpenBraceOnNewLineForFunctions: false, + placeOpenBraceOnNewLineForControlBlocks: false, + }; const notImplementedHost: LanguageServiceHost = { getCompilationSettings: notImplemented, @@ -133,7 +127,7 @@ namespace ts { startPosition: selectionRange.start, endPosition: selectionRange.end, host: notImplementedHost, - rulesProvider: getRuleProvider() + formatContext: formatting.getFormatContext(testFormatOptions), }; const rangeToExtract = refactor.extractSymbol.getRangeToExtract(sourceFile, createTextSpanFromBounds(selectionRange.start, selectionRange.end)); assert.equal(rangeToExtract.errors, undefined, rangeToExtract.errors && "Range error: " + rangeToExtract.errors[0].messageText); @@ -197,7 +191,7 @@ namespace ts { startPosition: selectionRange.start, endPosition: selectionRange.end, host: notImplementedHost, - rulesProvider: getRuleProvider() + formatContext: formatting.getFormatContext(testFormatOptions), }; const rangeToExtract = refactor.extractSymbol.getRangeToExtract(sourceFile, createTextSpanFromBounds(selectionRange.start, selectionRange.end)); assert.isUndefined(rangeToExtract.errors, rangeToExtract.errors && "Range error: " + rangeToExtract.errors[0].messageText); diff --git a/src/harness/unittests/textChanges.ts b/src/harness/unittests/textChanges.ts index aa0bbb253fa..ed571b37399 100644 --- a/src/harness/unittests/textChanges.ts +++ b/src/harness/unittests/textChanges.ts @@ -23,60 +23,8 @@ namespace ts { const printerOptions = { newLine: NewLineKind.LineFeed }; const newLineCharacter = getNewLineCharacter(printerOptions); - const getRuleProviderDefault = memoize(() => { - const options = { - indentSize: 4, - tabSize: 4, - newLineCharacter, - convertTabsToSpaces: true, - indentStyle: ts.IndentStyle.Smart, - insertSpaceAfterConstructor: false, - insertSpaceAfterCommaDelimiter: true, - insertSpaceAfterSemicolonInForStatements: true, - insertSpaceBeforeAndAfterBinaryOperators: true, - insertSpaceAfterKeywordsInControlFlowStatements: true, - insertSpaceAfterFunctionKeywordForAnonymousFunctions: false, - insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, - insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, - insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true, - insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, - insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false, - insertSpaceBeforeFunctionParenthesis: false, - placeOpenBraceOnNewLineForFunctions: false, - placeOpenBraceOnNewLineForControlBlocks: false, - }; - const rulesProvider = new formatting.RulesProvider(); - rulesProvider.ensureUpToDate(options); - return rulesProvider; - }); - const getRuleProviderNewlineBrace = memoize(() => { - const options = { - indentSize: 4, - tabSize: 4, - newLineCharacter, - convertTabsToSpaces: true, - indentStyle: ts.IndentStyle.Smart, - insertSpaceAfterConstructor: false, - insertSpaceAfterCommaDelimiter: true, - insertSpaceAfterSemicolonInForStatements: true, - insertSpaceBeforeAndAfterBinaryOperators: true, - insertSpaceAfterKeywordsInControlFlowStatements: true, - insertSpaceAfterFunctionKeywordForAnonymousFunctions: false, - insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, - insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, - insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true, - insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, - insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false, - insertSpaceBeforeFunctionParenthesis: false, - placeOpenBraceOnNewLineForFunctions: true, - placeOpenBraceOnNewLineForControlBlocks: false, - }; - const rulesProvider = new formatting.RulesProvider(); - rulesProvider.ensureUpToDate(options); - return rulesProvider; - }); - function getRuleProvider(placeOpenBraceOnNewLineForFunctions: boolean) { - return placeOpenBraceOnNewLineForFunctions ? getRuleProviderNewlineBrace() : getRuleProviderDefault(); + function getRuleProvider(placeOpenBraceOnNewLineForFunctions: boolean): formatting.FormatContext { + return formatting.getFormatContext(placeOpenBraceOnNewLineForFunctions ? { ...testFormatOptions, placeOpenBraceOnNewLineForFunctions: true } : testFormatOptions); } // validate that positions that were recovered from the printed text actually match positions that will be created if the same text is parsed. diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index e0e57801cf8..a0c7ffd75ea 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -166,7 +166,7 @@ namespace ts.codefix { return { host: context.host, newLineCharacter: context.newLineCharacter, - rulesProvider: context.rulesProvider, + formatContext: context.formatContext, sourceFile: context.sourceFile, checker, compilerOptions: context.program.getCompilerOptions(), diff --git a/src/services/completions.ts b/src/services/completions.ts index 3c233f4dbe8..f66242ca864 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -415,7 +415,7 @@ namespace ts.Completions { entryId: CompletionEntryIdentifier, allSourceFiles: ReadonlyArray, host: LanguageServiceHost, - rulesProvider: formatting.RulesProvider, + formatContext: formatting.FormatContext, ): CompletionEntryDetails { const { name, source } = entryId; // Compute all the completion symbols again. @@ -436,7 +436,7 @@ namespace ts.Completions { } case "symbol": { const { symbol, location, symbolToOriginInfoMap } = symbolCompletion; - const codeActions = getCompletionEntryCodeActions(symbolToOriginInfoMap, symbol, typeChecker, host, compilerOptions, sourceFile, rulesProvider); + const codeActions = getCompletionEntryCodeActions(symbolToOriginInfoMap, symbol, typeChecker, host, compilerOptions, sourceFile, formatContext); const kindModifiers = SymbolDisplay.getSymbolModifiers(symbol); const { displayParts, documentation, symbolKind, tags } = SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, location, location, SemanticMeaning.All); return { name, kindModifiers, kind: symbolKind, displayParts, documentation, tags, codeActions, source: source === undefined ? undefined : [textPart(source)] }; @@ -467,7 +467,7 @@ namespace ts.Completions { host: LanguageServiceHost, compilerOptions: CompilerOptions, sourceFile: SourceFile, - rulesProvider: formatting.RulesProvider, + formatContext: formatting.FormatContext, ): CodeAction[] | undefined { const symbolOriginInfo = symbolToOriginInfoMap[getSymbolId(symbol)]; if (!symbolOriginInfo) { @@ -481,7 +481,7 @@ namespace ts.Completions { newLineCharacter: host.getNewLine(), compilerOptions, sourceFile, - rulesProvider, + formatContext, symbolName: symbol.name, getCanonicalFileName: createGetCanonicalFileName(host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : false), symbolToken: undefined, diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 529fdae0545..b8122827491 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -1,10 +1,14 @@ -/// -/// -/// -/// +/// +/// +/// +/// /* @internal */ namespace ts.formatting { + export interface FormatContext { + readonly options: ts.FormatCodeSettings; + readonly getRule: ts.formatting.RulesMap; + } export interface TextRangeWithKind extends TextRange { kind: SyntaxKind; @@ -67,7 +71,7 @@ namespace ts.formatting { delta: number; } - export function formatOnEnter(position: number, sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeSettings): TextChange[] { + export function formatOnEnter(position: number, sourceFile: SourceFile, formatContext: FormatContext): TextChange[] { const line = sourceFile.getLineAndCharacterOfPosition(position).line; if (line === 0) { return []; @@ -93,15 +97,15 @@ namespace ts.formatting { // end value is exclusive so add 1 to the result end: endOfFormatSpan + 1 }; - return formatSpan(span, sourceFile, options, rulesProvider, FormattingRequestKind.FormatOnEnter); + return formatSpan(span, sourceFile, formatContext, FormattingRequestKind.FormatOnEnter); } - export function formatOnSemicolon(position: number, sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeSettings): TextChange[] { + export function formatOnSemicolon(position: number, sourceFile: SourceFile, formatContext: FormatContext): TextChange[] { const semicolon = findImmediatelyPrecedingTokenOfKind(position, SyntaxKind.SemicolonToken, sourceFile); - return formatNodeLines(findOutermostNodeWithinListLevel(semicolon), sourceFile, options, rulesProvider, FormattingRequestKind.FormatOnSemicolon); + return formatNodeLines(findOutermostNodeWithinListLevel(semicolon), sourceFile, formatContext, FormattingRequestKind.FormatOnSemicolon); } - export function formatOnOpeningCurly(position: number, sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeSettings): TextChange[] { + export function formatOnOpeningCurly(position: number, sourceFile: SourceFile, formatContext: FormatContext): TextChange[] { const openingCurly = findImmediatelyPrecedingTokenOfKind(position, SyntaxKind.OpenBraceToken, sourceFile); if (!openingCurly) { return []; @@ -126,29 +130,29 @@ namespace ts.formatting { end: position }; - return formatSpan(textRange, sourceFile, options, rulesProvider, FormattingRequestKind.FormatOnOpeningCurlyBrace); + return formatSpan(textRange, sourceFile, formatContext, FormattingRequestKind.FormatOnOpeningCurlyBrace); } - export function formatOnClosingCurly(position: number, sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeSettings): TextChange[] { + export function formatOnClosingCurly(position: number, sourceFile: SourceFile, formatContext: FormatContext): TextChange[] { const precedingToken = findImmediatelyPrecedingTokenOfKind(position, SyntaxKind.CloseBraceToken, sourceFile); - return formatNodeLines(findOutermostNodeWithinListLevel(precedingToken), sourceFile, options, rulesProvider, FormattingRequestKind.FormatOnClosingCurlyBrace); + return formatNodeLines(findOutermostNodeWithinListLevel(precedingToken), sourceFile, formatContext, FormattingRequestKind.FormatOnClosingCurlyBrace); } - export function formatDocument(sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeSettings): TextChange[] { + export function formatDocument(sourceFile: SourceFile, formatContext: FormatContext): TextChange[] { const span = { pos: 0, end: sourceFile.text.length }; - return formatSpan(span, sourceFile, options, rulesProvider, FormattingRequestKind.FormatDocument); + return formatSpan(span, sourceFile, formatContext, FormattingRequestKind.FormatDocument); } - export function formatSelection(start: number, end: number, sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeSettings): TextChange[] { + export function formatSelection(start: number, end: number, sourceFile: SourceFile, formatContext: FormatContext): TextChange[] { // format from the beginning of the line const span = { pos: getLineStartPositionForPosition(start, sourceFile), end, }; - return formatSpan(span, sourceFile, options, rulesProvider, FormattingRequestKind.FormatSelection); + return formatSpan(span, sourceFile, formatContext, FormattingRequestKind.FormatSelection); } /** @@ -337,7 +341,7 @@ namespace ts.formatting { } /* @internal */ - export function formatNodeGivenIndentation(node: Node, sourceFileLike: SourceFileLike, languageVariant: LanguageVariant, initialIndentation: number, delta: number, rulesProvider: RulesProvider): TextChange[] { + export function formatNodeGivenIndentation(node: Node, sourceFileLike: SourceFileLike, languageVariant: LanguageVariant, initialIndentation: number, delta: number, formatContext: FormatContext): TextChange[] { const range = { pos: 0, end: sourceFileLike.text.length }; return getFormattingScanner(sourceFileLike.text, languageVariant, range.pos, range.end, scanner => formatSpanWorker( range, @@ -345,14 +349,13 @@ namespace ts.formatting { initialIndentation, delta, scanner, - rulesProvider.getFormatOptions(), - rulesProvider, + formatContext, FormattingRequestKind.FormatSelection, _ => false, // assume that node does not have any errors sourceFileLike)); } - function formatNodeLines(node: Node, sourceFile: SourceFile, options: FormatCodeSettings, rulesProvider: RulesProvider, requestKind: FormattingRequestKind): TextChange[] { + function formatNodeLines(node: Node, sourceFile: SourceFile, formatContext: FormatContext, requestKind: FormattingRequestKind): TextChange[] { if (!node) { return []; } @@ -362,24 +365,19 @@ namespace ts.formatting { end: node.end }; - return formatSpan(span, sourceFile, options, rulesProvider, requestKind); + return formatSpan(span, sourceFile, formatContext, requestKind); } - function formatSpan(originalRange: TextRange, - sourceFile: SourceFile, - options: FormatCodeSettings, - rulesProvider: RulesProvider, - requestKind: FormattingRequestKind): TextChange[] { + function formatSpan(originalRange: TextRange, sourceFile: SourceFile, formatContext: FormatContext, requestKind: FormattingRequestKind): TextChange[] { // find the smallest node that fully wraps the range and compute the initial indentation for the node const enclosingNode = findEnclosingNode(originalRange, sourceFile); return getFormattingScanner(sourceFile.text, sourceFile.languageVariant, getScanStartPosition(enclosingNode, originalRange, sourceFile), originalRange.end, scanner => formatSpanWorker( originalRange, enclosingNode, - SmartIndenter.getIndentationForNode(enclosingNode, originalRange, sourceFile, options), - getOwnOrInheritedDelta(enclosingNode, options, sourceFile), + SmartIndenter.getIndentationForNode(enclosingNode, originalRange, sourceFile, formatContext.options), + getOwnOrInheritedDelta(enclosingNode, formatContext.options, sourceFile), scanner, - options, - rulesProvider, + formatContext, requestKind, prepareRangeContainsErrorFunction(sourceFile.parseDiagnostics, originalRange), sourceFile)); @@ -390,8 +388,7 @@ namespace ts.formatting { initialIndentation: number, delta: number, formattingScanner: FormattingScanner, - options: FormatCodeSettings, - rulesProvider: RulesProvider, + { options, getRule }: FormatContext, requestKind: FormattingRequestKind, rangeContainsError: (r: TextRange) => boolean, sourceFile: SourceFileLike): TextChange[] { @@ -917,14 +914,14 @@ namespace ts.formatting { formattingContext.updateContext(previousItem, previousParent, currentItem, currentParent, contextNode); - const rule = rulesProvider.getRulesMap().GetRule(formattingContext); + const rule = getRule(formattingContext); let trimTrailingWhitespaces: boolean; let lineAdded: boolean; if (rule) { applyRuleEdits(rule, previousItem, previousStartLine, currentItem, currentStartLine); - if (rule.operation.action & (RuleAction.Space | RuleAction.Delete) && currentStartLine !== previousStartLine) { + if (rule.action & (RuleAction.Space | RuleAction.Delete) && currentStartLine !== previousStartLine) { lineAdded = false; // Handle the case where the next line is moved to be the end of this line. // In this case we don't indent the next line in the next pass. @@ -932,7 +929,7 @@ namespace ts.formatting { dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ false); } } - else if (rule.operation.action & RuleAction.NewLine && currentStartLine === previousStartLine) { + else if (rule.action & RuleAction.NewLine && currentStartLine === previousStartLine) { lineAdded = true; // Handle the case where token2 is moved to the new line. // In this case we indent token2 in the next pass but we set @@ -943,7 +940,7 @@ namespace ts.formatting { } // We need to trim trailing whitespace between the tokens if they were on different lines, and no rule was applied to put them on the same line - trimTrailingWhitespaces = !(rule.operation.action & RuleAction.Delete) && rule.flag !== RuleFlags.CanDeleteNewLines; + trimTrailingWhitespaces = !(rule.action & RuleAction.Delete) && rule.flags !== RuleFlags.CanDeleteNewLines; } else { trimTrailingWhitespaces = true; @@ -1118,7 +1115,7 @@ namespace ts.formatting { currentRange: TextRangeWithKind, currentStartLine: number): void { - switch (rule.operation.action) { + switch (rule.action) { case RuleAction.Ignore: // no action required return; @@ -1132,7 +1129,7 @@ namespace ts.formatting { // exit early if we on different lines and rule cannot change number of newlines // if line1 and line2 are on subsequent lines then no edits are required - ok to exit // if line1 and line2 are separated with more than one newline - ok to exit since we cannot delete extra new lines - if (rule.flag !== RuleFlags.CanDeleteNewLines && previousStartLine !== currentStartLine) { + if (rule.flags !== RuleFlags.CanDeleteNewLines && previousStartLine !== currentStartLine) { return; } @@ -1144,7 +1141,7 @@ namespace ts.formatting { break; case RuleAction.Space: // exit early if we on different lines and rule cannot change number of newlines - if (rule.flag !== RuleFlags.CanDeleteNewLines && previousStartLine !== currentStartLine) { + if (rule.flags !== RuleFlags.CanDeleteNewLines && previousStartLine !== currentStartLine) { return; } diff --git a/src/services/formatting/formattingContext.ts b/src/services/formatting/formattingContext.ts index 043df72f434..2ba987e4af3 100644 --- a/src/services/formatting/formattingContext.ts +++ b/src/services/formatting/formattingContext.ts @@ -1,7 +1,14 @@ -/// - /* @internal */ namespace ts.formatting { + export const enum FormattingRequestKind { + FormatDocument, + FormatSelection, + FormatOnEnter, + FormatOnSemicolon, + FormatOnOpeningCurlyBrace, + FormatOnClosingCurlyBrace + } + export class FormattingContext { public currentTokenSpan: TextRangeWithKind; public nextTokenSpan: TextRangeWithKind; diff --git a/src/services/formatting/formattingRequestKind.ts b/src/services/formatting/formattingRequestKind.ts deleted file mode 100644 index 6c671e1b888..00000000000 --- a/src/services/formatting/formattingRequestKind.ts +++ /dev/null @@ -1,13 +0,0 @@ -/// - -/* @internal */ -namespace ts.formatting { - export const enum FormattingRequestKind { - FormatDocument, - FormatSelection, - FormatOnEnter, - FormatOnSemicolon, - FormatOnOpeningCurlyBrace, - FormatOnClosingCurlyBrace - } -} \ No newline at end of file diff --git a/src/services/formatting/references.ts b/src/services/formatting/references.ts deleted file mode 100644 index 318f10c664e..00000000000 --- a/src/services/formatting/references.ts +++ /dev/null @@ -1,12 +0,0 @@ -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// \ No newline at end of file diff --git a/src/services/formatting/rule.ts b/src/services/formatting/rule.ts index 8fd432586b4..aa1bb6b43e9 100644 --- a/src/services/formatting/rule.ts +++ b/src/services/formatting/rule.ts @@ -1,14 +1,30 @@ -/// - /* @internal */ namespace ts.formatting { - export class Rule { + export interface Rule { // Used for debugging to identify each rule based on the property name it's assigned to. - public debugName?: string; - constructor( - readonly descriptor: RuleDescriptor, - readonly operation: RuleOperation, - readonly flag: RuleFlags = RuleFlags.None) { - } + readonly debugName: string; + readonly context: ReadonlyArray; + readonly action: RuleAction; + readonly flags: RuleFlags; + } + + export type ContextPredicate = (context: FormattingContext) => boolean; + export const anyContext: ReadonlyArray = emptyArray; + + export const enum RuleAction { + Ignore = 1 << 0, + Space = 1 << 1, + NewLine = 1 << 2, + Delete = 1 << 3, + } + + export const enum RuleFlags { + None, + CanDeleteNewLines, + } + + export interface TokenRange { + readonly tokens: ReadonlyArray; + readonly isSpecific: boolean; } } \ No newline at end of file diff --git a/src/services/formatting/ruleAction.ts b/src/services/formatting/ruleAction.ts deleted file mode 100644 index 13e9043e1c6..00000000000 --- a/src/services/formatting/ruleAction.ts +++ /dev/null @@ -1,11 +0,0 @@ -/// - -/* @internal */ -namespace ts.formatting { - export const enum RuleAction { - Ignore = 0x00000001, - Space = 0x00000002, - NewLine = 0x00000004, - Delete = 0x00000008 - } -} \ No newline at end of file diff --git a/src/services/formatting/ruleDescriptor.ts b/src/services/formatting/ruleDescriptor.ts deleted file mode 100644 index b8529496956..00000000000 --- a/src/services/formatting/ruleDescriptor.ts +++ /dev/null @@ -1,30 +0,0 @@ -/// - -/* @internal */ -namespace ts.formatting { - export class RuleDescriptor { - constructor(public leftTokenRange: Shared.TokenRange, public rightTokenRange: Shared.TokenRange) { - } - - public toString(): string { - return "[leftRange=" + this.leftTokenRange + "," + - "rightRange=" + this.rightTokenRange + "]"; - } - - static create1(left: SyntaxKind, right: SyntaxKind): RuleDescriptor { - return RuleDescriptor.create4(Shared.TokenRange.FromToken(left), Shared.TokenRange.FromToken(right)); - } - - static create2(left: Shared.TokenRange, right: SyntaxKind): RuleDescriptor { - return RuleDescriptor.create4(left, Shared.TokenRange.FromToken(right)); - } - - static create3(left: SyntaxKind, right: Shared.TokenRange): RuleDescriptor { - return RuleDescriptor.create4(Shared.TokenRange.FromToken(left), right); - } - - static create4(left: Shared.TokenRange, right: Shared.TokenRange): RuleDescriptor { - return new RuleDescriptor(left, right); - } - } -} \ No newline at end of file diff --git a/src/services/formatting/ruleFlag.ts b/src/services/formatting/ruleFlag.ts deleted file mode 100644 index 7619f232ad4..00000000000 --- a/src/services/formatting/ruleFlag.ts +++ /dev/null @@ -1,10 +0,0 @@ -/// - - -/* @internal */ -namespace ts.formatting { - export const enum RuleFlags { - None, - CanDeleteNewLines - } -} \ No newline at end of file diff --git a/src/services/formatting/ruleOperation.ts b/src/services/formatting/ruleOperation.ts deleted file mode 100644 index 462c27352d8..00000000000 --- a/src/services/formatting/ruleOperation.ts +++ /dev/null @@ -1,21 +0,0 @@ -/// - -/* @internal */ -namespace ts.formatting { - export class RuleOperation { - constructor(readonly context: RuleOperationContext, readonly action: RuleAction) {} - - public toString(): string { - return "[context=" + this.context + "," + - "action=" + this.action + "]"; - } - - static create1(action: RuleAction) { - return RuleOperation.create2(RuleOperationContext.any, action); - } - - static create2(context: RuleOperationContext, action: RuleAction) { - return new RuleOperation(context, action); - } - } -} \ No newline at end of file diff --git a/src/services/formatting/ruleOperationContext.ts b/src/services/formatting/ruleOperationContext.ts deleted file mode 100644 index c433d106372..00000000000 --- a/src/services/formatting/ruleOperationContext.ts +++ /dev/null @@ -1,32 +0,0 @@ -/// - -/* @internal */ -namespace ts.formatting { - - export class RuleOperationContext { - private readonly customContextChecks: ((context: FormattingContext) => boolean)[]; - - constructor(...funcs: ((context: FormattingContext) => boolean)[]) { - this.customContextChecks = funcs; - } - - static readonly any: RuleOperationContext = new RuleOperationContext(); - - public IsAny(): boolean { - return this === RuleOperationContext.any; - } - - public InContext(context: FormattingContext): boolean { - if (this.IsAny()) { - return true; - } - - for (const check of this.customContextChecks) { - if (!check(context)) { - return false; - } - } - return true; - } - } -} \ No newline at end of file diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index c5b59e818eb..8214ffd6f2d 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -1,929 +1,723 @@ -/// - /* @internal */ namespace ts.formatting { - // tslint:disable variable-name (TODO) - export class Rules { - public IgnoreBeforeComment: Rule; - public IgnoreAfterLineComment: Rule; + export interface RuleSpec { + readonly leftTokenRange: TokenRange; + readonly rightTokenRange: TokenRange; + readonly rule: Rule; + } - // Space after keyword but not before ; or : or ? - public NoSpaceBeforeSemicolon: Rule; - public NoSpaceBeforeColon: Rule; - public NoSpaceBeforeQuestionMark: Rule; - public SpaceAfterColon: Rule; - // insert space after '?' only when it is used in conditional operator - public SpaceAfterQuestionMarkInConditionalOperator: Rule; - // in other cases there should be no space between '?' and next token - public NoSpaceAfterQuestionMark: Rule; + export function getAllRules(): RuleSpec[] { + const allTokens: SyntaxKind[] = []; + for (let token = SyntaxKind.FirstToken; token <= SyntaxKind.LastToken; token++) { + allTokens.push(token); + } + function anyTokenExcept(token: SyntaxKind): TokenRange { + return { tokens: allTokens.filter(t => t !== token), isSpecific: false }; + } - public SpaceAfterSemicolon: Rule; + const anyToken: TokenRange = { tokens: allTokens, isSpecific: false }; + const anyTokenIncludingMultilineComments = tokenRangeFrom([...allTokens, SyntaxKind.MultiLineCommentTrivia]); + const keywords = tokenRangeFromRange(SyntaxKind.FirstKeyword, SyntaxKind.LastKeyword); + const binaryOperators = tokenRangeFromRange(SyntaxKind.FirstBinaryOperator, SyntaxKind.LastBinaryOperator); + const binaryKeywordOperators = [SyntaxKind.InKeyword, SyntaxKind.InstanceOfKeyword, SyntaxKind.OfKeyword, SyntaxKind.AsKeyword, SyntaxKind.IsKeyword]; + const unaryPrefixOperators = [SyntaxKind.PlusPlusToken, SyntaxKind.MinusMinusToken, SyntaxKind.TildeToken, SyntaxKind.ExclamationToken]; + const unaryPrefixExpressions = [ + SyntaxKind.NumericLiteral, SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.OpenBracketToken, + SyntaxKind.OpenBraceToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]; + const unaryPreincrementExpressions = [SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]; + const unaryPostincrementExpressions = [SyntaxKind.Identifier, SyntaxKind.CloseParenToken, SyntaxKind.CloseBracketToken, SyntaxKind.NewKeyword]; + const unaryPredecrementExpressions = [SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]; + const unaryPostdecrementExpressions = [SyntaxKind.Identifier, SyntaxKind.CloseParenToken, SyntaxKind.CloseBracketToken, SyntaxKind.NewKeyword]; + const comments = [SyntaxKind.SingleLineCommentTrivia, SyntaxKind.MultiLineCommentTrivia]; + const typeNames = [SyntaxKind.Identifier, ...typeKeywords]; - // Space/new line after }. - public SpaceAfterCloseBrace: Rule; - - // Special case for (}, else) and (}, while) since else & while tokens are not part of the tree which makes SpaceAfterCloseBrace rule not applied - // Also should not apply to }) - public SpaceBetweenCloseBraceAndElse: Rule; - public SpaceBetweenCloseBraceAndWhile: Rule; - public NoSpaceAfterCloseBrace: Rule; - - // No space for dot - public NoSpaceBeforeDot: Rule; - public NoSpaceAfterDot: Rule; - - // No space before and after indexer - public NoSpaceBeforeOpenBracket: Rule; - public NoSpaceAfterCloseBracket: Rule; - - // Insert a space after { and before } in single-line contexts, but remove space from empty object literals {}. - public SpaceAfterOpenBrace: Rule; - public SpaceBeforeCloseBrace: Rule; - public NoSpaceAfterOpenBrace: Rule; - public NoSpaceBeforeCloseBrace: Rule; - public NoSpaceBetweenEmptyBraceBrackets: Rule; - - // Insert new line after { and before } in multi-line contexts. - public NewLineAfterOpenBraceInBlockContext: Rule; - - // For functions and control block place } on a new line [multi-line rule] - public NewLineBeforeCloseBraceInBlockContext: Rule; - - // Special handling of unary operators. - // Prefix operators generally shouldn't have a space between - // them and their target unary expression. - public NoSpaceAfterUnaryPrefixOperator: Rule; - public NoSpaceAfterUnaryPreincrementOperator: Rule; - public NoSpaceAfterUnaryPredecrementOperator: Rule; - public NoSpaceBeforeUnaryPostincrementOperator: Rule; - public NoSpaceBeforeUnaryPostdecrementOperator: Rule; - - // More unary operator special-casing. - // DevDiv 181814: Be careful when removing leading whitespace - // around unary operators. Examples: - // 1 - -2 --X--> 1--2 - // a + ++b --X--> a+++b - public SpaceAfterPostincrementWhenFollowedByAdd: Rule; - public SpaceAfterAddWhenFollowedByUnaryPlus: Rule; - public SpaceAfterAddWhenFollowedByPreincrement: Rule; - public SpaceAfterPostdecrementWhenFollowedBySubtract: Rule; - public SpaceAfterSubtractWhenFollowedByUnaryMinus: Rule; - public SpaceAfterSubtractWhenFollowedByPredecrement: Rule; - - public NoSpaceBeforeComma: Rule; - - public SpaceAfterCertainKeywords: Rule; - public NoSpaceAfterNewKeywordOnConstructorSignature: Rule; - public SpaceAfterLetConstInVariableDeclaration: Rule; - public NoSpaceBeforeOpenParenInFuncCall: Rule; - public SpaceAfterFunctionInFuncDecl: Rule; - public SpaceBeforeOpenParenInFuncDecl: Rule; - public NoSpaceBeforeOpenParenInFuncDecl: Rule; - public SpaceAfterVoidOperator: Rule; - - public NoSpaceBetweenReturnAndSemicolon: Rule; - - // Add a space between statements. All keywords except (do,else,case) has open/close parens after them. - // So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any] - public SpaceBetweenStatements: Rule; - - // This low-pri rule takes care of "try {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter. - public SpaceAfterTryFinally: Rule; - - // For get/set members, we check for (identifier,identifier) since get/set don't have tokens and they are represented as just an identifier token. - // Though, we do extra check on the context to make sure we are dealing with get/set node. Example: - // get x() {} - // set x(val) {} - public SpaceAfterGetSetInMember: Rule; - - // Special case for binary operators (that are keywords). For these we have to add a space and shouldn't follow any user options. - public SpaceBeforeBinaryKeywordOperator: Rule; - public SpaceAfterBinaryKeywordOperator: Rule; - - // TypeScript-specific rules - - // Treat constructor as an identifier in a function declaration, and remove spaces between constructor and following left parentheses - public SpaceAfterConstructor: Rule; - public NoSpaceAfterConstructor: Rule; - - // Use of module as a function call. e.g.: import m2 = module("m2"); - public NoSpaceAfterModuleImport: Rule; - - // Add a space around certain TypeScript keywords - public SpaceAfterCertainTypeScriptKeywords: Rule; - public SpaceBeforeCertainTypeScriptKeywords: Rule; - - // Treat string literals in module names as identifiers, and add a space between the literal and the opening Brace braces, e.g.: module "m2" { - public SpaceAfterModuleName: Rule; - - // Lambda expressions - public SpaceBeforeArrow: Rule; - public SpaceAfterArrow: Rule; - - // Optional parameters and let args - public NoSpaceAfterEllipsis: Rule; - public NoSpaceAfterOptionalParameters: Rule; - - // generics - public NoSpaceBeforeOpenAngularBracket: Rule; - public NoSpaceBetweenCloseParenAndAngularBracket: Rule; - public NoSpaceAfterOpenAngularBracket: Rule; - public NoSpaceBeforeCloseAngularBracket: Rule; - public NoSpaceAfterCloseAngularBracket: Rule; - - // Remove spaces in empty interface literals. e.g.: x: {} - public NoSpaceBetweenEmptyInterfaceBraceBrackets: Rule; - - // These rules are higher in priority than user-configurable rules. - public HighPriorityCommonRules: Rule[]; - - // These rules are applied after high priority rules. - public UserConfigurableRules: Rule[]; - - // These rules are lower in priority than user-configurable rules. - public LowPriorityCommonRules: Rule[]; - - /// - /// Rules controlled by user options - /// - - // Insert space after comma delimiter - public SpaceAfterComma: Rule; - public NoSpaceAfterComma: Rule; - - // Insert space before and after binary operators - public SpaceBeforeBinaryOperator: Rule; - public SpaceAfterBinaryOperator: Rule; - public NoSpaceBeforeBinaryOperator: Rule; - public NoSpaceAfterBinaryOperator: Rule; - - // Insert space after keywords in control flow statements - public SpaceAfterKeywordInControl: Rule; - public NoSpaceAfterKeywordInControl: Rule; - - // Open Brace braces after function + // Place a space before open brace in a function declaration // TypeScript: Function can have return types, which can be made of tons of different token kinds - public FunctionOpenBraceLeftTokenRange: Shared.TokenRange; - public SpaceBeforeOpenBraceInFunction: Rule; - public NewLineBeforeOpenBraceInFunction: Rule; + const functionOpenBraceLeftTokenRange = anyTokenIncludingMultilineComments; - // Open Brace braces after TypeScript module/class/interface - public TypeScriptOpenBraceLeftTokenRange: Shared.TokenRange; - public SpaceBeforeOpenBraceInTypeScriptDeclWithBlock: Rule; - public NewLineBeforeOpenBraceInTypeScriptDeclWithBlock: Rule; + // Place a space before open brace in a TypeScript declaration that has braces as children (class, module, enum, etc) + const typeScriptOpenBraceLeftTokenRange = tokenRangeFrom([SyntaxKind.Identifier, SyntaxKind.MultiLineCommentTrivia, SyntaxKind.ClassKeyword, SyntaxKind.ExportKeyword, SyntaxKind.ImportKeyword]); - // Open Brace braces after control block - public ControlOpenBraceLeftTokenRange: Shared.TokenRange; - public SpaceBeforeOpenBraceInControl: Rule; - public NewLineBeforeOpenBraceInControl: Rule; - - // Insert space after semicolon in for statement - public SpaceAfterSemicolonInFor: Rule; - public NoSpaceAfterSemicolonInFor: Rule; - - // Insert space after opening and before closing nonempty parenthesis - public SpaceAfterOpenParen: Rule; - public SpaceBeforeCloseParen: Rule; - public SpaceBetweenOpenParens: Rule; - public NoSpaceBetweenParens: Rule; - public NoSpaceAfterOpenParen: Rule; - public NoSpaceBeforeCloseParen: Rule; - - // Insert space after opening and before closing nonempty brackets - public SpaceAfterOpenBracket: Rule; - public SpaceBeforeCloseBracket: Rule; - public NoSpaceBetweenBrackets: Rule; - public NoSpaceAfterOpenBracket: Rule; - public NoSpaceBeforeCloseBracket: Rule; - - // Insert space after function keyword for anonymous functions - public SpaceAfterAnonymousFunctionKeyword: Rule; - public NoSpaceAfterAnonymousFunctionKeyword: Rule; - - // Insert space after @ in decorator - public SpaceBeforeAt: Rule; - public NoSpaceAfterAt: Rule; - public SpaceAfterDecorator: Rule; - - // Generator: function* - public NoSpaceBetweenFunctionKeywordAndStar: Rule; - public SpaceAfterStarInGeneratorDeclaration: Rule; - public NoSpaceBetweenYieldKeywordAndStar: Rule; - public SpaceBetweenYieldOrYieldStarAndOperand: Rule; - - // Async functions - public SpaceBetweenAsyncAndOpenParen: Rule; - public SpaceBetweenAsyncAndFunctionKeyword: Rule; - - // Template strings - public NoSpaceBetweenTagAndTemplateString: Rule; - public NoSpaceAfterTemplateHeadAndMiddle: Rule; - public SpaceAfterTemplateHeadAndMiddle: Rule; - public NoSpaceBeforeTemplateMiddleAndTail: Rule; - public SpaceBeforeTemplateMiddleAndTail: Rule; - - // No space after { and before } in JSX expression - public NoSpaceAfterOpenBraceInJsxExpression: Rule; - public SpaceAfterOpenBraceInJsxExpression: Rule; - public NoSpaceBeforeCloseBraceInJsxExpression: Rule; - public SpaceBeforeCloseBraceInJsxExpression: Rule; - - // JSX opening elements - public SpaceBeforeJsxAttribute: Rule; - public SpaceBeforeSlashInJsxOpeningElement: Rule; - public NoSpaceBeforeGreaterThanTokenInJsxOpeningElement: Rule; - public NoSpaceBeforeEqualInJsxAttribute: Rule; - public NoSpaceAfterEqualInJsxAttribute: Rule; - - // No space after type assertions - public NoSpaceAfterTypeAssertion: Rule; - public SpaceAfterTypeAssertion: Rule; - - // No space before non-null assertion operator - public NoSpaceBeforeNonNullAssertionOperator: Rule; - - constructor() { - /// - /// Common Rules - /// + // Place a space before open brace in a control flow construct + const controlOpenBraceLeftTokenRange = tokenRangeFrom([SyntaxKind.CloseParenToken, SyntaxKind.MultiLineCommentTrivia, SyntaxKind.DoKeyword, SyntaxKind.TryKeyword, SyntaxKind.FinallyKeyword, SyntaxKind.ElseKeyword]); + // These rules are higher in priority than user-configurable + const highPriorityCommonRules = [ // Leave comments alone - this.IgnoreBeforeComment = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.Comments), RuleOperation.create1(RuleAction.Ignore)); - this.IgnoreAfterLineComment = new Rule(RuleDescriptor.create3(SyntaxKind.SingleLineCommentTrivia, Shared.TokenRange.Any), RuleOperation.create1(RuleAction.Ignore)); + rule("IgnoreBeforeComment", anyToken, comments, anyContext, RuleAction.Ignore), + rule("IgnoreAfterLineComment", SyntaxKind.SingleLineCommentTrivia, anyToken, anyContext, RuleAction.Ignore), - // Space after keyword but not before ; or : or ? - this.NoSpaceBeforeSemicolon = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.SemicolonToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - this.NoSpaceBeforeColon = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.ColonToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBinaryOpContext), RuleAction.Delete)); - this.NoSpaceBeforeQuestionMark = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.QuestionToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBinaryOpContext), RuleAction.Delete)); - this.SpaceAfterColon = new Rule(RuleDescriptor.create3(SyntaxKind.ColonToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBinaryOpContext), RuleAction.Space)); - this.SpaceAfterQuestionMarkInConditionalOperator = new Rule(RuleDescriptor.create3(SyntaxKind.QuestionToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsConditionalOperatorContext), RuleAction.Space)); - this.NoSpaceAfterQuestionMark = new Rule(RuleDescriptor.create3(SyntaxKind.QuestionToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - this.SpaceAfterSemicolon = new Rule(RuleDescriptor.create3(SyntaxKind.SemicolonToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); + rule("NoSpaceBeforeColon", anyToken, SyntaxKind.ColonToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], RuleAction.Delete), + rule("SpaceAfterColon", SyntaxKind.ColonToken, anyToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], RuleAction.Space), + rule("NoSpaceBeforeQuestionMark", anyToken, SyntaxKind.QuestionToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], RuleAction.Delete), + // insert space after '?' only when it is used in conditional operator + rule("SpaceAfterQuestionMarkInConditionalOperator", SyntaxKind.QuestionToken, anyToken, [isNonJsxSameLineTokenContext, isConditionalOperatorContext], RuleAction.Space), - // Space after }. - this.SpaceAfterCloseBrace = new Rule(RuleDescriptor.create3(SyntaxKind.CloseBraceToken, Shared.TokenRange.FromRange(SyntaxKind.FirstToken, SyntaxKind.LastToken, [SyntaxKind.CloseParenToken])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsAfterCodeBlockContext), RuleAction.Space)); + // in other cases there should be no space between '?' and next token + rule("NoSpaceAfterQuestionMark", SyntaxKind.QuestionToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), - // Special case for (}, else) and (}, while) since else & while tokens are not part of the tree which makes SpaceAfterCloseBrace rule not applied - this.SpaceBetweenCloseBraceAndElse = new Rule(RuleDescriptor.create1(SyntaxKind.CloseBraceToken, SyntaxKind.ElseKeyword), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); - this.SpaceBetweenCloseBraceAndWhile = new Rule(RuleDescriptor.create1(SyntaxKind.CloseBraceToken, SyntaxKind.WhileKeyword), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); - this.NoSpaceAfterCloseBrace = new Rule(RuleDescriptor.create3(SyntaxKind.CloseBraceToken, Shared.TokenRange.FromTokens([SyntaxKind.CloseBracketToken, SyntaxKind.CommaToken, SyntaxKind.SemicolonToken])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - - // No space for dot - this.NoSpaceBeforeDot = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.DotToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - this.NoSpaceAfterDot = new Rule(RuleDescriptor.create3(SyntaxKind.DotToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - - // No space before and after indexer - this.NoSpaceBeforeOpenBracket = new Rule( - RuleDescriptor.create2(Shared.TokenRange.AnyExcept(SyntaxKind.AsyncKeyword), SyntaxKind.OpenBracketToken), - RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - this.NoSpaceAfterCloseBracket = new Rule(RuleDescriptor.create3(SyntaxKind.CloseBracketToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBeforeBlockInFunctionDeclarationContext), RuleAction.Delete)); - - // Place a space before open brace in a function declaration - this.FunctionOpenBraceLeftTokenRange = Shared.TokenRange.AnyIncludingMultilineComments; - this.SpaceBeforeOpenBraceInFunction = new Rule(RuleDescriptor.create2(this.FunctionOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForFunctions"), Rules.IsFunctionDeclContext, Rules.IsBeforeBlockContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeBlockContext), RuleAction.Space), RuleFlags.CanDeleteNewLines); - - // Place a space before open brace in a TypeScript declaration that has braces as children (class, module, enum, etc) - this.TypeScriptOpenBraceLeftTokenRange = Shared.TokenRange.FromTokens([SyntaxKind.Identifier, SyntaxKind.MultiLineCommentTrivia, SyntaxKind.ClassKeyword, SyntaxKind.ExportKeyword, SyntaxKind.ImportKeyword]); - this.SpaceBeforeOpenBraceInTypeScriptDeclWithBlock = new Rule(RuleDescriptor.create2(this.TypeScriptOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForFunctions"), Rules.IsTypeScriptDeclWithBlockContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeBlockContext), RuleAction.Space), RuleFlags.CanDeleteNewLines); - - // Place a space before open brace in a control flow construct - this.ControlOpenBraceLeftTokenRange = Shared.TokenRange.FromTokens([SyntaxKind.CloseParenToken, SyntaxKind.MultiLineCommentTrivia, SyntaxKind.DoKeyword, SyntaxKind.TryKeyword, SyntaxKind.FinallyKeyword, SyntaxKind.ElseKeyword]); - this.SpaceBeforeOpenBraceInControl = new Rule(RuleDescriptor.create2(this.ControlOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForControlBlocks"), Rules.IsControlDeclContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeBlockContext), RuleAction.Space), RuleFlags.CanDeleteNewLines); - - // Insert a space after { and before } in single-line contexts, but remove space from empty object literals {}. - this.SpaceAfterOpenBrace = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), Rules.IsBraceWrappedContext), RuleAction.Space)); - this.SpaceBeforeCloseBrace = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), Rules.IsBraceWrappedContext), RuleAction.Space)); - this.NoSpaceAfterOpenBrace = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - this.NoSpaceBeforeCloseBrace = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - this.NoSpaceBetweenEmptyBraceBrackets = new Rule(RuleDescriptor.create1(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsObjectContext), RuleAction.Delete)); - - // Insert new line after { and before } in multi-line contexts. - this.NewLineAfterOpenBraceInBlockContext = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsMultilineBlockContext), RuleAction.NewLine)); - - // For functions and control block place } on a new line [multi-line rule] - this.NewLineBeforeCloseBraceInBlockContext = new Rule(RuleDescriptor.create2(Shared.TokenRange.AnyIncludingMultilineComments, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsMultilineBlockContext), RuleAction.NewLine)); + rule("NoSpaceBeforeDot", anyToken, SyntaxKind.DotToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), + rule("NoSpaceAfterDot", SyntaxKind.DotToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), // Special handling of unary operators. // Prefix operators generally shouldn't have a space between // them and their target unary expression. - this.NoSpaceAfterUnaryPrefixOperator = new Rule(RuleDescriptor.create4(Shared.TokenRange.UnaryPrefixOperators, Shared.TokenRange.UnaryPrefixExpressions), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBinaryOpContext), RuleAction.Delete)); - this.NoSpaceAfterUnaryPreincrementOperator = new Rule(RuleDescriptor.create3(SyntaxKind.PlusPlusToken, Shared.TokenRange.UnaryPreincrementExpressions), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - this.NoSpaceAfterUnaryPredecrementOperator = new Rule(RuleDescriptor.create3(SyntaxKind.MinusMinusToken, Shared.TokenRange.UnaryPredecrementExpressions), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - this.NoSpaceBeforeUnaryPostincrementOperator = new Rule(RuleDescriptor.create2(Shared.TokenRange.UnaryPostincrementExpressions, SyntaxKind.PlusPlusToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - this.NoSpaceBeforeUnaryPostdecrementOperator = new Rule(RuleDescriptor.create2(Shared.TokenRange.UnaryPostdecrementExpressions, SyntaxKind.MinusMinusToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); + rule("NoSpaceAfterUnaryPrefixOperator", unaryPrefixOperators, unaryPrefixExpressions, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], RuleAction.Delete), + rule("NoSpaceAfterUnaryPreincrementOperator", SyntaxKind.PlusPlusToken, unaryPreincrementExpressions, [isNonJsxSameLineTokenContext], RuleAction.Delete), + rule("NoSpaceAfterUnaryPredecrementOperator", SyntaxKind.MinusMinusToken, unaryPredecrementExpressions, [isNonJsxSameLineTokenContext], RuleAction.Delete), + rule("NoSpaceBeforeUnaryPostincrementOperator", unaryPostincrementExpressions, SyntaxKind.PlusPlusToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), + rule("NoSpaceBeforeUnaryPostdecrementOperator", unaryPostdecrementExpressions, SyntaxKind.MinusMinusToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), // More unary operator special-casing. // DevDiv 181814: Be careful when removing leading whitespace // around unary operators. Examples: // 1 - -2 --X--> 1--2 // a + ++b --X--> a+++b - this.SpaceAfterPostincrementWhenFollowedByAdd = new Rule(RuleDescriptor.create1(SyntaxKind.PlusPlusToken, SyntaxKind.PlusToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space)); - this.SpaceAfterAddWhenFollowedByUnaryPlus = new Rule(RuleDescriptor.create1(SyntaxKind.PlusToken, SyntaxKind.PlusToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space)); - this.SpaceAfterAddWhenFollowedByPreincrement = new Rule(RuleDescriptor.create1(SyntaxKind.PlusToken, SyntaxKind.PlusPlusToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space)); - this.SpaceAfterPostdecrementWhenFollowedBySubtract = new Rule(RuleDescriptor.create1(SyntaxKind.MinusMinusToken, SyntaxKind.MinusToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space)); - this.SpaceAfterSubtractWhenFollowedByUnaryMinus = new Rule(RuleDescriptor.create1(SyntaxKind.MinusToken, SyntaxKind.MinusToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space)); - this.SpaceAfterSubtractWhenFollowedByPredecrement = new Rule(RuleDescriptor.create1(SyntaxKind.MinusToken, SyntaxKind.MinusMinusToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space)); + rule("SpaceAfterPostincrementWhenFollowedByAdd", SyntaxKind.PlusPlusToken, SyntaxKind.PlusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space), + rule("SpaceAfterAddWhenFollowedByUnaryPlus", SyntaxKind.PlusToken, SyntaxKind.PlusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space), + rule("SpaceAfterAddWhenFollowedByPreincrement", SyntaxKind.PlusToken, SyntaxKind.PlusPlusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space), + rule("SpaceAfterPostdecrementWhenFollowedBySubtract", SyntaxKind.MinusMinusToken, SyntaxKind.MinusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space), + rule("SpaceAfterSubtractWhenFollowedByUnaryMinus", SyntaxKind.MinusToken, SyntaxKind.MinusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space), + rule("SpaceAfterSubtractWhenFollowedByPredecrement", SyntaxKind.MinusToken, SyntaxKind.MinusMinusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space), - this.NoSpaceBeforeComma = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CommaToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); + rule("NoSpaceAfterCloseBrace", SyntaxKind.CloseBraceToken, [SyntaxKind.CloseBracketToken, SyntaxKind.CommaToken, SyntaxKind.SemicolonToken], [isNonJsxSameLineTokenContext], RuleAction.Delete), + // For functions and control block place } on a new line [multi-line rule] + rule("NewLineBeforeCloseBraceInBlockContext", anyTokenIncludingMultilineComments, SyntaxKind.CloseBraceToken, [isMultilineBlockContext], RuleAction.NewLine), - this.SpaceAfterCertainKeywords = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.VarKeyword, SyntaxKind.ThrowKeyword, SyntaxKind.NewKeyword, SyntaxKind.DeleteKeyword, SyntaxKind.ReturnKeyword, SyntaxKind.TypeOfKeyword, SyntaxKind.AwaitKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); - this.NoSpaceAfterNewKeywordOnConstructorSignature = new Rule(RuleDescriptor.create1(SyntaxKind.NewKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsConstructorSignatureContext), RuleAction.Delete)); - this.SpaceAfterLetConstInVariableDeclaration = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.LetKeyword, SyntaxKind.ConstKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsStartOfVariableDeclarationList), RuleAction.Space)); - this.NoSpaceBeforeOpenParenInFuncCall = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionCallOrNewContext, Rules.IsPreviousTokenNotComma), RuleAction.Delete)); - this.SpaceAfterFunctionInFuncDecl = new Rule(RuleDescriptor.create3(SyntaxKind.FunctionKeyword, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclContext), RuleAction.Space)); - this.SpaceBeforeOpenParenInFuncDecl = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceBeforeFunctionParenthesis"), Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionDeclContext), RuleAction.Space)); - this.NoSpaceBeforeOpenParenInFuncDecl = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceBeforeFunctionParenthesis"), Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionDeclContext), RuleAction.Delete)); - this.SpaceAfterVoidOperator = new Rule(RuleDescriptor.create3(SyntaxKind.VoidKeyword, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsVoidOpContext), RuleAction.Space)); + // Space/new line after }. + rule("SpaceAfterCloseBrace", SyntaxKind.CloseBraceToken, anyTokenExcept(SyntaxKind.CloseParenToken), [isNonJsxSameLineTokenContext, isAfterCodeBlockContext], RuleAction.Space), + // Special case for (}, else) and (}, while) since else & while tokens are not part of the tree which makes SpaceAfterCloseBrace rule not applied + // Also should not apply to }) + rule("SpaceBetweenCloseBraceAndElse", SyntaxKind.CloseBraceToken, SyntaxKind.ElseKeyword, [isNonJsxSameLineTokenContext], RuleAction.Space), + rule("SpaceBetweenCloseBraceAndWhile", SyntaxKind.CloseBraceToken, SyntaxKind.WhileKeyword, [isNonJsxSameLineTokenContext], RuleAction.Space), + rule("NoSpaceBetweenEmptyBraceBrackets", SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, [isNonJsxSameLineTokenContext, isObjectContext], RuleAction.Delete), - this.NoSpaceBetweenReturnAndSemicolon = new Rule(RuleDescriptor.create1(SyntaxKind.ReturnKeyword, SyntaxKind.SemicolonToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); + rule("NoSpaceBetweenFunctionKeywordAndStar", SyntaxKind.FunctionKeyword, SyntaxKind.AsteriskToken, [isFunctionDeclarationOrFunctionExpressionContext], RuleAction.Delete), + rule("SpaceAfterStarInGeneratorDeclaration", SyntaxKind.AsteriskToken, [SyntaxKind.Identifier, SyntaxKind.OpenParenToken], [isFunctionDeclarationOrFunctionExpressionContext], RuleAction.Space), - // Add a space between statements. All keywords except (do,else,case) has open/close parens after them. - // So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any] - this.SpaceBetweenStatements = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.CloseParenToken, SyntaxKind.DoKeyword, SyntaxKind.ElseKeyword, SyntaxKind.CaseKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNonJsxElementContext, Rules.IsNotForContext), RuleAction.Space)); - - // This low-pri rule takes care of "try {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter. - this.SpaceAfterTryFinally = new Rule(RuleDescriptor.create2(Shared.TokenRange.FromTokens([SyntaxKind.TryKeyword, SyntaxKind.FinallyKeyword]), SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); + rule("SpaceAfterFunctionInFuncDecl", SyntaxKind.FunctionKeyword, anyToken, [isFunctionDeclContext], RuleAction.Space), + // Insert new line after { and before } in multi-line contexts. + rule("NewLineAfterOpenBraceInBlockContext", SyntaxKind.OpenBraceToken, anyToken, [isMultilineBlockContext], RuleAction.NewLine), + // For get/set members, we check for (identifier,identifier) since get/set don't have tokens and they are represented as just an identifier token. + // Though, we do extra check on the context to make sure we are dealing with get/set node. Example: // get x() {} // set x(val) {} - this.SpaceAfterGetSetInMember = new Rule(RuleDescriptor.create2(Shared.TokenRange.FromTokens([SyntaxKind.GetKeyword, SyntaxKind.SetKeyword]), SyntaxKind.Identifier), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclContext), RuleAction.Space)); + rule("SpaceAfterGetSetInMember", [SyntaxKind.GetKeyword, SyntaxKind.SetKeyword], SyntaxKind.Identifier, [isFunctionDeclContext], RuleAction.Space), + + rule("NoSpaceBetweenYieldKeywordAndStar", SyntaxKind.YieldKeyword, SyntaxKind.AsteriskToken, [isNonJsxSameLineTokenContext, isYieldOrYieldStarWithOperand], RuleAction.Delete), + rule("SpaceBetweenYieldOrYieldStarAndOperand", [SyntaxKind.YieldKeyword, SyntaxKind.AsteriskToken], anyToken, [isNonJsxSameLineTokenContext, isYieldOrYieldStarWithOperand], RuleAction.Space), + + rule("NoSpaceBetweenReturnAndSemicolon", SyntaxKind.ReturnKeyword, SyntaxKind.SemicolonToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), + rule("SpaceAfterCertainKeywords", [SyntaxKind.VarKeyword, SyntaxKind.ThrowKeyword, SyntaxKind.NewKeyword, SyntaxKind.DeleteKeyword, SyntaxKind.ReturnKeyword, SyntaxKind.TypeOfKeyword, SyntaxKind.AwaitKeyword], anyToken, [isNonJsxSameLineTokenContext], RuleAction.Space), + rule("SpaceAfterLetConstInVariableDeclaration", [SyntaxKind.LetKeyword, SyntaxKind.ConstKeyword], anyToken, [isNonJsxSameLineTokenContext, isStartOfVariableDeclarationList], RuleAction.Space), + rule("NoSpaceBeforeOpenParenInFuncCall", anyToken, SyntaxKind.OpenParenToken, [isNonJsxSameLineTokenContext, isFunctionCallOrNewContext, isPreviousTokenNotComma], RuleAction.Delete), // Special case for binary operators (that are keywords). For these we have to add a space and shouldn't follow any user options. - this.SpaceBeforeBinaryKeywordOperator = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.BinaryKeywordOperators), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space)); - this.SpaceAfterBinaryKeywordOperator = new Rule(RuleDescriptor.create4(Shared.TokenRange.BinaryKeywordOperators, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space)); + rule("SpaceBeforeBinaryKeywordOperator", anyToken, binaryKeywordOperators, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space), + rule("SpaceAfterBinaryKeywordOperator", binaryKeywordOperators, anyToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space), - // TypeScript-specific higher priority rules - - this.SpaceAfterConstructor = new Rule(RuleDescriptor.create1(SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterConstructor"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); - this.NoSpaceAfterConstructor = new Rule(RuleDescriptor.create1(SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterConstructor"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - - // Use of module as a function call. e.g.: import m2 = module("m2"); - this.NoSpaceAfterModuleImport = new Rule(RuleDescriptor.create2(Shared.TokenRange.FromTokens([SyntaxKind.ModuleKeyword, SyntaxKind.RequireKeyword]), SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - - // Add a space around certain TypeScript keywords - this.SpaceAfterCertainTypeScriptKeywords = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.AbstractKeyword, SyntaxKind.ClassKeyword, SyntaxKind.DeclareKeyword, SyntaxKind.DefaultKeyword, SyntaxKind.EnumKeyword, SyntaxKind.ExportKeyword, SyntaxKind.ExtendsKeyword, SyntaxKind.GetKeyword, SyntaxKind.ImplementsKeyword, SyntaxKind.ImportKeyword, SyntaxKind.InterfaceKeyword, SyntaxKind.ModuleKeyword, SyntaxKind.NamespaceKeyword, SyntaxKind.PrivateKeyword, SyntaxKind.PublicKeyword, SyntaxKind.ProtectedKeyword, SyntaxKind.ReadonlyKeyword, SyntaxKind.SetKeyword, SyntaxKind.StaticKeyword, SyntaxKind.TypeKeyword, SyntaxKind.FromKeyword, SyntaxKind.KeyOfKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); - this.SpaceBeforeCertainTypeScriptKeywords = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.ExtendsKeyword, SyntaxKind.ImplementsKeyword, SyntaxKind.FromKeyword])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); - - // Treat string literals in module names as identifiers, and add a space between the literal and the opening Brace braces, e.g.: module "m2" { - this.SpaceAfterModuleName = new Rule(RuleDescriptor.create1(SyntaxKind.StringLiteral, SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsModuleDeclContext), RuleAction.Space)); - - // Lambda expressions - this.SpaceBeforeArrow = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.EqualsGreaterThanToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); - this.SpaceAfterArrow = new Rule(RuleDescriptor.create3(SyntaxKind.EqualsGreaterThanToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); - - // Optional parameters and let args - this.NoSpaceAfterEllipsis = new Rule(RuleDescriptor.create1(SyntaxKind.DotDotDotToken, SyntaxKind.Identifier), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - this.NoSpaceAfterOptionalParameters = new Rule(RuleDescriptor.create3(SyntaxKind.QuestionToken, Shared.TokenRange.FromTokens([SyntaxKind.CloseParenToken, SyntaxKind.CommaToken])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBinaryOpContext), RuleAction.Delete)); - - // generics and type assertions - this.NoSpaceBeforeOpenAngularBracket = new Rule(RuleDescriptor.create2(Shared.TokenRange.TypeNames, SyntaxKind.LessThanToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), RuleAction.Delete)); - this.NoSpaceBetweenCloseParenAndAngularBracket = new Rule(RuleDescriptor.create1(SyntaxKind.CloseParenToken, SyntaxKind.LessThanToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), RuleAction.Delete)); - this.NoSpaceAfterOpenAngularBracket = new Rule(RuleDescriptor.create3(SyntaxKind.LessThanToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), RuleAction.Delete)); - this.NoSpaceBeforeCloseAngularBracket = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.GreaterThanToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), RuleAction.Delete)); - this.NoSpaceAfterCloseAngularBracket = new Rule(RuleDescriptor.create3(SyntaxKind.GreaterThanToken, Shared.TokenRange.FromTokens([SyntaxKind.OpenParenToken, SyntaxKind.OpenBracketToken, SyntaxKind.GreaterThanToken, SyntaxKind.CommaToken])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), RuleAction.Delete)); - - // Remove spaces in empty interface literals. e.g.: x: {} - this.NoSpaceBetweenEmptyInterfaceBraceBrackets = new Rule(RuleDescriptor.create1(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsObjectTypeContext), RuleAction.Delete)); - - // decorators - this.SpaceBeforeAt = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.AtToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); - this.NoSpaceAfterAt = new Rule(RuleDescriptor.create3(SyntaxKind.AtToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - this.SpaceAfterDecorator = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.AbstractKeyword, SyntaxKind.Identifier, SyntaxKind.ExportKeyword, SyntaxKind.DefaultKeyword, SyntaxKind.ClassKeyword, SyntaxKind.StaticKeyword, SyntaxKind.PublicKeyword, SyntaxKind.PrivateKeyword, SyntaxKind.ProtectedKeyword, SyntaxKind.GetKeyword, SyntaxKind.SetKeyword, SyntaxKind.OpenBracketToken, SyntaxKind.AsteriskToken])), RuleOperation.create2(new RuleOperationContext(Rules.IsEndOfDecoratorContextOnSameLine), RuleAction.Space)); - - this.NoSpaceBetweenFunctionKeywordAndStar = new Rule(RuleDescriptor.create1(SyntaxKind.FunctionKeyword, SyntaxKind.AsteriskToken), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclarationOrFunctionExpressionContext), RuleAction.Delete)); - this.SpaceAfterStarInGeneratorDeclaration = new Rule(RuleDescriptor.create3(SyntaxKind.AsteriskToken, Shared.TokenRange.FromTokens([SyntaxKind.Identifier, SyntaxKind.OpenParenToken])), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclarationOrFunctionExpressionContext), RuleAction.Space)); - this.NoSpaceBetweenYieldKeywordAndStar = new Rule(RuleDescriptor.create1(SyntaxKind.YieldKeyword, SyntaxKind.AsteriskToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), RuleAction.Delete)); - this.SpaceBetweenYieldOrYieldStarAndOperand = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.YieldKeyword, SyntaxKind.AsteriskToken]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), RuleAction.Space)); + rule("SpaceAfterVoidOperator", SyntaxKind.VoidKeyword, anyToken, [isNonJsxSameLineTokenContext, isVoidOpContext], RuleAction.Space), // Async-await - this.SpaceBetweenAsyncAndOpenParen = new Rule(RuleDescriptor.create1(SyntaxKind.AsyncKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsArrowFunctionContext, Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); - this.SpaceBetweenAsyncAndFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.AsyncKeyword, SyntaxKind.FunctionKeyword), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); + rule("SpaceBetweenAsyncAndOpenParen", SyntaxKind.AsyncKeyword, SyntaxKind.OpenParenToken, [isArrowFunctionContext, isNonJsxSameLineTokenContext], RuleAction.Space), + rule("SpaceBetweenAsyncAndFunctionKeyword", SyntaxKind.AsyncKeyword, SyntaxKind.FunctionKeyword, [isNonJsxSameLineTokenContext], RuleAction.Space), // template string - this.NoSpaceBetweenTagAndTemplateString = new Rule(RuleDescriptor.create3(SyntaxKind.Identifier, Shared.TokenRange.FromTokens([SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); + rule("NoSpaceBetweenTagAndTemplateString", SyntaxKind.Identifier, [SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead], [isNonJsxSameLineTokenContext], RuleAction.Delete), - // jsx opening element - this.SpaceBeforeJsxAttribute = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.Identifier), RuleOperation.create2(new RuleOperationContext(Rules.IsNextTokenParentJsxAttribute, Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); - this.SpaceBeforeSlashInJsxOpeningElement = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.SlashToken), RuleOperation.create2(new RuleOperationContext(Rules.IsJsxSelfClosingElementContext, Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); - this.NoSpaceBeforeGreaterThanTokenInJsxOpeningElement = new Rule(RuleDescriptor.create1(SyntaxKind.SlashToken, SyntaxKind.GreaterThanToken), RuleOperation.create2(new RuleOperationContext(Rules.IsJsxSelfClosingElementContext, Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - this.NoSpaceBeforeEqualInJsxAttribute = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.EqualsToken), RuleOperation.create2(new RuleOperationContext(Rules.IsJsxAttributeContext, Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - this.NoSpaceAfterEqualInJsxAttribute = new Rule(RuleDescriptor.create3(SyntaxKind.EqualsToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsJsxAttributeContext, Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); + // JSX opening elements + rule("SpaceBeforeJsxAttribute", anyToken, SyntaxKind.Identifier, [isNextTokenParentJsxAttribute, isNonJsxSameLineTokenContext], RuleAction.Space), + rule("SpaceBeforeSlashInJsxOpeningElement", anyToken, SyntaxKind.SlashToken, [isJsxSelfClosingElementContext, isNonJsxSameLineTokenContext], RuleAction.Space), + rule("NoSpaceBeforeGreaterThanTokenInJsxOpeningElement", SyntaxKind.SlashToken, SyntaxKind.GreaterThanToken, [isJsxSelfClosingElementContext, isNonJsxSameLineTokenContext], RuleAction.Delete), + rule("NoSpaceBeforeEqualInJsxAttribute", anyToken, SyntaxKind.EqualsToken, [isJsxAttributeContext, isNonJsxSameLineTokenContext], RuleAction.Delete), + rule("NoSpaceAfterEqualInJsxAttribute", SyntaxKind.EqualsToken, anyToken, [isJsxAttributeContext, isNonJsxSameLineTokenContext], RuleAction.Delete), - // No space before non-null assertion operator - this.NoSpaceBeforeNonNullAssertionOperator = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.ExclamationToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNonNullAssertionContext), RuleAction.Delete)); + // TypeScript-specific rules + // Use of module as a function call. e.g.: import m2 = module("m2"); + rule("NoSpaceAfterModuleImport", [SyntaxKind.ModuleKeyword, SyntaxKind.RequireKeyword], SyntaxKind.OpenParenToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), + // Add a space around certain TypeScript keywords + rule( + "SpaceAfterCertainTypeScriptKeywords", + [ + SyntaxKind.AbstractKeyword, + SyntaxKind.ClassKeyword, + SyntaxKind.DeclareKeyword, + SyntaxKind.DefaultKeyword, + SyntaxKind.EnumKeyword, + SyntaxKind.ExportKeyword, + SyntaxKind.ExtendsKeyword, + SyntaxKind.GetKeyword, + SyntaxKind.ImplementsKeyword, + SyntaxKind.ImportKeyword, + SyntaxKind.InterfaceKeyword, + SyntaxKind.ModuleKeyword, + SyntaxKind.NamespaceKeyword, + SyntaxKind.PrivateKeyword, + SyntaxKind.PublicKeyword, + SyntaxKind.ProtectedKeyword, + SyntaxKind.ReadonlyKeyword, + SyntaxKind.SetKeyword, + SyntaxKind.StaticKeyword, + SyntaxKind.TypeKeyword, + SyntaxKind.FromKeyword, + SyntaxKind.KeyOfKeyword, + ], + anyToken, + [isNonJsxSameLineTokenContext], + RuleAction.Space), + rule( + "SpaceBeforeCertainTypeScriptKeywords", + anyToken, + [SyntaxKind.ExtendsKeyword, SyntaxKind.ImplementsKeyword, SyntaxKind.FromKeyword], + [isNonJsxSameLineTokenContext], + RuleAction.Space), + // Treat string literals in module names as identifiers, and add a space between the literal and the opening Brace braces, e.g.: module "m2" { + rule("SpaceAfterModuleName", SyntaxKind.StringLiteral, SyntaxKind.OpenBraceToken, [isModuleDeclContext], RuleAction.Space), - /// - /// Rules controlled by user options - /// + // Lambda expressions + rule("SpaceBeforeArrow", anyToken, SyntaxKind.EqualsGreaterThanToken, [isNonJsxSameLineTokenContext], RuleAction.Space), + rule("SpaceAfterArrow", SyntaxKind.EqualsGreaterThanToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.Space), - // Insert space after comma delimiter - this.SpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterCommaDelimiter"), Rules.IsNonJsxSameLineTokenContext, Rules.IsNonJsxElementContext, Rules.IsNextTokenNotCloseBracket), RuleAction.Space)); - this.NoSpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterCommaDelimiter"), Rules.IsNonJsxSameLineTokenContext, Rules.IsNonJsxElementContext), RuleAction.Delete)); + // Optional parameters and let args + rule("NoSpaceAfterEllipsis", SyntaxKind.DotDotDotToken, SyntaxKind.Identifier, [isNonJsxSameLineTokenContext], RuleAction.Delete), + rule("NoSpaceAfterOptionalParameters", SyntaxKind.QuestionToken, [SyntaxKind.CloseParenToken, SyntaxKind.CommaToken], [isNonJsxSameLineTokenContext, isNotBinaryOpContext], RuleAction.Delete), - // Insert space before and after binary operators - this.SpaceBeforeBinaryOperator = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.BinaryOperators), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceBeforeAndAfterBinaryOperators"), Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space)); - this.SpaceAfterBinaryOperator = new Rule(RuleDescriptor.create4(Shared.TokenRange.BinaryOperators, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceBeforeAndAfterBinaryOperators"), Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space)); - this.NoSpaceBeforeBinaryOperator = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.BinaryOperators), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceBeforeAndAfterBinaryOperators"), Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Delete)); - this.NoSpaceAfterBinaryOperator = new Rule(RuleDescriptor.create4(Shared.TokenRange.BinaryOperators, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceBeforeAndAfterBinaryOperators"), Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Delete)); + // Remove spaces in empty interface literals. e.g.: x: {} + rule("NoSpaceBetweenEmptyInterfaceBraceBrackets", SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, [isNonJsxSameLineTokenContext, isObjectTypeContext], RuleAction.Delete), + + // generics and type assertions + rule("NoSpaceBeforeOpenAngularBracket", typeNames, SyntaxKind.LessThanToken, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], RuleAction.Delete), + rule("NoSpaceBetweenCloseParenAndAngularBracket", SyntaxKind.CloseParenToken, SyntaxKind.LessThanToken, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], RuleAction.Delete), + rule("NoSpaceAfterOpenAngularBracket", SyntaxKind.LessThanToken, anyToken, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], RuleAction.Delete), + rule("NoSpaceBeforeCloseAngularBracket", anyToken, SyntaxKind.GreaterThanToken, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], RuleAction.Delete), + rule("NoSpaceAfterCloseAngularBracket", + SyntaxKind.GreaterThanToken, + [SyntaxKind.OpenParenToken, SyntaxKind.OpenBracketToken, SyntaxKind.GreaterThanToken, SyntaxKind.CommaToken], + [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], + RuleAction.Delete), + + // decorators + rule("SpaceBeforeAt", anyToken, SyntaxKind.AtToken, [isNonJsxSameLineTokenContext], RuleAction.Space), + rule("NoSpaceAfterAt", SyntaxKind.AtToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), + // Insert space after @ in decorator + rule("SpaceAfterDecorator", + anyToken, + [ + SyntaxKind.AbstractKeyword, + SyntaxKind.Identifier, + SyntaxKind.ExportKeyword, + SyntaxKind.DefaultKeyword, + SyntaxKind.ClassKeyword, + SyntaxKind.StaticKeyword, + SyntaxKind.PublicKeyword, + SyntaxKind.PrivateKeyword, + SyntaxKind.ProtectedKeyword, + SyntaxKind.GetKeyword, + SyntaxKind.SetKeyword, + SyntaxKind.OpenBracketToken, + SyntaxKind.AsteriskToken, + ], + [isEndOfDecoratorContextOnSameLine], + RuleAction.Space), + + rule("NoSpaceBeforeNonNullAssertionOperator", anyToken, SyntaxKind.ExclamationToken, [isNonJsxSameLineTokenContext, isNonNullAssertionContext], RuleAction.Delete), + rule("NoSpaceAfterNewKeywordOnConstructorSignature", SyntaxKind.NewKeyword, SyntaxKind.OpenParenToken, [isNonJsxSameLineTokenContext, isConstructorSignatureContext], RuleAction.Delete), + ]; + + // These rules are applied after high priority + const userConfigurableRules = [ + // Treat constructor as an identifier in a function declaration, and remove spaces between constructor and following left parentheses + rule("SpaceAfterConstructor", SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceAfterConstructor"), isNonJsxSameLineTokenContext], RuleAction.Space), + rule("NoSpaceAfterConstructor", SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken, [isOptionDisabledOrUndefined("insertSpaceAfterConstructor"), isNonJsxSameLineTokenContext], RuleAction.Delete), + + rule("SpaceAfterComma", SyntaxKind.CommaToken, anyToken, [isOptionEnabled("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementContext, isNextTokenNotCloseBracket], RuleAction.Space), + rule("NoSpaceAfterComma", SyntaxKind.CommaToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementContext], RuleAction.Delete), + + // Insert space after function keyword for anonymous functions + rule("SpaceAfterAnonymousFunctionKeyword", SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), isFunctionDeclContext], RuleAction.Space), + rule("NoSpaceAfterAnonymousFunctionKeyword", SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken, [isOptionDisabledOrUndefined("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), isFunctionDeclContext], RuleAction.Delete), // Insert space after keywords in control flow statements - this.SpaceAfterKeywordInControl = new Rule(RuleDescriptor.create2(Shared.TokenRange.Keywords, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterKeywordsInControlFlowStatements"), Rules.IsControlDeclContext), RuleAction.Space)); - this.NoSpaceAfterKeywordInControl = new Rule(RuleDescriptor.create2(Shared.TokenRange.Keywords, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterKeywordsInControlFlowStatements"), Rules.IsControlDeclContext), RuleAction.Delete)); + rule("SpaceAfterKeywordInControl", keywords, SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceAfterKeywordsInControlFlowStatements"), isControlDeclContext], RuleAction.Space), + rule("NoSpaceAfterKeywordInControl", keywords, SyntaxKind.OpenParenToken, [isOptionDisabledOrUndefined("insertSpaceAfterKeywordsInControlFlowStatements"), isControlDeclContext], RuleAction.Delete), + + // Insert space after opening and before closing nonempty parenthesis + rule("SpaceAfterOpenParen", SyntaxKind.OpenParenToken, anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], RuleAction.Space), + rule("SpaceBeforeCloseParen", anyToken, SyntaxKind.CloseParenToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], RuleAction.Space), + rule("SpaceBetweenOpenParens", SyntaxKind.OpenParenToken, SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], RuleAction.Space), + rule("NoSpaceBetweenParens", SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), + rule("NoSpaceAfterOpenParen", SyntaxKind.OpenParenToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], RuleAction.Delete), + rule("NoSpaceBeforeCloseParen", anyToken, SyntaxKind.CloseParenToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], RuleAction.Delete), + + // Insert space after opening and before closing nonempty brackets + rule("SpaceAfterOpenBracket", SyntaxKind.OpenBracketToken, anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], RuleAction.Space), + rule("SpaceBeforeCloseBracket", anyToken, SyntaxKind.CloseBracketToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], RuleAction.Space), + rule("NoSpaceBetweenBrackets", SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), + rule("NoSpaceAfterOpenBracket", SyntaxKind.OpenBracketToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], RuleAction.Delete), + rule("NoSpaceBeforeCloseBracket", anyToken, SyntaxKind.CloseBracketToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], RuleAction.Delete), + + // Insert a space after { and before } in single-line contexts, but remove space from empty object literals {}. + rule("SpaceAfterOpenBrace", SyntaxKind.OpenBraceToken, anyToken, [isOptionEnabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isBraceWrappedContext], RuleAction.Space), + rule("SpaceBeforeCloseBrace", anyToken, SyntaxKind.CloseBraceToken, [isOptionEnabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isBraceWrappedContext], RuleAction.Space), + rule("NoSpaceBetweenEmptyBraceBrackets", SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, [isNonJsxSameLineTokenContext, isObjectContext], RuleAction.Delete), + rule("NoSpaceAfterOpenBrace", SyntaxKind.OpenBraceToken, anyToken, [isOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isNonJsxSameLineTokenContext], RuleAction.Delete), + rule("NoSpaceBeforeCloseBrace", anyToken, SyntaxKind.CloseBraceToken, [isOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isNonJsxSameLineTokenContext], RuleAction.Delete), + + // Insert space after opening and before closing template string braces + rule("SpaceAfterTemplateHeadAndMiddle", [SyntaxKind.TemplateHead, SyntaxKind.TemplateMiddle], anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], RuleAction.Space), + rule("SpaceBeforeTemplateMiddleAndTail", anyToken, [SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail], [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], RuleAction.Space), + rule("NoSpaceAfterTemplateHeadAndMiddle", [SyntaxKind.TemplateHead, SyntaxKind.TemplateMiddle], anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], RuleAction.Delete), + rule("NoSpaceBeforeTemplateMiddleAndTail", anyToken, [SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail], [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], RuleAction.Delete), + + // No space after { and before } in JSX expression + rule("SpaceAfterOpenBraceInJsxExpression", SyntaxKind.OpenBraceToken, anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], RuleAction.Space), + rule("SpaceBeforeCloseBraceInJsxExpression", anyToken, SyntaxKind.CloseBraceToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], RuleAction.Space), + rule("NoSpaceAfterOpenBraceInJsxExpression", SyntaxKind.OpenBraceToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], RuleAction.Delete), + rule("NoSpaceBeforeCloseBraceInJsxExpression", anyToken, SyntaxKind.CloseBraceToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], RuleAction.Delete), + + // Insert space after semicolon in for statement + rule("SpaceAfterSemicolonInFor", SyntaxKind.SemicolonToken, anyToken, [isOptionEnabled("insertSpaceAfterSemicolonInForStatements"), isNonJsxSameLineTokenContext, isForContext], RuleAction.Space), + rule("NoSpaceAfterSemicolonInFor", SyntaxKind.SemicolonToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterSemicolonInForStatements"), isNonJsxSameLineTokenContext, isForContext], RuleAction.Delete), + + // Insert space before and after binary operators + rule("SpaceBeforeBinaryOperator", anyToken, binaryOperators, [isOptionEnabled("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space), + rule("SpaceAfterBinaryOperator", binaryOperators, anyToken, [isOptionEnabled("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space), + rule("NoSpaceBeforeBinaryOperator", anyToken, binaryOperators, [isOptionDisabledOrUndefined("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Delete), + rule("NoSpaceAfterBinaryOperator", binaryOperators, anyToken, [isOptionDisabledOrUndefined("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Delete), + + rule("SpaceBeforeOpenParenInFuncDecl", anyToken, SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceBeforeFunctionParenthesis"), isNonJsxSameLineTokenContext, isFunctionDeclContext], RuleAction.Space), + rule("NoSpaceBeforeOpenParenInFuncDecl", anyToken, SyntaxKind.OpenParenToken, [isOptionDisabledOrUndefined("insertSpaceBeforeFunctionParenthesis"), isNonJsxSameLineTokenContext, isFunctionDeclContext], RuleAction.Delete), + + // Open Brace braces after control block + rule("NewLineBeforeOpenBraceInControl", controlOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken, [isOptionEnabled("placeOpenBraceOnNewLineForControlBlocks"), isControlDeclContext, isBeforeMultilineBlockContext], RuleAction.NewLine, RuleFlags.CanDeleteNewLines), // Open Brace braces after function // TypeScript: Function can have return types, which can be made of tons of different token kinds - this.NewLineBeforeOpenBraceInFunction = new Rule(RuleDescriptor.create2(this.FunctionOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("placeOpenBraceOnNewLineForFunctions"), Rules.IsFunctionDeclContext, Rules.IsBeforeMultilineBlockContext), RuleAction.NewLine), RuleFlags.CanDeleteNewLines); - + rule("NewLineBeforeOpenBraceInFunction", functionOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken, [isOptionEnabled("placeOpenBraceOnNewLineForFunctions"), isFunctionDeclContext, isBeforeMultilineBlockContext], RuleAction.NewLine, RuleFlags.CanDeleteNewLines), // Open Brace braces after TypeScript module/class/interface - this.NewLineBeforeOpenBraceInTypeScriptDeclWithBlock = new Rule(RuleDescriptor.create2(this.TypeScriptOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("placeOpenBraceOnNewLineForFunctions"), Rules.IsTypeScriptDeclWithBlockContext, Rules.IsBeforeMultilineBlockContext), RuleAction.NewLine), RuleFlags.CanDeleteNewLines); + rule("NewLineBeforeOpenBraceInTypeScriptDeclWithBlock", typeScriptOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken, [isOptionEnabled("placeOpenBraceOnNewLineForFunctions"), isTypeScriptDeclWithBlockContext, isBeforeMultilineBlockContext], RuleAction.NewLine, RuleFlags.CanDeleteNewLines), - // Open Brace braces after control block - this.NewLineBeforeOpenBraceInControl = new Rule(RuleDescriptor.create2(this.ControlOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("placeOpenBraceOnNewLineForControlBlocks"), Rules.IsControlDeclContext, Rules.IsBeforeMultilineBlockContext), RuleAction.NewLine), RuleFlags.CanDeleteNewLines); + rule("SpaceAfterTypeAssertion", SyntaxKind.GreaterThanToken, anyToken, [isOptionEnabled("insertSpaceAfterTypeAssertion"), isNonJsxSameLineTokenContext, isTypeAssertionContext], RuleAction.Space), + rule("NoSpaceAfterTypeAssertion", SyntaxKind.GreaterThanToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterTypeAssertion"), isNonJsxSameLineTokenContext, isTypeAssertionContext], RuleAction.Delete), + ]; - // Insert space after semicolon in for statement - this.SpaceAfterSemicolonInFor = new Rule(RuleDescriptor.create3(SyntaxKind.SemicolonToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterSemicolonInForStatements"), Rules.IsNonJsxSameLineTokenContext, Rules.IsForContext), RuleAction.Space)); - this.NoSpaceAfterSemicolonInFor = new Rule(RuleDescriptor.create3(SyntaxKind.SemicolonToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterSemicolonInForStatements"), Rules.IsNonJsxSameLineTokenContext, Rules.IsForContext), RuleAction.Delete)); + // These rules are lower in priority than user-configurable + const lowPriorityCommonRules = [ + // Space after keyword but not before ; or : or ? + rule("NoSpaceBeforeSemicolon", anyToken, SyntaxKind.SemicolonToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), - // Insert space after opening and before closing nonempty parenthesis - this.SpaceAfterOpenParen = new Rule(RuleDescriptor.create3(SyntaxKind.OpenParenToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); - this.SpaceBeforeCloseParen = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); - this.SpaceBetweenOpenParens = new Rule(RuleDescriptor.create1(SyntaxKind.OpenParenToken, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); - this.NoSpaceBetweenParens = new Rule(RuleDescriptor.create1(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - this.NoSpaceAfterOpenParen = new Rule(RuleDescriptor.create3(SyntaxKind.OpenParenToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - this.NoSpaceBeforeCloseParen = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); + rule("SpaceBeforeOpenBraceInControl", controlOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken, [isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForControlBlocks"), isControlDeclContext, isNotFormatOnEnter, isSameLineTokenOrBeforeBlockContext], RuleAction.Space, RuleFlags.CanDeleteNewLines), + rule("SpaceBeforeOpenBraceInFunction", functionOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken, [isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForFunctions"), isFunctionDeclContext, isBeforeBlockContext, isNotFormatOnEnter, isSameLineTokenOrBeforeBlockContext], RuleAction.Space, RuleFlags.CanDeleteNewLines), + rule("SpaceBeforeOpenBraceInTypeScriptDeclWithBlock", typeScriptOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken, [isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForFunctions"), isTypeScriptDeclWithBlockContext, isNotFormatOnEnter, isSameLineTokenOrBeforeBlockContext], RuleAction.Space, RuleFlags.CanDeleteNewLines), - // Insert space after opening and before closing nonempty brackets - this.SpaceAfterOpenBracket = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBracketToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); - this.SpaceBeforeCloseBracket = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBracketToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); - this.NoSpaceBetweenBrackets = new Rule(RuleDescriptor.create1(SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - this.NoSpaceAfterOpenBracket = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBracketToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - this.NoSpaceBeforeCloseBracket = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBracketToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); + rule("NoSpaceBeforeComma", anyToken, SyntaxKind.CommaToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), + // No space before and after indexer + rule("NoSpaceBeforeOpenBracket", anyTokenExcept(SyntaxKind.AsyncKeyword), SyntaxKind.OpenBracketToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), + rule("NoSpaceAfterCloseBracket", SyntaxKind.CloseBracketToken, anyToken, [isNonJsxSameLineTokenContext, isNotBeforeBlockInFunctionDeclarationContext], RuleAction.Delete), + rule("SpaceAfterSemicolon", SyntaxKind.SemicolonToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.Space), - // Insert space after opening and before closing template string braces - this.NoSpaceAfterTemplateHeadAndMiddle = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.TemplateHead, SyntaxKind.TemplateMiddle]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - this.SpaceAfterTemplateHeadAndMiddle = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.TemplateHead, SyntaxKind.TemplateMiddle]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); - this.NoSpaceBeforeTemplateMiddleAndTail = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail])), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); - this.SpaceBeforeTemplateMiddleAndTail = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail])), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); + // Add a space between statements. All keywords except (do,else,case) has open/close parens after them. + // So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any] + rule( + "SpaceBetweenStatements", + [SyntaxKind.CloseParenToken, SyntaxKind.DoKeyword, SyntaxKind.ElseKeyword, SyntaxKind.CaseKeyword], + anyToken, + [isNonJsxSameLineTokenContext, isNonJsxElementContext, isNotForContext], + RuleAction.Space), + // This low-pri rule takes care of "try {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter. + rule("SpaceAfterTryFinally", [SyntaxKind.TryKeyword, SyntaxKind.FinallyKeyword], SyntaxKind.OpenBraceToken, [isNonJsxSameLineTokenContext], RuleAction.Space), + ]; - // No space after { and before } in JSX expression - this.NoSpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), RuleAction.Delete)); - this.SpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), RuleAction.Space)); - this.NoSpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), RuleAction.Delete)); - this.SpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), RuleAction.Space)); + return [ + ...highPriorityCommonRules, + ...userConfigurableRules, + ...lowPriorityCommonRules, + ]; + } - // Insert space after function keyword for anonymous functions - this.SpaceAfterAnonymousFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), Rules.IsFunctionDeclContext), RuleAction.Space)); - this.NoSpaceAfterAnonymousFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), Rules.IsFunctionDeclContext), RuleAction.Delete)); + function rule( + debugName: string, + left: SyntaxKind | ReadonlyArray | TokenRange, + right: SyntaxKind | ReadonlyArray | TokenRange, + context: ReadonlyArray, + action: RuleAction, + flags: RuleFlags = RuleFlags.None, + ): RuleSpec { + return { leftTokenRange: toTokenRange(left), rightTokenRange: toTokenRange(right), rule: { debugName, context, action, flags } }; + } - // No space after type assertion - this.NoSpaceAfterTypeAssertion = new Rule(RuleDescriptor.create3(SyntaxKind.GreaterThanToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionDisabledOrUndefined("insertSpaceAfterTypeAssertion"), Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeAssertionContext), RuleAction.Delete)); - this.SpaceAfterTypeAssertion = new Rule(RuleDescriptor.create3(SyntaxKind.GreaterThanToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsOptionEnabled("insertSpaceAfterTypeAssertion"), Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeAssertionContext), RuleAction.Space)); + function tokenRangeFrom(tokens: ReadonlyArray): TokenRange { + return { tokens, isSpecific: true }; + } - // These rules are higher in priority than user-configurable rules. - this.HighPriorityCommonRules = [ - this.IgnoreBeforeComment, this.IgnoreAfterLineComment, - this.NoSpaceBeforeColon, this.SpaceAfterColon, this.NoSpaceBeforeQuestionMark, this.SpaceAfterQuestionMarkInConditionalOperator, - this.NoSpaceAfterQuestionMark, - this.NoSpaceBeforeDot, this.NoSpaceAfterDot, - this.NoSpaceAfterUnaryPrefixOperator, - this.NoSpaceAfterUnaryPreincrementOperator, this.NoSpaceAfterUnaryPredecrementOperator, - this.NoSpaceBeforeUnaryPostincrementOperator, this.NoSpaceBeforeUnaryPostdecrementOperator, - this.SpaceAfterPostincrementWhenFollowedByAdd, - this.SpaceAfterAddWhenFollowedByUnaryPlus, this.SpaceAfterAddWhenFollowedByPreincrement, - this.SpaceAfterPostdecrementWhenFollowedBySubtract, - this.SpaceAfterSubtractWhenFollowedByUnaryMinus, this.SpaceAfterSubtractWhenFollowedByPredecrement, - this.NoSpaceAfterCloseBrace, - this.NewLineBeforeCloseBraceInBlockContext, - this.SpaceAfterCloseBrace, this.SpaceBetweenCloseBraceAndElse, this.SpaceBetweenCloseBraceAndWhile, this.NoSpaceBetweenEmptyBraceBrackets, - this.NoSpaceBetweenFunctionKeywordAndStar, this.SpaceAfterStarInGeneratorDeclaration, - this.SpaceAfterFunctionInFuncDecl, this.NewLineAfterOpenBraceInBlockContext, this.SpaceAfterGetSetInMember, - this.NoSpaceBetweenYieldKeywordAndStar, this.SpaceBetweenYieldOrYieldStarAndOperand, - this.NoSpaceBetweenReturnAndSemicolon, - this.SpaceAfterCertainKeywords, - this.SpaceAfterLetConstInVariableDeclaration, - this.NoSpaceBeforeOpenParenInFuncCall, - this.SpaceBeforeBinaryKeywordOperator, this.SpaceAfterBinaryKeywordOperator, - this.SpaceAfterVoidOperator, - this.SpaceBetweenAsyncAndOpenParen, this.SpaceBetweenAsyncAndFunctionKeyword, - this.NoSpaceBetweenTagAndTemplateString, - this.SpaceBeforeJsxAttribute, this.SpaceBeforeSlashInJsxOpeningElement, this.NoSpaceBeforeGreaterThanTokenInJsxOpeningElement, - this.NoSpaceBeforeEqualInJsxAttribute, this.NoSpaceAfterEqualInJsxAttribute, + function toTokenRange(arg: SyntaxKind | ReadonlyArray | TokenRange): TokenRange { + return typeof arg === "number" ? tokenRangeFrom([arg]) : isArray(arg) ? tokenRangeFrom(arg) : arg; + } - // TypeScript-specific rules - this.NoSpaceAfterModuleImport, - this.SpaceAfterCertainTypeScriptKeywords, this.SpaceBeforeCertainTypeScriptKeywords, - this.SpaceAfterModuleName, - this.SpaceBeforeArrow, this.SpaceAfterArrow, - this.NoSpaceAfterEllipsis, - this.NoSpaceAfterOptionalParameters, - this.NoSpaceBetweenEmptyInterfaceBraceBrackets, - this.NoSpaceBeforeOpenAngularBracket, - this.NoSpaceBetweenCloseParenAndAngularBracket, - this.NoSpaceAfterOpenAngularBracket, - this.NoSpaceBeforeCloseAngularBracket, - this.NoSpaceAfterCloseAngularBracket, - this.SpaceBeforeAt, - this.NoSpaceAfterAt, - this.SpaceAfterDecorator, - this.NoSpaceBeforeNonNullAssertionOperator, - this.NoSpaceAfterNewKeywordOnConstructorSignature - ]; - - // These rules are applied after high priority rules. - this.UserConfigurableRules = [ - this.SpaceAfterConstructor, this.NoSpaceAfterConstructor, - this.SpaceAfterComma, this.NoSpaceAfterComma, - this.SpaceAfterAnonymousFunctionKeyword, this.NoSpaceAfterAnonymousFunctionKeyword, - this.SpaceAfterKeywordInControl, this.NoSpaceAfterKeywordInControl, - this.SpaceAfterOpenParen, this.SpaceBeforeCloseParen, this.SpaceBetweenOpenParens, this.NoSpaceBetweenParens, this.NoSpaceAfterOpenParen, this.NoSpaceBeforeCloseParen, - this.SpaceAfterOpenBracket, this.SpaceBeforeCloseBracket, this.NoSpaceBetweenBrackets, this.NoSpaceAfterOpenBracket, this.NoSpaceBeforeCloseBracket, - this.SpaceAfterOpenBrace, this.SpaceBeforeCloseBrace, this.NoSpaceBetweenEmptyBraceBrackets, this.NoSpaceAfterOpenBrace, this.NoSpaceBeforeCloseBrace, - this.SpaceAfterTemplateHeadAndMiddle, this.SpaceBeforeTemplateMiddleAndTail, this.NoSpaceAfterTemplateHeadAndMiddle, this.NoSpaceBeforeTemplateMiddleAndTail, - this.SpaceAfterOpenBraceInJsxExpression, this.SpaceBeforeCloseBraceInJsxExpression, this.NoSpaceAfterOpenBraceInJsxExpression, this.NoSpaceBeforeCloseBraceInJsxExpression, - this.SpaceAfterSemicolonInFor, this.NoSpaceAfterSemicolonInFor, - this.SpaceBeforeBinaryOperator, this.SpaceAfterBinaryOperator, this.NoSpaceBeforeBinaryOperator, this.NoSpaceAfterBinaryOperator, - this.SpaceBeforeOpenParenInFuncDecl, this.NoSpaceBeforeOpenParenInFuncDecl, - this.NewLineBeforeOpenBraceInControl, - this.NewLineBeforeOpenBraceInFunction, this.NewLineBeforeOpenBraceInTypeScriptDeclWithBlock, - this.SpaceAfterTypeAssertion, this.NoSpaceAfterTypeAssertion - ]; - - // These rules are lower in priority than user-configurable rules. - this.LowPriorityCommonRules = [ - this.NoSpaceBeforeSemicolon, - this.SpaceBeforeOpenBraceInControl, this.SpaceBeforeOpenBraceInFunction, this.SpaceBeforeOpenBraceInTypeScriptDeclWithBlock, - this.NoSpaceBeforeComma, - this.NoSpaceBeforeOpenBracket, - this.NoSpaceAfterCloseBracket, - this.SpaceAfterSemicolon, - this.SpaceBetweenStatements, this.SpaceAfterTryFinally - ]; - - if (Debug.isDebugging) { - const o: ts.MapLike = this; - for (const name in o) { - const rule = o[name]; - if (rule instanceof Rule) { - rule.debugName = name; - } - } + function tokenRangeFromRange(from: SyntaxKind, to: SyntaxKind, except: ReadonlyArray = []): TokenRange { + const tokens: SyntaxKind[] = []; + for (let token = from; token <= to; token++) { + if (!contains(except, token)) { + tokens.push(token); } } + return tokenRangeFrom(tokens); + } - /// - /// Contexts - /// + /// + /// Contexts + /// - static IsOptionEnabled(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean { - return (context) => context.options && context.options.hasOwnProperty(optionName) && !!context.options[optionName]; - } + function isOptionEnabled(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean { + return (context) => context.options && context.options.hasOwnProperty(optionName) && !!context.options[optionName]; + } - static IsOptionDisabled(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean { - return (context) => context.options && context.options.hasOwnProperty(optionName) && !context.options[optionName]; - } + function isOptionDisabled(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean { + return (context) => context.options && context.options.hasOwnProperty(optionName) && !context.options[optionName]; + } - static IsOptionDisabledOrUndefined(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean { - return (context) => !context.options || !context.options.hasOwnProperty(optionName) || !context.options[optionName]; - } + function isOptionDisabledOrUndefined(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean { + return (context) => !context.options || !context.options.hasOwnProperty(optionName) || !context.options[optionName]; + } - static isOptionDisabledOrUndefinedOrTokensOnSameLine(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean { - return (context) => !context.options || !context.options.hasOwnProperty(optionName) || !context.options[optionName] || context.TokensAreOnSameLine(); - } + function isOptionDisabledOrUndefinedOrTokensOnSameLine(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean { + return (context) => !context.options || !context.options.hasOwnProperty(optionName) || !context.options[optionName] || context.TokensAreOnSameLine(); + } - static IsOptionEnabledOrUndefined(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean { - return (context) => !context.options || !context.options.hasOwnProperty(optionName) || !!context.options[optionName]; - } + function isOptionEnabledOrUndefined(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean { + return (context) => !context.options || !context.options.hasOwnProperty(optionName) || !!context.options[optionName]; + } - static IsForContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.ForStatement; - } + function isForContext(context: FormattingContext): boolean { + return context.contextNode.kind === SyntaxKind.ForStatement; + } - static IsNotForContext(context: FormattingContext): boolean { - return !Rules.IsForContext(context); - } + function isNotForContext(context: FormattingContext): boolean { + return !isForContext(context); + } - static IsBinaryOpContext(context: FormattingContext): boolean { + function isBinaryOpContext(context: FormattingContext): boolean { - switch (context.contextNode.kind) { - case SyntaxKind.BinaryExpression: - case SyntaxKind.ConditionalExpression: - case SyntaxKind.AsExpression: - case SyntaxKind.ExportSpecifier: - case SyntaxKind.ImportSpecifier: - case SyntaxKind.TypePredicate: - case SyntaxKind.UnionType: - case SyntaxKind.IntersectionType: - return true; - - // equals in binding elements: function foo([[x, y] = [1, 2]]) - case SyntaxKind.BindingElement: - // equals in type X = ... - case SyntaxKind.TypeAliasDeclaration: - // equal in import a = module('a'); - case SyntaxKind.ImportEqualsDeclaration: - // equal in let a = 0; - case SyntaxKind.VariableDeclaration: - // equal in p = 0; - case SyntaxKind.Parameter: - case SyntaxKind.EnumMember: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - return context.currentTokenSpan.kind === SyntaxKind.EqualsToken || context.nextTokenSpan.kind === SyntaxKind.EqualsToken; - // "in" keyword in for (let x in []) { } - case SyntaxKind.ForInStatement: - // "in" keyword in [P in keyof T]: T[P] - case SyntaxKind.TypeParameter: - return context.currentTokenSpan.kind === SyntaxKind.InKeyword || context.nextTokenSpan.kind === SyntaxKind.InKeyword; - // Technically, "of" is not a binary operator, but format it the same way as "in" - case SyntaxKind.ForOfStatement: - return context.currentTokenSpan.kind === SyntaxKind.OfKeyword || context.nextTokenSpan.kind === SyntaxKind.OfKeyword; - } - return false; - } - - static IsNotBinaryOpContext(context: FormattingContext): boolean { - return !Rules.IsBinaryOpContext(context); - } - - static IsConditionalOperatorContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.ConditionalExpression; - } - - static IsSameLineTokenOrBeforeBlockContext(context: FormattingContext): boolean { - return context.TokensAreOnSameLine() || Rules.IsBeforeBlockContext(context); - } - - static IsBraceWrappedContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.ObjectBindingPattern || Rules.IsSingleLineBlockContext(context); - } - - // This check is done before an open brace in a control construct, a function, or a typescript block declaration - static IsBeforeMultilineBlockContext(context: FormattingContext): boolean { - return Rules.IsBeforeBlockContext(context) && !(context.NextNodeAllOnSameLine() || context.NextNodeBlockIsOnOneLine()); - } - - static IsMultilineBlockContext(context: FormattingContext): boolean { - return Rules.IsBlockContext(context) && !(context.ContextNodeAllOnSameLine() || context.ContextNodeBlockIsOnOneLine()); - } - - static IsSingleLineBlockContext(context: FormattingContext): boolean { - return Rules.IsBlockContext(context) && (context.ContextNodeAllOnSameLine() || context.ContextNodeBlockIsOnOneLine()); - } - - static IsBlockContext(context: FormattingContext): boolean { - return Rules.NodeIsBlockContext(context.contextNode); - } - - static IsBeforeBlockContext(context: FormattingContext): boolean { - return Rules.NodeIsBlockContext(context.nextTokenParent); - } - - // IMPORTANT!!! This method must return true ONLY for nodes with open and close braces as immediate children - static NodeIsBlockContext(node: Node): boolean { - if (Rules.NodeIsTypeScriptDeclWithBlockContext(node)) { - // This means we are in a context that looks like a block to the user, but in the grammar is actually not a node (it's a class, module, enum, object type literal, etc). + switch (context.contextNode.kind) { + case SyntaxKind.BinaryExpression: + case SyntaxKind.ConditionalExpression: + case SyntaxKind.AsExpression: + case SyntaxKind.ExportSpecifier: + case SyntaxKind.ImportSpecifier: + case SyntaxKind.TypePredicate: + case SyntaxKind.UnionType: + case SyntaxKind.IntersectionType: return true; - } - switch (node.kind) { - case SyntaxKind.Block: - case SyntaxKind.CaseBlock: - case SyntaxKind.ObjectLiteralExpression: - case SyntaxKind.ModuleBlock: + // equals in binding elements: function foo([[x, y] = [1, 2]]) + case SyntaxKind.BindingElement: + // equals in type X = ... + case SyntaxKind.TypeAliasDeclaration: + // equal in import a = module('a'); + case SyntaxKind.ImportEqualsDeclaration: + // equal in let a = 0; + case SyntaxKind.VariableDeclaration: + // equal in p = 0; + case SyntaxKind.Parameter: + case SyntaxKind.EnumMember: + case SyntaxKind.PropertyDeclaration: + case SyntaxKind.PropertySignature: + return context.currentTokenSpan.kind === SyntaxKind.EqualsToken || context.nextTokenSpan.kind === SyntaxKind.EqualsToken; + // "in" keyword in for (let x in []) { } + case SyntaxKind.ForInStatement: + // "in" keyword in [P in keyof T]: T[P] + case SyntaxKind.TypeParameter: + return context.currentTokenSpan.kind === SyntaxKind.InKeyword || context.nextTokenSpan.kind === SyntaxKind.InKeyword; + // Technically, "of" is not a binary operator, but format it the same way as "in" + case SyntaxKind.ForOfStatement: + return context.currentTokenSpan.kind === SyntaxKind.OfKeyword || context.nextTokenSpan.kind === SyntaxKind.OfKeyword; + } + return false; + } + + function isNotBinaryOpContext(context: FormattingContext): boolean { + return !isBinaryOpContext(context); + } + + function isConditionalOperatorContext(context: FormattingContext): boolean { + return context.contextNode.kind === SyntaxKind.ConditionalExpression; + } + + function isSameLineTokenOrBeforeBlockContext(context: FormattingContext): boolean { + return context.TokensAreOnSameLine() || isBeforeBlockContext(context); + } + + function isBraceWrappedContext(context: FormattingContext): boolean { + return context.contextNode.kind === SyntaxKind.ObjectBindingPattern || isSingleLineBlockContext(context); + } + + // This check is done before an open brace in a control construct, a function, or a typescript block declaration + function isBeforeMultilineBlockContext(context: FormattingContext): boolean { + return isBeforeBlockContext(context) && !(context.NextNodeAllOnSameLine() || context.NextNodeBlockIsOnOneLine()); + } + + function isMultilineBlockContext(context: FormattingContext): boolean { + return isBlockContext(context) && !(context.ContextNodeAllOnSameLine() || context.ContextNodeBlockIsOnOneLine()); + } + + function isSingleLineBlockContext(context: FormattingContext): boolean { + return isBlockContext(context) && (context.ContextNodeAllOnSameLine() || context.ContextNodeBlockIsOnOneLine()); + } + + function isBlockContext(context: FormattingContext): boolean { + return nodeIsBlockContext(context.contextNode); + } + + function isBeforeBlockContext(context: FormattingContext): boolean { + return nodeIsBlockContext(context.nextTokenParent); + } + + // IMPORTANT!!! This method must return true ONLY for nodes with open and close braces as immediate children + function nodeIsBlockContext(node: Node): boolean { + if (nodeIsTypeScriptDeclWithBlockContext(node)) { + // This means we are in a context that looks like a block to the user, but in the grammar is actually not a node (it's a class, module, enum, object type literal, etc). + return true; + } + + switch (node.kind) { + case SyntaxKind.Block: + case SyntaxKind.CaseBlock: + case SyntaxKind.ObjectLiteralExpression: + case SyntaxKind.ModuleBlock: + return true; + } + + return false; + } + + function isFunctionDeclContext(context: FormattingContext): boolean { + switch (context.contextNode.kind) { + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.MethodSignature: + // case SyntaxKind.MemberFunctionDeclaration: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + // case SyntaxKind.MethodSignature: + case SyntaxKind.CallSignature: + case SyntaxKind.FunctionExpression: + case SyntaxKind.Constructor: + case SyntaxKind.ArrowFunction: + // case SyntaxKind.ConstructorDeclaration: + // case SyntaxKind.SimpleArrowFunctionExpression: + // case SyntaxKind.ParenthesizedArrowFunctionExpression: + case SyntaxKind.InterfaceDeclaration: // This one is not truly a function, but for formatting purposes, it acts just like one + return true; + } + + return false; + } + + function isFunctionDeclarationOrFunctionExpressionContext(context: FormattingContext): boolean { + return context.contextNode.kind === SyntaxKind.FunctionDeclaration || context.contextNode.kind === SyntaxKind.FunctionExpression; + } + + function isTypeScriptDeclWithBlockContext(context: FormattingContext): boolean { + return nodeIsTypeScriptDeclWithBlockContext(context.contextNode); + } + + function nodeIsTypeScriptDeclWithBlockContext(node: Node): boolean { + switch (node.kind) { + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.EnumDeclaration: + case SyntaxKind.TypeLiteral: + case SyntaxKind.ModuleDeclaration: + case SyntaxKind.ExportDeclaration: + case SyntaxKind.NamedExports: + case SyntaxKind.ImportDeclaration: + case SyntaxKind.NamedImports: + return true; + } + + return false; + } + + function isAfterCodeBlockContext(context: FormattingContext): boolean { + switch (context.currentTokenParent.kind) { + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ModuleDeclaration: + case SyntaxKind.EnumDeclaration: + case SyntaxKind.CatchClause: + case SyntaxKind.ModuleBlock: + case SyntaxKind.SwitchStatement: + return true; + case SyntaxKind.Block: { + const blockParent = context.currentTokenParent.parent; + // In a codefix scenario, we can't rely on parents being set. So just always return true. + if (!blockParent || blockParent.kind !== SyntaxKind.ArrowFunction && blockParent.kind !== SyntaxKind.FunctionExpression) { return true; - } - - return false; - } - - static IsFunctionDeclContext(context: FormattingContext): boolean { - switch (context.contextNode.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - // case SyntaxKind.MemberFunctionDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - // case SyntaxKind.MethodSignature: - case SyntaxKind.CallSignature: - case SyntaxKind.FunctionExpression: - case SyntaxKind.Constructor: - case SyntaxKind.ArrowFunction: - // case SyntaxKind.ConstructorDeclaration: - // case SyntaxKind.SimpleArrowFunctionExpression: - // case SyntaxKind.ParenthesizedArrowFunctionExpression: - case SyntaxKind.InterfaceDeclaration: // This one is not truly a function, but for formatting purposes, it acts just like one - return true; - } - - return false; - } - - static IsFunctionDeclarationOrFunctionExpressionContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.FunctionDeclaration || context.contextNode.kind === SyntaxKind.FunctionExpression; - } - - static IsTypeScriptDeclWithBlockContext(context: FormattingContext): boolean { - return Rules.NodeIsTypeScriptDeclWithBlockContext(context.contextNode); - } - - static NodeIsTypeScriptDeclWithBlockContext(node: Node): boolean { - switch (node.kind) { - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.TypeLiteral: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.ExportDeclaration: - case SyntaxKind.NamedExports: - case SyntaxKind.ImportDeclaration: - case SyntaxKind.NamedImports: - return true; - } - - return false; - } - - static IsAfterCodeBlockContext(context: FormattingContext): boolean { - switch (context.currentTokenParent.kind) { - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.CatchClause: - case SyntaxKind.ModuleBlock: - case SyntaxKind.SwitchStatement: - return true; - case SyntaxKind.Block: { - const blockParent = context.currentTokenParent.parent; - // In a codefix scenario, we can't rely on parents being set. So just always return true. - if (!blockParent || blockParent.kind !== SyntaxKind.ArrowFunction && blockParent.kind !== SyntaxKind.FunctionExpression) { - return true; - } } } - return false; } + return false; + } - static IsControlDeclContext(context: FormattingContext): boolean { - switch (context.contextNode.kind) { - case SyntaxKind.IfStatement: - case SyntaxKind.SwitchStatement: - case SyntaxKind.ForStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.WhileStatement: - case SyntaxKind.TryStatement: - case SyntaxKind.DoStatement: - case SyntaxKind.WithStatement: - // TODO - // case SyntaxKind.ElseClause: - case SyntaxKind.CatchClause: - return true; + function isControlDeclContext(context: FormattingContext): boolean { + switch (context.contextNode.kind) { + case SyntaxKind.IfStatement: + case SyntaxKind.SwitchStatement: + case SyntaxKind.ForStatement: + case SyntaxKind.ForInStatement: + case SyntaxKind.ForOfStatement: + case SyntaxKind.WhileStatement: + case SyntaxKind.TryStatement: + case SyntaxKind.DoStatement: + case SyntaxKind.WithStatement: + // TODO + // case SyntaxKind.ElseClause: + case SyntaxKind.CatchClause: + return true; - default: - return false; - } - } - - static IsObjectContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.ObjectLiteralExpression; - } - - static IsFunctionCallContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.CallExpression; - } - - static IsNewContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.NewExpression; - } - - static IsFunctionCallOrNewContext(context: FormattingContext): boolean { - return Rules.IsFunctionCallContext(context) || Rules.IsNewContext(context); - } - - static IsPreviousTokenNotComma(context: FormattingContext): boolean { - return context.currentTokenSpan.kind !== SyntaxKind.CommaToken; - } - - static IsNextTokenNotCloseBracket(context: FormattingContext): boolean { - return context.nextTokenSpan.kind !== SyntaxKind.CloseBracketToken; - } - - static IsArrowFunctionContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.ArrowFunction; - } - - static IsNonJsxSameLineTokenContext(context: FormattingContext): boolean { - return context.TokensAreOnSameLine() && context.contextNode.kind !== SyntaxKind.JsxText; - } - - static IsNonJsxElementContext(context: FormattingContext): boolean { - return context.contextNode.kind !== SyntaxKind.JsxElement; - } - - static IsJsxExpressionContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.JsxExpression; - } - - static IsNextTokenParentJsxAttribute(context: FormattingContext): boolean { - return context.nextTokenParent.kind === SyntaxKind.JsxAttribute; - } - - static IsJsxAttributeContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.JsxAttribute; - } - - static IsJsxSelfClosingElementContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.JsxSelfClosingElement; - } - - static IsNotBeforeBlockInFunctionDeclarationContext(context: FormattingContext): boolean { - return !Rules.IsFunctionDeclContext(context) && !Rules.IsBeforeBlockContext(context); - } - - static IsEndOfDecoratorContextOnSameLine(context: FormattingContext): boolean { - return context.TokensAreOnSameLine() && - context.contextNode.decorators && - Rules.NodeIsInDecoratorContext(context.currentTokenParent) && - !Rules.NodeIsInDecoratorContext(context.nextTokenParent); - } - - static NodeIsInDecoratorContext(node: Node): boolean { - while (isExpressionNode(node)) { - node = node.parent; - } - return node.kind === SyntaxKind.Decorator; - } - - static IsStartOfVariableDeclarationList(context: FormattingContext): boolean { - return context.currentTokenParent.kind === SyntaxKind.VariableDeclarationList && - context.currentTokenParent.getStart(context.sourceFile) === context.currentTokenSpan.pos; - } - - static IsNotFormatOnEnter(context: FormattingContext): boolean { - return context.formattingRequestKind !== FormattingRequestKind.FormatOnEnter; - } - - static IsModuleDeclContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.ModuleDeclaration; - } - - static IsObjectTypeContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.TypeLiteral; // && context.contextNode.parent.kind !== SyntaxKind.InterfaceDeclaration; - } - - static IsConstructorSignatureContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.ConstructSignature; - } - - static IsTypeArgumentOrParameterOrAssertion(token: TextRangeWithKind, parent: Node): boolean { - if (token.kind !== SyntaxKind.LessThanToken && token.kind !== SyntaxKind.GreaterThanToken) { + default: return false; - } - switch (parent.kind) { - case SyntaxKind.TypeReference: - case SyntaxKind.TypeAssertionExpression: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.CallExpression: - case SyntaxKind.NewExpression: - case SyntaxKind.ExpressionWithTypeArguments: - return true; - default: - return false; - - } - } - - static IsTypeArgumentOrParameterOrAssertionContext(context: FormattingContext): boolean { - return Rules.IsTypeArgumentOrParameterOrAssertion(context.currentTokenSpan, context.currentTokenParent) || - Rules.IsTypeArgumentOrParameterOrAssertion(context.nextTokenSpan, context.nextTokenParent); - } - - static IsTypeAssertionContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.TypeAssertionExpression; - } - - static IsVoidOpContext(context: FormattingContext): boolean { - return context.currentTokenSpan.kind === SyntaxKind.VoidKeyword && context.currentTokenParent.kind === SyntaxKind.VoidExpression; - } - - static IsYieldOrYieldStarWithOperand(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.YieldExpression && (context.contextNode).expression !== undefined; - } - - static IsNonNullAssertionContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.NonNullExpression; } } -} \ No newline at end of file + + function isObjectContext(context: FormattingContext): boolean { + return context.contextNode.kind === SyntaxKind.ObjectLiteralExpression; + } + + function isFunctionCallContext(context: FormattingContext): boolean { + return context.contextNode.kind === SyntaxKind.CallExpression; + } + + function isNewContext(context: FormattingContext): boolean { + return context.contextNode.kind === SyntaxKind.NewExpression; + } + + function isFunctionCallOrNewContext(context: FormattingContext): boolean { + return isFunctionCallContext(context) || isNewContext(context); + } + + function isPreviousTokenNotComma(context: FormattingContext): boolean { + return context.currentTokenSpan.kind !== SyntaxKind.CommaToken; + } + + function isNextTokenNotCloseBracket(context: FormattingContext): boolean { + return context.nextTokenSpan.kind !== SyntaxKind.CloseBracketToken; + } + + function isArrowFunctionContext(context: FormattingContext): boolean { + return context.contextNode.kind === SyntaxKind.ArrowFunction; + } + + function isNonJsxSameLineTokenContext(context: FormattingContext): boolean { + return context.TokensAreOnSameLine() && context.contextNode.kind !== SyntaxKind.JsxText; + } + + function isNonJsxElementContext(context: FormattingContext): boolean { + return context.contextNode.kind !== SyntaxKind.JsxElement; + } + + function isJsxExpressionContext(context: FormattingContext): boolean { + return context.contextNode.kind === SyntaxKind.JsxExpression; + } + + function isNextTokenParentJsxAttribute(context: FormattingContext): boolean { + return context.nextTokenParent.kind === SyntaxKind.JsxAttribute; + } + + function isJsxAttributeContext(context: FormattingContext): boolean { + return context.contextNode.kind === SyntaxKind.JsxAttribute; + } + + function isJsxSelfClosingElementContext(context: FormattingContext): boolean { + return context.contextNode.kind === SyntaxKind.JsxSelfClosingElement; + } + + function isNotBeforeBlockInFunctionDeclarationContext(context: FormattingContext): boolean { + return !isFunctionDeclContext(context) && !isBeforeBlockContext(context); + } + + function isEndOfDecoratorContextOnSameLine(context: FormattingContext): boolean { + return context.TokensAreOnSameLine() && + context.contextNode.decorators && + nodeIsInDecoratorContext(context.currentTokenParent) && + !nodeIsInDecoratorContext(context.nextTokenParent); + } + + function nodeIsInDecoratorContext(node: Node): boolean { + while (isExpressionNode(node)) { + node = node.parent; + } + return node.kind === SyntaxKind.Decorator; + } + + function isStartOfVariableDeclarationList(context: FormattingContext): boolean { + return context.currentTokenParent.kind === SyntaxKind.VariableDeclarationList && + context.currentTokenParent.getStart(context.sourceFile) === context.currentTokenSpan.pos; + } + + function isNotFormatOnEnter(context: FormattingContext): boolean { + return context.formattingRequestKind !== FormattingRequestKind.FormatOnEnter; + } + + function isModuleDeclContext(context: FormattingContext): boolean { + return context.contextNode.kind === SyntaxKind.ModuleDeclaration; + } + + function isObjectTypeContext(context: FormattingContext): boolean { + return context.contextNode.kind === SyntaxKind.TypeLiteral; // && context.contextNode.parent.kind !== SyntaxKind.InterfaceDeclaration; + } + + function isConstructorSignatureContext(context: FormattingContext): boolean { + return context.contextNode.kind === SyntaxKind.ConstructSignature; + } + + function isTypeArgumentOrParameterOrAssertion(token: TextRangeWithKind, parent: Node): boolean { + if (token.kind !== SyntaxKind.LessThanToken && token.kind !== SyntaxKind.GreaterThanToken) { + return false; + } + switch (parent.kind) { + case SyntaxKind.TypeReference: + case SyntaxKind.TypeAssertionExpression: + case SyntaxKind.TypeAliasDeclaration: + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.MethodSignature: + case SyntaxKind.CallSignature: + case SyntaxKind.ConstructSignature: + case SyntaxKind.CallExpression: + case SyntaxKind.NewExpression: + case SyntaxKind.ExpressionWithTypeArguments: + return true; + default: + return false; + + } + } + + function isTypeArgumentOrParameterOrAssertionContext(context: FormattingContext): boolean { + return isTypeArgumentOrParameterOrAssertion(context.currentTokenSpan, context.currentTokenParent) || + isTypeArgumentOrParameterOrAssertion(context.nextTokenSpan, context.nextTokenParent); + } + + function isTypeAssertionContext(context: FormattingContext): boolean { + return context.contextNode.kind === SyntaxKind.TypeAssertionExpression; + } + + function isVoidOpContext(context: FormattingContext): boolean { + return context.currentTokenSpan.kind === SyntaxKind.VoidKeyword && context.currentTokenParent.kind === SyntaxKind.VoidExpression; + } + + function isYieldOrYieldStarWithOperand(context: FormattingContext): boolean { + return context.contextNode.kind === SyntaxKind.YieldExpression && (context.contextNode).expression !== undefined; + } + + function isNonNullAssertionContext(context: FormattingContext): boolean { + return context.contextNode.kind === SyntaxKind.NonNullExpression; + } +} diff --git a/src/services/formatting/rulesMap.ts b/src/services/formatting/rulesMap.ts index 3b04308ebe8..d44e47a763a 100644 --- a/src/services/formatting/rulesMap.ts +++ b/src/services/formatting/rulesMap.ts @@ -1,60 +1,59 @@ -/// +/// /* @internal */ namespace ts.formatting { - export class RulesMap { - public map: RulesBucket[]; - public mapRowLength: number; + export function getFormatContext(options: FormatCodeSettings): formatting.FormatContext { + return { options, getRule: getRulesMap() }; + } - constructor(rules: ReadonlyArray) { - this.mapRowLength = SyntaxKind.LastToken + 1; - this.map = new Array(this.mapRowLength * this.mapRowLength); + let rulesMapCache: RulesMap | undefined; - // This array is used only during construction of the rulesbucket in the map - const rulesBucketConstructionStateList: RulesBucketConstructionState[] = new Array(this.map.length); - for (const rule of rules) { - this.FillRule(rule, rulesBucketConstructionStateList); - } + function getRulesMap(): RulesMap { + if (rulesMapCache === undefined) { + rulesMapCache = createRulesMap(getAllRules()); } + return rulesMapCache; + } - private GetRuleBucketIndex(row: number, column: number): number { - Debug.assert(row <= SyntaxKind.LastKeyword && column <= SyntaxKind.LastKeyword, "Must compute formatting context from tokens"); - return (row * this.mapRowLength) + column; - } + export type RulesMap = (context: FormattingContext) => Rule | undefined; + function createRulesMap(rules: ReadonlyArray): RulesMap { + const map = buildMap(rules); + return context => { + const bucket = map[getRuleBucketIndex(context.currentTokenSpan.kind, context.nextTokenSpan.kind)]; + return bucket && find(bucket, rule => every(rule.context, c => c(context))); + }; + } - private FillRule(rule: Rule, rulesBucketConstructionStateList: RulesBucketConstructionState[]): void { - const specificRule = rule.descriptor.leftTokenRange.isSpecific() && rule.descriptor.rightTokenRange.isSpecific(); + function buildMap(rules: ReadonlyArray): ReadonlyArray> { + // Map from bucket index to array of rules + const map: Rule[][] = new Array(mapRowLength * mapRowLength); + // This array is used only during construction of the rulesbucket in the map + const rulesBucketConstructionStateList = new Array(map.length); + for (const rule of rules) { + const specificRule = rule.leftTokenRange.isSpecific && rule.rightTokenRange.isSpecific; - rule.descriptor.leftTokenRange.GetTokens().forEach((left) => { - rule.descriptor.rightTokenRange.GetTokens().forEach((right) => { - const rulesBucketIndex = this.GetRuleBucketIndex(left, right); - - let rulesBucket = this.map[rulesBucketIndex]; + for (const left of rule.leftTokenRange.tokens) { + for (const right of rule.rightTokenRange.tokens) { + const index = getRuleBucketIndex(left, right); + let rulesBucket = map[index]; if (rulesBucket === undefined) { - rulesBucket = this.map[rulesBucketIndex] = new RulesBucket(); - } - - rulesBucket.AddRule(rule, specificRule, rulesBucketConstructionStateList, rulesBucketIndex); - }); - }); - } - - public GetRule(context: FormattingContext): Rule | undefined { - const bucketIndex = this.GetRuleBucketIndex(context.currentTokenSpan.kind, context.nextTokenSpan.kind); - const bucket = this.map[bucketIndex]; - if (bucket) { - for (const rule of bucket.Rules()) { - if (rule.operation.context.InContext(context)) { - return rule; + rulesBucket = map[index] = []; } + addRule(rulesBucket, rule.rule, specificRule, rulesBucketConstructionStateList, index); } } - return undefined; } + return map; + } + + function getRuleBucketIndex(row: number, column: number): number { + Debug.assert(row <= SyntaxKind.LastKeyword && column <= SyntaxKind.LastKeyword, "Must compute formatting context from tokens"); + return (row * mapRowLength) + column; } const maskBitSize = 5; - const mask = 0x1f; + const mask = 0b11111; // MaskBitSize bits + const mapRowLength = SyntaxKind.LastToken + 1; enum RulesPosition { IgnoreRulesSpecific = 0, @@ -65,92 +64,44 @@ namespace ts.formatting { NoContextRulesAny = maskBitSize * 5 } - export class RulesBucketConstructionState { - private rulesInsertionIndexBitmap: number; - - constructor() { - //// The Rules list contains all the inserted rules into a rulebucket in the following order: - //// 1- Ignore rules with specific token combination - //// 2- Ignore rules with any token combination - //// 3- Context rules with specific token combination - //// 4- Context rules with any token combination - //// 5- Non-context rules with specific token combination - //// 6- Non-context rules with any token combination - //// - //// The member rulesInsertionIndexBitmap is used to describe the number of rules - //// in each sub-bucket (above) hence can be used to know the index of where to insert - //// the next rule. It's a bitmap which contains 6 different sections each is given 5 bits. - //// - //// Example: - //// In order to insert a rule to the end of sub-bucket (3), we get the index by adding - //// the values in the bitmap segments 3rd, 2nd, and 1st. - this.rulesInsertionIndexBitmap = 0; - } - - public GetInsertionIndex(maskPosition: RulesPosition): number { - let index = 0; - - let pos = 0; - let indexBitmap = this.rulesInsertionIndexBitmap; - - while (pos <= maskPosition) { - index += (indexBitmap & mask); - indexBitmap >>= maskBitSize; - pos += maskBitSize; - } - - return index; - } - - public IncreaseInsertionIndex(maskPosition: RulesPosition): void { - let value = (this.rulesInsertionIndexBitmap >> maskPosition) & mask; - value++; - Debug.assert((value & mask) === value, "Adding more rules into the sub-bucket than allowed. Maximum allowed is 32 rules."); - - let temp = this.rulesInsertionIndexBitmap & ~(mask << maskPosition); - temp |= value << maskPosition; - - this.rulesInsertionIndexBitmap = temp; - } + // The Rules list contains all the inserted rules into a rulebucket in the following order: + // 1- Ignore rules with specific token combination + // 2- Ignore rules with any token combination + // 3- Context rules with specific token combination + // 4- Context rules with any token combination + // 5- Non-context rules with specific token combination + // 6- Non-context rules with any token combination + // + // The member rulesInsertionIndexBitmap is used to describe the number of rules + // in each sub-bucket (above) hence can be used to know the index of where to insert + // the next rule. It's a bitmap which contains 6 different sections each is given 5 bits. + // + // Example: + // In order to insert a rule to the end of sub-bucket (3), we get the index by adding + // the values in the bitmap segments 3rd, 2nd, and 1st. + function addRule(rules: Rule[], rule: Rule, specificTokens: boolean, constructionState: number[], rulesBucketIndex: number): void { + const position = rule.action === RuleAction.Ignore + ? specificTokens ? RulesPosition.IgnoreRulesSpecific : RulesPosition.IgnoreRulesAny + : rule.context !== anyContext + ? specificTokens ? RulesPosition.ContextRulesSpecific : RulesPosition.ContextRulesAny + : specificTokens ? RulesPosition.NoContextRulesSpecific : RulesPosition.NoContextRulesAny; + const state = constructionState[rulesBucketIndex] || 0; + rules.splice(getInsertionIndex(state, position), 0, rule); + constructionState[rulesBucketIndex] = increaseInsertionIndex(state, position); } - export class RulesBucket { - private rules: Rule[]; - - constructor() { - this.rules = []; + function getInsertionIndex(indexBitmap: number, maskPosition: RulesPosition) { + let index = 0; + for (let pos = 0; pos <= maskPosition; pos += maskBitSize) { + index += indexBitmap & mask; + indexBitmap >>= maskBitSize; } + return index; + } - public Rules(): Rule[] { - return this.rules; - } - - public AddRule(rule: Rule, specificTokens: boolean, constructionState: RulesBucketConstructionState[], rulesBucketIndex: number): void { - let position: RulesPosition; - - if (rule.operation.action === RuleAction.Ignore) { - position = specificTokens ? - RulesPosition.IgnoreRulesSpecific : - RulesPosition.IgnoreRulesAny; - } - else if (!rule.operation.context.IsAny()) { - position = specificTokens ? - RulesPosition.ContextRulesSpecific : - RulesPosition.ContextRulesAny; - } - else { - position = specificTokens ? - RulesPosition.NoContextRulesSpecific : - RulesPosition.NoContextRulesAny; - } - - let state = constructionState[rulesBucketIndex]; - if (state === undefined) { - state = constructionState[rulesBucketIndex] = new RulesBucketConstructionState(); - } - const index = state.GetInsertionIndex(position); - this.rules.splice(index, 0, rule); - state.IncreaseInsertionIndex(position); - } + function increaseInsertionIndex(indexBitmap: number, maskPosition: RulesPosition): number { + const value = ((indexBitmap >> maskPosition) & mask) + 1; + Debug.assert((value & mask) === value, "Adding more rules into the sub-bucket than allowed. Maximum allowed is 32 rules."); + return (indexBitmap & ~(mask << maskPosition)) | (value << maskPosition); } } \ No newline at end of file diff --git a/src/services/formatting/rulesProvider.ts b/src/services/formatting/rulesProvider.ts deleted file mode 100644 index fcf08541890..00000000000 --- a/src/services/formatting/rulesProvider.ts +++ /dev/null @@ -1,30 +0,0 @@ -/// - -/* @internal */ -namespace ts.formatting { - export class RulesProvider { - private globalRules: Rules; - private options: ts.FormatCodeSettings; - private rulesMap: RulesMap; - - constructor() { - this.globalRules = new Rules(); - const activeRules = this.globalRules.HighPriorityCommonRules.concat(this.globalRules.UserConfigurableRules).concat(this.globalRules.LowPriorityCommonRules); - this.rulesMap = new RulesMap(activeRules); - } - - public getRulesMap() { - return this.rulesMap; - } - - public getFormatOptions(): Readonly { - return this.options; - } - - public ensureUpToDate(options: ts.FormatCodeSettings) { - if (!this.options || !ts.compareDataObjects(this.options, options)) { - this.options = ts.clone(options); - } - } - } -} \ No newline at end of file diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 7701cff182c..5afe4cb1d31 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -1,5 +1,3 @@ -/// - /* @internal */ namespace ts.formatting { export namespace SmartIndenter { diff --git a/src/services/formatting/tokenRange.ts b/src/services/formatting/tokenRange.ts deleted file mode 100644 index 31e15bc738d..00000000000 --- a/src/services/formatting/tokenRange.ts +++ /dev/null @@ -1,124 +0,0 @@ -/// - -/* @internal */ -namespace ts.formatting { - export namespace Shared { - const allTokens: SyntaxKind[] = []; - for (let token = SyntaxKind.FirstToken; token <= SyntaxKind.LastToken; token++) { - allTokens.push(token); - } - - class TokenValuesAccess implements TokenRange { - constructor(private readonly tokens: SyntaxKind[] = []) { } - - public GetTokens(): SyntaxKind[] { - return this.tokens; - } - - public Contains(token: SyntaxKind): boolean { - return this.tokens.indexOf(token) >= 0; - } - - public isSpecific() { return true; } - } - - class TokenSingleValueAccess implements TokenRange { - constructor(private readonly token: SyntaxKind) {} - - public GetTokens(): SyntaxKind[] { - return [this.token]; - } - - public Contains(tokenValue: SyntaxKind): boolean { - return tokenValue === this.token; - } - - public isSpecific() { return true; } - } - - class TokenAllAccess implements TokenRange { - public GetTokens(): SyntaxKind[] { - return allTokens; - } - - public Contains(): boolean { - return true; - } - - public toString(): string { - return "[allTokens]"; - } - - public isSpecific() { return false; } - } - - class TokenAllExceptAccess implements TokenRange { - constructor(private readonly except: SyntaxKind) {} - - public GetTokens(): SyntaxKind[] { - return allTokens.filter(t => t !== this.except); - } - - public Contains(token: SyntaxKind): boolean { - return token !== this.except; - } - - public isSpecific() { return false; } - } - - export interface TokenRange { - GetTokens(): SyntaxKind[]; - Contains(token: SyntaxKind): boolean; - isSpecific(): boolean; - } - - export namespace TokenRange { - export function FromToken(token: SyntaxKind): TokenRange { - return new TokenSingleValueAccess(token); - } - - export function FromTokens(tokens: SyntaxKind[]): TokenRange { - return new TokenValuesAccess(tokens); - } - - export function FromRange(from: SyntaxKind, to: SyntaxKind, except: SyntaxKind[] = []): TokenRange { - const tokens: SyntaxKind[] = []; - for (let token = from; token <= to; token++) { - if (ts.indexOf(except, token) < 0) { - tokens.push(token); - } - } - return new TokenValuesAccess(tokens); - } - - export function AnyExcept(token: SyntaxKind): TokenRange { - return new TokenAllExceptAccess(token); - } - - // tslint:disable variable-name (TODO) - export const Any: TokenRange = new TokenAllAccess(); - export const AnyIncludingMultilineComments = TokenRange.FromTokens([...allTokens, SyntaxKind.MultiLineCommentTrivia]); - export const Keywords = TokenRange.FromRange(SyntaxKind.FirstKeyword, SyntaxKind.LastKeyword); - export const BinaryOperators = TokenRange.FromRange(SyntaxKind.FirstBinaryOperator, SyntaxKind.LastBinaryOperator); - export const BinaryKeywordOperators = TokenRange.FromTokens([ - SyntaxKind.InKeyword, SyntaxKind.InstanceOfKeyword, SyntaxKind.OfKeyword, SyntaxKind.AsKeyword, SyntaxKind.IsKeyword]); - export const UnaryPrefixOperators = TokenRange.FromTokens([ - SyntaxKind.PlusPlusToken, SyntaxKind.MinusMinusToken, SyntaxKind.TildeToken, SyntaxKind.ExclamationToken]); - export const UnaryPrefixExpressions = TokenRange.FromTokens([ - SyntaxKind.NumericLiteral, SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.OpenBracketToken, - SyntaxKind.OpenBraceToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]); - export const UnaryPreincrementExpressions = TokenRange.FromTokens([ - SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]); - export const UnaryPostincrementExpressions = TokenRange.FromTokens([ - SyntaxKind.Identifier, SyntaxKind.CloseParenToken, SyntaxKind.CloseBracketToken, SyntaxKind.NewKeyword]); - export const UnaryPredecrementExpressions = TokenRange.FromTokens([ - SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]); - export const UnaryPostdecrementExpressions = TokenRange.FromTokens([ - SyntaxKind.Identifier, SyntaxKind.CloseParenToken, SyntaxKind.CloseBracketToken, SyntaxKind.NewKeyword]); - export const Comments = TokenRange.FromTokens([SyntaxKind.SingleLineCommentTrivia, SyntaxKind.MultiLineCommentTrivia]); - export const TypeNames = TokenRange.FromTokens([ - SyntaxKind.Identifier, SyntaxKind.NumberKeyword, SyntaxKind.StringKeyword, SyntaxKind.BooleanKeyword, - SyntaxKind.SymbolKeyword, SyntaxKind.VoidKeyword, SyntaxKind.AnyKeyword]); - } - } -} diff --git a/src/services/refactors/convertFunctionToEs6Class.ts b/src/services/refactors/convertFunctionToEs6Class.ts index f5951bd26e4..b66d14ee449 100644 --- a/src/services/refactors/convertFunctionToEs6Class.ts +++ b/src/services/refactors/convertFunctionToEs6Class.ts @@ -50,7 +50,7 @@ namespace ts.refactor.convertFunctionToES6Class { const { file: sourceFile } = context; const ctorSymbol = getConstructorSymbol(context); - const newLine = context.rulesProvider.getFormatOptions().newLineCharacter; + const newLine = context.formatContext.options.newLineCharacter; const deletedNodes: Node[] = []; const deletes: (() => any)[] = []; diff --git a/src/services/services.ts b/src/services/services.ts index 04a8e148b73..37298c8eba8 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -33,9 +33,6 @@ namespace ts { /** The version of the language service API */ export const servicesVersion = "0.7"; - /* @internal */ - let ruleProvider: formatting.RulesProvider; - function createNode(kind: TKind, pos: number, end: number, parent?: Node): NodeObject | TokenObject | IdentifierObject { const node = isNodeKind(kind) ? new NodeObject(kind, pos, end) : kind === SyntaxKind.Identifier ? new IdentifierObject(SyntaxKind.Identifier, pos, end) : @@ -1157,7 +1154,6 @@ namespace ts { documentRegistry: DocumentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory())): LanguageService { const syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host); - ruleProvider = ruleProvider || new formatting.RulesProvider(); let program: Program; let lastProjectVersion: string; let lastTypesRootVersion = 0; @@ -1187,11 +1183,6 @@ namespace ts { return sourceFile; } - function getRuleProvider(options: FormatCodeSettings) { - ruleProvider.ensureUpToDate(options); - return ruleProvider; - } - function synchronizeHostData(): void { // perform fast check if host supports it if (host.getProjectVersion) { @@ -1429,7 +1420,6 @@ namespace ts { function getCompletionEntryDetails(fileName: string, position: number, name: string, formattingOptions?: FormatCodeSettings, source?: string): CompletionEntryDetails { synchronizeHostData(); - const ruleProvider = formattingOptions ? getRuleProvider(formattingOptions) : undefined; return Completions.getCompletionEntryDetails( program.getTypeChecker(), log, @@ -1439,7 +1429,7 @@ namespace ts { { name, source }, program.getSourceFiles(), host, - ruleProvider); + formattingOptions && formatting.getFormatContext(formattingOptions)); } function getCompletionEntrySymbol(fileName: string, position: number, name: string, source?: string): Symbol { @@ -1838,32 +1828,27 @@ namespace ts { function getFormattingEditsForRange(fileName: string, start: number, end: number, options: FormatCodeOptions | FormatCodeSettings): TextChange[] { const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - const settings = toEditorSettings(options); - return formatting.formatSelection(start, end, sourceFile, getRuleProvider(settings), settings); + return formatting.formatSelection(start, end, sourceFile, formatting.getFormatContext(toEditorSettings(options))); } function getFormattingEditsForDocument(fileName: string, options: FormatCodeOptions | FormatCodeSettings): TextChange[] { - const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - const settings = toEditorSettings(options); - return formatting.formatDocument(sourceFile, getRuleProvider(settings), settings); + return formatting.formatDocument(syntaxTreeCache.getCurrentSourceFile(fileName), formatting.getFormatContext(toEditorSettings(options))); } function getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions | FormatCodeSettings): TextChange[] { const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - const settings = toEditorSettings(options); + const formatContext = formatting.getFormatContext(toEditorSettings(options)); if (!isInComment(sourceFile, position)) { - if (key === "{") { - return formatting.formatOnOpeningCurly(position, sourceFile, getRuleProvider(settings), settings); - } - else if (key === "}") { - return formatting.formatOnClosingCurly(position, sourceFile, getRuleProvider(settings), settings); - } - else if (key === ";") { - return formatting.formatOnSemicolon(position, sourceFile, getRuleProvider(settings), settings); - } - else if (key === "\n") { - return formatting.formatOnEnter(position, sourceFile, getRuleProvider(settings), settings); + switch (key) { + case "{": + return formatting.formatOnOpeningCurly(position, sourceFile, formatContext); + case "}": + return formatting.formatOnClosingCurly(position, sourceFile, formatContext); + case ";": + return formatting.formatOnSemicolon(position, sourceFile, formatContext); + case "\n": + return formatting.formatOnEnter(position, sourceFile, formatContext); } } @@ -1875,11 +1860,11 @@ namespace ts { const sourceFile = getValidSourceFile(fileName); const span = createTextSpanFromBounds(start, end); const newLineCharacter = getNewLineOrDefaultFromHost(host); - const rulesProvider = getRuleProvider(formatOptions); + const formatContext = formatting.getFormatContext(formatOptions); return flatMap(deduplicate(errorCodes, equateValues, compareValues), errorCode => { cancellationToken.throwIfCancellationRequested(); - return codefix.getFixes({ errorCode, sourceFile, span, program, newLineCharacter, host, cancellationToken, rulesProvider }); + return codefix.getFixes({ errorCode, sourceFile, span, program, newLineCharacter, host, cancellationToken, formatContext }); }); } @@ -2104,7 +2089,7 @@ namespace ts { program: getProgram(), newLineCharacter: formatOptions ? formatOptions.newLineCharacter : host.getNewLine(), host, - rulesProvider: getRuleProvider(formatOptions), + formatContext: formatting.getFormatContext(formatOptions), cancellationToken, }; } diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index bc3a8e27ef0..7c4e25537ef 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -188,7 +188,7 @@ namespace ts.textChanges { export interface TextChangesContext { newLineCharacter: string; - rulesProvider: formatting.RulesProvider; + formatContext: ts.formatting.FormatContext; } export class ChangeTracker { @@ -196,7 +196,7 @@ namespace ts.textChanges { private readonly newLineCharacter: string; public static fromContext(context: TextChangesContext): ChangeTracker { - return new ChangeTracker(context.newLineCharacter === "\n" ? NewLineKind.LineFeed : NewLineKind.CarriageReturnLineFeed, context.rulesProvider); + return new ChangeTracker(context.newLineCharacter === "\n" ? NewLineKind.LineFeed : NewLineKind.CarriageReturnLineFeed, context.formatContext); } public static with(context: TextChangesContext, cb: (tracker: ChangeTracker) => void): FileTextChanges[] { @@ -207,7 +207,7 @@ namespace ts.textChanges { constructor( private readonly newLine: NewLineKind, - private readonly rulesProvider: formatting.RulesProvider, + private readonly formatContext: ts.formatting.FormatContext, private readonly validator?: (text: NonFormattedText) => void) { this.newLineCharacter = getNewLineCharacter({ newLine }); } @@ -475,7 +475,7 @@ namespace ts.textChanges { options: {} }); // use the same indentation as 'after' item - const indentation = formatting.SmartIndenter.findFirstNonWhitespaceColumn(afterStartLinePosition, afterStart, sourceFile, this.rulesProvider.getFormatOptions()); + const indentation = formatting.SmartIndenter.findFirstNonWhitespaceColumn(afterStartLinePosition, afterStart, sourceFile, this.formatContext.options); // insert element before the line break on the line that contains 'after' element let insertPos = skipTrivia(sourceFile.text, end, /*stopAfterLineBreak*/ true, /*stopAtComments*/ false); if (insertPos !== end && isLineBreak(sourceFile.text.charCodeAt(insertPos - 1))) { @@ -562,7 +562,7 @@ namespace ts.textChanges { this.validator(nonformattedText); } - const formatOptions = this.rulesProvider.getFormatOptions(); + const { options: formatOptions } = this.formatContext; const posStartsLine = getLineStartPositionForPosition(pos, sourceFile) === pos; const initialIndentation = @@ -578,7 +578,7 @@ namespace ts.textChanges { ? (formatOptions.indentSize || 0) : 0; - return applyFormatting(nonformattedText, sourceFile, initialIndentation, delta, this.rulesProvider); + return applyFormatting(nonformattedText, sourceFile, initialIndentation, delta, this.formatContext); } private static normalize(changes: Change[]): Change[] { @@ -605,14 +605,14 @@ namespace ts.textChanges { return { text: writer.getText(), node: assignPositionsToNode(node) }; } - function applyFormatting(nonFormattedText: NonFormattedText, sourceFile: SourceFile, initialIndentation: number, delta: number, rulesProvider: formatting.RulesProvider) { + function applyFormatting(nonFormattedText: NonFormattedText, sourceFile: SourceFile, initialIndentation: number, delta: number, formatContext: ts.formatting.FormatContext) { const lineMap = computeLineStarts(nonFormattedText.text); const file: SourceFileLike = { text: nonFormattedText.text, lineMap, getLineAndCharacterOfPosition: pos => computeLineAndCharacterOfPosition(lineMap, pos) }; - const changes = formatting.formatNodeGivenIndentation(nonFormattedText.node, file, sourceFile.languageVariant, initialIndentation, delta, rulesProvider); + const changes = formatting.formatNodeGivenIndentation(nonFormattedText.node, file, sourceFile.languageVariant, initialIndentation, delta, formatContext); return applyChanges(nonFormattedText.text, changes); } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index f59f6e56e91..1ed44d29f95 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1068,20 +1068,19 @@ namespace ts { return createTextSpanFromBounds(range.pos, range.end); } + export const typeKeywords: ReadonlyArray = [ + SyntaxKind.AnyKeyword, + SyntaxKind.BooleanKeyword, + SyntaxKind.NeverKeyword, + SyntaxKind.NumberKeyword, + SyntaxKind.ObjectKeyword, + SyntaxKind.StringKeyword, + SyntaxKind.SymbolKeyword, + SyntaxKind.VoidKeyword, + ]; + export function isTypeKeyword(kind: SyntaxKind): boolean { - switch (kind) { - case SyntaxKind.AnyKeyword: - case SyntaxKind.BooleanKeyword: - case SyntaxKind.NeverKeyword: - case SyntaxKind.NumberKeyword: - case SyntaxKind.ObjectKeyword: - case SyntaxKind.StringKeyword: - case SyntaxKind.SymbolKeyword: - case SyntaxKind.VoidKeyword: - return true; - default: - return false; - } + return contains(typeKeywords, kind); } /** True if the symbol is for an external module, as opposed to a namespace. */ From 6b08f3b99dc1fa72b66216b2a072eaf8382df3ee Mon Sep 17 00:00:00 2001 From: csigs Date: Wed, 8 Nov 2017 23:10:37 +0000 Subject: [PATCH 191/235] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl index 17236daf66b..bd78324f196 100644 --- a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2240,6 +2240,15 @@ + + + + + + + + + @@ -2969,6 +2978,15 @@ + + + + + + + + + @@ -3707,6 +3725,18 @@ + + + + + + + + + + + + @@ -3938,6 +3968,12 @@ + + + + + + @@ -4211,6 +4247,24 @@ + + + + + + + + + + + + + + + + + + From c1c79267352619c671d65d20878f1cbc6d325ccb Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 8 Nov 2017 15:18:35 -0800 Subject: [PATCH 192/235] Revert "Add TupleBase with unusable mutating Array methods" This reverts commits 4385444c4488f7d0fe802e58b7de303e088e0a01, 2399d58, es55de3, 888da3c --- src/compiler/checker.ts | 11 +++--- src/lib/es5.d.ts | 17 --------- .../arityAndOrderCompatibility01.errors.txt | 2 +- .../reference/arityAndOrderCompatibility01.js | 2 +- .../arityAndOrderCompatibility01.symbols | 4 +-- .../arityAndOrderCompatibility01.types | 4 +-- ...nmentCompatBetweenTupleAndArray.errors.txt | 18 +++++----- .../baselines/reference/tupleTypes.errors.txt | 36 +++++++++---------- .../typeInferenceWithTupleType.errors.txt | 31 ---------------- .../typeInferenceWithTupleType.symbols | 4 +-- .../typeInferenceWithTupleType.types | 8 ++--- .../tuple/arityAndOrderCompatibility01.ts | 2 +- 12 files changed, 41 insertions(+), 98 deletions(-) delete mode 100644 tests/baselines/reference/typeInferenceWithTupleType.errors.txt diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 264b5dad105..5aed0596ae2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -330,7 +330,6 @@ namespace ts { let globalFunctionType: ObjectType; let globalArrayType: GenericType; let globalReadonlyArrayType: GenericType; - let globalTupleBaseType: GenericType; let globalStringType: ObjectType; let globalNumberType: ObjectType; let globalBooleanType: ObjectType; @@ -773,7 +772,7 @@ namespace ts { * @param parameterName a name of the parameter to get the symbols for. * @return a tuple of two symbols */ - function getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: __String): Symbol[] { + function getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: __String): [Symbol, Symbol] { const constructorDeclaration = parameter.parent; const classDeclaration = parameter.parent.parent; @@ -4993,7 +4992,7 @@ namespace ts { function getBaseTypes(type: InterfaceType): BaseType[] { if (!type.resolvedBaseTypes) { if (type.objectFlags & ObjectFlags.Tuple) { - type.resolvedBaseTypes = [createTypeFromGenericGlobalType(globalTupleBaseType, [getUnionType(type.typeParameters)])]; + type.resolvedBaseTypes = [createArrayType(getUnionType(type.typeParameters))]; } else if (type.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { if (type.symbol.flags & SymbolFlags.Class) { @@ -10018,7 +10017,7 @@ namespace ts { const typeParameters = type.typeParameters || emptyArray; let variances = type.variances; if (!variances) { - if (type === globalArrayType || type === globalReadonlyArrayType || type === globalTupleBaseType) { + if (type === globalArrayType || type === globalReadonlyArrayType) { // Arrays are known to be covariant, no need to spend time computing this variances = [Variance.Covariant]; } @@ -10347,7 +10346,7 @@ namespace ts { function isArrayLikeType(type: Type): boolean { // A type is array-like if it is a reference to the global Array or global ReadonlyArray type, // or if it is not the undefined or null type and if it is assignable to ReadonlyArray - return getObjectFlags(type) & ObjectFlags.Reference && ((type).target === globalArrayType || (type).target === globalReadonlyArrayType || (type as TypeReference).target === globalTupleBaseType) || + return getObjectFlags(type) & ObjectFlags.Reference && ((type).target === globalArrayType || (type).target === globalReadonlyArrayType) || !(type.flags & TypeFlags.Nullable) && isTypeAssignableTo(type, anyReadonlyArrayType); } @@ -24524,9 +24523,7 @@ namespace ts { anyArrayType = createArrayType(anyType); autoArrayType = createArrayType(autoType); - // TODO: ReadonlyArray and TupleBase should always be available, but haven't been required previously globalReadonlyArrayType = getGlobalTypeOrUndefined("ReadonlyArray" as __String, /*arity*/ 1); - globalTupleBaseType = getGlobalTypeOrUndefined("TupleBase" as __String, /*arity*/ 1) || globalArrayType; anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType; globalThisType = getGlobalTypeOrUndefined("ThisType" as __String, /*arity*/ 1); } diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index d3760e3a310..fd2ae5b3fdf 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1240,23 +1240,6 @@ interface ArrayConstructor { declare const Array: ArrayConstructor; -interface TupleBase extends Array { - /** Mutation is not allowed on tuples. Do not use this method. */ - push: never; - /** Mutation is not allowed on tuples. Do not use this method. */ - pop: never; - /** Mutation is not allowed on tuples. Do not use this method. */ - reverse: never; - /** Mutation is not allowed on tuples. Do not use this method. */ - sort: never; - /** Mutation is not allowed on tuples. Do not use this method. */ - shift: never; - /** Mutation is not allowed on tuples. Do not use this method. */ - unshift: never; - /** Mutation is not allowed on tuples. Do not use this method. */ - splice: never; -} - interface TypedPropertyDescriptor { enumerable?: boolean; configurable?: boolean; diff --git a/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt b/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt index 273d1f3b318..4d6fbd063ae 100644 --- a/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt +++ b/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt @@ -40,7 +40,7 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(32,5): error ==== tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts (19 errors) ==== - interface StrNum extends TupleBase { + interface StrNum extends Array { 0: string; 1: number; length: 2; diff --git a/tests/baselines/reference/arityAndOrderCompatibility01.js b/tests/baselines/reference/arityAndOrderCompatibility01.js index e097b72594e..bf7736a80c9 100644 --- a/tests/baselines/reference/arityAndOrderCompatibility01.js +++ b/tests/baselines/reference/arityAndOrderCompatibility01.js @@ -1,5 +1,5 @@ //// [arityAndOrderCompatibility01.ts] -interface StrNum extends TupleBase { +interface StrNum extends Array { 0: string; 1: number; length: 2; diff --git a/tests/baselines/reference/arityAndOrderCompatibility01.symbols b/tests/baselines/reference/arityAndOrderCompatibility01.symbols index 8305819f593..3a5d55dc1e6 100644 --- a/tests/baselines/reference/arityAndOrderCompatibility01.symbols +++ b/tests/baselines/reference/arityAndOrderCompatibility01.symbols @@ -1,7 +1,7 @@ === tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts === -interface StrNum extends TupleBase { +interface StrNum extends Array { >StrNum : Symbol(StrNum, Decl(arityAndOrderCompatibility01.ts, 0, 0)) ->TupleBase : Symbol(TupleBase, Decl(lib.d.ts, --, --)) +>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) 0: string; 1: number; diff --git a/tests/baselines/reference/arityAndOrderCompatibility01.types b/tests/baselines/reference/arityAndOrderCompatibility01.types index 67a02599c40..80e91fbd2e7 100644 --- a/tests/baselines/reference/arityAndOrderCompatibility01.types +++ b/tests/baselines/reference/arityAndOrderCompatibility01.types @@ -1,7 +1,7 @@ === tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts === -interface StrNum extends TupleBase { +interface StrNum extends Array { >StrNum : StrNum ->TupleBase : TupleBase +>Array : T[] 0: string; 1: number; diff --git a/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt b/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt index 53073a5300a..03dcee9baf3 100644 --- a/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt +++ b/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt @@ -1,9 +1,8 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatBetweenTupleAndArray.ts(17,1): error TS2322: Type '[number, string]' is not assignable to type 'number[]'. - Types of property 'concat' are incompatible. - Type '{ (...items: ReadonlyArray[]): (string | number)[]; (...items: (string | number | ReadonlyArray)[]): (string | number)[]; }' is not assignable to type '{ (...items: ReadonlyArray[]): number[]; (...items: (number | ReadonlyArray)[]): number[]; }'. - Type '(string | number)[]' is not assignable to type 'number[]'. - Type 'string | number' is not assignable to type 'number'. - Type 'string' is not assignable to type 'number'. + Types of property 'pop' are incompatible. + Type '() => string | number' is not assignable to type '() => number'. + Type 'string | number' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatBetweenTupleAndArray.ts(18,1): error TS2322: Type '{}[]' is not assignable to type '[{}]'. Property '0' is missing in type '{}[]'. @@ -28,11 +27,10 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme numArray = numStrTuple; ~~~~~~~~ !!! error TS2322: Type '[number, string]' is not assignable to type 'number[]'. -!!! error TS2322: Types of property 'concat' are incompatible. -!!! error TS2322: Type '{ (...items: ReadonlyArray[]): (string | number)[]; (...items: (string | number | ReadonlyArray)[]): (string | number)[]; }' is not assignable to type '{ (...items: ReadonlyArray[]): number[]; (...items: (number | ReadonlyArray)[]): number[]; }'. -!!! error TS2322: Type '(string | number)[]' is not assignable to type 'number[]'. -!!! error TS2322: Type 'string | number' is not assignable to type 'number'. -!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! error TS2322: Types of property 'pop' are incompatible. +!!! error TS2322: Type '() => string | number' is not assignable to type '() => number'. +!!! error TS2322: Type 'string | number' is not assignable to type 'number'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. emptyObjTuple = emptyObjArray; ~~~~~~~~~~~~~ !!! error TS2322: Type '{}[]' is not assignable to type '[{}]'. diff --git a/tests/baselines/reference/tupleTypes.errors.txt b/tests/baselines/reference/tupleTypes.errors.txt index 750df3f5092..16a8f66ba79 100644 --- a/tests/baselines/reference/tupleTypes.errors.txt +++ b/tests/baselines/reference/tupleTypes.errors.txt @@ -10,17 +10,15 @@ tests/cases/compiler/tupleTypes.ts(18,1): error TS2322: Type '[number, string, n Type '3' is not assignable to type '2'. tests/cases/compiler/tupleTypes.ts(41,1): error TS2322: Type 'undefined[]' is not assignable to type '[number, string]'. tests/cases/compiler/tupleTypes.ts(47,1): error TS2322: Type '[number, string]' is not assignable to type 'number[]'. - Types of property 'concat' are incompatible. - Type '{ (...items: ReadonlyArray[]): (string | number)[]; (...items: (string | number | ReadonlyArray)[]): (string | number)[]; }' is not assignable to type '{ (...items: ReadonlyArray[]): number[]; (...items: (number | ReadonlyArray)[]): number[]; }'. - Type '(string | number)[]' is not assignable to type 'number[]'. - Type 'string | number' is not assignable to type 'number'. - Type 'string' is not assignable to type 'number'. + Types of property 'pop' are incompatible. + Type '() => string | number' is not assignable to type '() => number'. + Type 'string | number' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. tests/cases/compiler/tupleTypes.ts(49,1): error TS2322: Type '[number, {}]' is not assignable to type 'number[]'. - Types of property 'concat' are incompatible. - Type '{ (...items: ReadonlyArray[]): (number | {})[]; (...items: (number | {} | ReadonlyArray)[]): (number | {})[]; }' is not assignable to type '{ (...items: ReadonlyArray[]): number[]; (...items: (number | ReadonlyArray)[]): number[]; }'. - Type '(number | {})[]' is not assignable to type 'number[]'. - Type 'number | {}' is not assignable to type 'number'. - Type '{}' is not assignable to type 'number'. + Types of property 'pop' are incompatible. + Type '() => number | {}' is not assignable to type '() => number'. + Type 'number | {}' is not assignable to type 'number'. + Type '{}' is not assignable to type 'number'. tests/cases/compiler/tupleTypes.ts(50,1): error TS2322: Type '[number, number]' is not assignable to type '[number, string]'. Type 'number' is not assignable to type 'string'. tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is not assignable to type '[number, string]'. @@ -94,20 +92,18 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n a = a1; // Error ~ !!! error TS2322: Type '[number, string]' is not assignable to type 'number[]'. -!!! error TS2322: Types of property 'concat' are incompatible. -!!! error TS2322: Type '{ (...items: ReadonlyArray[]): (string | number)[]; (...items: (string | number | ReadonlyArray)[]): (string | number)[]; }' is not assignable to type '{ (...items: ReadonlyArray[]): number[]; (...items: (number | ReadonlyArray)[]): number[]; }'. -!!! error TS2322: Type '(string | number)[]' is not assignable to type 'number[]'. -!!! error TS2322: Type 'string | number' is not assignable to type 'number'. -!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! error TS2322: Types of property 'pop' are incompatible. +!!! error TS2322: Type '() => string | number' is not assignable to type '() => number'. +!!! error TS2322: Type 'string | number' is not assignable to type 'number'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. a = a2; a = a3; // Error ~ !!! error TS2322: Type '[number, {}]' is not assignable to type 'number[]'. -!!! error TS2322: Types of property 'concat' are incompatible. -!!! error TS2322: Type '{ (...items: ReadonlyArray[]): (number | {})[]; (...items: (number | {} | ReadonlyArray)[]): (number | {})[]; }' is not assignable to type '{ (...items: ReadonlyArray[]): number[]; (...items: (number | ReadonlyArray)[]): number[]; }'. -!!! error TS2322: Type '(number | {})[]' is not assignable to type 'number[]'. -!!! error TS2322: Type 'number | {}' is not assignable to type 'number'. -!!! error TS2322: Type '{}' is not assignable to type 'number'. +!!! error TS2322: Types of property 'pop' are incompatible. +!!! error TS2322: Type '() => number | {}' is not assignable to type '() => number'. +!!! error TS2322: Type 'number | {}' is not assignable to type 'number'. +!!! error TS2322: Type '{}' is not assignable to type 'number'. a1 = a2; // Error ~~ !!! error TS2322: Type '[number, number]' is not assignable to type '[number, string]'. diff --git a/tests/baselines/reference/typeInferenceWithTupleType.errors.txt b/tests/baselines/reference/typeInferenceWithTupleType.errors.txt deleted file mode 100644 index 9fba99de278..00000000000 --- a/tests/baselines/reference/typeInferenceWithTupleType.errors.txt +++ /dev/null @@ -1,31 +0,0 @@ -tests/cases/conformance/types/tuple/typeInferenceWithTupleType.ts(16,9): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'never' has no compatible call signatures. - - -==== tests/cases/conformance/types/tuple/typeInferenceWithTupleType.ts (1 errors) ==== - function combine(x: T, y: U): [T, U] { - return [x, y]; - } - - var combineResult = combine("string", 10); - var combineEle1 = combineResult[0]; // string - var combineEle2 = combineResult[1]; // number - - function zip(array1: T[], array2: U[]): [[T, U]] { - if (array1.length != array2.length) { - return [[undefined, undefined]]; - } - var length = array1.length; - var zipResult: [[T, U]]; - for (var i = 0; i < length; ++i) { - zipResult.push([array1[i], array2[i]]); - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'never' has no compatible call signatures. - } - return zipResult; - } - - var zipResult = zip(["foo", "bar"], [5, 6]); - var zipResultEle = zipResult[0]; // [string, number] - var zipResultEleEle = zipResult[0][0]; // string - - \ No newline at end of file diff --git a/tests/baselines/reference/typeInferenceWithTupleType.symbols b/tests/baselines/reference/typeInferenceWithTupleType.symbols index e28ea2571dd..6f3279db8c2 100644 --- a/tests/baselines/reference/typeInferenceWithTupleType.symbols +++ b/tests/baselines/reference/typeInferenceWithTupleType.symbols @@ -70,9 +70,9 @@ function zip(array1: T[], array2: U[]): [[T, U]] { >i : Symbol(i, Decl(typeInferenceWithTupleType.ts, 14, 12)) zipResult.push([array1[i], array2[i]]); ->zipResult.push : Symbol(TupleBase.push, Decl(lib.d.ts, --, --)) +>zipResult.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) >zipResult : Symbol(zipResult, Decl(typeInferenceWithTupleType.ts, 13, 7)) ->push : Symbol(TupleBase.push, Decl(lib.d.ts, --, --)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) >array1 : Symbol(array1, Decl(typeInferenceWithTupleType.ts, 8, 19)) >i : Symbol(i, Decl(typeInferenceWithTupleType.ts, 14, 12)) >array2 : Symbol(array2, Decl(typeInferenceWithTupleType.ts, 8, 31)) diff --git a/tests/baselines/reference/typeInferenceWithTupleType.types b/tests/baselines/reference/typeInferenceWithTupleType.types index e546a127758..a7f8bff6798 100644 --- a/tests/baselines/reference/typeInferenceWithTupleType.types +++ b/tests/baselines/reference/typeInferenceWithTupleType.types @@ -82,11 +82,11 @@ function zip(array1: T[], array2: U[]): [[T, U]] { >i : number zipResult.push([array1[i], array2[i]]); ->zipResult.push([array1[i], array2[i]]) : any ->zipResult.push : never +>zipResult.push([array1[i], array2[i]]) : number +>zipResult.push : (...items: [T, U][]) => number >zipResult : [[T, U]] ->push : never ->[array1[i], array2[i]] : (T | U)[] +>push : (...items: [T, U][]) => number +>[array1[i], array2[i]] : [T, U] >array1[i] : T >array1 : T[] >i : number diff --git a/tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts b/tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts index ebd7738125e..85a035d472b 100644 --- a/tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts +++ b/tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts @@ -1,4 +1,4 @@ -interface StrNum extends TupleBase { +interface StrNum extends Array { 0: string; 1: number; length: 2; From bb79308a2446266a3bff299d569620613cbabec7 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 8 Nov 2017 15:26:05 -0800 Subject: [PATCH 193/235] Use CRLF and emit test output for stdout/stderr I've got git problems and I'm not even on Windows! --- src/harness/externalCompileRunner.ts | 134 +++++++++++++-------------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/src/harness/externalCompileRunner.ts b/src/harness/externalCompileRunner.ts index 8ca0be807bf..9b8fc8c4fc5 100644 --- a/src/harness/externalCompileRunner.ts +++ b/src/harness/externalCompileRunner.ts @@ -1,67 +1,67 @@ -/// -/// -abstract class ExternalCompileRunnerBase extends RunnerBase { - abstract testDir: string; - public enumerateTestFiles() { - return Harness.IO.getDirectories(this.testDir); - } - /** Setup the runner's tests so that they are ready to be executed by the harness - * The first test should be a describe/it block that sets up the harness's compiler instance appropriately - */ - public initializeTests(): void { - // Read in and evaluate the test list - const testList = this.tests && this.tests.length ? this.tests : this.enumerateTestFiles(); - - describe(`${this.kind()} code samples`, () => { - for (const test of testList) { - this.runTest(test); - } - }); - } - private runTest(directoryName: string) { - describe(directoryName, () => { - const cp = require("child_process"); - const path = require("path"); - const fs = require("fs"); - - it("should build successfully", () => { - const cwd = path.join(__dirname, "../../", this.testDir, directoryName); - const timeout = 600000; // 600s = 10 minutes - if (fs.existsSync(path.join(cwd, "package.json"))) { - if (fs.existsSync(path.join(cwd, "package-lock.json"))) { - fs.unlinkSync(path.join(cwd, "package-lock.json")); - } - const stdio = isWorker ? "pipe" : "inherit"; - const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout, shell: true, stdio }); - if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed!`); - } - Harness.Baseline.runBaseline(`${this.kind()}/${directoryName}.log`, () => { - const result = cp.spawnSync(`node`, [path.join(__dirname, "tsc.js")], { cwd, timeout, shell: true }); - // tslint:disable-next-line:no-null-keyword - return result.status === 0 ? null : `Exit Code: ${result.status} -Standard output: -${result.stdout.toString().replace(/\r\n/g, "\n")} - - -Standard error: -${result.stderr.toString().replace(/\r\n/g, "\n")}`; - }); - }); - }); - } -} - -class UserCodeRunner extends ExternalCompileRunnerBase { - public readonly testDir = "tests/cases/user/"; - public kind(): TestRunnerKind { - return "user"; - } -} - -class DefinitelyTypedRunner extends ExternalCompileRunnerBase { - public readonly testDir = "../DefinitelyTyped/types/"; - public workingDirectory = this.testDir; - public kind(): TestRunnerKind { - return "dt"; - } -} +/// +/// +abstract class ExternalCompileRunnerBase extends RunnerBase { + abstract testDir: string; + public enumerateTestFiles() { + return Harness.IO.getDirectories(this.testDir); + } + /** Setup the runner's tests so that they are ready to be executed by the harness + * The first test should be a describe/it block that sets up the harness's compiler instance appropriately + */ + public initializeTests(): void { + // Read in and evaluate the test list + const testList = this.tests && this.tests.length ? this.tests : this.enumerateTestFiles(); + + describe(`${this.kind()} code samples`, () => { + for (const test of testList) { + this.runTest(test); + } + }); + } + private runTest(directoryName: string) { + describe(directoryName, () => { + const cp = require("child_process"); + const path = require("path"); + const fs = require("fs"); + + it("should build successfully", () => { + const cwd = path.join(__dirname, "../../", this.testDir, directoryName); + const timeout = 600000; // 600s = 10 minutes + if (fs.existsSync(path.join(cwd, "package.json"))) { + if (fs.existsSync(path.join(cwd, "package-lock.json"))) { + fs.unlinkSync(path.join(cwd, "package-lock.json")); + } + const stdio = isWorker ? "pipe" : "inherit"; + const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout, shell: true, stdio }); + if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed!`); + } + Harness.Baseline.runBaseline(`${this.kind()}/${directoryName}.log`, () => { + const result = cp.spawnSync(`node`, [path.join(__dirname, "tsc.js")], { cwd, timeout, shell: true }); + // tslint:disable-next-line:no-null-keyword + return result.status === 0 && !result.stdout.length && !result.stderr.length ? null : `Exit Code: ${result.status} +Standard output: +${result.stdout.toString().replace(/\r\n/g, "\n")} + + +Standard error: +${result.stderr.toString().replace(/\r\n/g, "\n")}`; + }); + }); + }); + } +} + +class UserCodeRunner extends ExternalCompileRunnerBase { + public readonly testDir = "tests/cases/user/"; + public kind(): TestRunnerKind { + return "user"; + } +} + +class DefinitelyTypedRunner extends ExternalCompileRunnerBase { + public readonly testDir = "../DefinitelyTyped/types/"; + public workingDirectory = this.testDir; + public kind(): TestRunnerKind { + return "dt"; + } +} From 1408a4d2b7604931687273169374f6a9d2c80c12 Mon Sep 17 00:00:00 2001 From: Adrian Leonhard Date: Thu, 9 Nov 2017 02:27:02 +0100 Subject: [PATCH 194/235] Add Symbol.species to ArrayConstructor, MapConstructor, SetConstructor, ArrayBufferConstructor. (#18652) Fix Symbol.species in RegExpConstructor and PromiseConstructor. See https://github.com/Microsoft/TypeScript/issues/2881 . --- src/lib/es2015.symbol.wellknown.d.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/lib/es2015.symbol.wellknown.d.ts b/src/lib/es2015.symbol.wellknown.d.ts index 268570ff232..23d836c6515 100644 --- a/src/lib/es2015.symbol.wellknown.d.ts +++ b/src/lib/es2015.symbol.wellknown.d.ts @@ -150,7 +150,7 @@ interface Promise { } interface PromiseConstructor { - readonly [Symbol.species]: Function; + readonly [Symbol.species]: PromiseConstructor; } interface RegExp { @@ -202,7 +202,7 @@ interface RegExp { } interface RegExpConstructor { - [Symbol.species](): RegExpConstructor; + readonly [Symbol.species]: RegExpConstructor; } interface String { @@ -283,3 +283,16 @@ interface Float32Array { interface Float64Array { readonly [Symbol.toStringTag]: "Float64Array"; } + +interface ArrayConstructor { + readonly [Symbol.species]: ArrayConstructor; +} +interface MapConstructor { + readonly [Symbol.species]: MapConstructor; +} +interface SetConstructor { + readonly [Symbol.species]: SetConstructor; +} +interface ArrayBufferConstructor { + readonly [Symbol.species]: ArrayBufferConstructor; +} \ No newline at end of file From e9841f3899ddba2052e5e68e68adfc9268afd891 Mon Sep 17 00:00:00 2001 From: "wenlu.wang" <805037171@163.com> Date: Wed, 8 Nov 2017 19:44:12 -0600 Subject: [PATCH 195/235] fix completions protected members in recursive generic types (#19192) (#19242) --- src/compiler/checker.ts | 7 +++---- ...ompletionsForRecursiveGenericTypesMember.ts | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 tests/cases/fourslash/completionsForRecursiveGenericTypesMember.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 38bc617c650..6f75bfa0d46 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15162,12 +15162,11 @@ namespace ts { if (flags & ModifierFlags.Static) { return true; } - // An instance property must be accessed through an instance of the enclosing class - if (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType) { + if (type.flags & TypeFlags.TypeParameter) { // get the original type -- represented as the type constraint of the 'this' type - type = getConstraintOfTypeParameter(type); + type = (type as TypeParameter).isThisType ? getConstraintOfTypeParameter(type) : getBaseConstraintOfType(type); } - if (!(getObjectFlags(getTargetType(type)) & ObjectFlags.ClassOrInterface && hasBaseType(type, enclosingClass))) { + if (!type || !hasBaseType(type, enclosingClass)) { error(errorNode, Diagnostics.Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1, symbolToString(prop), typeToString(enclosingClass)); return false; } diff --git a/tests/cases/fourslash/completionsForRecursiveGenericTypesMember.ts b/tests/cases/fourslash/completionsForRecursiveGenericTypesMember.ts new file mode 100644 index 00000000000..993b9eb73ac --- /dev/null +++ b/tests/cases/fourslash/completionsForRecursiveGenericTypesMember.ts @@ -0,0 +1,18 @@ +/// + +//// export class TestBase> +//// { +//// public publicMethod(p: any): void {} +//// private privateMethod(p: any): void {} +//// protected protectedMethod(p: any): void {} +//// public test(t: T): void +//// { +//// t./**/ +//// } +//// } + +goTo.marker(); + +verify.completionListContains('publicMethod'); +verify.completionListContains('privateMethod'); +verify.completionListContains('protectedMethod'); From 235356e6ffb9d9ad365758ab46ee245ec6df08d3 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 8 Nov 2017 18:15:23 -0800 Subject: [PATCH 196/235] Handle synthetic nodes correctly as namespace identifiers in system transform (#19623) * Handle synthetic nodes correctly as namespace identifiers in system transform * Add ref to issue in comment * Lock newline for ci --- src/compiler/factory.ts | 2 +- src/harness/unittests/transform.ts | 32 +++++++++++++++++++ ...nsformsCorrectly.transformAddImportStar.js | 13 ++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/transformApi/transformsCorrectly.transformAddImportStar.js diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 6a56b6da049..e8dfcbc1e94 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -4319,7 +4319,7 @@ namespace ts { const namespaceDeclaration = getNamespaceDeclarationNode(node); if (namespaceDeclaration && !isDefaultImport(node)) { const name = namespaceDeclaration.name; - return isGeneratedIdentifier(name) ? name : createIdentifier(getSourceTextOfNodeFromSourceFile(sourceFile, namespaceDeclaration.name)); + return isGeneratedIdentifier(name) ? name : createIdentifier(getSourceTextOfNodeFromSourceFile(sourceFile, name) || idText(name)); } if (node.kind === SyntaxKind.ImportDeclaration && (node).importClause) { return getGeneratedNameForNode(node); diff --git a/src/harness/unittests/transform.ts b/src/harness/unittests/transform.ts index 72f7072535c..a39249bb225 100644 --- a/src/harness/unittests/transform.ts +++ b/src/harness/unittests/transform.ts @@ -192,6 +192,38 @@ namespace ts { }; } }); + + // https://github.com/Microsoft/TypeScript/issues/19618 + testBaseline("transformAddImportStar", () => { + return ts.transpileModule("", { + transformers: { + before: [transformAddImportStar], + }, + compilerOptions: { + target: ts.ScriptTarget.ES5, + module: ts.ModuleKind.System, + newLine: NewLineKind.CarriageReturnLineFeed, + } + }).outputText; + + function transformAddImportStar(_context: ts.TransformationContext) { + return (sourceFile: ts.SourceFile): ts.SourceFile => { + return visitNode(sourceFile); + }; + function visitNode(sf: ts.SourceFile) { + // produce `import * as i0 from './comp'; + const importStar = ts.createImportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*importClause*/ ts.createImportClause( + /*name*/ undefined, + ts.createNamespaceImport(ts.createIdentifier("i0")) + ), + /*moduleSpecifier*/ ts.createLiteral("./comp1")); + return ts.updateSourceFileNode(sf, [importStar]); + } + } + }); }); } diff --git a/tests/baselines/reference/transformApi/transformsCorrectly.transformAddImportStar.js b/tests/baselines/reference/transformApi/transformsCorrectly.transformAddImportStar.js new file mode 100644 index 00000000000..167e8eaee09 --- /dev/null +++ b/tests/baselines/reference/transformApi/transformsCorrectly.transformAddImportStar.js @@ -0,0 +1,13 @@ +System.register(["./comp1"], function (exports_1, context_1) { + var __moduleName = context_1 && context_1.id; + var i0; + return { + setters: [ + function (i0_1) { + i0 = i0_1; + } + ], + execute: function () { + } + }; +}); From bfe74de0176f7eaabaf09674f5fcb9cb7248226e Mon Sep 17 00:00:00 2001 From: Yuval Greenfield Date: Wed, 8 Nov 2017 18:20:58 -0800 Subject: [PATCH 197/235] Only ignored params need underscores --- src/compiler/comments.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/comments.ts b/src/compiler/comments.ts index bb8ec9bf3e7..1fec1e9562f 100644 --- a/src/compiler/comments.ts +++ b/src/compiler/comments.ts @@ -260,7 +260,7 @@ namespace ts { } } - function emitLeadingComment(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) { + function emitLeadingComment(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) { if (!hasWrittenComment) { emitNewLineBeforeLeadingCommentOfPosition(currentLineMap, writer, rangePos, commentPos); hasWrittenComment = true; @@ -274,7 +274,7 @@ namespace ts { if (hasTrailingNewLine) { writer.writeLine(); } - else if (_kind === SyntaxKind.MultiLineCommentTrivia) { + else if (kind === SyntaxKind.MultiLineCommentTrivia) { writer.write(" "); } } From ceaeffa3ab2024aa4a8ff11a7a5d6826d1bd2bf3 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 8 Nov 2017 18:44:46 -0800 Subject: [PATCH 198/235] Fix declaration emit for imported export alias specifiers (#19852) * Badness * Revert #3641, whose original bug has been fixed by other means * Add another repro --- src/compiler/checker.ts | 1 - .../declarationEmitOfTypeofAliasedExport.js | 35 +++++++++ ...clarationEmitOfTypeofAliasedExport.symbols | 17 +++++ ...declarationEmitOfTypeofAliasedExport.types | 17 +++++ ...s6ExportClauseWithoutModuleSpecifier.types | 4 +- ...ortClauseWithoutModuleSpecifierInEs5.types | 4 +- .../exportSpecifierForAGlobal.errors.txt | 5 +- .../reference/exportSpecifierForAGlobal.js | 5 -- .../reference/exportsAndImports3-amd.symbols | 12 ++-- .../reference/exportsAndImports3-es6.symbols | 12 ++-- .../reference/exportsAndImports3.symbols | 12 ++-- .../reexportWrittenCorrectlyInDeclaration.js | 72 +++++++++++++++++++ ...xportWrittenCorrectlyInDeclaration.symbols | 29 ++++++++ ...eexportWrittenCorrectlyInDeclaration.types | 30 ++++++++ .../baselines/reference/systemModule15.types | 4 +- .../declarationEmitOfTypeofAliasedExport.ts | 8 +++ .../reexportWrittenCorrectlyInDeclaration.ts | 18 +++++ 17 files changed, 254 insertions(+), 31 deletions(-) create mode 100644 tests/baselines/reference/declarationEmitOfTypeofAliasedExport.js create mode 100644 tests/baselines/reference/declarationEmitOfTypeofAliasedExport.symbols create mode 100644 tests/baselines/reference/declarationEmitOfTypeofAliasedExport.types create mode 100644 tests/baselines/reference/reexportWrittenCorrectlyInDeclaration.js create mode 100644 tests/baselines/reference/reexportWrittenCorrectlyInDeclaration.symbols create mode 100644 tests/baselines/reference/reexportWrittenCorrectlyInDeclaration.types create mode 100644 tests/cases/compiler/declarationEmitOfTypeofAliasedExport.ts create mode 100644 tests/cases/compiler/reexportWrittenCorrectlyInDeclaration.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6f75bfa0d46..f619805628a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2161,7 +2161,6 @@ namespace ts { return forEachEntry(symbols, symbolFromSymbolTable => { if (symbolFromSymbolTable.flags & SymbolFlags.Alias && symbolFromSymbolTable.escapedName !== "export=" - && !getDeclarationOfKind(symbolFromSymbolTable, SyntaxKind.ExportSpecifier) && !(isUMDExportSymbol(symbolFromSymbolTable) && enclosingDeclaration && isExternalModule(getSourceFileOfNode(enclosingDeclaration))) // If `!useOnlyExternalAliasing`, we can use any type of alias to get the name && (!useOnlyExternalAliasing || some(symbolFromSymbolTable.declarations, isExternalModuleImportEqualsDeclaration))) { diff --git a/tests/baselines/reference/declarationEmitOfTypeofAliasedExport.js b/tests/baselines/reference/declarationEmitOfTypeofAliasedExport.js new file mode 100644 index 00000000000..5f1f5743201 --- /dev/null +++ b/tests/baselines/reference/declarationEmitOfTypeofAliasedExport.js @@ -0,0 +1,35 @@ +//// [tests/cases/compiler/declarationEmitOfTypeofAliasedExport.ts] //// + +//// [a.ts] +class C {} +export { C as D } + +//// [b.ts] +import * as a from "./a"; +export default a.D; + + +//// [a.js] +"use strict"; +exports.__esModule = true; +var C = /** @class */ (function () { + function C() { + } + return C; +}()); +exports.D = C; +//// [b.js] +"use strict"; +exports.__esModule = true; +var a = require("./a"); +exports["default"] = a.D; + + +//// [a.d.ts] +declare class C { +} +export { C as D }; +//// [b.d.ts] +import * as a from "./a"; +declare const _default: typeof a.D; +export default _default; diff --git a/tests/baselines/reference/declarationEmitOfTypeofAliasedExport.symbols b/tests/baselines/reference/declarationEmitOfTypeofAliasedExport.symbols new file mode 100644 index 00000000000..d13d242105b --- /dev/null +++ b/tests/baselines/reference/declarationEmitOfTypeofAliasedExport.symbols @@ -0,0 +1,17 @@ +=== /a.ts === +class C {} +>C : Symbol(C, Decl(a.ts, 0, 0)) + +export { C as D } +>C : Symbol(D, Decl(a.ts, 1, 8)) +>D : Symbol(D, Decl(a.ts, 1, 8)) + +=== /b.ts === +import * as a from "./a"; +>a : Symbol(a, Decl(b.ts, 0, 6)) + +export default a.D; +>a.D : Symbol(a.D, Decl(a.ts, 1, 8)) +>a : Symbol(a, Decl(b.ts, 0, 6)) +>D : Symbol(a.D, Decl(a.ts, 1, 8)) + diff --git a/tests/baselines/reference/declarationEmitOfTypeofAliasedExport.types b/tests/baselines/reference/declarationEmitOfTypeofAliasedExport.types new file mode 100644 index 00000000000..ccd13107166 --- /dev/null +++ b/tests/baselines/reference/declarationEmitOfTypeofAliasedExport.types @@ -0,0 +1,17 @@ +=== /a.ts === +class C {} +>C : C + +export { C as D } +>C : typeof C +>D : typeof C + +=== /b.ts === +import * as a from "./a"; +>a : typeof a + +export default a.D; +>a.D : typeof a.D +>a : typeof a +>D : typeof a.D + diff --git a/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifier.types b/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifier.types index abb1c3b69e2..acbe40fb9ab 100644 --- a/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifier.types +++ b/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifier.types @@ -30,8 +30,8 @@ export { c as c2 } from "server"; export { i, m as instantiatedModule } from "server"; >i : any ->m : typeof m ->instantiatedModule : typeof m +>m : typeof instantiatedModule +>instantiatedModule : typeof instantiatedModule export { uninstantiated } from "server"; >uninstantiated : any diff --git a/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifierInEs5.types b/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifierInEs5.types index b407d9b16f5..8a7e9c29b10 100644 --- a/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifierInEs5.types +++ b/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifierInEs5.types @@ -30,8 +30,8 @@ export { c as c2 } from "./server"; export { i, m as instantiatedModule } from "./server"; >i : any ->m : typeof m ->instantiatedModule : typeof m +>m : typeof instantiatedModule +>instantiatedModule : typeof instantiatedModule export { uninstantiated } from "./server"; >uninstantiated : any diff --git a/tests/baselines/reference/exportSpecifierForAGlobal.errors.txt b/tests/baselines/reference/exportSpecifierForAGlobal.errors.txt index d2f103a91fa..20a1c9a7d41 100644 --- a/tests/baselines/reference/exportSpecifierForAGlobal.errors.txt +++ b/tests/baselines/reference/exportSpecifierForAGlobal.errors.txt @@ -1,14 +1,17 @@ tests/cases/compiler/b.ts(1,9): error TS2661: Cannot export 'X'. Only local declarations can be exported from a module. +tests/cases/compiler/b.ts(2,17): error TS4060: Return type of exported function has or is using private name 'X'. ==== tests/cases/compiler/a.d.ts (0 errors) ==== declare class X { } -==== tests/cases/compiler/b.ts (1 errors) ==== +==== tests/cases/compiler/b.ts (2 errors) ==== export {X}; ~ !!! error TS2661: Cannot export 'X'. Only local declarations can be exported from a module. export function f() { + ~ +!!! error TS4060: Return type of exported function has or is using private name 'X'. var x: X; return x; } diff --git a/tests/baselines/reference/exportSpecifierForAGlobal.js b/tests/baselines/reference/exportSpecifierForAGlobal.js index 6023b7c7f14..9f12241cbd1 100644 --- a/tests/baselines/reference/exportSpecifierForAGlobal.js +++ b/tests/baselines/reference/exportSpecifierForAGlobal.js @@ -19,8 +19,3 @@ function f() { return x; } exports.f = f; - - -//// [b.d.ts] -export { X }; -export declare function f(): X; diff --git a/tests/baselines/reference/exportsAndImports3-amd.symbols b/tests/baselines/reference/exportsAndImports3-amd.symbols index f71014281c2..edc5d5c2e4e 100644 --- a/tests/baselines/reference/exportsAndImports3-amd.symbols +++ b/tests/baselines/reference/exportsAndImports3-amd.symbols @@ -15,17 +15,17 @@ export enum E { >E : Symbol(E, Decl(t1.ts, 5, 1)) A, B, C ->A : Symbol(E.A, Decl(t1.ts, 6, 15)) ->B : Symbol(E.B, Decl(t1.ts, 7, 6)) ->C : Symbol(E.C, Decl(t1.ts, 7, 9)) +>A : Symbol(E1.A, Decl(t1.ts, 6, 15)) +>B : Symbol(E1.B, Decl(t1.ts, 7, 6)) +>C : Symbol(E1.C, Decl(t1.ts, 7, 9)) } export const enum D { >D : Symbol(D, Decl(t1.ts, 8, 1)) A, B, C ->A : Symbol(D.A, Decl(t1.ts, 9, 21)) ->B : Symbol(D.B, Decl(t1.ts, 10, 6)) ->C : Symbol(D.C, Decl(t1.ts, 10, 9)) +>A : Symbol(D1.A, Decl(t1.ts, 9, 21)) +>B : Symbol(D1.B, Decl(t1.ts, 10, 6)) +>C : Symbol(D1.C, Decl(t1.ts, 10, 9)) } export module M { >M : Symbol(M, Decl(t1.ts, 11, 1)) diff --git a/tests/baselines/reference/exportsAndImports3-es6.symbols b/tests/baselines/reference/exportsAndImports3-es6.symbols index f71014281c2..edc5d5c2e4e 100644 --- a/tests/baselines/reference/exportsAndImports3-es6.symbols +++ b/tests/baselines/reference/exportsAndImports3-es6.symbols @@ -15,17 +15,17 @@ export enum E { >E : Symbol(E, Decl(t1.ts, 5, 1)) A, B, C ->A : Symbol(E.A, Decl(t1.ts, 6, 15)) ->B : Symbol(E.B, Decl(t1.ts, 7, 6)) ->C : Symbol(E.C, Decl(t1.ts, 7, 9)) +>A : Symbol(E1.A, Decl(t1.ts, 6, 15)) +>B : Symbol(E1.B, Decl(t1.ts, 7, 6)) +>C : Symbol(E1.C, Decl(t1.ts, 7, 9)) } export const enum D { >D : Symbol(D, Decl(t1.ts, 8, 1)) A, B, C ->A : Symbol(D.A, Decl(t1.ts, 9, 21)) ->B : Symbol(D.B, Decl(t1.ts, 10, 6)) ->C : Symbol(D.C, Decl(t1.ts, 10, 9)) +>A : Symbol(D1.A, Decl(t1.ts, 9, 21)) +>B : Symbol(D1.B, Decl(t1.ts, 10, 6)) +>C : Symbol(D1.C, Decl(t1.ts, 10, 9)) } export module M { >M : Symbol(M, Decl(t1.ts, 11, 1)) diff --git a/tests/baselines/reference/exportsAndImports3.symbols b/tests/baselines/reference/exportsAndImports3.symbols index f71014281c2..edc5d5c2e4e 100644 --- a/tests/baselines/reference/exportsAndImports3.symbols +++ b/tests/baselines/reference/exportsAndImports3.symbols @@ -15,17 +15,17 @@ export enum E { >E : Symbol(E, Decl(t1.ts, 5, 1)) A, B, C ->A : Symbol(E.A, Decl(t1.ts, 6, 15)) ->B : Symbol(E.B, Decl(t1.ts, 7, 6)) ->C : Symbol(E.C, Decl(t1.ts, 7, 9)) +>A : Symbol(E1.A, Decl(t1.ts, 6, 15)) +>B : Symbol(E1.B, Decl(t1.ts, 7, 6)) +>C : Symbol(E1.C, Decl(t1.ts, 7, 9)) } export const enum D { >D : Symbol(D, Decl(t1.ts, 8, 1)) A, B, C ->A : Symbol(D.A, Decl(t1.ts, 9, 21)) ->B : Symbol(D.B, Decl(t1.ts, 10, 6)) ->C : Symbol(D.C, Decl(t1.ts, 10, 9)) +>A : Symbol(D1.A, Decl(t1.ts, 9, 21)) +>B : Symbol(D1.B, Decl(t1.ts, 10, 6)) +>C : Symbol(D1.C, Decl(t1.ts, 10, 9)) } export module M { >M : Symbol(M, Decl(t1.ts, 11, 1)) diff --git a/tests/baselines/reference/reexportWrittenCorrectlyInDeclaration.js b/tests/baselines/reference/reexportWrittenCorrectlyInDeclaration.js new file mode 100644 index 00000000000..ae3ce21ff49 --- /dev/null +++ b/tests/baselines/reference/reexportWrittenCorrectlyInDeclaration.js @@ -0,0 +1,72 @@ +//// [tests/cases/compiler/reexportWrittenCorrectlyInDeclaration.ts] //// + +//// [ThingA.ts] +// https://github.com/Microsoft/TypeScript/issues/8612 +export class ThingA { } + +//// [ThingB.ts] +export class ThingB { } + +//// [Things.ts] +export {ThingA} from "./ThingA"; +export {ThingB} from "./ThingB"; + +//// [Test.ts] +import * as things from "./Things"; + +export class Test { + public method = (input: things.ThingA) => { }; +} + +//// [ThingA.js] +"use strict"; +exports.__esModule = true; +// https://github.com/Microsoft/TypeScript/issues/8612 +var ThingA = /** @class */ (function () { + function ThingA() { + } + return ThingA; +}()); +exports.ThingA = ThingA; +//// [ThingB.js] +"use strict"; +exports.__esModule = true; +var ThingB = /** @class */ (function () { + function ThingB() { + } + return ThingB; +}()); +exports.ThingB = ThingB; +//// [Things.js] +"use strict"; +exports.__esModule = true; +var ThingA_1 = require("./ThingA"); +exports.ThingA = ThingA_1.ThingA; +var ThingB_1 = require("./ThingB"); +exports.ThingB = ThingB_1.ThingB; +//// [Test.js] +"use strict"; +exports.__esModule = true; +var Test = /** @class */ (function () { + function Test() { + this.method = function (input) { }; + } + return Test; +}()); +exports.Test = Test; + + +//// [ThingA.d.ts] +export declare class ThingA { +} +//// [ThingB.d.ts] +export declare class ThingB { +} +//// [Things.d.ts] +export { ThingA } from "./ThingA"; +export { ThingB } from "./ThingB"; +//// [Test.d.ts] +import * as things from "./Things"; +export declare class Test { + method: (input: things.ThingA) => void; +} diff --git a/tests/baselines/reference/reexportWrittenCorrectlyInDeclaration.symbols b/tests/baselines/reference/reexportWrittenCorrectlyInDeclaration.symbols new file mode 100644 index 00000000000..347ff41cc71 --- /dev/null +++ b/tests/baselines/reference/reexportWrittenCorrectlyInDeclaration.symbols @@ -0,0 +1,29 @@ +=== tests/cases/compiler/ThingA.ts === +// https://github.com/Microsoft/TypeScript/issues/8612 +export class ThingA { } +>ThingA : Symbol(ThingA, Decl(ThingA.ts, 0, 0)) + +=== tests/cases/compiler/ThingB.ts === +export class ThingB { } +>ThingB : Symbol(ThingB, Decl(ThingB.ts, 0, 0)) + +=== tests/cases/compiler/Things.ts === +export {ThingA} from "./ThingA"; +>ThingA : Symbol(ThingA, Decl(Things.ts, 0, 8)) + +export {ThingB} from "./ThingB"; +>ThingB : Symbol(ThingB, Decl(Things.ts, 1, 8)) + +=== tests/cases/compiler/Test.ts === +import * as things from "./Things"; +>things : Symbol(things, Decl(Test.ts, 0, 6)) + +export class Test { +>Test : Symbol(Test, Decl(Test.ts, 0, 35)) + + public method = (input: things.ThingA) => { }; +>method : Symbol(Test.method, Decl(Test.ts, 2, 19)) +>input : Symbol(input, Decl(Test.ts, 3, 21)) +>things : Symbol(things, Decl(Test.ts, 0, 6)) +>ThingA : Symbol(things.ThingA, Decl(Things.ts, 0, 8)) +} diff --git a/tests/baselines/reference/reexportWrittenCorrectlyInDeclaration.types b/tests/baselines/reference/reexportWrittenCorrectlyInDeclaration.types new file mode 100644 index 00000000000..515ad0f5ac9 --- /dev/null +++ b/tests/baselines/reference/reexportWrittenCorrectlyInDeclaration.types @@ -0,0 +1,30 @@ +=== tests/cases/compiler/ThingA.ts === +// https://github.com/Microsoft/TypeScript/issues/8612 +export class ThingA { } +>ThingA : ThingA + +=== tests/cases/compiler/ThingB.ts === +export class ThingB { } +>ThingB : ThingB + +=== tests/cases/compiler/Things.ts === +export {ThingA} from "./ThingA"; +>ThingA : typeof ThingA + +export {ThingB} from "./ThingB"; +>ThingB : typeof ThingB + +=== tests/cases/compiler/Test.ts === +import * as things from "./Things"; +>things : typeof things + +export class Test { +>Test : Test + + public method = (input: things.ThingA) => { }; +>method : (input: things.ThingA) => void +>(input: things.ThingA) => { } : (input: things.ThingA) => void +>input : things.ThingA +>things : any +>ThingA : things.ThingA +} diff --git a/tests/baselines/reference/systemModule15.types b/tests/baselines/reference/systemModule15.types index 747583323ad..ac24678e568 100644 --- a/tests/baselines/reference/systemModule15.types +++ b/tests/baselines/reference/systemModule15.types @@ -23,9 +23,9 @@ use(moduleB.moduleC); use(moduleB.moduleCStar); >use(moduleB.moduleCStar) : void >use : (v: any) => void ->moduleB.moduleCStar : typeof "tests/cases/compiler/file3" +>moduleB.moduleCStar : typeof moduleB.moduleCStar >moduleB : typeof moduleB ->moduleCStar : typeof "tests/cases/compiler/file3" +>moduleCStar : typeof moduleB.moduleCStar === tests/cases/compiler/file2.ts === import * as moduleCStar from "./file3" diff --git a/tests/cases/compiler/declarationEmitOfTypeofAliasedExport.ts b/tests/cases/compiler/declarationEmitOfTypeofAliasedExport.ts new file mode 100644 index 00000000000..ab2912a0f1c --- /dev/null +++ b/tests/cases/compiler/declarationEmitOfTypeofAliasedExport.ts @@ -0,0 +1,8 @@ +// @declaration: true +// @filename: /a.ts +class C {} +export { C as D } + +// @filename: /b.ts +import * as a from "./a"; +export default a.D; diff --git a/tests/cases/compiler/reexportWrittenCorrectlyInDeclaration.ts b/tests/cases/compiler/reexportWrittenCorrectlyInDeclaration.ts new file mode 100644 index 00000000000..71947ca80c1 --- /dev/null +++ b/tests/cases/compiler/reexportWrittenCorrectlyInDeclaration.ts @@ -0,0 +1,18 @@ +// https://github.com/Microsoft/TypeScript/issues/8612 +// @declaration: true +// @filename: ThingA.ts +export class ThingA { } + +// @filename: ThingB.ts +export class ThingB { } + +// @filename: Things.ts +export {ThingA} from "./ThingA"; +export {ThingB} from "./ThingB"; + +// @filename: Test.ts +import * as things from "./Things"; + +export class Test { + public method = (input: things.ThingA) => { }; +} \ No newline at end of file From a1014b2b13f6662205876046e1c2c01d9d3367ed Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 9 Nov 2017 00:26:33 -0800 Subject: [PATCH 199/235] Mark all parameters as needed for metadata when one is decorated (#19849) * Mark all properties as needed for metadata when one is decorated * Add restarg test --- src/compiler/checker.ts | 4 + .../decoratorReferenceOnOtherProperty.js | 109 ++++++++++++++++++ .../decoratorReferenceOnOtherProperty.symbols | 46 ++++++++ .../decoratorReferenceOnOtherProperty.types | 46 ++++++++ .../decoratorReferenceOnOtherProperty.ts | 25 ++++ 5 files changed, 230 insertions(+) create mode 100644 tests/baselines/reference/decoratorReferenceOnOtherProperty.js create mode 100644 tests/baselines/reference/decoratorReferenceOnOtherProperty.symbols create mode 100644 tests/baselines/reference/decoratorReferenceOnOtherProperty.types create mode 100644 tests/cases/compiler/decoratorReferenceOnOtherProperty.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f619805628a..a9aaa77fa74 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20262,6 +20262,10 @@ namespace ts { case SyntaxKind.Parameter: markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(node)); + const containingSignature = (node as ParameterDeclaration).parent; + for (const parameter of containingSignature.parameters) { + markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter)); + } break; } } diff --git a/tests/baselines/reference/decoratorReferenceOnOtherProperty.js b/tests/baselines/reference/decoratorReferenceOnOtherProperty.js new file mode 100644 index 00000000000..6313f339ba9 --- /dev/null +++ b/tests/baselines/reference/decoratorReferenceOnOtherProperty.js @@ -0,0 +1,109 @@ +//// [tests/cases/compiler/decoratorReferenceOnOtherProperty.ts] //// + +//// [yoha.ts] +// https://github.com/Microsoft/TypeScript/issues/19799 +export class Yoha {} + +//// [index.ts] +import {Yoha} from './yoha'; + +function foo(...args: any[]) {} + +class Bar { + yoha(@foo yoha, bar: Yoha) {} + // ^^^^ +} + +//// [index2.ts] +import {Yoha} from './yoha'; + +function foo(...args: any[]) {} + +class Bar { + yoha(@foo yoha, ...bar: Yoha[]) {} + // ^^^^ +} + +//// [yoha.js] +"use strict"; +exports.__esModule = true; +// https://github.com/Microsoft/TypeScript/issues/19799 +var Yoha = /** @class */ (function () { + function Yoha() { + } + return Yoha; +}()); +exports.Yoha = Yoha; +//// [index.js] +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var __param = (this && this.__param) || function (paramIndex, decorator) { + return function (target, key) { decorator(target, key, paramIndex); } +}; +exports.__esModule = true; +var yoha_1 = require("./yoha"); +function foo() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } +} +var Bar = /** @class */ (function () { + function Bar() { + } + Bar.prototype.yoha = function (yoha, bar) { }; + __decorate([ + __param(0, foo), + __metadata("design:type", Function), + __metadata("design:paramtypes", [Object, yoha_1.Yoha]), + __metadata("design:returntype", void 0) + ], Bar.prototype, "yoha"); + return Bar; +}()); +//// [index2.js] +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var __param = (this && this.__param) || function (paramIndex, decorator) { + return function (target, key) { decorator(target, key, paramIndex); } +}; +exports.__esModule = true; +var yoha_1 = require("./yoha"); +function foo() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } +} +var Bar = /** @class */ (function () { + function Bar() { + } + Bar.prototype.yoha = function (yoha) { + var bar = []; + for (var _i = 1; _i < arguments.length; _i++) { + bar[_i - 1] = arguments[_i]; + } + }; + __decorate([ + __param(0, foo), + __metadata("design:type", Function), + __metadata("design:paramtypes", [Object, yoha_1.Yoha]), + __metadata("design:returntype", void 0) + ], Bar.prototype, "yoha"); + return Bar; +}()); diff --git a/tests/baselines/reference/decoratorReferenceOnOtherProperty.symbols b/tests/baselines/reference/decoratorReferenceOnOtherProperty.symbols new file mode 100644 index 00000000000..619e2afe4e9 --- /dev/null +++ b/tests/baselines/reference/decoratorReferenceOnOtherProperty.symbols @@ -0,0 +1,46 @@ +=== tests/cases/compiler/yoha.ts === +// https://github.com/Microsoft/TypeScript/issues/19799 +export class Yoha {} +>Yoha : Symbol(Yoha, Decl(yoha.ts, 0, 0)) + +=== tests/cases/compiler/index.ts === +import {Yoha} from './yoha'; +>Yoha : Symbol(Yoha, Decl(index.ts, 0, 8)) + +function foo(...args: any[]) {} +>foo : Symbol(foo, Decl(index.ts, 0, 28)) +>args : Symbol(args, Decl(index.ts, 2, 13)) + +class Bar { +>Bar : Symbol(Bar, Decl(index.ts, 2, 31)) + + yoha(@foo yoha, bar: Yoha) {} +>yoha : Symbol(Bar.yoha, Decl(index.ts, 4, 11)) +>foo : Symbol(foo, Decl(index.ts, 0, 28)) +>yoha : Symbol(yoha, Decl(index.ts, 5, 7)) +>bar : Symbol(bar, Decl(index.ts, 5, 17)) +>Yoha : Symbol(Yoha, Decl(index.ts, 0, 8)) + + // ^^^^ +} + +=== tests/cases/compiler/index2.ts === +import {Yoha} from './yoha'; +>Yoha : Symbol(Yoha, Decl(index2.ts, 0, 8)) + +function foo(...args: any[]) {} +>foo : Symbol(foo, Decl(index2.ts, 0, 28)) +>args : Symbol(args, Decl(index2.ts, 2, 13)) + +class Bar { +>Bar : Symbol(Bar, Decl(index2.ts, 2, 31)) + + yoha(@foo yoha, ...bar: Yoha[]) {} +>yoha : Symbol(Bar.yoha, Decl(index2.ts, 4, 11)) +>foo : Symbol(foo, Decl(index2.ts, 0, 28)) +>yoha : Symbol(yoha, Decl(index2.ts, 5, 7)) +>bar : Symbol(bar, Decl(index2.ts, 5, 17)) +>Yoha : Symbol(Yoha, Decl(index2.ts, 0, 8)) + + // ^^^^ +} diff --git a/tests/baselines/reference/decoratorReferenceOnOtherProperty.types b/tests/baselines/reference/decoratorReferenceOnOtherProperty.types new file mode 100644 index 00000000000..5994657aa31 --- /dev/null +++ b/tests/baselines/reference/decoratorReferenceOnOtherProperty.types @@ -0,0 +1,46 @@ +=== tests/cases/compiler/yoha.ts === +// https://github.com/Microsoft/TypeScript/issues/19799 +export class Yoha {} +>Yoha : Yoha + +=== tests/cases/compiler/index.ts === +import {Yoha} from './yoha'; +>Yoha : typeof Yoha + +function foo(...args: any[]) {} +>foo : (...args: any[]) => void +>args : any[] + +class Bar { +>Bar : Bar + + yoha(@foo yoha, bar: Yoha) {} +>yoha : (yoha: any, bar: Yoha) => void +>foo : (...args: any[]) => void +>yoha : any +>bar : Yoha +>Yoha : Yoha + + // ^^^^ +} + +=== tests/cases/compiler/index2.ts === +import {Yoha} from './yoha'; +>Yoha : typeof Yoha + +function foo(...args: any[]) {} +>foo : (...args: any[]) => void +>args : any[] + +class Bar { +>Bar : Bar + + yoha(@foo yoha, ...bar: Yoha[]) {} +>yoha : (yoha: any, ...bar: Yoha[]) => void +>foo : (...args: any[]) => void +>yoha : any +>bar : Yoha[] +>Yoha : Yoha + + // ^^^^ +} diff --git a/tests/cases/compiler/decoratorReferenceOnOtherProperty.ts b/tests/cases/compiler/decoratorReferenceOnOtherProperty.ts new file mode 100644 index 00000000000..c7465471ed8 --- /dev/null +++ b/tests/cases/compiler/decoratorReferenceOnOtherProperty.ts @@ -0,0 +1,25 @@ +// https://github.com/Microsoft/TypeScript/issues/19799 +// @experimentalDecorators: true +// @emitDecoratorMetadata: true +// @filename: yoha.ts +export class Yoha {} + +// @filename: index.ts +import {Yoha} from './yoha'; + +function foo(...args: any[]) {} + +class Bar { + yoha(@foo yoha, bar: Yoha) {} + // ^^^^ +} + +// @filename: index2.ts +import {Yoha} from './yoha'; + +function foo(...args: any[]) {} + +class Bar { + yoha(@foo yoha, ...bar: Yoha[]) {} + // ^^^^ +} \ No newline at end of file From 90ae9ffe6ed92ab9d3478cc620e5752c658cf121 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 9 Nov 2017 12:21:37 -0800 Subject: [PATCH 200/235] If there is an `export default x;` alias declaration, disallow other default exports (#19872) --- src/compiler/binder.ts | 9 ++++----- src/compiler/types.ts | 4 ++++ ...exportDefaultAlias_excludesEverything.errors.txt | 13 +++++++++++++ .../exportDefaultAlias_excludesEverything.js | 9 +++++++++ .../exportDefaultAlias_excludesEverything.symbols | 10 ++++++++++ .../exportDefaultAlias_excludesEverything.types | 10 ++++++++++ .../exportDefaultAlias_excludesEverything.ts | 3 +++ 7 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/exportDefaultAlias_excludesEverything.errors.txt create mode 100644 tests/baselines/reference/exportDefaultAlias_excludesEverything.js create mode 100644 tests/baselines/reference/exportDefaultAlias_excludesEverything.symbols create mode 100644 tests/baselines/reference/exportDefaultAlias_excludesEverything.types create mode 100644 tests/cases/compiler/exportDefaultAlias_excludesEverything.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index cf8b3eefde8..4e89abde780 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2205,15 +2205,14 @@ namespace ts { bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node)); } else { - // An export default clause with an expression exports a value - // We want to exclude both class and function here, this is necessary to issue an error when there are both - // default export-assignment and default export function and class declaration. - const flags = node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node) + const flags = node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node) // An export default clause with an EntityNameExpression exports all meanings of that identifier ? SymbolFlags.Alias // An export default clause with any other expression exports a value : SymbolFlags.Property; - declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.Property | SymbolFlags.AliasExcludes | SymbolFlags.Class | SymbolFlags.Function); + // If there is an `export default x;` alias declaration, can't `export default` anything else. + // (In contrast, you can still have `export default function f() {}` and `export default interface I {}`.) + declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.All); } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 1874821727c..d2107572ab4 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3021,6 +3021,10 @@ namespace ts { Optional = 1 << 24, // Optional property Transient = 1 << 25, // Transient symbol (created during type check) + /* @internal */ + All = FunctionScopedVariable | BlockScopedVariable | Property | EnumMember | Function | Class | Interface | ConstEnum | RegularEnum | ValueModule | NamespaceModule | TypeLiteral + | ObjectLiteral | Method | Constructor | GetAccessor | SetAccessor | Signature | TypeParameter | TypeAlias | ExportValue | Alias | Prototype | ExportStar | Optional | Transient, + Enum = RegularEnum | ConstEnum, Variable = FunctionScopedVariable | BlockScopedVariable, Value = Variable | Property | EnumMember | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor, diff --git a/tests/baselines/reference/exportDefaultAlias_excludesEverything.errors.txt b/tests/baselines/reference/exportDefaultAlias_excludesEverything.errors.txt new file mode 100644 index 00000000000..9181278db20 --- /dev/null +++ b/tests/baselines/reference/exportDefaultAlias_excludesEverything.errors.txt @@ -0,0 +1,13 @@ +tests/cases/compiler/exportDefaultAlias_excludesEverything.ts(1,26): error TS2528: A module cannot have multiple default exports. +tests/cases/compiler/exportDefaultAlias_excludesEverything.ts(3,16): error TS2528: A module cannot have multiple default exports. + + +==== tests/cases/compiler/exportDefaultAlias_excludesEverything.ts (2 errors) ==== + export default interface A {} + ~ +!!! error TS2528: A module cannot have multiple default exports. + interface B {} + export default B; + ~ +!!! error TS2528: A module cannot have multiple default exports. + \ No newline at end of file diff --git a/tests/baselines/reference/exportDefaultAlias_excludesEverything.js b/tests/baselines/reference/exportDefaultAlias_excludesEverything.js new file mode 100644 index 00000000000..27f75954c14 --- /dev/null +++ b/tests/baselines/reference/exportDefaultAlias_excludesEverything.js @@ -0,0 +1,9 @@ +//// [exportDefaultAlias_excludesEverything.ts] +export default interface A {} +interface B {} +export default B; + + +//// [exportDefaultAlias_excludesEverything.js] +"use strict"; +exports.__esModule = true; diff --git a/tests/baselines/reference/exportDefaultAlias_excludesEverything.symbols b/tests/baselines/reference/exportDefaultAlias_excludesEverything.symbols new file mode 100644 index 00000000000..73b403e0da1 --- /dev/null +++ b/tests/baselines/reference/exportDefaultAlias_excludesEverything.symbols @@ -0,0 +1,10 @@ +=== tests/cases/compiler/exportDefaultAlias_excludesEverything.ts === +export default interface A {} +>A : Symbol(A, Decl(exportDefaultAlias_excludesEverything.ts, 0, 0)) + +interface B {} +>B : Symbol(B, Decl(exportDefaultAlias_excludesEverything.ts, 0, 29)) + +export default B; +>B : Symbol(B, Decl(exportDefaultAlias_excludesEverything.ts, 0, 29)) + diff --git a/tests/baselines/reference/exportDefaultAlias_excludesEverything.types b/tests/baselines/reference/exportDefaultAlias_excludesEverything.types new file mode 100644 index 00000000000..cd9dd06f817 --- /dev/null +++ b/tests/baselines/reference/exportDefaultAlias_excludesEverything.types @@ -0,0 +1,10 @@ +=== tests/cases/compiler/exportDefaultAlias_excludesEverything.ts === +export default interface A {} +>A : A + +interface B {} +>B : B + +export default B; +>B : B + diff --git a/tests/cases/compiler/exportDefaultAlias_excludesEverything.ts b/tests/cases/compiler/exportDefaultAlias_excludesEverything.ts new file mode 100644 index 00000000000..eea8cb1e698 --- /dev/null +++ b/tests/cases/compiler/exportDefaultAlias_excludesEverything.ts @@ -0,0 +1,3 @@ +export default interface A {} +interface B {} +export default B; From ddd8c95c63766d2eb321404213bb7a999193aef8 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 9 Nov 2017 12:30:29 -0800 Subject: [PATCH 201/235] Remove testcases we don't like --- src/harness/unittests/tsserverProjectSystem.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index c72a27e173e..5b6c36d071f 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -1501,20 +1501,17 @@ namespace ts.projectSystem { ["jquery-max", "jquery-max"], ["jquery.min", "jquery"], ["jquery-min.4.2.3", "jquery"], - ["jquery.4.2-test.js", "jquery"], + // ["jquery.4.2-test.js", "jquery"], ["jquery.min.4.2.1", "jquery"], - ["jquery.7.min.js", "jquery"], - ["jquery.7.min-beta", "jquery"], + // ["jquery.7.min.js", "jquery"], + // ["jquery.7.min-beta", "jquery"], ["minimum", "minimum"], ["min", "min"], ["min.3.2", "min"], ["jquery", "jquery"] ]; - const suffixes = [".js", ".jsx", ""]; for (const t of testData) { - for (const suf of suffixes) { - assert.equal(removeMinAndVersionNumbers(t[0] + suf), t[1]); - } + assert.equal(removeMinAndVersionNumbers(t[0]), t[1], t[0]); } }); From 19cc42782b1abe17fdd3911505f8afe36689d053 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 9 Nov 2017 12:30:36 -0800 Subject: [PATCH 202/235] Format + new regex --- src/compiler/core.ts | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 626480035b1..657f362067b 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -74,13 +74,13 @@ namespace ts { } // The global Map object. This may not be available, so we must test for it. - declare const Map: { new(): Map } | undefined; + declare const Map: { new (): Map } | undefined; // Internet Explorer's Map doesn't support iteration, so don't use it. // tslint:disable-next-line:no-in-operator const MapCtr = typeof Map !== "undefined" && "entries" in Map.prototype ? Map : shimMap(); // Keep the class inside a function so it doesn't get compiled if it's not used. - function shimMap(): { new(): Map } { + function shimMap(): { new (): Map } { class MapIterator { private data: MapLike; @@ -103,7 +103,7 @@ namespace ts { } } - return class implements Map { + return class implements Map { private data = createDictionaryObject(); public size = 0; @@ -166,8 +166,8 @@ namespace ts { } export const enum Comparison { - LessThan = -1, - EqualTo = 0, + LessThan = -1, + EqualTo = 0, GreaterThan = 1 } @@ -2417,13 +2417,11 @@ namespace ts { * Takes a string like "jquery-min.4.2.3" and returns "jquery" */ export function removeMinAndVersionNumbers(fileName: string) { - const match = /((\w|(-(?!min)))+)(\.|-)?.*/.exec(fileName); - if (match) { - return match[1]; - } - else { - return fileName; - } + // Match a "." or "-" followed by a version number or 'min' at the end of the name + const trailingMinOrVersion = /[.-]((min)|(\d+(\.\d+)*))$/; + + // The "min" or version may both be present, in either order, so try applying the above twice. + return fileName.replace(trailingMinOrVersion, "").replace(trailingMinOrVersion, ""); } export interface ObjectAllocator { @@ -2627,7 +2625,7 @@ namespace ts { return findBestPatternMatch(patterns, _ => _, candidate); } - export function patternText({prefix, suffix}: Pattern): string { + export function patternText({ prefix, suffix }: Pattern): string { return `${prefix}*${suffix}`; } @@ -2657,7 +2655,7 @@ namespace ts { return matchedValue; } - function isPatternMatch({prefix, suffix}: Pattern, candidate: string) { + function isPatternMatch({ prefix, suffix }: Pattern, candidate: string) { return candidate.length >= prefix.length + suffix.length && startsWith(candidate, prefix) && endsWith(candidate, suffix); From 0e105ad8de2b64a262b978b78ebca6c465a45bbf Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 9 Nov 2017 12:30:44 -0800 Subject: [PATCH 203/235] Log more usefully when this test fails --- src/harness/unittests/typingsInstaller.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/harness/unittests/typingsInstaller.ts b/src/harness/unittests/typingsInstaller.ts index fb1a7a26a7a..65d904940b3 100644 --- a/src/harness/unittests/typingsInstaller.ts +++ b/src/harness/unittests/typingsInstaller.ts @@ -1057,11 +1057,12 @@ namespace ts.projectSystem { const host = createServerHost([app, jquery, chroma]); const logger = trackingLogger(); const result = JsTyping.discoverTypings(host, logger.log, [app.path, jquery.path, chroma.path], getDirectoryPath(app.path), safeList, emptyMap, { enable: true }, emptyArray); - assert.deepEqual(logger.finish(), [ + const finish = logger.finish(); + assert.deepEqual(finish, [ 'Inferred typings from file names: ["jquery","chroma-js"]', "Inferred typings from unresolved imports: []", 'Result: {"cachedTypingPaths":[],"newTypingNames":["jquery","chroma-js"],"filesToWatch":["/a/b/bower_components","/a/b/node_modules"]}', - ]); + ], finish.join("\r\n")); assert.deepEqual(result.newTypingNames, ["jquery", "chroma-js"]); }); From 65a191fa2b0d6671d4ce0b1eec5affd426e74739 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 9 Nov 2017 13:13:23 -0800 Subject: [PATCH 204/235] For import completion of default import, convert module name to identifier (#19875) * For import completion of default import, convert module name to identifier * Suggestions from code review --- src/compiler/scanner.ts | 2 +- src/compiler/types.ts | 6 ++-- src/compiler/utilities.ts | 8 +++++ src/harness/fourslash.ts | 2 +- src/services/codefixes/importFixes.ts | 36 +++++++++++++++++-- src/services/completions.ts | 34 +++++++++++------- .../completionsImport_default_anonymous.ts | 26 ++++++++++++++ .../importNameCodeFixDefaultExport.ts | 12 +++++++ 8 files changed, 108 insertions(+), 18 deletions(-) create mode 100644 tests/cases/fourslash/completionsImport_default_anonymous.ts create mode 100644 tests/cases/fourslash/importNameCodeFixDefaultExport.ts diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index fd8c54a18cc..9fddece11d0 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -294,7 +294,7 @@ namespace ts { } /* @internal */ - export function stringToToken(s: string): SyntaxKind { + export function stringToToken(s: string): SyntaxKind | undefined { return textToToken.get(s); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d2107572ab4..bb62bead00b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -214,7 +214,7 @@ namespace ts { UndefinedKeyword, FromKeyword, GlobalKeyword, - OfKeyword, // LastKeyword and LastToken + OfKeyword, // LastKeyword and LastToken and LastContextualKeyword // Parse tree nodes @@ -431,7 +431,9 @@ namespace ts { FirstJSDocNode = JSDocTypeExpression, LastJSDocNode = JSDocPropertyTag, FirstJSDocTagNode = JSDocTag, - LastJSDocTagNode = JSDocPropertyTag + LastJSDocTagNode = JSDocPropertyTag, + /* @internal */ FirstContextualKeyword = AbstractKeyword, + /* @internal */ LastContextualKeyword = OfKeyword, } export const enum NodeFlags { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 41a5512cb2a..1931c397ae7 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1905,6 +1905,14 @@ namespace ts { return SyntaxKind.FirstKeyword <= token && token <= SyntaxKind.LastKeyword; } + export function isContextualKeyword(token: SyntaxKind): boolean { + return SyntaxKind.FirstContextualKeyword <= token && token <= SyntaxKind.LastContextualKeyword; + } + + export function isNonContextualKeyword(token: SyntaxKind): boolean { + return isKeyword(token) && !isContextualKeyword(token); + } + export function isTrivia(token: SyntaxKind) { return SyntaxKind.FirstTriviaToken <= token && token <= SyntaxKind.LastTriviaToken; } diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index c9aa1c6403d..2687a660ca8 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -3102,7 +3102,7 @@ Actual: ${stringify(fullActual)}`); } } - const itemsString = items.map(item => stringify({ name: item.name, kind: item.kind })).join(",\n"); + const itemsString = items.map(item => stringify({ name: item.name, source: item.source, kind: item.kind })).join(",\n"); this.raiseError(`Expected "${stringify({ entryId, text, documentation, kind })}" to be in list [${itemsString}]`); } diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index a0c7ffd75ea..838e19fa35d 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -699,9 +699,10 @@ namespace ts.codefix { const defaultExport = checker.tryGetMemberInModuleExports("default", moduleSymbol); if (defaultExport) { const localSymbol = getLocalSymbolForExportDefault(defaultExport); - if (localSymbol && localSymbol.escapedName === symbolName && checkSymbolHasMeaning(localSymbol, currentTokenMeaning)) { + if ((localSymbol && localSymbol.escapedName === symbolName || moduleSymbolToValidIdentifier(moduleSymbol, context.compilerOptions.target) === symbolName) + && checkSymbolHasMeaning(localSymbol || defaultExport, currentTokenMeaning)) { // check if this symbol is already used - const symbolId = getUniqueSymbolId(localSymbol, checker); + const symbolId = getUniqueSymbolId(localSymbol || defaultExport, checker); symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, { ...context, kind: ImportKind.Default })); } } @@ -731,4 +732,35 @@ namespace ts.codefix { } } } + + export function moduleSymbolToValidIdentifier(moduleSymbol: Symbol, target: ScriptTarget): string { + return moduleSpecifierToValidIdentifier(removeFileExtension(getBaseFileName(moduleSymbol.name)), target); + } + + function moduleSpecifierToValidIdentifier(moduleSpecifier: string, target: ScriptTarget): string { + let res = ""; + let lastCharWasValid = true; + const firstCharCode = moduleSpecifier.charCodeAt(0); + if (isIdentifierStart(firstCharCode, target)) { + res += String.fromCharCode(firstCharCode); + } + else { + lastCharWasValid = false; + } + for (let i = 1; i < moduleSpecifier.length; i++) { + const ch = moduleSpecifier.charCodeAt(i); + const isValid = isIdentifierPart(ch, target); + if (isValid) { + let char = String.fromCharCode(ch); + if (!lastCharWasValid) { + char = char.toUpperCase(); + } + res += char; + } + lastCharWasValid = isValid; + } + // Need `|| "_"` to ensure result isn't empty. + const token = stringToToken(res); + return token === undefined || !isNonContextualKeyword(token) ? res || "_" : `_${res}`; + } } diff --git a/src/services/completions.ts b/src/services/completions.ts index f66242ca864..6a9af1e1941 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -39,7 +39,7 @@ namespace ts.Completions { return getStringLiteralCompletionEntries(sourceFile, position, typeChecker, compilerOptions, host, log); } - const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, options); + const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, options, compilerOptions.target); if (!completionData) { return undefined; } @@ -136,12 +136,12 @@ namespace ts.Completions { typeChecker: TypeChecker, target: ScriptTarget, allowStringLiteral: boolean, - origin: SymbolOriginInfo, + origin: SymbolOriginInfo | undefined, ): CompletionEntry | undefined { // Try to get a valid display name for this symbol, if we could not find one, then ignore it. // We would like to only show things that can be added after a dot, so for instance numeric properties can // not be accessed with a dot (a.1 <- invalid) - const displayName = getCompletionEntryDisplayNameForSymbol(symbol, target, performCharacterChecks, allowStringLiteral); + const displayName = getCompletionEntryDisplayNameForSymbol(symbol, target, performCharacterChecks, allowStringLiteral, origin); if (!displayName) { return undefined; } @@ -381,7 +381,7 @@ namespace ts.Completions { { name, source }: CompletionEntryIdentifier, allSourceFiles: ReadonlyArray, ): { type: "symbol", symbol: Symbol, location: Node, symbolToOriginInfoMap: SymbolOriginInfoMap } | { type: "request", request: Request } | { type: "none" } { - const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, { includeExternalModuleExports: true }); + const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, { includeExternalModuleExports: true }, compilerOptions.target); if (!completionData) { return { type: "none" }; } @@ -395,12 +395,18 @@ namespace ts.Completions { // We don't need to perform character checks here because we're only comparing the // name against 'entryName' (which is known to be good), not building a new // completion entry. - const symbol = find(symbols, s => - getCompletionEntryDisplayNameForSymbol(s, compilerOptions.target, /*performCharacterChecks*/ false, allowStringLiteral) === name - && getSourceFromOrigin(symbolToOriginInfoMap[getSymbolId(s)]) === source); + const symbol = find(symbols, s => { + const origin = symbolToOriginInfoMap[getSymbolId(s)]; + return getCompletionEntryDisplayNameForSymbol(s, compilerOptions.target, /*performCharacterChecks*/ false, allowStringLiteral, origin) === name + && getSourceFromOrigin(origin) === source; + }); return symbol ? { type: "symbol", symbol, location, symbolToOriginInfoMap } : { type: "none" }; } + function getSymbolName(symbol: Symbol, origin: SymbolOriginInfo | undefined, target: ScriptTarget): string { + return origin && origin.isDefaultExport && symbol.name === "default" ? codefix.moduleSymbolToValidIdentifier(origin.moduleSymbol, target) : symbol.name; + } + export interface CompletionEntryIdentifier { name: string; source?: string; @@ -482,7 +488,7 @@ namespace ts.Completions { compilerOptions, sourceFile, formatContext, - symbolName: symbol.name, + symbolName: getSymbolName(symbol, symbolOriginInfo, compilerOptions.target), getCanonicalFileName: createGetCanonicalFileName(host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : false), symbolToken: undefined, kind: isDefaultExport ? codefix.ImportKind.Default : codefix.ImportKind.Named, @@ -523,6 +529,7 @@ namespace ts.Completions { position: number, allSourceFiles: ReadonlyArray, options: GetCompletionsAtPositionOptions, + target: ScriptTarget, ): CompletionData | undefined { const isJavaScriptFile = isSourceFileJavaScript(sourceFile); @@ -921,7 +928,7 @@ namespace ts.Completions { symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings); if (options.includeExternalModuleExports) { - getSymbolsFromOtherSourceFileExports(symbols, previousToken && isIdentifier(previousToken) ? previousToken.text : ""); + getSymbolsFromOtherSourceFileExports(symbols, previousToken && isIdentifier(previousToken) ? previousToken.text : "", target); } filterGlobalCompletion(symbols); @@ -1003,7 +1010,7 @@ namespace ts.Completions { } } - function getSymbolsFromOtherSourceFileExports(symbols: Symbol[], tokenText: string): void { + function getSymbolsFromOtherSourceFileExports(symbols: Symbol[], tokenText: string, target: ScriptTarget): void { const tokenTextLowerCase = tokenText.toLowerCase(); codefix.forEachExternalModule(typeChecker, allSourceFiles, moduleSymbol => { @@ -1020,6 +1027,9 @@ namespace ts.Completions { symbol = localSymbol; name = localSymbol.name; } + else { + name = codefix.moduleSymbolToValidIdentifier(moduleSymbol, target); + } } if (symbol.declarations && symbol.declarations.some(d => isExportSpecifier(d) && !!d.parent.parent.moduleSpecifier)) { @@ -1847,8 +1857,8 @@ namespace ts.Completions { * * @return undefined if the name is of external module */ - function getCompletionEntryDisplayNameForSymbol(symbol: Symbol, target: ScriptTarget, performCharacterChecks: boolean, allowStringLiteral: boolean): string | undefined { - const name = symbol.name; + function getCompletionEntryDisplayNameForSymbol(symbol: Symbol, target: ScriptTarget, performCharacterChecks: boolean, allowStringLiteral: boolean, origin: SymbolOriginInfo | undefined): string | undefined { + const name = getSymbolName(symbol, origin, target); if (!name) return undefined; // First check of the displayName is not external module; if it is an external module, it is not valid entry diff --git a/tests/cases/fourslash/completionsImport_default_anonymous.ts b/tests/cases/fourslash/completionsImport_default_anonymous.ts new file mode 100644 index 00000000000..7c0697584f9 --- /dev/null +++ b/tests/cases/fourslash/completionsImport_default_anonymous.ts @@ -0,0 +1,26 @@ +/// + +// Use `/src` to test that directory names are not included in conversion from module path to identifier. + +// @Filename: /src/foo-bar.ts +////export default 0; + +// @Filename: /src/b.ts +////def/*0*/ +////fooB/*1*/ + +goTo.marker("0"); +verify.not.completionListContains({ name: "default", source: "/src/foo-bar" }, undefined, undefined, undefined, undefined, undefined, { includeExternalModuleExports: true }); + +goTo.marker("1"); +verify.completionListContains({ name: "fooBar", source: "/src/foo-bar" }, "(property) default: 0", "", "property", /*spanIndex*/ undefined, /*hasAction*/ true, { includeExternalModuleExports: true }); +verify.applyCodeActionFromCompletion("1", { + name: "fooBar", + source: "/src/foo-bar", + description: `Import 'fooBar' from "./foo-bar".`, + // TODO: GH#18445 + newFileContent: `import fooBar from "./foo-bar";\r +\r +def +fooB`, +}); diff --git a/tests/cases/fourslash/importNameCodeFixDefaultExport.ts b/tests/cases/fourslash/importNameCodeFixDefaultExport.ts new file mode 100644 index 00000000000..2f502aa66fa --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixDefaultExport.ts @@ -0,0 +1,12 @@ +/// + +// @Filename: /foo-bar.ts +////export default 0; + +// @Filename: /b.ts +////[|foo/**/Bar|] + +goTo.file("/b.ts"); +verify.importFixAtPosition([`import fooBar from "./foo-bar"; + +fooBar`]); From b94940525b77f31a8e7782c92fe3ea53371c93fb Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 9 Nov 2017 13:17:47 -0800 Subject: [PATCH 205/235] Allow applyCodeActionCommand to take an array (#19870) * Allow applyCodeActionCommand to take an array * Use this.host.newLine --- src/server/protocol.ts | 1 + src/server/session.ts | 7 +++++-- src/services/services.ts | 10 ++++++++-- src/services/types.ts | 2 ++ src/services/utilities.ts | 1 + tests/baselines/reference/api/tsserverlibrary.d.ts | 3 +++ tests/baselines/reference/api/typescript.d.ts | 2 ++ 7 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/server/protocol.ts b/src/server/protocol.ts index f44efa0db21..3761049017d 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -586,6 +586,7 @@ namespace ts.server.protocol { } export interface ApplyCodeActionCommandRequestArgs extends FileRequestArgs { + /** May also be an array of commands. */ command: {}; } diff --git a/src/server/session.ts b/src/server/session.ts index 6c97c3c8bd4..f9a145d16fd 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1571,9 +1571,12 @@ namespace ts.server { private applyCodeActionCommand(commandName: string, requestSeq: number, args: protocol.ApplyCodeActionCommandRequestArgs): void { const { file, project } = this.getFileAndProject(args); const output = (success: boolean, message: string) => this.doOutput({}, commandName, requestSeq, success, message); - const command = args.command as CodeActionCommand; // They should be sending back the command we sent them. + const command = args.command as CodeActionCommand | CodeActionCommand[]; // They should be sending back the command we sent them. + project.getLanguageService().applyCodeActionCommand(file, command).then( - ({ successMessage }) => { output(/*success*/ true, successMessage); }, + result => { + output(/*success*/ true, isArray(result) ? result.map(res => res.successMessage).join(`${this.host.newLine}${this.host.newLine}`) : result.successMessage); + }, error => { output(/*success*/ false, error); }); } diff --git a/src/services/services.ts b/src/services/services.ts index 37298c8eba8..06358d3a720 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1868,8 +1868,14 @@ namespace ts { }); } - function applyCodeActionCommand(fileName: Path, action: CodeActionCommand): Promise { - fileName = toPath(fileName, currentDirectory, getCanonicalFileName); + function applyCodeActionCommand(fileName: Path, action: CodeActionCommand): Promise; + function applyCodeActionCommand(fileName: Path, action: CodeActionCommand[]): Promise; + function applyCodeActionCommand(fileName: Path, action: CodeActionCommand | CodeActionCommand[]): Promise { + const path = toPath(fileName, currentDirectory, getCanonicalFileName); + return isArray(action) ? Promise.all(action.map(a => applySingleCodeActionCommand(path, a))) : applySingleCodeActionCommand(path, action); + } + + function applySingleCodeActionCommand(fileName: Path, action: CodeActionCommand): Promise { switch (action.type) { case "install package": return host.installPackage diff --git a/src/services/types.ts b/src/services/types.ts index a9244982fbb..bcebc437892 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -294,6 +294,8 @@ namespace ts { getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[]; applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise; + applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise; + applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise; getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined; diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 1ed44d29f95..cf71118292a 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -3,6 +3,7 @@ interface PromiseConstructor { new (executor: (resolve: (value?: T | PromiseLike) => void, reject: (reason?: any) => void) => void): Promise; reject(reason: any): Promise; + all(values: (T | PromiseLike)[]): Promise; } /* @internal */ declare var Promise: PromiseConstructor; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index a3499de08ab..78e8a377ec0 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3965,6 +3965,8 @@ declare namespace ts { getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan; getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[]; applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise; + applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise; + applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise; getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined; getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput; @@ -5263,6 +5265,7 @@ declare namespace ts.server.protocol { errorCodes?: number[]; } interface ApplyCodeActionCommandRequestArgs extends FileRequestArgs { + /** May also be an array of commands. */ command: {}; } /** diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 98d7137ddeb..3344193d0ce 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3965,6 +3965,8 @@ declare namespace ts { getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan; getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[]; applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise; + applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise; + applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise; getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined; getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput; From 0d5dec9a9870637cb4602cd7eb05683d97d0dcda Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 9 Nov 2017 13:55:20 -0800 Subject: [PATCH 206/235] Remove commented tests --- src/harness/unittests/tsserverProjectSystem.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 018934e9d7d..ea573726eb8 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -1544,10 +1544,7 @@ namespace ts.projectSystem { ["jquery-max", "jquery-max"], ["jquery.min", "jquery"], ["jquery-min.4.2.3", "jquery"], - // ["jquery.4.2-test.js", "jquery"], ["jquery.min.4.2.1", "jquery"], - // ["jquery.7.min.js", "jquery"], - // ["jquery.7.min-beta", "jquery"], ["minimum", "minimum"], ["min", "min"], ["min.3.2", "min"], From a5fa75a0cd095702d41e259cd2eb73d2c777b162 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 9 Nov 2017 14:21:08 -0800 Subject: [PATCH 207/235] DefinitelyTypedRunner skips ExpectErrors If all errors were ExpectErrors, then it does not fail. --- src/harness/externalCompileRunner.ts | 91 +++++++++++++++++++++++----- 1 file changed, 75 insertions(+), 16 deletions(-) diff --git a/src/harness/externalCompileRunner.ts b/src/harness/externalCompileRunner.ts index 9b8fc8c4fc5..ec8acf4872e 100644 --- a/src/harness/externalCompileRunner.ts +++ b/src/harness/externalCompileRunner.ts @@ -1,14 +1,17 @@ /// /// +const fs = require("fs"); +const path = require("path"); abstract class ExternalCompileRunnerBase extends RunnerBase { abstract testDir: string; - public enumerateTestFiles() { + abstract report(result: any, cwd: string): string; + enumerateTestFiles() { return Harness.IO.getDirectories(this.testDir); } /** Setup the runner's tests so that they are ready to be executed by the harness * The first test should be a describe/it block that sets up the harness's compiler instance appropriately */ - public initializeTests(): void { + initializeTests(): void { // Read in and evaluate the test list const testList = this.tests && this.tests.length ? this.tests : this.enumerateTestFiles(); @@ -36,15 +39,7 @@ abstract class ExternalCompileRunnerBase extends RunnerBase { if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed!`); } Harness.Baseline.runBaseline(`${this.kind()}/${directoryName}.log`, () => { - const result = cp.spawnSync(`node`, [path.join(__dirname, "tsc.js")], { cwd, timeout, shell: true }); - // tslint:disable-next-line:no-null-keyword - return result.status === 0 && !result.stdout.length && !result.stderr.length ? null : `Exit Code: ${result.status} -Standard output: -${result.stdout.toString().replace(/\r\n/g, "\n")} - - -Standard error: -${result.stderr.toString().replace(/\r\n/g, "\n")}`; + return this.report(cp.spawnSync(`node`, [path.join(__dirname, "tsc.js")], { cwd, timeout, shell: true }), cwd); }); }); }); @@ -52,16 +47,80 @@ ${result.stderr.toString().replace(/\r\n/g, "\n")}`; } class UserCodeRunner extends ExternalCompileRunnerBase { - public readonly testDir = "tests/cases/user/"; - public kind(): TestRunnerKind { + readonly testDir = "tests/cases/user/"; + kind(): TestRunnerKind { return "user"; } + report(result: any) { + // tslint:disable-next-line:no-null-keyword + return result.status === 0 && !result.stdout.length && !result.stderr.length ? null : `Exit Code: ${result.status} +Standard output: +${result.stdout.toString().replace(/\r\n/g, "\n")} + + +Standard error: +${result.stderr.toString().replace(/\r\n/g, "\n")}`; + } } class DefinitelyTypedRunner extends ExternalCompileRunnerBase { - public readonly testDir = "../DefinitelyTyped/types/"; - public workingDirectory = this.testDir; - public kind(): TestRunnerKind { + readonly testDir = "../DefinitelyTyped/types/"; + workingDirectory = this.testDir; + kind(): TestRunnerKind { return "dt"; } + report(result: any, cwd: string) { + const stdout = filterExpectedErrors(result.stdout.toString(), cwd) + const stderr = result.stderr.toString() + // tslint:disable-next-line:no-null-keyword + return !stdout.length && !stderr.length ? null : `Exit Code: ${result.status} +Standard output: +${stdout.replace(/\r\n/g, "\n")} + + +Standard error: +${stderr.replace(/\r\n/g, "\n")}`; + } +} + +function filterExpectedErrors(errors: string, cwd: string): string { + return breaks(errors.split("\n"), s => /^\w+/.test(s)).filter(isExpectedError(cwd)).map(lines => lines.join("\n")).join("\n"); +} +function isExpectedError(cwd: string) { + return (error: string[]) => { + if (error.length === 0) { + return true; + } + const match = error[0].match(/(.+\.ts)\((\d+),\d+\): error TS/); + if (!match) { + return true; + } + const errlines = fs.readFileSync(path.join(cwd, match[1]), { encoding: "utf8" }).split("\n"); + const index = parseInt(match[2]); + const errline = index < errlines.length ? errlines[index] : ""; + const prevline = index - 1 < errlines.length && index > 0 ? errlines[index - 1] : ""; + if (errline.indexOf("$ExpectError") > -1 || prevline.indexOf("$ExpectError") > -1) { + return false; + } + return true; + } +} +function breaks(xs: T[], isStart: (T: any) => boolean): T[][] { + const result = []; + let group: T[] = []; + for (const x of xs) { + if (isStart(x)) { + if (group.length) { + result.push(group); + } + group = [x]; + } + else { + group.push(x); + } + } + if (group.length) { + result.push(group); + } + return result; } From 2372ffcddc22c567d81f7667cd3ae8451f82e6ca Mon Sep 17 00:00:00 2001 From: csigs Date: Thu, 9 Nov 2017 23:10:34 +0000 Subject: [PATCH 208/235] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 160 +++++++++--------- 1 file changed, 77 insertions(+), 83 deletions(-) diff --git a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl index 8dab90a1ba2..3bb9642d207 100644 --- a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1620,12 +1620,9 @@ - + - - - - + @@ -3735,6 +3732,24 @@ + + + + + + + + + + + + + + + + + + @@ -3966,6 +3981,15 @@ + + + + + + + + + @@ -5211,24 +5235,6 @@ - - - - - - - - - - - - - - - - - - @@ -5256,24 +5262,6 @@ - - - - - - - - - - - - - - - - - - @@ -5292,6 +5280,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -5997,6 +6009,24 @@ + + + + + + + + + + + + + + + + + + @@ -6024,30 +6054,21 @@ - + - - - - + - + - - - - + - + - - - - + @@ -6078,33 +6099,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - From 16efae24338f09c9059c8ec1525166f521110935 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 9 Nov 2017 16:49:04 -0800 Subject: [PATCH 209/235] Consider the commonjs module indicator as a module indicator (#18490) * Consider the commonjs module indicator as an indicator that something is effectively an external module * Only use commonjs module indicator when targeting commonjs --- src/compiler/transformers/module/module.ts | 2 +- src/compiler/utilities.ts | 2 +- .../reference/javascriptCommonjsModule.js | 23 +++++++++++++++++++ .../javascriptCommonjsModule.symbols | 13 +++++++++++ .../reference/javascriptCommonjsModule.types | 15 ++++++++++++ .../compiler/javascriptCommonjsModule.ts | 11 +++++++++ 6 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/javascriptCommonjsModule.js create mode 100644 tests/baselines/reference/javascriptCommonjsModule.symbols create mode 100644 tests/baselines/reference/javascriptCommonjsModule.types create mode 100644 tests/cases/compiler/javascriptCommonjsModule.ts diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index f60e50ea365..0c8e2cda0f5 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -57,7 +57,7 @@ namespace ts { * @param node The SourceFile node. */ function transformSourceFile(node: SourceFile) { - if (node.isDeclarationFile || !(isExternalModule(node) || compilerOptions.isolatedModules || node.transformFlags & TransformFlags.ContainsDynamicImport)) { + if (node.isDeclarationFile || !(isEffectiveExternalModule(node, compilerOptions) || node.transformFlags & TransformFlags.ContainsDynamicImport)) { return node; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 1931c397ae7..e67635cba04 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -461,7 +461,7 @@ namespace ts { } export function isEffectiveExternalModule(node: SourceFile, compilerOptions: CompilerOptions) { - return isExternalModule(node) || compilerOptions.isolatedModules; + return isExternalModule(node) || compilerOptions.isolatedModules || ((getEmitModuleKind(compilerOptions) === ModuleKind.CommonJS) && !!node.commonJsModuleIndicator); } /* @internal */ diff --git a/tests/baselines/reference/javascriptCommonjsModule.js b/tests/baselines/reference/javascriptCommonjsModule.js new file mode 100644 index 00000000000..ab517f63805 --- /dev/null +++ b/tests/baselines/reference/javascriptCommonjsModule.js @@ -0,0 +1,23 @@ +//// [index.js] +class Foo {} + +class Bar extends Foo {} + +module.exports = Bar; + + +//// [index.js] +var tslib_1 = require("tslib"); +var Foo = /** @class */ (function () { + function Foo() { + } + return Foo; +}()); +var Bar = /** @class */ (function (_super) { + tslib_1.__extends(Bar, _super); + function Bar() { + return _super !== null && _super.apply(this, arguments) || this; + } + return Bar; +}(Foo)); +module.exports = Bar; diff --git a/tests/baselines/reference/javascriptCommonjsModule.symbols b/tests/baselines/reference/javascriptCommonjsModule.symbols new file mode 100644 index 00000000000..923e0b3467b --- /dev/null +++ b/tests/baselines/reference/javascriptCommonjsModule.symbols @@ -0,0 +1,13 @@ +=== tests/cases/compiler/index.js === +class Foo {} +>Foo : Symbol(Foo, Decl(index.js, 0, 0)) + +class Bar extends Foo {} +>Bar : Symbol(Bar, Decl(index.js, 0, 12)) +>Foo : Symbol(Foo, Decl(index.js, 0, 0)) + +module.exports = Bar; +>module : Symbol(export=, Decl(index.js, 2, 24)) +>exports : Symbol(export=, Decl(index.js, 2, 24)) +>Bar : Symbol(Bar, Decl(index.js, 0, 12)) + diff --git a/tests/baselines/reference/javascriptCommonjsModule.types b/tests/baselines/reference/javascriptCommonjsModule.types new file mode 100644 index 00000000000..88126ce4737 --- /dev/null +++ b/tests/baselines/reference/javascriptCommonjsModule.types @@ -0,0 +1,15 @@ +=== tests/cases/compiler/index.js === +class Foo {} +>Foo : Foo + +class Bar extends Foo {} +>Bar : Bar +>Foo : Foo + +module.exports = Bar; +>module.exports = Bar : typeof Bar +>module.exports : any +>module : any +>exports : any +>Bar : typeof Bar + diff --git a/tests/cases/compiler/javascriptCommonjsModule.ts b/tests/cases/compiler/javascriptCommonjsModule.ts new file mode 100644 index 00000000000..dde30580f70 --- /dev/null +++ b/tests/cases/compiler/javascriptCommonjsModule.ts @@ -0,0 +1,11 @@ +// @allowJS: true +// @outDir: ./out +// @module: commonjs +// @noEmitHelpers: true +// @importHelpers: true +// @filename: index.js +class Foo {} + +class Bar extends Foo {} + +module.exports = Bar; From 2010c4cda1097697390d981d63d31600d1fe9808 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 10 Nov 2017 08:30:59 -0800 Subject: [PATCH 210/235] Give lowest priority to inferences made from empty array literals --- src/compiler/checker.ts | 17 ++++++++++------- src/compiler/types.ts | 1 + 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a9aaa77fa74..fedc0c77c8f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10898,22 +10898,25 @@ namespace ts { // it as an inference candidate. Hopefully, a better candidate will come along that does // not contain anyFunctionType when we come back to this argument for its second round // of inference. Also, we exclude inferences for silentNeverType (which is used as a wildcard - // when constructing types from type parameters that had no inference candidates) and - // implicitNeverType (which is used as the element type for empty array literals). - if (source.flags & TypeFlags.ContainsAnyFunctionType || source === silentNeverType || source === implicitNeverType) { + // when constructing types from type parameters that had no inference candidates). + if (source.flags & TypeFlags.ContainsAnyFunctionType || source === silentNeverType) { return; } const inference = getInferenceInfoForType(target); if (inference) { if (!inference.isFixed) { - if (!inference.candidates || priority < inference.priority) { + // We give lowest priority to inferences of implicitNeverType (which is used as the + // element type for empty array literals). Thus, inferences from empty array literals + // only matter when no other inferences are made. + const p = priority | (source === implicitNeverType ? InferencePriority.NeverType : 0); + if (!inference.candidates || p < inference.priority) { inference.candidates = [source]; - inference.priority = priority; + inference.priority = p; } - else if (priority === inference.priority) { + else if (p === inference.priority) { inference.candidates.push(source); } - if (!(priority & InferencePriority.ReturnType) && target.flags & TypeFlags.TypeParameter && !isTypeParameterAtTopLevel(originalTarget, target)) { + if (!(p & InferencePriority.ReturnType) && target.flags & TypeFlags.TypeParameter && !isTypeParameterAtTopLevel(originalTarget, target)) { inference.topLevel = false; } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index bb62bead00b..3141e3f22d9 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3613,6 +3613,7 @@ namespace ts { NakedTypeVariable = 1 << 1, // Naked type variable in union or intersection type MappedType = 1 << 2, // Reverse inference for mapped type ReturnType = 1 << 3, // Inference made from return type of generic function + NeverType = 1 << 4, // Inference made from the never type } export interface InferenceInfo { From 197c635994a5d02c50d6066f05f4382da446a8fa Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 10 Nov 2017 08:36:50 -0800 Subject: [PATCH 211/235] Update tests --- .../cases/conformance/types/never/neverInference.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/cases/conformance/types/never/neverInference.ts b/tests/cases/conformance/types/never/neverInference.ts index 1258a35e3d3..c28d30d92c2 100644 --- a/tests/cases/conformance/types/never/neverInference.ts +++ b/tests/cases/conformance/types/never/neverInference.ts @@ -1,11 +1,11 @@ // @strict: true -declare function f(x: T[]): T; +declare function f1(x: T[]): T; let neverArray: never[] = []; -let a1 = f([]); // {} -let a2 = f(neverArray); // never +let a1 = f1([]); // never +let a2 = f1(neverArray); // never // Repro from #19576 @@ -22,3 +22,9 @@ declare function compareNumbers(x: number, y: number): number; declare function mkList(items: T[], comparator: Comparator): LinkedList; const list: LinkedList = mkList([], compareNumbers); + +// Repro from #19858 + +declare function f2
(as1: a[], as2: a[], cmp: (a1: a, a2: a) => number): void; +f2(Array.from([0]), [], (a1, a2) => a1 - a2); +f2(Array.from([]), [0], (a1, a2) => a1 - a2); From afec1e1fa154e1a51ec60ef15433f93ace5b74b9 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 10 Nov 2017 08:39:29 -0800 Subject: [PATCH 212/235] Update test --- tests/cases/conformance/types/never/neverInference.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/cases/conformance/types/never/neverInference.ts b/tests/cases/conformance/types/never/neverInference.ts index c28d30d92c2..549d27ae109 100644 --- a/tests/cases/conformance/types/never/neverInference.ts +++ b/tests/cases/conformance/types/never/neverInference.ts @@ -1,4 +1,5 @@ // @strict: true +// @target: es2015 declare function f1(x: T[]): T; From 2c43ef1e9b262477ced59124f2541a5102d0894d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 10 Nov 2017 08:39:49 -0800 Subject: [PATCH 213/235] Accept new baselines --- tests/baselines/reference/neverInference.js | 22 ++++-- .../reference/neverInference.symbols | 61 +++++++++++++---- .../baselines/reference/neverInference.types | 67 ++++++++++++++++--- 3 files changed, 121 insertions(+), 29 deletions(-) diff --git a/tests/baselines/reference/neverInference.js b/tests/baselines/reference/neverInference.js index d13e537eba4..3b570599772 100644 --- a/tests/baselines/reference/neverInference.js +++ b/tests/baselines/reference/neverInference.js @@ -1,10 +1,10 @@ //// [neverInference.ts] -declare function f(x: T[]): T; +declare function f1(x: T[]): T; let neverArray: never[] = []; -let a1 = f([]); // {} -let a2 = f(neverArray); // never +let a1 = f1([]); // never +let a2 = f1(neverArray); // never // Repro from #19576 @@ -21,11 +21,19 @@ declare function compareNumbers(x: number, y: number): number; declare function mkList(items: T[], comparator: Comparator): LinkedList; const list: LinkedList = mkList([], compareNumbers); + +// Repro from #19858 + +declare function f2(as1: a[], as2: a[], cmp: (a1: a, a2: a) => number): void; +f2(Array.from([0]), [], (a1, a2) => a1 - a2); +f2(Array.from([]), [0], (a1, a2) => a1 - a2); //// [neverInference.js] "use strict"; -var neverArray = []; -var a1 = f([]); // {} -var a2 = f(neverArray); // never -var list = mkList([], compareNumbers); +let neverArray = []; +let a1 = f1([]); // never +let a2 = f1(neverArray); // never +const list = mkList([], compareNumbers); +f2(Array.from([0]), [], (a1, a2) => a1 - a2); +f2(Array.from([]), [0], (a1, a2) => a1 - a2); diff --git a/tests/baselines/reference/neverInference.symbols b/tests/baselines/reference/neverInference.symbols index 683e079b2f8..0441770dd3f 100644 --- a/tests/baselines/reference/neverInference.symbols +++ b/tests/baselines/reference/neverInference.symbols @@ -1,27 +1,27 @@ === tests/cases/conformance/types/never/neverInference.ts === -declare function f(x: T[]): T; ->f : Symbol(f, Decl(neverInference.ts, 0, 0)) ->T : Symbol(T, Decl(neverInference.ts, 0, 19)) ->x : Symbol(x, Decl(neverInference.ts, 0, 22)) ->T : Symbol(T, Decl(neverInference.ts, 0, 19)) ->T : Symbol(T, Decl(neverInference.ts, 0, 19)) +declare function f1(x: T[]): T; +>f1 : Symbol(f1, Decl(neverInference.ts, 0, 0)) +>T : Symbol(T, Decl(neverInference.ts, 0, 20)) +>x : Symbol(x, Decl(neverInference.ts, 0, 23)) +>T : Symbol(T, Decl(neverInference.ts, 0, 20)) +>T : Symbol(T, Decl(neverInference.ts, 0, 20)) let neverArray: never[] = []; >neverArray : Symbol(neverArray, Decl(neverInference.ts, 2, 3)) -let a1 = f([]); // {} +let a1 = f1([]); // never >a1 : Symbol(a1, Decl(neverInference.ts, 4, 3)) ->f : Symbol(f, Decl(neverInference.ts, 0, 0)) +>f1 : Symbol(f1, Decl(neverInference.ts, 0, 0)) -let a2 = f(neverArray); // never +let a2 = f1(neverArray); // never >a2 : Symbol(a2, Decl(neverInference.ts, 5, 3)) ->f : Symbol(f, Decl(neverInference.ts, 0, 0)) +>f1 : Symbol(f1, Decl(neverInference.ts, 0, 0)) >neverArray : Symbol(neverArray, Decl(neverInference.ts, 2, 3)) // Repro from #19576 type Comparator = (x: T, y: T) => number; ->Comparator : Symbol(Comparator, Decl(neverInference.ts, 5, 23)) +>Comparator : Symbol(Comparator, Decl(neverInference.ts, 5, 24)) >T : Symbol(T, Decl(neverInference.ts, 9, 16)) >x : Symbol(x, Decl(neverInference.ts, 9, 22)) >T : Symbol(T, Decl(neverInference.ts, 9, 16)) @@ -34,7 +34,7 @@ interface LinkedList { comparator: Comparator, >comparator : Symbol(LinkedList.comparator, Decl(neverInference.ts, 11, 25)) ->Comparator : Symbol(Comparator, Decl(neverInference.ts, 5, 23)) +>Comparator : Symbol(Comparator, Decl(neverInference.ts, 5, 24)) >T : Symbol(T, Decl(neverInference.ts, 11, 21)) nodes: Node @@ -63,7 +63,7 @@ declare function mkList(items: T[], comparator: Comparator): LinkedList >items : Symbol(items, Decl(neverInference.ts, 19, 27)) >T : Symbol(T, Decl(neverInference.ts, 19, 24)) >comparator : Symbol(comparator, Decl(neverInference.ts, 19, 38)) ->Comparator : Symbol(Comparator, Decl(neverInference.ts, 5, 23)) +>Comparator : Symbol(Comparator, Decl(neverInference.ts, 5, 24)) >T : Symbol(T, Decl(neverInference.ts, 19, 24)) >LinkedList : Symbol(LinkedList, Decl(neverInference.ts, 9, 44)) >T : Symbol(T, Decl(neverInference.ts, 19, 24)) @@ -74,3 +74,38 @@ const list: LinkedList = mkList([], compareNumbers); >mkList : Symbol(mkList, Decl(neverInference.ts, 18, 62)) >compareNumbers : Symbol(compareNumbers, Decl(neverInference.ts, 16, 49)) +// Repro from #19858 + +declare function f2(as1: a[], as2: a[], cmp: (a1: a, a2: a) => number): void; +>f2 : Symbol(f2, Decl(neverInference.ts, 21, 60)) +>a : Symbol(a, Decl(neverInference.ts, 25, 20)) +>as1 : Symbol(as1, Decl(neverInference.ts, 25, 23)) +>a : Symbol(a, Decl(neverInference.ts, 25, 20)) +>as2 : Symbol(as2, Decl(neverInference.ts, 25, 32)) +>a : Symbol(a, Decl(neverInference.ts, 25, 20)) +>cmp : Symbol(cmp, Decl(neverInference.ts, 25, 42)) +>a1 : Symbol(a1, Decl(neverInference.ts, 25, 49)) +>a : Symbol(a, Decl(neverInference.ts, 25, 20)) +>a2 : Symbol(a2, Decl(neverInference.ts, 25, 55)) +>a : Symbol(a, Decl(neverInference.ts, 25, 20)) + +f2(Array.from([0]), [], (a1, a2) => a1 - a2); +>f2 : Symbol(f2, Decl(neverInference.ts, 21, 60)) +>Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>a1 : Symbol(a1, Decl(neverInference.ts, 26, 25)) +>a2 : Symbol(a2, Decl(neverInference.ts, 26, 28)) +>a1 : Symbol(a1, Decl(neverInference.ts, 26, 25)) +>a2 : Symbol(a2, Decl(neverInference.ts, 26, 28)) + +f2(Array.from([]), [0], (a1, a2) => a1 - a2); +>f2 : Symbol(f2, Decl(neverInference.ts, 21, 60)) +>Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>a1 : Symbol(a1, Decl(neverInference.ts, 27, 25)) +>a2 : Symbol(a2, Decl(neverInference.ts, 27, 28)) +>a1 : Symbol(a1, Decl(neverInference.ts, 27, 25)) +>a2 : Symbol(a2, Decl(neverInference.ts, 27, 28)) + diff --git a/tests/baselines/reference/neverInference.types b/tests/baselines/reference/neverInference.types index a7dd05a3f8b..2f4b9e0cc1e 100644 --- a/tests/baselines/reference/neverInference.types +++ b/tests/baselines/reference/neverInference.types @@ -1,6 +1,6 @@ === tests/cases/conformance/types/never/neverInference.ts === -declare function f(x: T[]): T; ->f : (x: T[]) => T +declare function f1(x: T[]): T; +>f1 : (x: T[]) => T >T : T >x : T[] >T : T @@ -10,16 +10,16 @@ let neverArray: never[] = []; >neverArray : never[] >[] : never[] -let a1 = f([]); // {} ->a1 : {} ->f([]) : {} ->f : (x: T[]) => T +let a1 = f1([]); // never +>a1 : never +>f1([]) : never +>f1 : (x: T[]) => T >[] : never[] -let a2 = f(neverArray); // never +let a2 = f1(neverArray); // never >a2 : never ->f(neverArray) : never ->f : (x: T[]) => T +>f1(neverArray) : never +>f1 : (x: T[]) => T >neverArray : never[] // Repro from #19576 @@ -81,3 +81,52 @@ const list: LinkedList = mkList([], compareNumbers); >[] : never[] >compareNumbers : (x: number, y: number) => number +// Repro from #19858 + +declare function f2(as1: a[], as2: a[], cmp: (a1: a, a2: a) => number): void; +>f2 : (as1: a[], as2: a[], cmp: (a1: a, a2: a) => number) => void +>a : a +>as1 : a[] +>a : a +>as2 : a[] +>a : a +>cmp : (a1: a, a2: a) => number +>a1 : a +>a : a +>a2 : a +>a : a + +f2(Array.from([0]), [], (a1, a2) => a1 - a2); +>f2(Array.from([0]), [], (a1, a2) => a1 - a2) : void +>f2 : (as1: a[], as2: a[], cmp: (a1: a, a2: a) => number) => void +>Array.from([0]) : number[] +>Array.from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } +>Array : ArrayConstructor +>from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } +>[0] : number[] +>0 : 0 +>[] : never[] +>(a1, a2) => a1 - a2 : (a1: number, a2: number) => number +>a1 : number +>a2 : number +>a1 - a2 : number +>a1 : number +>a2 : number + +f2(Array.from([]), [0], (a1, a2) => a1 - a2); +>f2(Array.from([]), [0], (a1, a2) => a1 - a2) : void +>f2 : (as1: a[], as2: a[], cmp: (a1: a, a2: a) => number) => void +>Array.from([]) : never[] +>Array.from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } +>Array : ArrayConstructor +>from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } +>[] : never[] +>[0] : number[] +>0 : 0 +>(a1, a2) => a1 - a2 : (a1: number, a2: number) => number +>a1 : number +>a2 : number +>a1 - a2 : number +>a1 : number +>a2 : number + From c3b650fb38eaba314301edc0a6ce64a7b122acd2 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 10 Nov 2017 08:44:38 -0800 Subject: [PATCH 214/235] Accept API baseline changes --- tests/baselines/reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 78e8a377ec0..ffca9ca6c5a 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2142,6 +2142,7 @@ declare namespace ts { NakedTypeVariable = 2, MappedType = 4, ReturnType = 8, + NeverType = 16, } interface InferenceInfo { typeParameter: TypeParameter; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 3344193d0ce..dcc077d2cd7 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2142,6 +2142,7 @@ declare namespace ts { NakedTypeVariable = 2, MappedType = 4, ReturnType = 8, + NeverType = 16, } interface InferenceInfo { typeParameter: TypeParameter; From d6614447fd0d02f71580fd74e4ad33bb3cc08d56 Mon Sep 17 00:00:00 2001 From: csigs Date: Fri, 10 Nov 2017 17:10:05 +0000 Subject: [PATCH 215/235] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 160 +++++++++--------- .../diagnosticMessages.generated.json.lcl | 160 +++++++++--------- .../diagnosticMessages.generated.json.lcl | 160 +++++++++--------- 3 files changed, 231 insertions(+), 249 deletions(-) diff --git a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl index c59e9c20060..292a20a49bf 100644 --- a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1611,12 +1611,9 @@ - + - - - - + @@ -3726,6 +3723,24 @@ + + + + + + + + + + + + + + + + + + @@ -3957,6 +3972,15 @@ + + + + + + + + + @@ -5202,24 +5226,6 @@ - - - - - - - - - - - - - - - - - - @@ -5247,24 +5253,6 @@ - - - - - - - - - - - - - - - - - - @@ -5283,6 +5271,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -5988,6 +6000,24 @@ + + + + + + + + + + + + + + + + + + @@ -6015,30 +6045,21 @@ - + - - - - + - + - - - - + - + - - - - + @@ -6069,33 +6090,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl index b2ae023f5a4..6ea7ba86fc7 100644 --- a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1611,12 +1611,9 @@ - + - - - - + @@ -3726,6 +3723,24 @@ + + + + + + + + + + + + + + + + + + @@ -3957,6 +3972,15 @@ + + + + + + + + + @@ -5202,24 +5226,6 @@ - - - - - - - - - - - - - - - - - - @@ -5247,24 +5253,6 @@ - - - - - - - - - - - - - - - - - - @@ -5283,6 +5271,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -5988,6 +6000,24 @@ + + + + + + + + + + + + + + + + + + @@ -6015,30 +6045,21 @@ - + - - - - + - + - - - - + - + - - - - + @@ -6069,33 +6090,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl index 2693d7cce27..80c5f4e15d2 100644 --- a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1611,12 +1611,9 @@ - + - - - - + @@ -3726,6 +3723,24 @@ + + + + + + + + + + + + + + + + + + @@ -3957,6 +3972,15 @@ + + + + + + + + + @@ -5202,24 +5226,6 @@ - - - - - - - - - - - - - - - - - - @@ -5247,24 +5253,6 @@ - - - - - - - - - - - - - - - - - - @@ -5283,6 +5271,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -5988,6 +6000,24 @@ + + + + + + + + + + + + + + + + + + @@ -6015,30 +6045,21 @@ - + - - - - + - + - - - - + - + - - - - + @@ -6069,33 +6090,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - From 5ffcc421696a11e3db9398629d84fcfb4305826b Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 10 Nov 2017 09:34:20 -0800 Subject: [PATCH 216/235] Simplify setting constEnumOnlyModule (#19735) --- src/compiler/binder.ts | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 4e89abde780..a0146740678 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1570,7 +1570,7 @@ namespace ts { else { let pattern: Pattern | undefined; if (node.name.kind === SyntaxKind.StringLiteral) { - const text = (node.name).text; + const { text } = node.name; if (hasZeroOrOneAsteriskCharacter(text)) { pattern = tryParsePattern(text); } @@ -1589,22 +1589,13 @@ namespace ts { else { const state = declareModuleSymbol(node); if (state !== ModuleInstanceState.NonInstantiated) { - if (node.symbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.RegularEnum)) { - // if module was already merged with some function, class or non-const enum - // treat is a non-const-enum-only - node.symbol.constEnumOnlyModule = false; - } - else { - const currentModuleIsConstEnumOnly = state === ModuleInstanceState.ConstEnumOnly; - if (node.symbol.constEnumOnlyModule === undefined) { - // non-merged case - use the current state - node.symbol.constEnumOnlyModule = currentModuleIsConstEnumOnly; - } - else { - // merged case: module is const enum only if all its pieces are non-instantiated or const enum - node.symbol.constEnumOnlyModule = node.symbol.constEnumOnlyModule && currentModuleIsConstEnumOnly; - } - } + const { symbol } = node; + // if module was already merged with some function, class or non-const enum, treat it as non-const-enum-only + symbol.constEnumOnlyModule = (!(symbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.RegularEnum))) + // Current must be `const enum` only + && state === ModuleInstanceState.ConstEnumOnly + // Can't have been set to 'false' in a previous merged symbol. ('undefined' OK) + && symbol.constEnumOnlyModule !== false; } } } From 0d5800a17bc0ed88094b5dc3e8190128f4f71446 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 10 Nov 2017 09:37:06 -0800 Subject: [PATCH 217/235] Address PR comments --- src/harness/externalCompileRunner.ts | 62 +++++++++++++++++----------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/src/harness/externalCompileRunner.ts b/src/harness/externalCompileRunner.ts index ec8acf4872e..5730c5c3c83 100644 --- a/src/harness/externalCompileRunner.ts +++ b/src/harness/externalCompileRunner.ts @@ -2,9 +2,16 @@ /// const fs = require("fs"); const path = require("path"); + +interface ExecResult { + stdout: Buffer; + stderr: Buffer; + status: number; +} + abstract class ExternalCompileRunnerBase extends RunnerBase { abstract testDir: string; - abstract report(result: any, cwd: string): string; + abstract report(result: ExecResult, cwd: string): string; enumerateTestFiles() { return Harness.IO.getDirectories(this.testDir); } @@ -24,8 +31,6 @@ abstract class ExternalCompileRunnerBase extends RunnerBase { private runTest(directoryName: string) { describe(directoryName, () => { const cp = require("child_process"); - const path = require("path"); - const fs = require("fs"); it("should build successfully", () => { const cwd = path.join(__dirname, "../../", this.testDir, directoryName); @@ -51,7 +56,7 @@ class UserCodeRunner extends ExternalCompileRunnerBase { kind(): TestRunnerKind { return "user"; } - report(result: any) { + report(result: ExecResult) { // tslint:disable-next-line:no-null-keyword return result.status === 0 && !result.stdout.length && !result.stderr.length ? null : `Exit Code: ${result.status} Standard output: @@ -69,9 +74,9 @@ class DefinitelyTypedRunner extends ExternalCompileRunnerBase { kind(): TestRunnerKind { return "dt"; } - report(result: any, cwd: string) { - const stdout = filterExpectedErrors(result.stdout.toString(), cwd) - const stderr = result.stderr.toString() + report(result: ExecResult, cwd: string) { + const stdout = removeExpectedErrors(result.stdout.toString(), cwd); + const stderr = result.stderr.toString(); // tslint:disable-next-line:no-null-keyword return !stdout.length && !stderr.length ? null : `Exit Code: ${result.status} Standard output: @@ -83,29 +88,40 @@ ${stderr.replace(/\r\n/g, "\n")}`; } } -function filterExpectedErrors(errors: string, cwd: string): string { - return breaks(errors.split("\n"), s => /^\w+/.test(s)).filter(isExpectedError(cwd)).map(lines => lines.join("\n")).join("\n"); +function removeExpectedErrors(errors: string, cwd: string): string { + return ts.flatten(splitBy(errors.split("\n"), s => /^\S+/.test(s)).filter(isUnexpectedError(cwd))).join("\n"); } -function isExpectedError(cwd: string) { +/** + * Returns true if the line that caused the error contains '$ExpectError', + * or if the line before that one contains '$ExpectError'. + * '$ExpectError' is a marker used in Definitely Typed tests, + * meaning that the error should not contribute toward our error baslines. + */ +function isUnexpectedError(cwd: string) { return (error: string[]) => { - if (error.length === 0) { - return true; - } + ts.Debug.assertGreaterThanOrEqual(error.length, 1); const match = error[0].match(/(.+\.ts)\((\d+),\d+\): error TS/); if (!match) { return true; } - const errlines = fs.readFileSync(path.join(cwd, match[1]), { encoding: "utf8" }).split("\n"); - const index = parseInt(match[2]); - const errline = index < errlines.length ? errlines[index] : ""; - const prevline = index - 1 < errlines.length && index > 0 ? errlines[index - 1] : ""; - if (errline.indexOf("$ExpectError") > -1 || prevline.indexOf("$ExpectError") > -1) { - return false; - } - return true; - } + const [, errorFile, lineNumberString] = match; + const lines = fs.readFileSync(path.join(cwd, errorFile), { encoding: "utf8" }).split("\n"); + const lineNumber = parseInt(lineNumberString); + ts.Debug.assertGreaterThanOrEqual(lineNumber, 0); + ts.Debug.assertLessThan(lineNumber, lines.length); + const previousLine = lineNumber - 1 > 0 ? lines[lineNumber - 1] : ""; + return lines[lineNumber].indexOf("$ExpectError") === -1 && previousLine.indexOf("$ExpectError") === -1; + }; } -function breaks(xs: T[], isStart: (T: any) => boolean): T[][] { +/** + * Split an array into multiple arrays whenever `isStart` returns true. + * @example + * splitBy([1,2,3,4,5,6], isOdd) + * ==> [[1, 2], [3, 4], [5, 6]] + * where + * const isOdd = n => !!(n % 2) + */ +function splitBy(xs: T[], isStart: (x: T) => boolean): T[][] { const result = []; let group: T[] = []; for (const x of xs) { From 5fff71742b019be600b5bfe4c60e03afc73fe594 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 10 Nov 2017 10:11:44 -0800 Subject: [PATCH 218/235] Use ts.stringContains instead of String.indexOf --- src/harness/externalCompileRunner.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/harness/externalCompileRunner.ts b/src/harness/externalCompileRunner.ts index 5730c5c3c83..33803752f94 100644 --- a/src/harness/externalCompileRunner.ts +++ b/src/harness/externalCompileRunner.ts @@ -110,7 +110,7 @@ function isUnexpectedError(cwd: string) { ts.Debug.assertGreaterThanOrEqual(lineNumber, 0); ts.Debug.assertLessThan(lineNumber, lines.length); const previousLine = lineNumber - 1 > 0 ? lines[lineNumber - 1] : ""; - return lines[lineNumber].indexOf("$ExpectError") === -1 && previousLine.indexOf("$ExpectError") === -1; + return !ts.stringContains(lines[lineNumber], "$ExpectError") && !ts.stringContains(previousLine, "$ExpectError"); }; } /** From 06dd3f246f56c763d2df0eb8bcdccdb55cca869a Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 10 Nov 2017 12:55:07 -0800 Subject: [PATCH 219/235] Fail fast on synthetic nodes in services (#19894) --- src/services/services.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/services/services.ts b/src/services/services.ts index 06358d3a720..95e23a708a3 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -62,39 +62,52 @@ namespace ts { this.kind = kind; } + private assertHasRealPosition(message?: string) { + // tslint:disable-next-line:debug-assert + Debug.assert(!positionIsSynthesized(this.pos) && !positionIsSynthesized(this.end), message || "Node must have a real position for this operation"); + } + public getSourceFile(): SourceFile { return getSourceFileOfNode(this); } public getStart(sourceFile?: SourceFileLike, includeJsDocComment?: boolean): number { + this.assertHasRealPosition(); return getTokenPosOfNode(this, sourceFile, includeJsDocComment); } public getFullStart(): number { + this.assertHasRealPosition(); return this.pos; } public getEnd(): number { + this.assertHasRealPosition(); return this.end; } public getWidth(sourceFile?: SourceFile): number { + this.assertHasRealPosition(); return this.getEnd() - this.getStart(sourceFile); } public getFullWidth(): number { + this.assertHasRealPosition(); return this.end - this.pos; } public getLeadingTriviaWidth(sourceFile?: SourceFile): number { + this.assertHasRealPosition(); return this.getStart(sourceFile) - this.pos; } public getFullText(sourceFile?: SourceFile): string { + this.assertHasRealPosition(); return (sourceFile || this.getSourceFile()).text.substring(this.pos, this.end); } public getText(sourceFile?: SourceFile): string { + this.assertHasRealPosition(); if (!sourceFile) { sourceFile = this.getSourceFile(); } @@ -183,21 +196,25 @@ namespace ts { } public getChildCount(sourceFile?: SourceFile): number { + this.assertHasRealPosition(); if (!this._children) this.createChildren(sourceFile); return this._children.length; } public getChildAt(index: number, sourceFile?: SourceFile): Node { + this.assertHasRealPosition(); if (!this._children) this.createChildren(sourceFile); return this._children[index]; } public getChildren(sourceFile?: SourceFileLike): Node[] { + this.assertHasRealPosition("Node without a real position cannot be scanned and thus has no token nodes - use forEachChild and collect the result if that's fine"); if (!this._children) this.createChildren(sourceFile); return this._children; } public getFirstToken(sourceFile?: SourceFile): Node { + this.assertHasRealPosition(); const children = this.getChildren(sourceFile); if (!children.length) { return undefined; @@ -210,6 +227,7 @@ namespace ts { } public getLastToken(sourceFile?: SourceFile): Node { + this.assertHasRealPosition(); const children = this.getChildren(sourceFile); const child = lastOrUndefined(children); From 1579f2f7bf1d6b5d1716876ad3b2d41f4f4b9842 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 14 Jul 2017 16:26:37 -0700 Subject: [PATCH 220/235] Add 'scripthost' to 'lib' for the 'generate-spec' target. --- Jakefile.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Jakefile.js b/Jakefile.js index c2d0717641f..4f39d6af5c6 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -731,7 +731,10 @@ compileFile(word2mdJs, [word2mdTs], [word2mdTs], [], - /*useBuiltCompiler*/ false); + /*useBuiltCompiler*/ false, + { + lib: "scripthost,es5" + }); // The generated spec.md; built for the 'generate-spec' task file(specMd, [word2mdJs, specWord], function () { From 7d5f5fd5556339311b2bf41de9edb92d1a53585c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 10 Nov 2017 13:13:21 -0800 Subject: [PATCH 221/235] Make comparable relationship bidirectional for primitive types --- src/compiler/checker.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a9aaa77fa74..19cc2351e39 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8907,7 +8907,9 @@ namespace ts { if (target.flags & TypeFlags.StringOrNumberLiteral && target.flags & TypeFlags.FreshLiteral) { target = (target).regularType; } - if (source === target || relation !== identityRelation && isSimpleTypeRelatedTo(source, target, relation)) { + if (source === target || + relation === comparableRelation && !(target.flags & TypeFlags.Never) && isSimpleTypeRelatedTo(target, source, relation) || + relation !== identityRelation && isSimpleTypeRelatedTo(source, target, relation)) { return true; } if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Object) { @@ -9050,7 +9052,8 @@ namespace ts { return isIdenticalTo(source, target); } - if (isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined)) return Ternary.True; + if (relation === comparableRelation && !(target.flags & TypeFlags.Never) && isSimpleTypeRelatedTo(target, source, relation) || + isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined)) return Ternary.True; if (isObjectLiteralType(source) && source.flags & TypeFlags.FreshLiteral) { if (hasExcessProperties(source, target, reportErrors)) { From d15926d9c7bdef8efc4c671914777304695e316f Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 10 Nov 2017 13:13:32 -0800 Subject: [PATCH 222/235] Add test --- .../reference/independentPropertyVariance.js | 13 +++++++++++++ .../independentPropertyVariance.symbols | 17 +++++++++++++++++ .../independentPropertyVariance.types | 18 ++++++++++++++++++ .../comparable/independentPropertyVariance.ts | 8 ++++++++ 4 files changed, 56 insertions(+) create mode 100644 tests/baselines/reference/independentPropertyVariance.js create mode 100644 tests/baselines/reference/independentPropertyVariance.symbols create mode 100644 tests/baselines/reference/independentPropertyVariance.types create mode 100644 tests/cases/conformance/types/typeRelationships/comparable/independentPropertyVariance.ts diff --git a/tests/baselines/reference/independentPropertyVariance.js b/tests/baselines/reference/independentPropertyVariance.js new file mode 100644 index 00000000000..612877bd973 --- /dev/null +++ b/tests/baselines/reference/independentPropertyVariance.js @@ -0,0 +1,13 @@ +//// [independentPropertyVariance.ts] +// Verify that properties can vary idependently in comparable relationship + +declare const x: { a: 1, b: string }; +declare const y: { a: number, b: 'a' }; + +x === y; + + +//// [independentPropertyVariance.js] +"use strict"; +// Verify that properties can vary idependently in comparable relationship +x === y; diff --git a/tests/baselines/reference/independentPropertyVariance.symbols b/tests/baselines/reference/independentPropertyVariance.symbols new file mode 100644 index 00000000000..19c691e6348 --- /dev/null +++ b/tests/baselines/reference/independentPropertyVariance.symbols @@ -0,0 +1,17 @@ +=== tests/cases/conformance/types/typeRelationships/comparable/independentPropertyVariance.ts === +// Verify that properties can vary idependently in comparable relationship + +declare const x: { a: 1, b: string }; +>x : Symbol(x, Decl(independentPropertyVariance.ts, 2, 13)) +>a : Symbol(a, Decl(independentPropertyVariance.ts, 2, 18)) +>b : Symbol(b, Decl(independentPropertyVariance.ts, 2, 24)) + +declare const y: { a: number, b: 'a' }; +>y : Symbol(y, Decl(independentPropertyVariance.ts, 3, 13)) +>a : Symbol(a, Decl(independentPropertyVariance.ts, 3, 18)) +>b : Symbol(b, Decl(independentPropertyVariance.ts, 3, 29)) + +x === y; +>x : Symbol(x, Decl(independentPropertyVariance.ts, 2, 13)) +>y : Symbol(y, Decl(independentPropertyVariance.ts, 3, 13)) + diff --git a/tests/baselines/reference/independentPropertyVariance.types b/tests/baselines/reference/independentPropertyVariance.types new file mode 100644 index 00000000000..cb5261a2114 --- /dev/null +++ b/tests/baselines/reference/independentPropertyVariance.types @@ -0,0 +1,18 @@ +=== tests/cases/conformance/types/typeRelationships/comparable/independentPropertyVariance.ts === +// Verify that properties can vary idependently in comparable relationship + +declare const x: { a: 1, b: string }; +>x : { a: 1; b: string; } +>a : 1 +>b : string + +declare const y: { a: number, b: 'a' }; +>y : { a: number; b: "a"; } +>a : number +>b : "a" + +x === y; +>x === y : boolean +>x : { a: 1; b: string; } +>y : { a: number; b: "a"; } + diff --git a/tests/cases/conformance/types/typeRelationships/comparable/independentPropertyVariance.ts b/tests/cases/conformance/types/typeRelationships/comparable/independentPropertyVariance.ts new file mode 100644 index 00000000000..9f71a0c656d --- /dev/null +++ b/tests/cases/conformance/types/typeRelationships/comparable/independentPropertyVariance.ts @@ -0,0 +1,8 @@ +// @strict: true + +// Verify that properties can vary idependently in comparable relationship + +declare const x: { a: 1, b: string }; +declare const y: { a: number, b: 'a' }; + +x === y; From 16b68ff25b538bb233a8e7f3dd8092c91bf9f3c5 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 10 Nov 2017 13:46:51 -0800 Subject: [PATCH 223/235] Fix typo --- tests/baselines/reference/independentPropertyVariance.js | 4 ++-- tests/baselines/reference/independentPropertyVariance.symbols | 2 +- tests/baselines/reference/independentPropertyVariance.types | 2 +- .../comparable/independentPropertyVariance.ts | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/baselines/reference/independentPropertyVariance.js b/tests/baselines/reference/independentPropertyVariance.js index 612877bd973..2439d8140fa 100644 --- a/tests/baselines/reference/independentPropertyVariance.js +++ b/tests/baselines/reference/independentPropertyVariance.js @@ -1,5 +1,5 @@ //// [independentPropertyVariance.ts] -// Verify that properties can vary idependently in comparable relationship +// Verify that properties can vary independently in comparable relationship declare const x: { a: 1, b: string }; declare const y: { a: number, b: 'a' }; @@ -9,5 +9,5 @@ x === y; //// [independentPropertyVariance.js] "use strict"; -// Verify that properties can vary idependently in comparable relationship +// Verify that properties can vary independently in comparable relationship x === y; diff --git a/tests/baselines/reference/independentPropertyVariance.symbols b/tests/baselines/reference/independentPropertyVariance.symbols index 19c691e6348..cf503476008 100644 --- a/tests/baselines/reference/independentPropertyVariance.symbols +++ b/tests/baselines/reference/independentPropertyVariance.symbols @@ -1,5 +1,5 @@ === tests/cases/conformance/types/typeRelationships/comparable/independentPropertyVariance.ts === -// Verify that properties can vary idependently in comparable relationship +// Verify that properties can vary independently in comparable relationship declare const x: { a: 1, b: string }; >x : Symbol(x, Decl(independentPropertyVariance.ts, 2, 13)) diff --git a/tests/baselines/reference/independentPropertyVariance.types b/tests/baselines/reference/independentPropertyVariance.types index cb5261a2114..d2808166e01 100644 --- a/tests/baselines/reference/independentPropertyVariance.types +++ b/tests/baselines/reference/independentPropertyVariance.types @@ -1,5 +1,5 @@ === tests/cases/conformance/types/typeRelationships/comparable/independentPropertyVariance.ts === -// Verify that properties can vary idependently in comparable relationship +// Verify that properties can vary independently in comparable relationship declare const x: { a: 1, b: string }; >x : { a: 1; b: string; } diff --git a/tests/cases/conformance/types/typeRelationships/comparable/independentPropertyVariance.ts b/tests/cases/conformance/types/typeRelationships/comparable/independentPropertyVariance.ts index 9f71a0c656d..cec30104c49 100644 --- a/tests/cases/conformance/types/typeRelationships/comparable/independentPropertyVariance.ts +++ b/tests/cases/conformance/types/typeRelationships/comparable/independentPropertyVariance.ts @@ -1,6 +1,6 @@ // @strict: true -// Verify that properties can vary idependently in comparable relationship +// Verify that properties can vary independently in comparable relationship declare const x: { a: 1, b: string }; declare const y: { a: number, b: 'a' }; From d66e94d09e6e66574b06a8fe01d1db63eb7b6a74 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 10 Nov 2017 13:50:18 -0800 Subject: [PATCH 224/235] ExternalCompileRunner works with submodules If there is a test.json in the directory, it expects to find a submodule in the directory. The submodule should have the same name as the directory itself. test.json contains a list of global types that need to be available, or the empty list if none. --- .gitmodules | 6 +++++ src/harness/externalCompileRunner.ts | 26 ++++++++++++++++--- .../TypeScript-Node-Starter | 1 + .../TypeScript-React-Starter | 1 + 4 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 .gitmodules create mode 160000 tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter create mode 160000 tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000000..1a1c6e193fd --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter"] + path = tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter + url = https://github.com/Microsoft/TypeScript-React-Starter +[submodule "tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter"] + path = tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter + url = https://github.com/Microsoft/TypeScript-Node-Starter.git diff --git a/src/harness/externalCompileRunner.ts b/src/harness/externalCompileRunner.ts index 33803752f94..0f9386ddb0f 100644 --- a/src/harness/externalCompileRunner.ts +++ b/src/harness/externalCompileRunner.ts @@ -9,6 +9,10 @@ interface ExecResult { status: number; } +interface UserConfig { + types: string[]; +} + abstract class ExternalCompileRunnerBase extends RunnerBase { abstract testDir: string; abstract report(result: ExecResult, cwd: string): string; @@ -33,18 +37,34 @@ abstract class ExternalCompileRunnerBase extends RunnerBase { const cp = require("child_process"); it("should build successfully", () => { - const cwd = path.join(__dirname, "../../", this.testDir, directoryName); + let cwd = path.join(__dirname, "../../", this.testDir, directoryName); const timeout = 600000; // 600s = 10 minutes + const stdio = isWorker ? "pipe" : "inherit"; + let types: string[]; + if (fs.existsSync(path.join(cwd, "test.json"))) { + const update = cp.spawnSync('git', ["submodule", "update", "--remote"], { cwd, timeout, shell: true, stdio }) + if (update.status !== 0) throw new Error(`git submodule update for ${directoryName} failed!`); + + const config = JSON.parse(fs.readFileSync(path.join(cwd, "test.json"), { encoding: "utf8" })) as UserConfig; + ts.Debug.assert(!!config.types, "Git is the only reason for using test.json right now"); + types = config.types; + + cwd = path.join(cwd, directoryName); + } if (fs.existsSync(path.join(cwd, "package.json"))) { if (fs.existsSync(path.join(cwd, "package-lock.json"))) { fs.unlinkSync(path.join(cwd, "package-lock.json")); } - const stdio = isWorker ? "pipe" : "inherit"; const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout, shell: true, stdio }); if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed!`); } + const args = [path.join(__dirname, "tsc.js")]; + if (types) { + args.push("--types", types.join(",")); + } + args.push("--noEmit"); Harness.Baseline.runBaseline(`${this.kind()}/${directoryName}.log`, () => { - return this.report(cp.spawnSync(`node`, [path.join(__dirname, "tsc.js")], { cwd, timeout, shell: true }), cwd); + return this.report(cp.spawnSync(`node`, args, { cwd, timeout, shell: true }), cwd); }); }); }); diff --git a/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter b/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter new file mode 160000 index 00000000000..ed149eb0c78 --- /dev/null +++ b/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter @@ -0,0 +1 @@ +Subproject commit ed149eb0c787b1195a95b44105822c64bb6eb636 diff --git a/tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter b/tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter new file mode 160000 index 00000000000..96fb6237a9d --- /dev/null +++ b/tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter @@ -0,0 +1 @@ +Subproject commit 96fb6237a9dda8d17059eea7fa7c22dd7db82c97 From c82c6f21cb0305ec1dc18a6118895444b05489d1 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 10 Nov 2017 14:03:41 -0800 Subject: [PATCH 225/235] Ensure that enum member value is computed before using it Fixes #19898 --- src/compiler/checker.ts | 2 +- src/harness/unittests/tscWatchMode.ts | 30 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a9aaa77fa74..664d93d57ed 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -22412,7 +22412,7 @@ namespace ts { const declaration = memberSymbol.valueDeclaration; if (declaration !== member) { if (isBlockScopedNameDeclaredBeforeUse(declaration, member)) { - return getNodeLinks(declaration).enumMemberValue; + return getEnumMemberValue(declaration as EnumMember); } error(expr, Diagnostics.A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums); return 0; diff --git a/src/harness/unittests/tscWatchMode.ts b/src/harness/unittests/tscWatchMode.ts index fc80a6f39ef..4e2d63cec90 100644 --- a/src/harness/unittests/tscWatchMode.ts +++ b/src/harness/unittests/tscWatchMode.ts @@ -1616,6 +1616,36 @@ namespace ts.tscWatch { return files.slice(0, 2); } }); + + it("Elides const enums correctly in incremental compilation", () => { + const currentDirectory = "/user/someone/projects/myproject"; + const file1: FileOrFolder = { + path: `${currentDirectory}/file1.ts`, + content: "export const enum E1 { V = 1 }" + }; + const file2: FileOrFolder = { + path: `${currentDirectory}/file2.ts`, + content: `import { E1 } from "./file1"; export const enum E2 { V = E1.V }` + }; + const file3: FileOrFolder = { + path: `${currentDirectory}/file3.ts`, + content: `import { E2 } from "./file2"; const v: E2 = E2.V;` + }; + const strictAndEsModule = `"use strict";\nexports.__esModule = true;\n`; + verifyEmittedFileContents("\n", [file3, file2, file1], [ + `${strictAndEsModule}var v = 1 /* V */;\n`, + strictAndEsModule, + strictAndEsModule + ], modifyFiles); + + function modifyFiles(files: FileOrFolderEmit[], emittedFiles: EmittedFile[]) { + files[0].content += `function foo2() { return 2; }`; + emittedFiles[0].content += `function foo2() { return 2; }\n`; + emittedFiles[1].shouldBeWritten = false; + emittedFiles[2].shouldBeWritten = false; + return [files[0]]; + } + }); }); describe("tsc-watch module resolution caching", () => { From d4c001d47c90d14a1ca020d2877babf58fffeb90 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 10 Nov 2017 14:20:55 -0800 Subject: [PATCH 226/235] Add test w/submodules for our starter kits --- .gitmodules | 9 +++++++++ tests/cases/user/TypeScript-Node-Starter/test.json | 3 +++ .../TypeScript-React-Native-Starter | 1 + .../cases/user/TypeScript-React-Native-Starter/test.json | 3 +++ tests/cases/user/TypeScript-React-Starter/test.json | 3 +++ .../user/TypeScript-Vue-Starter/TypeScript-Vue-Starter | 1 + tests/cases/user/TypeScript-Vue-Starter/test.json | 3 +++ .../TypeScript-WeChat-Starter/TypeScript-WeChat-Starter | 1 + tests/cases/user/TypeScript-WeChat-Starter/test.json | 3 +++ 9 files changed, 27 insertions(+) create mode 100644 tests/cases/user/TypeScript-Node-Starter/test.json create mode 160000 tests/cases/user/TypeScript-React-Native-Starter/TypeScript-React-Native-Starter create mode 100644 tests/cases/user/TypeScript-React-Native-Starter/test.json create mode 100644 tests/cases/user/TypeScript-React-Starter/test.json create mode 160000 tests/cases/user/TypeScript-Vue-Starter/TypeScript-Vue-Starter create mode 100644 tests/cases/user/TypeScript-Vue-Starter/test.json create mode 160000 tests/cases/user/TypeScript-WeChat-Starter/TypeScript-WeChat-Starter create mode 100644 tests/cases/user/TypeScript-WeChat-Starter/test.json diff --git a/.gitmodules b/.gitmodules index 1a1c6e193fd..f83d0f77c9e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,12 @@ [submodule "tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter"] path = tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter url = https://github.com/Microsoft/TypeScript-Node-Starter.git +[submodule "tests/cases/user/TypeScript-React-Native-Starter/TypeScript-React-Native-Starter"] + path = tests/cases/user/TypeScript-React-Native-Starter/TypeScript-React-Native-Starter + url = https://github.com/Microsoft/TypeScript-React-Native-Starter.git +[submodule "tests/cases/user/TypeScript-Vue-Starter/TypeScript-Vue-Starter"] + path = tests/cases/user/TypeScript-Vue-Starter/TypeScript-Vue-Starter + url = https://github.com/Microsoft/TypeScript-Vue-Starter.git +[submodule "tests/cases/user/TypeScript-WeChat-Starter/TypeScript-WeChat-Starter"] + path = tests/cases/user/TypeScript-WeChat-Starter/TypeScript-WeChat-Starter + url = https://github.com/Microsoft/TypeScript-WeChat-Starter.git diff --git a/tests/cases/user/TypeScript-Node-Starter/test.json b/tests/cases/user/TypeScript-Node-Starter/test.json new file mode 100644 index 00000000000..11d2aa87c59 --- /dev/null +++ b/tests/cases/user/TypeScript-Node-Starter/test.json @@ -0,0 +1,3 @@ +{ + "types": ["jquery"] +} diff --git a/tests/cases/user/TypeScript-React-Native-Starter/TypeScript-React-Native-Starter b/tests/cases/user/TypeScript-React-Native-Starter/TypeScript-React-Native-Starter new file mode 160000 index 00000000000..2c62f5a4ea5 --- /dev/null +++ b/tests/cases/user/TypeScript-React-Native-Starter/TypeScript-React-Native-Starter @@ -0,0 +1 @@ +Subproject commit 2c62f5a4ea51978e3715b475e17962cdeca75e38 diff --git a/tests/cases/user/TypeScript-React-Native-Starter/test.json b/tests/cases/user/TypeScript-React-Native-Starter/test.json new file mode 100644 index 00000000000..8b177c575aa --- /dev/null +++ b/tests/cases/user/TypeScript-React-Native-Starter/test.json @@ -0,0 +1,3 @@ +{ + "types": ["jest"] +} diff --git a/tests/cases/user/TypeScript-React-Starter/test.json b/tests/cases/user/TypeScript-React-Starter/test.json new file mode 100644 index 00000000000..8b177c575aa --- /dev/null +++ b/tests/cases/user/TypeScript-React-Starter/test.json @@ -0,0 +1,3 @@ +{ + "types": ["jest"] +} diff --git a/tests/cases/user/TypeScript-Vue-Starter/TypeScript-Vue-Starter b/tests/cases/user/TypeScript-Vue-Starter/TypeScript-Vue-Starter new file mode 160000 index 00000000000..713c6986f04 --- /dev/null +++ b/tests/cases/user/TypeScript-Vue-Starter/TypeScript-Vue-Starter @@ -0,0 +1 @@ +Subproject commit 713c6986f043f2c31976b8bc2c03aa0a2b05590b diff --git a/tests/cases/user/TypeScript-Vue-Starter/test.json b/tests/cases/user/TypeScript-Vue-Starter/test.json new file mode 100644 index 00000000000..e0d4d26bdca --- /dev/null +++ b/tests/cases/user/TypeScript-Vue-Starter/test.json @@ -0,0 +1,3 @@ +{ + "types": [] +} diff --git a/tests/cases/user/TypeScript-WeChat-Starter/TypeScript-WeChat-Starter b/tests/cases/user/TypeScript-WeChat-Starter/TypeScript-WeChat-Starter new file mode 160000 index 00000000000..5fca1032eda --- /dev/null +++ b/tests/cases/user/TypeScript-WeChat-Starter/TypeScript-WeChat-Starter @@ -0,0 +1 @@ +Subproject commit 5fca1032edaab5414ec1c167f42d3dc59220d9aa diff --git a/tests/cases/user/TypeScript-WeChat-Starter/test.json b/tests/cases/user/TypeScript-WeChat-Starter/test.json new file mode 100644 index 00000000000..e0d4d26bdca --- /dev/null +++ b/tests/cases/user/TypeScript-WeChat-Starter/test.json @@ -0,0 +1,3 @@ +{ + "types": [] +} From 0d63589fb2da23c0a243a8fd47cb0c96df6deac7 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 10 Nov 2017 14:21:53 -0800 Subject: [PATCH 227/235] Fix quote lint --- src/harness/externalCompileRunner.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/harness/externalCompileRunner.ts b/src/harness/externalCompileRunner.ts index 0f9386ddb0f..75ccecb047d 100644 --- a/src/harness/externalCompileRunner.ts +++ b/src/harness/externalCompileRunner.ts @@ -42,7 +42,7 @@ abstract class ExternalCompileRunnerBase extends RunnerBase { const stdio = isWorker ? "pipe" : "inherit"; let types: string[]; if (fs.existsSync(path.join(cwd, "test.json"))) { - const update = cp.spawnSync('git', ["submodule", "update", "--remote"], { cwd, timeout, shell: true, stdio }) + const update = cp.spawnSync("git", ["submodule", "update", "--remote"], { cwd, timeout, shell: true, stdio }); if (update.status !== 0) throw new Error(`git submodule update for ${directoryName} failed!`); const config = JSON.parse(fs.readFileSync(path.join(cwd, "test.json"), { encoding: "utf8" })) as UserConfig; From ba232b2164e7d0789bdc668e6b750696f8f7a8e2 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 10 Nov 2017 14:36:49 -0800 Subject: [PATCH 228/235] Update baselines --- tests/baselines/reference/user/electron.log | 2 +- tests/baselines/reference/user/leveldown.log | 2 +- tests/baselines/reference/user/rxjs.log | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/baselines/reference/user/electron.log b/tests/baselines/reference/user/electron.log index e5eef689d49..7ba43481c3b 100644 --- a/tests/baselines/reference/user/electron.log +++ b/tests/baselines/reference/user/electron.log @@ -1,4 +1,4 @@ -Exit Code: 2 +Exit Code: 1 Standard output: node_modules/electron/electron.d.ts(5390,13): error TS2430: Interface 'WebviewTag' incorrectly extends interface 'HTMLElement'. Types of property 'addEventListener' are incompatible. diff --git a/tests/baselines/reference/user/leveldown.log b/tests/baselines/reference/user/leveldown.log index c37a983f73d..011071ebc52 100644 --- a/tests/baselines/reference/user/leveldown.log +++ b/tests/baselines/reference/user/leveldown.log @@ -1,4 +1,4 @@ -Exit Code: 2 +Exit Code: 1 Standard output: node_modules/abstract-leveldown/index.d.ts(2,3): error TS7010: 'open', which lacks return-type annotation, implicitly has an 'any' return type. node_modules/abstract-leveldown/index.d.ts(3,3): error TS7010: 'open', which lacks return-type annotation, implicitly has an 'any' return type. diff --git a/tests/baselines/reference/user/rxjs.log b/tests/baselines/reference/user/rxjs.log index 73058119ce9..c17014c5c13 100644 --- a/tests/baselines/reference/user/rxjs.log +++ b/tests/baselines/reference/user/rxjs.log @@ -1,4 +1,4 @@ -Exit Code: 2 +Exit Code: 1 Standard output: node_modules/rxjs/scheduler/VirtualTimeScheduler.d.ts(22,22): error TS2415: Class 'VirtualAction' incorrectly extends base class 'AsyncAction'. Types of property 'work' are incompatible. From 19b26c564cf18a3a76d00204d8fa92979f20e1f9 Mon Sep 17 00:00:00 2001 From: csigs Date: Fri, 10 Nov 2017 23:10:42 +0000 Subject: [PATCH 229/235] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 160 +++++++++--------- .../diagnosticMessages.generated.json.lcl | 160 +++++++++--------- .../diagnosticMessages.generated.json.lcl | 160 +++++++++--------- .../diagnosticMessages.generated.json.lcl | 160 +++++++++--------- .../diagnosticMessages.generated.json.lcl | 142 +++++++--------- .../diagnosticMessages.generated.json.lcl | 160 +++++++++--------- 6 files changed, 444 insertions(+), 498 deletions(-) diff --git a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl index 2bf61430d60..803d5940ac2 100644 --- a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1620,12 +1620,9 @@ - + - - - - + @@ -3735,6 +3732,24 @@ + + + + + + + + + + + + + + + + + + @@ -3966,6 +3981,15 @@ + + + + + + + + + @@ -5211,24 +5235,6 @@ - - - - - - - - - - - - - - - - - - @@ -5256,24 +5262,6 @@ - - - - - - - - - - - - - - - - - - @@ -5292,6 +5280,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -5997,6 +6009,24 @@ + + + + + + + + + + + + + + + + + + @@ -6024,30 +6054,21 @@ - + - - - - + - + - - - - + - + - - - - + @@ -6078,33 +6099,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl index 31f3bfdefd5..2e603f114b6 100644 --- a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1611,12 +1611,9 @@ - + - - - - + @@ -3726,6 +3723,24 @@ + + + + + + + + + + + + + + + + + + @@ -3957,6 +3972,15 @@ + + + + + + + + + @@ -5202,24 +5226,6 @@ - - - - - - - - - - - - - - - - - - @@ -5247,24 +5253,6 @@ - - - - - - - - - - - - - - - - - - @@ -5283,6 +5271,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -5988,6 +6000,24 @@ + + + + + + + + + + + + + + + + + + @@ -6015,30 +6045,21 @@ - + - - - - + - + - - - - + - + - - - - + @@ -6069,33 +6090,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl index b9d115872b6..0badf531a75 100644 --- a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1598,12 +1598,9 @@ - + - - - - + @@ -3707,6 +3704,24 @@ + + + + + + + + + + + + + + + + + + @@ -3938,6 +3953,15 @@ + + + + + + + + + @@ -5183,24 +5207,6 @@ - - - - - - - - - - - - - - - - - - @@ -5228,24 +5234,6 @@ - - - - - - - - - - - - - - - - - - @@ -5264,6 +5252,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -5963,6 +5975,24 @@ + + + + + + + + + + + + + + + + + + @@ -5990,30 +6020,21 @@ - + - - - - + - + - - - - + - + - - - - + @@ -6044,33 +6065,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl index 1e480ff2a08..7677920dd1d 100644 --- a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1598,12 +1598,9 @@ - + - - - - + @@ -3707,6 +3704,24 @@ + + + + + + + + + + + + + + + + + + @@ -3938,6 +3953,15 @@ + + + + + + + + + @@ -5183,24 +5207,6 @@ - - - - - - - - - - - - - - - - - - @@ -5228,24 +5234,6 @@ - - - - - - - - - - - - - - - - - - @@ -5264,6 +5252,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -5963,6 +5975,24 @@ + + + + + + + + + + + + + + + + + + @@ -5990,30 +6020,21 @@ - + - - - - + - + - - - - + - + - - - - + @@ -6044,33 +6065,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl index bd78324f196..b71915fbd67 100644 --- a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1610,12 +1610,9 @@ - + - - - - + @@ -3728,12 +3725,18 @@ + + + + + + @@ -3971,6 +3974,9 @@ + + + @@ -5219,24 +5225,6 @@ - - - - - - - - - - - - - - - - - - @@ -5264,24 +5252,6 @@ - - - - - - - - - - - - - - - - - - @@ -5300,6 +5270,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -6005,6 +5999,24 @@ + + + + + + + + + + + + + + + + + + @@ -6032,30 +6044,21 @@ - + - - - - + - + - - - - + - + - - - - + @@ -6086,33 +6089,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 0eafa4da0b2..6c92a1c0bd1 100644 --- a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1604,12 +1604,9 @@ - + - - - - + @@ -3719,6 +3716,24 @@ + + + + + + + + + + + + + + + + + + @@ -3950,6 +3965,15 @@ + + + + + + + + + @@ -5195,24 +5219,6 @@ - - - - - - - - - - - - - - - - - - @@ -5240,24 +5246,6 @@ - - - - - - - - - - - - - - - - - - @@ -5276,6 +5264,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -5981,6 +5993,24 @@ + + + + + + + + + + + + + + + + + + @@ -6008,30 +6038,21 @@ - + - - - - + - + - - - - + - + - - - - + @@ -6062,33 +6083,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - From 4d0139084596a18a2ba0af583bd2cc3bad164aab Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 10 Nov 2017 15:55:29 -0800 Subject: [PATCH 230/235] Improve assert message --- src/harness/externalCompileRunner.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/harness/externalCompileRunner.ts b/src/harness/externalCompileRunner.ts index 75ccecb047d..2a44badd813 100644 --- a/src/harness/externalCompileRunner.ts +++ b/src/harness/externalCompileRunner.ts @@ -46,7 +46,7 @@ abstract class ExternalCompileRunnerBase extends RunnerBase { if (update.status !== 0) throw new Error(`git submodule update for ${directoryName} failed!`); const config = JSON.parse(fs.readFileSync(path.join(cwd, "test.json"), { encoding: "utf8" })) as UserConfig; - ts.Debug.assert(!!config.types, "Git is the only reason for using test.json right now"); + ts.Debug.assert(!!config.types, "Bad format from test.json: Types field must be present."); types = config.types; cwd = path.join(cwd, directoryName); From 59fca7fc30bfbcdde8d5b3e544bdf09da5fa9e9a Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 10 Nov 2017 16:26:16 -0800 Subject: [PATCH 231/235] Fix crash when running tsc with -diagnostics --- src/compiler/performance.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/performance.ts b/src/compiler/performance.ts index 225b34de9cf..104148ed4ab 100644 --- a/src/compiler/performance.ts +++ b/src/compiler/performance.ts @@ -10,7 +10,8 @@ namespace ts { namespace ts.performance { declare const onProfilerEvent: { (markName: string): void; profiler: boolean; }; - const profilerEvent: (markName: string) => void = typeof onProfilerEvent === "function" && onProfilerEvent.profiler === true ? onProfilerEvent : noop; + // NOTE: cannot use ts.noop as core.ts loads after this + const profilerEvent: (markName: string) => void = typeof onProfilerEvent === "function" && onProfilerEvent.profiler === true ? onProfilerEvent : () => { /*empty*/ }; let enabled = false; let profilerStart = 0; From cba2e966a37f843150809659e0f762985f988bcd Mon Sep 17 00:00:00 2001 From: csigs Date: Sat, 11 Nov 2017 05:10:06 +0000 Subject: [PATCH 232/235] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 160 +++++++++--------- 1 file changed, 77 insertions(+), 83 deletions(-) diff --git a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl index c00e5a2a2e7..d362101e51f 100644 --- a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1605,12 +1605,9 @@ - + - - - - + @@ -3714,6 +3711,24 @@ + + + + + + + + + + + + + + + + + + @@ -3945,6 +3960,15 @@ + + + + + + + + + @@ -5190,24 +5214,6 @@ - - - - - - - - - - - - - - - - - - @@ -5235,24 +5241,6 @@ - - - - - - - - - - - - - - - - - - @@ -5271,6 +5259,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -5970,6 +5982,24 @@ + + + + + + + + + + + + + + + + + + @@ -5997,30 +6027,21 @@ - + - - - - + - + - - - - + - + - - - - + @@ -6051,33 +6072,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - From 74fe5c5b74983a2b152b4fe3e23b2e450431128b Mon Sep 17 00:00:00 2001 From: csigs Date: Mon, 13 Nov 2017 17:10:16 +0000 Subject: [PATCH 233/235] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 160 +++++++++--------- .../diagnosticMessages.generated.json.lcl | 160 +++++++++--------- 2 files changed, 154 insertions(+), 166 deletions(-) diff --git a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl index 929b7edf058..a55da48f2c2 100644 --- a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1611,12 +1611,9 @@ - + - - - - + @@ -3726,6 +3723,24 @@ + + + + + + + + + + + + + + + + + + @@ -3957,6 +3972,15 @@ + + + + + + + + + @@ -5202,24 +5226,6 @@ - - - - - - - - - - - - - - - - - - @@ -5247,24 +5253,6 @@ - - - - - - - - - - - - - - - - - - @@ -5283,6 +5271,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -5988,6 +6000,24 @@ + + + + + + + + + + + + + + + + + + @@ -6015,30 +6045,21 @@ - + - - - - + - + - - - - + - + - - - - + @@ -6069,33 +6090,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl index 4865cf6c508..58a00519e04 100644 --- a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1620,12 +1620,9 @@ - + - - - - + @@ -3735,6 +3732,24 @@ + + + + + + + + + + + + + + + + + + @@ -3966,6 +3981,15 @@ + + + + + + + + + @@ -5211,24 +5235,6 @@ - - - - - - - - - - - - - - - - - - @@ -5256,24 +5262,6 @@ - - - - - - - - - - - - - - - - - - @@ -5292,6 +5280,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -5997,6 +6009,24 @@ + + + + + + + + + + + + + + + + + + @@ -6024,30 +6054,21 @@ - + - - - - + - + - - - - + - + - - - - + @@ -6078,33 +6099,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - From e7df83263df9433d2b27a2b86e9d198fca68bd92 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 13 Nov 2017 09:18:36 -0800 Subject: [PATCH 234/235] Break out of speculative parsing on bad parameter initializer (#19158) * Break out of speculative parsing on bad parameter initializer * Remove uses of 'finally' * give up -> stop * Do without exceptions * Remove `resetAfterSpeculation` * Use Fail and FailList objects * Remove `inSpeculation` parameter to parseDelimitedList * Don't use `createNodeArray`, it's not always in scope * Move Fail and FailList inside initializeState * More code review * More code review --- src/compiler/parser.ts | 180 +++++++++++++----- .../parserArrowFunctionExpression7.js | 16 ++ .../parserArrowFunctionExpression7.symbols | 10 + .../parserArrowFunctionExpression7.types | 13 ++ .../parserArrowFunctionExpression7.ts | 7 + 5 files changed, 176 insertions(+), 50 deletions(-) create mode 100644 tests/baselines/reference/parserArrowFunctionExpression7.js create mode 100644 tests/baselines/reference/parserArrowFunctionExpression7.symbols create mode 100644 tests/baselines/reference/parserArrowFunctionExpression7.types create mode 100644 tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression7.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 79b5eb30c49..64cd8219a01 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -531,6 +531,18 @@ namespace ts { let TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let IdentifierConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; + interface Fail extends Node { kind: SyntaxKind.Unknown; } + interface FailList extends NodeArray { pos: -1; } + let Fail: Fail; + let FailList: FailList; + function isFail(x: Node | undefined): x is Fail { + Debug.assert(Fail !== undefined); + return x === Fail; + } + function isFailList(x: NodeArray | undefined): x is FailList { + Debug.assert(Fail !== undefined); + return x === FailList; + } // tslint:enable variable-name let sourceFile: SourceFile; @@ -681,6 +693,9 @@ namespace ts { IdentifierConstructor = objectAllocator.getIdentifierConstructor(); SourceFileConstructor = objectAllocator.getSourceFileConstructor(); + Fail = createNode(SyntaxKind.Unknown) as Fail; + FailList = createNodeArray([], -1) as FailList; + sourceText = _sourceText; syntaxCursor = _syntaxCursor; @@ -736,7 +751,7 @@ namespace ts { processReferenceComments(sourceFile); sourceFile.statements = parseList(ParsingContext.SourceElements, parseStatement); - Debug.assert(token() === SyntaxKind.EndOfFileToken); + Debug.assertEqual(token(), SyntaxKind.EndOfFileToken); sourceFile.endOfFileToken = addJSDocComment(parseTokenNode() as EndOfFileToken); setExternalModuleIndicator(sourceFile); @@ -1003,7 +1018,7 @@ namespace ts { return currentToken = scanner.scanJsxAttributeValue(); } - function speculationHelper(callback: () => T, isLookAhead: boolean): T { + function speculationHelper(callback: () => T, isLookAhead: boolean): T | undefined { // Keep track of the state we'll need to rollback to if lookahead fails (or if the // caller asked us to always reset our state). const saveToken = currentToken; @@ -1015,6 +1030,7 @@ namespace ts { // descent nature of our parser. However, we still store this here just so we can // assert that invariant holds. const saveContextFlags = contextFlags; + const saveParsingContext = parsingContext; // If we're only looking ahead, then tell the scanner to only lookahead as well. // Otherwise, if we're actually speculatively parsing, then tell the scanner to do the @@ -1023,7 +1039,8 @@ namespace ts { ? scanner.lookAhead(callback) : scanner.tryScan(callback); - Debug.assert(saveContextFlags === contextFlags); + Debug.assertEqual(saveContextFlags, contextFlags); + Debug.assertEqual(saveParsingContext, parsingContext); // If our callback returned something 'falsy' or we're just looking ahead, // then unconditionally restore us to where we were. @@ -1577,7 +1594,7 @@ namespace ts { return createNodeArray(list, listPos); } - function parseListElement(parsingContext: ParsingContext, parseElement: () => T): T { + function parseListElement(parsingContext: ParsingContext, parseElement: () => T): T { const node = currentNode(parsingContext); if (node) { return consumeNode(node); @@ -1901,17 +1918,24 @@ namespace ts { } // Parses a comma-delimited list of elements - function parseDelimitedList(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimiter?: boolean): NodeArray { + function parseDelimitedList(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimiter?: boolean): NodeArray; + function parseDelimitedList(kind: ParsingContext, parseElement: () => T | Fail, considerSemicolonAsDelimiter?: boolean): NodeArray | FailList; + function parseDelimitedList(kind: ParsingContext, parseElement: () => T | Fail, considerSemicolonAsDelimiter?: boolean): NodeArray | FailList { const saveParsingContext = parsingContext; parsingContext |= 1 << kind; - const list = []; + const list: T[] = []; const listPos = getNodePos(); let commaStart = -1; // Meaning the previous token was not a comma while (true) { if (isListElement(kind, /*inErrorRecovery*/ false)) { const startPos = scanner.getStartPos(); - list.push(parseListElement(kind, parseElement)); + const elem = parseListElement(kind, parseElement); + if (isFail(elem)) { + parsingContext = saveParsingContext; + return FailList; + } + list.push(elem); commaStart = scanner.getTokenPos(); if (parseOptional(SyntaxKind.CommaToken)) { @@ -2271,7 +2295,13 @@ namespace ts { isStartOfType(/*inStartOfParameter*/ true); } - function parseParameter(requireEqualsToken?: boolean): ParameterDeclaration { + function tryParseParameter(): ParameterDeclaration | Fail { + return parseParameterWorker(/*inSpeculation*/ true); + } + function parseParameter(): ParameterDeclaration { + return parseParameterWorker(/*inSpeculation*/ false) as ParameterDeclaration; + } + function parseParameterWorker(inSpeculation: boolean): ParameterDeclaration | Fail { const node = createNode(SyntaxKind.Parameter); if (token() === SyntaxKind.ThisKeyword) { node.name = createIdentifier(/*isIdentifier*/ true); @@ -2285,7 +2315,11 @@ namespace ts { // FormalParameter [Yield,Await]: // BindingElement[?Yield,?Await] - node.name = parseIdentifierOrPattern(); + const name = parseIdentifierOrPattern(inSpeculation); + if (isFail(name)) { + return Fail; + } + node.name = name; if (getFullWidth(node.name) === 0 && !hasModifiers(node) && isModifierKind(token())) { // in cases like // 'use strict' @@ -2300,20 +2334,27 @@ namespace ts { node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken); node.type = parseParameterType(); - node.initializer = parseInitializer(/*inParameter*/ true, requireEqualsToken); + const initializer = parseInitializer(/*inParameter*/ true, inSpeculation); + if (isFail(initializer)) { + return Fail; + } + node.initializer = initializer; return addJSDocComment(finishNode(node)); } - function fillSignature( - returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, - flags: SignatureFlags, - signature: SignatureDeclaration): void { + /** @return 'true' on success. */ + function fillSignature(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, flags: SignatureFlags, signature: SignatureDeclaration, inSpeculation?: boolean): boolean { if (!(flags & SignatureFlags.JSDoc)) { signature.typeParameters = parseTypeParameters(); } - signature.parameters = parseParameterList(flags); + const parameters = parseParameterList(flags, inSpeculation); + if (isFailList(parameters)) { + return false; + } + signature.parameters = parameters; signature.type = parseReturnType(returnToken, !!(flags & SignatureFlags.Type)); + return true; } function parseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean): TypeNode | undefined { @@ -2336,7 +2377,7 @@ namespace ts { return false; } - function parseParameterList(flags: SignatureFlags) { + function parseParameterList(flags: SignatureFlags, inSpeculation: boolean): NodeArray | FailList { // FormalParameters [Yield,Await]: (modified) // [empty] // FormalParameterList[?Yield,Await] @@ -2357,9 +2398,9 @@ namespace ts { setYieldContext(!!(flags & SignatureFlags.Yield)); setAwaitContext(!!(flags & SignatureFlags.Await)); - const result = parseDelimitedList(ParsingContext.Parameters, - flags & SignatureFlags.JSDoc ? parseJSDocParameter : () => parseParameter(!!(flags & SignatureFlags.RequireCompleteParameterList))); - + const result = parseDelimitedList( + ParsingContext.Parameters, + flags & SignatureFlags.JSDoc ? parseJSDocParameter : inSpeculation ? tryParseParameter : parseParameter); setYieldContext(savedYieldContext); setAwaitContext(savedAwaitContext); @@ -3032,14 +3073,16 @@ namespace ts { while ((operatorToken = parseOptionalToken(SyntaxKind.CommaToken))) { expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher()); } - if (saveDecoratorContext) { setDecoratorContext(/*val*/ true); } + return expr; } - function parseInitializer(inParameter: boolean, requireEqualsToken?: boolean): Expression { + function parseInitializer(inParameter: boolean): Expression | undefined; + function parseInitializer(inParameter: boolean, inSpeculation?: boolean): Expression | Fail | undefined; + function parseInitializer(inParameter: boolean, inSpeculation?: boolean): Expression | Fail | undefined { if (token() !== SyntaxKind.EqualsToken) { // It's not uncommon during typing for the user to miss writing the '=' token. Check if // there is no newline after the last token and if we're on an expression. If so, parse @@ -3054,12 +3097,8 @@ namespace ts { // do not try to parse initializer return undefined; } - if (inParameter && requireEqualsToken) { - // = is required when speculatively parsing arrow function parameters, - // so return a fake initializer as a signal that the equals token was missing - const result = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics._0_expected, "=") as Identifier; - result.escapedText = "= not found" as __String; - return result; + if (inSpeculation) { + return Fail; } } @@ -3225,7 +3264,7 @@ namespace ts { // it out, but don't allow any ambiguity, and return 'undefined' if this could be an // expression instead. const arrowFunction = triState === Tristate.True - ? parseParenthesizedArrowFunctionExpressionHead(/*allowAmbiguity*/ true) + ? parseParenthesizedArrowFunctionExpressionHead(/*inSpeculation*/ false) : tryParse(parsePossibleParenthesizedArrowFunctionExpressionHead); if (!arrowFunction) { @@ -3373,7 +3412,7 @@ namespace ts { } function parsePossibleParenthesizedArrowFunctionExpressionHead(): ArrowFunction { - return parseParenthesizedArrowFunctionExpressionHead(/*allowAmbiguity*/ false); + return parseParenthesizedArrowFunctionExpressionHead(/*inSpeculation*/ true); } function tryParseAsyncSimpleArrowFunctionExpression(): ArrowFunction | undefined { @@ -3409,7 +3448,7 @@ namespace ts { return Tristate.False; } - function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity: boolean): ArrowFunction { + function parseParenthesizedArrowFunctionExpressionHead(inSpeculation: boolean): ArrowFunction | undefined { const node = createNode(SyntaxKind.ArrowFunction); node.modifiers = parseModifiersForArrowFunction(); const isAsync = hasModifier(node, ModifierFlags.Async) ? SignatureFlags.Await : SignatureFlags.None; @@ -3420,7 +3459,10 @@ namespace ts { // a => (b => c) // And think that "(b =>" was actually a parenthesized arrow function with a missing // close paren. - fillSignature(SyntaxKind.ColonToken, isAsync | (allowAmbiguity ? SignatureFlags.None : SignatureFlags.RequireCompleteParameterList), node); + + if (!fillSignature(SyntaxKind.ColonToken, isAsync | (inSpeculation ? SignatureFlags.RequireCompleteParameterList : SignatureFlags.None), node, inSpeculation)) { + return undefined; + } // If we couldn't get parameters, we definitely could not parse out an arrow function. if (!node.parameters) { @@ -3435,8 +3477,7 @@ namespace ts { // - "a ? (b): c" will have "(b):" parsed as a signature with a return type annotation. // // So we need just a bit of lookahead to ensure that it can only be a signature. - if (!allowAmbiguity && ((token() !== SyntaxKind.EqualsGreaterThanToken && token() !== SyntaxKind.OpenBraceToken) || - find(node.parameters, p => p.initializer && ts.isIdentifier(p.initializer) && p.initializer.escapedText === "= not found"))) { + if (inSpeculation && token() !== SyntaxKind.EqualsGreaterThanToken && token() !== SyntaxKind.OpenBraceToken) { // Returning undefined here will cause our caller to rewind to where we started from. return undefined; } @@ -4574,7 +4615,6 @@ namespace ts { if (saveDecoratorContext) { setDecoratorContext(/*val*/ false); } - const node = createNode(SyntaxKind.FunctionExpression); node.modifiers = parseModifiers(); parseExpected(SyntaxKind.FunctionKeyword); @@ -4590,7 +4630,6 @@ namespace ts { fillSignature(SyntaxKind.ColonToken, isGenerator | isAsync, node); node.body = parseFunctionBlock(isGenerator | isAsync); - if (saveDecoratorContext) { setDecoratorContext(/*val*/ true); } @@ -4653,7 +4692,6 @@ namespace ts { } const block = parseBlock(!!(flags & SignatureFlags.IgnoreMissingOpenBrace), diagnosticMessage); - if (saveDecoratorContext) { setDecoratorContext(/*val*/ true); } @@ -5227,18 +5265,38 @@ namespace ts { // DECLARATIONS + function tryParseArrayBindingElement(): ArrayBindingElement | Fail { + return parseArrayBindingElementWorker(/*inSpeculation*/ true); + } function parseArrayBindingElement(): ArrayBindingElement { + return parseArrayBindingElementWorker(/*inSpeculation*/ false) as ArrayBindingElement; + } + function parseArrayBindingElementWorker(inSpeculation: boolean): ArrayBindingElement | Fail { if (token() === SyntaxKind.CommaToken) { return createNode(SyntaxKind.OmittedExpression); } const node = createNode(SyntaxKind.BindingElement); node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); - node.name = parseIdentifierOrPattern(); - node.initializer = parseInitializer(/*inParameter*/ false); + const name = parseIdentifierOrPattern(inSpeculation); + if (isFail(name)) { + return Fail; + } + node.name = name; + const init = parseInitializer(/*inParameter*/ false, inSpeculation); + if (isFail(init)) { + return Fail; + } + node.initializer = init; return finishNode(node); } + function tryParseObjectBindingElement(): BindingElement | Fail { + return parseObjectBindingElementWorker(/*inSpeculation*/ true); + } function parseObjectBindingElement(): BindingElement { + return parseObjectBindingElementWorker(/*inSpeculation*/ false) as BindingElement; + } + function parseObjectBindingElementWorker(inSpeculation: boolean): BindingElement | Fail { const node = createNode(SyntaxKind.BindingElement); node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); const tokenIsIdentifier = isIdentifier(); @@ -5249,24 +5307,46 @@ namespace ts { else { parseExpected(SyntaxKind.ColonToken); node.propertyName = propertyName; - node.name = parseIdentifierOrPattern(); + const name = parseIdentifierOrPattern(inSpeculation); + if (isFail(name)) { + return Fail; + } + node.name = name; } - node.initializer = parseInitializer(/*inParameter*/ false); + const init = parseInitializer(/*inParameter*/ false, inSpeculation); + if (isFail(init)) { + return Fail; + } + node.initializer = init; return finishNode(node); } - function parseObjectBindingPattern(): ObjectBindingPattern { + function parseObjectBindingPattern(inSpeculation: boolean): ObjectBindingPattern | Fail { const node = createNode(SyntaxKind.ObjectBindingPattern); parseExpected(SyntaxKind.OpenBraceToken); - node.elements = parseDelimitedList(ParsingContext.ObjectBindingElements, parseObjectBindingElement); + const elements = parseDelimitedList( + ParsingContext.ObjectBindingElements, + inSpeculation ? tryParseObjectBindingElement : parseObjectBindingElement, + /*considerSemicolonAsDelimiter*/ undefined); + if (isFailList(elements)) { + return Fail; + } + node.elements = elements; parseExpected(SyntaxKind.CloseBraceToken); return finishNode(node); } - function parseArrayBindingPattern(): ArrayBindingPattern { + function parseArrayBindingPattern(inSpeculation: boolean): ArrayBindingPattern | Fail { const node = createNode(SyntaxKind.ArrayBindingPattern); parseExpected(SyntaxKind.OpenBracketToken); - node.elements = parseDelimitedList(ParsingContext.ArrayBindingElements, parseArrayBindingElement); + const elements = parseDelimitedList( + ParsingContext.ArrayBindingElements, + inSpeculation ? tryParseArrayBindingElement : parseArrayBindingElement, + /*considerSemicolonAsDelimiter*/ undefined); + if (isFailList(elements)) { + return Fail; + } + node.elements = elements; parseExpected(SyntaxKind.CloseBracketToken); return finishNode(node); } @@ -5275,12 +5355,14 @@ namespace ts { return token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.OpenBracketToken || isIdentifier(); } - function parseIdentifierOrPattern(): Identifier | BindingPattern { + function parseIdentifierOrPattern(): Identifier | BindingPattern; + function parseIdentifierOrPattern(inSpeculation: boolean): Identifier | BindingPattern | Fail; + function parseIdentifierOrPattern(inSpeculation?: boolean): Identifier | BindingPattern | Fail { if (token() === SyntaxKind.OpenBracketToken) { - return parseArrayBindingPattern(); + return parseArrayBindingPattern(inSpeculation); } if (token() === SyntaxKind.OpenBraceToken) { - return parseObjectBindingPattern(); + return parseObjectBindingPattern(inSpeculation); } return parseIdentifier(); } @@ -5328,9 +5410,7 @@ namespace ts { else { const savedDisallowIn = inDisallowInContext(); setDisallowInContext(inForStatementInitializer); - node.declarations = parseDelimitedList(ParsingContext.VariableDeclarations, parseVariableDeclaration); - setDisallowInContext(savedDisallowIn); } @@ -5428,7 +5508,7 @@ namespace ts { } } - function parseNonParameterInitializer() { + function parseNonParameterInitializer(): Expression | undefined { return parseInitializer(/*inParameter*/ false); } diff --git a/tests/baselines/reference/parserArrowFunctionExpression7.js b/tests/baselines/reference/parserArrowFunctionExpression7.js new file mode 100644 index 00000000000..0646a1bf438 --- /dev/null +++ b/tests/baselines/reference/parserArrowFunctionExpression7.js @@ -0,0 +1,16 @@ +//// [parserArrowFunctionExpression7.ts] +({ + async m() { + for (;;) { + } + } +}); + + +//// [parserArrowFunctionExpression7.js] +({ + async m() { + for (;;) { + } + } +}); diff --git a/tests/baselines/reference/parserArrowFunctionExpression7.symbols b/tests/baselines/reference/parserArrowFunctionExpression7.symbols new file mode 100644 index 00000000000..0dbc2cf05a1 --- /dev/null +++ b/tests/baselines/reference/parserArrowFunctionExpression7.symbols @@ -0,0 +1,10 @@ +=== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression7.ts === +({ + async m() { +>m : Symbol(m, Decl(parserArrowFunctionExpression7.ts, 0, 2)) + + for (;;) { + } + } +}); + diff --git a/tests/baselines/reference/parserArrowFunctionExpression7.types b/tests/baselines/reference/parserArrowFunctionExpression7.types new file mode 100644 index 00000000000..072a1548bd2 --- /dev/null +++ b/tests/baselines/reference/parserArrowFunctionExpression7.types @@ -0,0 +1,13 @@ +=== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression7.ts === +({ +>({ async m() { for (;;) { } }}) : { m(): Promise; } +>{ async m() { for (;;) { } }} : { m(): Promise; } + + async m() { +>m : () => Promise + + for (;;) { + } + } +}); + diff --git a/tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression7.ts b/tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression7.ts new file mode 100644 index 00000000000..65911cf0fc6 --- /dev/null +++ b/tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression7.ts @@ -0,0 +1,7 @@ +// @target: esnext +({ + async m() { + for (;;) { + } + } +}); From c2f0c580dbfec93f6d00a449faa60760469918ea Mon Sep 17 00:00:00 2001 From: Wilson Hobbs Date: Mon, 13 Nov 2017 13:37:54 -0500 Subject: [PATCH 235/235] add types for escape and unescape methods #18813 (#19015) * add types for escape and unescape methods #18813 although the issue is marked working as expected, it is important to mention that most major browsers maintain support for escape and unescape, and some javascript codebases moving to typescript may have escape and unescape in them. They are valid JavaScript, and thus they should be included in the global definition. * add escape and unescape types to lib in tests * update tests to turn CI green --- src/lib/es5.d.ts | 12 + .../fourslash/completionInJSDocFunctionNew.ts | 2 +- .../completionInJSDocFunctionThis.ts | 2 +- .../tsxCompletionOnOpeningTagWithoutJSX1.ts | 2 +- tests/lib/lib.d.ts | 1652 +++++++++-------- 5 files changed, 847 insertions(+), 823 deletions(-) diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index fd2ae5b3fdf..aaefeec7d1a 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -62,6 +62,18 @@ declare function encodeURI(uri: string): string; */ declare function encodeURIComponent(uriComponent: string): string; +/** + * Computes a new string in which certain characters have been replaced by a hexadecimal escape sequence. + * @param string A string value + */ +declare function escape(string: string): string; + +/** + * Computes a new string in which hexadecimal escape sequences are replaced with the character that it represents. + * @param string A string value + */ +declare function unescape(string: string): string; + interface PropertyDescriptor { configurable?: boolean; enumerable?: boolean; diff --git a/tests/cases/fourslash/completionInJSDocFunctionNew.ts b/tests/cases/fourslash/completionInJSDocFunctionNew.ts index 0d3391cf774..742627974bd 100644 --- a/tests/cases/fourslash/completionInJSDocFunctionNew.ts +++ b/tests/cases/fourslash/completionInJSDocFunctionNew.ts @@ -6,5 +6,5 @@ ////var f = function () { return new/**/; } goTo.marker(); -verify.completionListCount(115); +verify.completionListCount(117); verify.completionListContains('new'); diff --git a/tests/cases/fourslash/completionInJSDocFunctionThis.ts b/tests/cases/fourslash/completionInJSDocFunctionThis.ts index c28eeeb397f..e22180aab52 100644 --- a/tests/cases/fourslash/completionInJSDocFunctionThis.ts +++ b/tests/cases/fourslash/completionInJSDocFunctionThis.ts @@ -5,6 +5,6 @@ ////var f = function (s) { return this/**/; } goTo.marker(); -verify.completionListCount(116); +verify.completionListCount(118); verify.completionListContains('this'); diff --git a/tests/cases/fourslash/tsxCompletionOnOpeningTagWithoutJSX1.ts b/tests/cases/fourslash/tsxCompletionOnOpeningTagWithoutJSX1.ts index f208b0a44a4..85cae83288a 100644 --- a/tests/cases/fourslash/tsxCompletionOnOpeningTagWithoutJSX1.ts +++ b/tests/cases/fourslash/tsxCompletionOnOpeningTagWithoutJSX1.ts @@ -4,4 +4,4 @@ //// var x = (o: T): T; @@ -189,25 +201,25 @@ interface ObjectConstructor { /** * Prevents the addition of new properties to an object. - * @param o Object to make non-extensible. + * @param o Object to make non-extensible. */ preventExtensions(o: T): T; /** * Returns true if existing property attributes cannot be modified in an object and new properties cannot be added to the object. - * @param o Object to test. + * @param o Object to test. */ isSealed(o: any): boolean; /** * Returns true if existing property attributes and values cannot be modified in an object, and new properties cannot be added to the object. - * @param o Object to test. + * @param o Object to test. */ isFrozen(o: any): boolean; /** * Returns a value that indicates whether new properties can be added to an object. - * @param o Object to test. + * @param o Object to test. */ isExtensible(o: any): boolean; @@ -242,7 +254,7 @@ interface Function { call(thisArg: any, ...argArray: any[]): any; /** - * For a given function, creates a bound function that has the same body as the original function. + * For a given function, creates a bound function that has the same body as the original function. * The this object of the bound function is associated with the specified object, and has the specified initial parameters. * @param thisArg An object to which the this keyword can refer inside the new function. * @param argArray A list of arguments to be passed to the new function. @@ -285,7 +297,7 @@ interface String { */ charAt(pos: number): string; - /** + /** * Returns the Unicode value of the character at the specified location. * @param index The zero-based index of the desired character. If there is no character at the specified index, NaN is returned. */ @@ -293,12 +305,12 @@ interface String { /** * Returns a string that contains the concatenation of two or more strings. - * @param strings The strings to append to the end of the string. + * @param strings The strings to append to the end of the string. */ concat(...strings: string[]): string; /** - * Returns the position of the first occurrence of a substring. + * Returns the position of the first occurrence of a substring. * @param searchString The substring to search for in the string * @param position The index at which to begin searching the String object. If omitted, search starts at the beginning of the string. */ @@ -317,15 +329,15 @@ interface String { */ localeCompare(that: string): number; - /** + /** * Matches a string with a regular expression, and returns an array containing the results of that search. * @param regexp A variable name or string literal containing the regular expression pattern and flags. */ match(regexp: string): RegExpMatchArray; - /** + /** * Matches a string with a regular expression, and returns an array containing the results of that search. - * @param regexp A regular expression object that contains the regular expression pattern and applicable flags. + * @param regexp A regular expression object that contains the regular expression pattern and applicable flags. */ match(regexp: RegExp): RegExpMatchArray; @@ -359,40 +371,40 @@ interface String { /** * Finds the first substring match in a regular expression search. - * @param regexp The regular expression pattern and applicable flags. + * @param regexp The regular expression pattern and applicable flags. */ search(regexp: string): number; /** * Finds the first substring match in a regular expression search. - * @param regexp The regular expression pattern and applicable flags. + * @param regexp The regular expression pattern and applicable flags. */ search(regexp: RegExp): number; /** * Returns a section of a string. - * @param start The index to the beginning of the specified portion of stringObj. - * @param end The index to the end of the specified portion of stringObj. The substring includes the characters up to, but not including, the character indicated by end. + * @param start The index to the beginning of the specified portion of stringObj. + * @param end The index to the end of the specified portion of stringObj. The substring includes the characters up to, but not including, the character indicated by end. * If this value is not specified, the substring continues to the end of stringObj. */ slice(start?: number, end?: number): string; /** * Split a string into substrings using the specified separator and return them as an array. - * @param separator A string that identifies character or characters to use in separating the string. If omitted, a single-element array containing the entire string is returned. + * @param separator A string that identifies character or characters to use in separating the string. If omitted, a single-element array containing the entire string is returned. * @param limit A value used to limit the number of elements returned in the array. */ split(separator: string, limit?: number): string[]; /** * Split a string into substrings using the specified separator and return them as an array. - * @param separator A Regular Express that identifies character or characters to use in separating the string. If omitted, a single-element array containing the entire string is returned. + * @param separator A Regular Express that identifies character or characters to use in separating the string. If omitted, a single-element array containing the entire string is returned. * @param limit A value used to limit the number of elements returned in the array. */ split(separator: RegExp, limit?: number): string[]; /** - * Returns the substring at the specified location within a String object. + * Returns the substring at the specified location within a String object. * @param start The zero-based index number indicating the beginning of the substring. * @param end Zero-based index number indicating the end of the substring. The substring includes the characters up to, but not including, the character indicated by end. * If end is omitted, the characters from start through the end of the original string are returned. @@ -438,8 +450,8 @@ interface StringConstructor { fromCharCode(...codes: number[]): string; } -/** - * Allows manipulation and formatting of text strings and determination and location of substrings within strings. +/** + * Allows manipulation and formatting of text strings and determination and location of substrings within strings. */ declare var String: StringConstructor; @@ -463,7 +475,7 @@ interface Number { */ toString(radix?: number): string; - /** + /** * Returns a string representing a number in fixed-point notation. * @param fractionDigits Number of digits after the decimal point. Must be in the range 0 - 20, inclusive. */ @@ -496,21 +508,21 @@ interface NumberConstructor { /** The closest number to zero that can be represented in JavaScript. Equal to approximately 5.00E-324. */ MIN_VALUE: number; - /** + /** * A value that is not a number. * In equality comparisons, NaN does not equal any value, including itself. To test whether a value is equivalent to NaN, use the isNaN function. */ NaN: number; - /** + /** * A value that is less than the largest negative number that can be represented in JavaScript. - * JavaScript displays NEGATIVE_INFINITY values as -infinity. + * JavaScript displays NEGATIVE_INFINITY values as -infinity. */ NEGATIVE_INFINITY: number; /** - * A value greater than the largest number that can be represented in JavaScript. - * JavaScript displays POSITIVE_INFINITY values as infinity. + * A value greater than the largest number that can be represented in JavaScript. + * JavaScript displays POSITIVE_INFINITY values as infinity. */ POSITIVE_INFINITY: number; } @@ -540,23 +552,23 @@ interface Math { /** The square root of 2. */ SQRT2: number; /** - * Returns the absolute value of a number (the value without regard to whether it is positive or negative). + * Returns the absolute value of a number (the value without regard to whether it is positive or negative). * For example, the absolute value of -5 is the same as the absolute value of 5. * @param x A numeric expression for which the absolute value is needed. */ abs(x: number): number; /** - * Returns the arc cosine (or inverse cosine) of a number. + * Returns the arc cosine (or inverse cosine) of a number. * @param x A numeric expression. */ acos(x: number): number; - /** - * Returns the arcsine of a number. + /** + * Returns the arcsine of a number. * @param x A numeric expression. */ asin(x: number): number; /** - * Returns the arctangent of a number. + * Returns the arctangent of a number. * @param x A numeric expression for which the arctangent is needed. */ atan(x: number): number; @@ -567,49 +579,49 @@ interface Math { */ atan2(y: number, x: number): number; /** - * Returns the smallest number greater than or equal to its numeric argument. + * Returns the smallest number greater than or equal to its numeric argument. * @param x A numeric expression. */ ceil(x: number): number; /** - * Returns the cosine of a number. + * Returns the cosine of a number. * @param x A numeric expression that contains an angle measured in radians. */ cos(x: number): number; /** - * Returns e (the base of natural logarithms) raised to a power. + * Returns e (the base of natural logarithms) raised to a power. * @param x A numeric expression representing the power of e. */ exp(x: number): number; /** - * Returns the greatest number less than or equal to its numeric argument. + * Returns the greatest number less than or equal to its numeric argument. * @param x A numeric expression. */ floor(x: number): number; /** - * Returns the natural logarithm (base e) of a number. + * Returns the natural logarithm (base e) of a number. * @param x A numeric expression. */ log(x: number): number; /** - * Returns the larger of a set of supplied numeric expressions. + * Returns the larger of a set of supplied numeric expressions. * @param values Numeric expressions to be evaluated. */ max(...values: number[]): number; /** - * Returns the smaller of a set of supplied numeric expressions. + * Returns the smaller of a set of supplied numeric expressions. * @param values Numeric expressions to be evaluated. */ min(...values: number[]): number; /** - * Returns the value of a base expression taken to a specified power. + * Returns the value of a base expression taken to a specified power. * @param x The base value of the expression. * @param y The exponent value of the expression. */ pow(x: number, y: number): number; /** Returns a pseudorandom number between 0 and 1. */ random(): number; - /** + /** * Returns a supplied numeric expression rounded to the nearest number. * @param x The value to be rounded to the nearest number. */ @@ -685,24 +697,24 @@ interface Date { getUTCMilliseconds(): number; /** Gets the difference in minutes between the time on the local computer and Universal Coordinated Time (UTC). */ getTimezoneOffset(): number; - /** + /** * Sets the date and time value in the Date object. - * @param time A numeric value representing the number of elapsed milliseconds since midnight, January 1, 1970 GMT. + * @param time A numeric value representing the number of elapsed milliseconds since midnight, January 1, 1970 GMT. */ setTime(time: number): number; /** - * Sets the milliseconds value in the Date object using local time. + * Sets the milliseconds value in the Date object using local time. * @param ms A numeric value equal to the millisecond value. */ setMilliseconds(ms: number): number; - /** + /** * Sets the milliseconds value in the Date object using Universal Coordinated Time (UTC). - * @param ms A numeric value equal to the millisecond value. + * @param ms A numeric value equal to the millisecond value. */ setUTCMilliseconds(ms: number): number; /** - * Sets the seconds value in the Date object using local time. + * Sets the seconds value in the Date object using local time. * @param sec A numeric value equal to the seconds value. * @param ms A numeric value equal to the milliseconds value. */ @@ -714,16 +726,16 @@ interface Date { */ setUTCSeconds(sec: number, ms?: number): number; /** - * Sets the minutes value in the Date object using local time. - * @param min A numeric value equal to the minutes value. - * @param sec A numeric value equal to the seconds value. + * Sets the minutes value in the Date object using local time. + * @param min A numeric value equal to the minutes value. + * @param sec A numeric value equal to the seconds value. * @param ms A numeric value equal to the milliseconds value. */ setMinutes(min: number, sec?: number, ms?: number): number; /** * Sets the minutes value in the Date object using Universal Coordinated Time (UTC). - * @param min A numeric value equal to the minutes value. - * @param sec A numeric value equal to the seconds value. + * @param min A numeric value equal to the minutes value. + * @param sec A numeric value equal to the seconds value. * @param ms A numeric value equal to the milliseconds value. */ setUTCMinutes(min: number, sec?: number, ms?: number): number; @@ -731,7 +743,7 @@ interface Date { * Sets the hour value in the Date object using local time. * @param hours A numeric value equal to the hours value. * @param min A numeric value equal to the minutes value. - * @param sec A numeric value equal to the seconds value. + * @param sec A numeric value equal to the seconds value. * @param ms A numeric value equal to the milliseconds value. */ setHours(hours: number, min?: number, sec?: number, ms?: number): number; @@ -739,23 +751,23 @@ interface Date { * Sets the hours value in the Date object using Universal Coordinated Time (UTC). * @param hours A numeric value equal to the hours value. * @param min A numeric value equal to the minutes value. - * @param sec A numeric value equal to the seconds value. + * @param sec A numeric value equal to the seconds value. * @param ms A numeric value equal to the milliseconds value. */ setUTCHours(hours: number, min?: number, sec?: number, ms?: number): number; /** - * Sets the numeric day-of-the-month value of the Date object using local time. + * Sets the numeric day-of-the-month value of the Date object using local time. * @param date A numeric value equal to the day of the month. */ setDate(date: number): number; - /** + /** * Sets the numeric day of the month in the Date object using Universal Coordinated Time (UTC). - * @param date A numeric value equal to the day of the month. + * @param date A numeric value equal to the day of the month. */ setUTCDate(date: number): number; - /** - * Sets the month value in the Date object using local time. - * @param month A numeric value equal to the month. The value for January is 0, and other month values follow consecutively. + /** + * Sets the month value in the Date object using local time. + * @param month A numeric value equal to the month. The value for January is 0, and other month values follow consecutively. * @param date A numeric value representing the day of the month. If this value is not supplied, the value from a call to the getDate method is used. */ setMonth(month: number, date?: number): number; @@ -800,7 +812,7 @@ interface DateConstructor { */ parse(s: string): number; /** - * Returns the number of milliseconds between midnight, January 1, 1970 Universal Coordinated Time (UTC) (or GMT) and the specified date. + * Returns the number of milliseconds between midnight, January 1, 1970 Universal Coordinated Time (UTC) (or GMT) and the specified date. * @param year The full year designation is required for cross-century date accuracy. If year is between 0 and 99 is used, then year is assumed to be 1900 + year. * @param month The month as an number between 0 and 11 (January to December). * @param date The date as an number between 1 and 31. @@ -826,13 +838,13 @@ interface RegExpExecArray extends Array { } interface RegExp { - /** + /** * Executes a search on a string using a regular expression pattern, and returns an array containing the results of that search. * @param string The String object or string literal on which to perform the search. */ exec(string: string): RegExpExecArray; - /** + /** * Returns a Boolean value that indicates whether or not a pattern exists in a searched string. * @param string String on which to perform the search. */ @@ -959,8 +971,8 @@ interface JSON { /** * Converts a JavaScript Object Notation (JSON) string into an object. * @param text A valid JSON string. - * @param reviver A function that transforms the results. This function is called for each member of the object. - * If a member contains nested objects, the nested objects are transformed before the parent object is. + * @param reviver A function that transforms the results. This function is called for each member of the object. + * If a member contains nested objects, the nested objects are transformed before the parent object is. */ parse(text: string, reviver?: (key: any, value: any) => any): any; /** @@ -1040,14 +1052,14 @@ interface Array { */ join(separator?: string): string; /** - * Reverses the elements in an Array. + * Reverses the elements in an Array. */ reverse(): T[]; /** * Removes the first element from an array and returns it. */ shift(): T; - /** + /** * Returns a section of an array. * @param start The beginning of the specified portion of the array. * @param end The end of the specified portion of the array. @@ -1110,21 +1122,21 @@ interface Array { /** * Performs the specified action for each element in an array. - * @param callbackfn A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array. + * @param callbackfn A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array. * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value. */ forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; /** * Calls a defined callback function on each element of an array, and returns an array that contains the results. - * @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array. + * @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array. * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value. */ map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; /** - * Returns the elements of an array that meet the condition specified in a callback function. - * @param callbackfn A function that accepts up to three arguments. The filter method calls the callbackfn function one time for each element in the array. + * Returns the elements of an array that meet the condition specified in a callback function. + * @param callbackfn A function that accepts up to three arguments. The filter method calls the callbackfn function one time for each element in the array. * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value. */ filter(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): T[]; @@ -1142,15 +1154,15 @@ interface Array { */ reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; - /** + /** * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array. + * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array. * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value. */ reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T; - /** + /** * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array. + * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array. * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value. */ reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; @@ -1205,10 +1217,10 @@ interface ArrayLike { /** - * Represents a raw buffer of binary data, which is used to store data for the - * different typed arrays. ArrayBuffers cannot be read from or written to directly, - * but can be passed to a typed array or DataView Object to interpret the raw - * buffer as needed. + * Represents a raw buffer of binary data, which is used to store data for the + * different typed arrays. ArrayBuffers cannot be read from or written to directly, + * but can be passed to a typed array or DataView Object to interpret the raw + * buffer as needed. */ interface ArrayBuffer { /** @@ -1231,7 +1243,7 @@ declare var ArrayBuffer: ArrayBufferConstructor; interface ArrayBufferView { /** - * The ArrayBuffer instance referenced by the array. + * The ArrayBuffer instance referenced by the array. */ buffer: ArrayBuffer; @@ -1251,124 +1263,124 @@ interface DataView { byteLength: number; byteOffset: number; /** - * Gets the Float32 value at the specified byte offset from the start of the view. There is - * no alignment constraint; multi-byte values may be fetched from any offset. + * Gets the Float32 value at the specified byte offset from the start of the view. There is + * no alignment constraint; multi-byte values may be fetched from any offset. * @param byteOffset The place in the buffer at which the value should be retrieved. */ getFloat32(byteOffset: number, littleEndian?: boolean): number; /** * Gets the Float64 value at the specified byte offset from the start of the view. There is - * no alignment constraint; multi-byte values may be fetched from any offset. + * no alignment constraint; multi-byte values may be fetched from any offset. * @param byteOffset The place in the buffer at which the value should be retrieved. */ getFloat64(byteOffset: number, littleEndian?: boolean): number; /** - * Gets the Int8 value at the specified byte offset from the start of the view. There is - * no alignment constraint; multi-byte values may be fetched from any offset. + * Gets the Int8 value at the specified byte offset from the start of the view. There is + * no alignment constraint; multi-byte values may be fetched from any offset. * @param byteOffset The place in the buffer at which the value should be retrieved. */ getInt8(byteOffset: number): number; /** - * Gets the Int16 value at the specified byte offset from the start of the view. There is - * no alignment constraint; multi-byte values may be fetched from any offset. + * Gets the Int16 value at the specified byte offset from the start of the view. There is + * no alignment constraint; multi-byte values may be fetched from any offset. * @param byteOffset The place in the buffer at which the value should be retrieved. */ getInt16(byteOffset: number, littleEndian?: boolean): number; /** - * Gets the Int32 value at the specified byte offset from the start of the view. There is - * no alignment constraint; multi-byte values may be fetched from any offset. + * Gets the Int32 value at the specified byte offset from the start of the view. There is + * no alignment constraint; multi-byte values may be fetched from any offset. * @param byteOffset The place in the buffer at which the value should be retrieved. */ getInt32(byteOffset: number, littleEndian?: boolean): number; /** - * Gets the Uint8 value at the specified byte offset from the start of the view. There is - * no alignment constraint; multi-byte values may be fetched from any offset. + * Gets the Uint8 value at the specified byte offset from the start of the view. There is + * no alignment constraint; multi-byte values may be fetched from any offset. * @param byteOffset The place in the buffer at which the value should be retrieved. */ getUint8(byteOffset: number): number; /** - * Gets the Uint16 value at the specified byte offset from the start of the view. There is - * no alignment constraint; multi-byte values may be fetched from any offset. + * Gets the Uint16 value at the specified byte offset from the start of the view. There is + * no alignment constraint; multi-byte values may be fetched from any offset. * @param byteOffset The place in the buffer at which the value should be retrieved. */ getUint16(byteOffset: number, littleEndian?: boolean): number; /** - * Gets the Uint32 value at the specified byte offset from the start of the view. There is - * no alignment constraint; multi-byte values may be fetched from any offset. + * Gets the Uint32 value at the specified byte offset from the start of the view. There is + * no alignment constraint; multi-byte values may be fetched from any offset. * @param byteOffset The place in the buffer at which the value should be retrieved. */ getUint32(byteOffset: number, littleEndian?: boolean): number; /** - * Stores an Float32 value at the specified byte offset from the start of the view. + * Stores an Float32 value at the specified byte offset from the start of the view. * @param byteOffset The place in the buffer at which the value should be set. * @param value The value to set. - * @param littleEndian If false or undefined, a big-endian value should be written, + * @param littleEndian If false or undefined, a big-endian value should be written, * otherwise a little-endian value should be written. */ setFloat32(byteOffset: number, value: number, littleEndian?: boolean): void; /** - * Stores an Float64 value at the specified byte offset from the start of the view. + * Stores an Float64 value at the specified byte offset from the start of the view. * @param byteOffset The place in the buffer at which the value should be set. * @param value The value to set. - * @param littleEndian If false or undefined, a big-endian value should be written, + * @param littleEndian If false or undefined, a big-endian value should be written, * otherwise a little-endian value should be written. */ setFloat64(byteOffset: number, value: number, littleEndian?: boolean): void; /** - * Stores an Int8 value at the specified byte offset from the start of the view. + * Stores an Int8 value at the specified byte offset from the start of the view. * @param byteOffset The place in the buffer at which the value should be set. * @param value The value to set. */ setInt8(byteOffset: number, value: number): void; /** - * Stores an Int16 value at the specified byte offset from the start of the view. + * Stores an Int16 value at the specified byte offset from the start of the view. * @param byteOffset The place in the buffer at which the value should be set. * @param value The value to set. - * @param littleEndian If false or undefined, a big-endian value should be written, + * @param littleEndian If false or undefined, a big-endian value should be written, * otherwise a little-endian value should be written. */ setInt16(byteOffset: number, value: number, littleEndian?: boolean): void; /** - * Stores an Int32 value at the specified byte offset from the start of the view. + * Stores an Int32 value at the specified byte offset from the start of the view. * @param byteOffset The place in the buffer at which the value should be set. * @param value The value to set. - * @param littleEndian If false or undefined, a big-endian value should be written, + * @param littleEndian If false or undefined, a big-endian value should be written, * otherwise a little-endian value should be written. */ setInt32(byteOffset: number, value: number, littleEndian?: boolean): void; /** - * Stores an Uint8 value at the specified byte offset from the start of the view. + * Stores an Uint8 value at the specified byte offset from the start of the view. * @param byteOffset The place in the buffer at which the value should be set. * @param value The value to set. */ setUint8(byteOffset: number, value: number): void; /** - * Stores an Uint16 value at the specified byte offset from the start of the view. + * Stores an Uint16 value at the specified byte offset from the start of the view. * @param byteOffset The place in the buffer at which the value should be set. * @param value The value to set. - * @param littleEndian If false or undefined, a big-endian value should be written, + * @param littleEndian If false or undefined, a big-endian value should be written, * otherwise a little-endian value should be written. */ setUint16(byteOffset: number, value: number, littleEndian?: boolean): void; /** - * Stores an Uint32 value at the specified byte offset from the start of the view. + * Stores an Uint32 value at the specified byte offset from the start of the view. * @param byteOffset The place in the buffer at which the value should be set. * @param value The value to set. - * @param littleEndian If false or undefined, a big-endian value should be written, + * @param littleEndian If false or undefined, a big-endian value should be written, * otherwise a little-endian value should be written. */ setUint32(byteOffset: number, value: number, littleEndian?: boolean): void; @@ -1380,17 +1392,17 @@ interface DataViewConstructor { declare var DataView: DataViewConstructor; /** - * A typed array of 8-bit integer values. The contents are initialized to 0. If the requested + * A typed array of 8-bit integer values. The contents are initialized to 0. If the requested * number of bytes could not be allocated an exception is raised. */ interface Int8Array { /** - * The size in bytes of each element in the array. + * The size in bytes of each element in the array. */ BYTES_PER_ELEMENT: number; /** - * The ArrayBuffer instance referenced by the array. + * The ArrayBuffer instance referenced by the array. */ buffer: ArrayBuffer; @@ -1404,21 +1416,21 @@ interface Int8Array { */ byteOffset: number; - /** + /** * Returns the this object after copying a section of the array identified by start and end * to the same array starting at position target - * @param target If target is negative, it is treated as length+target where length is the - * length of the array. - * @param start If start is negative, it is treated as length+start. If end is negative, it + * @param target If target is negative, it is treated as length+target where length is the + * length of the array. + * @param start If start is negative, it is treated as length+start. If end is negative, it * is treated as length+end. - * @param end If not specified, length of the this object is used as its default value. + * @param end If not specified, length of the this object is used as its default value. */ copyWithin(target: number, start: number, end?: number): Int8Array; /** * Determines whether all the members of an array satisfy the specified test. - * @param callbackfn A function that accepts up to three arguments. The every method calls - * the callbackfn function for each element in array1 until the callbackfn returns false, + * @param callbackfn A function that accepts up to three arguments. The every method calls + * the callbackfn function for each element in array1 until the callbackfn returns false, * or until the end of the array. * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. @@ -1428,49 +1440,49 @@ interface Int8Array { /** * Returns the this object after filling the section identified by start and end with value * @param value value to fill array section with - * @param start index to start filling the array at. If start is negative, it is treated as - * length+start where length is the length of the array. - * @param end index to stop filling the array at. If end is negative, it is treated as + * @param start index to start filling the array at. If start is negative, it is treated as + * length+start where length is the length of the array. + * @param end index to stop filling the array at. If end is negative, it is treated as * length+end. */ fill(value: number, start?: number, end?: number): Int8Array; /** - * Returns the elements of an array that meet the condition specified in a callback function. - * @param callbackfn A function that accepts up to three arguments. The filter method calls - * the callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * Returns the elements of an array that meet the condition specified in a callback function. + * @param callbackfn A function that accepts up to three arguments. The filter method calls + * the callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ filter(callbackfn: (value: number, index: number, array: Int8Array) => boolean, thisArg?: any): Int8Array; - /** - * Returns the value of the first element in the array where predicate is true, and undefined + /** + * Returns the value of the first element in the array where predicate is true, and undefined * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find + * @param predicate find calls predicate once for each element of the array, in ascending + * order, until it finds one where predicate returns true. If such an element is found, find * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of + * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ find(predicate: (value: number, index: number, obj: Array) => boolean, thisArg?: any): number; - /** - * Returns the index of the first element in the array where predicate is true, and undefined + /** + * Returns the index of the first element in the array where predicate is true, and undefined * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find + * @param predicate find calls predicate once for each element of the array, in ascending + * order, until it finds one where predicate returns true. If such an element is found, find * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of + * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ findIndex(predicate: (value: number) => boolean, thisArg?: any): number; /** * Performs the specified action for each element in an array. - * @param callbackfn A function that accepts up to three arguments. forEach calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param callbackfn A function that accepts up to three arguments. forEach calls the + * callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ forEach(callbackfn: (value: number, index: number, array: Int8Array) => void, thisArg?: any): void; @@ -1485,7 +1497,7 @@ interface Int8Array { /** * Adds all the elements of an array separated by the specified separator string. - * @param separator A string used to separate one element of an array from the next in the + * @param separator A string used to separate one element of an array from the next in the * resulting String. If omitted, the array elements are separated with a comma. */ join(separator?: string): string; @@ -1493,7 +1505,7 @@ interface Int8Array { /** * Returns the index of the last occurrence of a value in an array. * @param searchElement The value to locate in the array. - * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the + * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the * search starts at index 0. */ lastIndexOf(searchElement: number, fromIndex?: number): number; @@ -1504,65 +1516,65 @@ interface Int8Array { length: number; /** - * Calls a defined callback function on each element of an array, and returns an array that + * Calls a defined callback function on each element of an array, and returns an array that * contains the results. - * @param callbackfn A function that accepts up to three arguments. The map method calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param callbackfn A function that accepts up to three arguments. The map method calls the + * callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ map(callbackfn: (value: number, index: number, array: Int8Array) => number, thisArg?: any): Int8Array; /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next + * Calls the specified callback function for all the elements in an array. The return value of + * the callback function is the accumulated result, and is provided as an argument in the next * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the + * @param callbackfn A function that accepts up to four arguments. The reduce method calls the * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start + * @param initialValue If initialValue is specified, it is used as the initial value to start * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number, initialValue?: number): number; /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next + * Calls the specified callback function for all the elements in an array. The return value of + * the callback function is the accumulated result, and is provided as an argument in the next * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the + * @param callbackfn A function that accepts up to four arguments. The reduce method calls the * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduce(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int8Array) => U, initialValue: U): U; - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an + /** + * Calls the specified callback function for all the elements in an array, in descending order. + * The return value of the callback function is the accumulated result, and is provided as an * argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an + * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls + * the callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an * argument instead of an array value. */ reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number, initialValue?: number): number; - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an + /** + * Calls the specified callback function for all the elements in an array, in descending order. + * The return value of the callback function is the accumulated result, and is provided as an * argument in the next call to the callback function. * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start + * the callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduceRight(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int8Array) => U, initialValue: U): U; /** - * Reverses the elements in an Array. + * Reverses the elements in an Array. */ reverse(): Int8Array; @@ -1580,7 +1592,7 @@ interface Int8Array { */ set(array: ArrayLike, offset?: number): void; - /** + /** * Returns a section of an array. * @param start The beginning of the specified portion of the array. * @param end The end of the specified portion of the array. @@ -1589,31 +1601,31 @@ interface Int8Array { /** * Determines whether the specified callback function returns true for any element of an array. - * @param callbackfn A function that accepts up to three arguments. The some method calls the - * callbackfn function for each element in array1 until the callbackfn returns true, or until + * @param callbackfn A function that accepts up to three arguments. The some method calls the + * callbackfn function for each element in array1 until the callbackfn returns true, or until * the end of the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ some(callbackfn: (value: number, index: number, array: Int8Array) => boolean, thisArg?: any): boolean; /** * Sorts an array. - * @param compareFn The name of the function used to determine the order of the elements. If + * @param compareFn The name of the function used to determine the order of the elements. If * omitted, the elements are sorted in ascending, ASCII character order. */ sort(compareFn?: (a: number, b: number) => number): Int8Array; /** * Gets a new Int8Array view of the ArrayBuffer store for this array, referencing the elements - * at begin, inclusive, up to end, exclusive. + * at begin, inclusive, up to end, exclusive. * @param begin The index of the beginning of the array. * @param end The index of the end of the array. */ subarray(begin: number, end?: number): Int8Array; /** - * Converts a number to a string by using the current locale. + * Converts a number to a string by using the current locale. */ toLocaleString(): string; @@ -1631,7 +1643,7 @@ interface Int8ArrayConstructor { new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Int8Array; /** - * The size in bytes of each element in the array. + * The size in bytes of each element in the array. */ BYTES_PER_ELEMENT: number; @@ -1640,7 +1652,7 @@ interface Int8ArrayConstructor { * @param items A set of elements to include in the new array object. */ of(...items: number[]): Int8Array; - + /** * Creates an array from an array-like or iterable object. * @param arrayLike An array-like or iterable object to convert to an array. @@ -1653,17 +1665,17 @@ interface Int8ArrayConstructor { declare var Int8Array: Int8ArrayConstructor; /** - * A typed array of 8-bit unsigned integer values. The contents are initialized to 0. If the + * A typed array of 8-bit unsigned integer values. The contents are initialized to 0. If the * requested number of bytes could not be allocated an exception is raised. */ interface Uint8Array { /** - * The size in bytes of each element in the array. + * The size in bytes of each element in the array. */ BYTES_PER_ELEMENT: number; /** - * The ArrayBuffer instance referenced by the array. + * The ArrayBuffer instance referenced by the array. */ buffer: ArrayBuffer; @@ -1677,21 +1689,21 @@ interface Uint8Array { */ byteOffset: number; - /** + /** * Returns the this object after copying a section of the array identified by start and end * to the same array starting at position target - * @param target If target is negative, it is treated as length+target where length is the - * length of the array. - * @param start If start is negative, it is treated as length+start. If end is negative, it + * @param target If target is negative, it is treated as length+target where length is the + * length of the array. + * @param start If start is negative, it is treated as length+start. If end is negative, it * is treated as length+end. - * @param end If not specified, length of the this object is used as its default value. + * @param end If not specified, length of the this object is used as its default value. */ copyWithin(target: number, start: number, end?: number): Uint8Array; /** * Determines whether all the members of an array satisfy the specified test. - * @param callbackfn A function that accepts up to three arguments. The every method calls - * the callbackfn function for each element in array1 until the callbackfn returns false, + * @param callbackfn A function that accepts up to three arguments. The every method calls + * the callbackfn function for each element in array1 until the callbackfn returns false, * or until the end of the array. * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. @@ -1701,49 +1713,49 @@ interface Uint8Array { /** * Returns the this object after filling the section identified by start and end with value * @param value value to fill array section with - * @param start index to start filling the array at. If start is negative, it is treated as - * length+start where length is the length of the array. - * @param end index to stop filling the array at. If end is negative, it is treated as + * @param start index to start filling the array at. If start is negative, it is treated as + * length+start where length is the length of the array. + * @param end index to stop filling the array at. If end is negative, it is treated as * length+end. */ fill(value: number, start?: number, end?: number): Uint8Array; /** - * Returns the elements of an array that meet the condition specified in a callback function. - * @param callbackfn A function that accepts up to three arguments. The filter method calls - * the callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * Returns the elements of an array that meet the condition specified in a callback function. + * @param callbackfn A function that accepts up to three arguments. The filter method calls + * the callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ filter(callbackfn: (value: number, index: number, array: Uint8Array) => boolean, thisArg?: any): Uint8Array; - /** - * Returns the value of the first element in the array where predicate is true, and undefined + /** + * Returns the value of the first element in the array where predicate is true, and undefined * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find + * @param predicate find calls predicate once for each element of the array, in ascending + * order, until it finds one where predicate returns true. If such an element is found, find * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of + * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ find(predicate: (value: number, index: number, obj: Array) => boolean, thisArg?: any): number; - /** - * Returns the index of the first element in the array where predicate is true, and undefined + /** + * Returns the index of the first element in the array where predicate is true, and undefined * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find + * @param predicate find calls predicate once for each element of the array, in ascending + * order, until it finds one where predicate returns true. If such an element is found, find * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of + * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ findIndex(predicate: (value: number) => boolean, thisArg?: any): number; /** * Performs the specified action for each element in an array. - * @param callbackfn A function that accepts up to three arguments. forEach calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param callbackfn A function that accepts up to three arguments. forEach calls the + * callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ forEach(callbackfn: (value: number, index: number, array: Uint8Array) => void, thisArg?: any): void; @@ -1758,7 +1770,7 @@ interface Uint8Array { /** * Adds all the elements of an array separated by the specified separator string. - * @param separator A string used to separate one element of an array from the next in the + * @param separator A string used to separate one element of an array from the next in the * resulting String. If omitted, the array elements are separated with a comma. */ join(separator?: string): string; @@ -1766,7 +1778,7 @@ interface Uint8Array { /** * Returns the index of the last occurrence of a value in an array. * @param searchElement The value to locate in the array. - * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the + * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the * search starts at index 0. */ lastIndexOf(searchElement: number, fromIndex?: number): number; @@ -1777,65 +1789,65 @@ interface Uint8Array { length: number; /** - * Calls a defined callback function on each element of an array, and returns an array that + * Calls a defined callback function on each element of an array, and returns an array that * contains the results. - * @param callbackfn A function that accepts up to three arguments. The map method calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param callbackfn A function that accepts up to three arguments. The map method calls the + * callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ map(callbackfn: (value: number, index: number, array: Uint8Array) => number, thisArg?: any): Uint8Array; /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next + * Calls the specified callback function for all the elements in an array. The return value of + * the callback function is the accumulated result, and is provided as an argument in the next * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the + * @param callbackfn A function that accepts up to four arguments. The reduce method calls the * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start + * @param initialValue If initialValue is specified, it is used as the initial value to start * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number, initialValue?: number): number; /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next + * Calls the specified callback function for all the elements in an array. The return value of + * the callback function is the accumulated result, and is provided as an argument in the next * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the + * @param callbackfn A function that accepts up to four arguments. The reduce method calls the * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduce(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint8Array) => U, initialValue: U): U; - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an + /** + * Calls the specified callback function for all the elements in an array, in descending order. + * The return value of the callback function is the accumulated result, and is provided as an * argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an + * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls + * the callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an * argument instead of an array value. */ reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number, initialValue?: number): number; - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an + /** + * Calls the specified callback function for all the elements in an array, in descending order. + * The return value of the callback function is the accumulated result, and is provided as an * argument in the next call to the callback function. * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start + * the callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduceRight(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint8Array) => U, initialValue: U): U; /** - * Reverses the elements in an Array. + * Reverses the elements in an Array. */ reverse(): Uint8Array; @@ -1853,7 +1865,7 @@ interface Uint8Array { */ set(array: ArrayLike, offset?: number): void; - /** + /** * Returns a section of an array. * @param start The beginning of the specified portion of the array. * @param end The end of the specified portion of the array. @@ -1862,31 +1874,31 @@ interface Uint8Array { /** * Determines whether the specified callback function returns true for any element of an array. - * @param callbackfn A function that accepts up to three arguments. The some method calls the - * callbackfn function for each element in array1 until the callbackfn returns true, or until + * @param callbackfn A function that accepts up to three arguments. The some method calls the + * callbackfn function for each element in array1 until the callbackfn returns true, or until * the end of the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ some(callbackfn: (value: number, index: number, array: Uint8Array) => boolean, thisArg?: any): boolean; /** * Sorts an array. - * @param compareFn The name of the function used to determine the order of the elements. If + * @param compareFn The name of the function used to determine the order of the elements. If * omitted, the elements are sorted in ascending, ASCII character order. */ sort(compareFn?: (a: number, b: number) => number): Uint8Array; /** * Gets a new Uint8Array view of the ArrayBuffer store for this array, referencing the elements - * at begin, inclusive, up to end, exclusive. + * at begin, inclusive, up to end, exclusive. * @param begin The index of the beginning of the array. * @param end The index of the end of the array. */ subarray(begin: number, end?: number): Uint8Array; /** - * Converts a number to a string by using the current locale. + * Converts a number to a string by using the current locale. */ toLocaleString(): string; @@ -1905,7 +1917,7 @@ interface Uint8ArrayConstructor { new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Uint8Array; /** - * The size in bytes of each element in the array. + * The size in bytes of each element in the array. */ BYTES_PER_ELEMENT: number; @@ -1914,7 +1926,7 @@ interface Uint8ArrayConstructor { * @param items A set of elements to include in the new array object. */ of(...items: number[]): Uint8Array; - + /** * Creates an array from an array-like or iterable object. * @param arrayLike An array-like or iterable object to convert to an array. @@ -1927,17 +1939,17 @@ interface Uint8ArrayConstructor { declare var Uint8Array: Uint8ArrayConstructor; /** - * A typed array of 8-bit unsigned integer (clamped) values. The contents are initialized to 0. + * A typed array of 8-bit unsigned integer (clamped) values. The contents are initialized to 0. * If the requested number of bytes could not be allocated an exception is raised. */ interface Uint8ClampedArray { /** - * The size in bytes of each element in the array. + * The size in bytes of each element in the array. */ BYTES_PER_ELEMENT: number; /** - * The ArrayBuffer instance referenced by the array. + * The ArrayBuffer instance referenced by the array. */ buffer: ArrayBuffer; @@ -1951,21 +1963,21 @@ interface Uint8ClampedArray { */ byteOffset: number; - /** + /** * Returns the this object after copying a section of the array identified by start and end * to the same array starting at position target - * @param target If target is negative, it is treated as length+target where length is the - * length of the array. - * @param start If start is negative, it is treated as length+start. If end is negative, it + * @param target If target is negative, it is treated as length+target where length is the + * length of the array. + * @param start If start is negative, it is treated as length+start. If end is negative, it * is treated as length+end. - * @param end If not specified, length of the this object is used as its default value. + * @param end If not specified, length of the this object is used as its default value. */ copyWithin(target: number, start: number, end?: number): Uint8ClampedArray; /** * Determines whether all the members of an array satisfy the specified test. - * @param callbackfn A function that accepts up to three arguments. The every method calls - * the callbackfn function for each element in array1 until the callbackfn returns false, + * @param callbackfn A function that accepts up to three arguments. The every method calls + * the callbackfn function for each element in array1 until the callbackfn returns false, * or until the end of the array. * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. @@ -1975,49 +1987,49 @@ interface Uint8ClampedArray { /** * Returns the this object after filling the section identified by start and end with value * @param value value to fill array section with - * @param start index to start filling the array at. If start is negative, it is treated as - * length+start where length is the length of the array. - * @param end index to stop filling the array at. If end is negative, it is treated as + * @param start index to start filling the array at. If start is negative, it is treated as + * length+start where length is the length of the array. + * @param end index to stop filling the array at. If end is negative, it is treated as * length+end. */ fill(value: number, start?: number, end?: number): Uint8ClampedArray; /** - * Returns the elements of an array that meet the condition specified in a callback function. - * @param callbackfn A function that accepts up to three arguments. The filter method calls - * the callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * Returns the elements of an array that meet the condition specified in a callback function. + * @param callbackfn A function that accepts up to three arguments. The filter method calls + * the callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ filter(callbackfn: (value: number, index: number, array: Uint8ClampedArray) => boolean, thisArg?: any): Uint8ClampedArray; - /** - * Returns the value of the first element in the array where predicate is true, and undefined + /** + * Returns the value of the first element in the array where predicate is true, and undefined * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find + * @param predicate find calls predicate once for each element of the array, in ascending + * order, until it finds one where predicate returns true. If such an element is found, find * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of + * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ find(predicate: (value: number, index: number, obj: Array) => boolean, thisArg?: any): number; - /** - * Returns the index of the first element in the array where predicate is true, and undefined + /** + * Returns the index of the first element in the array where predicate is true, and undefined * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find + * @param predicate find calls predicate once for each element of the array, in ascending + * order, until it finds one where predicate returns true. If such an element is found, find * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of + * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ findIndex(predicate: (value: number) => boolean, thisArg?: any): number; /** * Performs the specified action for each element in an array. - * @param callbackfn A function that accepts up to three arguments. forEach calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param callbackfn A function that accepts up to three arguments. forEach calls the + * callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ forEach(callbackfn: (value: number, index: number, array: Uint8ClampedArray) => void, thisArg?: any): void; @@ -2032,7 +2044,7 @@ interface Uint8ClampedArray { /** * Adds all the elements of an array separated by the specified separator string. - * @param separator A string used to separate one element of an array from the next in the + * @param separator A string used to separate one element of an array from the next in the * resulting String. If omitted, the array elements are separated with a comma. */ join(separator?: string): string; @@ -2040,7 +2052,7 @@ interface Uint8ClampedArray { /** * Returns the index of the last occurrence of a value in an array. * @param searchElement The value to locate in the array. - * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the + * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the * search starts at index 0. */ lastIndexOf(searchElement: number, fromIndex?: number): number; @@ -2051,65 +2063,65 @@ interface Uint8ClampedArray { length: number; /** - * Calls a defined callback function on each element of an array, and returns an array that + * Calls a defined callback function on each element of an array, and returns an array that * contains the results. - * @param callbackfn A function that accepts up to three arguments. The map method calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param callbackfn A function that accepts up to three arguments. The map method calls the + * callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ map(callbackfn: (value: number, index: number, array: Uint8ClampedArray) => number, thisArg?: any): Uint8ClampedArray; /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next + * Calls the specified callback function for all the elements in an array. The return value of + * the callback function is the accumulated result, and is provided as an argument in the next * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the + * @param callbackfn A function that accepts up to four arguments. The reduce method calls the * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start + * @param initialValue If initialValue is specified, it is used as the initial value to start * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => number, initialValue?: number): number; /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next + * Calls the specified callback function for all the elements in an array. The return value of + * the callback function is the accumulated result, and is provided as an argument in the next * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the + * @param callbackfn A function that accepts up to four arguments. The reduce method calls the * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduce(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => U, initialValue: U): U; - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an + /** + * Calls the specified callback function for all the elements in an array, in descending order. + * The return value of the callback function is the accumulated result, and is provided as an * argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an + * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls + * the callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an * argument instead of an array value. */ reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => number, initialValue?: number): number; - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an + /** + * Calls the specified callback function for all the elements in an array, in descending order. + * The return value of the callback function is the accumulated result, and is provided as an * argument in the next call to the callback function. * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start + * the callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduceRight(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => U, initialValue: U): U; /** - * Reverses the elements in an Array. + * Reverses the elements in an Array. */ reverse(): Uint8ClampedArray; @@ -2127,7 +2139,7 @@ interface Uint8ClampedArray { */ set(array: Uint8ClampedArray, offset?: number): void; - /** + /** * Returns a section of an array. * @param start The beginning of the specified portion of the array. * @param end The end of the specified portion of the array. @@ -2136,31 +2148,31 @@ interface Uint8ClampedArray { /** * Determines whether the specified callback function returns true for any element of an array. - * @param callbackfn A function that accepts up to three arguments. The some method calls the - * callbackfn function for each element in array1 until the callbackfn returns true, or until + * @param callbackfn A function that accepts up to three arguments. The some method calls the + * callbackfn function for each element in array1 until the callbackfn returns true, or until * the end of the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ some(callbackfn: (value: number, index: number, array: Uint8ClampedArray) => boolean, thisArg?: any): boolean; /** * Sorts an array. - * @param compareFn The name of the function used to determine the order of the elements. If + * @param compareFn The name of the function used to determine the order of the elements. If * omitted, the elements are sorted in ascending, ASCII character order. */ sort(compareFn?: (a: number, b: number) => number): Uint8ClampedArray; /** * Gets a new Uint8ClampedArray view of the ArrayBuffer store for this array, referencing the elements - * at begin, inclusive, up to end, exclusive. + * at begin, inclusive, up to end, exclusive. * @param begin The index of the beginning of the array. * @param end The index of the end of the array. */ subarray(begin: number, end?: number): Uint8ClampedArray; /** - * Converts a number to a string by using the current locale. + * Converts a number to a string by using the current locale. */ toLocaleString(): string; @@ -2179,7 +2191,7 @@ interface Uint8ClampedArrayConstructor { new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Uint8ClampedArray; /** - * The size in bytes of each element in the array. + * The size in bytes of each element in the array. */ BYTES_PER_ELEMENT: number; @@ -2200,17 +2212,17 @@ interface Uint8ClampedArrayConstructor { declare var Uint8ClampedArray: Uint8ClampedArrayConstructor; /** - * A typed array of 16-bit signed integer values. The contents are initialized to 0. If the + * A typed array of 16-bit signed integer values. The contents are initialized to 0. If the * requested number of bytes could not be allocated an exception is raised. */ interface Int16Array { /** - * The size in bytes of each element in the array. + * The size in bytes of each element in the array. */ BYTES_PER_ELEMENT: number; /** - * The ArrayBuffer instance referenced by the array. + * The ArrayBuffer instance referenced by the array. */ buffer: ArrayBuffer; @@ -2224,21 +2236,21 @@ interface Int16Array { */ byteOffset: number; - /** + /** * Returns the this object after copying a section of the array identified by start and end * to the same array starting at position target - * @param target If target is negative, it is treated as length+target where length is the - * length of the array. - * @param start If start is negative, it is treated as length+start. If end is negative, it + * @param target If target is negative, it is treated as length+target where length is the + * length of the array. + * @param start If start is negative, it is treated as length+start. If end is negative, it * is treated as length+end. - * @param end If not specified, length of the this object is used as its default value. + * @param end If not specified, length of the this object is used as its default value. */ copyWithin(target: number, start: number, end?: number): Int16Array; /** * Determines whether all the members of an array satisfy the specified test. - * @param callbackfn A function that accepts up to three arguments. The every method calls - * the callbackfn function for each element in array1 until the callbackfn returns false, + * @param callbackfn A function that accepts up to three arguments. The every method calls + * the callbackfn function for each element in array1 until the callbackfn returns false, * or until the end of the array. * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. @@ -2248,49 +2260,49 @@ interface Int16Array { /** * Returns the this object after filling the section identified by start and end with value * @param value value to fill array section with - * @param start index to start filling the array at. If start is negative, it is treated as - * length+start where length is the length of the array. - * @param end index to stop filling the array at. If end is negative, it is treated as + * @param start index to start filling the array at. If start is negative, it is treated as + * length+start where length is the length of the array. + * @param end index to stop filling the array at. If end is negative, it is treated as * length+end. */ fill(value: number, start?: number, end?: number): Int16Array; /** - * Returns the elements of an array that meet the condition specified in a callback function. - * @param callbackfn A function that accepts up to three arguments. The filter method calls - * the callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * Returns the elements of an array that meet the condition specified in a callback function. + * @param callbackfn A function that accepts up to three arguments. The filter method calls + * the callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ filter(callbackfn: (value: number, index: number, array: Int16Array) => boolean, thisArg?: any): Int16Array; - /** - * Returns the value of the first element in the array where predicate is true, and undefined + /** + * Returns the value of the first element in the array where predicate is true, and undefined * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find + * @param predicate find calls predicate once for each element of the array, in ascending + * order, until it finds one where predicate returns true. If such an element is found, find * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of + * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ find(predicate: (value: number, index: number, obj: Array) => boolean, thisArg?: any): number; - /** - * Returns the index of the first element in the array where predicate is true, and undefined + /** + * Returns the index of the first element in the array where predicate is true, and undefined * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find + * @param predicate find calls predicate once for each element of the array, in ascending + * order, until it finds one where predicate returns true. If such an element is found, find * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of + * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ findIndex(predicate: (value: number) => boolean, thisArg?: any): number; /** * Performs the specified action for each element in an array. - * @param callbackfn A function that accepts up to three arguments. forEach calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param callbackfn A function that accepts up to three arguments. forEach calls the + * callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ forEach(callbackfn: (value: number, index: number, array: Int16Array) => void, thisArg?: any): void; @@ -2305,7 +2317,7 @@ interface Int16Array { /** * Adds all the elements of an array separated by the specified separator string. - * @param separator A string used to separate one element of an array from the next in the + * @param separator A string used to separate one element of an array from the next in the * resulting String. If omitted, the array elements are separated with a comma. */ join(separator?: string): string; @@ -2313,7 +2325,7 @@ interface Int16Array { /** * Returns the index of the last occurrence of a value in an array. * @param searchElement The value to locate in the array. - * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the + * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the * search starts at index 0. */ lastIndexOf(searchElement: number, fromIndex?: number): number; @@ -2324,65 +2336,65 @@ interface Int16Array { length: number; /** - * Calls a defined callback function on each element of an array, and returns an array that + * Calls a defined callback function on each element of an array, and returns an array that * contains the results. - * @param callbackfn A function that accepts up to three arguments. The map method calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param callbackfn A function that accepts up to three arguments. The map method calls the + * callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ map(callbackfn: (value: number, index: number, array: Int16Array) => number, thisArg?: any): Int16Array; /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next + * Calls the specified callback function for all the elements in an array. The return value of + * the callback function is the accumulated result, and is provided as an argument in the next * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the + * @param callbackfn A function that accepts up to four arguments. The reduce method calls the * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start + * @param initialValue If initialValue is specified, it is used as the initial value to start * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number, initialValue?: number): number; /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next + * Calls the specified callback function for all the elements in an array. The return value of + * the callback function is the accumulated result, and is provided as an argument in the next * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the + * @param callbackfn A function that accepts up to four arguments. The reduce method calls the * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduce(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int16Array) => U, initialValue: U): U; - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an + /** + * Calls the specified callback function for all the elements in an array, in descending order. + * The return value of the callback function is the accumulated result, and is provided as an * argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an + * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls + * the callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an * argument instead of an array value. */ reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number, initialValue?: number): number; - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an + /** + * Calls the specified callback function for all the elements in an array, in descending order. + * The return value of the callback function is the accumulated result, and is provided as an * argument in the next call to the callback function. * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start + * the callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduceRight(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int16Array) => U, initialValue: U): U; /** - * Reverses the elements in an Array. + * Reverses the elements in an Array. */ reverse(): Int16Array; @@ -2400,7 +2412,7 @@ interface Int16Array { */ set(array: ArrayLike, offset?: number): void; - /** + /** * Returns a section of an array. * @param start The beginning of the specified portion of the array. * @param end The end of the specified portion of the array. @@ -2409,31 +2421,31 @@ interface Int16Array { /** * Determines whether the specified callback function returns true for any element of an array. - * @param callbackfn A function that accepts up to three arguments. The some method calls the - * callbackfn function for each element in array1 until the callbackfn returns true, or until + * @param callbackfn A function that accepts up to three arguments. The some method calls the + * callbackfn function for each element in array1 until the callbackfn returns true, or until * the end of the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ some(callbackfn: (value: number, index: number, array: Int16Array) => boolean, thisArg?: any): boolean; /** * Sorts an array. - * @param compareFn The name of the function used to determine the order of the elements. If + * @param compareFn The name of the function used to determine the order of the elements. If * omitted, the elements are sorted in ascending, ASCII character order. */ sort(compareFn?: (a: number, b: number) => number): Int16Array; /** * Gets a new Int16Array view of the ArrayBuffer store for this array, referencing the elements - * at begin, inclusive, up to end, exclusive. + * at begin, inclusive, up to end, exclusive. * @param begin The index of the beginning of the array. * @param end The index of the end of the array. */ subarray(begin: number, end?: number): Int16Array; /** - * Converts a number to a string by using the current locale. + * Converts a number to a string by using the current locale. */ toLocaleString(): string; @@ -2452,7 +2464,7 @@ interface Int16ArrayConstructor { new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Int16Array; /** - * The size in bytes of each element in the array. + * The size in bytes of each element in the array. */ BYTES_PER_ELEMENT: number; @@ -2461,7 +2473,7 @@ interface Int16ArrayConstructor { * @param items A set of elements to include in the new array object. */ of(...items: number[]): Int16Array; - + /** * Creates an array from an array-like or iterable object. * @param arrayLike An array-like or iterable object to convert to an array. @@ -2474,17 +2486,17 @@ interface Int16ArrayConstructor { declare var Int16Array: Int16ArrayConstructor; /** - * A typed array of 16-bit unsigned integer values. The contents are initialized to 0. If the + * A typed array of 16-bit unsigned integer values. The contents are initialized to 0. If the * requested number of bytes could not be allocated an exception is raised. */ interface Uint16Array { /** - * The size in bytes of each element in the array. + * The size in bytes of each element in the array. */ BYTES_PER_ELEMENT: number; /** - * The ArrayBuffer instance referenced by the array. + * The ArrayBuffer instance referenced by the array. */ buffer: ArrayBuffer; @@ -2498,21 +2510,21 @@ interface Uint16Array { */ byteOffset: number; - /** + /** * Returns the this object after copying a section of the array identified by start and end * to the same array starting at position target - * @param target If target is negative, it is treated as length+target where length is the - * length of the array. - * @param start If start is negative, it is treated as length+start. If end is negative, it + * @param target If target is negative, it is treated as length+target where length is the + * length of the array. + * @param start If start is negative, it is treated as length+start. If end is negative, it * is treated as length+end. - * @param end If not specified, length of the this object is used as its default value. + * @param end If not specified, length of the this object is used as its default value. */ copyWithin(target: number, start: number, end?: number): Uint16Array; /** * Determines whether all the members of an array satisfy the specified test. - * @param callbackfn A function that accepts up to three arguments. The every method calls - * the callbackfn function for each element in array1 until the callbackfn returns false, + * @param callbackfn A function that accepts up to three arguments. The every method calls + * the callbackfn function for each element in array1 until the callbackfn returns false, * or until the end of the array. * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. @@ -2522,49 +2534,49 @@ interface Uint16Array { /** * Returns the this object after filling the section identified by start and end with value * @param value value to fill array section with - * @param start index to start filling the array at. If start is negative, it is treated as - * length+start where length is the length of the array. - * @param end index to stop filling the array at. If end is negative, it is treated as + * @param start index to start filling the array at. If start is negative, it is treated as + * length+start where length is the length of the array. + * @param end index to stop filling the array at. If end is negative, it is treated as * length+end. */ fill(value: number, start?: number, end?: number): Uint16Array; /** - * Returns the elements of an array that meet the condition specified in a callback function. - * @param callbackfn A function that accepts up to three arguments. The filter method calls - * the callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * Returns the elements of an array that meet the condition specified in a callback function. + * @param callbackfn A function that accepts up to three arguments. The filter method calls + * the callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ filter(callbackfn: (value: number, index: number, array: Uint16Array) => boolean, thisArg?: any): Uint16Array; - /** - * Returns the value of the first element in the array where predicate is true, and undefined + /** + * Returns the value of the first element in the array where predicate is true, and undefined * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find + * @param predicate find calls predicate once for each element of the array, in ascending + * order, until it finds one where predicate returns true. If such an element is found, find * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of + * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ find(predicate: (value: number, index: number, obj: Array) => boolean, thisArg?: any): number; - /** - * Returns the index of the first element in the array where predicate is true, and undefined + /** + * Returns the index of the first element in the array where predicate is true, and undefined * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find + * @param predicate find calls predicate once for each element of the array, in ascending + * order, until it finds one where predicate returns true. If such an element is found, find * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of + * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ findIndex(predicate: (value: number) => boolean, thisArg?: any): number; /** * Performs the specified action for each element in an array. - * @param callbackfn A function that accepts up to three arguments. forEach calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param callbackfn A function that accepts up to three arguments. forEach calls the + * callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ forEach(callbackfn: (value: number, index: number, array: Uint16Array) => void, thisArg?: any): void; @@ -2579,7 +2591,7 @@ interface Uint16Array { /** * Adds all the elements of an array separated by the specified separator string. - * @param separator A string used to separate one element of an array from the next in the + * @param separator A string used to separate one element of an array from the next in the * resulting String. If omitted, the array elements are separated with a comma. */ join(separator?: string): string; @@ -2587,7 +2599,7 @@ interface Uint16Array { /** * Returns the index of the last occurrence of a value in an array. * @param searchElement The value to locate in the array. - * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the + * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the * search starts at index 0. */ lastIndexOf(searchElement: number, fromIndex?: number): number; @@ -2598,65 +2610,65 @@ interface Uint16Array { length: number; /** - * Calls a defined callback function on each element of an array, and returns an array that + * Calls a defined callback function on each element of an array, and returns an array that * contains the results. - * @param callbackfn A function that accepts up to three arguments. The map method calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param callbackfn A function that accepts up to three arguments. The map method calls the + * callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ map(callbackfn: (value: number, index: number, array: Uint16Array) => number, thisArg?: any): Uint16Array; /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next + * Calls the specified callback function for all the elements in an array. The return value of + * the callback function is the accumulated result, and is provided as an argument in the next * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the + * @param callbackfn A function that accepts up to four arguments. The reduce method calls the * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start + * @param initialValue If initialValue is specified, it is used as the initial value to start * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint16Array) => number, initialValue?: number): number; /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next + * Calls the specified callback function for all the elements in an array. The return value of + * the callback function is the accumulated result, and is provided as an argument in the next * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the + * @param callbackfn A function that accepts up to four arguments. The reduce method calls the * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduce(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint16Array) => U, initialValue: U): U; - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an + /** + * Calls the specified callback function for all the elements in an array, in descending order. + * The return value of the callback function is the accumulated result, and is provided as an * argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an + * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls + * the callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an * argument instead of an array value. */ reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint16Array) => number, initialValue?: number): number; - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an + /** + * Calls the specified callback function for all the elements in an array, in descending order. + * The return value of the callback function is the accumulated result, and is provided as an * argument in the next call to the callback function. * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start + * the callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduceRight(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint16Array) => U, initialValue: U): U; /** - * Reverses the elements in an Array. + * Reverses the elements in an Array. */ reverse(): Uint16Array; @@ -2674,7 +2686,7 @@ interface Uint16Array { */ set(array: ArrayLike, offset?: number): void; - /** + /** * Returns a section of an array. * @param start The beginning of the specified portion of the array. * @param end The end of the specified portion of the array. @@ -2683,31 +2695,31 @@ interface Uint16Array { /** * Determines whether the specified callback function returns true for any element of an array. - * @param callbackfn A function that accepts up to three arguments. The some method calls the - * callbackfn function for each element in array1 until the callbackfn returns true, or until + * @param callbackfn A function that accepts up to three arguments. The some method calls the + * callbackfn function for each element in array1 until the callbackfn returns true, or until * the end of the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ some(callbackfn: (value: number, index: number, array: Uint16Array) => boolean, thisArg?: any): boolean; /** * Sorts an array. - * @param compareFn The name of the function used to determine the order of the elements. If + * @param compareFn The name of the function used to determine the order of the elements. If * omitted, the elements are sorted in ascending, ASCII character order. */ sort(compareFn?: (a: number, b: number) => number): Uint16Array; /** * Gets a new Uint16Array view of the ArrayBuffer store for this array, referencing the elements - * at begin, inclusive, up to end, exclusive. + * at begin, inclusive, up to end, exclusive. * @param begin The index of the beginning of the array. * @param end The index of the end of the array. */ subarray(begin: number, end?: number): Uint16Array; /** - * Converts a number to a string by using the current locale. + * Converts a number to a string by using the current locale. */ toLocaleString(): string; @@ -2726,7 +2738,7 @@ interface Uint16ArrayConstructor { new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Uint16Array; /** - * The size in bytes of each element in the array. + * The size in bytes of each element in the array. */ BYTES_PER_ELEMENT: number; @@ -2735,7 +2747,7 @@ interface Uint16ArrayConstructor { * @param items A set of elements to include in the new array object. */ of(...items: number[]): Uint16Array; - + /** * Creates an array from an array-like or iterable object. * @param arrayLike An array-like or iterable object to convert to an array. @@ -2747,17 +2759,17 @@ interface Uint16ArrayConstructor { } declare var Uint16Array: Uint16ArrayConstructor; /** - * A typed array of 32-bit signed integer values. The contents are initialized to 0. If the + * A typed array of 32-bit signed integer values. The contents are initialized to 0. If the * requested number of bytes could not be allocated an exception is raised. */ interface Int32Array { /** - * The size in bytes of each element in the array. + * The size in bytes of each element in the array. */ BYTES_PER_ELEMENT: number; /** - * The ArrayBuffer instance referenced by the array. + * The ArrayBuffer instance referenced by the array. */ buffer: ArrayBuffer; @@ -2771,21 +2783,21 @@ interface Int32Array { */ byteOffset: number; - /** + /** * Returns the this object after copying a section of the array identified by start and end * to the same array starting at position target - * @param target If target is negative, it is treated as length+target where length is the - * length of the array. - * @param start If start is negative, it is treated as length+start. If end is negative, it + * @param target If target is negative, it is treated as length+target where length is the + * length of the array. + * @param start If start is negative, it is treated as length+start. If end is negative, it * is treated as length+end. - * @param end If not specified, length of the this object is used as its default value. + * @param end If not specified, length of the this object is used as its default value. */ copyWithin(target: number, start: number, end?: number): Int32Array; /** * Determines whether all the members of an array satisfy the specified test. - * @param callbackfn A function that accepts up to three arguments. The every method calls - * the callbackfn function for each element in array1 until the callbackfn returns false, + * @param callbackfn A function that accepts up to three arguments. The every method calls + * the callbackfn function for each element in array1 until the callbackfn returns false, * or until the end of the array. * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. @@ -2795,49 +2807,49 @@ interface Int32Array { /** * Returns the this object after filling the section identified by start and end with value * @param value value to fill array section with - * @param start index to start filling the array at. If start is negative, it is treated as - * length+start where length is the length of the array. - * @param end index to stop filling the array at. If end is negative, it is treated as + * @param start index to start filling the array at. If start is negative, it is treated as + * length+start where length is the length of the array. + * @param end index to stop filling the array at. If end is negative, it is treated as * length+end. */ fill(value: number, start?: number, end?: number): Int32Array; /** - * Returns the elements of an array that meet the condition specified in a callback function. - * @param callbackfn A function that accepts up to three arguments. The filter method calls - * the callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * Returns the elements of an array that meet the condition specified in a callback function. + * @param callbackfn A function that accepts up to three arguments. The filter method calls + * the callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ filter(callbackfn: (value: number, index: number, array: Int32Array) => boolean, thisArg?: any): Int32Array; - /** - * Returns the value of the first element in the array where predicate is true, and undefined + /** + * Returns the value of the first element in the array where predicate is true, and undefined * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find + * @param predicate find calls predicate once for each element of the array, in ascending + * order, until it finds one where predicate returns true. If such an element is found, find * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of + * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ find(predicate: (value: number, index: number, obj: Array) => boolean, thisArg?: any): number; - /** - * Returns the index of the first element in the array where predicate is true, and undefined + /** + * Returns the index of the first element in the array where predicate is true, and undefined * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find + * @param predicate find calls predicate once for each element of the array, in ascending + * order, until it finds one where predicate returns true. If such an element is found, find * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of + * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ findIndex(predicate: (value: number) => boolean, thisArg?: any): number; /** * Performs the specified action for each element in an array. - * @param callbackfn A function that accepts up to three arguments. forEach calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param callbackfn A function that accepts up to three arguments. forEach calls the + * callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ forEach(callbackfn: (value: number, index: number, array: Int32Array) => void, thisArg?: any): void; @@ -2852,7 +2864,7 @@ interface Int32Array { /** * Adds all the elements of an array separated by the specified separator string. - * @param separator A string used to separate one element of an array from the next in the + * @param separator A string used to separate one element of an array from the next in the * resulting String. If omitted, the array elements are separated with a comma. */ join(separator?: string): string; @@ -2860,7 +2872,7 @@ interface Int32Array { /** * Returns the index of the last occurrence of a value in an array. * @param searchElement The value to locate in the array. - * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the + * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the * search starts at index 0. */ lastIndexOf(searchElement: number, fromIndex?: number): number; @@ -2871,65 +2883,65 @@ interface Int32Array { length: number; /** - * Calls a defined callback function on each element of an array, and returns an array that + * Calls a defined callback function on each element of an array, and returns an array that * contains the results. - * @param callbackfn A function that accepts up to three arguments. The map method calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param callbackfn A function that accepts up to three arguments. The map method calls the + * callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ map(callbackfn: (value: number, index: number, array: Int32Array) => number, thisArg?: any): Int32Array; /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next + * Calls the specified callback function for all the elements in an array. The return value of + * the callback function is the accumulated result, and is provided as an argument in the next * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the + * @param callbackfn A function that accepts up to four arguments. The reduce method calls the * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start + * @param initialValue If initialValue is specified, it is used as the initial value to start * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number, initialValue?: number): number; /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next + * Calls the specified callback function for all the elements in an array. The return value of + * the callback function is the accumulated result, and is provided as an argument in the next * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the + * @param callbackfn A function that accepts up to four arguments. The reduce method calls the * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduce(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int32Array) => U, initialValue: U): U; - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an + /** + * Calls the specified callback function for all the elements in an array, in descending order. + * The return value of the callback function is the accumulated result, and is provided as an * argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an + * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls + * the callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an * argument instead of an array value. */ reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number, initialValue?: number): number; - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an + /** + * Calls the specified callback function for all the elements in an array, in descending order. + * The return value of the callback function is the accumulated result, and is provided as an * argument in the next call to the callback function. * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start + * the callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduceRight(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int32Array) => U, initialValue: U): U; /** - * Reverses the elements in an Array. + * Reverses the elements in an Array. */ reverse(): Int32Array; @@ -2947,7 +2959,7 @@ interface Int32Array { */ set(array: ArrayLike, offset?: number): void; - /** + /** * Returns a section of an array. * @param start The beginning of the specified portion of the array. * @param end The end of the specified portion of the array. @@ -2956,31 +2968,31 @@ interface Int32Array { /** * Determines whether the specified callback function returns true for any element of an array. - * @param callbackfn A function that accepts up to three arguments. The some method calls the - * callbackfn function for each element in array1 until the callbackfn returns true, or until + * @param callbackfn A function that accepts up to three arguments. The some method calls the + * callbackfn function for each element in array1 until the callbackfn returns true, or until * the end of the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ some(callbackfn: (value: number, index: number, array: Int32Array) => boolean, thisArg?: any): boolean; /** * Sorts an array. - * @param compareFn The name of the function used to determine the order of the elements. If + * @param compareFn The name of the function used to determine the order of the elements. If * omitted, the elements are sorted in ascending, ASCII character order. */ sort(compareFn?: (a: number, b: number) => number): Int32Array; /** * Gets a new Int32Array view of the ArrayBuffer store for this array, referencing the elements - * at begin, inclusive, up to end, exclusive. + * at begin, inclusive, up to end, exclusive. * @param begin The index of the beginning of the array. * @param end The index of the end of the array. */ subarray(begin: number, end?: number): Int32Array; /** - * Converts a number to a string by using the current locale. + * Converts a number to a string by using the current locale. */ toLocaleString(): string; @@ -2999,7 +3011,7 @@ interface Int32ArrayConstructor { new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Int32Array; /** - * The size in bytes of each element in the array. + * The size in bytes of each element in the array. */ BYTES_PER_ELEMENT: number; @@ -3008,7 +3020,7 @@ interface Int32ArrayConstructor { * @param items A set of elements to include in the new array object. */ of(...items: number[]): Int32Array; - + /** * Creates an array from an array-like or iterable object. * @param arrayLike An array-like or iterable object to convert to an array. @@ -3020,17 +3032,17 @@ interface Int32ArrayConstructor { declare var Int32Array: Int32ArrayConstructor; /** - * A typed array of 32-bit unsigned integer values. The contents are initialized to 0. If the + * A typed array of 32-bit unsigned integer values. The contents are initialized to 0. If the * requested number of bytes could not be allocated an exception is raised. */ interface Uint32Array { /** - * The size in bytes of each element in the array. + * The size in bytes of each element in the array. */ BYTES_PER_ELEMENT: number; /** - * The ArrayBuffer instance referenced by the array. + * The ArrayBuffer instance referenced by the array. */ buffer: ArrayBuffer; @@ -3044,21 +3056,21 @@ interface Uint32Array { */ byteOffset: number; - /** + /** * Returns the this object after copying a section of the array identified by start and end * to the same array starting at position target - * @param target If target is negative, it is treated as length+target where length is the - * length of the array. - * @param start If start is negative, it is treated as length+start. If end is negative, it + * @param target If target is negative, it is treated as length+target where length is the + * length of the array. + * @param start If start is negative, it is treated as length+start. If end is negative, it * is treated as length+end. - * @param end If not specified, length of the this object is used as its default value. + * @param end If not specified, length of the this object is used as its default value. */ copyWithin(target: number, start: number, end?: number): Uint32Array; /** * Determines whether all the members of an array satisfy the specified test. - * @param callbackfn A function that accepts up to three arguments. The every method calls - * the callbackfn function for each element in array1 until the callbackfn returns false, + * @param callbackfn A function that accepts up to three arguments. The every method calls + * the callbackfn function for each element in array1 until the callbackfn returns false, * or until the end of the array. * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. @@ -3068,49 +3080,49 @@ interface Uint32Array { /** * Returns the this object after filling the section identified by start and end with value * @param value value to fill array section with - * @param start index to start filling the array at. If start is negative, it is treated as - * length+start where length is the length of the array. - * @param end index to stop filling the array at. If end is negative, it is treated as + * @param start index to start filling the array at. If start is negative, it is treated as + * length+start where length is the length of the array. + * @param end index to stop filling the array at. If end is negative, it is treated as * length+end. */ fill(value: number, start?: number, end?: number): Uint32Array; /** - * Returns the elements of an array that meet the condition specified in a callback function. - * @param callbackfn A function that accepts up to three arguments. The filter method calls - * the callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * Returns the elements of an array that meet the condition specified in a callback function. + * @param callbackfn A function that accepts up to three arguments. The filter method calls + * the callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ filter(callbackfn: (value: number, index: number, array: Uint32Array) => boolean, thisArg?: any): Uint32Array; - /** - * Returns the value of the first element in the array where predicate is true, and undefined + /** + * Returns the value of the first element in the array where predicate is true, and undefined * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find + * @param predicate find calls predicate once for each element of the array, in ascending + * order, until it finds one where predicate returns true. If such an element is found, find * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of + * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ find(predicate: (value: number, index: number, obj: Array) => boolean, thisArg?: any): number; - /** - * Returns the index of the first element in the array where predicate is true, and undefined + /** + * Returns the index of the first element in the array where predicate is true, and undefined * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find + * @param predicate find calls predicate once for each element of the array, in ascending + * order, until it finds one where predicate returns true. If such an element is found, find * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of + * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ findIndex(predicate: (value: number) => boolean, thisArg?: any): number; /** * Performs the specified action for each element in an array. - * @param callbackfn A function that accepts up to three arguments. forEach calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param callbackfn A function that accepts up to three arguments. forEach calls the + * callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ forEach(callbackfn: (value: number, index: number, array: Uint32Array) => void, thisArg?: any): void; @@ -3125,7 +3137,7 @@ interface Uint32Array { /** * Adds all the elements of an array separated by the specified separator string. - * @param separator A string used to separate one element of an array from the next in the + * @param separator A string used to separate one element of an array from the next in the * resulting String. If omitted, the array elements are separated with a comma. */ join(separator?: string): string; @@ -3133,7 +3145,7 @@ interface Uint32Array { /** * Returns the index of the last occurrence of a value in an array. * @param searchElement The value to locate in the array. - * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the + * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the * search starts at index 0. */ lastIndexOf(searchElement: number, fromIndex?: number): number; @@ -3144,65 +3156,65 @@ interface Uint32Array { length: number; /** - * Calls a defined callback function on each element of an array, and returns an array that + * Calls a defined callback function on each element of an array, and returns an array that * contains the results. - * @param callbackfn A function that accepts up to three arguments. The map method calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param callbackfn A function that accepts up to three arguments. The map method calls the + * callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ map(callbackfn: (value: number, index: number, array: Uint32Array) => number, thisArg?: any): Uint32Array; /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next + * Calls the specified callback function for all the elements in an array. The return value of + * the callback function is the accumulated result, and is provided as an argument in the next * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the + * @param callbackfn A function that accepts up to four arguments. The reduce method calls the * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start + * @param initialValue If initialValue is specified, it is used as the initial value to start * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint32Array) => number, initialValue?: number): number; /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next + * Calls the specified callback function for all the elements in an array. The return value of + * the callback function is the accumulated result, and is provided as an argument in the next * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the + * @param callbackfn A function that accepts up to four arguments. The reduce method calls the * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduce(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint32Array) => U, initialValue: U): U; - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an + /** + * Calls the specified callback function for all the elements in an array, in descending order. + * The return value of the callback function is the accumulated result, and is provided as an * argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an + * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls + * the callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an * argument instead of an array value. */ reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint32Array) => number, initialValue?: number): number; - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an + /** + * Calls the specified callback function for all the elements in an array, in descending order. + * The return value of the callback function is the accumulated result, and is provided as an * argument in the next call to the callback function. * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start + * the callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduceRight(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint32Array) => U, initialValue: U): U; /** - * Reverses the elements in an Array. + * Reverses the elements in an Array. */ reverse(): Uint32Array; @@ -3220,7 +3232,7 @@ interface Uint32Array { */ set(array: ArrayLike, offset?: number): void; - /** + /** * Returns a section of an array. * @param start The beginning of the specified portion of the array. * @param end The end of the specified portion of the array. @@ -3229,31 +3241,31 @@ interface Uint32Array { /** * Determines whether the specified callback function returns true for any element of an array. - * @param callbackfn A function that accepts up to three arguments. The some method calls the - * callbackfn function for each element in array1 until the callbackfn returns true, or until + * @param callbackfn A function that accepts up to three arguments. The some method calls the + * callbackfn function for each element in array1 until the callbackfn returns true, or until * the end of the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ some(callbackfn: (value: number, index: number, array: Uint32Array) => boolean, thisArg?: any): boolean; /** * Sorts an array. - * @param compareFn The name of the function used to determine the order of the elements. If + * @param compareFn The name of the function used to determine the order of the elements. If * omitted, the elements are sorted in ascending, ASCII character order. */ sort(compareFn?: (a: number, b: number) => number): Uint32Array; /** * Gets a new Uint32Array view of the ArrayBuffer store for this array, referencing the elements - * at begin, inclusive, up to end, exclusive. + * at begin, inclusive, up to end, exclusive. * @param begin The index of the beginning of the array. * @param end The index of the end of the array. */ subarray(begin: number, end?: number): Uint32Array; /** - * Converts a number to a string by using the current locale. + * Converts a number to a string by using the current locale. */ toLocaleString(): string; @@ -3272,7 +3284,7 @@ interface Uint32ArrayConstructor { new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Uint32Array; /** - * The size in bytes of each element in the array. + * The size in bytes of each element in the array. */ BYTES_PER_ELEMENT: number; @@ -3281,7 +3293,7 @@ interface Uint32ArrayConstructor { * @param items A set of elements to include in the new array object. */ of(...items: number[]): Uint32Array; - + /** * Creates an array from an array-like or iterable object. * @param arrayLike An array-like or iterable object to convert to an array. @@ -3298,12 +3310,12 @@ declare var Uint32Array: Uint32ArrayConstructor; */ interface Float32Array { /** - * The size in bytes of each element in the array. + * The size in bytes of each element in the array. */ BYTES_PER_ELEMENT: number; /** - * The ArrayBuffer instance referenced by the array. + * The ArrayBuffer instance referenced by the array. */ buffer: ArrayBuffer; @@ -3317,21 +3329,21 @@ interface Float32Array { */ byteOffset: number; - /** + /** * Returns the this object after copying a section of the array identified by start and end * to the same array starting at position target - * @param target If target is negative, it is treated as length+target where length is the - * length of the array. - * @param start If start is negative, it is treated as length+start. If end is negative, it + * @param target If target is negative, it is treated as length+target where length is the + * length of the array. + * @param start If start is negative, it is treated as length+start. If end is negative, it * is treated as length+end. - * @param end If not specified, length of the this object is used as its default value. + * @param end If not specified, length of the this object is used as its default value. */ copyWithin(target: number, start: number, end?: number): Float32Array; /** * Determines whether all the members of an array satisfy the specified test. - * @param callbackfn A function that accepts up to three arguments. The every method calls - * the callbackfn function for each element in array1 until the callbackfn returns false, + * @param callbackfn A function that accepts up to three arguments. The every method calls + * the callbackfn function for each element in array1 until the callbackfn returns false, * or until the end of the array. * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. @@ -3341,49 +3353,49 @@ interface Float32Array { /** * Returns the this object after filling the section identified by start and end with value * @param value value to fill array section with - * @param start index to start filling the array at. If start is negative, it is treated as - * length+start where length is the length of the array. - * @param end index to stop filling the array at. If end is negative, it is treated as + * @param start index to start filling the array at. If start is negative, it is treated as + * length+start where length is the length of the array. + * @param end index to stop filling the array at. If end is negative, it is treated as * length+end. */ fill(value: number, start?: number, end?: number): Float32Array; /** - * Returns the elements of an array that meet the condition specified in a callback function. - * @param callbackfn A function that accepts up to three arguments. The filter method calls - * the callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * Returns the elements of an array that meet the condition specified in a callback function. + * @param callbackfn A function that accepts up to three arguments. The filter method calls + * the callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ filter(callbackfn: (value: number, index: number, array: Float32Array) => boolean, thisArg?: any): Float32Array; - /** - * Returns the value of the first element in the array where predicate is true, and undefined + /** + * Returns the value of the first element in the array where predicate is true, and undefined * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find + * @param predicate find calls predicate once for each element of the array, in ascending + * order, until it finds one where predicate returns true. If such an element is found, find * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of + * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ find(predicate: (value: number, index: number, obj: Array) => boolean, thisArg?: any): number; - /** - * Returns the index of the first element in the array where predicate is true, and undefined + /** + * Returns the index of the first element in the array where predicate is true, and undefined * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find + * @param predicate find calls predicate once for each element of the array, in ascending + * order, until it finds one where predicate returns true. If such an element is found, find * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of + * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ findIndex(predicate: (value: number) => boolean, thisArg?: any): number; /** * Performs the specified action for each element in an array. - * @param callbackfn A function that accepts up to three arguments. forEach calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param callbackfn A function that accepts up to three arguments. forEach calls the + * callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ forEach(callbackfn: (value: number, index: number, array: Float32Array) => void, thisArg?: any): void; @@ -3398,7 +3410,7 @@ interface Float32Array { /** * Adds all the elements of an array separated by the specified separator string. - * @param separator A string used to separate one element of an array from the next in the + * @param separator A string used to separate one element of an array from the next in the * resulting String. If omitted, the array elements are separated with a comma. */ join(separator?: string): string; @@ -3406,7 +3418,7 @@ interface Float32Array { /** * Returns the index of the last occurrence of a value in an array. * @param searchElement The value to locate in the array. - * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the + * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the * search starts at index 0. */ lastIndexOf(searchElement: number, fromIndex?: number): number; @@ -3417,65 +3429,65 @@ interface Float32Array { length: number; /** - * Calls a defined callback function on each element of an array, and returns an array that + * Calls a defined callback function on each element of an array, and returns an array that * contains the results. - * @param callbackfn A function that accepts up to three arguments. The map method calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param callbackfn A function that accepts up to three arguments. The map method calls the + * callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ map(callbackfn: (value: number, index: number, array: Float32Array) => number, thisArg?: any): Float32Array; /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next + * Calls the specified callback function for all the elements in an array. The return value of + * the callback function is the accumulated result, and is provided as an argument in the next * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the + * @param callbackfn A function that accepts up to four arguments. The reduce method calls the * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start + * @param initialValue If initialValue is specified, it is used as the initial value to start * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number, initialValue?: number): number; /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next + * Calls the specified callback function for all the elements in an array. The return value of + * the callback function is the accumulated result, and is provided as an argument in the next * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the + * @param callbackfn A function that accepts up to four arguments. The reduce method calls the * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduce(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float32Array) => U, initialValue: U): U; - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an + /** + * Calls the specified callback function for all the elements in an array, in descending order. + * The return value of the callback function is the accumulated result, and is provided as an * argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an + * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls + * the callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an * argument instead of an array value. */ reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number, initialValue?: number): number; - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an + /** + * Calls the specified callback function for all the elements in an array, in descending order. + * The return value of the callback function is the accumulated result, and is provided as an * argument in the next call to the callback function. * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start + * the callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduceRight(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float32Array) => U, initialValue: U): U; /** - * Reverses the elements in an Array. + * Reverses the elements in an Array. */ reverse(): Float32Array; @@ -3493,7 +3505,7 @@ interface Float32Array { */ set(array: ArrayLike, offset?: number): void; - /** + /** * Returns a section of an array. * @param start The beginning of the specified portion of the array. * @param end The end of the specified portion of the array. @@ -3502,31 +3514,31 @@ interface Float32Array { /** * Determines whether the specified callback function returns true for any element of an array. - * @param callbackfn A function that accepts up to three arguments. The some method calls the - * callbackfn function for each element in array1 until the callbackfn returns true, or until + * @param callbackfn A function that accepts up to three arguments. The some method calls the + * callbackfn function for each element in array1 until the callbackfn returns true, or until * the end of the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ some(callbackfn: (value: number, index: number, array: Float32Array) => boolean, thisArg?: any): boolean; /** * Sorts an array. - * @param compareFn The name of the function used to determine the order of the elements. If + * @param compareFn The name of the function used to determine the order of the elements. If * omitted, the elements are sorted in ascending, ASCII character order. */ sort(compareFn?: (a: number, b: number) => number): Float32Array; /** * Gets a new Float32Array view of the ArrayBuffer store for this array, referencing the elements - * at begin, inclusive, up to end, exclusive. + * at begin, inclusive, up to end, exclusive. * @param begin The index of the beginning of the array. * @param end The index of the end of the array. */ subarray(begin: number, end?: number): Float32Array; /** - * Converts a number to a string by using the current locale. + * Converts a number to a string by using the current locale. */ toLocaleString(): string; @@ -3545,7 +3557,7 @@ interface Float32ArrayConstructor { new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Float32Array; /** - * The size in bytes of each element in the array. + * The size in bytes of each element in the array. */ BYTES_PER_ELEMENT: number; @@ -3554,7 +3566,7 @@ interface Float32ArrayConstructor { * @param items A set of elements to include in the new array object. */ of(...items: number[]): Float32Array; - + /** * Creates an array from an array-like or iterable object. * @param arrayLike An array-like or iterable object to convert to an array. @@ -3567,17 +3579,17 @@ interface Float32ArrayConstructor { declare var Float32Array: Float32ArrayConstructor; /** - * A typed array of 64-bit float values. The contents are initialized to 0. If the requested + * A typed array of 64-bit float values. The contents are initialized to 0. If the requested * number of bytes could not be allocated an exception is raised. */ interface Float64Array { /** - * The size in bytes of each element in the array. + * The size in bytes of each element in the array. */ BYTES_PER_ELEMENT: number; /** - * The ArrayBuffer instance referenced by the array. + * The ArrayBuffer instance referenced by the array. */ buffer: ArrayBuffer; @@ -3591,21 +3603,21 @@ interface Float64Array { */ byteOffset: number; - /** + /** * Returns the this object after copying a section of the array identified by start and end * to the same array starting at position target - * @param target If target is negative, it is treated as length+target where length is the - * length of the array. - * @param start If start is negative, it is treated as length+start. If end is negative, it + * @param target If target is negative, it is treated as length+target where length is the + * length of the array. + * @param start If start is negative, it is treated as length+start. If end is negative, it * is treated as length+end. - * @param end If not specified, length of the this object is used as its default value. + * @param end If not specified, length of the this object is used as its default value. */ copyWithin(target: number, start: number, end?: number): Float64Array; /** * Determines whether all the members of an array satisfy the specified test. - * @param callbackfn A function that accepts up to three arguments. The every method calls - * the callbackfn function for each element in array1 until the callbackfn returns false, + * @param callbackfn A function that accepts up to three arguments. The every method calls + * the callbackfn function for each element in array1 until the callbackfn returns false, * or until the end of the array. * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. @@ -3615,49 +3627,49 @@ interface Float64Array { /** * Returns the this object after filling the section identified by start and end with value * @param value value to fill array section with - * @param start index to start filling the array at. If start is negative, it is treated as - * length+start where length is the length of the array. - * @param end index to stop filling the array at. If end is negative, it is treated as + * @param start index to start filling the array at. If start is negative, it is treated as + * length+start where length is the length of the array. + * @param end index to stop filling the array at. If end is negative, it is treated as * length+end. */ fill(value: number, start?: number, end?: number): Float64Array; /** - * Returns the elements of an array that meet the condition specified in a callback function. - * @param callbackfn A function that accepts up to three arguments. The filter method calls - * the callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * Returns the elements of an array that meet the condition specified in a callback function. + * @param callbackfn A function that accepts up to three arguments. The filter method calls + * the callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ filter(callbackfn: (value: number, index: number, array: Float64Array) => boolean, thisArg?: any): Float64Array; - /** - * Returns the value of the first element in the array where predicate is true, and undefined + /** + * Returns the value of the first element in the array where predicate is true, and undefined * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find + * @param predicate find calls predicate once for each element of the array, in ascending + * order, until it finds one where predicate returns true. If such an element is found, find * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of + * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ find(predicate: (value: number, index: number, obj: Array) => boolean, thisArg?: any): number; - /** - * Returns the index of the first element in the array where predicate is true, and undefined + /** + * Returns the index of the first element in the array where predicate is true, and undefined * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find + * @param predicate find calls predicate once for each element of the array, in ascending + * order, until it finds one where predicate returns true. If such an element is found, find * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of + * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ findIndex(predicate: (value: number) => boolean, thisArg?: any): number; /** * Performs the specified action for each element in an array. - * @param callbackfn A function that accepts up to three arguments. forEach calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param callbackfn A function that accepts up to three arguments. forEach calls the + * callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ forEach(callbackfn: (value: number, index: number, array: Float64Array) => void, thisArg?: any): void; @@ -3672,7 +3684,7 @@ interface Float64Array { /** * Adds all the elements of an array separated by the specified separator string. - * @param separator A string used to separate one element of an array from the next in the + * @param separator A string used to separate one element of an array from the next in the * resulting String. If omitted, the array elements are separated with a comma. */ join(separator?: string): string; @@ -3680,7 +3692,7 @@ interface Float64Array { /** * Returns the index of the last occurrence of a value in an array. * @param searchElement The value to locate in the array. - * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the + * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the * search starts at index 0. */ lastIndexOf(searchElement: number, fromIndex?: number): number; @@ -3691,65 +3703,65 @@ interface Float64Array { length: number; /** - * Calls a defined callback function on each element of an array, and returns an array that + * Calls a defined callback function on each element of an array, and returns an array that * contains the results. - * @param callbackfn A function that accepts up to three arguments. The map method calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param callbackfn A function that accepts up to three arguments. The map method calls the + * callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ map(callbackfn: (value: number, index: number, array: Float64Array) => number, thisArg?: any): Float64Array; /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next + * Calls the specified callback function for all the elements in an array. The return value of + * the callback function is the accumulated result, and is provided as an argument in the next * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the + * @param callbackfn A function that accepts up to four arguments. The reduce method calls the * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start + * @param initialValue If initialValue is specified, it is used as the initial value to start * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number, initialValue?: number): number; /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next + * Calls the specified callback function for all the elements in an array. The return value of + * the callback function is the accumulated result, and is provided as an argument in the next * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the + * @param callbackfn A function that accepts up to four arguments. The reduce method calls the * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduce(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float64Array) => U, initialValue: U): U; - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an + /** + * Calls the specified callback function for all the elements in an array, in descending order. + * The return value of the callback function is the accumulated result, and is provided as an * argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an + * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls + * the callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an * argument instead of an array value. */ reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number, initialValue?: number): number; - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an + /** + * Calls the specified callback function for all the elements in an array, in descending order. + * The return value of the callback function is the accumulated result, and is provided as an * argument in the next call to the callback function. * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start + * the callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ reduceRight(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float64Array) => U, initialValue: U): U; /** - * Reverses the elements in an Array. + * Reverses the elements in an Array. */ reverse(): Float64Array; @@ -3767,7 +3779,7 @@ interface Float64Array { */ set(array: ArrayLike, offset?: number): void; - /** + /** * Returns a section of an array. * @param start The beginning of the specified portion of the array. * @param end The end of the specified portion of the array. @@ -3776,31 +3788,31 @@ interface Float64Array { /** * Determines whether the specified callback function returns true for any element of an array. - * @param callbackfn A function that accepts up to three arguments. The some method calls the - * callbackfn function for each element in array1 until the callbackfn returns true, or until + * @param callbackfn A function that accepts up to three arguments. The some method calls the + * callbackfn function for each element in array1 until the callbackfn returns true, or until * the end of the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ some(callbackfn: (value: number, index: number, array: Float64Array) => boolean, thisArg?: any): boolean; /** * Sorts an array. - * @param compareFn The name of the function used to determine the order of the elements. If + * @param compareFn The name of the function used to determine the order of the elements. If * omitted, the elements are sorted in ascending, ASCII character order. */ sort(compareFn?: (a: number, b: number) => number): Float64Array; /** * Gets a new Float64Array view of the ArrayBuffer store for this array, referencing the elements - * at begin, inclusive, up to end, exclusive. + * at begin, inclusive, up to end, exclusive. * @param begin The index of the beginning of the array. * @param end The index of the end of the array. */ subarray(begin: number, end?: number): Float64Array; /** - * Converts a number to a string by using the current locale. + * Converts a number to a string by using the current locale. */ toLocaleString(): string; @@ -3819,7 +3831,7 @@ interface Float64ArrayConstructor { new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Float64Array; /** - * The size in bytes of each element in the array. + * The size in bytes of each element in the array. */ BYTES_PER_ELEMENT: number; @@ -3828,7 +3840,7 @@ interface Float64ArrayConstructor { * @param items A set of elements to include in the new array object. */ of(...items: number[]): Float64Array; - + /** * Creates an array from an array-like or iterable object. * @param arrayLike An array-like or iterable object to convert to an array. @@ -3839,7 +3851,7 @@ interface Float64ArrayConstructor { } declare var Float64Array: Float64ArrayConstructor; ///////////////////////////// -/// ECMAScript Internationalization API +/// ECMAScript Internationalization API ///////////////////////////// declare module Intl { @@ -3982,14 +3994,14 @@ interface String { interface Number { /** - * Converts a number to a string by using the current or specified locale. + * Converts a number to a string by using the current or specified locale. * @param locales An array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used. * @param options An object that contains one or more properties that specify comparison options. */ toLocaleString(locales?: string[], options?: Intl.NumberFormatOptions): string; /** - * Converts a number to a string by using the current or specified locale. + * Converts a number to a string by using the current or specified locale. * @param locale Locale tag. If you omit this parameter, the default locale of the JavaScript runtime is used. * @param options An object that contains one or more properties that specify comparison options. */ @@ -3998,41 +4010,41 @@ interface Number { interface Date { /** - * Converts a date and time to a string by using the current or specified locale. + * Converts a date and time to a string by using the current or specified locale. * @param locales An array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used. * @param options An object that contains one or more properties that specify comparison options. */ toLocaleString(locales?: string[], options?: Intl.DateTimeFormatOptions): string; /** - * Converts a date to a string by using the current or specified locale. + * Converts a date to a string by using the current or specified locale. * @param locales An array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used. * @param options An object that contains one or more properties that specify comparison options. */ toLocaleDateString(locales?: string[], options?: Intl.DateTimeFormatOptions): string; /** - * Converts a time to a string by using the current or specified locale. + * Converts a time to a string by using the current or specified locale. * @param locale Locale tag. If you omit this parameter, the default locale of the JavaScript runtime is used. * @param options An object that contains one or more properties that specify comparison options. */ toLocaleTimeString(locale?: string[], options?: Intl.DateTimeFormatOptions): string; - + /** - * Converts a date and time to a string by using the current or specified locale. + * Converts a date and time to a string by using the current or specified locale. * @param locale Locale tag. If you omit this parameter, the default locale of the JavaScript runtime is used. * @param options An object that contains one or more properties that specify comparison options. */ toLocaleString(locale?: string, options?: Intl.DateTimeFormatOptions): string; - + /** - * Converts a date to a string by using the current or specified locale. + * Converts a date to a string by using the current or specified locale. * @param locale Locale tag. If you omit this parameter, the default locale of the JavaScript runtime is used. * @param options An object that contains one or more properties that specify comparison options. */ toLocaleDateString(locale?: string, options?: Intl.DateTimeFormatOptions): string; /** - * Converts a time to a string by using the current or specified locale. + * Converts a time to a string by using the current or specified locale. * @param locale Locale tag. If you omit this parameter, the default locale of the JavaScript runtime is used. * @param options An object that contains one or more properties that specify comparison options. */ @@ -5636,7 +5648,7 @@ declare var DeviceRotationRate: { interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEvent { /** - * Sets or gets the URL for the current document. + * Sets or gets the URL for the current document. */ URL: string; /** @@ -5664,7 +5676,7 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven */ applets: HTMLCollection; /** - * Deprecated. Sets or retrieves a value that indicates the background color behind the object. + * Deprecated. Sets or retrieves a value that indicates the background color behind the object. */ bgColor: string; /** @@ -5691,19 +5703,19 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven */ designMode: string; /** - * Sets or retrieves a value that indicates the reading order of the object. + * Sets or retrieves a value that indicates the reading order of the object. */ dir: string; /** - * Gets an object representing the document type declaration associated with the current document. + * Gets an object representing the document type declaration associated with the current document. */ doctype: DocumentType; /** - * Gets a reference to the root node of the document. + * Gets a reference to the root node of the document. */ documentElement: HTMLElement; /** - * Sets or gets the security domain of the document. + * Sets or gets the security domain of the document. */ domain: string; /** @@ -5727,7 +5739,7 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven */ images: HTMLCollection; /** - * Gets the implementation object of the current document. + * Gets the implementation object of the current document. */ implementation: DOMImplementation; /** @@ -5735,11 +5747,11 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven */ inputEncoding: string; /** - * Gets the date that the page was last modified, if the page supplies one. + * Gets the date that the page was last modified, if the page supplies one. */ lastModified: string; /** - * Sets or gets the color of the document links. + * Sets or gets the color of the document links. */ linkColor: string; /** @@ -5747,7 +5759,7 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven */ links: HTMLCollection; /** - * Contains information about the current URL. + * Contains information about the current URL. */ location: Location; media: string; @@ -5775,19 +5787,19 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven * @param ev The event. */ onbeforedeactivate: (ev: UIEvent) => any; - /** - * Fires when the object loses the input focus. + /** + * Fires when the object loses the input focus. * @param ev The focus event. */ onblur: (ev: FocusEvent) => any; /** - * Occurs when playback is possible, but would require further buffering. + * Occurs when playback is possible, but would require further buffering. * @param ev The event. */ oncanplay: (ev: Event) => any; oncanplaythrough: (ev: Event) => any; /** - * Fires when the contents of the object or selection have changed. + * Fires when the contents of the object or selection have changed. * @param ev The event. */ onchange: (ev: Event) => any; @@ -5797,7 +5809,7 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven */ onclick: (ev: MouseEvent) => any; /** - * Fires when the user clicks the right mouse button in the client area, opening the context menu. + * Fires when the user clicks the right mouse button in the client area, opening the context menu. * @param ev The mouse event. */ oncontextmenu: (ev: PointerEvent) => any; @@ -5821,12 +5833,12 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven * @param ev The event. */ ondragend: (ev: DragEvent) => any; - /** + /** * Fires on the target element when the user drags the object to a valid drop target. * @param ev The drag event. */ ondragenter: (ev: DragEvent) => any; - /** + /** * Fires on the target object when the user moves the mouse out of a valid drop target during a drag operation. * @param ev The drag event. */ @@ -5837,23 +5849,23 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven */ ondragover: (ev: DragEvent) => any; /** - * Fires on the source object when the user starts to drag a text selection or selected object. + * Fires on the source object when the user starts to drag a text selection or selected object. * @param ev The event. */ ondragstart: (ev: DragEvent) => any; ondrop: (ev: DragEvent) => any; /** - * Occurs when the duration attribute is updated. + * Occurs when the duration attribute is updated. * @param ev The event. */ ondurationchange: (ev: Event) => any; /** - * Occurs when the media element is reset to its initial state. + * Occurs when the media element is reset to its initial state. * @param ev The event. */ onemptied: (ev: Event) => any; /** - * Occurs when the end of playback is reached. + * Occurs when the end of playback is reached. * @param ev The event */ onended: (ev: Event) => any; @@ -5863,7 +5875,7 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven */ onerror: (ev: Event) => any; /** - * Fires when the object receives focus. + * Fires when the object receives focus. * @param ev The event. */ onfocus: (ev: FocusEvent) => any; @@ -5886,12 +5898,12 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven */ onkeyup: (ev: KeyboardEvent) => any; /** - * Fires immediately after the browser loads the object. + * Fires immediately after the browser loads the object. * @param ev The event. */ onload: (ev: Event) => any; /** - * Occurs when media data is loaded at the current playback position. + * Occurs when media data is loaded at the current playback position. * @param ev The event. */ onloadeddata: (ev: Event) => any; @@ -5901,22 +5913,22 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven */ onloadedmetadata: (ev: Event) => any; /** - * Occurs when Internet Explorer begins looking for media data. + * Occurs when Internet Explorer begins looking for media data. * @param ev The event. */ onloadstart: (ev: Event) => any; /** - * Fires when the user clicks the object with either mouse button. + * Fires when the user clicks the object with either mouse button. * @param ev The mouse event. */ onmousedown: (ev: MouseEvent) => any; /** - * Fires when the user moves the mouse over the object. + * Fires when the user moves the mouse over the object. * @param ev The mouse event. */ onmousemove: (ev: MouseEvent) => any; /** - * Fires when the user moves the mouse pointer outside the boundaries of the object. + * Fires when the user moves the mouse pointer outside the boundaries of the object. * @param ev The mouse event. */ onmouseout: (ev: MouseEvent) => any; @@ -5926,12 +5938,12 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven */ onmouseover: (ev: MouseEvent) => any; /** - * Fires when the user releases a mouse button while the mouse is over the object. + * Fires when the user releases a mouse button while the mouse is over the object. * @param ev The mouse event. */ onmouseup: (ev: MouseEvent) => any; /** - * Fires when the wheel button is rotated. + * Fires when the wheel button is rotated. * @param ev The mouse event */ onmousewheel: (ev: MouseWheelEvent) => any; @@ -5953,7 +5965,7 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven onmspointerover: (ev: MSPointerEvent) => any; onmspointerup: (ev: MSPointerEvent) => any; /** - * Occurs when an item is removed from a Jump List of a webpage running in Site Mode. + * Occurs when an item is removed from a Jump List of a webpage running in Site Mode. * @param ev The event. */ onmssitemodejumplistitemremoved: (ev: MSSiteModeEvent) => any; @@ -5968,24 +5980,24 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven */ onpause: (ev: Event) => any; /** - * Occurs when the play method is requested. + * Occurs when the play method is requested. * @param ev The event. */ onplay: (ev: Event) => any; /** - * Occurs when the audio or video has started playing. + * Occurs when the audio or video has started playing. * @param ev The event. */ onplaying: (ev: Event) => any; onpointerlockchange: (ev: Event) => any; onpointerlockerror: (ev: Event) => any; /** - * Occurs to indicate progress while downloading media data. + * Occurs to indicate progress while downloading media data. * @param ev The event. */ onprogress: (ev: ProgressEvent) => any; /** - * Occurs when the playback rate is increased or decreased. + * Occurs when the playback rate is increased or decreased. * @param ev The event. */ onratechange: (ev: Event) => any; @@ -5995,22 +6007,22 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven */ onreadystatechange: (ev: ProgressEvent) => any; /** - * Fires when the user resets a form. + * Fires when the user resets a form. * @param ev The event. */ onreset: (ev: Event) => any; /** - * Fires when the user repositions the scroll box in the scroll bar on the object. + * Fires when the user repositions the scroll box in the scroll bar on the object. * @param ev The event. */ onscroll: (ev: UIEvent) => any; /** - * Occurs when the seek operation ends. + * Occurs when the seek operation ends. * @param ev The event. */ onseeked: (ev: Event) => any; /** - * Occurs when the current playback position is moved. + * Occurs when the current playback position is moved. * @param ev The event. */ onseeking: (ev: Event) => any; @@ -6021,7 +6033,7 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven onselect: (ev: UIEvent) => any; onselectstart: (ev: Event) => any; /** - * Occurs when the download has stopped. + * Occurs when the download has stopped. * @param ev The event. */ onstalled: (ev: Event) => any; @@ -6032,7 +6044,7 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven onstop: (ev: Event) => any; onsubmit: (ev: Event) => any; /** - * Occurs if the load operation has been intentionally halted. + * Occurs if the load operation has been intentionally halted. * @param ev The event. */ onsuspend: (ev: Event) => any; @@ -6051,7 +6063,7 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven */ onvolumechange: (ev: Event) => any; /** - * Occurs when playback stops because the next frame of a video resource is not available. + * Occurs when playback stops because the next frame of a video resource is not available. * @param ev The event. */ onwaiting: (ev: Event) => any; @@ -6085,7 +6097,7 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven */ title: string; visibilityState: string; - /** + /** * Sets or gets the color of the links that the user has visited. */ vlinkColor: string; @@ -6300,7 +6312,7 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven createExpression(expression: string, resolver: XPathNSResolver): XPathExpression; createNSResolver(nodeResolver: Node): XPathNSResolver; /** - * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document. + * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document. * @param root The root element or node to start traversing on. * @param whatToShow The type of nodes or elements to appear in the node list * @param filter A custom NodeFilter function to use. For more information, see filter. Use null for no filter. @@ -6309,11 +6321,11 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven createNodeIterator(root: Node, whatToShow?: number, filter?: NodeFilter, entityReferenceExpansion?: boolean): NodeIterator; createProcessingInstruction(target: string, data: string): ProcessingInstruction; /** - * Returns an empty range object that has both of its boundary points positioned at the beginning of the document. + * Returns an empty range object that has both of its boundary points positioned at the beginning of the document. */ createRange(): Range; /** - * Creates a text string from the specified value. + * Creates a text string from the specified value. * @param data String that specifies the nodeValue property of the text node. */ createTextNode(data: string): Text; @@ -6328,7 +6340,7 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven */ createTreeWalker(root: Node, whatToShow?: number, filter?: NodeFilter, entityReferenceExpansion?: boolean): TreeWalker; /** - * Returns the element for the specified x coordinate and the specified y coordinate. + * Returns the element for the specified x coordinate and the specified y coordinate. * @param x The x-offset * @param y The y-offset */ @@ -6561,7 +6573,7 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven * @param replace Specifies whether the existing entry for the document is replaced in the history list. */ open(url?: string, name?: string, features?: string, replace?: boolean): Document; - /** + /** * Returns a Boolean value that indicates whether a specified command can be successfully executed using execCommand, given the current state of the document. * @param commandId Specifies a command identifier. */ @@ -6583,7 +6595,7 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven queryCommandSupported(commandId: string): boolean; /** * Retrieves the string associated with a command. - * @param commandId String that contains the identifier of a command. This can be any command identifier given in the list of Command Identifiers. + * @param commandId String that contains the identifier of a command. This can be any command identifier given in the list of Command Identifiers. */ queryCommandText(commandId: string): string; /** @@ -6599,12 +6611,12 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven webkitCancelFullScreen(): void; webkitExitFullscreen(): void; /** - * Writes one or more HTML expressions to a document in the specified window. + * Writes one or more HTML expressions to a document in the specified window. * @param content Specifies the text and HTML tags to write. */ write(...content: string[]): void; /** - * Writes one or more HTML expressions, followed by a carriage return, to a document in the specified window. + * Writes one or more HTML expressions, followed by a carriage return, to a document in the specified window. * @param content The text and HTML tags to write. */ writeln(...content: string[]): void; @@ -7312,12 +7324,12 @@ interface HTMLAnchorElement extends HTMLElement { */ target: string; /** - * Retrieves or sets the text of the object as a string. + * Retrieves or sets the text of the object as a string. */ text: string; type: string; urn: string; - /** + /** * Returns a string representation of an object. */ toString(): string; @@ -7418,7 +7430,7 @@ interface HTMLAreaElement extends HTMLElement { */ host: string; /** - * Sets or retrieves the host name part of the location or URL. + * Sets or retrieves the host name part of the location or URL. */ hostname: string; /** @@ -7454,7 +7466,7 @@ interface HTMLAreaElement extends HTMLElement { * Sets or retrieves the window or frame at which to target content. */ target: string; - /** + /** * Returns a string representation of an object. */ toString(): string; @@ -7737,7 +7749,7 @@ interface HTMLButtonElement extends HTMLElement { * Overrides the target attribute on a form element. */ formTarget: string; - /** + /** * Sets or retrieves the name of the object. */ name: string; @@ -7754,7 +7766,7 @@ interface HTMLButtonElement extends HTMLElement { * Returns a ValidityState object that represents the validity states of an element. */ validity: ValidityState; - /** + /** * Sets or retrieves the default or selected value of the control. */ value: string; @@ -7888,7 +7900,7 @@ declare var HTMLDirectoryElement: { interface HTMLDivElement extends HTMLElement { /** - * Sets or retrieves how the object is aligned with adjacent text. + * Sets or retrieves how the object is aligned with adjacent text. */ align: string; /** @@ -9034,7 +9046,7 @@ interface HTMLInputElement extends HTMLElement { */ files: FileList; /** - * Retrieves a reference to the form that the object is embedded in. + * Retrieves a reference to the form that the object is embedded in. */ form: HTMLFormElement; /** @@ -9204,7 +9216,7 @@ interface HTMLIsIndexElement extends HTMLElement { */ action: string; /** - * Retrieves a reference to the form that the object is embedded in. + * Retrieves a reference to the form that the object is embedded in. */ form: HTMLFormElement; prompt: string; @@ -9763,7 +9775,7 @@ interface HTMLMetaElement extends HTMLElement { */ scheme: string; /** - * Sets or retrieves the URL property that will be loaded after the specified time has elapsed. + * Sets or retrieves the URL property that will be loaded after the specified time has elapsed. */ url: string; } @@ -10009,7 +10021,7 @@ declare var HTMLOptionElement: { interface HTMLParagraphElement extends HTMLElement { /** - * Sets or retrieves how the object is aligned with adjacent text. + * Sets or retrieves how the object is aligned with adjacent text. */ align: string; clear: string; @@ -10128,10 +10140,10 @@ interface HTMLScriptElement extends HTMLElement { */ defer: boolean; /** - * Sets or retrieves the event for which the script is written. + * Sets or retrieves the event for which the script is written. */ event: string; - /** + /** * Sets or retrieves the object that is bound to the event script. */ htmlFor: string; @@ -10140,7 +10152,7 @@ interface HTMLScriptElement extends HTMLElement { */ src: string; /** - * Retrieves or sets the text of the object as a string. + * Retrieves or sets the text of the object as a string. */ text: string; /** @@ -10161,7 +10173,7 @@ interface HTMLSelectElement extends HTMLElement { autofocus: boolean; disabled: boolean; /** - * Retrieves a reference to the form that the object is embedded in. + * Retrieves a reference to the form that the object is embedded in. */ form: HTMLFormElement; /** @@ -10186,7 +10198,7 @@ interface HTMLSelectElement extends HTMLElement { */ selectedIndex: number; /** - * Sets or retrieves the number of rows in the list box. + * Sets or retrieves the number of rows in the list box. */ size: number; /** @@ -10212,7 +10224,7 @@ interface HTMLSelectElement extends HTMLElement { /** * Adds an element to the areas, controlRange, or options collection. * @param element Variant of type Number that specifies the index position in the collection where the element is placed. If no value is given, the method places the element at the end of the collection. - * @param before Variant of type Object that specifies an element to insert before, or null to append the object to the collection. + * @param before Variant of type Object that specifies an element to insert before, or null to append the object to the collection. */ add(element: HTMLElement, before?: HTMLElement | number): void; /** @@ -10404,7 +10416,7 @@ interface HTMLTableElement extends HTMLElement { */ border: string; /** - * Sets or retrieves the border color of the object. + * Sets or retrieves the border color of the object. */ borderColor: any; /** @@ -10693,7 +10705,7 @@ declare var HTMLTextAreaElement: { interface HTMLTitleElement extends HTMLElement { /** - * Retrieves or sets the text of the object as a string. + * Retrieves or sets the text of the object as a string. */ text: string; } @@ -16980,9 +16992,9 @@ declare function addEventListener(type: "waiting", listener: (ev: Event) => any, declare function addEventListener(type: "wheel", listener: (ev: WheelEvent) => any, useCapture?: boolean): void; declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; ///////////////////////////// -/// WorkerGlobalScope APIs +/// WorkerGlobalScope APIs ///////////////////////////// -// These are only available in a Web Worker +// These are only available in a Web Worker declare function importScripts(...urls: string[]): void; @@ -17015,7 +17027,7 @@ interface TextStreamBase { /** * Closes a text stream. - * It is not necessary to close standard streams; they close automatically when the process ends. If + * It is not necessary to close standard streams; they close automatically when the process ends. If * you close a standard stream, be aware that any other pointers to that standard stream become invalid. */ Close(): void;