From 28c4b8acbabb6c2368897e79ce64a8ab5af8a2ea Mon Sep 17 00:00:00 2001 From: Ricardo N Feliciano Date: Wed, 7 Feb 2018 12:36:56 -0800 Subject: [PATCH 01/28] Try out CircleCI. --- .circleci/config.yml | 58 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000000..c0e51dfd5d8 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,58 @@ +workflows: + version: 2 + main: + jobs: + - node9: + filters: + branches: + only: + - master + - release-2.5 + - release-2.6 + - release-2.7 + - circleci + - node8: + filters: + branches: + only: + - master + - release-2.5 + - release-2.6 + - release-2.7 + - circleci + - node6: + filters: + branches: + only: + - master + - release-2.5 + - release-2.6 + - release-2.7 + - circleci + +base: &base + environment: + - workerCount: 3 + steps: + - checkout + - run: | + npm uninstall typescript --no-save + npm uninstall tslint --no-save + npm install + #npm update Appeared in Jenkins only + npm test + +version: 2 +jobs: + node9: + docker: + - image: circleci/node:9 + <<: *base + node8: + docker: + - image: circleci/node:8 + <<: *base + node6: + docker: + - image: circleci/node:6 + <<: *base From 655980db414c0342bbf63864c09316aab0ccb42b Mon Sep 17 00:00:00 2001 From: Ricardo N Feliciano Date: Thu, 8 Feb 2018 12:18:38 -0800 Subject: [PATCH 02/28] Add Scheduled Workflows/Cron. --- .circleci/config.yml | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c0e51dfd5d8..96873cf5f43 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -29,10 +29,48 @@ workflows: - release-2.6 - release-2.7 - circleci + nightly: + triggers: + - schedule: + cron: "0 8 * * *" + filters: + branches: + only: master + jobs: + - node9: + filters: + branches: + only: + - master + - release-2.5 + - release-2.6 + - release-2.7 + - circleci + context: nightlies + - node8: + filters: + branches: + only: + - master + - release-2.5 + - release-2.6 + - release-2.7 + - circleci + context: nightlies + - node6: + filters: + branches: + only: + - master + - release-2.5 + - release-2.6 + - release-2.7 + - circleci + context: nightlies base: &base environment: - - workerCount: 3 + - workerCount: 4 steps: - checkout - run: | From 3a61f638ba9f7f5923b5a7c1614a05de5ec40ffa Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 14 Feb 2018 09:19:47 -0800 Subject: [PATCH 03/28] Instantiation of 'keyof T' for wildcard type produces wildcard type --- src/compiler/checker.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 75ab23407b3..8b6f464d5ed 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7948,6 +7948,7 @@ namespace ts { function getIndexType(type: Type): Type { return maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(type) : getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(type) : + type === wildcardType ? wildcardType : type.flags & TypeFlags.Any || getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromPropertyNames(type); } From 3de1cd6f2de644d0e3723935479ad06df62ff822 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 14 Feb 2018 09:20:13 -0800 Subject: [PATCH 04/28] Add regression tests --- .../types/conditional/conditionalTypes1.ts | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/cases/conformance/types/conditional/conditionalTypes1.ts b/tests/cases/conformance/types/conditional/conditionalTypes1.ts index 94a802a0ffc..9449cc6d766 100644 --- a/tests/cases/conformance/types/conditional/conditionalTypes1.ts +++ b/tests/cases/conformance/types/conditional/conditionalTypes1.ts @@ -287,3 +287,33 @@ function f50() { type A = Omit<{ a: void; b: never; }>; // 'a' type B = Omit2<{ a: void; b: never; }>; // 'a' } + +// Repro from #21862 + +type OldDiff = ( + & { [P in T]: P; } + & { [P in U]: never; } + & { [x: string]: never; } +)[T]; +type NewDiff = T extends U ? never : T; +interface A { + a: 'a'; +} +interface B1 extends A { + b: 'b'; + c: OldDiff; +} +interface B2 extends A { + b: 'b'; + c: NewDiff; +} +type c1 = B1['c']; // 'c' | 'b' +type c2 = B2['c']; // 'c' | 'b' + +// Repro from #21929 + +type NonFooKeys1 = OldDiff; +type NonFooKeys2 = Exclude; + +type Test1 = NonFooKeys1<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz" +type Test2 = NonFooKeys2<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz" From 9b227fc520674b8794f623dfa24578a0c94fd35a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 14 Feb 2018 09:20:21 -0800 Subject: [PATCH 05/28] Accept new baselines --- .../reference/conditionalTypes1.errors.txt | 30 ++++++ .../baselines/reference/conditionalTypes1.js | 63 ++++++++++++ .../reference/conditionalTypes1.symbols | 96 +++++++++++++++++++ .../reference/conditionalTypes1.types | 96 +++++++++++++++++++ 4 files changed, 285 insertions(+) diff --git a/tests/baselines/reference/conditionalTypes1.errors.txt b/tests/baselines/reference/conditionalTypes1.errors.txt index 869e740ad1a..72d88b60d64 100644 --- a/tests/baselines/reference/conditionalTypes1.errors.txt +++ b/tests/baselines/reference/conditionalTypes1.errors.txt @@ -447,4 +447,34 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(275,43): error TS type A = Omit<{ a: void; b: never; }>; // 'a' type B = Omit2<{ a: void; b: never; }>; // 'a' } + + // Repro from #21862 + + type OldDiff = ( + & { [P in T]: P; } + & { [P in U]: never; } + & { [x: string]: never; } + )[T]; + type NewDiff = T extends U ? never : T; + interface A { + a: 'a'; + } + interface B1 extends A { + b: 'b'; + c: OldDiff; + } + interface B2 extends A { + b: 'b'; + c: NewDiff; + } + type c1 = B1['c']; // 'c' | 'b' + type c2 = B2['c']; // 'c' | 'b' + + // Repro from #21929 + + type NonFooKeys1 = OldDiff; + type NonFooKeys2 = Exclude; + + type Test1 = NonFooKeys1<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz" + type Test2 = NonFooKeys2<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz" \ No newline at end of file diff --git a/tests/baselines/reference/conditionalTypes1.js b/tests/baselines/reference/conditionalTypes1.js index 9020774d7fe..c7ad450f712 100644 --- a/tests/baselines/reference/conditionalTypes1.js +++ b/tests/baselines/reference/conditionalTypes1.js @@ -285,6 +285,36 @@ function f50() { type A = Omit<{ a: void; b: never; }>; // 'a' type B = Omit2<{ a: void; b: never; }>; // 'a' } + +// Repro from #21862 + +type OldDiff = ( + & { [P in T]: P; } + & { [P in U]: never; } + & { [x: string]: never; } +)[T]; +type NewDiff = T extends U ? never : T; +interface A { + a: 'a'; +} +interface B1 extends A { + b: 'b'; + c: OldDiff; +} +interface B2 extends A { + b: 'b'; + c: NewDiff; +} +type c1 = B1['c']; // 'c' | 'b' +type c2 = B2['c']; // 'c' | 'b' + +// Repro from #21929 + +type NonFooKeys1 = OldDiff; +type NonFooKeys2 = Exclude; + +type Test1 = NonFooKeys1<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz" +type Test2 = NonFooKeys2<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz" //// [conditionalTypes1.js] @@ -561,3 +591,36 @@ declare type T95 = T extends string ? boolean : number; declare const f44: (value: T94) => T95; declare const f45: (value: T95) => T94; declare function f50(): void; +declare type OldDiff = ({ + [P in T]: P; +} & { + [P in U]: never; +} & { + [x: string]: never; +})[T]; +declare type NewDiff = T extends U ? never : T; +interface A { + a: 'a'; +} +interface B1 extends A { + b: 'b'; + c: OldDiff; +} +interface B2 extends A { + b: 'b'; + c: NewDiff; +} +declare type c1 = B1['c']; +declare type c2 = B2['c']; +declare type NonFooKeys1 = OldDiff; +declare type NonFooKeys2 = Exclude; +declare type Test1 = NonFooKeys1<{ + foo: 1; + bar: 2; + baz: 3; +}>; +declare type Test2 = NonFooKeys2<{ + foo: 1; + bar: 2; + baz: 3; +}>; diff --git a/tests/baselines/reference/conditionalTypes1.symbols b/tests/baselines/reference/conditionalTypes1.symbols index 6c05ee1eeee..8802f25b1a8 100644 --- a/tests/baselines/reference/conditionalTypes1.symbols +++ b/tests/baselines/reference/conditionalTypes1.symbols @@ -1121,3 +1121,99 @@ function f50() { >b : Symbol(b, Decl(conditionalTypes1.ts, 284, 29)) } +// Repro from #21862 + +type OldDiff = ( +>OldDiff : Symbol(OldDiff, Decl(conditionalTypes1.ts, 285, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 289, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 289, 30)) + + & { [P in T]: P; } +>P : Symbol(P, Decl(conditionalTypes1.ts, 290, 9)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 289, 13)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 290, 9)) + + & { [P in U]: never; } +>P : Symbol(P, Decl(conditionalTypes1.ts, 291, 9)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 289, 30)) + + & { [x: string]: never; } +>x : Symbol(x, Decl(conditionalTypes1.ts, 292, 9)) + +)[T]; +>T : Symbol(T, Decl(conditionalTypes1.ts, 289, 13)) + +type NewDiff = T extends U ? never : T; +>NewDiff : Symbol(NewDiff, Decl(conditionalTypes1.ts, 293, 5)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 294, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 294, 15)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 294, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 294, 15)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 294, 13)) + +interface A { +>A : Symbol(A, Decl(conditionalTypes1.ts, 294, 45)) + + a: 'a'; +>a : Symbol(A.a, Decl(conditionalTypes1.ts, 295, 13)) +} +interface B1 extends A { +>B1 : Symbol(B1, Decl(conditionalTypes1.ts, 297, 1)) +>A : Symbol(A, Decl(conditionalTypes1.ts, 294, 45)) + + b: 'b'; +>b : Symbol(B1.b, Decl(conditionalTypes1.ts, 298, 24)) + + c: OldDiff; +>c : Symbol(B1.c, Decl(conditionalTypes1.ts, 299, 11)) +>OldDiff : Symbol(OldDiff, Decl(conditionalTypes1.ts, 285, 1)) +>A : Symbol(A, Decl(conditionalTypes1.ts, 294, 45)) +} +interface B2 extends A { +>B2 : Symbol(B2, Decl(conditionalTypes1.ts, 301, 1)) +>A : Symbol(A, Decl(conditionalTypes1.ts, 294, 45)) + + b: 'b'; +>b : Symbol(B2.b, Decl(conditionalTypes1.ts, 302, 24)) + + c: NewDiff; +>c : Symbol(B2.c, Decl(conditionalTypes1.ts, 303, 11)) +>NewDiff : Symbol(NewDiff, Decl(conditionalTypes1.ts, 293, 5)) +>A : Symbol(A, Decl(conditionalTypes1.ts, 294, 45)) +} +type c1 = B1['c']; // 'c' | 'b' +>c1 : Symbol(c1, Decl(conditionalTypes1.ts, 305, 1)) +>B1 : Symbol(B1, Decl(conditionalTypes1.ts, 297, 1)) + +type c2 = B2['c']; // 'c' | 'b' +>c2 : Symbol(c2, Decl(conditionalTypes1.ts, 306, 18)) +>B2 : Symbol(B2, Decl(conditionalTypes1.ts, 301, 1)) + +// Repro from #21929 + +type NonFooKeys1 = OldDiff; +>NonFooKeys1 : Symbol(NonFooKeys1, Decl(conditionalTypes1.ts, 307, 18)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 311, 17)) +>OldDiff : Symbol(OldDiff, Decl(conditionalTypes1.ts, 285, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 311, 17)) + +type NonFooKeys2 = Exclude; +>NonFooKeys2 : Symbol(NonFooKeys2, Decl(conditionalTypes1.ts, 311, 61)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 312, 17)) +>Exclude : Symbol(Exclude, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 312, 17)) + +type Test1 = NonFooKeys1<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz" +>Test1 : Symbol(Test1, Decl(conditionalTypes1.ts, 312, 61)) +>NonFooKeys1 : Symbol(NonFooKeys1, Decl(conditionalTypes1.ts, 307, 18)) +>foo : Symbol(foo, Decl(conditionalTypes1.ts, 314, 26)) +>bar : Symbol(bar, Decl(conditionalTypes1.ts, 314, 33)) +>baz : Symbol(baz, Decl(conditionalTypes1.ts, 314, 41)) + +type Test2 = NonFooKeys2<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz" +>Test2 : Symbol(Test2, Decl(conditionalTypes1.ts, 314, 51)) +>NonFooKeys2 : Symbol(NonFooKeys2, Decl(conditionalTypes1.ts, 311, 61)) +>foo : Symbol(foo, Decl(conditionalTypes1.ts, 315, 26)) +>bar : Symbol(bar, Decl(conditionalTypes1.ts, 315, 33)) +>baz : Symbol(baz, Decl(conditionalTypes1.ts, 315, 41)) + diff --git a/tests/baselines/reference/conditionalTypes1.types b/tests/baselines/reference/conditionalTypes1.types index b544acdf3e2..1eebf8ba833 100644 --- a/tests/baselines/reference/conditionalTypes1.types +++ b/tests/baselines/reference/conditionalTypes1.types @@ -1274,3 +1274,99 @@ function f50() { >b : never } +// Repro from #21862 + +type OldDiff = ( +>OldDiff : ({ [P in T]: P; } & { [P in U]: never; } & { [x: string]: never; })[T] +>T : T +>U : U + + & { [P in T]: P; } +>P : P +>T : T +>P : P + + & { [P in U]: never; } +>P : P +>U : U + + & { [x: string]: never; } +>x : string + +)[T]; +>T : T + +type NewDiff = T extends U ? never : T; +>NewDiff : NewDiff +>T : T +>U : U +>T : T +>U : U +>T : T + +interface A { +>A : A + + a: 'a'; +>a : "a" +} +interface B1 extends A { +>B1 : B1 +>A : A + + b: 'b'; +>b : "b" + + c: OldDiff; +>c : ({ [P in keyof this]: P; } & { a: never; } & { [x: string]: never; })[keyof this] +>OldDiff : ({ [P in T]: P; } & { [P in U]: never; } & { [x: string]: never; })[T] +>A : A +} +interface B2 extends A { +>B2 : B2 +>A : A + + b: 'b'; +>b : "b" + + c: NewDiff; +>c : NewDiff +>NewDiff : NewDiff +>A : A +} +type c1 = B1['c']; // 'c' | 'b' +>c1 : "b" | "c" +>B1 : B1 + +type c2 = B2['c']; // 'c' | 'b' +>c2 : "b" | "c" +>B2 : B2 + +// Repro from #21929 + +type NonFooKeys1 = OldDiff; +>NonFooKeys1 : ({ [P in keyof T]: P; } & { foo: never; } & { [x: string]: never; })[keyof T] +>T : T +>OldDiff : ({ [P in T]: P; } & { [P in U]: never; } & { [x: string]: never; })[T] +>T : T + +type NonFooKeys2 = Exclude; +>NonFooKeys2 : Exclude +>T : T +>Exclude : Exclude +>T : T + +type Test1 = NonFooKeys1<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz" +>Test1 : "bar" | "baz" +>NonFooKeys1 : ({ [P in keyof T]: P; } & { foo: never; } & { [x: string]: never; })[keyof T] +>foo : 1 +>bar : 2 +>baz : 3 + +type Test2 = NonFooKeys2<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz" +>Test2 : "bar" | "baz" +>NonFooKeys2 : Exclude +>foo : 1 +>bar : 2 +>baz : 3 + From 81df5313d75cd6d94eecf5a0b74f3eb734069a6c Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 15 Feb 2018 13:02:32 -0800 Subject: [PATCH 06/28] Simplify getOccurrencesAtPosition (#21977) --- src/services/services.ts | 47 ++++++++++------------------------------ 1 file changed, 11 insertions(+), 36 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index b8c086a67e7..5eb0f6a06ca 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1567,17 +1567,17 @@ namespace ts { /// References and Occurrences function getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[] { - let results = getOccurrencesAtPositionCore(fileName, position); - - if (results) { - const sourceFile = getCanonicalFileName(normalizeSlashes(fileName)); - - // Get occurrences only supports reporting occurrences for the file queried. So - // filter down to that list. - results = filter(results, r => getCanonicalFileName(ts.normalizeSlashes(r.fileName)) === sourceFile); - } - - return results; + const canonicalFileName = getCanonicalFileName(normalizeSlashes(fileName)); + return flatMap(getDocumentHighlights(fileName, position, [fileName]), entry => entry.highlightSpans.map(highlightSpan => { + Debug.assert(getCanonicalFileName(normalizeSlashes(entry.fileName)) === canonicalFileName); // Get occurrences only supports reporting occurrences for the file queried. + return { + fileName: entry.fileName, + textSpan: highlightSpan.textSpan, + isWriteAccess: highlightSpan.kind === HighlightSpanKind.writtenReference, + isDefinition: false, + isInString: highlightSpan.isInString, + }; + })); } function getDocumentHighlights(fileName: string, position: number, filesToSearch: ReadonlyArray): DocumentHighlights[] { @@ -1587,31 +1587,6 @@ namespace ts { return DocumentHighlights.getDocumentHighlights(program, cancellationToken, sourceFile, position, sourceFilesToSearch); } - function getOccurrencesAtPositionCore(fileName: string, position: number): ReferenceEntry[] { - return convertDocumentHighlights(getDocumentHighlights(fileName, position, [fileName])); - - function convertDocumentHighlights(documentHighlights: DocumentHighlights[]): ReferenceEntry[] { - if (!documentHighlights) { - return undefined; - } - - const result: ReferenceEntry[] = []; - for (const entry of documentHighlights) { - for (const highlightSpan of entry.highlightSpans) { - result.push({ - fileName: entry.fileName, - textSpan: highlightSpan.textSpan, - isWriteAccess: highlightSpan.kind === HighlightSpanKind.writtenReference, - isDefinition: false, - isInString: highlightSpan.isInString, - }); - } - } - - return result; - } - } - function findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[] { return getReferences(fileName, position, { findInStrings, findInComments, isForRename: true }); } From 347bff14a9dfac03bbad921514e71f3292af97e2 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 15 Feb 2018 13:02:45 -0800 Subject: [PATCH 07/28] textChanges: Simplify getChanges (#21971) * textChanges: Simplify getChanges * Return ReadonlyArray --- src/compiler/core.ts | 8 ++++++++ src/services/textChanges.ts | 30 +++++------------------------- 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 424380892c7..212fa86b366 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1438,6 +1438,14 @@ namespace ts { } } + export function group(values: ReadonlyArray, getGroupId: (value: T) => string): ReadonlyArray> { + const groupIdToGroup = createMultiMap(); + for (const value of values) { + groupIdToGroup.add(getGroupId(value), value); + } + return arrayFrom(groupIdToGroup.values()); + } + /** * Tests whether a value is an array. */ diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index d3f6cde8e8d..1469f61bf36 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -593,32 +593,12 @@ namespace ts.textChanges { public getChanges(): FileTextChanges[] { this.finishInsertNodeAtClassStart(); - - const changesPerFile = createMap(); - // group changes per file - for (const c of this.changes) { - let changesInFile = changesPerFile.get(c.sourceFile.path); - if (!changesInFile) { - changesPerFile.set(c.sourceFile.path, changesInFile = []); - } - changesInFile.push(c); - } - // convert changes - const fileChangesList: FileTextChanges[] = []; - changesPerFile.forEach(changesInFile => { + return group(this.changes, c => c.sourceFile.path).map(changesInFile => { const sourceFile = changesInFile[0].sourceFile; - const fileTextChanges: FileTextChanges = { fileName: sourceFile.fileName, textChanges: [] }; - for (const c of ChangeTracker.normalize(changesInFile)) { - fileTextChanges.textChanges.push(createTextChange(this.computeSpan(c, sourceFile), this.computeNewText(c, sourceFile))); - } - fileChangesList.push(fileTextChanges); + const textChanges = ChangeTracker.normalize(changesInFile).map(c => + createTextChange(createTextSpanFromRange(c.range), this.computeNewText(c, sourceFile))); + return { fileName: sourceFile.fileName, textChanges }; }); - - return fileChangesList; - } - - private computeSpan(change: Change, _sourceFile: SourceFile): TextSpan { - return createTextSpanFromRange(change.range); } private computeNewText(change: Change, sourceFile: SourceFile): string { @@ -675,7 +655,7 @@ namespace ts.textChanges { return applyFormatting(nonformattedText, sourceFile, initialIndentation, delta, this.formatContext); } - private static normalize(changes: Change[]): Change[] { + private static normalize(changes: ReadonlyArray): ReadonlyArray { // 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 f8f4bb8fdd01e848f9d3100a3fded7ad767b95ee Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 15 Feb 2018 13:02:56 -0800 Subject: [PATCH 08/28] textChanges: Clean up handling of newLineCharacter (#21970) --- src/harness/unittests/textChanges.ts | 2 +- src/services/textChanges.ts | 16 +++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/harness/unittests/textChanges.ts b/src/harness/unittests/textChanges.ts index 934da4e3ba1..0a3602ea0b1 100644 --- a/src/harness/unittests/textChanges.ts +++ b/src/harness/unittests/textChanges.ts @@ -57,7 +57,7 @@ namespace ts { Harness.Baseline.runBaseline(`textChanges/${caption}.js`, () => { const sourceFile = createSourceFile("source.ts", text, ScriptTarget.ES2015, /*setParentNodes*/ true); const rulesProvider = getRuleProvider(placeOpenBraceOnNewLineForFunctions); - const changeTracker = new textChanges.ChangeTracker(printerOptions.newLine, rulesProvider, validateNodes ? verifyPositions : undefined); + const changeTracker = new textChanges.ChangeTracker(newLineCharacter, rulesProvider, validateNodes ? verifyPositions : undefined); testBlock(sourceFile, changeTracker); const changes = changeTracker.getChanges(); assert.equal(changes.length, 1); diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 1469f61bf36..04a20bbbbb8 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -197,13 +197,12 @@ namespace ts.textChanges { export class ChangeTracker { private readonly changes: Change[] = []; - private readonly newLineCharacter: string; private readonly deletedNodesInLists: true[] = []; // Stores ids of nodes in lists that we already deleted. Used to avoid deleting `, ` twice in `a, b`. // Map from class id to nodes to insert at the start private readonly nodesInsertedAtClassStarts = createMap<{ sourceFile: SourceFile, cls: ClassLikeDeclaration, members: ClassElement[] }>(); public static fromContext(context: TextChangesContext): ChangeTracker { - return new ChangeTracker(getNewLineOrDefaultFromHost(context.host, context.formatContext.options) === "\n" ? NewLineKind.LineFeed : NewLineKind.CarriageReturnLineFeed, context.formatContext); + return new ChangeTracker(getNewLineOrDefaultFromHost(context.host, context.formatContext.options), context.formatContext); } public static with(context: TextChangesContext, cb: (tracker: ChangeTracker) => void): FileTextChanges[] { @@ -212,11 +211,11 @@ namespace ts.textChanges { return tracker.getChanges(); } + /** Public for tests only. Other callers should use `ChangeTracker.with`. */ constructor( - private readonly newLine: NewLineKind, + private readonly newLineCharacter: string, private readonly formatContext: ts.formatting.FormatContext, private readonly validator?: (text: NonFormattedText) => void) { - this.newLineCharacter = getNewLineCharacter({ newLine }); } public deleteRange(sourceFile: SourceFile, range: TextRange) { @@ -631,7 +630,7 @@ namespace ts.textChanges { } private getFormattedTextOfNode(node: Node, sourceFile: SourceFile, pos: number, options: ChangeNodeOptions): string { - const nonformattedText = getNonformattedText(node, sourceFile, this.newLine); + const nonformattedText = getNonformattedText(node, sourceFile, this.newLineCharacter); if (this.validator) { this.validator(nonformattedText); } @@ -671,10 +670,9 @@ namespace ts.textChanges { readonly node: Node; } - function getNonformattedText(node: Node, sourceFile: SourceFile | undefined, newLine: NewLineKind): NonFormattedText { - const options = { newLine, target: sourceFile && sourceFile.languageVersion }; - const writer = new Writer(getNewLineCharacter(options)); - const printer = createPrinter(options, writer); + function getNonformattedText(node: Node, sourceFile: SourceFile | undefined, newLine: string): NonFormattedText { + const writer = new Writer(newLine); + const printer = createPrinter({ newLine: newLine === "\n" ? NewLineKind.LineFeed : NewLineKind.CarriageReturnLineFeed }, writer); printer.writeNode(EmitHint.Unspecified, node, sourceFile, writer); return { text: writer.getText(), node: assignPositionsToNode(node) }; } From cfc234f959db400023e303ded85c2566408d807d Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 15 Feb 2018 16:29:42 -0800 Subject: [PATCH 09/28] Simplify getBraceMatchingAtPosition (#21979) --- src/services/services.ts | 60 +++++++++------------------------------- 1 file changed, 13 insertions(+), 47 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 5eb0f6a06ca..6df52dd804e 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1767,55 +1767,21 @@ namespace ts { return OutliningElementsCollector.collectElements(sourceFile, cancellationToken); } - function getBraceMatchingAtPosition(fileName: string, position: number) { + const braceMatching = createMapFromTemplate({ + [SyntaxKind.OpenBraceToken]: SyntaxKind.CloseBraceToken, + [SyntaxKind.OpenParenToken]: SyntaxKind.CloseParenToken, + [SyntaxKind.OpenBracketToken]: SyntaxKind.CloseBracketToken, + [SyntaxKind.GreaterThanToken]: SyntaxKind.LessThanToken, + }); + braceMatching.forEach((value, key) => braceMatching.set(value.toString(), Number(key) as SyntaxKind)); + + function getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[] { const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - const result: TextSpan[] = []; - const token = getTouchingToken(sourceFile, position, /*includeJsDocComment*/ false); - - if (token.getStart(sourceFile) === position) { - const matchKind = getMatchingTokenKind(token); - - // Ensure that there is a corresponding token to match ours. - if (matchKind) { - const parentElement = token.parent; - - const childNodes = parentElement.getChildren(sourceFile); - for (const current of childNodes) { - if (current.kind === matchKind) { - const range1 = createTextSpan(token.getStart(sourceFile), token.getWidth(sourceFile)); - const range2 = createTextSpan(current.getStart(sourceFile), current.getWidth(sourceFile)); - - // We want to order the braces when we return the result. - if (range1.start < range2.start) { - result.push(range1, range2); - } - else { - result.push(range2, range1); - } - - break; - } - } - } - } - - return result; - - function getMatchingTokenKind(token: Node): ts.SyntaxKind { - switch (token.kind) { - case ts.SyntaxKind.OpenBraceToken: return ts.SyntaxKind.CloseBraceToken; - case ts.SyntaxKind.OpenParenToken: return ts.SyntaxKind.CloseParenToken; - case ts.SyntaxKind.OpenBracketToken: return ts.SyntaxKind.CloseBracketToken; - case ts.SyntaxKind.LessThanToken: return ts.SyntaxKind.GreaterThanToken; - case ts.SyntaxKind.CloseBraceToken: return ts.SyntaxKind.OpenBraceToken; - case ts.SyntaxKind.CloseParenToken: return ts.SyntaxKind.OpenParenToken; - case ts.SyntaxKind.CloseBracketToken: return ts.SyntaxKind.OpenBracketToken; - case ts.SyntaxKind.GreaterThanToken: return ts.SyntaxKind.LessThanToken; - } - - return undefined; - } + const matchKind = token.getStart(sourceFile) === position ? braceMatching.get(token.kind.toString()) : undefined; + const match = matchKind && findChildOfKind(token.parent, matchKind, sourceFile); + // We want to order the braces when we return the result. + return match ? [createTextSpanFromNode(token, sourceFile), createTextSpanFromNode(match, sourceFile)].sort((a, b) => a.start - b.start) : emptyArray; } function getIndentationAtPosition(fileName: string, position: number, editorOptions: EditorOptions | EditorSettings) { From b70aa229c636210a0503806eb3df953e0aa59abd Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 16 Feb 2018 10:48:57 -0800 Subject: [PATCH 10/28] getTextOfPropertyName: Assert input value is a PropertyName (#21981) --- src/compiler/checker.ts | 12 +++++++----- src/compiler/utilities.ts | 12 +++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2df80926c14..b817d9b965a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -21909,11 +21909,13 @@ namespace ts { // check private/protected variable access const parent = node.parent.parent; const parentType = getTypeForBindingElementParent(parent); - const name = node.propertyName || node.name; - const property = getPropertyOfType(parentType, getTextOfPropertyName(name)); - markPropertyAsReferenced(property, /*nodeForCheckWriteOnly*/ undefined, /*isThisAccess*/ false); // A destructuring is never a write-only reference. - if (parent.initializer && property) { - checkPropertyAccessibility(parent, parent.initializer, parentType, property); + const name = node.propertyName || node.name; + if (!isBindingPattern(name)) { + const property = getPropertyOfType(parentType, getTextOfPropertyName(name)); + markPropertyAsReferenced(property, /*nodeForCheckWriteOnly*/ undefined, /*isThisAccess*/ false); // A destructuring is never a write-only reference. + if (parent.initializer && property) { + checkPropertyAccessibility(parent, parent.initializer, parentType, property); + } } } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 9023e1e62f3..4e5b5700d29 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -570,17 +570,15 @@ namespace ts { export function getTextOfPropertyName(name: PropertyName): __String { switch (name.kind) { case SyntaxKind.Identifier: - return (name).escapedText; + return name.escapedText; case SyntaxKind.StringLiteral: case SyntaxKind.NumericLiteral: - return escapeLeadingUnderscores((name).text); + return escapeLeadingUnderscores(name.text); case SyntaxKind.ComputedPropertyName: - if (isStringOrNumericLiteral((name).expression)) { - return escapeLeadingUnderscores(((name).expression).text); - } + return isStringOrNumericLiteral(name.expression) ? escapeLeadingUnderscores(name.expression.text) : undefined; + default: + Debug.assertNever(name); } - - return undefined; } export function entityNameToString(name: EntityNameOrEntityNameExpression): string { From 5656f35b6a1120599fb62291b16161f6f9b818b2 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 31 Jan 2018 11:20:41 -0800 Subject: [PATCH 11/28] Introduce an organizeImports command In phase 1, it coalesces imports from the same module and sorts the results, but does not remove unused imports. Some trivia is lost during coalescing, but none should be duplicated. --- Jakefile.js | 1 + src/harness/harnessLanguageService.ts | 3 + src/harness/tsconfig.json | 1 + src/harness/unittests/organizeImports.ts | 426 ++++++++++++++++++ src/harness/unittests/session.ts | 2 + src/server/client.ts | 4 + src/server/protocol.ts | 25 + src/server/session.ts | 19 + src/services/services.ts | 287 ++++++++++++ src/services/types.ts | 3 + .../reference/api/tsserverlibrary.d.ts | 21 + tests/baselines/reference/api/typescript.d.ts | 2 + .../organizeImports/CoalesceTrivia.ts | 15 + .../reference/organizeImports/MoveToTop.ts | 18 + .../reference/organizeImports/Simple.ts | 20 + .../reference/organizeImports/SortTrivia.ts | 10 + 16 files changed, 857 insertions(+) create mode 100644 src/harness/unittests/organizeImports.ts create mode 100644 tests/baselines/reference/organizeImports/CoalesceTrivia.ts create mode 100644 tests/baselines/reference/organizeImports/MoveToTop.ts create mode 100644 tests/baselines/reference/organizeImports/Simple.ts create mode 100644 tests/baselines/reference/organizeImports/SortTrivia.ts diff --git a/Jakefile.js b/Jakefile.js index 9e8c51a306e..d676926abac 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -141,6 +141,7 @@ var harnessSources = harnessCoreSources.concat([ "typingsInstaller.ts", "projectErrors.ts", "matchFiles.ts", + "organizeImports.ts", "initializeTSConfig.ts", "extractConstants.ts", "extractFunctions.ts", diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 1c85acfb80e..d24f572d1d5 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -522,6 +522,9 @@ namespace Harness.LanguageService { getApplicableRefactors(): ts.ApplicableRefactorInfo[] { throw new Error("Not supported on the shim."); } + organizeImports(_scope: ts.OrganizeImportsScope, _formatOptions: ts.FormatCodeSettings): ReadonlyArray { + throw new Error("Not supported on the shim."); + } getEmitOutput(fileName: string): ts.EmitOutput { return unwrapJSONCallResult(this.shim.getEmitOutput(fileName)); } diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json index 25642ab5179..cd6dbc5e0bb 100644 --- a/src/harness/tsconfig.json +++ b/src/harness/tsconfig.json @@ -117,6 +117,7 @@ "./unittests/tsserverProjectSystem.ts", "./unittests/tscWatchMode.ts", "./unittests/matchFiles.ts", + "./unittests/organizeImports.ts", "./unittests/initializeTSConfig.ts", "./unittests/compileOnSave.ts", "./unittests/typingsInstaller.ts", diff --git a/src/harness/unittests/organizeImports.ts b/src/harness/unittests/organizeImports.ts new file mode 100644 index 00000000000..5cac601d08e --- /dev/null +++ b/src/harness/unittests/organizeImports.ts @@ -0,0 +1,426 @@ +/// +/// + + +namespace ts { + describe("Organize imports", () => { + describe("Sort imports", () => { + it("No imports", () => { + assert.isEmpty(sortImports([])); + }); + + it("One import", () => { + const unsortedImports = parseImports(`import "lib";`); + const actualSortedImports = sortImports(unsortedImports); + const expectedSortedImports = unsortedImports; + assertListEqual(expectedSortedImports, actualSortedImports); + }); + + it("Stable - import kind", () => { + assertUnaffectedBySort( + `import "lib";`, + `import * as x from "lib";`, + `import x from "lib";`, + `import {x} from "lib";`); + }); + + it("Stable - default property alias", () => { + assertUnaffectedBySort( + `import x from "lib";`, + `import y from "lib";`); + }); + + it("Stable - module alias", () => { + assertUnaffectedBySort( + `import * as x from "lib";`, + `import * as y from "lib";`); + }); + + it("Stable - symbol", () => { + assertUnaffectedBySort( + `import {x} from "lib";`, + `import {y} from "lib";`); + }); + + it("Sort - non-relative vs non-relative", () => { + assertSortsBefore( + `import y from "lib1";`, + `import x from "lib2";`); + }); + + it("Sort - relative vs relative", () => { + assertSortsBefore( + `import y from "./lib1";`, + `import x from "./lib2";`); + }); + + it("Sort - invalid vs invalid", () => { + assertSortsBefore( + "import y from `${'lib1'}`;", + "import x from `${'lib2'}`;"); + }); + + it("Sort - relative vs non-relative", () => { + assertSortsBefore( + `import y from "lib";`, + `import x from "./lib";`); + }); + + it("Sort - non-relative vs invalid", () => { + assertSortsBefore( + `import y from "lib";`, + "import x from `${'lib'}`;"); + }); + + it("Sort - relative vs invalid", () => { + assertSortsBefore( + `import y from "./lib";`, + "import x from `${'lib'}`;"); + }); + + function assertUnaffectedBySort(...importStrings: string[]) { + const unsortedImports1 = parseImports(...importStrings); + assertListEqual(unsortedImports1, sortImports(unsortedImports1)); + + const unsortedImports2 = reverse(unsortedImports1); + assertListEqual(unsortedImports2, sortImports(unsortedImports2)); + } + + function assertSortsBefore(importString1: string, importString2: string) { + const imports = parseImports(importString1, importString2); + assertListEqual(imports, sortImports(imports)); + assertListEqual(imports, sortImports(reverse(imports))); + } + }); + + describe("Coalesce imports", () => { + it("No imports", () => { + assert.isEmpty(coalesceImports([])); + }); + + it("Sort specifiers", () => { + const sortedImports = parseImports(`import { default as m, a as n, b, y, z as o } from "lib";`); + const actualCoalescedImports = coalesceImports(sortedImports); + const expectedCoalescedImports = parseImports(`import { a as n, b, default as m, y, z as o } from "lib";`); + assertListEqual(expectedCoalescedImports, actualCoalescedImports); + }); + + it("Combine side-effect-only imports", () => { + const sortedImports = parseImports( + `import "lib";`, + `import "lib";`); + const actualCoalescedImports = coalesceImports(sortedImports); + const expectedCoalescedImports = parseImports(`import "lib";`); + assertListEqual(expectedCoalescedImports, actualCoalescedImports); + }); + + it("Combine namespace imports", () => { + const sortedImports = parseImports( + `import * as x from "lib";`, + `import * as y from "lib";`); + const actualCoalescedImports = coalesceImports(sortedImports); + const expectedCoalescedImports = sortedImports; + assertListEqual(expectedCoalescedImports, actualCoalescedImports); + }); + + it("Combine default imports", () => { + const sortedImports = parseImports( + `import x from "lib";`, + `import y from "lib";`); + const actualCoalescedImports = coalesceImports(sortedImports); + const expectedCoalescedImports = parseImports(`import { default as x, default as y } from "lib";`); + assertListEqual(expectedCoalescedImports, actualCoalescedImports); + }); + + it("Combine property imports", () => { + const sortedImports = parseImports( + `import { x } from "lib";`, + `import { y as z } from "lib";`); + const actualCoalescedImports = coalesceImports(sortedImports); + const expectedCoalescedImports = parseImports(`import { x, y as z } from "lib";`); + assertListEqual(expectedCoalescedImports, actualCoalescedImports); + }); + + it("Combine side-effect-only import with namespace import", () => { + const sortedImports = parseImports( + `import "lib";`, + `import * as x from "lib";`); + const actualCoalescedImports = coalesceImports(sortedImports); + const expectedCoalescedImports = sortedImports; + assertListEqual(expectedCoalescedImports, actualCoalescedImports); + }); + + it("Combine side-effect-only import with default import", () => { + const sortedImports = parseImports( + `import "lib";`, + `import x from "lib";`); + const actualCoalescedImports = coalesceImports(sortedImports); + const expectedCoalescedImports = sortedImports; + assertListEqual(expectedCoalescedImports, actualCoalescedImports); + }); + + it("Combine side-effect-only import with property import", () => { + const sortedImports = parseImports( + `import "lib";`, + `import { x } from "lib";`); + const actualCoalescedImports = coalesceImports(sortedImports); + const expectedCoalescedImports = sortedImports; + assertListEqual(expectedCoalescedImports, actualCoalescedImports); + }); + + it("Combine namespace import with default import", () => { + const sortedImports = parseImports( + `import * as x from "lib";`, + `import y from "lib";`); + const actualCoalescedImports = coalesceImports(sortedImports); + const expectedCoalescedImports = parseImports( + `import y, * as x from "lib";`); + assertListEqual(expectedCoalescedImports, actualCoalescedImports); + }); + + it("Combine namespace import with property import", () => { + const sortedImports = parseImports( + `import * as x from "lib";`, + `import { y } from "lib";`); + const actualCoalescedImports = coalesceImports(sortedImports); + const expectedCoalescedImports = sortedImports; + assertListEqual(expectedCoalescedImports, actualCoalescedImports); + }); + + it("Combine default import with property import", () => { + const sortedImports = parseImports( + `import x from "lib";`, + `import { y } from "lib";`); + const actualCoalescedImports = coalesceImports(sortedImports); + const expectedCoalescedImports = parseImports( + `import x, { y } from "lib";`); + assertListEqual(expectedCoalescedImports, actualCoalescedImports); + }); + + it("Combine many imports", () => { + const sortedImports = parseImports( + `import "lib";`, + `import * as y from "lib";`, + `import w from "lib";`, + `import { b } from "lib";`, + `import "lib";`, + `import * as x from "lib";`, + `import z from "lib";`, + `import { a } from "lib";`); + const actualCoalescedImports = coalesceImports(sortedImports); + const expectedCoalescedImports = parseImports( + `import "lib";`, + `import * as x from "lib";`, + `import * as y from "lib";`, + `import { a, b, default as w, default as z } from "lib";`); + assertListEqual(expectedCoalescedImports, actualCoalescedImports); + }); + + it("Combine imports from different modules", () => { + const sortedImports = parseImports( + `import { d } from "lib1";`, + `import { b } from "lib1";`, + `import { c } from "lib2";`, + `import { a } from "lib2";`); + const actualCoalescedImports = coalesceImports(sortedImports); + const expectedCoalescedImports = parseImports( + `import { b, d } from "lib1";`, + `import { a, c } from "lib2";`); + assertListEqual(expectedCoalescedImports, actualCoalescedImports); + }); + + // This is descriptive, rather than normative + it("Combine two namespace imports with one default import", () => { + const sortedImports = parseImports( + `import * as x from "lib";`, + `import * as y from "lib";`, + `import z from "lib";`); + const actualCoalescedImports = coalesceImports(sortedImports); + const expectedCoalescedImports = sortedImports; + assertListEqual(expectedCoalescedImports, actualCoalescedImports); + }); + }); + + describe("Baselines", () => { + + const libFile = { + path: "/lib.ts", + content: ` +export function F1(); +export default function F2(); +`, + }; + + testOrganizeImports("Simple", + { + path: "/test.ts", + content: ` +import { F1, F2 } from "lib"; +import * as NS from "lib"; +import D from "lib"; + +NS.F1(); +D(); +F1(); +F2(); +`, + }, + libFile); + + testOrganizeImports("MoveToTop", + { + path: "/test.ts", + content: ` +import { F1, F2 } from "lib"; +F1(); +F2(); +import * as NS from "lib"; +NS.F1(); +import D from "lib"; +D(); +`, + }, + libFile); + + testOrganizeImports("CoalesceTrivia", + { + path: "/test.ts", + content: ` +/*A*/import /*B*/ { /*C*/ F2 /*D*/ } /*E*/ from /*F*/ "lib" /*G*/;/*H*/ //I +/*J*/import /*K*/ { /*L*/ F1 /*M*/ } /*N*/ from /*O*/ "lib" /*P*/;/*Q*/ //R + +F1(); +F2(); +`, + }, + libFile); + + testOrganizeImports("SortTrivia", + { + path: "/test.ts", + content: ` +/*A*/import /*B*/ "lib2" /*C*/;/*D*/ //E +/*F*/import /*G*/ "lib1" /*H*/;/*I*/ //J +`, + }, + { path: "/lib1.ts", content: "" }, + { path: "/lib2.ts", content: "" }); + + function testOrganizeImports(testName: string, testFile: TestFSWithWatch.FileOrFolder, ...otherFiles: TestFSWithWatch.FileOrFolder[]) { + it(testName, () => runBaseline(`organizeImports/${testName}.ts`, testFile, ...otherFiles)); + } + + function runBaseline(baselinePath: string, testFile: TestFSWithWatch.FileOrFolder, ...otherFiles: TestFSWithWatch.FileOrFolder[]) { + const { path: testPath, content: testContent } = testFile; + const languageService = makeLanguageService(testFile, ...otherFiles); + const changes = languageService.organizeImports({ type: "file", fileName: testPath }, testFormatOptions); + assert.equal(1, changes.length); + assert.equal(testPath, changes[0].fileName); + + Harness.Baseline.runBaseline(baselinePath, () => { + const data: string[] = []; + data.push(`// ==ORIGINAL==`); + data.push(testContent); + + data.push(`// ==ORGANIZED==`); + const newText = textChanges.applyChanges(testContent, changes[0].textChanges); + data.push(newText); + + return data.join(newLineCharacter); + }); + } + + function makeLanguageService(...files: TestFSWithWatch.FileOrFolder[]) { + const host = projectSystem.createServerHost(files); + const projectService = projectSystem.createProjectService(host, { useSingleInferredProject: true }); + files.forEach(f => projectService.openClientFile(f.path)); + return projectService.inferredProjects[0].getLanguageService(); + } + }); + + function parseImports(...importStrings: string[]): ReadonlyArray { + const sourceFile = createSourceFile("a.ts", importStrings.join("\n"), ScriptTarget.ES2015, /*setParentNodes*/ true, ScriptKind.TS); + const imports = filter(sourceFile.statements, isImportDeclaration); + assert.equal(importStrings.length, imports.length); + return imports; + } + + function assertEqual(node1?: Node, node2?: Node) { + if (node1 === undefined) { + assert.isUndefined(node2); + return; + } + else if (node2 === undefined) { + assert.isUndefined(node1); // Guaranteed to fail + return; + } + + assert.equal(node1.kind, node2.kind); + + switch(node1.kind) { + case SyntaxKind.ImportDeclaration: + const decl1 = node1 as ImportDeclaration; + const decl2 = node2 as ImportDeclaration; + assertEqual(decl1.importClause, decl2.importClause); + assertEqual(decl1.moduleSpecifier, decl2.moduleSpecifier); + break; + case SyntaxKind.ImportClause: + const clause1 = node1 as ImportClause; + const clause2 = node2 as ImportClause; + assertEqual(clause1.name, clause2.name); + assertEqual(clause1.namedBindings, clause2.namedBindings); + case SyntaxKind.NamespaceImport: + const nsi1 = node1 as NamespaceImport; + const nsi2 = node2 as NamespaceImport; + assertEqual(nsi1.name, nsi2.name); + break; + case SyntaxKind.NamedImports: + const ni1 = node1 as NamedImports; + const ni2 = node2 as NamedImports; + assertListEqual(ni1.elements, ni2.elements); + break; + case SyntaxKind.ImportSpecifier: + const is1 = node1 as ImportSpecifier; + const is2 = node2 as ImportSpecifier; + assertEqual(is1.name, is2.name); + assertEqual(is1.propertyName, is2.propertyName); + break; + case SyntaxKind.Identifier: + const id1 = node1 as Identifier; + const id2 = node2 as Identifier; + assert.equal(id1.text, id2.text); + break; + case SyntaxKind.StringLiteral: + case SyntaxKind.NoSubstitutionTemplateLiteral: + const sl1 = node1 as LiteralLikeNode; + const sl2 = node2 as LiteralLikeNode; + assert.equal(sl1.text, sl2.text); + break; + default: + assert.equal(node1.getText(), node2.getText()); + break; + } + } + + function assertListEqual(list1: ReadonlyArray, list2: ReadonlyArray) { + if (list1 === undefined || list2 === undefined) { + assert.isUndefined(list1); + assert.isUndefined(list2); + return; + } + + assert.equal(list1.length, list2.length); + for (let i = 0; i < list1.length; i++) { + assertEqual(list1[i], list2[i]); + } + } + + function reverse(list: ReadonlyArray) { + const result = []; + for (let i = list.length - 1; i >= 0; i--) { + result.push(list[i]); + } + return result; + } + }); +} \ No newline at end of file diff --git a/src/harness/unittests/session.ts b/src/harness/unittests/session.ts index 7d1e5b0816c..765fc29ee49 100644 --- a/src/harness/unittests/session.ts +++ b/src/harness/unittests/session.ts @@ -262,6 +262,8 @@ namespace ts.server { CommandNames.GetApplicableRefactors, CommandNames.GetEditsForRefactor, CommandNames.GetEditsForRefactorFull, + CommandNames.OrganizeImports, + CommandNames.OrganizeImportsFull, ]; it("should not throw when commands are executed with invalid arguments", () => { diff --git a/src/server/client.ts b/src/server/client.ts index 8203475b06d..cee65c0e5a4 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -629,6 +629,10 @@ namespace ts.server { }; } + organizeImports(_scope: OrganizeImportsScope, _formatOptions: FormatCodeSettings): ReadonlyArray { + return notImplemented(); + } + private convertCodeEditsToTextChanges(edits: protocol.FileCodeEdits[]): FileTextChanges[] { return edits.map(edit => { const fileName = edit.fileName; diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 45c08034e6e..fbff4501133 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -113,6 +113,10 @@ namespace ts.server.protocol { /* @internal */ GetEditsForRefactorFull = "getEditsForRefactor-full", + OrganizeImports = "organizeImports", + /* @internal */ + OrganizeImportsFull = "organizeImports-full", + // NOTE: If updating this, be sure to also update `allCommandNames` in `harness/unittests/session.ts`. } @@ -547,6 +551,27 @@ namespace ts.server.protocol { renameFilename?: string; } + /** + * Organize imports by: + * 1) Removing unused imports + * 2) Coalescing imports from the same module + * 3) Sorting imports + */ + export interface OrganizeImportsRequest extends Request { + command: CommandTypes.OrganizeImports; + arguments: OrganizeImportsRequestArgs; + } + + export type OrganizeImportsScope = GetCombinedCodeFixScope; + + export interface OrganizeImportsRequestArgs { + scope: OrganizeImportsScope; + } + + export interface OrganizeImportsResponse extends Response { + edits: ReadonlyArray; + } + /** * Request for the available codefixes at a specific position. */ diff --git a/src/server/session.ts b/src/server/session.ts index 356ea0d254e..bff19d7bc23 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1597,6 +1597,19 @@ namespace ts.server { } } + private organizeImports({ scope }: protocol.OrganizeImportsRequestArgs, simplifiedResult: boolean): ReadonlyArray | ReadonlyArray { + Debug.assert(scope.type === "file"); + const { file, project } = this.getFileAndProject(scope.args); + const formatOptions = this.projectService.getFormatCodeOptions(file); + const changes = project.getLanguageService().organizeImports({ type: "file", fileName: file }, formatOptions); + if (simplifiedResult) { + return this.mapTextChangesToCodeEdits(project, changes); + } + else { + return changes; + } + } + private getCodeFixes(args: protocol.CodeFixRequestArgs, simplifiedResult: boolean): ReadonlyArray | ReadonlyArray { if (args.errorCodes.length === 0) { return undefined; @@ -2041,6 +2054,12 @@ namespace ts.server { }, [CommandNames.GetEditsForRefactorFull]: (request: protocol.GetEditsForRefactorRequest) => { return this.requiredResponse(this.getEditsForRefactor(request.arguments, /*simplifiedResult*/ false)); + }, + [CommandNames.OrganizeImports]: (request: protocol.OrganizeImportsRequest) => { + return this.requiredResponse(this.organizeImports(request.arguments, /*simplifiedResult*/ true)); + }, + [CommandNames.OrganizeImportsFull]: (request: protocol.OrganizeImportsRequest) => { + return this.requiredResponse(this.organizeImports(request.arguments, /*simplifiedResult*/ false)); } }); diff --git a/src/services/services.ts b/src/services/services.ts index 6df52dd804e..22692f818e9 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1848,6 +1848,58 @@ namespace ts { return codefix.getAllFixes({ fixId, sourceFile, program, host, cancellationToken, formatContext }); } + function organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings): ReadonlyArray { + synchronizeHostData(); + Debug.assert(scope.type === "file"); + const sourceFile = getValidSourceFile(scope.fileName); + const formatContext = formatting.getFormatContext(formatOptions); + + // All of the (old) ImportDeclarations in the file, in syntactic order. + const oldImportDecls: ImportDeclaration[] = []; + + forEachChild(sourceFile, node => { + cancellationToken.throwIfCancellationRequested(); + if (isImportDeclaration(node)) { + oldImportDecls.push(node); + } + // TODO (https://github.com/Microsoft/TypeScript/issues/10020): sort *within* ambient modules (find using isAmbientModule) + }); + + if (oldImportDecls.length === 0) { + return []; + } + + const usedImportDecls = removeUnusedImports(oldImportDecls); + const sortedImportDecls = sortImports(usedImportDecls); + const coalescedImportDecls = coalesceImports(sortedImportDecls); + + // All of the (new) ImportDeclarations in the file, in sorted order. + const newImportDecls = coalescedImportDecls; + + const changeTracker = textChanges.ChangeTracker.fromContext({ host, formatContext }); + + // NB: Stopping before i === 0 + for (let i = oldImportDecls.length - 1; i > 0; i--) { + changeTracker.deleteNode(sourceFile, oldImportDecls[i]); + } + + if (newImportDecls.length === 0) { + changeTracker.deleteNode(sourceFile, oldImportDecls[0]); + } + else { + // Delete the surrounding trivia because it will have been retained in newImportDecls. + const replaceOptions = { + useNonAdjustedStartPosition: false, + useNonAdjustedEndPosition: false, + suffix: getNewLineOrDefaultFromHost(host, formatOptions), + }; + changeTracker.replaceNodeWithNodes(sourceFile, oldImportDecls[0], newImportDecls, replaceOptions); + } + + const changes = changeTracker.getChanges(); + return changes; + } + function applyCodeActionCommand(action: CodeActionCommand): Promise; function applyCodeActionCommand(action: CodeActionCommand[]): Promise; function applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise; @@ -2143,6 +2195,7 @@ namespace ts { getCodeFixesAtPosition, getCombinedCodeFix, applyCodeActionCommand, + organizeImports, getEmitOutput, getNonBoundSourceFile, getSourceFile, @@ -2268,4 +2321,238 @@ namespace ts { } objectAllocator = getServicesObjectAllocator(); + + function removeUnusedImports(oldImports: ReadonlyArray) { + return oldImports; // TODO (https://github.com/Microsoft/TypeScript/issues/10020) + } + + /* @internal */ // Internal for testing + export function sortImports(oldImports: ReadonlyArray) { + if (oldImports.length < 2) { + return oldImports; + } + + // NB: declaration order determines sort order + const enum ModuleNameKind { + NonRelative, + Relative, + Invalid, + } + + const importRecords = oldImports.map(createImportRecord); + + const sortedRecords = stableSort(importRecords, (import1, import2) => { + const { name: name1, kind: kind1 } = import1; + const { name: name2, kind: kind2 } = import2; + + if (kind1 !== kind2) { + return kind1 < kind2 + ? Comparison.LessThan + : Comparison.GreaterThan; + } + + // Note that we're using simple equality, retaining case-sensitivity. + if (name1 !== name2) { + return name1 < name2 + ? Comparison.LessThan + : Comparison.GreaterThan; + } + + return Comparison.EqualTo; + }); + + return sortedRecords.map(r => r.importDeclaration); + + function createImportRecord(importDeclaration: ImportDeclaration) { + const specifier = importDeclaration.moduleSpecifier; + const name = getExternalModuleName(specifier); + if (name) { + const isRelative = isExternalModuleNameRelative(name); + return { importDeclaration, name, kind: isRelative ? ModuleNameKind.Relative : ModuleNameKind.NonRelative } + } + + return { importDeclaration, name: specifier.getText(), kind: ModuleNameKind.Invalid }; + } + } + + function getExternalModuleName(specifier: Expression) { + return isStringLiteral(specifier) || isNoSubstitutionTemplateLiteral(specifier) + ? specifier.text + : undefined; + } + + /** + * @param sortedImports a non-empty list of ImportDeclarations, sorted by module name. + */ + function groupSortedImports(sortedImports: ReadonlyArray): ReadonlyArray> { + Debug.assert(length(sortedImports) > 0); + + const groups: ImportDeclaration[][] = []; + + let groupName: string | undefined = getExternalModuleName(sortedImports[0].moduleSpecifier); + let group: ImportDeclaration[] = []; + + for (const importDeclaration of sortedImports) { + const moduleName = getExternalModuleName(importDeclaration.moduleSpecifier); + if (moduleName && moduleName === groupName) { + group.push(importDeclaration); + } + else if (group.length) { + groups.push(group); + + groupName = moduleName; + group = [importDeclaration]; + } + } + + if (group.length) { + groups.push(group); + } + + return groups; + } + + /* @internal */ // Internal for testing + /** + * @param sortedImports a list of ImportDeclarations, sorted by module name. + */ + export function coalesceImports(sortedImports: ReadonlyArray) { + if (sortedImports.length === 0) { + return sortedImports; + } + + const coalescedImports: ImportDeclaration[] = []; + + const groupedImports = groupSortedImports(sortedImports); + for (const importGroup of groupedImports) { + + let seenImportWithoutClause = false; + + const defaultImports: Identifier[] = []; + const namespaceImports: NamespaceImport[] = []; + const namedImports: NamedImports[] = []; + + for (const importDeclaration of importGroup) { + if (importDeclaration.importClause === undefined) { + // Only the first such import is interesting - the others are redundant. + // Note: Unfortunately, we will lose trivia that was on this node. + if (!seenImportWithoutClause) { + coalescedImports.push(importDeclaration); + } + + seenImportWithoutClause = true; + continue; + } + + const { name, namedBindings } = importDeclaration.importClause; + + if (name) { + defaultImports.push(name); + } + + if (namedBindings) { + if (isNamespaceImport(namedBindings)) { + namespaceImports.push(namedBindings); + } + else { + namedImports.push(namedBindings); + } + } + } + + // Normally, we don't combine default and namespace imports, but it would be silly to + // produce two import declarations in this special case. + if (defaultImports.length === 1 && namespaceImports.length === 1 && namedImports.length === 0) { + // Add the namespace import to the existing default ImportDeclaration. + const defaultImportClause = defaultImports[0].parent as ImportClause; + coalescedImports.push( + updateImportDeclarationAndClause(defaultImportClause, defaultImportClause.name, namespaceImports[0])); + + continue; + } + + // For convenience, we cheat and do a little sorting during coalescing. + // Seems reasonable since we're restructuring so much anyway. + const sortedNamespaceImports = stableSort(namespaceImports, (n1, n2) => compareIdentifiers(n1.name, n2.name)); + + for (const namespaceImport of sortedNamespaceImports) { + // Drop the name, if any + coalescedImports.push( + updateImportDeclarationAndClause(namespaceImport.parent, /*name*/ undefined, namespaceImport)); + } + + if (defaultImports.length === 0 && namedImports.length === 0) { + continue; + } + + let newDefaultImport: Identifier = undefined; + const newImportSpecifiers: ImportSpecifier[] = []; + if (defaultImports.length === 1) { + newDefaultImport = defaultImports[0]; + } + else { + for (const defaultImport of defaultImports) { + newImportSpecifiers.push( + createImportSpecifier(createIdentifier("default"), defaultImport)); + } + } + + for (const namedImport of namedImports) { + for (const specifier of namedImport.elements) { + newImportSpecifiers.push(specifier); + } + } + + const sortedImportSpecifiers = stableSort(newImportSpecifiers, (s1, s2) => { + const nameComparison = compareIdentifiers(s1.propertyName || s1.name, s2.propertyName || s2.name); + return nameComparison != Comparison.EqualTo + ? nameComparison + : compareIdentifiers(s1.name, s2.name); + }); + + const importClause = defaultImports.length > 0 + ? defaultImports[0].parent as ImportClause + : namedImports[0].parent; + + const newNamedImports = sortedImportSpecifiers.length === 0 + ? undefined + : namedImports.length === 0 + ? createNamedImports(sortedImportSpecifiers) + : updateNamedImports(namedImports[0], sortedImportSpecifiers); + + coalescedImports.push( + updateImportDeclarationAndClause(importClause, newDefaultImport, newNamedImports)); + } + + return coalescedImports; + + // `undefined` is the min value. + function compareIdentifiers(s1: Identifier | undefined, s2: Identifier | undefined) { + return s1 === undefined + ? s2 === undefined + ? Comparison.EqualTo + : Comparison.LessThan + : s2 === undefined + ? Comparison.GreaterThan + : s1.text < s2.text + ? Comparison.LessThan + : s1.text > s2.text + ? Comparison.GreaterThan + : Comparison.EqualTo; + } + + function updateImportDeclarationAndClause( + importClause: ImportClause, + name: Identifier | undefined, + namedBindings: NamedImportBindings | undefined) { + + const importDeclaration = importClause.parent; + return updateImportDeclaration( + importDeclaration, + importDeclaration.decorators, + importDeclaration.modifiers, + updateImportClause(importClause, name, namedBindings), + importDeclaration.moduleSpecifier); + } + } } diff --git a/src/services/types.ts b/src/services/types.ts index 594484e1ea7..51710c88f4f 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -308,6 +308,7 @@ namespace ts { 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; + organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings): ReadonlyArray; getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput; @@ -326,6 +327,8 @@ namespace ts { export interface CombinedCodeFixScope { type: "file"; fileName: string; } + export type OrganizeImportsScope = CombinedCodeFixScope; + export interface GetCompletionsAtPositionOptions { includeExternalModuleExports: boolean; includeInsertTextCompletions: boolean; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 370d841a7f1..1a7edaa44c8 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4135,6 +4135,7 @@ declare namespace ts { 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; + organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings): ReadonlyArray; getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput; getProgram(): Program; dispose(): void; @@ -4143,6 +4144,7 @@ declare namespace ts { type: "file"; fileName: string; } + type OrganizeImportsScope = CombinedCodeFixScope; interface GetCompletionsAtPositionOptions { includeExternalModuleExports: boolean; includeInsertTextCompletions: boolean; @@ -5078,6 +5080,7 @@ declare namespace ts.server.protocol { GetSupportedCodeFixes = "getSupportedCodeFixes", GetApplicableRefactors = "getApplicableRefactors", GetEditsForRefactor = "getEditsForRefactor", + OrganizeImports = "organizeImports", } /** * A TypeScript Server message @@ -5429,6 +5432,23 @@ declare namespace ts.server.protocol { renameLocation?: Location; renameFilename?: string; } + /** + * Organize imports by: + * 1) Removing unused imports + * 2) Coalescing imports from the same module + * 3) Sorting imports + */ + interface OrganizeImportsRequest extends Request { + command: CommandTypes.OrganizeImports; + arguments: OrganizeImportsRequestArgs; + } + type OrganizeImportsScope = GetCombinedCodeFixScope; + interface OrganizeImportsRequestArgs { + scope: OrganizeImportsScope; + } + interface OrganizeImportsResponse extends Response { + edits: ReadonlyArray; + } /** * Request for the available codefixes at a specific position. */ @@ -7282,6 +7302,7 @@ declare namespace ts.server { private extractPositionAndRange(args, scriptInfo); private getApplicableRefactors(args); private getEditsForRefactor(args, simplifiedResult); + private organizeImports({scope}, simplifiedResult); private getCodeFixes(args, simplifiedResult); private getCombinedCodeFix({scope, fixId}, simplifiedResult); private applyCodeActionCommand(args); diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index baed457b3b0..8f9c095090d 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4387,6 +4387,7 @@ declare namespace ts { 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; + organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings): ReadonlyArray; getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput; getProgram(): Program; dispose(): void; @@ -4395,6 +4396,7 @@ declare namespace ts { type: "file"; fileName: string; } + type OrganizeImportsScope = CombinedCodeFixScope; interface GetCompletionsAtPositionOptions { includeExternalModuleExports: boolean; includeInsertTextCompletions: boolean; diff --git a/tests/baselines/reference/organizeImports/CoalesceTrivia.ts b/tests/baselines/reference/organizeImports/CoalesceTrivia.ts new file mode 100644 index 00000000000..972df9e18eb --- /dev/null +++ b/tests/baselines/reference/organizeImports/CoalesceTrivia.ts @@ -0,0 +1,15 @@ +// ==ORIGINAL== + +/*A*/import /*B*/ { /*C*/ F2 /*D*/ } /*E*/ from /*F*/ "lib" /*G*/;/*H*/ //I +/*J*/import /*K*/ { /*L*/ F1 /*M*/ } /*N*/ from /*O*/ "lib" /*P*/;/*Q*/ //R + +F1(); +F2(); + +// ==ORGANIZED== + +/*A*/ import { /*L*/ F1 /*M*/, /*C*/ F2 /*D*/ } /*E*/ from "lib" /*G*/; /*H*/ //I + + +F1(); +F2(); diff --git a/tests/baselines/reference/organizeImports/MoveToTop.ts b/tests/baselines/reference/organizeImports/MoveToTop.ts new file mode 100644 index 00000000000..c0e57b930ab --- /dev/null +++ b/tests/baselines/reference/organizeImports/MoveToTop.ts @@ -0,0 +1,18 @@ +// ==ORIGINAL== + +import { F1, F2 } from "lib"; +F1(); +F2(); +import * as NS from "lib"; +NS.F1(); +import D from "lib"; +D(); + +// ==ORGANIZED== + +import * as NS from "lib"; +import D, { F1, F2 } from "lib"; +F1(); +F2(); +NS.F1(); +D(); diff --git a/tests/baselines/reference/organizeImports/Simple.ts b/tests/baselines/reference/organizeImports/Simple.ts new file mode 100644 index 00000000000..3f36ae633a6 --- /dev/null +++ b/tests/baselines/reference/organizeImports/Simple.ts @@ -0,0 +1,20 @@ +// ==ORIGINAL== + +import { F1, F2 } from "lib"; +import * as NS from "lib"; +import D from "lib"; + +NS.F1(); +D(); +F1(); +F2(); + +// ==ORGANIZED== + +import * as NS from "lib"; +import D, { F1, F2 } from "lib"; + +NS.F1(); +D(); +F1(); +F2(); diff --git a/tests/baselines/reference/organizeImports/SortTrivia.ts b/tests/baselines/reference/organizeImports/SortTrivia.ts new file mode 100644 index 00000000000..e46c836b966 --- /dev/null +++ b/tests/baselines/reference/organizeImports/SortTrivia.ts @@ -0,0 +1,10 @@ +// ==ORIGINAL== + +/*A*/import /*B*/ "lib2" /*C*/;/*D*/ //E +/*F*/import /*G*/ "lib1" /*H*/;/*I*/ //J + +// ==ORGANIZED== + +/*F*/ import "lib1" /*H*/; /*I*/ //J +/*A*/ import "lib2" /*C*/; /*D*/ //E + From 979b14689e1abb9f7ba6e314b163496bd0008ca3 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Mon, 12 Feb 2018 18:29:01 -0800 Subject: [PATCH 12/28] Fix lint errors --- src/harness/unittests/organizeImports.ts | 7 ++++++- src/services/services.ts | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/harness/unittests/organizeImports.ts b/src/harness/unittests/organizeImports.ts index 5cac601d08e..e78a88ca232 100644 --- a/src/harness/unittests/organizeImports.ts +++ b/src/harness/unittests/organizeImports.ts @@ -56,7 +56,9 @@ namespace ts { it("Sort - invalid vs invalid", () => { assertSortsBefore( + // tslint:disable-next-line no-invalid-template-strings "import y from `${'lib1'}`;", + // tslint:disable-next-line no-invalid-template-strings "import x from `${'lib2'}`;"); }); @@ -69,12 +71,14 @@ namespace ts { it("Sort - non-relative vs invalid", () => { assertSortsBefore( `import y from "lib";`, + // tslint:disable-next-line no-invalid-template-strings "import x from `${'lib'}`;"); }); it("Sort - relative vs invalid", () => { assertSortsBefore( `import y from "./lib";`, + // tslint:disable-next-line no-invalid-template-strings "import x from `${'lib'}`;"); }); @@ -357,7 +361,7 @@ F2(); assert.equal(node1.kind, node2.kind); - switch(node1.kind) { + switch (node1.kind) { case SyntaxKind.ImportDeclaration: const decl1 = node1 as ImportDeclaration; const decl2 = node2 as ImportDeclaration; @@ -369,6 +373,7 @@ F2(); const clause2 = node2 as ImportClause; assertEqual(clause1.name, clause2.name); assertEqual(clause1.namedBindings, clause2.namedBindings); + break; case SyntaxKind.NamespaceImport: const nsi1 = node1 as NamespaceImport; const nsi2 = node2 as NamespaceImport; diff --git a/src/services/services.ts b/src/services/services.ts index 22692f818e9..3b984c2e159 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2368,7 +2368,7 @@ namespace ts { const name = getExternalModuleName(specifier); if (name) { const isRelative = isExternalModuleNameRelative(name); - return { importDeclaration, name, kind: isRelative ? ModuleNameKind.Relative : ModuleNameKind.NonRelative } + return { importDeclaration, name, kind: isRelative ? ModuleNameKind.Relative : ModuleNameKind.NonRelative }; } return { importDeclaration, name: specifier.getText(), kind: ModuleNameKind.Invalid }; @@ -2505,7 +2505,7 @@ namespace ts { const sortedImportSpecifiers = stableSort(newImportSpecifiers, (s1, s2) => { const nameComparison = compareIdentifiers(s1.propertyName || s1.name, s2.propertyName || s2.name); - return nameComparison != Comparison.EqualTo + return nameComparison !== Comparison.EqualTo ? nameComparison : compareIdentifiers(s1.name, s2.name); }); From f4141ac6bfd726becafb9eef00adb79afbc1f027 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Tue, 13 Feb 2018 14:52:15 -0800 Subject: [PATCH 13/28] Separate OrganizeImports into its own namespace and file --- src/harness/unittests/organizeImports.ts | 42 ++-- src/services/organizeImports.ts | 291 +++++++++++++++++++++++ src/services/services.ts | 280 +--------------------- 3 files changed, 314 insertions(+), 299 deletions(-) create mode 100644 src/services/organizeImports.ts diff --git a/src/harness/unittests/organizeImports.ts b/src/harness/unittests/organizeImports.ts index e78a88ca232..eaa21bbb72f 100644 --- a/src/harness/unittests/organizeImports.ts +++ b/src/harness/unittests/organizeImports.ts @@ -6,12 +6,12 @@ namespace ts { describe("Organize imports", () => { describe("Sort imports", () => { it("No imports", () => { - assert.isEmpty(sortImports([])); + assert.isEmpty(OrganizeImports.sortImports([])); }); it("One import", () => { const unsortedImports = parseImports(`import "lib";`); - const actualSortedImports = sortImports(unsortedImports); + const actualSortedImports = OrganizeImports.sortImports(unsortedImports); const expectedSortedImports = unsortedImports; assertListEqual(expectedSortedImports, actualSortedImports); }); @@ -84,27 +84,27 @@ namespace ts { function assertUnaffectedBySort(...importStrings: string[]) { const unsortedImports1 = parseImports(...importStrings); - assertListEqual(unsortedImports1, sortImports(unsortedImports1)); + assertListEqual(unsortedImports1, OrganizeImports.sortImports(unsortedImports1)); const unsortedImports2 = reverse(unsortedImports1); - assertListEqual(unsortedImports2, sortImports(unsortedImports2)); + assertListEqual(unsortedImports2, OrganizeImports.sortImports(unsortedImports2)); } function assertSortsBefore(importString1: string, importString2: string) { const imports = parseImports(importString1, importString2); - assertListEqual(imports, sortImports(imports)); - assertListEqual(imports, sortImports(reverse(imports))); + assertListEqual(imports, OrganizeImports.sortImports(imports)); + assertListEqual(imports, OrganizeImports.sortImports(reverse(imports))); } }); describe("Coalesce imports", () => { it("No imports", () => { - assert.isEmpty(coalesceImports([])); + assert.isEmpty(OrganizeImports.coalesceImports([])); }); it("Sort specifiers", () => { const sortedImports = parseImports(`import { default as m, a as n, b, y, z as o } from "lib";`); - const actualCoalescedImports = coalesceImports(sortedImports); + const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = parseImports(`import { a as n, b, default as m, y, z as o } from "lib";`); assertListEqual(expectedCoalescedImports, actualCoalescedImports); }); @@ -113,7 +113,7 @@ namespace ts { const sortedImports = parseImports( `import "lib";`, `import "lib";`); - const actualCoalescedImports = coalesceImports(sortedImports); + const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = parseImports(`import "lib";`); assertListEqual(expectedCoalescedImports, actualCoalescedImports); }); @@ -122,7 +122,7 @@ namespace ts { const sortedImports = parseImports( `import * as x from "lib";`, `import * as y from "lib";`); - const actualCoalescedImports = coalesceImports(sortedImports); + const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = sortedImports; assertListEqual(expectedCoalescedImports, actualCoalescedImports); }); @@ -131,7 +131,7 @@ namespace ts { const sortedImports = parseImports( `import x from "lib";`, `import y from "lib";`); - const actualCoalescedImports = coalesceImports(sortedImports); + const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = parseImports(`import { default as x, default as y } from "lib";`); assertListEqual(expectedCoalescedImports, actualCoalescedImports); }); @@ -140,7 +140,7 @@ namespace ts { const sortedImports = parseImports( `import { x } from "lib";`, `import { y as z } from "lib";`); - const actualCoalescedImports = coalesceImports(sortedImports); + const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = parseImports(`import { x, y as z } from "lib";`); assertListEqual(expectedCoalescedImports, actualCoalescedImports); }); @@ -149,7 +149,7 @@ namespace ts { const sortedImports = parseImports( `import "lib";`, `import * as x from "lib";`); - const actualCoalescedImports = coalesceImports(sortedImports); + const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = sortedImports; assertListEqual(expectedCoalescedImports, actualCoalescedImports); }); @@ -158,7 +158,7 @@ namespace ts { const sortedImports = parseImports( `import "lib";`, `import x from "lib";`); - const actualCoalescedImports = coalesceImports(sortedImports); + const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = sortedImports; assertListEqual(expectedCoalescedImports, actualCoalescedImports); }); @@ -167,7 +167,7 @@ namespace ts { const sortedImports = parseImports( `import "lib";`, `import { x } from "lib";`); - const actualCoalescedImports = coalesceImports(sortedImports); + const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = sortedImports; assertListEqual(expectedCoalescedImports, actualCoalescedImports); }); @@ -176,7 +176,7 @@ namespace ts { const sortedImports = parseImports( `import * as x from "lib";`, `import y from "lib";`); - const actualCoalescedImports = coalesceImports(sortedImports); + const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = parseImports( `import y, * as x from "lib";`); assertListEqual(expectedCoalescedImports, actualCoalescedImports); @@ -186,7 +186,7 @@ namespace ts { const sortedImports = parseImports( `import * as x from "lib";`, `import { y } from "lib";`); - const actualCoalescedImports = coalesceImports(sortedImports); + const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = sortedImports; assertListEqual(expectedCoalescedImports, actualCoalescedImports); }); @@ -195,7 +195,7 @@ namespace ts { const sortedImports = parseImports( `import x from "lib";`, `import { y } from "lib";`); - const actualCoalescedImports = coalesceImports(sortedImports); + const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = parseImports( `import x, { y } from "lib";`); assertListEqual(expectedCoalescedImports, actualCoalescedImports); @@ -211,7 +211,7 @@ namespace ts { `import * as x from "lib";`, `import z from "lib";`, `import { a } from "lib";`); - const actualCoalescedImports = coalesceImports(sortedImports); + const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = parseImports( `import "lib";`, `import * as x from "lib";`, @@ -226,7 +226,7 @@ namespace ts { `import { b } from "lib1";`, `import { c } from "lib2";`, `import { a } from "lib2";`); - const actualCoalescedImports = coalesceImports(sortedImports); + const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = parseImports( `import { b, d } from "lib1";`, `import { a, c } from "lib2";`); @@ -239,7 +239,7 @@ namespace ts { `import * as x from "lib";`, `import * as y from "lib";`, `import z from "lib";`); - const actualCoalescedImports = coalesceImports(sortedImports); + const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = sortedImports; assertListEqual(expectedCoalescedImports, actualCoalescedImports); }); diff --git a/src/services/organizeImports.ts b/src/services/organizeImports.ts new file mode 100644 index 00000000000..aaff3331941 --- /dev/null +++ b/src/services/organizeImports.ts @@ -0,0 +1,291 @@ +/* @internal */ +namespace ts.OrganizeImports { + export function organizeImports( + sourceFile: SourceFile, + formatContext: formatting.FormatContext, + host: LanguageServiceHost, + cancellationToken: CancellationToken) { + + // All of the (old) ImportDeclarations in the file, in syntactic order. + const oldImportDecls: ImportDeclaration[] = []; + + forEachChild(sourceFile, node => { + cancellationToken.throwIfCancellationRequested(); + if (isImportDeclaration(node)) { + oldImportDecls.push(node); + } + // TODO (https://github.com/Microsoft/TypeScript/issues/10020): sort *within* ambient modules (find using isAmbientModule) + }); + + if (oldImportDecls.length === 0) { + return []; + } + + const usedImportDecls = removeUnusedImports(oldImportDecls); + cancellationToken.throwIfCancellationRequested(); + const sortedImportDecls = sortImports(usedImportDecls); + cancellationToken.throwIfCancellationRequested(); + const coalescedImportDecls = coalesceImports(sortedImportDecls); + cancellationToken.throwIfCancellationRequested(); + + // All of the (new) ImportDeclarations in the file, in sorted order. + const newImportDecls = coalescedImportDecls; + + const changeTracker = textChanges.ChangeTracker.fromContext({ host, formatContext }); + + // NB: Stopping before i === 0 + for (let i = oldImportDecls.length - 1; i > 0; i--) { + changeTracker.deleteNode(sourceFile, oldImportDecls[i]); + } + + if (newImportDecls.length === 0) { + changeTracker.deleteNode(sourceFile, oldImportDecls[0]); + } + else { + // Delete the surrounding trivia because it will have been retained in newImportDecls. + const replaceOptions = { + useNonAdjustedStartPosition: false, + useNonAdjustedEndPosition: false, + suffix: getNewLineOrDefaultFromHost(host, formatContext.options), + }; + changeTracker.replaceNodeWithNodes(sourceFile, oldImportDecls[0], newImportDecls, replaceOptions); + } + + const changes = changeTracker.getChanges(); + return changes; + } + + function removeUnusedImports(oldImports: ReadonlyArray) { + return oldImports; // TODO (https://github.com/Microsoft/TypeScript/issues/10020) + } + + /* @internal */ // Internal for testing + export function sortImports(oldImports: ReadonlyArray) { + if (oldImports.length < 2) { + return oldImports; + } + + // NB: declaration order determines sort order + const enum ModuleNameKind { + NonRelative, + Relative, + Invalid, + } + + const importRecords = oldImports.map(createImportRecord); + + const sortedRecords = stableSort(importRecords, (import1, import2) => { + const { name: name1, kind: kind1 } = import1; + const { name: name2, kind: kind2 } = import2; + + if (kind1 !== kind2) { + return kind1 < kind2 + ? Comparison.LessThan + : Comparison.GreaterThan; + } + + // Note that we're using simple equality, retaining case-sensitivity. + if (name1 !== name2) { + return name1 < name2 + ? Comparison.LessThan + : Comparison.GreaterThan; + } + + return Comparison.EqualTo; + }); + + return sortedRecords.map(r => r.importDeclaration); + + function createImportRecord(importDeclaration: ImportDeclaration) { + const specifier = importDeclaration.moduleSpecifier; + const name = getExternalModuleName(specifier); + if (name) { + const isRelative = isExternalModuleNameRelative(name); + return { importDeclaration, name, kind: isRelative ? ModuleNameKind.Relative : ModuleNameKind.NonRelative }; + } + + return { importDeclaration, name: specifier.getText(), kind: ModuleNameKind.Invalid }; + } + } + + function getExternalModuleName(specifier: Expression) { + return isStringLiteral(specifier) || isNoSubstitutionTemplateLiteral(specifier) + ? specifier.text + : undefined; + } + + /** + * @param sortedImports a non-empty list of ImportDeclarations, sorted by module name. + */ + function groupSortedImports(sortedImports: ReadonlyArray): ReadonlyArray> { + Debug.assert(length(sortedImports) > 0); + + const groups: ImportDeclaration[][] = []; + + let groupName: string | undefined = getExternalModuleName(sortedImports[0].moduleSpecifier); + let group: ImportDeclaration[] = []; + + for (const importDeclaration of sortedImports) { + const moduleName = getExternalModuleName(importDeclaration.moduleSpecifier); + if (moduleName && moduleName === groupName) { + group.push(importDeclaration); + } + else if (group.length) { + groups.push(group); + + groupName = moduleName; + group = [importDeclaration]; + } + } + + if (group.length) { + groups.push(group); + } + + return groups; + } + + /* @internal */ // Internal for testing + /** + * @param sortedImports a list of ImportDeclarations, sorted by module name. + */ + export function coalesceImports(sortedImports: ReadonlyArray) { + if (sortedImports.length === 0) { + return sortedImports; + } + + const coalescedImports: ImportDeclaration[] = []; + + const groupedImports = groupSortedImports(sortedImports); + for (const importGroup of groupedImports) { + + let seenImportWithoutClause = false; + + const defaultImports: Identifier[] = []; + const namespaceImports: NamespaceImport[] = []; + const namedImports: NamedImports[] = []; + + for (const importDeclaration of importGroup) { + if (importDeclaration.importClause === undefined) { + // Only the first such import is interesting - the others are redundant. + // Note: Unfortunately, we will lose trivia that was on this node. + if (!seenImportWithoutClause) { + coalescedImports.push(importDeclaration); + } + + seenImportWithoutClause = true; + continue; + } + + const { name, namedBindings } = importDeclaration.importClause; + + if (name) { + defaultImports.push(name); + } + + if (namedBindings) { + if (isNamespaceImport(namedBindings)) { + namespaceImports.push(namedBindings); + } + else { + namedImports.push(namedBindings); + } + } + } + + // Normally, we don't combine default and namespace imports, but it would be silly to + // produce two import declarations in this special case. + if (defaultImports.length === 1 && namespaceImports.length === 1 && namedImports.length === 0) { + // Add the namespace import to the existing default ImportDeclaration. + const defaultImportClause = defaultImports[0].parent as ImportClause; + coalescedImports.push( + updateImportDeclarationAndClause(defaultImportClause, defaultImportClause.name, namespaceImports[0])); + + continue; + } + + // For convenience, we cheat and do a little sorting during coalescing. + // Seems reasonable since we're restructuring so much anyway. + const sortedNamespaceImports = stableSort(namespaceImports, (n1, n2) => compareIdentifiers(n1.name, n2.name)); + + for (const namespaceImport of sortedNamespaceImports) { + // Drop the name, if any + coalescedImports.push( + updateImportDeclarationAndClause(namespaceImport.parent, /*name*/ undefined, namespaceImport)); + } + + if (defaultImports.length === 0 && namedImports.length === 0) { + continue; + } + + let newDefaultImport: Identifier = undefined; + const newImportSpecifiers: ImportSpecifier[] = []; + if (defaultImports.length === 1) { + newDefaultImport = defaultImports[0]; + } + else { + for (const defaultImport of defaultImports) { + newImportSpecifiers.push( + createImportSpecifier(createIdentifier("default"), defaultImport)); + } + } + + for (const namedImport of namedImports) { + for (const specifier of namedImport.elements) { + newImportSpecifiers.push(specifier); + } + } + + const sortedImportSpecifiers = stableSort(newImportSpecifiers, (s1, s2) => { + const nameComparison = compareIdentifiers(s1.propertyName || s1.name, s2.propertyName || s2.name); + return nameComparison !== Comparison.EqualTo + ? nameComparison + : compareIdentifiers(s1.name, s2.name); + }); + + const importClause = defaultImports.length > 0 + ? defaultImports[0].parent as ImportClause + : namedImports[0].parent; + + const newNamedImports = sortedImportSpecifiers.length === 0 + ? undefined + : namedImports.length === 0 + ? createNamedImports(sortedImportSpecifiers) + : updateNamedImports(namedImports[0], sortedImportSpecifiers); + + coalescedImports.push( + updateImportDeclarationAndClause(importClause, newDefaultImport, newNamedImports)); + } + + return coalescedImports; + + // `undefined` is the min value. + function compareIdentifiers(s1: Identifier | undefined, s2: Identifier | undefined) { + return s1 === undefined + ? s2 === undefined + ? Comparison.EqualTo + : Comparison.LessThan + : s2 === undefined + ? Comparison.GreaterThan + : s1.text < s2.text + ? Comparison.LessThan + : s1.text > s2.text + ? Comparison.GreaterThan + : Comparison.EqualTo; + } + + function updateImportDeclarationAndClause( + importClause: ImportClause, + name: Identifier | undefined, + namedBindings: NamedImportBindings | undefined) { + + const importDeclaration = importClause.parent; + return updateImportDeclaration( + importDeclaration, + importDeclaration.decorators, + importDeclaration.modifiers, + updateImportClause(importClause, name, namedBindings), + importDeclaration.moduleSpecifier); + } + } +} \ No newline at end of file diff --git a/src/services/services.ts b/src/services/services.ts index 3b984c2e159..37cc192442f 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -14,6 +14,7 @@ /// /// /// +/// /// /// /// @@ -1854,50 +1855,7 @@ namespace ts { const sourceFile = getValidSourceFile(scope.fileName); const formatContext = formatting.getFormatContext(formatOptions); - // All of the (old) ImportDeclarations in the file, in syntactic order. - const oldImportDecls: ImportDeclaration[] = []; - - forEachChild(sourceFile, node => { - cancellationToken.throwIfCancellationRequested(); - if (isImportDeclaration(node)) { - oldImportDecls.push(node); - } - // TODO (https://github.com/Microsoft/TypeScript/issues/10020): sort *within* ambient modules (find using isAmbientModule) - }); - - if (oldImportDecls.length === 0) { - return []; - } - - const usedImportDecls = removeUnusedImports(oldImportDecls); - const sortedImportDecls = sortImports(usedImportDecls); - const coalescedImportDecls = coalesceImports(sortedImportDecls); - - // All of the (new) ImportDeclarations in the file, in sorted order. - const newImportDecls = coalescedImportDecls; - - const changeTracker = textChanges.ChangeTracker.fromContext({ host, formatContext }); - - // NB: Stopping before i === 0 - for (let i = oldImportDecls.length - 1; i > 0; i--) { - changeTracker.deleteNode(sourceFile, oldImportDecls[i]); - } - - if (newImportDecls.length === 0) { - changeTracker.deleteNode(sourceFile, oldImportDecls[0]); - } - else { - // Delete the surrounding trivia because it will have been retained in newImportDecls. - const replaceOptions = { - useNonAdjustedStartPosition: false, - useNonAdjustedEndPosition: false, - suffix: getNewLineOrDefaultFromHost(host, formatOptions), - }; - changeTracker.replaceNodeWithNodes(sourceFile, oldImportDecls[0], newImportDecls, replaceOptions); - } - - const changes = changeTracker.getChanges(); - return changes; + return OrganizeImports.organizeImports(sourceFile, formatContext, host, cancellationToken); } function applyCodeActionCommand(action: CodeActionCommand): Promise; @@ -2321,238 +2279,4 @@ namespace ts { } objectAllocator = getServicesObjectAllocator(); - - function removeUnusedImports(oldImports: ReadonlyArray) { - return oldImports; // TODO (https://github.com/Microsoft/TypeScript/issues/10020) - } - - /* @internal */ // Internal for testing - export function sortImports(oldImports: ReadonlyArray) { - if (oldImports.length < 2) { - return oldImports; - } - - // NB: declaration order determines sort order - const enum ModuleNameKind { - NonRelative, - Relative, - Invalid, - } - - const importRecords = oldImports.map(createImportRecord); - - const sortedRecords = stableSort(importRecords, (import1, import2) => { - const { name: name1, kind: kind1 } = import1; - const { name: name2, kind: kind2 } = import2; - - if (kind1 !== kind2) { - return kind1 < kind2 - ? Comparison.LessThan - : Comparison.GreaterThan; - } - - // Note that we're using simple equality, retaining case-sensitivity. - if (name1 !== name2) { - return name1 < name2 - ? Comparison.LessThan - : Comparison.GreaterThan; - } - - return Comparison.EqualTo; - }); - - return sortedRecords.map(r => r.importDeclaration); - - function createImportRecord(importDeclaration: ImportDeclaration) { - const specifier = importDeclaration.moduleSpecifier; - const name = getExternalModuleName(specifier); - if (name) { - const isRelative = isExternalModuleNameRelative(name); - return { importDeclaration, name, kind: isRelative ? ModuleNameKind.Relative : ModuleNameKind.NonRelative }; - } - - return { importDeclaration, name: specifier.getText(), kind: ModuleNameKind.Invalid }; - } - } - - function getExternalModuleName(specifier: Expression) { - return isStringLiteral(specifier) || isNoSubstitutionTemplateLiteral(specifier) - ? specifier.text - : undefined; - } - - /** - * @param sortedImports a non-empty list of ImportDeclarations, sorted by module name. - */ - function groupSortedImports(sortedImports: ReadonlyArray): ReadonlyArray> { - Debug.assert(length(sortedImports) > 0); - - const groups: ImportDeclaration[][] = []; - - let groupName: string | undefined = getExternalModuleName(sortedImports[0].moduleSpecifier); - let group: ImportDeclaration[] = []; - - for (const importDeclaration of sortedImports) { - const moduleName = getExternalModuleName(importDeclaration.moduleSpecifier); - if (moduleName && moduleName === groupName) { - group.push(importDeclaration); - } - else if (group.length) { - groups.push(group); - - groupName = moduleName; - group = [importDeclaration]; - } - } - - if (group.length) { - groups.push(group); - } - - return groups; - } - - /* @internal */ // Internal for testing - /** - * @param sortedImports a list of ImportDeclarations, sorted by module name. - */ - export function coalesceImports(sortedImports: ReadonlyArray) { - if (sortedImports.length === 0) { - return sortedImports; - } - - const coalescedImports: ImportDeclaration[] = []; - - const groupedImports = groupSortedImports(sortedImports); - for (const importGroup of groupedImports) { - - let seenImportWithoutClause = false; - - const defaultImports: Identifier[] = []; - const namespaceImports: NamespaceImport[] = []; - const namedImports: NamedImports[] = []; - - for (const importDeclaration of importGroup) { - if (importDeclaration.importClause === undefined) { - // Only the first such import is interesting - the others are redundant. - // Note: Unfortunately, we will lose trivia that was on this node. - if (!seenImportWithoutClause) { - coalescedImports.push(importDeclaration); - } - - seenImportWithoutClause = true; - continue; - } - - const { name, namedBindings } = importDeclaration.importClause; - - if (name) { - defaultImports.push(name); - } - - if (namedBindings) { - if (isNamespaceImport(namedBindings)) { - namespaceImports.push(namedBindings); - } - else { - namedImports.push(namedBindings); - } - } - } - - // Normally, we don't combine default and namespace imports, but it would be silly to - // produce two import declarations in this special case. - if (defaultImports.length === 1 && namespaceImports.length === 1 && namedImports.length === 0) { - // Add the namespace import to the existing default ImportDeclaration. - const defaultImportClause = defaultImports[0].parent as ImportClause; - coalescedImports.push( - updateImportDeclarationAndClause(defaultImportClause, defaultImportClause.name, namespaceImports[0])); - - continue; - } - - // For convenience, we cheat and do a little sorting during coalescing. - // Seems reasonable since we're restructuring so much anyway. - const sortedNamespaceImports = stableSort(namespaceImports, (n1, n2) => compareIdentifiers(n1.name, n2.name)); - - for (const namespaceImport of sortedNamespaceImports) { - // Drop the name, if any - coalescedImports.push( - updateImportDeclarationAndClause(namespaceImport.parent, /*name*/ undefined, namespaceImport)); - } - - if (defaultImports.length === 0 && namedImports.length === 0) { - continue; - } - - let newDefaultImport: Identifier = undefined; - const newImportSpecifiers: ImportSpecifier[] = []; - if (defaultImports.length === 1) { - newDefaultImport = defaultImports[0]; - } - else { - for (const defaultImport of defaultImports) { - newImportSpecifiers.push( - createImportSpecifier(createIdentifier("default"), defaultImport)); - } - } - - for (const namedImport of namedImports) { - for (const specifier of namedImport.elements) { - newImportSpecifiers.push(specifier); - } - } - - const sortedImportSpecifiers = stableSort(newImportSpecifiers, (s1, s2) => { - const nameComparison = compareIdentifiers(s1.propertyName || s1.name, s2.propertyName || s2.name); - return nameComparison !== Comparison.EqualTo - ? nameComparison - : compareIdentifiers(s1.name, s2.name); - }); - - const importClause = defaultImports.length > 0 - ? defaultImports[0].parent as ImportClause - : namedImports[0].parent; - - const newNamedImports = sortedImportSpecifiers.length === 0 - ? undefined - : namedImports.length === 0 - ? createNamedImports(sortedImportSpecifiers) - : updateNamedImports(namedImports[0], sortedImportSpecifiers); - - coalescedImports.push( - updateImportDeclarationAndClause(importClause, newDefaultImport, newNamedImports)); - } - - return coalescedImports; - - // `undefined` is the min value. - function compareIdentifiers(s1: Identifier | undefined, s2: Identifier | undefined) { - return s1 === undefined - ? s2 === undefined - ? Comparison.EqualTo - : Comparison.LessThan - : s2 === undefined - ? Comparison.GreaterThan - : s1.text < s2.text - ? Comparison.LessThan - : s1.text > s2.text - ? Comparison.GreaterThan - : Comparison.EqualTo; - } - - function updateImportDeclarationAndClause( - importClause: ImportClause, - name: Identifier | undefined, - namedBindings: NamedImportBindings | undefined) { - - const importDeclaration = importClause.parent; - return updateImportDeclaration( - importDeclaration, - importDeclaration.decorators, - importDeclaration.modifiers, - updateImportClause(importClause, name, namedBindings), - importDeclaration.moduleSpecifier); - } - } } From 5c278cee17008877f3805f70a214e17ba3f37949 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 14 Feb 2018 13:57:09 -0800 Subject: [PATCH 14/28] Address PR feedback Eliminate cancellation token Add organizeImports.ts to tsconfig.json Simplify ts.OrganizeImports.organizeImports Simplify sortImports Semantic change: all invalid module specifiers are now considered to be equal. Simplify comparisons using || Pull out imports with invalid modules specifiers ...for separate processing. They are tacked on to the end of the organized imports in their original order. Bonus: downstream functions can now assume imports have valid module specifiers. Rename baseline folder with leading lowercase Simplify coalesceImports Remove some unnecessary null checks Simplify baseline generation --- src/compiler/core.ts | 5 + src/harness/unittests/organizeImports.ts | 55 ++-- src/services/organizeImports.ts | 259 +++++++----------- src/services/services.ts | 2 +- src/services/tsconfig.json | 1 + .../organizeImports/MoveToTop_Invalid.ts | 22 ++ 6 files changed, 155 insertions(+), 189 deletions(-) create mode 100644 tests/baselines/reference/organizeImports/MoveToTop_Invalid.ts diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 212fa86b366..698824fa9b0 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1905,6 +1905,11 @@ namespace ts { Comparison.EqualTo; } + /** True is greater than false. */ + export function compareBooleans(a: boolean, b: boolean): Comparison { + return compareValues(a ? 1 : 0, b ? 1 : 0); + } + function compareMessageText(text1: string | DiagnosticMessageChain, text2: string | DiagnosticMessageChain): Comparison { while (text1 && text2) { // We still have both chains. diff --git a/src/harness/unittests/organizeImports.ts b/src/harness/unittests/organizeImports.ts index eaa21bbb72f..2accc84d43f 100644 --- a/src/harness/unittests/organizeImports.ts +++ b/src/harness/unittests/organizeImports.ts @@ -54,34 +54,12 @@ namespace ts { `import x from "./lib2";`); }); - it("Sort - invalid vs invalid", () => { - assertSortsBefore( - // tslint:disable-next-line no-invalid-template-strings - "import y from `${'lib1'}`;", - // tslint:disable-next-line no-invalid-template-strings - "import x from `${'lib2'}`;"); - }); - it("Sort - relative vs non-relative", () => { assertSortsBefore( `import y from "lib";`, `import x from "./lib";`); }); - it("Sort - non-relative vs invalid", () => { - assertSortsBefore( - `import y from "lib";`, - // tslint:disable-next-line no-invalid-template-strings - "import x from `${'lib'}`;"); - }); - - it("Sort - relative vs invalid", () => { - assertSortsBefore( - `import y from "./lib";`, - // tslint:disable-next-line no-invalid-template-strings - "import x from `${'lib'}`;"); - }); - function assertUnaffectedBySort(...importStrings: string[]) { const unsortedImports1 = parseImports(...importStrings); assertListEqual(unsortedImports1, OrganizeImports.sortImports(unsortedImports1)); @@ -286,6 +264,25 @@ D(); }, libFile); + // tslint:disable no-invalid-template-strings + testOrganizeImports("MoveToTop_Invalid", + { + path: "/test.ts", + content: ` +import { F1, F2 } from "lib"; +F1(); +F2(); +import * as NS from "lib"; +NS.F1(); +import b from ${"`${'lib'}`"}; +import a from ${"`${'lib'}`"}; +import D from "lib"; +D(); +`, + }, + libFile); + // tslint:enable no-invalid-template-strings + testOrganizeImports("CoalesceTrivia", { path: "/test.ts", @@ -322,15 +319,13 @@ F2(); assert.equal(testPath, changes[0].fileName); Harness.Baseline.runBaseline(baselinePath, () => { - const data: string[] = []; - data.push(`// ==ORIGINAL==`); - data.push(testContent); - - data.push(`// ==ORGANIZED==`); const newText = textChanges.applyChanges(testContent, changes[0].textChanges); - data.push(newText); - - return data.join(newLineCharacter); + return [ + "// ==ORIGINAL==", + testContent, + "// ==ORGANIZED==", + newText, + ].join(newLineCharacter); }); } diff --git a/src/services/organizeImports.ts b/src/services/organizeImports.ts index aaff3331941..d6b782a19aa 100644 --- a/src/services/organizeImports.ts +++ b/src/services/organizeImports.ts @@ -3,56 +3,44 @@ namespace ts.OrganizeImports { export function organizeImports( sourceFile: SourceFile, formatContext: formatting.FormatContext, - host: LanguageServiceHost, - cancellationToken: CancellationToken) { + host: LanguageServiceHost) { - // All of the (old) ImportDeclarations in the file, in syntactic order. - const oldImportDecls: ImportDeclaration[] = []; + // TODO (https://github.com/Microsoft/TypeScript/issues/10020): sort *within* ambient modules (find using isAmbientModule) - forEachChild(sourceFile, node => { - cancellationToken.throwIfCancellationRequested(); - if (isImportDeclaration(node)) { - oldImportDecls.push(node); - } - // TODO (https://github.com/Microsoft/TypeScript/issues/10020): sort *within* ambient modules (find using isAmbientModule) - }); + // All of the old ImportDeclarations in the file, in syntactic order. + const oldImportDecls = sourceFile.statements.filter(isImportDeclaration); if (oldImportDecls.length === 0) { return []; } - const usedImportDecls = removeUnusedImports(oldImportDecls); - cancellationToken.throwIfCancellationRequested(); - const sortedImportDecls = sortImports(usedImportDecls); - cancellationToken.throwIfCancellationRequested(); - const coalescedImportDecls = coalesceImports(sortedImportDecls); - cancellationToken.throwIfCancellationRequested(); + const oldValidImportDecls = oldImportDecls.filter(importDecl => getExternalModuleName(importDecl.moduleSpecifier)); + const oldInvalidImportDecls = oldImportDecls.filter(importDecl => !getExternalModuleName(importDecl.moduleSpecifier)); - // All of the (new) ImportDeclarations in the file, in sorted order. - const newImportDecls = coalescedImportDecls; + // All of the new ImportDeclarations in the file, in sorted order. + const newImportDecls = coalesceImports(sortImports(removeUnusedImports(oldValidImportDecls))).concat(oldInvalidImportDecls); const changeTracker = textChanges.ChangeTracker.fromContext({ host, formatContext }); - // NB: Stopping before i === 0 - for (let i = oldImportDecls.length - 1; i > 0; i--) { - changeTracker.deleteNode(sourceFile, oldImportDecls[i]); - } - + // Delete or replace the first import. if (newImportDecls.length === 0) { changeTracker.deleteNode(sourceFile, oldImportDecls[0]); } else { - // Delete the surrounding trivia because it will have been retained in newImportDecls. - const replaceOptions = { + // Note: Delete the surrounding trivia because it will have been retained in newImportDecls. + changeTracker.replaceNodeWithNodes(sourceFile, oldImportDecls[0], newImportDecls, { useNonAdjustedStartPosition: false, useNonAdjustedEndPosition: false, suffix: getNewLineOrDefaultFromHost(host, formatContext.options), - }; - changeTracker.replaceNodeWithNodes(sourceFile, oldImportDecls[0], newImportDecls, replaceOptions); + }); } - const changes = changeTracker.getChanges(); - return changes; + // Delete any subsequent imports. + for (let i = 1; i < oldImportDecls.length; i++) { + changeTracker.deleteNode(sourceFile, oldImportDecls[i]); + } + + return changeTracker.getChanges(); } function removeUnusedImports(oldImports: ReadonlyArray) { @@ -61,51 +49,14 @@ namespace ts.OrganizeImports { /* @internal */ // Internal for testing export function sortImports(oldImports: ReadonlyArray) { - if (oldImports.length < 2) { - return oldImports; - } - - // NB: declaration order determines sort order - const enum ModuleNameKind { - NonRelative, - Relative, - Invalid, - } - - const importRecords = oldImports.map(createImportRecord); - - const sortedRecords = stableSort(importRecords, (import1, import2) => { - const { name: name1, kind: kind1 } = import1; - const { name: name2, kind: kind2 } = import2; - - if (kind1 !== kind2) { - return kind1 < kind2 - ? Comparison.LessThan - : Comparison.GreaterThan; - } - - // Note that we're using simple equality, retaining case-sensitivity. - if (name1 !== name2) { - return name1 < name2 - ? Comparison.LessThan - : Comparison.GreaterThan; - } - - return Comparison.EqualTo; + return stableSort(oldImports, (import1, import2) => { + const name1 = getExternalModuleName(import1.moduleSpecifier); + const name2 = getExternalModuleName(import2.moduleSpecifier); + Debug.assert(name1 !== undefined); + Debug.assert(name2 !== undefined); + return compareBooleans(isExternalModuleNameRelative(name1), isExternalModuleNameRelative(name2)) || + compareStringsCaseSensitive(name1, name2); }); - - return sortedRecords.map(r => r.importDeclaration); - - function createImportRecord(importDeclaration: ImportDeclaration) { - const specifier = importDeclaration.moduleSpecifier; - const name = getExternalModuleName(specifier); - if (name) { - const isRelative = isExternalModuleNameRelative(name); - return { importDeclaration, name, kind: isRelative ? ModuleNameKind.Relative : ModuleNameKind.NonRelative }; - } - - return { importDeclaration, name: specifier.getText(), kind: ModuleNameKind.Invalid }; - } } function getExternalModuleName(specifier: Expression) { @@ -123,11 +74,13 @@ namespace ts.OrganizeImports { const groups: ImportDeclaration[][] = []; let groupName: string | undefined = getExternalModuleName(sortedImports[0].moduleSpecifier); + Debug.assert(groupName !== undefined); let group: ImportDeclaration[] = []; for (const importDeclaration of sortedImports) { const moduleName = getExternalModuleName(importDeclaration.moduleSpecifier); - if (moduleName && moduleName === groupName) { + Debug.assert(moduleName !== undefined); + if (moduleName === groupName) { group.push(importDeclaration); } else if (group.length) { @@ -159,8 +112,71 @@ namespace ts.OrganizeImports { const groupedImports = groupSortedImports(sortedImports); for (const importGroup of groupedImports) { - let seenImportWithoutClause = false; + const { importWithoutClause, defaultImports, namespaceImports, namedImports } = getImportParts(importGroup); + if (importWithoutClause) { + coalescedImports.push(importWithoutClause); + } + + // Normally, we don't combine default and namespace imports, but it would be silly to + // produce two import declarations in this special case. + if (defaultImports.length === 1 && namespaceImports.length === 1 && namedImports.length === 0) { + // Add the namespace import to the existing default ImportDeclaration. + const defaultImportClause = defaultImports[0].parent as ImportClause; + coalescedImports.push( + updateImportDeclarationAndClause(defaultImportClause, defaultImportClause.name, namespaceImports[0])); + + continue; + } + + const sortedNamespaceImports = stableSort(namespaceImports, (n1, n2) => compareIdentifiers(n1.name, n2.name)); + + for (const namespaceImport of sortedNamespaceImports) { + // Drop the name, if any + coalescedImports.push( + updateImportDeclarationAndClause(namespaceImport.parent, /*name*/ undefined, namespaceImport)); + } + + if (defaultImports.length === 0 && namedImports.length === 0) { + continue; + } + + let newDefaultImport: Identifier | undefined; + const newImportSpecifiers: ImportSpecifier[] = []; + if (defaultImports.length === 1) { + newDefaultImport = defaultImports[0]; + } + else { + for (const defaultImport of defaultImports) { + newImportSpecifiers.push( + createImportSpecifier(createIdentifier("default"), defaultImport)); + } + } + + newImportSpecifiers.push(...flatMap(namedImports, n => n.elements)); + + const sortedImportSpecifiers = stableSort(newImportSpecifiers, (s1, s2) => + compareIdentifiers(s1.propertyName || s1.name, s2.propertyName || s2.name) || + compareIdentifiers(s1.name, s2.name)); + + const importClause = defaultImports.length > 0 + ? defaultImports[0].parent as ImportClause + : namedImports[0].parent; + + const newNamedImports = sortedImportSpecifiers.length === 0 + ? undefined + : namedImports.length === 0 + ? createNamedImports(sortedImportSpecifiers) + : updateNamedImports(namedImports[0], sortedImportSpecifiers); + + coalescedImports.push( + updateImportDeclarationAndClause(importClause, newDefaultImport, newNamedImports)); + } + + return coalescedImports; + + function getImportParts(importGroup: ReadonlyArray) { + let importWithoutClause: ImportDeclaration | undefined; const defaultImports: Identifier[] = []; const namespaceImports: NamespaceImport[] = []; const namedImports: NamedImports[] = []; @@ -169,11 +185,7 @@ namespace ts.OrganizeImports { if (importDeclaration.importClause === undefined) { // Only the first such import is interesting - the others are redundant. // Note: Unfortunately, we will lose trivia that was on this node. - if (!seenImportWithoutClause) { - coalescedImports.push(importDeclaration); - } - - seenImportWithoutClause = true; + importWithoutClause = importWithoutClause || importDeclaration; continue; } @@ -193,85 +205,16 @@ namespace ts.OrganizeImports { } } - // Normally, we don't combine default and namespace imports, but it would be silly to - // produce two import declarations in this special case. - if (defaultImports.length === 1 && namespaceImports.length === 1 && namedImports.length === 0) { - // Add the namespace import to the existing default ImportDeclaration. - const defaultImportClause = defaultImports[0].parent as ImportClause; - coalescedImports.push( - updateImportDeclarationAndClause(defaultImportClause, defaultImportClause.name, namespaceImports[0])); - - continue; - } - - // For convenience, we cheat and do a little sorting during coalescing. - // Seems reasonable since we're restructuring so much anyway. - const sortedNamespaceImports = stableSort(namespaceImports, (n1, n2) => compareIdentifiers(n1.name, n2.name)); - - for (const namespaceImport of sortedNamespaceImports) { - // Drop the name, if any - coalescedImports.push( - updateImportDeclarationAndClause(namespaceImport.parent, /*name*/ undefined, namespaceImport)); - } - - if (defaultImports.length === 0 && namedImports.length === 0) { - continue; - } - - let newDefaultImport: Identifier = undefined; - const newImportSpecifiers: ImportSpecifier[] = []; - if (defaultImports.length === 1) { - newDefaultImport = defaultImports[0]; - } - else { - for (const defaultImport of defaultImports) { - newImportSpecifiers.push( - createImportSpecifier(createIdentifier("default"), defaultImport)); - } - } - - for (const namedImport of namedImports) { - for (const specifier of namedImport.elements) { - newImportSpecifiers.push(specifier); - } - } - - const sortedImportSpecifiers = stableSort(newImportSpecifiers, (s1, s2) => { - const nameComparison = compareIdentifiers(s1.propertyName || s1.name, s2.propertyName || s2.name); - return nameComparison !== Comparison.EqualTo - ? nameComparison - : compareIdentifiers(s1.name, s2.name); - }); - - const importClause = defaultImports.length > 0 - ? defaultImports[0].parent as ImportClause - : namedImports[0].parent; - - const newNamedImports = sortedImportSpecifiers.length === 0 - ? undefined - : namedImports.length === 0 - ? createNamedImports(sortedImportSpecifiers) - : updateNamedImports(namedImports[0], sortedImportSpecifiers); - - coalescedImports.push( - updateImportDeclarationAndClause(importClause, newDefaultImport, newNamedImports)); + return { + importWithoutClause, + defaultImports, + namespaceImports, + namedImports, + }; } - return coalescedImports; - - // `undefined` is the min value. - function compareIdentifiers(s1: Identifier | undefined, s2: Identifier | undefined) { - return s1 === undefined - ? s2 === undefined - ? Comparison.EqualTo - : Comparison.LessThan - : s2 === undefined - ? Comparison.GreaterThan - : s1.text < s2.text - ? Comparison.LessThan - : s1.text > s2.text - ? Comparison.GreaterThan - : Comparison.EqualTo; + function compareIdentifiers(s1: Identifier, s2: Identifier) { + return compareStringsCaseSensitive(s1.text, s2.text); } function updateImportDeclarationAndClause( diff --git a/src/services/services.ts b/src/services/services.ts index 37cc192442f..b5d6f0ec2a6 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1855,7 +1855,7 @@ namespace ts { const sourceFile = getValidSourceFile(scope.fileName); const formatContext = formatting.getFormatContext(formatOptions); - return OrganizeImports.organizeImports(sourceFile, formatContext, host, cancellationToken); + return OrganizeImports.organizeImports(sourceFile, formatContext, host); } function applyCodeActionCommand(action: CodeActionCommand): Promise; diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index ef0d68b2041..bbd88a1a004 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -58,6 +58,7 @@ "jsTyping.ts", "navigateTo.ts", "navigationBar.ts", + "organizeImports.ts", "outliningElementsCollector.ts", "pathCompletions.ts", "patternMatcher.ts", diff --git a/tests/baselines/reference/organizeImports/MoveToTop_Invalid.ts b/tests/baselines/reference/organizeImports/MoveToTop_Invalid.ts new file mode 100644 index 00000000000..e2372f680cf --- /dev/null +++ b/tests/baselines/reference/organizeImports/MoveToTop_Invalid.ts @@ -0,0 +1,22 @@ +// ==ORIGINAL== + +import { F1, F2 } from "lib"; +F1(); +F2(); +import * as NS from "lib"; +NS.F1(); +import b from `${'lib'}`; +import a from `${'lib'}`; +import D from "lib"; +D(); + +// ==ORGANIZED== + +import * as NS from "lib"; +import D, { F1, F2 } from "lib"; +import b from `${'lib'}`; +import a from `${'lib'}`; +F1(); +F2(); +NS.F1(); +D(); From 7a313947880ba57b0628b78c158ba9210b614d89 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Thu, 15 Feb 2018 15:06:34 -0800 Subject: [PATCH 15/28] Group imports before sorting and coalescing --- src/harness/unittests/organizeImports.ts | 128 ++++-------- src/services/organizeImports.ts | 194 +++++++----------- .../CoalesceMultipleModules.ts | 11 + 3 files changed, 133 insertions(+), 200 deletions(-) create mode 100644 tests/baselines/reference/OrganizeImports/CoalesceMultipleModules.ts diff --git a/src/harness/unittests/organizeImports.ts b/src/harness/unittests/organizeImports.ts index 2accc84d43f..8d7b0904eb7 100644 --- a/src/harness/unittests/organizeImports.ts +++ b/src/harness/unittests/organizeImports.ts @@ -5,43 +5,6 @@ namespace ts { describe("Organize imports", () => { describe("Sort imports", () => { - it("No imports", () => { - assert.isEmpty(OrganizeImports.sortImports([])); - }); - - it("One import", () => { - const unsortedImports = parseImports(`import "lib";`); - const actualSortedImports = OrganizeImports.sortImports(unsortedImports); - const expectedSortedImports = unsortedImports; - assertListEqual(expectedSortedImports, actualSortedImports); - }); - - it("Stable - import kind", () => { - assertUnaffectedBySort( - `import "lib";`, - `import * as x from "lib";`, - `import x from "lib";`, - `import {x} from "lib";`); - }); - - it("Stable - default property alias", () => { - assertUnaffectedBySort( - `import x from "lib";`, - `import y from "lib";`); - }); - - it("Stable - module alias", () => { - assertUnaffectedBySort( - `import * as x from "lib";`, - `import * as y from "lib";`); - }); - - it("Stable - symbol", () => { - assertUnaffectedBySort( - `import {x} from "lib";`, - `import {y} from "lib";`); - }); - it("Sort - non-relative vs non-relative", () => { assertSortsBefore( `import y from "lib1";`, @@ -60,18 +23,10 @@ namespace ts { `import x from "./lib";`); }); - function assertUnaffectedBySort(...importStrings: string[]) { - const unsortedImports1 = parseImports(...importStrings); - assertListEqual(unsortedImports1, OrganizeImports.sortImports(unsortedImports1)); - - const unsortedImports2 = reverse(unsortedImports1); - assertListEqual(unsortedImports2, OrganizeImports.sortImports(unsortedImports2)); - } - function assertSortsBefore(importString1: string, importString2: string) { - const imports = parseImports(importString1, importString2); - assertListEqual(imports, OrganizeImports.sortImports(imports)); - assertListEqual(imports, OrganizeImports.sortImports(reverse(imports))); + const [{moduleSpecifier: moduleSpecifier1}, {moduleSpecifier: moduleSpecifier2}] = parseImports(importString1, importString2); + assert.equal(OrganizeImports.compareModuleSpecifiers(moduleSpecifier1, moduleSpecifier2), Comparison.LessThan); + assert.equal(OrganizeImports.compareModuleSpecifiers(moduleSpecifier2, moduleSpecifier1), Comparison.GreaterThan); } }); @@ -84,7 +39,7 @@ namespace ts { const sortedImports = parseImports(`import { default as m, a as n, b, y, z as o } from "lib";`); const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = parseImports(`import { a as n, b, default as m, y, z as o } from "lib";`); - assertListEqual(expectedCoalescedImports, actualCoalescedImports); + assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine side-effect-only imports", () => { @@ -93,7 +48,7 @@ namespace ts { `import "lib";`); const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = parseImports(`import "lib";`); - assertListEqual(expectedCoalescedImports, actualCoalescedImports); + assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine namespace imports", () => { @@ -102,7 +57,7 @@ namespace ts { `import * as y from "lib";`); const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = sortedImports; - assertListEqual(expectedCoalescedImports, actualCoalescedImports); + assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine default imports", () => { @@ -111,7 +66,7 @@ namespace ts { `import y from "lib";`); const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = parseImports(`import { default as x, default as y } from "lib";`); - assertListEqual(expectedCoalescedImports, actualCoalescedImports); + assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine property imports", () => { @@ -120,7 +75,7 @@ namespace ts { `import { y as z } from "lib";`); const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = parseImports(`import { x, y as z } from "lib";`); - assertListEqual(expectedCoalescedImports, actualCoalescedImports); + assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine side-effect-only import with namespace import", () => { @@ -129,7 +84,7 @@ namespace ts { `import * as x from "lib";`); const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = sortedImports; - assertListEqual(expectedCoalescedImports, actualCoalescedImports); + assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine side-effect-only import with default import", () => { @@ -138,7 +93,7 @@ namespace ts { `import x from "lib";`); const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = sortedImports; - assertListEqual(expectedCoalescedImports, actualCoalescedImports); + assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine side-effect-only import with property import", () => { @@ -147,7 +102,7 @@ namespace ts { `import { x } from "lib";`); const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = sortedImports; - assertListEqual(expectedCoalescedImports, actualCoalescedImports); + assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine namespace import with default import", () => { @@ -157,7 +112,7 @@ namespace ts { const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = parseImports( `import y, * as x from "lib";`); - assertListEqual(expectedCoalescedImports, actualCoalescedImports); + assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine namespace import with property import", () => { @@ -166,7 +121,7 @@ namespace ts { `import { y } from "lib";`); const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = sortedImports; - assertListEqual(expectedCoalescedImports, actualCoalescedImports); + assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine default import with property import", () => { @@ -176,7 +131,7 @@ namespace ts { const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = parseImports( `import x, { y } from "lib";`); - assertListEqual(expectedCoalescedImports, actualCoalescedImports); + assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine many imports", () => { @@ -195,20 +150,7 @@ namespace ts { `import * as x from "lib";`, `import * as y from "lib";`, `import { a, b, default as w, default as z } from "lib";`); - assertListEqual(expectedCoalescedImports, actualCoalescedImports); - }); - - it("Combine imports from different modules", () => { - const sortedImports = parseImports( - `import { d } from "lib1";`, - `import { b } from "lib1";`, - `import { c } from "lib2";`, - `import { a } from "lib2";`); - const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); - const expectedCoalescedImports = parseImports( - `import { b, d } from "lib1";`, - `import { a, c } from "lib2";`); - assertListEqual(expectedCoalescedImports, actualCoalescedImports); + assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); // This is descriptive, rather than normative @@ -219,7 +161,7 @@ namespace ts { `import z from "lib";`); const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = sortedImports; - assertListEqual(expectedCoalescedImports, actualCoalescedImports); + assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); }); @@ -233,6 +175,17 @@ export default function F2(); `, }; + // Don't bother to actually emit a baseline for this. + it("NoImports", () => { + const testFile = { + path: "/a.ts", + content: "function F() { }", + }; + const languageService = makeLanguageService(testFile); + const changes = languageService.organizeImports({ type: "file", fileName: testFile.path }, testFormatOptions); + assert.isEmpty(changes); + }); + testOrganizeImports("Simple", { path: "/test.ts", @@ -283,6 +236,19 @@ D(); libFile); // tslint:enable no-invalid-template-strings + testOrganizeImports("CoalesceMultipleModules", + { + path: "/test.ts", + content: ` +import { d } from "lib1"; +import { b } from "lib1"; +import { c } from "lib2"; +import { a } from "lib2"; +`, + }, + { path: "/lib1.ts", content: "" }, + { path: "/lib2.ts", content: "" }); + testOrganizeImports("CoalesceTrivia", { path: "/test.ts", @@ -315,8 +281,8 @@ F2(); const { path: testPath, content: testContent } = testFile; const languageService = makeLanguageService(testFile, ...otherFiles); const changes = languageService.organizeImports({ type: "file", fileName: testPath }, testFormatOptions); - assert.equal(1, changes.length); - assert.equal(testPath, changes[0].fileName); + assert.equal(changes.length, 1); + assert.equal(changes[0].fileName, testPath); Harness.Baseline.runBaseline(baselinePath, () => { const newText = textChanges.applyChanges(testContent, changes[0].textChanges); @@ -340,7 +306,7 @@ F2(); function parseImports(...importStrings: string[]): ReadonlyArray { const sourceFile = createSourceFile("a.ts", importStrings.join("\n"), ScriptTarget.ES2015, /*setParentNodes*/ true, ScriptKind.TS); const imports = filter(sourceFile.statements, isImportDeclaration); - assert.equal(importStrings.length, imports.length); + assert.equal(imports.length, importStrings.length); return imports; } @@ -414,13 +380,5 @@ F2(); assertEqual(list1[i], list2[i]); } } - - function reverse(list: ReadonlyArray) { - const result = []; - for (let i = list.length - 1; i >= 0; i--) { - result.push(list[i]); - } - return result; - } }); } \ No newline at end of file diff --git a/src/services/organizeImports.ts b/src/services/organizeImports.ts index d6b782a19aa..e75db1aa59d 100644 --- a/src/services/organizeImports.ts +++ b/src/services/organizeImports.ts @@ -14,11 +14,15 @@ namespace ts.OrganizeImports { return []; } - const oldValidImportDecls = oldImportDecls.filter(importDecl => getExternalModuleName(importDecl.moduleSpecifier)); - const oldInvalidImportDecls = oldImportDecls.filter(importDecl => !getExternalModuleName(importDecl.moduleSpecifier)); + const oldImportGroups = group(oldImportDecls, importDecl => getExternalModuleName(importDecl.moduleSpecifier)); - // All of the new ImportDeclarations in the file, in sorted order. - const newImportDecls = coalesceImports(sortImports(removeUnusedImports(oldValidImportDecls))).concat(oldInvalidImportDecls); + const sortedImportGroups = stableSort(oldImportGroups, (group1, group2) => + compareModuleSpecifiers(group1[0].moduleSpecifier, group2[0].moduleSpecifier)); + + const newImportDecls = flatMap(sortedImportGroups, importGroup => + getExternalModuleName(importGroup[0].moduleSpecifier) + ? coalesceImports(removeUnusedImports(importGroup)) + : importGroup); const changeTracker = textChanges.ChangeTracker.fromContext({ host, formatContext }); @@ -47,132 +51,83 @@ namespace ts.OrganizeImports { return oldImports; // TODO (https://github.com/Microsoft/TypeScript/issues/10020) } - /* @internal */ // Internal for testing - export function sortImports(oldImports: ReadonlyArray) { - return stableSort(oldImports, (import1, import2) => { - const name1 = getExternalModuleName(import1.moduleSpecifier); - const name2 = getExternalModuleName(import2.moduleSpecifier); - Debug.assert(name1 !== undefined); - Debug.assert(name2 !== undefined); - return compareBooleans(isExternalModuleNameRelative(name1), isExternalModuleNameRelative(name2)) || - compareStringsCaseSensitive(name1, name2); - }); - } - function getExternalModuleName(specifier: Expression) { return isStringLiteral(specifier) || isNoSubstitutionTemplateLiteral(specifier) ? specifier.text : undefined; } - /** - * @param sortedImports a non-empty list of ImportDeclarations, sorted by module name. - */ - function groupSortedImports(sortedImports: ReadonlyArray): ReadonlyArray> { - Debug.assert(length(sortedImports) > 0); - - const groups: ImportDeclaration[][] = []; - - let groupName: string | undefined = getExternalModuleName(sortedImports[0].moduleSpecifier); - Debug.assert(groupName !== undefined); - let group: ImportDeclaration[] = []; - - for (const importDeclaration of sortedImports) { - const moduleName = getExternalModuleName(importDeclaration.moduleSpecifier); - Debug.assert(moduleName !== undefined); - if (moduleName === groupName) { - group.push(importDeclaration); - } - else if (group.length) { - groups.push(group); - - groupName = moduleName; - group = [importDeclaration]; - } - } - - if (group.length) { - groups.push(group); - } - - return groups; - } - /* @internal */ // Internal for testing /** - * @param sortedImports a list of ImportDeclarations, sorted by module name. + * @param importGroup a list of ImportDeclarations, all with the same module name. */ - export function coalesceImports(sortedImports: ReadonlyArray) { - if (sortedImports.length === 0) { - return sortedImports; + export function coalesceImports(importGroup: ReadonlyArray) { + if (importGroup.length === 0) { + return importGroup; } + const { importWithoutClause, defaultImports, namespaceImports, namedImports } = getImportParts(importGroup); + const coalescedImports: ImportDeclaration[] = []; - const groupedImports = groupSortedImports(sortedImports); - for (const importGroup of groupedImports) { - - const { importWithoutClause, defaultImports, namespaceImports, namedImports } = getImportParts(importGroup); - - if (importWithoutClause) { - coalescedImports.push(importWithoutClause); - } - - // Normally, we don't combine default and namespace imports, but it would be silly to - // produce two import declarations in this special case. - if (defaultImports.length === 1 && namespaceImports.length === 1 && namedImports.length === 0) { - // Add the namespace import to the existing default ImportDeclaration. - const defaultImportClause = defaultImports[0].parent as ImportClause; - coalescedImports.push( - updateImportDeclarationAndClause(defaultImportClause, defaultImportClause.name, namespaceImports[0])); - - continue; - } - - const sortedNamespaceImports = stableSort(namespaceImports, (n1, n2) => compareIdentifiers(n1.name, n2.name)); - - for (const namespaceImport of sortedNamespaceImports) { - // Drop the name, if any - coalescedImports.push( - updateImportDeclarationAndClause(namespaceImport.parent, /*name*/ undefined, namespaceImport)); - } - - if (defaultImports.length === 0 && namedImports.length === 0) { - continue; - } - - let newDefaultImport: Identifier | undefined; - const newImportSpecifiers: ImportSpecifier[] = []; - if (defaultImports.length === 1) { - newDefaultImport = defaultImports[0]; - } - else { - for (const defaultImport of defaultImports) { - newImportSpecifiers.push( - createImportSpecifier(createIdentifier("default"), defaultImport)); - } - } - - newImportSpecifiers.push(...flatMap(namedImports, n => n.elements)); - - const sortedImportSpecifiers = stableSort(newImportSpecifiers, (s1, s2) => - compareIdentifiers(s1.propertyName || s1.name, s2.propertyName || s2.name) || - compareIdentifiers(s1.name, s2.name)); - - const importClause = defaultImports.length > 0 - ? defaultImports[0].parent as ImportClause - : namedImports[0].parent; - - const newNamedImports = sortedImportSpecifiers.length === 0 - ? undefined - : namedImports.length === 0 - ? createNamedImports(sortedImportSpecifiers) - : updateNamedImports(namedImports[0], sortedImportSpecifiers); - - coalescedImports.push( - updateImportDeclarationAndClause(importClause, newDefaultImport, newNamedImports)); + if (importWithoutClause) { + coalescedImports.push(importWithoutClause); } + // Normally, we don't combine default and namespace imports, but it would be silly to + // produce two import declarations in this special case. + if (defaultImports.length === 1 && namespaceImports.length === 1 && namedImports.length === 0) { + // Add the namespace import to the existing default ImportDeclaration. + const defaultImportClause = defaultImports[0].parent as ImportClause; + coalescedImports.push( + updateImportDeclarationAndClause(defaultImportClause, defaultImportClause.name, namespaceImports[0])); + + return coalescedImports; + } + + const sortedNamespaceImports = stableSort(namespaceImports, (n1, n2) => compareIdentifiers(n1.name, n2.name)); + + for (const namespaceImport of sortedNamespaceImports) { + // Drop the name, if any + coalescedImports.push( + updateImportDeclarationAndClause(namespaceImport.parent, /*name*/ undefined, namespaceImport)); + } + + if (defaultImports.length === 0 && namedImports.length === 0) { + return coalescedImports; + } + + let newDefaultImport: Identifier | undefined; + const newImportSpecifiers: ImportSpecifier[] = []; + if (defaultImports.length === 1) { + newDefaultImport = defaultImports[0]; + } + else { + for (const defaultImport of defaultImports) { + newImportSpecifiers.push( + createImportSpecifier(createIdentifier("default"), defaultImport)); + } + } + + newImportSpecifiers.push(...flatMap(namedImports, n => n.elements)); + + const sortedImportSpecifiers = stableSort(newImportSpecifiers, (s1, s2) => + compareIdentifiers(s1.propertyName || s1.name, s2.propertyName || s2.name) || + compareIdentifiers(s1.name, s2.name)); + + const importClause = defaultImports.length > 0 + ? defaultImports[0].parent as ImportClause + : namedImports[0].parent; + + const newNamedImports = sortedImportSpecifiers.length === 0 + ? undefined + : namedImports.length === 0 + ? createNamedImports(sortedImportSpecifiers) + : updateNamedImports(namedImports[0], sortedImportSpecifiers); + + coalescedImports.push( + updateImportDeclarationAndClause(importClause, newDefaultImport, newNamedImports)); + return coalescedImports; function getImportParts(importGroup: ReadonlyArray) { @@ -231,4 +186,13 @@ namespace ts.OrganizeImports { importDeclaration.moduleSpecifier); } } + + /* internal */ // Exported for testing + export function compareModuleSpecifiers(m1: Expression, m2: Expression) { + const name1 = getExternalModuleName(m1); + const name2 = getExternalModuleName(m2); + return compareBooleans(name1 === undefined, name2 === undefined) || + compareBooleans(isExternalModuleNameRelative(name1), isExternalModuleNameRelative(name2)) || + compareStringsCaseSensitive(name1, name2); + } } \ No newline at end of file diff --git a/tests/baselines/reference/OrganizeImports/CoalesceMultipleModules.ts b/tests/baselines/reference/OrganizeImports/CoalesceMultipleModules.ts new file mode 100644 index 00000000000..6278722f2a9 --- /dev/null +++ b/tests/baselines/reference/OrganizeImports/CoalesceMultipleModules.ts @@ -0,0 +1,11 @@ +// ==ORIGINAL== + +import { d } from "lib1"; +import { b } from "lib1"; +import { c } from "lib2"; +import { a } from "lib2"; + +// ==ORGANIZED== + +import { b, d } from "lib1"; +import { a, c } from "lib2"; From 7e8dab681a40ba3345508c425dae2fd81f6fbe2a Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 16 Feb 2018 14:00:10 -0800 Subject: [PATCH 16/28] typingsInstaller:Remove triple-slash references (#21982) Replace them with an explicit list of files in tsconfig. I got this list by adding --listFiles to the jake-generated command. --- src/server/typingsInstaller/nodeTypingsInstaller.ts | 1 - src/server/typingsInstaller/tsconfig.json | 12 ++++++++++++ src/server/typingsInstaller/typingsInstaller.ts | 9 +-------- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/server/typingsInstaller/nodeTypingsInstaller.ts b/src/server/typingsInstaller/nodeTypingsInstaller.ts index e51ec68561c..b0844b2369c 100644 --- a/src/server/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/server/typingsInstaller/nodeTypingsInstaller.ts @@ -1,4 +1,3 @@ -/// /// namespace ts.server.typingsInstaller { diff --git a/src/server/typingsInstaller/tsconfig.json b/src/server/typingsInstaller/tsconfig.json index 4cfa26f8d9c..1606fbf3592 100644 --- a/src/server/typingsInstaller/tsconfig.json +++ b/src/server/typingsInstaller/tsconfig.json @@ -12,6 +12,18 @@ ] }, "files": [ + "../../compiler/types.ts", + "../../compiler/performance.ts", + "../../compiler/core.ts", + "../../compiler/sys.ts", + "../../compiler/diagnosticInformationMap.generated.ts", + "../../compiler/utilities.ts", + "../../compiler/scanner.ts", + "../../compiler/parser.ts", + "../../compiler/commandLineParser.ts", + "../../compiler/moduleNameResolver.ts", + "../../services/semver.ts", + "../../services/jsTyping.ts", "../types.ts", "../shared.ts", "typingsInstaller.ts", diff --git a/src/server/typingsInstaller/typingsInstaller.ts b/src/server/typingsInstaller/typingsInstaller.ts index 465f281006e..059967ecb4d 100644 --- a/src/server/typingsInstaller/typingsInstaller.ts +++ b/src/server/typingsInstaller/typingsInstaller.ts @@ -1,10 +1,3 @@ -/// -/// -/// -/// -/// -/// - namespace ts.server.typingsInstaller { interface NpmConfig { devDependencies: MapLike; @@ -413,4 +406,4 @@ namespace ts.server.typingsInstaller { } const latestDistTag = "latest"; -} \ No newline at end of file +} From 9c2b95dae3378f2b41abfee7fde9e8d1ecc6aeee Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Fri, 16 Feb 2018 14:49:23 -0800 Subject: [PATCH 17/28] Make FAR handle non-existent imported symbols --- src/services/findAllReferences.ts | 2 +- tests/cases/fourslash/findAllRefsBadImport.ts | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/findAllRefsBadImport.ts diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index b1e6909f093..bc36ef06226 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -356,7 +356,7 @@ namespace ts.FindAllReferences.Core { /** Core find-all-references algorithm for a normal symbol. */ function getReferencedSymbolsForSymbol(symbol: Symbol, node: Node, sourceFiles: ReadonlyArray, checker: TypeChecker, cancellationToken: CancellationToken, options: Options): SymbolAndEntries[] { - symbol = skipPastExportOrImportSpecifierOrUnion(symbol, node, checker); + symbol = skipPastExportOrImportSpecifierOrUnion(symbol, node, checker) || symbol; // Compute the meaning from the location and the symbol it references const searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), symbol.declarations); diff --git a/tests/cases/fourslash/findAllRefsBadImport.ts b/tests/cases/fourslash/findAllRefsBadImport.ts new file mode 100644 index 00000000000..89a81d81f79 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsBadImport.ts @@ -0,0 +1,7 @@ +/// + +////import { [|ab|] as [|cd|] } from "doesNotExist"; + +const [r0, r1] = test.ranges(); +verify.referencesOf(r0, [r1]); +verify.referencesOf(r1, [r1]); From 1faefc77030e41836f0a10995af97e1f91da4513 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Fri, 16 Feb 2018 14:51:31 -0800 Subject: [PATCH 18/28] Use correct lowercase name --- .../CoalesceMultipleModules.ts | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/baselines/reference/{OrganizeImports => organizeImports}/CoalesceMultipleModules.ts (100%) diff --git a/tests/baselines/reference/OrganizeImports/CoalesceMultipleModules.ts b/tests/baselines/reference/organizeImports/CoalesceMultipleModules.ts similarity index 100% rename from tests/baselines/reference/OrganizeImports/CoalesceMultipleModules.ts rename to tests/baselines/reference/organizeImports/CoalesceMultipleModules.ts From b64eefdb2059648f4c186842f8c611699710fe44 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Fri, 16 Feb 2018 15:50:12 -0800 Subject: [PATCH 19/28] Remove redundant null check --- src/services/findAllReferences.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index bc36ef06226..5684b3f3e37 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -405,7 +405,7 @@ namespace ts.FindAllReferences.Core { } /** Handle a few special cases relating to export/import specifiers. */ - function skipPastExportOrImportSpecifierOrUnion(symbol: Symbol, node: Node, checker: TypeChecker): Symbol { + function skipPastExportOrImportSpecifierOrUnion(symbol: Symbol, node: Node, checker: TypeChecker): Symbol | undefined { const { parent } = node; if (isExportSpecifier(parent)) { return getLocalSymbolForExportSpecifier(node as Identifier, symbol, parent, checker); @@ -425,7 +425,7 @@ namespace ts.FindAllReferences.Core { return isTypeLiteralNode(decl.parent) && isUnionTypeNode(decl.parent.parent) ? checker.getPropertyOfType(checker.getTypeFromTypeNode(decl.parent.parent), symbol.name) : undefined; - }) || symbol; + }); } /** From f95b9bc65de732cbc81b2e67fecfb6c08770bf2d Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 16 Feb 2018 15:53:44 -0800 Subject: [PATCH 20/28] Port generated lib files (#22003) * Port generated lib files * Port generated lib files --- src/lib/dom.generated.d.ts | 802 ++++++++++++++++--------------- src/lib/webworker.generated.d.ts | 98 ++-- 2 files changed, 462 insertions(+), 438 deletions(-) diff --git a/src/lib/dom.generated.d.ts b/src/lib/dom.generated.d.ts index ff764a8a06e..78ecb23eac3 100644 --- a/src/lib/dom.generated.d.ts +++ b/src/lib/dom.generated.d.ts @@ -1169,13 +1169,15 @@ interface WheelEventInit extends MouseEventInit { deltaZ?: number; } -type EventListener = (evt: Event) => void | { handleEvent(evt: Event): void; }; +interface EventListener { + (evt: Event): void; +} -type WebKitEntriesCallback = (entries: WebKitEntry[]) => void | { handleEvent(entries: WebKitEntry[]): void; }; +type WebKitEntriesCallback = ((entries: WebKitEntry[]) => void) | { handleEvent(entries: WebKitEntry[]): void; }; -type WebKitErrorCallback = (err: DOMError) => void | { handleEvent(err: DOMError): void; }; +type WebKitErrorCallback = ((err: DOMError) => void) | { handleEvent(err: DOMError): void; }; -type WebKitFileCallback = (file: File) => void | { handleEvent(file: File): void; }; +type WebKitFileCallback = ((file: File) => void) | { handleEvent(file: File): void; }; interface AnalyserNode extends AudioNode { fftSize: number; @@ -1249,9 +1251,9 @@ interface ApplicationCache extends EventTarget { readonly UNCACHED: number; readonly UPDATEREADY: number; addEventListener(type: K, listener: (this: ApplicationCache, ev: ApplicationCacheEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var ApplicationCache: { @@ -1308,9 +1310,9 @@ interface AudioBufferSourceNode extends AudioNode { start(when?: number, offset?: number, duration?: number): void; stop(when?: number): void; addEventListener(type: K, listener: (this: AudioBufferSourceNode, ev: AudioBufferSourceNodeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var AudioBufferSourceNode: { @@ -1352,9 +1354,9 @@ interface AudioContextBase extends EventTarget { decodeAudioData(audioData: ArrayBuffer, successCallback?: DecodeSuccessCallback, errorCallback?: DecodeErrorCallback): Promise; resume(): Promise; addEventListener(type: K, listener: (this: AudioContext, ev: AudioContextEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } interface AudioContext extends AudioContextBase { @@ -1462,9 +1464,9 @@ interface AudioTrackList extends EventTarget { getTrackById(id: string): AudioTrack | null; item(index: number): AudioTrack; addEventListener(type: K, listener: (this: AudioTrackList, ev: AudioTrackListEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; [index: number]: AudioTrack; } @@ -2383,9 +2385,9 @@ declare var CustomEvent: { interface DataCue extends TextTrackCue { data: ArrayBuffer; addEventListener(type: K, listener: (this: DataCue, ev: TextTrackCueEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var DataCue: { @@ -3310,9 +3312,9 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven */ writeln(...content: string[]): void; addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var Document: { @@ -3640,9 +3642,9 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec insertAdjacentText(where: InsertPosition, text: string): void; attachShadow(shadowRootInitDict: ShadowRootInit): ShadowRoot; addEventListener(type: K, listener: (this: Element, ev: ElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var Element: { @@ -3697,9 +3699,9 @@ declare var Event: { }; interface EventTarget { - addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; dispatchEvent(evt: Event): boolean; - removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var EventTarget: { @@ -3780,9 +3782,9 @@ interface FileReader extends EventTarget, MSBaseReader { readAsDataURL(blob: Blob): void; readAsText(blob: Blob, encoding?: string): void; addEventListener(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var FileReader: { @@ -4015,9 +4017,9 @@ interface HTMLAnchorElement extends HTMLElement { */ toString(): string; addEventListener(type: K, listener: (this: HTMLAnchorElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLAnchorElement: { @@ -4091,9 +4093,9 @@ interface HTMLAppletElement extends HTMLElement { vspace: number; width: number; addEventListener(type: K, listener: (this: HTMLAppletElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLAppletElement: { @@ -4161,9 +4163,9 @@ interface HTMLAreaElement extends HTMLElement { */ toString(): string; addEventListener(type: K, listener: (this: HTMLAreaElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLAreaElement: { @@ -4181,9 +4183,9 @@ declare var HTMLAreasCollection: { interface HTMLAudioElement extends HTMLMediaElement { addEventListener(type: K, listener: (this: HTMLAudioElement, ev: HTMLMediaElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLAudioElement: { @@ -4201,9 +4203,9 @@ interface HTMLBaseElement extends HTMLElement { */ target: string; addEventListener(type: K, listener: (this: HTMLBaseElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLBaseElement: { @@ -4221,9 +4223,9 @@ interface HTMLBaseFontElement extends HTMLElement, DOML2DeprecatedColorProperty */ size: number; addEventListener(type: K, listener: (this: HTMLBaseFontElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLBaseFontElement: { @@ -4277,9 +4279,9 @@ interface HTMLBodyElement extends HTMLElement { text: any; vLink: any; addEventListener(type: K, listener: (this: HTMLBodyElement, ev: HTMLBodyElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLBodyElement: { @@ -4293,9 +4295,9 @@ interface HTMLBRElement extends HTMLElement { */ clear: string; addEventListener(type: K, listener: (this: HTMLBRElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLBRElement: { @@ -4368,9 +4370,9 @@ interface HTMLButtonElement extends HTMLElement { */ setCustomValidity(error: string): void; addEventListener(type: K, listener: (this: HTMLButtonElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLButtonElement: { @@ -4405,9 +4407,9 @@ 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, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLCanvasElement: { @@ -4442,9 +4444,9 @@ declare var HTMLCollection: { interface HTMLDataElement extends HTMLElement { value: string; addEventListener(type: K, listener: (this: HTMLDataElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLDataElement: { @@ -4455,9 +4457,9 @@ declare var HTMLDataElement: { interface HTMLDataListElement extends HTMLElement { options: HTMLCollectionOf; addEventListener(type: K, listener: (this: HTMLDataListElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLDataListElement: { @@ -4468,9 +4470,9 @@ declare var HTMLDataListElement: { interface HTMLDirectoryElement extends HTMLElement { compact: boolean; addEventListener(type: K, listener: (this: HTMLDirectoryElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLDirectoryElement: { @@ -4488,9 +4490,9 @@ interface HTMLDivElement extends HTMLElement { */ noWrap: boolean; addEventListener(type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLDivElement: { @@ -4501,9 +4503,9 @@ declare var HTMLDivElement: { interface HTMLDListElement extends HTMLElement { compact: boolean; addEventListener(type: K, listener: (this: HTMLDListElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLDListElement: { @@ -4513,9 +4515,9 @@ declare var HTMLDListElement: { interface HTMLDocument extends Document { addEventListener(type: K, listener: (this: HTMLDocument, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLDocument: { @@ -4689,9 +4691,9 @@ interface HTMLElement extends Element { msGetInputContext(): MSInputMethodContext; animate(keyframes: AnimationKeyFrame | AnimationKeyFrame[], options: number | AnimationOptions): Animation; addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLElement: { @@ -4747,9 +4749,9 @@ interface HTMLEmbedElement extends HTMLElement, GetSVGDocument { */ width: string; addEventListener(type: K, listener: (this: HTMLEmbedElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLEmbedElement: { @@ -4790,9 +4792,9 @@ interface HTMLFieldSetElement extends HTMLElement { */ setCustomValidity(error: string): void; addEventListener(type: K, listener: (this: HTMLFieldSetElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLFieldSetElement: { @@ -4806,9 +4808,9 @@ interface HTMLFontElement extends HTMLElement, DOML2DeprecatedColorProperty, DOM */ face: string; addEventListener(type: K, listener: (this: HTMLFontElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLFontElement: { @@ -4895,9 +4897,9 @@ interface HTMLFormElement extends HTMLElement { reportValidity(): boolean; reportValidity(): boolean; addEventListener(type: K, listener: (this: HTMLFormElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; [name: string]: any; } @@ -4972,9 +4974,9 @@ interface HTMLFrameElement extends HTMLElement, GetSVGDocument { */ width: string | number; addEventListener(type: K, listener: (this: HTMLFrameElement, ev: HTMLFrameElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLFrameElement: { @@ -5042,9 +5044,9 @@ interface HTMLFrameSetElement extends HTMLElement { */ rows: string; addEventListener(type: K, listener: (this: HTMLFrameSetElement, ev: HTMLFrameSetElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLFrameSetElement: { @@ -5055,9 +5057,9 @@ declare var HTMLFrameSetElement: { interface HTMLHeadElement extends HTMLElement { profile: string; addEventListener(type: K, listener: (this: HTMLHeadElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLHeadElement: { @@ -5071,9 +5073,9 @@ interface HTMLHeadingElement extends HTMLElement { */ align: string; addEventListener(type: K, listener: (this: HTMLHeadingElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLHeadingElement: { @@ -5095,9 +5097,9 @@ interface HTMLHRElement extends HTMLElement, DOML2DeprecatedColorProperty, DOML2 */ width: number; addEventListener(type: K, listener: (this: HTMLHRElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLHRElement: { @@ -5111,9 +5113,9 @@ interface HTMLHtmlElement extends HTMLElement { */ version: string; addEventListener(type: K, listener: (this: HTMLHtmlElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLHtmlElement: { @@ -5202,9 +5204,9 @@ interface HTMLIFrameElement extends HTMLElement, GetSVGDocument { */ srcdoc: string; addEventListener(type: K, listener: (this: HTMLIFrameElement, ev: HTMLIFrameElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLIFrameElement: { @@ -5295,9 +5297,9 @@ interface HTMLImageElement extends HTMLElement { readonly y: number; msGetAsCastingSource(): any; addEventListener(type: K, listener: (this: HTMLImageElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLImageElement: { @@ -5510,9 +5512,9 @@ interface HTMLInputElement extends HTMLElement { */ stepUp(n?: number): void; addEventListener(type: K, listener: (this: HTMLInputElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLInputElement: { @@ -5531,9 +5533,9 @@ interface HTMLLabelElement extends HTMLElement { htmlFor: string; readonly control: HTMLInputElement | null; addEventListener(type: K, listener: (this: HTMLLabelElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLLabelElement: { @@ -5551,9 +5553,9 @@ interface HTMLLegendElement extends HTMLElement { */ readonly form: HTMLFormElement | null; addEventListener(type: K, listener: (this: HTMLLegendElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLLegendElement: { @@ -5568,9 +5570,9 @@ interface HTMLLIElement extends HTMLElement { */ value: number; addEventListener(type: K, listener: (this: HTMLLIElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLLIElement: { @@ -5615,9 +5617,9 @@ interface HTMLLinkElement extends HTMLElement, LinkStyle { import?: Document; integrity: string; addEventListener(type: K, listener: (this: HTMLLinkElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLLinkElement: { @@ -5635,9 +5637,9 @@ interface HTMLMapElement extends HTMLElement { */ name: string; addEventListener(type: K, listener: (this: HTMLMapElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLMapElement: { @@ -5669,9 +5671,9 @@ interface HTMLMarqueeElement extends HTMLElement { start(): void; stop(): void; addEventListener(type: K, listener: (this: HTMLMarqueeElement, ev: HTMLMarqueeElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLMarqueeElement: { @@ -5853,9 +5855,9 @@ interface HTMLMediaElement extends HTMLElement { readonly NETWORK_LOADING: number; readonly NETWORK_NO_SOURCE: number; addEventListener(type: K, listener: (this: HTMLMediaElement, ev: HTMLMediaElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLMediaElement: { @@ -5876,9 +5878,9 @@ interface HTMLMenuElement extends HTMLElement { compact: boolean; type: string; addEventListener(type: K, listener: (this: HTMLMenuElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLMenuElement: { @@ -5912,9 +5914,9 @@ interface HTMLMetaElement extends HTMLElement { */ url: string; addEventListener(type: K, listener: (this: HTMLMetaElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLMetaElement: { @@ -5930,9 +5932,9 @@ interface HTMLMeterElement extends HTMLElement { optimum: number; value: number; addEventListener(type: K, listener: (this: HTMLMeterElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLMeterElement: { @@ -5950,9 +5952,9 @@ interface HTMLModElement extends HTMLElement { */ dateTime: string; addEventListener(type: K, listener: (this: HTMLModElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLModElement: { @@ -6066,9 +6068,9 @@ interface HTMLObjectElement extends HTMLElement, GetSVGDocument { */ setCustomValidity(error: string): void; addEventListener(type: K, listener: (this: HTMLObjectElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLObjectElement: { @@ -6084,9 +6086,9 @@ interface HTMLOListElement extends HTMLElement { start: number; type: string; addEventListener(type: K, listener: (this: HTMLOListElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLOListElement: { @@ -6125,9 +6127,9 @@ interface HTMLOptGroupElement extends HTMLElement { */ value: string; addEventListener(type: K, listener: (this: HTMLOptGroupElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLOptGroupElement: { @@ -6166,9 +6168,9 @@ interface HTMLOptionElement extends HTMLElement { */ value: string; addEventListener(type: K, listener: (this: HTMLOptionElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLOptionElement: { @@ -6202,9 +6204,9 @@ interface HTMLOutputElement extends HTMLElement { reportValidity(): boolean; setCustomValidity(error: string): void; addEventListener(type: K, listener: (this: HTMLOutputElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLOutputElement: { @@ -6219,9 +6221,9 @@ interface HTMLParagraphElement extends HTMLElement { align: string; clear: string; addEventListener(type: K, listener: (this: HTMLParagraphElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLParagraphElement: { @@ -6247,9 +6249,9 @@ interface HTMLParamElement extends HTMLElement { */ valueType: string; addEventListener(type: K, listener: (this: HTMLParamElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLParamElement: { @@ -6259,9 +6261,9 @@ declare var HTMLParamElement: { interface HTMLPictureElement extends HTMLElement { addEventListener(type: K, listener: (this: HTMLPictureElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLPictureElement: { @@ -6275,9 +6277,9 @@ interface HTMLPreElement extends HTMLElement { */ width: number; addEventListener(type: K, listener: (this: HTMLPreElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLPreElement: { @@ -6303,9 +6305,9 @@ interface HTMLProgressElement extends HTMLElement { */ value: number; addEventListener(type: K, listener: (this: HTMLProgressElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLProgressElement: { @@ -6319,9 +6321,9 @@ interface HTMLQuoteElement extends HTMLElement { */ cite: string; addEventListener(type: K, listener: (this: HTMLQuoteElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLQuoteElement: { @@ -6362,9 +6364,9 @@ interface HTMLScriptElement extends HTMLElement { type: string; integrity: string; addEventListener(type: K, listener: (this: HTMLScriptElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLScriptElement: { @@ -6460,9 +6462,9 @@ interface HTMLSelectElement extends HTMLElement { */ setCustomValidity(error: string): void; addEventListener(type: K, listener: (this: HTMLSelectElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; [name: string]: any; } @@ -6488,9 +6490,9 @@ interface HTMLSourceElement extends HTMLElement { */ type: string; addEventListener(type: K, listener: (this: HTMLSourceElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLSourceElement: { @@ -6500,9 +6502,9 @@ declare var HTMLSourceElement: { interface HTMLSpanElement extends HTMLElement { addEventListener(type: K, listener: (this: HTMLSpanElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLSpanElement: { @@ -6521,9 +6523,9 @@ interface HTMLStyleElement extends HTMLElement, LinkStyle { */ type: string; addEventListener(type: K, listener: (this: HTMLStyleElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLStyleElement: { @@ -6541,9 +6543,9 @@ interface HTMLTableCaptionElement extends HTMLElement { */ vAlign: string; addEventListener(type: K, listener: (this: HTMLTableCaptionElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTableCaptionElement: { @@ -6598,9 +6600,9 @@ interface HTMLTableCellElement extends HTMLElement, HTMLTableAlignment { */ width: string; addEventListener(type: K, listener: (this: HTMLTableCellElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTableCellElement: { @@ -6622,9 +6624,9 @@ interface HTMLTableColElement extends HTMLElement, HTMLTableAlignment { */ width: any; addEventListener(type: K, listener: (this: HTMLTableColElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTableColElement: { @@ -6634,9 +6636,9 @@ declare var HTMLTableColElement: { interface HTMLTableDataCellElement extends HTMLTableCellElement { addEventListener(type: K, listener: (this: HTMLTableDataCellElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTableDataCellElement: { @@ -6749,9 +6751,9 @@ interface HTMLTableElement extends HTMLElement { */ insertRow(index?: number): HTMLTableRowElement; addEventListener(type: K, listener: (this: HTMLTableElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTableElement: { @@ -6765,9 +6767,9 @@ interface HTMLTableHeaderCellElement extends HTMLTableCellElement { */ scope: string; addEventListener(type: K, listener: (this: HTMLTableHeaderCellElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTableHeaderCellElement: { @@ -6808,9 +6810,9 @@ interface HTMLTableRowElement extends HTMLElement, HTMLTableAlignment { */ insertCell(index?: number): HTMLTableDataCellElement; addEventListener(type: K, listener: (this: HTMLTableRowElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTableRowElement: { @@ -6838,9 +6840,9 @@ interface HTMLTableSectionElement extends HTMLElement, HTMLTableAlignment { */ insertRow(index?: number): HTMLTableRowElement; addEventListener(type: K, listener: (this: HTMLTableSectionElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTableSectionElement: { @@ -6851,9 +6853,9 @@ declare var HTMLTableSectionElement: { interface HTMLTemplateElement extends HTMLElement { readonly content: DocumentFragment; addEventListener(type: K, listener: (this: HTMLTemplateElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTemplateElement: { @@ -6961,9 +6963,9 @@ interface HTMLTextAreaElement extends HTMLElement { */ setSelectionRange(start: number, end: number, direction?: "forward" | "backward" | "none"): void; addEventListener(type: K, listener: (this: HTMLTextAreaElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTextAreaElement: { @@ -6974,9 +6976,9 @@ declare var HTMLTextAreaElement: { interface HTMLTimeElement extends HTMLElement { dateTime: string; addEventListener(type: K, listener: (this: HTMLTimeElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTimeElement: { @@ -6990,9 +6992,9 @@ interface HTMLTitleElement extends HTMLElement { */ text: string; addEventListener(type: K, listener: (this: HTMLTitleElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTitleElement: { @@ -7013,9 +7015,9 @@ interface HTMLTrackElement extends HTMLElement { readonly LOADING: number; readonly NONE: number; addEventListener(type: K, listener: (this: HTMLTrackElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLTrackElement: { @@ -7031,9 +7033,9 @@ interface HTMLUListElement extends HTMLElement { compact: boolean; type: string; addEventListener(type: K, listener: (this: HTMLUListElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLUListElement: { @@ -7043,9 +7045,9 @@ declare var HTMLUListElement: { interface HTMLUnknownElement extends HTMLElement { addEventListener(type: K, listener: (this: HTMLUnknownElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLUnknownElement: { @@ -7100,9 +7102,9 @@ interface HTMLVideoElement extends HTMLMediaElement { webkitExitFullscreen(): void; webkitExitFullScreen(): void; addEventListener(type: K, listener: (this: HTMLVideoElement, ev: HTMLVideoElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var HTMLVideoElement: { @@ -7162,9 +7164,9 @@ interface IDBDatabase extends EventTarget { 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: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var IDBDatabase: { @@ -7249,9 +7251,9 @@ 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, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var IDBOpenDBRequest: { @@ -7273,9 +7275,9 @@ interface IDBRequest extends EventTarget { source: IDBObjectStore | IDBIndex | IDBCursor; readonly transaction: IDBTransaction; addEventListener(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var IDBRequest: { @@ -7302,9 +7304,9 @@ interface IDBTransaction extends EventTarget { readonly READ_WRITE: string; readonly VERSION_CHANGE: string; addEventListener(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var IDBTransaction: { @@ -7474,9 +7476,9 @@ interface MediaDevices extends EventTarget { getSupportedConstraints(): MediaTrackSupportedConstraints; getUserMedia(constraints: MediaStreamConstraints): Promise; addEventListener(type: K, listener: (this: MediaDevices, ev: MediaDevicesEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var MediaDevices: { @@ -7648,9 +7650,9 @@ interface MediaStream extends EventTarget { removeTrack(track: MediaStreamTrack): void; stop(): void; addEventListener(type: K, listener: (this: MediaStream, ev: MediaStreamEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var MediaStream: { @@ -7722,9 +7724,9 @@ interface MediaStreamTrack extends EventTarget { getSettings(): MediaTrackSettings; stop(): void; addEventListener(type: K, listener: (this: MediaStreamTrack, ev: MediaStreamTrackEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var MediaStreamTrack: { @@ -7774,9 +7776,9 @@ interface MessagePort extends EventTarget { postMessage(message?: any, transfer?: any[]): void; start(): void; addEventListener(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var MessagePort: { @@ -7881,9 +7883,9 @@ interface MSAppAsyncOperation extends EventTarget { readonly ERROR: number; readonly STARTED: number; addEventListener(type: K, listener: (this: MSAppAsyncOperation, ev: MSAppAsyncOperationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var MSAppAsyncOperation: { @@ -8039,9 +8041,9 @@ interface MSHTMLWebViewElement extends HTMLElement { refresh(): void; stop(): void; addEventListener(type: K, listener: (this: MSHTMLWebViewElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var MSHTMLWebViewElement: { @@ -8067,9 +8069,9 @@ interface MSInputMethodContext extends EventTarget { hasComposition(): boolean; isCandidateWindowVisible(): boolean; addEventListener(type: K, listener: (this: MSInputMethodContext, ev: MSInputMethodContextEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var MSInputMethodContext: { @@ -8235,9 +8237,9 @@ interface MSStreamReader extends EventTarget, MSBaseReader { readAsDataURL(stream: MSStream, size?: number): void; readAsText(stream: MSStream, encoding?: string, size?: number): void; addEventListener(type: K, listener: (this: MSStreamReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var MSStreamReader: { @@ -8266,9 +8268,9 @@ interface MSWebViewAsyncOperation extends EventTarget { readonly TYPE_CREATE_DATA_PACKAGE_FROM_SELECTION: number; readonly TYPE_INVOKE_SCRIPT: number; addEventListener(type: K, listener: (this: MSWebViewAsyncOperation, ev: MSWebViewAsyncOperationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var MSWebViewAsyncOperation: { @@ -8559,9 +8561,9 @@ interface Notification extends EventTarget { readonly title: string; close(): void; addEventListener(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var Notification: { @@ -8641,9 +8643,9 @@ interface OfflineAudioContext extends AudioContextBase { startRendering(): Promise; suspend(suspendTime: number): Promise; addEventListener(type: K, listener: (this: OfflineAudioContext, ev: OfflineAudioContextEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var OfflineAudioContext: { @@ -8664,9 +8666,9 @@ interface OscillatorNode extends AudioNode { start(when?: number): void; stop(when?: number): void; addEventListener(type: K, listener: (this: OscillatorNode, ev: OscillatorNodeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var OscillatorNode: { @@ -8761,9 +8763,9 @@ interface PaymentRequest extends EventTarget { abort(): Promise; show(): Promise; addEventListener(type: K, listener: (this: PaymentRequest, ev: PaymentRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var PaymentRequest: { @@ -9271,9 +9273,9 @@ interface RTCDtlsTransport extends RTCStatsProvider { start(remoteParameters: RTCDtlsParameters): void; stop(): void; addEventListener(type: K, listener: (this: RTCDtlsTransport, ev: RTCDtlsTransportEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var RTCDtlsTransport: { @@ -9303,9 +9305,9 @@ interface RTCDtmfSender extends EventTarget { readonly toneBuffer: string; insertDTMF(tones: string, duration?: number, interToneGap?: number): void; addEventListener(type: K, listener: (this: RTCDtmfSender, ev: RTCDtmfSenderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var RTCDtmfSender: { @@ -9356,9 +9358,9 @@ interface RTCIceGatherer extends RTCStatsProvider { getLocalCandidates(): RTCIceCandidateDictionary[]; getLocalParameters(): RTCIceParameters; addEventListener(type: K, listener: (this: RTCIceGatherer, ev: RTCIceGathererEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var RTCIceGatherer: { @@ -9396,9 +9398,9 @@ interface RTCIceTransport extends RTCStatsProvider { start(gatherer: RTCIceGatherer, remoteParameters: RTCIceParameters, role?: RTCIceRole): void; stop(): void; addEventListener(type: K, listener: (this: RTCIceTransport, ev: RTCIceTransportEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var RTCIceTransport: { @@ -9453,9 +9455,9 @@ interface RTCPeerConnection extends EventTarget { 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, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var RTCPeerConnection: { @@ -9487,9 +9489,9 @@ interface RTCRtpReceiver extends RTCStatsProvider { setTransport(transport: RTCDtlsTransport | RTCSrtpSdesTransport, rtcpTransport?: RTCDtlsTransport): void; stop(): void; addEventListener(type: K, listener: (this: RTCRtpReceiver, ev: RTCRtpReceiverEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var RTCRtpReceiver: { @@ -9514,9 +9516,9 @@ interface RTCRtpSender extends RTCStatsProvider { setTransport(transport: RTCDtlsTransport | RTCSrtpSdesTransport, rtcpTransport?: RTCDtlsTransport): void; stop(): void; addEventListener(type: K, listener: (this: RTCRtpSender, ev: RTCRtpSenderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var RTCRtpSender: { @@ -9544,9 +9546,9 @@ interface RTCSrtpSdesTransport extends EventTarget { onerror: ((this: RTCSrtpSdesTransport, ev: Event) => any) | null; readonly transport: RTCIceTransport; addEventListener(type: K, listener: (this: RTCSrtpSdesTransport, ev: RTCSrtpSdesTransportEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var RTCSrtpSdesTransport: { @@ -9617,10 +9619,12 @@ interface Screen extends EventTarget { readonly width: number; msLockOrientation(orientations: string | string[]): boolean; msUnlockOrientation(): void; + lockOrientation(orientations: OrientationLockType | OrientationLockType[]): boolean; + unlockOrientation(): void; addEventListener(type: K, listener: (this: Screen, ev: ScreenEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var Screen: { @@ -9646,9 +9650,9 @@ interface ScriptProcessorNode extends AudioNode { readonly bufferSize: number; onaudioprocess: (this: ScriptProcessorNode, ev: AudioProcessingEvent) => any; addEventListener(type: K, listener: (this: ScriptProcessorNode, ev: ScriptProcessorNodeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var ScriptProcessorNode: { @@ -9700,9 +9704,9 @@ interface ServiceWorker extends EventTarget, AbstractWorker { readonly state: ServiceWorkerState; postMessage(message: any, transfer?: any[]): void; addEventListener(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var ServiceWorker: { @@ -9724,9 +9728,9 @@ interface ServiceWorkerContainer extends EventTarget { getRegistrations(): Promise; register(scriptURL: USVString, options?: RegistrationOptions): Promise; addEventListener(type: K, listener: (this: ServiceWorkerContainer, ev: ServiceWorkerContainerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var ServiceWorkerContainer: { @@ -9764,9 +9768,9 @@ interface ServiceWorkerRegistration extends EventTarget { unregister(): Promise; update(): Promise; addEventListener(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var ServiceWorkerRegistration: { @@ -9820,9 +9824,9 @@ interface SpeechSynthesis extends EventTarget { resume(): void; speak(utterance: SpeechSynthesisUtterance): void; addEventListener(type: K, listener: (this: SpeechSynthesis, ev: SpeechSynthesisEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SpeechSynthesis: { @@ -9867,9 +9871,9 @@ interface SpeechSynthesisUtterance extends EventTarget { voice: SpeechSynthesisVoice; volume: number; addEventListener(type: K, listener: (this: SpeechSynthesisUtterance, ev: SpeechSynthesisUtteranceEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SpeechSynthesisUtterance: { @@ -10004,9 +10008,9 @@ declare var SubtleCrypto: { interface SVGAElement extends SVGGraphicsElement, SVGURIReference { readonly target: SVGAnimatedString; addEventListener(type: K, listener: (this: SVGAElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGAElement: { @@ -10163,9 +10167,9 @@ interface SVGCircleElement extends SVGGraphicsElement { readonly cy: SVGAnimatedLength; readonly r: SVGAnimatedLength; addEventListener(type: K, listener: (this: SVGCircleElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGCircleElement: { @@ -10176,9 +10180,9 @@ declare var SVGCircleElement: { interface SVGClipPathElement extends SVGGraphicsElement, SVGUnitTypes { readonly clipPathUnits: SVGAnimatedEnumeration; addEventListener(type: K, listener: (this: SVGClipPathElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGClipPathElement: { @@ -10201,9 +10205,9 @@ interface SVGComponentTransferFunctionElement extends SVGElement { readonly SVG_FECOMPONENTTRANSFER_TYPE_TABLE: number; readonly SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN: number; addEventListener(type: K, listener: (this: SVGComponentTransferFunctionElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGComponentTransferFunctionElement: { @@ -10219,9 +10223,9 @@ declare var SVGComponentTransferFunctionElement: { interface SVGDefsElement extends SVGGraphicsElement { addEventListener(type: K, listener: (this: SVGDefsElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGDefsElement: { @@ -10231,9 +10235,9 @@ declare var SVGDefsElement: { interface SVGDescElement extends SVGElement { addEventListener(type: K, listener: (this: SVGDescElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGDescElement: { @@ -10271,9 +10275,9 @@ interface SVGElement extends Element { readonly viewportElement: SVGElement; xmlbase: string; addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGElement: { @@ -10313,9 +10317,9 @@ interface SVGEllipseElement extends SVGGraphicsElement { readonly rx: SVGAnimatedLength; readonly ry: SVGAnimatedLength; addEventListener(type: K, listener: (this: SVGEllipseElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGEllipseElement: { @@ -10345,9 +10349,9 @@ interface SVGFEBlendElement extends SVGElement, SVGFilterPrimitiveStandardAttrib readonly SVG_FEBLEND_MODE_SOFT_LIGHT: number; readonly SVG_FEBLEND_MODE_UNKNOWN: number; addEventListener(type: K, listener: (this: SVGFEBlendElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEBlendElement: { @@ -10382,9 +10386,9 @@ interface SVGFEColorMatrixElement extends SVGElement, SVGFilterPrimitiveStandard readonly SVG_FECOLORMATRIX_TYPE_SATURATE: number; readonly SVG_FECOLORMATRIX_TYPE_UNKNOWN: number; addEventListener(type: K, listener: (this: SVGFEColorMatrixElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEColorMatrixElement: { @@ -10400,9 +10404,9 @@ declare var SVGFEColorMatrixElement: { interface SVGFEComponentTransferElement extends SVGElement, SVGFilterPrimitiveStandardAttributes { readonly in1: SVGAnimatedString; addEventListener(type: K, listener: (this: SVGFEComponentTransferElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEComponentTransferElement: { @@ -10426,9 +10430,9 @@ interface SVGFECompositeElement extends SVGElement, SVGFilterPrimitiveStandardAt readonly SVG_FECOMPOSITE_OPERATOR_UNKNOWN: number; readonly SVG_FECOMPOSITE_OPERATOR_XOR: number; addEventListener(type: K, listener: (this: SVGFECompositeElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFECompositeElement: { @@ -10461,9 +10465,9 @@ interface SVGFEConvolveMatrixElement extends SVGElement, SVGFilterPrimitiveStand readonly SVG_EDGEMODE_UNKNOWN: number; readonly SVG_EDGEMODE_WRAP: number; addEventListener(type: K, listener: (this: SVGFEConvolveMatrixElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEConvolveMatrixElement: { @@ -10482,9 +10486,9 @@ interface SVGFEDiffuseLightingElement extends SVGElement, SVGFilterPrimitiveStan readonly kernelUnitLengthY: SVGAnimatedNumber; readonly surfaceScale: SVGAnimatedNumber; addEventListener(type: K, listener: (this: SVGFEDiffuseLightingElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEDiffuseLightingElement: { @@ -10504,9 +10508,9 @@ interface SVGFEDisplacementMapElement extends SVGElement, SVGFilterPrimitiveStan readonly SVG_CHANNEL_R: number; readonly SVG_CHANNEL_UNKNOWN: number; addEventListener(type: K, listener: (this: SVGFEDisplacementMapElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEDisplacementMapElement: { @@ -10523,9 +10527,9 @@ interface SVGFEDistantLightElement extends SVGElement { readonly azimuth: SVGAnimatedNumber; readonly elevation: SVGAnimatedNumber; addEventListener(type: K, listener: (this: SVGFEDistantLightElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEDistantLightElement: { @@ -10535,9 +10539,9 @@ declare var SVGFEDistantLightElement: { interface SVGFEFloodElement extends SVGElement, SVGFilterPrimitiveStandardAttributes { addEventListener(type: K, listener: (this: SVGFEFloodElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEFloodElement: { @@ -10547,9 +10551,9 @@ declare var SVGFEFloodElement: { interface SVGFEFuncAElement extends SVGComponentTransferFunctionElement { addEventListener(type: K, listener: (this: SVGFEFuncAElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEFuncAElement: { @@ -10559,9 +10563,9 @@ declare var SVGFEFuncAElement: { interface SVGFEFuncBElement extends SVGComponentTransferFunctionElement { addEventListener(type: K, listener: (this: SVGFEFuncBElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEFuncBElement: { @@ -10571,9 +10575,9 @@ declare var SVGFEFuncBElement: { interface SVGFEFuncGElement extends SVGComponentTransferFunctionElement { addEventListener(type: K, listener: (this: SVGFEFuncGElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEFuncGElement: { @@ -10583,9 +10587,9 @@ declare var SVGFEFuncGElement: { interface SVGFEFuncRElement extends SVGComponentTransferFunctionElement { addEventListener(type: K, listener: (this: SVGFEFuncRElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEFuncRElement: { @@ -10599,9 +10603,9 @@ interface SVGFEGaussianBlurElement extends SVGElement, SVGFilterPrimitiveStandar readonly stdDeviationY: SVGAnimatedNumber; setStdDeviation(stdDeviationX: number, stdDeviationY: number): void; addEventListener(type: K, listener: (this: SVGFEGaussianBlurElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEGaussianBlurElement: { @@ -10612,9 +10616,9 @@ declare var SVGFEGaussianBlurElement: { interface SVGFEImageElement extends SVGElement, SVGFilterPrimitiveStandardAttributes, SVGURIReference { readonly preserveAspectRatio: SVGAnimatedPreserveAspectRatio; addEventListener(type: K, listener: (this: SVGFEImageElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEImageElement: { @@ -10624,9 +10628,9 @@ declare var SVGFEImageElement: { interface SVGFEMergeElement extends SVGElement, SVGFilterPrimitiveStandardAttributes { addEventListener(type: K, listener: (this: SVGFEMergeElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEMergeElement: { @@ -10637,9 +10641,9 @@ declare var SVGFEMergeElement: { interface SVGFEMergeNodeElement extends SVGElement { readonly in1: SVGAnimatedString; addEventListener(type: K, listener: (this: SVGFEMergeNodeElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEMergeNodeElement: { @@ -10656,9 +10660,9 @@ interface SVGFEMorphologyElement extends SVGElement, SVGFilterPrimitiveStandardA readonly SVG_MORPHOLOGY_OPERATOR_ERODE: number; readonly SVG_MORPHOLOGY_OPERATOR_UNKNOWN: number; addEventListener(type: K, listener: (this: SVGFEMorphologyElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEMorphologyElement: { @@ -10674,9 +10678,9 @@ interface SVGFEOffsetElement extends SVGElement, SVGFilterPrimitiveStandardAttri readonly dy: SVGAnimatedNumber; readonly in1: SVGAnimatedString; addEventListener(type: K, listener: (this: SVGFEOffsetElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEOffsetElement: { @@ -10689,9 +10693,9 @@ interface SVGFEPointLightElement extends SVGElement { readonly y: SVGAnimatedNumber; readonly z: SVGAnimatedNumber; addEventListener(type: K, listener: (this: SVGFEPointLightElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFEPointLightElement: { @@ -10707,9 +10711,9 @@ interface SVGFESpecularLightingElement extends SVGElement, SVGFilterPrimitiveSta readonly specularExponent: SVGAnimatedNumber; readonly surfaceScale: SVGAnimatedNumber; addEventListener(type: K, listener: (this: SVGFESpecularLightingElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFESpecularLightingElement: { @@ -10727,9 +10731,9 @@ interface SVGFESpotLightElement extends SVGElement { readonly y: SVGAnimatedNumber; readonly z: SVGAnimatedNumber; addEventListener(type: K, listener: (this: SVGFESpotLightElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFESpotLightElement: { @@ -10740,9 +10744,9 @@ declare var SVGFESpotLightElement: { interface SVGFETileElement extends SVGElement, SVGFilterPrimitiveStandardAttributes { readonly in1: SVGAnimatedString; addEventListener(type: K, listener: (this: SVGFETileElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFETileElement: { @@ -10764,9 +10768,9 @@ interface SVGFETurbulenceElement extends SVGElement, SVGFilterPrimitiveStandardA readonly SVG_TURBULENCE_TYPE_TURBULENCE: number; readonly SVG_TURBULENCE_TYPE_UNKNOWN: number; addEventListener(type: K, listener: (this: SVGFETurbulenceElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFETurbulenceElement: { @@ -10791,9 +10795,9 @@ interface SVGFilterElement extends SVGElement, SVGUnitTypes, SVGURIReference { readonly y: SVGAnimatedLength; setFilterRes(filterResX: number, filterResY: number): void; addEventListener(type: K, listener: (this: SVGFilterElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGFilterElement: { @@ -10807,9 +10811,9 @@ interface SVGForeignObjectElement extends SVGGraphicsElement { readonly x: SVGAnimatedLength; readonly y: SVGAnimatedLength; addEventListener(type: K, listener: (this: SVGForeignObjectElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGForeignObjectElement: { @@ -10819,9 +10823,9 @@ declare var SVGForeignObjectElement: { interface SVGGElement extends SVGGraphicsElement { addEventListener(type: K, listener: (this: SVGGElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGGElement: { @@ -10838,9 +10842,9 @@ interface SVGGradientElement extends SVGElement, SVGUnitTypes, SVGURIReference { readonly SVG_SPREADMETHOD_REPEAT: number; readonly SVG_SPREADMETHOD_UNKNOWN: number; addEventListener(type: K, listener: (this: SVGGradientElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGGradientElement: { @@ -10861,9 +10865,9 @@ interface SVGGraphicsElement extends SVGElement, SVGTests { getScreenCTM(): SVGMatrix; getTransformToElement(element: SVGElement): SVGMatrix; addEventListener(type: K, listener: (this: SVGGraphicsElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGGraphicsElement: { @@ -10878,9 +10882,9 @@ interface SVGImageElement extends SVGGraphicsElement, SVGURIReference { readonly x: SVGAnimatedLength; readonly y: SVGAnimatedLength; addEventListener(type: K, listener: (this: SVGImageElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGImageElement: { @@ -10946,9 +10950,9 @@ interface SVGLinearGradientElement extends SVGGradientElement { readonly y1: SVGAnimatedLength; readonly y2: SVGAnimatedLength; addEventListener(type: K, listener: (this: SVGLinearGradientElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGLinearGradientElement: { @@ -10962,9 +10966,9 @@ interface SVGLineElement extends SVGGraphicsElement { readonly y1: SVGAnimatedLength; readonly y2: SVGAnimatedLength; addEventListener(type: K, listener: (this: SVGLineElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGLineElement: { @@ -10989,9 +10993,9 @@ interface SVGMarkerElement extends SVGElement, SVGFitToViewBox { readonly SVG_MARKERUNITS_UNKNOWN: number; readonly SVG_MARKERUNITS_USERSPACEONUSE: number; addEventListener(type: K, listener: (this: SVGMarkerElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGMarkerElement: { @@ -11013,9 +11017,9 @@ interface SVGMaskElement extends SVGElement, SVGTests, SVGUnitTypes { readonly x: SVGAnimatedLength; readonly y: SVGAnimatedLength; addEventListener(type: K, listener: (this: SVGMaskElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGMaskElement: { @@ -11050,9 +11054,9 @@ declare var SVGMatrix: { interface SVGMetadataElement extends SVGElement { addEventListener(type: K, listener: (this: SVGMetadataElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGMetadataElement: { @@ -11110,9 +11114,9 @@ interface SVGPathElement extends SVGGraphicsElement { getPointAtLength(distance: number): SVGPoint; getTotalLength(): number; addEventListener(type: K, listener: (this: SVGPathElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGPathElement: { @@ -11405,9 +11409,9 @@ interface SVGPatternElement extends SVGElement, SVGTests, SVGUnitTypes, SVGFitTo readonly x: SVGAnimatedLength; readonly y: SVGAnimatedLength; addEventListener(type: K, listener: (this: SVGPatternElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGPatternElement: { @@ -11444,9 +11448,9 @@ declare var SVGPointList: { interface SVGPolygonElement extends SVGGraphicsElement, SVGAnimatedPoints { addEventListener(type: K, listener: (this: SVGPolygonElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGPolygonElement: { @@ -11456,9 +11460,9 @@ declare var SVGPolygonElement: { interface SVGPolylineElement extends SVGGraphicsElement, SVGAnimatedPoints { addEventListener(type: K, listener: (this: SVGPolylineElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGPolylineElement: { @@ -11511,9 +11515,9 @@ interface SVGRadialGradientElement extends SVGGradientElement { readonly fy: SVGAnimatedLength; readonly r: SVGAnimatedLength; addEventListener(type: K, listener: (this: SVGRadialGradientElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGRadialGradientElement: { @@ -11541,9 +11545,9 @@ interface SVGRectElement extends SVGGraphicsElement { readonly x: SVGAnimatedLength; readonly y: SVGAnimatedLength; addEventListener(type: K, listener: (this: SVGRectElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGRectElement: { @@ -11554,9 +11558,9 @@ declare var SVGRectElement: { interface SVGScriptElement extends SVGElement, SVGURIReference { type: string; addEventListener(type: K, listener: (this: SVGScriptElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGScriptElement: { @@ -11567,9 +11571,9 @@ declare var SVGScriptElement: { interface SVGStopElement extends SVGElement { readonly offset: SVGAnimatedNumber; addEventListener(type: K, listener: (this: SVGStopElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGStopElement: { @@ -11599,9 +11603,9 @@ interface SVGStyleElement extends SVGElement { title: string; type: string; addEventListener(type: K, listener: (this: SVGStyleElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGStyleElement: { @@ -11662,9 +11666,9 @@ interface SVGSVGElement extends SVGGraphicsElement, DocumentEvent, SVGFitToViewB unsuspendRedraw(suspendHandleID: number): void; unsuspendRedrawAll(): void; addEventListener(type: K, listener: (this: SVGSVGElement, ev: SVGSVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGSVGElement: { @@ -11674,9 +11678,9 @@ declare var SVGSVGElement: { interface SVGSwitchElement extends SVGGraphicsElement { addEventListener(type: K, listener: (this: SVGSwitchElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGSwitchElement: { @@ -11686,9 +11690,9 @@ declare var SVGSwitchElement: { interface SVGSymbolElement extends SVGElement, SVGFitToViewBox { addEventListener(type: K, listener: (this: SVGSymbolElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGSymbolElement: { @@ -11712,9 +11716,9 @@ interface SVGTextContentElement extends SVGGraphicsElement { readonly LENGTHADJUST_SPACINGANDGLYPHS: number; readonly LENGTHADJUST_UNKNOWN: number; addEventListener(type: K, listener: (this: SVGTextContentElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGTextContentElement: { @@ -11727,9 +11731,9 @@ declare var SVGTextContentElement: { interface SVGTextElement extends SVGTextPositioningElement { addEventListener(type: K, listener: (this: SVGTextElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGTextElement: { @@ -11748,9 +11752,9 @@ interface SVGTextPathElement extends SVGTextContentElement, SVGURIReference { readonly TEXTPATH_SPACINGTYPE_EXACT: number; readonly TEXTPATH_SPACINGTYPE_UNKNOWN: number; addEventListener(type: K, listener: (this: SVGTextPathElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGTextPathElement: { @@ -11771,9 +11775,9 @@ interface SVGTextPositioningElement extends SVGTextContentElement { readonly x: SVGAnimatedLengthList; readonly y: SVGAnimatedLengthList; addEventListener(type: K, listener: (this: SVGTextPositioningElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGTextPositioningElement: { @@ -11783,9 +11787,9 @@ declare var SVGTextPositioningElement: { interface SVGTitleElement extends SVGElement { addEventListener(type: K, listener: (this: SVGTitleElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGTitleElement: { @@ -11844,9 +11848,9 @@ declare var SVGTransformList: { interface SVGTSpanElement extends SVGTextPositioningElement { addEventListener(type: K, listener: (this: SVGTSpanElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGTSpanElement: { @@ -11869,9 +11873,9 @@ interface SVGUseElement extends SVGGraphicsElement, SVGURIReference { readonly x: SVGAnimatedLength; readonly y: SVGAnimatedLength; addEventListener(type: K, listener: (this: SVGUseElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGUseElement: { @@ -11882,9 +11886,9 @@ declare var SVGUseElement: { interface SVGViewElement extends SVGElement, SVGZoomAndPan, SVGFitToViewBox { readonly viewTarget: SVGStringList; addEventListener(type: K, listener: (this: SVGViewElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var SVGViewElement: { @@ -12005,9 +12009,9 @@ interface TextTrack extends EventTarget { readonly NONE: number; readonly SHOWING: number; addEventListener(type: K, listener: (this: TextTrack, ev: TextTrackEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var TextTrack: { @@ -12038,9 +12042,9 @@ interface TextTrackCue extends EventTarget { readonly track: TextTrack; getCueAsHTML(): DocumentFragment; addEventListener(type: K, listener: (this: TextTrackCue, ev: TextTrackCueEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var TextTrackCue: { @@ -12069,9 +12073,9 @@ interface TextTrackList extends EventTarget { onaddtrack: ((this: TextTrackList, ev: TrackEvent) => any) | null; item(index: number): TextTrack; addEventListener(type: K, listener: (this: TextTrackList, ev: TextTrackListEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; [index: number]: TextTrack; } @@ -12280,9 +12284,9 @@ interface VideoTrackList extends EventTarget { getTrackById(id: string): VideoTrack | null; item(index: number): VideoTrack; addEventListener(type: K, listener: (this: VideoTrackList, ev: VideoTrackListEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; [index: number]: VideoTrack; } @@ -13323,9 +13327,9 @@ declare var WebKitPoint: { interface webkitRTCPeerConnection extends RTCPeerConnection { addEventListener(type: K, listener: (this: webkitRTCPeerConnection, ev: RTCPeerConnectionEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var webkitRTCPeerConnection: { @@ -13358,9 +13362,9 @@ interface WebSocket extends EventTarget { readonly CONNECTING: number; readonly OPEN: number; addEventListener(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var WebSocket: { @@ -13673,9 +13677,9 @@ interface Window extends EventTarget, WindowTimers, WindowSessionStorage, Window scrollTo(options?: ScrollToOptions): void; scrollBy(options?: ScrollToOptions): void; addEventListener(type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var Window: { @@ -13692,9 +13696,9 @@ interface Worker extends EventTarget, AbstractWorker { postMessage(message: any, transfer?: any[]): void; terminate(): void; addEventListener(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var Worker: { @@ -13704,9 +13708,9 @@ declare var Worker: { interface XMLDocument extends Document { addEventListener(type: K, listener: (this: XMLDocument, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var XMLDocument: { @@ -13748,9 +13752,9 @@ interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget { readonly OPENED: number; readonly UNSENT: number; addEventListener(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var XMLHttpRequest: { @@ -13765,9 +13769,9 @@ declare var XMLHttpRequest: { interface XMLHttpRequestUpload extends EventTarget, XMLHttpRequestEventTarget { addEventListener(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var XMLHttpRequestUpload: { @@ -13873,9 +13877,9 @@ interface AbstractWorkerEventMap { interface AbstractWorker { onerror: (this: AbstractWorker, ev: ErrorEvent) => any; addEventListener(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } interface Body { @@ -14021,9 +14025,9 @@ interface GlobalEventHandlers { onpointerup: (this: GlobalEventHandlers, ev: PointerEvent) => any; onwheel: (this: GlobalEventHandlers, ev: WheelEvent) => any; addEventListener(type: K, listener: (this: GlobalEventHandlers, ev: GlobalEventHandlersEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } interface GlobalFetch { @@ -14076,9 +14080,9 @@ interface MSBaseReader { readonly EMPTY: number; readonly LOADING: number; addEventListener(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } interface MSFileSaver { @@ -14227,9 +14231,9 @@ interface XMLHttpRequestEventTarget { onprogress: (this: XMLHttpRequest, ev: ProgressEvent) => any; ontimeout: (this: XMLHttpRequest, ev: ProgressEvent) => any; addEventListener(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } interface BroadcastChannel extends EventTarget { @@ -14239,9 +14243,9 @@ interface BroadcastChannel extends EventTarget { close(): void; postMessage(message: any): void; addEventListener(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var BroadcastChannel: { @@ -14348,6 +14352,10 @@ interface FilePropertyBag extends BlobPropertyBag { lastModified?: number; } +interface EventListenerObject { + handleEvent(evt: Event): void; +} + interface ProgressEventInit extends EventInit { lengthComputable?: boolean; loaded?: number; @@ -14853,6 +14861,12 @@ interface EventSourceInit { readonly withCredentials: boolean; } +interface AnimationKeyFrame { + offset?: number | null | (number | null)[]; + easing?: string | string[]; + [index: string]: string | number | number[] | string[] | null | (number | null)[] | undefined; +} + interface AnimationOptions { id?: string; delay?: number; @@ -14922,6 +14936,8 @@ declare var Animation: { new(effect?: AnimationEffectReadOnly, timeline?: AnimationTimeline): Animation; }; +declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject; + interface DecodeErrorCallback { (error: DOMException): void; } @@ -15384,9 +15400,9 @@ 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, options?: boolean | AddEventListenerOptions): void; -declare function addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; +declare function removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; type AAGUID = string; type AlgorithmIdentifier = string | Algorithm; type BodyInit = Blob | BufferSource | FormData | string; @@ -15431,7 +15447,7 @@ type ScrollRestoration = "auto" | "manual"; type FormDataEntryValue = string | File; type InsertPosition = "beforebegin" | "afterbegin" | "beforeend" | "afterend"; type HeadersInit = Headers | string[][] | { [key: string]: string }; -type AnimationKeyFrame = {offset?: number | null | (number | null)[]} & {[key: string]: string | number | number[] | string[]}; +type OrientationLockType = "any" | "natural" | "portrait" | "landscape" | "portrait-primary" | "portrait-secondary" | "landscape-primary"| "landscape-secondary"; 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 187aa6072b2..abc25d5e077 100644 --- a/src/lib/webworker.generated.d.ts +++ b/src/lib/webworker.generated.d.ts @@ -128,7 +128,9 @@ interface SyncEventInit extends ExtendableEventInit { lastChance?: boolean; } -type EventListener = (evt: Event) => void | { handleEvent(evt: Event): void; }; +interface EventListener { + (evt: Event): void; +} interface AudioBuffer { readonly duration: number; @@ -390,9 +392,9 @@ declare var Event: { }; interface EventTarget { - addEventListener(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; dispatchEvent(evt: Event): boolean; - removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var EventTarget: { @@ -430,9 +432,9 @@ interface FileReader extends EventTarget, MSBaseReader { readAsDataURL(blob: Blob): void; readAsText(blob: Blob, encoding?: string): void; addEventListener(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var FileReader: { @@ -515,9 +517,9 @@ interface IDBDatabase extends EventTarget { 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: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var IDBDatabase: { @@ -602,9 +604,9 @@ 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, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var IDBOpenDBRequest: { @@ -626,9 +628,9 @@ interface IDBRequest extends EventTarget { source: IDBObjectStore | IDBIndex | IDBCursor; readonly transaction: IDBTransaction; addEventListener(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var IDBRequest: { @@ -655,9 +657,9 @@ interface IDBTransaction extends EventTarget { readonly READ_WRITE: string; readonly VERSION_CHANGE: string; addEventListener(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var IDBTransaction: { @@ -723,9 +725,9 @@ interface MessagePort extends EventTarget { postMessage(message?: any, transfer?: any[]): void; start(): void; addEventListener(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var MessagePort: { @@ -754,9 +756,9 @@ interface Notification extends EventTarget { readonly title: string; close(): void; addEventListener(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var Notification: { @@ -985,9 +987,9 @@ interface ServiceWorker extends EventTarget, AbstractWorker { readonly state: ServiceWorkerState; postMessage(message: any, transfer?: any[]): void; addEventListener(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var ServiceWorker: { @@ -1012,9 +1014,9 @@ interface ServiceWorkerRegistration extends EventTarget { unregister(): Promise; update(): Promise; addEventListener(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var ServiceWorkerRegistration: { @@ -1080,9 +1082,9 @@ interface WebSocket extends EventTarget { readonly CONNECTING: number; readonly OPEN: number; addEventListener(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var WebSocket: { @@ -1103,9 +1105,9 @@ interface Worker extends EventTarget, AbstractWorker { postMessage(message: any, transfer?: any[]): void; terminate(): void; addEventListener(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var Worker: { @@ -1146,9 +1148,9 @@ interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget { readonly OPENED: number; readonly UNSENT: number; addEventListener(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var XMLHttpRequest: { @@ -1163,9 +1165,9 @@ declare var XMLHttpRequest: { interface XMLHttpRequestUpload extends EventTarget, XMLHttpRequestEventTarget { addEventListener(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var XMLHttpRequestUpload: { @@ -1180,9 +1182,9 @@ interface AbstractWorkerEventMap { interface AbstractWorker { onerror: (this: AbstractWorker, ev: ErrorEvent) => any; addEventListener(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } interface Body { @@ -1220,9 +1222,9 @@ interface MSBaseReader { readonly EMPTY: number; readonly LOADING: number; addEventListener(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } interface NavigatorBeacon { @@ -1277,9 +1279,9 @@ interface XMLHttpRequestEventTarget { onprogress: (this: XMLHttpRequest, ev: ProgressEvent) => any; ontimeout: (this: XMLHttpRequest, ev: ProgressEvent) => any; addEventListener(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } interface Client { @@ -1315,9 +1317,9 @@ interface DedicatedWorkerGlobalScope extends WorkerGlobalScope { close(): void; postMessage(message: any, transfer?: any[]): void; addEventListener(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var DedicatedWorkerGlobalScope: { @@ -1428,9 +1430,9 @@ interface ServiceWorkerGlobalScope extends WorkerGlobalScope { readonly registration: ServiceWorkerRegistration; skipWaiting(): Promise; addEventListener(type: K, listener: (this: ServiceWorkerGlobalScope, ev: ServiceWorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var ServiceWorkerGlobalScope: { @@ -1475,9 +1477,9 @@ interface WorkerGlobalScope extends EventTarget, WorkerUtils, WindowConsole, Glo 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, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var WorkerGlobalScope: { @@ -1535,9 +1537,9 @@ interface BroadcastChannel extends EventTarget { close(): void; postMessage(message: any): void; addEventListener(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } declare var BroadcastChannel: { @@ -1617,6 +1619,10 @@ interface FilePropertyBag extends BlobPropertyBag { lastModified?: number; } +interface EventListenerObject { + handleEvent(evt: Event): void; +} + interface ProgressEventInit extends EventInit { lengthComputable?: boolean; loaded?: number; @@ -1843,6 +1849,8 @@ interface EventSourceInit { readonly withCredentials: boolean; } +declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject; + interface DecodeErrorCallback { (error: DOMException): void; } @@ -1899,9 +1907,9 @@ 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, options?: boolean | AddEventListenerOptions): void; -declare function addEventListener(type: string, listener: EventListener, 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: EventListener, options?: boolean | EventListenerOptions): void; +declare function removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; type AlgorithmIdentifier = string | Algorithm; type BodyInit = Blob | BufferSource | FormData | string; type IDBKeyPath = string; From b6f82adfed459389ea9ac274bd5f37ce9a13e1e0 Mon Sep 17 00:00:00 2001 From: Sergii Bezliudnyi Date: Sat, 17 Feb 2018 01:27:57 +0100 Subject: [PATCH 21/28] add template to jsdoc completion (#21978) --- src/services/jsDoc.ts | 1 + tests/cases/fourslash/completionInJsDoc.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 91774e2290c..2a5b4f26ce6 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -37,6 +37,7 @@ namespace ts.JsDoc { "see", "since", "static", + "template", "throws", "type", "typedef", diff --git a/tests/cases/fourslash/completionInJsDoc.ts b/tests/cases/fourslash/completionInJsDoc.ts index 4c1bb004671..1a9170ca950 100644 --- a/tests/cases/fourslash/completionInJsDoc.ts +++ b/tests/cases/fourslash/completionInJsDoc.ts @@ -59,6 +59,7 @@ verify.completionListContains("constructor"); verify.completionListContains("param"); verify.completionListContains("type"); verify.completionListContains("method"); +verify.completionListContains("template"); goTo.marker('2'); verify.completionListContains("constructor"); From ecddf8468fae73208126f2bc5aba4c39ef1e0875 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 16 Feb 2018 16:37:32 -0800 Subject: [PATCH 22/28] Fix the assert for undefined leaf in LineNode (#21924) Fixes #21818 --- src/server/scriptVersionCache.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/scriptVersionCache.ts b/src/server/scriptVersionCache.ts index dccf4d3267b..fa4445bfc4f 100644 --- a/src/server/scriptVersionCache.ts +++ b/src/server/scriptVersionCache.ts @@ -680,7 +680,7 @@ namespace ts.server { // Skipped all children const { leaf } = this.lineNumberToInfo(this.lineCount(), 0); - return { oneBasedLine: this.lineCount(), zeroBasedColumn: leaf.charCount(), lineText: undefined }; + return { oneBasedLine: this.lineCount(), zeroBasedColumn: leaf ? leaf.charCount() : 0, lineText: undefined }; } /** From 9ee51fadd9d10f2070d62608970f2868aa71452b Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 16 Feb 2018 16:47:13 -0800 Subject: [PATCH 23/28] Have Symbol#isReferenced check the SymbolFlags of the reference (#21996) --- src/compiler/checker.ts | 19 +++++------- src/compiler/types.ts | 2 +- ...ypeParameterMergedWithParameter.errors.txt | 27 ++++++++++++++++ ...Locals_typeParameterMergedWithParameter.js | 23 ++++++++++++++ ...s_typeParameterMergedWithParameter.symbols | 31 +++++++++++++++++++ ...als_typeParameterMergedWithParameter.types | 31 +++++++++++++++++++ ...Locals_typeParameterMergedWithParameter.ts | 14 +++++++++ 7 files changed, 135 insertions(+), 12 deletions(-) create mode 100644 tests/baselines/reference/noUnusedLocals_typeParameterMergedWithParameter.errors.txt create mode 100644 tests/baselines/reference/noUnusedLocals_typeParameterMergedWithParameter.js create mode 100644 tests/baselines/reference/noUnusedLocals_typeParameterMergedWithParameter.symbols create mode 100644 tests/baselines/reference/noUnusedLocals_typeParameterMergedWithParameter.types create mode 100644 tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b817d9b965a..a8fefc17dcc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1394,7 +1394,7 @@ namespace ts { // If `result === lastSelfReferenceLocation.symbol`, that means that we are somewhere inside `lastSelfReferenceLocation` looking up a name, and resolving to `lastLocation` itself. // That means that this is a self-reference of `lastLocation`, and shouldn't count this when considering whether `lastLocation` is used. if (isUse && result && nameNotFoundMessage && noUnusedIdentifiers && (!lastSelfReferenceLocation || result !== lastSelfReferenceLocation.symbol)) { - result.isReferenced = true; + result.isReferenced |= meaning; } if (!result) { @@ -15697,7 +15697,7 @@ namespace ts { if (reactSym) { // Mark local symbol as referenced here because it might not have been marked // if jsx emit was not react as there wont be error being emitted - reactSym.isReferenced = true; + reactSym.isReferenced = SymbolFlags.All; // If react symbol is alias, mark it as refereced if (reactSym.flags & SymbolFlags.Alias && !isConstEnumOrConstEnumOnlyModule(resolveAlias(reactSym))) { @@ -16267,12 +16267,7 @@ namespace ts { } } - if (getCheckFlags(prop) & CheckFlags.Instantiated) { - getSymbolLinks(prop).target.isReferenced = true; - } - else { - prop.isReferenced = true; - } + (getCheckFlags(prop) & CheckFlags.Instantiated ? getSymbolLinks(prop).target : prop).isReferenced = SymbolFlags.All; } function isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: __String): boolean { @@ -21442,7 +21437,9 @@ namespace ts { function checkUnusedLocalsAndParameters(node: Node): void { if (noUnusedIdentifiers && !(node.flags & NodeFlags.Ambient)) { node.locals.forEach(local => { - if (!local.isReferenced) { + // If it's purely a type parameter, ignore, will be checked in `checkUnusedTypeParameters`. + // If it's a type parameter merged with a parameter, check if the parameter-side is used. + if (local.flags & SymbolFlags.TypeParameter ? (local.flags & SymbolFlags.Variable && !(local.isReferenced & SymbolFlags.Variable)) : !local.isReferenced) { if (local.valueDeclaration && getRootDeclaration(local.valueDeclaration).kind === SyntaxKind.Parameter) { const parameter = getRootDeclaration(local.valueDeclaration); const name = getNameOfDeclaration(local.valueDeclaration); @@ -21453,7 +21450,7 @@ namespace ts { error(name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(local)); } } - else if (local.flags & SymbolFlags.TypeParameter ? compilerOptions.noUnusedParameters : compilerOptions.noUnusedLocals) { + else if (compilerOptions.noUnusedLocals) { forEach(local.declarations, d => errorUnusedLocal(d, symbolName(local))); } } @@ -21538,7 +21535,7 @@ namespace ts { return; } for (const typeParameter of node.typeParameters) { - if (!getMergedSymbol(typeParameter.symbol).isReferenced && !isIdentifierThatStartsWithUnderScore(typeParameter.name)) { + if (!(getMergedSymbol(typeParameter.symbol).isReferenced & SymbolFlags.TypeParameter) && !isIdentifierThatStartsWithUnderScore(typeParameter.name)) { error(typeParameter.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(typeParameter.symbol)); } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0e3f83f6e09..bb039e0e1e5 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3307,7 +3307,7 @@ namespace ts { /* @internal */ parent?: Symbol; // Parent symbol /* @internal */ exportSymbol?: Symbol; // Exported symbol associated with this symbol /* @internal */ constEnumOnlyModule?: boolean; // True if module contains only const enums or other modules with only const enums - /* @internal */ isReferenced?: boolean; // True if the symbol is referenced elsewhere + /* @internal */ isReferenced?: SymbolFlags; // True if the symbol is referenced elsewhere. Keeps track of the meaning of a reference in case a symbol is both a type parameter and parameter. /* @internal */ isReplaceableByMethod?: boolean; // Can this Javascript class property be replaced by a method symbol? /* @internal */ isAssigned?: boolean; // True if the symbol is a parameter with assignments } diff --git a/tests/baselines/reference/noUnusedLocals_typeParameterMergedWithParameter.errors.txt b/tests/baselines/reference/noUnusedLocals_typeParameterMergedWithParameter.errors.txt new file mode 100644 index 00000000000..e3b59b34cf8 --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_typeParameterMergedWithParameter.errors.txt @@ -0,0 +1,27 @@ +tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts(1,18): error TS6133: 'T' is declared but its value is never read. +tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts(1,21): error TS6133: 'T' is declared but its value is never read. +tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts(3,19): error TS6133: 'T' is declared but its value is never read. +tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts(7,26): error TS6133: 'T' is declared but its value is never read. + + +==== tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts (4 errors) ==== + function useNone(T: number) {} + ~ +!!! error TS6133: 'T' is declared but its value is never read. + ~ +!!! error TS6133: 'T' is declared but its value is never read. + + function useParam(T: number) { + ~ +!!! error TS6133: 'T' is declared but its value is never read. + return T; + } + + function useTypeParam(T: T) {} + ~ +!!! error TS6133: 'T' is declared but its value is never read. + + function useBoth(T: T) { + return T; + } + \ No newline at end of file diff --git a/tests/baselines/reference/noUnusedLocals_typeParameterMergedWithParameter.js b/tests/baselines/reference/noUnusedLocals_typeParameterMergedWithParameter.js new file mode 100644 index 00000000000..0b41d982012 --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_typeParameterMergedWithParameter.js @@ -0,0 +1,23 @@ +//// [noUnusedLocals_typeParameterMergedWithParameter.ts] +function useNone(T: number) {} + +function useParam(T: number) { + return T; +} + +function useTypeParam(T: T) {} + +function useBoth(T: T) { + return T; +} + + +//// [noUnusedLocals_typeParameterMergedWithParameter.js] +function useNone(T) { } +function useParam(T) { + return T; +} +function useTypeParam(T) { } +function useBoth(T) { + return T; +} diff --git a/tests/baselines/reference/noUnusedLocals_typeParameterMergedWithParameter.symbols b/tests/baselines/reference/noUnusedLocals_typeParameterMergedWithParameter.symbols new file mode 100644 index 00000000000..e0346382055 --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_typeParameterMergedWithParameter.symbols @@ -0,0 +1,31 @@ +=== tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts === +function useNone(T: number) {} +>useNone : Symbol(useNone, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 0, 0)) +>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 0, 17), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 0, 20)) +>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 0, 17), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 0, 20)) + +function useParam(T: number) { +>useParam : Symbol(useParam, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 0, 33)) +>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 2, 18), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 2, 21)) +>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 2, 18), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 2, 21)) + + return T; +>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 2, 18), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 2, 21)) +} + +function useTypeParam(T: T) {} +>useTypeParam : Symbol(useTypeParam, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 4, 1)) +>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 6, 22), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 6, 25)) +>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 6, 22), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 6, 25)) +>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 6, 22), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 6, 25)) + +function useBoth(T: T) { +>useBoth : Symbol(useBoth, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 6, 33)) +>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 17), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 20)) +>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 17), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 20)) +>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 17), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 20)) + + return T; +>T : Symbol(T, Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 17), Decl(noUnusedLocals_typeParameterMergedWithParameter.ts, 8, 20)) +} + diff --git a/tests/baselines/reference/noUnusedLocals_typeParameterMergedWithParameter.types b/tests/baselines/reference/noUnusedLocals_typeParameterMergedWithParameter.types new file mode 100644 index 00000000000..42725968779 --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_typeParameterMergedWithParameter.types @@ -0,0 +1,31 @@ +=== tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts === +function useNone(T: number) {} +>useNone : (T: number) => void +>T : T +>T : number + +function useParam(T: number) { +>useParam : (T: number) => number +>T : T +>T : number + + return T; +>T : number +} + +function useTypeParam(T: T) {} +>useTypeParam : (T: T) => void +>T : T +>T : T +>T : T + +function useBoth(T: T) { +>useBoth : (T: T) => T +>T : T +>T : T +>T : T + + return T; +>T : T +} + diff --git a/tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts b/tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts new file mode 100644 index 00000000000..b0240b36381 --- /dev/null +++ b/tests/cases/compiler/noUnusedLocals_typeParameterMergedWithParameter.ts @@ -0,0 +1,14 @@ +// @noUnusedLocals: true +// @noUnusedParameters: true + +function useNone(T: number) {} + +function useParam(T: number) { + return T; +} + +function useTypeParam(T: T) {} + +function useBoth(T: T) { + return T; +} From 69abe49930761aea92dc564f9b6a5db74d6e1be9 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 16 Feb 2018 16:48:03 -0800 Subject: [PATCH 24/28] Supports more locations for completions contextual types (#21946) --- src/compiler/checker.ts | 27 ++++++++---- src/compiler/types.ts | 2 + src/services/completions.ts | 44 ++++++++++++------- src/services/signatureHelp.ts | 9 ++-- .../completionsRecommended_contextualTypes.ts | 27 ++++++++++++ .../fourslash/signatureHelpIncompleteCalls.ts | 2 +- 6 files changed, 80 insertions(+), 31 deletions(-) create mode 100644 tests/cases/fourslash/completionsRecommended_contextualTypes.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a8fefc17dcc..032a640bc1d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -191,6 +191,14 @@ namespace ts { node = getParseTreeNode(node, isExpression); return node ? getContextualType(node) : undefined; }, + getContextualTypeForArgumentAtIndex: (node, argIndex) => { + node = getParseTreeNode(node, isCallLikeExpression); + return node && getContextualTypeForArgumentAtIndex(node, argIndex); + }, + getContextualTypeForJsxAttribute: (node) => { + node = getParseTreeNode(node, isJsxAttributeLike); + return node && getContextualTypeForJsxAttribute(node); + }, isContextSensitive, getFullyQualifiedName, getResolvedSignature: (node, candidatesOutArray, theArgumentCount) => { @@ -14183,14 +14191,15 @@ namespace ts { // In a typed function call, an argument or substitution expression is contextually typed by the type of the corresponding parameter. function getContextualTypeForArgument(callTarget: CallLikeExpression, arg: Expression): Type { const args = getEffectiveCallArguments(callTarget); - const argIndex = args.indexOf(arg); - if (argIndex >= 0) { - // If we're already in the process of resolving the given signature, don't resolve again as - // that could cause infinite recursion. Instead, return anySignature. - const signature = getNodeLinks(callTarget).resolvedSignature === resolvingSignature ? resolvingSignature : getResolvedSignature(callTarget); - return getTypeAtPosition(signature, argIndex); - } - return undefined; + const argIndex = args.indexOf(arg); // -1 for e.g. the expression of a CallExpression, or the tag of a TaggedTemplateExpression + return argIndex === -1 ? undefined : getContextualTypeForArgumentAtIndex(callTarget, argIndex); + } + + function getContextualTypeForArgumentAtIndex(callTarget: CallLikeExpression, argIndex: number): Type { + // If we're already in the process of resolving the given signature, don't resolve again as + // that could cause infinite recursion. Instead, return anySignature. + const signature = getNodeLinks(callTarget).resolvedSignature === resolvingSignature ? resolvingSignature : getResolvedSignature(callTarget); + return getTypeAtPosition(signature, argIndex); } function getContextualTypeForSubstitutionExpression(template: TemplateExpression, substitutionExpression: Expression) { @@ -14324,7 +14333,7 @@ namespace ts { : undefined; } - function getContextualTypeForJsxAttribute(attribute: JsxAttribute | JsxSpreadAttribute) { + function getContextualTypeForJsxAttribute(attribute: JsxAttribute | JsxSpreadAttribute): Type | undefined { // When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give its attributes a contextual type // which is a type of the parameter of the signature we are trying out. // If there is no contextual type (e.g. we are trying to resolve stateful component), get attributes type from resolving element's tagName diff --git a/src/compiler/types.ts b/src/compiler/types.ts index bb039e0e1e5..39e4f90698d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2835,6 +2835,8 @@ namespace ts { getAugmentedPropertiesOfType(type: Type): Symbol[]; getRootSymbols(symbol: Symbol): Symbol[]; getContextualType(node: Expression): Type | undefined; + /* @internal */ getContextualTypeForArgumentAtIndex(call: CallLikeExpression, argIndex: number): Type; + /* @internal */ getContextualTypeForJsxAttribute(attribute: JsxAttribute | JsxSpreadAttribute): Type | undefined; /* @internal */ isContextSensitive(node: Expression | MethodDeclaration | ObjectLiteralElementLike | JsxAttributeLike): boolean; /** diff --git a/src/services/completions.ts b/src/services/completions.ts index 68ec65a1e19..41f9a300b2e 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -657,8 +657,8 @@ namespace ts.Completions { None, } - function getRecommendedCompletion(currentToken: Node, checker: TypeChecker): Symbol | undefined { - const ty = getContextualType(currentToken, checker); + function getRecommendedCompletion(currentToken: Node, position: number, sourceFile: SourceFile, checker: TypeChecker): Symbol | undefined { + const ty = getContextualType(currentToken, position, sourceFile, checker); const symbol = ty && ty.symbol; // Don't include make a recommended completion for an abstract class return symbol && (symbol.flags & SymbolFlags.Enum || symbol.flags & SymbolFlags.Class && !isAbstractConstructorSymbol(symbol)) @@ -666,23 +666,37 @@ namespace ts.Completions { : undefined; } - function getContextualType(currentToken: Node, checker: ts.TypeChecker): Type | undefined { + function getContextualType(currentToken: Node, position: number, sourceFile: SourceFile, checker: TypeChecker): Type | undefined { const { parent } = currentToken; switch (currentToken.kind) { - case ts.SyntaxKind.Identifier: - return getContextualTypeFromParent(currentToken as ts.Identifier, checker); - case ts.SyntaxKind.EqualsToken: - return ts.isVariableDeclaration(parent) ? checker.getContextualType(parent.initializer) : - ts.isBinaryExpression(parent) ? checker.getTypeAtLocation(parent.left) : undefined; - case ts.SyntaxKind.NewKeyword: - return checker.getContextualType(parent as ts.Expression); - case ts.SyntaxKind.CaseKeyword: - return getSwitchedType(cast(currentToken.parent, isCaseClause), checker); + case SyntaxKind.Identifier: + return getContextualTypeFromParent(currentToken as Identifier, checker); + case SyntaxKind.EqualsToken: + switch (parent.kind) { + case ts.SyntaxKind.VariableDeclaration: + return checker.getContextualType((parent as VariableDeclaration).initializer); + case ts.SyntaxKind.BinaryExpression: + return checker.getTypeAtLocation((parent as BinaryExpression).left); + case ts.SyntaxKind.JsxAttribute: + return checker.getContextualTypeForJsxAttribute(parent as JsxAttribute); + default: + return undefined; + } + case SyntaxKind.NewKeyword: + return checker.getContextualType(parent as Expression); + case SyntaxKind.CaseKeyword: + return getSwitchedType(cast(parent, isCaseClause), checker); + case SyntaxKind.OpenBraceToken: + return isJsxExpression(parent) && parent.parent.kind !== SyntaxKind.JsxElement ? checker.getContextualTypeForJsxAttribute(parent.parent) : undefined; default: - return isEqualityOperatorKind(currentToken.kind) && ts.isBinaryExpression(parent) && isEqualityOperatorKind(parent.operatorToken.kind) + const argInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(currentToken, position, sourceFile); + return argInfo + // At `,`, treat this as the next argument after the comma. + ? checker.getContextualTypeForArgumentAtIndex(argInfo.invocation, argInfo.argumentIndex + (currentToken.kind === SyntaxKind.CommaToken ? 1 : 0)) + : isEqualityOperatorKind(currentToken.kind) && isBinaryExpression(parent) && isEqualityOperatorKind(parent.operatorToken.kind) // completion at `x ===/**/` should be for the right side ? checker.getTypeAtLocation(parent.left) - : checker.getContextualType(currentToken as ts.Expression); + : checker.getContextualType(currentToken as Expression); } } @@ -956,7 +970,7 @@ namespace ts.Completions { log("getCompletionData: Semantic work: " + (timestamp() - semanticStart)); - const recommendedCompletion = previousToken && getRecommendedCompletion(previousToken, typeChecker); + const recommendedCompletion = previousToken && getRecommendedCompletion(previousToken, position, sourceFile, typeChecker); return { kind: CompletionDataKind.Data, symbols, completionKind, propertyAccessToConvert, isNewIdentifierLocation, location, keywordFilters, symbolToOriginInfoMap, recommendedCompletion, previousToken, isJsxInitializer }; type JSDocTagWithTypeExpression = JSDocParameterTag | JSDocPropertyTag | JSDocReturnTag | JSDocTypeTag | JSDocTypedefTag; diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index aa30ba0de6f..c96d621dd24 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -95,7 +95,7 @@ namespace ts.SignatureHelp { * Returns relevant information for the argument list and the current argument if we are * in the argument of an invocation; returns undefined otherwise. */ - export function getImmediatelyContainingArgumentInfo(node: Node, position: number, sourceFile: SourceFile): ArgumentListInfo { + export function getImmediatelyContainingArgumentInfo(node: Node, position: number, sourceFile: SourceFile): ArgumentListInfo | undefined { if (isCallOrNewExpression(node.parent)) { const invocation = node.parent; let list: Node; @@ -207,8 +207,7 @@ namespace ts.SignatureHelp { // that trailing comma in the list, and we'll have generated the appropriate // arg index. let argumentIndex = 0; - const listChildren = argumentsList.getChildren(); - for (const child of listChildren) { + for (const child of argumentsList.getChildren()) { if (child === node) { break; } @@ -270,9 +269,7 @@ namespace ts.SignatureHelp { function getArgumentListInfoForTemplate(tagExpression: TaggedTemplateExpression, argumentIndex: number, sourceFile: SourceFile): ArgumentListInfo { // argumentCount is either 1 or (numSpans + 1) to account for the template strings array argument. - const argumentCount = tagExpression.template.kind === SyntaxKind.NoSubstitutionTemplateLiteral - ? 1 - : (tagExpression.template).templateSpans.length + 1; + const argumentCount = isNoSubstitutionTemplateLiteral(tagExpression.template) ? 1 : tagExpression.template.templateSpans.length + 1; if (argumentIndex !== 0) { Debug.assertLessThan(argumentIndex, argumentCount); diff --git a/tests/cases/fourslash/completionsRecommended_contextualTypes.ts b/tests/cases/fourslash/completionsRecommended_contextualTypes.ts new file mode 100644 index 00000000000..d5d7f50c30b --- /dev/null +++ b/tests/cases/fourslash/completionsRecommended_contextualTypes.ts @@ -0,0 +1,27 @@ +/// + +// @jsx: preserve + +// @Filename: /a.tsx +////enum E {} +////enum F {} +////function f(e: E, f: F) {} +////f(/*arg0*/, /*arg1*/); +//// +////function tag(arr: TemplateStringsArray, x: E) {} +////tag`${/*tag*/}`; +//// +////declare function MainButton(props: { e: E }): any; +//// +//// + +recommended("arg0"); +recommended("arg1", "F"); +recommended("tag"); +recommended("jsx"); +recommended("jsx2"); + +function recommended(markerName: string, enumName = "E") { + goTo.marker(markerName); + verify.completionListContains(enumName, `enum ${enumName}`, "", "enum", undefined, undefined , { isRecommended: true }); +} diff --git a/tests/cases/fourslash/signatureHelpIncompleteCalls.ts b/tests/cases/fourslash/signatureHelpIncompleteCalls.ts index ec4fcccc0fe..7403b98733d 100644 --- a/tests/cases/fourslash/signatureHelpIncompleteCalls.ts +++ b/tests/cases/fourslash/signatureHelpIncompleteCalls.ts @@ -27,5 +27,5 @@ verify.currentSignatureParameterCountIs(2); verify.currentSignatureHelpIs("f3(n: number, s: string): string"); verify.currentParameterHelpArgumentNameIs("s"); -verify.currentParameterSpanIs("s: string"); +verify.currentParameterSpanIs("s: string"); From 8e078b9fde39562d055286ac76b5403b8b3521d2 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 16 Feb 2018 16:48:42 -0800 Subject: [PATCH 25/28] Add comment to isGlobalCompletion (#21973) --- src/services/types.ts | 1 + tests/baselines/reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + 3 files changed, 3 insertions(+) diff --git a/src/services/types.ts b/src/services/types.ts index 51710c88f4f..60e33c200ad 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -727,6 +727,7 @@ namespace ts { } export interface CompletionInfo { + /** Not true for all glboal completions. This will be true if the enclosing scope matches a few syntax kinds. See `isGlobalCompletionScope`. */ isGlobalCompletion: boolean; isMemberCompletion: boolean; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 1a7edaa44c8..86a33c179a3 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4490,6 +4490,7 @@ declare namespace ts { argumentCount: number; } interface CompletionInfo { + /** Not true for all glboal completions. This will be true if the enclosing scope matches a few syntax kinds. See `isGlobalCompletionScope`. */ isGlobalCompletion: boolean; isMemberCompletion: boolean; /** diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 8f9c095090d..1c3c13f48b0 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4742,6 +4742,7 @@ declare namespace ts { argumentCount: number; } interface CompletionInfo { + /** Not true for all glboal completions. This will be true if the enclosing scope matches a few syntax kinds. See `isGlobalCompletionScope`. */ isGlobalCompletion: boolean; isMemberCompletion: boolean; /** From b3edc8f9f4d9cf4203c4c4493e4f0f3dc96c845d Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 16 Feb 2018 18:38:00 -0800 Subject: [PATCH 26/28] Apply 'no-unnecessary-type-assertion' lint rule (#22005) * Apply 'no-unnecessary-type-assertion' lint rule * Fix type error * Fix tsconfig.json * Add --format back --- Gulpfile.ts | 14 +- Jakefile.js | 16 +- scripts/tslint/rules/booleanTriviaRule.ts | 4 +- .../rules/noUnnecessaryTypeAssertion2Rule.ts | 98 +++++ scripts/tslint/tsconfig.json | 1 + src/compiler/binder.ts | 27 +- src/compiler/builder.ts | 2 +- src/compiler/checker.ts | 336 +++++++++--------- src/compiler/declarationEmitter.ts | 36 +- src/compiler/emitter.ts | 12 +- src/compiler/factory.ts | 50 +-- src/compiler/parser.ts | 16 +- src/compiler/program.ts | 2 +- src/compiler/transformers/es2015.ts | 20 +- src/compiler/transformers/es2017.ts | 2 +- src/compiler/transformers/esnext.ts | 5 +- src/compiler/transformers/generators.ts | 7 +- src/compiler/transformers/jsx.ts | 20 +- src/compiler/transformers/module/module.ts | 2 +- src/compiler/transformers/module/system.ts | 11 +- src/compiler/transformers/ts.ts | 22 +- src/compiler/utilities.ts | 62 ++-- src/harness/fourslash.ts | 16 +- src/harness/harness.ts | 7 +- src/harness/harnessLanguageService.ts | 2 +- .../unittests/reuseProgramStructure.ts | 2 +- src/harness/unittests/textChanges.ts | 2 +- .../unittests/tsserverProjectSystem.ts | 2 +- src/harness/virtualFileSystem.ts | 13 +- src/server/editorServices.ts | 2 +- src/server/scriptVersionCache.ts | 6 +- src/services/breakpoints.ts | 9 +- src/services/codefixes/fixUnusedIdentifier.ts | 6 +- src/services/codefixes/helpers.ts | 2 +- src/services/codefixes/inferFromUsage.ts | 4 +- src/services/completions.ts | 12 +- src/services/findAllReferences.ts | 10 +- src/services/formatting/formatting.ts | 2 +- src/services/formatting/smartIndenter.ts | 5 +- src/services/importTracker.ts | 2 +- src/services/jsDoc.ts | 4 +- src/services/navigateTo.ts | 6 +- src/services/navigationBar.ts | 8 +- .../refactors/annotateWithTypeFromJSDoc.ts | 2 +- .../refactors/convertFunctionToEs6Class.ts | 3 +- src/services/refactors/convertToEs6Module.ts | 14 +- src/services/refactors/extractSymbol.ts | 10 +- src/services/services.ts | 8 +- src/services/signatureHelp.ts | 14 +- src/services/symbolDisplay.ts | 4 +- src/services/utilities.ts | 2 +- tslint.json | 2 + 52 files changed, 495 insertions(+), 451 deletions(-) create mode 100644 scripts/tslint/rules/noUnnecessaryTypeAssertion2Rule.ts diff --git a/Gulpfile.ts b/Gulpfile.ts index 7222c9bcd6a..e8bd7a990fe 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -53,7 +53,6 @@ const cmdLineOptions = minimist(process.argv.slice(2), { "ru": "runners", "runner": "runners", "r": "reporter", "c": "colors", "color": "colors", - "f": "files", "file": "files", "w": "workers", }, default: { @@ -69,7 +68,6 @@ const cmdLineOptions = minimist(process.argv.slice(2), { light: process.env.light === undefined || process.env.light !== "false", reporter: process.env.reporter || process.env.r, lint: process.env.lint || true, - files: process.env.f || process.env.file || process.env.files || "", workers: process.env.workerCount || os.cpus().length, } }); @@ -1112,13 +1110,11 @@ function spawnLintWorker(files: {path: string}[], callback: (failures: number) = gulp.task("lint", "Runs tslint on the compiler sources. Optional arguments are: --f[iles]=regex", ["build-rules"], () => { if (fold.isTravis()) console.log(fold.start("lint")); - const fileMatcher = cmdLineOptions.files; - const files = fileMatcher - ? `src/**/${fileMatcher}` - : `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] }); + for (const project of ["scripts/tslint/tsconfig.json", "src/tsconfig-base.json"]) { + const cmd = `node node_modules/tslint/bin/tslint --project ${project} --formatters-dir ./built/local/tslint/formatters --format autolinkableStylish`; + console.log("Linting: " + cmd); + child_process.execSync(cmd, { stdio: [0, 1, 2] }); + } if (fold.isTravis()) console.log(fold.end("lint")); }); diff --git a/Jakefile.js b/Jakefile.js index d676926abac..9935b6b0f13 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -1302,15 +1302,13 @@ function spawnLintWorker(files, callback) { desc("Runs tslint on the compiler sources. Optional arguments are: f[iles]=regex"); task("lint", ["build-rules"], () => { if (fold.isTravis()) console.log(fold.start("lint")); - 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/*.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, windowsVerbatimArguments: true }, () => { + function lint(project, cb) { + const cmd = `node node_modules/tslint/bin/tslint --project ${project} --formatters-dir ./built/local/tslint/formatters --format autolinkableStylish`; + console.log("Linting: " + cmd); + jake.exec([cmd], { interactive: true, windowsVerbatimArguments: true }, cb); + } + lint("scripts/tslint/tsconfig.json", () => lint("src/tsconfig-base.json", () => { if (fold.isTravis()) console.log(fold.end("lint")); complete(); - }); + })); }); diff --git a/scripts/tslint/rules/booleanTriviaRule.ts b/scripts/tslint/rules/booleanTriviaRule.ts index c498131be16..dbfdc28438e 100644 --- a/scripts/tslint/rules/booleanTriviaRule.ts +++ b/scripts/tslint/rules/booleanTriviaRule.ts @@ -27,7 +27,7 @@ function walk(ctx: Lint.WalkContext): void { /** Skip certain function/method names whose parameter names are not informative. */ function shouldIgnoreCalledExpression(expression: ts.Expression): boolean { if (expression.kind === ts.SyntaxKind.PropertyAccessExpression) { - const methodName = (expression as ts.PropertyAccessExpression).name.text as string; + const methodName = (expression as ts.PropertyAccessExpression).name.text; if (methodName.indexOf("set") === 0) { return true; } @@ -45,7 +45,7 @@ function walk(ctx: Lint.WalkContext): void { } } else if (expression.kind === ts.SyntaxKind.Identifier) { - const functionName = (expression as ts.Identifier).text as string; + const functionName = (expression as ts.Identifier).text; if (functionName.indexOf("set") === 0) { return true; } diff --git a/scripts/tslint/rules/noUnnecessaryTypeAssertion2Rule.ts b/scripts/tslint/rules/noUnnecessaryTypeAssertion2Rule.ts new file mode 100644 index 00000000000..bcfb91b739f --- /dev/null +++ b/scripts/tslint/rules/noUnnecessaryTypeAssertion2Rule.ts @@ -0,0 +1,98 @@ +/** + * @license + * Copyright 2016 Palantir Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as ts from "typescript"; +import * as Lint from "tslint"; + +export class Rule extends Lint.Rules.TypedRule { + /* tslint:disable:object-literal-sort-keys */ + public static metadata: Lint.IRuleMetadata = { + ruleName: "no-unnecessary-type-assertion", + description: "Warns if a type assertion does not change the type of an expression.", + options: { + type: "list", + listType: { + type: "array", + items: { type: "string" }, + }, + }, + optionsDescription: "A list of whitelisted assertion types to ignore", + type: "typescript", + hasFix: true, + typescriptOnly: true, + requiresTypeInfo: true, + }; + /* tslint:enable:object-literal-sort-keys */ + + public static FAILURE_STRING = "This assertion is unnecessary since it does not change the type of the expression."; + + public applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): Lint.RuleFailure[] { + return this.applyWithWalker(new Walker(sourceFile, this.ruleName, this.ruleArguments, program.getTypeChecker())); + } +} + +class Walker extends Lint.AbstractWalker { + constructor(sourceFile: ts.SourceFile, ruleName: string, options: string[], private readonly checker: ts.TypeChecker) { + super(sourceFile, ruleName, options); + } + + public walk(sourceFile: ts.SourceFile) { + const cb = (node: ts.Node): void => { + switch (node.kind) { + case ts.SyntaxKind.TypeAssertionExpression: + case ts.SyntaxKind.AsExpression: + this.verifyCast(node as ts.TypeAssertion | ts.AsExpression); + } + + return ts.forEachChild(node, cb); + }; + + return ts.forEachChild(sourceFile, cb); + } + + private verifyCast(node: ts.TypeAssertion | ts.NonNullExpression | ts.AsExpression) { + if (ts.isAssertionExpression(node) && this.options.indexOf(node.type.getText(this.sourceFile)) !== -1) { + return; + } + const castType = this.checker.getTypeAtLocation(node); + if (castType === undefined) { + return; + } + + if (node.kind !== ts.SyntaxKind.NonNullExpression && + (castType.flags & ts.TypeFlags.Literal || + castType.flags & ts.TypeFlags.Object && + (castType as ts.ObjectType).objectFlags & ts.ObjectFlags.Tuple) || + // Sometimes tuple types don't have ObjectFlags.Tuple set, like when + // they're being matched against an inferred type. So, in addition, + // check if any properties are numbers, which implies that this is + // likely a tuple type. + (castType.getProperties().some((symbol) => !isNaN(Number(symbol.name))))) { + + // It's not always safe to remove a cast to a literal type or tuple + // type, as those types are sometimes widened without the cast. + return; + } + + const uncastType = this.checker.getTypeAtLocation(node.expression); + if (uncastType === castType) { + this.addFailureAtNode(node, Rule.FAILURE_STRING, node.kind === ts.SyntaxKind.TypeAssertionExpression + ? Lint.Replacement.deleteFromTo(node.getStart(), node.expression.getStart()) + : Lint.Replacement.deleteFromTo(node.expression.getEnd(), node.getEnd())); + } + } +} diff --git a/scripts/tslint/tsconfig.json b/scripts/tslint/tsconfig.json index c9bf8dc01dc..9d348658394 100644 --- a/scripts/tslint/tsconfig.json +++ b/scripts/tslint/tsconfig.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "lib": ["es6"], "noImplicitAny": true, "noImplicitReturns": true, "noImplicitThis": true, diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 05edda7cd3c..06b15c7718d 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -264,7 +264,7 @@ namespace ts { return (isGlobalScopeAugmentation(node) ? "__global" : `"${moduleName}"`) as __String; } if (name.kind === SyntaxKind.ComputedPropertyName) { - const nameExpression = (name).expression; + const nameExpression = name.expression; // treat computed property names where expression is string/numeric literal as just string/numeric literal if (isStringOrNumericLiteral(nameExpression)) { return escapeLeadingUnderscores(nameExpression.text); @@ -459,10 +459,7 @@ namespace ts { // and this case is specially handled. Module augmentations should only be merged with original module definition // and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed. if (node.kind === SyntaxKind.JSDocTypedefTag) Debug.assert(isInJavaScriptFile(node)); // We shouldn't add symbols for JSDoc nodes if not in a JS file. - const isJSDocTypedefInJSDocNamespace = node.kind === SyntaxKind.JSDocTypedefTag && - (node as JSDocTypedefTag).name && - (node as JSDocTypedefTag).name.kind === SyntaxKind.Identifier && - ((node as JSDocTypedefTag).name as Identifier).isInJSDocNamespace; + const isJSDocTypedefInJSDocNamespace = isJSDocTypedefTag(node) && node.name && node.name.kind === SyntaxKind.Identifier && node.name.isInJSDocNamespace; if ((!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) || isJSDocTypedefInJSDocNamespace) { const exportKind = symbolFlags & SymbolFlags.Value ? SymbolFlags.ExportValue : 0; const local = declareSymbol(container.locals, /*parent*/ undefined, node, exportKind, symbolExcludes); @@ -527,7 +524,7 @@ namespace ts { if (!isIIFE) { currentFlow = { flags: FlowFlags.Start }; if (containerFlags & (ContainerFlags.IsFunctionExpression | ContainerFlags.IsObjectLiteralOrClassExpressionMethod)) { - (currentFlow).container = node; + currentFlow.container = node; } } // We create a return control flow graph for IIFEs and constructors. For constructors @@ -997,7 +994,7 @@ namespace ts { addAntecedent(postLoopLabel, currentFlow); bind(node.initializer); if (node.initializer.kind !== SyntaxKind.VariableDeclarationList) { - bindAssignmentTargetFlow(node.initializer); + bindAssignmentTargetFlow(node.initializer); } bindIterativeStatement(node.statement, postLoopLabel, preLoopLabel); addAntecedent(preLoopLabel, currentFlow); @@ -1170,7 +1167,7 @@ namespace ts { i++; } const preCaseLabel = createBranchLabel(); - addAntecedent(preCaseLabel, createFlowSwitchClause(preSwitchCaseFlow, node.parent, clauseStart, i + 1)); + addAntecedent(preCaseLabel, createFlowSwitchClause(preSwitchCaseFlow, node.parent, clauseStart, i + 1)); addAntecedent(preCaseLabel, fallthroughFlow); currentFlow = finishFlowLabel(preCaseLabel); const clause = clauses[i]; @@ -1251,13 +1248,13 @@ namespace ts { else if (node.kind === SyntaxKind.ObjectLiteralExpression) { for (const p of (node).properties) { if (p.kind === SyntaxKind.PropertyAssignment) { - bindDestructuringTargetFlow((p).initializer); + bindDestructuringTargetFlow(p.initializer); } else if (p.kind === SyntaxKind.ShorthandPropertyAssignment) { - bindAssignmentTargetFlow((p).name); + bindAssignmentTargetFlow(p.name); } else if (p.kind === SyntaxKind.SpreadAssignment) { - bindAssignmentTargetFlow((p).expression); + bindAssignmentTargetFlow(p.expression); } } } @@ -1572,7 +1569,7 @@ namespace ts { } function hasExportDeclarations(node: ModuleDeclaration | SourceFile): boolean { - const body = node.kind === SyntaxKind.SourceFile ? node : (node).body; + const body = node.kind === SyntaxKind.SourceFile ? node : node.body; if (body && (body.kind === SyntaxKind.SourceFile || body.kind === SyntaxKind.ModuleBlock)) { for (const stat of (body).statements) { if (stat.kind === SyntaxKind.ExportDeclaration || stat.kind === SyntaxKind.ExportAssignment) { @@ -2210,7 +2207,7 @@ namespace ts { function checkTypePredicate(node: TypePredicateNode) { const { parameterName, type } = node; if (parameterName && parameterName.kind === SyntaxKind.Identifier) { - checkStrictModeIdentifier(parameterName as Identifier); + checkStrictModeIdentifier(parameterName); } if (parameterName && parameterName.kind === SyntaxKind.ThisType) { seenThisKeyword = true; @@ -2555,13 +2552,13 @@ namespace ts { } } - checkStrictModeFunctionName(node); + checkStrictModeFunctionName(node); if (inStrictMode) { checkStrictModeFunctionDeclaration(node); bindBlockScopedDeclaration(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes); } else { - declareSymbolAndAddToSymbolTable(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes); + declareSymbolAndAddToSymbolTable(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes); } } diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index 121609db104..c2f816a4c71 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -228,7 +228,7 @@ namespace ts { host = oldProgramOrHost as CompilerHost; } else { - newProgram = newProgramOrRootNames as Program; + newProgram = newProgramOrRootNames; host = hostOrOptions as BuilderProgramHost; oldProgram = oldProgramOrHost as BuilderProgram; } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 032a640bc1d..2768c142f5a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1277,7 +1277,7 @@ namespace ts { // by the same name as a constructor parameter or local variable are inaccessible // in initializer expressions for instance member variables. if (isClassLike(location.parent) && !hasModifier(location, ModifierFlags.Static)) { - const ctor = findConstructorDeclaration(location.parent); + const ctor = findConstructorDeclaration(location.parent); if (ctor && ctor.locals) { if (lookup(ctor.locals, name, meaning & SymbolFlags.Value)) { // Remember the property node, it will be used later to report appropriate error @@ -1688,7 +1688,7 @@ namespace ts { if (node.moduleReference.kind === SyntaxKind.ExternalModuleReference) { return resolveExternalModuleSymbol(resolveExternalModuleName(node, getExternalModuleImportEqualsDeclarationExpression(node))); } - return getSymbolOfPartOfRightHandSideOfImportEquals(node.moduleReference, dontResolveAlias); + return getSymbolOfPartOfRightHandSideOfImportEquals(node.moduleReference, dontResolveAlias); } function resolveExportByName(moduleSymbol: Symbol, name: __String, dontResolveAlias: boolean) { @@ -1729,7 +1729,7 @@ namespace ts { } function getTargetOfImportClause(node: ImportClause, dontResolveAlias: boolean): Symbol { - const moduleSymbol = resolveExternalModuleName(node, (node.parent).moduleSpecifier); + const moduleSymbol = resolveExternalModuleName(node, node.parent.moduleSpecifier); if (moduleSymbol) { let exportDefaultSymbol: Symbol; @@ -1754,7 +1754,7 @@ namespace ts { } function getTargetOfNamespaceImport(node: NamespaceImport, dontResolveAlias: boolean): Symbol { - const moduleSpecifier = (node.parent.parent).moduleSpecifier; + const moduleSpecifier = node.parent.parent.moduleSpecifier; return resolveESModuleSymbol(resolveExternalModuleName(node, moduleSpecifier), moduleSpecifier, dontResolveAlias); } @@ -1844,7 +1844,7 @@ namespace ts { } function getTargetOfImportSpecifier(node: ImportSpecifier, dontResolveAlias: boolean): Symbol { - return getExternalModuleMember(node.parent.parent.parent, node, dontResolveAlias); + return getExternalModuleMember(node.parent.parent.parent, node, dontResolveAlias); } function getTargetOfNamespaceExportDeclaration(node: NamespaceExportDeclaration, dontResolveAlias: boolean): Symbol { @@ -1945,7 +1945,7 @@ namespace ts { } else if (isInternalModuleImportEqualsDeclaration(node)) { // import foo = - checkExpressionCached((node).moduleReference); + checkExpressionCached(node.moduleReference); } } } @@ -1998,7 +1998,7 @@ namespace ts { let left: EntityNameOrEntityNameExpression; if (name.kind === SyntaxKind.QualifiedName) { - left = (name).left; + left = name.left; } else if (name.kind === SyntaxKind.PropertyAccessExpression) { left = name.expression; @@ -3048,7 +3048,7 @@ namespace ts { function createTypeNodeFromObjectType(type: ObjectType): TypeNode { if (isGenericMappedType(type)) { - return createMappedTypeNodeFromType(type); + return createMappedTypeNodeFromType(type); } const resolved = resolveStructuredTypeMembers(type); @@ -3138,7 +3138,7 @@ namespace ts { const typeArgumentSlice = mapToTypeNodes(typeArguments.slice(start, i), context); const typeArgumentNodes = typeArgumentSlice && createNodeArray(typeArgumentSlice); const namePart = symbolToTypeReferenceName(parent); - (namePart.kind === SyntaxKind.Identifier ? namePart : namePart.right).typeArguments = typeArgumentNodes; + (namePart.kind === SyntaxKind.Identifier ? namePart : namePart.right).typeArguments = typeArgumentNodes; if (qualifiedName) { Debug.assert(!qualifiedName.right); @@ -3170,7 +3170,7 @@ namespace ts { } if (typeArgumentNodes) { - const lastIdentifier = entityName.kind === SyntaxKind.Identifier ? entityName : entityName.right; + const lastIdentifier = entityName.kind === SyntaxKind.Identifier ? entityName : entityName.right; lastIdentifier.typeArguments = undefined; } @@ -3191,7 +3191,7 @@ namespace ts { rightPart = rightPart.left; } - left.right = rightPart.left; + left.right = rightPart.left; rightPart.left = left; return right; } @@ -3326,7 +3326,7 @@ namespace ts { const typePredicate = getTypePredicateOfSignature(signature); if (typePredicate) { const parameterName = typePredicate.kind === TypePredicateKind.Identifier ? - setEmitFlags(createIdentifier((typePredicate).parameterName), EmitFlags.NoAsciiEscaping) : + setEmitFlags(createIdentifier(typePredicate.parameterName), EmitFlags.NoAsciiEscaping) : createThisTypeNode(); const typeNode = typeToTypeNodeHelper(typePredicate.type, context); returnTypeNode = createTypePredicateNode(parameterName, typeNode); @@ -3809,7 +3809,7 @@ namespace ts { if (isInternalModuleImportEqualsDeclaration(declaration)) { // Add the referenced top container visible - const internalModuleReference = (declaration).moduleReference; + const internalModuleReference = declaration.moduleReference; const firstIdentifier = getFirstIdentifier(internalModuleReference); const importSymbol = resolveName(declaration, firstIdentifier.escapedText, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace, undefined, undefined, /*isUse*/ false); @@ -3934,7 +3934,7 @@ namespace ts { } function isComputedNonLiteralName(name: PropertyName): boolean { - return name.kind === SyntaxKind.ComputedPropertyName && !isStringOrNumericLiteral((name).expression); + return name.kind === SyntaxKind.ComputedPropertyName && !isStringOrNumericLiteral(name.expression); } function getRestType(source: Type, properties: PropertyName[], symbol: Symbol): Type { @@ -3992,7 +3992,7 @@ namespace ts { } const literalMembers: PropertyName[] = []; for (const element of pattern.elements) { - if (!(element as BindingElement).dotDotDotToken) { + if (!element.dotDotDotToken) { literalMembers.push(element.propertyName || element.name as Identifier); } } @@ -4088,7 +4088,7 @@ namespace ts { // A variable declared in a for..in statement is of type string, or of type keyof T when the // right hand expression is of a type parameter type. if (isVariableDeclaration(declaration) && declaration.parent.parent.kind === SyntaxKind.ForInStatement) { - const indexType = getIndexType(checkNonNullExpression((declaration.parent.parent).expression)); + const indexType = getIndexType(checkNonNullExpression(declaration.parent.parent.expression)); return indexType.flags & (TypeFlags.TypeParameter | TypeFlags.Index) ? indexType : stringType; } @@ -4097,7 +4097,7 @@ namespace ts { // missing properties/signatures required to get its iteratedType (like // [Symbol.iterator] or next). This may be because we accessed properties from anyType, // or it may have led to an error inside getElementTypeOfIterable. - const forOfStatement = declaration.parent.parent; + const forOfStatement = declaration.parent.parent; return checkRightHandSideOfForOf(forOfStatement.expression, forOfStatement.awaitModifier) || anyType; } @@ -4150,7 +4150,7 @@ namespace ts { type = getContextualThisParameterType(func); } else { - type = getContextuallyTypedParameterType(declaration); + type = getContextuallyTypedParameterType(declaration); } if (type) { return addOptionality(type, isOptional); @@ -4171,7 +4171,7 @@ namespace ts { // If the declaration specifies a binding pattern, use the type implied by the binding pattern if (isBindingPattern(declaration.name)) { - return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ false, /*reportErrors*/ true); + return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ false, /*reportErrors*/ true); } // No type specified and nothing can be inferred @@ -4232,7 +4232,7 @@ namespace ts { return checkDeclarationInitializer(element); } if (isBindingPattern(element.name)) { - return getTypeFromBindingPattern(element.name, includePatternInType, reportErrors); + return getTypeFromBindingPattern(element.name, includePatternInType, reportErrors); } if (reportErrors && noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) { reportImplicitAnyError(element, anyType); @@ -4300,8 +4300,8 @@ namespace ts { // the parameter. function getTypeFromBindingPattern(pattern: BindingPattern, includePatternInType?: boolean, reportErrors?: boolean): Type { return pattern.kind === SyntaxKind.ObjectBindingPattern - ? getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors) - : getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors); + ? getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors) + : getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors); } // Return the type associated with a variable, parameter, or property declaration. In the simple case this is the type @@ -5976,7 +5976,7 @@ namespace ts { function getCombinedMappedTypeOptionality(type: MappedType): number { const optionality = getMappedTypeOptionality(type); const modifiersType = getModifiersTypeFromMappedType(type); - return optionality || (isGenericMappedType(modifiersType) ? getMappedTypeOptionality(modifiersType) : 0); + return optionality || (isGenericMappedType(modifiersType) ? getMappedTypeOptionality(modifiersType) : 0); } function isPartialMappedType(type: Type) { @@ -6517,9 +6517,8 @@ namespace ts { } if (node.initializer) { - const signatureDeclaration = node.parent; - const signature = getSignatureFromDeclaration(signatureDeclaration); - const parameterIndex = signatureDeclaration.parameters.indexOf(node); + const signature = getSignatureFromDeclaration(node.parent); + const parameterIndex = node.parent.parameters.indexOf(node); Debug.assert(parameterIndex >= 0); return parameterIndex >= signature.minArgumentCount; } @@ -6539,7 +6538,7 @@ namespace ts { if (parameterName.kind === SyntaxKind.Identifier) { return createIdentifierTypePredicate( parameterName && parameterName.escapedText as string, // TODO: GH#18217 - parameterName && getTypePredicateParameterIndex((node.parent as SignatureDeclaration).parameters, parameterName), + parameterName && getTypePredicateParameterIndex(node.parent.parameters, parameterName), type); } else { @@ -7187,11 +7186,11 @@ namespace ts { function getTypeReferenceName(node: TypeReferenceType): EntityNameOrEntityNameExpression | undefined { switch (node.kind) { case SyntaxKind.TypeReference: - return (node).typeName; + return node.typeName; case SyntaxKind.ExpressionWithTypeArguments: // We only support expressions that are simple qualified names. For other // expressions this produces undefined. - const expr = (node).expression; + const expr = node.expression; if (isEntityNameExpression(expr)) { return expr; } @@ -7992,10 +7991,10 @@ namespace ts { } function getPropertyTypeForIndexType(objectType: Type, indexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode, cacheSymbol: boolean) { - const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined; + const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined; const propName = isTypeUsableAsLateBoundName(indexType) ? getLateBoundNameFromType(indexType) : accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) ? - getPropertyNameForKnownSymbolName(idText(((accessExpression.argumentExpression).name))) : + getPropertyNameForKnownSymbolName(idText((accessExpression.argumentExpression).name)) : undefined; if (propName !== undefined) { const prop = getPropertyOfType(objectType, propName); @@ -8039,7 +8038,7 @@ namespace ts { } } if (accessNode) { - const indexNode = accessNode.kind === SyntaxKind.ElementAccessExpression ? (accessNode).argumentExpression : (accessNode).indexType; + const indexNode = accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode.argumentExpression : accessNode.indexType; if (indexType.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral)) { error(indexNode, Diagnostics.Property_0_does_not_exist_on_type_1, "" + (indexType).value, typeToString(objectType)); } @@ -8129,10 +8128,9 @@ namespace ts { } function substituteIndexedMappedType(objectType: MappedType, type: IndexedAccessType) { - const mapper = createTypeMapper([getTypeParameterFromMappedType(objectType)], [type.indexType]); - const objectTypeMapper = (objectType).mapper; - const templateMapper = objectTypeMapper ? combineTypeMappers(objectTypeMapper, mapper) : mapper; - return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper); + const mapper = createTypeMapper([getTypeParameterFromMappedType(objectType)], [type.indexType]); + const templateMapper = objectType.mapper ? combineTypeMappers(objectType.mapper, mapper) : mapper; + return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper); } function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode): Type { @@ -9241,13 +9239,12 @@ namespace ts { } if (source.kind === TypePredicateKind.Identifier) { - const sourcePredicate = source as IdentifierTypePredicate; const targetPredicate = target as IdentifierTypePredicate; - const sourceIndex = sourcePredicate.parameterIndex - (getThisParameter(sourceDeclaration) ? 1 : 0); + const sourceIndex = source.parameterIndex - (getThisParameter(sourceDeclaration) ? 1 : 0); const targetIndex = targetPredicate.parameterIndex - (getThisParameter(targetDeclaration) ? 1 : 0); if (sourceIndex !== targetIndex) { if (reportErrors) { - errorReporter(Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, sourcePredicate.parameterName, targetPredicate.parameterName); + errorReporter(Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, source.parameterName, targetPredicate.parameterName); errorReporter(Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target)); } return Ternary.False; @@ -10022,17 +10019,17 @@ namespace ts { } else if (isGenericMappedType(target)) { // A source type T is related to a target type { [P in X]: T[P] } - const template = getTemplateTypeFromMappedType(target); - const modifiers = getMappedTypeModifiers(target); + const template = getTemplateTypeFromMappedType(target); + const modifiers = getMappedTypeModifiers(target); if (!(modifiers & MappedTypeModifiers.ExcludeOptional)) { if (template.flags & TypeFlags.IndexedAccess && (template).objectType === source && - (template).indexType === getTypeParameterFromMappedType(target)) { + (template).indexType === getTypeParameterFromMappedType(target)) { return Ternary.True; } // A source type T is related to a target type { [P in keyof T]: X } if T[P] is related to X. - if (!isGenericMappedType(source) && getConstraintTypeFromMappedType(target) === getIndexType(source)) { - const indexedAccessType = getIndexedAccessType(source, getTypeParameterFromMappedType(target)); - const templateType = getTemplateTypeFromMappedType(target); + if (!isGenericMappedType(source) && getConstraintTypeFromMappedType(target) === getIndexType(source)) { + const indexedAccessType = getIndexedAccessType(source, getTypeParameterFromMappedType(target)); + const templateType = getTemplateTypeFromMappedType(target); if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) { errorInfo = saveErrorInfo; return result; @@ -10154,7 +10151,7 @@ namespace ts { result = Ternary.True; } else if (isGenericMappedType(target)) { - result = isGenericMappedType(source) ? mappedTypeRelatedTo(source, target, reportStructuralErrors) : Ternary.False; + result = isGenericMappedType(source) ? mappedTypeRelatedTo(source, target, reportStructuralErrors) : Ternary.False; } else { result = propertiesRelatedTo(source, target, reportStructuralErrors); @@ -10192,9 +10189,9 @@ namespace ts { getCombinedMappedTypeOptionality(source) <= getCombinedMappedTypeOptionality(target)); if (modifiersRelated) { let result: Ternary; - if (result = isRelatedTo(getConstraintTypeFromMappedType(target), getConstraintTypeFromMappedType(source), reportErrors)) { - const mapper = createTypeMapper([getTypeParameterFromMappedType(source)], [getTypeParameterFromMappedType(target)]); - return result & isRelatedTo(instantiateType(getTemplateTypeFromMappedType(source), mapper), getTemplateTypeFromMappedType(target), reportErrors); + if (result = isRelatedTo(getConstraintTypeFromMappedType(target), getConstraintTypeFromMappedType(source), reportErrors)) { + const mapper = createTypeMapper([getTypeParameterFromMappedType(source)], [getTypeParameterFromMappedType(target)]); + return result & isRelatedTo(instantiateType(getTemplateTypeFromMappedType(source), mapper), getTemplateTypeFromMappedType(target), reportErrors); } } return Ternary.False; @@ -10500,7 +10497,7 @@ namespace ts { if (isGenericMappedType(source)) { // A generic mapped type { [P in K]: T } is related to an index signature { [x: string]: U } // if T is related to U. - return kind === IndexKind.String && isRelatedTo(getTemplateTypeFromMappedType(source), targetInfo.type, reportErrors); + return kind === IndexKind.String && isRelatedTo(getTemplateTypeFromMappedType(source), targetInfo.type, reportErrors); } if (isObjectTypeWithInferableIndex(source)) { let related = Ternary.True; @@ -11679,8 +11676,8 @@ namespace ts { if (isGenericMappedType(source) && isGenericMappedType(target)) { // The source and target types are generic types { [P in S]: X } and { [P in T]: Y }, so we infer // from S to T and from X to Y. - inferFromTypes(getConstraintTypeFromMappedType(source), getConstraintTypeFromMappedType(target)); - inferFromTypes(getTemplateTypeFromMappedType(source), getTemplateTypeFromMappedType(target)); + inferFromTypes(getConstraintTypeFromMappedType(source), getConstraintTypeFromMappedType(target)); + inferFromTypes(getTemplateTypeFromMappedType(source), getTemplateTypeFromMappedType(target)); } if (getObjectFlags(target) & ObjectFlags.Mapped) { const constraintType = getConstraintTypeFromMappedType(target); @@ -12243,7 +12240,7 @@ namespace ts { } function getAssignedTypeOfPropertyAssignment(node: PropertyAssignment | ShorthandPropertyAssignment): Type { - return getTypeOfDestructuredProperty(getAssignedType(node.parent), node.name); + return getTypeOfDestructuredProperty(getAssignedType(node.parent), node.name); } function getAssignedTypeOfShorthandPropertyAssignment(node: ShorthandPropertyAssignment): Type { @@ -12274,7 +12271,7 @@ namespace ts { } function getInitialTypeOfBindingElement(node: BindingElement): Type { - const pattern = node.parent; + const pattern = node.parent; const parentType = getInitialType(pattern.parent); const type = pattern.kind === SyntaxKind.ObjectBindingPattern ? getTypeOfDestructuredProperty(parentType, node.propertyName || node.name) : @@ -12300,21 +12297,21 @@ namespace ts { return stringType; } if (node.parent.parent.kind === SyntaxKind.ForOfStatement) { - return checkRightHandSideOfForOf((node.parent.parent).expression, (node.parent.parent).awaitModifier) || unknownType; + return checkRightHandSideOfForOf(node.parent.parent.expression, node.parent.parent.awaitModifier) || unknownType; } return unknownType; } function getInitialType(node: VariableDeclaration | BindingElement) { return node.kind === SyntaxKind.VariableDeclaration ? - getInitialTypeOfVariableDeclaration(node) : - getInitialTypeOfBindingElement(node); + getInitialTypeOfVariableDeclaration(node) : + getInitialTypeOfBindingElement(node); } function getInitialOrAssignedType(node: VariableDeclaration | BindingElement | Expression) { return node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement ? getInitialType(node) : - getAssignedType(node); + getAssignedType(node); } function isEmptyArrayAssignment(node: VariableDeclaration | BindingElement | Expression) { @@ -12349,7 +12346,7 @@ namespace ts { function getTypeOfSwitchClause(clause: CaseClause | DefaultClause) { if (clause.kind === SyntaxKind.CaseClause) { - const caseType = getRegularTypeOfLiteralType(getTypeOfExpression((clause).expression)); + const caseType = getRegularTypeOfLiteralType(getTypeOfExpression(clause.expression)); return isUnitType(caseType) ? caseType : undefined; } return neverType; @@ -12722,22 +12719,22 @@ namespace ts { if (declaredType === autoType || declaredType === autoArrayType) { const node = flow.node; const expr = node.kind === SyntaxKind.CallExpression ? - ((node).expression).expression : - ((node).left).expression; + (node.expression).expression : + (node.left).expression; if (isMatchingReference(reference, getReferenceCandidate(expr))) { const flowType = getTypeAtFlowNode(flow.antecedent); const type = getTypeFromFlowType(flowType); if (getObjectFlags(type) & ObjectFlags.EvolvingArray) { let evolvedType = type; if (node.kind === SyntaxKind.CallExpression) { - for (const arg of (node).arguments) { + for (const arg of node.arguments) { evolvedType = addEvolvingArrayElementType(evolvedType, arg); } } else { - const indexType = getTypeOfExpression(((node).left).argumentExpression); + const indexType = getTypeOfExpression((node.left).argumentExpression); if (isTypeAssignableToKind(indexType, TypeFlags.NumberLike)) { - evolvedType = addEvolvingArrayElementType(evolvedType, (node).right); + evolvedType = addEvolvingArrayElementType(evolvedType, node.right); } } return evolvedType === type ? flowType : createFlowType(evolvedType, isIncomplete(flowType)); @@ -13954,10 +13951,10 @@ namespace ts { } } - function getContainingObjectLiteral(func: FunctionLike) { + function getContainingObjectLiteral(func: FunctionLike): ObjectLiteralExpression | undefined { return (func.kind === SyntaxKind.MethodDeclaration || func.kind === SyntaxKind.GetAccessor || - func.kind === SyntaxKind.SetAccessor) && func.parent.kind === SyntaxKind.ObjectLiteralExpression ? func.parent : + func.kind === SyntaxKind.SetAccessor) && func.parent.kind === SyntaxKind.ObjectLiteralExpression ? func.parent : func.kind === SyntaxKind.FunctionExpression && func.parent.kind === SyntaxKind.PropertyAssignment ? func.parent.parent : undefined; } @@ -14097,17 +14094,17 @@ namespace ts { return getTypeFromTypeNode(typeNode); } if (declaration.kind === SyntaxKind.Parameter) { - const type = getContextuallyTypedParameterType(declaration); + const type = getContextuallyTypedParameterType(declaration); if (type) { return type; } } if (isBindingPattern(declaration.name)) { - return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ true, /*reportErrors*/ false); + return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ true, /*reportErrors*/ false); } if (isBindingPattern(declaration.parent)) { const parentDeclaration = declaration.parent.parent; - const name = (declaration as BindingElement).propertyName || (declaration as BindingElement).name; + const name = (declaration as BindingElement).propertyName || declaration.name; if (parentDeclaration.kind !== SyntaxKind.BindingElement) { const parentTypeNode = getEffectiveTypeAnnotationNode(parentDeclaration); if (parentTypeNode && !isBindingPattern(name)) { @@ -14891,19 +14888,19 @@ namespace ts { let type: Type; if (memberDecl.kind === SyntaxKind.PropertyAssignment) { if (memberDecl.name.kind === SyntaxKind.ComputedPropertyName) { - const t = checkComputedPropertyName(memberDecl.name); + const t = checkComputedPropertyName(memberDecl.name); if (t.flags & TypeFlags.Literal) { literalName = escapeLeadingUnderscores("" + (t as LiteralType).value); } } - type = checkPropertyAssignment(memberDecl, checkMode); + type = checkPropertyAssignment(memberDecl, checkMode); } else if (memberDecl.kind === SyntaxKind.MethodDeclaration) { - type = checkObjectLiteralMethod(memberDecl, checkMode); + type = checkObjectLiteralMethod(memberDecl, checkMode); } else { Debug.assert(memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment); - type = checkExpressionForMutableLocation((memberDecl).name, checkMode); + type = checkExpressionForMutableLocation(memberDecl.name, checkMode); } if (jsdocType) { @@ -14922,8 +14919,8 @@ namespace ts { // If object literal is an assignment pattern and if the assignment pattern specifies a default value // for the property, make the property optional. const isOptional = - (memberDecl.kind === SyntaxKind.PropertyAssignment && hasDefaultValue((memberDecl).initializer)) || - (memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment && (memberDecl).objectAssignmentInitializer); + (memberDecl.kind === SyntaxKind.PropertyAssignment && hasDefaultValue(memberDecl.initializer)) || + (memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment && memberDecl.objectAssignmentInitializer); if (isOptional) { prop.flags |= SymbolFlags.Optional; } @@ -14966,7 +14963,7 @@ namespace ts { hasComputedNumberProperty = false; typeFlags = 0; } - const type = checkExpression((memberDecl as SpreadAssignment).expression); + const type = checkExpression(memberDecl.expression); if (!isValidSpreadType(type)) { error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types); return unknownType; @@ -15133,7 +15130,7 @@ namespace ts { if (isJsxAttribute(attributeDecl)) { const exprType = checkJsxAttribute(attributeDecl, checkMode); - const attributeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient | member.flags, member.escapedName); + const attributeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient | member.flags, member.escapedName); attributeSymbol.declarations = member.declarations; attributeSymbol.parent = member.parent; if (member.valueDeclaration) { @@ -15175,7 +15172,7 @@ namespace ts { const parent = openingLikeElement.parent.kind === SyntaxKind.JsxElement ? openingLikeElement.parent as JsxElement : undefined; // We have to check that openingElement of the parent is the one we are visiting as this may not be true for selfClosingElement if (parent && parent.openingElement === openingLikeElement && parent.children.length > 0) { - const childrenTypes: Type[] = checkJsxChildren(parent as JsxElement, checkMode); + const childrenTypes: Type[] = checkJsxChildren(parent, checkMode); if (!hasSpreadAnyType && jsxChildrenPropertyName && jsxChildrenPropertyName !== "") { // Error if there is a attribute named "children" explicitly specified and children element. @@ -15239,7 +15236,7 @@ namespace ts { * @param node a JSXAttributes to be resolved of its type */ function checkJsxAttributes(node: JsxAttributes, checkMode: CheckMode) { - return createJsxAttributesTypeFromAttributesProperty(node.parent as JsxOpeningLikeElement, checkMode); + return createJsxAttributesTypeFromAttributesProperty(node.parent, checkMode); } function getJsxType(name: __String) { @@ -15795,7 +15792,7 @@ namespace ts { if (!isJsxAttribute(attribute)) { continue; } - const attrName = attribute.name as Identifier; + const attrName = attribute.name; const isNotIgnoredJsxProperty = (isUnhyphenatedJsxName(idText(attrName)) || !!(getPropertyOfType(targetAttributesType, attrName.escapedText))); if (isNotIgnoredJsxProperty && !isKnownProperty(targetAttributesType, attrName.escapedText, /*isComparingJsxAttributes*/ true)) { error(attribute, Diagnostics.Property_0_does_not_exist_on_type_1, idText(attrName), typeToString(targetAttributesType)); @@ -15845,7 +15842,7 @@ namespace ts { function checkPropertyAccessibility(node: PropertyAccessExpression | QualifiedName | VariableLikeDeclaration, left: Expression | QualifiedName, type: Type, prop: Symbol): boolean { const flags = getDeclarationModifierFlagsFromSymbol(prop); const errorNode = node.kind === SyntaxKind.PropertyAccessExpression || node.kind === SyntaxKind.VariableDeclaration ? - (node).name : + node.name : (node).right; if (getCheckFlags(prop) & CheckFlags.ContainsPrivate) { @@ -16451,7 +16448,7 @@ namespace ts { } if (node.kind === SyntaxKind.TaggedTemplateExpression) { - checkExpression((node).template); + checkExpression(node.template); } else if (node.kind !== SyntaxKind.Decorator) { forEach((node).arguments, argument => { @@ -16542,18 +16539,15 @@ namespace ts { } if (node.kind === SyntaxKind.TaggedTemplateExpression) { - const tagExpression = node; - // Even if the call is incomplete, we'll have a missing expression as our last argument, // so we can say the count is just the arg list length argCount = args.length; typeArguments = undefined; - if (tagExpression.template.kind === SyntaxKind.TemplateExpression) { + if (node.template.kind === SyntaxKind.TemplateExpression) { // If a tagged template expression lacks a tail literal, the call is incomplete. // Specifically, a template only can end in a TemplateTail or a Missing literal. - const templateExpression = tagExpression.template; - const lastSpan = lastOrUndefined(templateExpression.templateSpans); + const lastSpan = lastOrUndefined(node.template.templateSpans); Debug.assert(lastSpan !== undefined); // we should always have at least one span. callIsIncomplete = nodeIsMissing(lastSpan.literal) || !!lastSpan.literal.isUnterminated; } @@ -16561,7 +16555,7 @@ namespace ts { // If the template didn't end in a backtick, or its beginning occurred right prior to EOF, // then this might actually turn out to be a TemplateHead in the future; // so we consider the call to be incomplete. - const templateLiteral = tagExpression.template; + const templateLiteral = node.template; Debug.assert(templateLiteral.kind === SyntaxKind.NoSubstitutionTemplateLiteral); callIsIncomplete = !!templateLiteral.isUnterminated; } @@ -16571,10 +16565,9 @@ namespace ts { argCount = getEffectiveArgumentCount(node, /*args*/ undefined, signature); } else { - const callExpression = node; - if (!callExpression.arguments) { + if (!node.arguments) { // This only happens when we have something of the form: 'new C' - Debug.assert(callExpression.kind === SyntaxKind.NewExpression); + Debug.assert(node.kind === SyntaxKind.NewExpression); return signature.minArgumentCount === 0; } @@ -16582,9 +16575,9 @@ namespace ts { argCount = signatureHelpTrailingComma ? args.length + 1 : args.length; // If we are missing the close parenthesis, the call is incomplete. - callIsIncomplete = callExpression.arguments.end === callExpression.end; + callIsIncomplete = node.arguments.end === node.end; - typeArguments = callExpression.typeArguments; + typeArguments = node.typeArguments; spreadArgIndex = getSpreadArgumentIndex(args); } @@ -16811,7 +16804,7 @@ namespace ts { excludeArgument: boolean[], reportErrors: boolean) { if (isJsxOpeningLikeElement(node)) { - return checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation); + return checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation); } const thisType = getThisTypeOfSignature(signature); if (thisType && thisType !== voidType && node.kind !== SyntaxKind.NewExpression) { @@ -16858,7 +16851,7 @@ namespace ts { */ function getThisArgumentOfCall(node: CallLikeExpression): LeftHandSideExpression { if (node.kind === SyntaxKind.CallExpression) { - const callee = (node).expression; + const callee = node.expression; if (callee.kind === SyntaxKind.PropertyAccessExpression) { return (callee as PropertyAccessExpression).expression; } @@ -16879,10 +16872,10 @@ namespace ts { */ function getEffectiveCallArguments(node: CallLikeExpression): ReadonlyArray { if (node.kind === SyntaxKind.TaggedTemplateExpression) { - const template = (node).template; + const template = node.template; const args: Expression[] = [undefined]; if (template.kind === SyntaxKind.TemplateExpression) { - forEach((template).templateSpans, span => { + forEach(template.templateSpans, span => { args.push(span.expression); }); } @@ -17134,7 +17127,7 @@ namespace ts { // a special first argument, and string literals get string literal types // unless we're reporting errors if (node.kind === SyntaxKind.Decorator) { - return getEffectiveDecoratorArgumentType(node, argIndex); + return getEffectiveDecoratorArgumentType(node, argIndex); } else if (argIndex === 0 && node.kind === SyntaxKind.TaggedTemplateExpression) { return getGlobalTemplateStringsArrayType(); @@ -17164,11 +17157,11 @@ namespace ts { function getEffectiveArgumentErrorNode(node: CallLikeExpression, argIndex: number, arg: Expression) { if (node.kind === SyntaxKind.Decorator) { // For a decorator, we use the expression of the decorator for error reporting. - return (node).expression; + return node.expression; } else if (argIndex === 0 && node.kind === SyntaxKind.TaggedTemplateExpression) { // For a the first argument of a tagged template expression, we use the template of the tag for error reporting. - return (node).template; + return node.template; } else { return arg; @@ -17260,7 +17253,7 @@ namespace ts { // If we are in signature help, a trailing comma indicates that we intend to provide another argument, // so we will only accept overloads with arity at least 1 higher than the current number of provided arguments. const signatureHelpTrailingComma = - candidatesOutArray && node.kind === SyntaxKind.CallExpression && (node).arguments.hasTrailingComma; + candidatesOutArray && node.kind === SyntaxKind.CallExpression && node.arguments.hasTrailingComma; // Section 4.12.1: // if the candidate list contains one or more signatures for which the type of each argument @@ -17814,17 +17807,17 @@ namespace ts { function resolveSignature(node: CallLikeExpression, candidatesOutArray?: Signature[]): Signature { switch (node.kind) { case SyntaxKind.CallExpression: - return resolveCallExpression(node, candidatesOutArray); + return resolveCallExpression(node, candidatesOutArray); case SyntaxKind.NewExpression: - return resolveNewExpression(node, candidatesOutArray); + return resolveNewExpression(node, candidatesOutArray); case SyntaxKind.TaggedTemplateExpression: - return resolveTaggedTemplateExpression(node, candidatesOutArray); + return resolveTaggedTemplateExpression(node, candidatesOutArray); case SyntaxKind.Decorator: - return resolveDecorator(node, candidatesOutArray); + return resolveDecorator(node, candidatesOutArray); case SyntaxKind.JsxOpeningElement: case SyntaxKind.JsxSelfClosingElement: // This code-path is called by language service - return resolveStatelessJsxOpeningLikeElement(node, checkExpression((node).tagName), candidatesOutArray) || unknownSignature; + return resolveStatelessJsxOpeningLikeElement(node, checkExpression(node.tagName), candidatesOutArray) || unknownSignature; } Debug.assertNever(node, "Branch in 'resolveSignature' should be unreachable."); } @@ -18210,7 +18203,7 @@ namespace ts { if (globalPromiseType !== emptyGenericType) { // if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type promisedType = getAwaitedType(promisedType) || emptyObjectType; - return createTypeReference(globalPromiseType, [promisedType]); + return createTypeReference(globalPromiseType, [promisedType]); } return emptyObjectType; @@ -18241,7 +18234,7 @@ namespace ts { const functionFlags = getFunctionFlags(func); let type: Type; if (func.body.kind !== SyntaxKind.Block) { - type = checkExpressionCached(func.body, checkMode); + type = checkExpressionCached(func.body, checkMode); if (functionFlags & FunctionFlags.Async) { // From within an async function you can return either a non-promise value or a promise. Any // Promise/A+ compatible implementation will always assimilate any foreign promise, so the @@ -18526,9 +18519,9 @@ namespace ts { } if (produceDiagnostics && node.kind !== SyntaxKind.MethodDeclaration) { - checkCollisionWithCapturedSuperVariable(node, (node).name); - checkCollisionWithCapturedThisVariable(node, (node).name); - checkCollisionWithCapturedNewTargetVariable(node, (node).name); + checkCollisionWithCapturedSuperVariable(node, node.name); + checkCollisionWithCapturedThisVariable(node, node.name); + checkCollisionWithCapturedNewTargetVariable(node, node.name); } return type; @@ -18568,7 +18561,7 @@ namespace ts { // should not be checking assignability of a promise to the return type. Instead, we need to // check assignability of the awaited type of the expression body against the promised type of // its return type annotation. - const exprType = checkExpression(node.body); + const exprType = checkExpression(node.body); if (returnOrPromisedType) { if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async) { // Async function const awaitedType = checkAwaitedType(exprType, node.body, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); @@ -18849,9 +18842,9 @@ namespace ts { /** Note: If property cannot be a SpreadAssignment, then allProperties does not need to be provided */ function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType: Type, property: ObjectLiteralElementLike, allProperties?: ReadonlyArray) { if (property.kind === SyntaxKind.PropertyAssignment || property.kind === SyntaxKind.ShorthandPropertyAssignment) { - const name = (property).name; + const name = property.name; if (name.kind === SyntaxKind.ComputedPropertyName) { - checkComputedPropertyName(name); + checkComputedPropertyName(name); } if (isComputedNonLiteralName(name)) { return undefined; @@ -18865,11 +18858,11 @@ namespace ts { getIndexTypeOfType(objectLiteralType, IndexKind.String); if (type) { if (property.kind === SyntaxKind.ShorthandPropertyAssignment) { - return checkDestructuringAssignment(property, type); + return checkDestructuringAssignment(property, type); } else { // non-shorthand property assignments should always have initializers - return checkDestructuringAssignment((property).initializer, type); + return checkDestructuringAssignment(property.initializer, type); } } else { @@ -18971,7 +18964,7 @@ namespace ts { target = (exprOrAssignment).name; } else { - target = exprOrAssignment; + target = exprOrAssignment; } if (target.kind === SyntaxKind.BinaryExpression && (target).operatorToken.kind === SyntaxKind.EqualsToken) { @@ -19373,7 +19366,7 @@ namespace ts { // It is worth asking whether this is what we really want though. // A place where we actually *are* concerned with the expressions' types are // in tagged templates. - forEach((node).templateSpans, templateSpan => { + forEach(node.templateSpans, templateSpan => { checkExpression(templateSpan.expression); }); @@ -19471,10 +19464,10 @@ namespace ts { // We want to perform checkComputedPropertyName for all computed properties, including // well known symbols. if (node.name.kind === SyntaxKind.ComputedPropertyName) { - checkComputedPropertyName(node.name); + checkComputedPropertyName(node.name); } - return checkExpressionForMutableLocation((node).initializer, checkMode); + return checkExpressionForMutableLocation(node.initializer, checkMode); } function checkObjectLiteralMethod(node: MethodDeclaration, checkMode?: CheckMode): Type { @@ -19485,7 +19478,7 @@ namespace ts { // We want to perform checkComputedPropertyName for all computed properties, including // well known symbols. if (node.name.kind === SyntaxKind.ComputedPropertyName) { - checkComputedPropertyName(node.name); + checkComputedPropertyName(node.name); } const uninstantiatedType = checkFunctionExpressionOrObjectLiteralMethod(node, checkMode); @@ -19559,8 +19552,8 @@ namespace ts { type = checkQualifiedName(node); } else { - const uninstantiatedType = checkExpressionWorker(node, checkMode); - type = instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode); + const uninstantiatedType = checkExpressionWorker(node, checkMode); + type = instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode); } if (isConstEnumObjectType(type)) { @@ -20179,7 +20172,7 @@ namespace ts { // Skip past any prologue directives to find the first statement // to ensure that it was a super call. if (superCallShouldBeFirst) { - const statements = (node.body).statements; + const statements = node.body.statements; let superCallStatement: ExpressionStatement; for (const statement of statements) { @@ -20220,7 +20213,7 @@ namespace ts { // We want to perform checkComputedPropertyName for all computed properties, including // well known symbols. if (node.name.kind === SyntaxKind.ComputedPropertyName) { - checkComputedPropertyName(node.name); + checkComputedPropertyName(node.name); } if (!hasNonBindableDynamicName(node)) { // TypeScript 1.0 spec (April 2014): 8.4.3 @@ -21327,7 +21320,7 @@ namespace ts { if (node.name && node.name.kind === SyntaxKind.ComputedPropertyName) { // This check will account for methods in class/interface declarations, // as well as accessors in classes/object literals - checkComputedPropertyName(node.name); + checkComputedPropertyName(node.name); } if (!hasNonBindableDynamicName(node)) { @@ -21931,7 +21924,7 @@ namespace ts { checkExternalEmitHelpers(node, ExternalEmitHelpers.Read); } - forEach((node.name).elements, checkSourceElement); + forEach(node.name.elements, checkSourceElement); } // For a parameter declaration with an initializer, error and exit if the containing function doesn't have a body if (node.initializer && getRootDeclaration(node).kind === SyntaxKind.Parameter && nodeIsMissing((getContainingFunction(node) as FunctionLikeDeclaration).body)) { @@ -21985,7 +21978,7 @@ namespace ts { // We know we don't have a binding pattern or computed name here checkExportsOnMergedDeclarations(node); if (node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement) { - checkVarDeclaredNamesNotShadowed(node); + checkVarDeclaredNamesNotShadowed(node); } checkCollisionWithCapturedSuperVariable(node, node.name); checkCollisionWithCapturedThisVariable(node, node.name); @@ -22035,7 +22028,7 @@ namespace ts { } function checkBindingElement(node: BindingElement) { - checkGrammarBindingElement(node); + checkGrammarBindingElement(node); return checkVariableLikeDeclaration(node); } @@ -22095,7 +22088,7 @@ namespace ts { forEach((node.initializer).declarations, checkVariableDeclaration); } else { - checkExpression(node.initializer); + checkExpression(node.initializer); } } @@ -22111,7 +22104,7 @@ namespace ts { checkGrammarForInOrForOfStatement(node); if (node.kind === SyntaxKind.ForOfStatement) { - if ((node).awaitModifier) { + if (node.awaitModifier) { const functionFlags = getFunctionFlags(getContainingFunction(node)); if ((functionFlags & (FunctionFlags.Invalid | FunctionFlags.Async)) === FunctionFlags.Async && languageVersion < ScriptTarget.ESNext) { // for..await..of in an async function or async generator function prior to ESNext requires the __asyncValues helper @@ -22133,7 +22126,7 @@ namespace ts { checkForInOrForOfVariableDeclaration(node); } else { - const varExpr = node.initializer; + const varExpr = node.initializer; const iteratedType = checkRightHandSideOfForOf(node.expression, node.awaitModifier); // There may be a destructuring assignment on the left side @@ -22185,7 +22178,7 @@ namespace ts { // for (Var in Expr) Statement // Var must be an expression classified as a reference of type Any or the String primitive type, // and Expr must be an expression of type Any, an object type, or a type parameter type. - const varExpr = node.initializer; + const varExpr = node.initializer; const leftType = checkExpression(varExpr); if (varExpr.kind === SyntaxKind.ArrayLiteralExpression || varExpr.kind === SyntaxKind.ObjectLiteralExpression) { error(varExpr, Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern); @@ -22652,11 +22645,10 @@ namespace ts { } if (produceDiagnostics && clause.kind === SyntaxKind.CaseClause) { - const caseClause = clause; // TypeScript 1.0 spec (April 2014): 5.9 // In a 'switch' statement, each 'case' expression must be of a type that is comparable // to or from the type of the 'switch' expression. - let caseType = checkExpression(caseClause.expression); + let caseType = checkExpression(clause.expression); const caseIsLiteral = isLiteralType(caseType); let comparedExpressionType = expressionType; if (!caseIsLiteral || !expressionIsLiteral) { @@ -22665,7 +22657,7 @@ namespace ts { } if (!isTypeEqualityComparableTo(comparedExpressionType, caseType)) { // expressionType is not comparable to caseType, try the reversed check and report errors if it fails - checkTypeComparableTo(caseType, comparedExpressionType, caseClause.expression, /*headMessage*/ undefined); + checkTypeComparableTo(caseType, comparedExpressionType, clause.expression, /*headMessage*/ undefined); } } forEach(clause.statements, checkSourceElement); @@ -22759,7 +22751,7 @@ namespace ts { }); if (getObjectFlags(type) & ObjectFlags.Class && isClassLike(type.symbol.valueDeclaration)) { - const classDeclaration = type.symbol.valueDeclaration; + const classDeclaration = type.symbol.valueDeclaration; for (const member of classDeclaration.members) { // Only process instance properties with computed names here. // Static properties cannot be in conflict with indexers, @@ -22850,7 +22842,7 @@ namespace ts { case "symbol": case "void": case "object": - error(name, message, (name).escapedText as string); + error(name, message, name.escapedText as string); } } @@ -23355,11 +23347,11 @@ namespace ts { } function computeMemberValue(member: EnumMember, autoValue: number) { - if (isComputedNonLiteralName(member.name)) { + if (isComputedNonLiteralName(member.name)) { error(member.name, Diagnostics.Computed_property_names_are_not_allowed_in_enums); } else { - const text = getTextOfPropertyName(member.name); + const text = getTextOfPropertyName(member.name); if (isNumericLiteralName(text) && !isInfinityOrNaNString(text)) { error(member.name, Diagnostics.An_enum_member_cannot_have_a_numeric_name); } @@ -23745,17 +23737,17 @@ namespace ts { function getFirstIdentifier(node: EntityNameOrEntityNameExpression): Identifier { switch (node.kind) { case SyntaxKind.Identifier: - return node; + return node; case SyntaxKind.QualifiedName: do { - node = (node).left; + node = node.left; } while (node.kind !== SyntaxKind.Identifier); - return node; + return node; case SyntaxKind.PropertyAccessExpression: do { - node = (node).expression; + node = node.expression; } while (node.kind !== SyntaxKind.Identifier); - return node; + return node; } } @@ -23765,7 +23757,7 @@ namespace ts { error(moduleName, Diagnostics.String_literal_expected); return false; } - const inAmbientExternalModule = node.parent.kind === SyntaxKind.ModuleBlock && isAmbientModule(node.parent.parent); + const inAmbientExternalModule = node.parent.kind === SyntaxKind.ModuleBlock && isAmbientModule(node.parent.parent); if (node.parent.kind !== SyntaxKind.SourceFile && !inAmbientExternalModule) { error(moduleName, node.kind === SyntaxKind.ExportDeclaration ? Diagnostics.Export_declarations_are_not_permitted_in_a_namespace : @@ -23841,10 +23833,10 @@ namespace ts { } if (importClause.namedBindings) { if (importClause.namedBindings.kind === SyntaxKind.NamespaceImport) { - checkImportBinding(importClause.namedBindings); + checkImportBinding(importClause.namedBindings); } else { - forEach((importClause.namedBindings).elements, checkImportBinding); + forEach(importClause.namedBindings.elements, checkImportBinding); } } } @@ -23868,7 +23860,7 @@ namespace ts { if (target !== unknownSymbol) { if (target.flags & SymbolFlags.Value) { // Target is a value symbol, check that it is not hidden by a local declaration with the same name - const moduleName = getFirstIdentifier(node.moduleReference); + const moduleName = getFirstIdentifier(node.moduleReference); if (!(resolveEntityName(moduleName, SymbolFlags.Value | SymbolFlags.Namespace).flags & SymbolFlags.Namespace)) { error(moduleName, Diagnostics.Module_0_is_hidden_by_a_local_declaration_with_the_same_name, declarationNameToString(moduleName)); } @@ -23937,7 +23929,7 @@ namespace ts { if (compilerOptions.declaration) { collectLinkedAliases(node.propertyName || node.name, /*setVisibility*/ true); } - if (!(node.parent.parent).moduleSpecifier) { + if (!node.parent.parent.moduleSpecifier) { const exportedName = node.propertyName || node.name; // find immediate value referenced by exported name (SymbolFlags.Alias is set so we don't chase down aliases) const symbol = resolveName(exportedName, exportedName.escapedText, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias, @@ -23957,7 +23949,7 @@ namespace ts { return; } - const container = node.parent.kind === SyntaxKind.SourceFile ? node.parent : node.parent.parent; + const container = node.parent.kind === SyntaxKind.SourceFile ? node.parent : node.parent.parent; if (container.kind === SyntaxKind.ModuleDeclaration && !isAmbientModule(container)) { if (node.isExportEquals) { error(node, Diagnostics.An_export_assignment_cannot_be_used_in_a_namespace); @@ -24645,11 +24637,11 @@ namespace ts { /*all meanings*/ SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias); } - if (entityName.kind !== SyntaxKind.PropertyAccessExpression && isInRightSideOfImportOrExportAssignment(entityName)) { + if (entityName.kind !== SyntaxKind.PropertyAccessExpression && isInRightSideOfImportOrExportAssignment(entityName)) { // Since we already checked for ExportAssignment, this really could only be an Import - const importEqualsDeclaration = getAncestor(entityName, SyntaxKind.ImportEqualsDeclaration); + const importEqualsDeclaration = getAncestor(entityName, SyntaxKind.ImportEqualsDeclaration); Debug.assert(importEqualsDeclaration !== undefined); - return getSymbolOfPartOfRightHandSideOfImportEquals(entityName, /*dontResolveAlias*/ true); + return getSymbolOfPartOfRightHandSideOfImportEquals(entityName, /*dontResolveAlias*/ true); } if (isRightSideOfQualifiedNameOrPropertyAccess(entityName)) { @@ -24843,8 +24835,8 @@ namespace ts { /** Returns the target of an export specifier without following aliases */ function getExportSpecifierLocalTargetSymbol(node: ExportSpecifier): Symbol { - return (node.parent.parent).moduleSpecifier ? - getExternalModuleMember(node.parent.parent, node) : + return node.parent.parent.moduleSpecifier ? + getExternalModuleMember(node.parent.parent, node) : resolveEntityName(node.propertyName || node.name, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias); } @@ -25305,7 +25297,7 @@ namespace ts { } function getEnumMemberValue(node: EnumMember): string | number { - computeEnumMemberValues(node.parent); + computeEnumMemberValues(node.parent); return getNodeLinks(node).enumMemberValue; } @@ -25321,7 +25313,7 @@ namespace ts { function getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): string | number { if (node.kind === SyntaxKind.EnumMember) { - return getEnumMemberValue(node); + return getEnumMemberValue(node); } const symbol = getNodeLinks(node).resolvedSymbol; @@ -25636,7 +25628,7 @@ namespace ts { if (!moduleSymbol) { return undefined; } - return getDeclarationOfKind(moduleSymbol, SyntaxKind.SourceFile) as SourceFile; + return getDeclarationOfKind(moduleSymbol, SyntaxKind.SourceFile); } function initializeTypeChecker() { @@ -26358,13 +26350,13 @@ namespace ts { const name = prop.name; if (name.kind === SyntaxKind.ComputedPropertyName) { // If the name is not a ComputedPropertyName, the grammar checking will skip it - checkGrammarComputedPropertyName(name); + checkGrammarComputedPropertyName(name); } - if (prop.kind === SyntaxKind.ShorthandPropertyAssignment && !inDestructuring && (prop).objectAssignmentInitializer) { + if (prop.kind === SyntaxKind.ShorthandPropertyAssignment && !inDestructuring && prop.objectAssignmentInitializer) { // having objectAssignmentInitializer is only valid in ObjectAssignmentPattern // outside of destructuring it is a syntax error - return grammarErrorOnNode((prop).equalsToken, Diagnostics.can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment); + return grammarErrorOnNode(prop.equalsToken, Diagnostics.can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment); } // Modifiers are never allowed on properties except for 'async' on a method declaration @@ -26389,9 +26381,9 @@ namespace ts { case SyntaxKind.PropertyAssignment: case SyntaxKind.ShorthandPropertyAssignment: // Grammar checking for computedPropertyName and shorthandPropertyAssignment - checkGrammarForInvalidQuestionMark((prop).questionToken, Diagnostics.An_object_member_cannot_be_declared_optional); + checkGrammarForInvalidQuestionMark(prop.questionToken, Diagnostics.An_object_member_cannot_be_declared_optional); if (name.kind === SyntaxKind.NumericLiteral) { - checkGrammarNumericLiteral(name); + checkGrammarNumericLiteral(name); } // falls through case SyntaxKind.MethodDeclaration: @@ -26443,8 +26435,7 @@ namespace ts { continue; } - const jsxAttr = (attr); - const name = jsxAttr.name; + const { name, initializer } = attr; if (!seen.get(name.escapedText)) { seen.set(name.escapedText, true); } @@ -26452,9 +26443,8 @@ namespace ts { return grammarErrorOnNode(name, Diagnostics.JSX_elements_cannot_have_multiple_attributes_with_the_same_name); } - const initializer = jsxAttr.initializer; - if (initializer && initializer.kind === SyntaxKind.JsxExpression && !(initializer).expression) { - return grammarErrorOnNode(jsxAttr.initializer, Diagnostics.JSX_attributes_must_only_be_assigned_a_non_empty_expression); + if (initializer && initializer.kind === SyntaxKind.JsxExpression && !initializer.expression) { + return grammarErrorOnNode(initializer, Diagnostics.JSX_attributes_must_only_be_assigned_a_non_empty_expression); } } } @@ -26714,7 +26704,7 @@ namespace ts { function checkGrammarBindingElement(node: BindingElement) { if (node.dotDotDotToken) { - const elements = (node.parent).elements; + const elements = node.parent.elements; if (node !== last(elements)) { return grammarErrorOnNode(node, Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern); } @@ -26799,7 +26789,7 @@ namespace ts { } } else { - const elements = (name).elements; + const elements = name.elements; for (const element of elements) { if (!isOmittedExpression(element)) { return checkESModuleMarker(element.name); @@ -26810,12 +26800,12 @@ namespace ts { function checkGrammarNameInLetOrConstDeclarations(name: Identifier | BindingPattern): boolean { if (name.kind === SyntaxKind.Identifier) { - if ((name).originalKeywordKind === SyntaxKind.LetKeyword) { + if (name.originalKeywordKind === SyntaxKind.LetKeyword) { return grammarErrorOnNode(name, Diagnostics.let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations); } } else { - const elements = (name).elements; + const elements = name.elements; for (const element of elements) { if (!isOmittedExpression(element)) { checkGrammarNameInLetOrConstDeclarations(element.name); diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index f18a32889aa..a9b3568bfe6 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -350,8 +350,8 @@ namespace ts { // and also for non-optional initialized parameters that aren't a parameter property // these types may need to add `undefined`. const shouldUseResolverType = declaration.kind === SyntaxKind.Parameter && - (resolver.isRequiredInitializedParameter(declaration as ParameterDeclaration) || - resolver.isOptionalUninitializedParameterProperty(declaration as ParameterDeclaration)); + (resolver.isRequiredInitializedParameter(declaration) || + resolver.isOptionalUninitializedParameterProperty(declaration)); if (type && !shouldUseResolverType) { // Write the type emitType(type); @@ -839,10 +839,10 @@ namespace ts { function isVisibleNamedBinding(namedBindings: NamespaceImport | NamedImports): boolean { if (namedBindings) { if (namedBindings.kind === SyntaxKind.NamespaceImport) { - return resolver.isDeclarationVisible(namedBindings); + return resolver.isDeclarationVisible(namedBindings); } else { - return forEach((namedBindings).elements, namedImport => resolver.isDeclarationVisible(namedImport)); + return namedBindings.elements.some(namedImport => resolver.isDeclarationVisible(namedImport)); } } } @@ -865,11 +865,11 @@ namespace ts { } if (node.importClause.namedBindings.kind === SyntaxKind.NamespaceImport) { write("* as "); - writeTextOfNode(currentText, (node.importClause.namedBindings).name); + writeTextOfNode(currentText, node.importClause.namedBindings.name); } else { write("{ "); - emitCommaList((node.importClause.namedBindings).elements, emitImportOrExportSpecifier, resolver.isDeclarationVisible); + emitCommaList(node.importClause.namedBindings.elements, emitImportOrExportSpecifier, resolver.isDeclarationVisible); write(" }"); } } @@ -886,18 +886,8 @@ namespace ts { // external modules since they are indistinguishable from script files with ambient modules. To fix this in such d.ts files we'll emit top level 'export {}' // so compiler will treat them as external modules. resultHasExternalModuleIndicator = resultHasExternalModuleIndicator || parent.kind !== SyntaxKind.ModuleDeclaration; - let moduleSpecifier: Node; - if (parent.kind === SyntaxKind.ImportEqualsDeclaration) { - const node = parent as ImportEqualsDeclaration; - moduleSpecifier = getExternalModuleImportEqualsDeclarationExpression(node); - } - else if (parent.kind === SyntaxKind.ModuleDeclaration) { - moduleSpecifier = (parent).name; - } - else { - const node = parent as (ImportDeclaration | ExportDeclaration); - moduleSpecifier = node.moduleSpecifier; - } + const moduleSpecifier = parent.kind === SyntaxKind.ImportEqualsDeclaration ? getExternalModuleImportEqualsDeclarationExpression(parent) : + parent.kind === SyntaxKind.ModuleDeclaration ? parent.name : parent.moduleSpecifier; if (moduleSpecifier.kind === SyntaxKind.StringLiteral && isBundledEmit && (compilerOptions.out || compilerOptions.outFile)) { const moduleName = getExternalModuleNameFromDeclaration(host, resolver, parent); @@ -1293,7 +1283,7 @@ namespace ts { // so there is no check needed to see if declaration is visible if (node.kind !== SyntaxKind.VariableDeclaration || isVariableDeclarationVisible(node)) { if (isBindingPattern(node.name)) { - emitBindingPattern(node.name); + emitBindingPattern(node.name); } else { writeNameOfDeclaration(node, getVariableDeclarationTypeVisibilityError); @@ -1301,7 +1291,7 @@ namespace ts { // If optional property emit ? but in the case of parameterProperty declaration with "?" indicating optional parameter for the constructor // we don't want to emit property declaration with "?" if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature || - (node.kind === SyntaxKind.Parameter && !isParameterPropertyDeclaration(node))) && hasQuestionToken(node)) { + (node.kind === SyntaxKind.Parameter && !isParameterPropertyDeclaration(node))) && hasQuestionToken(node)) { write("?"); } if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && node.parent.kind === SyntaxKind.TypeLiteral) { @@ -1389,7 +1379,7 @@ namespace ts { if (bindingElement.name) { if (isBindingPattern(bindingElement.name)) { - emitBindingPattern(bindingElement.name); + emitBindingPattern(bindingElement.name); } else { writeTextOfNode(currentText, bindingElement.name); @@ -1782,7 +1772,7 @@ namespace ts { // For bindingPattern, we can't simply writeTextOfNode from the source file // because we want to omit the initializer and using writeTextOfNode will result in initializer get emitted. // Therefore, we will have to recursively emit each element in the bindingPattern. - emitBindingPattern(node.name); + emitBindingPattern(node.name); } else { writeTextOfNode(currentText, node.name); @@ -1921,7 +1911,7 @@ namespace ts { // emit : declare function foo([a, [[b]], c]: [number, [[string]], number]): void; // original with rest: function foo([a, ...c]) {} // emit : declare function foo([a, ...c]): void; - emitBindingPattern(bindingElement.name); + emitBindingPattern(bindingElement.name); } else { Debug.assert(bindingElement.name.kind === SyntaxKind.Identifier); diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 735e0d67f47..df1394efd00 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -951,7 +951,7 @@ namespace ts { function emitEntityName(node: EntityName) { if (node.kind === SyntaxKind.Identifier) { - emitExpression(node); + emitExpression(node); } else { emit(node); @@ -1709,7 +1709,7 @@ namespace ts { emit(node); } else { - emitExpression(node); + emitExpression(node); } } } @@ -2068,7 +2068,7 @@ namespace ts { function emitModuleReference(node: ModuleReference) { if (node.kind === SyntaxKind.Identifier) { - emitExpression(node); + emitExpression(node); } else { emit(node); @@ -2472,12 +2472,12 @@ namespace ts { function emitPrologueDirectivesIfNeeded(sourceFileOrBundle: Bundle | SourceFile) { if (isSourceFile(sourceFileOrBundle)) { - setSourceFile(sourceFileOrBundle as SourceFile); - emitPrologueDirectives((sourceFileOrBundle as SourceFile).statements); + setSourceFile(sourceFileOrBundle); + emitPrologueDirectives(sourceFileOrBundle.statements); } else { const seenPrologueDirectives = createMap(); - for (const sourceFile of (sourceFileOrBundle as Bundle).sourceFiles) { + for (const sourceFile of sourceFileOrBundle.sourceFiles) { setSourceFile(sourceFile); emitPrologueDirectives(sourceFile.statements, /*startWithNewLine*/ true, seenPrologueDirectives); } diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 8166196e469..647ae6983fa 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -644,7 +644,7 @@ namespace ts { } export function updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) { - return updateSignatureDeclaration(node, typeParameters, parameters, type); + return updateSignatureDeclaration(node, typeParameters, parameters, type); } export function createConstructorTypeNode(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) { @@ -652,7 +652,7 @@ namespace ts { } export function updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) { - return updateSignatureDeclaration(node, typeParameters, parameters, type); + return updateSignatureDeclaration(node, typeParameters, parameters, type); } export function createTypeQueryNode(exprName: EntityName) { @@ -1285,7 +1285,7 @@ namespace ts { export function createYield(asteriskTokenOrExpression?: AsteriskToken | Expression, expression?: Expression) { const node = createSynthesizedNode(SyntaxKind.YieldExpression); node.asteriskToken = asteriskTokenOrExpression && asteriskTokenOrExpression.kind === SyntaxKind.AsteriskToken ? asteriskTokenOrExpression : undefined; - node.expression = asteriskTokenOrExpression && asteriskTokenOrExpression.kind !== SyntaxKind.AsteriskToken ? asteriskTokenOrExpression : expression; + node.expression = asteriskTokenOrExpression && asteriskTokenOrExpression.kind !== SyntaxKind.AsteriskToken ? asteriskTokenOrExpression : expression; return node; } @@ -3415,13 +3415,13 @@ namespace ts { switch (property.kind) { case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: - return createExpressionForAccessorDeclaration(node.properties, property, receiver, node.multiLine); + return createExpressionForAccessorDeclaration(node.properties, property, receiver, node.multiLine); case SyntaxKind.PropertyAssignment: - return createExpressionForPropertyAssignment(property, receiver); + return createExpressionForPropertyAssignment(property, receiver); case SyntaxKind.ShorthandPropertyAssignment: - return createExpressionForShorthandPropertyAssignment(property, receiver); + return createExpressionForShorthandPropertyAssignment(property, receiver); case SyntaxKind.MethodDeclaration: - return createExpressionForMethodDeclaration(property, receiver); + return createExpressionForMethodDeclaration(property, receiver); } } @@ -4065,13 +4065,13 @@ namespace ts { export function parenthesizePostfixOperand(operand: Expression) { return isLeftHandSideExpression(operand) - ? operand + ? operand : setTextRange(createParen(operand), operand); } export function parenthesizePrefixOperand(operand: Expression) { return isUnaryExpression(operand) - ? operand + ? operand : setTextRange(createParen(operand), operand); } @@ -4203,7 +4203,7 @@ namespace ts { export function parenthesizeConciseBody(body: ConciseBody): ConciseBody { if (!isBlock(body) && getLeftmostExpression(body, /*stopAtCallExpressions*/ false).kind === SyntaxKind.ObjectLiteralExpression) { - return setTextRange(createParen(body), body); + return setTextRange(createParen(body), body); } return body; @@ -4370,10 +4370,10 @@ namespace ts { const name = namespaceDeclaration.name; return isGeneratedIdentifier(name) ? name : createIdentifier(getSourceTextOfNodeFromSourceFile(sourceFile, name) || idText(name)); } - if (node.kind === SyntaxKind.ImportDeclaration && (node).importClause) { + if (node.kind === SyntaxKind.ImportDeclaration && node.importClause) { return getGeneratedNameForNode(node); } - if (node.kind === SyntaxKind.ExportDeclaration && (node).moduleSpecifier) { + if (node.kind === SyntaxKind.ExportDeclaration && node.moduleSpecifier) { return getGeneratedNameForNode(node); } return undefined; @@ -4494,7 +4494,7 @@ namespace ts { // `{a}` in `let [{a} = 1] = ...` // `[a]` in `let [[a]] = ...` // `[a]` in `let [[a] = 1] = ...` - return bindingElement.name; + return bindingElement.name; } if (isObjectLiteralElementLike(bindingElement)) { @@ -4556,12 +4556,12 @@ namespace ts { case SyntaxKind.Parameter: case SyntaxKind.BindingElement: // `...` in `let [...a] = ...` - return (bindingElement).dotDotDotToken; + return bindingElement.dotDotDotToken; case SyntaxKind.SpreadElement: case SyntaxKind.SpreadAssignment: // `...` in `[...a] = ...` - return bindingElement; + return bindingElement; } return undefined; @@ -4577,8 +4577,8 @@ namespace ts { // `[a]` in `let { [a]: b } = ...` // `"a"` in `let { "a": b } = ...` // `1` in `let { 1: b } = ...` - if ((bindingElement).propertyName) { - const propertyName = (bindingElement).propertyName; + if (bindingElement.propertyName) { + const propertyName = bindingElement.propertyName; return isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression) ? propertyName.expression : propertyName; @@ -4591,8 +4591,8 @@ namespace ts { // `[a]` in `({ [a]: b } = ...)` // `"a"` in `({ "a": b } = ...)` // `1` in `({ 1: b } = ...)` - if ((bindingElement).name) { - const propertyName = (bindingElement).name; + if (bindingElement.name) { + const propertyName = bindingElement.name; return isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression) ? propertyName.expression : propertyName; @@ -4602,7 +4602,7 @@ namespace ts { case SyntaxKind.SpreadAssignment: // `a` in `({ ...a } = ...)` - return (bindingElement).name; + return bindingElement.name; } const target = getTargetOfBindingOrAssignmentElement(bindingElement); @@ -4639,7 +4639,7 @@ namespace ts { Debug.assertNode(element.name, isIdentifier); return setOriginalNode(setTextRange(createSpread(element.name), element), element); } - const expression = convertToAssignmentElementTarget(element.name); + const expression = convertToAssignmentElementTarget(element.name); return element.initializer ? setOriginalNode( setTextRange( @@ -4661,7 +4661,7 @@ namespace ts { return setOriginalNode(setTextRange(createSpreadAssignment(element.name), element), element); } if (element.propertyName) { - const expression = convertToAssignmentElementTarget(element.name); + const expression = convertToAssignmentElementTarget(element.name); return setOriginalNode(setTextRange(createPropertyAssignment(element.propertyName, element.initializer ? createAssignment(expression, element.initializer) : expression), element), element); } Debug.assertNode(element.name, isIdentifier); @@ -4694,7 +4694,7 @@ namespace ts { ); } Debug.assertNode(node, isObjectLiteralExpression); - return node; + return node; } export function convertToArrayAssignmentPattern(node: ArrayBindingOrAssignmentPattern) { @@ -4708,7 +4708,7 @@ namespace ts { ); } Debug.assertNode(node, isArrayLiteralExpression); - return node; + return node; } export function convertToAssignmentElementTarget(node: BindingOrAssignmentElementTarget): Expression { @@ -4717,6 +4717,6 @@ namespace ts { } Debug.assertNode(node, isExpression); - return node; + return node; } } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index b71983b9783..70ddb7b791d 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -690,7 +690,7 @@ namespace ts { // Prime the scanner. nextToken(); if (token() === SyntaxKind.EndOfFileToken) { - sourceFile.endOfFileToken = parseTokenNode(); + sourceFile.endOfFileToken = parseTokenNode(); } else if (token() === SyntaxKind.OpenBraceToken || lookAhead(() => token() === SyntaxKind.StringLiteral)) { @@ -773,7 +773,7 @@ namespace ts { sourceFile.statements = parseList(ParsingContext.SourceElements, parseStatement); Debug.assert(token() === SyntaxKind.EndOfFileToken); - sourceFile.endOfFileToken = addJSDocComment(parseTokenNode() as EndOfFileToken); + sourceFile.endOfFileToken = addJSDocComment(parseTokenNode()); setExternalModuleIndicator(sourceFile); @@ -1794,7 +1794,7 @@ namespace ts { // into an actual .ConstructorDeclaration. const methodDeclaration = node; const nameIsConstructor = methodDeclaration.name.kind === SyntaxKind.Identifier && - (methodDeclaration.name).originalKeywordKind === SyntaxKind.ConstructorKeyword; + methodDeclaration.name.originalKeywordKind === SyntaxKind.ConstructorKeyword; return !nameIsConstructor; } @@ -3175,7 +3175,7 @@ namespace ts { // Note: we call reScanGreaterToken so that we get an appropriately merged token // for cases like `> > =` becoming `>>=` if (isLeftHandSideExpression(expr) && isAssignmentOperator(reScanGreaterToken())) { - return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher()); + return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher()); } // It wasn't an assignment or a lambda. This is a conditional expression: @@ -3624,7 +3624,7 @@ namespace ts { } } else { - leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence)); + leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence)); } } @@ -4079,7 +4079,7 @@ namespace ts { else { Debug.assert(opening.kind === SyntaxKind.JsxSelfClosingElement); // Nothing else to do for self-closing elements - result = opening; + result = opening; } // If the user writes the invalid code '
' in an expression context (i.e. not wrapped in @@ -4097,7 +4097,7 @@ namespace ts { badNode.end = invalidElement.end; badNode.left = result; badNode.right = invalidElement; - badNode.operatorToken = createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined); + badNode.operatorToken = createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined); badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos; return badNode; } @@ -5253,7 +5253,7 @@ namespace ts { if (node.decorators || node.modifiers) { // We reached this point because we encountered decorators and/or modifiers and assumed a declaration // would follow. For recovery and error reporting purposes, return an incomplete declaration. - const missing = createMissingNode(SyntaxKind.MissingDeclaration, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected); + const missing = createMissingNode(SyntaxKind.MissingDeclaration, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected); missing.pos = node.pos; missing.decorators = node.decorators; missing.modifiers = node.modifiers; diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 1f2a3bfcd5d..2cba011131e 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -812,7 +812,7 @@ namespace ts { if (!result) { // There were no unresolved/ambient resolutions. Debug.assert(resolutions.length === moduleNames.length); - return resolutions; + return resolutions; } let j = 0; diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 0956c1075ef..7e4769a3e50 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -1995,7 +1995,7 @@ namespace ts { // If we are here it is because this is a destructuring assignment. if (isDestructuringAssignment(node)) { return flattenDestructuringAssignment( - node, + node, visitor, context, FlattenLevel.All, @@ -2023,7 +2023,7 @@ namespace ts { ); } else { - assignment = createBinary(decl.name, SyntaxKind.EqualsToken, visitNode(decl.initializer, visitor, isExpression)); + assignment = createBinary(decl.name, SyntaxKind.EqualsToken, visitNode(decl.initializer, visitor, isExpression)); setTextRange(assignment, decl); } @@ -2632,10 +2632,10 @@ namespace ts { function visit(node: Identifier | BindingPattern) { if (node.kind === SyntaxKind.Identifier) { - state.hoistedLocalVariables.push((node)); + state.hoistedLocalVariables.push(node); } else { - for (const element of (node).elements) { + for (const element of node.elements) { if (!isOmittedExpression(element)) { visit(element.name); } @@ -2716,7 +2716,7 @@ namespace ts { convertedLoopState = outerConvertedLoopState; if (loopOutParameters.length || lexicalEnvironment) { - const statements = isBlock(loopBody) ? (loopBody).statements.slice() : [loopBody]; + const statements = isBlock(loopBody) ? loopBody.statements.slice() : [loopBody]; if (loopOutParameters.length) { copyOutParameters(loopOutParameters, CopyDirection.ToOutParameter, statements); } @@ -2856,7 +2856,7 @@ namespace ts { loop = convert(node, outermostLabeledStatement, convertedLoopBodyStatements); } else { - let clone = getMutableClone(node); + let clone = getMutableClone(node); // clean statement part clone.statement = undefined; // visit childnodes to transform initializer/condition/incrementor parts @@ -3039,7 +3039,7 @@ namespace ts { switch (property.kind) { case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: - const accessors = getAllAccessorDeclarations(node.properties, property); + const accessors = getAllAccessorDeclarations(node.properties, property); if (property === accessors.firstAccessor) { expressions.push(transformAccessorsToExpression(receiver, accessors, node, node.multiLine)); } @@ -3047,15 +3047,15 @@ namespace ts { break; case SyntaxKind.MethodDeclaration: - expressions.push(transformObjectLiteralMethodDeclarationToExpression(property, receiver, node, node.multiLine)); + expressions.push(transformObjectLiteralMethodDeclarationToExpression(property, receiver, node, node.multiLine)); break; case SyntaxKind.PropertyAssignment: - expressions.push(transformPropertyAssignmentToExpression(property, receiver, node.multiLine)); + expressions.push(transformPropertyAssignmentToExpression(property, receiver, node.multiLine)); break; case SyntaxKind.ShorthandPropertyAssignment: - expressions.push(transformShorthandPropertyAssignmentToExpression(property, receiver, node.multiLine)); + expressions.push(transformShorthandPropertyAssignmentToExpression(property, receiver, node.multiLine)); break; default: diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 905686c8861..0c6b25cf0b5 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -183,7 +183,7 @@ namespace ts { : visitNode(node.initializer, visitor, isForInitializer), visitNode(node.condition, visitor, isExpression), visitNode(node.incrementor, visitor, isExpression), - visitNode((node).statement, asyncBodyVisitor, isStatement, liftToBlock) + visitNode(node.statement, asyncBodyVisitor, isStatement, liftToBlock) ); } diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index 82ff52ead90..74afe44a097 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -167,7 +167,7 @@ namespace ts { objects.push(createObjectLiteral(chunkObject)); chunkObject = undefined; } - const target = (e as SpreadAssignment).expression; + const target = e.expression; objects.push(visitNode(target, visitor, isExpression)); } else { @@ -175,8 +175,7 @@ namespace ts { chunkObject = []; } if (e.kind === SyntaxKind.PropertyAssignment) { - const p = e as PropertyAssignment; - chunkObject.push(createPropertyAssignment(p.name, visitNode(p.initializer, visitor, isExpression))); + chunkObject.push(createPropertyAssignment(e.name, visitNode(e.initializer, visitor, isExpression))); } else { chunkObject.push(visitNode(e, visitor, isObjectLiteralElementLike)); diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 8df05e4f3ab..1a4c82020c7 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -1771,16 +1771,15 @@ namespace ts { for (let i = clausesWritten; i < numClauses; i++) { const clause = caseBlock.clauses[i]; if (clause.kind === SyntaxKind.CaseClause) { - const caseClause = clause; - if (containsYield(caseClause.expression) && pendingClauses.length > 0) { + if (containsYield(clause.expression) && pendingClauses.length > 0) { break; } pendingClauses.push( createCaseClause( - visitNode(caseClause.expression, visitor, isExpression), + visitNode(clause.expression, visitor, isExpression), [ - createInlineBreak(clauseLabels[i], /*location*/ caseClause.expression) + createInlineBreak(clauseLabels[i], /*location*/ clause.expression) ] ) ); diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index 35eaae2a5cf..94e41af9c28 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -57,19 +57,19 @@ namespace ts { function transformJsxChildToExpression(node: JsxChild): Expression { switch (node.kind) { case SyntaxKind.JsxText: - return visitJsxText(node); + return visitJsxText(node); case SyntaxKind.JsxExpression: - return visitJsxExpression(node); + return visitJsxExpression(node); case SyntaxKind.JsxElement: - return visitJsxElement(node, /*isChild*/ true); + return visitJsxElement(node, /*isChild*/ true); case SyntaxKind.JsxSelfClosingElement: - return visitJsxSelfClosingElement(node, /*isChild*/ true); + return visitJsxSelfClosingElement(node, /*isChild*/ true); case SyntaxKind.JsxFragment: - return visitJsxFragment(node, /*isChild*/ true); + return visitJsxFragment(node, /*isChild*/ true); default: Debug.failBadSyntaxKind(node); @@ -171,15 +171,15 @@ namespace ts { else if (node.kind === SyntaxKind.StringLiteral) { // Always recreate the literal to escape any escape sequences or newlines which may be in the original jsx string and which // Need to be escaped to be handled correctly in a normal string - const literal = createLiteral(tryDecodeEntities((node).text) || (node).text); - literal.singleQuote = (node as StringLiteral).singleQuote !== undefined ? (node as StringLiteral).singleQuote : !isStringDoubleQuoted(node as StringLiteral, currentSourceFile); + const literal = createLiteral(tryDecodeEntities(node.text) || node.text); + literal.singleQuote = node.singleQuote !== undefined ? node.singleQuote : !isStringDoubleQuoted(node, currentSourceFile); return setTextRange(literal, node); } else if (node.kind === SyntaxKind.JsxExpression) { if (node.expression === undefined) { return createTrue(); } - return visitJsxExpression(node); + return visitJsxExpression(node); } else { Debug.failBadSyntaxKind(node); @@ -279,10 +279,10 @@ namespace ts { function getTagName(node: JsxElement | JsxOpeningLikeElement): Expression { if (node.kind === SyntaxKind.JsxElement) { - return getTagName((node).openingElement); + return getTagName(node.openingElement); } else { - const name = (node).tagName; + const name = node.tagName; if (isIdentifier(name) && isIntrinsicJsxName(name.escapedText)) { return createLiteral(idText(name)); } diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 2c75964d616..b55dc583aa9 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -533,7 +533,7 @@ namespace ts { } if (isImportCall(node)) { - return visitImportCallExpression(node); + return visitImportCallExpression(node); } else { return visitEachChild(node, importCallExpressionVisitor, context); diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 2e6f6d84b51..d4bae723052 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -343,13 +343,12 @@ namespace ts { continue; } - const exportDecl = externalImport; - if (!exportDecl.exportClause) { + if (!externalImport.exportClause) { // export * from ... continue; } - for (const element of exportDecl.exportClause.elements) { + for (const element of externalImport.exportClause.elements) { // write name of indirectly exported entry, i.e. 'export {x} from ...' exportedNames.push( createPropertyAssignment( @@ -472,7 +471,7 @@ namespace ts { const importVariableName = getLocalNameForExternalImport(entry, currentSourceFile); switch (entry.kind) { case SyntaxKind.ImportDeclaration: - if (!(entry).importClause) { + if (!entry.importClause) { // 'import "..."' case // module is imported only for side-effects, no emit required break; @@ -491,7 +490,7 @@ namespace ts { case SyntaxKind.ExportDeclaration: Debug.assert(importVariableName !== undefined); - if ((entry).exportClause) { + if (entry.exportClause) { // export {a, b as c} from 'foo' // // emit as: @@ -501,7 +500,7 @@ namespace ts { // "c": _["b"] // }); const properties: PropertyAssignment[] = []; - for (const e of (entry).exportClause.elements) { + for (const e of entry.exportClause.elements) { properties.push( createPropertyAssignment( createLiteral(idText(e.name)), diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 0e70b3099c0..059ae73ea2b 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -242,13 +242,13 @@ namespace ts { } switch (node.kind) { case SyntaxKind.ImportDeclaration: - return visitImportDeclaration(node); + return visitImportDeclaration(node); case SyntaxKind.ImportEqualsDeclaration: - return visitImportEqualsDeclaration(node); + return visitImportEqualsDeclaration(node); case SyntaxKind.ExportAssignment: - return visitExportAssignment(node); + return visitExportAssignment(node); case SyntaxKind.ExportDeclaration: - return visitExportDeclaration(node); + return visitExportDeclaration(node); default: Debug.fail("Unhandled ellided statement"); } @@ -2010,7 +2010,7 @@ namespace ts { case SyntaxKind.Identifier: // Create a clone of the name with a new parent, and treat it as if it were // a source tree node for the purposes of the checker. - const name = getMutableClone(node); + const name = getMutableClone(node); name.flags &= ~NodeFlags.Synthesized; name.original = undefined; name.parent = getParseTreeNode(currentScope); // ensure the parent is set to a parse tree node. @@ -2027,7 +2027,7 @@ namespace ts { return name; case SyntaxKind.QualifiedName: - return serializeQualifiedNameAsExpression(node, useFallback); + return serializeQualifiedNameAsExpression(node, useFallback); } } @@ -2091,9 +2091,9 @@ namespace ts { function getExpressionForPropertyName(member: ClassElement | EnumMember, generateNameForComputedPropertyName: boolean): Expression { const name = member.name; if (isComputedPropertyName(name)) { - return generateNameForComputedPropertyName && !isSimpleInlineableExpression((name).expression) + return generateNameForComputedPropertyName && !isSimpleInlineableExpression(name.expression) ? getGeneratedNameForNode(name) - : (name).expression; + : name.expression; } else if (isIdentifier(name)) { return createLiteral(idText(name)); @@ -2961,7 +2961,7 @@ namespace ts { const body = node.body; if (body.kind === SyntaxKind.ModuleBlock) { saveStateAndInvoke(body, body => addRange(statements, visitNodes((body).statements, namespaceElementVisitor, isStatement))); - statementsLocation = (body).statements; + statementsLocation = body.statements; blockLocation = body; } else { @@ -3547,9 +3547,7 @@ namespace ts { return undefined; } - return isPropertyAccessExpression(node) || isElementAccessExpression(node) - ? resolver.getConstantValue(node) - : undefined; + return isPropertyAccessExpression(node) || isElementAccessExpression(node) ? resolver.getConstantValue(node) : undefined; } } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 4e5b5700d29..63214d68e5d 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -904,11 +904,10 @@ namespace ts { return; default: if (isFunctionLike(node)) { - const name = (node).name; - if (name && name.kind === SyntaxKind.ComputedPropertyName) { + if (node.name && node.name.kind === SyntaxKind.ComputedPropertyName) { // Note that we will not include methods/accessors of a class because they would require // first descending into the class. This is by design. - traverse((name).expression); + traverse(node.name.expression); return; } } @@ -1219,15 +1218,15 @@ namespace ts { } export function getInvokedExpression(node: CallLikeExpression): Expression { - if (node.kind === SyntaxKind.TaggedTemplateExpression) { - return (node).tag; + switch (node.kind) { + case SyntaxKind.TaggedTemplateExpression: + return node.tag; + case SyntaxKind.JsxOpeningElement: + case SyntaxKind.JsxSelfClosingElement: + return node.tagName; + default: + return node.expression; } - else if (isJsxOpeningLikeElement(node)) { - return node.tagName; - } - - // Will either be a CallExpression, NewExpression, or Decorator. - return (node).expression; } export function nodeCanBeDecorated(node: ClassDeclaration): true; @@ -1559,7 +1558,7 @@ namespace ts { if (node.kind === SyntaxKind.ImportEqualsDeclaration) { const reference = (node).moduleReference; if (reference.kind === SyntaxKind.ExternalModuleReference) { - return (reference).expression; + return reference.expression; } } if (node.kind === SyntaxKind.ExportDeclaration) { @@ -1571,20 +1570,20 @@ namespace ts { } export function getNamespaceDeclarationNode(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration): ImportEqualsDeclaration | NamespaceImport { - if (node.kind === SyntaxKind.ImportEqualsDeclaration) { - return node; - } - - const importClause = (node).importClause; - if (importClause && importClause.namedBindings && importClause.namedBindings.kind === SyntaxKind.NamespaceImport) { - return importClause.namedBindings; + switch (node.kind) { + case SyntaxKind.ImportDeclaration: + return node.importClause && tryCast(node.importClause.namedBindings, isNamespaceImport); + case SyntaxKind.ImportEqualsDeclaration: + return node; + case SyntaxKind.ExportDeclaration: + return undefined; + default: + return Debug.assertNever(node); } } export function isDefaultImport(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration) { - return node.kind === SyntaxKind.ImportDeclaration - && (node).importClause - && !!(node).importClause.name; + return node.kind === SyntaxKind.ImportDeclaration && node.importClause && !!node.importClause.name; } export function hasQuestionToken(node: Node) { @@ -2127,8 +2126,8 @@ namespace ts { export function isDynamicName(name: DeclarationName): boolean { return name.kind === SyntaxKind.ComputedPropertyName && - !isStringOrNumericLiteral((name).expression) && - !isWellKnownSymbolSyntactically((name).expression); + !isStringOrNumericLiteral(name.expression) && + !isWellKnownSymbolSyntactically(name.expression); } /** @@ -2168,7 +2167,7 @@ namespace ts { if (node.kind === SyntaxKind.StringLiteral || node.kind === SyntaxKind.NumericLiteral) { - return (node as LiteralLikeNode).text; + return node.text; } } @@ -2183,7 +2182,7 @@ namespace ts { if (node.kind === SyntaxKind.StringLiteral || node.kind === SyntaxKind.NumericLiteral) { - return escapeLeadingUnderscores((node as LiteralLikeNode).text); + return escapeLeadingUnderscores(node.text); } } @@ -4258,13 +4257,12 @@ namespace ts { // Covers remaining cases switch (hostNode.kind) { case SyntaxKind.VariableStatement: - if ((hostNode as VariableStatement).declarationList && - (hostNode as VariableStatement).declarationList.declarations[0]) { - return getDeclarationIdentifier((hostNode as VariableStatement).declarationList.declarations[0]); + if (hostNode.declarationList && hostNode.declarationList.declarations[0]) { + return getDeclarationIdentifier(hostNode.declarationList.declarations[0]); } return undefined; case SyntaxKind.ExpressionStatement: - const expr = (hostNode as ExpressionStatement).expression; + const expr = hostNode.expression; switch (expr.kind) { case SyntaxKind.PropertyAccessExpression: return (expr as PropertyAccessExpression).name; @@ -4297,7 +4295,7 @@ namespace ts { } export function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | undefined { - return declaration.name || nameForNamelessJSDocTypedef(declaration as JSDocTypedefTag); + return declaration.name || nameForNamelessJSDocTypedef(declaration); } export function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined { @@ -4353,7 +4351,7 @@ namespace ts { export function getJSDocParameterTags(param: ParameterDeclaration): ReadonlyArray | undefined { if (param.name && isIdentifier(param.name)) { const name = param.name.escapedText; - return getJSDocTags(param.parent).filter((tag): tag is JSDocParameterTag => isJSDocParameterTag(tag) && isIdentifier(tag.name) && tag.name.escapedText === name) as JSDocParameterTag[]; + return getJSDocTags(param.parent).filter((tag): tag is JSDocParameterTag => isJSDocParameterTag(tag) && isIdentifier(tag.name) && tag.name.escapedText === name); } // a binding pattern doesn't have a name, so it's not possible to match it a JSDoc parameter, which is identified by name return undefined; diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index ab07182b8e7..fa9bf124e51 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1621,7 +1621,7 @@ Actual: ${stringify(fullActual)}`); const diagnostics = ts.getPreEmitDiagnostics(this.languageService.getProgram()); for (const diagnostic of diagnostics) { if (!ts.isString(diagnostic.messageText)) { - let chainedMessage = diagnostic.messageText; + let chainedMessage = diagnostic.messageText; let indentation = " "; while (chainedMessage) { resultString += indentation + chainedMessage.messageText + Harness.IO.newLine(); @@ -3170,24 +3170,23 @@ Actual: ${stringify(fullActual)}`); } private findFile(indexOrName: string | number) { - let result: FourSlashFile; if (typeof indexOrName === "number") { - const index = indexOrName; + const index = indexOrName; if (index >= this.testData.files.length) { throw new Error(`File index (${index}) in openFile was out of range. There are only ${this.testData.files.length} files in this test.`); } else { - result = this.testData.files[index]; + return this.testData.files[index]; } } else if (ts.isString(indexOrName)) { - let name = indexOrName; + let name = indexOrName; // names are stored in the compiler with this relative path, this allows people to use goTo.file on just the fileName name = name.indexOf("/") === -1 ? (this.basePath + "/" + name) : name; const availableNames: string[] = []; - result = ts.forEach(this.testData.files, file => { + const result = ts.forEach(this.testData.files, file => { const fn = file.fileName; if (fn) { if (fn === name) { @@ -3200,12 +3199,11 @@ Actual: ${stringify(fullActual)}`); if (!result) { throw new Error(`No test file named "${name}" exists. Available file names are: ${availableNames.join(", ")}`); } + return result; } else { - throw new Error("Unknown argument type"); + return ts.Debug.assertNever(indexOrName); } - - return result; } private getLineColStringAtPosition(position: number) { diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 53f8133b8e5..e35ecba2a04 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -57,7 +57,7 @@ var assert: typeof _chai.assert = _chai.assert; } declare var __dirname: string; // Node-specific -var global: NodeJS.Global = Function("return this").call(undefined); +var global: NodeJS.Global = Function("return this").call(undefined); declare var window: {}; declare var XMLHttpRequest: { @@ -767,10 +767,9 @@ namespace Harness { return ts.matchFiles(path, extension, exclude, include, useCaseSensitiveFileNames(), getCurrentDirectory(), depth, path => { const entry = fs.traversePath(path); if (entry && entry.isDirectory()) { - const directory = entry; return { - files: ts.map(directory.getFiles(), f => f.name), - directories: ts.map(directory.getDirectories(), d => d.name) + files: ts.map(entry.getFiles(), f => f.name), + directories: ts.map(entry.getDirectories(), d => d.name) }; } return { files: [], directories: [] }; diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index d24f572d1d5..c38ab1f3c6d 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -143,7 +143,7 @@ namespace Harness.LanguageService { public getScriptInfo(fileName: string): ScriptInfo { const fileEntry = this.virtualFileSystem.traversePath(fileName); - return fileEntry && fileEntry.isFile() ? (fileEntry).content : undefined; + return fileEntry && fileEntry.isFile() ? fileEntry.content : undefined; } public addScript(fileName: string, content: string, isRootFile: boolean): void { diff --git a/src/harness/unittests/reuseProgramStructure.ts b/src/harness/unittests/reuseProgramStructure.ts index 454e97b3133..70325831f51 100644 --- a/src/harness/unittests/reuseProgramStructure.ts +++ b/src/harness/unittests/reuseProgramStructure.ts @@ -165,7 +165,7 @@ namespace ts { export function updateProgram(oldProgram: ProgramWithSourceTexts, rootNames: ReadonlyArray, options: CompilerOptions, updater: (files: NamedSourceText[]) => void, newTexts?: NamedSourceText[]) { if (!newTexts) { - newTexts = (oldProgram).sourceTexts.slice(0); + newTexts = oldProgram.sourceTexts.slice(0); } updater(newTexts); const host = createTestCompilerHost(newTexts, options.target, oldProgram); diff --git a/src/harness/unittests/textChanges.ts b/src/harness/unittests/textChanges.ts index 0a3602ea0b1..e3f67b8c513 100644 --- a/src/harness/unittests/textChanges.ts +++ b/src/harness/unittests/textChanges.ts @@ -91,7 +91,7 @@ namespace M } }`; runSingleFileTest("extractMethodLike", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - const statements = ((findChild("foo", sourceFile)).body).statements.slice(1); + const statements = (findChild("foo", sourceFile)).body.statements.slice(1); const newFunction = createFunctionDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 8d84732f3aa..e09dff2a6d5 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -2560,7 +2560,7 @@ namespace ts.projectSystem { } assert.equal(e.eventName, server.ProjectLanguageServiceStateEvent); assert.equal(e.data.project.getProjectName(), config.path, "project name"); - lastEvent = e; + lastEvent = e; } }); session.executeCommand({ diff --git a/src/harness/virtualFileSystem.ts b/src/harness/virtualFileSystem.ts index 54572814d8e..16267a092fc 100644 --- a/src/harness/virtualFileSystem.ts +++ b/src/harness/virtualFileSystem.ts @@ -42,12 +42,12 @@ namespace Utils { getDirectory(name: string): VirtualDirectory { const entry = this.getFileSystemEntry(name); - return entry.isDirectory() ? entry : undefined; + return entry.isDirectory() ? entry : undefined; } getFile(name: string): VirtualFile { const entry = this.getFileSystemEntry(name); - return entry.isFile() ? entry : undefined; + return entry.isFile() ? entry : undefined; } } @@ -66,7 +66,7 @@ namespace Utils { return directory; } else if (entry.isDirectory()) { - return entry; + return entry; } else { return undefined; @@ -149,7 +149,7 @@ namespace Utils { return undefined; } else if (entry.isDirectory()) { - directory = entry; + directory = entry; } else { return entry; @@ -167,10 +167,9 @@ namespace Utils { getAccessibleFileSystemEntries(path: string) { const entry = this.traversePath(path); if (entry && entry.isDirectory()) { - const directory = entry; return { - files: ts.map(directory.getFiles(), f => f.name), - directories: ts.map(directory.getDirectories(), d => d.name) + files: ts.map(entry.getFiles(), f => f.name), + directories: ts.map(entry.getDirectories(), d => d.name) }; } return { files: [], directories: [] }; diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 3d0d623c6d4..c525d5a3bc8 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -2026,7 +2026,7 @@ namespace ts.server { } else { configFileErrors = project.getAllProjectErrors(); - this.sendConfigFileDiagEvent(project as ConfiguredProject, fileName); + this.sendConfigFileDiagEvent(project, fileName); } } else { diff --git a/src/server/scriptVersionCache.ts b/src/server/scriptVersionCache.ts index fa4445bfc4f..8a3f43a5434 100644 --- a/src/server/scriptVersionCache.ts +++ b/src/server/scriptVersionCache.ts @@ -765,13 +765,13 @@ namespace ts.server { for (let i = 0; i < splitNodeCount; i++) { splitNodes[i] = new LineNode(); } - let splitNode = splitNodes[0]; + let splitNode = splitNodes[0]; while (nodeIndex < nodeCount) { splitNode.add(nodes[nodeIndex]); nodeIndex++; if (splitNode.children.length === lineCollectionCapacity) { splitNodeIndex++; - splitNode = splitNodes[splitNodeIndex]; + splitNode = splitNodes[splitNodeIndex]; } } for (let i = splitNodes.length - 1; i >= 0; i--) { @@ -785,7 +785,7 @@ namespace ts.server { } this.updateCounts(); for (let i = 0; i < splitNodeCount; i++) { - (splitNodes[i]).updateCounts(); + splitNodes[i].updateCounts(); } return splitNodes; } diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index 26df417f879..efc27314a98 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -390,7 +390,7 @@ namespace ts.BreakpointResolver { // If this is a destructuring pattern, set breakpoint in binding pattern if (isBindingPattern(variableDeclaration.name)) { - return spanInBindingPattern(variableDeclaration.name); + return spanInBindingPattern(variableDeclaration.name); } // Breakpoint is possible in variableDeclaration only if there is initialization @@ -420,7 +420,7 @@ namespace ts.BreakpointResolver { function spanInParameterDeclaration(parameter: ParameterDeclaration): TextSpan { if (isBindingPattern(parameter.name)) { // Set breakpoint in binding pattern - return spanInBindingPattern(parameter.name); + return spanInBindingPattern(parameter.name); } else if (canHaveSpanInParameterDeclaration(parameter)) { return textSpan(parameter); @@ -540,10 +540,7 @@ namespace ts.BreakpointResolver { function spanInArrayLiteralOrObjectLiteralDestructuringPattern(node: DestructuringPattern): TextSpan { Debug.assert(node.kind !== SyntaxKind.ArrayBindingPattern && node.kind !== SyntaxKind.ObjectBindingPattern); - const elements: NodeArray = - node.kind === SyntaxKind.ArrayLiteralExpression ? - (node).elements : - (node).properties; + const elements: NodeArray = node.kind === SyntaxKind.ArrayLiteralExpression ? node.elements : (node as ObjectLiteralExpression).properties; const firstBindingElement = forEach(elements, element => element.kind !== SyntaxKind.OmittedExpression ? element : undefined); diff --git a/src/services/codefixes/fixUnusedIdentifier.ts b/src/services/codefixes/fixUnusedIdentifier.ts index cb94c2112af..de053c2fe8f 100644 --- a/src/services/codefixes/fixUnusedIdentifier.ts +++ b/src/services/codefixes/fixUnusedIdentifier.ts @@ -195,7 +195,7 @@ namespace ts.codefix { } function tryDeleteNamedImportBinding(changes: textChanges.ChangeTracker, sourceFile: SourceFile, namedBindings: NamedImportBindings): void { - if ((namedBindings.parent).name) { + if (namedBindings.parent.name) { // Delete named imports while preserving the default import // import d|, * as ns| from './file' // import d|, { a }| from './file' @@ -229,7 +229,7 @@ namespace ts.codefix { } case SyntaxKind.ForOfStatement: - const forOfStatement = varDecl.parent.parent; + const forOfStatement = varDecl.parent.parent; Debug.assert(forOfStatement.initializer.kind === SyntaxKind.VariableDeclarationList); const forOfInitializer = forOfStatement.initializer; changes.replaceNode(sourceFile, forOfInitializer.declarations[0], createObjectLiteral()); @@ -240,7 +240,7 @@ namespace ts.codefix { break; default: - const variableStatement = varDecl.parent.parent; + const variableStatement = varDecl.parent.parent; if (variableStatement.declarationList.declarations.length === 1) { changes.deleteNode(sourceFile, variableStatement); } diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 47e23e717d9..6a45c66ca81 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -24,7 +24,7 @@ namespace ts.codefix { return undefined; } - const declaration = declarations[0] as Declaration; + const declaration = declarations[0]; // Clone name to remove leading trivia. const name = getSynthesizedDeepClone(getNameOfDeclaration(declaration)) as PropertyName; const visibilityModifier = createVisibilityModifier(getModifierFlags(declaration)); diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 902764a1729..e17c5183611 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -140,7 +140,7 @@ namespace ts.codefix { case SyntaxKind.Constructor: return true; case SyntaxKind.FunctionExpression: - return !!(declaration as FunctionExpression).name; + return !!declaration.name; } return false; } @@ -497,7 +497,7 @@ namespace ts.codefix { } function inferTypeFromSwitchStatementLabelContext(parent: CaseOrDefaultClause, checker: TypeChecker, usageContext: UsageContext): void { - addCandidateType(usageContext, checker.getTypeAtLocation((parent.parent.parent).expression)); + addCandidateType(usageContext, checker.getTypeAtLocation(parent.parent.parent.expression)); } function inferTypeFromCallExpressionContext(parent: CallExpression | NewExpression, checker: TypeChecker, usageContext: UsageContext): void { diff --git a/src/services/completions.ts b/src/services/completions.ts index 41f9a300b2e..a77185ab94e 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1082,10 +1082,10 @@ namespace ts.Completions { let attrsType: Type; if ((jsxContainer.kind === SyntaxKind.JsxSelfClosingElement) || (jsxContainer.kind === SyntaxKind.JsxOpeningElement)) { // Cursor is inside a JSX self-closing element or opening element - attrsType = typeChecker.getAllAttributesTypeFromJsxOpeningLikeElement(jsxContainer); + attrsType = typeChecker.getAllAttributesTypeFromJsxOpeningLikeElement(jsxContainer); if (attrsType) { - symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), (jsxContainer).attributes.properties); + symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), jsxContainer.attributes.properties); completionKind = CompletionKind.MemberLike; isNewIdentifierLocation = false; return true; @@ -1443,10 +1443,10 @@ namespace ts.Completions { // We are completing on contextual types, but may also include properties // other than those within the declared type. isNewIdentifierLocation = true; - const typeForObject = typeChecker.getContextualType(objectLikeContainer); + const typeForObject = typeChecker.getContextualType(objectLikeContainer); if (!typeForObject) return false; typeMembers = getPropertiesForCompletion(typeForObject, typeChecker, /*isForAccess*/ false); - existingMembers = (objectLikeContainer).properties; + existingMembers = objectLikeContainer.properties; } else { Debug.assert(objectLikeContainer.kind === SyntaxKind.ObjectBindingPattern); @@ -1475,7 +1475,7 @@ namespace ts.Completions { if (!typeForObject) return false; // In a binding pattern, get only known properties. Everywhere else we will get all possible properties. typeMembers = typeChecker.getPropertiesOfType(typeForObject).filter((symbol) => !(getDeclarationModifierFlagsFromSymbol(symbol) & ModifierFlags.NonPublicAccessibilityModifier)); - existingMembers = (objectLikeContainer).elements; + existingMembers = objectLikeContainer.elements; } } @@ -2087,7 +2087,7 @@ namespace ts.Completions { } if (attr.kind === SyntaxKind.JsxAttribute) { - seenNames.set((attr).name.escapedText, true); + seenNames.set(attr.name.escapedText, true); } } diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 5684b3f3e37..8100a021fb8 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -912,7 +912,7 @@ namespace ts.FindAllReferences.Core { // For `export { foo as bar }`, rename `foo`, but not `bar`. if (!(referenceLocation === propertyName && state.options.isForRename)) { - const exportKind = (referenceLocation as Identifier).originalKeywordKind === ts.SyntaxKind.DefaultKeyword ? ExportKind.Default : ExportKind.Named; + const exportKind = referenceLocation.originalKeywordKind === ts.SyntaxKind.DefaultKeyword ? ExportKind.Default : ExportKind.Named; const exportInfo = getExportInfo(referenceSymbol, exportKind, state.checker); Debug.assert(!!exportInfo); searchForImportsOfExport(referenceLocation, referenceSymbol, exportInfo, state); @@ -1125,7 +1125,7 @@ namespace ts.FindAllReferences.Core { } }); } - else if (isImplementationExpression(body)) { + else if (isImplementationExpression(body)) { addReference(body); } } @@ -1647,10 +1647,10 @@ namespace ts.FindAllReferences.Core { function getNameFromObjectLiteralElement(node: ObjectLiteralElement): string { if (node.name.kind === SyntaxKind.ComputedPropertyName) { - const nameExpression = (node.name).expression; + const nameExpression = node.name.expression; // treat computed property names where expression is string/numeric literal as just string/numeric literal if (isStringOrNumericLiteral(nameExpression)) { - return (nameExpression).text; + return nameExpression.text; } return undefined; } @@ -1728,7 +1728,7 @@ namespace ts.FindAllReferences.Core { function getParentStatementOfVariableDeclaration(node: VariableDeclaration): VariableStatement { if (node.parent && node.parent.parent && node.parent.parent.kind === SyntaxKind.VariableStatement) { Debug.assert(node.parent.kind === SyntaxKind.VariableDeclarationList); - return node.parent.parent; + return node.parent.parent; } } diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 22446a98ce2..3ed602d17fb 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -200,7 +200,7 @@ namespace ts.formatting { return rangeContainsRange((parent).members, node); case SyntaxKind.ModuleDeclaration: const body = (parent).body; - return body && body.kind === SyntaxKind.ModuleBlock && rangeContainsRange((body).statements, node); + return body && body.kind === SyntaxKind.ModuleBlock && rangeContainsRange(body.statements, node); case SyntaxKind.SourceFile: case SyntaxKind.Block: case SyntaxKind.ModuleBlock: diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 1e6323be9fa..f124c444f6d 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -383,9 +383,8 @@ namespace ts.formatting { return Value.Unknown; } - if (node.parent && isCallOrNewExpression(node.parent) && (node.parent).expression !== node) { - - const fullCallOrNewExpression = (node.parent).expression; + if (node.parent && isCallOrNewExpression(node.parent) && node.parent.expression !== node) { + const fullCallOrNewExpression = node.parent.expression; const startingExpression = getStartingExpression(fullCallOrNewExpression); if (fullCallOrNewExpression === startingExpression) { diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index d3e57b124de..a9e2f202726 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -629,7 +629,7 @@ namespace ts.FindAllReferences { // For `export { foo } from './bar", there's nothing to skip, because it does not create a new alias. But `export { foo } does. if (symbol.declarations) { for (const declaration of symbol.declarations) { - if (isExportSpecifier(declaration) && !(declaration as ExportSpecifier).propertyName && !(declaration as ExportSpecifier).parent.parent.moduleSpecifier) { + if (isExportSpecifier(declaration) && !declaration.propertyName && !declaration.parent.parent.moduleSpecifier) { return checker.getExportSpecifierLocalTargetSymbol(declaration); } } diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 2a5b4f26ce6..cf3c9606fb4 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -269,9 +269,7 @@ namespace ts.JsDoc { 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; + const paramName = currentName.kind === SyntaxKind.Identifier ? currentName.escapedText : "param" + i; if (isJavaScriptFile) { docParams += `${indentationStr} * @param {any} ${paramName}${newLine}`; } diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index 8449805ee71..3b5e5ee59ba 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -97,7 +97,7 @@ namespace ts.NavigateTo { containers.unshift(text); } else if (name.kind === SyntaxKind.ComputedPropertyName) { - return tryAddComputedPropertyName((name).expression, containers, /*includeLastPortion*/ true); + return tryAddComputedPropertyName(name.expression, containers, /*includeLastPortion*/ true); } else { // Don't know how to add this. @@ -140,7 +140,7 @@ namespace ts.NavigateTo { // portion into the container array. const name = getNameOfDeclaration(declaration); if (name.kind === SyntaxKind.ComputedPropertyName) { - if (!tryAddComputedPropertyName((name).expression, containers, /*includeLastPortion*/ false)) { + if (!tryAddComputedPropertyName(name.expression, containers, /*includeLastPortion*/ false)) { return undefined; } } @@ -181,7 +181,7 @@ namespace ts.NavigateTo { function createNavigateToItem(rawItem: RawNavigateToItem): NavigateToItem { const declaration = rawItem.declaration; - const container = getContainerNode(declaration); + const container = getContainerNode(declaration); const containerName = container && getNameOfDeclaration(container); return { name: rawItem.name, diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 19a74c5af57..cdc7b2b1864 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -197,10 +197,10 @@ namespace ts.NavigationBar { const {namedBindings} = importClause; if (namedBindings) { if (namedBindings.kind === SyntaxKind.NamespaceImport) { - addLeafNode(namedBindings); + addLeafNode(namedBindings); } else { - for (const element of (namedBindings).elements) { + for (const element of namedBindings.elements) { addLeafNode(element); } } @@ -475,8 +475,8 @@ namespace ts.NavigationBar { else { const parentNode = node.parent && node.parent.parent; if (parentNode && parentNode.kind === SyntaxKind.VariableStatement) { - if ((parentNode).declarationList.declarations.length > 0) { - const nameIdentifier = (parentNode).declarationList.declarations[0].name; + if (parentNode.declarationList.declarations.length > 0) { + const nameIdentifier = parentNode.declarationList.declarations[0].name; if (nameIdentifier.kind === SyntaxKind.Identifier) { return nameIdentifier.text; } diff --git a/src/services/refactors/annotateWithTypeFromJSDoc.ts b/src/services/refactors/annotateWithTypeFromJSDoc.ts index 6f87332aa96..3258da4636a 100644 --- a/src/services/refactors/annotateWithTypeFromJSDoc.ts +++ b/src/services/refactors/annotateWithTypeFromJSDoc.ts @@ -118,7 +118,7 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { case SyntaxKind.Constructor: return createConstructor(decl.decorators, decl.modifiers, parameters, decl.body); case SyntaxKind.FunctionExpression: - return createFunctionExpression(decl.modifiers, decl.asteriskToken, (decl as FunctionExpression).name, typeParameters, parameters, returnType, decl.body); + return createFunctionExpression(decl.modifiers, decl.asteriskToken, decl.name, typeParameters, parameters, returnType, decl.body); case SyntaxKind.ArrowFunction: return createArrowFunction(decl.modifiers, typeParameters, parameters, returnType, decl.equalsGreaterThanToken, decl.body); case SyntaxKind.MethodDeclaration: diff --git a/src/services/refactors/convertFunctionToEs6Class.ts b/src/services/refactors/convertFunctionToEs6Class.ts index 6645f8434b6..ddb13c3e04c 100644 --- a/src/services/refactors/convertFunctionToEs6Class.ts +++ b/src/services/refactors/convertFunctionToEs6Class.ts @@ -180,8 +180,7 @@ namespace ts.refactor.convertFunctionToES6Class { } // case 2: () => [1,2,3] else { - const expression = arrowFunctionBody as Expression; - bodyBlock = createBlock([createReturn(expression)]); + bodyBlock = createBlock([createReturn(arrowFunctionBody)]); } const fullModifiers = concatenate(modifiers, getModifierKindFromSource(arrowFunction, SyntaxKind.AsyncKeyword)); const method = createMethod(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, diff --git a/src/services/refactors/convertToEs6Module.ts b/src/services/refactors/convertToEs6Module.ts index f1f3c16b6bb..6ed9cbec2ee 100644 --- a/src/services/refactors/convertToEs6Module.ts +++ b/src/services/refactors/convertToEs6Module.ts @@ -194,7 +194,7 @@ namespace ts.refactor { } function convertVariableStatement(sourceFile: SourceFile, statement: VariableStatement, changes: textChanges.ChangeTracker, checker: TypeChecker, identifiers: Identifiers, target: ScriptTarget): void { - const { declarationList } = statement as VariableStatement; + const { declarationList } = statement; let foundImport = false; const newNodes = flatMap(declarationList.declarations, decl => { const { name, initializer } = decl; @@ -290,14 +290,10 @@ namespace ts.refactor { case SyntaxKind.ShorthandPropertyAssignment: case SyntaxKind.SpreadAssignment: return undefined; - case SyntaxKind.PropertyAssignment: { - const { name, initializer } = prop as PropertyAssignment; - return !isIdentifier(name) ? undefined : convertExportsDotXEquals(name.text, initializer); - } - case SyntaxKind.MethodDeclaration: { - const m = prop as MethodDeclaration; - return !isIdentifier(m.name) ? undefined : functionExpressionToDeclaration(m.name.text, [createToken(SyntaxKind.ExportKeyword)], m); - } + case SyntaxKind.PropertyAssignment: + return !isIdentifier(prop.name) ? undefined : convertExportsDotXEquals(prop.name.text, prop.initializer); + case SyntaxKind.MethodDeclaration: + return !isIdentifier(prop.name) ? undefined : functionExpressionToDeclaration(prop.name.text, [createToken(SyntaxKind.ExportKeyword)], prop); default: Debug.assertNever(prop); } diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index bf410ab27a9..65c9fd6268c 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -223,7 +223,7 @@ namespace ts.refactor.extractSymbol { return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] }; } const statements: Statement[] = []; - for (const statement of (start.parent).statements) { + for (const statement of start.parent.statements) { if (statement === start || statements.length) { const errors = checkNode(statement); if (errors) { @@ -1476,7 +1476,7 @@ namespace ts.refactor.extractSymbol { } const seenUsages = createMap(); - const target = isReadonlyArray(targetRange.range) ? createBlock(targetRange.range) : targetRange.range; + const target = isReadonlyArray(targetRange.range) ? createBlock(targetRange.range) : targetRange.range; const unmodifiedNode = isReadonlyArray(targetRange.range) ? first(targetRange.range) : targetRange.range; const inGenericContext = isInGenericContext(unmodifiedNode); @@ -1681,9 +1681,9 @@ namespace ts.refactor.extractSymbol { // if we get here this means that we are trying to handle 'write' and 'read' was already processed // walk scopes and update existing records. for (const perScope of usagesPerScope) { - const prevEntry = perScope.usages.get(identifier.text as string); + const prevEntry = perScope.usages.get(identifier.text); if (prevEntry) { - perScope.usages.set(identifier.text as string, { usage, symbol, node: identifier }); + perScope.usages.set(identifier.text, { usage, symbol, node: identifier }); } } return symbolId; @@ -1730,7 +1730,7 @@ namespace ts.refactor.extractSymbol { } } else { - usagesPerScope[i].usages.set(identifier.text as string, { usage, symbol, node: identifier }); + usagesPerScope[i].usages.set(identifier.text, { usage, symbol, node: identifier }); } } } diff --git a/src/services/services.ts b/src/services/services.ts index b5d6f0ec2a6..991b6c10606 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -728,7 +728,7 @@ namespace ts { } if (name.kind === SyntaxKind.ComputedPropertyName) { - const expr = (name).expression; + const expr = name.expression; if (expr.kind === SyntaxKind.PropertyAccessExpression) { return (expr).name.text; } @@ -832,10 +832,10 @@ namespace ts { // import {a, b as B} from "mod"; if (importClause.namedBindings) { if (importClause.namedBindings.kind === SyntaxKind.NamespaceImport) { - addDeclaration(importClause.namedBindings); + addDeclaration(importClause.namedBindings); } else { - forEach((importClause.namedBindings).elements, visit); + forEach(importClause.namedBindings.elements, visit); } } } @@ -2218,7 +2218,7 @@ namespace ts { case SyntaxKind.Identifier: return isObjectLiteralElement(node.parent) && (node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression || node.parent.parent.kind === SyntaxKind.JsxAttributes) && - (node.parent).name === node ? node.parent as ObjectLiteralElement : undefined; + node.parent.name === node ? node.parent : undefined; } return undefined; } diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index c96d621dd24..250127ecfc6 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -57,14 +57,9 @@ namespace ts.SignatureHelp { } // See if we can find some symbol with the call expression name that has call signatures. - const callExpression = argumentInfo.invocation; + const callExpression = argumentInfo.invocation; const expression = callExpression.expression; - const name = expression.kind === SyntaxKind.Identifier - ? expression - : expression.kind === SyntaxKind.PropertyAccessExpression - ? (expression).name - : undefined; - + const name = isIdentifier(expression) ? expression : isPropertyAccessExpression(expression) ? expression.name : undefined; if (!name || !name.escapedText) { return undefined; } @@ -160,7 +155,7 @@ namespace ts.SignatureHelp { } else if (node.parent.kind === SyntaxKind.TemplateSpan && node.parent.parent.parent.kind === SyntaxKind.TaggedTemplateExpression) { const templateSpan = node.parent; - const templateExpression = templateSpan.parent; + const templateExpression = templateSpan.parent; const tagExpression = templateExpression.parent; Debug.assert(templateExpression.kind === SyntaxKind.TemplateExpression); @@ -270,7 +265,6 @@ namespace ts.SignatureHelp { function getArgumentListInfoForTemplate(tagExpression: TaggedTemplateExpression, argumentIndex: number, sourceFile: SourceFile): ArgumentListInfo { // argumentCount is either 1 or (numSpans + 1) to account for the template strings array argument. const argumentCount = isNoSubstitutionTemplateLiteral(tagExpression.template) ? 1 : tagExpression.template.templateSpans.length + 1; - if (argumentIndex !== 0) { Debug.assertLessThan(argumentIndex, argumentCount); } @@ -311,7 +305,7 @@ namespace ts.SignatureHelp { // This is because a Missing node has no width. However, what we actually want is to include trivia // leading up to the next token in case the user is about to type in a TemplateMiddle or TemplateTail. if (template.kind === SyntaxKind.TemplateExpression) { - const lastSpan = lastOrUndefined((template).templateSpans); + const lastSpan = lastOrUndefined(template.templateSpans); if (lastSpan.literal.getFullWidth() === 0) { applicableSpanEnd = skipTrivia(sourceFile.text, applicableSpanEnd, /*stopAfterLineBreak*/ false); } diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index 387d027d999..135e906143f 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -146,13 +146,13 @@ namespace ts.SymbolDisplay { // try get the call/construct signature from the type if it matches let callExpressionLike: CallExpression | NewExpression | JsxOpeningLikeElement; if (isCallOrNewExpression(location)) { - callExpressionLike = location; + callExpressionLike = location; } else if (isCallExpressionTarget(location) || isNewExpressionTarget(location)) { callExpressionLike = location.parent; } else if (location.parent && isJsxOpeningLikeElement(location.parent) && isFunctionLike(symbol.valueDeclaration)) { - callExpressionLike = location.parent; + callExpressionLike = location.parent; } if (callExpressionLike) { diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 8df8a902734..263ac0f4c3b 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -131,7 +131,7 @@ namespace ts { while (node.parent.kind === SyntaxKind.QualifiedName) { node = node.parent; } - return isInternalModuleImportEqualsDeclaration(node.parent) && (node.parent).moduleReference === node; + return isInternalModuleImportEqualsDeclaration(node.parent) && node.parent.moduleReference === node; } function isNamespaceReference(node: Node): boolean { diff --git a/tslint.json b/tslint.json index b801df720f2..bd06724edb8 100644 --- a/tslint.json +++ b/tslint.json @@ -2,6 +2,8 @@ "extends": "tslint:latest", "rulesDirectory": "built/local/tslint/rules", "rules": { + "no-unnecessary-type-assertion-2": true, + "array-type": [true, "array"], "ban-types": { "options": [ From e305c5190e4eeb807350fa6d8eaf595099e58d1d Mon Sep 17 00:00:00 2001 From: csigs Date: Tue, 20 Feb 2018 05:10:17 +0000 Subject: [PATCH 27/28] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl index e651b11346d..9c0ffaf818e 100644 --- a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -3021,6 +3021,15 @@ + + + + + + + + + From 64c24b61f1fcb85222be94b872605c97a1901532 Mon Sep 17 00:00:00 2001 From: csigs Date: Tue, 20 Feb 2018 17:10:32 +0000 Subject: [PATCH 28/28] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 3de4abb5ce7..5d0a9a141b0 100644 --- a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -3011,6 +3011,15 @@ + + + + + + + + +