diff --git a/.mailmap b/.mailmap index ede478c8a18..6a9362f6e4c 100644 --- a/.mailmap +++ b/.mailmap @@ -8,11 +8,14 @@ Alexander Rusakov Alex Eagle Anatoly Ressin Anders Hejlsberg unknown unknown +about-code # Andreas Martin Andrej Baran +Andrew Ochsner Andrew Z Allen Andy Hanson Andy Anil Anar Anton Tolmachev +Anubha Mathur anubmat Arnavion # Arnav Singh Arthur Ozga Arthur Ozga Arthur Ozga Arthur Ozga Arthur Ozga Asad Saeeduddin @@ -37,6 +40,7 @@ Dan Corder Dan Quirk Dan Quirk nknown Daniel Rosenwasser Daniel Rosenwasser Daniel Rosenwasser Daniel Rosenwasser Daniel Rosenwasser David Li +David Sheldrick David Souther Denis Nedelyaev Dick van den Brink unknown unknown @@ -52,6 +56,7 @@ Evan Sebastian Eyas # Eyas Sharaiha Fabian Cook falsandtru # @falsandtru +flowmemo # @flowmemo Frank Wallis František Žiacik František Žiacik Gabe Moothart @@ -62,6 +67,7 @@ Graeme Wicksted Guillaume Salles Guy Bedford guybedford Harald Niesche +Homa Wong Iain Monro Ingvar Stepanyan impinball # Isiah Meadows @@ -81,6 +87,7 @@ Jonathan Park Jonathan Turner Jonathan Turner Jonathan Toland Jesse Schalken +Joel Day Josh Abernathy joshaber Josh Kalderimis Josh Soref @@ -95,10 +102,12 @@ Kanchalai Tanglertsampan Yui T Kanchalai Tanglertsampan Yui Kanchalai Tanglertsampan Yui Kanchalai Tanglertsampan yui T +Kārlis Gaņģis Keith Mashinter kmashint Ken Howard Kevin Lang kimamula # Kenji Imamula +Klaus Meinhardt Kyle Kelley Lorant Pinter Lucien Greathouse @@ -107,6 +116,7 @@ Martin Vseticka Martin Všeticka # Marin Marinov vvakame # Masahiro Wakame Matt McCutchen +MANISH-GIRI # Manish Giri Max Deepfield Micah Zoltu Michael @@ -213,4 +223,6 @@ Tim Perry Vidar Tonaas Fauske Viktor Zozulyak rix # Richard Sentino -rohitverma007 # Rohit Verma \ No newline at end of file +rohitverma007 # Rohit Verma +rdosanjh # Raj Dosanjh +gdh1995 # Dahan Gong \ No newline at end of file diff --git a/AUTHORS.md b/AUTHORS.md index ae7832176ea..196f5e84542 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -12,13 +12,16 @@ TypeScript is authored by: * Aliaksandr Radzivanovich * Anatoly Ressin * Anders Hejlsberg +* Andreas Martin * Andrej Baran +* Andrew Ochsner * Andrew Z Allen * András Parditka * Andy Hanson * Anil Anar * Anton Khlynovskiy * Anton Tolmachev +* Anubha Mathur * Arnav Singh * Arthur Ozga * Asad Saeeduddin @@ -42,12 +45,14 @@ TypeScript is authored by: * Cotton Hou * Cyrus Najmabadi * Dafrok Zhang +* Dahan Gong * Dan Corder * Dan Quirk * Daniel Hollocher * Daniel Rosenwasser * David Kmenta * David Li +* David Sheldrick * David Souther * Denis Nedelyaev * Dick van den Brink @@ -66,6 +71,7 @@ TypeScript is authored by: * Eyas Sharaiha * Fabian Cook * @falsandtru +* @flowmemo * Frank Wallis * Franklin Tse * František Žiacik @@ -79,6 +85,7 @@ TypeScript is authored by: * Guy Bedford * Harald Niesche * Herrington Darkholme +* Homa Wong * Iain Monro * Ingvar Stepanyan * Isiah Meadows @@ -93,6 +100,7 @@ TypeScript is authored by: * Jeffrey Morlan * Jesse Schalken * Jiri Tobisek +* Joel Day * Joey Wilson * Johannes Rieken * John Vilk @@ -114,10 +122,13 @@ TypeScript is authored by: * Ken Howard * Kenji Imamula * Kevin Lang +* Klaus Meinhardt * Kyle Kelley +* Kārlis Gaņģis * Lorant Pinter * Lucien Greathouse * Lukas Elmer +* Manish Giri * Marin Marinov * Marius Schulz * Martin Vseticka @@ -155,6 +166,7 @@ TypeScript is authored by: * @progre * Punya Biswal * Rado Kirov +* Raj Dosanjh * Richard Knoll * Richard Sentino * Robert Coie diff --git a/Jakefile.js b/Jakefile.js index 3ee8476c842..0b3a26dbb77 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -269,6 +269,7 @@ var harnessSources = harnessCoreSources.concat([ "projectErrors.ts", "matchFiles.ts", "initializeTSConfig.ts", + "printer.ts", ].map(function (f) { return path.join(unittestsDirectory, f); })).concat([ diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 69d019688b1..931fec458b4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -640,7 +640,7 @@ namespace ts { } // declaration is after usage // can be legal if usage is deferred (i.e. inside function or in initializer of instance property) - if (isUsedInFunctionOrNonStaticProperty(usage)) { + if (isUsedInFunctionOrInstanceProperty(usage)) { return true; } const sourceFiles = host.getSourceFiles(); @@ -667,10 +667,12 @@ namespace ts { } - // declaration is after usage - // can be legal if usage is deferred (i.e. inside function or in initializer of instance property) + // declaration is after usage, but it can still be legal if usage is deferred: + // 1. inside a function + // 2. inside an instance property initializer, a reference to a non-instance property const container = getEnclosingBlockScopeContainer(declaration); - return isUsedInFunctionOrNonStaticProperty(usage, container); + const isInstanceProperty = declaration.kind === SyntaxKind.PropertyDeclaration && !(getModifierFlags(declaration) & ModifierFlags.Static); + return isUsedInFunctionOrInstanceProperty(usage, isInstanceProperty, container); function isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration: VariableDeclaration, usage: Node): boolean { const container = getEnclosingBlockScopeContainer(declaration); @@ -699,7 +701,7 @@ namespace ts { return false; } - function isUsedInFunctionOrNonStaticProperty(usage: Node, container?: Node): boolean { + function isUsedInFunctionOrInstanceProperty(usage: Node, isDeclarationInstanceProperty?: boolean, container?: Node): boolean { let current = usage; while (current) { if (current === container) { @@ -710,13 +712,13 @@ namespace ts { return true; } - const initializerOfNonStaticProperty = current.parent && + const initializerOfInstanceProperty = current.parent && current.parent.kind === SyntaxKind.PropertyDeclaration && (getModifierFlags(current.parent) & ModifierFlags.Static) === 0 && (current.parent).initializer === current; - if (initializerOfNonStaticProperty) { - return true; + if (initializerOfInstanceProperty) { + return !isDeclarationInstanceProperty; } current = current.parent; @@ -985,10 +987,10 @@ namespace ts { // interface bar {} // } // const foo/*1*/: foo/*2*/.bar; - // The foo at /*1*/ and /*2*/ will share same symbol with two meaning - // block - scope variable and namespace module. However, only when we + // The foo at /*1*/ and /*2*/ will share same symbol with two meanings: + // block-scoped variable and namespace module. However, only when we // try to resolve name in /*1*/ which is used in variable position, - // we want to check for block- scoped + // we want to check for block-scoped if (meaning & SymbolFlags.BlockScopedVariable) { const exportOrLocalSymbol = getExportSymbolOfValueSymbolIfExported(result); if (exportOrLocalSymbol.flags & SymbolFlags.BlockScopedVariable) { @@ -1012,7 +1014,7 @@ namespace ts { return false; } - const container = getThisContainer(errorLocation, /* includeArrowFunctions */ true); + const container = getThisContainer(errorLocation, /*includeArrowFunctions*/ true); let location = container; while (location) { if (isClassLike(location.parent)) { @@ -3994,7 +3996,7 @@ namespace ts { // A valid base type is any non-generic object type or intersection of non-generic // object types. function isValidBaseType(type: Type): boolean { - return type.flags & TypeFlags.Object && !isGenericMappedType(type) || + return type.flags & (TypeFlags.Object | TypeFlags.NonPrimitive) && !isGenericMappedType(type) || type.flags & TypeFlags.Intersection && !forEach((type).types, t => !isValidBaseType(t)); } @@ -4932,7 +4934,7 @@ namespace ts { } function getApparentTypeOfIntersectionType(type: IntersectionType) { - return type.resolvedIndexType || (type.resolvedApparentType = getTypeWithThisArgument(type, type)); + return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, type)); } /** @@ -4947,7 +4949,7 @@ namespace ts { t.flags & TypeFlags.NumberLike ? globalNumberType : t.flags & TypeFlags.BooleanLike ? globalBooleanType : t.flags & TypeFlags.ESSymbol ? getGlobalESSymbolType() : - t.flags & TypeFlags.NonPrimitive ? globalObjectType : + t.flags & TypeFlags.NonPrimitive ? emptyObjectType : t; } @@ -12546,6 +12548,16 @@ namespace ts { } } + function isInPropertyInitializer(node: Node): boolean { + while (node) { + if (node.parent && node.parent.kind === SyntaxKind.PropertyDeclaration && (node.parent as PropertyDeclaration).initializer === node) { + return true; + } + node = node.parent; + } + return false; + } + function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, right: Identifier) { const type = checkNonNullExpression(left); if (isTypeAny(type) || type === silentNeverType) { @@ -12568,6 +12580,11 @@ namespace ts { } return unknownType; } + if (prop.valueDeclaration && + isInPropertyInitializer(node) && + !isBlockScopedNameDeclaredBeforeUse(prop.valueDeclaration, right)) { + error(right, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, right.text); + } markPropertyAsReferenced(prop); diff --git a/src/compiler/comments.ts b/src/compiler/comments.ts index bd9190dbec7..200158c2f5c 100644 --- a/src/compiler/comments.ts +++ b/src/compiler/comments.ts @@ -5,17 +5,16 @@ namespace ts { export interface CommentWriter { reset(): void; setSourceFile(sourceFile: SourceFile): void; - emitNodeWithComments(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void; + setWriter(writer: EmitTextWriter): void; + emitNodeWithComments(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void; emitBodyWithDetachedComments(node: Node, detachedRange: TextRange, emitCallback: (node: Node) => void): void; emitTrailingCommentsOfPosition(pos: number): void; } - export function createCommentWriter(host: EmitHost, writer: EmitTextWriter, sourceMap: SourceMapWriter): CommentWriter { - const compilerOptions = host.getCompilerOptions(); - const extendedDiagnostics = compilerOptions.extendedDiagnostics; - const newLine = host.getNewLine(); - const { emitPos } = sourceMap; - + export function createCommentWriter(printerOptions: PrinterOptions, emitPos: ((pos: number) => void) | undefined): CommentWriter { + const extendedDiagnostics = printerOptions.extendedDiagnostics; + const newLine = getNewLineCharacter(printerOptions); + let writer: EmitTextWriter; let containerPos = -1; let containerEnd = -1; let declarationListContainerEnd = -1; @@ -24,19 +23,20 @@ namespace ts { let currentLineMap: number[]; let detachedCommentsInfo: { nodePos: number, detachedCommentEndPos: number}[]; let hasWrittenComment = false; - let disabled: boolean = compilerOptions.removeComments; + let disabled: boolean = printerOptions.removeComments; return { reset, + setWriter, setSourceFile, emitNodeWithComments, emitBodyWithDetachedComments, emitTrailingCommentsOfPosition, }; - function emitNodeWithComments(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) { + function emitNodeWithComments(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) { if (disabled) { - emitCallback(emitContext, node); + emitCallback(hint, node); return; } @@ -47,11 +47,11 @@ namespace ts { // Both pos and end are synthesized, so just emit the node without comments. if (emitFlags & EmitFlags.NoNestedComments) { disabled = true; - emitCallback(emitContext, node); + emitCallback(hint, node); disabled = false; } else { - emitCallback(emitContext, node); + emitCallback(hint, node); } } else { @@ -94,11 +94,11 @@ namespace ts { if (emitFlags & EmitFlags.NoNestedComments) { disabled = true; - emitCallback(emitContext, node); + emitCallback(hint, node); disabled = false; } else { - emitCallback(emitContext, node); + emitCallback(hint, node); } if (extendedDiagnostics) { @@ -198,9 +198,9 @@ namespace ts { } // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space - emitPos(commentPos); + if (emitPos) emitPos(commentPos); writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine); - emitPos(commentEnd); + if (emitPos) emitPos(commentEnd); if (hasTrailingNewLine) { writer.writeLine(); @@ -220,9 +220,9 @@ namespace ts { writer.write(" "); } - emitPos(commentPos); + if (emitPos) emitPos(commentPos); writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine); - emitPos(commentEnd); + if (emitPos) emitPos(commentEnd); if (hasTrailingNewLine) { writer.writeLine(); @@ -248,9 +248,9 @@ namespace ts { function emitTrailingCommentOfPosition(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean) { // trailing comments of a position are emitted at /*trailing comment1 */space/*trailing comment*/space - emitPos(commentPos); + if (emitPos) emitPos(commentPos); writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine); - emitPos(commentEnd); + if (emitPos) emitPos(commentEnd); if (hasTrailingNewLine) { writer.writeLine(); @@ -286,6 +286,10 @@ namespace ts { detachedCommentsInfo = undefined; } + function setWriter(output: EmitTextWriter): void { + writer = output; + } + function setSourceFile(sourceFile: SourceFile) { currentSourceFile = sourceFile; currentText = currentSourceFile.text; @@ -323,9 +327,9 @@ namespace ts { } function writeComment(text: string, lineMap: number[], writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) { - emitPos(commentPos); + if (emitPos) emitPos(commentPos); writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine); - emitPos(commentEnd); + if (emitPos) emitPos(commentEnd); } /** diff --git a/src/compiler/core.ts b/src/compiler/core.ts index d11f9925c05..94e32dfdbb3 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1455,7 +1455,7 @@ namespace ts { return /^\.\.?($|[\\/])/.test(moduleName); } - export function getEmitScriptTarget(compilerOptions: CompilerOptions) { + export function getEmitScriptTarget(compilerOptions: CompilerOptions | PrinterOptions) { return compilerOptions.target || ScriptTarget.ES3; } diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 46df4fed689..4b878adaff5 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -35,13 +35,15 @@ namespace ts { forEachEmittedFile(host, getDeclarationDiagnosticsFromFile, targetSourceFile); return declarationDiagnostics.getDiagnostics(targetSourceFile ? targetSourceFile.fileName : undefined); - function getDeclarationDiagnosticsFromFile({ declarationFilePath }: EmitFileNames, sources: SourceFile[], isBundledEmit: boolean) { - emitDeclarations(host, resolver, declarationDiagnostics, declarationFilePath, sources, isBundledEmit, /*emitOnlyDtsFiles*/ false); + function getDeclarationDiagnosticsFromFile({ declarationFilePath }: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle) { + emitDeclarations(host, resolver, declarationDiagnostics, declarationFilePath, sourceFileOrBundle, /*emitOnlyDtsFiles*/ false); } } function emitDeclarations(host: EmitHost, resolver: EmitResolver, emitterDiagnostics: DiagnosticCollection, declarationFilePath: string, - sourceFiles: SourceFile[], isBundledEmit: boolean, emitOnlyDtsFiles: boolean): DeclarationEmit { + sourceFileOrBundle: SourceFile | Bundle, emitOnlyDtsFiles: boolean): DeclarationEmit { + const sourceFiles = sourceFileOrBundle.kind === SyntaxKind.Bundle ? sourceFileOrBundle.sourceFiles : [sourceFileOrBundle]; + const isBundledEmit = sourceFileOrBundle.kind === SyntaxKind.Bundle; const newLine = host.getNewLine(); const compilerOptions = host.getCompilerOptions(); @@ -1803,8 +1805,9 @@ namespace ts { } return addedBundledEmitReference; - function getDeclFileName(emitFileNames: EmitFileNames, _sourceFiles: SourceFile[], isBundledEmit: boolean) { + function getDeclFileName(emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle) { // Dont add reference path to this file if it is a bundled emit and caller asked not emit bundled file path + const isBundledEmit = sourceFileOrBundle.kind === SyntaxKind.Bundle; if (isBundledEmit && !addBundledFileReference) { return; } @@ -1817,10 +1820,11 @@ namespace ts { } /* @internal */ - export function writeDeclarationFile(declarationFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean, host: EmitHost, resolver: EmitResolver, emitterDiagnostics: DiagnosticCollection, emitOnlyDtsFiles: boolean) { - const emitDeclarationResult = emitDeclarations(host, resolver, emitterDiagnostics, declarationFilePath, sourceFiles, isBundledEmit, emitOnlyDtsFiles); + export function writeDeclarationFile(declarationFilePath: string, sourceFileOrBundle: SourceFile | Bundle, host: EmitHost, resolver: EmitResolver, emitterDiagnostics: DiagnosticCollection, emitOnlyDtsFiles: boolean) { + const emitDeclarationResult = emitDeclarations(host, resolver, emitterDiagnostics, declarationFilePath, sourceFileOrBundle, emitOnlyDtsFiles); const emitSkipped = emitDeclarationResult.reportedDeclarationError || host.isEmitBlocked(declarationFilePath) || host.getCompilerOptions().noEmit; if (!emitSkipped) { + const sourceFiles = sourceFileOrBundle.kind === SyntaxKind.Bundle ? sourceFileOrBundle.sourceFiles : [sourceFileOrBundle]; const declarationOutput = emitDeclarationResult.referencesOutput + getDeclarationOutput(emitDeclarationResult.synchronousDeclarationOutput, emitDeclarationResult.moduleElementDeclarationEmitInfo); writeFile(host, emitterDiagnostics, declarationFilePath, declarationOutput, host.getCompilerOptions().emitBOM, sourceFiles); diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 27285a4c2dc..700102a7069 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1,61 +1,27 @@ -/// +/// /// -/// -/// +/// +/// /// -/* @internal */ namespace ts { - // Flags enum to track count of temp variables and a few dedicated names - const enum TempFlags { - Auto = 0x00000000, // No preferred name - CountMask = 0x0FFFFFFF, // Temp variable counter - _i = 0x10000000, // Use/preference flag for '_i' - } - - const id = (s: SourceFile) => s; - const nullTransformers: Transformer[] = [_ => id]; + const delimiters = createDelimiterMap(); + const brackets = createBracketsMap(); + /*@internal*/ // targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile, emitOnlyDtsFiles?: boolean): EmitResult { - const delimiters = createDelimiterMap(); - const brackets = createBracketsMap(); const compilerOptions = host.getCompilerOptions(); - const languageVersion = getEmitScriptTarget(compilerOptions); const moduleKind = getEmitModuleKind(compilerOptions); const sourceMapDataList: SourceMapData[] = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? [] : undefined; const emittedFilesList: string[] = compilerOptions.listEmittedFiles ? [] : undefined; const emitterDiagnostics = createDiagnosticCollection(); const newLine = host.getNewLine(); - const transformers: Transformer[] = emitOnlyDtsFiles ? nullTransformers : getTransformers(compilerOptions); + const transformers = emitOnlyDtsFiles ? [] : getTransformers(compilerOptions); const writer = createTextWriter(newLine); - const { - write, - writeLine, - increaseIndent, - decreaseIndent - } = writer; - const sourceMap = createSourceMapWriter(host, writer); - const { - emitNodeWithSourceMap, - emitTokenWithSourceMap - } = sourceMap; - const comments = createCommentWriter(host, writer, sourceMap); - const { - emitNodeWithComments, - emitBodyWithDetachedComments, - emitTrailingCommentsOfPosition - } = comments; - - let nodeIdToGeneratedName: string[]; - let autoGeneratedIdToGeneratedName: string[]; - let generatedNameSet: Map; - let tempFlags: TempFlags; let currentSourceFile: SourceFile; - let currentText: string; - let currentFileIdentifiers: Map; let bundledHelpers: Map; let isOwnFileEmit: boolean; let emitSkipped = false; @@ -63,17 +29,30 @@ namespace ts { const sourceFiles = getSourceFilesToEmit(host, targetSourceFile); // Transform the source files - performance.mark("beforeTransform"); - const { - transformed, - emitNodeWithSubstitution, - emitNodeWithNotification - } = transformFiles(resolver, host, sourceFiles, transformers); - performance.measure("transformTime", "beforeTransform"); + const transform = transformFiles(resolver, host, sourceFiles, transformers); + + // Create a printer to print the nodes + const printer = createPrinter(compilerOptions, { + // resolver hooks + hasGlobalName: resolver.hasGlobalName, + + // transform hooks + onEmitNode: transform.emitNodeWithNotification, + onSubstituteNode: transform.emitNodeWithSubstitution, + + // sourcemap hooks + onEmitSourceMapOfNode: sourceMap.emitNodeWithSourceMap, + onEmitSourceMapOfToken: sourceMap.emitTokenWithSourceMap, + onEmitSourceMapOfPosition: sourceMap.emitPos, + + // emitter hooks + onEmitHelpers: emitHelpers, + onSetSourceFile: setSourceFile, + }); // Emit each output file performance.mark("beforePrint"); - forEachEmittedFile(host, emitFile, transformed, emitOnlyDtsFiles); + forEachEmittedFile(host, emitSourceFileOrBundle, transform.transformed, emitOnlyDtsFiles); performance.measure("printTime", "beforePrint"); // Clean up emit nodes on parse tree @@ -88,11 +67,11 @@ namespace ts { sourceMaps: sourceMapDataList }; - function emitFile({ jsFilePath, sourceMapFilePath, declarationFilePath }: EmitFileNames, sourceFiles: SourceFile[], isBundledEmit: boolean) { + function emitSourceFileOrBundle({ jsFilePath, sourceMapFilePath, declarationFilePath }: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle) { // Make sure not to write js file and source map file if any of them cannot be written if (!host.isEmitBlocked(jsFilePath) && !compilerOptions.noEmit) { if (!emitOnlyDtsFiles) { - printFile(jsFilePath, sourceMapFilePath, sourceFiles, isBundledEmit); + printSourceFileOrBundle(jsFilePath, sourceMapFilePath, sourceFileOrBundle); } } else { @@ -100,7 +79,7 @@ namespace ts { } if (declarationFilePath) { - emitSkipped = writeDeclarationFile(declarationFilePath, getOriginalSourceFiles(sourceFiles), isBundledEmit, host, resolver, emitterDiagnostics, emitOnlyDtsFiles) || emitSkipped; + emitSkipped = writeDeclarationFile(declarationFilePath, getOriginalSourceFileOrBundle(sourceFileOrBundle), host, resolver, emitterDiagnostics, emitOnlyDtsFiles) || emitSkipped; } if (!emitSkipped && emittedFilesList) { @@ -116,34 +95,32 @@ namespace ts { } } - function printFile(jsFilePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) { - sourceMap.initialize(jsFilePath, sourceMapFilePath, sourceFiles, isBundledEmit); - nodeIdToGeneratedName = []; - autoGeneratedIdToGeneratedName = []; - generatedNameSet = createMap(); - bundledHelpers = isBundledEmit ? createMap() : undefined; - isOwnFileEmit = !isBundledEmit; + function printSourceFileOrBundle(jsFilePath: string, sourceMapFilePath: string, sourceFileOrBundle: SourceFile | Bundle) { + const bundle = sourceFileOrBundle.kind === SyntaxKind.Bundle ? sourceFileOrBundle : undefined; + const sourceFile = sourceFileOrBundle.kind === SyntaxKind.SourceFile ? sourceFileOrBundle : undefined; + const sourceFiles = bundle ? bundle.sourceFiles : [sourceFile]; + sourceMap.initialize(jsFilePath, sourceMapFilePath, sourceFileOrBundle); - // Emit helpers from all the files - if (isBundledEmit && moduleKind) { - for (const sourceFile of sourceFiles) { - emitHelpers(sourceFile, /*isBundle*/ true); - } + if (bundle) { + bundledHelpers = createMap(); + isOwnFileEmit = false; + printer.writeBundle(bundle, writer); + } + else { + isOwnFileEmit = true; + printer.writeFile(sourceFile, writer); } - // Print each transformed source file. - forEach(sourceFiles, printSourceFile); - - writeLine(); + writer.writeLine(); const sourceMappingURL = sourceMap.getSourceMappingURL(); if (sourceMappingURL) { - write(`//# ${"sourceMappingURL"}=${sourceMappingURL}`); // Sometimes tools can sometimes see this line as a source mapping url comment + writer.write(`//# ${"sourceMappingURL"}=${sourceMappingURL}`); // Sometimes tools can sometimes see this line as a source mapping url comment } // Write the source map if (compilerOptions.sourceMap && !compilerOptions.inlineSourceMap) { - writeFile(host, emitterDiagnostics, sourceMapFilePath, sourceMap.getText(), /*writeByteOrderMark*/ false, sourceFiles); + writeFile(host, emitterDiagnostics, sourceMapFilePath, sourceMap.getText(), /*writeByteOrderMark*/ false, sourceFiles); } // Record source map data for the test harness. @@ -156,153 +133,281 @@ namespace ts { // Reset state sourceMap.reset(); - comments.reset(); writer.reset(); - tempFlags = TempFlags.Auto; currentSourceFile = undefined; - currentText = undefined; + bundledHelpers = undefined; isOwnFileEmit = false; } - function printSourceFile(node: SourceFile) { + function setSourceFile(node: SourceFile) { currentSourceFile = node; - currentText = node.text; - currentFileIdentifiers = node.identifiers; sourceMap.setSourceFile(node); - comments.setSourceFile(node); - pipelineEmitWithNotification(EmitContext.SourceFile, node); } - /** - * Emits a node. - */ - function emit(node: Node) { - pipelineEmitWithNotification(EmitContext.Unspecified, node); + function emitHelpers(node: Node, writeLines: (text: string) => void) { + let helpersEmitted = false; + const bundle = node.kind === SyntaxKind.Bundle ? node : undefined; + if (bundle && moduleKind === ModuleKind.None) { + return; + } + + const numNodes = bundle ? bundle.sourceFiles.length : 1; + for (let i = 0; i < numNodes; i++) { + const currentNode = bundle ? bundle.sourceFiles[i] : node; + const sourceFile = isSourceFile(currentNode) ? currentNode : currentSourceFile; + const shouldSkip = compilerOptions.noEmitHelpers || (sourceFile && getExternalHelpersModuleName(sourceFile) !== undefined); + const shouldBundle = isSourceFile(currentNode) && !isOwnFileEmit; + const helpers = getEmitHelpers(currentNode); + if (helpers) { + for (const helper of stableSort(helpers, compareEmitHelpers)) { + if (!helper.scoped) { + // Skip the helper if it can be skipped and the noEmitHelpers compiler + // option is set, or if it can be imported and the importHelpers compiler + // option is set. + if (shouldSkip) continue; + + // Skip the helper if it can be bundled but hasn't already been emitted and we + // are emitting a bundled module. + if (shouldBundle) { + if (bundledHelpers.get(helper.name)) { + continue; + } + + bundledHelpers.set(helper.name, true); + } + } + else if (bundle) { + // Skip the helper if it is scoped and we are emitting bundled helpers + continue; + } + + writeLines(helper.text); + helpersEmitted = true; + } + } + } + + return helpersEmitted; + } + } + + export function createPrinter(printerOptions: PrinterOptions = {}, handlers: PrintHandlers = {}): Printer { + const { + hasGlobalName, + onEmitSourceMapOfNode, + onEmitSourceMapOfToken, + onEmitSourceMapOfPosition, + onEmitNode, + onEmitHelpers, + onSetSourceFile, + onSubstituteNode, + } = handlers; + + const newLine = getNewLineCharacter(printerOptions); + const languageVersion = getEmitScriptTarget(printerOptions); + const comments = createCommentWriter(printerOptions, onEmitSourceMapOfPosition); + const { + emitNodeWithComments, + emitBodyWithDetachedComments, + emitTrailingCommentsOfPosition, + } = comments; + + let currentSourceFile: SourceFile; + let nodeIdToGeneratedName: string[]; // Map of generated names for specific nodes. + let autoGeneratedIdToGeneratedName: string[]; // Map of generated names for temp and loop variables. + let generatedNames: Map; // Set of names generated by the NameGenerator. + let tempFlagsStack: TempFlags[]; // Stack of enclosing name generation scopes. + let tempFlags: TempFlags; // TempFlags for the current name generation scope. + let writer: EmitTextWriter; + let ownWriter: EmitTextWriter; + + reset(); + return { + // public API + printNode, + printFile, + printBundle, + + // internal API + writeNode, + writeFile, + writeBundle + }; + + function printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): string { + switch (hint) { + case EmitHint.SourceFile: + Debug.assert(isSourceFile(node), "Expected a SourceFile node."); + break; + case EmitHint.IdentifierName: + Debug.assert(isIdentifier(node), "Expected an Identifier node."); + break; + case EmitHint.Expression: + Debug.assert(isExpression(node), "Expected an Expression node."); + break; + } + switch (node.kind) { + case SyntaxKind.SourceFile: return printFile(node); + case SyntaxKind.Bundle: return printBundle(node); + } + writeNode(hint, node, sourceFile, beginPrint()); + return endPrint(); + } + + function printBundle(bundle: Bundle): string { + writeBundle(bundle, beginPrint()); + return endPrint(); + } + + function printFile(sourceFile: SourceFile): string { + writeFile(sourceFile, beginPrint()); + return endPrint(); + } + + function writeNode(hint: EmitHint, node: Node, sourceFile: SourceFile, output: EmitTextWriter) { + const previousWriter = writer; + setWriter(output); + print(hint, node, sourceFile); + reset(); + writer = previousWriter; + } + + function writeBundle(bundle: Bundle, output: EmitTextWriter) { + const previousWriter = writer; + setWriter(output); + emitHelpersIndirect(bundle); + for (const sourceFile of bundle.sourceFiles) { + print(EmitHint.SourceFile, sourceFile, sourceFile); + } + reset(); + writer = previousWriter; + } + + function writeFile(sourceFile: SourceFile, output: EmitTextWriter) { + const previousWriter = writer; + setWriter(output); + print(EmitHint.SourceFile, sourceFile, sourceFile); + reset(); + writer = previousWriter; + } + + function beginPrint() { + return ownWriter || (ownWriter = createTextWriter(newLine)); + } + + function endPrint() { + const text = ownWriter.getText(); + ownWriter.reset(); + return text; + } + + function print(hint: EmitHint, node: Node, sourceFile: SourceFile) { + setSourceFile(sourceFile); + pipelineEmitWithNotification(hint, node); + } + + function setSourceFile(sourceFile: SourceFile) { + currentSourceFile = sourceFile; + comments.setSourceFile(sourceFile); + if (onSetSourceFile) { + onSetSourceFile(sourceFile); + } + } + + function setWriter(output: EmitTextWriter | undefined) { + writer = output; + comments.setWriter(output); + } + + function reset() { + nodeIdToGeneratedName = []; + autoGeneratedIdToGeneratedName = []; + generatedNames = createMap(); + tempFlagsStack = []; + tempFlags = TempFlags.Auto; + comments.reset(); + setWriter(/*output*/ undefined); + } + + function emit(node: Node, hint = EmitHint.Unspecified) { + pipelineEmitWithNotification(hint, node); } - /** - * Emits an IdentifierName. - */ function emitIdentifierName(node: Identifier) { - pipelineEmitWithNotification(EmitContext.IdentifierName, node); + pipelineEmitWithNotification(EmitHint.IdentifierName, node); } - /** - * Emits an expression node. - */ function emitExpression(node: Expression) { - pipelineEmitWithNotification(EmitContext.Expression, node); + pipelineEmitWithNotification(EmitHint.Expression, node); } - /** - * Emits a node with possible notification. - * - * NOTE: Do not call this method directly. It is part of the emit pipeline - * and should only be called from printSourceFile, emit, emitExpression, or - * emitIdentifierName. - */ - function pipelineEmitWithNotification(emitContext: EmitContext, node: Node) { - emitNodeWithNotification(emitContext, node, pipelineEmitWithComments); + function pipelineEmitWithNotification(hint: EmitHint, node: Node) { + if (onEmitNode) { + onEmitNode(hint, node, pipelineEmitWithComments); + } + else { + pipelineEmitWithComments(hint, node); + } } - /** - * Emits a node with comments. - * - * NOTE: Do not call this method directly. It is part of the emit pipeline - * and should only be called indirectly from pipelineEmitWithNotification. - */ - function pipelineEmitWithComments(emitContext: EmitContext, node: Node) { - // Do not emit comments for SourceFile - if (emitContext === EmitContext.SourceFile) { - pipelineEmitWithSourceMap(emitContext, node); + function pipelineEmitWithComments(hint: EmitHint, node: Node) { + if (emitNodeWithComments && hint !== EmitHint.SourceFile) { + emitNodeWithComments(hint, node, pipelineEmitWithSourceMap); + } + else { + pipelineEmitWithSourceMap(hint, node); + } + } + + function pipelineEmitWithSourceMap(hint: EmitHint, node: Node) { + if (onEmitSourceMapOfNode && hint !== EmitHint.SourceFile && hint !== EmitHint.IdentifierName) { + onEmitSourceMapOfNode(hint, node, pipelineEmitWithSubstitution); + } + else { + pipelineEmitWithSubstitution(hint, node); + } + } + + function pipelineEmitWithSubstitution(hint: EmitHint, node: Node) { + if (onSubstituteNode) { + onSubstituteNode(hint, node, pipelineEmitWithHint); + } + else { + pipelineEmitWithHint(hint, node); + } + } + + function pipelineEmitWithHint(hint: EmitHint, node: Node): void { + switch (hint) { + case EmitHint.SourceFile: return pipelineEmitSourceFile(node); + case EmitHint.IdentifierName: return pipelineEmitIdentifierName(node); + case EmitHint.Expression: return pipelineEmitExpression(node); + case EmitHint.Unspecified: return pipelineEmitUnspecified(node); + } + } + + function pipelineEmitSourceFile(node: Node): void { + Debug.assertNode(node, isSourceFile); + emitSourceFile(node); + } + + function pipelineEmitIdentifierName(node: Node): void { + Debug.assertNode(node, isIdentifier); + emitIdentifier(node); + } + + function pipelineEmitUnspecified(node: Node): void { + const kind = node.kind; + + // Reserved words + // Strict mode reserved words + // Contextual keywords + if (isKeyword(kind)) { + writeTokenText(kind); return; } - emitNodeWithComments(emitContext, node, pipelineEmitWithSourceMap); - } - - /** - * Emits a node with source maps. - * - * NOTE: Do not call this method directly. It is part of the emit pipeline - * and should only be called indirectly from pipelineEmitWithComments. - */ - function pipelineEmitWithSourceMap(emitContext: EmitContext, node: Node) { - // Do not emit source mappings for SourceFile or IdentifierName - if (emitContext === EmitContext.SourceFile - || emitContext === EmitContext.IdentifierName) { - pipelineEmitWithSubstitution(emitContext, node); - return; - } - - emitNodeWithSourceMap(emitContext, node, pipelineEmitWithSubstitution); - } - - /** - * Emits a node with possible substitution. - * - * NOTE: Do not call this method directly. It is part of the emit pipeline - * and should only be called indirectly from pipelineEmitWithSourceMap or - * pipelineEmitInUnspecifiedContext (when picking a more specific context). - */ - function pipelineEmitWithSubstitution(emitContext: EmitContext, node: Node) { - emitNodeWithSubstitution(emitContext, node, pipelineEmitForContext); - } - - /** - * Emits a node. - * - * NOTE: Do not call this method directly. It is part of the emit pipeline - * and should only be called indirectly from pipelineEmitWithSubstitution. - */ - function pipelineEmitForContext(emitContext: EmitContext, node: Node): void { - switch (emitContext) { - case EmitContext.SourceFile: return pipelineEmitInSourceFileContext(node); - case EmitContext.IdentifierName: return pipelineEmitInIdentifierNameContext(node); - case EmitContext.Unspecified: return pipelineEmitInUnspecifiedContext(node); - case EmitContext.Expression: return pipelineEmitInExpressionContext(node); - } - } - - /** - * Emits a node in the SourceFile EmitContext. - * - * NOTE: Do not call this method directly. It is part of the emit pipeline - * and should only be called indirectly from pipelineEmitForContext. - */ - function pipelineEmitInSourceFileContext(node: Node): void { - const kind = node.kind; - switch (kind) { - // Top-level nodes - case SyntaxKind.SourceFile: - return emitSourceFile(node); - } - } - - /** - * Emits a node in the IdentifierName EmitContext. - * - * NOTE: Do not call this method directly. It is part of the emit pipeline - * and should only be called indirectly from pipelineEmitForContext. - */ - function pipelineEmitInIdentifierNameContext(node: Node): void { - const kind = node.kind; - switch (kind) { - // Identifiers - case SyntaxKind.Identifier: - return emitIdentifier(node); - } - } - - /** - * Emits a node in the Unspecified EmitContext. - * - * NOTE: Do not call this method directly. It is part of the emit pipeline - * and should only be called indirectly from pipelineEmitForContext. - */ - function pipelineEmitInUnspecifiedContext(node: Node): void { - const kind = node.kind; switch (kind) { // Pseudo-literals case SyntaxKind.TemplateHead: @@ -314,46 +419,6 @@ namespace ts { case SyntaxKind.Identifier: return emitIdentifier(node); - // Reserved words - case SyntaxKind.ConstKeyword: - case SyntaxKind.DefaultKeyword: - case SyntaxKind.ExportKeyword: - case SyntaxKind.VoidKeyword: - - // Strict mode reserved words - case SyntaxKind.PrivateKeyword: - case SyntaxKind.ProtectedKeyword: - case SyntaxKind.PublicKeyword: - case SyntaxKind.StaticKeyword: - - // Contextual keywords - case SyntaxKind.AbstractKeyword: - case SyntaxKind.AsKeyword: - case SyntaxKind.AnyKeyword: - case SyntaxKind.AsyncKeyword: - case SyntaxKind.AwaitKeyword: - case SyntaxKind.BooleanKeyword: - case SyntaxKind.ConstructorKeyword: - case SyntaxKind.DeclareKeyword: - case SyntaxKind.GetKeyword: - case SyntaxKind.IsKeyword: - case SyntaxKind.ModuleKeyword: - case SyntaxKind.NamespaceKeyword: - case SyntaxKind.NeverKeyword: - case SyntaxKind.ReadonlyKeyword: - case SyntaxKind.RequireKeyword: - case SyntaxKind.NumberKeyword: - case SyntaxKind.SetKeyword: - case SyntaxKind.StringKeyword: - case SyntaxKind.SymbolKeyword: - case SyntaxKind.TypeKeyword: - case SyntaxKind.UndefinedKeyword: - case SyntaxKind.FromKeyword: - case SyntaxKind.GlobalKeyword: - case SyntaxKind.OfKeyword: - writeTokenText(kind); - return; - // Parse tree nodes // Names @@ -572,17 +637,11 @@ namespace ts { // If the node is an expression, try to emit it as an expression with // substitution. if (isExpression(node)) { - return pipelineEmitWithSubstitution(EmitContext.Expression, node); + return pipelineEmitWithSubstitution(EmitHint.Expression, node); } } - /** - * Emits a node in the Expression EmitContext. - * - * NOTE: Do not call this method directly. It is part of the emit pipeline - * and should only be called indirectly from pipelineEmitForContext. - */ - function pipelineEmitInExpressionContext(node: Node): void { + function pipelineEmitExpression(node: Node): void { const kind = node.kind; switch (kind) { // Literals @@ -675,6 +734,21 @@ namespace ts { } } + function emitBodyIndirect(node: Node, elements: NodeArray, emitCallback: (node: Node) => void): void { + if (emitBodyWithDetachedComments) { + emitBodyWithDetachedComments(node, elements, emitCallback); + } + else { + emitCallback(node); + } + } + + function emitHelpersIndirect(node: Node) { + if (onEmitHelpers) { + onEmitHelpers(node, writeLines); + } + } + // // Literals/Pseudo-literals // @@ -695,7 +769,7 @@ namespace ts { // SyntaxKind.TemplateTail function emitLiteral(node: LiteralLikeNode) { const text = getLiteralTextOfNode(node); - if ((compilerOptions.sourceMap || compilerOptions.inlineSourceMap) + if ((printerOptions.sourceMap || printerOptions.inlineSourceMap) && (node.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(node.kind))) { writer.writeLiteral(text); } @@ -934,17 +1008,13 @@ namespace ts { write("{"); writeLine(); increaseIndent(); - if (node.readonlyToken) { - write("readonly "); - } + writeIfPresent(node.readonlyToken, "readonly "); write("["); emit(node.typeParameter.name); write(" in "); emit(node.typeParameter.constraint); write("]"); - if (node.questionToken) { - write("?"); - } + writeIfPresent(node.questionToken, "?"); write(": "); emit(node.type); write(";"); @@ -1033,7 +1103,7 @@ namespace ts { let indentAfterDot = false; if (!(getEmitFlags(node) & EmitFlags.NoIndentation)) { const dotRangeStart = node.expression.end; - const dotRangeEnd = skipTrivia(currentText, node.expression.end) + 1; + const dotRangeEnd = skipTrivia(currentSourceFile.text, node.expression.end) + 1; const dotToken = { kind: SyntaxKind.DotToken, pos: dotRangeStart, end: dotRangeEnd }; indentBeforeDot = needsIndentation(node, node.expression, dotToken); indentAfterDot = needsIndentation(node, dotToken, node.name); @@ -1066,7 +1136,7 @@ namespace ts { // isFinite handles cases when constantValue is undefined return isFinite(constantValue) && Math.floor(constantValue) === constantValue - && compilerOptions.removeComments; + && printerOptions.removeComments; } } @@ -1097,12 +1167,9 @@ namespace ts { } function emitTypeAssertionExpression(node: TypeAssertion) { - if (node.type) { - write("<"); - emit(node.type); - write(">"); - } - + write("<"); + emit(node.type); + write(">"); emitExpression(node.expression); } @@ -1502,11 +1569,10 @@ namespace ts { emitBlockFunctionBody(body); } else { - const savedTempFlags = tempFlags; - tempFlags = 0; + pushNameGenerationScope(); emitSignatureHead(node); emitBlockFunctionBody(body); - tempFlags = savedTempFlags; + popNameGenerationScope(); } if (indentedFlag) { @@ -1574,10 +1640,11 @@ namespace ts { write(" {"); increaseIndent(); - emitBodyWithDetachedComments(body, body.statements, - shouldEmitBlockFunctionBodyOnSingleLine(body) - ? emitBlockFunctionBodyOnSingleLine - : emitBlockFunctionBodyWorker); + const emitBlockFunctionBody = shouldEmitBlockFunctionBodyOnSingleLine(body) + ? emitBlockFunctionBodyOnSingleLine + : emitBlockFunctionBodyWorker; + + emitBodyIndirect(body, body.statements, emitBlockFunctionBody); decreaseIndent(); writeToken(SyntaxKind.CloseBraceToken, body.statements.end, body); @@ -1590,9 +1657,9 @@ namespace ts { function emitBlockFunctionBodyWorker(body: Block, emitBlockFunctionBodyOnSingleLine?: boolean) { // Emit all the prologue directives (like "use strict"). const statementOffset = emitPrologueDirectives(body.statements, /*startWithNewLine*/ true); - const helpersEmitted = emitHelpers(body); - - if (statementOffset === 0 && !helpersEmitted && emitBlockFunctionBodyOnSingleLine) { + const pos = writer.getTextPos(); + emitHelpersIndirect(body); + if (statementOffset === 0 && pos === writer.getTextPos() && emitBlockFunctionBodyOnSingleLine) { decreaseIndent(); emitList(body, body.statements, ListFormat.SingleLineFunctionBodyStatements); increaseIndent(); @@ -1620,18 +1687,15 @@ namespace ts { emitTypeParameters(node, node.typeParameters); emitList(node, node.heritageClauses, ListFormat.ClassHeritageClauses); - const savedTempFlags = tempFlags; - tempFlags = 0; - + pushNameGenerationScope(); write(" {"); emitList(node, node.members, ListFormat.ClassMembers); write("}"); + popNameGenerationScope(); if (indentedFlag) { decreaseIndent(); } - - tempFlags = savedTempFlags; } function emitInterfaceDeclaration(node: InterfaceDeclaration) { @@ -1661,14 +1725,11 @@ namespace ts { emitModifiers(node, node.modifiers); write("enum "); emit(node.name); - - const savedTempFlags = tempFlags; - tempFlags = 0; - + pushNameGenerationScope(); write(" {"); emitList(node, node.members, ListFormat.EnumMembers); write("}"); - tempFlags = savedTempFlags; + popNameGenerationScope(); } function emitModuleDeclaration(node: ModuleDeclaration) { @@ -1692,13 +1753,12 @@ namespace ts { write("{ }"); } else { - const savedTempFlags = tempFlags; - tempFlags = 0; + pushNameGenerationScope(); write("{"); increaseIndent(); emitBlockStatements(node); write("}"); - tempFlags = savedTempFlags; + popNameGenerationScope(); } } @@ -1923,7 +1983,6 @@ namespace ts { } function emitCatchClause(node: CatchClause) { - writeLine(); const openParenPos = writeToken(SyntaxKind.CatchKeyword, node.pos); write(" "); writeToken(SyntaxKind.OpenParenToken, openParenPos); @@ -1948,11 +2007,10 @@ namespace ts { // "comment1" is not considered to be leading comment for node.initializer // but rather a trailing comment on the previous node. const initializer = node.initializer; - if ((getEmitFlags(initializer) & EmitFlags.NoLeadingComments) === 0) { + if (emitTrailingCommentsOfPosition && (getEmitFlags(initializer) & EmitFlags.NoLeadingComments) === 0) { const commentRange = getCommentRange(initializer); emitTrailingCommentsOfPosition(commentRange.pos); } - emitExpression(initializer); } @@ -1987,17 +2045,16 @@ namespace ts { function emitSourceFile(node: SourceFile) { writeLine(); emitShebang(); - emitBodyWithDetachedComments(node, node.statements, emitSourceFileWorker); + emitBodyIndirect(node, node.statements, emitSourceFileWorker); } function emitSourceFileWorker(node: SourceFile) { const statements = node.statements; const statementOffset = emitPrologueDirectives(statements); - const savedTempFlags = tempFlags; - tempFlags = 0; - emitHelpers(node); + pushNameGenerationScope(); + emitHelpersIndirect(node); emitList(node, statements, ListFormat.MultiLine, statementOffset); - tempFlags = savedTempFlags; + popNameGenerationScope(); } // Transformation nodes @@ -2027,83 +2084,12 @@ namespace ts { return statements.length; } - function emitHelpers(node: Node, isBundle?: boolean) { - const sourceFile = isSourceFile(node) ? node : currentSourceFile; - const shouldSkip = compilerOptions.noEmitHelpers || (sourceFile && getExternalHelpersModuleName(sourceFile) !== undefined); - const shouldBundle = isSourceFile(node) && !isOwnFileEmit; - - let helpersEmitted = false; - const helpers = getEmitHelpers(node); - if (helpers) { - for (const helper of stableSort(helpers, compareEmitHelpers)) { - if (!helper.scoped) { - // Skip the helper if it can be skipped and the noEmitHelpers compiler - // option is set, or if it can be imported and the importHelpers compiler - // option is set. - if (shouldSkip) continue; - - // Skip the helper if it can be bundled but hasn't already been emitted and we - // are emitting a bundled module. - if (shouldBundle) { - if (bundledHelpers.get(helper.name)) { - continue; - } - - bundledHelpers.set(helper.name, true); - } - } - else if (isBundle) { - // Skip the helper if it is scoped and we are emitting bundled helpers - continue; - } - - writeLines(helper.text); - helpersEmitted = true; - } - } - - if (helpersEmitted) { - writeLine(); - } - - return helpersEmitted; - } - - function writeLines(text: string): void { - const lines = text.split(/\r\n?|\n/g); - const indentation = guessIndentation(lines); - for (let i = 0; i < lines.length; i++) { - const line = indentation ? lines[i].slice(indentation) : lines[i]; - if (line.length) { - if (i > 0) { - writeLine(); - } - write(line); - } - } - } - - function guessIndentation(lines: string[]) { - let indentation: number; - for (const line of lines) { - for (let i = 0; i < line.length && (indentation === undefined || i < indentation); i++) { - if (!isWhiteSpace(line.charCodeAt(i))) { - if (indentation === undefined || i < indentation) { - indentation = i; - break; - } - } - } - } - return indentation; - } - // // Helpers // function emitShebang() { - const shebang = getShebang(currentText); + const shebang = getShebang(currentSourceFile.text); if (shebang) { write(shebang); writeLine(); @@ -2261,15 +2247,17 @@ namespace ts { } } + // Emit this child. if (shouldEmitInterveningComments) { - const commentRange = getCommentRange(child); - emitTrailingCommentsOfPosition(commentRange.pos); + if (emitTrailingCommentsOfPosition) { + const commentRange = getCommentRange(child); + emitTrailingCommentsOfPosition(commentRange.pos); + } } else { shouldEmitInterveningComments = mayEmitInterveningComments; } - // Emit this child. emit(child); if (shouldDecreaseIndentAfterEmit) { @@ -2305,6 +2293,46 @@ namespace ts { } } + function write(s: string) { + writer.write(s); + } + + function writeLine() { + writer.writeLine(); + } + + function increaseIndent() { + writer.increaseIndent(); + } + + function decreaseIndent() { + writer.decreaseIndent(); + } + + function writeIfAny(nodes: NodeArray, text: string) { + if (some(nodes)) { + write(text); + } + } + + function writeIfPresent(node: Node, text: string) { + if (node) { + write(text); + } + } + + function writeToken(token: SyntaxKind, pos: number, contextNode?: Node) { + return onEmitSourceMapOfToken + ? onEmitSourceMapOfToken(contextNode, token, pos, writeTokenText) + : writeTokenText(token, pos); + } + + function writeTokenText(token: SyntaxKind, pos?: number) { + const tokenString = tokenToString(token); + write(tokenString); + return pos < 0 ? pos : pos + tokenString.length; + } + function writeLineOrSpace(node: Node) { if (getEmitFlags(node) & EmitFlags.SingleLine) { write(" "); @@ -2314,26 +2342,32 @@ namespace ts { } } - function writeIfAny(nodes: NodeArray, text: string) { - if (nodes && nodes.length > 0) { - write(text); + function writeLines(text: string): void { + const lines = text.split(/\r\n?|\n/g); + const indentation = guessIndentation(lines); + for (let i = 0; i < lines.length; i++) { + const line = indentation ? lines[i].slice(indentation) : lines[i]; + if (line.length) { + writeLine(); + write(line); + writeLine(); + } } } - function writeIfPresent(node: Node, text: string) { - if (node !== undefined) { - write(text); + function guessIndentation(lines: string[]) { + let indentation: number; + for (const line of lines) { + for (let i = 0; i < line.length && (indentation === undefined || i < indentation); i++) { + if (!isWhiteSpace(line.charCodeAt(i))) { + if (indentation === undefined || i < indentation) { + indentation = i; + break; + } + } + } } - } - - function writeToken(token: SyntaxKind, pos: number, contextNode?: Node) { - return emitTokenWithSourceMap(contextNode, token, pos, writeTokenText); - } - - function writeTokenText(token: SyntaxKind, pos?: number) { - const tokenString = tokenToString(token); - write(tokenString); - return pos < 0 ? pos : pos + tokenString.length; + return indentation; } function increaseIndentIf(value: boolean, valueToWriteWhenNotIndenting?: string) { @@ -2459,6 +2493,16 @@ namespace ts { && !rangeEndIsOnSameLineAsRangeStart(node1, node2, currentSourceFile); } + function isSingleLineEmptyBlock(block: Block) { + return !block.multiLine + && isEmptyBlock(block); + } + + function isEmptyBlock(block: BlockLike) { + return block.statements.length === 0 + && rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile); + } + function skipSynthesizedParentheses(node: Node) { while (node.kind === SyntaxKind.ParenthesizedExpression && nodeIsSynthesized(node)) { node = (node).expression; @@ -2469,7 +2513,7 @@ namespace ts { function getTextOfNode(node: Node, includeTrivia?: boolean): string { if (isGeneratedIdentifier(node)) { - return getGeneratedIdentifier(node); + return generateName(node); } else if (isIdentifier(node) && (nodeIsSynthesized(node) || !node.parent)) { return unescapeIdentifier(node.text); @@ -2498,22 +2542,57 @@ namespace ts { return getLiteralText(node, currentSourceFile, languageVersion); } - function isSingleLineEmptyBlock(block: Block) { - return !block.multiLine - && isEmptyBlock(block); + /** + * Push a new name generation scope. + */ + function pushNameGenerationScope() { + tempFlagsStack.push(tempFlags); + tempFlags = 0; } - function isEmptyBlock(block: BlockLike) { - return block.statements.length === 0 - && rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile); + /** + * Pop the current name generation scope. + */ + function popNameGenerationScope() { + tempFlags = tempFlagsStack.pop(); } + /** + * Generate the text for a generated identifier. + */ + function generateName(name: GeneratedIdentifier) { + if (name.autoGenerateKind === GeneratedIdentifierKind.Node) { + // Node names generate unique names based on their original node + // and are cached based on that node's id. + const node = getNodeForGeneratedName(name); + return generateNameCached(node); + } + else { + // Auto, Loop, and Unique names are cached based on their unique + // autoGenerateId. + const autoGenerateId = name.autoGenerateId; + return autoGeneratedIdToGeneratedName[autoGenerateId] || (autoGeneratedIdToGeneratedName[autoGenerateId] = unescapeIdentifier(makeName(name))); + } + } + + function generateNameCached(node: Node) { + const nodeId = getNodeId(node); + return nodeIdToGeneratedName[nodeId] || (nodeIdToGeneratedName[nodeId] = unescapeIdentifier(generateNameForNode(node))); + } + + /** + * Returns a value indicating whether a name is unique globally, within the current file, + * or within the NameGenerator. + */ function isUniqueName(name: string): boolean { - return !resolver.hasGlobalName(name) && - !currentFileIdentifiers.has(name) && - !generatedNameSet.has(name); + return !(hasGlobalName && hasGlobalName(name)) + && !currentSourceFile.identifiers.has(name) + && !generatedNames.has(name); } + /** + * Returns a value indicating whether a name is unique within a container. + */ function isUniqueLocalName(name: string, container: Node): boolean { for (let node = container; isNodeDescendantOf(node, container); node = node.nextContainer) { if (node.locals) { @@ -2528,10 +2607,10 @@ namespace ts { } /** - * Return the next available name in the pattern _a ... _z, _0, _1, ... - * TempFlags._i or TempFlags._n may be used to express a preference for that dedicated name. - * Note that names generated by makeTempVariableName and makeUniqueName will never conflict. - */ + * Return the next available name in the pattern _a ... _z, _0, _1, ... + * TempFlags._i or TempFlags._n may be used to express a preference for that dedicated name. + * Note that names generated by makeTempVariableName and makeUniqueName will never conflict. + */ function makeTempVariableName(flags: TempFlags): string { if (flags && !(tempFlags & flags)) { const name = flags === TempFlags._i ? "_i" : "_n"; @@ -2555,10 +2634,12 @@ namespace ts { } } - // Generate a name that is unique within the current file and doesn't conflict with any names - // in global scope. The name is formed by adding an '_n' suffix to the specified base name, - // where n is a positive integer. Note that names generated by makeTempVariableName and - // makeUniqueName are guaranteed to never conflict. + /** + * Generate a name that is unique within the current file and doesn't conflict with any names + * in global scope. The name is formed by adding an '_n' suffix to the specified base name, + * where n is a positive integer. Note that names generated by makeTempVariableName and + * makeUniqueName are guaranteed to never conflict. + */ function makeUniqueName(baseName: string): string { // Find the first unique 'name_n', where n is a positive number if (baseName.charCodeAt(baseName.length - 1) !== CharacterCodes._) { @@ -2568,19 +2649,25 @@ namespace ts { while (true) { const generatedName = baseName + i; if (isUniqueName(generatedName)) { - generatedNameSet.set(generatedName, generatedName); + generatedNames.set(generatedName, generatedName); return generatedName; } i++; } } + /** + * Generates a unique name for a ModuleDeclaration or EnumDeclaration. + */ function generateNameForModuleOrEnum(node: ModuleDeclaration | EnumDeclaration) { const name = getTextOfNode(node.name); // Use module/enum name itself if it is unique, otherwise make a unique variation return isUniqueLocalName(name, node) ? name : makeUniqueName(name); } + /** + * Generates a unique name for an ImportDeclaration or ExportDeclaration. + */ function generateNameForImportOrExportDeclaration(node: ImportDeclaration | ExportDeclaration) { const expr = getExternalModuleName(node); const baseName = expr.kind === SyntaxKind.StringLiteral ? @@ -2588,25 +2675,29 @@ namespace ts { return makeUniqueName(baseName); } + /** + * Generates a unique name for a default export. + */ function generateNameForExportDefault() { return makeUniqueName("default"); } + /** + * Generates a unique name for a class expression. + */ function generateNameForClassExpression() { return makeUniqueName("class"); } function generateNameForMethodOrAccessor(node: MethodDeclaration | AccessorDeclaration) { if (isIdentifier(node.name)) { - return generateNameForNodeCached(node.name); + return generateNameCached(node.name); } return makeTempVariableName(TempFlags.Auto); } /** * Generates a unique name from a node. - * - * @param node A node. */ function generateNameForNode(node: Node): string { switch (node.kind) { @@ -2635,17 +2726,15 @@ namespace ts { /** * Generates a unique identifier for a node. - * - * @param name A generated name. */ - function generateName(name: Identifier) { + function makeName(name: GeneratedIdentifier) { switch (name.autoGenerateKind) { case GeneratedIdentifierKind.Auto: return makeTempVariableName(TempFlags.Auto); case GeneratedIdentifierKind.Loop: return makeTempVariableName(TempFlags._i); case GeneratedIdentifierKind.Unique: - return makeUniqueName(name.text); + return makeUniqueName(unescapeIdentifier(name.text)); } Debug.fail("Unsupported GeneratedIdentifierKind."); @@ -2653,10 +2742,8 @@ namespace ts { /** * Gets the node from which a name should be generated. - * - * @param name A generated name wrapper. */ - function getNodeForGeneratedName(name: Identifier) { + function getNodeForGeneratedName(name: GeneratedIdentifier) { const autoGenerateId = name.autoGenerateId; let node = name as Node; let original = node.original; @@ -2677,61 +2764,43 @@ namespace ts { // otherwise, return the original node for the source; return node; } + } - function generateNameForNodeCached(node: Node) { - const nodeId = getNodeId(node); - return nodeIdToGeneratedName[nodeId] || (nodeIdToGeneratedName[nodeId] = unescapeIdentifier(generateNameForNode(node))); - } + function createDelimiterMap() { + const delimiters: string[] = []; + delimiters[ListFormat.None] = ""; + delimiters[ListFormat.CommaDelimited] = ","; + delimiters[ListFormat.BarDelimited] = " |"; + delimiters[ListFormat.AmpersandDelimited] = " &"; + return delimiters; + } - /** - * Gets the generated identifier text from a generated identifier. - * - * @param name The generated identifier. - */ - function getGeneratedIdentifier(name: Identifier) { - if (name.autoGenerateKind === GeneratedIdentifierKind.Node) { - // Generated names generate unique names based on their original node - // and are cached based on that node's id - const node = getNodeForGeneratedName(name); - return generateNameForNodeCached(node); - } - else { - // Auto, Loop, and Unique names are cached based on their unique - // autoGenerateId. - const autoGenerateId = name.autoGenerateId; - return autoGeneratedIdToGeneratedName[autoGenerateId] || (autoGeneratedIdToGeneratedName[autoGenerateId] = unescapeIdentifier(generateName(name))); - } - } + function getDelimiter(format: ListFormat) { + return delimiters[format & ListFormat.DelimitersMask]; + } - function createDelimiterMap() { - const delimiters: string[] = []; - delimiters[ListFormat.None] = ""; - delimiters[ListFormat.CommaDelimited] = ","; - delimiters[ListFormat.BarDelimited] = " |"; - delimiters[ListFormat.AmpersandDelimited] = " &"; - return delimiters; - } + function createBracketsMap() { + const brackets: string[][] = []; + brackets[ListFormat.Braces] = ["{", "}"]; + brackets[ListFormat.Parenthesis] = ["(", ")"]; + brackets[ListFormat.AngleBrackets] = ["<", ">"]; + brackets[ListFormat.SquareBrackets] = ["[", "]"]; + return brackets; + } - function getDelimiter(format: ListFormat) { - return delimiters[format & ListFormat.DelimitersMask]; - } + function getOpeningBracket(format: ListFormat) { + return brackets[format & ListFormat.BracketsMask][0]; + } - function createBracketsMap() { - const brackets: string[][] = []; - brackets[ListFormat.Braces] = ["{", "}"]; - brackets[ListFormat.Parenthesis] = ["(", ")"]; - brackets[ListFormat.AngleBrackets] = ["<", ">"]; - brackets[ListFormat.SquareBrackets] = ["[", "]"]; - return brackets; - } + function getClosingBracket(format: ListFormat) { + return brackets[format & ListFormat.BracketsMask][1]; + } - function getOpeningBracket(format: ListFormat) { - return brackets[format & ListFormat.BracketsMask][0]; - } - - function getClosingBracket(format: ListFormat) { - return brackets[format & ListFormat.BracketsMask][1]; - } + // Flags enum to track count of temp variables and a few dedicated names + const enum TempFlags { + Auto = 0x00000000, // No preferred name + CountMask = 0x0FFFFFFF, // Temp variable counter + _i = 0x10000000, // Use/preference flag for '_i' } const enum ListFormat { @@ -2758,7 +2827,7 @@ namespace ts { SpaceBetweenSiblings = 1 << 8, // Inserts a space between each sibling node. // Brackets/Braces - Braces = 1 << 9, // The list is surrounded by "{" and "}". + Braces = 1 << 9, // The list is surrounded by "{" and "}". Parenthesis = 1 << 10, // The list is surrounded by "(" and ")". AngleBrackets = 1 << 11, // The list is surrounded by "<" and ">". SquareBrackets = 1 << 12, // The list is surrounded by "[" and "]". @@ -2809,4 +2878,4 @@ namespace ts { Parameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented | Parenthesis, IndexSignatureParameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented | SquareBrackets, } -} +} \ No newline at end of file diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index f63094ae16d..d5d8482a0ba 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1,28 +1,18 @@ /// /// -/* @internal */ namespace ts { - let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; - let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; - - function createNode(kind: SyntaxKind, location?: TextRange, flags?: NodeFlags): Node { - const ConstructorForKind = kind === SyntaxKind.SourceFile - ? (SourceFileConstructor || (SourceFileConstructor = objectAllocator.getSourceFileConstructor())) - : (NodeConstructor || (NodeConstructor = objectAllocator.getNodeConstructor())); - - const node = location - ? new ConstructorForKind(kind, location.pos, location.end) - : new ConstructorForKind(kind, /*pos*/ -1, /*end*/ -1); - - node.flags = flags | NodeFlags.Synthesized; - + function createSynthesizedNode(kind: SyntaxKind): Node { + const node = createNode(kind, -1, -1); + node.flags |= NodeFlags.Synthesized; return node; } + /* @internal */ export function updateNode(updated: T, original: T): T { if (updated !== original) { setOriginalNode(updated, original); + setTextRange(updated, original); if (original.startsOnNewLine) { updated.startsOnNewLine = true; } @@ -31,7 +21,10 @@ namespace ts { return updated; } - export function createNodeArray(elements?: T[], location?: TextRange, hasTrailingComma?: boolean): NodeArray { + /** + * Make `elements` into a `NodeArray`. If `elements` is `undefined`, returns an empty `NodeArray`. + */ + export function createNodeArray(elements?: T[], hasTrailingComma?: boolean): NodeArray { if (elements) { if (isNodeArray(elements)) { return elements; @@ -42,40 +35,22 @@ namespace ts { } const array = >elements; - if (location) { - array.pos = location.pos; - array.end = location.end; - } - else { - array.pos = -1; - array.end = -1; - } - - if (hasTrailingComma) { - array.hasTrailingComma = true; - } - + array.pos = -1; + array.end = -1; + array.hasTrailingComma = hasTrailingComma; return array; } - export function createSynthesizedNode(kind: SyntaxKind, startsOnNewLine?: boolean): Node { - const node = createNode(kind, /*location*/ undefined); - node.startsOnNewLine = startsOnNewLine; - return node; - } - - export function createSynthesizedNodeArray(elements?: T[]): NodeArray { - return createNodeArray(elements, /*location*/ undefined); - } - /** * Creates a shallow, memberwise clone of a node with no source map location. */ + /* @internal */ export function getSynthesizedClone(node: T): T { // We don't use "clone" from core.ts here, as we need to preserve the prototype chain of // the original node. We also need to exclude specific properties and only include own- // properties (to skip members already defined on the shared prototype). - const clone = createNode(node.kind, /*location*/ undefined, node.flags); + const clone = createSynthesizedNode(node.kind); + clone.flags |= node.flags; setOriginalNode(clone, node); for (const key in node) { @@ -89,63 +64,62 @@ namespace ts { return clone; } - /** - * Creates a shallow, memberwise clone of a node for mutation. - */ - export function getMutableClone(node: T): T { - const clone = getSynthesizedClone(node); - clone.pos = node.pos; - clone.end = node.end; - clone.parent = node.parent; - return clone; - } - // Literals - export function createLiteral(textSource: StringLiteral | NumericLiteral | Identifier, location?: TextRange): StringLiteral; - export function createLiteral(value: string, location?: TextRange): StringLiteral; - export function createLiteral(value: number, location?: TextRange): NumericLiteral; - export function createLiteral(value: boolean, location?: TextRange): BooleanLiteral; - export function createLiteral(value: string | number | boolean, location?: TextRange): PrimaryExpression; - export function createLiteral(value: string | number | boolean | StringLiteral | NumericLiteral | Identifier, location?: TextRange): PrimaryExpression { + export function createLiteral(value: string): StringLiteral; + export function createLiteral(value: number): NumericLiteral; + export function createLiteral(value: boolean): BooleanLiteral; + /** Create a string literal whose source text is read from a source node during emit. */ + export function createLiteral(sourceNode: StringLiteral | NumericLiteral | Identifier): StringLiteral; + export function createLiteral(value: string | number | boolean): PrimaryExpression; + export function createLiteral(value: string | number | boolean | StringLiteral | NumericLiteral | Identifier): PrimaryExpression { if (typeof value === "number") { - const node = createNode(SyntaxKind.NumericLiteral, location, /*flags*/ undefined); - node.text = value.toString(); - return node; + return createNumericLiteral(value + ""); } - else if (typeof value === "boolean") { - return createNode(value ? SyntaxKind.TrueKeyword : SyntaxKind.FalseKeyword, location, /*flags*/ undefined); + if (typeof value === "boolean") { + return value ? createTrue() : createFalse(); } - else if (typeof value === "string") { - const node = createNode(SyntaxKind.StringLiteral, location, /*flags*/ undefined); - node.text = value; - return node; - } - else if (value) { - const node = createNode(SyntaxKind.StringLiteral, location, /*flags*/ undefined); - node.textSourceNode = value; - node.text = value.text; - return node; + if (typeof value === "string") { + return createStringLiteral(value); } + return createLiteralFromNode(value); } + export function createNumericLiteral(value: string): NumericLiteral { + const node = createSynthesizedNode(SyntaxKind.NumericLiteral); + node.text = value; + return node; + } + + function createStringLiteral(text: string): StringLiteral { + const node = createSynthesizedNode(SyntaxKind.StringLiteral); + node.text = text; + return node; + } + + function createLiteralFromNode(sourceNode: StringLiteral | NumericLiteral | Identifier): StringLiteral { + const node = createStringLiteral(sourceNode.text); + node.textSourceNode = sourceNode; + return node; + } + + // Identifiers - let nextAutoGenerateId = 0; - - export function createIdentifier(text: string, location?: TextRange): Identifier { - const node = createNode(SyntaxKind.Identifier, location); + export function createIdentifier(text: string): Identifier { + const node = createSynthesizedNode(SyntaxKind.Identifier); node.text = escapeIdentifier(text); - node.originalKeywordKind = stringToToken(text); + node.originalKeywordKind = text ? stringToToken(text) : SyntaxKind.Unknown; node.autoGenerateKind = GeneratedIdentifierKind.None; node.autoGenerateId = 0; return node; } - export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined, location?: TextRange): Identifier { - const name = createNode(SyntaxKind.Identifier, location); - name.text = ""; - name.originalKeywordKind = SyntaxKind.Unknown; + let nextAutoGenerateId = 0; + + /** Create a unique temporary variable. */ + export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined): Identifier { + const name = createIdentifier(""); name.autoGenerateKind = GeneratedIdentifierKind.Auto; name.autoGenerateId = nextAutoGenerateId; nextAutoGenerateId++; @@ -155,33 +129,30 @@ namespace ts { return name; } - export function createLoopVariable(location?: TextRange): Identifier { - const name = createNode(SyntaxKind.Identifier, location); - name.text = ""; - name.originalKeywordKind = SyntaxKind.Unknown; + /** Create a unique temporary variable for use in a loop. */ + export function createLoopVariable(): Identifier { + const name = createIdentifier(""); name.autoGenerateKind = GeneratedIdentifierKind.Loop; name.autoGenerateId = nextAutoGenerateId; nextAutoGenerateId++; return name; } - export function createUniqueName(text: string, location?: TextRange): Identifier { - const name = createNode(SyntaxKind.Identifier, location); - name.text = text; - name.originalKeywordKind = SyntaxKind.Unknown; + /** Create a unique name based on the supplied text. */ + export function createUniqueName(text: string): Identifier { + const name = createIdentifier(text); name.autoGenerateKind = GeneratedIdentifierKind.Unique; name.autoGenerateId = nextAutoGenerateId; nextAutoGenerateId++; return name; } - export function getGeneratedNameForNode(node: Node, location?: TextRange): Identifier { - const name = createNode(SyntaxKind.Identifier, location); - name.original = node; - name.text = ""; - name.originalKeywordKind = SyntaxKind.Unknown; + /** Create a unique name generated for a node. */ + export function getGeneratedNameForNode(node: Node): Identifier { + const name = createIdentifier(""); name.autoGenerateKind = GeneratedIdentifierKind.Node; name.autoGenerateId = nextAutoGenerateId; + name.original = node; nextAutoGenerateId++; return name; } @@ -189,49 +160,67 @@ namespace ts { // Punctuation export function createToken(token: TKind) { - return >createNode(token); + return >createSynthesizedNode(token); } // Reserved words export function createSuper() { - const node = createNode(SyntaxKind.SuperKeyword); - return node; + return createSynthesizedNode(SyntaxKind.SuperKeyword); } - export function createThis(location?: TextRange) { - const node = createNode(SyntaxKind.ThisKeyword, location); - return node; + export function createThis() { + return createSynthesizedNode(SyntaxKind.ThisKeyword); } export function createNull() { - const node = createNode(SyntaxKind.NullKeyword); - return node; + return createSynthesizedNode(SyntaxKind.NullKeyword); + } + + export function createTrue() { + return createSynthesizedNode(SyntaxKind.TrueKeyword); + } + + export function createFalse() { + return createSynthesizedNode(SyntaxKind.FalseKeyword); } // Names - export function createComputedPropertyName(expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.ComputedPropertyName, location); + export function createQualifiedName(left: EntityName, right: string | Identifier) { + const node = createSynthesizedNode(SyntaxKind.QualifiedName); + node.left = left; + node.right = asName(right); + return node; + } + + export function updateQualifiedName(node: QualifiedName, left: EntityName, right: Identifier) { + return node.left !== left + || node.right !== right + ? updateNode(createQualifiedName(left, right), node) + : node; + } + + export function createComputedPropertyName(expression: Expression) { + const node = createSynthesizedNode(SyntaxKind.ComputedPropertyName); node.expression = expression; return node; } export function updateComputedPropertyName(node: ComputedPropertyName, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createComputedPropertyName(expression, node), node); - } - return node; + return node.expression !== expression + ? updateNode(createComputedPropertyName(expression), node) + : node; } // Signature elements - export function createParameter(decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: DotDotDotToken, name: string | Identifier | BindingPattern, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression, location?: TextRange, flags?: NodeFlags) { - const node = createNode(SyntaxKind.Parameter, location, flags); - node.decorators = decorators ? createNodeArray(decorators) : undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + export function createParameter(decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: DotDotDotToken, name: string | Identifier | BindingPattern, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression) { + const node = createSynthesizedNode(SyntaxKind.Parameter); + node.decorators = asNodeArray(decorators); + node.modifiers = asNodeArray(modifiers); node.dotDotDotToken = dotDotDotToken; - node.name = typeof name === "string" ? createIdentifier(name) : name; + node.name = asName(name); node.questionToken = questionToken; node.type = type; node.initializer = initializer ? parenthesizeExpressionForList(initializer) : undefined; @@ -239,20 +228,35 @@ namespace ts { } export function updateParameter(node: ParameterDeclaration, decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: DotDotDotToken, name: BindingName, type: TypeNode, initializer: Expression) { - if (node.decorators !== decorators || node.modifiers !== modifiers || node.dotDotDotToken !== dotDotDotToken || node.name !== name || node.type !== type || node.initializer !== initializer) { - return updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, node.questionToken, type, initializer, /*location*/ node, /*flags*/ node.flags), node); - } + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.dotDotDotToken !== dotDotDotToken + || node.name !== name + || node.type !== type + || node.initializer !== initializer + ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, node.questionToken, type, initializer), node) + : node; + } + export function createDecorator(expression: Expression) { + const node = createSynthesizedNode(SyntaxKind.Decorator); + node.expression = parenthesizeForAccess(expression); return node; } + export function updateDecorator(node: Decorator, expression: Expression) { + return node.expression !== expression + ? updateNode(createDecorator(expression), node) + : node; + } + // Type members - export function createProperty(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, questionToken: QuestionToken, type: TypeNode, initializer: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.PropertyDeclaration, location); - node.decorators = decorators ? createNodeArray(decorators) : undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; - node.name = typeof name === "string" ? createIdentifier(name) : name; + export function createProperty(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, questionToken: QuestionToken, type: TypeNode, initializer: Expression) { + const node = createSynthesizedNode(SyntaxKind.PropertyDeclaration); + node.decorators = asNodeArray(decorators); + node.modifiers = asNodeArray(modifiers); + node.name = asName(name); node.questionToken = questionToken; node.type = type; node.initializer = initializer; @@ -260,19 +264,22 @@ namespace ts { } export function updateProperty(node: PropertyDeclaration, decorators: Decorator[], modifiers: Modifier[], name: PropertyName, type: TypeNode, initializer: Expression) { - if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.type !== type || node.initializer !== initializer) { - return updateNode(createProperty(decorators, modifiers, name, node.questionToken, type, initializer, node), node); - } - return node; + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.name !== name + || node.type !== type + || node.initializer !== initializer + ? updateNode(createProperty(decorators, modifiers, name, node.questionToken, type, initializer), node) + : node; } - export function createMethod(decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) { - const node = createNode(SyntaxKind.MethodDeclaration, location, flags); - node.decorators = decorators ? createNodeArray(decorators) : undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + export function createMethod(decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) { + const node = createSynthesizedNode(SyntaxKind.MethodDeclaration); + node.decorators = asNodeArray(decorators); + node.modifiers = asNodeArray(modifiers); node.asteriskToken = asteriskToken; - node.name = typeof name === "string" ? createIdentifier(name) : name; - node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined; + node.name = asName(name); + node.typeParameters = asNodeArray(typeParameters); node.parameters = createNodeArray(parameters); node.type = type; node.body = body; @@ -280,16 +287,21 @@ namespace ts { } export function updateMethod(node: MethodDeclaration, decorators: Decorator[], modifiers: Modifier[], name: PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) { - if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body) { - return updateNode(createMethod(decorators, modifiers, node.asteriskToken, name, typeParameters, parameters, type, body, /*location*/ node, node.flags), node); - } - return node; + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.name !== name + || node.typeParameters !== typeParameters + || node.parameters !== parameters + || node.type !== type + || node.body !== body + ? updateNode(createMethod(decorators, modifiers, node.asteriskToken, name, typeParameters, parameters, type, body), node) + : node; } - export function createConstructor(decorators: Decorator[], modifiers: Modifier[], parameters: ParameterDeclaration[], body: Block, location?: TextRange, flags?: NodeFlags) { - const node = createNode(SyntaxKind.Constructor, location, flags); - node.decorators = decorators ? createNodeArray(decorators) : undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + export function createConstructor(decorators: Decorator[], modifiers: Modifier[], parameters: ParameterDeclaration[], body: Block) { + const node = createSynthesizedNode(SyntaxKind.Constructor); + node.decorators = asNodeArray(decorators); + node.modifiers = asNodeArray(modifiers); node.typeParameters = undefined; node.parameters = createNodeArray(parameters); node.type = undefined; @@ -298,17 +310,19 @@ namespace ts { } export function updateConstructor(node: ConstructorDeclaration, decorators: Decorator[], modifiers: Modifier[], parameters: ParameterDeclaration[], body: Block) { - if (node.decorators !== decorators || node.modifiers !== modifiers || node.parameters !== parameters || node.body !== body) { - return updateNode(createConstructor(decorators, modifiers, parameters, body, /*location*/ node, node.flags), node); - } - return node; + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.parameters !== parameters + || node.body !== body + ? updateNode(createConstructor(decorators, modifiers, parameters, body), node) + : node; } - export function createGetAccessor(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) { - const node = createNode(SyntaxKind.GetAccessor, location, flags); - node.decorators = decorators ? createNodeArray(decorators) : undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; - node.name = typeof name === "string" ? createIdentifier(name) : name; + export function createGetAccessor(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, parameters: ParameterDeclaration[], type: TypeNode, body: Block) { + const node = createSynthesizedNode(SyntaxKind.GetAccessor); + node.decorators = asNodeArray(decorators); + node.modifiers = asNodeArray(modifiers); + node.name = asName(name); node.typeParameters = undefined; node.parameters = createNodeArray(parameters); node.type = type; @@ -317,17 +331,21 @@ namespace ts { } export function updateGetAccessor(node: GetAccessorDeclaration, decorators: Decorator[], modifiers: Modifier[], name: PropertyName, parameters: ParameterDeclaration[], type: TypeNode, body: Block) { - if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.parameters !== parameters || node.type !== type || node.body !== body) { - return updateNode(createGetAccessor(decorators, modifiers, name, parameters, type, body, /*location*/ node, node.flags), node); - } - return node; + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.name !== name + || node.parameters !== parameters + || node.type !== type + || node.body !== body + ? updateNode(createGetAccessor(decorators, modifiers, name, parameters, type, body), node) + : node; } - export function createSetAccessor(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, parameters: ParameterDeclaration[], body: Block, location?: TextRange, flags?: NodeFlags) { - const node = createNode(SyntaxKind.SetAccessor, location, flags); - node.decorators = decorators ? createNodeArray(decorators) : undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; - node.name = typeof name === "string" ? createIdentifier(name) : name; + export function createSetAccessor(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, parameters: ParameterDeclaration[], body: Block) { + const node = createSynthesizedNode(SyntaxKind.SetAccessor); + node.decorators = asNodeArray(decorators); + node.modifiers = asNodeArray(modifiers); + node.name = asName(name); node.typeParameters = undefined; node.parameters = createNodeArray(parameters); node.body = body; @@ -335,60 +353,63 @@ namespace ts { } export function updateSetAccessor(node: SetAccessorDeclaration, decorators: Decorator[], modifiers: Modifier[], name: PropertyName, parameters: ParameterDeclaration[], body: Block) { - if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.parameters !== parameters || node.body !== body) { - return updateNode(createSetAccessor(decorators, modifiers, name, parameters, body, /*location*/ node, node.flags), node); - } - return node; + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.name !== name + || node.parameters !== parameters + || node.body !== body + ? updateNode(createSetAccessor(decorators, modifiers, name, parameters, body), node) + : node; } // Binding Patterns - export function createObjectBindingPattern(elements: BindingElement[], location?: TextRange) { - const node = createNode(SyntaxKind.ObjectBindingPattern, location); + export function createObjectBindingPattern(elements: BindingElement[]) { + const node = createSynthesizedNode(SyntaxKind.ObjectBindingPattern); node.elements = createNodeArray(elements); return node; } export function updateObjectBindingPattern(node: ObjectBindingPattern, elements: BindingElement[]) { - if (node.elements !== elements) { - return updateNode(createObjectBindingPattern(elements, node), node); - } - return node; + return node.elements !== elements + ? updateNode(createObjectBindingPattern(elements), node) + : node; } - export function createArrayBindingPattern(elements: ArrayBindingElement[], location?: TextRange) { - const node = createNode(SyntaxKind.ArrayBindingPattern, location); + export function createArrayBindingPattern(elements: ArrayBindingElement[]) { + const node = createSynthesizedNode(SyntaxKind.ArrayBindingPattern); node.elements = createNodeArray(elements); return node; } export function updateArrayBindingPattern(node: ArrayBindingPattern, elements: ArrayBindingElement[]) { - if (node.elements !== elements) { - return updateNode(createArrayBindingPattern(elements, node), node); - } - return node; + return node.elements !== elements + ? updateNode(createArrayBindingPattern(elements), node) + : node; } - export function createBindingElement(propertyName: string | PropertyName, dotDotDotToken: DotDotDotToken, name: string | BindingName, initializer?: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.BindingElement, location); - node.propertyName = typeof propertyName === "string" ? createIdentifier(propertyName) : propertyName; + export function createBindingElement(propertyName: string | PropertyName, dotDotDotToken: DotDotDotToken, name: string | BindingName, initializer?: Expression) { + const node = createSynthesizedNode(SyntaxKind.BindingElement); + node.propertyName = asName(propertyName); node.dotDotDotToken = dotDotDotToken; - node.name = typeof name === "string" ? createIdentifier(name) : name; + node.name = asName(name); node.initializer = initializer; return node; } export function updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken, propertyName: PropertyName, name: BindingName, initializer: Expression) { - if (node.propertyName !== propertyName || node.dotDotDotToken !== dotDotDotToken || node.name !== name || node.initializer !== initializer) { - return updateNode(createBindingElement(propertyName, dotDotDotToken, name, initializer, node), node); - } - return node; + return node.propertyName !== propertyName + || node.dotDotDotToken !== dotDotDotToken + || node.name !== name + || node.initializer !== initializer + ? updateNode(createBindingElement(propertyName, dotDotDotToken, name, initializer), node) + : node; } // Expression - export function createArrayLiteral(elements?: Expression[], location?: TextRange, multiLine?: boolean) { - const node = createNode(SyntaxKind.ArrayLiteralExpression, location); + export function createArrayLiteral(elements?: Expression[], multiLine?: boolean) { + const node = createSynthesizedNode(SyntaxKind.ArrayLiteralExpression); node.elements = parenthesizeListElements(createNodeArray(elements)); if (multiLine) { node.multiLine = true; @@ -398,14 +419,13 @@ namespace ts { } export function updateArrayLiteral(node: ArrayLiteralExpression, elements: Expression[]) { - if (node.elements !== elements) { - return updateNode(createArrayLiteral(elements, node, node.multiLine), node); - } - return node; + return node.elements !== elements + ? updateNode(createArrayLiteral(elements, node.multiLine), node) + : node; } - export function createObjectLiteral(properties?: ObjectLiteralElementLike[], location?: TextRange, multiLine?: boolean) { - const node = createNode(SyntaxKind.ObjectLiteralExpression, location); + export function createObjectLiteral(properties?: ObjectLiteralElementLike[], multiLine?: boolean) { + const node = createSynthesizedNode(SyntaxKind.ObjectLiteralExpression); node.properties = createNodeArray(properties); if (multiLine) { node.multiLine = true; @@ -414,110 +434,120 @@ namespace ts { } export function updateObjectLiteral(node: ObjectLiteralExpression, properties: ObjectLiteralElementLike[]) { - if (node.properties !== properties) { - return updateNode(createObjectLiteral(properties, node, node.multiLine), node); - } - return node; + return node.properties !== properties + ? updateNode(createObjectLiteral(properties, node.multiLine), node) + : node; } - export function createPropertyAccess(expression: Expression, name: string | Identifier, location?: TextRange, flags?: NodeFlags) { - const node = createNode(SyntaxKind.PropertyAccessExpression, location, flags); + export function createPropertyAccess(expression: Expression, name: string | Identifier) { + const node = createSynthesizedNode(SyntaxKind.PropertyAccessExpression); node.expression = parenthesizeForAccess(expression); - (node.emitNode || (node.emitNode = {})).flags |= EmitFlags.NoIndentation; - node.name = typeof name === "string" ? createIdentifier(name) : name; + node.name = asName(name); + setEmitFlags(node, EmitFlags.NoIndentation); return node; } export function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier) { - if (node.expression !== expression || node.name !== name) { - const propertyAccess = createPropertyAccess(expression, name, /*location*/ node, node.flags); - // Because we are updating existed propertyAccess we want to inherit its emitFlags instead of using default from createPropertyAccess - (propertyAccess.emitNode || (propertyAccess.emitNode = {})).flags = getEmitFlags(node); - return updateNode(propertyAccess, node); - } - return node; + // Because we are updating existed propertyAccess we want to inherit its emitFlags + // instead of using the default from createPropertyAccess + return node.expression !== expression + || node.name !== name + ? updateNode(setEmitFlags(createPropertyAccess(expression, name), getEmitFlags(node)), node) + : node; } - export function createElementAccess(expression: Expression, index: number | Expression, location?: TextRange) { - const node = createNode(SyntaxKind.ElementAccessExpression, location); + export function createElementAccess(expression: Expression, index: number | Expression) { + const node = createSynthesizedNode(SyntaxKind.ElementAccessExpression); node.expression = parenthesizeForAccess(expression); - node.argumentExpression = typeof index === "number" ? createLiteral(index) : index; + node.argumentExpression = asExpression(index); return node; } export function updateElementAccess(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression) { - if (node.expression !== expression || node.argumentExpression !== argumentExpression) { - return updateNode(createElementAccess(expression, argumentExpression, node), node); - } - return node; + return node.expression !== expression + || node.argumentExpression !== argumentExpression + ? updateNode(createElementAccess(expression, argumentExpression), node) + : node; } - export function createCall(expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[], location?: TextRange, flags?: NodeFlags) { - const node = createNode(SyntaxKind.CallExpression, location, flags); + export function createCall(expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[]) { + const node = createSynthesizedNode(SyntaxKind.CallExpression); node.expression = parenthesizeForAccess(expression); - if (typeArguments) { - node.typeArguments = createNodeArray(typeArguments); - } - + node.typeArguments = asNodeArray(typeArguments); node.arguments = parenthesizeListElements(createNodeArray(argumentsArray)); return node; } export function updateCall(node: CallExpression, expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[]) { - if (expression !== node.expression || typeArguments !== node.typeArguments || argumentsArray !== node.arguments) { - return updateNode(createCall(expression, typeArguments, argumentsArray, /*location*/ node, node.flags), node); - } - return node; + return expression !== node.expression + || typeArguments !== node.typeArguments + || argumentsArray !== node.arguments + ? updateNode(createCall(expression, typeArguments, argumentsArray), node) + : node; } - export function createNew(expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[], location?: TextRange, flags?: NodeFlags) { - const node = createNode(SyntaxKind.NewExpression, location, flags); + export function createNew(expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[]) { + const node = createSynthesizedNode(SyntaxKind.NewExpression); node.expression = parenthesizeForNew(expression); - node.typeArguments = typeArguments ? createNodeArray(typeArguments) : undefined; + node.typeArguments = asNodeArray(typeArguments); node.arguments = argumentsArray ? parenthesizeListElements(createNodeArray(argumentsArray)) : undefined; return node; } export function updateNew(node: NewExpression, expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[]) { - if (node.expression !== expression || node.typeArguments !== typeArguments || node.arguments !== argumentsArray) { - return updateNode(createNew(expression, typeArguments, argumentsArray, /*location*/ node, node.flags), node); - } - return node; + return node.expression !== expression + || node.typeArguments !== typeArguments + || node.arguments !== argumentsArray + ? updateNode(createNew(expression, typeArguments, argumentsArray), node) + : node; } - export function createTaggedTemplate(tag: Expression, template: TemplateLiteral, location?: TextRange) { - const node = createNode(SyntaxKind.TaggedTemplateExpression, location); + export function createTaggedTemplate(tag: Expression, template: TemplateLiteral) { + const node = createSynthesizedNode(SyntaxKind.TaggedTemplateExpression); node.tag = parenthesizeForAccess(tag); node.template = template; return node; } export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral) { - if (node.tag !== tag || node.template !== template) { - return updateNode(createTaggedTemplate(tag, template, node), node); - } + return node.tag !== tag + || node.template !== template + ? updateNode(createTaggedTemplate(tag, template), node) + : node; + } + + export function createTypeAssertion(type: TypeNode, expression: Expression) { + const node = createSynthesizedNode(SyntaxKind.TypeAssertionExpression); + node.type = type; + node.expression = parenthesizePrefixOperand(expression); return node; } - export function createParen(expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.ParenthesizedExpression, location); + export function updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression) { + return node.type !== type + || node.expression !== expression + ? updateNode(createTypeAssertion(type, expression), node) + : node; + } + + export function createParen(expression: Expression) { + const node = createSynthesizedNode(SyntaxKind.ParenthesizedExpression); node.expression = expression; return node; } export function updateParen(node: ParenthesizedExpression, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createParen(expression, node), node); - } - return node; + return node.expression !== expression + ? updateNode(createParen(expression), node) + : node; } - export function createFunctionExpression(modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) { - const node = createNode(SyntaxKind.FunctionExpression, location, flags); - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + export function createFunctionExpression(modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) { + const node = createSynthesizedNode(SyntaxKind.FunctionExpression); + node.modifiers = asNodeArray(modifiers); node.asteriskToken = asteriskToken; - node.name = typeof name === "string" ? createIdentifier(name) : name; - node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined; + node.name = asName(name); + node.typeParameters = asNodeArray(typeParameters); node.parameters = createNodeArray(parameters); node.type = type; node.body = body; @@ -525,16 +555,20 @@ namespace ts { } export function updateFunctionExpression(node: FunctionExpression, modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) { - if (node.name !== name || node.modifiers !== modifiers || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body) { - return updateNode(createFunctionExpression(modifiers, node.asteriskToken, name, typeParameters, parameters, type, body, /*location*/ node, node.flags), node); - } - return node; + return node.name !== name + || node.modifiers !== modifiers + || node.typeParameters !== typeParameters + || node.parameters !== parameters + || node.type !== type + || node.body !== body + ? updateNode(createFunctionExpression(modifiers, node.asteriskToken, name, typeParameters, parameters, type, body), node) + : node; } - export function createArrowFunction(modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, equalsGreaterThanToken: EqualsGreaterThanToken, body: ConciseBody, location?: TextRange, flags?: NodeFlags) { - const node = createNode(SyntaxKind.ArrowFunction, location, flags); - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; - node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined; + export function createArrowFunction(modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, equalsGreaterThanToken: EqualsGreaterThanToken, body: ConciseBody) { + const node = createSynthesizedNode(SyntaxKind.ArrowFunction); + node.modifiers = asNodeArray(modifiers); + node.typeParameters = asNodeArray(typeParameters); node.parameters = createNodeArray(parameters); node.type = type; node.equalsGreaterThanToken = equalsGreaterThanToken || createToken(SyntaxKind.EqualsGreaterThanToken); @@ -543,96 +577,93 @@ namespace ts { } export function updateArrowFunction(node: ArrowFunction, modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: ConciseBody) { - if (node.modifiers !== modifiers || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body) { - return updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, node.equalsGreaterThanToken, body, /*location*/ node, node.flags), node); - } - return node; + return node.modifiers !== modifiers + || node.typeParameters !== typeParameters + || node.parameters !== parameters + || node.type !== type + || node.body !== body + ? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, node.equalsGreaterThanToken, body), node) + : node; } - export function createDelete(expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.DeleteExpression, location); + export function createDelete(expression: Expression) { + const node = createSynthesizedNode(SyntaxKind.DeleteExpression); node.expression = parenthesizePrefixOperand(expression); return node; } export function updateDelete(node: DeleteExpression, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createDelete(expression, node), expression); - } - return node; + return node.expression !== expression + ? updateNode(createDelete(expression), node) + : node; } - export function createTypeOf(expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.TypeOfExpression, location); + export function createTypeOf(expression: Expression) { + const node = createSynthesizedNode(SyntaxKind.TypeOfExpression); node.expression = parenthesizePrefixOperand(expression); return node; } export function updateTypeOf(node: TypeOfExpression, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createTypeOf(expression, node), expression); - } - return node; + return node.expression !== expression + ? updateNode(createTypeOf(expression), node) + : node; } - export function createVoid(expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.VoidExpression, location); + export function createVoid(expression: Expression) { + const node = createSynthesizedNode(SyntaxKind.VoidExpression); node.expression = parenthesizePrefixOperand(expression); return node; } export function updateVoid(node: VoidExpression, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createVoid(expression, node), node); - } - return node; + return node.expression !== expression + ? updateNode(createVoid(expression), node) + : node; } - export function createAwait(expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.AwaitExpression, location); + export function createAwait(expression: Expression) { + const node = createSynthesizedNode(SyntaxKind.AwaitExpression); node.expression = parenthesizePrefixOperand(expression); return node; } export function updateAwait(node: AwaitExpression, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createAwait(expression, node), node); - } - return node; + return node.expression !== expression + ? updateNode(createAwait(expression), node) + : node; } - export function createPrefix(operator: PrefixUnaryOperator, operand: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.PrefixUnaryExpression, location); + export function createPrefix(operator: PrefixUnaryOperator, operand: Expression) { + const node = createSynthesizedNode(SyntaxKind.PrefixUnaryExpression); node.operator = operator; node.operand = parenthesizePrefixOperand(operand); return node; } export function updatePrefix(node: PrefixUnaryExpression, operand: Expression) { - if (node.operand !== operand) { - return updateNode(createPrefix(node.operator, operand, node), node); - } - return node; + return node.operand !== operand + ? updateNode(createPrefix(node.operator, operand), node) + : node; } - export function createPostfix(operand: Expression, operator: PostfixUnaryOperator, location?: TextRange) { - const node = createNode(SyntaxKind.PostfixUnaryExpression, location); + export function createPostfix(operand: Expression, operator: PostfixUnaryOperator) { + const node = createSynthesizedNode(SyntaxKind.PostfixUnaryExpression); node.operand = parenthesizePostfixOperand(operand); node.operator = operator; return node; } export function updatePostfix(node: PostfixUnaryExpression, operand: Expression) { - if (node.operand !== operand) { - return updateNode(createPostfix(operand, node.operator, node), node); - } - return node; + return node.operand !== operand + ? updateNode(createPostfix(operand, node.operator), node) + : node; } - export function createBinary(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression, location?: TextRange) { - const operatorToken = typeof operator === "number" ? createToken(operator) : operator; + export function createBinary(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression) { + const node = createSynthesizedNode(SyntaxKind.BinaryExpression); + const operatorToken = asToken(operator); const operatorKind = operatorToken.kind; - const node = createNode(SyntaxKind.BinaryExpression, location); node.left = parenthesizeBinaryOperand(operatorKind, left, /*isLeftSideOfBinary*/ true, /*leftOperand*/ undefined); node.operatorToken = operatorToken; node.right = parenthesizeBinaryOperand(operatorKind, right, /*isLeftSideOfBinary*/ false, node.left); @@ -640,218 +671,231 @@ namespace ts { } export function updateBinary(node: BinaryExpression, left: Expression, right: Expression) { - if (node.left !== left || node.right !== right) { - return updateNode(createBinary(left, node.operatorToken, right, /*location*/ node), node); - } - return node; + return node.left !== left + || node.right !== right + ? updateNode(createBinary(left, node.operatorToken, right), node) + : node; } - export function createConditional(condition: Expression, whenTrue: Expression, whenFalse: Expression, location?: TextRange): ConditionalExpression; - export function createConditional(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression, location?: TextRange): ConditionalExpression; - export function createConditional(condition: Expression, questionTokenOrWhenTrue: QuestionToken | Expression, whenTrueOrWhenFalse: Expression, colonTokenOrLocation?: ColonToken | TextRange, whenFalse?: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.ConditionalExpression, whenFalse ? location : colonTokenOrLocation); + export function createConditional(condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression; + export function createConditional(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression; + export function createConditional(condition: Expression, questionTokenOrWhenTrue: QuestionToken | Expression, whenTrueOrWhenFalse: Expression, colonToken?: ColonToken, whenFalse?: Expression) { + const node = createSynthesizedNode(SyntaxKind.ConditionalExpression); node.condition = parenthesizeForConditionalHead(condition); - if (whenFalse) { - // second overload - node.questionToken = questionTokenOrWhenTrue; - node.whenTrue = parenthesizeSubexpressionOfConditionalExpression(whenTrueOrWhenFalse); - node.colonToken = colonTokenOrLocation; - node.whenFalse = parenthesizeSubexpressionOfConditionalExpression(whenFalse); - } - else { - // first overload - node.questionToken = createToken(SyntaxKind.QuestionToken); - node.whenTrue = parenthesizeSubexpressionOfConditionalExpression(questionTokenOrWhenTrue); - node.colonToken = createToken(SyntaxKind.ColonToken); - node.whenFalse = parenthesizeSubexpressionOfConditionalExpression(whenTrueOrWhenFalse); - } + node.questionToken = whenFalse ? questionTokenOrWhenTrue : createToken(SyntaxKind.QuestionToken); + node.whenTrue = parenthesizeSubexpressionOfConditionalExpression(whenFalse ? whenTrueOrWhenFalse : questionTokenOrWhenTrue); + node.colonToken = whenFalse ? colonToken : createToken(SyntaxKind.ColonToken); + node.whenFalse = parenthesizeSubexpressionOfConditionalExpression(whenFalse ? whenFalse : whenTrueOrWhenFalse); return node; } export function updateConditional(node: ConditionalExpression, condition: Expression, whenTrue: Expression, whenFalse: Expression) { - if (node.condition !== condition || node.whenTrue !== whenTrue || node.whenFalse !== whenFalse) { - return updateNode(createConditional(condition, node.questionToken, whenTrue, node.colonToken, whenFalse, node), node); - } - return node; + return node.condition !== condition + || node.whenTrue !== whenTrue + || node.whenFalse !== whenFalse + ? updateNode(createConditional(condition, node.questionToken, whenTrue, node.colonToken, whenFalse), node) + : node; } - export function createTemplateExpression(head: TemplateHead, templateSpans: TemplateSpan[], location?: TextRange) { - const node = createNode(SyntaxKind.TemplateExpression, location); + export function createTemplateExpression(head: TemplateHead, templateSpans: TemplateSpan[]) { + const node = createSynthesizedNode(SyntaxKind.TemplateExpression); node.head = head; node.templateSpans = createNodeArray(templateSpans); return node; } export function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: TemplateSpan[]) { - if (node.head !== head || node.templateSpans !== templateSpans) { - return updateNode(createTemplateExpression(head, templateSpans, node), node); - } - return node; + return node.head !== head + || node.templateSpans !== templateSpans + ? updateNode(createTemplateExpression(head, templateSpans), node) + : node; } - export function createYield(asteriskToken: AsteriskToken, expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.YieldExpression, location); - node.asteriskToken = asteriskToken; - node.expression = expression; + export function createYield(expression?: Expression): YieldExpression; + export function createYield(asteriskToken: AsteriskToken, expression: Expression): YieldExpression; + 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; return node; } export function updateYield(node: YieldExpression, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createYield(node.asteriskToken, expression, node), node); - } - return node; + return node.expression !== expression + ? updateNode(createYield(node.asteriskToken, expression), node) + : node; } - export function createSpread(expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.SpreadElement, location); + export function createSpread(expression: Expression) { + const node = createSynthesizedNode(SyntaxKind.SpreadElement); node.expression = parenthesizeExpressionForList(expression); return node; } export function updateSpread(node: SpreadElement, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createSpread(expression, node), node); - } - return node; + return node.expression !== expression + ? updateNode(createSpread(expression), node) + : node; } - export function createClassExpression(modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], heritageClauses: HeritageClause[], members: ClassElement[], location?: TextRange) { - const node = createNode(SyntaxKind.ClassExpression, location); + export function createClassExpression(modifiers: Modifier[], name: string | Identifier, typeParameters: TypeParameterDeclaration[], heritageClauses: HeritageClause[], members: ClassElement[]) { + const node = createSynthesizedNode(SyntaxKind.ClassExpression); node.decorators = undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; - node.name = name; - node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined; - node.heritageClauses = createNodeArray(heritageClauses); + node.modifiers = asNodeArray(modifiers); + node.name = asName(name); + node.typeParameters = asNodeArray(typeParameters); + node.heritageClauses = asNodeArray(heritageClauses); node.members = createNodeArray(members); return node; } export function updateClassExpression(node: ClassExpression, modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], heritageClauses: HeritageClause[], members: ClassElement[]) { - if (node.modifiers !== modifiers || node.name !== name || node.typeParameters !== typeParameters || node.heritageClauses !== heritageClauses || node.members !== members) { - return updateNode(createClassExpression(modifiers, name, typeParameters, heritageClauses, members, node), node); - } - return node; + return node.modifiers !== modifiers + || node.name !== name + || node.typeParameters !== typeParameters + || node.heritageClauses !== heritageClauses + || node.members !== members + ? updateNode(createClassExpression(modifiers, name, typeParameters, heritageClauses, members), node) + : node; } - export function createOmittedExpression(location?: TextRange) { - const node = createNode(SyntaxKind.OmittedExpression, location); - return node; + export function createOmittedExpression() { + return createSynthesizedNode(SyntaxKind.OmittedExpression); } - export function createExpressionWithTypeArguments(typeArguments: TypeNode[], expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.ExpressionWithTypeArguments, location); - node.typeArguments = typeArguments ? createNodeArray(typeArguments) : undefined; + export function createExpressionWithTypeArguments(typeArguments: TypeNode[], expression: Expression) { + const node = createSynthesizedNode(SyntaxKind.ExpressionWithTypeArguments); node.expression = parenthesizeForAccess(expression); + node.typeArguments = asNodeArray(typeArguments); return node; } export function updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, typeArguments: TypeNode[], expression: Expression) { - if (node.typeArguments !== typeArguments || node.expression !== expression) { - return updateNode(createExpressionWithTypeArguments(typeArguments, expression, node), node); - } + return node.typeArguments !== typeArguments + || node.expression !== expression + ? updateNode(createExpressionWithTypeArguments(typeArguments, expression), node) + : node; + } + + export function createAsExpression(expression: Expression, type: TypeNode) { + const node = createSynthesizedNode(SyntaxKind.AsExpression); + node.expression = expression; + node.type = type; return node; } + export function updateAsExpression(node: AsExpression, expression: Expression, type: TypeNode) { + return node.expression !== expression + || node.type !== type + ? updateNode(createAsExpression(expression, type), node) + : node; + } + + export function createNonNullExpression(expression: Expression) { + const node = createSynthesizedNode(SyntaxKind.NonNullExpression); + node.expression = parenthesizeForAccess(expression); + return node; + } + + export function updateNonNullExpression(node: NonNullExpression, expression: Expression) { + return node.expression !== expression + ? updateNode(createNonNullExpression(expression), node) + : node; + } // Misc - export function createTemplateSpan(expression: Expression, literal: TemplateMiddle | TemplateTail, location?: TextRange) { - const node = createNode(SyntaxKind.TemplateSpan, location); + export function createTemplateSpan(expression: Expression, literal: TemplateMiddle | TemplateTail) { + const node = createSynthesizedNode(SyntaxKind.TemplateSpan); node.expression = expression; node.literal = literal; return node; } export function updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle | TemplateTail) { - if (node.expression !== expression || node.literal !== literal) { - return updateNode(createTemplateSpan(expression, literal, node), node); - } - return node; + return node.expression !== expression + || node.literal !== literal + ? updateNode(createTemplateSpan(expression, literal), node) + : node; } // Element - export function createBlock(statements: Statement[], location?: TextRange, multiLine?: boolean, flags?: NodeFlags): Block { - const block = createNode(SyntaxKind.Block, location, flags); + export function createBlock(statements: Statement[], multiLine?: boolean): Block { + const block = createSynthesizedNode(SyntaxKind.Block); block.statements = createNodeArray(statements); - if (multiLine) { - block.multiLine = true; - } + if (multiLine) block.multiLine = multiLine; return block; } export function updateBlock(node: Block, statements: Statement[]) { - if (statements !== node.statements) { - return updateNode(createBlock(statements, /*location*/ node, node.multiLine, node.flags), node); - } - - return node; + return statements !== node.statements + ? updateNode(createBlock(statements, node.multiLine), node) + : node; } - export function createVariableStatement(modifiers: Modifier[], declarationList: VariableDeclarationList | VariableDeclaration[], location?: TextRange, flags?: NodeFlags): VariableStatement { - const node = createNode(SyntaxKind.VariableStatement, location, flags); + export function createVariableStatement(modifiers: Modifier[], declarationList: VariableDeclarationList | VariableDeclaration[]): VariableStatement { + const node = createSynthesizedNode(SyntaxKind.VariableStatement); node.decorators = undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + node.modifiers = asNodeArray(modifiers); node.declarationList = isArray(declarationList) ? createVariableDeclarationList(declarationList) : declarationList; return node; } export function updateVariableStatement(node: VariableStatement, modifiers: Modifier[], declarationList: VariableDeclarationList): VariableStatement { - if (node.modifiers !== modifiers || node.declarationList !== declarationList) { - return updateNode(createVariableStatement(modifiers, declarationList, /*location*/ node, node.flags), node); - } - return node; + return node.modifiers !== modifiers + || node.declarationList !== declarationList + ? updateNode(createVariableStatement(modifiers, declarationList), node) + : node; } - export function createVariableDeclarationList(declarations: VariableDeclaration[], location?: TextRange, flags?: NodeFlags): VariableDeclarationList { - const node = createNode(SyntaxKind.VariableDeclarationList, location, flags); + export function createVariableDeclarationList(declarations: VariableDeclaration[], flags?: NodeFlags): VariableDeclarationList { + const node = createSynthesizedNode(SyntaxKind.VariableDeclarationList); + node.flags |= flags; node.declarations = createNodeArray(declarations); return node; } export function updateVariableDeclarationList(node: VariableDeclarationList, declarations: VariableDeclaration[]) { - if (node.declarations !== declarations) { - return updateNode(createVariableDeclarationList(declarations, /*location*/ node, node.flags), node); - } - return node; + return node.declarations !== declarations + ? updateNode(createVariableDeclarationList(declarations, node.flags), node) + : node; } - export function createVariableDeclaration(name: string | BindingPattern | Identifier, type?: TypeNode, initializer?: Expression, location?: TextRange, flags?: NodeFlags): VariableDeclaration { - const node = createNode(SyntaxKind.VariableDeclaration, location, flags); - node.name = typeof name === "string" ? createIdentifier(name) : name; + export function createVariableDeclaration(name: string | BindingName, type?: TypeNode, initializer?: Expression): VariableDeclaration { + const node = createSynthesizedNode(SyntaxKind.VariableDeclaration); + node.name = asName(name); node.type = type; node.initializer = initializer !== undefined ? parenthesizeExpressionForList(initializer) : undefined; return node; } export function updateVariableDeclaration(node: VariableDeclaration, name: BindingName, type: TypeNode, initializer: Expression) { - if (node.name !== name || node.type !== type || node.initializer !== initializer) { - return updateNode(createVariableDeclaration(name, type, initializer, /*location*/ node, node.flags), node); - } - return node; + return node.name !== name + || node.type !== type + || node.initializer !== initializer + ? updateNode(createVariableDeclaration(name, type, initializer), node) + : node; } - export function createEmptyStatement(location: TextRange) { - return createNode(SyntaxKind.EmptyStatement, location); + export function createEmptyStatement() { + return createSynthesizedNode(SyntaxKind.EmptyStatement); } - export function createStatement(expression: Expression, location?: TextRange, flags?: NodeFlags): ExpressionStatement { - const node = createNode(SyntaxKind.ExpressionStatement, location, flags); + export function createStatement(expression: Expression): ExpressionStatement { + const node = createSynthesizedNode(SyntaxKind.ExpressionStatement); node.expression = parenthesizeExpressionForExpressionStatement(expression); return node; } export function updateStatement(node: ExpressionStatement, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createStatement(expression, /*location*/ node, node.flags), node); - } - - return node; + return node.expression !== expression + ? updateNode(createStatement(expression), node) + : node; } - export function createIf(expression: Expression, thenStatement: Statement, elseStatement?: Statement, location?: TextRange) { - const node = createNode(SyntaxKind.IfStatement, location); + export function createIf(expression: Expression, thenStatement: Statement, elseStatement?: Statement) { + const node = createSynthesizedNode(SyntaxKind.IfStatement); node.expression = expression; node.thenStatement = thenStatement; node.elseStatement = elseStatement; @@ -859,42 +903,43 @@ namespace ts { } export function updateIf(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement) { - if (node.expression !== expression || node.thenStatement !== thenStatement || node.elseStatement !== elseStatement) { - return updateNode(createIf(expression, thenStatement, elseStatement, /*location*/ node), node); - } - return node; + return node.expression !== expression + || node.thenStatement !== thenStatement + || node.elseStatement !== elseStatement + ? updateNode(createIf(expression, thenStatement, elseStatement), node) + : node; } - export function createDo(statement: Statement, expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.DoStatement, location); + export function createDo(statement: Statement, expression: Expression) { + const node = createSynthesizedNode(SyntaxKind.DoStatement); node.statement = statement; node.expression = expression; return node; } export function updateDo(node: DoStatement, statement: Statement, expression: Expression) { - if (node.statement !== statement || node.expression !== expression) { - return updateNode(createDo(statement, expression, node), node); - } - return node; + return node.statement !== statement + || node.expression !== expression + ? updateNode(createDo(statement, expression), node) + : node; } - export function createWhile(expression: Expression, statement: Statement, location?: TextRange) { - const node = createNode(SyntaxKind.WhileStatement, location); + export function createWhile(expression: Expression, statement: Statement) { + const node = createSynthesizedNode(SyntaxKind.WhileStatement); node.expression = expression; node.statement = statement; return node; } export function updateWhile(node: WhileStatement, expression: Expression, statement: Statement) { - if (node.expression !== expression || node.statement !== statement) { - return updateNode(createWhile(expression, statement, node), node); - } - return node; + return node.expression !== expression + || node.statement !== statement + ? updateNode(createWhile(expression, statement), node) + : node; } - export function createFor(initializer: ForInitializer, condition: Expression, incrementor: Expression, statement: Statement, location?: TextRange) { - const node = createNode(SyntaxKind.ForStatement, location, /*flags*/ undefined); + export function createFor(initializer: ForInitializer, condition: Expression, incrementor: Expression, statement: Statement) { + const node = createSynthesizedNode(SyntaxKind.ForStatement); node.initializer = initializer; node.condition = condition; node.incrementor = incrementor; @@ -903,14 +948,16 @@ namespace ts { } export function updateFor(node: ForStatement, initializer: ForInitializer, condition: Expression, incrementor: Expression, statement: Statement) { - if (node.initializer !== initializer || node.condition !== condition || node.incrementor !== incrementor || node.statement !== statement) { - return updateNode(createFor(initializer, condition, incrementor, statement, node), node); - } - return node; + return node.initializer !== initializer + || node.condition !== condition + || node.incrementor !== incrementor + || node.statement !== statement + ? updateNode(createFor(initializer, condition, incrementor, statement), node) + : node; } - export function createForIn(initializer: ForInitializer, expression: Expression, statement: Statement, location?: TextRange) { - const node = createNode(SyntaxKind.ForInStatement, location); + export function createForIn(initializer: ForInitializer, expression: Expression, statement: Statement) { + const node = createSynthesizedNode(SyntaxKind.ForInStatement); node.initializer = initializer; node.expression = expression; node.statement = statement; @@ -918,14 +965,15 @@ namespace ts { } export function updateForIn(node: ForInStatement, initializer: ForInitializer, expression: Expression, statement: Statement) { - if (node.initializer !== initializer || node.expression !== expression || node.statement !== statement) { - return updateNode(createForIn(initializer, expression, statement, node), node); - } - return node; + return node.initializer !== initializer + || node.expression !== expression + || node.statement !== statement + ? updateNode(createForIn(initializer, expression, statement), node) + : node; } - export function createForOf(initializer: ForInitializer, expression: Expression, statement: Statement, location?: TextRange) { - const node = createNode(SyntaxKind.ForOfStatement, location); + export function createForOf(initializer: ForInitializer, expression: Expression, statement: Statement) { + const node = createSynthesizedNode(SyntaxKind.ForOfStatement); node.initializer = initializer; node.expression = expression; node.statement = statement; @@ -933,112 +981,105 @@ namespace ts { } export function updateForOf(node: ForOfStatement, initializer: ForInitializer, expression: Expression, statement: Statement) { - if (node.initializer !== initializer || node.expression !== expression || node.statement !== statement) { - return updateNode(createForOf(initializer, expression, statement, node), node); - } - return node; + return node.initializer !== initializer + || node.expression !== expression + || node.statement !== statement + ? updateNode(createForOf(initializer, expression, statement), node) + : node; } - export function createContinue(label?: Identifier, location?: TextRange): ContinueStatement { - const node = createNode(SyntaxKind.ContinueStatement, location); - if (label) { - node.label = label; - } + export function createContinue(label?: string | Identifier): ContinueStatement { + const node = createSynthesizedNode(SyntaxKind.ContinueStatement); + node.label = asName(label); return node; } export function updateContinue(node: ContinueStatement, label: Identifier) { - if (node.label !== label) { - return updateNode(createContinue(label, node), node); - } - return node; + return node.label !== label + ? updateNode(createContinue(label), node) + : node; } - export function createBreak(label?: Identifier, location?: TextRange): BreakStatement { - const node = createNode(SyntaxKind.BreakStatement, location); - if (label) { - node.label = label; - } + export function createBreak(label?: string | Identifier): BreakStatement { + const node = createSynthesizedNode(SyntaxKind.BreakStatement); + node.label = asName(label); return node; } export function updateBreak(node: BreakStatement, label: Identifier) { - if (node.label !== label) { - return updateNode(createBreak(label, node), node); - } - return node; + return node.label !== label + ? updateNode(createBreak(label), node) + : node; } - export function createReturn(expression?: Expression, location?: TextRange): ReturnStatement { - const node = createNode(SyntaxKind.ReturnStatement, location); + export function createReturn(expression?: Expression): ReturnStatement { + const node = createSynthesizedNode(SyntaxKind.ReturnStatement); node.expression = expression; return node; } export function updateReturn(node: ReturnStatement, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createReturn(expression, /*location*/ node), node); - } - return node; + return node.expression !== expression + ? updateNode(createReturn(expression), node) + : node; } - export function createWith(expression: Expression, statement: Statement, location?: TextRange) { - const node = createNode(SyntaxKind.WithStatement, location); + export function createWith(expression: Expression, statement: Statement) { + const node = createSynthesizedNode(SyntaxKind.WithStatement); node.expression = expression; node.statement = statement; return node; } export function updateWith(node: WithStatement, expression: Expression, statement: Statement) { - if (node.expression !== expression || node.statement !== statement) { - return updateNode(createWith(expression, statement, node), node); - } - return node; + return node.expression !== expression + || node.statement !== statement + ? updateNode(createWith(expression, statement), node) + : node; } - export function createSwitch(expression: Expression, caseBlock: CaseBlock, location?: TextRange): SwitchStatement { - const node = createNode(SyntaxKind.SwitchStatement, location); + export function createSwitch(expression: Expression, caseBlock: CaseBlock): SwitchStatement { + const node = createSynthesizedNode(SyntaxKind.SwitchStatement); node.expression = parenthesizeExpressionForList(expression); node.caseBlock = caseBlock; return node; } export function updateSwitch(node: SwitchStatement, expression: Expression, caseBlock: CaseBlock) { - if (node.expression !== expression || node.caseBlock !== caseBlock) { - return updateNode(createSwitch(expression, caseBlock, node), node); - } - return node; + return node.expression !== expression + || node.caseBlock !== caseBlock + ? updateNode(createSwitch(expression, caseBlock), node) + : node; } - export function createLabel(label: string | Identifier, statement: Statement, location?: TextRange) { - const node = createNode(SyntaxKind.LabeledStatement, location); - node.label = typeof label === "string" ? createIdentifier(label) : label; + export function createLabel(label: string | Identifier, statement: Statement) { + const node = createSynthesizedNode(SyntaxKind.LabeledStatement); + node.label = asName(label); node.statement = statement; return node; } export function updateLabel(node: LabeledStatement, label: Identifier, statement: Statement) { - if (node.label !== label || node.statement !== statement) { - return updateNode(createLabel(label, statement, node), node); - } - return node; + return node.label !== label + || node.statement !== statement + ? updateNode(createLabel(label, statement), node) + : node; } - export function createThrow(expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.ThrowStatement, location); + export function createThrow(expression: Expression) { + const node = createSynthesizedNode(SyntaxKind.ThrowStatement); node.expression = expression; return node; } export function updateThrow(node: ThrowStatement, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createThrow(expression, node), node); - } - return node; + return node.expression !== expression + ? updateNode(createThrow(expression), node) + : node; } - export function createTry(tryBlock: Block, catchClause: CatchClause, finallyBlock: Block, location?: TextRange) { - const node = createNode(SyntaxKind.TryStatement, location); + export function createTry(tryBlock: Block, catchClause: CatchClause, finallyBlock: Block) { + const node = createSynthesizedNode(SyntaxKind.TryStatement); node.tryBlock = tryBlock; node.catchClause = catchClause; node.finallyBlock = finallyBlock; @@ -1046,32 +1087,20 @@ namespace ts { } export function updateTry(node: TryStatement, tryBlock: Block, catchClause: CatchClause, finallyBlock: Block) { - if (node.tryBlock !== tryBlock || node.catchClause !== catchClause || node.finallyBlock !== finallyBlock) { - return updateNode(createTry(tryBlock, catchClause, finallyBlock, node), node); - } - return node; + return node.tryBlock !== tryBlock + || node.catchClause !== catchClause + || node.finallyBlock !== finallyBlock + ? updateNode(createTry(tryBlock, catchClause, finallyBlock), node) + : node; } - export function createCaseBlock(clauses: CaseOrDefaultClause[], location?: TextRange): CaseBlock { - const node = createNode(SyntaxKind.CaseBlock, location); - node.clauses = createNodeArray(clauses); - return node; - } - - export function updateCaseBlock(node: CaseBlock, clauses: CaseOrDefaultClause[]) { - if (node.clauses !== clauses) { - return updateNode(createCaseBlock(clauses, node), node); - } - return node; - } - - export function createFunctionDeclaration(decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) { - const node = createNode(SyntaxKind.FunctionDeclaration, location, flags); - node.decorators = decorators ? createNodeArray(decorators) : undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + export function createFunctionDeclaration(decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) { + const node = createSynthesizedNode(SyntaxKind.FunctionDeclaration); + node.decorators = asNodeArray(decorators); + node.modifiers = asNodeArray(modifiers); node.asteriskToken = asteriskToken; - node.name = typeof name === "string" ? createIdentifier(name) : name; - node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined; + node.name = asName(name); + node.typeParameters = asNodeArray(typeParameters); node.parameters = createNodeArray(parameters); node.type = type; node.body = body; @@ -1079,163 +1108,265 @@ namespace ts { } export function updateFunctionDeclaration(node: FunctionDeclaration, decorators: Decorator[], modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) { - if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body) { - return updateNode(createFunctionDeclaration(decorators, modifiers, node.asteriskToken, name, typeParameters, parameters, type, body, /*location*/ node, node.flags), node); - } - return node; + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.name !== name + || node.typeParameters !== typeParameters + || node.parameters !== parameters + || node.type !== type + || node.body !== body + ? updateNode(createFunctionDeclaration(decorators, modifiers, node.asteriskToken, name, typeParameters, parameters, type, body), node) + : node; } - export function createClassDeclaration(decorators: Decorator[], modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], heritageClauses: HeritageClause[], members: ClassElement[], location?: TextRange) { - const node = createNode(SyntaxKind.ClassDeclaration, location); - node.decorators = decorators ? createNodeArray(decorators) : undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; - node.name = name; - node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined; - node.heritageClauses = createNodeArray(heritageClauses); + export function createClassDeclaration(decorators: Decorator[], modifiers: Modifier[], name: string | Identifier, typeParameters: TypeParameterDeclaration[], heritageClauses: HeritageClause[], members: ClassElement[]) { + const node = createSynthesizedNode(SyntaxKind.ClassDeclaration); + node.decorators = asNodeArray(decorators); + node.modifiers = asNodeArray(modifiers); + node.name = asName(name); + node.typeParameters = asNodeArray(typeParameters); + node.heritageClauses = asNodeArray(heritageClauses); node.members = createNodeArray(members); return node; } export function updateClassDeclaration(node: ClassDeclaration, decorators: Decorator[], modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], heritageClauses: HeritageClause[], members: ClassElement[]) { - if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.typeParameters !== typeParameters || node.heritageClauses !== heritageClauses || node.members !== members) { - return updateNode(createClassDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members, node), node); - } + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.name !== name + || node.typeParameters !== typeParameters + || node.heritageClauses !== heritageClauses + || node.members !== members + ? updateNode(createClassDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members), node) + : node; + } + + export function createEnumDeclaration(decorators: Decorator[], modifiers: Modifier[], name: string | Identifier, members: EnumMember[]) { + const node = createSynthesizedNode(SyntaxKind.EnumDeclaration); + node.decorators = asNodeArray(decorators); + node.modifiers = asNodeArray(modifiers); + node.name = asName(name); + node.members = createNodeArray(members); return node; } - export function createImportDeclaration(decorators: Decorator[], modifiers: Modifier[], importClause: ImportClause, moduleSpecifier?: Expression, location?: TextRange): ImportDeclaration { - const node = createNode(SyntaxKind.ImportDeclaration, location); - node.decorators = decorators ? createNodeArray(decorators) : undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + export function updateEnumDeclaration(node: EnumDeclaration, decorators: Decorator[], modifiers: Modifier[], name: Identifier, members: EnumMember[]) { + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.name !== name + || node.members !== members + ? updateNode(createEnumDeclaration(decorators, modifiers, name, members), node) + : node; + } + + export function createModuleDeclaration(decorators: Decorator[], modifiers: Modifier[], name: ModuleName, body: ModuleBody, flags?: NodeFlags) { + const node = createSynthesizedNode(SyntaxKind.ModuleDeclaration); + node.flags |= flags; + node.decorators = asNodeArray(decorators); + node.modifiers = asNodeArray(modifiers); + node.name = name; + node.body = body; + return node; + } + + export function updateModuleDeclaration(node: ModuleDeclaration, decorators: Decorator[], modifiers: Modifier[], name: ModuleName, body: ModuleBody) { + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.name !== name + || node.body !== body + ? updateNode(createModuleDeclaration(decorators, modifiers, name, body, node.flags), node) + : node; + } + + export function createModuleBlock(statements: Statement[]) { + const node = createSynthesizedNode(SyntaxKind.CaseBlock); + node.statements = createNodeArray(statements); + return node; + } + + export function updateModuleBlock(node: ModuleBlock, statements: Statement[]) { + return node.statements !== statements + ? updateNode(createModuleBlock(statements), node) + : node; + } + + export function createCaseBlock(clauses: CaseOrDefaultClause[]): CaseBlock { + const node = createSynthesizedNode(SyntaxKind.CaseBlock); + node.clauses = createNodeArray(clauses); + return node; + } + + export function updateCaseBlock(node: CaseBlock, clauses: CaseOrDefaultClause[]) { + return node.clauses !== clauses + ? updateNode(createCaseBlock(clauses), node) + : node; + } + + export function createImportEqualsDeclaration(decorators: Decorator[], modifiers: Modifier[], name: string | Identifier, moduleReference: ModuleReference) { + const node = createSynthesizedNode(SyntaxKind.ImportEqualsDeclaration); + node.decorators = asNodeArray(decorators); + node.modifiers = asNodeArray(modifiers); + node.name = asName(name); + node.moduleReference = moduleReference; + return node; + } + + export function updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Decorator[], modifiers: Modifier[], name: Identifier, moduleReference: ModuleReference) { + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.name !== name + || node.moduleReference !== moduleReference + ? updateNode(createImportEqualsDeclaration(decorators, modifiers, name, moduleReference), node) + : node; + } + + export function createImportDeclaration(decorators: Decorator[], modifiers: Modifier[], importClause: ImportClause, moduleSpecifier?: Expression): ImportDeclaration { + const node = createSynthesizedNode(SyntaxKind.ImportDeclaration); + node.decorators = asNodeArray(decorators); + node.modifiers = asNodeArray(modifiers); node.importClause = importClause; node.moduleSpecifier = moduleSpecifier; return node; } export function updateImportDeclaration(node: ImportDeclaration, decorators: Decorator[], modifiers: Modifier[], importClause: ImportClause, moduleSpecifier: Expression) { - if (node.decorators !== decorators || node.modifiers !== modifiers || node.importClause !== importClause || node.moduleSpecifier !== moduleSpecifier) { - return updateNode(createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier, node), node); - } - return node; + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.importClause !== importClause || node.moduleSpecifier !== moduleSpecifier + ? updateNode(createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier), node) + : node; } - export function createImportClause(name: Identifier, namedBindings: NamedImportBindings, location?: TextRange): ImportClause { - const node = createNode(SyntaxKind.ImportClause, location); + export function createImportClause(name: Identifier, namedBindings: NamedImportBindings): ImportClause { + const node = createSynthesizedNode(SyntaxKind.ImportClause); node.name = name; node.namedBindings = namedBindings; return node; } export function updateImportClause(node: ImportClause, name: Identifier, namedBindings: NamedImportBindings) { - if (node.name !== name || node.namedBindings !== namedBindings) { - return updateNode(createImportClause(name, namedBindings, node), node); - } - return node; + return node.name !== name + || node.namedBindings !== namedBindings + ? updateNode(createImportClause(name, namedBindings), node) + : node; } - export function createNamespaceImport(name: Identifier, location?: TextRange): NamespaceImport { - const node = createNode(SyntaxKind.NamespaceImport, location); + export function createNamespaceImport(name: Identifier): NamespaceImport { + const node = createSynthesizedNode(SyntaxKind.NamespaceImport); node.name = name; return node; } export function updateNamespaceImport(node: NamespaceImport, name: Identifier) { - if (node.name !== name) { - return updateNode(createNamespaceImport(name, node), node); - } - return node; + return node.name !== name + ? updateNode(createNamespaceImport(name), node) + : node; } - export function createNamedImports(elements: ImportSpecifier[], location?: TextRange): NamedImports { - const node = createNode(SyntaxKind.NamedImports, location); + export function createNamedImports(elements: ImportSpecifier[]): NamedImports { + const node = createSynthesizedNode(SyntaxKind.NamedImports); node.elements = createNodeArray(elements); return node; } export function updateNamedImports(node: NamedImports, elements: ImportSpecifier[]) { - if (node.elements !== elements) { - return updateNode(createNamedImports(elements, node), node); - } - return node; + return node.elements !== elements + ? updateNode(createNamedImports(elements), node) + : node; } - export function createImportSpecifier(propertyName: Identifier, name: Identifier, location?: TextRange) { - const node = createNode(SyntaxKind.ImportSpecifier, location); + export function createImportSpecifier(propertyName: Identifier, name: Identifier) { + const node = createSynthesizedNode(SyntaxKind.ImportSpecifier); node.propertyName = propertyName; node.name = name; return node; } export function updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier, name: Identifier) { - if (node.propertyName !== propertyName || node.name !== name) { - return updateNode(createImportSpecifier(propertyName, name, node), node); - } - return node; + return node.propertyName !== propertyName + || node.name !== name + ? updateNode(createImportSpecifier(propertyName, name), node) + : node; } - export function createExportAssignment(decorators: Decorator[], modifiers: Modifier[], isExportEquals: boolean, expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.ExportAssignment, location); - node.decorators = decorators ? createNodeArray(decorators) : undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + export function createExportAssignment(decorators: Decorator[], modifiers: Modifier[], isExportEquals: boolean, expression: Expression) { + const node = createSynthesizedNode(SyntaxKind.ExportAssignment); + node.decorators = asNodeArray(decorators); + node.modifiers = asNodeArray(modifiers); node.isExportEquals = isExportEquals; node.expression = expression; return node; } export function updateExportAssignment(node: ExportAssignment, decorators: Decorator[], modifiers: Modifier[], expression: Expression) { - if (node.decorators !== decorators || node.modifiers !== modifiers || node.expression !== expression) { - return updateNode(createExportAssignment(decorators, modifiers, node.isExportEquals, expression, node), node); - } - return node; + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.expression !== expression + ? updateNode(createExportAssignment(decorators, modifiers, node.isExportEquals, expression), node) + : node; } - export function createExportDeclaration(decorators: Decorator[], modifiers: Modifier[], exportClause: NamedExports, moduleSpecifier?: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.ExportDeclaration, location); - node.decorators = decorators ? createNodeArray(decorators) : undefined; - node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; + export function createExportDeclaration(decorators: Decorator[], modifiers: Modifier[], exportClause: NamedExports, moduleSpecifier?: Expression) { + const node = createSynthesizedNode(SyntaxKind.ExportDeclaration); + node.decorators = asNodeArray(decorators); + node.modifiers = asNodeArray(modifiers); node.exportClause = exportClause; node.moduleSpecifier = moduleSpecifier; return node; } export function updateExportDeclaration(node: ExportDeclaration, decorators: Decorator[], modifiers: Modifier[], exportClause: NamedExports, moduleSpecifier: Expression) { - if (node.decorators !== decorators || node.modifiers !== modifiers || node.exportClause !== exportClause || node.moduleSpecifier !== moduleSpecifier) { - return updateNode(createExportDeclaration(decorators, modifiers, exportClause, moduleSpecifier, node), node); - } - return node; + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.exportClause !== exportClause + || node.moduleSpecifier !== moduleSpecifier + ? updateNode(createExportDeclaration(decorators, modifiers, exportClause, moduleSpecifier), node) + : node; } - export function createNamedExports(elements: ExportSpecifier[], location?: TextRange) { - const node = createNode(SyntaxKind.NamedExports, location); + export function createNamedExports(elements: ExportSpecifier[]) { + const node = createSynthesizedNode(SyntaxKind.NamedExports); node.elements = createNodeArray(elements); return node; } export function updateNamedExports(node: NamedExports, elements: ExportSpecifier[]) { - if (node.elements !== elements) { - return updateNode(createNamedExports(elements, node), node); - } - return node; + return node.elements !== elements + ? updateNode(createNamedExports(elements), node) + : node; } - export function createExportSpecifier(name: string | Identifier, propertyName?: string | Identifier, location?: TextRange) { - const node = createNode(SyntaxKind.ExportSpecifier, location); - node.name = typeof name === "string" ? createIdentifier(name) : name; - node.propertyName = typeof propertyName === "string" ? createIdentifier(propertyName) : propertyName; + export function createExportSpecifier(name: string | Identifier, propertyName?: string | Identifier) { + const node = createSynthesizedNode(SyntaxKind.ExportSpecifier); + node.name = asName(name); + node.propertyName = asName(propertyName); return node; } export function updateExportSpecifier(node: ExportSpecifier, name: Identifier, propertyName: Identifier) { - if (node.name !== name || node.propertyName !== propertyName) { - return updateNode(createExportSpecifier(name, propertyName, node), node); - } + return node.name !== name || node.propertyName !== propertyName + ? updateNode(createExportSpecifier(name, propertyName), node) + : node; + } + + // Module references + + export function createExternalModuleReference(expression: Expression) { + const node = createSynthesizedNode(SyntaxKind.ExternalModuleReference); + node.expression = expression; return node; } + export function updateExternalModuleReference(node: ExternalModuleReference, expression: Expression) { + return node.expression !== expression + ? updateNode(createExternalModuleReference(expression), node) + : node; + } + // JSX - export function createJsxElement(openingElement: JsxOpeningElement, children: JsxChild[], closingElement: JsxClosingElement, location?: TextRange) { - const node = createNode(SyntaxKind.JsxElement, location); + export function createJsxElement(openingElement: JsxOpeningElement, children: JsxChild[], closingElement: JsxClosingElement) { + const node = createSynthesizedNode(SyntaxKind.JsxElement); node.openingElement = openingElement; node.children = createNodeArray(children); node.closingElement = closingElement; @@ -1243,98 +1374,96 @@ namespace ts { } export function updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: JsxChild[], closingElement: JsxClosingElement) { - if (node.openingElement !== openingElement || node.children !== children || node.closingElement !== closingElement) { - return updateNode(createJsxElement(openingElement, children, closingElement, node), node); - } - return node; + return node.openingElement !== openingElement + || node.children !== children + || node.closingElement !== closingElement + ? updateNode(createJsxElement(openingElement, children, closingElement), node) + : node; } - export function createJsxSelfClosingElement(tagName: JsxTagNameExpression, attributes: JsxAttributeLike[], location?: TextRange) { - const node = createNode(SyntaxKind.JsxSelfClosingElement, location); + export function createJsxSelfClosingElement(tagName: JsxTagNameExpression, attributes: JsxAttributeLike[]) { + const node = createSynthesizedNode(SyntaxKind.JsxSelfClosingElement); node.tagName = tagName; node.attributes = createNodeArray(attributes); return node; } export function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, attributes: JsxAttributeLike[]) { - if (node.tagName !== tagName || node.attributes !== attributes) { - return updateNode(createJsxSelfClosingElement(tagName, attributes, node), node); - } - return node; + return node.tagName !== tagName + || node.attributes !== attributes + ? updateNode(createJsxSelfClosingElement(tagName, attributes), node) + : node; } - export function createJsxOpeningElement(tagName: JsxTagNameExpression, attributes: JsxAttributeLike[], location?: TextRange) { - const node = createNode(SyntaxKind.JsxOpeningElement, location); + export function createJsxOpeningElement(tagName: JsxTagNameExpression, attributes: JsxAttributeLike[]) { + const node = createSynthesizedNode(SyntaxKind.JsxOpeningElement); node.tagName = tagName; node.attributes = createNodeArray(attributes); return node; } export function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, attributes: JsxAttributeLike[]) { - if (node.tagName !== tagName || node.attributes !== attributes) { - return updateNode(createJsxOpeningElement(tagName, attributes, node), node); - } - return node; + return node.tagName !== tagName + || node.attributes !== attributes + ? updateNode(createJsxOpeningElement(tagName, attributes), node) + : node; } - export function createJsxClosingElement(tagName: JsxTagNameExpression, location?: TextRange) { - const node = createNode(SyntaxKind.JsxClosingElement, location); + export function createJsxClosingElement(tagName: JsxTagNameExpression) { + const node = createSynthesizedNode(SyntaxKind.JsxClosingElement); node.tagName = tagName; return node; } export function updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNameExpression) { - if (node.tagName !== tagName) { - return updateNode(createJsxClosingElement(tagName, node), node); - } - return node; + return node.tagName !== tagName + ? updateNode(createJsxClosingElement(tagName), node) + : node; } - export function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression, location?: TextRange) { - const node = createNode(SyntaxKind.JsxAttribute, location); + export function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression) { + const node = createSynthesizedNode(SyntaxKind.JsxAttribute); node.name = name; node.initializer = initializer; return node; } export function updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral | JsxExpression) { - if (node.name !== name || node.initializer !== initializer) { - return updateNode(createJsxAttribute(name, initializer, node), node); - } - return node; + return node.name !== name + || node.initializer !== initializer + ? updateNode(createJsxAttribute(name, initializer), node) + : node; } - export function createJsxSpreadAttribute(expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.JsxSpreadAttribute, location); + export function createJsxSpreadAttribute(expression: Expression) { + const node = createSynthesizedNode(SyntaxKind.JsxSpreadAttribute); node.expression = expression; return node; } export function updateJsxSpreadAttribute(node: JsxSpreadAttribute, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createJsxSpreadAttribute(expression, node), node); - } - return node; + return node.expression !== expression + ? updateNode(createJsxSpreadAttribute(expression), node) + : node; } - export function createJsxExpression(expression: Expression, dotDotDotToken: Token, location?: TextRange) { - const node = createNode(SyntaxKind.JsxExpression, location); + export function createJsxExpression(expression: Expression, dotDotDotToken: DotDotDotToken) { + const node = createSynthesizedNode(SyntaxKind.JsxExpression); node.dotDotDotToken = dotDotDotToken; node.expression = expression; return node; } export function updateJsxExpression(node: JsxExpression, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createJsxExpression(expression, node.dotDotDotToken, node), node); - } - return node; + return node.expression !== expression + ? updateNode(createJsxExpression(expression, node.dotDotDotToken), node) + : node; } // Clauses - export function createHeritageClause(token: SyntaxKind, types: ExpressionWithTypeArguments[], location?: TextRange) { - const node = createNode(SyntaxKind.HeritageClause, location); + export function createHeritageClause(token: SyntaxKind, types: ExpressionWithTypeArguments[]) { + const node = createSynthesizedNode(SyntaxKind.HeritageClause); node.token = token; node.types = createNodeArray(types); return node; @@ -1342,13 +1471,13 @@ namespace ts { export function updateHeritageClause(node: HeritageClause, types: ExpressionWithTypeArguments[]) { if (node.types !== types) { - return updateNode(createHeritageClause(node.token, types, node), node); + return updateNode(createHeritageClause(node.token, types), node); } return node; } - export function createCaseClause(expression: Expression, statements: Statement[], location?: TextRange) { - const node = createNode(SyntaxKind.CaseClause, location); + export function createCaseClause(expression: Expression, statements: Statement[]) { + const node = createSynthesizedNode(SyntaxKind.CaseClause); node.expression = parenthesizeExpressionForList(expression); node.statements = createNodeArray(statements); return node; @@ -1356,26 +1485,26 @@ namespace ts { export function updateCaseClause(node: CaseClause, expression: Expression, statements: Statement[]) { if (node.expression !== expression || node.statements !== statements) { - return updateNode(createCaseClause(expression, statements, node), node); + return updateNode(createCaseClause(expression, statements), node); } return node; } - export function createDefaultClause(statements: Statement[], location?: TextRange) { - const node = createNode(SyntaxKind.DefaultClause, location); + export function createDefaultClause(statements: Statement[]) { + const node = createSynthesizedNode(SyntaxKind.DefaultClause); node.statements = createNodeArray(statements); return node; } export function updateDefaultClause(node: DefaultClause, statements: Statement[]) { if (node.statements !== statements) { - return updateNode(createDefaultClause(statements, node), node); + return updateNode(createDefaultClause(statements), node); } return node; } - export function createCatchClause(variableDeclaration: string | VariableDeclaration, block: Block, location?: TextRange) { - const node = createNode(SyntaxKind.CatchClause, location); + export function createCatchClause(variableDeclaration: string | VariableDeclaration, block: Block) { + const node = createSynthesizedNode(SyntaxKind.CatchClause); node.variableDeclaration = typeof variableDeclaration === "string" ? createVariableDeclaration(variableDeclaration) : variableDeclaration; node.block = block; return node; @@ -1383,16 +1512,16 @@ namespace ts { export function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration, block: Block) { if (node.variableDeclaration !== variableDeclaration || node.block !== block) { - return updateNode(createCatchClause(variableDeclaration, block, node), node); + return updateNode(createCatchClause(variableDeclaration, block), node); } return node; } // Property assignments - export function createPropertyAssignment(name: string | PropertyName, initializer: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.PropertyAssignment, location); - node.name = typeof name === "string" ? createIdentifier(name) : name; + export function createPropertyAssignment(name: string | PropertyName, initializer: Expression) { + const node = createSynthesizedNode(SyntaxKind.PropertyAssignment); + node.name = asName(name); node.questionToken = undefined; node.initializer = initializer !== undefined ? parenthesizeExpressionForList(initializer) : undefined; return node; @@ -1400,43 +1529,60 @@ namespace ts { export function updatePropertyAssignment(node: PropertyAssignment, name: PropertyName, initializer: Expression) { if (node.name !== name || node.initializer !== initializer) { - return updateNode(createPropertyAssignment(name, initializer, node), node); + return updateNode(createPropertyAssignment(name, initializer), node); } return node; } - export function createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.ShorthandPropertyAssignment, location); - node.name = typeof name === "string" ? createIdentifier(name) : name; + export function createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer: Expression) { + const node = createSynthesizedNode(SyntaxKind.ShorthandPropertyAssignment); + node.name = asName(name); node.objectAssignmentInitializer = objectAssignmentInitializer !== undefined ? parenthesizeExpressionForList(objectAssignmentInitializer) : undefined; return node; } - export function createSpreadAssignment(expression: Expression, location?: TextRange) { - const node = createNode(SyntaxKind.SpreadAssignment, location); + export function createSpreadAssignment(expression: Expression) { + const node = createSynthesizedNode(SyntaxKind.SpreadAssignment); node.expression = expression !== undefined ? parenthesizeExpressionForList(expression) : undefined; return node; } export function updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression) { if (node.name !== name || node.objectAssignmentInitializer !== objectAssignmentInitializer) { - return updateNode(createShorthandPropertyAssignment(name, objectAssignmentInitializer, node), node); + return updateNode(createShorthandPropertyAssignment(name, objectAssignmentInitializer), node); } return node; } export function updateSpreadAssignment(node: SpreadAssignment, expression: Expression) { if (node.expression !== expression) { - return updateNode(createSpreadAssignment(expression, node), node); + return updateNode(createSpreadAssignment(expression), node); } return node; } + // Enum + + export function createEnumMember(name: string | PropertyName, initializer?: Expression) { + const node = createSynthesizedNode(SyntaxKind.EnumMember); + node.name = asName(name); + node.initializer = initializer && parenthesizeExpressionForList(initializer); + return node; + } + + export function updateEnumMember(node: EnumMember, name: PropertyName, initializer: Expression | undefined) { + return node.name !== name + || node.initializer !== initializer + ? updateNode(createEnumMember(name, initializer), node) + : node; + } + // Top-level nodes export function updateSourceFileNode(node: SourceFile, statements: Statement[]) { if (node.statements !== statements) { - const updated = createNode(SyntaxKind.SourceFile, /*location*/ node, node.flags); + const updated = createSynthesizedNode(SyntaxKind.SourceFile); + updated.flags |= node.flags; updated.statements = createNodeArray(statements); updated.endOfFileToken = node.endOfFileToken; updated.fileName = node.fileName; @@ -1472,6 +1618,17 @@ namespace ts { return node; } + /** + * Creates a shallow, memberwise clone of a node for mutation. + */ + export function getMutableClone(node: T): T { + const clone = getSynthesizedClone(node); + clone.pos = node.pos; + clone.end = node.end; + clone.parent = node.parent; + return clone; + } + // Transformation nodes /** @@ -1481,8 +1638,9 @@ namespace ts { * @param original The original statement. */ export function createNotEmittedStatement(original: Node) { - const node = createNode(SyntaxKind.NotEmittedStatement, /*location*/ original); + const node = createSynthesizedNode(SyntaxKind.NotEmittedStatement); node.original = original; + setTextRange(node, original); return node; } @@ -1490,8 +1648,9 @@ namespace ts { * Creates a synthetic element to act as a placeholder for the end of an emitted declaration in * order to properly emit exports. */ + /* @internal */ export function createEndOfDeclarationMarker(original: Node) { - const node = createNode(SyntaxKind.EndOfDeclarationMarker); + const node = createSynthesizedNode(SyntaxKind.EndOfDeclarationMarker); node.emitNode = {}; node.original = original; return node; @@ -1501,8 +1660,9 @@ namespace ts { * Creates a synthetic element to act as a placeholder for the beginning of a merged declaration in * order to properly emit exports. */ + /* @internal */ export function createMergeDeclarationMarker(original: Node) { - const node = createNode(SyntaxKind.MergeDeclarationMarker); + const node = createSynthesizedNode(SyntaxKind.MergeDeclarationMarker); node.emitNode = {}; node.original = original; return node; @@ -1516,16 +1676,30 @@ namespace ts { * @param original The original outer expression. * @param location The location for the expression. Defaults to the positions from "original" if provided. */ - export function createPartiallyEmittedExpression(expression: Expression, original?: Node, location?: TextRange) { - const node = createNode(SyntaxKind.PartiallyEmittedExpression, /*location*/ location || original); + export function createPartiallyEmittedExpression(expression: Expression, original?: Node) { + const node = createSynthesizedNode(SyntaxKind.PartiallyEmittedExpression); node.expression = expression; node.original = original; + setTextRange(node, original); return node; } export function updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression) { if (node.expression !== expression) { - return updateNode(createPartiallyEmittedExpression(expression, node.original, node), node); + return updateNode(createPartiallyEmittedExpression(expression, node.original), node); + } + return node; + } + + export function createBundle(sourceFiles: SourceFile[]) { + const node = createNode(SyntaxKind.Bundle); + node.sourceFiles = sourceFiles; + return node; + } + + export function updateBundle(node: Bundle, sourceFiles: SourceFile[]) { + if (node.sourceFiles !== sourceFiles) { + return createBundle(sourceFiles); } return node; } @@ -1536,14 +1710,14 @@ namespace ts { return createBinary(left, SyntaxKind.CommaToken, right); } - export function createLessThan(left: Expression, right: Expression, location?: TextRange) { - return createBinary(left, SyntaxKind.LessThanToken, right, location); + export function createLessThan(left: Expression, right: Expression) { + return createBinary(left, SyntaxKind.LessThanToken, right); } - export function createAssignment(left: ObjectLiteralExpression | ArrayLiteralExpression, right: Expression, location?: TextRange): DestructuringAssignment; - export function createAssignment(left: Expression, right: Expression, location?: TextRange): BinaryExpression; - export function createAssignment(left: Expression, right: Expression, location?: TextRange) { - return createBinary(left, SyntaxKind.EqualsToken, right, location); + export function createAssignment(left: ObjectLiteralExpression | ArrayLiteralExpression, right: Expression): DestructuringAssignment; + export function createAssignment(left: Expression, right: Expression): BinaryExpression; + export function createAssignment(left: Expression, right: Expression) { + return createBinary(left, SyntaxKind.EqualsToken, right); } export function createStrictEquality(left: Expression, right: Expression) { @@ -1562,8 +1736,8 @@ namespace ts { return createBinary(left, SyntaxKind.MinusToken, right); } - export function createPostfixIncrement(operand: Expression, location?: TextRange) { - return createPostfix(operand, SyntaxKind.PlusPlusToken, location); + export function createPostfixIncrement(operand: Expression) { + return createPostfix(operand, SyntaxKind.PlusPlusToken); } export function createLogicalAnd(left: Expression, right: Expression) { @@ -1582,6 +1756,298 @@ namespace ts { return createVoid(createLiteral(0)); } + export function createExportDefault(expression: Expression) { + return createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportEquals*/ false, expression); + } + + export function createExternalModuleExport(exportName: Identifier) { + return createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([createExportSpecifier(exportName)])); + } + + // Utilities + + function asName(name: string | Identifier): Identifier; + function asName(name: string | BindingName): BindingName; + function asName(name: string | PropertyName): PropertyName; + function asName(name: string | Identifier | BindingName | PropertyName) { + return typeof name === "string" ? createIdentifier(name) : name; + } + + function asExpression(value: string | number | Expression) { + return typeof value === "string" || typeof value === "number" ? createLiteral(value) : value; + } + + function asNodeArray(array: T[] | undefined): NodeArray | undefined { + return array ? createNodeArray(array) : undefined; + } + + function asToken(value: TKind | Token): Token { + return typeof value === "number" ? createToken(value) : value; + } + + /** + * Clears any EmitNode entries from parse-tree nodes. + * @param sourceFile A source file. + */ + export function disposeEmitNodes(sourceFile: SourceFile) { + // During transformation we may need to annotate a parse tree node with transient + // transformation properties. As parse tree nodes live longer than transformation + // nodes, we need to make sure we reclaim any memory allocated for custom ranges + // from these nodes to ensure we do not hold onto entire subtrees just for position + // information. We also need to reset these nodes to a pre-transformation state + // for incremental parsing scenarios so that we do not impact later emit. + sourceFile = getSourceFileOfNode(getParseTreeNode(sourceFile)); + const emitNode = sourceFile && sourceFile.emitNode; + const annotatedNodes = emitNode && emitNode.annotatedNodes; + if (annotatedNodes) { + for (const node of annotatedNodes) { + node.emitNode = undefined; + } + } + } + + /** + * Associates a node with the current transformation, initializing + * various transient transformation properties. + */ + /* @internal */ + export function getOrCreateEmitNode(node: Node) { + if (!node.emitNode) { + if (isParseTreeNode(node)) { + // To avoid holding onto transformation artifacts, we keep track of any + // parse tree node we are annotating. This allows us to clean them up after + // all transformations have completed. + if (node.kind === SyntaxKind.SourceFile) { + return node.emitNode = { annotatedNodes: [node] }; + } + + const sourceFile = getSourceFileOfNode(node); + getOrCreateEmitNode(sourceFile).annotatedNodes.push(node); + } + + node.emitNode = {}; + } + + return node.emitNode; + } + + export function setTextRange(range: T, location: TextRange | undefined): T { + if (location) { + range.pos = location.pos; + range.end = location.end; + } + return range; + } + + /** + * Gets flags that control emit behavior of a node. + */ + export function getEmitFlags(node: Node) { + const emitNode = node.emitNode; + return emitNode && emitNode.flags; + } + + /** + * Sets flags that control emit behavior of a node. + */ + export function setEmitFlags(node: T, emitFlags: EmitFlags) { + getOrCreateEmitNode(node).flags = emitFlags; + return node; + } + + /** + * Gets a custom text range to use when emitting source maps. + */ + export function getSourceMapRange(node: Node) { + const emitNode = node.emitNode; + return (emitNode && emitNode.sourceMapRange) || node; + } + + /** + * Sets a custom text range to use when emitting source maps. + */ + export function setSourceMapRange(node: T, range: TextRange) { + getOrCreateEmitNode(node).sourceMapRange = range; + return node; + } + + /** + * Gets the TextRange to use for source maps for a token of a node. + */ + export function getTokenSourceMapRange(node: Node, token: SyntaxKind) { + const emitNode = node.emitNode; + const tokenSourceMapRanges = emitNode && emitNode.tokenSourceMapRanges; + return tokenSourceMapRanges && tokenSourceMapRanges[token]; + } + + /** + * Sets the TextRange to use for source maps for a token of a node. + */ + export function setTokenSourceMapRange(node: T, token: SyntaxKind, range: TextRange) { + const emitNode = getOrCreateEmitNode(node); + const tokenSourceMapRanges = emitNode.tokenSourceMapRanges || (emitNode.tokenSourceMapRanges = []); + tokenSourceMapRanges[token] = range; + return node; + } + + /** + * Gets a custom text range to use when emitting comments. + */ + export function getCommentRange(node: Node) { + const emitNode = node.emitNode; + return (emitNode && emitNode.commentRange) || node; + } + + /** + * Sets a custom text range to use when emitting comments. + */ + export function setCommentRange(node: T, range: TextRange) { + getOrCreateEmitNode(node).commentRange = range; + return node; + } + + /** + * Gets the constant value to emit for an expression. + */ + export function getConstantValue(node: PropertyAccessExpression | ElementAccessExpression) { + const emitNode = node.emitNode; + return emitNode && emitNode.constantValue; + } + + /** + * Sets the constant value to emit for an expression. + */ + export function setConstantValue(node: PropertyAccessExpression | ElementAccessExpression, value: number) { + const emitNode = getOrCreateEmitNode(node); + emitNode.constantValue = value; + return node; + } + + /** + * Adds an EmitHelper to a node. + */ + export function addEmitHelper(node: T, helper: EmitHelper): T { + const emitNode = getOrCreateEmitNode(node); + emitNode.helpers = append(emitNode.helpers, helper); + return node; + } + + /** + * Add EmitHelpers to a node. + */ + export function addEmitHelpers(node: T, helpers: EmitHelper[] | undefined): T { + if (some(helpers)) { + const emitNode = getOrCreateEmitNode(node); + for (const helper of helpers) { + if (!contains(emitNode.helpers, helper)) { + emitNode.helpers = append(emitNode.helpers, helper); + } + } + } + return node; + } + + /** + * Removes an EmitHelper from a node. + */ + export function removeEmitHelper(node: Node, helper: EmitHelper): boolean { + const emitNode = node.emitNode; + if (emitNode) { + const helpers = emitNode.helpers; + if (helpers) { + return orderedRemoveItem(helpers, helper); + } + } + return false; + } + + /** + * Gets the EmitHelpers of a node. + */ + export function getEmitHelpers(node: Node): EmitHelper[] | undefined { + const emitNode = node.emitNode; + return emitNode && emitNode.helpers; + } + + /** + * Moves matching emit helpers from a source node to a target node. + */ + export function moveEmitHelpers(source: Node, target: Node, predicate: (helper: EmitHelper) => boolean) { + const sourceEmitNode = source.emitNode; + const sourceEmitHelpers = sourceEmitNode && sourceEmitNode.helpers; + if (!some(sourceEmitHelpers)) return; + + const targetEmitNode = getOrCreateEmitNode(target); + let helpersRemoved = 0; + for (let i = 0; i < sourceEmitHelpers.length; i++) { + const helper = sourceEmitHelpers[i]; + if (predicate(helper)) { + helpersRemoved++; + if (!contains(targetEmitNode.helpers, helper)) { + targetEmitNode.helpers = append(targetEmitNode.helpers, helper); + } + } + else if (helpersRemoved > 0) { + sourceEmitHelpers[i - helpersRemoved] = helper; + } + } + + if (helpersRemoved > 0) { + sourceEmitHelpers.length -= helpersRemoved; + } + } + + /* @internal */ + export function compareEmitHelpers(x: EmitHelper, y: EmitHelper) { + if (x === y) return Comparison.EqualTo; + if (x.priority === y.priority) return Comparison.EqualTo; + if (x.priority === undefined) return Comparison.GreaterThan; + if (y.priority === undefined) return Comparison.LessThan; + return compareValues(x.priority, y.priority); + } + + export function setOriginalNode(node: T, original: Node): T { + node.original = original; + if (original) { + const emitNode = original.emitNode; + if (emitNode) node.emitNode = mergeEmitNode(emitNode, node.emitNode); + } + return node; + } + + function mergeEmitNode(sourceEmitNode: EmitNode, destEmitNode: EmitNode) { + const { + flags, + commentRange, + sourceMapRange, + tokenSourceMapRanges, + constantValue, + helpers + } = sourceEmitNode; + if (!destEmitNode) destEmitNode = {}; + if (flags) destEmitNode.flags = flags; + if (commentRange) destEmitNode.commentRange = commentRange; + if (sourceMapRange) destEmitNode.sourceMapRange = sourceMapRange; + if (tokenSourceMapRanges) destEmitNode.tokenSourceMapRanges = mergeTokenSourceMapRanges(tokenSourceMapRanges, destEmitNode.tokenSourceMapRanges); + if (constantValue !== undefined) destEmitNode.constantValue = constantValue; + if (helpers) destEmitNode.helpers = addRange(destEmitNode.helpers, helpers); + return destEmitNode; + } + + function mergeTokenSourceMapRanges(sourceRanges: TextRange[], destRanges: TextRange[]) { + if (!destRanges) destRanges = []; + for (const key in sourceRanges) { + destRanges[key] = sourceRanges[key]; + } + return destRanges; + } +} + +/* @internal */ +namespace ts { + + // Compound nodes + export type TypeOfTag = "undefined" | "number" | "boolean" | "string" | "symbol" | "object" | "function"; export function createTypeCheck(value: Expression, tag: TypeOfTag) { @@ -1592,35 +2058,43 @@ namespace ts { export function createMemberAccessForPropertyName(target: Expression, memberName: PropertyName, location?: TextRange): MemberExpression { if (isComputedPropertyName(memberName)) { - return createElementAccess(target, memberName.expression, location); + return setTextRange(createElementAccess(target, memberName.expression), location); } else { - const expression = isIdentifier(memberName) ? createPropertyAccess(target, memberName, location) : createElementAccess(target, memberName, location); - (expression.emitNode || (expression.emitNode = {})).flags |= EmitFlags.NoNestedSourceMaps; + const expression = setTextRange( + isIdentifier(memberName) + ? createPropertyAccess(target, memberName) + : createElementAccess(target, memberName), + memberName + ); + getOrCreateEmitNode(expression).flags |= EmitFlags.NoNestedSourceMaps; return expression; } } export function createFunctionCall(func: Expression, thisArg: Expression, argumentsList: Expression[], location?: TextRange) { - return createCall( - createPropertyAccess(func, "call"), - /*typeArguments*/ undefined, - [ - thisArg, - ...argumentsList - ], + return setTextRange( + createCall( + createPropertyAccess(func, "call"), + /*typeArguments*/ undefined, + [ + thisArg, + ...argumentsList + ]), location ); } export function createFunctionApply(func: Expression, thisArg: Expression, argumentsExpression: Expression, location?: TextRange) { - return createCall( - createPropertyAccess(func, "apply"), - /*typeArguments*/ undefined, - [ - thisArg, - argumentsExpression - ], + return setTextRange( + createCall( + createPropertyAccess(func, "apply"), + /*typeArguments*/ undefined, + [ + thisArg, + argumentsExpression + ] + ), location ); } @@ -1643,10 +2117,12 @@ namespace ts { } export function createMathPow(left: Expression, right: Expression, location?: TextRange) { - return createCall( - createPropertyAccess(createIdentifier("Math"), "pow"), - /*typeArguments*/ undefined, - [left, right], + return setTextRange( + createCall( + createPropertyAccess(createIdentifier("Math"), "pow"), + /*typeArguments*/ undefined, + [left, right] + ), location ); } @@ -1666,7 +2142,7 @@ namespace ts { function createJsxFactoryExpressionFromEntityName(jsxFactory: EntityName, parent: JsxOpeningLikeElement): Expression { if (isQualifiedName(jsxFactory)) { const left = createJsxFactoryExpressionFromEntityName(jsxFactory.left, parent); - const right = createSynthesizedNode(SyntaxKind.Identifier); + const right = createIdentifier(jsxFactory.right.text); right.text = jsxFactory.right.text; return createPropertyAccess(left, right); } @@ -1706,34 +2182,16 @@ namespace ts { } } - return createCall( - createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parentElement), - /*typeArguments*/ undefined, - argumentsList, + return setTextRange( + createCall( + createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parentElement), + /*typeArguments*/ undefined, + argumentsList + ), location ); } - export function createExportDefault(expression: Expression) { - return createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportEquals*/ false, expression); - } - - export function createExternalModuleExport(exportName: Identifier) { - return createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([createExportSpecifier(exportName)])); - } - - export function createLetStatement(name: Identifier, initializer: Expression, location?: TextRange) { - return createVariableStatement(/*modifiers*/ undefined, createLetDeclarationList([createVariableDeclaration(name, /*type*/ undefined, initializer)]), location); - } - - export function createLetDeclarationList(declarations: VariableDeclaration[], location?: TextRange) { - return createVariableDeclarationList(declarations, location, NodeFlags.Let); - } - - export function createConstDeclarationList(declarations: VariableDeclaration[], location?: TextRange) { - return createVariableDeclarationList(declarations, location, NodeFlags.Const); - } - // Helpers export function getHelperName(name: string) { @@ -1796,7 +2254,9 @@ namespace ts { } else if (callee.kind === SyntaxKind.SuperKeyword) { thisArg = createThis(); - target = languageVersion < ScriptTarget.ES2015 ? createIdentifier("_super", /*location*/ callee) : callee; + target = languageVersion < ScriptTarget.ES2015 + ? setTextRange(createIdentifier("_super"), callee) + : callee; } else { switch (callee.kind) { @@ -1805,14 +2265,16 @@ namespace ts { // for `a.b()` target is `(_a = a).b` and thisArg is `_a` thisArg = createTempVariable(recordTempVariable); target = createPropertyAccess( - createAssignment( - thisArg, - (callee).expression, - /*location*/ (callee).expression + setTextRange( + createAssignment( + thisArg, + (callee).expression + ), + (callee).expression ), - (callee).name, - /*location*/ callee + (callee).name ); + setTextRange(target, callee); } else { thisArg = (callee).expression; @@ -1826,14 +2288,16 @@ namespace ts { // for `a[b]()` target is `(_a = a)[b]` and thisArg is `_a` thisArg = createTempVariable(recordTempVariable); target = createElementAccess( - createAssignment( - thisArg, - (callee).expression, - /*location*/ (callee).expression + setTextRange( + createAssignment( + thisArg, + (callee).expression + ), + (callee).expression ), - (callee).argumentExpression, - /*location*/ callee + (callee).argumentExpression ); + setTextRange(target, callee); } else { thisArg = (callee).expression; @@ -1863,7 +2327,7 @@ namespace ts { if (isQualifiedName(node)) { const left = createExpressionFromEntityName(node.left); const right = getMutableClone(node.right); - return createPropertyAccess(left, right, /*location*/ node); + return setTextRange(createPropertyAccess(left, right), node); } else { return getMutableClone(node); @@ -1872,7 +2336,7 @@ namespace ts { export function createExpressionForPropertyName(memberName: PropertyName): Expression { if (isIdentifier(memberName)) { - return createLiteral(memberName, /*location*/ undefined); + return createLiteral(memberName); } else if (isComputedPropertyName(memberName)) { return getMutableClone(memberName.expression); @@ -1908,9 +2372,9 @@ namespace ts { /*typeParameters*/ undefined, getAccessor.parameters, /*type*/ undefined, - getAccessor.body, - /*location*/ getAccessor + getAccessor.body ); + setTextRange(getterFunction, getAccessor); setOriginalNode(getterFunction, getAccessor); const getter = createPropertyAssignment("get", getterFunction); properties.push(getter); @@ -1924,25 +2388,27 @@ namespace ts { /*typeParameters*/ undefined, setAccessor.parameters, /*type*/ undefined, - setAccessor.body, - /*location*/ setAccessor + setAccessor.body ); + setTextRange(setterFunction, setAccessor); setOriginalNode(setterFunction, setAccessor); const setter = createPropertyAssignment("set", setterFunction); properties.push(setter); } - properties.push(createPropertyAssignment("enumerable", createLiteral(true))); - properties.push(createPropertyAssignment("configurable", createLiteral(true))); + properties.push(createPropertyAssignment("enumerable", createTrue())); + properties.push(createPropertyAssignment("configurable", createTrue())); - const expression = createCall( - createPropertyAccess(createIdentifier("Object"), "defineProperty"), - /*typeArguments*/ undefined, - [ - receiver, - createExpressionForPropertyName(property.name), - createObjectLiteral(properties, /*location*/ undefined, multiLine) - ], + const expression = setTextRange( + createCall( + createPropertyAccess(createIdentifier("Object"), "defineProperty"), + /*typeArguments*/ undefined, + [ + receiver, + createExpressionForPropertyName(property.name), + createObjectLiteral(properties, multiLine) + ] + ), /*location*/ firstAccessor ); @@ -1955,12 +2421,14 @@ namespace ts { function createExpressionForPropertyAssignment(property: PropertyAssignment, receiver: Expression) { return aggregateTransformFlags( setOriginalNode( - createAssignment( - createMemberAccessForPropertyName(receiver, property.name, /*location*/ property.name), - property.initializer, - /*location*/ property + setTextRange( + createAssignment( + createMemberAccessForPropertyName(receiver, property.name, /*location*/ property.name), + property.initializer + ), + property ), - /*original*/ property + property ) ); } @@ -1968,9 +2436,11 @@ namespace ts { function createExpressionForShorthandPropertyAssignment(property: ShorthandPropertyAssignment, receiver: Expression) { return aggregateTransformFlags( setOriginalNode( - createAssignment( - createMemberAccessForPropertyName(receiver, property.name, /*location*/ property.name), - getSynthesizedClone(property.name), + setTextRange( + createAssignment( + createMemberAccessForPropertyName(receiver, property.name, /*location*/ property.name), + getSynthesizedClone(property.name) + ), /*location*/ property ), /*original*/ property @@ -1981,20 +2451,24 @@ namespace ts { function createExpressionForMethodDeclaration(method: MethodDeclaration, receiver: Expression) { return aggregateTransformFlags( setOriginalNode( - createAssignment( - createMemberAccessForPropertyName(receiver, method.name, /*location*/ method.name), - setOriginalNode( - createFunctionExpression( - method.modifiers, - method.asteriskToken, - /*name*/ undefined, - /*typeParameters*/ undefined, - method.parameters, - /*type*/ undefined, - method.body, - /*location*/ method - ), - /*original*/ method + setTextRange( + createAssignment( + createMemberAccessForPropertyName(receiver, method.name, /*location*/ method.name), + setOriginalNode( + setTextRange( + createFunctionExpression( + method.modifiers, + method.asteriskToken, + /*name*/ undefined, + /*typeParameters*/ undefined, + method.parameters, + /*type*/ undefined, + method.body + ), + /*location*/ method + ), + /*original*/ method + ) ), /*location*/ method ), @@ -2096,7 +2570,8 @@ namespace ts { * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. */ export function getNamespaceMemberName(ns: Identifier, name: Identifier, allowComments?: boolean, allowSourceMaps?: boolean): PropertyAccessExpression { - const qualifiedName = createPropertyAccess(ns, nodeIsSynthesized(name) ? name : getSynthesizedClone(name), /*location*/ name); + const qualifiedName = createPropertyAccess(ns, nodeIsSynthesized(name) ? name : getSynthesizedClone(name)); + setTextRange(qualifiedName, name); let emitFlags: EmitFlags; if (!allowSourceMaps) emitFlags |= EmitFlags.NoSourceMap; if (!allowComments) emitFlags |= EmitFlags.NoComments; @@ -2105,7 +2580,7 @@ namespace ts { } export function convertToFunctionBody(node: ConciseBody, multiLine?: boolean) { - return isBlock(node) ? node : createBlock([createReturn(node, /*location*/ node)], /*location*/ node, multiLine); + return isBlock(node) ? node : setTextRange(createBlock([setTextRange(createReturn(node), node)], multiLine), node); } function isUseStrictPrologue(node: ExpressionStatement): boolean { @@ -2184,10 +2659,13 @@ namespace ts { } if (!foundUseStrict) { - return createNodeArray([ - startOnNewLine(createStatement(createLiteral("use strict"))), - ...statements - ], statements); + return setTextRange( + createNodeArray([ + startOnNewLine(createStatement(createLiteral("use strict"))), + ...statements + ]), + statements + ); } return statements; @@ -2380,7 +2858,7 @@ namespace ts { return condition; } - function parenthesizeSubexpressionOfConditionalExpression(e: Expression): Expression { + export function parenthesizeSubexpressionOfConditionalExpression(e: Expression): Expression { // per ES grammar both 'whenTrue' and 'whenFalse' parts of conditional expression are assignment expressions // so in case when comma expression is introduced as a part of previous transformations // if should be wrapped in parens since comma operator has the lowest precedence @@ -2432,22 +2910,22 @@ namespace ts { return expression; } - return createParen(expression, /*location*/ expression); + return setTextRange(createParen(expression), expression); } export function parenthesizePostfixOperand(operand: Expression) { return isLeftHandSideExpression(operand) ? operand - : createParen(operand, /*location*/ operand); + : setTextRange(createParen(operand), operand); } export function parenthesizePrefixOperand(operand: Expression) { return isUnaryExpression(operand) ? operand - : createParen(operand, /*location*/ operand); + : setTextRange(createParen(operand), operand); } - function parenthesizeListElements(elements: NodeArray) { + export function parenthesizeListElements(elements: NodeArray) { let result: Expression[]; for (let i = 0; i < elements.length; i++) { const element = parenthesizeExpressionForList(elements[i]); @@ -2461,7 +2939,7 @@ namespace ts { } if (result !== undefined) { - return createNodeArray(result, elements, elements.hasTrailingComma); + return setTextRange(createNodeArray(result, elements.hasTrailingComma), elements); } return elements; @@ -2473,7 +2951,7 @@ namespace ts { const commaPrecedence = getOperatorPrecedence(SyntaxKind.BinaryExpression, SyntaxKind.CommaToken); return expressionPrecedence > commaPrecedence ? expression - : createParen(expression, /*location*/ expression); + : setTextRange(createParen(expression), expression); } export function parenthesizeExpressionForExpressionStatement(expression: Expression) { @@ -2483,14 +2961,14 @@ namespace ts { const kind = skipPartiallyEmittedExpressions(callee).kind; if (kind === SyntaxKind.FunctionExpression || kind === SyntaxKind.ArrowFunction) { const mutableCall = getMutableClone(emittedExpression); - mutableCall.expression = createParen(callee, /*location*/ callee); + mutableCall.expression = setTextRange(createParen(callee), callee); return recreatePartiallyEmittedExpressions(expression, mutableCall); } } else { const leftmostExpressionKind = getLeftmostExpression(emittedExpression).kind; if (leftmostExpressionKind === SyntaxKind.ObjectLiteralExpression || leftmostExpressionKind === SyntaxKind.FunctionExpression) { - return createParen(expression, /*location*/ expression); + return setTextRange(createParen(expression), expression); } } @@ -2546,7 +3024,7 @@ namespace ts { export function parenthesizeConciseBody(body: ConciseBody): ConciseBody { const emittedBody = skipPartiallyEmittedExpressions(body); if (emittedBody.kind === SyntaxKind.ObjectLiteralExpression) { - return createParen(body, /*location*/ body); + return setTextRange(createParen(body), body); } return body; @@ -2618,192 +3096,6 @@ namespace ts { return node; } - export function setOriginalNode(node: T, original: Node): T { - node.original = original; - if (original) { - const emitNode = original.emitNode; - if (emitNode) node.emitNode = mergeEmitNode(emitNode, node.emitNode); - } - return node; - } - - function mergeEmitNode(sourceEmitNode: EmitNode, destEmitNode: EmitNode) { - const { - flags, - commentRange, - sourceMapRange, - tokenSourceMapRanges, - constantValue, - helpers - } = sourceEmitNode; - if (!destEmitNode) destEmitNode = {}; - if (flags) destEmitNode.flags = flags; - if (commentRange) destEmitNode.commentRange = commentRange; - if (sourceMapRange) destEmitNode.sourceMapRange = sourceMapRange; - if (tokenSourceMapRanges) destEmitNode.tokenSourceMapRanges = mergeTokenSourceMapRanges(tokenSourceMapRanges, destEmitNode.tokenSourceMapRanges); - if (constantValue !== undefined) destEmitNode.constantValue = constantValue; - if (helpers) destEmitNode.helpers = addRange(destEmitNode.helpers, helpers); - return destEmitNode; - } - - function mergeTokenSourceMapRanges(sourceRanges: TextRange[], destRanges: TextRange[]) { - if (!destRanges) destRanges = []; - for (const key in sourceRanges) { - destRanges[key] = sourceRanges[key]; - } - return destRanges; - } - - /** - * Clears any EmitNode entries from parse-tree nodes. - * @param sourceFile A source file. - */ - export function disposeEmitNodes(sourceFile: SourceFile) { - // During transformation we may need to annotate a parse tree node with transient - // transformation properties. As parse tree nodes live longer than transformation - // nodes, we need to make sure we reclaim any memory allocated for custom ranges - // from these nodes to ensure we do not hold onto entire subtrees just for position - // information. We also need to reset these nodes to a pre-transformation state - // for incremental parsing scenarios so that we do not impact later emit. - sourceFile = getSourceFileOfNode(getParseTreeNode(sourceFile)); - const emitNode = sourceFile && sourceFile.emitNode; - const annotatedNodes = emitNode && emitNode.annotatedNodes; - if (annotatedNodes) { - for (const node of annotatedNodes) { - node.emitNode = undefined; - } - } - } - - /** - * Associates a node with the current transformation, initializing - * various transient transformation properties. - * - * @param node The node. - */ - export function getOrCreateEmitNode(node: Node) { - if (!node.emitNode) { - if (isParseTreeNode(node)) { - // To avoid holding onto transformation artifacts, we keep track of any - // parse tree node we are annotating. This allows us to clean them up after - // all transformations have completed. - if (node.kind === SyntaxKind.SourceFile) { - return node.emitNode = { annotatedNodes: [node] }; - } - - const sourceFile = getSourceFileOfNode(node); - getOrCreateEmitNode(sourceFile).annotatedNodes.push(node); - } - - node.emitNode = {}; - } - - return node.emitNode; - } - - /** - * Gets flags that control emit behavior of a node. - * - * @param node The node. - */ - export function getEmitFlags(node: Node) { - const emitNode = node.emitNode; - return emitNode && emitNode.flags; - } - - /** - * Sets flags that control emit behavior of a node. - * - * @param node The node. - * @param emitFlags The NodeEmitFlags for the node. - */ - export function setEmitFlags(node: T, emitFlags: EmitFlags) { - getOrCreateEmitNode(node).flags = emitFlags; - return node; - } - - /** - * Gets a custom text range to use when emitting source maps. - * - * @param node The node. - */ - export function getSourceMapRange(node: Node) { - const emitNode = node.emitNode; - return (emitNode && emitNode.sourceMapRange) || node; - } - - /** - * Sets a custom text range to use when emitting source maps. - * - * @param node The node. - * @param range The text range. - */ - export function setSourceMapRange(node: T, range: TextRange) { - getOrCreateEmitNode(node).sourceMapRange = range; - return node; - } - - /** - * Gets the TextRange to use for source maps for a token of a node. - * - * @param node The node. - * @param token The token. - */ - export function getTokenSourceMapRange(node: Node, token: SyntaxKind) { - const emitNode = node.emitNode; - const tokenSourceMapRanges = emitNode && emitNode.tokenSourceMapRanges; - return tokenSourceMapRanges && tokenSourceMapRanges[token]; - } - - /** - * Sets the TextRange to use for source maps for a token of a node. - * - * @param node The node. - * @param token The token. - * @param range The text range. - */ - export function setTokenSourceMapRange(node: T, token: SyntaxKind, range: TextRange) { - const emitNode = getOrCreateEmitNode(node); - const tokenSourceMapRanges = emitNode.tokenSourceMapRanges || (emitNode.tokenSourceMapRanges = []); - tokenSourceMapRanges[token] = range; - return node; - } - - /** - * Gets a custom text range to use when emitting comments. - * - * @param node The node. - */ - export function getCommentRange(node: Node) { - const emitNode = node.emitNode; - return (emitNode && emitNode.commentRange) || node; - } - - /** - * Sets a custom text range to use when emitting comments. - */ - export function setCommentRange(node: T, range: TextRange) { - getOrCreateEmitNode(node).commentRange = range; - return node; - } - - /** - * Gets the constant value to emit for an expression. - */ - export function getConstantValue(node: PropertyAccessExpression | ElementAccessExpression) { - const emitNode = node.emitNode; - return emitNode && emitNode.constantValue; - } - - /** - * Sets the constant value to emit for an expression. - */ - export function setConstantValue(node: PropertyAccessExpression | ElementAccessExpression, value: number) { - const emitNode = getOrCreateEmitNode(node); - emitNode.constantValue = value; - return node; - } - export function getExternalHelpersModuleName(node: SourceFile) { const parseNode = getOriginalNode(node, isSourceFile); const emitNode = parseNode && parseNode.emitNode; @@ -2829,110 +3121,6 @@ namespace ts { } } } - /** - * Adds an EmitHelper to a node. - */ - export function addEmitHelper(node: T, helper: EmitHelper): T { - const emitNode = getOrCreateEmitNode(node); - emitNode.helpers = append(emitNode.helpers, helper); - return node; - } - - /** - * Adds an EmitHelper to a node. - */ - export function addEmitHelpers(node: T, helpers: EmitHelper[] | undefined): T { - if (some(helpers)) { - const emitNode = getOrCreateEmitNode(node); - for (const helper of helpers) { - if (!contains(emitNode.helpers, helper)) { - emitNode.helpers = append(emitNode.helpers, helper); - } - } - } - return node; - } - - /** - * Removes an EmitHelper from a node. - */ - export function removeEmitHelper(node: Node, helper: EmitHelper): boolean { - const emitNode = node.emitNode; - if (emitNode) { - const helpers = emitNode.helpers; - if (helpers) { - return orderedRemoveItem(helpers, helper); - } - } - return false; - } - - /** - * Gets the EmitHelpers of a node. - */ - export function getEmitHelpers(node: Node): EmitHelper[] | undefined { - const emitNode = node.emitNode; - return emitNode && emitNode.helpers; - } - - /** - * Moves matching emit helpers from a source node to a target node. - */ - export function moveEmitHelpers(source: Node, target: Node, predicate: (helper: EmitHelper) => boolean) { - const sourceEmitNode = source.emitNode; - const sourceEmitHelpers = sourceEmitNode && sourceEmitNode.helpers; - if (!some(sourceEmitHelpers)) return; - - const targetEmitNode = getOrCreateEmitNode(target); - let helpersRemoved = 0; - for (let i = 0; i < sourceEmitHelpers.length; i++) { - const helper = sourceEmitHelpers[i]; - if (predicate(helper)) { - helpersRemoved++; - if (!contains(targetEmitNode.helpers, helper)) { - targetEmitNode.helpers = append(targetEmitNode.helpers, helper); - } - } - else if (helpersRemoved > 0) { - sourceEmitHelpers[i - helpersRemoved] = helper; - } - } - - if (helpersRemoved > 0) { - sourceEmitHelpers.length -= helpersRemoved; - } - } - - export function compareEmitHelpers(x: EmitHelper, y: EmitHelper) { - if (x === y) return Comparison.EqualTo; - if (x.priority === y.priority) return Comparison.EqualTo; - if (x.priority === undefined) return Comparison.GreaterThan; - if (y.priority === undefined) return Comparison.LessThan; - return compareValues(x.priority, y.priority); - } - - export function setTextRange(node: T, location: TextRange): T { - if (location) { - node.pos = location.pos; - node.end = location.end; - } - return node; - } - - export function setNodeFlags(node: T, flags: NodeFlags): T { - node.flags = flags; - return node; - } - - export function setMultiLine(node: T, multiLine: boolean): T { - node.multiLine = multiLine; - return node; - } - - export function setHasTrailingComma(nodes: NodeArray, hasTrailingComma: boolean): NodeArray { - nodes.hasTrailingComma = hasTrailingComma; - return nodes; - } /** * Get the name of that target module from an import or export declaration @@ -3210,10 +3398,18 @@ namespace ts { if (isBindingElement(element)) { if (element.dotDotDotToken) { Debug.assertNode(element.name, isIdentifier); - return setOriginalNode(createSpread(element.name, element), element); + return setOriginalNode(setTextRange(createSpread(element.name), element), element); } const expression = convertToAssignmentElementTarget(element.name); - return element.initializer ? setOriginalNode(createAssignment(expression, element.initializer, element), element) : expression; + return element.initializer + ? setOriginalNode( + setTextRange( + createAssignment(expression, element.initializer), + element + ), + element + ) + : expression; } Debug.assertNode(element, isExpression); return element; @@ -3223,14 +3419,14 @@ namespace ts { if (isBindingElement(element)) { if (element.dotDotDotToken) { Debug.assertNode(element.name, isIdentifier); - return setOriginalNode(createSpreadAssignment(element.name, element), element); + return setOriginalNode(setTextRange(createSpreadAssignment(element.name), element), element); } if (element.propertyName) { const expression = convertToAssignmentElementTarget(element.name); - return setOriginalNode(createPropertyAssignment(element.propertyName, element.initializer ? createAssignment(expression, element.initializer) : expression, element), element); + return setOriginalNode(setTextRange(createPropertyAssignment(element.propertyName, element.initializer ? createAssignment(expression, element.initializer) : expression), element), element); } Debug.assertNode(element.name, isIdentifier); - return setOriginalNode(createShorthandPropertyAssignment(element.name, element.initializer, element), element); + return setOriginalNode(setTextRange(createShorthandPropertyAssignment(element.name, element.initializer), element), element); } Debug.assertNode(element, isObjectLiteralElementLike); return element; @@ -3250,7 +3446,13 @@ namespace ts { export function convertToObjectAssignmentPattern(node: ObjectBindingOrAssignmentPattern) { if (isObjectBindingPattern(node)) { - return setOriginalNode(createObjectLiteral(map(node.elements, convertToObjectAssignmentElement), node), node); + return setOriginalNode( + setTextRange( + createObjectLiteral(map(node.elements, convertToObjectAssignmentElement)), + node + ), + node + ); } Debug.assertNode(node, isObjectLiteralExpression); return node; @@ -3258,7 +3460,13 @@ namespace ts { export function convertToArrayAssignmentPattern(node: ArrayBindingOrAssignmentPattern) { if (isArrayBindingPattern(node)) { - return setOriginalNode(createArrayLiteral(map(node.elements, convertToArrayAssignmentElement), node), node); + return setOriginalNode( + setTextRange( + createArrayLiteral(map(node.elements, convertToArrayAssignmentElement)), + node + ), + node + ); } Debug.assertNode(node, isArrayLiteralExpression); return node; diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 650711afc79..62f3c066442 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1152,13 +1152,10 @@ namespace ts { && (options.isolatedModules || isExternalModuleFile) && !file.isDeclarationFile) { // synthesize 'import "tslib"' declaration - const externalHelpersModuleReference = createSynthesizedNode(SyntaxKind.StringLiteral); - externalHelpersModuleReference.text = externalHelpersModuleNameText; - const importDecl = createSynthesizedNode(SyntaxKind.ImportDeclaration); - - importDecl.parent = file; + const externalHelpersModuleReference = createLiteral(externalHelpersModuleNameText); + const importDecl = createImportDeclaration(undefined, undefined, undefined); externalHelpersModuleReference.parent = importDecl; - + importDecl.parent = file; imports = [externalHelpersModuleReference]; } diff --git a/src/compiler/sourcemap.ts b/src/compiler/sourcemap.ts index 650b9b0ef02..d743f488e75 100644 --- a/src/compiler/sourcemap.ts +++ b/src/compiler/sourcemap.ts @@ -8,10 +8,9 @@ namespace ts { * * @param filePath The path to the generated output file. * @param sourceMapFilePath The path to the output source map file. - * @param sourceFiles The input source files for the program. - * @param isBundledEmit A value indicating whether the generated output file is a bundle. + * @param sourceFileOrBundle The input source file or bundle for the program. */ - initialize(filePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean): void; + initialize(filePath: string, sourceMapFilePath: string, sourceFileOrBundle: SourceFile | Bundle): void; /** * Reset the SourceMapWriter to an empty state. @@ -38,11 +37,11 @@ namespace ts { /** * Emits a node with possible leading and trailing source maps. * - * @param emitContext The current emit context + * @param hint The current emit context * @param node The node to emit. * @param emitCallback The callback used to emit the node. */ - emitNodeWithSourceMap(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void; + emitNodeWithSourceMap(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void; /** * Emits a token of a node node with possible leading and trailing source maps. @@ -115,10 +114,9 @@ namespace ts { * * @param filePath The path to the generated output file. * @param sourceMapFilePath The path to the output source map file. - * @param sourceFiles The input source files for the program. - * @param isBundledEmit A value indicating whether the generated output file is a bundle. + * @param sourceFileOrBundle The input source file or bundle for the program. */ - function initialize(filePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) { + function initialize(filePath: string, sourceMapFilePath: string, sourceFileOrBundle: SourceFile | Bundle) { if (disabled) { return; } @@ -161,11 +159,10 @@ namespace ts { if (compilerOptions.mapRoot) { sourceMapDir = normalizeSlashes(compilerOptions.mapRoot); - if (!isBundledEmit) { // emitting single module file - Debug.assert(sourceFiles.length === 1); + if (sourceFileOrBundle.kind === SyntaxKind.SourceFile) { // emitting single module file // For modules or multiple emit files the mapRoot will have directory structure like the sources // So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map - sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFiles[0], host, sourceMapDir)); + sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFileOrBundle, host, sourceMapDir)); } if (!isRootedDiskPath(sourceMapDir) && !isUrl(sourceMapDir)) { @@ -311,12 +308,13 @@ namespace ts { /** * Emits a node with possible leading and trailing source maps. * + * @param hint A hint as to the intended usage of the node. * @param node The node to emit. * @param emitCallback The callback used to emit the node. */ - function emitNodeWithSourceMap(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) { + function emitNodeWithSourceMap(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) { if (disabled) { - return emitCallback(emitContext, node); + return emitCallback(hint, node); } if (node) { @@ -332,11 +330,11 @@ namespace ts { if (emitFlags & EmitFlags.NoNestedSourceMaps) { disabled = true; - emitCallback(emitContext, node); + emitCallback(hint, node); disabled = false; } else { - emitCallback(emitContext, node); + emitCallback(hint, node); } if (node.kind !== SyntaxKind.NotEmittedStatement diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index cef8c701455..62469df79c1 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -105,14 +105,16 @@ namespace ts { hoistFunctionDeclaration, requestEmitHelper, readEmitHelpers, - onSubstituteNode: (_emitContext, node) => node, + onSubstituteNode: (_, node) => node, enableSubstitution, isSubstitutionEnabled, - onEmitNode: (node, emitContext, emitCallback) => emitCallback(node, emitContext), + onEmitNode: (hint, node, callback) => callback(hint, node), enableEmitNotification, isEmitNotificationEnabled }; + performance.mark("beforeTransform"); + // Chain together and initialize each transformer. const transformation = chain(...transformers)(context); @@ -122,6 +124,9 @@ namespace ts { // Disable modification of the lexical environment. lexicalEnvironmentDisabled = true; + performance.mark("afterTransform"); + performance.measure("transformTime", "beforeTransform", "afterTransform"); + return { transformed, emitNodeWithSubstitution, @@ -159,21 +164,16 @@ namespace ts { /** * Emits a node with possible substitution. * - * @param emitContext The current emit context. + * @param hint A hint as to the intended usage of the node. * @param node The node to emit. * @param emitCallback The callback used to emit the node or its substitute. */ - function emitNodeWithSubstitution(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) { + function emitNodeWithSubstitution(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) { if (node) { if (isSubstitutionEnabled(node)) { - const substitute = context.onSubstituteNode(emitContext, node); - if (substitute && substitute !== node) { - emitCallback(emitContext, substitute); - return; - } + node = context.onSubstituteNode(hint, node) || node; } - - emitCallback(emitContext, node); + emitCallback(hint, node); } } @@ -196,17 +196,17 @@ namespace ts { /** * Emits a node with possible emit notification. * - * @param emitContext The current emit context. + * @param hint A hint as to the intended usage of the node. * @param node The node to emit. * @param emitCallback The callback used to emit the node. */ - function emitNodeWithNotification(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) { + function emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) { if (node) { if (isEmitNotificationEnabled(node)) { - context.onEmitNode(emitContext, node, emitCallback); + context.onEmitNode(hint, node, emitCallback); } else { - emitCallback(emitContext, node); + emitCallback(hint, node); } } } diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index 8e32259ff0f..b4473e6a261 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -112,7 +112,10 @@ namespace ts { Debug.assertNode(target, createAssignmentCallback ? isIdentifier : isExpression); const expression = createAssignmentCallback ? createAssignmentCallback(target, value, location) - : createAssignment(visitNode(target, visitor, isExpression), value, location); + : setTextRange( + createAssignment(visitNode(target, visitor, isExpression), value), + location + ); expression.original = original; emitExpression(expression); } @@ -174,9 +177,10 @@ namespace ts { const variable = createVariableDeclaration( name, /*type*/ undefined, - pendingExpressions ? inlineExpressions(append(pendingExpressions, value)) : value, - location); + pendingExpressions ? inlineExpressions(append(pendingExpressions, value)) : value + ); variable.original = original; + setTextRange(variable, location); if (isIdentifier(name)) { setEmitFlags(variable, EmitFlags.NoNestedSourceMaps); } @@ -416,7 +420,7 @@ namespace ts { const temp = createTempVariable(/*recordTempVariable*/ undefined); if (flattenContext.hoistTempVariables) { flattenContext.context.hoistVariableDeclaration(temp); - flattenContext.emitExpression(createAssignment(temp, value, location)); + flattenContext.emitExpression(setTextRange(createAssignment(temp, value), location)); } else { flattenContext.emitBindingOrAssignment(temp, value, location, /*original*/ undefined); @@ -492,6 +496,15 @@ namespace ts { } } } - return createCall(getHelperName("__rest"), undefined, [value, createArrayLiteral(propertyNames, location)]); + return createCall( + getHelperName("__rest"), + undefined, + [ + value, + setTextRange( + createArrayLiteral(propertyNames), + location + ) + ]); } } diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 3b8b4524aab..e0fd435a90d 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -514,7 +514,7 @@ namespace ts { exitSubtree(ancestorFacts, HierarchyFacts.None, HierarchyFacts.None); return updateSourceFileNode( node, - createNodeArray(statements, node.statements) + setTextRange(createNodeArray(statements), node.statements) ); } @@ -671,9 +671,10 @@ namespace ts { setOriginalNode(variable, node); const statements: Statement[] = []; - const statement = createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([variable]), /*location*/ node); + const statement = createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([variable])); setOriginalNode(statement, node); + setTextRange(statement, node); startOnNewLine(statement); statements.push(statement); @@ -818,7 +819,7 @@ namespace ts { addRange(statements, endLexicalEnvironment()); - const block = createBlock(createNodeArray(statements, /*location*/ node.members), /*location*/ undefined, /*multiLine*/ true); + const block = createBlock(setTextRange(createNodeArray(statements), /*location*/ node.members), /*multiLine*/ true); setEmitFlags(block, EmitFlags.NoComments); return block; } @@ -833,8 +834,10 @@ namespace ts { function addExtendsHelperIfNeeded(statements: Statement[], node: ClassExpression | ClassDeclaration, extendsClauseElement: ExpressionWithTypeArguments): void { if (extendsClauseElement) { statements.push( - createStatement( - createExtendsHelper(context, getLocalName(node)), + setTextRange( + createStatement( + createExtendsHelper(context, getLocalName(node)) + ), /*location*/ extendsClauseElement ) ); @@ -854,19 +857,18 @@ namespace ts { const ancestorFacts = enterSubtree(HierarchyFacts.ConstructorExcludes, HierarchyFacts.ConstructorIncludes); const constructor = getFirstConstructorWithBody(node); const hasSynthesizedSuper = hasSynthesizedDefaultSuperCall(constructor, extendsClauseElement !== undefined); - const constructorFunction = - createFunctionDeclaration( - /*decorators*/ undefined, - /*modifiers*/ undefined, - /*asteriskToken*/ undefined, - getDeclarationName(node), - /*typeParameters*/ undefined, - transformConstructorParameters(constructor, hasSynthesizedSuper), - /*type*/ undefined, - transformConstructorBody(constructor, node, extendsClauseElement, hasSynthesizedSuper), - /*location*/ constructor || node - ); + const constructorFunction = createFunctionDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*asteriskToken*/ undefined, + getDeclarationName(node), + /*typeParameters*/ undefined, + transformConstructorParameters(constructor, hasSynthesizedSuper), + /*type*/ undefined, + transformConstructorBody(constructor, node, extendsClauseElement, hasSynthesizedSuper) + ); + setTextRange(constructorFunction, constructor || node); if (extendsClauseElement) { setEmitFlags(constructorFunction, EmitFlags.CapturesThis); } @@ -962,14 +964,16 @@ namespace ts { } const block = createBlock( - createNodeArray( - statements, + setTextRange( + createNodeArray( + statements + ), /*location*/ constructor ? constructor.body.statements : node.members ), - /*location*/ constructor ? constructor.body : node, /*multiLine*/ true ); + setTextRange(block, constructor ? constructor.body : node); if (!constructor) { setEmitFlags(block, EmitFlags.NoComments); } @@ -1139,14 +1143,16 @@ namespace ts { // Binding patterns are converted into a generated name and are // evaluated inside the function body. return setOriginalNode( - createParameter( - /*decorators*/ undefined, - /*modifiers*/ undefined, - /*dotDotDotToken*/ undefined, - getGeneratedNameForNode(node), - /*questionToken*/ undefined, - /*type*/ undefined, - /*initializer*/ undefined, + setTextRange( + createParameter( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, + getGeneratedNameForNode(node), + /*questionToken*/ undefined, + /*type*/ undefined, + /*initializer*/ undefined + ), /*location*/ node ), /*original*/ node @@ -1155,14 +1161,16 @@ namespace ts { else if (node.initializer) { // Initializers are elided return setOriginalNode( - createParameter( - /*decorators*/ undefined, - /*modifiers*/ undefined, - /*dotDotDotToken*/ undefined, - node.name, - /*questionToken*/ undefined, - /*type*/ undefined, - /*initializer*/ undefined, + setTextRange( + createParameter( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, + node.name, + /*questionToken*/ undefined, + /*type*/ undefined, + /*initializer*/ undefined + ), /*location*/ node ), /*original*/ node @@ -1274,21 +1282,25 @@ namespace ts { const statement = createIf( createTypeCheck(getSynthesizedClone(name), "undefined"), setEmitFlags( - createBlock([ - createStatement( - createAssignment( - setEmitFlags(getMutableClone(name), EmitFlags.NoSourceMap), - setEmitFlags(initializer, EmitFlags.NoSourceMap | getEmitFlags(initializer)), - /*location*/ parameter + setTextRange( + createBlock([ + createStatement( + setTextRange( + createAssignment( + setEmitFlags(getMutableClone(name), EmitFlags.NoSourceMap), + setEmitFlags(initializer, EmitFlags.NoSourceMap | getEmitFlags(initializer)) + ), + parameter + ) ) - ) - ], /*location*/ parameter), + ]), + parameter + ), EmitFlags.SingleLine | EmitFlags.NoTrailingSourceMap | EmitFlags.NoTokenSourceMaps - ), - /*elseStatement*/ undefined, - /*location*/ parameter + ) ); statement.startsOnNewLine = true; + setTextRange(statement, parameter); setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoTrailingSourceMap | EmitFlags.CustomPrologue); statements.push(statement); } @@ -1332,15 +1344,17 @@ namespace ts { // var param = []; statements.push( setEmitFlags( - createVariableStatement( - /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( - declarationName, - /*type*/ undefined, - createArrayLiteral([]) - ) - ]), + setTextRange( + createVariableStatement( + /*modifiers*/ undefined, + createVariableDeclarationList([ + createVariableDeclaration( + declarationName, + /*type*/ undefined, + createArrayLiteral([]) + ) + ]) + ), /*location*/ parameter ), EmitFlags.CustomPrologue @@ -1351,26 +1365,33 @@ namespace ts { // param[_i - restIndex] = arguments[_i]; // } const forStatement = createFor( - createVariableDeclarationList([ - createVariableDeclaration(temp, /*type*/ undefined, createLiteral(restIndex)) - ], /*location*/ parameter), - createLessThan( - temp, - createPropertyAccess(createIdentifier("arguments"), "length"), - /*location*/ parameter + setTextRange( + createVariableDeclarationList([ + createVariableDeclaration(temp, /*type*/ undefined, createLiteral(restIndex)) + ]), + parameter ), - createPostfixIncrement(temp, /*location*/ parameter), + setTextRange( + createLessThan( + temp, + createPropertyAccess(createIdentifier("arguments"), "length") + ), + parameter + ), + setTextRange(createPostfixIncrement(temp), parameter), createBlock([ startOnNewLine( - createStatement( - createAssignment( - createElementAccess( - expressionName, - restIndex === 0 - ? temp - : createSubtract(temp, createLiteral(restIndex)) - ), - createElementAccess(createIdentifier("arguments"), temp) + setTextRange( + createStatement( + createAssignment( + createElementAccess( + expressionName, + restIndex === 0 + ? temp + : createSubtract(temp, createLiteral(restIndex)) + ), + createElementAccess(createIdentifier("arguments"), temp) + ) ), /*location*/ parameter ) @@ -1405,11 +1426,10 @@ namespace ts { /*type*/ undefined, initializer ) - ]), - originalStatement + ]) ); - setEmitFlags(captureThisStatement, EmitFlags.NoComments | EmitFlags.CustomPrologue); + setTextRange(captureThisStatement, originalStatement); setSourceMapRange(captureThisStatement, node); statements.push(captureThisStatement); } @@ -1529,7 +1549,7 @@ namespace ts { * @param member The SemicolonClassElement node. */ function transformSemicolonClassElementToStatement(member: SemicolonClassElement) { - return createEmptyStatement(/*location*/ member); + return setTextRange(createEmptyStatement(), member); } /** @@ -1547,8 +1567,10 @@ namespace ts { setEmitFlags(memberFunction, EmitFlags.NoComments); setSourceMapRange(memberFunction, sourceMapRange); - const statement = createStatement( - createAssignment(memberName, memberFunction), + const statement = setTextRange( + createStatement( + createAssignment(memberName, memberFunction) + ), /*location*/ member ); @@ -1571,15 +1593,12 @@ namespace ts { * @param accessors The set of related get/set accessors. */ function transformAccessorsToStatement(receiver: LeftHandSideExpression, accessors: AllAccessorDeclarations, container: Node): Statement { - const statement = createStatement( - transformAccessorsToExpression(receiver, accessors, container, /*startsOnNewLine*/ false), - /*location*/ getSourceMapRange(accessors.firstAccessor) - ); - + const statement = createStatement(transformAccessorsToExpression(receiver, accessors, container, /*startsOnNewLine*/ false)); // The location for the statement is used to emit source maps only. // No comments should be emitted for this statement to align with the // old emitter. setEmitFlags(statement, EmitFlags.NoComments); + setSourceMapRange(statement, getSourceMapRange(accessors.firstAccessor)); return statement; } @@ -1622,8 +1641,8 @@ namespace ts { } properties.push( - createPropertyAssignment("enumerable", createLiteral(true)), - createPropertyAssignment("configurable", createLiteral(true)) + createPropertyAssignment("enumerable", createTrue()), + createPropertyAssignment("configurable", createTrue()) ); const call = createCall( @@ -1632,7 +1651,7 @@ namespace ts { [ target, propertyName, - createObjectLiteral(properties, /*location*/ undefined, /*multiLine*/ true) + createObjectLiteral(properties, /*multiLine*/ true) ] ); if (startsOnNewLine) { @@ -1662,9 +1681,9 @@ namespace ts { /*typeParameters*/ undefined, visitParameterList(node.parameters, visitor, context), /*type*/ undefined, - transformFunctionBody(node), - node + transformFunctionBody(node) ); + setTextRange(func, node); setOriginalNode(func, node); setEmitFlags(func, EmitFlags.CapturesThis); exitSubtree(ancestorFacts, HierarchyFacts.None, HierarchyFacts.None); @@ -1758,14 +1777,16 @@ namespace ts { exitSubtree(ancestorFacts, HierarchyFacts.PropagateNewTargetMask, HierarchyFacts.None); convertedLoopState = savedConvertedLoopState; return setOriginalNode( - createFunctionExpression( - /*modifiers*/ undefined, - node.asteriskToken, - name, - /*typeParameters*/ undefined, - parameters, - /*type*/ undefined, - body, + setTextRange( + createFunctionExpression( + /*modifiers*/ undefined, + node.asteriskToken, + name, + /*typeParameters*/ undefined, + parameters, + /*type*/ undefined, + body + ), location ), /*original*/ node @@ -1832,7 +1853,8 @@ namespace ts { } const expression = visitNode(body, visitor, isExpression); - const returnStatement = createReturn(expression, /*location*/ body); + const returnStatement = createReturn(expression); + setTextRange(returnStatement, body); setEmitFlags(returnStatement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoTrailingSourceMap | EmitFlags.NoTrailingComments); statements.push(returnStatement); @@ -1851,7 +1873,8 @@ namespace ts { multiLine = true; } - const block = createBlock(createNodeArray(statements, statementsLocation), node.body, multiLine); + const block = createBlock(setTextRange(createNodeArray(statements), statementsLocation), multiLine); + setTextRange(block, node.body); if (!multiLine && singleLine) { setEmitFlags(block, EmitFlags.SingleLine); } @@ -1868,8 +1891,10 @@ namespace ts { const updated = visitFunctionBody(node.body, functionBodyVisitor, context); return updateBlock( updated, - createNodeArray( - prependCaptureNewTargetIfNeeded(updated.statements, node, /*copyOnWrite*/ true), + setTextRange( + createNodeArray( + prependCaptureNewTargetIfNeeded(updated.statements, node, /*copyOnWrite*/ true) + ), /*location*/ updated.statements ) ); @@ -1969,7 +1994,7 @@ namespace ts { } } if (assignments) { - updated = createStatement(reduceLeft(assignments, (acc, v) => createBinary(v, SyntaxKind.CommaToken, acc)), node); + updated = setTextRange(createStatement(reduceLeft(assignments, (acc, v) => createBinary(v, SyntaxKind.CommaToken, acc))), node); } else { // none of declarations has initializer - the entire variable statement can be deleted @@ -1999,8 +2024,9 @@ namespace ts { ? visitVariableDeclarationInLetDeclarationList : visitVariableDeclaration)); - const declarationList = createVariableDeclarationList(declarations, /*location*/ node); + const declarationList = createVariableDeclarationList(declarations); setOriginalNode(declarationList, node); + setTextRange(declarationList, node); setCommentRange(declarationList, node); if (node.transformFlags & TransformFlags.ContainsBindingPattern @@ -2225,7 +2251,7 @@ namespace ts { // we don't want to emit a temporary variable for the RHS, just use it directly. const counter = createLoopVariable(); const rhsReference = expression.kind === SyntaxKind.Identifier - ? createUniqueName((expression).text) + ? createUniqueName(unescapeIdentifier((expression).text)) : createTempVariable(/*recordTempVariable*/ undefined); const elementAccess = createElementAccess(rhsReference, counter); @@ -2248,8 +2274,9 @@ namespace ts { elementAccess ); - const declarationList = createVariableDeclarationList(declarations, /*location*/ initializer); + const declarationList = createVariableDeclarationList(declarations); setOriginalNode(declarationList, initializer); + setTextRange(declarationList, initializer); // Adjust the source map range for the first declaration to align with the old // emitter. @@ -2268,19 +2295,24 @@ namespace ts { // The following call does not include the initializer, so we have // to emit it separately. statements.push( - createVariableStatement( - /*modifiers*/ undefined, - setOriginalNode( - createVariableDeclarationList([ - createVariableDeclaration( - firstOriginalDeclaration ? firstOriginalDeclaration.name : createTempVariable(/*recordTempVariable*/ undefined), - /*type*/ undefined, - createElementAccess(rhsReference, counter) - ) - ], /*location*/ moveRangePos(initializer, -1)), - initializer + setTextRange( + createVariableStatement( + /*modifiers*/ undefined, + setOriginalNode( + setTextRange( + createVariableDeclarationList([ + createVariableDeclaration( + firstOriginalDeclaration ? firstOriginalDeclaration.name : createTempVariable(/*recordTempVariable*/ undefined), + /*type*/ undefined, + createElementAccess(rhsReference, counter) + ) + ]), + moveRangePos(initializer, -1) + ), + initializer + ) ), - /*location*/ moveRangeEnd(initializer, -1) + moveRangeEnd(initializer, -1) ) ); } @@ -2306,7 +2338,7 @@ namespace ts { // Currently there is not way to check that assignment is binary expression of destructing assignment // so we have to cast never type to binaryExpression (assignment).end = initializer.end; - statements.push(createStatement(assignment, /*location*/ moveRangeEnd(initializer, -1))); + statements.push(setTextRange(createStatement(assignment), moveRangeEnd(initializer, -1))); } } @@ -2332,33 +2364,38 @@ namespace ts { // The old emitter does not emit source maps for the block. // We add the location to preserve comments. - const body = createBlock( - createNodeArray(statements, /*location*/ statementsLocation), - /*location*/ bodyLocation - ); - + const body = createBlock(setTextRange(createNodeArray(statements), /*location*/ statementsLocation)); + setTextRange(body, bodyLocation); setEmitFlags(body, EmitFlags.NoSourceMap | EmitFlags.NoTokenSourceMaps); const forStatement = createFor( setEmitFlags( - createVariableDeclarationList([ - createVariableDeclaration(counter, /*type*/ undefined, createLiteral(0), /*location*/ moveRangePos(node.expression, -1)), - createVariableDeclaration(rhsReference, /*type*/ undefined, expression, /*location*/ node.expression) - ], /*location*/ node.expression), + setTextRange( + createVariableDeclarationList([ + setTextRange(createVariableDeclaration(counter, /*type*/ undefined, createLiteral(0)), moveRangePos(node.expression, -1)), + setTextRange(createVariableDeclaration(rhsReference, /*type*/ undefined, expression), node.expression) + ]), + node.expression + ), EmitFlags.NoHoisting ), - createLessThan( - counter, - createPropertyAccess(rhsReference, "length"), - /*location*/ node.expression + setTextRange( + createLessThan( + counter, + createPropertyAccess(rhsReference, "length") + ), + node.expression ), - createPostfixIncrement(counter, /*location*/ node.expression), - body, - /*location*/ node + setTextRange( + createPostfixIncrement(counter), + node.expression + ), + body ); // Disable trailing source maps for the OpenParenToken to align source map emit with the old emitter. setEmitFlags(forStatement, EmitFlags.NoTokenTrailingSourceMaps); + setTextRange(forStatement, node); return restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel); } @@ -2418,7 +2455,6 @@ namespace ts { setEmitFlags( createObjectLiteral( visitNodes(properties, visitor, isObjectLiteralElementLike, 0, numInitialProperties), - /*location*/ undefined, node.multiLine ), EmitFlags.Indented @@ -2546,14 +2582,14 @@ namespace ts { copyOutParameters(loopOutParameters, CopyDirection.ToOutParameter, statements); } addRange(statements, lexicalEnvironment) - loopBody = createBlock(statements, /*location*/ undefined, /*multiline*/ true); + loopBody = createBlock(statements, /*multiline*/ true); } if (isBlock(loopBody)) { loopBody.multiLine = true; } else { - loopBody = createBlock([loopBody], /*location*/ undefined, /*multiline*/ true); + loopBody = createBlock([loopBody], /*multiline*/ true); } const isAsyncBlockContainingAwait = @@ -2687,12 +2723,7 @@ namespace ts { // visit childnodes to transform initializer/condition/incrementor parts clone = visitEachChild(clone, visitor, context); // set loop statement - clone.statement = createBlock( - convertedLoopBodyStatements, - /*location*/ undefined, - /*multiline*/ true - ); - + clone.statement = createBlock(convertedLoopBodyStatements, /*multiline*/ true); // reset and re-aggregate the transform flags clone.transformFlags = 0; aggregateTransformFlags(clone); @@ -2841,7 +2872,7 @@ namespace ts { else { loopParameters.push(createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name)); if (resolver.getNodeCheckFlags(decl) & NodeCheckFlags.NeedsLoopOutParameter) { - const outParamName = createUniqueName("out_" + name.text); + const outParamName = createUniqueName("out_" + unescapeIdentifier(name.text)); loopOutParameters.push({ originalName: name, outParamName }); } } @@ -2903,9 +2934,9 @@ namespace ts { receiver, visitNode(property.name, visitor, isPropertyName) ), - visitNode(property.initializer, visitor, isExpression), - /*location*/ property + visitNode(property.initializer, visitor, isExpression) ); + setTextRange(expression, property); if (startsOnNewLine) { expression.startsOnNewLine = true; } @@ -2925,9 +2956,9 @@ namespace ts { receiver, visitNode(property.name, visitor, isPropertyName) ), - getSynthesizedClone(property.name), - /*location*/ property + getSynthesizedClone(property.name) ); + setTextRange(expression, property); if (startsOnNewLine) { expression.startsOnNewLine = true; } @@ -2948,9 +2979,9 @@ namespace ts { receiver, visitNode(method.name, visitor, isPropertyName) ), - transformFunctionLikeToExpression(method, /*location*/ method, /*name*/ undefined, container), - /*location*/ method + transformFunctionLikeToExpression(method, /*location*/ method, /*name*/ undefined, container) ); + setTextRange(expression, method); if (startsOnNewLine) { expression.startsOnNewLine = true; } @@ -2963,7 +2994,8 @@ namespace ts { let updated: CatchClause; if (isBindingPattern(node.variableDeclaration.name)) { const temp = createTempVariable(undefined); - const newVariableDeclaration = createVariableDeclaration(temp, undefined, undefined, node.variableDeclaration); + const newVariableDeclaration = createVariableDeclaration(temp); + setTextRange(newVariableDeclaration, node.variableDeclaration); const vars = flattenDestructuringBinding( node.variableDeclaration, visitor, @@ -2971,8 +3003,9 @@ namespace ts { FlattenLevel.All, temp ); - const list = createVariableDeclarationList(vars, /*location*/node.variableDeclaration, /*flags*/node.variableDeclaration.flags); - const destructure = createVariableStatement(undefined, list); + const list = createVariableDeclarationList(vars); + setTextRange(list, node.variableDeclaration); + const destructure = createVariableStatement(/*modifiers*/ undefined, list); updated = updateCatchClause(node, newVariableDeclaration, addStatementToStartOfBlock(node.block, destructure)); } else { @@ -3001,9 +3034,11 @@ namespace ts { Debug.assert(!isComputedPropertyName(node.name)); const functionExpression = transformFunctionLikeToExpression(node, /*location*/ moveRangePos(node, -1), /*name*/ undefined, /*container*/ undefined); setEmitFlags(functionExpression, EmitFlags.NoLeadingComments | getEmitFlags(functionExpression)); - return createPropertyAssignment( - node.name, - functionExpression, + return setTextRange( + createPropertyAssignment( + node.name, + functionExpression + ), /*location*/ node ); } @@ -3030,9 +3065,11 @@ namespace ts { * @param node A ShorthandPropertyAssignment node. */ function visitShorthandPropertyAssignment(node: ShorthandPropertyAssignment): ObjectLiteralElementLike { - return createPropertyAssignment( - node.name, - getSynthesizedClone(node.name), + return setTextRange( + createPropertyAssignment( + node.name, + getSynthesizedClone(node.name) + ), /*location*/ node ); } @@ -3225,8 +3262,7 @@ namespace ts { function visitSpanOfNonSpreads(chunk: Expression[], multiLine: boolean, hasTrailingComma: boolean): VisitResult { return createArrayLiteral( - visitNodes(createNodeArray(chunk, /*location*/ undefined, hasTrailingComma), visitor, isExpression), - /*location*/ undefined, + visitNodes(createNodeArray(chunk, hasTrailingComma), visitor, isExpression), multiLine ); } @@ -3250,7 +3286,7 @@ namespace ts { * @param node A template literal. */ function visitTemplateLiteral(node: LiteralExpression): LeftHandSideExpression { - return createLiteral(node.text, /*location*/ node); + return setTextRange(createLiteral(node.text), node); } /** @@ -3318,7 +3354,7 @@ namespace ts { // ES6 Spec 11.8.6.1 - Static Semantics of TV's and TRV's // and LineTerminatorSequences are normalized to for both TV and TRV. text = text.replace(/\r\n?/g, "\n"); - return createLiteral(text, /*location*/ node); + return setTextRange(createLiteral(text), node); } /** @@ -3342,7 +3378,8 @@ namespace ts { // "abc" + (1 << 2) + "" const expression = reduceLeft(expressions, createAdd); if (nodeIsSynthesized(expression)) { - setTextRange(expression, node); + expression.pos = node.pos; + expression.end = node.end; } return expression; @@ -3435,9 +3472,11 @@ namespace ts { /** * Called by the printer just before a node is printed. * + * @param hint A hint as to the intended usage of the node. * @param node The node to be printed. + * @param emitCallback The callback used to emit the node. */ - function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) { + function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) { if (enabledSubstitutions & ES2015SubstitutionFlags.CapturedThis && isFunctionLike(node)) { // If we are tracking a captured `this`, keep track of the enclosing function. const ancestorFacts = enterSubtree( @@ -3445,11 +3484,11 @@ namespace ts { getEmitFlags(node) & EmitFlags.CapturesThis ? HierarchyFacts.FunctionIncludes | HierarchyFacts.CapturesThis : HierarchyFacts.FunctionIncludes); - previousOnEmitNode(emitContext, node, emitCallback); + previousOnEmitNode(hint, node, emitCallback); exitSubtree(ancestorFacts, HierarchyFacts.None, HierarchyFacts.None); return; } - previousOnEmitNode(emitContext, node, emitCallback); + previousOnEmitNode(hint, node, emitCallback); } /** @@ -3484,13 +3523,13 @@ namespace ts { /** * Hooks node substitutions. * - * @param emitContext The context for the emitter. + * @param hint The context for the emitter. * @param node The node to substitute. */ - function onSubstituteNode(emitContext: EmitContext, node: Node) { - node = previousOnSubstituteNode(emitContext, node); + function onSubstituteNode(hint: EmitHint, node: Node) { + node = previousOnSubstituteNode(hint, node); - if (emitContext === EmitContext.Expression) { + if (hint === EmitHint.Expression) { return substituteExpression(node); } @@ -3578,7 +3617,7 @@ namespace ts { function substituteThisKeyword(node: PrimaryExpression): PrimaryExpression { if (enabledSubstitutions & ES2015SubstitutionFlags.CapturedThis && hierarchyFacts & HierarchyFacts.CapturesThis) { - return createIdentifier("_this", /*location*/ node); + return setTextRange(createIdentifier("_this"), node); } return node; } diff --git a/src/compiler/transformers/es2016.ts b/src/compiler/transformers/es2016.ts index 5959753fcef..1118e6ad9b6 100644 --- a/src/compiler/transformers/es2016.ts +++ b/src/compiler/transformers/es2016.ts @@ -48,29 +48,37 @@ namespace ts { // Transforms `a[x] **= b` into `(_a = a)[_x = x] = Math.pow(_a[_x], b)` const expressionTemp = createTempVariable(hoistVariableDeclaration); const argumentExpressionTemp = createTempVariable(hoistVariableDeclaration); - target = createElementAccess( - createAssignment(expressionTemp, left.expression, /*location*/ left.expression), - createAssignment(argumentExpressionTemp, left.argumentExpression, /*location*/ left.argumentExpression), - /*location*/ left + target = setTextRange( + createElementAccess( + setTextRange(createAssignment(expressionTemp, left.expression), left.expression), + setTextRange(createAssignment(argumentExpressionTemp, left.argumentExpression), left.argumentExpression) + ), + left ); - value = createElementAccess( - expressionTemp, - argumentExpressionTemp, - /*location*/ left + value = setTextRange( + createElementAccess( + expressionTemp, + argumentExpressionTemp + ), + left ); } else if (isPropertyAccessExpression(left)) { // Transforms `a.x **= b` into `(_a = a).x = Math.pow(_a.x, b)` const expressionTemp = createTempVariable(hoistVariableDeclaration); - target = createPropertyAccess( - createAssignment(expressionTemp, left.expression, /*location*/ left.expression), - left.name, - /*location*/ left + target = setTextRange( + createPropertyAccess( + setTextRange(createAssignment(expressionTemp, left.expression), left.expression), + left.name + ), + left ); - value = createPropertyAccess( - expressionTemp, - left.name, - /*location*/ left + value = setTextRange( + createPropertyAccess( + expressionTemp, + left.name + ), + left ); } else { @@ -78,7 +86,13 @@ namespace ts { target = left; value = left; } - return createAssignment(target, createMathPow(value, right, /*location*/ node), /*location*/ node); + return setTextRange( + createAssignment( + target, + createMathPow(value, right, /*location*/ node) + ), + node + ); } function visitExponentiationExpression(node: BinaryExpression) { diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index c87dbe32518..b437298656c 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -104,10 +104,12 @@ namespace ts { */ function visitAwaitExpression(node: AwaitExpression): Expression { return setOriginalNode( - createYield( - /*asteriskToken*/ undefined, - visitNode(node.expression, visitor, isExpression), - /*location*/ node + setTextRange( + createYield( + /*asteriskToken*/ undefined, + visitNode(node.expression, visitor, isExpression) + ), + node ), node ); @@ -238,7 +240,8 @@ namespace ts { addRange(statements, endLexicalEnvironment()); - const block = createBlock(statements, /*location*/ node.body, /*multiLine*/ true); + const block = createBlock(statements, /*multiLine*/ true); + setTextRange(block, node.body); // Minor optimization, emit `_super` helper to capture `super` access in an arrow. // This step isn't needed if we eventually transform this to ES5. @@ -266,7 +269,7 @@ namespace ts { const declarations = endLexicalEnvironment(); if (some(declarations)) { const block = convertToFunctionBody(expression); - return updateBlock(block, createNodeArray(concatenate(block.statements, declarations), block.statements)); + return updateBlock(block, setTextRange(createNodeArray(concatenate(block.statements, declarations)), block.statements)); } return expression; @@ -281,7 +284,7 @@ namespace ts { startLexicalEnvironment(); const visited = convertToFunctionBody(visitNode(body, visitor, isConciseBody)); const declarations = endLexicalEnvironment(); - return updateBlock(visited, createNodeArray(concatenate(visited.statements, declarations), visited.statements)); + return updateBlock(visited, setTextRange(createNodeArray(concatenate(visited.statements, declarations)), visited.statements)); } } @@ -396,33 +399,33 @@ namespace ts { /** * Hook for node emit. * + * @param hint A hint as to the intended usage of the node. * @param node The node to emit. * @param emit A callback used to emit the node in the printer. */ - function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void { + function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void { // If we need to support substitutions for `super` in an async method, // we should track it here. if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && isSuperContainer(node)) { const savedCurrentSuperContainer = currentSuperContainer; currentSuperContainer = node; - previousOnEmitNode(emitContext, node, emitCallback); + previousOnEmitNode(hint, node, emitCallback); currentSuperContainer = savedCurrentSuperContainer; } else { - previousOnEmitNode(emitContext, node, emitCallback); + previousOnEmitNode(hint, node, emitCallback); } } /** * Hooks node substitutions. * + * @param hint A hint as to the intended usage of the node. * @param node The node to substitute. - * @param isExpression A value indicating whether the node is to be used in an expression - * position. */ - function onSubstituteNode(emitContext: EmitContext, node: Node) { - node = previousOnSubstituteNode(emitContext, node); - if (emitContext === EmitContext.Expression) { + function onSubstituteNode(hint: EmitHint, node: Node) { + node = previousOnSubstituteNode(hint, node); + if (hint === EmitHint.Expression) { return substituteExpression(node); } @@ -431,21 +434,25 @@ namespace ts { function createSuperAccessInAsyncMethod(argumentExpression: Expression, flags: NodeCheckFlags, location: TextRange): LeftHandSideExpression { if (flags & NodeCheckFlags.AsyncMethodWithSuperBinding) { - return createPropertyAccess( + return setTextRange( + createPropertyAccess( + createCall( + createIdentifier("_super"), + /*typeArguments*/ undefined, + [argumentExpression] + ), + "value" + ), + location + ); + } + else { + return setTextRange( createCall( createIdentifier("_super"), /*typeArguments*/ undefined, [argumentExpression] ), - "value", - location - ); - } - else { - return createCall( - createIdentifier("_super"), - /*typeArguments*/ undefined, - [argumentExpression], location ); } diff --git a/src/compiler/transformers/es5.ts b/src/compiler/transformers/es5.ts index c3b011fe36d..bcecb86e75d 100644 --- a/src/compiler/transformers/es5.ts +++ b/src/compiler/transformers/es5.ts @@ -12,7 +12,7 @@ namespace ts { const compilerOptions = context.getCompilerOptions(); // enable emit notification only if using --jsx preserve or react-native - let previousOnEmitNode: (emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) => void; + let previousOnEmitNode: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void; let noSubstitution: boolean[]; if (compilerOptions.jsx === JsxEmit.Preserve || compilerOptions.jsx === JsxEmit.ReactNative) { previousOnEmitNode = context.onEmitNode; @@ -41,9 +41,11 @@ namespace ts { /** * Called by the printer just before a node is printed. * - * @param node The node to be printed. + * @param hint A hint as to the intended usage of the node. + * @param node The node to emit. + * @param emitCallback A callback used to emit the node. */ - function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) { + function onEmitNode(hint: EmitHint, node: Node, emitCallback: (emitContext: EmitHint, node: Node) => void) { switch (node.kind) { case SyntaxKind.JsxOpeningElement: case SyntaxKind.JsxClosingElement: @@ -53,21 +55,21 @@ namespace ts { break; } - previousOnEmitNode(emitContext, node, emitCallback); + previousOnEmitNode(hint, node, emitCallback); } /** * Hooks node substitutions. * - * @param emitContext The context for the emitter. + * @param hint A hint as to the intended usage of the node. * @param node The node to substitute. */ - function onSubstituteNode(emitContext: EmitContext, node: Node) { + function onSubstituteNode(hint: EmitHint, node: Node) { if (node.id && noSubstitution && noSubstitution[node.id]) { - return previousOnSubstituteNode(emitContext, node); + return previousOnSubstituteNode(hint, node); } - node = previousOnSubstituteNode(emitContext, node); + node = previousOnSubstituteNode(hint, node); if (isPropertyAccessExpression(node)) { return substitutePropertyAccessExpression(node); } @@ -85,7 +87,7 @@ namespace ts { function substitutePropertyAccessExpression(node: PropertyAccessExpression): Expression { const literalName = trySubstituteReservedName(node.name); if (literalName) { - return createElementAccess(node.expression, literalName, /*location*/ node); + return setTextRange(createElementAccess(node.expression, literalName), node); } return node; } @@ -111,7 +113,7 @@ namespace ts { function trySubstituteReservedName(name: Identifier) { const token = name.originalKeywordKind || (nodeIsSynthesized(name) ? stringToToken(name.text) : undefined); if (token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord) { - return createLiteral(name, /*location*/ name); + return setTextRange(createLiteral(name), name); } return undefined; } diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index 8b5a095a17e..f058e627df7 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -210,36 +210,40 @@ namespace ts { const statement = createVariableStatement( /*modifiers*/ undefined, updateVariableDeclarationList(initializer, declarations), - /*location*/ initializer ); + setTextRange(statement, initializer); leadingStatements = append(leadingStatements, statement); } } else if (isAssignmentPattern(initializer)) { temp = createTempVariable(/*recordTempVariable*/ undefined); const expression = flattenDestructuringAssignment( - aggregateTransformFlags(createAssignment(initializer, temp, /*location*/ node.initializer)), + aggregateTransformFlags( + setTextRange( + createAssignment(initializer, temp), + node.initializer + ) + ), visitor, context, FlattenLevel.ObjectRest ); - leadingStatements = append(leadingStatements, createStatement(expression, /*location*/ node.initializer)); + leadingStatements = append(leadingStatements, setTextRange(createStatement(expression), node.initializer)); } } if (temp) { const expression = visitNode(node.expression, visitor, isExpression); const statement = visitNode(node.statement, visitor, isStatement); const block = isBlock(statement) - ? updateBlock(statement, createNodeArray(concatenate(leadingStatements, statement.statements), statement.statements)) - : createBlock(append(leadingStatements, statement), statement, /*multiLine*/ true); + ? updateBlock(statement, setTextRange(createNodeArray(concatenate(leadingStatements, statement.statements)), statement.statements)) + : setTextRange(createBlock(append(leadingStatements, statement), /*multiLine*/ true), statement); return updateForOf( node, - createVariableDeclarationList( - [ - createVariableDeclaration(temp, /*type*/ undefined, /*initializer*/ undefined, node.initializer) - ], - node.initializer, - NodeFlags.Let + setTextRange( + createVariableDeclarationList([ + setTextRange(createVariableDeclaration(temp), node.initializer) + ], NodeFlags.Let), + node.initializer ), expression, block @@ -380,7 +384,7 @@ namespace ts { const trailingStatements = endLexicalEnvironment(); if (some(leadingStatements) || some(trailingStatements)) { const block = convertToFunctionBody(body, /*multiLine*/ true); - return updateBlock(block, createNodeArray(concatenate(concatenate(leadingStatements, block.statements), trailingStatements), block.statements)); + return updateBlock(block, setTextRange(createNodeArray(concatenate(concatenate(leadingStatements, block.statements), trailingStatements)), block.statements)); } return body; } diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 7dcfe76a427..cabd5d2a96d 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -450,15 +450,17 @@ namespace ts { // Currently, we only support generators that were originally async functions. if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { node = setOriginalNode( - createFunctionDeclaration( - /*decorators*/ undefined, - node.modifiers, - /*asteriskToken*/ undefined, - node.name, - /*typeParameters*/ undefined, - visitParameterList(node.parameters, visitor, context), - /*type*/ undefined, - transformGeneratorFunctionBody(node.body), + setTextRange( + createFunctionDeclaration( + /*decorators*/ undefined, + node.modifiers, + /*asteriskToken*/ undefined, + node.name, + /*typeParameters*/ undefined, + visitParameterList(node.parameters, visitor, context), + /*type*/ undefined, + transformGeneratorFunctionBody(node.body) + ), /*location*/ node ), node @@ -498,14 +500,16 @@ namespace ts { // Currently, we only support generators that were originally async functions. if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { node = setOriginalNode( - createFunctionExpression( - /*modifiers*/ undefined, - /*asteriskToken*/ undefined, - node.name, - /*typeParameters*/ undefined, - visitParameterList(node.parameters, visitor, context), - /*type*/ undefined, - transformGeneratorFunctionBody(node.body), + setTextRange( + createFunctionExpression( + /*modifiers*/ undefined, + /*asteriskToken*/ undefined, + node.name, + /*typeParameters*/ undefined, + visitParameterList(node.parameters, visitor, context), + /*type*/ undefined, + transformGeneratorFunctionBody(node.body) + ), /*location*/ node ), node @@ -606,7 +610,7 @@ namespace ts { operationLocations = savedOperationLocations; state = savedState; - return createBlock(statements, /*location*/ body, body.multiLine); + return setTextRange(createBlock(statements, body.multiLine), body); } /** @@ -739,14 +743,17 @@ namespace ts { const operator = node.operatorToken.kind; if (isCompoundAssignment(operator)) { - return createBinary( - target, - SyntaxKind.EqualsToken, - createBinary( - cacheExpression(target), - getOperatorForCompoundAssignment(operator), - visitNode(right, visitor, isExpression), - node + return setTextRange( + createAssignment( + target, + setTextRange( + createBinary( + cacheExpression(target), + getOperatorForCompoundAssignment(operator), + visitNode(right, visitor, isExpression) + ), + node + ) ), node ); @@ -988,8 +995,11 @@ namespace ts { const expressions = reduceLeft(elements, reduceElement, [], numInitialElements); return hasAssignedTemp - ? createArrayConcat(temp, [createArrayLiteral(expressions, /*location*/ undefined, multiLine)]) - : createArrayLiteral(leadingElement ? [leadingElement, ...expressions] : expressions, location, multiLine); + ? createArrayConcat(temp, [createArrayLiteral(expressions, multiLine)]) + : setTextRange( + createArrayLiteral(leadingElement ? [leadingElement, ...expressions] : expressions, multiLine), + location + ); function reduceElement(expressions: Expression[], element: Expression) { if (containsYield(element) && expressions.length > 0) { @@ -998,11 +1008,10 @@ namespace ts { hasAssignedTemp ? createArrayConcat( temp, - [createArrayLiteral(expressions, /*location*/ undefined, multiLine)] + [createArrayLiteral(expressions, multiLine)] ) : createArrayLiteral( leadingElement ? [leadingElement, ...expressions] : expressions, - /*location*/ undefined, multiLine ) ); @@ -1043,7 +1052,6 @@ namespace ts { emitAssignment(temp, createObjectLiteral( visitNodes(properties, visitor, isObjectLiteralElementLike, 0, numInitialProperties), - /*location*/ undefined, multiLine ) ); @@ -1139,18 +1147,20 @@ namespace ts { const { target, thisArg } = createCallBinding(createPropertyAccess(node.expression, "bind"), hoistVariableDeclaration); return setOriginalNode( - createNew( - createFunctionApply( - cacheExpression(visitNode(target, visitor, isExpression)), - thisArg, - visitElements( - node.arguments, - /*leadingElement*/ createVoidZero() - ) + setTextRange( + createNew( + createFunctionApply( + cacheExpression(visitNode(target, visitor, isExpression)), + thisArg, + visitElements( + node.arguments, + /*leadingElement*/ createVoidZero() + ) + ), + /*typeArguments*/ undefined, + [] ), - /*typeArguments*/ undefined, - [], - /*location*/ node + node ), node ); @@ -1423,9 +1433,11 @@ namespace ts { } else { emitStatement( - createStatement( - visitNode(initializer, visitor, isExpression), - /*location*/ initializer + setTextRange( + createStatement( + visitNode(initializer, visitor, isExpression) + ), + initializer ) ); } @@ -1441,9 +1453,11 @@ namespace ts { markLabel(incrementLabel); if (node.incrementor) { emitStatement( - createStatement( - visitNode(node.incrementor, visitor, isExpression), - /*location*/ node.incrementor + setTextRange( + createStatement( + visitNode(node.incrementor, visitor, isExpression) + ), + node.incrementor ) ); } @@ -1909,9 +1923,9 @@ namespace ts { return -1; } - function onSubstituteNode(emitContext: EmitContext, node: Node): Node { - node = previousOnSubstituteNode(emitContext, node); - if (emitContext === EmitContext.Expression) { + function onSubstituteNode(hint: EmitHint, node: Node): Node { + node = previousOnSubstituteNode(hint, node); + if (hint === EmitHint.Expression) { return substituteExpression(node); } return node; @@ -2417,11 +2431,13 @@ namespace ts { */ function createInlineBreak(label: Label, location?: TextRange): ReturnStatement { Debug.assert(label > 0, `Invalid label: ${label}`); - return createReturn( - createArrayLiteral([ - createInstruction(Instruction.Break), - createLabel(label) - ]), + return setTextRange( + createReturn( + createArrayLiteral([ + createInstruction(Instruction.Break), + createLabel(label) + ]) + ), location ); } @@ -2433,10 +2449,12 @@ namespace ts { * @param location An optional source map location for the statement. */ function createInlineReturn(expression?: Expression, location?: TextRange): ReturnStatement { - return createReturn( - createArrayLiteral(expression - ? [createInstruction(Instruction.Return), expression] - : [createInstruction(Instruction.Return)] + return setTextRange( + createReturn( + createArrayLiteral(expression + ? [createInstruction(Instruction.Return), expression] + : [createInstruction(Instruction.Return)] + ) ), location ); @@ -2446,7 +2464,14 @@ namespace ts { * Creates an expression that can be used to resume from a Yield operation. */ function createGeneratorResume(location?: TextRange): LeftHandSideExpression { - return createCall(createPropertyAccess(state, "sent"), /*typeArguments*/ undefined, [], location); + return setTextRange( + createCall( + createPropertyAccess(state, "sent"), + /*typeArguments*/ undefined, + [] + ), + location + ); } /** @@ -2614,7 +2639,6 @@ namespace ts { /*type*/ undefined, createBlock( buildResult, - /*location*/ undefined, /*multiLine*/ buildResult.length > 0 ) ), @@ -2944,7 +2968,7 @@ namespace ts { * @param operationLocation The source map location for the operation. */ function writeAssign(left: Expression, right: Expression, operationLocation: TextRange): void { - writeStatement(createStatement(createAssignment(left, right), operationLocation)); + writeStatement(setTextRange(createStatement(createAssignment(left, right)), operationLocation)); } /** @@ -2956,7 +2980,7 @@ namespace ts { function writeThrow(expression: Expression, operationLocation: TextRange): void { lastOperationWasAbrupt = true; lastOperationWasCompletion = true; - writeStatement(createThrow(expression, operationLocation)); + writeStatement(setTextRange(createThrow(expression), operationLocation)); } /** @@ -2970,10 +2994,12 @@ namespace ts { lastOperationWasCompletion = true; writeStatement( setEmitFlags( - createReturn( - createArrayLiteral(expression - ? [createInstruction(Instruction.Return), expression] - : [createInstruction(Instruction.Return)] + setTextRange( + createReturn( + createArrayLiteral(expression + ? [createInstruction(Instruction.Return), expression] + : [createInstruction(Instruction.Return)] + ) ), operationLocation ), @@ -2992,11 +3018,13 @@ namespace ts { lastOperationWasAbrupt = true; writeStatement( setEmitFlags( - createReturn( - createArrayLiteral([ - createInstruction(Instruction.Break), - createLabel(label) - ]), + setTextRange( + createReturn( + createArrayLiteral([ + createInstruction(Instruction.Break), + createLabel(label) + ]) + ), operationLocation ), EmitFlags.NoTokenSourceMaps @@ -3017,11 +3045,13 @@ namespace ts { createIf( condition, setEmitFlags( - createReturn( - createArrayLiteral([ - createInstruction(Instruction.Break), - createLabel(label) - ]), + setTextRange( + createReturn( + createArrayLiteral([ + createInstruction(Instruction.Break), + createLabel(label) + ]) + ), operationLocation ), EmitFlags.NoTokenSourceMaps @@ -3045,11 +3075,13 @@ namespace ts { createIf( createLogicalNot(condition), setEmitFlags( - createReturn( - createArrayLiteral([ - createInstruction(Instruction.Break), - createLabel(label) - ]), + setTextRange( + createReturn( + createArrayLiteral([ + createInstruction(Instruction.Break), + createLabel(label) + ]) + ), operationLocation ), EmitFlags.NoTokenSourceMaps @@ -3070,11 +3102,13 @@ namespace ts { lastOperationWasAbrupt = true; writeStatement( setEmitFlags( - createReturn( - createArrayLiteral( - expression - ? [createInstruction(Instruction.Yield), expression] - : [createInstruction(Instruction.Yield)] + setTextRange( + createReturn( + createArrayLiteral( + expression + ? [createInstruction(Instruction.Yield), expression] + : [createInstruction(Instruction.Yield)] + ) ), operationLocation ), @@ -3093,11 +3127,13 @@ namespace ts { lastOperationWasAbrupt = true; writeStatement( setEmitFlags( - createReturn( - createArrayLiteral([ - createInstruction(Instruction.YieldStar), - expression - ]), + setTextRange( + createReturn( + createArrayLiteral([ + createInstruction(Instruction.YieldStar), + expression + ]) + ), operationLocation ), EmitFlags.NoTokenSourceMaps diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index 1307a7f8551..60053d98e57 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -143,15 +143,15 @@ namespace ts { function transformJsxAttributeInitializer(node: StringLiteral | JsxExpression) { if (node === undefined) { - return createLiteral(true); + return createTrue(); } else if (node.kind === SyntaxKind.StringLiteral) { const decoded = tryDecodeEntities((node).text); - return decoded ? createLiteral(decoded, /*location*/ node) : node; + return decoded ? setTextRange(createLiteral(decoded), node) : node; } else if (node.kind === SyntaxKind.JsxExpression) { if (node.expression === undefined) { - return createLiteral(true); + return createTrue(); } return visitJsxExpression(node); } diff --git a/src/compiler/transformers/module/es2015.ts b/src/compiler/transformers/module/es2015.ts index 5611f890164..cc197073c32 100644 --- a/src/compiler/transformers/module/es2015.ts +++ b/src/compiler/transformers/module/es2015.ts @@ -37,7 +37,7 @@ namespace ts { addRange(statements, visitNodes(node.statements, visitor, isStatement, statementOffset)); return updateSourceFileNode( node, - createNodeArray(statements, node.statements)); + setTextRange(createNodeArray(statements), node.statements)); } else { return visitEachChild(node, visitor, context); @@ -71,18 +71,18 @@ namespace ts { /** * Hook for node emit. * - * @param emitContext A context hint for the emitter. + * @param hint A hint as to the intended usage of the node. * @param node The node to emit. * @param emit A callback used to emit the node in the printer. */ - function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void { + function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void { if (isSourceFile(node)) { currentSourceFile = node; - previousOnEmitNode(emitContext, node, emitCallback); + previousOnEmitNode(hint, node, emitCallback); currentSourceFile = undefined; } else { - previousOnEmitNode(emitContext, node, emitCallback); + previousOnEmitNode(hint, node, emitCallback); } } @@ -93,12 +93,12 @@ namespace ts { /** * Hooks node substitutions. * - * @param emitContext A context hint for the emitter. + * @param hint A hint as to the intended usage of the node. * @param node The node to substitute. */ - function onSubstituteNode(emitContext: EmitContext, node: Node) { - node = previousOnSubstituteNode(emitContext, node); - if (isIdentifier(node) && emitContext === EmitContext.Expression) { + function onSubstituteNode(hint: EmitHint, node: Node) { + node = previousOnSubstituteNode(hint, node); + if (isIdentifier(node) && hint === EmitHint.Expression) { return substituteExpressionIdentifier(node); } return node; diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 0adea4fd540..f6e51fa9fdd 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -88,7 +88,7 @@ namespace ts { addRange(statements, endLexicalEnvironment()); addExportEqualsIfNeeded(statements, /*emitAsReturn*/ false); - const updated = updateSourceFileNode(node, createNodeArray(statements, node.statements)); + const updated = updateSourceFileNode(node, setTextRange(createNodeArray(statements), node.statements)); if (currentModuleInfo.hasExportStarsToExportValues) { addEmitHelper(updated, exportStarHelper); } @@ -131,47 +131,49 @@ namespace ts { // Create an updated SourceFile: // // define(moduleName?, ["module1", "module2"], function ... - return updateSourceFileNode(node, createNodeArray( - [ - createStatement( - createCall( - define, - /*typeArguments*/ undefined, - [ - // Add the module name (if provided). - ...(moduleName ? [moduleName] : []), + return updateSourceFileNode(node, + setTextRange( + createNodeArray([ + createStatement( + createCall( + define, + /*typeArguments*/ undefined, + [ + // Add the module name (if provided). + ...(moduleName ? [moduleName] : []), - // Add the dependency array argument: - // - // ["require", "exports", module1", "module2", ...] - createArrayLiteral([ - createLiteral("require"), - createLiteral("exports"), - ...aliasedModuleNames, - ...unaliasedModuleNames - ]), + // Add the dependency array argument: + // + // ["require", "exports", module1", "module2", ...] + createArrayLiteral([ + createLiteral("require"), + createLiteral("exports"), + ...aliasedModuleNames, + ...unaliasedModuleNames + ]), - // Add the module body function argument: - // - // function (require, exports, module1, module2) ... - createFunctionExpression( - /*modifiers*/ undefined, - /*asteriskToken*/ undefined, - /*name*/ undefined, - /*typeParameters*/ undefined, - [ - createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "require"), - createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "exports"), - ...importAliasNames - ], - /*type*/ undefined, - transformAsynchronousModuleBody(node) - ) - ] + // Add the module body function argument: + // + // function (require, exports, module1, module2) ... + createFunctionExpression( + /*modifiers*/ undefined, + /*asteriskToken*/ undefined, + /*name*/ undefined, + /*typeParameters*/ undefined, + [ + createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "require"), + createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "exports"), + ...importAliasNames + ], + /*type*/ undefined, + transformAsynchronousModuleBody(node) + ) + ] + ) ) - ) - ], - /*location*/ node.statements) + ]), + /*location*/ node.statements + ) ); } @@ -189,74 +191,76 @@ namespace ts { /*typeParameters*/ undefined, [createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "factory")], /*type*/ undefined, - createBlock( - [ - createIf( - createLogicalAnd( - createTypeCheck(createIdentifier("module"), "object"), - createTypeCheck(createPropertyAccess(createIdentifier("module"), "exports"), "object") - ), - createBlock([ - createVariableStatement( - /*modifiers*/ undefined, - [ - createVariableDeclaration( - "v", - /*type*/ undefined, + setTextRange( + createBlock( + [ + createIf( + createLogicalAnd( + createTypeCheck(createIdentifier("module"), "object"), + createTypeCheck(createPropertyAccess(createIdentifier("module"), "exports"), "object") + ), + createBlock([ + createVariableStatement( + /*modifiers*/ undefined, + [ + createVariableDeclaration( + "v", + /*type*/ undefined, + createCall( + createIdentifier("factory"), + /*typeArguments*/ undefined, + [ + createIdentifier("require"), + createIdentifier("exports") + ] + ) + ) + ] + ), + setEmitFlags( + createIf( + createStrictInequality( + createIdentifier("v"), + createIdentifier("undefined") + ), + createStatement( + createAssignment( + createPropertyAccess(createIdentifier("module"), "exports"), + createIdentifier("v") + ) + ) + ), + EmitFlags.SingleLine + ) + ]), + createIf( + createLogicalAnd( + createTypeCheck(createIdentifier("define"), "function"), + createPropertyAccess(createIdentifier("define"), "amd") + ), + createBlock([ + createStatement( createCall( - createIdentifier("factory"), + createIdentifier("define"), /*typeArguments*/ undefined, [ - createIdentifier("require"), - createIdentifier("exports") + createArrayLiteral([ + createLiteral("require"), + createLiteral("exports"), + ...aliasedModuleNames, + ...unaliasedModuleNames + ]), + createIdentifier("factory") ] ) ) - ] - ), - setEmitFlags( - createIf( - createStrictInequality( - createIdentifier("v"), - createIdentifier("undefined") - ), - createStatement( - createAssignment( - createPropertyAccess(createIdentifier("module"), "exports"), - createIdentifier("v") - ) - ) - ), - EmitFlags.SingleLine + ]) ) - ]), - createIf( - createLogicalAnd( - createTypeCheck(createIdentifier("define"), "function"), - createPropertyAccess(createIdentifier("define"), "amd") - ), - createBlock([ - createStatement( - createCall( - createIdentifier("define"), - /*typeArguments*/ undefined, - [ - createArrayLiteral([ - createLiteral("require"), - createLiteral("exports"), - ...aliasedModuleNames, - ...unaliasedModuleNames - ]), - createIdentifier("factory") - ] - ) - ) - ]) ) - ) - ], - /*location*/ undefined, - /*multiLine*/ true + ], + /*multiLine*/ true + ), + /*location*/ undefined ) ); @@ -274,8 +278,8 @@ namespace ts { return updateSourceFileNode( node, - createNodeArray( - [ + setTextRange( + createNodeArray([ createStatement( createCall( umdHeader, @@ -300,7 +304,7 @@ namespace ts { ] ) ) - ], + ]), /*location*/ node.statements ) ); @@ -378,7 +382,7 @@ namespace ts { // Append the 'export =' statement if provided. addExportEqualsIfNeeded(statements, /*emitAsReturn*/ true); - const body = createBlock(statements, /*location*/ undefined, /*multiLine*/ true); + const body = createBlock(statements, /*multiLine*/ true); if (currentModuleInfo.hasExportStarsToExportValues) { // If we have any `export * from ...` declarations // we need to inform the emitter to add the __export helper. @@ -399,11 +403,8 @@ namespace ts { function addExportEqualsIfNeeded(statements: Statement[], emitAsReturn: boolean) { if (currentModuleInfo.exportEquals) { if (emitAsReturn) { - const statement = createReturn( - currentModuleInfo.exportEquals.expression, - /*location*/ currentModuleInfo.exportEquals - ); - + const statement = createReturn(currentModuleInfo.exportEquals.expression); + setTextRange(statement, currentModuleInfo.exportEquals); setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoComments); statements.push(statement); } @@ -415,10 +416,10 @@ namespace ts { "exports" ), currentModuleInfo.exportEquals.expression - ), - /*location*/ currentModuleInfo.exportEquals + ) ); + setTextRange(statement, currentModuleInfo.exportEquals); setEmitFlags(statement, EmitFlags.NoComments); statements.push(statement); } @@ -481,7 +482,7 @@ namespace ts { if (moduleKind !== ModuleKind.AMD) { if (!node.importClause) { // import "mod"; - return createStatement(createRequireCall(node), /*location*/ node); + return setTextRange(createStatement(createRequireCall(node)), node); } else { const variables: VariableDeclaration[] = []; @@ -520,12 +521,13 @@ namespace ts { } statements = append(statements, - createVariableStatement( - /*modifiers*/ undefined, - createVariableDeclarationList( - variables, - /*location*/ undefined, - languageVersion >= ScriptTarget.ES2015 ? NodeFlags.Const : NodeFlags.None + setTextRange( + createVariableStatement( + /*modifiers*/ undefined, + createVariableDeclarationList( + variables, + languageVersion >= ScriptTarget.ES2015 ? NodeFlags.Const : NodeFlags.None + ) ), /*location*/ node ) @@ -539,14 +541,15 @@ namespace ts { /*modifiers*/ undefined, createVariableDeclarationList( [ - createVariableDeclaration( - getSynthesizedClone(namespaceDeclaration.name), - /*type*/ undefined, - getGeneratedNameForNode(node), + setTextRange( + createVariableDeclaration( + getSynthesizedClone(namespaceDeclaration.name), + /*type*/ undefined, + getGeneratedNameForNode(node) + ), /*location*/ node ) ], - /*location*/ undefined, languageVersion >= ScriptTarget.ES2015 ? NodeFlags.Const : NodeFlags.None ) ) @@ -592,31 +595,34 @@ namespace ts { if (moduleKind !== ModuleKind.AMD) { if (hasModifier(node, ModifierFlags.Export)) { statements = append(statements, - createStatement( - createExportExpression( - node.name, - createRequireCall(node) + setTextRange( + createStatement( + createExportExpression( + node.name, + createRequireCall(node) + ) ), - /*location*/ node + node ) ); } else { statements = append(statements, - createVariableStatement( - /*modifiers*/ undefined, - createVariableDeclarationList( - [ - createVariableDeclaration( - getSynthesizedClone(node.name), - /*type*/ undefined, - createRequireCall(node) - ) - ], - /*location*/ undefined, - /*flags*/ languageVersion >= ScriptTarget.ES2015 ? NodeFlags.Const : NodeFlags.None + setTextRange( + createVariableStatement( + /*modifiers*/ undefined, + createVariableDeclarationList( + [ + createVariableDeclaration( + getSynthesizedClone(node.name), + /*type*/ undefined, + createRequireCall(node) + ) + ], + /*flags*/ languageVersion >= ScriptTarget.ES2015 ? NodeFlags.Const : NodeFlags.None + ) ), - /*location*/ node + node ) ); } @@ -624,9 +630,11 @@ namespace ts { else { if (hasModifier(node, ModifierFlags.Export)) { statements = append(statements, - createStatement( - createExportExpression(getExportName(node), getLocalName(node)), - /*location*/ node + setTextRange( + createStatement( + createExportExpression(getExportName(node), getLocalName(node)) + ), + node ) ); } @@ -662,15 +670,17 @@ namespace ts { // export { x, y } from "mod"; if (moduleKind !== ModuleKind.AMD) { statements.push( - createVariableStatement( - /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( - generatedName, - /*type*/ undefined, - createRequireCall(node) - ) - ]), + setTextRange( + createVariableStatement( + /*modifiers*/ undefined, + createVariableDeclarationList([ + createVariableDeclaration( + generatedName, + /*type*/ undefined, + createRequireCall(node) + ) + ]) + ), /*location*/ node ) ); @@ -681,9 +691,11 @@ namespace ts { specifier.propertyName || specifier.name ); statements.push( - createStatement( - createExportExpression(getExportName(specifier), exportedValue), - /*location*/ specifier + setTextRange( + createStatement( + createExportExpression(getExportName(specifier), exportedValue) + ), + specifier ) ); } @@ -692,17 +704,19 @@ namespace ts { } else { // export * from "mod"; - return createStatement( - createCall( - createIdentifier("__export"), - /*typeArguments*/ undefined, - [ - moduleKind !== ModuleKind.AMD - ? createRequireCall(node) - : generatedName - ] + return setTextRange( + createStatement( + createCall( + createIdentifier("__export"), + /*typeArguments*/ undefined, + [ + moduleKind !== ModuleKind.AMD + ? createRequireCall(node) + : generatedName + ] + ) ), - /*location*/ node + node ); } } @@ -741,15 +755,17 @@ namespace ts { if (hasModifier(node, ModifierFlags.Export)) { statements = append(statements, setOriginalNode( - createFunctionDeclaration( - /*decorators*/ undefined, - visitNodes(node.modifiers, modifierVisitor, isModifier), - node.asteriskToken, - getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), - /*typeParameters*/ undefined, - node.parameters, - /*type*/ undefined, - node.body, + setTextRange( + createFunctionDeclaration( + /*decorators*/ undefined, + visitNodes(node.modifiers, modifierVisitor, isModifier), + node.asteriskToken, + getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), + /*typeParameters*/ undefined, + node.parameters, + /*type*/ undefined, + node.body + ), /*location*/ node ), /*original*/ node @@ -782,16 +798,18 @@ namespace ts { if (hasModifier(node, ModifierFlags.Export)) { statements = append(statements, setOriginalNode( - createClassDeclaration( - /*decorators*/ undefined, - visitNodes(node.modifiers, modifierVisitor, isModifier), - getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), - /*typeParameters*/ undefined, - node.heritageClauses, - node.members, - /*location*/ node + setTextRange( + createClassDeclaration( + /*decorators*/ undefined, + visitNodes(node.modifiers, modifierVisitor, isModifier), + getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), + /*typeParameters*/ undefined, + node.heritageClauses, + node.members + ), + node ), - /*original*/ node + node ) ); } @@ -843,7 +861,7 @@ namespace ts { } if (expressions) { - statements = append(statements, createStatement(inlineExpressions(expressions), /*location*/ node)); + statements = append(statements, setTextRange(createStatement(inlineExpressions(expressions)), node)); } } else { @@ -880,9 +898,11 @@ namespace ts { } else { return createAssignment( - createPropertyAccess( - createIdentifier("exports"), - node.name, + setTextRange( + createPropertyAccess( + createIdentifier("exports"), + node.name + ), /*location*/ node.name ), node.initializer @@ -1115,7 +1135,7 @@ namespace ts { createStatement( createExportExpression( createIdentifier("__esModule"), - createLiteral(true) + createTrue() ) ) ); @@ -1130,7 +1150,7 @@ namespace ts { createIdentifier("exports"), createLiteral("__esModule"), createObjectLiteral([ - createPropertyAssignment("value", createLiteral(true)) + createPropertyAssignment("value", createTrue()) ]) ] ) @@ -1153,7 +1173,7 @@ namespace ts { * @param allowComments An optional value indicating whether to emit comments for the statement. */ function createExportStatement(name: Identifier, value: Expression, location?: TextRange, allowComments?: boolean) { - const statement = createStatement(createExportExpression(name, value), location); + const statement = setTextRange(createStatement(createExportExpression(name, value)), location); startOnNewLine(statement); if (!allowComments) { setEmitFlags(statement, EmitFlags.NoComments); @@ -1170,12 +1190,14 @@ namespace ts { * @param location The location to use for source maps and comments for the export. */ function createExportExpression(name: Identifier, value: Expression, location?: TextRange) { - return createAssignment( - createPropertyAccess( - createIdentifier("exports"), - getSynthesizedClone(name) + return setTextRange( + createAssignment( + createPropertyAccess( + createIdentifier("exports"), + getSynthesizedClone(name) + ), + value ), - value, location ); } @@ -1207,24 +1229,24 @@ namespace ts { /** * Hook for node emit notifications. * - * @param emitContext A context hint for the emitter. + * @param hint A hint as to the intended usage of the node. * @param node The node to emit. * @param emit A callback used to emit the node in the printer. */ - function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void { + function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void { if (node.kind === SyntaxKind.SourceFile) { currentSourceFile = node; currentModuleInfo = moduleInfoMap[getOriginalNodeId(currentSourceFile)]; noSubstitution = []; - previousOnEmitNode(emitContext, node, emitCallback); + previousOnEmitNode(hint, node, emitCallback); currentSourceFile = undefined; currentModuleInfo = undefined; noSubstitution = undefined; } else { - previousOnEmitNode(emitContext, node, emitCallback); + previousOnEmitNode(hint, node, emitCallback); } } @@ -1235,16 +1257,16 @@ namespace ts { /** * Hooks node substitutions. * - * @param emitContext A context hint for the emitter. + * @param hint A hint as to the intended usage of the node. * @param node The node to substitute. */ - function onSubstituteNode(emitContext: EmitContext, node: Node) { - node = previousOnSubstituteNode(emitContext, node); + function onSubstituteNode(hint: EmitHint, node: Node) { + node = previousOnSubstituteNode(hint, node); if (node.id && noSubstitution[node.id]) { return node; } - if (emitContext === EmitContext.Expression) { + if (hint === EmitHint.Expression) { return substituteExpression(node); } else if (isShorthandPropertyAssignment(node)) { @@ -1268,9 +1290,9 @@ namespace ts { // destructuring assignment if (node.objectAssignmentInitializer) { const initializer = createAssignment(exportedOrImportedName, node.objectAssignmentInitializer); - return createPropertyAssignment(name, initializer, /*location*/ node); + return setTextRange(createPropertyAssignment(name, initializer), node); } - return createPropertyAssignment(name, exportedOrImportedName, /*location*/ node); + return setTextRange(createPropertyAssignment(name, exportedOrImportedName), node); } return node; } @@ -1312,9 +1334,11 @@ namespace ts { if (!isGeneratedIdentifier(node) && !isLocalName(node)) { const exportContainer = resolver.getReferencedExportContainer(node, isExportName(node)); if (exportContainer && exportContainer.kind === SyntaxKind.SourceFile) { - return createPropertyAccess( - createIdentifier("exports"), - getSynthesizedClone(node), + return setTextRange( + createPropertyAccess( + createIdentifier("exports"), + getSynthesizedClone(node) + ), /*location*/ node ); } @@ -1322,17 +1346,21 @@ namespace ts { const importDeclaration = resolver.getReferencedImportDeclaration(node); if (importDeclaration) { if (isImportClause(importDeclaration)) { - return createPropertyAccess( - getGeneratedNameForNode(importDeclaration.parent), - createIdentifier("default"), + return setTextRange( + createPropertyAccess( + getGeneratedNameForNode(importDeclaration.parent), + createIdentifier("default") + ), /*location*/ node ); } else if (isImportSpecifier(importDeclaration)) { const name = importDeclaration.propertyName || importDeclaration.name; - return createPropertyAccess( - getGeneratedNameForNode(importDeclaration.parent.parent.parent), - getSynthesizedClone(name), + return setTextRange( + createPropertyAccess( + getGeneratedNameForNode(importDeclaration.parent.parent.parent), + getSynthesizedClone(name) + ), /*location*/ node ); } @@ -1400,10 +1428,12 @@ namespace ts { const exportedNames = getExports(node.operand); if (exportedNames) { let expression: Expression = node.kind === SyntaxKind.PostfixUnaryExpression - ? createBinary( - node.operand, - createToken(node.operator === SyntaxKind.PlusPlusToken ? SyntaxKind.PlusEqualsToken : SyntaxKind.MinusEqualsToken), - createLiteral(1), + ? setTextRange( + createBinary( + node.operand, + createToken(node.operator === SyntaxKind.PlusPlusToken ? SyntaxKind.PlusEqualsToken : SyntaxKind.MinusEqualsToken), + createLiteral(1) + ), /*location*/ node) : node; for (const exportName of exportedNames) { diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 3f1488b649d..b2999201504 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -105,17 +105,20 @@ namespace ts { const updated = setEmitFlags( updateSourceFileNode( node, - createNodeArray([ - createStatement( - createCall( - createPropertyAccess(createIdentifier("System"), "register"), - /*typeArguments*/ undefined, - moduleName - ? [moduleName, dependencies, moduleBodyFunction] - : [dependencies, moduleBodyFunction] + setTextRange( + createNodeArray([ + createStatement( + createCall( + createPropertyAccess(createIdentifier("System"), "register"), + /*typeArguments*/ undefined, + moduleName + ? [moduleName, dependencies, moduleBodyFunction] + : [dependencies, moduleBodyFunction] + ) ) - ) - ], node.statements) + ]), + node.statements + ) ), EmitFlags.NoTrailingComments); if (!(compilerOptions.outFile || compilerOptions.out)) { @@ -260,35 +263,26 @@ namespace ts { addRange(statements, endLexicalEnvironment()); const exportStarFunction = addExportStarIfNeeded(statements); - statements.push( - createReturn( - setMultiLine( - createObjectLiteral([ - createPropertyAssignment("setters", - createSettersArray(exportStarFunction, dependencyGroups) - ), - createPropertyAssignment("execute", - createFunctionExpression( - /*modifiers*/ undefined, - /*asteriskToken*/ undefined, - /*name*/ undefined, - /*typeParameters*/ undefined, - /*parameters*/ [], - /*type*/ undefined, - createBlock( - executeStatements, - /*location*/ undefined, - /*multiLine*/ true - ) - ) - ) - ]), - /*multiLine*/ true + const moduleObject = createObjectLiteral([ + createPropertyAssignment("setters", + createSettersArray(exportStarFunction, dependencyGroups) + ), + createPropertyAssignment("execute", + createFunctionExpression( + /*modifiers*/ undefined, + /*asteriskToken*/ undefined, + /*name*/ undefined, + /*typeParameters*/ undefined, + /*parameters*/ [], + /*type*/ undefined, + createBlock(executeStatements, /*multiLine*/ true) ) ) - ); + ]); - return createBlock(statements, /*location*/ undefined, /*multiLine*/ true); + moduleObject.multiLine = true; + statements.push(createReturn(moduleObject)); + return createBlock(statements, /*multiLine*/ true); } /** @@ -337,7 +331,7 @@ namespace ts { exportedNames.push( createPropertyAssignment( createLiteral(exportedLocalName), - createLiteral(true) + createTrue() ) ); } @@ -359,7 +353,7 @@ namespace ts { exportedNames.push( createPropertyAssignment( createLiteral((element.name || element.propertyName).text), - createLiteral(true) + createTrue() ) ); } @@ -373,7 +367,7 @@ namespace ts { createVariableDeclaration( exportedNamesStorageRef, /*type*/ undefined, - createObjectLiteral(exportedNames, /*location*/ undefined, /*multiline*/ true) + createObjectLiteral(exportedNames, /*multiline*/ true) ) ]) ) @@ -456,9 +450,7 @@ namespace ts { [exports] ) ) - ], - /*location*/ undefined, - /*multiline*/ true) + ], /*multiline*/ true) ); } @@ -525,7 +517,7 @@ namespace ts { createCall( exportFunction, /*typeArguments*/ undefined, - [createObjectLiteral(properties, /*location*/ undefined, /*multiline*/ true)] + [createObjectLiteral(properties, /*multiline*/ true)] ) ) ); @@ -558,12 +550,12 @@ namespace ts { /*typeParameters*/ undefined, [createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], /*type*/ undefined, - createBlock(statements, /*location*/ undefined, /*multiLine*/ true) + createBlock(statements, /*multiLine*/ true) ) ); } - return createArrayLiteral(setters, /*location*/ undefined, /*multiLine*/ true); + return createArrayLiteral(setters, /*multiLine*/ true); } // @@ -713,19 +705,23 @@ namespace ts { // Rewrite the class declaration into an assignment of a class expression. statements = append(statements, - createStatement( - createAssignment( - name, - createClassExpression( - /*modifiers*/ undefined, - node.name, - /*typeParameters*/ undefined, - visitNodes(node.heritageClauses, destructuringVisitor, isHeritageClause), - visitNodes(node.members, destructuringVisitor, isClassElement), - /*location*/ node + setTextRange( + createStatement( + createAssignment( + name, + setTextRange( + createClassExpression( + /*modifiers*/ undefined, + node.name, + /*typeParameters*/ undefined, + visitNodes(node.heritageClauses, destructuringVisitor, isHeritageClause), + visitNodes(node.members, destructuringVisitor, isClassElement) + ), + node + ) ) ), - /*location*/ node + node ) ); @@ -766,7 +762,7 @@ namespace ts { let statements: Statement[]; if (expressions) { - statements = append(statements, createStatement(inlineExpressions(expressions), /*location*/ node)); + statements = append(statements, setTextRange(createStatement(inlineExpressions(expressions)), node)); } if (isMarkedDeclaration) { @@ -864,8 +860,8 @@ namespace ts { function createVariableAssignment(name: Identifier, value: Expression, location: TextRange, isExportedDeclaration: boolean) { hoistVariableDeclaration(getSynthesizedClone(name)); return isExportedDeclaration - ? createExportExpression(name, preventSubstitution(createAssignment(name, value, location))) - : preventSubstitution(createAssignment(name, value, location)); + ? createExportExpression(name, preventSubstitution(setTextRange(createAssignment(name, value), location))) + : preventSubstitution(setTextRange(createAssignment(name, value), location)); } /** @@ -1548,11 +1544,11 @@ namespace ts { /** * Hook for node emit notifications. * - * @param emitContext A context hint for the emitter. + * @param hint A hint as to the intended usage of the node. * @param node The node to emit. - * @param emit A callback used to emit the node in the printer. + * @param emitCallback A callback used to emit the node in the printer. */ - function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void { + function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void { if (node.kind === SyntaxKind.SourceFile) { const id = getOriginalNodeId(node); currentSourceFile = node; @@ -1564,7 +1560,7 @@ namespace ts { delete noSubstitutionMap[id]; } - previousOnEmitNode(emitContext, node, emitCallback); + previousOnEmitNode(hint, node, emitCallback); currentSourceFile = undefined; moduleInfo = undefined; @@ -1572,7 +1568,7 @@ namespace ts { noSubstitution = undefined; } else { - previousOnEmitNode(emitContext, node, emitCallback); + previousOnEmitNode(hint, node, emitCallback); } } @@ -1583,16 +1579,16 @@ namespace ts { /** * Hooks node substitutions. * - * @param emitContext A context hint for the emitter. + * @param hint A hint as to the intended usage of the node. * @param node The node to substitute. */ - function onSubstituteNode(emitContext: EmitContext, node: Node) { - node = previousOnSubstituteNode(emitContext, node); + function onSubstituteNode(hint: EmitHint, node: Node) { + node = previousOnSubstituteNode(hint, node); if (isSubstitutionPrevented(node)) { return node; } - if (emitContext === EmitContext.Expression) { + if (hint === EmitHint.Expression) { return substituteExpression(node); } @@ -1642,16 +1638,20 @@ namespace ts { const importDeclaration = resolver.getReferencedImportDeclaration(node); if (importDeclaration) { if (isImportClause(importDeclaration)) { - return createPropertyAccess( - getGeneratedNameForNode(importDeclaration.parent), - createIdentifier("default"), + return setTextRange( + createPropertyAccess( + getGeneratedNameForNode(importDeclaration.parent), + createIdentifier("default") + ), /*location*/ node ); } else if (isImportSpecifier(importDeclaration)) { - return createPropertyAccess( - getGeneratedNameForNode(importDeclaration.parent.parent.parent), - getSynthesizedClone(importDeclaration.propertyName || importDeclaration.name), + return setTextRange( + createPropertyAccess( + getGeneratedNameForNode(importDeclaration.parent.parent.parent), + getSynthesizedClone(importDeclaration.propertyName || importDeclaration.name) + ), /*location*/ node ); } @@ -1718,10 +1718,13 @@ namespace ts { const exportedNames = getExports(node.operand); if (exportedNames) { let expression: Expression = node.kind === SyntaxKind.PostfixUnaryExpression - ? createPrefix( - node.operator, - node.operand, - /*location*/ node) + ? setTextRange( + createPrefix( + node.operator, + node.operand + ), + node + ) : node; for (const exportName of exportedNames) { diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index e2b8b8fe2ec..4ef3bd5c067 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -588,17 +588,17 @@ namespace ts { name, /*typeParameters*/ undefined, visitNodes(node.heritageClauses, visitor, isHeritageClause), - transformClassMembers(node, hasExtendsClause), - node); - - let emitFlags = getEmitFlags(node); + transformClassMembers(node, hasExtendsClause) + ); // To better align with the old emitter, we should not emit a trailing source map // entry if the class has static properties. + let emitFlags = getEmitFlags(node); if (hasStaticProperties) { emitFlags |= EmitFlags.NoTrailingSourceMap; } + setTextRange(classDeclaration, node); setOriginalNode(classDeclaration, node); setEmitFlags(classDeclaration, emitFlags); return classDeclaration; @@ -709,13 +709,24 @@ namespace ts { // } const heritageClauses = visitNodes(node.heritageClauses, visitor, isHeritageClause); const members = transformClassMembers(node, hasExtendsClause); - const classExpression = createClassExpression(/*modifiers*/ undefined, name, /*typeParameters*/ undefined, heritageClauses, members, location); + const classExpression = createClassExpression(/*modifiers*/ undefined, name, /*typeParameters*/ undefined, heritageClauses, members); setOriginalNode(classExpression, node); + setTextRange(classExpression, location); // let ${name} = ${classExpression} where name is either declaredName if the class doesn't contain self-reference // or decoratedClassAlias if the class contain self-reference. - const statement = createLetStatement(declName, classAlias ? createAssignment(classAlias, classExpression) : classExpression, location); + const statement = createVariableStatement( + /*modifiers*/ undefined, + createVariableDeclarationList([ + createVariableDeclaration( + declName, + /*type*/ undefined, + classAlias ? createAssignment(classAlias, classExpression) : classExpression + ) + ], NodeFlags.Let) + ); setOriginalNode(statement, node); + setTextRange(statement, location); setCommentRange(statement, node); return statement; } @@ -734,18 +745,17 @@ namespace ts { const heritageClauses = visitNodes(node.heritageClauses, visitor, isHeritageClause); const members = transformClassMembers(node, some(heritageClauses, c => c.token === SyntaxKind.ExtendsKeyword)); - const classExpression = setOriginalNode( - createClassExpression( - /*modifiers*/ undefined, - node.name, - /*typeParameters*/ undefined, - heritageClauses, - members, - /*location*/ node - ), - node + const classExpression = createClassExpression( + /*modifiers*/ undefined, + node.name, + /*typeParameters*/ undefined, + heritageClauses, + members ); + setOriginalNode(classExpression, node); + setTextRange(classExpression, node); + if (staticProperties.length > 0) { const expressions: Expression[] = []; const temp = createTempVariable(hoistVariableDeclaration); @@ -781,7 +791,7 @@ namespace ts { } addRange(members, visitNodes(node.members, classElementVisitor, isClassElement)); - return createNodeArray(members, /*location*/ node.members); + return setTextRange(createNodeArray(members), /*location*/ node.members); } /** @@ -812,12 +822,14 @@ namespace ts { // } return startOnNewLine( setOriginalNode( - createConstructor( - /*decorators*/ undefined, - /*modifiers*/ undefined, - parameters, - body, - /*location*/ constructor || node + setTextRange( + createConstructor( + /*decorators*/ undefined, + /*modifiers*/ undefined, + parameters, + body + ), + constructor || node ), constructor ) @@ -919,13 +931,15 @@ namespace ts { // End the lexical environment. addRange(statements, endLexicalEnvironment()); - return createBlock( - createNodeArray( - statements, - /*location*/ constructor ? constructor.body.statements : node.members + return setTextRange( + createBlock( + setTextRange( + createNodeArray(statements), + /*location*/ constructor ? constructor.body.statements : node.members + ), + /*multiLine*/ true ), - /*location*/ constructor ? constructor.body : /*location*/ undefined, - /*multiLine*/ true + /*location*/ constructor ? constructor.body : undefined ); } @@ -991,16 +1005,20 @@ namespace ts { setEmitFlags(localName, EmitFlags.NoComments); return startOnNewLine( - createStatement( - createAssignment( - createPropertyAccess( - createThis(), - propertyName, - /*location*/ node.name - ), - localName + setTextRange( + createStatement( + createAssignment( + setTextRange( + createPropertyAccess( + createThis(), + propertyName + ), + node.name + ), + localName + ) ), - /*location*/ moveRangePos(node, -1) + moveRangePos(node, -1) ) ); } @@ -1504,7 +1522,7 @@ namespace ts { (properties || (properties = [])).push(createPropertyAssignment("returnType", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, createToken(SyntaxKind.EqualsGreaterThanToken), serializeReturnTypeOfNode(node)))); } if (properties) { - decoratorExpressions.push(createMetadataHelper(context, "design:typeinfo", createObjectLiteral(properties, /*location*/ undefined, /*multiLine*/ true))); + decoratorExpressions.push(createMetadataHelper(context, "design:typeinfo", createObjectLiteral(properties, /*multiLine*/ true))); } } } @@ -1939,10 +1957,7 @@ namespace ts { expression = createAssignment(generatedName, expression); } - return setOriginalNode( - createComputedPropertyName(expression, /*location*/ name), - name - ); + return updateComputedPropertyName(name, expression); } else { return name; @@ -1961,9 +1976,11 @@ namespace ts { function visitHeritageClause(node: HeritageClause): HeritageClause { if (node.token === SyntaxKind.ExtendsKeyword) { const types = visitNodes(node.types, visitor, isExpressionWithTypeArguments, 0, 1); - return createHeritageClause( - SyntaxKind.ExtendsKeyword, - types, + return setTextRange( + createHeritageClause( + SyntaxKind.ExtendsKeyword, + types + ), node ); } @@ -1980,11 +1997,10 @@ namespace ts { * @param node The ExpressionWithTypeArguments to transform. */ function visitExpressionWithTypeArguments(node: ExpressionWithTypeArguments): ExpressionWithTypeArguments { - const expression = visitNode(node.expression, visitor, isLeftHandSideExpression); - return createExpressionWithTypeArguments( + return updateExpressionWithTypeArguments( + node, /*typeArguments*/ undefined, - expression, - node + visitNode(node.expression, visitor, isLeftHandSideExpression) ); } @@ -2205,13 +2221,13 @@ namespace ts { visitNode(node.name, visitor, isBindingName), /*questionToken*/ undefined, /*type*/ undefined, - visitNode(node.initializer, visitor, isExpression), - /*location*/ moveRangePastModifiers(node) + visitNode(node.initializer, visitor, isExpression) ); // While we emit the source map for the node after skipping decorators and modifiers, // we need to emit the comments for the original range. setOriginalNode(parameter, node); + setTextRange(parameter, moveRangePastModifiers(node)); setCommentRange(parameter, node); setSourceMapRange(parameter, moveRangePastModifiers(node)); setEmitFlags(parameter.name, EmitFlags.NoTrailingSourceMap); @@ -2233,11 +2249,13 @@ namespace ts { return undefined; } - return createStatement( - inlineExpressions( - map(variables, transformInitializedVariable) + return setTextRange( + createStatement( + inlineExpressions( + map(variables, transformInitializedVariable) + ) ), - /*location*/ node + node ); } else { @@ -2258,9 +2276,11 @@ namespace ts { ); } else { - return createAssignment( - getNamespaceMemberNameWithSourceMapsAndWithoutComments(name), - visitNode(node.initializer, visitor, isExpression), + return setTextRange( + createAssignment( + getNamespaceMemberNameWithSourceMapsAndWithoutComments(name), + visitNode(node.initializer, visitor, isExpression) + ), /*location*/ node ); } @@ -2418,11 +2438,11 @@ namespace ts { ), /*typeArguments*/ undefined, [moduleArg] - ), - /*location*/ node + ) ); setOriginalNode(enumStatement, node); + setTextRange(enumStatement, node); setEmitFlags(enumStatement, emitFlags); statements.push(enumStatement); @@ -2448,8 +2468,7 @@ namespace ts { currentNamespaceContainerName = savedCurrentNamespaceLocalName; return createBlock( - createNodeArray(statements, /*location*/ node.members), - /*location*/ undefined, + setTextRange(createNodeArray(statements), /*location*/ node.members), /*multiLine*/ true ); } @@ -2464,22 +2483,26 @@ namespace ts { // we pass false as 'generateNameForComputedPropertyName' for a backward compatibility purposes // old emitter always generate 'expression' part of the name as-is. const name = getExpressionForPropertyName(member, /*generateNameForComputedPropertyName*/ false); - return createStatement( - createAssignment( - createElementAccess( - currentNamespaceContainerName, + return setTextRange( + createStatement( + setTextRange( createAssignment( createElementAccess( currentNamespaceContainerName, - name + createAssignment( + createElementAccess( + currentNamespaceContainerName, + name + ), + transformEnumMemberDeclarationValue(member) + ) ), - transformEnumMemberDeclarationValue(member) - ) - ), - name, - /*location*/ member + name + ), + member + ) ), - /*location*/ member + member ); } @@ -2697,11 +2720,11 @@ namespace ts { ), /*typeArguments*/ undefined, [moduleArg] - ), - /*location*/ node + ) ); setOriginalNode(moduleStatement, node); + setTextRange(moduleStatement, node); setEmitFlags(moduleStatement, emitFlags); statements.push(moduleStatement); @@ -2756,13 +2779,13 @@ namespace ts { currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName; const block = createBlock( - createNodeArray( - statements, + setTextRange( + createNodeArray(statements), /*location*/ statementsLocation ), - /*location*/ blockLocation, /*multiLine*/ true ); + setTextRange(block, blockLocation); // namespace hello.hi.world { // function foo() {} @@ -2962,18 +2985,20 @@ namespace ts { // export var ${name} = ${moduleReference}; // var ${name} = ${moduleReference}; return setOriginalNode( - createVariableStatement( - visitNodes(node.modifiers, modifierVisitor, isModifier), - createVariableDeclarationList([ - setOriginalNode( - createVariableDeclaration( - node.name, - /*type*/ undefined, - moduleReference - ), - node - ) - ]), + setTextRange( + createVariableStatement( + visitNodes(node.modifiers, modifierVisitor, isModifier), + createVariableDeclarationList([ + setOriginalNode( + createVariableDeclaration( + node.name, + /*type*/ undefined, + moduleReference + ), + node + ) + ]) + ), node ), node @@ -3034,7 +3059,7 @@ namespace ts { * Creates a statement for the provided expression. This is used in calls to `map`. */ function expressionToStatement(expression: Expression) { - return createStatement(expression, /*location*/ undefined); + return createStatement(expression); } function addExportMemberAssignment(statements: Statement[], node: ClassDeclaration | FunctionDeclaration) { @@ -3050,17 +3075,19 @@ namespace ts { } function createNamespaceExport(exportName: Identifier, exportValue: Expression, location?: TextRange) { - return createStatement( - createAssignment( - getNamespaceMemberName(currentNamespaceContainerName, exportName, /*allowComments*/ false, /*allowSourceMaps*/ true), - exportValue + return setTextRange( + createStatement( + createAssignment( + getNamespaceMemberName(currentNamespaceContainerName, exportName, /*allowComments*/ false, /*allowSourceMaps*/ true), + exportValue + ) ), location ); } function createNamespaceExportExpression(exportName: Identifier, exportValue: Expression, location?: TextRange) { - return createAssignment(getNamespaceMemberNameWithSourceMapsAndWithoutComments(exportName), exportValue, location); + return setTextRange(createAssignment(getNamespaceMemberNameWithSourceMapsAndWithoutComments(exportName), exportValue), location); } function getNamespaceMemberNameWithSourceMapsAndWithoutComments(name: Identifier) { @@ -3092,7 +3119,7 @@ namespace ts { function getClassAliasIfNeeded(node: ClassDeclaration) { if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference) { enableSubstitutionForClassAliases(); - const classAlias = createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? node.name.text : "default"); + const classAlias = createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? unescapeIdentifier(node.name.text) : "default"); classAliases[getOriginalNodeId(node)] = classAlias; hoistVariableDeclaration(classAlias); return classAlias; @@ -3154,11 +3181,11 @@ namespace ts { /** * Hook for node emit. * - * @param emitContext A context hint for the emitter. + * @param hint A hint as to the intended usage of the node. * @param node The node to emit. * @param emit A callback used to emit the node in the printer. */ - function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void { + function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void { const savedApplicableSubstitutions = applicableSubstitutions; if (enabledSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports && isTransformedModuleDeclaration(node)) { @@ -3169,7 +3196,7 @@ namespace ts { applicableSubstitutions |= TypeScriptSubstitutionFlags.NonQualifiedEnumMembers; } - previousOnEmitNode(emitContext, node, emitCallback); + previousOnEmitNode(hint, node, emitCallback); applicableSubstitutions = savedApplicableSubstitutions; } @@ -3177,12 +3204,12 @@ namespace ts { /** * Hooks node substitutions. * - * @param emitContext A context hint for the emitter. + * @param hint A hint as to the intended usage of the node. * @param node The node to substitute. */ - function onSubstituteNode(emitContext: EmitContext, node: Node) { - node = previousOnSubstituteNode(emitContext, node); - if (emitContext === EmitContext.Expression) { + function onSubstituteNode(hint: EmitHint, node: Node) { + node = previousOnSubstituteNode(hint, node); + if (hint === EmitHint.Expression) { return substituteExpression(node); } else if (isShorthandPropertyAssignment(node)) { @@ -3201,9 +3228,9 @@ namespace ts { // destructuring assignment if (node.objectAssignmentInitializer) { const initializer = createAssignment(exportedName, node.objectAssignmentInitializer); - return createPropertyAssignment(name, initializer, /*location*/ node); + return setTextRange(createPropertyAssignment(name, initializer), node); } - return createPropertyAssignment(name, exportedName, /*location*/ node); + return setTextRange(createPropertyAssignment(name, exportedName), node); } } return node; @@ -3263,7 +3290,10 @@ namespace ts { (applicableSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports && container.kind === SyntaxKind.ModuleDeclaration) || (applicableSubstitutions & TypeScriptSubstitutionFlags.NonQualifiedEnumMembers && container.kind === SyntaxKind.EnumDeclaration); if (substitute) { - return createPropertyAccess(getGeneratedNameForNode(container), node, /*location*/ node); + return setTextRange( + createPropertyAccess(getGeneratedNameForNode(container), node), + /*location*/ node + ); } } } @@ -3322,13 +3352,15 @@ namespace ts { function createParamHelper(context: TransformationContext, expression: Expression, parameterOffset: number, location?: TextRange) { context.requestEmitHelper(paramHelper); - return createCall( - getHelperName("__param"), - /*typeArguments*/ undefined, - [ - createLiteral(parameterOffset), - expression - ], + return setTextRange( + createCall( + getHelperName("__param"), + /*typeArguments*/ undefined, + [ + createLiteral(parameterOffset), + expression + ] + ), location ); } @@ -3371,7 +3403,7 @@ namespace ts { function createDecorateHelper(context: TransformationContext, decoratorExpressions: Expression[], target: Expression, memberName?: Expression, descriptor?: Expression, location?: TextRange) { context.requestEmitHelper(decorateHelper); const argumentsArray: Expression[] = []; - argumentsArray.push(createArrayLiteral(decoratorExpressions, /*location*/ undefined, /*multiLine*/ true)); + argumentsArray.push(createArrayLiteral(decoratorExpressions, /*multiLine*/ true)); argumentsArray.push(target); if (memberName) { argumentsArray.push(memberName); @@ -3380,6 +3412,13 @@ namespace ts { } } - return createCall(getHelperName("__decorate"), /*typeArguments*/ undefined, argumentsArray, location); + return setTextRange( + createCall( + getHelperName("__decorate"), + /*typeArguments*/ undefined, + argumentsArray + ), + location + ); } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 8b49af402cf..49e744682bc 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -348,6 +348,7 @@ EnumMember, // Top-level nodes SourceFile, + Bundle, // JSDoc nodes JSDocTypeExpression, @@ -957,8 +958,7 @@ } // Represents an expression that is elided as part of a transformation to emit comments on a - // not-emitted node. The 'expression' property of a NotEmittedExpression should be emitted. - // @internal + // not-emitted node. The 'expression' property of a PartiallyEmittedExpression should be emitted. export interface PartiallyEmittedExpression extends LeftHandSideExpression { kind: SyntaxKind.PartiallyEmittedExpression; expression: Expression; @@ -1537,7 +1537,6 @@ // Represents a statement that is elided as part of a transformation to emit comments on a // not-emitted node. - // @internal export interface NotEmittedStatement extends Statement { kind: SyntaxKind.NotEmittedStatement; } @@ -1772,24 +1771,28 @@ members: NodeArray; } - export type ModuleBody = ModuleBlock | ModuleDeclaration; - export type ModuleName = Identifier | StringLiteral; + export type ModuleBody = NamespaceBody | JSDocNamespaceBody; + export interface ModuleDeclaration extends DeclarationStatement { kind: SyntaxKind.ModuleDeclaration; name: Identifier | StringLiteral; - body?: ModuleBlock | NamespaceDeclaration | JSDocNamespaceDeclaration | Identifier; + body?: ModuleBody | JSDocNamespaceDeclaration | Identifier; } + export type NamespaceBody = ModuleBlock | NamespaceDeclaration; + export interface NamespaceDeclaration extends ModuleDeclaration { name: Identifier; - body: ModuleBlock | NamespaceDeclaration; + body: NamespaceBody; } + export type JSDocNamespaceBody = Identifier | JSDocNamespaceDeclaration; + export interface JSDocNamespaceDeclaration extends ModuleDeclaration { name: Identifier; - body: JSDocNamespaceDeclaration | Identifier; + body: JSDocNamespaceBody; } export interface ModuleBlock extends Node, Statement { @@ -2201,6 +2204,11 @@ /* @internal */ ambientModuleNames: string[]; } + export interface Bundle extends Node { + kind: SyntaxKind.Bundle; + sourceFiles: SourceFile[]; + } + export interface ScriptReferenceHost { getCompilerOptions(): CompilerOptions; getSourceFile(fileName: string): SourceFile; @@ -3724,7 +3732,6 @@ helpers?: EmitHelper[]; // Emit helpers for the node } - /* @internal */ export const enum EmitFlags { SingleLine = 1 << 0, // The contents of this node should be emitted on a single line. AdviseOnEmitNode = 1 << 1, // The printer should invoke the onEmitNode callback when printing this node. @@ -3753,7 +3760,6 @@ HasEndOfDeclarationMarker = 1 << 21, // Declaration has an associated NotEmittedStatement to mark the end of the declaration } - /* @internal */ export interface EmitHelper { readonly name: string; // A unique name for this helper. readonly scoped: boolean; // Indicates whether ther helper MUST be emitted in the current scope. @@ -3780,8 +3786,7 @@ LastEmitHelper = Generator } - /* @internal */ - export const enum EmitContext { + export const enum EmitHint { SourceFile, // Emitting a SourceFile Expression, // Emitting an Expression IdentifierName, // Emitting an IdentifierName @@ -3856,7 +3861,7 @@ * Hook used by transformers to substitute expressions just before they * are emitted by the pretty printer. */ - onSubstituteNode?: (emitContext: EmitContext, node: Node) => Node; + onSubstituteNode?: (hint: EmitHint, node: Node) => Node; /** * Enables before/after emit notifications in the pretty printer for the provided @@ -3874,7 +3879,7 @@ * Hook used to allow transformers to capture state before or after * the printer emits a node. */ - onEmitNode?: (emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) => void; + onEmitNode?: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void; } /* @internal */ @@ -3887,25 +3892,132 @@ /** * Emits the substitute for a node, if one is available; otherwise, emits the node. * - * @param emitContext The current emit context. + * @param hint A hint as to the intended usage of the node. * @param node The node to substitute. * @param emitCallback A callback used to emit the node or its substitute. */ - emitNodeWithSubstitution(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void; + emitNodeWithSubstitution(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void; /** * Emits a node with possible notification. * - * @param emitContext The current emit context. + * @param hint A hint as to the intended usage of the node. * @param node The node to emit. * @param emitCallback A callback used to emit the node. */ - emitNodeWithNotification(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void; + emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void; } /* @internal */ export type Transformer = (context: TransformationContext) => (node: SourceFile) => SourceFile; + export interface Printer { + /** + * Print a node and its subtree as-is, without any emit transformations. + * @param hint A value indicating the purpose of a node. This is primarily used to + * distinguish between an `Identifier` used in an expression position, versus an + * `Identifier` used as an `IdentifierName` as part of a declaration. For most nodes you + * should just pass `Unspecified`. + * @param node The node to print. The node and its subtree are printed as-is, without any + * emit transformations. + * @param sourceFile A source file that provides context for the node. The source text of + * the file is used to emit the original source content for literals and identifiers, while + * the identifiers of the source file are used when generating unique names to avoid + * collisions. + */ + printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): string; + /** + * Prints a source file as-is, without any emit transformations. + */ + printFile(sourceFile: SourceFile): string; + /** + * Prints a bundle of source files as-is, without any emit transformations. + */ + printBundle(bundle: Bundle): string; + /*@internal*/ writeNode(hint: EmitHint, node: Node, sourceFile: SourceFile, writer: EmitTextWriter): void; + /*@internal*/ writeFile(sourceFile: SourceFile, writer: EmitTextWriter): void; + /*@internal*/ writeBundle(bundle: Bundle, writer: EmitTextWriter): void; + } + + export interface PrintHandlers { + /** + * A hook used by the Printer when generating unique names to avoid collisions with + * globally defined names that exist outside of the current source file. + */ + hasGlobalName?(name: string): boolean; + /** + * A hook used by the Printer to provide notifications prior to emitting a node. A + * compatible implementation **must** invoke `emitCallback` with the provided `hint` and + * `node` values. + * @param hint A hint indicating the intended purpose of the node. + * @param node The node to emit. + * @param emitCallback A callback that, when invoked, will emit the node. + * @example + * ```ts + * var printer = createPrinter(printerOptions, { + * onEmitNode(hint, node, emitCallback) { + * // set up or track state prior to emitting the node... + * emitCallback(hint, node); + * // restore state after emitting the node... + * } + * }); + * ``` + */ + onEmitNode?(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void; + /** + * A hook used by the Printer to perform just-in-time substitution of a node. This is + * primarily used by node transformations that need to substitute one node for another, + * such as replacing `myExportedVar` with `exports.myExportedVar`. A compatible + * implementation **must** invoke `emitCallback` eith the provided `hint` and either + * the provided `node`, or its substitute. + * @param hint A hint indicating the intended purpose of the node. + * @param node The node to emit. + * @param emitCallback A callback that, when invoked, will emit the node. + * @example + * ```ts + * var printer = createPrinter(printerOptions, { + * onSubstituteNode(hint, node, emitCallback) { + * // perform substitution if necessary... + * emitCallback(hint, node); + * } + * }); + * ``` + */ + onSubstituteNode?(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void; + /*@internal*/ onEmitSourceMapOfNode?: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void; + /*@internal*/ onEmitSourceMapOfToken?: (node: Node, token: SyntaxKind, pos: number, emitCallback: (token: SyntaxKind, pos: number) => number) => number; + /*@internal*/ onEmitSourceMapOfPosition?: (pos: number) => void; + /*@internal*/ onEmitHelpers?: (node: Node, writeLines: (text: string) => void) => void; + /*@internal*/ onSetSourceFile?: (node: SourceFile) => void; + } + + export interface PrinterOptions { + target?: ScriptTarget; + removeComments?: boolean; + newLine?: NewLineKind; + /*@internal*/ sourceMap?: boolean; + /*@internal*/ inlineSourceMap?: boolean; + /*@internal*/ extendedDiagnostics?: boolean; + } + + /*@internal*/ + export interface EmitTextWriter { + write(s: string): void; + writeTextOfNode(text: string, node: Node): void; + writeLine(): void; + increaseIndent(): void; + decreaseIndent(): void; + getText(): string; + rawWrite(s: string): void; + writeLiteral(s: string): void; + getTextPos(): number; + getLine(): number; + getColumn(): number; + getIndent(): number; + isAtStartOfLine(): boolean; + reset(): void; + } + export interface TextSpan { start: number; length: number; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 985564e0d94..91cd6a89b8b 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2042,67 +2042,19 @@ namespace ts { || positionIsSynthesized(node.end); } - export function getOriginalNode(node: Node): Node; - export function getOriginalNode(node: Node, nodeTest: (node: Node) => node is T): T; - export function getOriginalNode(node: Node, nodeTest?: (node: Node) => boolean): Node { - if (node) { - while (node.original !== undefined) { - node = node.original; - } + export function getOriginalSourceFileOrBundle(sourceFileOrBundle: SourceFile | Bundle) { + if (sourceFileOrBundle.kind === SyntaxKind.Bundle) { + return updateBundle(sourceFileOrBundle, sameMap(sourceFileOrBundle.sourceFiles, getOriginalSourceFile)); } - - return !nodeTest || nodeTest(node) ? node : undefined; + return getOriginalSourceFile(sourceFileOrBundle); } - /** - * Gets a value indicating whether a node originated in the parse tree. - * - * @param node The node to test. - */ - export function isParseTreeNode(node: Node): boolean { - return (node.flags & NodeFlags.Synthesized) === 0; - } - - /** - * Gets the original parse tree node for a node. - * - * @param node The original node. - * @returns The original parse tree node if found; otherwise, undefined. - */ - export function getParseTreeNode(node: Node): Node; - - /** - * Gets the original parse tree node for a node. - * - * @param node The original node. - * @param nodeTest A callback used to ensure the correct type of parse tree node is returned. - * @returns The original parse tree node if found; otherwise, undefined. - */ - export function getParseTreeNode(node: Node, nodeTest?: (node: Node) => node is T): T; - export function getParseTreeNode(node: Node, nodeTest?: (node: Node) => boolean): Node { - if (isParseTreeNode(node)) { - return node; - } - - node = getOriginalNode(node); - - if (isParseTreeNode(node) && (!nodeTest || nodeTest(node))) { - return node; - } - - return undefined; + function getOriginalSourceFile(sourceFile: SourceFile) { + return getParseTreeNode(sourceFile, isSourceFile) || sourceFile; } export function getOriginalSourceFiles(sourceFiles: SourceFile[]) { - const originalSourceFiles: SourceFile[] = []; - for (const sourceFile of sourceFiles) { - const originalSourceFile = getParseTreeNode(sourceFile, isSourceFile); - if (originalSourceFile) { - originalSourceFiles.push(originalSourceFile); - } - } - - return originalSourceFiles; + return sameMap(sourceFiles, getOriginalSourceFile); } export function getOriginalNodeId(node: Node) { @@ -2441,23 +2393,6 @@ namespace ts { s; } - export interface EmitTextWriter { - write(s: string): void; - writeTextOfNode(text: string, node: Node): void; - writeLine(): void; - increaseIndent(): void; - decreaseIndent(): void; - getText(): string; - rawWrite(s: string): void; - writeLiteral(s: string): void; - getTextPos(): number; - getLine(): number; - getColumn(): number; - getIndent(): number; - isAtStartOfLine(): boolean; - reset(): void; - } - const indentStrings: string[] = ["", " "]; export function getIndentString(level: number) { if (indentStrings[level] === undefined) { @@ -2640,7 +2575,7 @@ namespace ts { * Else, calls `getSourceFilesToEmit` with the (optional) target source file to determine the list of source files to emit. */ export function forEachEmittedFile( - host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFiles: SourceFile[], isBundledEmit: boolean, emitOnlyDtsFiles: boolean) => void, + host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle, emitOnlyDtsFiles: boolean) => void, sourceFilesOrTargetSourceFile?: SourceFile[] | SourceFile, emitOnlyDtsFiles?: boolean) { @@ -2651,7 +2586,7 @@ namespace ts { const jsFilePath = options.outFile || options.out; const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options); const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : undefined; - action({ jsFilePath, sourceMapFilePath, declarationFilePath }, sourceFiles, /*isBundledEmit*/true, emitOnlyDtsFiles); + action({ jsFilePath, sourceMapFilePath, declarationFilePath }, createBundle(sourceFiles), emitOnlyDtsFiles); } } else { @@ -2659,7 +2594,7 @@ namespace ts { const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, getOutputExtension(sourceFile, options)); const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options); const declarationFilePath = !isSourceFileJavaScript(sourceFile) && (emitOnlyDtsFiles || options.declaration) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined; - action({ jsFilePath, sourceMapFilePath, declarationFilePath }, [sourceFile], /*isBundledEmit*/false, emitOnlyDtsFiles); + action({ jsFilePath, sourceMapFilePath, declarationFilePath }, sourceFile, emitOnlyDtsFiles); } } } @@ -3234,7 +3169,7 @@ namespace ts { const carriageReturnLineFeed = "\r\n"; const lineFeed = "\n"; - export function getNewLineCharacter(options: CompilerOptions): string { + export function getNewLineCharacter(options: CompilerOptions | PrinterOptions): string { if (options.newLine === NewLineKind.CarriageReturnLineFeed) { return carriageReturnLineFeed; } @@ -3345,6 +3280,14 @@ namespace ts { } } + export function getRangePos(range: TextRange | undefined) { + return range ? range.pos : -1; + } + + export function getRangeEnd(range: TextRange | undefined) { + return range ? range.end : -1; + } + /** * Increases (or decreases) a position by the provided amount. * @@ -3944,6 +3887,19 @@ namespace ts { export function isModuleBody(node: Node): node is ModuleBody { const kind = node.kind; return kind === SyntaxKind.ModuleBlock + || kind === SyntaxKind.ModuleDeclaration + || kind === SyntaxKind.Identifier; + } + + export function isNamespaceBody(node: Node): node is NamespaceBody { + const kind = node.kind; + return kind === SyntaxKind.ModuleBlock + || kind === SyntaxKind.ModuleDeclaration; + } + + export function isJSDocNamespaceBody(node: Node): node is JSDocNamespaceBody { + const kind = node.kind; + return kind === SyntaxKind.Identifier || kind === SyntaxKind.ModuleDeclaration; } @@ -4536,4 +4492,55 @@ namespace ts { return true; } } + + export function getOriginalNode(node: Node): Node; + export function getOriginalNode(node: Node, nodeTest: (node: Node) => node is T): T; + export function getOriginalNode(node: Node, nodeTest?: (node: Node) => boolean): Node { + if (node) { + while (node.original !== undefined) { + node = node.original; + } + } + + return !nodeTest || nodeTest(node) ? node : undefined; + } + + /** + * Gets a value indicating whether a node originated in the parse tree. + * + * @param node The node to test. + */ + export function isParseTreeNode(node: Node): boolean { + return (node.flags & NodeFlags.Synthesized) === 0; + } + + /** + * Gets the original parse tree node for a node. + * + * @param node The original node. + * @returns The original parse tree node if found; otherwise, undefined. + */ + export function getParseTreeNode(node: Node): Node; + + /** + * Gets the original parse tree node for a node. + * + * @param node The original node. + * @param nodeTest A callback used to ensure the correct type of parse tree node is returned. + * @returns The original parse tree node if found; otherwise, undefined. + */ + export function getParseTreeNode(node: Node, nodeTest?: (node: Node) => node is T): T; + export function getParseTreeNode(node: Node, nodeTest?: (node: Node) => boolean): Node { + if (isParseTreeNode(node)) { + return node; + } + + node = getOriginalNode(node); + + if (isParseTreeNode(node) && (!nodeTest || nodeTest(node))) { + return node; + } + + return undefined; + } } diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index f3efc040e35..fd2b0314dda 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -6,97 +6,6 @@ namespace ts { export type VisitResult = T | T[]; - /** - * Describes an edge of a Node, used when traversing a syntax tree. - */ - interface NodeEdge { - /** The property name for the edge. */ - name: string; - - /** Indicates that the result is optional. */ - optional?: boolean; - - /** A callback used to test whether a node is valid. */ - test?: (node: Node) => node is Node; - - /** A callback used to lift a NodeArrayNode into a valid node. */ - lift?: (nodes: NodeArray) => Node; - - /** A callback used to parenthesize a node to preserve the intended order of operations. */ - parenthesize?: (value: Node, parentNode: Node) => Node; - }; - - /** - * Describes the shape of a Node. - */ - type NodeTraversalPath = NodeEdge[]; - - /** - * This map contains information about the shape of each Node in "types.ts" pertaining to how - * each node should be traversed during a transformation. - * - * Each edge corresponds to a property in a Node subtype that should be traversed when visiting - * each child. The properties are assigned in the order in which traversal should occur. - * - * We only add entries for nodes that do not have a create/update pair defined in factory.ts - * - * NOTE: This needs to be kept up to date with changes to nodes in "types.ts". Currently, this - * map is not comprehensive. Only node edges relevant to tree transformation are - * currently defined. We may extend this to be more comprehensive, and eventually - * supplant the existing `forEachChild` implementation if performance is not - * significantly impacted. - */ - function getNodeEdgeTraversal(kind: SyntaxKind): NodeTraversalPath { - switch (kind) { - case SyntaxKind.QualifiedName: return [ - { name: "left", test: isEntityName }, - { name: "right", test: isIdentifier } - ]; - case SyntaxKind.Decorator: return [ - { name: "expression", test: isLeftHandSideExpression } - ]; - case SyntaxKind.TypeAssertionExpression: return [ - { name: "type", test: isTypeNode }, - { name: "expression", test: isUnaryExpression } - ]; - case SyntaxKind.AsExpression: return [ - { name: "expression", test: isExpression }, - { name: "type", test: isTypeNode } - ]; - case SyntaxKind.NonNullExpression: return [ - { name: "expression", test: isLeftHandSideExpression } - ]; - case SyntaxKind.EnumDeclaration: return [ - { name: "decorators", test: isDecorator }, - { name: "modifiers", test: isModifier }, - { name: "name", test: isIdentifier }, - { name: "members", test: isEnumMember } - ]; - case SyntaxKind.ModuleDeclaration: return [ - { name: "decorators", test: isDecorator }, - { name: "modifiers", test: isModifier }, - { name: "name", test: isModuleName }, - { name: "body", test: isModuleBody } - ]; - case SyntaxKind.ModuleBlock: return [ - { name: "statements", test: isStatement } - ]; - case SyntaxKind.ImportEqualsDeclaration: return [ - { name: "decorators", test: isDecorator }, - { name: "modifiers", test: isModifier }, - { name: "name", test: isIdentifier }, - { name: "moduleReference", test: isModuleReference } - ]; - case SyntaxKind.ExternalModuleReference: return [ - { name: "expression", test: isExpression, optional: true } - ]; - case SyntaxKind.EnumMember: return [ - { name: "name", test: isPropertyName }, - { name: "initializer", test: isExpression, optional: true, parenthesize: parenthesizeExpressionForList } - ]; - } - } - function reduceNode(node: Node, f: (memo: T, node: Node) => T, initial: T) { return node ? f(initial, node) : initial; } @@ -107,8 +16,7 @@ namespace ts { /** * Similar to `reduceLeft`, performs a reduction against each child of a node. - * NOTE: Unlike `forEachChild`, this does *not* visit every node. Only nodes added to the - * `nodeEdgeTraversalMap` above will be visited. + * NOTE: Unlike `forEachChild`, this does *not* visit every node. * * @param node The node containing the children to reduce. * @param initial The initial value to supply to the reduction. @@ -145,6 +53,11 @@ namespace ts { break; // Names + case SyntaxKind.QualifiedName: + result = reduceNode((node).left, cbNode, result); + result = reduceNode((node).right, cbNode, result); + break; + case SyntaxKind.ComputedPropertyName: result = reduceNode((node).expression, cbNode, result); break; @@ -252,6 +165,11 @@ namespace ts { result = reduceNode((node).template, cbNode, result); break; + case SyntaxKind.TypeAssertionExpression: + result = reduceNode((node).type, cbNode, result); + result = reduceNode((node).expression, cbNode, result); + break; + case SyntaxKind.FunctionExpression: result = reduceNodes((node).modifiers, cbNodes, result); result = reduceNode((node).name, cbNode, result); @@ -314,6 +232,15 @@ namespace ts { result = reduceNodes((node).typeArguments, cbNodes, result); break; + case SyntaxKind.AsExpression: + result = reduceNode((node).expression, cbNode, result); + result = reduceNode((node).type, cbNode, result); + break; + + case SyntaxKind.NonNullExpression: + result = reduceNode((node).expression, cbNode, result); + break; + // Misc case SyntaxKind.TemplateSpan: result = reduceNode((node).expression, cbNode, result); @@ -415,10 +342,35 @@ namespace ts { result = reduceNodes((node).members, cbNodes, result); break; + case SyntaxKind.EnumDeclaration: + result = reduceNodes((node).decorators, cbNodes, result); + result = reduceNodes((node).modifiers, cbNodes, result); + result = reduceNode((node).name, cbNode, result); + result = reduceNodes((node).members, cbNodes, result); + break; + + case SyntaxKind.ModuleDeclaration: + result = reduceNodes((node).decorators, cbNodes, result); + result = reduceNodes((node).modifiers, cbNodes, result); + result = reduceNode((node).name, cbNode, result); + result = reduceNode((node).body, cbNode, result); + break; + + case SyntaxKind.ModuleBlock: + result = reduceNodes((node).statements, cbNodes, result); + break; + case SyntaxKind.CaseBlock: result = reduceNodes((node).clauses, cbNodes, result); break; + case SyntaxKind.ImportEqualsDeclaration: + result = reduceNodes((node).decorators, cbNodes, result); + result = reduceNodes((node).modifiers, cbNodes, result); + result = reduceNode((node).name, cbNode, result); + result = reduceNode((node).moduleReference, cbNode, result); + break; + case SyntaxKind.ImportDeclaration: result = reduceNodes((node).decorators, cbNodes, result); result = reduceNodes((node).modifiers, cbNodes, result); @@ -459,6 +411,11 @@ namespace ts { result = reduceNode((node).moduleSpecifier, cbNode, result); break; + // Module references + case SyntaxKind.ExternalModuleReference: + result = reduceNode((node).expression, cbNode, result); + break; + // JSX case SyntaxKind.JsxElement: result = reduceNode((node).openingElement, cbNode, result); @@ -519,30 +476,25 @@ namespace ts { break; case SyntaxKind.SpreadAssignment: - result = reduceNode((node as SpreadAssignment).expression, cbNode, result); + result = reduceNode((node).expression, cbNode, result); break; + // Enum + case SyntaxKind.EnumMember: + result = reduceNode((node).name, cbNode, result); + result = reduceNode((node).initializer, cbNode, result); + // Top-level nodes case SyntaxKind.SourceFile: result = reduceNodes((node).statements, cbNodes, result); break; + // Transformation nodes case SyntaxKind.PartiallyEmittedExpression: result = reduceNode((node).expression, cbNode, result); break; default: - const edgeTraversalPath = getNodeEdgeTraversal(kind); - if (edgeTraversalPath) { - for (const edge of edgeTraversalPath) { - const value = (>node)[edge.name]; - if (value !== undefined) { - result = isArray(value) - ? reduceNodes(>value, cbNodes, result) - : cbNode(result, value); - } - } - } break; } @@ -556,11 +508,9 @@ namespace ts { * @param visitor The callback used to visit the Node. * @param test A callback to execute to verify the Node is valid. * @param optional An optional value indicating whether the Node is itself optional. - * @param lift An optional callback to execute to lift a NodeArrayNode into a valid Node. + * @param lift An optional callback to execute to lift a NodeArray into a valid Node. */ - export function visitNode(node: T, visitor: (node: Node) => VisitResult, test: (node: Node) => boolean, optional?: boolean, lift?: (node: NodeArray) => T): T; - export function visitNode(node: T, visitor: (node: Node) => VisitResult, test: (node: Node) => boolean, optional: boolean, lift: (node: NodeArray) => T, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node): T; - export function visitNode(node: Node, visitor: (node: Node) => VisitResult, test: (node: Node) => boolean, optional?: boolean, lift?: (node: Node[]) => Node, parenthesize?: (node: Node, parentNode: Node) => Node, parentNode?: Node): Node { + export function visitNode(node: T, visitor: (node: Node) => VisitResult, test: (node: Node) => boolean, optional?: boolean, lift?: (node: NodeArray) => T): T { if (node === undefined || visitor === undefined) { return node; } @@ -586,13 +536,9 @@ namespace ts { visitedNode = visited; } - if (parenthesize !== undefined) { - visitedNode = parenthesize(visitedNode, parentNode); - } - Debug.assertNode(visitedNode, test); aggregateTransformFlags(visitedNode); - return visitedNode; + return visitedNode; } /** @@ -604,14 +550,12 @@ namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - export function visitNodes(nodes: NodeArray, visitor: (node: Node) => VisitResult, test: (node: Node) => boolean, start?: number, count?: number): NodeArray; - export function visitNodes(nodes: NodeArray, visitor: (node: Node) => VisitResult, test: (node: Node) => boolean, start: number, count: number, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node): NodeArray; - export function visitNodes(nodes: NodeArray, visitor: (node: Node) => VisitResult, test: (node: Node) => boolean, start?: number, count?: number, parenthesize?: (node: Node, parentNode: Node) => Node, parentNode?: Node): NodeArray { + export function visitNodes(nodes: NodeArray, visitor: (node: Node) => VisitResult, test: (node: Node) => boolean, start?: number, count?: number): NodeArray { if (nodes === undefined) { return undefined; } - let updated: NodeArray; + let updated: NodeArray; // Ensure start and count have valid values const length = nodes.length; @@ -627,8 +571,7 @@ namespace ts { // If we are not visiting all of the original nodes, we must always create a new array. // Since this is a fragment of a node array, we do not copy over the previous location // and will only copy over `hasTrailingComma` if we are including the last element. - updated = createNodeArray([], /*location*/ undefined, - /*hasTrailingComma*/ nodes.hasTrailingComma && start + count === length); + updated = createNodeArray([], /*hasTrailingComma*/ nodes.hasTrailingComma && start + count === length); } // Visit each original node. @@ -639,26 +582,21 @@ namespace ts { if (updated !== undefined || visited === undefined || visited !== node) { if (updated === undefined) { // Ensure we have a copy of `nodes`, up to the current index. - updated = createNodeArray(nodes.slice(0, i), /*location*/ nodes, nodes.hasTrailingComma); + updated = createNodeArray(nodes.slice(0, i), nodes.hasTrailingComma); + setTextRange(updated, nodes); } if (visited) { if (isArray(visited)) { - for (let visitedNode of visited) { - visitedNode = parenthesize - ? parenthesize(visitedNode, parentNode) - : visitedNode; + for (const visitedNode of visited) { Debug.assertNode(visitedNode, test); aggregateTransformFlags(visitedNode); - updated.push(visitedNode); + updated.push(visitedNode); } } else { - const visitedNode = parenthesize - ? parenthesize(visited, parentNode) - : visited; - Debug.assertNode(visitedNode, test); - aggregateTransformFlags(visitedNode); - updated.push(visitedNode); + Debug.assertNode(visited, test); + aggregateTransformFlags(visited); + updated.push(visited); } } } @@ -675,10 +613,10 @@ namespace ts { context.startLexicalEnvironment(); statements = visitNodes(statements, visitor, isStatement, start); if (ensureUseStrict && !startsWithUseStrict(statements)) { - statements = createNodeArray([createStatement(createLiteral("use strict")), ...statements], statements); + statements = setTextRange(createNodeArray([createStatement(createLiteral("use strict")), ...statements]), statements); } const declarations = context.endLexicalEnvironment(); - return createNodeArray(concatenate(statements, declarations), statements); + return setTextRange(createNodeArray(concatenate(statements, declarations)), statements); } /** @@ -747,6 +685,11 @@ namespace ts { return node; // Names + case SyntaxKind.QualifiedName: + return updateQualifiedName(node, + visitNode((node).left, visitor, isEntityName), + visitNode((node).right, visitor, isIdentifier)); + case SyntaxKind.ComputedPropertyName: return updateComputedPropertyName(node, visitNode((node).expression, visitor, isExpression)); @@ -761,6 +704,10 @@ namespace ts { visitNode((node).type, visitor, isTypeNode, /*optional*/ true), visitNode((node).initializer, visitor, isExpression, /*optional*/ true)); + case SyntaxKind.Decorator: + return updateDecorator(node, + visitNode((node).expression, visitor, isExpression)); + // Type member case SyntaxKind.PropertyDeclaration: return updateProperty(node, @@ -856,6 +803,11 @@ namespace ts { visitNode((node).tag, visitor, isExpression), visitNode((node).template, visitor, isTemplateLiteral)); + case SyntaxKind.TypeAssertionExpression: + return updateTypeAssertion(node, + visitNode((node).type, visitor, isTypeNode), + visitNode((node).expression, visitor, isExpression)); + case SyntaxKind.ParenthesizedExpression: return updateParen(node, visitNode((node).expression, visitor, isExpression)); @@ -938,6 +890,15 @@ namespace ts { visitNodes((node).typeArguments, visitor, isTypeNode), visitNode((node).expression, visitor, isExpression)); + case SyntaxKind.AsExpression: + return updateAsExpression(node, + visitNode((node).expression, visitor, isExpression), + visitNode((node).type, visitor, isTypeNode)); + + case SyntaxKind.NonNullExpression: + return updateNonNullExpression(node, + visitNode((node).expression, visitor, isExpression)); + // Misc case SyntaxKind.TemplateSpan: return updateTemplateSpan(node, @@ -1059,10 +1020,35 @@ namespace ts { visitNodes((node).heritageClauses, visitor, isHeritageClause), visitNodes((node).members, visitor, isClassElement)); + case SyntaxKind.EnumDeclaration: + return updateEnumDeclaration(node, + visitNodes((node).decorators, visitor, isDecorator), + visitNodes((node).modifiers, visitor, isModifier), + visitNode((node).name, visitor, isIdentifier), + visitNodes((node).members, visitor, isEnumMember)); + + case SyntaxKind.ModuleDeclaration: + return updateModuleDeclaration(node, + visitNodes((node).decorators, visitor, isDecorator), + visitNodes((node).modifiers, visitor, isModifier), + visitNode((node).name, visitor, isIdentifier), + visitNode((node).body, visitor, isModuleBody)); + + case SyntaxKind.ModuleBlock: + return updateModuleBlock(node, + visitNodes((node).statements, visitor, isStatement)); + case SyntaxKind.CaseBlock: return updateCaseBlock(node, visitNodes((node).clauses, visitor, isCaseOrDefaultClause)); + case SyntaxKind.ImportEqualsDeclaration: + return updateImportEqualsDeclaration(node, + visitNodes((node).decorators, visitor, isDecorator), + visitNodes((node).modifiers, visitor, isModifier), + visitNode((node).name, visitor, isIdentifier), + visitNode((node).moduleReference, visitor, isModuleReference)); + case SyntaxKind.ImportDeclaration: return updateImportDeclaration(node, visitNodes((node).decorators, visitor, isDecorator), @@ -1110,6 +1096,11 @@ namespace ts { visitNode((node).propertyName, visitor, isIdentifier, /*optional*/ true), visitNode((node).name, visitor, isIdentifier)); + // Module references + case SyntaxKind.ExternalModuleReference: + return updateExternalModuleReference(node, + visitNode((node).expression, visitor, isExpression)); + // JSX case SyntaxKind.JsxElement: return updateJsxElement(node, @@ -1175,10 +1166,16 @@ namespace ts { visitNode((node).objectAssignmentInitializer, visitor, isExpression)); case SyntaxKind.SpreadAssignment: - return updateSpreadAssignment(node as SpreadAssignment, - visitNode((node as SpreadAssignment).expression, visitor, isExpression)); + return updateSpreadAssignment(node, + visitNode((node).expression, visitor, isExpression)); - // Top-level nodes + // Enum + case SyntaxKind.EnumMember: + return updateEnumMember(node, + visitNode((node).name, visitor, isPropertyName), + visitNode((node).initializer, visitor, isExpression, /*optional*/ true)); + + // Top-level nodes case SyntaxKind.SourceFile: return updateSourceFileNode(node, visitLexicalEnvironment((node).statements, visitor, context)); @@ -1189,30 +1186,8 @@ namespace ts { visitNode((node).expression, visitor, isExpression)); default: - let updated: Node & MapLike; - const edgeTraversalPath = getNodeEdgeTraversal(kind); - if (edgeTraversalPath) { - for (const edge of edgeTraversalPath) { - const value = >(>node)[edge.name]; - if (value !== undefined) { - const visited = isArray(value) - ? visitNodes(value, visitor, edge.test, 0, value.length, edge.parenthesize, node) - : visitNode(value, visitor, edge.test, edge.optional, edge.lift, edge.parenthesize, node); - if (updated !== undefined || visited !== value) { - if (updated === undefined) { - updated = getMutableClone(node); - } - if (visited !== value) { - updated[edge.name] = visited; - } - } - } - } - } - return updated ? updateNode(updated, node) : node; + return node; } - - // return node; } /** @@ -1228,7 +1203,7 @@ namespace ts { return statements; } return isNodeArray(statements) - ? createNodeArray(concatenate(statements, declarations), statements) + ? setTextRange(createNodeArray(concatenate(statements, declarations)), statements) : addRange(statements, declarations); } @@ -1252,13 +1227,19 @@ namespace ts { export function mergeFunctionBodyLexicalEnvironment(body: ConciseBody, declarations: Statement[]): ConciseBody { if (body && declarations !== undefined && declarations.length > 0) { if (isBlock(body)) { - return updateBlock(body, createNodeArray(concatenate(body.statements, declarations), body.statements)); + return updateBlock(body, setTextRange(createNodeArray(concatenate(body.statements, declarations)), body.statements)); } else { - return createBlock( - createNodeArray([createReturn(body, /*location*/ body), ...declarations], body), - /*location*/ body, - /*multiLine*/ true); + return setTextRange( + createBlock( + setTextRange( + createNodeArray([setTextRange(createReturn(body), body), ...declarations]), + body + ), + /*multiLine*/ true + ), + /*location*/ body + ); } } return body; diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json index ebd07118cc5..bea688d358b 100644 --- a/src/harness/tsconfig.json +++ b/src/harness/tsconfig.json @@ -118,6 +118,7 @@ "./unittests/initializeTSConfig.ts", "./unittests/compileOnSave.ts", "./unittests/typingsInstaller.ts", - "./unittests/projectErrors.ts" + "./unittests/projectErrors.ts", + "./unittests/printer.ts" ] } diff --git a/src/harness/unittests/printer.ts b/src/harness/unittests/printer.ts new file mode 100644 index 00000000000..2496a880bc5 --- /dev/null +++ b/src/harness/unittests/printer.ts @@ -0,0 +1,97 @@ +/// +/// + +namespace ts { + describe("PrinterAPI", () => { + function makePrintsCorrectly(prefix: string) { + return function printsCorrectly(name: string, options: PrinterOptions, printCallback: (printer: Printer) => string) { + it(name, () => { + Harness.Baseline.runBaseline(`printerApi/${prefix}.${name}.js`, () => + printCallback(createPrinter({ newLine: NewLineKind.CarriageReturnLineFeed, ...options }))); + }); + } + } + + describe("printFile", () => { + const printsCorrectly = makePrintsCorrectly("printsFileCorrectly"); + const sourceFile = createSourceFile("source.ts", ` + interface A { + // comment1 + readonly prop?: T; + + // comment2 + method(): void; + + // comment3 + new (): A; + + // comment4 + (): A; + } + + // comment5 + type B = number | string | object; + type C = A & { x: string; }; // comment6 + + // comment7 + enum E1 { + // comment8 + first + } + + const enum E2 { + second + } + + // comment9 + console.log(1 + 2); + `, ScriptTarget.ES2015); + + printsCorrectly("default", {}, printer => printer.printFile(sourceFile)); + printsCorrectly("removeComments", { removeComments: true }, printer => printer.printFile(sourceFile)); + }); + + describe("printBundle", () => { + const printsCorrectly = makePrintsCorrectly("printsBundleCorrectly"); + const bundle = createBundle([ + createSourceFile("a.ts", ` + /*! [a.ts] */ + + // comment0 + const a = 1; + `, ScriptTarget.ES2015), + createSourceFile("b.ts", ` + /*! [b.ts] */ + + // comment1 + const b = 2; + `, ScriptTarget.ES2015) + ]); + printsCorrectly("default", {}, printer => printer.printBundle(bundle)); + printsCorrectly("removeComments", { removeComments: true }, printer => printer.printBundle(bundle)); + }); + + describe("printNode", () => { + const printsCorrectly = makePrintsCorrectly("printsNodeCorrectly"); + const sourceFile = createSourceFile("source.ts", "", ScriptTarget.ES2015); + const syntheticNode = createClassDeclaration( + undefined, + undefined, + /*name*/ createIdentifier("C"), + undefined, + undefined, + createNodeArray([ + createProperty( + undefined, + createNodeArray([createToken(SyntaxKind.PublicKeyword)]), + createIdentifier("prop"), + undefined, + undefined, + undefined + ) + ]) + ); + printsCorrectly("class", {}, printer => printer.printNode(EmitHint.Unspecified, syntheticNode, sourceFile)); + }); + }); +} diff --git a/src/harness/unittests/typingsInstaller.ts b/src/harness/unittests/typingsInstaller.ts index d4956a387ee..2b79141c3e3 100644 --- a/src/harness/unittests/typingsInstaller.ts +++ b/src/harness/unittests/typingsInstaller.ts @@ -44,6 +44,8 @@ namespace ts.projectSystem { }); } + import typingsName = server.typingsInstaller.typingsName; + describe("typingsInstaller", () => { it("configured projects (typings installed) 1", () => { const file1 = { @@ -519,32 +521,32 @@ namespace ts.projectSystem { const commander = { path: "/a/data/node_modules/@types/commander/index.d.ts", content: "declare const commander: { x: number }", - typings: "@types/commander" + typings: typingsName("commander") }; const jquery = { path: "/a/data/node_modules/@types/jquery/index.d.ts", content: "declare const jquery: { x: number }", - typings: "@types/jquery" + typings: typingsName("jquery") }; const lodash = { path: "/a/data/node_modules/@types/lodash/index.d.ts", content: "declare const lodash: { x: number }", - typings: "@types/lodash" + typings: typingsName("lodash") }; const cordova = { path: "/a/data/node_modules/@types/cordova/index.d.ts", content: "declare const cordova: { x: number }", - typings: "@types/cordova" + typings: typingsName("cordova") }; const grunt = { path: "/a/data/node_modules/@types/grunt/index.d.ts", content: "declare const grunt: { x: number }", - typings: "@types/grunt" + typings: typingsName("grunt") }; const gulp = { path: "/a/data/node_modules/@types/gulp/index.d.ts", content: "declare const gulp: { x: number }", - typings: "@types/gulp" + typings: typingsName("gulp") }; const host = createServerHost([lodashJs, commanderJs, file3]); @@ -554,7 +556,7 @@ namespace ts.projectSystem { } installWorker(_requestId: number, args: string[], _cwd: string, cb: TI.RequestCompletedAction): void { let typingFiles: (FileOrFolder & { typings: string })[] = []; - if (args.indexOf("@types/commander") >= 0) { + if (args.indexOf(typingsName("commander")) >= 0) { typingFiles = [commander, jquery, lodash, cordova]; } else { @@ -982,7 +984,7 @@ namespace ts.projectSystem { return; } if (response.kind === server.EventEndInstallTypes) { - assert.deepEqual(response.packagesToInstall, ["@types/commander"]); + assert.deepEqual(response.packagesToInstall, [typingsName("commander")]); seenTelemetryEvent = true; return; } diff --git a/src/lib/dom.generated.d.ts b/src/lib/dom.generated.d.ts index d9825897ebc..b4217c131f9 100644 --- a/src/lib/dom.generated.d.ts +++ b/src/lib/dom.generated.d.ts @@ -3,18 +3,50 @@ /// IE DOM APIs ///////////////////////////// +interface Account { + rpDisplayName?: string; + displayName?: string; + id?: string; + name?: string; + imageURL?: string; +} + interface Algorithm { name: string; } -interface AriaRequestEventInit extends EventInit { - attributeName?: string; - attributeValue?: string; +interface AnimationEventInit extends EventInit { + animationName?: string; + elapsedTime?: number; } -interface CommandEventInit extends EventInit { - commandName?: string; - detail?: string; +interface AssertionOptions { + timeoutSeconds?: number; + rpId?: USVString; + allowList?: ScopedCredentialDescriptor[]; + extensions?: WebAuthnExtensions; +} + +interface CacheQueryOptions { + ignoreSearch?: boolean; + ignoreMethod?: boolean; + ignoreVary?: boolean; + cacheName?: string; +} + +interface ClientData { + challenge?: string; + origin?: string; + rpId?: string; + hashAlg?: string | Algorithm; + tokenBinding?: string; + extensions?: WebAuthnExtensions; +} + +interface CloseEventInit extends EventInit { + wasClean?: boolean; + code?: number; + reason?: string; } interface CompositionEventInit extends UIEventInit { @@ -54,6 +86,13 @@ interface CustomEventInit extends EventInit { detail?: any; } +interface DOMRectInit { + x?: any; + y?: any; + width?: any; + height?: any; +} + interface DeviceAccelerationDict { x?: number; y?: number; @@ -64,6 +103,20 @@ interface DeviceLightEventInit extends EventInit { value?: number; } +interface DeviceMotionEventInit extends EventInit { + acceleration?: DeviceAccelerationDict; + accelerationIncludingGravity?: DeviceAccelerationDict; + rotationRate?: DeviceRotationRateDict; + interval?: number; +} + +interface DeviceOrientationEventInit extends EventInit { + alpha?: number; + beta?: number; + gamma?: number; + absolute?: boolean; +} + interface DeviceRotationRateDict { alpha?: number; beta?: number; @@ -75,6 +128,14 @@ interface DoubleRange { min?: number; } +interface ErrorEventInit extends EventInit { + message?: string; + filename?: string; + lineno?: number; + colno?: number; + error?: any; +} + interface EventInit { scoped?: boolean; bubbles?: boolean; @@ -107,6 +168,29 @@ interface FocusEventInit extends UIEventInit { relatedTarget?: EventTarget; } +interface FocusNavigationEventInit extends EventInit { + navigationReason?: string; + originLeft?: number; + originTop?: number; + originWidth?: number; + originHeight?: number; +} + +interface FocusNavigationOrigin { + originLeft?: number; + originTop?: number; + originWidth?: number; + originHeight?: number; +} + +interface GamepadEventInit extends EventInit { + gamepad?: Gamepad; +} + +interface GetNotificationOptions { + tag?: string; +} + interface HashChangeEventInit extends EventInit { newURL?: string; oldURL?: string; @@ -122,6 +206,20 @@ interface IDBObjectStoreParameters { keyPath?: IDBKeyPath; } +interface IntersectionObserverEntryInit { + time?: number; + rootBounds?: DOMRectInit; + boundingClientRect?: DOMRectInit; + intersectionRect?: DOMRectInit; + target?: Element; +} + +interface IntersectionObserverInit { + root?: Element; + rootMargin?: string; + threshold?: number | number[]; +} + interface KeyAlgorithm { name?: string; } @@ -324,6 +422,11 @@ interface MSPayloadBase extends RTCStats { payloadDescription?: string; } +interface MSPortRange { + min?: number; + max?: number; +} + interface MSRelayAddress { relayAddress?: string; port?: number; @@ -374,7 +477,7 @@ interface MSUtilization { } interface MSVideoPayload extends MSPayloadBase { - resoluton?: string; + resolution?: string; videoBitRateAvg?: number; videoBitRateMax?: number; videoFrameRateAvg?: number; @@ -457,6 +560,10 @@ interface MediaStreamErrorEventInit extends EventInit { error?: MediaStreamError; } +interface MediaStreamEventInit extends EventInit { + stream?: MediaStream; +} + interface MediaStreamTrackEventInit extends EventInit { track?: MediaStreamTrack; } @@ -521,6 +628,15 @@ interface MediaTrackSupportedConstraints { groupId?: boolean; } +interface MessageEventInit extends EventInit { + lastEventId?: string; + channel?: string; + data?: any; + origin?: string; + source?: Window; + ports?: MessagePort[]; +} + interface MouseEventInit extends EventModifierInit { screenX?: number; screenY?: number; @@ -550,10 +666,68 @@ interface MutationObserverInit { attributeFilter?: string[]; } +interface NotificationOptions { + dir?: string; + lang?: string; + body?: string; + tag?: string; + icon?: string; +} + interface ObjectURLOptions { oneTimeOnly?: boolean; } +interface PaymentCurrencyAmount { + currency?: string; + value?: string; + currencySystem?: string; +} + +interface PaymentDetails { + total?: PaymentItem; + displayItems?: PaymentItem[]; + shippingOptions?: PaymentShippingOption[]; + modifiers?: PaymentDetailsModifier[]; + error?: string; +} + +interface PaymentDetailsModifier { + supportedMethods?: string[]; + total?: PaymentItem; + additionalDisplayItems?: PaymentItem[]; + data?: any; +} + +interface PaymentItem { + label?: string; + amount?: PaymentCurrencyAmount; + pending?: boolean; +} + +interface PaymentMethodData { + supportedMethods?: string[]; + data?: any; +} + +interface PaymentOptions { + requestPayerName?: boolean; + requestPayerEmail?: boolean; + requestPayerPhone?: boolean; + requestShipping?: boolean; + shippingType?: string; +} + +interface PaymentRequestUpdateEventInit extends EventInit { +} + +interface PaymentShippingOption { + id?: string; + label?: string; + amount?: PaymentCurrencyAmount; + selected?: boolean; +} + interface PeriodicWaveConstraints { disableNormalization?: boolean; } @@ -569,12 +743,34 @@ interface PointerEventInit extends MouseEventInit { isPrimary?: boolean; } +interface PopStateEventInit extends EventInit { + state?: any; +} + interface PositionOptions { enableHighAccuracy?: boolean; timeout?: number; maximumAge?: number; } +interface ProgressEventInit extends EventInit { + lengthComputable?: boolean; + loaded?: number; + total?: number; +} + +interface PushSubscriptionOptionsInit { + userVisibleOnly?: boolean; + applicationServerKey?: any; +} + +interface RTCConfiguration { + iceServers?: RTCIceServer[]; + iceTransportPolicy?: string; + bundlePolicy?: string; + peerIdentity?: string; +} + interface RTCDTMFToneChangeEventInit extends EventInit { tone?: string; } @@ -589,18 +785,6 @@ interface RTCDtlsParameters { fingerprints?: RTCDtlsFingerprint[]; } -interface RTCIceCandidate { - foundation?: string; - priority?: number; - ip?: string; - protocol?: string; - port?: number; - type?: string; - tcpType?: string; - relatedAddress?: string; - relatedPort?: number; -} - interface RTCIceCandidateAttributes extends RTCStats { ipAddress?: string; portNumber?: number; @@ -613,9 +797,28 @@ interface RTCIceCandidateAttributes extends RTCStats { interface RTCIceCandidateComplete { } +interface RTCIceCandidateDictionary { + foundation?: string; + priority?: number; + ip?: string; + protocol?: string; + port?: number; + type?: string; + tcpType?: string; + relatedAddress?: string; + relatedPort?: number; + msMTurnSessionId?: string; +} + +interface RTCIceCandidateInit { + candidate?: string; + sdpMid?: string; + sdpMLineIndex?: number; +} + interface RTCIceCandidatePair { - local?: RTCIceCandidate; - remote?: RTCIceCandidate; + local?: RTCIceCandidateDictionary; + remote?: RTCIceCandidateDictionary; } interface RTCIceCandidatePairStats extends RTCStats { @@ -637,11 +840,13 @@ interface RTCIceCandidatePairStats extends RTCStats { interface RTCIceGatherOptions { gatherPolicy?: string; iceservers?: RTCIceServer[]; + portRange?: MSPortRange; } interface RTCIceParameters { usernameFragment?: string; password?: string; + iceLite?: boolean; } interface RTCIceServer { @@ -675,6 +880,13 @@ interface RTCMediaStreamTrackStats extends RTCStats { echoReturnLossEnhancement?: number; } +interface RTCOfferOptions { + offerToReceiveVideo?: number; + offerToReceiveAudio?: number; + voiceActivityDetection?: boolean; + iceRestart?: boolean; +} + interface RTCOutboundRTPStreamStats extends RTCRTPStreamStats { packetsSent?: number; bytesSent?: number; @@ -682,6 +894,10 @@ interface RTCOutboundRTPStreamStats extends RTCRTPStreamStats { roundTripTime?: number; } +interface RTCPeerConnectionIceEventInit extends EventInit { + candidate?: RTCIceCandidate; +} + interface RTCRTPStreamStats extends RTCStats { ssrc?: string; associateStatsId?: string; @@ -719,6 +935,7 @@ interface RTCRtpCodecCapability { clockRate?: number; preferredPayloadType?: number; maxptime?: number; + ptime?: number; numChannels?: number; rtcpFeedback?: RTCRtcpFeedback[]; parameters?: any; @@ -733,6 +950,7 @@ interface RTCRtpCodecParameters { payloadType?: any; clockRate?: number; maxptime?: number; + ptime?: number; numChannels?: number; rtcpFeedback?: RTCRtcpFeedback[]; parameters?: any; @@ -752,9 +970,9 @@ interface RTCRtpEncodingParameters { priority?: number; maxBitrate?: number; minQuality?: number; - framerateBias?: number; resolutionScale?: number; framerateScale?: number; + maxFramerate?: number; active?: boolean; encodingId?: string; dependencyEncodingIds?: string[]; @@ -785,6 +1003,7 @@ interface RTCRtpParameters { headerExtensions?: RTCRtpHeaderExtensionParameters[]; encodings?: RTCRtpEncodingParameters[]; rtcp?: RTCRtcpParameters; + degradationPreference?: string; } interface RTCRtpRtxParameters { @@ -797,6 +1016,11 @@ interface RTCRtpUnhandled { muxId?: string; } +interface RTCSessionDescriptionInit { + type?: string; + sdp?: string; +} + interface RTCSrtpKeyParam { keyMethod?: string; keySalt?: string; @@ -837,6 +1061,64 @@ interface RTCTransportStats extends RTCStats { remoteCertificateId?: string; } +interface RegistrationOptions { + scope?: string; +} + +interface RequestInit { + method?: string; + headers?: any; + body?: any; + referrer?: string; + referrerPolicy?: string; + mode?: string; + credentials?: string; + cache?: string; + redirect?: string; + integrity?: string; + keepalive?: boolean; + window?: any; +} + +interface ResponseInit { + status?: number; + statusText?: string; + headers?: any; +} + +interface ScopedCredentialDescriptor { + type?: string; + id?: any; + transports?: string[]; +} + +interface ScopedCredentialOptions { + timeoutSeconds?: number; + rpId?: USVString; + excludeList?: ScopedCredentialDescriptor[]; + extensions?: WebAuthnExtensions; +} + +interface ScopedCredentialParameters { + type?: string; + algorithm?: string | Algorithm; +} + +interface ServiceWorkerMessageEventInit extends EventInit { + data?: any; + origin?: string; + lastEventId?: string; + source?: ServiceWorker | MessagePort; + ports?: MessagePort[]; +} + +interface SpeechSynthesisEventInit extends EventInit { + utterance?: SpeechSynthesisUtterance; + charIndex?: number; + elapsedTime?: number; + name?: string; +} + interface StoreExceptionsInformation extends ExceptionInformation { siteName?: string; explanationString?: string; @@ -847,11 +1129,23 @@ interface StoreSiteSpecificExceptionsInformation extends StoreExceptionsInformat arrayOfDomainStrings?: string[]; } +interface TrackEventInit extends EventInit { + track?: VideoTrack | AudioTrack | TextTrack; +} + +interface TransitionEventInit extends EventInit { + propertyName?: string; + elapsedTime?: number; +} + interface UIEventInit extends EventInit { view?: Window; detail?: number; } +interface WebAuthnExtensions { +} + interface WebGLContextAttributes { failIfMajorPerformanceCaveat?: boolean; alpha?: boolean; @@ -877,6 +1171,18 @@ interface EventListener { (evt: Event): void; } +interface WebKitEntriesCallback { + (evt: Event): void; +} + +interface WebKitErrorCallback { + (evt: Event): void; +} + +interface WebKitFileCallback { + (evt: Event): void; +} + interface ANGLE_instanced_arrays { drawArraysInstancedANGLE(mode: number, first: number, count: number, primcount: number): void; drawElementsInstancedANGLE(mode: number, count: number, type: number, offset: number, primcount: number): void; @@ -915,14 +1221,14 @@ interface AnimationEvent extends Event { declare var AnimationEvent: { prototype: AnimationEvent; - new(): AnimationEvent; + new(typeArg: string, eventInitDict?: AnimationEventInit): AnimationEvent; } interface ApplicationCacheEventMap { "cached": Event; "checking": Event; "downloading": Event; - "error": ErrorEvent; + "error": Event; "noupdate": Event; "obsolete": Event; "progress": ProgressEvent; @@ -933,7 +1239,7 @@ interface ApplicationCache extends EventTarget { oncached: (this: ApplicationCache, ev: Event) => any; onchecking: (this: ApplicationCache, ev: Event) => any; ondownloading: (this: ApplicationCache, ev: Event) => any; - onerror: (this: ApplicationCache, ev: ErrorEvent) => any; + onerror: (this: ApplicationCache, ev: Event) => any; onnoupdate: (this: ApplicationCache, ev: Event) => any; onobsolete: (this: ApplicationCache, ev: Event) => any; onprogress: (this: ApplicationCache, ev: ProgressEvent) => any; @@ -963,16 +1269,6 @@ declare var ApplicationCache: { readonly UPDATEREADY: number; } -interface AriaRequestEvent extends Event { - readonly attributeName: string; - attributeValue: string | null; -} - -declare var AriaRequestEvent: { - prototype: AriaRequestEvent; - new(type: string, eventInitDict?: AriaRequestEventInit): AriaRequestEvent; -} - interface Attr extends Node { readonly name: string; readonly ownerElement: Element; @@ -1024,12 +1320,18 @@ declare var AudioBufferSourceNode: { new(): AudioBufferSourceNode; } -interface AudioContext extends EventTarget { +interface AudioContextEventMap { + "statechange": Event; +} + +interface AudioContextBase extends EventTarget { readonly currentTime: number; readonly destination: AudioDestinationNode; readonly listener: AudioListener; + onstatechange: (this: AudioContext, ev: Event) => any; readonly sampleRate: number; - state: string; + readonly state: string; + close(): PromiseLike; createAnalyser(): AnalyserNode; createBiquadFilter(): BiquadFilterNode; createBuffer(numberOfChannels: number, length: number, sampleRate: number): AudioBuffer; @@ -1040,6 +1342,7 @@ interface AudioContext extends EventTarget { createDelay(maxDelayTime?: number): DelayNode; createDynamicsCompressor(): DynamicsCompressorNode; createGain(): GainNode; + createIIRFilter(feedforward: number[], feedback: number[]): IIRFilterNode; createMediaElementSource(mediaElement: HTMLMediaElement): MediaElementAudioSourceNode; createMediaStreamSource(mediaStream: MediaStream): MediaStreamAudioSourceNode; createOscillator(): OscillatorNode; @@ -1049,6 +1352,13 @@ interface AudioContext extends EventTarget { createStereoPanner(): StereoPannerNode; createWaveShaper(): WaveShaperNode; decodeAudioData(audioData: ArrayBuffer, successCallback?: DecodeSuccessCallback, errorCallback?: DecodeErrorCallback): PromiseLike; + resume(): PromiseLike; + addEventListener(type: K, listener: (this: AudioContext, ev: AudioContextEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +} + +interface AudioContext extends AudioContextBase { + suspend(): PromiseLike; } declare var AudioContext: { @@ -1085,7 +1395,7 @@ interface AudioNode extends EventTarget { readonly context: AudioContext; readonly numberOfInputs: number; readonly numberOfOutputs: number; - connect(destination: AudioNode, output?: number, input?: number): void; + connect(destination: AudioNode, output?: number, input?: number): AudioNode; disconnect(output?: number): void; disconnect(destination: AudioNode, output?: number, input?: number): void; disconnect(destination: AudioParam, output?: number): void; @@ -1099,12 +1409,12 @@ declare var AudioNode: { interface AudioParam { readonly defaultValue: number; value: number; - cancelScheduledValues(startTime: number): void; - exponentialRampToValueAtTime(value: number, endTime: number): void; - linearRampToValueAtTime(value: number, endTime: number): void; - setTargetAtTime(target: number, startTime: number, timeConstant: number): void; - setValueAtTime(value: number, startTime: number): void; - setValueCurveAtTime(values: Float32Array, startTime: number, duration: number): void; + cancelScheduledValues(startTime: number): AudioParam; + exponentialRampToValueAtTime(value: number, endTime: number): AudioParam; + linearRampToValueAtTime(value: number, endTime: number): AudioParam; + setTargetAtTime(target: number, startTime: number, timeConstant: number): AudioParam; + setValueAtTime(value: number, startTime: number): AudioParam; + setValueCurveAtTime(values: Float32Array, startTime: number, duration: number): AudioParam; } declare var AudioParam: { @@ -1481,10 +1791,16 @@ interface CSSStyleDeclaration { imeMode: string | null; justifyContent: string | null; kerning: string | null; + layoutGrid: string | null; + layoutGridChar: string | null; + layoutGridLine: string | null; + layoutGridMode: string | null; + layoutGridType: string | null; left: string | null; readonly length: number; letterSpacing: string | null; lightingColor: string | null; + lineBreak: string | null; lineHeight: string | null; listStyle: string | null; listStyleImage: string | null; @@ -1556,6 +1872,7 @@ interface CSSStyleDeclaration { orphans: string | null; outline: string | null; outlineColor: string | null; + outlineOffset: string | null; outlineStyle: string | null; outlineWidth: string | null; overflow: string | null; @@ -1576,9 +1893,11 @@ interface CSSStyleDeclaration { position: string | null; quotes: string | null; right: string | null; + rotate: string | null; rubyAlign: string | null; rubyOverhang: string | null; rubyPosition: string | null; + scale: string | null; stopColor: string | null; stopOpacity: string | null; stroke: string | null; @@ -1612,6 +1931,7 @@ interface CSSStyleDeclaration { transitionDuration: string | null; transitionProperty: string | null; transitionTimingFunction: string | null; + translate: string | null; unicodeBidi: string | null; verticalAlign: string | null; visibility: string | null; @@ -1672,6 +1992,9 @@ interface CSSStyleDeclaration { webkitTapHighlightColor: string | null; webkitTextFillColor: string | null; webkitTextSizeAdjust: any; + webkitTextStroke: string | null; + webkitTextStrokeColor: string | null; + webkitTextStrokeWidth: string | null; webkitTransform: string | null; webkitTransformOrigin: string | null; webkitTransformStyle: string | null; @@ -1693,6 +2016,7 @@ interface CSSStyleDeclaration { zIndex: string | null; zoom: string | null; resize: string | null; + userSelect: string | null; getPropertyPriority(propertyName: string): string; getPropertyValue(propertyName: string): string; item(index: number): string; @@ -1720,7 +2044,6 @@ declare var CSSStyleRule: { interface CSSStyleSheet extends StyleSheet { readonly cssRules: CSSRuleList; cssText: string; - readonly href: string; readonly id: string; readonly imports: StyleSheetList; readonly isAlternate: boolean; @@ -1752,6 +2075,34 @@ declare var CSSSupportsRule: { new(): CSSSupportsRule; } +interface Cache { + add(request: RequestInfo): PromiseLike; + addAll(requests: RequestInfo[]): PromiseLike; + delete(request: RequestInfo, options?: CacheQueryOptions): PromiseLike; + keys(request?: RequestInfo, options?: CacheQueryOptions): any; + match(request: RequestInfo, options?: CacheQueryOptions): PromiseLike; + matchAll(request?: RequestInfo, options?: CacheQueryOptions): any; + put(request: RequestInfo, response: Response): PromiseLike; +} + +declare var Cache: { + prototype: Cache; + new(): Cache; +} + +interface CacheStorage { + delete(cacheName: string): PromiseLike; + has(cacheName: string): PromiseLike; + keys(): any; + match(request: RequestInfo, options?: CacheQueryOptions): PromiseLike; + open(cacheName: string): PromiseLike; +} + +declare var CacheStorage: { + prototype: CacheStorage; + new(): CacheStorage; +} + interface CanvasGradient { addColorStop(offset: number, color: string): void; } @@ -1776,13 +2127,13 @@ interface CanvasRenderingContext2D extends Object, CanvasPathMethods { font: string; globalAlpha: number; globalCompositeOperation: string; + imageSmoothingEnabled: boolean; lineCap: string; lineDashOffset: number; lineJoin: string; lineWidth: number; miterLimit: number; msFillRule: string; - msImageSmoothingEnabled: boolean; shadowBlur: number; shadowColor: string; shadowOffsetX: number; @@ -1800,6 +2151,7 @@ interface CanvasRenderingContext2D extends Object, CanvasPathMethods { createLinearGradient(x0: number, y0: number, x1: number, y1: number): CanvasGradient; createPattern(image: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement, repetition: string): CanvasPattern; createRadialGradient(x0: number, y0: number, r0: number, x1: number, y1: number, r1: number): CanvasGradient; + drawFocusIfNeeded(element: Element): void; drawImage(image: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement, offsetX: number, offsetY: number, width?: number, height?: number, canvasOffsetX?: number, canvasOffsetY?: number, canvasImageWidth?: number, canvasImageHeight?: number): void; fill(fillRule?: string): void; fillRect(x: number, y: number, w: number, h: number): void; @@ -1815,7 +2167,7 @@ interface CanvasRenderingContext2D extends Object, CanvasPathMethods { scale(x: number, y: number): void; setLineDash(segments: number[]): void; setTransform(m11: number, m12: number, m21: number, m22: number, dx: number, dy: number): void; - stroke(): void; + stroke(path?: Path2D): void; strokeRect(x: number, y: number, w: number, h: number): void; strokeText(text: string, x: number, y: number, maxWidth?: number): void; transform(m11: number, m12: number, m21: number, m22: number, dx: number, dy: number): void; @@ -1901,17 +2253,7 @@ interface CloseEvent extends Event { declare var CloseEvent: { prototype: CloseEvent; - new(): CloseEvent; -} - -interface CommandEvent extends Event { - readonly commandName: string; - readonly detail: string | null; -} - -declare var CommandEvent: { - prototype: CommandEvent; - new(type: string, eventInitDict?: CommandEventInit): CommandEvent; + new(typeArg: string, eventInitDict?: CloseEventInit): CloseEvent; } interface Comment extends CharacterData { @@ -1938,7 +2280,7 @@ interface Console { assert(test?: boolean, message?: string, ...optionalParams: any[]): void; clear(): void; count(countTitle?: string): void; - debug(message?: string, ...optionalParams: any[]): void; + debug(message?: any, ...optionalParams: any[]): void; dir(value?: any, ...optionalParams: any[]): void; dirxml(value: any): void; error(message?: any, ...optionalParams: any[]): void; @@ -2108,9 +2450,9 @@ declare var DOMException: { interface DOMImplementation { createDocument(namespaceURI: string | null, qualifiedName: string | null, doctype: DocumentType): Document; - createDocumentType(qualifiedName: string, publicId: string | null, systemId: string | null): DocumentType; + createDocumentType(qualifiedName: string, publicId: string, systemId: string): DocumentType; createHTMLDocument(title: string): Document; - hasFeature(feature: string | null, version: string | null): boolean; + hasFeature(): boolean; } declare var DOMImplementation: { @@ -2149,7 +2491,7 @@ declare var DOMStringList: { } interface DOMStringMap { - [name: string]: string; + [name: string]: string | undefined; } declare var DOMStringMap: { @@ -2175,7 +2517,7 @@ declare var DOMTokenList: { interface DataCue extends TextTrackCue { data: ArrayBuffer; - addEventListener(type: K, listener: (this: TextTrackCue, ev: TextTrackCueEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: DataCue, ev: TextTrackCueEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -2205,6 +2547,7 @@ interface DataTransferItem { readonly type: string; getAsFile(): File | null; getAsString(_callback: FunctionStringCallback | null): void; + webkitGetAsEntry(): any; } declare var DataTransferItem: { @@ -2265,7 +2608,7 @@ interface DeviceLightEvent extends Event { declare var DeviceLightEvent: { prototype: DeviceLightEvent; - new(type: string, eventInitDict?: DeviceLightEventInit): DeviceLightEvent; + new(typeArg: string, eventInitDict?: DeviceLightEventInit): DeviceLightEvent; } interface DeviceMotionEvent extends Event { @@ -2278,7 +2621,7 @@ interface DeviceMotionEvent extends Event { declare var DeviceMotionEvent: { prototype: DeviceMotionEvent; - new(): DeviceMotionEvent; + new(typeArg: string, eventInitDict?: DeviceMotionEventInit): DeviceMotionEvent; } interface DeviceOrientationEvent extends Event { @@ -2291,7 +2634,7 @@ interface DeviceOrientationEvent extends Event { declare var DeviceOrientationEvent: { prototype: DeviceOrientationEvent; - new(): DeviceOrientationEvent; + new(typeArg: string, eventInitDict?: DeviceOrientationEventInit): DeviceOrientationEvent; } interface DeviceRotationRate { @@ -2373,7 +2716,7 @@ interface DocumentEventMap extends GlobalEventHandlersEventMap { "pointerlockerror": Event; "progress": ProgressEvent; "ratechange": Event; - "readystatechange": ProgressEvent; + "readystatechange": Event; "reset": Event; "scroll": UIEvent; "seeked": Event; @@ -2444,10 +2787,6 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven readonly compatMode: string; cookie: string; readonly currentScript: HTMLScriptElement | SVGScriptElement; - /** - * Gets the default character set from the current regional language settings. - */ - readonly defaultCharset: string; readonly defaultView: Window; /** * Sets or gets a value that indicates whether the document can be edited. @@ -2754,7 +3093,7 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven * Fires when the state of the object has changed. * @param ev The event */ - onreadystatechange: (this: Document, ev: ProgressEvent) => any; + onreadystatechange: (this: Document, ev: Event) => any; /** * Fires when the user resets a form. * @param ev The event. @@ -3122,8 +3461,8 @@ interface DocumentType extends Node, ChildNode { readonly internalSubset: string | null; readonly name: string; readonly notations: NamedNodeMap; - readonly publicId: string | null; - readonly systemId: string | null; + readonly publicId: string; + readonly systemId: string; } declare var DocumentType: { @@ -3146,7 +3485,7 @@ interface DynamicsCompressorNode extends AudioNode { readonly attack: AudioParam; readonly knee: AudioParam; readonly ratio: AudioParam; - readonly reduction: AudioParam; + readonly reduction: number; readonly release: AudioParam; readonly threshold: AudioParam; } @@ -3177,8 +3516,8 @@ declare var EXT_texture_filter_anisotropic: { } interface ElementEventMap extends GlobalEventHandlersEventMap { - "ariarequest": AriaRequestEvent; - "command": CommandEvent; + "ariarequest": Event; + "command": Event; "gotpointercapture": PointerEvent; "lostpointercapture": PointerEvent; "MSGestureChange": MSGestureEvent; @@ -3214,10 +3553,11 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec readonly clientTop: number; readonly clientWidth: number; id: string; + innerHTML: string; msContentZoomFactor: number; readonly msRegionOverflow: string; - onariarequest: (this: Element, ev: AriaRequestEvent) => any; - oncommand: (this: Element, ev: CommandEvent) => any; + onariarequest: (this: Element, ev: Event) => any; + oncommand: (this: Element, ev: Event) => any; ongotpointercapture: (this: Element, ev: PointerEvent) => any; onlostpointercapture: (this: Element, ev: PointerEvent) => any; onmsgesturechange: (this: Element, ev: MSGestureEvent) => any; @@ -3243,13 +3583,13 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec ontouchstart: (ev: TouchEvent) => any; onwebkitfullscreenchange: (this: Element, ev: Event) => any; onwebkitfullscreenerror: (this: Element, ev: Event) => any; + outerHTML: string; readonly prefix: string | null; readonly scrollHeight: number; scrollLeft: number; scrollTop: number; readonly scrollWidth: number; readonly tagName: string; - innerHTML: string; readonly assignedSlot: HTMLSlotElement | null; slot: string; readonly shadowRoot: ShadowRoot | null; @@ -3273,7 +3613,7 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec msSetPointerCapture(pointerId: number): void; msZoomTo(args: MsZoomToOptions): void; releasePointerCapture(pointerId: number): void; - removeAttribute(name?: string): void; + removeAttribute(qualifiedName: string): void; removeAttributeNS(namespaceURI: string, localName: string): void; removeAttributeNode(oldAttr: Attr): Attr; requestFullscreen(): void; @@ -3320,7 +3660,7 @@ interface ErrorEvent extends Event { declare var ErrorEvent: { prototype: ErrorEvent; - new(): ErrorEvent; + new(type: string, errorEventInitDict?: ErrorEventInit): ErrorEvent; } interface Event { @@ -3349,7 +3689,7 @@ interface Event { declare var Event: { prototype: Event; - new(type: string, eventInitDict?: EventInit): Event; + new(typeArg: string, eventInitDict?: EventInit): Event; readonly AT_TARGET: number; readonly BUBBLING_PHASE: number; readonly CAPTURING_PHASE: number; @@ -3366,6 +3706,21 @@ declare var EventTarget: { new(): EventTarget; } +interface ExtensionScriptApis { + extensionIdToShortId(extensionId: string): number; + fireExtensionApiTelemetry(functionName: string, isSucceeded: boolean, isSupported: boolean): void; + genericFunction(routerAddress: any, parameters?: string, callbackId?: number): void; + genericSynchronousFunction(functionId: number, parameters?: string): string; + getExtensionId(): string; + registerGenericFunctionCallbackHandler(callbackHandler: any): void; + registerGenericPersistentCallbackHandler(callbackHandler: any): void; +} + +declare var ExtensionScriptApis: { + prototype: ExtensionScriptApis; + new(): ExtensionScriptApis; +} + interface External { } @@ -3402,7 +3757,7 @@ interface FileReader extends EventTarget, MSBaseReader { readAsBinaryString(blob: Blob): void; readAsDataURL(blob: Blob): void; readAsText(blob: Blob, encoding?: string): void; - addEventListener(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -3421,6 +3776,20 @@ declare var FocusEvent: { new(typeArg: string, eventInitDict?: FocusEventInit): FocusEvent; } +interface FocusNavigationEvent extends Event { + readonly navigationReason: string; + readonly originHeight: number; + readonly originLeft: number; + readonly originTop: number; + readonly originWidth: number; + requestFocus(): void; +} + +declare var FocusNavigationEvent: { + prototype: FocusNavigationEvent; + new(type: string, eventInitDict?: FocusNavigationEventInit): FocusNavigationEvent; +} + interface FormData { append(name: any, value: any, blobName?: string): void; } @@ -3470,7 +3839,7 @@ interface GamepadEvent extends Event { declare var GamepadEvent: { prototype: GamepadEvent; - new(): GamepadEvent; + new(typeArg: string, eventInitDict?: GamepadEventInit): GamepadEvent; } interface Geolocation { @@ -3484,8 +3853,11 @@ declare var Geolocation: { new(): Geolocation; } -interface HTMLAllCollection extends HTMLCollection { - namedItem(name: string): Element; +interface HTMLAllCollection { + readonly length: number; + item(nameOrIndex?: string): HTMLCollection | Element | null; + namedItem(name: string): HTMLCollection | Element | null; + [index: number]: Element; } declare var HTMLAllCollection: { @@ -3573,7 +3945,7 @@ interface HTMLAnchorElement extends HTMLElement { * Returns a string representation of an object. */ toString(): string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLAnchorElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -3647,7 +4019,7 @@ interface HTMLAppletElement extends HTMLElement { useMap: string; vspace: number; width: number; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLAppletElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -3715,7 +4087,7 @@ interface HTMLAreaElement extends HTMLElement { * Returns a string representation of an object. */ toString(): string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLAreaElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -3724,15 +4096,7 @@ declare var HTMLAreaElement: { new(): HTMLAreaElement; } -interface HTMLAreasCollection extends HTMLCollection { - /** - * Adds an element to the areas, controlRange, or options collection. - */ - add(element: HTMLElement, before?: HTMLElement | number): void; - /** - * Removes an element from the collection. - */ - remove(index?: number): void; +interface HTMLAreasCollection extends HTMLCollectionBase { } declare var HTMLAreasCollection: { @@ -3741,7 +4105,7 @@ declare var HTMLAreasCollection: { } interface HTMLAudioElement extends HTMLMediaElement { - addEventListener(type: K, listener: (this: HTMLMediaElement, ev: HTMLMediaElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLAudioElement, ev: HTMLMediaElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -3755,7 +4119,7 @@ interface HTMLBRElement extends HTMLElement { * Sets or retrieves the side on which floating objects are not to be positioned when any IHTMLBlockElement is inserted into the document. */ clear: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLBRElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -3773,7 +4137,7 @@ interface HTMLBaseElement extends HTMLElement { * Sets or retrieves the window or frame at which to target content. */ target: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLBaseElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -3791,7 +4155,7 @@ interface HTMLBaseFontElement extends HTMLElement, DOML2DeprecatedColorProperty * Sets or retrieves the font size of the object. */ size: number; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLBaseFontElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -3817,6 +4181,7 @@ interface HTMLBodyElementEventMap extends HTMLElementEventMap { "pageshow": PageTransitionEvent; "popstate": PopStateEvent; "resize": UIEvent; + "scroll": UIEvent; "storage": StorageEvent; "unload": Event; } @@ -3844,6 +4209,7 @@ interface HTMLBodyElement extends HTMLElement { onpageshow: (this: HTMLBodyElement, ev: PageTransitionEvent) => any; onpopstate: (this: HTMLBodyElement, ev: PopStateEvent) => any; onresize: (this: HTMLBodyElement, ev: UIEvent) => any; + onscroll: (this: HTMLBodyElement, ev: UIEvent) => any; onstorage: (this: HTMLBodyElement, ev: StorageEvent) => any; onunload: (this: HTMLBodyElement, ev: Event) => any; text: any; @@ -3921,7 +4287,7 @@ interface HTMLButtonElement extends HTMLElement { * @param error Sets a custom error message that is displayed when a form is submitted. */ setCustomValidity(error: string): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLButtonElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -3956,7 +4322,7 @@ 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: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLCanvasElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -3965,7 +4331,7 @@ declare var HTMLCanvasElement: { new(): HTMLCanvasElement; } -interface HTMLCollection { +interface HTMLCollectionBase { /** * Sets or retrieves the number of objects in a collection. */ @@ -3974,11 +4340,14 @@ interface HTMLCollection { * Retrieves an object from various collections. */ item(index: number): Element; + [index: number]: Element; +} + +interface HTMLCollection extends HTMLCollectionBase { /** * Retrieves a select object or an object from an options collection. */ - namedItem(name: string): Element; - [index: number]: Element; + namedItem(name: string): Element | null; } declare var HTMLCollection: { @@ -3988,7 +4357,7 @@ declare var HTMLCollection: { interface HTMLDListElement extends HTMLElement { compact: boolean; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLDListElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -3997,9 +4366,20 @@ declare var HTMLDListElement: { new(): HTMLDListElement; } +interface HTMLDataElement extends HTMLElement { + value: string; + addEventListener(type: K, listener: (this: HTMLDataElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +} + +declare var HTMLDataElement: { + prototype: HTMLDataElement; + new(): HTMLDataElement; +} + interface HTMLDataListElement extends HTMLElement { options: HTMLCollectionOf; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLDataListElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -4010,7 +4390,7 @@ declare var HTMLDataListElement: { interface HTMLDirectoryElement extends HTMLElement { compact: boolean; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLDirectoryElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -4028,7 +4408,7 @@ interface HTMLDivElement extends HTMLElement { * Sets or retrieves whether the browser automatically performs wordwrap. */ noWrap: boolean; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -4038,7 +4418,7 @@ declare var HTMLDivElement: { } interface HTMLDocument extends Document { - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLDocument, ev: DocumentEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -4126,7 +4506,6 @@ interface HTMLElement extends Element { draggable: boolean; hidden: boolean; hideFocus: boolean; - innerHTML: string; innerText: string; readonly isContentEditable: boolean; lang: string; @@ -4202,7 +4581,6 @@ interface HTMLElement extends Element { ontimeupdate: (this: HTMLElement, ev: Event) => any; onvolumechange: (this: HTMLElement, ev: Event) => any; onwaiting: (this: HTMLElement, ev: Event) => any; - outerHTML: string; outerText: string; spellcheck: boolean; readonly style: CSSStyleDeclaration; @@ -4213,7 +4591,6 @@ interface HTMLElement extends Element { dragDrop(): boolean; focus(): void; msGetInputContext(): MSInputMethodContext; - setActive(): void; addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -4270,7 +4647,7 @@ interface HTMLEmbedElement extends HTMLElement, GetSVGDocument { * Sets or retrieves the width of the object. */ width: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLEmbedElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -4289,6 +4666,7 @@ interface HTMLFieldSetElement extends HTMLElement { * Retrieves a reference to the form that the object is embedded in. */ readonly form: HTMLFormElement; + name: string; /** * Returns the error message that would be displayed if the user submits the form, or an empty string if no error message. It also triggers the standard error message, such as "this is a required field". The result is that the user sees validation messages without actually submitting. */ @@ -4310,7 +4688,7 @@ interface HTMLFieldSetElement extends HTMLElement { * @param error Sets a custom error message that is displayed when a form is submitted. */ setCustomValidity(error: string): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLFieldSetElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -4324,7 +4702,7 @@ interface HTMLFontElement extends HTMLElement, DOML2DeprecatedColorProperty, DOM * Sets or retrieves the current typeface family. */ face: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLFontElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -4333,6 +4711,15 @@ declare var HTMLFontElement: { new(): HTMLFontElement; } +interface HTMLFormControlsCollection extends HTMLCollectionBase { + namedItem(name: string): HTMLCollection | Element | null; +} + +declare var HTMLFormControlsCollection: { + prototype: HTMLFormControlsCollection; + new(): HTMLFormControlsCollection; +} + interface HTMLFormElement extends HTMLElement { /** * Sets or retrieves a list of character encodings for input data that must be accepted by the server processing the form. @@ -4349,7 +4736,7 @@ interface HTMLFormElement extends HTMLElement { /** * Retrieves a collection, in source order, of all controls in a given form. */ - readonly elements: HTMLCollection; + readonly elements: HTMLFormControlsCollection; /** * Sets or retrieves the MIME encoding for the form. */ @@ -4400,7 +4787,7 @@ interface HTMLFormElement extends HTMLElement { * Fires when a FORM is about to be submitted. */ submit(): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLFormElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; [name: string]: any; } @@ -4489,6 +4876,7 @@ declare var HTMLFrameElement: { } interface HTMLFrameSetElementEventMap extends HTMLElementEventMap { + "afterprint": Event; "beforeprint": Event; "beforeunload": BeforeUnloadEvent; "blur": FocusEvent; @@ -4502,7 +4890,9 @@ interface HTMLFrameSetElementEventMap extends HTMLElementEventMap { "orientationchange": Event; "pagehide": PageTransitionEvent; "pageshow": PageTransitionEvent; + "popstate": PopStateEvent; "resize": UIEvent; + "scroll": UIEvent; "storage": StorageEvent; "unload": Event; } @@ -4546,7 +4936,9 @@ interface HTMLFrameSetElement extends HTMLElement { onorientationchange: (this: HTMLFrameSetElement, ev: Event) => any; onpagehide: (this: HTMLFrameSetElement, ev: PageTransitionEvent) => any; onpageshow: (this: HTMLFrameSetElement, ev: PageTransitionEvent) => any; + onpopstate: (this: HTMLFrameSetElement, ev: PopStateEvent) => any; onresize: (this: HTMLFrameSetElement, ev: UIEvent) => any; + onscroll: (this: HTMLFrameSetElement, ev: UIEvent) => any; onstorage: (this: HTMLFrameSetElement, ev: StorageEvent) => any; onunload: (this: HTMLFrameSetElement, ev: Event) => any; /** @@ -4575,7 +4967,7 @@ interface HTMLHRElement extends HTMLElement, DOML2DeprecatedColorProperty, DOML2 * Sets or retrieves the width of the object. */ width: number; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLHRElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -4586,7 +4978,7 @@ declare var HTMLHRElement: { interface HTMLHeadElement extends HTMLElement { profile: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLHeadElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -4600,7 +4992,7 @@ interface HTMLHeadingElement extends HTMLElement { * Sets or retrieves a value that indicates the table alignment. */ align: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLHeadingElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -4614,7 +5006,7 @@ interface HTMLHtmlElement extends HTMLElement { * Sets or retrieves the DTD version that governs the current document. */ version: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLHtmlElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -4633,6 +5025,7 @@ interface HTMLIFrameElement extends HTMLElement, GetSVGDocument { */ align: string; allowFullscreen: boolean; + allowPaymentRequest: boolean; /** * Specifies the properties of a border drawn around an object. */ @@ -4728,7 +5121,7 @@ interface HTMLImageElement extends HTMLElement { * Retrieves whether the object is fully loaded. */ readonly complete: boolean; - crossOrigin: string; + crossOrigin: string | null; readonly currentSrc: string; /** * Sets or retrieves the height of the object. @@ -4793,14 +5186,13 @@ interface HTMLImageElement extends HTMLElement { readonly x: number; readonly y: number; msGetAsCastingSource(): any; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLImageElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } declare var HTMLImageElement: { prototype: HTMLImageElement; new(): HTMLImageElement; - create(): HTMLImageElement; } interface HTMLInputElement extends HTMLElement { @@ -5006,7 +5398,7 @@ interface HTMLInputElement extends HTMLElement { * @param n Value to increment the value by. */ stepUp(n?: number): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLInputElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5021,7 +5413,7 @@ interface HTMLLIElement extends HTMLElement { * Sets or retrieves the value of a list item. */ value: number; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLLIElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5039,7 +5431,7 @@ interface HTMLLabelElement extends HTMLElement { * Sets or retrieves the object to which the given label object is assigned. */ htmlFor: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLLabelElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5057,7 +5449,7 @@ interface HTMLLegendElement extends HTMLElement { * Retrieves a reference to the form that the object is embedded in. */ readonly form: HTMLFormElement; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLLegendElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5102,7 +5494,7 @@ interface HTMLLinkElement extends HTMLElement, LinkStyle { type: string; import?: Document; integrity: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLLinkElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5120,7 +5512,7 @@ interface HTMLMapElement extends HTMLElement { * Sets or retrieves the name of the object. */ name: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLMapElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5183,7 +5575,7 @@ interface HTMLMediaElement extends HTMLElement { * Gets or sets a flag that indicates whether the client provides a set of controls for the media (in case the developer does not include controls for the player). */ controls: boolean; - crossOrigin: string; + crossOrigin: string | null; /** * Gets the address or URL of the current media resource that is selected by IHTMLMediaElement. */ @@ -5355,7 +5747,7 @@ declare var HTMLMediaElement: { interface HTMLMenuElement extends HTMLElement { compact: boolean; type: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLMenuElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5389,7 +5781,7 @@ interface HTMLMetaElement extends HTMLElement { * Sets or retrieves the URL property that will be loaded after the specified time has elapsed. */ url: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLMetaElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5405,7 +5797,7 @@ interface HTMLMeterElement extends HTMLElement { min: number; optimum: number; value: number; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLMeterElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5423,7 +5815,7 @@ interface HTMLModElement extends HTMLElement { * Sets or retrieves the date and time of a modification to the object. */ dateTime: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLModElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5439,7 +5831,7 @@ interface HTMLOListElement extends HTMLElement { */ start: number; type: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLOListElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5517,10 +5909,6 @@ interface HTMLObjectElement extends HTMLElement, GetSVGDocument { * Sets or retrieves the name of the object. */ name: string; - /** - * Retrieves the contained object. - */ - readonly object: any; readonly readyState: number; /** * Sets or retrieves a message to be displayed while an object is loading. @@ -5560,7 +5948,7 @@ interface HTMLObjectElement extends HTMLElement, GetSVGDocument { * @param error Sets a custom error message that is displayed when a form is submitted. */ setCustomValidity(error: string): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLObjectElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5599,7 +5987,7 @@ interface HTMLOptGroupElement extends HTMLElement { * Sets or retrieves the value which is returned to the server when the form control is submitted. */ value: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLOptGroupElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5638,14 +6026,13 @@ interface HTMLOptionElement extends HTMLElement { * Sets or retrieves the value which is returned to the server when the form control is submitted. */ value: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLOptionElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } declare var HTMLOptionElement: { prototype: HTMLOptionElement; new(): HTMLOptionElement; - create(): HTMLOptionElement; } interface HTMLOptionsCollection extends HTMLCollectionOf { @@ -5660,13 +6047,35 @@ declare var HTMLOptionsCollection: { new(): HTMLOptionsCollection; } +interface HTMLOutputElement extends HTMLElement { + defaultValue: string; + readonly form: HTMLFormElement; + readonly htmlFor: DOMSettableTokenList; + name: string; + readonly type: string; + readonly validationMessage: string; + readonly validity: ValidityState; + value: string; + readonly willValidate: boolean; + checkValidity(): boolean; + reportValidity(): boolean; + setCustomValidity(error: string): void; + addEventListener(type: K, listener: (this: HTMLOutputElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +} + +declare var HTMLOutputElement: { + prototype: HTMLOutputElement; + new(): HTMLOutputElement; +} + interface HTMLParagraphElement extends HTMLElement { /** * Sets or retrieves how the object is aligned with adjacent text. */ align: string; clear: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLParagraphElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5692,7 +6101,7 @@ interface HTMLParamElement extends HTMLElement { * Sets or retrieves the data type of the value attribute. */ valueType: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLParamElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5702,7 +6111,7 @@ declare var HTMLParamElement: { } interface HTMLPictureElement extends HTMLElement { - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLPictureElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5716,7 +6125,7 @@ interface HTMLPreElement extends HTMLElement { * Sets or gets a value that you can use to implement your own width functionality for the object. */ width: number; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLPreElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5742,7 +6151,7 @@ interface HTMLProgressElement extends HTMLElement { * Sets or gets the current value of a progress element. The value must be a non-negative number between 0 and the max value. */ value: number; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLProgressElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5756,7 +6165,7 @@ interface HTMLQuoteElement extends HTMLElement { * Sets or retrieves reference information about the object. */ cite: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLQuoteElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5771,6 +6180,7 @@ interface HTMLScriptElement extends HTMLElement { * Sets or retrieves the character set used to encode the object. */ charset: string; + crossOrigin: string | null; /** * Sets or retrieves the status of the script. */ @@ -5796,7 +6206,7 @@ interface HTMLScriptElement extends HTMLElement { */ type: string; integrity: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLScriptElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5892,7 +6302,7 @@ interface HTMLSelectElement extends HTMLElement { * @param error Sets a custom error message that is displayed when a form is submitted. */ setCustomValidity(error: string): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLSelectElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; [name: string]: any; } @@ -5918,7 +6328,7 @@ interface HTMLSourceElement extends HTMLElement { * Gets or sets the MIME type of a media resource. */ type: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLSourceElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5928,7 +6338,7 @@ declare var HTMLSourceElement: { } interface HTMLSpanElement extends HTMLElement { - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLSpanElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5947,7 +6357,7 @@ interface HTMLStyleElement extends HTMLElement, LinkStyle { * Retrieves the CSS language in which the style sheet is written. */ type: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLStyleElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -5965,7 +6375,7 @@ interface HTMLTableCaptionElement extends HTMLElement { * Sets or retrieves whether the caption appears at the top or bottom of the table. */ vAlign: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTableCaptionElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -6020,7 +6430,7 @@ interface HTMLTableCellElement extends HTMLElement, HTMLTableAlignment { * Sets or retrieves the width of the object. */ width: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTableCellElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -6042,7 +6452,7 @@ interface HTMLTableColElement extends HTMLElement, HTMLTableAlignment { * Sets or retrieves the width of the object. */ width: any; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTableColElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -6052,6 +6462,8 @@ declare var HTMLTableColElement: { } interface HTMLTableDataCellElement extends HTMLTableCellElement { + addEventListener(type: K, listener: (this: HTMLTableDataCellElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } declare var HTMLTableDataCellElement: { @@ -6163,7 +6575,7 @@ interface HTMLTableElement extends HTMLElement { * @param index Number that specifies where to insert the row in the rows collection. The default value is -1, which appends the new row to the end of the rows collection. */ insertRow(index?: number): HTMLTableRowElement; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTableElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -6177,6 +6589,8 @@ interface HTMLTableHeaderCellElement extends HTMLTableCellElement { * Sets or retrieves the group of cells in a table to which the object's information applies. */ scope: string; + addEventListener(type: K, listener: (this: HTMLTableHeaderCellElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } declare var HTMLTableHeaderCellElement: { @@ -6216,7 +6630,7 @@ interface HTMLTableRowElement extends HTMLElement, HTMLTableAlignment { * @param index Number that specifies where to insert the cell in the tr. The default value is -1, which appends the new cell to the end of the cells collection. */ insertCell(index?: number): HTMLTableDataCellElement; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTableRowElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -6244,7 +6658,7 @@ interface HTMLTableSectionElement extends HTMLElement, HTMLTableAlignment { * @param index Number that specifies where to insert the row in the rows collection. The default value is -1, which appends the new row to the end of the rows collection. */ insertRow(index?: number): HTMLTableRowElement; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTableSectionElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -6255,7 +6669,7 @@ declare var HTMLTableSectionElement: { interface HTMLTemplateElement extends HTMLElement { readonly content: DocumentFragment; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTemplateElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -6362,7 +6776,7 @@ interface HTMLTextAreaElement extends HTMLElement { * @param end The offset into the text field for the end of the selection. */ setSelectionRange(start: number, end: number): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTextAreaElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -6371,12 +6785,23 @@ declare var HTMLTextAreaElement: { new(): HTMLTextAreaElement; } +interface HTMLTimeElement extends HTMLElement { + dateTime: string; + addEventListener(type: K, listener: (this: HTMLTimeElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +} + +declare var HTMLTimeElement: { + prototype: HTMLTimeElement; + new(): HTMLTimeElement; +} + interface HTMLTitleElement extends HTMLElement { /** * Retrieves or sets the text of the object as a string. */ text: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTitleElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -6397,7 +6822,7 @@ interface HTMLTrackElement extends HTMLElement { readonly LOADED: number; readonly LOADING: number; readonly NONE: number; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLTrackElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -6413,7 +6838,7 @@ declare var HTMLTrackElement: { interface HTMLUListElement extends HTMLElement { compact: boolean; type: string; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLUListElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -6423,7 +6848,7 @@ declare var HTMLUListElement: { } interface HTMLUnknownElement extends HTMLElement { - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: HTMLUnknownElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -6494,7 +6919,21 @@ interface HashChangeEvent extends Event { declare var HashChangeEvent: { prototype: HashChangeEvent; - new(type: string, eventInitDict?: HashChangeEventInit): HashChangeEvent; + new(typeArg: string, eventInitDict?: HashChangeEventInit): HashChangeEvent; +} + +interface Headers { + append(name: string, value: string): void; + delete(name: string): void; + forEach(callback: ForEachCallback): void; + get(name: string): string | null; + has(name: string): boolean; + set(name: string, value: string): void; +} + +declare var Headers: { + prototype: Headers; + new(init?: any): Headers; } interface History { @@ -6548,14 +6987,14 @@ declare var IDBCursorWithValue: { interface IDBDatabaseEventMap { "abort": Event; - "error": ErrorEvent; + "error": Event; } interface IDBDatabase extends EventTarget { readonly name: string; readonly objectStoreNames: DOMStringList; onabort: (this: IDBDatabase, ev: Event) => any; - onerror: (this: IDBDatabase, ev: ErrorEvent) => any; + onerror: (this: IDBDatabase, ev: Event) => any; version: number; onversionchange: (ev: IDBVersionChangeEvent) => any; close(): void; @@ -6658,13 +7097,13 @@ declare var IDBOpenDBRequest: { } interface IDBRequestEventMap { - "error": ErrorEvent; + "error": Event; "success": Event; } interface IDBRequest extends EventTarget { readonly error: DOMError; - onerror: (this: IDBRequest, ev: ErrorEvent) => any; + onerror: (this: IDBRequest, ev: Event) => any; onsuccess: (this: IDBRequest, ev: Event) => any; readonly readyState: string; readonly result: any; @@ -6682,7 +7121,7 @@ declare var IDBRequest: { interface IDBTransactionEventMap { "abort": Event; "complete": Event; - "error": ErrorEvent; + "error": Event; } interface IDBTransaction extends EventTarget { @@ -6691,7 +7130,7 @@ interface IDBTransaction extends EventTarget { readonly mode: string; onabort: (this: IDBTransaction, ev: Event) => any; oncomplete: (this: IDBTransaction, ev: Event) => any; - onerror: (this: IDBTransaction, ev: ErrorEvent) => any; + onerror: (this: IDBTransaction, ev: Event) => any; abort(): void; objectStore(name: string): IDBObjectStore; readonly READ_ONLY: string; @@ -6719,6 +7158,15 @@ declare var IDBVersionChangeEvent: { new(): IDBVersionChangeEvent; } +interface IIRFilterNode extends AudioNode { + getFrequencyResponse(frequencyHz: Float32Array, magResponse: Float32Array, phaseResponse: Float32Array): void; +} + +declare var IIRFilterNode: { + prototype: IIRFilterNode; + new(): IIRFilterNode; +} + interface ImageData { data: Uint8ClampedArray; readonly height: number; @@ -6731,6 +7179,35 @@ declare var ImageData: { new(array: Uint8ClampedArray, width: number, height: number): ImageData; } +interface IntersectionObserver { + readonly root: Element | null; + readonly rootMargin: string; + readonly thresholds: number[]; + disconnect(): void; + observe(target: Element): void; + takeRecords(): IntersectionObserverEntry[]; + unobserve(target: Element): void; +} + +declare var IntersectionObserver: { + prototype: IntersectionObserver; + new(callback: IntersectionObserverCallback, options?: IntersectionObserverInit): IntersectionObserver; +} + +interface IntersectionObserverEntry { + readonly boundingClientRect: ClientRect; + readonly intersectionRatio: number; + readonly intersectionRect: ClientRect; + readonly rootBounds: ClientRect; + readonly target: Element; + readonly time: number; +} + +declare var IntersectionObserverEntry: { + prototype: IntersectionObserverEntry; + new(intersectionObserverEntryInit: IntersectionObserverEntryInit): IntersectionObserverEntry; +} + interface KeyboardEvent extends UIEvent { readonly altKey: boolean; readonly char: string | null; @@ -6832,13 +7309,13 @@ declare var MSApp: MSApp; interface MSAppAsyncOperationEventMap { "complete": Event; - "error": ErrorEvent; + "error": Event; } interface MSAppAsyncOperation extends EventTarget { readonly error: DOMError; oncomplete: (this: MSAppAsyncOperation, ev: Event) => any; - onerror: (this: MSAppAsyncOperation, ev: ErrorEvent) => any; + onerror: (this: MSAppAsyncOperation, ev: Event) => any; readonly readyState: number; readonly result: any; start(): void; @@ -6995,12 +7472,13 @@ interface MSHTMLWebViewElement extends HTMLElement { goForward(): void; invokeScriptAsync(scriptName: string, ...args: any[]): MSWebViewAsyncOperation; navigate(uri: string): void; + navigateFocus(navigationReason: string, origin: FocusNavigationOrigin): void; navigateToLocalStreamUri(source: string, streamResolver: any): void; navigateToString(contents: string): void; navigateWithHttpRequestMessage(requestMessage: any): void; refresh(): void; stop(): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: MSHTMLWebViewElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -7192,7 +7670,7 @@ interface MSStreamReader extends EventTarget, MSBaseReader { readAsBlob(stream: MSStream, size?: number): void; readAsDataURL(stream: MSStream, size?: number): void; readAsText(stream: MSStream, encoding?: string, size?: number): void; - addEventListener(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: MSStreamReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -7203,13 +7681,13 @@ declare var MSStreamReader: { interface MSWebViewAsyncOperationEventMap { "complete": Event; - "error": ErrorEvent; + "error": Event; } interface MSWebViewAsyncOperation extends EventTarget { readonly error: DOMError; oncomplete: (this: MSWebViewAsyncOperation, ev: Event) => any; - onerror: (this: MSWebViewAsyncOperation, ev: ErrorEvent) => any; + onerror: (this: MSWebViewAsyncOperation, ev: Event) => any; readonly readyState: number; readonly result: any; readonly target: MSHTMLWebViewElement; @@ -7419,18 +7897,18 @@ declare var MediaSource: { interface MediaStreamEventMap { "active": Event; - "addtrack": TrackEvent; + "addtrack": MediaStreamTrackEvent; "inactive": Event; - "removetrack": TrackEvent; + "removetrack": MediaStreamTrackEvent; } interface MediaStream extends EventTarget { readonly active: boolean; readonly id: string; onactive: (this: MediaStream, ev: Event) => any; - onaddtrack: (this: MediaStream, ev: TrackEvent) => any; + onaddtrack: (this: MediaStream, ev: MediaStreamTrackEvent) => any; oninactive: (this: MediaStream, ev: Event) => any; - onremovetrack: (this: MediaStream, ev: TrackEvent) => any; + onremovetrack: (this: MediaStream, ev: MediaStreamTrackEvent) => any; addTrack(track: MediaStreamTrack): void; clone(): MediaStream; getAudioTracks(): MediaStreamTrack[]; @@ -7473,7 +7951,16 @@ interface MediaStreamErrorEvent extends Event { declare var MediaStreamErrorEvent: { prototype: MediaStreamErrorEvent; - new(type: string, eventInitDict?: MediaStreamErrorEventInit): MediaStreamErrorEvent; + new(typeArg: string, eventInitDict?: MediaStreamErrorEventInit): MediaStreamErrorEvent; +} + +interface MediaStreamEvent extends Event { + readonly stream: MediaStream | null; +} + +declare var MediaStreamEvent: { + prototype: MediaStreamEvent; + new(type: string, eventInitDict: MediaStreamEventInit): MediaStreamEvent; } interface MediaStreamTrackEventMap { @@ -7517,7 +8004,7 @@ interface MediaStreamTrackEvent extends Event { declare var MediaStreamTrackEvent: { prototype: MediaStreamTrackEvent; - new(type: string, eventInitDict?: MediaStreamTrackEventInit): MediaStreamTrackEvent; + new(typeArg: string, eventInitDict?: MediaStreamTrackEventInit): MediaStreamTrackEvent; } interface MessageChannel { @@ -7550,7 +8037,7 @@ interface MessagePortEventMap { interface MessagePort extends EventTarget { onmessage: (this: MessagePort, ev: MessageEvent) => any; close(): void; - postMessage(message?: any, ports?: any): void; + postMessage(message?: any, transfer?: any[]): void; start(): void; addEventListener(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; @@ -7712,9 +8199,10 @@ declare var NavigationEventWithReferrer: { new(): NavigationEventWithReferrer; } -interface Navigator extends Object, NavigatorID, NavigatorOnLine, NavigatorContentUtils, NavigatorStorageUtils, NavigatorGeolocation, MSNavigatorDoNotTrack, MSFileSaver, NavigatorUserMedia { - readonly appCodeName: string; +interface Navigator extends Object, NavigatorID, NavigatorOnLine, NavigatorContentUtils, NavigatorStorageUtils, NavigatorGeolocation, MSNavigatorDoNotTrack, MSFileSaver, NavigatorBeacon, NavigatorConcurrentHardware, NavigatorUserMedia { + readonly authentication: WebAuthentication; readonly cookieEnabled: boolean; + gamepadInputEmulation: string; readonly language: string; readonly maxTouchPoints: number; readonly mimeTypes: MimeTypeArray; @@ -7723,6 +8211,7 @@ interface Navigator extends Object, NavigatorID, NavigatorOnLine, NavigatorConte readonly msPointerEnabled: boolean; readonly plugins: PluginArray; readonly pointerEnabled: boolean; + readonly serviceWorker: ServiceWorkerContainer; readonly webdriver: boolean; readonly hardwareConcurrency: number; getGamepads(): Gamepad[]; @@ -7754,7 +8243,7 @@ interface Node extends EventTarget { readonly parentNode: Node | null; readonly previousSibling: Node | null; textContent: string | null; - appendChild(newChild: Node): Node; + appendChild(newChild: T): T; cloneNode(deep?: boolean): Node; compareDocumentPosition(other: Node): number; contains(child: Node): boolean; @@ -7861,6 +8350,36 @@ declare var NodeList: { new(): NodeList; } +interface NotificationEventMap { + "click": Event; + "close": Event; + "error": Event; + "show": Event; +} + +interface Notification extends EventTarget { + readonly body: string; + readonly dir: string; + readonly icon: string; + readonly lang: string; + onclick: (this: Notification, ev: Event) => any; + onclose: (this: Notification, ev: Event) => any; + onerror: (this: Notification, ev: Event) => any; + onshow: (this: Notification, ev: Event) => any; + readonly permission: string; + readonly tag: string; + readonly title: string; + close(): void; + addEventListener(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +} + +declare var Notification: { + prototype: Notification; + new(title: string, options?: NotificationOptions): Notification; + requestPermission(callback?: NotificationPermissionCallback): PromiseLike; +} + interface OES_element_index_uint { } @@ -7895,6 +8414,24 @@ declare var OES_texture_float_linear: { new(): OES_texture_float_linear; } +interface OES_texture_half_float { + readonly HALF_FLOAT_OES: number; +} + +declare var OES_texture_half_float: { + prototype: OES_texture_half_float; + new(): OES_texture_half_float; + readonly HALF_FLOAT_OES: number; +} + +interface OES_texture_half_float_linear { +} + +declare var OES_texture_half_float_linear: { + prototype: OES_texture_half_float_linear; + new(): OES_texture_half_float_linear; +} + interface OfflineAudioCompletionEvent extends Event { readonly renderedBuffer: AudioBuffer; } @@ -7904,13 +8441,15 @@ declare var OfflineAudioCompletionEvent: { new(): OfflineAudioCompletionEvent; } -interface OfflineAudioContextEventMap { - "complete": Event; +interface OfflineAudioContextEventMap extends AudioContextEventMap { + "complete": OfflineAudioCompletionEvent; } -interface OfflineAudioContext extends AudioContext { - oncomplete: (this: OfflineAudioContext, ev: Event) => any; +interface OfflineAudioContext extends AudioContextBase { + readonly length: number; + oncomplete: (this: OfflineAudioContext, ev: OfflineAudioCompletionEvent) => any; startRendering(): PromiseLike; + suspend(suspendTime: number): PromiseLike; addEventListener(type: K, listener: (this: OfflineAudioContext, ev: OfflineAudioContextEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -7986,6 +8525,82 @@ declare var PannerNode: { new(): PannerNode; } +interface Path2D extends Object, CanvasPathMethods { +} + +declare var Path2D: { + prototype: Path2D; + new(path?: Path2D): Path2D; +} + +interface PaymentAddress { + readonly addressLine: string[]; + readonly city: string; + readonly country: string; + readonly dependentLocality: string; + readonly languageCode: string; + readonly organization: string; + readonly phone: string; + readonly postalCode: string; + readonly recipient: string; + readonly region: string; + readonly sortingCode: string; + toJSON(): any; +} + +declare var PaymentAddress: { + prototype: PaymentAddress; + new(): PaymentAddress; +} + +interface PaymentRequestEventMap { + "shippingaddresschange": Event; + "shippingoptionchange": Event; +} + +interface PaymentRequest extends EventTarget { + onshippingaddresschange: (this: PaymentRequest, ev: Event) => any; + onshippingoptionchange: (this: PaymentRequest, ev: Event) => any; + readonly shippingAddress: PaymentAddress | null; + readonly shippingOption: string | null; + readonly shippingType: string | null; + abort(): PromiseLike; + show(): PromiseLike; + addEventListener(type: K, listener: (this: PaymentRequest, ev: PaymentRequestEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +} + +declare var PaymentRequest: { + prototype: PaymentRequest; + new(methodData: PaymentMethodData[], details: PaymentDetails, options?: PaymentOptions): PaymentRequest; +} + +interface PaymentRequestUpdateEvent extends Event { + updateWith(d: PromiseLike): void; +} + +declare var PaymentRequestUpdateEvent: { + prototype: PaymentRequestUpdateEvent; + new(type: string, eventInitDict?: PaymentRequestUpdateEventInit): PaymentRequestUpdateEvent; +} + +interface PaymentResponse { + readonly details: any; + readonly methodName: string; + readonly payerEmail: string | null; + readonly payerName: string | null; + readonly payerPhone: string | null; + readonly shippingAddress: PaymentAddress | null; + readonly shippingOption: string | null; + complete(result?: string): PromiseLike; + toJSON(): any; +} + +declare var PaymentResponse: { + prototype: PaymentResponse; + new(): PaymentResponse; +} + interface PerfWidgetExternal { readonly activeNetworkRequestCount: number; readonly averageFrameTime: number; @@ -8251,7 +8866,7 @@ interface PopStateEvent extends Event { declare var PopStateEvent: { prototype: PopStateEvent; - new(): PopStateEvent; + new(typeArg: string, eventInitDict?: PopStateEventInit): PopStateEvent; } interface Position { @@ -8302,23 +8917,57 @@ declare var ProgressEvent: { new(type: string, eventInitDict?: ProgressEventInit): ProgressEvent; } +interface PushManager { + getSubscription(): PromiseLike; + permissionState(options?: PushSubscriptionOptionsInit): PromiseLike; + subscribe(options?: PushSubscriptionOptionsInit): PromiseLike; +} + +declare var PushManager: { + prototype: PushManager; + new(): PushManager; +} + +interface PushSubscription { + readonly endpoint: USVString; + readonly options: PushSubscriptionOptions; + getKey(name: string): ArrayBuffer | null; + toJSON(): any; + unsubscribe(): PromiseLike; +} + +declare var PushSubscription: { + prototype: PushSubscription; + new(): PushSubscription; +} + +interface PushSubscriptionOptions { + readonly applicationServerKey: ArrayBuffer | null; + readonly userVisibleOnly: boolean; +} + +declare var PushSubscriptionOptions: { + prototype: PushSubscriptionOptions; + new(): PushSubscriptionOptions; +} + interface RTCDTMFToneChangeEvent extends Event { readonly tone: string; } declare var RTCDTMFToneChangeEvent: { prototype: RTCDTMFToneChangeEvent; - new(type: string, eventInitDict: RTCDTMFToneChangeEventInit): RTCDTMFToneChangeEvent; + new(typeArg: string, eventInitDict: RTCDTMFToneChangeEventInit): RTCDTMFToneChangeEvent; } interface RTCDtlsTransportEventMap { "dtlsstatechange": RTCDtlsTransportStateChangedEvent; - "error": ErrorEvent; + "error": Event; } interface RTCDtlsTransport extends RTCStatsProvider { ondtlsstatechange: ((this: RTCDtlsTransport, ev: RTCDtlsTransportStateChangedEvent) => any) | null; - onerror: ((this: RTCDtlsTransport, ev: ErrorEvent) => any) | null; + onerror: ((this: RTCDtlsTransport, ev: Event) => any) | null; readonly state: string; readonly transport: RTCIceTransport; getLocalParameters(): RTCDtlsParameters; @@ -8365,6 +9014,18 @@ declare var RTCDtmfSender: { new(sender: RTCRtpSender): RTCDtmfSender; } +interface RTCIceCandidate { + candidate: string | null; + sdpMLineIndex: number | null; + sdpMid: string | null; + toJSON(): any; +} + +declare var RTCIceCandidate: { + prototype: RTCIceCandidate; + new(candidateInitDict?: RTCIceCandidateInit): RTCIceCandidate; +} + interface RTCIceCandidatePairChangedEvent extends Event { readonly pair: RTCIceCandidatePair; } @@ -8375,16 +9036,16 @@ declare var RTCIceCandidatePairChangedEvent: { } interface RTCIceGathererEventMap { - "error": ErrorEvent; + "error": Event; "localcandidate": RTCIceGathererEvent; } interface RTCIceGatherer extends RTCStatsProvider { readonly component: string; - onerror: ((this: RTCIceGatherer, ev: ErrorEvent) => any) | null; + onerror: ((this: RTCIceGatherer, ev: Event) => any) | null; onlocalcandidate: ((this: RTCIceGatherer, ev: RTCIceGathererEvent) => any) | null; createAssociatedGatherer(): RTCIceGatherer; - getLocalCandidates(): RTCIceCandidate[]; + getLocalCandidates(): RTCIceCandidateDictionary[]; getLocalParameters(): RTCIceParameters; addEventListener(type: K, listener: (this: RTCIceGatherer, ev: RTCIceGathererEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; @@ -8396,7 +9057,7 @@ declare var RTCIceGatherer: { } interface RTCIceGathererEvent extends Event { - readonly candidate: RTCIceCandidate | RTCIceCandidateComplete; + readonly candidate: RTCIceCandidateDictionary | RTCIceCandidateComplete; } declare var RTCIceGathererEvent: { @@ -8416,12 +9077,12 @@ interface RTCIceTransport extends RTCStatsProvider { onicestatechange: ((this: RTCIceTransport, ev: RTCIceTransportStateChangedEvent) => any) | null; readonly role: string; readonly state: string; - addRemoteCandidate(remoteCandidate: RTCIceCandidate | RTCIceCandidateComplete): void; + addRemoteCandidate(remoteCandidate: RTCIceCandidateDictionary | RTCIceCandidateComplete): void; createAssociatedTransport(): RTCIceTransport; getNominatedCandidatePair(): RTCIceCandidatePair | null; - getRemoteCandidates(): RTCIceCandidate[]; + getRemoteCandidates(): RTCIceCandidateDictionary[]; getRemoteParameters(): RTCIceParameters | null; - setRemoteCandidates(remoteCandidates: RTCIceCandidate[]): void; + setRemoteCandidates(remoteCandidates: RTCIceCandidateDictionary[]): void; start(gatherer: RTCIceGatherer, remoteParameters: RTCIceParameters, role?: string): void; stop(): void; addEventListener(type: K, listener: (this: RTCIceTransport, ev: RTCIceTransportEventMap[K]) => any, useCapture?: boolean): void; @@ -8442,12 +9103,67 @@ declare var RTCIceTransportStateChangedEvent: { new(): RTCIceTransportStateChangedEvent; } +interface RTCPeerConnectionEventMap { + "addstream": MediaStreamEvent; + "icecandidate": RTCPeerConnectionIceEvent; + "iceconnectionstatechange": Event; + "icegatheringstatechange": Event; + "negotiationneeded": Event; + "removestream": MediaStreamEvent; + "signalingstatechange": Event; +} + +interface RTCPeerConnection extends EventTarget { + readonly canTrickleIceCandidates: boolean | null; + readonly iceConnectionState: string; + readonly iceGatheringState: string; + readonly localDescription: RTCSessionDescription | null; + onaddstream: (this: RTCPeerConnection, ev: MediaStreamEvent) => any; + onicecandidate: (this: RTCPeerConnection, ev: RTCPeerConnectionIceEvent) => any; + oniceconnectionstatechange: (this: RTCPeerConnection, ev: Event) => any; + onicegatheringstatechange: (this: RTCPeerConnection, ev: Event) => any; + onnegotiationneeded: (this: RTCPeerConnection, ev: Event) => any; + onremovestream: (this: RTCPeerConnection, ev: MediaStreamEvent) => any; + onsignalingstatechange: (this: RTCPeerConnection, ev: Event) => any; + readonly remoteDescription: RTCSessionDescription | null; + readonly signalingState: string; + addIceCandidate(candidate: RTCIceCandidate, successCallback?: VoidFunction, failureCallback?: RTCPeerConnectionErrorCallback): PromiseLike; + addStream(stream: MediaStream): void; + close(): void; + createAnswer(successCallback?: RTCSessionDescriptionCallback, failureCallback?: RTCPeerConnectionErrorCallback): PromiseLike; + createOffer(successCallback?: RTCSessionDescriptionCallback, failureCallback?: RTCPeerConnectionErrorCallback, options?: RTCOfferOptions): PromiseLike; + getConfiguration(): RTCConfiguration; + getLocalStreams(): MediaStream[]; + getRemoteStreams(): MediaStream[]; + getStats(selector: MediaStreamTrack | null, successCallback?: RTCStatsCallback, failureCallback?: RTCPeerConnectionErrorCallback): PromiseLike; + getStreamById(streamId: string): MediaStream | null; + removeStream(stream: MediaStream): void; + setLocalDescription(description: RTCSessionDescription, successCallback?: VoidFunction, failureCallback?: RTCPeerConnectionErrorCallback): PromiseLike; + setRemoteDescription(description: RTCSessionDescription, successCallback?: VoidFunction, failureCallback?: RTCPeerConnectionErrorCallback): PromiseLike; + addEventListener(type: K, listener: (this: RTCPeerConnection, ev: RTCPeerConnectionEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +} + +declare var RTCPeerConnection: { + prototype: RTCPeerConnection; + new(configuration: RTCConfiguration): RTCPeerConnection; +} + +interface RTCPeerConnectionIceEvent extends Event { + readonly candidate: RTCIceCandidate; +} + +declare var RTCPeerConnectionIceEvent: { + prototype: RTCPeerConnectionIceEvent; + new(type: string, eventInitDict: RTCPeerConnectionIceEventInit): RTCPeerConnectionIceEvent; +} + interface RTCRtpReceiverEventMap { - "error": ErrorEvent; + "error": Event; } interface RTCRtpReceiver extends RTCStatsProvider { - onerror: ((this: RTCRtpReceiver, ev: ErrorEvent) => any) | null; + onerror: ((this: RTCRtpReceiver, ev: Event) => any) | null; readonly rtcpTransport: RTCDtlsTransport; readonly track: MediaStreamTrack | null; readonly transport: RTCDtlsTransport | RTCSrtpSdesTransport; @@ -8467,12 +9183,12 @@ declare var RTCRtpReceiver: { } interface RTCRtpSenderEventMap { - "error": ErrorEvent; + "error": Event; "ssrcconflict": RTCSsrcConflictEvent; } interface RTCRtpSender extends RTCStatsProvider { - onerror: ((this: RTCRtpSender, ev: ErrorEvent) => any) | null; + onerror: ((this: RTCRtpSender, ev: Event) => any) | null; onssrcconflict: ((this: RTCRtpSender, ev: RTCSsrcConflictEvent) => any) | null; readonly rtcpTransport: RTCDtlsTransport; readonly track: MediaStreamTrack; @@ -8491,12 +9207,23 @@ declare var RTCRtpSender: { getCapabilities(kind?: string): RTCRtpCapabilities; } +interface RTCSessionDescription { + sdp: string | null; + type: string | null; + toJSON(): any; +} + +declare var RTCSessionDescription: { + prototype: RTCSessionDescription; + new(descriptionInitDict?: RTCSessionDescriptionInit): RTCSessionDescription; +} + interface RTCSrtpSdesTransportEventMap { - "error": ErrorEvent; + "error": Event; } interface RTCSrtpSdesTransport extends EventTarget { - onerror: ((this: RTCSrtpSdesTransport, ev: ErrorEvent) => any) | null; + onerror: ((this: RTCSrtpSdesTransport, ev: Event) => any) | null; readonly transport: RTCIceTransport; addEventListener(type: K, listener: (this: RTCSrtpSdesTransport, ev: RTCSrtpSdesTransportEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; @@ -8571,9 +9298,69 @@ declare var Range: { readonly START_TO_START: number; } -interface SVGAElement extends SVGElement, SVGStylable, SVGTransformable, SVGTests, SVGLangSpace, SVGExternalResourcesRequired, SVGURIReference { +interface ReadableStream { + readonly locked: boolean; + cancel(): PromiseLike; + getReader(): ReadableStreamReader; +} + +declare var ReadableStream: { + prototype: ReadableStream; + new(): ReadableStream; +} + +interface ReadableStreamReader { + cancel(): PromiseLike; + read(): PromiseLike; + releaseLock(): void; +} + +declare var ReadableStreamReader: { + prototype: ReadableStreamReader; + new(): ReadableStreamReader; +} + +interface Request extends Object, Body { + readonly cache: string; + readonly credentials: string; + readonly destination: string; + readonly headers: Headers; + readonly integrity: string; + readonly keepalive: boolean; + readonly method: string; + readonly mode: string; + readonly redirect: string; + readonly referrer: string; + readonly referrerPolicy: string; + readonly type: string; + readonly url: string; + clone(): Request; +} + +declare var Request: { + prototype: Request; + new(input: Request | string, init?: RequestInit): Request; +} + +interface Response extends Object, Body { + readonly body: ReadableStream | null; + readonly headers: Headers; + readonly ok: boolean; + readonly status: number; + readonly statusText: string; + readonly type: string; + readonly url: string; + clone(): Response; +} + +declare var Response: { + prototype: Response; + new(body?: any, init?: ResponseInit): Response; +} + +interface SVGAElement extends SVGGraphicsElement, SVGURIReference { readonly target: SVGAnimatedString; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGAElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -8726,11 +9513,11 @@ declare var SVGAnimatedTransformList: { new(): SVGAnimatedTransformList; } -interface SVGCircleElement extends SVGElement, SVGStylable, SVGTransformable, SVGTests, SVGLangSpace, SVGExternalResourcesRequired { +interface SVGCircleElement extends SVGGraphicsElement { readonly cx: SVGAnimatedLength; readonly cy: SVGAnimatedLength; readonly r: SVGAnimatedLength; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGCircleElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -8739,9 +9526,9 @@ declare var SVGCircleElement: { new(): SVGCircleElement; } -interface SVGClipPathElement extends SVGElement, SVGStylable, SVGTransformable, SVGTests, SVGLangSpace, SVGExternalResourcesRequired, SVGUnitTypes { +interface SVGClipPathElement extends SVGGraphicsElement, SVGUnitTypes { readonly clipPathUnits: SVGAnimatedEnumeration; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGClipPathElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -8764,7 +9551,7 @@ interface SVGComponentTransferFunctionElement extends SVGElement { readonly SVG_FECOMPONENTTRANSFER_TYPE_LINEAR: number; readonly SVG_FECOMPONENTTRANSFER_TYPE_TABLE: number; readonly SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN: number; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGComponentTransferFunctionElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -8779,8 +9566,8 @@ declare var SVGComponentTransferFunctionElement: { readonly SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN: number; } -interface SVGDefsElement extends SVGElement, SVGStylable, SVGTransformable, SVGTests, SVGLangSpace, SVGExternalResourcesRequired { - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; +interface SVGDefsElement extends SVGGraphicsElement { + addEventListener(type: K, listener: (this: SVGDefsElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -8789,8 +9576,8 @@ declare var SVGDefsElement: { new(): SVGDefsElement; } -interface SVGDescElement extends SVGElement, SVGStylable, SVGLangSpace { - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; +interface SVGDescElement extends SVGElement { + addEventListener(type: K, listener: (this: SVGDescElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -8813,6 +9600,7 @@ interface SVGElementEventMap extends ElementEventMap { } interface SVGElement extends Element { + className: any; onclick: (this: SVGElement, ev: MouseEvent) => any; ondblclick: (this: SVGElement, ev: MouseEvent) => any; onfocusin: (this: SVGElement, ev: FocusEvent) => any; @@ -8824,9 +9612,9 @@ interface SVGElement extends Element { onmouseover: (this: SVGElement, ev: MouseEvent) => any; onmouseup: (this: SVGElement, ev: MouseEvent) => any; readonly ownerSVGElement: SVGSVGElement; + readonly style: CSSStyleDeclaration; readonly viewportElement: SVGElement; xmlbase: string; - className: any; addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -8862,12 +9650,12 @@ declare var SVGElementInstanceList: { new(): SVGElementInstanceList; } -interface SVGEllipseElement extends SVGElement, SVGStylable, SVGTransformable, SVGTests, SVGLangSpace, SVGExternalResourcesRequired { +interface SVGEllipseElement extends SVGGraphicsElement { readonly cx: SVGAnimatedLength; readonly cy: SVGAnimatedLength; readonly rx: SVGAnimatedLength; readonly ry: SVGAnimatedLength; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGEllipseElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -8897,7 +9685,7 @@ interface SVGFEBlendElement extends SVGElement, SVGFilterPrimitiveStandardAttrib readonly SVG_FEBLEND_MODE_SCREEN: number; readonly SVG_FEBLEND_MODE_SOFT_LIGHT: number; readonly SVG_FEBLEND_MODE_UNKNOWN: number; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEBlendElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -8932,7 +9720,7 @@ interface SVGFEColorMatrixElement extends SVGElement, SVGFilterPrimitiveStandard readonly SVG_FECOLORMATRIX_TYPE_MATRIX: number; readonly SVG_FECOLORMATRIX_TYPE_SATURATE: number; readonly SVG_FECOLORMATRIX_TYPE_UNKNOWN: number; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEColorMatrixElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -8948,7 +9736,7 @@ declare var SVGFEColorMatrixElement: { interface SVGFEComponentTransferElement extends SVGElement, SVGFilterPrimitiveStandardAttributes { readonly in1: SVGAnimatedString; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEComponentTransferElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -8972,7 +9760,7 @@ interface SVGFECompositeElement extends SVGElement, SVGFilterPrimitiveStandardAt readonly SVG_FECOMPOSITE_OPERATOR_OVER: number; readonly SVG_FECOMPOSITE_OPERATOR_UNKNOWN: number; readonly SVG_FECOMPOSITE_OPERATOR_XOR: number; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFECompositeElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9005,7 +9793,7 @@ interface SVGFEConvolveMatrixElement extends SVGElement, SVGFilterPrimitiveStand readonly SVG_EDGEMODE_NONE: number; readonly SVG_EDGEMODE_UNKNOWN: number; readonly SVG_EDGEMODE_WRAP: number; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEConvolveMatrixElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9024,7 +9812,7 @@ interface SVGFEDiffuseLightingElement extends SVGElement, SVGFilterPrimitiveStan readonly kernelUnitLengthX: SVGAnimatedNumber; readonly kernelUnitLengthY: SVGAnimatedNumber; readonly surfaceScale: SVGAnimatedNumber; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEDiffuseLightingElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9044,7 +9832,7 @@ interface SVGFEDisplacementMapElement extends SVGElement, SVGFilterPrimitiveStan readonly SVG_CHANNEL_G: number; readonly SVG_CHANNEL_R: number; readonly SVG_CHANNEL_UNKNOWN: number; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEDisplacementMapElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9061,7 +9849,7 @@ declare var SVGFEDisplacementMapElement: { interface SVGFEDistantLightElement extends SVGElement { readonly azimuth: SVGAnimatedNumber; readonly elevation: SVGAnimatedNumber; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEDistantLightElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9071,7 +9859,7 @@ declare var SVGFEDistantLightElement: { } interface SVGFEFloodElement extends SVGElement, SVGFilterPrimitiveStandardAttributes { - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEFloodElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9081,6 +9869,8 @@ declare var SVGFEFloodElement: { } interface SVGFEFuncAElement extends SVGComponentTransferFunctionElement { + addEventListener(type: K, listener: (this: SVGFEFuncAElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } declare var SVGFEFuncAElement: { @@ -9089,6 +9879,8 @@ declare var SVGFEFuncAElement: { } interface SVGFEFuncBElement extends SVGComponentTransferFunctionElement { + addEventListener(type: K, listener: (this: SVGFEFuncBElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } declare var SVGFEFuncBElement: { @@ -9097,6 +9889,8 @@ declare var SVGFEFuncBElement: { } interface SVGFEFuncGElement extends SVGComponentTransferFunctionElement { + addEventListener(type: K, listener: (this: SVGFEFuncGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } declare var SVGFEFuncGElement: { @@ -9105,6 +9899,8 @@ declare var SVGFEFuncGElement: { } interface SVGFEFuncRElement extends SVGComponentTransferFunctionElement { + addEventListener(type: K, listener: (this: SVGFEFuncRElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } declare var SVGFEFuncRElement: { @@ -9117,7 +9913,7 @@ interface SVGFEGaussianBlurElement extends SVGElement, SVGFilterPrimitiveStandar readonly stdDeviationX: SVGAnimatedNumber; readonly stdDeviationY: SVGAnimatedNumber; setStdDeviation(stdDeviationX: number, stdDeviationY: number): void; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEGaussianBlurElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9126,9 +9922,9 @@ declare var SVGFEGaussianBlurElement: { new(): SVGFEGaussianBlurElement; } -interface SVGFEImageElement extends SVGElement, SVGFilterPrimitiveStandardAttributes, SVGLangSpace, SVGURIReference, SVGExternalResourcesRequired { +interface SVGFEImageElement extends SVGElement, SVGFilterPrimitiveStandardAttributes, SVGURIReference { readonly preserveAspectRatio: SVGAnimatedPreserveAspectRatio; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEImageElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9138,7 +9934,7 @@ declare var SVGFEImageElement: { } interface SVGFEMergeElement extends SVGElement, SVGFilterPrimitiveStandardAttributes { - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEMergeElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9149,7 +9945,7 @@ declare var SVGFEMergeElement: { interface SVGFEMergeNodeElement extends SVGElement { readonly in1: SVGAnimatedString; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEMergeNodeElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9166,7 +9962,7 @@ interface SVGFEMorphologyElement extends SVGElement, SVGFilterPrimitiveStandardA readonly SVG_MORPHOLOGY_OPERATOR_DILATE: number; readonly SVG_MORPHOLOGY_OPERATOR_ERODE: number; readonly SVG_MORPHOLOGY_OPERATOR_UNKNOWN: number; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEMorphologyElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9182,7 +9978,7 @@ interface SVGFEOffsetElement extends SVGElement, SVGFilterPrimitiveStandardAttri readonly dx: SVGAnimatedNumber; readonly dy: SVGAnimatedNumber; readonly in1: SVGAnimatedString; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEOffsetElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9195,7 +9991,7 @@ interface SVGFEPointLightElement extends SVGElement { readonly x: SVGAnimatedNumber; readonly y: SVGAnimatedNumber; readonly z: SVGAnimatedNumber; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFEPointLightElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9211,7 +10007,7 @@ interface SVGFESpecularLightingElement extends SVGElement, SVGFilterPrimitiveSta readonly specularConstant: SVGAnimatedNumber; readonly specularExponent: SVGAnimatedNumber; readonly surfaceScale: SVGAnimatedNumber; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFESpecularLightingElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9229,7 +10025,7 @@ interface SVGFESpotLightElement extends SVGElement { readonly x: SVGAnimatedNumber; readonly y: SVGAnimatedNumber; readonly z: SVGAnimatedNumber; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFESpotLightElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9240,7 +10036,7 @@ declare var SVGFESpotLightElement: { interface SVGFETileElement extends SVGElement, SVGFilterPrimitiveStandardAttributes { readonly in1: SVGAnimatedString; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFETileElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9262,7 +10058,7 @@ interface SVGFETurbulenceElement extends SVGElement, SVGFilterPrimitiveStandardA readonly SVG_TURBULENCE_TYPE_FRACTALNOISE: number; readonly SVG_TURBULENCE_TYPE_TURBULENCE: number; readonly SVG_TURBULENCE_TYPE_UNKNOWN: number; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFETurbulenceElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9277,7 +10073,7 @@ declare var SVGFETurbulenceElement: { readonly SVG_TURBULENCE_TYPE_UNKNOWN: number; } -interface SVGFilterElement extends SVGElement, SVGUnitTypes, SVGStylable, SVGLangSpace, SVGURIReference, SVGExternalResourcesRequired { +interface SVGFilterElement extends SVGElement, SVGUnitTypes, SVGURIReference { readonly filterResX: SVGAnimatedInteger; readonly filterResY: SVGAnimatedInteger; readonly filterUnits: SVGAnimatedEnumeration; @@ -9287,7 +10083,7 @@ interface SVGFilterElement extends SVGElement, SVGUnitTypes, SVGStylable, SVGLan readonly x: SVGAnimatedLength; readonly y: SVGAnimatedLength; setFilterRes(filterResX: number, filterResY: number): void; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGFilterElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9296,12 +10092,12 @@ declare var SVGFilterElement: { new(): SVGFilterElement; } -interface SVGForeignObjectElement extends SVGElement, SVGStylable, SVGTransformable, SVGTests, SVGLangSpace, SVGExternalResourcesRequired { +interface SVGForeignObjectElement extends SVGGraphicsElement { readonly height: SVGAnimatedLength; readonly width: SVGAnimatedLength; readonly x: SVGAnimatedLength; readonly y: SVGAnimatedLength; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGForeignObjectElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9310,8 +10106,8 @@ declare var SVGForeignObjectElement: { new(): SVGForeignObjectElement; } -interface SVGGElement extends SVGElement, SVGStylable, SVGTransformable, SVGTests, SVGLangSpace, SVGExternalResourcesRequired { - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; +interface SVGGElement extends SVGGraphicsElement { + addEventListener(type: K, listener: (this: SVGGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9320,7 +10116,7 @@ declare var SVGGElement: { new(): SVGGElement; } -interface SVGGradientElement extends SVGElement, SVGStylable, SVGExternalResourcesRequired, SVGURIReference, SVGUnitTypes { +interface SVGGradientElement extends SVGElement, SVGUnitTypes, SVGURIReference { readonly gradientTransform: SVGAnimatedTransformList; readonly gradientUnits: SVGAnimatedEnumeration; readonly spreadMethod: SVGAnimatedEnumeration; @@ -9328,7 +10124,7 @@ interface SVGGradientElement extends SVGElement, SVGStylable, SVGExternalResourc readonly SVG_SPREADMETHOD_REFLECT: number; readonly SVG_SPREADMETHOD_REPEAT: number; readonly SVG_SPREADMETHOD_UNKNOWN: number; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGGradientElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9341,13 +10137,30 @@ declare var SVGGradientElement: { readonly SVG_SPREADMETHOD_UNKNOWN: number; } -interface SVGImageElement extends SVGElement, SVGStylable, SVGTransformable, SVGTests, SVGLangSpace, SVGExternalResourcesRequired, SVGURIReference { +interface SVGGraphicsElement extends SVGElement, SVGTests { + readonly farthestViewportElement: SVGElement; + readonly nearestViewportElement: SVGElement; + readonly transform: SVGAnimatedTransformList; + getBBox(): SVGRect; + getCTM(): SVGMatrix; + getScreenCTM(): SVGMatrix; + getTransformToElement(element: SVGElement): SVGMatrix; + addEventListener(type: K, listener: (this: SVGGraphicsElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +} + +declare var SVGGraphicsElement: { + prototype: SVGGraphicsElement; + new(): SVGGraphicsElement; +} + +interface SVGImageElement extends SVGGraphicsElement, SVGURIReference { readonly height: SVGAnimatedLength; readonly preserveAspectRatio: SVGAnimatedPreserveAspectRatio; readonly width: SVGAnimatedLength; readonly x: SVGAnimatedLength; readonly y: SVGAnimatedLength; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGImageElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9408,12 +10221,12 @@ declare var SVGLengthList: { new(): SVGLengthList; } -interface SVGLineElement extends SVGElement, SVGStylable, SVGTransformable, SVGTests, SVGLangSpace, SVGExternalResourcesRequired { +interface SVGLineElement extends SVGGraphicsElement { readonly x1: SVGAnimatedLength; readonly x2: SVGAnimatedLength; readonly y1: SVGAnimatedLength; readonly y2: SVGAnimatedLength; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGLineElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9427,6 +10240,8 @@ interface SVGLinearGradientElement extends SVGGradientElement { readonly x2: SVGAnimatedLength; readonly y1: SVGAnimatedLength; readonly y2: SVGAnimatedLength; + addEventListener(type: K, listener: (this: SVGLinearGradientElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } declare var SVGLinearGradientElement: { @@ -9434,7 +10249,7 @@ declare var SVGLinearGradientElement: { new(): SVGLinearGradientElement; } -interface SVGMarkerElement extends SVGElement, SVGStylable, SVGLangSpace, SVGExternalResourcesRequired, SVGFitToViewBox { +interface SVGMarkerElement extends SVGElement, SVGFitToViewBox { readonly markerHeight: SVGAnimatedLength; readonly markerUnits: SVGAnimatedEnumeration; readonly markerWidth: SVGAnimatedLength; @@ -9450,7 +10265,7 @@ interface SVGMarkerElement extends SVGElement, SVGStylable, SVGLangSpace, SVGExt readonly SVG_MARKER_ORIENT_ANGLE: number; readonly SVG_MARKER_ORIENT_AUTO: number; readonly SVG_MARKER_ORIENT_UNKNOWN: number; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGMarkerElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9465,14 +10280,14 @@ declare var SVGMarkerElement: { readonly SVG_MARKER_ORIENT_UNKNOWN: number; } -interface SVGMaskElement extends SVGElement, SVGStylable, SVGTests, SVGLangSpace, SVGExternalResourcesRequired, SVGUnitTypes { +interface SVGMaskElement extends SVGElement, SVGTests, SVGUnitTypes { readonly height: SVGAnimatedLength; readonly maskContentUnits: SVGAnimatedEnumeration; readonly maskUnits: SVGAnimatedEnumeration; readonly width: SVGAnimatedLength; readonly x: SVGAnimatedLength; readonly y: SVGAnimatedLength; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGMaskElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9507,7 +10322,7 @@ declare var SVGMatrix: { } interface SVGMetadataElement extends SVGElement { - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGMetadataElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9541,7 +10356,8 @@ declare var SVGNumberList: { new(): SVGNumberList; } -interface SVGPathElement extends SVGElement, SVGStylable, SVGTransformable, SVGTests, SVGLangSpace, SVGExternalResourcesRequired, SVGAnimatedPathData { +interface SVGPathElement extends SVGGraphicsElement { + readonly pathSegList: SVGPathSegList; createSVGPathSegArcAbs(x: number, y: number, r1: number, r2: number, angle: number, largeArcFlag: boolean, sweepFlag: boolean): SVGPathSegArcAbs; createSVGPathSegArcRel(x: number, y: number, r1: number, r2: number, angle: number, largeArcFlag: boolean, sweepFlag: boolean): SVGPathSegArcRel; createSVGPathSegClosePath(): SVGPathSegClosePath; @@ -9564,7 +10380,7 @@ interface SVGPathElement extends SVGElement, SVGStylable, SVGTransformable, SVGT getPathSegAtLength(distance: number): number; getPointAtLength(distance: number): SVGPoint; getTotalLength(): number; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGPathElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9849,7 +10665,7 @@ declare var SVGPathSegMovetoRel: { new(): SVGPathSegMovetoRel; } -interface SVGPatternElement extends SVGElement, SVGStylable, SVGTests, SVGLangSpace, SVGExternalResourcesRequired, SVGFitToViewBox, SVGURIReference, SVGUnitTypes { +interface SVGPatternElement extends SVGElement, SVGTests, SVGUnitTypes, SVGFitToViewBox, SVGURIReference { readonly height: SVGAnimatedLength; readonly patternContentUnits: SVGAnimatedEnumeration; readonly patternTransform: SVGAnimatedTransformList; @@ -9857,7 +10673,7 @@ interface SVGPatternElement extends SVGElement, SVGStylable, SVGTests, SVGLangSp readonly width: SVGAnimatedLength; readonly x: SVGAnimatedLength; readonly y: SVGAnimatedLength; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGPatternElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9893,8 +10709,8 @@ declare var SVGPointList: { new(): SVGPointList; } -interface SVGPolygonElement extends SVGElement, SVGStylable, SVGTransformable, SVGTests, SVGLangSpace, SVGExternalResourcesRequired, SVGAnimatedPoints { - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; +interface SVGPolygonElement extends SVGGraphicsElement, SVGAnimatedPoints { + addEventListener(type: K, listener: (this: SVGPolygonElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9903,8 +10719,8 @@ declare var SVGPolygonElement: { new(): SVGPolygonElement; } -interface SVGPolylineElement extends SVGElement, SVGStylable, SVGTransformable, SVGTests, SVGLangSpace, SVGExternalResourcesRequired, SVGAnimatedPoints { - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; +interface SVGPolylineElement extends SVGGraphicsElement, SVGAnimatedPoints { + addEventListener(type: K, listener: (this: SVGPolylineElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -9957,6 +10773,8 @@ interface SVGRadialGradientElement extends SVGGradientElement { readonly fx: SVGAnimatedLength; readonly fy: SVGAnimatedLength; readonly r: SVGAnimatedLength; + addEventListener(type: K, listener: (this: SVGRadialGradientElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } declare var SVGRadialGradientElement: { @@ -9976,14 +10794,14 @@ declare var SVGRect: { new(): SVGRect; } -interface SVGRectElement extends SVGElement, SVGStylable, SVGTransformable, SVGTests, SVGLangSpace, SVGExternalResourcesRequired { +interface SVGRectElement extends SVGGraphicsElement { readonly height: SVGAnimatedLength; readonly rx: SVGAnimatedLength; readonly ry: SVGAnimatedLength; readonly width: SVGAnimatedLength; readonly x: SVGAnimatedLength; readonly y: SVGAnimatedLength; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGRectElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -10001,7 +10819,7 @@ interface SVGSVGElementEventMap extends SVGElementEventMap { "SVGZoom": SVGZoomEvent; } -interface SVGSVGElement extends SVGElement, DocumentEvent, SVGLocatable, SVGTests, SVGStylable, SVGLangSpace, SVGExternalResourcesRequired, SVGFitToViewBox, SVGZoomAndPan { +interface SVGSVGElement extends SVGGraphicsElement, DocumentEvent, SVGFitToViewBox, SVGZoomAndPan { contentScriptType: string; contentStyleType: string; currentScale: number; @@ -10053,9 +10871,9 @@ declare var SVGSVGElement: { new(): SVGSVGElement; } -interface SVGScriptElement extends SVGElement, SVGExternalResourcesRequired, SVGURIReference { +interface SVGScriptElement extends SVGElement, SVGURIReference { type: string; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGScriptElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -10064,9 +10882,9 @@ declare var SVGScriptElement: { new(): SVGScriptElement; } -interface SVGStopElement extends SVGElement, SVGStylable { +interface SVGStopElement extends SVGElement { readonly offset: SVGAnimatedNumber; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGStopElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -10091,12 +10909,12 @@ declare var SVGStringList: { new(): SVGStringList; } -interface SVGStyleElement extends SVGElement, SVGLangSpace { +interface SVGStyleElement extends SVGElement { disabled: boolean; media: string; title: string; type: string; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGStyleElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -10105,8 +10923,8 @@ declare var SVGStyleElement: { new(): SVGStyleElement; } -interface SVGSwitchElement extends SVGElement, SVGStylable, SVGTransformable, SVGTests, SVGLangSpace, SVGExternalResourcesRequired { - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; +interface SVGSwitchElement extends SVGGraphicsElement { + addEventListener(type: K, listener: (this: SVGSwitchElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -10115,8 +10933,8 @@ declare var SVGSwitchElement: { new(): SVGSwitchElement; } -interface SVGSymbolElement extends SVGElement, SVGStylable, SVGLangSpace, SVGExternalResourcesRequired, SVGFitToViewBox { - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; +interface SVGSymbolElement extends SVGElement, SVGFitToViewBox { + addEventListener(type: K, listener: (this: SVGSymbolElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -10126,6 +10944,8 @@ declare var SVGSymbolElement: { } interface SVGTSpanElement extends SVGTextPositioningElement { + addEventListener(type: K, listener: (this: SVGTSpanElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } declare var SVGTSpanElement: { @@ -10133,7 +10953,7 @@ declare var SVGTSpanElement: { new(): SVGTSpanElement; } -interface SVGTextContentElement extends SVGElement, SVGStylable, SVGTests, SVGLangSpace, SVGExternalResourcesRequired { +interface SVGTextContentElement extends SVGGraphicsElement { readonly lengthAdjust: SVGAnimatedEnumeration; readonly textLength: SVGAnimatedLength; getCharNumAtPosition(point: SVGPoint): number; @@ -10148,7 +10968,7 @@ interface SVGTextContentElement extends SVGElement, SVGStylable, SVGTests, SVGLa readonly LENGTHADJUST_SPACING: number; readonly LENGTHADJUST_SPACINGANDGLYPHS: number; readonly LENGTHADJUST_UNKNOWN: number; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGTextContentElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -10160,7 +10980,9 @@ declare var SVGTextContentElement: { readonly LENGTHADJUST_UNKNOWN: number; } -interface SVGTextElement extends SVGTextPositioningElement, SVGTransformable { +interface SVGTextElement extends SVGTextPositioningElement { + addEventListener(type: K, listener: (this: SVGTextElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } declare var SVGTextElement: { @@ -10178,6 +11000,8 @@ interface SVGTextPathElement extends SVGTextContentElement, SVGURIReference { readonly TEXTPATH_SPACINGTYPE_AUTO: number; readonly TEXTPATH_SPACINGTYPE_EXACT: number; readonly TEXTPATH_SPACINGTYPE_UNKNOWN: number; + addEventListener(type: K, listener: (this: SVGTextPathElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } declare var SVGTextPathElement: { @@ -10197,6 +11021,8 @@ interface SVGTextPositioningElement extends SVGTextContentElement { readonly rotate: SVGAnimatedNumberList; readonly x: SVGAnimatedLengthList; readonly y: SVGAnimatedLengthList; + addEventListener(type: K, listener: (this: SVGTextPositioningElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } declare var SVGTextPositioningElement: { @@ -10204,8 +11030,8 @@ declare var SVGTextPositioningElement: { new(): SVGTextPositioningElement; } -interface SVGTitleElement extends SVGElement, SVGStylable, SVGLangSpace { - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; +interface SVGTitleElement extends SVGElement { + addEventListener(type: K, listener: (this: SVGTitleElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -10270,14 +11096,14 @@ interface SVGUnitTypes { } declare var SVGUnitTypes: SVGUnitTypes; -interface SVGUseElement extends SVGElement, SVGStylable, SVGTransformable, SVGTests, SVGLangSpace, SVGExternalResourcesRequired, SVGURIReference { +interface SVGUseElement extends SVGGraphicsElement, SVGURIReference { readonly animatedInstanceRoot: SVGElementInstance; readonly height: SVGAnimatedLength; readonly instanceRoot: SVGElementInstance; readonly width: SVGAnimatedLength; readonly x: SVGAnimatedLength; readonly y: SVGAnimatedLength; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGUseElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -10286,9 +11112,9 @@ declare var SVGUseElement: { new(): SVGUseElement; } -interface SVGViewElement extends SVGElement, SVGExternalResourcesRequired, SVGFitToViewBox, SVGZoomAndPan { +interface SVGViewElement extends SVGElement, SVGZoomAndPan, SVGFitToViewBox { readonly viewTarget: SVGStringList; - addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: SVGViewElement, ev: SVGElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -10320,6 +11146,26 @@ declare var SVGZoomEvent: { new(): SVGZoomEvent; } +interface ScopedCredential { + readonly id: ArrayBuffer; + readonly type: string; +} + +declare var ScopedCredential: { + prototype: ScopedCredential; + new(): ScopedCredential; +} + +interface ScopedCredentialInfo { + readonly credential: ScopedCredential; + readonly publicKey: CryptoKey; +} + +declare var ScopedCredentialInfo: { + prototype: ScopedCredentialInfo; + new(): ScopedCredentialInfo; +} + interface ScreenEventMap { "MSOrientationChange": Event; } @@ -10381,6 +11227,10 @@ declare var ScriptProcessorNode: { interface Selection { readonly anchorNode: Node; readonly anchorOffset: number; + readonly baseNode: Node; + readonly baseOffset: number; + readonly extentNode: Node; + readonly extentOffset: number; readonly focusNode: Node; readonly focusOffset: number; readonly isCollapsed: boolean; @@ -10399,6 +11249,7 @@ interface Selection { removeRange(range: Range): void; selectAllChildren(parentNode: Node): void; setBaseAndExtent(baseNode: Node, baseOffset: number, extentNode: Node, extentOffset: number): void; + setPosition(parentNode: Node, offset: number): void; toString(): string; } @@ -10407,6 +11258,84 @@ declare var Selection: { new(): Selection; } +interface ServiceWorkerEventMap extends AbstractWorkerEventMap { + "statechange": Event; +} + +interface ServiceWorker extends EventTarget, AbstractWorker { + onstatechange: (this: ServiceWorker, ev: Event) => any; + readonly scriptURL: USVString; + readonly state: string; + postMessage(message: any, transfer?: any[]): void; + addEventListener(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +} + +declare var ServiceWorker: { + prototype: ServiceWorker; + new(): ServiceWorker; +} + +interface ServiceWorkerContainerEventMap { + "controllerchange": Event; + "message": ServiceWorkerMessageEvent; +} + +interface ServiceWorkerContainer extends EventTarget { + readonly controller: ServiceWorker | null; + oncontrollerchange: (this: ServiceWorkerContainer, ev: Event) => any; + onmessage: (this: ServiceWorkerContainer, ev: ServiceWorkerMessageEvent) => any; + readonly ready: PromiseLike; + getRegistration(clientURL?: USVString): PromiseLike; + getRegistrations(): any; + register(scriptURL: USVString, options?: RegistrationOptions): PromiseLike; + addEventListener(type: K, listener: (this: ServiceWorkerContainer, ev: ServiceWorkerContainerEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +} + +declare var ServiceWorkerContainer: { + prototype: ServiceWorkerContainer; + new(): ServiceWorkerContainer; +} + +interface ServiceWorkerMessageEvent extends Event { + readonly data: any; + readonly lastEventId: string; + readonly origin: string; + readonly ports: MessagePort[] | null; + readonly source: ServiceWorker | MessagePort | null; +} + +declare var ServiceWorkerMessageEvent: { + prototype: ServiceWorkerMessageEvent; + new(type: string, eventInitDict?: ServiceWorkerMessageEventInit): ServiceWorkerMessageEvent; +} + +interface ServiceWorkerRegistrationEventMap { + "updatefound": Event; +} + +interface ServiceWorkerRegistration extends EventTarget { + readonly active: ServiceWorker | null; + readonly installing: ServiceWorker | null; + onupdatefound: (this: ServiceWorkerRegistration, ev: Event) => any; + readonly pushManager: PushManager; + readonly scope: USVString; + readonly sync: SyncManager; + readonly waiting: ServiceWorker | null; + getNotifications(filter?: GetNotificationOptions): any; + showNotification(title: string, options?: NotificationOptions): PromiseLike; + unregister(): PromiseLike; + update(): PromiseLike; + addEventListener(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +} + +declare var ServiceWorkerRegistration: { + prototype: ServiceWorkerRegistration; + new(): ServiceWorkerRegistration; +} + interface SourceBuffer extends EventTarget { appendWindowEnd: number; appendWindowStart: number; @@ -10438,6 +11367,87 @@ declare var SourceBufferList: { new(): SourceBufferList; } +interface SpeechSynthesisEventMap { + "voiceschanged": Event; +} + +interface SpeechSynthesis extends EventTarget { + onvoiceschanged: (this: SpeechSynthesis, ev: Event) => any; + readonly paused: boolean; + readonly pending: boolean; + readonly speaking: boolean; + cancel(): void; + getVoices(): SpeechSynthesisVoice[]; + pause(): void; + resume(): void; + speak(utterance: SpeechSynthesisUtterance): void; + addEventListener(type: K, listener: (this: SpeechSynthesis, ev: SpeechSynthesisEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +} + +declare var SpeechSynthesis: { + prototype: SpeechSynthesis; + new(): SpeechSynthesis; +} + +interface SpeechSynthesisEvent extends Event { + readonly charIndex: number; + readonly elapsedTime: number; + readonly name: string; + readonly utterance: SpeechSynthesisUtterance | null; +} + +declare var SpeechSynthesisEvent: { + prototype: SpeechSynthesisEvent; + new(type: string, eventInitDict?: SpeechSynthesisEventInit): SpeechSynthesisEvent; +} + +interface SpeechSynthesisUtteranceEventMap { + "boundary": Event; + "end": Event; + "error": Event; + "mark": Event; + "pause": Event; + "resume": Event; + "start": Event; +} + +interface SpeechSynthesisUtterance extends EventTarget { + lang: string; + onboundary: (this: SpeechSynthesisUtterance, ev: Event) => any; + onend: (this: SpeechSynthesisUtterance, ev: Event) => any; + onerror: (this: SpeechSynthesisUtterance, ev: Event) => any; + onmark: (this: SpeechSynthesisUtterance, ev: Event) => any; + onpause: (this: SpeechSynthesisUtterance, ev: Event) => any; + onresume: (this: SpeechSynthesisUtterance, ev: Event) => any; + onstart: (this: SpeechSynthesisUtterance, ev: Event) => any; + pitch: number; + rate: number; + text: string; + voice: SpeechSynthesisVoice; + volume: number; + addEventListener(type: K, listener: (this: SpeechSynthesisUtterance, ev: SpeechSynthesisUtteranceEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +} + +declare var SpeechSynthesisUtterance: { + prototype: SpeechSynthesisUtterance; + new(text?: string): SpeechSynthesisUtterance; +} + +interface SpeechSynthesisVoice { + readonly default: boolean; + readonly lang: string; + readonly localService: boolean; + readonly name: string; + readonly voiceURI: string; +} + +declare var SpeechSynthesisVoice: { + prototype: SpeechSynthesisVoice; + new(): SpeechSynthesisVoice; +} + interface StereoPannerNode extends AudioNode { readonly pan: AudioParam; } @@ -10549,6 +11559,16 @@ declare var SubtleCrypto: { new(): SubtleCrypto; } +interface SyncManager { + getTags(): any; + register(tag: string): PromiseLike; +} + +declare var SyncManager: { + prototype: SyncManager; + new(): SyncManager; +} + interface Text extends CharacterData { readonly wholeText: string; readonly assignedSlot: HTMLSlotElement | null; @@ -10603,7 +11623,7 @@ declare var TextMetrics: { interface TextTrackEventMap { "cuechange": Event; - "error": ErrorEvent; + "error": Event; "load": Event; } @@ -10616,7 +11636,7 @@ interface TextTrack extends EventTarget { readonly language: string; mode: any; oncuechange: (this: TextTrack, ev: Event) => any; - onerror: (this: TextTrack, ev: ErrorEvent) => any; + onerror: (this: TextTrack, ev: Event) => any; onload: (this: TextTrack, ev: Event) => any; readonly readyState: number; addCue(cue: TextTrackCue): void; @@ -10728,11 +11748,14 @@ declare var Touch: { interface TouchEvent extends UIEvent { readonly altKey: boolean; readonly changedTouches: TouchList; + readonly charCode: number; readonly ctrlKey: boolean; + readonly keyCode: number; readonly metaKey: boolean; readonly shiftKey: boolean; readonly targetTouches: TouchList; readonly touches: TouchList; + readonly which: number; } declare var TouchEvent: { @@ -10752,12 +11775,12 @@ declare var TouchList: { } interface TrackEvent extends Event { - readonly track: any; + readonly track: VideoTrack | AudioTrack | TextTrack | null; } declare var TrackEvent: { prototype: TrackEvent; - new(): TrackEvent; + new(typeArg: string, eventInitDict?: TrackEventInit): TrackEvent; } interface TransitionEvent extends Event { @@ -10768,7 +11791,7 @@ interface TransitionEvent extends Event { declare var TransitionEvent: { prototype: TransitionEvent; - new(): TransitionEvent; + new(typeArg: string, eventInitDict?: TransitionEventInit): TransitionEvent; } interface TreeWalker { @@ -10799,7 +11822,7 @@ interface UIEvent extends Event { declare var UIEvent: { prototype: UIEvent; - new(type: string, eventInitDict?: UIEventInit): UIEvent; + new(typeArg: string, eventInitDict?: UIEventInit): UIEvent; } interface URL { @@ -10814,6 +11837,7 @@ interface URL { protocol: string; search: string; username: string; + readonly searchparams: URLSearchParams; toString(): string; } @@ -10950,6 +11974,28 @@ declare var WaveShaperNode: { new(): WaveShaperNode; } +interface WebAuthentication { + getAssertion(assertionChallenge: any, options?: AssertionOptions): PromiseLike; + makeCredential(accountInformation: Account, cryptoParameters: ScopedCredentialParameters[], attestationChallenge: any, options?: ScopedCredentialOptions): PromiseLike; +} + +declare var WebAuthentication: { + prototype: WebAuthentication; + new(): WebAuthentication; +} + +interface WebAuthnAssertion { + readonly authenticatorData: ArrayBuffer; + readonly clientData: ArrayBuffer; + readonly credential: ScopedCredential; + readonly signature: ArrayBuffer; +} + +declare var WebAuthnAssertion: { + prototype: WebAuthnAssertion; + new(): WebAuthnAssertion; +} + interface WebGLActiveInfo { readonly name: string; readonly size: number; @@ -10975,7 +12021,7 @@ interface WebGLContextEvent extends Event { declare var WebGLContextEvent: { prototype: WebGLContextEvent; - new(type: string, eventInitDict?: WebGLContextEventInit): WebGLContextEvent; + new(typeArg: string, eventInitDict?: WebGLContextEventInit): WebGLContextEvent; } interface WebGLFramebuffer extends WebGLObject { @@ -11102,7 +12148,7 @@ interface WebGLRenderingContext { isTexture(texture: WebGLTexture | null): boolean; lineWidth(width: number): void; linkProgram(program: WebGLProgram | null): void; - pixelStorei(pname: number, param: number): void; + pixelStorei(pname: number, param: number | boolean): void; polygonOffset(factor: number, units: number): void; readPixels(x: number, y: number, width: number, height: number, format: number, type: number, pixels: ArrayBufferView | null): void; renderbufferStorage(target: number, internalformat: number, width: number, height: number): void; @@ -11828,6 +12874,56 @@ declare var WebKitCSSMatrix: { new(text?: string): WebKitCSSMatrix; } +interface WebKitDirectoryEntry extends WebKitEntry { + createReader(): WebKitDirectoryReader; +} + +declare var WebKitDirectoryEntry: { + prototype: WebKitDirectoryEntry; + new(): WebKitDirectoryEntry; +} + +interface WebKitDirectoryReader { + readEntries(successCallback: WebKitEntriesCallback, errorCallback?: WebKitErrorCallback): void; +} + +declare var WebKitDirectoryReader: { + prototype: WebKitDirectoryReader; + new(): WebKitDirectoryReader; +} + +interface WebKitEntry { + readonly filesystem: WebKitFileSystem; + readonly fullPath: string; + readonly isDirectory: boolean; + readonly isFile: boolean; + readonly name: string; +} + +declare var WebKitEntry: { + prototype: WebKitEntry; + new(): WebKitEntry; +} + +interface WebKitFileEntry extends WebKitEntry { + file(successCallback: WebKitFileCallback, errorCallback?: WebKitErrorCallback): void; +} + +declare var WebKitFileEntry: { + prototype: WebKitFileEntry; + new(): WebKitFileEntry; +} + +interface WebKitFileSystem { + readonly name: string; + readonly root: WebKitDirectoryEntry; +} + +declare var WebKitFileSystem: { + prototype: WebKitFileSystem; + new(): WebKitFileSystem; +} + interface WebKitPoint { x: number; y: number; @@ -11840,7 +12936,7 @@ declare var WebKitPoint: { interface WebSocketEventMap { "close": CloseEvent; - "error": ErrorEvent; + "error": Event; "message": MessageEvent; "open": Event; } @@ -11850,7 +12946,7 @@ interface WebSocket extends EventTarget { readonly bufferedAmount: number; readonly extensions: string; onclose: (this: WebSocket, ev: CloseEvent) => any; - onerror: (this: WebSocket, ev: ErrorEvent) => any; + onerror: (this: WebSocket, ev: Event) => any; onmessage: (this: WebSocket, ev: MessageEvent) => any; onopen: (this: WebSocket, ev: Event) => any; readonly protocol: string; @@ -11987,8 +13083,9 @@ interface WindowEventMap extends GlobalEventHandlersEventMap { "waiting": Event; } -interface Window extends EventTarget, WindowTimers, WindowSessionStorage, WindowLocalStorage, WindowConsole, GlobalEventHandlers, IDBEnvironment, WindowBase64 { +interface Window extends EventTarget, WindowTimers, WindowSessionStorage, WindowLocalStorage, WindowConsole, GlobalEventHandlers, IDBEnvironment, WindowBase64, GlobalFetch { readonly applicationCache: ApplicationCache; + readonly caches: CacheStorage; readonly clientInformation: Navigator; readonly closed: boolean; readonly crypto: Crypto; @@ -12003,10 +13100,12 @@ interface Window extends EventTarget, WindowTimers, WindowSessionStorage, Window readonly history: History; readonly innerHeight: number; readonly innerWidth: number; + readonly isSecureContext: boolean; readonly length: number; readonly location: Location; readonly locationbar: BarProp; readonly menubar: BarProp; + readonly msContentScript: ExtensionScriptApis; readonly msCredentials: MSCredentials; name: string; readonly navigator: Navigator; @@ -12120,6 +13219,7 @@ interface Window extends EventTarget, WindowTimers, WindowSessionStorage, Window readonly scrollY: number; readonly scrollbars: BarProp; readonly self: Window; + readonly speechSynthesis: SpeechSynthesis; status: string; readonly statusbar: BarProp; readonly styleMedia: StyleMedia; @@ -12128,12 +13228,14 @@ interface Window extends EventTarget, WindowTimers, WindowSessionStorage, Window readonly window: Window; URL: typeof URL; Blob: typeof Blob; + customElements: CustomElementRegistry; alert(message?: any): void; blur(): void; cancelAnimationFrame(handle: number): void; captureEvents(): void; close(): void; confirm(message?: string): boolean; + departFocus(navigationReason: string, origin: FocusNavigationOrigin): void; focus(): void; getComputedStyle(elt: Element, pseudoElt?: string): CSSStyleDeclaration; getMatchedCSSRules(elt: Element, pseudoElt?: string): CSSRuleList; @@ -12153,6 +13255,7 @@ interface Window extends EventTarget, WindowTimers, WindowSessionStorage, Window scroll(x?: number, y?: number): void; scrollBy(x?: number, y?: number): void; scrollTo(x?: number, y?: number): void; + stop(): void; webkitCancelAnimationFrame(handle: number): void; webkitConvertPointFromNodeToPage(node: Node, pt: WebKitPoint): WebKitPoint; webkitConvertPointFromPageToNode(node: Node, pt: WebKitPoint): WebKitPoint; @@ -12175,7 +13278,7 @@ interface WorkerEventMap extends AbstractWorkerEventMap { interface Worker extends EventTarget, AbstractWorker { onmessage: (this: Worker, ev: MessageEvent) => any; - postMessage(message: any, ports?: any): void; + postMessage(message: any, transfer?: any[]): void; terminate(): void; addEventListener(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; @@ -12187,7 +13290,7 @@ declare var Worker: { } interface XMLDocument extends Document { - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: XMLDocument, ev: DocumentEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -12206,14 +13309,14 @@ interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget { readonly response: any; readonly responseText: string; responseType: string; - readonly responseXML: any; + readonly responseURL: string; + readonly responseXML: Document | null; readonly status: number; readonly statusText: string; timeout: number; readonly upload: XMLHttpRequestUpload; withCredentials: boolean; msCaching?: string; - readonly responseURL: string; abort(): void; getAllResponseHeaders(): string; getResponseHeader(header: string): string | null; @@ -12241,11 +13344,10 @@ declare var XMLHttpRequest: { readonly LOADING: number; readonly OPENED: number; readonly UNSENT: number; - create(): XMLHttpRequest; } interface XMLHttpRequestUpload extends EventTarget, XMLHttpRequestEventTarget { - addEventListener(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -12345,6 +13447,16 @@ declare var XSLTProcessor: { new(): XSLTProcessor; } +interface webkitRTCPeerConnection extends RTCPeerConnection { + addEventListener(type: K, listener: (this: webkitRTCPeerConnection, ev: RTCPeerConnectionEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +} + +declare var webkitRTCPeerConnection: { + prototype: webkitRTCPeerConnection; + new(configuration: RTCConfiguration): webkitRTCPeerConnection; +} + interface AbstractWorkerEventMap { "error": ErrorEvent; } @@ -12355,6 +13467,14 @@ interface AbstractWorker { addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } +interface Body { + readonly bodyUsed: boolean; + arrayBuffer(): PromiseLike; + blob(): PromiseLike; + json(): PromiseLike; + text(): PromiseLike; +} + interface CanvasPathMethods { arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean): void; arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void; @@ -12381,12 +13501,10 @@ interface DOML2DeprecatedSizeProperty { interface DocumentEvent { createEvent(eventInterface:"AnimationEvent"): AnimationEvent; - createEvent(eventInterface:"AriaRequestEvent"): AriaRequestEvent; createEvent(eventInterface:"AudioProcessingEvent"): AudioProcessingEvent; createEvent(eventInterface:"BeforeUnloadEvent"): BeforeUnloadEvent; createEvent(eventInterface:"ClipboardEvent"): ClipboardEvent; createEvent(eventInterface:"CloseEvent"): CloseEvent; - createEvent(eventInterface:"CommandEvent"): CommandEvent; createEvent(eventInterface:"CompositionEvent"): CompositionEvent; createEvent(eventInterface:"CustomEvent"): CustomEvent; createEvent(eventInterface:"DeviceLightEvent"): DeviceLightEvent; @@ -12397,6 +13515,7 @@ interface DocumentEvent { createEvent(eventInterface:"Event"): Event; createEvent(eventInterface:"Events"): Event; createEvent(eventInterface:"FocusEvent"): FocusEvent; + createEvent(eventInterface:"FocusNavigationEvent"): FocusNavigationEvent; createEvent(eventInterface:"GamepadEvent"): GamepadEvent; createEvent(eventInterface:"HashChangeEvent"): HashChangeEvent; createEvent(eventInterface:"IDBVersionChangeEvent"): IDBVersionChangeEvent; @@ -12412,6 +13531,7 @@ interface DocumentEvent { createEvent(eventInterface:"MediaEncryptedEvent"): MediaEncryptedEvent; createEvent(eventInterface:"MediaKeyMessageEvent"): MediaKeyMessageEvent; createEvent(eventInterface:"MediaStreamErrorEvent"): MediaStreamErrorEvent; + createEvent(eventInterface:"MediaStreamEvent"): MediaStreamEvent; createEvent(eventInterface:"MediaStreamTrackEvent"): MediaStreamTrackEvent; createEvent(eventInterface:"MessageEvent"): MessageEvent; createEvent(eventInterface:"MouseEvent"): MouseEvent; @@ -12424,6 +13544,7 @@ interface DocumentEvent { createEvent(eventInterface:"OfflineAudioCompletionEvent"): OfflineAudioCompletionEvent; createEvent(eventInterface:"OverflowEvent"): OverflowEvent; createEvent(eventInterface:"PageTransitionEvent"): PageTransitionEvent; + createEvent(eventInterface:"PaymentRequestUpdateEvent"): PaymentRequestUpdateEvent; createEvent(eventInterface:"PermissionRequestedEvent"): PermissionRequestedEvent; createEvent(eventInterface:"PointerEvent"): PointerEvent; createEvent(eventInterface:"PopStateEvent"): PopStateEvent; @@ -12433,10 +13554,13 @@ interface DocumentEvent { createEvent(eventInterface:"RTCIceCandidatePairChangedEvent"): RTCIceCandidatePairChangedEvent; createEvent(eventInterface:"RTCIceGathererEvent"): RTCIceGathererEvent; createEvent(eventInterface:"RTCIceTransportStateChangedEvent"): RTCIceTransportStateChangedEvent; + createEvent(eventInterface:"RTCPeerConnectionIceEvent"): RTCPeerConnectionIceEvent; createEvent(eventInterface:"RTCSsrcConflictEvent"): RTCSsrcConflictEvent; createEvent(eventInterface:"SVGZoomEvent"): SVGZoomEvent; createEvent(eventInterface:"SVGZoomEvents"): SVGZoomEvent; createEvent(eventInterface:"ScriptNotifyEvent"): ScriptNotifyEvent; + createEvent(eventInterface:"ServiceWorkerMessageEvent"): ServiceWorkerMessageEvent; + createEvent(eventInterface:"SpeechSynthesisEvent"): SpeechSynthesisEvent; createEvent(eventInterface:"StorageEvent"): StorageEvent; createEvent(eventInterface:"TextEvent"): TextEvent; createEvent(eventInterface:"TouchEvent"): TouchEvent; @@ -12452,10 +13576,10 @@ interface DocumentEvent { interface ElementTraversal { readonly childElementCount: number; - readonly firstElementChild: Element; - readonly lastElementChild: Element; - readonly nextElementSibling: Element; - readonly previousElementSibling: Element; + readonly firstElementChild: Element | null; + readonly lastElementChild: Element | null; + readonly nextElementSibling: Element | null; + readonly previousElementSibling: Element | null; } interface GetSVGDocument { @@ -12488,6 +13612,10 @@ interface GlobalEventHandlers { addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } +interface GlobalFetch { + fetch(input: RequestInfo, init?: RequestInit): PromiseLike; +} + interface HTMLTableAlignment { /** * Sets or retrieves a value that you can use to implement your own ch functionality for the object. @@ -12551,6 +13679,14 @@ interface MSNavigatorDoNotTrack { storeWebWideTrackingException(args: StoreExceptionsInformation): void; } +interface NavigatorBeacon { + sendBeacon(url: USVString, data?: BodyInit): boolean; +} + +interface NavigatorConcurrentHardware { + readonly hardwareConcurrency: number; +} + interface NavigatorContentUtils { } @@ -12559,6 +13695,7 @@ interface NavigatorGeolocation { } interface NavigatorID { + readonly appCodeName: string; readonly appName: string; readonly appVersion: string; readonly platform: string; @@ -12592,20 +13729,12 @@ interface RandomSource { getRandomValues(array: ArrayBufferView): ArrayBufferView; } -interface SVGAnimatedPathData { - readonly pathSegList: SVGPathSegList; -} - interface SVGAnimatedPoints { readonly animatedPoints: SVGPointList; readonly points: SVGPointList; } -interface SVGExternalResourcesRequired { - readonly externalResourcesRequired: SVGAnimatedBoolean; -} - -interface SVGFilterPrimitiveStandardAttributes extends SVGStylable { +interface SVGFilterPrimitiveStandardAttributes { readonly height: SVGAnimatedLength; readonly result: SVGAnimatedString; readonly width: SVGAnimatedLength; @@ -12618,25 +13747,6 @@ interface SVGFitToViewBox { readonly viewBox: SVGAnimatedRect; } -interface SVGLangSpace { - xmllang: string; - xmlspace: string; -} - -interface SVGLocatable { - readonly farthestViewportElement: SVGElement; - readonly nearestViewportElement: SVGElement; - getBBox(): SVGRect; - getCTM(): SVGMatrix; - getScreenCTM(): SVGMatrix; - getTransformToElement(element: SVGElement): SVGMatrix; -} - -interface SVGStylable { - className: any; - readonly style: CSSStyleDeclaration; -} - interface SVGTests { readonly requiredExtensions: SVGStringList; readonly requiredFeatures: SVGStringList; @@ -12644,10 +13754,6 @@ interface SVGTests { hasExtension(extension: string): boolean; } -interface SVGTransformable extends SVGLocatable { - readonly transform: SVGAnimatedTransformList; -} - interface SVGURIReference { readonly href: SVGAnimatedString; } @@ -12706,6 +13812,14 @@ interface XMLHttpRequestEventTarget { addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } +interface ErrorEventInit { + message?: string; + filename?: string; + lineno?: number; + conlno?: number; + error?: any; +} + interface StorageEventInit extends EventInit { key?: string; oldValue?: string; @@ -12721,6 +13835,41 @@ interface Canvas2DContextAttributes { [attribute: string]: boolean | string | undefined; } +interface URLSearchParams { + /** + * Appends a specified key/value pair as a new search parameter. + */ + append(name: string, value: string): void; + /** + * Deletes the given search parameter, and its associated value, from the list of all search parameters. + */ + delete(name: string): void; + /** + * Returns the first value associated to the given search parameter. + */ + get(name: string): string | null; + /** + * Returns all the values association with a given search parameter. + */ + getAll(name: string): string[]; + /** + * Returns a Boolean indicating if such a search parameter exists. + */ + has(name: string): boolean; + /** + * Sets the value associated to a given search parameter to the given value. If there were several values, delete the others. + */ + set(name: string, value: string): void; +} + +declare var URLSearchParams: { + prototype: URLSearchParams; + /** + * Constructor returning a URLSearchParams object. + */ + new (init?: string | URLSearchParams): URLSearchParams; +} + interface NodeListOf extends NodeList { length: number; item(index: number): TNode; @@ -12730,7 +13879,6 @@ interface NodeListOf extends NodeList { interface HTMLCollectionOf extends HTMLCollection { item(index: number): T; namedItem(name: string): T; - [index: number]: T; } interface BlobPropertyBag { @@ -12747,15 +13895,6 @@ interface EventListenerObject { handleEvent(evt: Event): void; } -interface MessageEventInit extends EventInit { - data?: any; - origin?: string; - lastEventId?: string; - channel?: string; - source?: any; - ports?: MessagePort[]; -} - interface ProgressEventInit extends EventInit { lengthComputable?: boolean; loaded?: number; @@ -12957,8 +14096,8 @@ interface JsonWebKey { interface ParentNode { readonly children: HTMLCollection; - readonly firstElementChild: Element; - readonly lastElementChild: Element; + readonly firstElementChild: Element | null; + readonly lastElementChild: Element | null; readonly childElementCount: number; } @@ -12989,6 +14128,26 @@ interface AssignedNodesOptions { flatten?: boolean; } +interface ElementDefinitionOptions { + extends: string; +} + +interface CustomElementRegistry { + define(name: string, constructor: Function, options?: ElementDefinitionOptions): void; + get(name: string): any; + whenDefined(name: string): PromiseLike; +} + +interface PromiseRejectionEvent extends Event { + readonly promise: PromiseLike; + readonly reason: any; +} + +interface PromiseRejectionEventInit extends EventInit { + promise: PromiseLike; + reason?: any; +} + declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject; interface ErrorEventHandler { @@ -13024,6 +14183,18 @@ interface DecodeSuccessCallback { interface DecodeErrorCallback { (error: DOMException): void; } +interface VoidFunction { + (): void; +} +interface RTCSessionDescriptionCallback { + (sdp: RTCSessionDescription): void; +} +interface RTCPeerConnectionErrorCallback { + (error: DOMError): void; +} +interface RTCStatsCallback { + (report: RTCStatsReport): void; +} interface FunctionStringCallback { (data: string): void; } @@ -13036,6 +14207,12 @@ interface NavigatorUserMediaErrorCallback { interface ForEachCallback { (keyId: any, status: string): void; } +interface NotificationPermissionCallback { + (permission: string): void; +} +interface IntersectionObserverCallback { + (entries: IntersectionObserverEntry[], observer: IntersectionObserver): void; +} interface HTMLElementTagNameMap { "a": HTMLAnchorElement; "applet": HTMLAppletElement; @@ -13051,6 +14228,7 @@ interface HTMLElementTagNameMap { "caption": HTMLTableCaptionElement; "col": HTMLTableColElement; "colgroup": HTMLTableColElement; + "data": HTMLDataElement; "datalist": HTMLDataListElement; "del": HTMLModElement; "dir": HTMLDirectoryElement; @@ -13091,6 +14269,7 @@ interface HTMLElementTagNameMap { "ol": HTMLOListElement; "optgroup": HTMLOptGroupElement; "option": HTMLOptionElement; + "output": HTMLOutputElement; "p": HTMLParagraphElement; "param": HTMLParamElement; "picture": HTMLPictureElement; @@ -13110,6 +14289,7 @@ interface HTMLElementTagNameMap { "tfoot": HTMLTableSectionElement; "th": HTMLTableHeaderCellElement; "thead": HTMLTableSectionElement; + "time": HTMLTimeElement; "title": HTMLTitleElement; "tr": HTMLTableRowElement; "track": HTMLTrackElement; @@ -13147,6 +14327,7 @@ interface ElementTagNameMap { "code": HTMLElement; "col": HTMLTableColElement; "colgroup": HTMLTableColElement; + "data": HTMLDataElement; "datalist": HTMLDataListElement; "dd": HTMLElement; "defs": SVGDefsElement; @@ -13240,6 +14421,7 @@ interface ElementTagNameMap { "ol": HTMLOListElement; "optgroup": HTMLOptGroupElement; "option": HTMLOptionElement; + "output": HTMLOutputElement; "p": HTMLParagraphElement; "param": HTMLParamElement; "path": SVGPathElement; @@ -13282,6 +14464,7 @@ interface ElementTagNameMap { "tfoot": HTMLTableSectionElement; "th": HTMLTableHeaderCellElement; "thead": HTMLTableSectionElement; + "time": HTMLTimeElement; "title": HTMLTitleElement; "tr": HTMLTableRowElement; "track": HTMLTrackElement; @@ -13326,6 +14509,7 @@ interface ElementListTagNameMap { "code": NodeListOf; "col": NodeListOf; "colgroup": NodeListOf; + "data": NodeListOf; "datalist": NodeListOf; "dd": NodeListOf; "defs": NodeListOf; @@ -13419,6 +14603,7 @@ interface ElementListTagNameMap { "ol": NodeListOf; "optgroup": NodeListOf; "option": NodeListOf; + "output": NodeListOf; "p": NodeListOf; "param": NodeListOf; "path": NodeListOf; @@ -13461,6 +14646,7 @@ interface ElementListTagNameMap { "tfoot": NodeListOf; "th": NodeListOf; "thead": NodeListOf; + "time": NodeListOf; "title": NodeListOf; "tr": NodeListOf; "track": NodeListOf; @@ -13481,6 +14667,7 @@ declare var Audio: {new(src?: string): HTMLAudioElement; }; declare var Image: {new(width?: number, height?: number): HTMLImageElement; }; declare var Option: {new(text?: string, value?: string, defaultSelected?: boolean, selected?: boolean): HTMLOptionElement; }; declare var applicationCache: ApplicationCache; +declare var caches: CacheStorage; declare var clientInformation: Navigator; declare var closed: boolean; declare var crypto: Crypto; @@ -13495,10 +14682,12 @@ declare var frames: Window; declare var history: History; declare var innerHeight: number; declare var innerWidth: number; +declare var isSecureContext: boolean; declare var length: number; declare var location: Location; declare var locationbar: BarProp; declare var menubar: BarProp; +declare var msContentScript: ExtensionScriptApis; declare var msCredentials: MSCredentials; declare const name: never; declare var navigator: Navigator; @@ -13612,18 +14801,21 @@ declare var scrollX: number; declare var scrollY: number; declare var scrollbars: BarProp; declare var self: Window; +declare var speechSynthesis: SpeechSynthesis; declare var status: string; declare var statusbar: BarProp; declare var styleMedia: StyleMedia; declare var toolbar: BarProp; declare var top: Window; declare var window: Window; +declare var customElements: CustomElementRegistry; declare function alert(message?: any): void; declare function blur(): void; declare function cancelAnimationFrame(handle: number): void; declare function captureEvents(): void; declare function close(): void; declare function confirm(message?: string): boolean; +declare function departFocus(navigationReason: string, origin: FocusNavigationOrigin): void; declare function focus(): void; declare function getComputedStyle(elt: Element, pseudoElt?: string): CSSStyleDeclaration; declare function getMatchedCSSRules(elt: Element, pseudoElt?: string): CSSRuleList; @@ -13643,6 +14835,7 @@ declare function resizeTo(x?: number, y?: number): void; declare function scroll(x?: number, y?: number): void; declare function scrollBy(x?: number, y?: number): void; declare function scrollTo(x?: number, y?: number): void; +declare function stop(): void; declare function webkitCancelAnimationFrame(handle: number): void; declare function webkitConvertPointFromNodeToPage(node: Node, pt: WebKitPoint): WebKitPoint; declare function webkitConvertPointFromPageToNode(node: Node, pt: WebKitPoint): WebKitPoint; @@ -13677,10 +14870,13 @@ declare var onwheel: (this: Window, ev: WheelEvent) => any; declare var indexedDB: IDBFactory; declare function atob(encodedString: string): string; declare function btoa(rawString: string): string; +declare function fetch(input: RequestInfo, init?: RequestInit): PromiseLike; declare function addEventListener(type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, useCapture?: boolean): void; declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; type AAGUID = string; type AlgorithmIdentifier = string | Algorithm; +type BodyInit = any; +type ByteString = string; type ConstrainBoolean = boolean | ConstrainBooleanParameters; type ConstrainDOMString = string | string[] | ConstrainDOMStringParameters; type ConstrainDouble = number | ConstrainDoubleRange; @@ -13700,6 +14896,7 @@ type GLsizeiptr = number; type GLubyte = number; type GLuint = number; type GLushort = number; +type HeadersInit = any; type IDBKeyPath = string; type KeyFormat = string; type KeyType = string; @@ -13707,8 +14904,10 @@ type KeyUsage = string; type MSInboundPayload = MSVideoRecvPayload | MSAudioRecvPayload; type MSLocalClientEvent = MSLocalClientEventBase | MSAudioLocalClientEvent; type MSOutboundPayload = MSVideoSendPayload | MSAudioSendPayload; -type RTCIceGatherCandidate = RTCIceCandidate | RTCIceCandidateComplete; +type RTCIceGatherCandidate = RTCIceCandidateDictionary | RTCIceCandidateComplete; type RTCTransport = RTCDtlsTransport | RTCSrtpSdesTransport; +type RequestInfo = Request | string; +type USVString = string; type payloadtype = number; type ScrollBehavior = "auto" | "instant" | "smooth"; type ScrollLogicalPosition = "start" | "center" | "end" | "nearest"; diff --git a/src/lib/webworker.generated.d.ts b/src/lib/webworker.generated.d.ts index 089d0bdc5d5..e949526641b 100644 --- a/src/lib/webworker.generated.d.ts +++ b/src/lib/webworker.generated.d.ts @@ -7,12 +7,29 @@ interface Algorithm { name: string; } +interface CacheQueryOptions { + ignoreSearch?: boolean; + ignoreMethod?: boolean; + ignoreVary?: boolean; + cacheName?: string; +} + +interface CloseEventInit extends EventInit { + wasClean?: boolean; + code?: number; + reason?: string; +} + interface EventInit { scoped?: boolean; bubbles?: boolean; cancelable?: boolean; } +interface GetNotificationOptions { + tag?: string; +} + interface IDBIndexParameters { multiEntry?: boolean; unique?: boolean; @@ -27,10 +44,101 @@ interface KeyAlgorithm { name?: string; } +interface MessageEventInit extends EventInit { + lastEventId?: string; + channel?: string; + data?: any; + origin?: string; + source?: any; + ports?: MessagePort[]; +} + +interface NotificationOptions { + dir?: string; + lang?: string; + body?: string; + tag?: string; + icon?: string; +} + +interface PushSubscriptionOptionsInit { + userVisibleOnly?: boolean; + applicationServerKey?: any; +} + +interface RequestInit { + method?: string; + headers?: any; + body?: any; + referrer?: string; + referrerPolicy?: string; + mode?: string; + credentials?: string; + cache?: string; + redirect?: string; + integrity?: string; + keepalive?: boolean; + window?: any; +} + +interface ResponseInit { + status?: number; + statusText?: string; + headers?: any; +} + +interface ClientQueryOptions { + includeUncontrolled?: boolean; + type?: string; +} + +interface ExtendableEventInit extends EventInit { +} + +interface ExtendableMessageEventInit extends ExtendableEventInit { + data?: any; + origin?: string; + lastEventId?: string; + source?: Client | ServiceWorker | MessagePort; + ports?: MessagePort[]; +} + +interface FetchEventInit extends ExtendableEventInit { + request?: Request; + clientId?: string; + isReload?: boolean; +} + +interface NotificationEventInit extends ExtendableEventInit { + notification?: Notification; + action?: string; +} + +interface PushEventInit extends ExtendableEventInit { + data?: any; +} + +interface SyncEventInit extends ExtendableEventInit { + tag?: string; + lastChance?: boolean; +} + interface EventListener { (evt: Event): void; } +interface WebKitEntriesCallback { + (evt: Event): void; +} + +interface WebKitErrorCallback { + (evt: Event): void; +} + +interface WebKitFileCallback { + (evt: Event): void; +} + interface AudioBuffer { readonly duration: number; readonly length: number; @@ -59,6 +167,34 @@ declare var Blob: { new (blobParts?: any[], options?: BlobPropertyBag): Blob; } +interface Cache { + add(request: RequestInfo): PromiseLike; + addAll(requests: RequestInfo[]): PromiseLike; + delete(request: RequestInfo, options?: CacheQueryOptions): PromiseLike; + keys(request?: RequestInfo, options?: CacheQueryOptions): any; + match(request: RequestInfo, options?: CacheQueryOptions): PromiseLike; + matchAll(request?: RequestInfo, options?: CacheQueryOptions): any; + put(request: RequestInfo, response: Response): PromiseLike; +} + +declare var Cache: { + prototype: Cache; + new(): Cache; +} + +interface CacheStorage { + delete(cacheName: string): PromiseLike; + has(cacheName: string): PromiseLike; + keys(): any; + match(request: RequestInfo, options?: CacheQueryOptions): PromiseLike; + open(cacheName: string): PromiseLike; +} + +declare var CacheStorage: { + prototype: CacheStorage; + new(): CacheStorage; +} + interface CloseEvent extends Event { readonly code: number; readonly reason: string; @@ -68,14 +204,14 @@ interface CloseEvent extends Event { declare var CloseEvent: { prototype: CloseEvent; - new(): CloseEvent; + new(typeArg: string, eventInitDict?: CloseEventInit): CloseEvent; } interface Console { assert(test?: boolean, message?: string, ...optionalParams: any[]): void; clear(): void; count(countTitle?: string): void; - debug(message?: string, ...optionalParams: any[]): void; + debug(message?: any, ...optionalParams: any[]): void; dir(value?: any, ...optionalParams: any[]): void; dirxml(value: any): void; error(message?: any, ...optionalParams: any[]): void; @@ -227,7 +363,7 @@ interface ErrorEvent extends Event { declare var ErrorEvent: { prototype: ErrorEvent; - new(): ErrorEvent; + new(type: string, errorEventInitDict?: ErrorEventInit): ErrorEvent; } interface Event { @@ -256,7 +392,7 @@ interface Event { declare var Event: { prototype: Event; - new(type: string, eventInitDict?: EventInit): Event; + new(typeArg: string, eventInitDict?: EventInit): Event; readonly AT_TARGET: number; readonly BUBBLING_PHASE: number; readonly CAPTURING_PHASE: number; @@ -301,7 +437,7 @@ interface FileReader extends EventTarget, MSBaseReader { readAsBinaryString(blob: Blob): void; readAsDataURL(blob: Blob): void; readAsText(blob: Blob, encoding?: string): void; - addEventListener(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -310,6 +446,20 @@ declare var FileReader: { new(): FileReader; } +interface Headers { + append(name: string, value: string): void; + delete(name: string): void; + forEach(callback: ForEachCallback): void; + get(name: string): string | null; + has(name: string): boolean; + set(name: string, value: string): void; +} + +declare var Headers: { + prototype: Headers; + new(init?: any): Headers; +} + interface IDBCursor { readonly direction: string; key: IDBKeyRange | IDBValidKey; @@ -345,14 +495,14 @@ declare var IDBCursorWithValue: { interface IDBDatabaseEventMap { "abort": Event; - "error": ErrorEvent; + "error": Event; } interface IDBDatabase extends EventTarget { readonly name: string; readonly objectStoreNames: DOMStringList; onabort: (this: IDBDatabase, ev: Event) => any; - onerror: (this: IDBDatabase, ev: ErrorEvent) => any; + onerror: (this: IDBDatabase, ev: Event) => any; version: number; onversionchange: (ev: IDBVersionChangeEvent) => any; close(): void; @@ -455,13 +605,13 @@ declare var IDBOpenDBRequest: { } interface IDBRequestEventMap { - "error": ErrorEvent; + "error": Event; "success": Event; } interface IDBRequest extends EventTarget { readonly error: DOMError; - onerror: (this: IDBRequest, ev: ErrorEvent) => any; + onerror: (this: IDBRequest, ev: Event) => any; onsuccess: (this: IDBRequest, ev: Event) => any; readonly readyState: string; readonly result: any; @@ -479,7 +629,7 @@ declare var IDBRequest: { interface IDBTransactionEventMap { "abort": Event; "complete": Event; - "error": ErrorEvent; + "error": Event; } interface IDBTransaction extends EventTarget { @@ -488,7 +638,7 @@ interface IDBTransaction extends EventTarget { readonly mode: string; onabort: (this: IDBTransaction, ev: Event) => any; oncomplete: (this: IDBTransaction, ev: Event) => any; - onerror: (this: IDBTransaction, ev: ErrorEvent) => any; + onerror: (this: IDBTransaction, ev: Event) => any; abort(): void; objectStore(name: string): IDBObjectStore; readonly READ_ONLY: string; @@ -528,105 +678,6 @@ declare var ImageData: { new(array: Uint8ClampedArray, width: number, height: number): ImageData; } -interface MSApp { - clearTemporaryWebDataAsync(): MSAppAsyncOperation; - createBlobFromRandomAccessStream(type: string, seeker: any): Blob; - createDataPackage(object: any): any; - createDataPackageFromSelection(): any; - createFileFromStorageFile(storageFile: any): File; - createStreamFromInputStream(type: string, inputStream: any): MSStream; - execAsyncAtPriority(asynchronousCallback: MSExecAtPriorityFunctionCallback, priority: string, ...args: any[]): void; - execAtPriority(synchronousCallback: MSExecAtPriorityFunctionCallback, priority: string, ...args: any[]): any; - getCurrentPriority(): string; - getHtmlPrintDocumentSourceAsync(htmlDoc: any): PromiseLike; - getViewId(view: any): any; - isTaskScheduledAtPriorityOrHigher(priority: string): boolean; - pageHandlesAllApplicationActivations(enabled: boolean): void; - suppressSubdownloadCredentialPrompts(suppress: boolean): void; - terminateApp(exceptionObject: any): void; - readonly CURRENT: string; - readonly HIGH: string; - readonly IDLE: string; - readonly NORMAL: string; -} -declare var MSApp: MSApp; - -interface MSAppAsyncOperationEventMap { - "complete": Event; - "error": ErrorEvent; -} - -interface MSAppAsyncOperation extends EventTarget { - readonly error: DOMError; - oncomplete: (this: MSAppAsyncOperation, ev: Event) => any; - onerror: (this: MSAppAsyncOperation, ev: ErrorEvent) => any; - readonly readyState: number; - readonly result: any; - start(): void; - readonly COMPLETED: number; - readonly ERROR: number; - readonly STARTED: number; - addEventListener(type: K, listener: (this: MSAppAsyncOperation, ev: MSAppAsyncOperationEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; -} - -declare var MSAppAsyncOperation: { - prototype: MSAppAsyncOperation; - new(): MSAppAsyncOperation; - readonly COMPLETED: number; - readonly ERROR: number; - readonly STARTED: number; -} - -interface MSBlobBuilder { - append(data: any, endings?: string): void; - getBlob(contentType?: string): Blob; -} - -declare var MSBlobBuilder: { - prototype: MSBlobBuilder; - new(): MSBlobBuilder; -} - -interface MSStream { - readonly type: string; - msClose(): void; - msDetachStream(): any; -} - -declare var MSStream: { - prototype: MSStream; - new(): MSStream; -} - -interface MSStreamReader extends EventTarget, MSBaseReader { - readonly error: DOMError; - readAsArrayBuffer(stream: MSStream, size?: number): void; - readAsBinaryString(stream: MSStream, size?: number): void; - readAsBlob(stream: MSStream, size?: number): void; - readAsDataURL(stream: MSStream, size?: number): void; - readAsText(stream: MSStream, encoding?: string, size?: number): void; - addEventListener(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; -} - -declare var MSStreamReader: { - prototype: MSStreamReader; - new(): MSStreamReader; -} - -interface MediaQueryList { - readonly matches: boolean; - readonly media: string; - addListener(listener: MediaQueryListListener): void; - removeListener(listener: MediaQueryListListener): void; -} - -declare var MediaQueryList: { - prototype: MediaQueryList; - new(): MediaQueryList; -} - interface MessageChannel { readonly port1: MessagePort; readonly port2: MessagePort; @@ -657,7 +708,7 @@ interface MessagePortEventMap { interface MessagePort extends EventTarget { onmessage: (this: MessagePort, ev: MessageEvent) => any; close(): void; - postMessage(message?: any, ports?: any): void; + postMessage(message?: any, transfer?: any[]): void; start(): void; addEventListener(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; @@ -668,6 +719,109 @@ declare var MessagePort: { new(): MessagePort; } +interface NotificationEventMap { + "click": Event; + "close": Event; + "error": Event; + "show": Event; +} + +interface Notification extends EventTarget { + readonly body: string; + readonly dir: string; + readonly icon: string; + readonly lang: string; + onclick: (this: Notification, ev: Event) => any; + onclose: (this: Notification, ev: Event) => any; + onerror: (this: Notification, ev: Event) => any; + onshow: (this: Notification, ev: Event) => any; + readonly permission: string; + readonly tag: string; + readonly title: string; + close(): void; + addEventListener(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +} + +declare var Notification: { + prototype: Notification; + new(title: string, options?: NotificationOptions): Notification; + requestPermission(callback?: NotificationPermissionCallback): PromiseLike; +} + +interface Performance { + readonly navigation: PerformanceNavigation; + readonly timing: PerformanceTiming; + clearMarks(markName?: string): void; + clearMeasures(measureName?: string): void; + clearResourceTimings(): void; + getEntries(): any; + getEntriesByName(name: string, entryType?: string): any; + getEntriesByType(entryType: string): any; + getMarks(markName?: string): any; + getMeasures(measureName?: string): any; + mark(markName: string): void; + measure(measureName: string, startMarkName?: string, endMarkName?: string): void; + now(): number; + setResourceTimingBufferSize(maxSize: number): void; + toJSON(): any; +} + +declare var Performance: { + prototype: Performance; + new(): Performance; +} + +interface PerformanceNavigation { + readonly redirectCount: number; + readonly type: number; + toJSON(): any; + readonly TYPE_BACK_FORWARD: number; + readonly TYPE_NAVIGATE: number; + readonly TYPE_RELOAD: number; + readonly TYPE_RESERVED: number; +} + +declare var PerformanceNavigation: { + prototype: PerformanceNavigation; + new(): PerformanceNavigation; + readonly TYPE_BACK_FORWARD: number; + readonly TYPE_NAVIGATE: number; + readonly TYPE_RELOAD: number; + readonly TYPE_RESERVED: number; +} + +interface PerformanceTiming { + readonly connectEnd: number; + readonly connectStart: number; + readonly domComplete: number; + readonly domContentLoadedEventEnd: number; + readonly domContentLoadedEventStart: number; + readonly domInteractive: number; + readonly domLoading: number; + readonly domainLookupEnd: number; + readonly domainLookupStart: number; + readonly fetchStart: number; + readonly loadEventEnd: number; + readonly loadEventStart: number; + readonly msFirstPaint: number; + readonly navigationStart: number; + readonly redirectEnd: number; + readonly redirectStart: number; + readonly requestStart: number; + readonly responseEnd: number; + readonly responseStart: number; + readonly unloadEventEnd: number; + readonly unloadEventStart: number; + readonly secureConnectionStart: number; + toJSON(): any; +} + +declare var PerformanceTiming: { + prototype: PerformanceTiming; + new(): PerformanceTiming; +} + interface Position { readonly coords: Coordinates; readonly timestamp: number; @@ -707,9 +861,156 @@ declare var ProgressEvent: { new(type: string, eventInitDict?: ProgressEventInit): ProgressEvent; } +interface PushManager { + getSubscription(): PromiseLike; + permissionState(options?: PushSubscriptionOptionsInit): PromiseLike; + subscribe(options?: PushSubscriptionOptionsInit): PromiseLike; +} + +declare var PushManager: { + prototype: PushManager; + new(): PushManager; +} + +interface PushSubscription { + readonly endpoint: USVString; + readonly options: PushSubscriptionOptions; + getKey(name: string): ArrayBuffer | null; + toJSON(): any; + unsubscribe(): PromiseLike; +} + +declare var PushSubscription: { + prototype: PushSubscription; + new(): PushSubscription; +} + +interface PushSubscriptionOptions { + readonly applicationServerKey: ArrayBuffer | null; + readonly userVisibleOnly: boolean; +} + +declare var PushSubscriptionOptions: { + prototype: PushSubscriptionOptions; + new(): PushSubscriptionOptions; +} + +interface ReadableStream { + readonly locked: boolean; + cancel(): PromiseLike; + getReader(): ReadableStreamReader; +} + +declare var ReadableStream: { + prototype: ReadableStream; + new(): ReadableStream; +} + +interface ReadableStreamReader { + cancel(): PromiseLike; + read(): PromiseLike; + releaseLock(): void; +} + +declare var ReadableStreamReader: { + prototype: ReadableStreamReader; + new(): ReadableStreamReader; +} + +interface Request extends Object, Body { + readonly cache: string; + readonly credentials: string; + readonly destination: string; + readonly headers: Headers; + readonly integrity: string; + readonly keepalive: boolean; + readonly method: string; + readonly mode: string; + readonly redirect: string; + readonly referrer: string; + readonly referrerPolicy: string; + readonly type: string; + readonly url: string; + clone(): Request; +} + +declare var Request: { + prototype: Request; + new(input: Request | string, init?: RequestInit): Request; +} + +interface Response extends Object, Body { + readonly body: ReadableStream | null; + readonly headers: Headers; + readonly ok: boolean; + readonly status: number; + readonly statusText: string; + readonly type: string; + readonly url: string; + clone(): Response; +} + +declare var Response: { + prototype: Response; + new(body?: any, init?: ResponseInit): Response; +} + +interface ServiceWorkerEventMap extends AbstractWorkerEventMap { + "statechange": Event; +} + +interface ServiceWorker extends EventTarget, AbstractWorker { + onstatechange: (this: ServiceWorker, ev: Event) => any; + readonly scriptURL: USVString; + readonly state: string; + postMessage(message: any, transfer?: any[]): void; + addEventListener(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +} + +declare var ServiceWorker: { + prototype: ServiceWorker; + new(): ServiceWorker; +} + +interface ServiceWorkerRegistrationEventMap { + "updatefound": Event; +} + +interface ServiceWorkerRegistration extends EventTarget { + readonly active: ServiceWorker | null; + readonly installing: ServiceWorker | null; + onupdatefound: (this: ServiceWorkerRegistration, ev: Event) => any; + readonly pushManager: PushManager; + readonly scope: USVString; + readonly sync: SyncManager; + readonly waiting: ServiceWorker | null; + getNotifications(filter?: GetNotificationOptions): any; + showNotification(title: string, options?: NotificationOptions): PromiseLike; + unregister(): PromiseLike; + update(): PromiseLike; + addEventListener(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +} + +declare var ServiceWorkerRegistration: { + prototype: ServiceWorkerRegistration; + new(): ServiceWorkerRegistration; +} + +interface SyncManager { + getTags(): any; + register(tag: string): PromiseLike; +} + +declare var SyncManager: { + prototype: SyncManager; + new(): SyncManager; +} + interface WebSocketEventMap { "close": CloseEvent; - "error": ErrorEvent; + "error": Event; "message": MessageEvent; "open": Event; } @@ -719,7 +1020,7 @@ interface WebSocket extends EventTarget { readonly bufferedAmount: number; readonly extensions: string; onclose: (this: WebSocket, ev: CloseEvent) => any; - onerror: (this: WebSocket, ev: ErrorEvent) => any; + onerror: (this: WebSocket, ev: Event) => any; onmessage: (this: WebSocket, ev: MessageEvent) => any; onopen: (this: WebSocket, ev: Event) => any; readonly protocol: string; @@ -750,7 +1051,7 @@ interface WorkerEventMap extends AbstractWorkerEventMap { interface Worker extends EventTarget, AbstractWorker { onmessage: (this: Worker, ev: MessageEvent) => any; - postMessage(message: any, ports?: any): void; + postMessage(message: any, transfer?: any[]): void; terminate(): void; addEventListener(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; @@ -771,6 +1072,7 @@ interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget { readonly response: any; readonly responseText: string; responseType: string; + readonly responseURL: string; readonly responseXML: any; readonly status: number; readonly statusText: string; @@ -778,7 +1080,6 @@ interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget { readonly upload: XMLHttpRequestUpload; withCredentials: boolean; msCaching?: string; - readonly responseURL: string; abort(): void; getAllResponseHeaders(): string; getResponseHeader(header: string): string | null; @@ -805,11 +1106,10 @@ declare var XMLHttpRequest: { readonly LOADING: number; readonly OPENED: number; readonly UNSENT: number; - create(): XMLHttpRequest; } interface XMLHttpRequestUpload extends EventTarget, XMLHttpRequestEventTarget { - addEventListener(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -828,6 +1128,18 @@ interface AbstractWorker { addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } +interface Body { + readonly bodyUsed: boolean; + arrayBuffer(): PromiseLike; + blob(): PromiseLike; + json(): PromiseLike; + text(): PromiseLike; +} + +interface GlobalFetch { + fetch(input: RequestInfo, init?: RequestInit): PromiseLike; +} + interface MSBaseReaderEventMap { "abort": Event; "error": ErrorEvent; @@ -854,7 +1166,16 @@ interface MSBaseReader { addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } +interface NavigatorBeacon { + sendBeacon(url: USVString, data?: BodyInit): boolean; +} + +interface NavigatorConcurrentHardware { + readonly hardwareConcurrency: number; +} + interface NavigatorID { + readonly appCodeName: string; readonly appName: string; readonly appVersion: string; readonly platform: string; @@ -900,6 +1221,81 @@ interface XMLHttpRequestEventTarget { addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } +interface Client { + readonly frameType: string; + readonly id: string; + readonly url: USVString; + postMessage(message: any, transfer?: any[]): void; +} + +declare var Client: { + prototype: Client; + new(): Client; +} + +interface Clients { + claim(): PromiseLike; + get(id: string): PromiseLike; + matchAll(options?: ClientQueryOptions): any; + openWindow(url: USVString): PromiseLike; +} + +declare var Clients: { + prototype: Clients; + new(): Clients; +} + +interface DedicatedWorkerGlobalScopeEventMap extends WorkerGlobalScopeEventMap { + "message": MessageEvent; +} + +interface DedicatedWorkerGlobalScope extends WorkerGlobalScope { + onmessage: (this: DedicatedWorkerGlobalScope, ev: MessageEvent) => any; + close(): void; + postMessage(message: any, transfer?: any[]): void; + addEventListener(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +} + +declare var DedicatedWorkerGlobalScope: { + prototype: DedicatedWorkerGlobalScope; + new(): DedicatedWorkerGlobalScope; +} + +interface ExtendableEvent extends Event { + waitUntil(f: PromiseLike): void; +} + +declare var ExtendableEvent: { + prototype: ExtendableEvent; + new(type: string, eventInitDict?: ExtendableEventInit): ExtendableEvent; +} + +interface ExtendableMessageEvent extends ExtendableEvent { + readonly data: any; + readonly lastEventId: string; + readonly origin: string; + readonly ports: MessagePort[] | null; + readonly source: Client | ServiceWorker | MessagePort | null; +} + +declare var ExtendableMessageEvent: { + prototype: ExtendableMessageEvent; + new(type: string, eventInitDict?: ExtendableMessageEventInit): ExtendableMessageEvent; +} + +interface FetchEvent extends ExtendableEvent { + readonly clientId: string | null; + readonly isReload: boolean; + readonly request: Request; + respondWith(r: PromiseLike): void; +} + +declare var FetchEvent: { + prototype: FetchEvent; + new(type: string, eventInitDict: FetchEventInit): FetchEvent; +} + interface FileReaderSync { readAsArrayBuffer(blob: Blob): any; readAsBinaryString(blob: Blob): void; @@ -912,17 +1308,105 @@ declare var FileReaderSync: { new(): FileReaderSync; } -interface WorkerGlobalScopeEventMap extends DedicatedWorkerGlobalScopeEventMap { +interface NotificationEvent extends ExtendableEvent { + readonly action: string; + readonly notification: Notification; +} + +declare var NotificationEvent: { + prototype: NotificationEvent; + new(type: string, eventInitDict: NotificationEventInit): NotificationEvent; +} + +interface PushEvent extends ExtendableEvent { + readonly data: PushMessageData | null; +} + +declare var PushEvent: { + prototype: PushEvent; + new(type: string, eventInitDict?: PushEventInit): PushEvent; +} + +interface PushMessageData { + arrayBuffer(): ArrayBuffer; + blob(): Blob; + json(): JSON; + text(): USVString; +} + +declare var PushMessageData: { + prototype: PushMessageData; + new(): PushMessageData; +} + +interface ServiceWorkerGlobalScopeEventMap extends WorkerGlobalScopeEventMap { + "activate": ExtendableEvent; + "fetch": FetchEvent; + "install": ExtendableEvent; + "message": ExtendableMessageEvent; + "notificationclick": NotificationEvent; + "notificationclose": NotificationEvent; + "push": PushEvent; + "pushsubscriptionchange": ExtendableEvent; + "sync": SyncEvent; +} + +interface ServiceWorkerGlobalScope extends WorkerGlobalScope { + readonly clients: Clients; + onactivate: (this: ServiceWorkerGlobalScope, ev: ExtendableEvent) => any; + onfetch: (this: ServiceWorkerGlobalScope, ev: FetchEvent) => any; + oninstall: (this: ServiceWorkerGlobalScope, ev: ExtendableEvent) => any; + onmessage: (this: ServiceWorkerGlobalScope, ev: ExtendableMessageEvent) => any; + onnotificationclick: (this: ServiceWorkerGlobalScope, ev: NotificationEvent) => any; + onnotificationclose: (this: ServiceWorkerGlobalScope, ev: NotificationEvent) => any; + onpush: (this: ServiceWorkerGlobalScope, ev: PushEvent) => any; + onpushsubscriptionchange: (this: ServiceWorkerGlobalScope, ev: ExtendableEvent) => any; + onsync: (this: ServiceWorkerGlobalScope, ev: SyncEvent) => any; + readonly registration: ServiceWorkerRegistration; + skipWaiting(): PromiseLike; + addEventListener(type: K, listener: (this: ServiceWorkerGlobalScope, ev: ServiceWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +} + +declare var ServiceWorkerGlobalScope: { + prototype: ServiceWorkerGlobalScope; + new(): ServiceWorkerGlobalScope; +} + +interface SyncEvent extends ExtendableEvent { + readonly lastChance: boolean; + readonly tag: string; +} + +declare var SyncEvent: { + prototype: SyncEvent; + new(type: string, init: SyncEventInit): SyncEvent; +} + +interface WindowClient extends Client { + readonly focused: boolean; + readonly visibilityState: string; + focus(): PromiseLike; + navigate(url: USVString): PromiseLike; +} + +declare var WindowClient: { + prototype: WindowClient; + new(): WindowClient; +} + +interface WorkerGlobalScopeEventMap { "error": ErrorEvent; } -interface WorkerGlobalScope extends EventTarget, WorkerUtils, DedicatedWorkerGlobalScope, WindowConsole { +interface WorkerGlobalScope extends EventTarget, WorkerUtils, WindowConsole, GlobalFetch { + readonly caches: CacheStorage; + readonly isSecureContext: boolean; readonly location: WorkerLocation; onerror: (this: WorkerGlobalScope, ev: ErrorEvent) => any; + readonly performance: Performance; readonly self: WorkerGlobalScope; - close(): void; msWriteProfilerMark(profilerMarkName: string): void; - toString(): string; addEventListener(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -937,6 +1421,7 @@ interface WorkerLocation { readonly host: string; readonly hostname: string; readonly href: string; + readonly origin: string; readonly pathname: string; readonly port: string; readonly protocol: string; @@ -949,7 +1434,7 @@ declare var WorkerLocation: { new(): WorkerLocation; } -interface WorkerNavigator extends Object, NavigatorID, NavigatorOnLine { +interface WorkerNavigator extends Object, NavigatorID, NavigatorOnLine, NavigatorBeacon, NavigatorConcurrentHardware { readonly hardwareConcurrency: number; } @@ -958,17 +1443,6 @@ declare var WorkerNavigator: { new(): WorkerNavigator; } -interface DedicatedWorkerGlobalScopeEventMap { - "message": MessageEvent; -} - -interface DedicatedWorkerGlobalScope { - onmessage: (this: DedicatedWorkerGlobalScope, ev: MessageEvent) => any; - postMessage(data: any): void; - addEventListener(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; -} - interface WorkerUtils extends Object, WindowBase64 { readonly indexedDB: IDBFactory; readonly msIndexedDB: IDBFactory; @@ -985,6 +1459,14 @@ interface WorkerUtils extends Object, WindowBase64 { setTimeout(handler: any, timeout?: any, ...args: any[]): number; } +interface ErrorEventInit { + message?: string; + filename?: string; + lineno?: number; + conlno?: number; + error?: any; +} + interface BlobPropertyBag { type?: string; endings?: string; @@ -999,15 +1481,6 @@ interface EventListenerObject { handleEvent(evt: Event): void; } -interface MessageEventInit extends EventInit { - data?: any; - origin?: string; - lastEventId?: string; - channel?: string; - source?: any; - ports?: MessagePort[]; -} - interface ProgressEventInit extends EventInit { lengthComputable?: boolean; loaded?: number; @@ -1199,18 +1672,6 @@ interface PositionCallback { interface PositionErrorCallback { (error: PositionError): void; } -interface MediaQueryListListener { - (mql: MediaQueryList): void; -} -interface MSLaunchUriCallback { - (): void; -} -interface MSUnsafeFunctionCallback { - (): any; -} -interface MSExecAtPriorityFunctionCallback { - (...args: any[]): any; -} interface DecodeSuccessCallback { (decodedData: AudioBuffer): void; } @@ -1220,12 +1681,22 @@ interface DecodeErrorCallback { interface FunctionStringCallback { (data: string): void; } -declare var location: WorkerLocation; -declare var onerror: (this: WorkerGlobalScope, ev: ErrorEvent) => any; -declare var self: WorkerGlobalScope; +interface ForEachCallback { + (keyId: any, status: string): void; +} +interface NotificationPermissionCallback { + (permission: string): void; +} +declare var onmessage: (this: DedicatedWorkerGlobalScope, ev: MessageEvent) => any; declare function close(): void; +declare function postMessage(message: any, transfer?: any[]): void; +declare var caches: CacheStorage; +declare var isSecureContext: boolean; +declare var location: WorkerLocation; +declare var onerror: (this: DedicatedWorkerGlobalScope, ev: ErrorEvent) => any; +declare var performance: Performance; +declare var self: WorkerGlobalScope; declare function msWriteProfilerMark(profilerMarkName: string): void; -declare function toString(): string; declare function dispatchEvent(evt: Event): boolean; declare function removeEventListener(type: string, listener?: EventListenerOrEventListenerObject, useCapture?: boolean): void; declare var indexedDB: IDBFactory; @@ -1243,12 +1714,16 @@ declare function setTimeout(handler: (...args: any[]) => void, timeout: number): declare function setTimeout(handler: any, timeout?: any, ...args: any[]): number; declare function atob(encodedString: string): string; declare function btoa(rawString: string): string; -declare var onmessage: (this: WorkerGlobalScope, ev: MessageEvent) => any; -declare function postMessage(data: any): void; declare var console: Console; -declare function addEventListener(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void; +declare function fetch(input: RequestInfo, init?: RequestInit): PromiseLike; +declare function dispatchEvent(evt: Event): boolean; +declare function removeEventListener(type: string, listener?: EventListenerOrEventListenerObject, useCapture?: boolean): void; +declare function addEventListener(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void; declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; type AlgorithmIdentifier = string | Algorithm; +type BodyInit = any; type IDBKeyPath = string; +type RequestInfo = Request | string; +type USVString = string; type IDBValidKey = number | string | Date | IDBArrayKey; type BufferSource = ArrayBuffer | ArrayBufferView; \ No newline at end of file diff --git a/src/server/typingsInstaller/typingsInstaller.ts b/src/server/typingsInstaller/typingsInstaller.ts index 1869c542a6e..e889f98789a 100644 --- a/src/server/typingsInstaller/typingsInstaller.ts +++ b/src/server/typingsInstaller/typingsInstaller.ts @@ -295,8 +295,7 @@ namespace ts.server.typingsInstaller { this.log.writeLine(`Installing typings ${JSON.stringify(typingsToInstall)}`); } const filteredTypings = this.filterTypings(typingsToInstall); - const scopedTypings = filteredTypings.map(x => `@types/${x}`); - if (scopedTypings.length === 0) { + if (filteredTypings.length === 0) { if (this.log.isEnabled()) { this.log.writeLine(`All typings are known to be missing or invalid - no need to go any further`); } @@ -316,6 +315,7 @@ namespace ts.server.typingsInstaller { projectName: req.projectName }); + const scopedTypings = filteredTypings.map(typingsName); this.installTypingsAsync(requestId, scopedTypings, cachePath, ok => { try { if (!ok) { @@ -429,4 +429,10 @@ namespace ts.server.typingsInstaller { protected abstract installWorker(requestId: number, args: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void; protected abstract sendResponse(response: SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes): void; } + + /* @internal */ + export function typingsName(packageName: string): string { + return `@types/${packageName}@ts${versionMajorMinor}`; + } + const versionMajorMinor = version.split(".").slice(0, 2).join("."); } \ No newline at end of file diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 49b8526a1e0..1f1b499d03b 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -115,6 +115,7 @@ namespace ts.codefix { registerCodeFix({ errorCodes: [ Diagnostics.Cannot_find_name_0.code, + Diagnostics.Cannot_find_namespace_0.code, Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code ], getCodeActions: (context: CodeFixContext) => { @@ -416,8 +417,8 @@ namespace ts.codefix { ); function getModuleSpecifierForNewImport() { - const fileName = sourceFile.path; - const moduleFileName = moduleSymbol.valueDeclaration.getSourceFile().path; + const fileName = sourceFile.fileName; + const moduleFileName = moduleSymbol.valueDeclaration.getSourceFile().fileName; const sourceDirectory = getDirectoryPath(fileName); const options = context.program.getCompilerOptions(); @@ -439,8 +440,7 @@ namespace ts.codefix { return undefined; } - const normalizedBaseUrl = toPath(options.baseUrl, getDirectoryPath(options.baseUrl), getCanonicalFileName); - let relativeName = tryRemoveParentDirectoryName(moduleFileName, normalizedBaseUrl); + let relativeName = getRelativePathIfInDirectory(moduleFileName, options.baseUrl); if (!relativeName) { return undefined; } @@ -477,9 +477,8 @@ namespace ts.codefix { function tryGetModuleNameFromRootDirs() { if (options.rootDirs) { - const normalizedRootDirs = map(options.rootDirs, rootDir => toPath(rootDir, /*basePath*/ undefined, getCanonicalFileName)); - const normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, normalizedRootDirs); - const normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, normalizedRootDirs); + const normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, options.rootDirs); + const normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, options.rootDirs); if (normalizedTargetPath !== undefined) { const relativePath = normalizedSourcePath !== undefined ? getRelativePath(normalizedTargetPath, normalizedSourcePath) : normalizedTargetPath; return removeFileExtension(relativePath); @@ -546,9 +545,9 @@ namespace ts.codefix { } } - function getPathRelativeToRootDirs(path: Path, rootDirs: Path[]) { + function getPathRelativeToRootDirs(path: string, rootDirs: string[]) { for (const rootDir of rootDirs) { - const relativeName = tryRemoveParentDirectoryName(path, rootDir); + const relativeName = getRelativePathIfInDirectory(path, rootDir); if (relativeName !== undefined) { return relativeName; } @@ -564,20 +563,15 @@ namespace ts.codefix { return fileName; } + function getRelativePathIfInDirectory(path: string, directoryPath: string) { + const relativePath = getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, false); + return isRootedDiskPath(relativePath) || startsWith(relativePath, "..") ? undefined : relativePath; + } + function getRelativePath(path: string, directoryPath: string) { const relativePath = getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, false); return moduleHasNonRelativeName(relativePath) ? "./" + relativePath : relativePath; } - - function tryRemoveParentDirectoryName(path: Path, parentDirectory: Path) { - const index = path.indexOf(parentDirectory); - if (index === 0) { - return endsWith(parentDirectory, directorySeparator) - ? path.substring(parentDirectory.length) - : path.substring(parentDirectory.length + 1); - } - return undefined; - } } } diff --git a/src/services/codefixes/unusedIdentifierFixes.ts b/src/services/codefixes/unusedIdentifierFixes.ts index 2784a09a504..0ca01a81eb1 100644 --- a/src/services/codefixes/unusedIdentifierFixes.ts +++ b/src/services/codefixes/unusedIdentifierFixes.ts @@ -25,7 +25,7 @@ namespace ts.codefix { const forStatement = token.parent.parent.parent; const forInitializer = forStatement.initializer; if (forInitializer.declarations.length === 1) { - return createCodeFix("", forInitializer.pos, forInitializer.end - forInitializer.pos); + return createCodeFixToRemoveNode(forInitializer); } else { return removeSingleItem(forInitializer.declarations, token); @@ -35,7 +35,7 @@ namespace ts.codefix { const forOfStatement = token.parent.parent.parent; if (forOfStatement.initializer.kind === SyntaxKind.VariableDeclarationList) { const forOfInitializer = forOfStatement.initializer; - return createCodeFix("{}", forOfInitializer.declarations[0].pos, forOfInitializer.declarations[0].end - forOfInitializer.declarations[0].pos); + return createCodeFix("{}", forOfInitializer.declarations[0].getStart(), forOfInitializer.declarations[0].getWidth()); } break; @@ -47,12 +47,12 @@ namespace ts.codefix { case SyntaxKind.CatchClause: const catchClause = token.parent.parent; const parameter = catchClause.variableDeclaration.getChildren()[0]; - return createCodeFix("", parameter.pos, parameter.end - parameter.pos); + return createCodeFixToRemoveNode(parameter); default: const variableStatement = token.parent.parent.parent; if (variableStatement.declarationList.declarations.length === 1) { - return createCodeFix("", variableStatement.pos, variableStatement.end - variableStatement.pos); + return createCodeFixToRemoveNode(variableStatement); } else { const declarations = variableStatement.declarationList.declarations; @@ -72,7 +72,7 @@ namespace ts.codefix { case ts.SyntaxKind.Parameter: const functionDeclaration = token.parent.parent; if (functionDeclaration.parameters.length === 1) { - return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); + return createCodeFixToRemoveNode(token.parent); } else { return removeSingleItem(functionDeclaration.parameters, token); @@ -81,14 +81,14 @@ namespace ts.codefix { // handle case where 'import a = A;' case SyntaxKind.ImportEqualsDeclaration: const importEquals = findImportDeclaration(token); - return createCodeFix("", importEquals.pos, importEquals.end - importEquals.pos); + return createCodeFixToRemoveNode(importEquals); case SyntaxKind.ImportSpecifier: const namedImports = token.parent.parent; if (namedImports.elements.length === 1) { // Only 1 import and it is unused. So the entire declaration should be removed. const importSpec = findImportDeclaration(token); - return createCodeFix("", importSpec.pos, importSpec.end - importSpec.pos); + return createCodeFixToRemoveNode(importSpec); } else { return removeSingleItem(namedImports.elements, token); @@ -100,17 +100,24 @@ namespace ts.codefix { const importClause = token.parent; if (!importClause.namedBindings) { // |import d from './file'| or |import * as ns from './file'| const importDecl = findImportDeclaration(importClause); - return createCodeFix("", importDecl.pos, importDecl.end - importDecl.pos); + return createCodeFixToRemoveNode(importDecl); } - else { // import |d,| * as ns from './file' - return createCodeFix("", importClause.name.pos, importClause.namedBindings.pos - importClause.name.pos); + else { + // import |d,| * as ns from './file' + const start = importClause.name.getStart(); + let end = findFirstNonSpaceCharPosStarting(importClause.name.end); + if (sourceFile.text.charCodeAt(end) === CharacterCodes.comma) { + end = findFirstNonSpaceCharPosStarting(end + 1); + } + + return createCodeFix("", start, end - start); } case SyntaxKind.NamespaceImport: const namespaceImport = token.parent; if (namespaceImport.name == token && !(namespaceImport.parent).name) { const importDecl = findImportDeclaration(namespaceImport); - return createCodeFix("", importDecl.pos, importDecl.end - importDecl.pos); + return createCodeFixToRemoveNode(importDecl); } else { const start = (namespaceImport.parent).name.end; @@ -120,16 +127,14 @@ namespace ts.codefix { break; case SyntaxKind.PropertyDeclaration: - return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); - case SyntaxKind.NamespaceImport: - return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); + return createCodeFixToRemoveNode(token.parent); } if (isDeclarationName(token)) { - return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); + return createCodeFixToRemoveNode(token.parent); } else if (isLiteralComputedPropertyDeclarationName(token)) { - return createCodeFix("", token.parent.parent.pos, token.parent.parent.end - token.parent.parent.pos); + return createCodeFixToRemoveNode(token.parent.parent); } else { return undefined; @@ -144,6 +149,17 @@ namespace ts.codefix { return importDecl; } + function createCodeFixToRemoveNode(node: Node) { + return createCodeFix("", node.getStart(), node.getWidth()); + } + + function findFirstNonSpaceCharPosStarting(start: number) { + while (isWhiteSpace(sourceFile.text.charCodeAt(start))) { + start += 1; + } + return start; + } + function createCodeFix(newText: string, start: number, length: number): CodeAction[] { return [{ description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Remove_declaration_for_Colon_0), { 0: token.getText() }), diff --git a/src/services/completions.ts b/src/services/completions.ts index 5a08dbcb9c8..df78ab931d1 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -173,6 +173,18 @@ namespace ts.Completions { // var y = require("/*completion position*/"); return getStringLiteralCompletionEntriesFromModuleNames(node, compilerOptions, host, typeChecker); } + else if (isEqualityExpression(node.parent)) { + // Get completions from the type of the other operand + // i.e. switch (a) { + // case '/*completion position*/' + // } + return getStringLiteralCompletionEntriesFromType(typeChecker.getTypeAtLocation(node.parent.left === node ? node.parent.right : node.parent.left), typeChecker); + } + else if (isCaseOrDefaultClause(node.parent)) { + // Get completions from the type of the switch expression + // i.e. x === '/*completion position' + return getStringLiteralCompletionEntriesFromType(typeChecker.getTypeAtLocation((node.parent.parent.parent).expression), typeChecker); + } else { const argumentInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile); if (argumentInfo) { @@ -184,7 +196,7 @@ namespace ts.Completions { // Get completion for string literal from string literal type // i.e. var x: "hi" | "hello" = "/*completion position*/" - return getStringLiteralCompletionEntriesFromContextualType(node, typeChecker); + return getStringLiteralCompletionEntriesFromType(typeChecker.getContextualType(node), typeChecker); } } @@ -228,8 +240,7 @@ namespace ts.Completions { return undefined; } - function getStringLiteralCompletionEntriesFromContextualType(node: StringLiteral, typeChecker: TypeChecker): CompletionInfo | undefined { - const type = typeChecker.getContextualType(node); + function getStringLiteralCompletionEntriesFromType(type: Type, typeChecker: TypeChecker): CompletionInfo | undefined { if (type) { const entries: CompletionEntry[] = []; addStringLiteralCompletionsFromType(type, entries, typeChecker); @@ -1756,4 +1767,15 @@ namespace ts.Completions { catch (e) {} return undefined; } + + function isEqualityExpression(node: Node): node is BinaryExpression { + return isBinaryExpression(node) && isEqualityOperatorKind(node.operatorToken.kind); + } + + function isEqualityOperatorKind(kind: SyntaxKind) { + return kind == SyntaxKind.EqualsEqualsToken || + kind === SyntaxKind.ExclamationEqualsToken || + kind === SyntaxKind.EqualsEqualsEqualsToken || + kind === SyntaxKind.ExclamationEqualsEqualsToken; + } } diff --git a/src/services/transform.ts b/src/services/transform.ts new file mode 100644 index 00000000000..c9107eea853 --- /dev/null +++ b/src/services/transform.ts @@ -0,0 +1,29 @@ +/// +/// +namespace ts { + /** + * Transform one or more source files using the supplied transformers. + * @param source A `SourceFile` or an array of `SourceFiles`. + * @param transformers An array of `Transformer` callbacks used to process the transformation. + */ + export function transform(source: SourceFile | SourceFile[], transformers: Transformer[]) { + const diagnostics: Diagnostic[] = []; + const compilerOptions: CompilerOptions = {}; + const sourceFiles = isArray(source) ? source : [source]; + const fileMap = arrayToMap(sourceFiles, sourceFile => sourceFile.fileName); + const emitHost: EmitHost = { + getCompilerOptions: () => compilerOptions, + getCanonicalFileName: fileName => fileName, + getCommonSourceDirectory: () => "", + getCurrentDirectory: () => "", + getNewLine: () => "\n", + getSourceFile: fileName => fileMap.get(fileName), + getSourceFileByPath: fileName => fileMap.get(fileName), + getSourceFiles: () => sourceFiles, + isSourceFileFromExternalLibrary: () => false, + isEmitBlocked: () => false, + writeFile: () => Debug.fail("'writeFile()' is not supported during transformation.") + }; + return transformFiles(/*resolver*/ undefined, emitHost, sourceFiles, transformers); + } +} \ No newline at end of file diff --git a/tests/baselines/reference/forwardRefInClassProperties.errors.txt b/tests/baselines/reference/forwardRefInClassProperties.errors.txt new file mode 100644 index 00000000000..dcf153076ed --- /dev/null +++ b/tests/baselines/reference/forwardRefInClassProperties.errors.txt @@ -0,0 +1,27 @@ +tests/cases/compiler/forwardRefInClassProperties.ts(3,15): error TS2448: Block-scoped variable '_a' used before its declaration. +tests/cases/compiler/forwardRefInClassProperties.ts(6,22): error TS2448: Block-scoped variable '_A' used before its declaration. +tests/cases/compiler/forwardRefInClassProperties.ts(11,17): error TS2448: Block-scoped variable 'b' used before its declaration. + + +==== tests/cases/compiler/forwardRefInClassProperties.ts (3 errors) ==== + class Test + { + _b = this._a; // undefined, no error/warning + ~~ +!!! error TS2448: Block-scoped variable '_a' used before its declaration. + _a = 3; + + static _B = Test._A; // undefined, no error/warning + ~~ +!!! error TS2448: Block-scoped variable '_A' used before its declaration. + static _A = 3; + + method() + { + let a = b; // Block-scoped variable 'b' used before its declaration + ~ +!!! error TS2448: Block-scoped variable 'b' used before its declaration. + let b = 3; + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/forwardRefInClassProperties.js b/tests/baselines/reference/forwardRefInClassProperties.js new file mode 100644 index 00000000000..1dc455729ab --- /dev/null +++ b/tests/baselines/reference/forwardRefInClassProperties.js @@ -0,0 +1,31 @@ +//// [forwardRefInClassProperties.ts] +class Test +{ + _b = this._a; // undefined, no error/warning + _a = 3; + + static _B = Test._A; // undefined, no error/warning + static _A = 3; + + method() + { + let a = b; // Block-scoped variable 'b' used before its declaration + let b = 3; + } +} + + +//// [forwardRefInClassProperties.js] +var Test = (function () { + function Test() { + this._b = this._a; // undefined, no error/warning + this._a = 3; + } + Test.prototype.method = function () { + var a = b; // Block-scoped variable 'b' used before its declaration + var b = 3; + }; + return Test; +}()); +Test._B = Test._A; // undefined, no error/warning +Test._A = 3; diff --git a/tests/baselines/reference/keyofAndIndexedAccess.js b/tests/baselines/reference/keyofAndIndexedAccess.js index 62b848e97df..2b1b22d3595 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.js +++ b/tests/baselines/reference/keyofAndIndexedAccess.js @@ -526,6 +526,33 @@ class Form { this.childFormFactories[prop](value) } } + +// Repro from #13787 + +class SampleClass

{ + public props: Readonly

; + constructor(props: P) { + this.props = Object.freeze(props); + } +} + +interface Foo { + foo: string; +} + +declare function merge(obj1: T, obj2: U): T & U; + +class AnotherSampleClass extends SampleClass { + constructor(props: T) { + const foo: Foo = { foo: "bar" }; + super(merge(props, foo)); + } + + public brokenMethod() { + this.props.foo.concat; + } +} +new AnotherSampleClass({}); //// [keyofAndIndexedAccess.js] @@ -881,6 +908,27 @@ var Form = (function () { }; return Form; }()); +// Repro from #13787 +var SampleClass = (function () { + function SampleClass(props) { + this.props = Object.freeze(props); + } + return SampleClass; +}()); +var AnotherSampleClass = (function (_super) { + __extends(AnotherSampleClass, _super); + function AnotherSampleClass(props) { + var _this = this; + var foo = { foo: "bar" }; + _this = _super.call(this, merge(props, foo)) || this; + return _this; + } + AnotherSampleClass.prototype.brokenMethod = function () { + this.props.foo.concat; + }; + return AnotherSampleClass; +}(SampleClass)); +new AnotherSampleClass({}); //// [keyofAndIndexedAccess.d.ts] @@ -1127,3 +1175,15 @@ declare class Form { private childFormFactories; set(prop: K, value: T[K]): void; } +declare class SampleClass

{ + props: Readonly

; + constructor(props: P); +} +interface Foo { + foo: string; +} +declare function merge(obj1: T, obj2: U): T & U; +declare class AnotherSampleClass extends SampleClass { + constructor(props: T); + brokenMethod(): void; +} diff --git a/tests/baselines/reference/keyofAndIndexedAccess.symbols b/tests/baselines/reference/keyofAndIndexedAccess.symbols index 54fff19f428..f6425b5ed0e 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccess.symbols @@ -1880,3 +1880,86 @@ class Form { } } +// Repro from #13787 + +class SampleClass

{ +>SampleClass : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 526, 1)) +>P : Symbol(P, Decl(keyofAndIndexedAccess.ts, 530, 18)) + + public props: Readonly

; +>props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 530, 22)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>P : Symbol(P, Decl(keyofAndIndexedAccess.ts, 530, 18)) + + constructor(props: P) { +>props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 532, 16)) +>P : Symbol(P, Decl(keyofAndIndexedAccess.ts, 530, 18)) + + this.props = Object.freeze(props); +>this.props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 530, 22)) +>this : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 526, 1)) +>props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 530, 22)) +>Object.freeze : Symbol(ObjectConstructor.freeze, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>freeze : Symbol(ObjectConstructor.freeze, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 532, 16)) + } +} + +interface Foo { +>Foo : Symbol(Foo, Decl(keyofAndIndexedAccess.ts, 535, 1)) + + foo: string; +>foo : Symbol(Foo.foo, Decl(keyofAndIndexedAccess.ts, 537, 15)) +} + +declare function merge(obj1: T, obj2: U): T & U; +>merge : Symbol(merge, Decl(keyofAndIndexedAccess.ts, 539, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 541, 23)) +>U : Symbol(U, Decl(keyofAndIndexedAccess.ts, 541, 25)) +>obj1 : Symbol(obj1, Decl(keyofAndIndexedAccess.ts, 541, 29)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 541, 23)) +>obj2 : Symbol(obj2, Decl(keyofAndIndexedAccess.ts, 541, 37)) +>U : Symbol(U, Decl(keyofAndIndexedAccess.ts, 541, 25)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 541, 23)) +>U : Symbol(U, Decl(keyofAndIndexedAccess.ts, 541, 25)) + +class AnotherSampleClass extends SampleClass { +>AnotherSampleClass : Symbol(AnotherSampleClass, Decl(keyofAndIndexedAccess.ts, 541, 54)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 543, 25)) +>SampleClass : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 526, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 543, 25)) +>Foo : Symbol(Foo, Decl(keyofAndIndexedAccess.ts, 535, 1)) + + constructor(props: T) { +>props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 544, 16)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 543, 25)) + + const foo: Foo = { foo: "bar" }; +>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 545, 13)) +>Foo : Symbol(Foo, Decl(keyofAndIndexedAccess.ts, 535, 1)) +>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 545, 26)) + + super(merge(props, foo)); +>super : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 526, 1)) +>merge : Symbol(merge, Decl(keyofAndIndexedAccess.ts, 539, 1)) +>props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 544, 16)) +>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 545, 13)) + } + + public brokenMethod() { +>brokenMethod : Symbol(AnotherSampleClass.brokenMethod, Decl(keyofAndIndexedAccess.ts, 547, 5)) + + this.props.foo.concat; +>this.props.foo.concat : Symbol(String.concat, Decl(lib.d.ts, --, --)) +>this.props.foo : Symbol(foo) +>this.props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 530, 22)) +>this : Symbol(AnotherSampleClass, Decl(keyofAndIndexedAccess.ts, 541, 54)) +>props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 530, 22)) +>foo : Symbol(foo) +>concat : Symbol(String.concat, Decl(lib.d.ts, --, --)) + } +} +new AnotherSampleClass({}); +>AnotherSampleClass : Symbol(AnotherSampleClass, Decl(keyofAndIndexedAccess.ts, 541, 54)) + diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index e987ee9043b..86469efc284 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -2204,3 +2204,94 @@ class Form { } } +// Repro from #13787 + +class SampleClass

{ +>SampleClass : SampleClass

+>P : P + + public props: Readonly

; +>props : Readonly

+>Readonly : Readonly +>P : P + + constructor(props: P) { +>props : P +>P : P + + this.props = Object.freeze(props); +>this.props = Object.freeze(props) : Readonly

+>this.props : Readonly

+>this : this +>props : Readonly

+>Object.freeze(props) : Readonly

+>Object.freeze : { (a: T[]): ReadonlyArray; (f: T): T; (o: T): Readonly; } +>Object : ObjectConstructor +>freeze : { (a: T[]): ReadonlyArray; (f: T): T; (o: T): Readonly; } +>props : P + } +} + +interface Foo { +>Foo : Foo + + foo: string; +>foo : string +} + +declare function merge(obj1: T, obj2: U): T & U; +>merge : (obj1: T, obj2: U) => T & U +>T : T +>U : U +>obj1 : T +>T : T +>obj2 : U +>U : U +>T : T +>U : U + +class AnotherSampleClass extends SampleClass { +>AnotherSampleClass : AnotherSampleClass +>T : T +>SampleClass : SampleClass +>T : T +>Foo : Foo + + constructor(props: T) { +>props : T +>T : T + + const foo: Foo = { foo: "bar" }; +>foo : Foo +>Foo : Foo +>{ foo: "bar" } : { foo: string; } +>foo : string +>"bar" : "bar" + + super(merge(props, foo)); +>super(merge(props, foo)) : void +>super : typeof SampleClass +>merge(props, foo) : T & Foo +>merge : (obj1: T, obj2: U) => T & U +>props : T +>foo : Foo + } + + public brokenMethod() { +>brokenMethod : () => void + + this.props.foo.concat; +>this.props.foo.concat : (...strings: string[]) => string +>this.props.foo : (T & Foo)["foo"] +>this.props : Readonly +>this : this +>props : Readonly +>foo : (T & Foo)["foo"] +>concat : (...strings: string[]) => string + } +} +new AnotherSampleClass({}); +>new AnotherSampleClass({}) : AnotherSampleClass<{}> +>AnotherSampleClass : typeof AnotherSampleClass +>{} : {} + diff --git a/tests/baselines/reference/mixinClassesAnonymous.js b/tests/baselines/reference/mixinClassesAnonymous.js index c7b8ab5fd63..aa148c25acf 100644 --- a/tests/baselines/reference/mixinClassesAnonymous.js +++ b/tests/baselines/reference/mixinClassesAnonymous.js @@ -55,6 +55,14 @@ class Thing3 extends Thing2 { this.print(); } } + +// Repro from #13805 + +const Timestamped = >(Base: CT) => { + return class extends Base { + timestamp = new Date(); + }; +} //// [mixinClassesAnonymous.js] @@ -138,3 +146,15 @@ var Thing3 = (function (_super) { }; return Thing3; }(Thing2)); +// Repro from #13805 +var Timestamped = function (Base) { + return (function (_super) { + __extends(class_2, _super); + function class_2() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.timestamp = new Date(); + return _this; + } + return class_2; + }(Base)); +}; diff --git a/tests/baselines/reference/mixinClassesAnonymous.symbols b/tests/baselines/reference/mixinClassesAnonymous.symbols index 204d9c589fd..bd709501f31 100644 --- a/tests/baselines/reference/mixinClassesAnonymous.symbols +++ b/tests/baselines/reference/mixinClassesAnonymous.symbols @@ -167,3 +167,22 @@ class Thing3 extends Thing2 { } } +// Repro from #13805 + +const Timestamped = >(Base: CT) => { +>Timestamped : Symbol(Timestamped, Decl(mixinClassesAnonymous.ts, 59, 5)) +>CT : Symbol(CT, Decl(mixinClassesAnonymous.ts, 59, 21)) +>Constructor : Symbol(Constructor, Decl(mixinClassesAnonymous.ts, 0, 0)) +>Base : Symbol(Base, Decl(mixinClassesAnonymous.ts, 59, 53)) +>CT : Symbol(CT, Decl(mixinClassesAnonymous.ts, 59, 21)) + + return class extends Base { +>Base : Symbol(Base, Decl(mixinClassesAnonymous.ts, 59, 53)) + + timestamp = new Date(); +>timestamp : Symbol((Anonymous class).timestamp, Decl(mixinClassesAnonymous.ts, 60, 31)) +>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + }; +} + diff --git a/tests/baselines/reference/mixinClassesAnonymous.types b/tests/baselines/reference/mixinClassesAnonymous.types index 54b1c2c3819..516b15af2f3 100644 --- a/tests/baselines/reference/mixinClassesAnonymous.types +++ b/tests/baselines/reference/mixinClassesAnonymous.types @@ -198,3 +198,25 @@ class Thing3 extends Thing2 { } } +// Repro from #13805 + +const Timestamped = >(Base: CT) => { +>Timestamped : >(Base: CT) => { new (...args: any[]): (Anonymous class); prototype: .(Anonymous class); } & CT +>>(Base: CT) => { return class extends Base { timestamp = new Date(); };} : >(Base: CT) => { new (...args: any[]): (Anonymous class); prototype: .(Anonymous class); } & CT +>CT : CT +>Constructor : Constructor +>Base : CT +>CT : CT + + return class extends Base { +>class extends Base { timestamp = new Date(); } : { new (...args: any[]): (Anonymous class); prototype: .(Anonymous class); } & CT +>Base : object + + timestamp = new Date(); +>timestamp : Date +>new Date() : Date +>Date : DateConstructor + + }; +} + diff --git a/tests/baselines/reference/modularizeLibrary_Dom.iterable.types b/tests/baselines/reference/modularizeLibrary_Dom.iterable.types index d681322e2a7..f9a58d554cf 100644 --- a/tests/baselines/reference/modularizeLibrary_Dom.iterable.types +++ b/tests/baselines/reference/modularizeLibrary_Dom.iterable.types @@ -3,9 +3,9 @@ for (const element of document.getElementsByTagName("a")) { >element : HTMLAnchorElement >document.getElementsByTagName("a") : NodeListOf ->document.getElementsByTagName : { (tagname: K): ElementListTagNameMap[K]; (tagname: string): NodeListOf; } +>document.getElementsByTagName : { (tagname: K): ElementListTagNameMap[K]; (tagname: string): NodeListOf; } >document : Document ->getElementsByTagName : { (tagname: K): ElementListTagNameMap[K]; (tagname: string): NodeListOf; } +>getElementsByTagName : { (tagname: K): ElementListTagNameMap[K]; (tagname: string): NodeListOf; } >"a" : "a" element.href; diff --git a/tests/baselines/reference/nonPrimitiveAssignError.errors.txt b/tests/baselines/reference/nonPrimitiveAssignError.errors.txt index a9bfaaa4a8a..f8c4450f3aa 100644 --- a/tests/baselines/reference/nonPrimitiveAssignError.errors.txt +++ b/tests/baselines/reference/nonPrimitiveAssignError.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveAssignError.ts(5,1): error TS2322: Type 'object' is not assignable to type '{ foo: string; }'. - Property 'foo' is missing in type 'Object'. + Property 'foo' is missing in type '{}'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveAssignError.ts(13,1): error TS2322: Type 'number' is not assignable to type 'object'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveAssignError.ts(14,1): error TS2322: Type 'true' is not assignable to type 'object'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveAssignError.ts(15,1): error TS2322: Type 'string' is not assignable to type 'object'. @@ -16,7 +16,7 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveAssignError.ts(19,1): err y = a; // expect error ~ !!! error TS2322: Type 'object' is not assignable to type '{ foo: string; }'. -!!! error TS2322: Property 'foo' is missing in type 'Object'. +!!! error TS2322: Property 'foo' is missing in type '{}'. a = x; a = y; diff --git a/tests/baselines/reference/printerApi/printsBundleCorrectly.default.js b/tests/baselines/reference/printerApi/printsBundleCorrectly.default.js new file mode 100644 index 00000000000..2d86cc0c09c --- /dev/null +++ b/tests/baselines/reference/printerApi/printsBundleCorrectly.default.js @@ -0,0 +1,6 @@ +/*! [a.ts] */ +// comment0 +const a = 1; +/*! [b.ts] */ +// comment1 +const b = 2; diff --git a/tests/baselines/reference/printerApi/printsBundleCorrectly.removeComments.js b/tests/baselines/reference/printerApi/printsBundleCorrectly.removeComments.js new file mode 100644 index 00000000000..22b03719cf3 --- /dev/null +++ b/tests/baselines/reference/printerApi/printsBundleCorrectly.removeComments.js @@ -0,0 +1,4 @@ +/*! [a.ts] */ +const a = 1; +/*! [b.ts] */ +const b = 2; diff --git a/tests/baselines/reference/printerApi/printsFileCorrectly.default.js b/tests/baselines/reference/printerApi/printsFileCorrectly.default.js new file mode 100644 index 00000000000..9bff9d656b3 --- /dev/null +++ b/tests/baselines/reference/printerApi/printsFileCorrectly.default.js @@ -0,0 +1,25 @@ +interface A { + // comment1 + readonly prop?: T; + // comment2 + method(): void; + // comment3 + new (): A; + // comment4 + (): A; +} +// comment5 +type B = number | string | object; +type C = A & { + x: string; +}; // comment6 +// comment7 +enum E1 { + // comment8 + first +} +const enum E2 { + second +} +// comment9 +console.log(1 + 2); diff --git a/tests/baselines/reference/printerApi/printsFileCorrectly.removeComments.js b/tests/baselines/reference/printerApi/printsFileCorrectly.removeComments.js new file mode 100644 index 00000000000..b511aff5e78 --- /dev/null +++ b/tests/baselines/reference/printerApi/printsFileCorrectly.removeComments.js @@ -0,0 +1,17 @@ +interface A { + readonly prop?: T; + method(): void; + new (): A; + (): A; +} +type B = number | string | object; +type C = A & { + x: string; +}; +enum E1 { + first +} +const enum E2 { + second +} +console.log(1 + 2); diff --git a/tests/baselines/reference/printerApi/printsNodeCorrectly.class.js b/tests/baselines/reference/printerApi/printsNodeCorrectly.class.js new file mode 100644 index 00000000000..fa19e836fed --- /dev/null +++ b/tests/baselines/reference/printerApi/printsNodeCorrectly.class.js @@ -0,0 +1,3 @@ +class C { + public prop; +} \ No newline at end of file diff --git a/tests/cases/compiler/forwardRefInClassProperties.ts b/tests/cases/compiler/forwardRefInClassProperties.ts new file mode 100644 index 00000000000..80819b1a175 --- /dev/null +++ b/tests/cases/compiler/forwardRefInClassProperties.ts @@ -0,0 +1,14 @@ +class Test +{ + _b = this._a; // undefined, no error/warning + _a = 3; + + static _B = Test._A; // undefined, no error/warning + static _A = 3; + + method() + { + let a = b; // Block-scoped variable 'b' used before its declaration + let b = 3; + } +} diff --git a/tests/cases/conformance/classes/mixinClassesAnonymous.ts b/tests/cases/conformance/classes/mixinClassesAnonymous.ts index 24289b61e3e..0e422888087 100644 --- a/tests/cases/conformance/classes/mixinClassesAnonymous.ts +++ b/tests/cases/conformance/classes/mixinClassesAnonymous.ts @@ -54,3 +54,11 @@ class Thing3 extends Thing2 { this.print(); } } + +// Repro from #13805 + +const Timestamped = >(Base: CT) => { + return class extends Base { + timestamp = new Date(); + }; +} diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts index a8a5acd450f..70b70dff6ea 100644 --- a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts @@ -527,3 +527,30 @@ class Form { this.childFormFactories[prop](value) } } + +// Repro from #13787 + +class SampleClass

{ + public props: Readonly

; + constructor(props: P) { + this.props = Object.freeze(props); + } +} + +interface Foo { + foo: string; +} + +declare function merge(obj1: T, obj2: U): T & U; + +class AnotherSampleClass extends SampleClass { + constructor(props: T) { + const foo: Foo = { foo: "bar" }; + super(merge(props, foo)); + } + + public brokenMethod() { + this.props.foo.concat; + } +} +new AnotherSampleClass({}); diff --git a/tests/cases/fourslash/completionForStringLiteral10.ts b/tests/cases/fourslash/completionForStringLiteral10.ts new file mode 100644 index 00000000000..76a98eb732f --- /dev/null +++ b/tests/cases/fourslash/completionForStringLiteral10.ts @@ -0,0 +1,12 @@ +/// + +////type As = 'arf' | 'abacus' | 'abaddon'; +////let a: As; +////if ('/**/' != a + +goTo.marker(); +verify.completionListContains("arf"); +verify.completionListContains("abacus"); +verify.completionListContains("abaddon"); +verify.completionListCount(3); + diff --git a/tests/cases/fourslash/completionForStringLiteral11.ts b/tests/cases/fourslash/completionForStringLiteral11.ts new file mode 100644 index 00000000000..f6acac28a65 --- /dev/null +++ b/tests/cases/fourslash/completionForStringLiteral11.ts @@ -0,0 +1,14 @@ +/// + +////type As = 'arf' | 'abacus' | 'abaddon'; +////let a: As; +////switch (a) { +//// case '/**/ +////} + +goTo.marker(); +verify.completionListContains("arf"); +verify.completionListContains("abacus"); +verify.completionListContains("abaddon"); +verify.completionListCount(3); + diff --git a/tests/cases/fourslash/completionForStringLiteral8.ts b/tests/cases/fourslash/completionForStringLiteral8.ts new file mode 100644 index 00000000000..727bdf6e6a4 --- /dev/null +++ b/tests/cases/fourslash/completionForStringLiteral8.ts @@ -0,0 +1,12 @@ +/// + +////type As = 'arf' | 'abacus' | 'abaddon'; +////let a: As; +////if (a === '/**/ + +goTo.marker(); +verify.completionListContains("arf"); +verify.completionListContains("abacus"); +verify.completionListContains("abaddon"); +verify.completionListCount(3); + diff --git a/tests/cases/fourslash/goToDefinitionFoo.ts b/tests/cases/fourslash/goToDefinitionFoo.ts deleted file mode 100644 index 3e05ee20ecb..00000000000 --- a/tests/cases/fourslash/goToDefinitionFoo.ts +++ /dev/null @@ -1,6 +0,0 @@ -/// - -////function /*def*/f() {} -/////*use*/f(123); - -verify.goToDefinition("use", "def"); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportFile1.ts b/tests/cases/fourslash/importNameCodeFixNewImportFile1.ts index 0223d96e018..9f6cac0b7c1 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportFile1.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportFile1.ts @@ -3,7 +3,7 @@ //// [|/// //// f1/*0*/();|] -// @Filename: module.ts +// @Filename: Module.ts //// export function f1() {} //// export var v1 = 5; @@ -12,7 +12,7 @@ verify.importFixAtPosition([ `/// -import { f1 } from "./module"; +import { f1 } from "./Module"; f1();` ]); \ No newline at end of file diff --git a/tests/cases/fourslash/importNameCodeFixNewImportFile3.ts b/tests/cases/fourslash/importNameCodeFixNewImportFile3.ts new file mode 100644 index 00000000000..af7901e03e6 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixNewImportFile3.ts @@ -0,0 +1,15 @@ +/// + +//// [|let t: XXX/*0*/.I;|] + +// @Filename: ./module.ts +//// export module XXX { +//// export interface I { +//// } +//// } + +verify.importFixAtPosition([ +`import { XXX } from "./module"; + +let t: XXX.I;` +]); \ No newline at end of file diff --git a/tests/cases/fourslash/importNameCodeFixNewImportFile4.ts b/tests/cases/fourslash/importNameCodeFixNewImportFile4.ts new file mode 100644 index 00000000000..62cf48c4977 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixNewImportFile4.ts @@ -0,0 +1,16 @@ +/// + +//// [|let t: A/*0*/.B.I;|] + +// @Filename: ./module.ts +//// export namespace A { +//// export namespace B { +//// export interface I { } +//// } +//// } + +verify.importFixAtPosition([ +`import { A } from "./module"; + +let t: A.B.I;` +]); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedFunctionInNamespace1.ts b/tests/cases/fourslash/unusedFunctionInNamespace1.ts index 8ebf1f7072a..288573608f2 100644 --- a/tests/cases/fourslash/unusedFunctionInNamespace1.ts +++ b/tests/cases/fourslash/unusedFunctionInNamespace1.ts @@ -2,9 +2,11 @@ // @noUnusedLocals: true //// [| namespace greeter { +//// // some legit comments //// function function1() { //// }/*1*/ //// } |] verify.rangeAfterCodeFix(`namespace greeter { + // some legit comments }`); diff --git a/tests/cases/fourslash/unusedImports3FS.ts b/tests/cases/fourslash/unusedImports3FS.ts index 98dc30c4336..6926f97bb4f 100644 --- a/tests/cases/fourslash/unusedImports3FS.ts +++ b/tests/cases/fourslash/unusedImports3FS.ts @@ -2,7 +2,7 @@ // @noUnusedLocals: true // @Filename: file2.ts -////[| import {Calculator, test, test2} from "./file1" |] +////[| import {Calculator, /*some comments*/ test, test2} from "./file1" |] //// test(); //// test2(); @@ -20,5 +20,5 @@ //// //// } -verify.rangeAfterCodeFix(`import {test, test2} from "./file1"`); +verify.rangeAfterCodeFix(`import {/*some comments*/ test, test2} from "./file1"`);