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/Gulpfile.ts b/Gulpfile.ts index a981271ed9f..cc86394d460 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -50,7 +50,8 @@ const cmdLineOptions = minimist(process.argv.slice(2), { r: "reporter", color: "colors", f: "files", - file: "files" + file: "files", + w: "workers", }, default: { soft: false, @@ -63,6 +64,7 @@ const cmdLineOptions = minimist(process.argv.slice(2), { reporter: process.env.reporter || process.env.r, lint: process.env.lint || true, files: process.env.f || process.env.file || process.env.files || "", + workers: process.env.workerCount || os.cpus().length, } }); @@ -337,6 +339,7 @@ const builtGeneratedDiagnosticMessagesJSON = path.join(builtLocalDirectory, "dia // processDiagnosticMessages script gulp.task(processDiagnosticMessagesJs, false, [], () => { const settings: tsc.Settings = getCompilerSettings({ + target: "es5", declaration: false, removeComments: true, noResolve: false, @@ -612,7 +615,7 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done: } while (fs.existsSync(taskConfigsFolder)); fs.mkdirSync(taskConfigsFolder); - workerCount = process.env.workerCount || os.cpus().length; + workerCount = cmdLineOptions["workers"]; } if (tests || light || taskConfigsFolder) { @@ -1025,7 +1028,7 @@ gulp.task("lint", "Runs tslint on the compiler sources. Optional arguments are: cb(); }, (cb) => { files = files.filter(file => fileMatcher.test(file.path)).sort((filea, fileb) => filea.stat.size - fileb.stat.size); - const workerCount = (process.env.workerCount && +process.env.workerCount) || os.cpus().length; + const workerCount = cmdLineOptions["workers"]; for (let i = 0; i < workerCount; i++) { spawnLintWorker(files, finished); } diff --git a/Jakefile.js b/Jakefile.js index 1ca6f16620d..f9c9bb64819 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([ @@ -465,7 +466,7 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts options += " --stripInternal"; } - options += " --target es5 --noUnusedLocals --noUnusedParameters"; + options += " --target es5 --lib es5,scripthost --noUnusedLocals --noUnusedParameters"; var cmd = host + " " + compilerPath + " " + options + " "; cmd = cmd + sources.join(" "); @@ -735,7 +736,7 @@ compileFile( // Appending exports at the end of the server library var tsserverLibraryDefinitionFileContents = - fs.readFileSync(tsserverLibraryDefinitionFile).toString() + + fs.readFileSync(tsserverLibraryDefinitionFile).toString() + "\r\nexport = ts;" + "\r\nexport as namespace ts;"; diff --git a/scripts/processDiagnosticMessages.ts b/scripts/processDiagnosticMessages.ts index e5eaa46c8e5..db7a9e0f1f2 100644 --- a/scripts/processDiagnosticMessages.ts +++ b/scripts/processDiagnosticMessages.ts @@ -27,7 +27,7 @@ function main(): void { var inputFilePath = sys.args[0].replace(/\\/g, "/"); var inputStr = sys.readFile(inputFilePath); - + var diagnosticMessages: InputDiagnosticMessageTable = JSON.parse(inputStr); var names = Utilities.getObjectKeys(diagnosticMessages); @@ -44,7 +44,7 @@ function main(): void { function checkForUniqueCodes(messages: string[], diagnosticTable: InputDiagnosticMessageTable) { const originalMessageForCode: string[] = []; let numConflicts = 0; - + for (const currentMessage of messages) { const code = diagnosticTable[currentMessage].code; @@ -74,7 +74,7 @@ function buildUniqueNameMap(names: string[]): ts.Map { var uniqueNames = NameGenerator.ensureUniqueness(names, /* isCaseSensitive */ false, /* isFixed */ undefined); for (var i = 0; i < names.length; i++) { - nameMap[names[i]] = uniqueNames[i]; + nameMap.set(names[i], uniqueNames[i]); } return nameMap; @@ -91,7 +91,7 @@ function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable, nameMap: for (var i = 0; i < names.length; i++) { var name = names[i]; var diagnosticDetails = messageTable[name]; - var propName = convertPropertyName(nameMap[name]); + var propName = convertPropertyName(nameMap.get(name)); result += ' ' + propName + @@ -114,7 +114,7 @@ function buildDiagnosticMessageOutput(messageTable: InputDiagnosticMessageTable, for (var i = 0; i < names.length; i++) { var name = names[i]; var diagnosticDetails = messageTable[name]; - var propName = convertPropertyName(nameMap[name]); + var propName = convertPropertyName(nameMap.get(name)); result += '\r\n "' + createKey(propName, diagnosticDetails.code) + '"' + ' : "' + name.replace(/[\"]/g, '\\"') + '"'; if (i !== names.length - 1) { diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 8a9b1a507c5..df395ce57ce 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -349,17 +349,20 @@ namespace ts { // Otherwise, we'll be merging into a compatible existing symbol (for example when // you have multiple 'vars' with the same name in the same container). In this case // just add this node into the declarations list of the symbol. - symbol = symbolTable[name] || (symbolTable[name] = createSymbol(SymbolFlags.None, name)); + symbol = symbolTable.get(name); + if (!symbol) { + symbolTable.set(name, symbol = createSymbol(SymbolFlags.None, name)); + } if (name && (includes & SymbolFlags.Classifiable)) { - classifiableNames[name] = name; + classifiableNames.set(name, name); } if (symbol.flags & excludes) { if (symbol.isReplaceableByMethod) { // Javascript constructor-declared symbols can be discarded in favor of // prototype symbols like methods. - symbol = symbolTable[name] = createSymbol(SymbolFlags.None, name); + symbolTable.set(name, symbol = createSymbol(SymbolFlags.None, name)); } else { if (node.name) { @@ -1512,7 +1515,7 @@ namespace ts { errorOnFirstToken(node, Diagnostics.export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible); } if (isExternalModuleAugmentation(node)) { - declareSymbolAndAddToSymbolTable(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes); + declareModuleSymbol(node); } else { let pattern: Pattern | undefined; @@ -1534,12 +1537,8 @@ namespace ts { } } else { - const state = getModuleInstanceState(node); - if (state === ModuleInstanceState.NonInstantiated) { - declareSymbolAndAddToSymbolTable(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes); - } - else { - declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); + const state = declareModuleSymbol(node); + if (state !== ModuleInstanceState.NonInstantiated) { if (node.symbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.RegularEnum)) { // if module was already merged with some function, class or non-const enum // treat is a non-const-enum-only @@ -1560,6 +1559,15 @@ namespace ts { } } + function declareModuleSymbol(node: ModuleDeclaration): ModuleInstanceState { + const state = getModuleInstanceState(node); + const instantiated = state !== ModuleInstanceState.NonInstantiated; + declareSymbolAndAddToSymbolTable(node, + instantiated ? SymbolFlags.ValueModule : SymbolFlags.NamespaceModule, + instantiated ? SymbolFlags.ValueModuleExcludes : SymbolFlags.NamespaceModuleExcludes); + return state; + } + function bindFunctionOrConstructorType(node: SignatureDeclaration): void { // For a given function symbol "<...>(...) => T" we want to generate a symbol identical // to the one we would get for: { <...>(...): T } @@ -1573,7 +1581,7 @@ namespace ts { const typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, "__type"); addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral); typeLiteralSymbol.members = createMap(); - typeLiteralSymbol.members[symbol.name] = symbol; + typeLiteralSymbol.members.set(symbol.name, symbol); } function bindObjectLiteralExpression(node: ObjectLiteralExpression) { @@ -1604,9 +1612,9 @@ namespace ts { ? ElementKind.Property : ElementKind.Accessor; - const existingKind = seen[identifier.text]; + const existingKind = seen.get(identifier.text); if (!existingKind) { - seen[identifier.text] = currentKind; + seen.set(identifier.text, currentKind); continue; } @@ -2211,7 +2219,7 @@ namespace ts { constructorFunction.parent = classPrototype; classPrototype.parent = leftSideOfAssignment; - const funcSymbol = container.locals[constructorFunction.text]; + const funcSymbol = container.locals.get(constructorFunction.text); if (!funcSymbol || !(funcSymbol.flags & SymbolFlags.Function || isDeclarationOfFunctionExpression(funcSymbol))) { return; } @@ -2242,7 +2250,7 @@ namespace ts { bindAnonymousDeclaration(node, SymbolFlags.Class, bindingName); // Add name of class expression into the map for semantic classifier if (node.name) { - classifiableNames[node.name.text] = node.name.text; + classifiableNames.set(node.name.text, node.name.text); } } @@ -2258,14 +2266,14 @@ namespace ts { // module might have an exported variable called 'prototype'. We can't allow that as // that would clash with the built-in 'prototype' for the class. const prototypeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Prototype, "prototype"); - if (symbol.exports[prototypeSymbol.name]) { + const symbolExport = symbol.exports.get(prototypeSymbol.name); + if (symbolExport) { if (node.name) { node.name.parent = node; } - file.bindDiagnostics.push(createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0], - Diagnostics.Duplicate_identifier_0, prototypeSymbol.name)); + file.bindDiagnostics.push(createDiagnosticForNode(symbolExport.declarations[0], Diagnostics.Duplicate_identifier_0, prototypeSymbol.name)); } - symbol.exports[prototypeSymbol.name] = prototypeSymbol; + symbol.exports.set(prototypeSymbol.name, prototypeSymbol); prototypeSymbol.parent = symbol; } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1817036f25c..e96f55c22fe 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1,4 +1,4 @@ -/// +/// /// /* @internal */ @@ -84,6 +84,7 @@ namespace ts { getIndexTypeOfType, getBaseTypes, getTypeFromTypeNode, + getParameterType: getTypeAtPosition, getReturnTypeOfSignature, getNonNullableType, getSymbolsInScope, @@ -305,7 +306,7 @@ namespace ts { NullFacts = TypeofEQObject | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | TypeofNEHostObject | EQNull | EQUndefinedOrNull | NEUndefined | Falsy, } - const typeofEQFacts = createMap({ + const typeofEQFacts = createMapFromTemplate({ "string": TypeFacts.TypeofEQString, "number": TypeFacts.TypeofEQNumber, "boolean": TypeFacts.TypeofEQBoolean, @@ -315,7 +316,7 @@ namespace ts { "function": TypeFacts.TypeofEQFunction }); - const typeofNEFacts = createMap({ + const typeofNEFacts = createMapFromTemplate({ "string": TypeFacts.TypeofNEString, "number": TypeFacts.TypeofNENumber, "boolean": TypeFacts.TypeofNEBoolean, @@ -325,7 +326,7 @@ namespace ts { "function": TypeFacts.TypeofNEFunction }); - const typeofTypesByName = createMap({ + const typeofTypesByName = createMapFromTemplate({ "string": stringType, "number": numberType, "boolean": booleanType, @@ -368,7 +369,7 @@ namespace ts { } const builtinGlobals = createMap(); - builtinGlobals[undefinedSymbol.name] = undefinedSymbol; + builtinGlobals.set(undefinedSymbol.name, undefinedSymbol); initializeTypeChecker(); @@ -474,6 +475,9 @@ namespace ts { } recordMergedSymbol(target, source); } + else if (target.flags & SymbolFlags.NamespaceModule) { + error(source.valueDeclaration.name, Diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, symbolToString(target)); + } else { const message = target.flags & SymbolFlags.BlockScopedVariable || source.flags & SymbolFlags.BlockScopedVariable ? Diagnostics.Cannot_redeclare_block_scoped_variable_0 : Diagnostics.Duplicate_identifier_0; @@ -487,18 +491,19 @@ namespace ts { } function mergeSymbolTable(target: SymbolTable, source: SymbolTable) { - for (const id in source) { - let targetSymbol = target[id]; + source.forEach((sourceSymbol, id) => { + let targetSymbol = target.get(id); if (!targetSymbol) { - target[id] = source[id]; + target.set(id, sourceSymbol); } else { if (!(targetSymbol.flags & SymbolFlags.Merged)) { - target[id] = targetSymbol = cloneSymbol(targetSymbol); + targetSymbol = cloneSymbol(targetSymbol); + target.set(id, targetSymbol); } - mergeSymbol(targetSymbol, source[id]); + mergeSymbol(targetSymbol, sourceSymbol); } - } + }); } function mergeModuleAugmentation(moduleName: LiteralExpression): void { @@ -539,15 +544,16 @@ namespace ts { } function addToSymbolTable(target: SymbolTable, source: SymbolTable, message: DiagnosticMessage) { - for (const id in source) { - if (target[id]) { + source.forEach((sourceSymbol, id) => { + const targetSymbol = target.get(id); + if (targetSymbol) { // Error on redeclarations - forEach(target[id].declarations, addDeclarationDiagnostic(id, message)); + forEach(targetSymbol.declarations, addDeclarationDiagnostic(id, message)); } else { - target[id] = source[id]; + target.set(id, sourceSymbol); } - } + }); function addDeclarationDiagnostic(id: string, message: DiagnosticMessage) { return (declaration: Declaration) => diagnostics.add(createDiagnosticForNode(declaration, message, id)); @@ -575,7 +581,7 @@ namespace ts { function getSymbol(symbols: SymbolTable, name: string, meaning: SymbolFlags): Symbol { if (meaning) { - const symbol = symbols[name]; + const symbol = symbols.get(name); if (symbol) { Debug.assert((symbol.flags & SymbolFlags.Instantiated) === 0, "Should never get an instantiated symbol here."); if (symbol.flags & meaning) { @@ -783,7 +789,7 @@ namespace ts { // It's an external module. First see if the module has an export default and if the local // name of that export default matches. - if (result = moduleExports["default"]) { + if (result = moduleExports.get("default")) { const localSymbol = getLocalSymbolForExportDefault(result); if (localSymbol && (result.flags & meaning) && localSymbol.name === name) { break loop; @@ -802,9 +808,10 @@ namespace ts { // 2. We check === SymbolFlags.Alias in order to check that the symbol is *purely* // an alias. If we used &, we'd be throwing out symbols that have non alias aspects, // which is not the desired behavior. - if (moduleExports[name] && - moduleExports[name].flags === SymbolFlags.Alias && - getDeclarationOfKind(moduleExports[name], SyntaxKind.ExportSpecifier)) { + const moduleExport = moduleExports.get(name); + if (moduleExport && + moduleExport.flags === SymbolFlags.Alias && + getDeclarationOfKind(moduleExport, SyntaxKind.ExportSpecifier)) { break; } } @@ -1132,11 +1139,16 @@ namespace ts { const moduleSymbol = resolveExternalModuleName(node, (node.parent).moduleSpecifier); if (moduleSymbol) { - const exportDefaultSymbol = isShorthandAmbientModuleSymbol(moduleSymbol) ? - moduleSymbol : - moduleSymbol.exports["export="] ? - getPropertyOfType(getTypeOfSymbol(moduleSymbol.exports["export="]), "default") : - resolveSymbol(moduleSymbol.exports["default"]); + let exportDefaultSymbol: Symbol; + if (isShorthandAmbientModuleSymbol(moduleSymbol)) { + exportDefaultSymbol = moduleSymbol; + } + else { + const exportValue = moduleSymbol.exports.get("export="); + exportDefaultSymbol = exportValue + ? getPropertyOfType(getTypeOfSymbol(exportValue), "default") + : resolveSymbol(moduleSymbol.exports.get("default")); + } if (!exportDefaultSymbol && !allowSyntheticDefaultImports) { error(node.name, Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol)); @@ -1186,7 +1198,7 @@ namespace ts { function getExportOfModule(symbol: Symbol, name: string): Symbol { if (symbol.flags & SymbolFlags.Module) { - const exportedSymbol = getExportsOfSymbol(symbol)[name]; + const exportedSymbol = getExportsOfSymbol(symbol).get(name); if (exportedSymbol) { return resolveSymbol(exportedSymbol); } @@ -1214,7 +1226,7 @@ namespace ts { let symbolFromVariable: Symbol; // First check if module was specified with "export=". If so, get the member from the resolved type - if (moduleSymbol && moduleSymbol.exports && moduleSymbol.exports["export="]) { + if (moduleSymbol && moduleSymbol.exports && moduleSymbol.exports.get("export=")) { symbolFromVariable = getPropertyOfType(getTypeOfSymbol(targetSymbol), name.text); } else { @@ -1494,7 +1506,7 @@ namespace ts { // An external module with an 'export =' declaration resolves to the target of the 'export =' declaration, // and an external module with no 'export =' declaration resolves to the module itself. function resolveExternalModuleSymbol(moduleSymbol: Symbol): Symbol { - return moduleSymbol && getMergedSymbol(resolveSymbol(moduleSymbol.exports["export="])) || moduleSymbol; + return moduleSymbol && getMergedSymbol(resolveSymbol(moduleSymbol.exports.get("export="))) || moduleSymbol; } // An external module with an 'export =' declaration may be referenced as an ES6 module provided the 'export =' @@ -1510,7 +1522,7 @@ namespace ts { } function hasExportAssignmentSymbol(moduleSymbol: Symbol): boolean { - return moduleSymbol.exports["export="] !== undefined; + return moduleSymbol.exports.get("export=") !== undefined; } function getExportsOfModuleAsArray(moduleSymbol: Symbol): Symbol[] { @@ -1529,7 +1541,7 @@ namespace ts { function tryGetMemberInModuleExports(memberName: string, moduleSymbol: Symbol): Symbol | undefined { const symbolTable = getExportsOfModule(moduleSymbol); if (symbolTable) { - return symbolTable[memberName]; + return symbolTable.get(memberName); } } @@ -1552,24 +1564,28 @@ namespace ts { * Not passing `lookupTable` and `exportNode` disables this collection, and just extends the tables */ function extendExportSymbols(target: SymbolTable, source: SymbolTable, lookupTable?: Map, exportNode?: ExportDeclaration) { - for (const id in source) { - if (id !== "default" && !target[id]) { - target[id] = source[id]; + source && source.forEach((sourceSymbol, id) => { + if (id === "default") return; + + const targetSymbol = target.get(id); + if (!targetSymbol) { + target.set(id, sourceSymbol); if (lookupTable && exportNode) { - lookupTable[id] = { + lookupTable.set(id, { specifierText: getTextOfNode(exportNode.moduleSpecifier) - } as ExportCollisionTracker; + } as ExportCollisionTracker); } } - else if (lookupTable && exportNode && id !== "default" && target[id] && resolveSymbol(target[id]) !== resolveSymbol(source[id])) { - if (!lookupTable[id].exportsWithDuplicate) { - lookupTable[id].exportsWithDuplicate = [exportNode]; + else if (lookupTable && exportNode && targetSymbol && resolveSymbol(targetSymbol) !== resolveSymbol(sourceSymbol)) { + const collisionTracker = lookupTable.get(id); + if (!collisionTracker.exportsWithDuplicate) { + collisionTracker.exportsWithDuplicate = [exportNode]; } else { - lookupTable[id].exportsWithDuplicate.push(exportNode); + collisionTracker.exportsWithDuplicate.push(exportNode); } } - } + }); } function getExportsForModule(moduleSymbol: Symbol): SymbolTable { @@ -1589,7 +1605,7 @@ namespace ts { visitedSymbols.push(symbol); const symbols = cloneMap(symbol.exports); // All export * declarations are collected in an __export symbol by the binder - const exportStars = symbol.exports["__export"]; + const exportStars = symbol.exports.get("__export"); if (exportStars) { const nestedSymbols = createMap(); const lookupTable = createMap(); @@ -1603,21 +1619,20 @@ namespace ts { node as ExportDeclaration ); } - for (const id in lookupTable) { - const { exportsWithDuplicate } = lookupTable[id]; + lookupTable.forEach(({ exportsWithDuplicate }, id) => { // It's not an error if the file with multiple `export *`s with duplicate names exports a member with that name itself - if (id === "export=" || !(exportsWithDuplicate && exportsWithDuplicate.length) || symbols[id]) { - continue; + if (id === "export=" || !(exportsWithDuplicate && exportsWithDuplicate.length) || symbols.has(id)) { + return; } for (const node of exportsWithDuplicate) { diagnostics.add(createDiagnosticForNode( node, Diagnostics.Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity, - lookupTable[id].specifierText, + lookupTable.get(id).specifierText, id )); } - } + }); extendExportSymbols(symbols, nestedSymbols); } return symbols; @@ -1712,15 +1727,14 @@ namespace ts { function getNamedMembers(members: SymbolTable): Symbol[] { let result: Symbol[]; - for (const id in members) { + members.forEach((symbol, id) => { if (!isReservedMemberName(id)) { if (!result) result = []; - const symbol = members[id]; if (symbolIsValue(symbol)) { result.push(symbol); } } - } + }); return result || emptyArray; } @@ -1806,12 +1820,12 @@ namespace ts { function trySymbolTable(symbols: SymbolTable) { // If symbol is directly available by its name in the symbol table - if (isAccessible(symbols[symbol.name])) { + if (isAccessible(symbols.get(symbol.name))) { return [symbol]; } // Check if symbol is any of the alias - return forEachProperty(symbols, symbolFromSymbolTable => { + return forEachEntry(symbols, symbolFromSymbolTable => { if (symbolFromSymbolTable.flags & SymbolFlags.Alias && symbolFromSymbolTable.name !== "export=" && !getDeclarationOfKind(symbolFromSymbolTable, SyntaxKind.ExportSpecifier)) { @@ -1847,7 +1861,7 @@ namespace ts { let qualify = false; forEachSymbolTableInScope(enclosingDeclaration, symbolTable => { // If symbol of this name is not available in the symbol table we are ok - let symbolFromSymbolTable = symbolTable[symbol.name]; + let symbolFromSymbolTable = symbolTable.get(symbol.name); if (!symbolFromSymbolTable) { // Continue to the next symbol table return false; @@ -2149,24 +2163,25 @@ namespace ts { return type.flags & TypeFlags.StringLiteral ? `"${escapeString((type).text)}"` : (type).text; } - function getSymbolDisplayBuilder(): SymbolDisplayBuilder { - function getNameOfSymbol(symbol: Symbol): string { - if (symbol.declarations && symbol.declarations.length) { - const declaration = symbol.declarations[0]; - if (declaration.name) { - return declarationNameToString(declaration.name); - } - switch (declaration.kind) { - case SyntaxKind.ClassExpression: - return "(Anonymous class)"; - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - return "(Anonymous function)"; - } + function getNameOfSymbol(symbol: Symbol): string { + if (symbol.declarations && symbol.declarations.length) { + const declaration = symbol.declarations[0]; + if (declaration.name) { + return declarationNameToString(declaration.name); + } + switch (declaration.kind) { + case SyntaxKind.ClassExpression: + return "(Anonymous class)"; + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: + return "(Anonymous function)"; } - return symbol.name; } + return symbol.name; + } + + function getSymbolDisplayBuilder(): SymbolDisplayBuilder { /** * Writes only the name of the symbol out to the writer. Uses the original source text @@ -2439,7 +2454,8 @@ namespace ts { const symbol = type.symbol; if (symbol) { // Always use 'typeof T' for type of class, enum, and module objects - if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.ValueModule)) { + if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) || + symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule)) { writeTypeOfSymbol(type, flags); } else if (shouldWriteTypeOfFunctionSymbol()) { @@ -3119,14 +3135,14 @@ namespace ts { const members = createMap(); const names = createMap(); for (const name of properties) { - names[getTextOfPropertyName(name)] = true; + names.set(getTextOfPropertyName(name), true); } for (const prop of getPropertiesOfType(source)) { - const inNamesToRemove = prop.name in names; + const inNamesToRemove = names.has(prop.name); const isPrivate = getDeclarationModifierFlagsFromSymbol(prop) & (ModifierFlags.Private | ModifierFlags.Protected); const isSetOnlyAccessor = prop.flags & SymbolFlags.SetAccessor && !(prop.flags & SymbolFlags.GetAccessor); if (!inNamesToRemove && !isPrivate && !isClassMethod(prop) && !isSetOnlyAccessor) { - members[prop.name] = prop; + members.set(prop.name, prop); } } const stringIndexInfo = getIndexInfoOfType(source, IndexKind.String); @@ -3389,7 +3405,7 @@ namespace ts { const symbol = createSymbol(flags, text); symbol.type = getTypeFromBindingElement(e, includePatternInType, reportErrors); symbol.bindingElement = e; - members[symbol.name] = symbol; + members.set(symbol.name, symbol); }); const result = createAnonymousType(undefined, members, emptyArray, emptyArray, stringIndexInfo, undefined); if (includePatternInType) { @@ -3614,6 +3630,11 @@ namespace ts { return links.type; } + function getBaseTypeVariableOfClass(symbol: Symbol) { + const baseConstructorType = getBaseConstructorTypeOfClass(getDeclaredTypeOfClassOrInterface(symbol)); + return baseConstructorType.flags & TypeFlags.TypeVariable ? baseConstructorType : undefined; + } + function getTypeOfFuncClassEnumModule(symbol: Symbol): Type { const links = getSymbolLinks(symbol); if (!links.type) { @@ -3622,8 +3643,13 @@ namespace ts { } else { const type = createObjectType(ObjectFlags.Anonymous, symbol); - links.type = strictNullChecks && symbol.flags & SymbolFlags.Optional ? - includeFalsyTypes(type, TypeFlags.Undefined) : type; + if (symbol.flags & SymbolFlags.Class) { + const baseTypeVariable = getBaseTypeVariableOfClass(symbol); + links.type = baseTypeVariable ? getIntersectionType([type, baseTypeVariable]) : type; + } + else { + links.type = strictNullChecks && symbol.flags & SymbolFlags.Optional ? includeFalsyTypes(type, TypeFlags.Undefined) : type; + } } } return links.type; @@ -3717,11 +3743,16 @@ namespace ts { return getObjectFlags(type) & ObjectFlags.Reference ? (type).target : type; } - function hasBaseType(type: InterfaceType, checkBase: InterfaceType) { + function hasBaseType(type: BaseType, checkBase: BaseType) { return check(type); - function check(type: InterfaceType): boolean { - const target = getTargetType(type); - return target === checkBase || forEach(getBaseTypes(target), check); + function check(type: BaseType): boolean { + if (getObjectFlags(type) & (ObjectFlags.ClassOrInterface | ObjectFlags.Reference)) { + const target = getTargetType(type); + return target === checkBase || forEach(getBaseTypes(target), check); + } + else if (type.flags & TypeFlags.Intersection) { + return forEach((type).types, check); + } } } @@ -3789,8 +3820,26 @@ namespace ts { return concatenate(getOuterTypeParametersOfClassOrInterface(symbol), getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol)); } + // A type is a mixin constructor if it has a single construct signature taking no type parameters and a single + // rest parameter of type any[]. + function isMixinConstructorType(type: Type) { + const signatures = getSignaturesOfType(type, SignatureKind.Construct); + if (signatures.length === 1) { + const s = signatures[0]; + return !s.typeParameters && s.parameters.length === 1 && s.hasRestParameter && getTypeOfParameter(s.parameters[0]) === anyArrayType; + } + return false; + } + function isConstructorType(type: Type): boolean { - return type.flags & TypeFlags.Object && getSignaturesOfType(type, SignatureKind.Construct).length > 0; + if (isValidBaseType(type) && getSignaturesOfType(type, SignatureKind.Construct).length > 0) { + return true; + } + if (type.flags & TypeFlags.TypeVariable) { + const constraint = getBaseConstraintOfType(type); + return isValidBaseType(constraint) && isMixinConstructorType(constraint); + } + return false; } function getBaseTypeNodeOfClass(type: InterfaceType): ExpressionWithTypeArguments { @@ -3829,7 +3878,7 @@ namespace ts { return unknownType; } const baseConstructorType = checkExpression(baseTypeNode.expression); - if (baseConstructorType.flags & TypeFlags.Object) { + if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection)) { // Resolving the members of a class requires us to resolve the base class of that class. // We force resolution here such that we catch circularities now. resolveStructuredTypeMembers(baseConstructorType); @@ -3847,7 +3896,7 @@ namespace ts { return type.resolvedBaseConstructorType; } - function getBaseTypes(type: InterfaceType): ObjectType[] { + function getBaseTypes(type: InterfaceType): BaseType[] { if (!type.resolvedBaseTypes) { if (type.objectFlags & ObjectFlags.Tuple) { type.resolvedBaseTypes = [createArrayType(getUnionType(type.typeParameters))]; @@ -3869,8 +3918,8 @@ namespace ts { function resolveBaseTypesOfClass(type: InterfaceType): void { type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray; - const baseConstructorType = getBaseConstructorTypeOfClass(type); - if (!(baseConstructorType.flags & TypeFlags.Object)) { + const baseConstructorType = getApparentType(getBaseConstructorTypeOfClass(type)); + if (!(baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection))) { return; } const baseTypeNode = getBaseTypeNodeOfClass(type); @@ -3907,11 +3956,11 @@ namespace ts { if (baseType === unknownType) { return; } - if (!(getObjectFlags(getTargetType(baseType)) & ObjectFlags.ClassOrInterface)) { + if (!isValidBaseType(baseType)) { error(baseTypeNode.expression, Diagnostics.Base_constructor_return_type_0_is_not_a_class_or_interface_type, typeToString(baseType)); return; } - if (type === baseType || hasBaseType(baseType, type)) { + if (type === baseType || hasBaseType(baseType, type)) { error(valueDecl, Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType)); return; @@ -3936,6 +3985,13 @@ namespace ts { return true; } + // 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 | TypeFlags.NonPrimitive) && !isGenericMappedType(type) || + type.flags & TypeFlags.Intersection && !forEach((type).types, t => !isValidBaseType(t)); + } + function resolveBaseTypesOfInterface(type: InterfaceType): void { type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray; for (const declaration of type.symbol.declarations) { @@ -3943,8 +3999,8 @@ namespace ts { for (const node of getInterfaceBaseTypeNodes(declaration)) { const baseType = getTypeFromTypeNode(node); if (baseType !== unknownType) { - if (getObjectFlags(getTargetType(baseType)) & ObjectFlags.ClassOrInterface) { - if (type !== baseType && !hasBaseType(baseType, type)) { + if (isValidBaseType(baseType)) { + if (type !== baseType && !hasBaseType(baseType, type)) { if (type.resolvedBaseTypes === emptyArray) { type.resolvedBaseTypes = [baseType]; } @@ -4008,7 +4064,7 @@ namespace ts { type.outerTypeParameters = outerTypeParameters; type.localTypeParameters = localTypeParameters; (type).instantiations = createMap(); - (type).instantiations[getTypeListId(type.typeParameters)] = type; + (type).instantiations.set(getTypeListId(type.typeParameters), type); (type).target = type; (type).typeArguments = type.typeParameters; type.thisType = createType(TypeFlags.TypeParameter); @@ -4051,7 +4107,7 @@ namespace ts { // an instantiation of the type alias with the type parameters supplied as type arguments. links.typeParameters = typeParameters; links.instantiations = createMap(); - links.instantiations[getTypeListId(typeParameters)] = type; + links.instantiations.set(getTypeListId(typeParameters), type); } } else { @@ -4071,7 +4127,7 @@ namespace ts { return expr.kind === SyntaxKind.NumericLiteral || expr.kind === SyntaxKind.PrefixUnaryExpression && (expr).operator === SyntaxKind.MinusToken && (expr).operand.kind === SyntaxKind.NumericLiteral || - expr.kind === SyntaxKind.Identifier && !!symbol.exports[(expr).text]; + expr.kind === SyntaxKind.Identifier && !!symbol.exports.get((expr).text); } function enumHasLiteralMembers(symbol: Symbol) { @@ -4102,7 +4158,7 @@ namespace ts { enumType.symbol = symbol; if (enumHasLiteralMembers(symbol)) { const memberTypeList: Type[] = []; - const memberTypes = createMap(); + const memberTypes: EnumLiteralType[] = []; for (const declaration of enumType.symbol.declarations) { if (declaration.kind === SyntaxKind.EnumDeclaration) { computeEnumMemberValues(declaration); @@ -4120,7 +4176,7 @@ namespace ts { if (memberTypeList.length > 1) { enumType.flags |= TypeFlags.Union; (enumType).types = memberTypeList; - unionTypes[getTypeListId(memberTypeList)] = enumType; + unionTypes.set(getTypeListId(memberTypeList), enumType); } } } @@ -4157,7 +4213,6 @@ namespace ts { } function getDeclaredTypeOfSymbol(symbol: Symbol): Type { - Debug.assert((symbol.flags & SymbolFlags.Instantiated) === 0); if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { return getDeclaredTypeOfClassOrInterface(symbol); } @@ -4262,7 +4317,7 @@ namespace ts { function createSymbolTable(symbols: Symbol[]): SymbolTable { const result = createMap(); for (const symbol of symbols) { - result[symbol.name] = symbol; + result.set(symbol.name, symbol); } return result; } @@ -4272,15 +4327,15 @@ namespace ts { function createInstantiatedSymbolTable(symbols: Symbol[], mapper: TypeMapper, mappingThisOnly: boolean): SymbolTable { const result = createMap(); for (const symbol of symbols) { - result[symbol.name] = mappingThisOnly && isIndependentMember(symbol) ? symbol : instantiateSymbol(symbol, mapper); + result.set(symbol.name, mappingThisOnly && isIndependentMember(symbol) ? symbol : instantiateSymbol(symbol, mapper)); } return result; } function addInheritedMembers(symbols: SymbolTable, baseSymbols: Symbol[]) { for (const s of baseSymbols) { - if (!symbols[s.name]) { - symbols[s.name] = s; + if (!symbols.has(s.name)) { + symbols.set(s.name, s); } } } @@ -4289,8 +4344,8 @@ namespace ts { if (!(type).declaredProperties) { const symbol = type.symbol; (type).declaredProperties = getNamedMembers(symbol.members); - (type).declaredCallSignatures = getSignaturesOfSymbol(symbol.members["__call"]); - (type).declaredConstructSignatures = getSignaturesOfSymbol(symbol.members["__new"]); + (type).declaredCallSignatures = getSignaturesOfSymbol(symbol.members.get("__call")); + (type).declaredConstructSignatures = getSignaturesOfSymbol(symbol.members.get("__new")); (type).declaredStringIndexInfo = getIndexInfoOfSymbol(symbol, IndexKind.String); (type).declaredNumberIndexInfo = getIndexInfoOfSymbol(symbol, IndexKind.Number); } @@ -4299,8 +4354,14 @@ namespace ts { function getTypeWithThisArgument(type: Type, thisArgument?: Type): Type { if (getObjectFlags(type) & ObjectFlags.Reference) { - return createTypeReference((type).target, - concatenate((type).typeArguments, [thisArgument || (type).target.thisType])); + const target = (type).target; + const typeArguments = (type).typeArguments; + if (length(target.typeParameters) === length(typeArguments)) { + return createTypeReference(target, concatenate(typeArguments, [thisArgument || target.thisType])); + } + } + else if (type.flags & TypeFlags.Intersection) { + return getIntersectionType(map((type).types, t => getTypeWithThisArgument(t, thisArgument))); } return type; } @@ -4335,8 +4396,8 @@ namespace ts { } const thisArgument = lastOrUndefined(typeArguments); for (const baseType of baseTypes) { - const instantiatedBaseType = thisArgument ? getTypeWithThisArgument(instantiateType(baseType, mapper), thisArgument) : baseType; - addInheritedMembers(members, getPropertiesOfObjectType(instantiatedBaseType)); + const instantiatedBaseType = thisArgument ? getTypeWithThisArgument(instantiateType(baseType, mapper), thisArgument) : baseType; + addInheritedMembers(members, getPropertiesOfType(instantiatedBaseType)); callSignatures = concatenate(callSignatures, getSignaturesOfType(instantiatedBaseType, SignatureKind.Call)); constructSignatures = concatenate(constructSignatures, getSignaturesOfType(instantiatedBaseType, SignatureKind.Construct)); stringIndexInfo = stringIndexInfo || getIndexInfoOfType(instantiatedBaseType, IndexKind.String); @@ -4507,16 +4568,47 @@ namespace ts { getUnionType([info1.type, info2.type]), info1.isReadonly || info2.isReadonly); } + function includeMixinType(type: Type, types: Type[], index: number): Type { + const mixedTypes: Type[] = []; + for (let i = 0; i < types.length; i++) { + if (i === index) { + mixedTypes.push(type); + } + else if (isMixinConstructorType(types[i])) { + mixedTypes.push(getReturnTypeOfSignature(getSignaturesOfType(types[i], SignatureKind.Construct)[0])); + } + } + return getIntersectionType(mixedTypes); + } + function resolveIntersectionTypeMembers(type: IntersectionType) { // The members and properties collections are empty for intersection types. To get all properties of an // intersection type use getPropertiesOfType (only the language service uses this). let callSignatures: Signature[] = emptyArray; let constructSignatures: Signature[] = emptyArray; - let stringIndexInfo: IndexInfo = undefined; - let numberIndexInfo: IndexInfo = undefined; - for (const t of type.types) { + let stringIndexInfo: IndexInfo; + let numberIndexInfo: IndexInfo; + const types = type.types; + const mixinCount = countWhere(types, isMixinConstructorType); + for (let i = 0; i < types.length; i++) { + const t = type.types[i]; + // When an intersection type contains mixin constructor types, the construct signatures from + // those types are discarded and their return types are mixed into the return types of all + // other construct signatures in the intersection type. For example, the intersection type + // '{ new(...args: any[]) => A } & { new(s: string) => B }' has a single construct signature + // 'new(s: string) => A & B'. + if (mixinCount === 0 || mixinCount === types.length && i === 0 || !isMixinConstructorType(t)) { + let signatures = getSignaturesOfType(t, SignatureKind.Construct); + if (signatures.length && mixinCount > 0) { + signatures = map(signatures, s => { + const clone = cloneSignature(s); + clone.resolvedReturnType = includeMixinType(getReturnTypeOfSignature(s), types, i); + return clone; + }); + } + constructSignatures = concatenate(constructSignatures, signatures); + } callSignatures = concatenate(callSignatures, getSignaturesOfType(t, SignatureKind.Call)); - constructSignatures = concatenate(constructSignatures, getSignaturesOfType(t, SignatureKind.Construct)); stringIndexInfo = intersectIndexInfos(stringIndexInfo, getIndexInfoOfType(t, IndexKind.String)); numberIndexInfo = intersectIndexInfos(numberIndexInfo, getIndexInfoOfType(t, IndexKind.Number)); } @@ -4538,8 +4630,8 @@ namespace ts { } else if (symbol.flags & SymbolFlags.TypeLiteral) { const members = symbol.members; - const callSignatures = getSignaturesOfSymbol(members["__call"]); - const constructSignatures = getSignaturesOfSymbol(members["__new"]); + const callSignatures = getSignaturesOfSymbol(members.get("__call")); + const constructSignatures = getSignaturesOfSymbol(members.get("__new")); const stringIndexInfo = getIndexInfoOfSymbol(symbol, IndexKind.String); const numberIndexInfo = getIndexInfoOfSymbol(symbol, IndexKind.Number); setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo); @@ -4553,14 +4645,14 @@ namespace ts { } if (symbol.flags & SymbolFlags.Class) { const classType = getDeclaredTypeOfClassOrInterface(symbol); - constructSignatures = getSignaturesOfSymbol(symbol.members["__constructor"]); + constructSignatures = getSignaturesOfSymbol(symbol.members.get("__constructor")); if (!constructSignatures.length) { constructSignatures = getDefaultConstructSignatures(classType); } const baseConstructorType = getBaseConstructorTypeOfClass(classType); - if (baseConstructorType.flags & TypeFlags.Object) { + if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection | TypeFlags.TypeVariable)) { members = createSymbolTable(getNamedMembers(members)); - addInheritedMembers(members, getPropertiesOfObjectType(baseConstructorType)); + addInheritedMembers(members, getPropertiesOfType(baseConstructorType)); } } const numberIndexInfo = symbol.flags & SymbolFlags.Enum ? enumNumberIndexInfo : undefined; @@ -4586,12 +4678,14 @@ namespace ts { const typeParameter = getTypeParameterFromMappedType(type); const constraintType = getConstraintTypeFromMappedType(type); const templateType = getTemplateTypeFromMappedType(type); - const modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); + const modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T' const templateReadonly = !!type.declaration.readonlyToken; const templateOptional = !!type.declaration.questionToken; if (type.declaration.typeParameter.constraint.kind === SyntaxKind.TypeOperator) { // We have a { [P in keyof T]: X } - forEachType(getLiteralTypeFromPropertyNames(modifiersType), addMemberForKeyType); + for (const propertySymbol of getPropertiesOfType(modifiersType)) { + addMemberForKeyType(getLiteralTypeFromPropertyName(propertySymbol), propertySymbol); + } if (getIndexInfoOfType(modifiersType, IndexKind.String)) { addMemberForKeyType(stringType); } @@ -4606,7 +4700,7 @@ namespace ts { } setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, undefined); - function addMemberForKeyType(t: Type) { + function addMemberForKeyType(t: Type, propertySymbol?: Symbol) { // Create a mapper from T to the current iteration type constituent. Then, if the // mapped type is itself an instantiated type, combine the iteration mapper with the // instantiation mapper. @@ -4622,7 +4716,10 @@ namespace ts { const prop = createSymbol(SymbolFlags.Property | SymbolFlags.Transient | (isOptional ? SymbolFlags.Optional : 0), propName); prop.type = propType; prop.isReadonly = templateReadonly || modifiersProp && isReadonlySymbol(modifiersProp); - members[propName] = prop; + if (propertySymbol) { + prop.mappedTypeOrigin = propertySymbol; + } + members.set(propName, prop); } else if (t.flags & TypeFlags.String) { stringIndexInfo = createIndexInfo(propType, templateReadonly); @@ -4716,7 +4813,7 @@ namespace ts { function getPropertyOfObjectType(type: Type, name: string): Symbol { if (type.flags & TypeFlags.Object) { const resolved = resolveStructuredTypeMembers(type); - const symbol = resolved.members[name]; + const symbol = resolved.members.get(name); if (symbol && symbolIsValue(symbol)) { return symbol; } @@ -4724,29 +4821,26 @@ namespace ts { } function getPropertiesOfUnionOrIntersectionType(type: UnionOrIntersectionType): Symbol[] { - for (const current of type.types) { - for (const prop of getPropertiesOfType(current)) { - getUnionOrIntersectionProperty(type, prop.name); - } - // The properties of a union type are those that are present in all constituent types, so - // we only need to check the properties of the first type - if (type.flags & TypeFlags.Union) { - break; - } - } - const props = type.resolvedProperties; - if (props) { - const result: Symbol[] = []; - for (const key in props) { - const prop = props[key]; - // We need to filter out partial properties in union types - if (!(prop.flags & SymbolFlags.SyntheticProperty && (prop).isPartial)) { - result.push(prop); + if (!type.resolvedProperties) { + const members = createMap(); + for (const current of type.types) { + for (const prop of getPropertiesOfType(current)) { + if (!members.has(prop.name)) { + const combinedProp = getPropertyOfUnionOrIntersectionType(type, prop.name); + if (combinedProp) { + members.set(prop.name, combinedProp); + } + } + } + // The properties of a union type are those that are present in all constituent types, so + // we only need to check the properties of the first type + if (type.flags & TypeFlags.Union) { + break; } } - return result; + type.resolvedProperties = getNamedMembers(members); } - return emptyArray; + return type.resolvedProperties; } function getPropertiesOfType(type: Type): Symbol[] { @@ -4831,6 +4925,10 @@ namespace ts { } } + function getApparentTypeOfIntersectionType(type: IntersectionType) { + return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, type)); + } + /** * For a type parameter, return the base constraint of the type parameter. For the string, number, * boolean, and symbol primitive types, return the corresponding object types. Otherwise return the @@ -4838,16 +4936,18 @@ namespace ts { */ function getApparentType(type: Type): Type { const t = type.flags & TypeFlags.TypeVariable ? getBaseConstraintOfType(type) || emptyObjectType : type; - return t.flags & TypeFlags.StringLike ? globalStringType : + return t.flags & TypeFlags.Intersection ? getApparentTypeOfIntersectionType(t) : + t.flags & TypeFlags.StringLike ? globalStringType : t.flags & TypeFlags.NumberLike ? globalNumberType : t.flags & TypeFlags.BooleanLike ? globalBooleanType : t.flags & TypeFlags.ESSymbol ? getGlobalESSymbolType(/*reportErrors*/ languageVersion >= ScriptTarget.ES2015) : - t.flags & TypeFlags.NonPrimitive ? globalObjectType : + t.flags & TypeFlags.NonPrimitive ? emptyObjectType : t; } function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: string): Symbol { const types = containingType.types; + const excludeModifiers = containingType.flags & TypeFlags.Union ? ModifierFlags.Private | ModifierFlags.Protected : 0; let props: Symbol[]; // Flags we want to propagate to the result if they exist in all source symbols let commonFlags = (containingType.flags & TypeFlags.Intersection) ? SymbolFlags.Optional : SymbolFlags.None; @@ -4857,7 +4957,7 @@ namespace ts { const type = getApparentType(current); if (type !== unknownType) { const prop = getPropertyOfType(type, name); - if (prop && !(getDeclarationModifierFlagsFromSymbol(prop) & (ModifierFlags.Private | ModifierFlags.Protected))) { + if (prop && !(getDeclarationModifierFlagsFromSymbol(prop) & excludeModifiers)) { commonFlags &= prop.flags; if (!props) { props = [prop]; @@ -4914,12 +5014,12 @@ namespace ts { // these partial properties when identifying discriminant properties, but otherwise they are filtered out // and do not appear to be present in the union type. function getUnionOrIntersectionProperty(type: UnionOrIntersectionType, name: string): Symbol { - const properties = type.resolvedProperties || (type.resolvedProperties = createMap()); - let property = properties[name]; + const properties = type.propertyCache || (type.propertyCache = createMap()); + let property = properties.get(name); if (!property) { property = createUnionOrIntersectionProperty(type, name); if (property) { - properties[name] = property; + properties.set(name, property); } } return property; @@ -4943,7 +5043,7 @@ namespace ts { type = getApparentType(type); if (type.flags & TypeFlags.Object) { const resolved = resolveStructuredTypeMembers(type); - const symbol = resolved.members[name]; + const symbol = resolved.members.get(name); if (symbol && symbolIsValue(symbol)) { return symbol; } @@ -5042,11 +5142,11 @@ namespace ts { function symbolsToArray(symbols: SymbolTable): Symbol[] { const result: Symbol[] = []; - for (const id in symbols) { + symbols.forEach((symbol, id) => { if (!isReservedMemberName(id)) { - result.push(symbols[id]); + result.push(symbol); } - } + }); return result; } @@ -5312,7 +5412,11 @@ namespace ts { function getSignatureInstantiation(signature: Signature, typeArguments: Type[]): Signature { const instantiations = signature.instantiations || (signature.instantiations = createMap()); const id = getTypeListId(typeArguments); - return instantiations[id] || (instantiations[id] = createSignatureInstantiation(signature, typeArguments)); + let instantiation = instantiations.get(id); + if (!instantiation) { + instantiations.set(id, instantiation = createSignatureInstantiation(signature, typeArguments)); + } + return instantiation; } function createSignatureInstantiation(signature: Signature, typeArguments: Type[]): Signature { @@ -5346,7 +5450,7 @@ namespace ts { } function getIndexSymbol(symbol: Symbol): Symbol { - return symbol.members["__index"]; + return symbol.members.get("__index"); } function getIndexDeclarationOfSymbol(symbol: Symbol, kind: IndexKind): SignatureDeclaration { @@ -5442,9 +5546,10 @@ namespace ts { function createTypeReference(target: GenericType, typeArguments: Type[]): TypeReference { const id = getTypeListId(typeArguments); - let type = target.instantiations[id]; + let type = target.instantiations.get(id); if (!type) { - type = target.instantiations[id] = createObjectType(ObjectFlags.Reference, target.symbol); + type = createObjectType(ObjectFlags.Reference, target.symbol); + target.instantiations.set(id, type); type.flags |= typeArguments ? getPropagatingFlagsOfTypes(typeArguments, /*excludeKinds*/ 0) : 0; type.target = target; type.typeArguments = typeArguments; @@ -5491,7 +5596,11 @@ namespace ts { const links = getSymbolLinks(symbol); const typeParameters = links.typeParameters; const id = getTypeListId(typeArguments); - return links.instantiations[id] || (links.instantiations[id] = instantiateTypeNoAlias(type, createTypeMapper(typeParameters, typeArguments))); + let instantiation = links.instantiations.get(id); + if (!instantiation) { + links.instantiations.set(id, instantiation = instantiateTypeNoAlias(type, createTypeMapper(typeParameters, typeArguments))); + } + return instantiation; } // Get type from reference to type alias. When a type alias is generic, the declared type of the type alias may include @@ -5789,7 +5898,7 @@ namespace ts { type.outerTypeParameters = undefined; type.localTypeParameters = typeParameters; type.instantiations = createMap(); - type.instantiations[getTypeListId(type.typeParameters)] = type; + type.instantiations.set(getTypeListId(type.typeParameters), type); type.target = type; type.typeArguments = type.typeParameters; type.thisType = createType(TypeFlags.TypeParameter); @@ -5994,10 +6103,11 @@ namespace ts { return types[0]; } const id = getTypeListId(types); - let type = unionTypes[id]; + let type = unionTypes.get(id); if (!type) { const propagatedFlags = getPropagatingFlagsOfTypes(types, /*excludeKinds*/ TypeFlags.Nullable); - type = unionTypes[id] = createType(TypeFlags.Union | propagatedFlags); + type = createType(TypeFlags.Union | propagatedFlags); + unionTypes.set(id, type); type.types = types; type.aliasSymbol = aliasSymbol; type.aliasTypeArguments = aliasTypeArguments; @@ -6068,10 +6178,11 @@ namespace ts { /*subtypeReduction*/ false, aliasSymbol, aliasTypeArguments); } const id = getTypeListId(typeSet); - let type = intersectionTypes[id]; + let type = intersectionTypes.get(id); if (!type) { const propagatedFlags = getPropagatingFlagsOfTypes(typeSet, /*excludeKinds*/ TypeFlags.Nullable); - type = intersectionTypes[id] = createType(TypeFlags.Intersection | propagatedFlags); + type = createType(TypeFlags.Intersection | propagatedFlags); + intersectionTypes.set(id, type); type.types = typeSet; type.aliasSymbol = aliasSymbol; type.aliasTypeArguments = aliasTypeArguments; @@ -6228,7 +6339,11 @@ namespace ts { } // Otherwise we defer the operation by creating an indexed access type. const id = objectType.id + "," + indexType.id; - return indexedAccessTypes[id] || (indexedAccessTypes[id] = createIndexedAccessType(objectType, indexType)); + let type = indexedAccessTypes.get(id); + if (!type) { + indexedAccessTypes.set(id, type = createIndexedAccessType(objectType, indexType)); + } + return type; } // In the following we resolve T[K] to the type of the property in T selected by K. const apparentObjectType = getApparentType(objectType); @@ -6274,7 +6389,7 @@ namespace ts { if (!links.resolvedType) { // Deferred resolution of members is handled by resolveObjectTypeMembers const aliasSymbol = getAliasSymbolForTypeNode(node); - if (isEmpty(node.symbol.members) && !aliasSymbol) { + if (node.symbol.members.size === 0 && !aliasSymbol) { links.resolvedType = emptyTypeLiteralType; } else { @@ -6319,6 +6434,9 @@ namespace ts { if (right.flags & TypeFlags.Union) { return mapType(right, t => getSpreadType(left, t)); } + if (right.flags & TypeFlags.NonPrimitive) { + return emptyObjectType; + } const members = createMap(); const skippedPrivateMembers = createMap(); @@ -6338,20 +6456,20 @@ namespace ts { // we approximate own properties as non-methods plus methods that are inside the object literal const isSetterWithoutGetter = rightProp.flags & SymbolFlags.SetAccessor && !(rightProp.flags & SymbolFlags.GetAccessor); if (getDeclarationModifierFlagsFromSymbol(rightProp) & (ModifierFlags.Private | ModifierFlags.Protected)) { - skippedPrivateMembers[rightProp.name] = true; + skippedPrivateMembers.set(rightProp.name, true); } else if (!isClassMethod(rightProp) && !isSetterWithoutGetter) { - members[rightProp.name] = rightProp; + members.set(rightProp.name, rightProp); } } for (const leftProp of getPropertiesOfType(left)) { if (leftProp.flags & SymbolFlags.SetAccessor && !(leftProp.flags & SymbolFlags.GetAccessor) - || leftProp.name in skippedPrivateMembers + || skippedPrivateMembers.has(leftProp.name) || isClassMethod(leftProp)) { continue; } - if (leftProp.name in members) { - const rightProp = members[leftProp.name]; + if (members.has(leftProp.name)) { + const rightProp = members.get(leftProp.name); const rightType = getTypeOfSymbol(rightProp); if (maybeTypeOfKind(rightType, TypeFlags.Undefined) || rightProp.flags & SymbolFlags.Optional) { const declarations: Declaration[] = concatenate(leftProp.declarations, rightProp.declarations); @@ -6362,11 +6480,11 @@ namespace ts { result.rightSpread = rightProp; result.declarations = declarations; result.isReadonly = isReadonlySymbol(leftProp) || isReadonlySymbol(rightProp); - members[leftProp.name] = result; + members.set(leftProp.name, result); } } else { - members[leftProp.name] = leftProp; + members.set(leftProp.name, leftProp); } } return createAnonymousType(undefined, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo); @@ -6400,7 +6518,11 @@ namespace ts { function getLiteralTypeForText(flags: TypeFlags, text: string) { const map = flags & TypeFlags.StringLiteral ? stringLiteralTypes : numericLiteralTypes; - return map[text] || (map[text] = createLiteralType(flags, text)); + let type = map.get(text); + if (!type) { + map.set(text, type = createLiteralType(flags, text)); + } + return type; } function getTypeFromLiteralTypeNode(node: LiteralTypeNode): Type { @@ -6796,6 +6918,11 @@ namespace ts { } } break; + case SyntaxKind.MappedType: + if (contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode((node).typeParameter)))) { + return true; + } + break; case SyntaxKind.JSDocFunctionType: const func = node as JSDocFunctionType; for (const p of func.parameters) { @@ -6958,9 +7085,12 @@ namespace ts { result.properties = resolved.properties; result.callSignatures = emptyArray; result.constructSignatures = emptyArray; - type = result; + return result; } } + else if (type.flags & TypeFlags.Intersection) { + return getIntersectionType(map((type).types, getTypeWithoutSignatures)); + } return type; } @@ -7198,13 +7328,15 @@ namespace ts { return true; } const id = source.id + "," + target.id; - if (enumRelation[id] !== undefined) { - return enumRelation[id]; + const relation = enumRelation.get(id); + if (relation !== undefined) { + return relation; } if (source.symbol.name !== target.symbol.name || !(source.symbol.flags & SymbolFlags.RegularEnum) || !(target.symbol.flags & SymbolFlags.RegularEnum) || (source.flags & TypeFlags.Union) !== (target.flags & TypeFlags.Union)) { - return enumRelation[id] = false; + enumRelation.set(id, false); + return false; } const targetEnumType = getTypeOfSymbol(target.symbol); for (const property of getPropertiesOfType(getTypeOfSymbol(source.symbol))) { @@ -7215,11 +7347,13 @@ namespace ts { errorReporter(Diagnostics.Property_0_is_missing_in_type_1, property.name, typeToString(target, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType)); } - return enumRelation[id] = false; + enumRelation.set(id, false); + return false; } } } - return enumRelation[id] = true; + enumRelation.set(id, true); + return true; } function isSimpleTypeRelatedTo(source: Type, target: Type, relation: Map, errorReporter?: ErrorReporter) { @@ -7263,7 +7397,7 @@ namespace ts { } if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Object) { const id = relation !== identityRelation || source.id < target.id ? source.id + "," + target.id : target.id + "," + source.id; - const related = relation[id]; + const related = relation.get(id); if (related !== undefined) { return related === RelationComparisonResult.Succeeded; } @@ -7607,7 +7741,7 @@ namespace ts { function isKnownProperty(type: Type, name: string): boolean { if (type.flags & TypeFlags.Object) { const resolved = resolveStructuredTypeMembers(type); - if ((relation === assignableRelation || relation === comparableRelation) && (type === globalObjectType || isEmptyObjectType(resolved)) || + if ((relation === assignableRelation || relation === comparableRelation) && (type === globalObjectType || isEmptyResolvedType(resolved)) || resolved.stringIndexInfo || (resolved.numberIndexInfo && isNumericLiteralName(name)) || getPropertyOfType(type, name)) { @@ -7624,7 +7758,7 @@ namespace ts { return false; } - function isEmptyObjectType(t: ResolvedType) { + function isEmptyResolvedType(t: ResolvedType) { return t.properties.length === 0 && t.callSignatures.length === 0 && t.constructSignatures.length === 0 && @@ -7632,6 +7766,10 @@ namespace ts { !t.numberIndexInfo; } + function isEmptyObjectType(type: Type) { + return type.flags & TypeFlags.Object && isEmptyResolvedType(resolveStructuredTypeMembers(type)); + } + function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean { if (maybeTypeOfKind(target, TypeFlags.Object) && !(getObjectFlags(target) & ObjectFlags.ObjectLiteralPatternWithComputedProperties)) { for (const prop of getPropertiesOfObjectType(source)) { @@ -7749,12 +7887,12 @@ namespace ts { return Ternary.False; } const id = relation !== identityRelation || source.id < target.id ? source.id + "," + target.id : target.id + "," + source.id; - const related = relation[id]; + const related = relation.get(id); if (related !== undefined) { if (reportErrors && related === RelationComparisonResult.Failed) { // We are elaborating errors and the cached result is an unreported failure. Record the result as a reported // failure and continue computing the relation such that errors get reported. - relation[id] = RelationComparisonResult.FailedAndReported; + relation.set(id, RelationComparisonResult.FailedAndReported); } else { return related === RelationComparisonResult.Succeeded ? Ternary.True : Ternary.False; @@ -7763,7 +7901,7 @@ namespace ts { if (depth > 0) { for (let i = 0; i < depth; i++) { // If source and target are already being compared, consider them related with assumptions - if (maybeStack[i][id]) { + if (maybeStack[i].get(id)) { return Ternary.Maybe; } } @@ -7781,7 +7919,7 @@ namespace ts { sourceStack[depth] = source; targetStack[depth] = target; maybeStack[depth] = createMap(); - maybeStack[depth][id] = RelationComparisonResult.Succeeded; + maybeStack[depth].set(id, RelationComparisonResult.Succeeded); depth++; const saveExpandingFlags = expandingFlags; if (!(expandingFlags & 1) && isDeeplyNestedGeneric(source, sourceStack, depth)) expandingFlags |= 1; @@ -7814,12 +7952,12 @@ namespace ts { const maybeCache = maybeStack[depth]; // If result is definitely true, copy assumptions to global cache, else copy to next level up const destinationCache = (result === Ternary.True || depth === 0) ? relation : maybeStack[depth - 1]; - copyProperties(maybeCache, destinationCache); + copyEntries(maybeCache, destinationCache); } else { // A false result goes straight into global cache (when something is false under assumptions it // will also be false without assumptions) - relation[id] = reportErrors ? RelationComparisonResult.FailedAndReported : RelationComparisonResult.Failed; + relation.set(id, reportErrors ? RelationComparisonResult.FailedAndReported : RelationComparisonResult.Failed); } return result; } @@ -7845,10 +7983,14 @@ namespace ts { } } } + else if ((target).declaration.questionToken && isEmptyObjectType(source)) { + return Ternary.True; + + } } else if (relation !== identityRelation) { const resolved = resolveStructuredTypeMembers(target); - if (isEmptyObjectType(resolved) || resolved.stringIndexInfo && resolved.stringIndexInfo.type.flags & TypeFlags.Any) { + if (isEmptyResolvedType(resolved) || resolved.stringIndexInfo && resolved.stringIndexInfo.type.flags & TypeFlags.Any) { return Ternary.True; } } @@ -8490,7 +8632,7 @@ namespace ts { for (const property of getPropertiesOfObjectType(type)) { const original = getTypeOfSymbol(property); const updated = f(original); - members[property.name] = updated === original ? property : createTransientSymbol(property, updated); + members.set(property.name, updated === original ? property : createTransientSymbol(property, updated)); }; return members; } @@ -8732,7 +8874,7 @@ namespace ts { inferredProp.declarations = prop.declarations; inferredProp.type = inferredPropType; inferredProp.isReadonly = readonlyMask && isReadonlySymbol(prop); - members[prop.name] = inferredProp; + members.set(prop.name, inferredProp); } if (indexInfo) { const inferredIndexType = inferTargetType(indexInfo.type); @@ -8907,10 +9049,10 @@ namespace ts { return; } const key = source.id + "," + target.id; - if (visited[key]) { + if (visited.get(key)) { return; } - visited[key] = true; + visited.set(key, true); if (depth === 0) { sourceStack = []; targetStack = []; @@ -9291,7 +9433,7 @@ namespace ts { // check. This gives us a quicker out in the common case where an object type is not a function. const resolved = resolveStructuredTypeMembers(type); return !!(resolved.callSignatures.length || resolved.constructSignatures.length || - resolved.members["bind"] && isTypeSubtypeOf(type, globalFunctionType)); + resolved.members.get("bind") && isTypeSubtypeOf(type, globalFunctionType)); } function getTypeFacts(type: Type): TypeFacts { @@ -9914,8 +10056,9 @@ namespace ts { if (!key) { key = getFlowCacheKey(reference); } - if (cache[key]) { - return cache[key]; + const cached = cache.get(key); + if (cached) { + return cached; } // If this flow loop junction and reference are already being processed, return // the union of the types computed for each branch so far, marked as incomplete. @@ -9949,8 +10092,9 @@ namespace ts { // If we see a value appear in the cache it is a sign that control flow analysis // was restarted and completed by checkExpressionCached. We can simply pick up // the resulting type and bail out. - if (cache[key]) { - return cache[key]; + const cached = cache.get(key); + if (cached) { + return cached; } if (!contains(antecedentTypes, type)) { antecedentTypes.push(type); @@ -9974,7 +10118,8 @@ namespace ts { if (isIncomplete(firstAntecedentType)) { return createFlowType(result, /*incomplete*/ true); } - return cache[key] = result; + cache.set(key, result); + return result; } function isMatchingReferenceDiscriminant(expr: Expression) { @@ -10097,14 +10242,14 @@ namespace ts { // We narrow a non-union type to an exact primitive type if the non-union type // is a supertype of that primitive type. For example, type 'any' can be narrowed // to one of the primitive types. - const targetType = typeofTypesByName[literal.text]; + const targetType = typeofTypesByName.get(literal.text); if (targetType && isTypeSubtypeOf(targetType, type)) { return targetType; } } const facts = assumeTrue ? - typeofEQFacts[literal.text] || TypeFacts.TypeofEQHostObject : - typeofNEFacts[literal.text] || TypeFacts.TypeofNEHostObject; + typeofEQFacts.get(literal.text) || TypeFacts.TypeofEQHostObject : + typeofNEFacts.get(literal.text) || TypeFacts.TypeofNEHostObject; return getTypeWithFacts(type, facts); } @@ -11711,7 +11856,7 @@ namespace ts { member = prop; } else if (memberDecl.kind === SyntaxKind.SpreadAssignment) { - if (languageVersion < ScriptTarget.ESNext) { + if (languageVersion < ScriptTarget.ES2015) { checkExternalEmitHelpers(memberDecl, ExternalEmitHelpers.Assign); } if (propertiesArray.length > 0) { @@ -11750,7 +11895,7 @@ namespace ts { } } else { - propertiesTable[member.name] = member; + propertiesTable.set(member.name, member); } propertiesArray.push(member); } @@ -11759,12 +11904,12 @@ namespace ts { // type with those properties for which the binding pattern specifies a default value. if (contextualTypeHasPattern) { for (const prop of getPropertiesOfType(contextualType)) { - if (!propertiesTable[prop.name]) { + if (!propertiesTable.get(prop.name)) { if (!(prop.flags & SymbolFlags.Optional)) { error(prop.valueDeclaration || (prop).bindingElement, Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value); } - propertiesTable[prop.name] = prop; + propertiesTable.set(prop.name, prop); propertiesArray.push(prop); } } @@ -11805,7 +11950,7 @@ namespace ts { } function isValidSpreadType(type: Type): boolean { - return !!(type.flags & (TypeFlags.Any | TypeFlags.Null | TypeFlags.Undefined) || + return !!(type.flags & (TypeFlags.Any | TypeFlags.Null | TypeFlags.Undefined | TypeFlags.NonPrimitive) || type.flags & TypeFlags.Object && !isGenericMappedType(type) || type.flags & TypeFlags.UnionOrIntersection && !forEach((type).types, t => !isValidSpreadType(t))); } @@ -11869,6 +12014,16 @@ namespace ts { function checkJsxAttribute(node: JsxAttribute, elementAttributesType: Type, nameTable: Map) { let correspondingPropType: Type = undefined; + // We need to unconditionally get the expression type + let exprType: Type; + if (node.initializer) { + exprType = checkExpression(node.initializer); + } + else { + // is sugar for + exprType = booleanType; + } + // Look up the corresponding property for this attribute if (elementAttributesType === emptyObjectType && isUnhyphenatedJsxName(node.name.text)) { // If there is no 'props' property, you may not have non-"data-" attributes @@ -11892,20 +12047,11 @@ namespace ts { } } - let exprType: Type; - if (node.initializer) { - exprType = checkExpression(node.initializer); - } - else { - // is sugar for - exprType = booleanType; - } - if (correspondingPropType) { checkTypeAssignableTo(exprType, correspondingPropType, node); } - nameTable[node.name.text] = true; + nameTable.set(node.name.text, true); return exprType; } @@ -11918,24 +12064,25 @@ namespace ts { for (const prop of props) { // Is there a corresponding property in the element attributes type? Skip checking of properties // that have already been assigned to, as these are not actually pushed into the resulting type - if (!nameTable[prop.name]) { + if (!nameTable.get(prop.name)) { const targetPropSym = getPropertyOfType(elementAttributesType, prop.name); if (targetPropSym) { const msg = chainDiagnosticMessages(undefined, Diagnostics.Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property, prop.name); checkTypeAssignableTo(getTypeOfSymbol(prop), getTypeOfSymbol(targetPropSym), node, undefined, msg); } - nameTable[prop.name] = true; + nameTable.set(prop.name, true); } } return type; } function getJsxType(name: string) { - if (jsxTypes[name] === undefined) { - return jsxTypes[name] = getExportedTypeFromNamespace(JsxNames.JSX, name) || unknownType; + let jsxType = jsxTypes.get(name); + if (jsxType === undefined) { + jsxTypes.set(name, jsxType = getExportedTypeFromNamespace(JsxNames.JSX, name) || unknownType); } - return jsxTypes[name]; + return jsxType; } /** @@ -12268,11 +12415,9 @@ namespace ts { // was spreaded in, though, assume that it provided all required properties if (targetAttributesType && !sawSpreadedAny) { const targetProperties = getPropertiesOfType(targetAttributesType); - for (let i = 0; i < targetProperties.length; i++) { - if (!(targetProperties[i].flags & SymbolFlags.Optional) && - !nameTable[targetProperties[i].name]) { - - error(node, Diagnostics.Property_0_is_missing_in_type_1, targetProperties[i].name, typeToString(targetAttributesType)); + for (const targetProperty of targetProperties) { + if (!(targetProperty.flags & SymbolFlags.Optional) && !nameTable.get(targetProperty.name)) { + error(node, Diagnostics.Property_0_is_missing_in_type_1, targetProperty.name, typeToString(targetAttributesType)); } } } @@ -12327,12 +12472,15 @@ namespace ts { // - In a static member function or static member accessor // where this references the constructor function object of a derived class, // a super property access is permitted and must specify a public static member function of the base class. - if (languageVersion < ScriptTarget.ES2015 && getDeclarationKindFromSymbol(prop) !== SyntaxKind.MethodDeclaration) { - // `prop` refers to a *property* declared in the super class - // rather than a *method*, so it does not satisfy the above criteria. + if (languageVersion < ScriptTarget.ES2015) { + const propKind = getDeclarationKindFromSymbol(prop); + if (propKind !== SyntaxKind.MethodDeclaration && propKind !== SyntaxKind.MethodSignature) { + // `prop` refers to a *property* declared in the super class + // rather than a *method*, so it does not satisfy the above criteria. - error(errorNode, Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword); - return false; + error(errorNode, Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword); + return false; + } } if (flags & ModifierFlags.Abstract) { @@ -12400,16 +12548,18 @@ namespace ts { } function checkNonNullExpression(node: Expression | QualifiedName) { - const type = checkExpression(node); - if (strictNullChecks) { - const kind = getFalsyFlags(type) & TypeFlags.Nullable; - if (kind) { - error(node, kind & TypeFlags.Undefined ? kind & TypeFlags.Null ? - Diagnostics.Object_is_possibly_null_or_undefined : - Diagnostics.Object_is_possibly_undefined : - Diagnostics.Object_is_possibly_null); - } - return getNonNullableType(type); + return checkNonNullType(checkExpression(node), node); + } + + function checkNonNullType(type: Type, errorNode: Node): Type { + const kind = (strictNullChecks ? getFalsyFlags(type) : type.flags) & TypeFlags.Nullable; + if (kind) { + error(errorNode, kind & TypeFlags.Undefined ? kind & TypeFlags.Null ? + Diagnostics.Object_is_possibly_null_or_undefined : + Diagnostics.Object_is_possibly_undefined : + Diagnostics.Object_is_possibly_null); + const t = getNonNullableType(type); + return t.flags & (TypeFlags.Nullable | TypeFlags.Never) ? unknownType : t; } return type; } @@ -12464,6 +12614,10 @@ namespace ts { } const prop = getPropertyOfType(apparentType, right.text); if (!prop) { + const stringIndexType = getIndexTypeOfType(apparentType, IndexKind.String); + if (stringIndexType) { + return stringIndexType; + } if (right.text && !checkAndReportErrorForExtendingInterface(node)) { reportNonexistentProperty(right, type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType ? apparentType : type); } @@ -14568,6 +14722,7 @@ namespace ts { case SyntaxKind.PlusToken: case SyntaxKind.MinusToken: case SyntaxKind.TildeToken: + checkNonNullType(operandType, node.operand); if (maybeTypeOfKind(operandType, TypeFlags.ESSymbol)) { error(node.operand, Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, tokenToString(node.operator)); } @@ -14579,7 +14734,7 @@ namespace ts { booleanType; case SyntaxKind.PlusPlusToken: case SyntaxKind.MinusMinusToken: - const ok = checkArithmeticOperandType(node.operand, getNonNullableType(operandType), + const ok = checkArithmeticOperandType(node.operand, checkNonNullType(operandType, node.operand), Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type); if (ok) { // run check only if former checks succeeded to avoid reporting cascading errors @@ -14595,7 +14750,7 @@ namespace ts { if (operandType === silentNeverType) { return silentNeverType; } - const ok = checkArithmeticOperandType(node.operand, getNonNullableType(operandType), + const ok = checkArithmeticOperandType(node.operand, checkNonNullType(operandType, node.operand), Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type); if (ok) { // run check only if former checks succeeded to avoid reporting cascading errors @@ -14670,7 +14825,6 @@ namespace ts { } // NOTE: do not raise error if right is unknown as related error was already reported if (!(isTypeAny(rightType) || - rightType.flags & TypeFlags.Nullable || getSignaturesOfType(rightType, SignatureKind.Call).length || getSignaturesOfType(rightType, SignatureKind.Construct).length || isTypeSubtypeOf(rightType, globalFunctionType))) { @@ -14683,6 +14837,8 @@ namespace ts { if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; } + leftType = checkNonNullType(leftType, left); + rightType = checkNonNullType(rightType, right); // TypeScript 1.0 spec (April 2014): 4.15.5 // The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type, // and the right operand to be of type Any, an object type, or a type parameter type. @@ -14971,17 +15127,9 @@ namespace ts { if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; } - // TypeScript 1.0 spec (April 2014): 4.19.1 - // These operators require their operands to be of type Any, the Number primitive type, - // or an enum type. Operands of an enum type are treated - // as having the primitive type Number. If one operand is the null or undefined value, - // it is treated as having the type of the other operand. - // The result is always of the Number primitive type. - if (leftType.flags & TypeFlags.Nullable) leftType = rightType; - if (rightType.flags & TypeFlags.Nullable) rightType = leftType; - leftType = getNonNullableType(leftType); - rightType = getNonNullableType(rightType); + leftType = checkNonNullType(leftType, left); + rightType = checkNonNullType(rightType, right); let suggestedOperator: SyntaxKind; // if a user tries to apply a bitwise operator to 2 boolean operands @@ -15006,16 +15154,11 @@ namespace ts { if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; } - // TypeScript 1.0 spec (April 2014): 4.19.2 - // The binary + operator requires both operands to be of the Number primitive type or an enum type, - // or at least one of the operands to be of type Any or the String primitive type. - // If one operand is the null or undefined value, it is treated as having the type of the other operand. - if (leftType.flags & TypeFlags.Nullable) leftType = rightType; - if (rightType.flags & TypeFlags.Nullable) rightType = leftType; - - leftType = getNonNullableType(leftType); - rightType = getNonNullableType(rightType); + if (!isTypeOfKind(leftType, TypeFlags.Any | TypeFlags.StringLike) && !isTypeOfKind(rightType, TypeFlags.Any | TypeFlags.StringLike)) { + leftType = checkNonNullType(leftType, left); + rightType = checkNonNullType(rightType, right); + } let resultType: Type; if (isTypeOfKind(leftType, TypeFlags.NumberLike) && isTypeOfKind(rightType, TypeFlags.NumberLike)) { @@ -15054,8 +15197,8 @@ namespace ts { case SyntaxKind.LessThanEqualsToken: case SyntaxKind.GreaterThanEqualsToken: if (checkForDisallowedESSymbolOperand(operator)) { - leftType = getBaseTypeOfLiteralType(leftType); - rightType = getBaseTypeOfLiteralType(rightType); + leftType = getBaseTypeOfLiteralType(checkNonNullType(leftType, left)); + rightType = getBaseTypeOfLiteralType(checkNonNullType(rightType, right)); if (!isTypeComparableTo(leftType, rightType) && !isTypeComparableTo(rightType, leftType)) { reportOperatorError(); } @@ -15757,7 +15900,7 @@ namespace ts { } } else { - const isStatic = forEach(member.modifiers, m => m.kind === SyntaxKind.StaticKeyword); + const isStatic = getModifierFlags(member) & ModifierFlags.Static; const names = isStatic ? staticNames : instanceNames; const memberName = member.name && getPropertyNameForPropertyNameNode(member.name); @@ -15780,17 +15923,49 @@ namespace ts { } function addName(names: Map, location: Node, name: string, meaning: Accessor) { - const prev = names[name]; + const prev = names.get(name); if (prev) { if (prev & meaning) { error(location, Diagnostics.Duplicate_identifier_0, getTextOfNode(location)); } else { - names[name] = prev | meaning; + names.set(name, prev | meaning); } } else { - names[name] = meaning; + names.set(name, meaning); + } + } + } + + /** + * Static members being set on a constructor function may conflict with built-in properties + * of Function. Esp. in ECMAScript 5 there are non-configurable and non-writable + * built-in properties. This check issues a transpile error when a class has a static + * member with the same name as a non-writable built-in property. + * + * @see http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.3 + * @see http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.5 + * @see http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-function-constructor + * @see http://www.ecma-international.org/ecma-262/6.0/#sec-function-instances + */ + function checkClassForStaticPropertyNameConflicts(node: ClassLikeDeclaration) { + for (const member of node.members) { + const memberNameNode = member.name; + const isStatic = getModifierFlags(member) & ModifierFlags.Static; + if (isStatic && memberNameNode) { + const memberName = getPropertyNameForPropertyNameNode(memberNameNode); + switch (memberName) { + case "name": + case "length": + case "caller": + case "arguments": + case "prototype": + const message = Diagnostics.Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1; + const className = getNameOfSymbol(getSymbolOfNode(node)); + error(memberNameNode, message, memberName, className); + break; + } } } } @@ -15810,12 +15985,12 @@ namespace ts { continue; } - if (names[memberName]) { + if (names.get(memberName)) { error(member.symbol.valueDeclaration.name, Diagnostics.Duplicate_identifier_0, memberName); error(member.name, Diagnostics.Duplicate_identifier_0, memberName); } else { - names[memberName] = true; + names.set(memberName, true); } } } @@ -16135,14 +16310,24 @@ namespace ts { } function checkIndexedAccessIndexType(type: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode) { - if (type.flags & TypeFlags.IndexedAccess) { - // Check that the index type is assignable to 'keyof T' for the object type. - const objectType = (type).objectType; - const indexType = (type).indexType; - if (!isTypeAssignableTo(indexType, getIndexType(objectType))) { - error(accessNode, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType)); + if (!(type.flags & TypeFlags.IndexedAccess)) { + return type; + } + // Check if the index type is assignable to 'keyof T' for the object type. + const objectType = (type).objectType; + const indexType = (type).indexType; + if (isTypeAssignableTo(indexType, getIndexType(objectType))) { + return type; + } + // Check if we're indexing with a numeric type and the object type is a generic + // type with a constraint that has a numeric index signature. + if (maybeTypeOfKind(objectType, TypeFlags.TypeVariable) && isTypeOfKind(indexType, TypeFlags.NumberLike)) { + const constraint = getBaseConstraintOfType(objectType); + if (constraint && getIndexInfoOfType(constraint, IndexKind.Number)) { + return type; } } + error(accessNode, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType)); return type; } @@ -17040,8 +17225,7 @@ namespace ts { function checkUnusedLocalsAndParameters(node: Node): void { if (node.parent.kind !== SyntaxKind.InterfaceDeclaration && noUnusedIdentifiers && !isInAmbientContext(node)) { - for (const key in node.locals) { - const local = node.locals[key]; + node.locals.forEach(local => { if (!local.isReferenced) { if (local.valueDeclaration && getRootDeclaration(local.valueDeclaration).kind === SyntaxKind.Parameter) { const parameter = getRootDeclaration(local.valueDeclaration); @@ -17056,7 +17240,7 @@ namespace ts { forEach(local.declarations, d => errorUnusedLocal(d.name || d, local.name)); } } - } + }); } } @@ -17133,8 +17317,7 @@ namespace ts { function checkUnusedModuleMembers(node: ModuleDeclaration | SourceFile): void { if (compilerOptions.noUnusedLocals && !isInAmbientContext(node)) { - for (const key in node.locals) { - const local = node.locals[key]; + node.locals.forEach(local => { if (!local.isReferenced && !local.exportSymbol) { for (const declaration of local.declarations) { if (!isAmbientModule(declaration)) { @@ -17142,7 +17325,7 @@ namespace ts { } } } - } + }); } } @@ -18399,12 +18582,12 @@ namespace ts { else { const blockLocals = catchClause.block.locals; if (blockLocals) { - for (const caughtName in catchClause.locals) { - const blockLocal = blockLocals[caughtName]; + forEachKey(catchClause.locals, caughtName => { + const blockLocal = blockLocals.get(caughtName); if (blockLocal && (blockLocal.flags & SymbolFlags.BlockScopedVariable) !== 0) { grammarErrorOnNode(blockLocal.valueDeclaration, Diagnostics.Cannot_redeclare_identifier_0_in_catch_clause, caughtName); } - } + }); } } } @@ -18473,16 +18656,18 @@ namespace ts { return; } + const propDeclaration = prop.valueDeclaration; + // index is numeric and property name is not valid numeric literal - if (indexKind === IndexKind.Number && !isNumericName(prop.valueDeclaration.name)) { + if (indexKind === IndexKind.Number && !(propDeclaration ? isNumericName(propDeclaration.name) : isNumericLiteralName(prop.name))) { return; } // perform property check if property or indexer is declared in 'type' // this allows to rule out cases when both property and indexer are inherited from the base class let errorNode: Node; - if (prop.valueDeclaration.name.kind === SyntaxKind.ComputedPropertyName || prop.parent === containingType.symbol) { - errorNode = prop.valueDeclaration; + if (propDeclaration && (propDeclaration.name.kind === SyntaxKind.ComputedPropertyName || prop.parent === containingType.symbol)) { + errorNode = propDeclaration; } else if (indexDeclaration) { errorNode = indexDeclaration; @@ -18596,6 +18781,11 @@ namespace ts { checkTypeParameterListsIdentical(node, symbol); checkClassForDuplicateDeclarations(node); + // Only check for reserved static identifiers on non-ambient context. + if (!isInAmbientContext(node)) { + checkClassForStaticPropertyNameConflicts(node); + } + const baseTypeNode = getClassExtendsHeritageClauseElement(node); if (baseTypeNode) { if (languageVersion < ScriptTarget.ES2015 && !isInAmbientContext(node)) { @@ -18605,7 +18795,8 @@ namespace ts { const baseTypes = getBaseTypes(type); if (baseTypes.length && produceDiagnostics) { const baseType = baseTypes[0]; - const staticBaseType = getBaseConstructorTypeOfClass(type); + const baseConstructorType = getBaseConstructorTypeOfClass(type); + const staticBaseType = getApparentType(baseConstructorType); checkBaseTypeAccessibility(staticBaseType, baseTypeNode); checkSourceElement(baseTypeNode.expression); if (baseTypeNode.typeArguments) { @@ -18619,8 +18810,11 @@ namespace ts { checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(baseType, type.thisType), node.name || node, Diagnostics.Class_0_incorrectly_extends_base_class_1); checkTypeAssignableTo(staticType, getTypeWithoutSignatures(staticBaseType), node.name || node, Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1); + if (baseConstructorType.flags & TypeFlags.TypeVariable && !isMixinConstructorType(staticType)) { + error(node.name || node, Diagnostics.A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any); + } - if (baseType.symbol.valueDeclaration && + if (baseType.symbol && baseType.symbol.valueDeclaration && !isInAmbientContext(baseType.symbol.valueDeclaration) && baseType.symbol.valueDeclaration.kind === SyntaxKind.ClassDeclaration) { if (!isBlockScopedNameDeclaredBeforeUse(baseType.symbol.valueDeclaration, node)) { @@ -18628,7 +18822,7 @@ namespace ts { } } - if (!(staticBaseType.symbol && staticBaseType.symbol.flags & SymbolFlags.Class)) { + if (!(staticBaseType.symbol && staticBaseType.symbol.flags & SymbolFlags.Class) && !(baseConstructorType.flags & TypeFlags.TypeVariable)) { // When the static base type is a "class-like" constructor function (but not actually a class), we verify // that all instantiated base constructor signatures return the same type. We can simply compare the type // references (as opposed to checking the structure of the types) because elsewhere we have already checked @@ -18652,8 +18846,7 @@ namespace ts { if (produceDiagnostics) { const t = getTypeFromTypeNode(typeRefNode); if (t !== unknownType) { - const declaredType = getObjectFlags(t) & ObjectFlags.Reference ? (t).target : t; - if (getObjectFlags(declaredType) & ObjectFlags.ClassOrInterface) { + if (isValidBaseType(t)) { checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(t, type.thisType), node.name || node, Diagnostics.Class_0_incorrectly_implements_interface_1); } else { @@ -18693,7 +18886,7 @@ namespace ts { return forEach(symbol.declarations, d => isClassLike(d) ? d : undefined); } - function checkKindsOfPropertyMemberOverrides(type: InterfaceType, baseType: ObjectType): void { + function checkKindsOfPropertyMemberOverrides(type: InterfaceType, baseType: BaseType): void { // TypeScript 1.0 spec (April 2014): 8.2.3 // A derived class inherits all members from its base class it doesn't override. @@ -18710,7 +18903,7 @@ namespace ts { // derived class instance member variables and accessors, but not by other kinds of members. // NOTE: assignability is checked in checkClassDeclaration - const baseProperties = getPropertiesOfObjectType(baseType); + const baseProperties = getPropertiesOfType(baseType); for (const baseProperty of baseProperties) { const base = getTargetSymbol(baseProperty); @@ -18830,15 +19023,15 @@ namespace ts { } const seen = createMap<{ prop: Symbol; containingType: Type }>(); - forEach(resolveDeclaredMembers(type).declaredProperties, p => { seen[p.name] = { prop: p, containingType: type }; }); + forEach(resolveDeclaredMembers(type).declaredProperties, p => { seen.set(p.name, { prop: p, containingType: type }); }); let ok = true; for (const base of baseTypes) { - const properties = getPropertiesOfObjectType(getTypeWithThisArgument(base, type.thisType)); + const properties = getPropertiesOfType(getTypeWithThisArgument(base, type.thisType)); for (const prop of properties) { - const existing = seen[prop.name]; + const existing = seen.get(prop.name); if (!existing) { - seen[prop.name] = { prop: prop, containingType: base }; + seen.set(prop.name, { prop: prop, containingType: base }); } else { const isInheritedProperty = existing.containingType !== type; @@ -19588,19 +19781,14 @@ namespace ts { } function hasExportedMembers(moduleSymbol: Symbol) { - for (const id in moduleSymbol.exports) { - if (id !== "export=") { - return true; - } - } - return false; + return forEachEntry(moduleSymbol.exports, (_, id) => id !== "export="); } function checkExternalModuleExports(node: SourceFile | ModuleDeclaration) { const moduleSymbol = getSymbolOfNode(node); const links = getSymbolLinks(moduleSymbol); if (!links.exportsChecked) { - const exportEqualsSymbol = moduleSymbol.exports["export="]; + const exportEqualsSymbol = moduleSymbol.exports.get("export="); if (exportEqualsSymbol && hasExportedMembers(moduleSymbol)) { const declaration = getDeclarationOfAliasSymbol(exportEqualsSymbol) || exportEqualsSymbol.valueDeclaration; if (!isTopLevelInExternalModuleAugmentation(declaration)) { @@ -19609,21 +19797,20 @@ namespace ts { } // Checks for export * conflicts const exports = getExportsOfModule(moduleSymbol); - for (const id in exports) { + exports && exports.forEach(({ declarations, flags }, id) => { if (id === "__export") { - continue; + return; } - const { declarations, flags } = exports[id]; // ECMA262: 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries. // (TS Exceptions: namespaces, function overloads, enums, and interfaces) if (flags & (SymbolFlags.Namespace | SymbolFlags.Interface | SymbolFlags.Enum)) { - continue; + return; } const exportedDeclarationsCount = countWhere(declarations, isNotOverload); if (flags & SymbolFlags.TypeAlias && exportedDeclarationsCount <= 2) { // it is legal to merge type alias with other values // so count should be either 1 (just type alias) or 2 (type alias + merged value) - continue; + return; } if (exportedDeclarationsCount > 1) { for (const declaration of declarations) { @@ -19632,7 +19819,7 @@ namespace ts { } } } - } + }); links.exportsChecked = true; } @@ -20021,18 +20208,17 @@ namespace ts { // We will copy all symbol regardless of its reserved name because // symbolsToArray will check whether the key is a reserved name and // it will not copy symbol with reserved name to the array - if (!symbols[id]) { - symbols[id] = symbol; + if (!symbols.has(id)) { + symbols.set(id, symbol); } } } function copySymbols(source: SymbolTable, meaning: SymbolFlags): void { if (meaning) { - for (const id in source) { - const symbol = source[id]; + source.forEach(symbol => { copySymbol(symbol, meaning); - } + }); } } } @@ -20443,8 +20629,8 @@ namespace ts { const propsByName = createSymbolTable(getPropertiesOfType(type)); if (getSignaturesOfType(type, SignatureKind.Call).length || getSignaturesOfType(type, SignatureKind.Construct).length) { forEach(getPropertiesOfType(globalFunctionType), p => { - if (!propsByName[p.name]) { - propsByName[p.name] = p; + if (!propsByName.has(p.name)) { + propsByName.set(p.name, p); } }); } @@ -20468,6 +20654,10 @@ namespace ts { const links = symbol as SymbolLinks; return [links.leftSpread, links.rightSpread]; } + if ((symbol as SymbolLinks).mappedTypeOrigin) { + return getRootSymbols((symbol as SymbolLinks).mappedTypeOrigin); + } + let target: Symbol; let next = symbol; while (next = getSymbolLinks(next).target) { @@ -20486,7 +20676,8 @@ namespace ts { if (!isGeneratedIdentifier(node)) { node = getParseTreeNode(node, isIdentifier); if (node) { - return getReferencedValueSymbol(node) === argumentsSymbol; + const isPropertyName = node.parent.kind === SyntaxKind.PropertyAccessExpression && (node.parent).name === node; + return !isPropertyName && getReferencedValueSymbol(node) === argumentsSymbol; } } @@ -20511,7 +20702,7 @@ namespace ts { // otherwise - check if at least one export is value symbolLinks.exportsSomeValue = hasExportAssignment ? !!(moduleSymbol.flags & SymbolFlags.Value) - : forEachProperty(getExportsOfModule(moduleSymbol), isValue); + : forEachEntry(getExportsOfModule(moduleSymbol), isValue); } return symbolLinks.exportsSomeValue; @@ -20781,18 +20972,21 @@ namespace ts { function getTypeReferenceSerializationKind(typeName: EntityName, location?: Node): TypeReferenceSerializationKind { // Resolve the symbol as a value to ensure the type can be reached at runtime during emit. const valueSymbol = resolveEntityName(typeName, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location); - const globalPromiseSymbol = getGlobalPromiseConstructorSymbol(/*reportErrors*/ false); - if (globalPromiseSymbol && valueSymbol === globalPromiseSymbol) { - return TypeReferenceSerializationKind.Promise; - } - - const constructorType = valueSymbol ? getTypeOfSymbol(valueSymbol) : undefined; - if (constructorType && isConstructorType(constructorType)) { - return TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue; - } // Resolve the symbol as a type so that we can provide a more useful hint for the type serializer. const typeSymbol = resolveEntityName(typeName, SymbolFlags.Type, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location); + if (valueSymbol && valueSymbol === typeSymbol) { + const globalPromiseSymbol = getGlobalPromiseConstructorSymbol(/*reportErrors*/ false); + if (globalPromiseSymbol && valueSymbol === globalPromiseSymbol) { + return TypeReferenceSerializationKind.Promise; + } + + const constructorType = getTypeOfSymbol(valueSymbol); + if (constructorType && isConstructorType(constructorType)) { + return TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue; + } + } + // We might not be able to resolve type symbol so use unknown type in that case (eg error case) if (!typeSymbol) { return TypeReferenceSerializationKind.ObjectType; @@ -20861,7 +21055,7 @@ namespace ts { } function hasGlobalName(name: string): boolean { - return !!globals[name]; + return globals.has(name); } function getReferencedValueSymbol(reference: Identifier, startInDeclarationContainer?: boolean): Symbol { @@ -20918,14 +21112,13 @@ namespace ts { if (resolvedTypeReferenceDirectives) { // populate reverse mapping: file path -> type reference directive that was resolved to this file fileToDirective = createFileMap(); - for (const key in resolvedTypeReferenceDirectives) { - const resolvedDirective = resolvedTypeReferenceDirectives[key]; + resolvedTypeReferenceDirectives.forEach((resolvedDirective, key) => { if (!resolvedDirective) { - continue; + return; } const file = host.getSourceFile(resolvedDirective.resolvedFileName); fileToDirective.set(file.path, key); - } + }); } return { getReferencedExportContainer, @@ -21069,11 +21262,11 @@ namespace ts { if (file.symbol && file.symbol.globalExports) { // Merge in UMD exports with first-in-wins semantics (see #9771) const source = file.symbol.globalExports; - for (const id in source) { - if (!(id in globals)) { - globals[id] = source[id]; + source.forEach((sourceSymbol, id) => { + if (!globals.has(id)) { + globals.set(id, sourceSymbol); } - } + }); } } @@ -21772,17 +21965,17 @@ namespace ts { continue; } - if (!seen[effectiveName]) { - seen[effectiveName] = currentKind; + const existingKind = seen.get(effectiveName); + if (!existingKind) { + seen.set(effectiveName, currentKind); } else { - const existingKind = seen[effectiveName]; if (currentKind === Property && existingKind === Property) { grammarErrorOnNode(name, Diagnostics.Duplicate_identifier_0, getTextOfNode(name)); } else if ((currentKind & GetOrSetAccessor) && (existingKind & GetOrSetAccessor)) { if (existingKind !== GetOrSetAccessor && currentKind !== existingKind) { - seen[effectiveName] = currentKind | existingKind; + seen.set(effectiveName, currentKind | existingKind); } else { return grammarErrorOnNode(name, Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name); @@ -21804,8 +21997,8 @@ namespace ts { const jsxAttr = (attr); const name = jsxAttr.name; - if (!seen[name.text]) { - seen[name.text] = true; + if (!seen.get(name.text)) { + seen.set(name.text, true); } else { return grammarErrorOnNode(name, Diagnostics.JSX_elements_cannot_have_multiple_attributes_with_the_same_name); @@ -22330,11 +22523,11 @@ namespace ts { function getAmbientModules(): Symbol[] { const result: Symbol[] = []; - for (const sym in globals) { + globals.forEach((global, sym) => { if (ambientModuleSymbolRegex.test(sym)) { - result.push(globals[sym]); + result.push(global); } - } + }); return result; } } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index ef2af79a71b..b98158f71ff 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1,4 +1,4 @@ -/// +/// /// /// /// @@ -65,12 +65,13 @@ namespace ts { }, { name: "jsx", - type: createMap({ + type: createMapFromTemplate({ "preserve": JsxEmit.Preserve, + "react-native": JsxEmit.ReactNative, "react": JsxEmit.React }), paramType: Diagnostics.KIND, - description: Diagnostics.Specify_JSX_code_generation_Colon_preserve_or_react, + description: Diagnostics.Specify_JSX_code_generation_Colon_preserve_react_native_or_react, }, { name: "reactNamespace", @@ -100,7 +101,7 @@ namespace ts { { name: "module", shortName: "m", - type: createMap({ + type: createMapFromTemplate({ "none": ModuleKind.None, "commonjs": ModuleKind.CommonJS, "amd": ModuleKind.AMD, @@ -114,7 +115,7 @@ namespace ts { }, { name: "newLine", - type: createMap({ + type: createMapFromTemplate({ "crlf": NewLineKind.CarriageReturnLineFeed, "lf": NewLineKind.LineFeed }), @@ -263,7 +264,7 @@ namespace ts { { name: "target", shortName: "t", - type: createMap({ + type: createMapFromTemplate({ "es3": ScriptTarget.ES3, "es5": ScriptTarget.ES5, "es6": ScriptTarget.ES2015, @@ -300,7 +301,7 @@ namespace ts { }, { name: "moduleResolution", - type: createMap({ + type: createMapFromTemplate({ "node": ModuleResolutionKind.NodeJs, "classic": ModuleResolutionKind.Classic, }), @@ -414,7 +415,7 @@ namespace ts { type: "list", element: { name: "lib", - type: createMap({ + type: createMapFromTemplate({ // JavaScript only "es5": "lib.es5.d.ts", "es6": "lib.es2015.d.ts", @@ -538,9 +539,9 @@ namespace ts { const optionNameMap = createMap(); const shortOptionNames = createMap(); forEach(optionDeclarations, option => { - optionNameMap[option.name.toLowerCase()] = option; + optionNameMap.set(option.name.toLowerCase(), option); if (option.shortName) { - shortOptionNames[option.shortName] = option.name; + shortOptionNames.set(option.shortName, option.name); } }); @@ -550,7 +551,7 @@ namespace ts { /* @internal */ export function createCompilerDiagnosticForInvalidCustomType(opt: CommandLineOptionOfCustomType): Diagnostic { - const namesOfType = Object.keys(opt.type).map(key => `'${key}'`).join(", "); + const namesOfType = arrayFrom(opt.type.keys()).map(key => `'${key}'`).join(", "); return createCompilerDiagnostic(Diagnostics.Argument_for_0_option_must_be_Colon_1, `--${opt.name}`, namesOfType); } @@ -604,13 +605,13 @@ namespace ts { s = s.slice(s.charCodeAt(1) === CharacterCodes.minus ? 2 : 1).toLowerCase(); // Try to translate short option names to their full equivalents. - if (s in shortOptionNames) { - s = shortOptionNames[s]; + const short = shortOptionNames.get(s); + if (short !== undefined) { + s = short; } - if (s in optionNameMap) { - const opt = optionNameMap[s]; - + const opt = optionNameMap.get(s); + if (opt) { if (opt.isTSConfigOnly) { errors.push(createCompilerDiagnostic(Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file, opt.name)); } @@ -733,7 +734,7 @@ namespace ts { * @param fileNames array of filenames to be generated into tsconfig.json */ /* @internal */ - export function generateTSConfig(options: CompilerOptions, fileNames: string[]): { compilerOptions: Map } { + export function generateTSConfig(options: CompilerOptions, fileNames: string[]): { compilerOptions: MapLike } { const compilerOptions = extend(options, defaultInitCompilerOptions); const configurations: any = { compilerOptions: serializeCompilerOptions(compilerOptions) @@ -758,18 +759,17 @@ namespace ts { } } - function getNameOfCompilerOptionValue(value: CompilerOptionsValue, customTypeMap: MapLike): string | undefined { + function getNameOfCompilerOptionValue(value: CompilerOptionsValue, customTypeMap: Map): string | undefined { // There is a typeMap associated with this command-line option so use it to map value back to its name - for (const key in customTypeMap) { - if (customTypeMap[key] === value) { + return forEachEntry(customTypeMap, (mapValue, key) => { + if (mapValue === value) { return key; } - } - return undefined; + }); } - function serializeCompilerOptions(options: CompilerOptions): Map { - const result = createMap(); + function serializeCompilerOptions(options: CompilerOptions): MapLike { + const result: ts.MapLike = {}; const optionsNameMap = getOptionNameMap().optionNameMap; for (const name in options) { @@ -785,7 +785,7 @@ namespace ts { break; default: const value = options[name]; - const optionDefinition = optionsNameMap[name.toLowerCase()]; + const optionDefinition = optionsNameMap.get(name.toLowerCase()); if (optionDefinition) { const customTypeMap = getCustomTypeMapOfCommandLineOption(optionDefinition); if (!customTypeMap) { @@ -1056,8 +1056,8 @@ namespace ts { const optionNameMap = arrayToMap(optionDeclarations, opt => opt.name); for (const id in jsonOptions) { - if (id in optionNameMap) { - const opt = optionNameMap[id]; + const opt = optionNameMap.get(id); + if (opt) { defaultOptions[opt.name] = convertJsonOption(opt, jsonOptions[id], basePath, errors); } else { @@ -1093,8 +1093,9 @@ namespace ts { function convertJsonOptionOfCustomType(opt: CommandLineOptionOfCustomType, value: string, errors: Diagnostic[]) { const key = value.toLowerCase(); - if (key in opt.type) { - return opt.type[key]; + const val = opt.type.get(key); + if (val !== undefined) { + return val; } else { errors.push(createCompilerDiagnosticForInvalidCustomType(opt)); @@ -1222,7 +1223,7 @@ namespace ts { // file map that marks whether it was a regular wildcard match (with a `*` or `?` token), // or a recursive directory. This information is used by filesystem watchers to monitor for // new entries in these paths. - const wildcardDirectories: Map = getWildcardDirectories(include, exclude, basePath, host.useCaseSensitiveFileNames); + const wildcardDirectories = getWildcardDirectories(include, exclude, basePath, host.useCaseSensitiveFileNames); // Rather than requery this for each file and filespec, we query the supported extensions // once and store it on the expansion context. @@ -1233,7 +1234,7 @@ namespace ts { if (fileNames) { for (const fileName of fileNames) { const file = combinePaths(basePath, fileName); - literalFileMap[keyMapper(file)] = file; + literalFileMap.set(keyMapper(file), file); } } @@ -1256,15 +1257,14 @@ namespace ts { removeWildcardFilesWithLowerPriorityExtension(file, wildcardFileMap, supportedExtensions, keyMapper); const key = keyMapper(file); - if (!(key in literalFileMap) && !(key in wildcardFileMap)) { - wildcardFileMap[key] = file; + if (!literalFileMap.has(key) && !wildcardFileMap.has(key)) { + wildcardFileMap.set(key, file); } } } - const literalFiles = reduceProperties(literalFileMap, addFileToOutput, []); - const wildcardFiles = reduceProperties(wildcardFileMap, addFileToOutput, []); - wildcardFiles.sort(host.useCaseSensitiveFileNames ? compareStrings : compareStringsCaseInsensitive); + const literalFiles = arrayFrom(literalFileMap.values()); + const wildcardFiles = arrayFrom(wildcardFileMap.values()); return { fileNames: literalFiles.concat(wildcardFiles), wildcardDirectories @@ -1294,7 +1294,7 @@ namespace ts { /** * Gets directories in a set of include patterns that should be watched for changes. */ - function getWildcardDirectories(include: string[], exclude: string[], path: string, useCaseSensitiveFileNames: boolean): Map { + function getWildcardDirectories(include: string[], exclude: string[], path: string, useCaseSensitiveFileNames: boolean): MapLike { // We watch a directory recursively if it contains a wildcard anywhere in a directory segment // of the pattern: // @@ -1309,7 +1309,7 @@ namespace ts { // /a/b/a?z - Watch /a/b directly to catch any new file matching a?z const rawExcludeRegex = getRegularExpressionForWildcard(exclude, path, "exclude"); const excludeRegex = rawExcludeRegex && new RegExp(rawExcludeRegex, useCaseSensitiveFileNames ? "" : "i"); - const wildcardDirectories = createMap(); + const wildcardDirectories: ts.MapLike = {}; if (include !== undefined) { const recursiveKeys: string[] = []; for (const file of include) { @@ -1332,13 +1332,13 @@ namespace ts { } // Remove any subpaths under an existing recursively watched directory. - for (const key in wildcardDirectories) { + for (const key in wildcardDirectories) if (hasProperty(wildcardDirectories, key)) { for (const recursiveKey of recursiveKeys) { if (key !== recursiveKey && containsPath(recursiveKey, key, path, !useCaseSensitiveFileNames)) { delete wildcardDirectories[key]; } } - } + }; } return wildcardDirectories; @@ -1372,7 +1372,7 @@ namespace ts { for (let i = ExtensionPriority.Highest; i < adjustedExtensionPriority; i++) { const higherPriorityExtension = extensions[i]; const higherPriorityPath = keyMapper(changeExtension(file, higherPriorityExtension)); - if (higherPriorityPath in literalFiles || higherPriorityPath in wildcardFiles) { + if (literalFiles.has(higherPriorityPath) || wildcardFiles.has(higherPriorityPath)) { return true; } } @@ -1394,21 +1394,10 @@ namespace ts { for (let i = nextExtensionPriority; i < extensions.length; i++) { const lowerPriorityExtension = extensions[i]; const lowerPriorityPath = keyMapper(changeExtension(file, lowerPriorityExtension)); - delete wildcardFiles[lowerPriorityPath]; + wildcardFiles.delete(lowerPriorityPath); } } - /** - * Adds a file to an array of files. - * - * @param output The output array. - * @param file The file path. - */ - function addFileToOutput(output: string[], file: string) { - output.push(file); - return output; - } - /** * Gets a case sensitive key. * diff --git a/src/compiler/comments.ts b/src/compiler/comments.ts index 42ca685e295..ea51ddd9d43 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 22e65a3299e..304fba69b26 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -23,13 +23,14 @@ namespace ts { True = -1 } - const createObject = Object.create; - // More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times. - export const collator: { compare(a: string, b: string): number } = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator() : undefined; + export const collator: { compare(a: string, b: string): number } = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(/*locales*/ undefined, { usage: "sort", sensitivity: "accent" }) : undefined; + // Intl is missing in Safari, and node 0.10 treats "a" as greater than "B". + export const localeCompareIsCorrect = ts.collator && ts.collator.compare("a", "B") < 0; - export function createMap(template?: MapLike): Map { - const map: Map = createObject(null); // tslint:disable-line:no-null-keyword + /** Create a MapLike with good performance. */ + function createDictionaryObject(): MapLike { + const map = Object.create(null); // tslint:disable-line:no-null-keyword // Using 'delete' on an object causes V8 to put the object in dictionary mode. // This disables creation of hidden classes, which are expensive when an object is @@ -37,17 +38,113 @@ namespace ts { map["__"] = undefined; delete map["__"]; + return map; + } + + /** Create a new map. If a template object is provided, the map will copy entries from it. */ + export function createMap(): Map { + return new MapCtr(); + } + + export function createMapFromTemplate(template?: MapLike): Map { + const map: Map = new MapCtr(); + // Copies keys/values from template. Note that for..in will not throw if // template is undefined, and instead will just exit the loop. for (const key in template) if (hasOwnProperty.call(template, key)) { - map[key] = template[key]; + map.set(key, template[key]); } return map; } + // The global Map object. This may not be available, so we must test for it. + declare const Map: { new(): Map } | undefined; + // Internet Explorer's Map doesn't support iteration, so don't use it. + // tslint:disable-next-line:no-in-operator + const MapCtr = typeof Map !== "undefined" && "entries" in Map.prototype ? Map : shimMap(); + + // Keep the class inside a function so it doesn't get compiled if it's not used. + function shimMap(): { new(): Map } { + + class MapIterator { + private data: MapLike; + private keys: string[]; + private index = 0; + private selector: (data: MapLike, key: string) => U; + constructor(data: MapLike, selector: (data: MapLike, key: string) => U) { + this.data = data; + this.selector = selector; + this.keys = Object.keys(data); + } + + public next(): { value: U, done: false } | { value: never, done: true } { + const index = this.index; + if (index < this.keys.length) { + this.index++; + return { value: this.selector(this.data, this.keys[index]), done: false }; + } + return { value: undefined as never, done: true } + } + } + + return class implements Map { + private data = createDictionaryObject(); + public size = 0; + + get(key: string): T { + return this.data[key]; + } + + set(key: string, value: T): this { + if (!this.has(key)) { + this.size++; + } + this.data[key] = value; + return this; + } + + has(key: string): boolean { + // tslint:disable-next-line:no-in-operator + return key in this.data; + } + + delete(key: string): boolean { + if (this.has(key)) { + this.size--; + delete this.data[key]; + return true; + } + return false; + } + + clear(): void { + this.data = createDictionaryObject(); + this.size = 0; + } + + keys() { + return new MapIterator(this.data, (_data, key) => key); + } + + values() { + return new MapIterator(this.data, (data, key) => data[key]); + } + + entries() { + return new MapIterator(this.data, (data, key) => [key, data[key]] as [string, T]); + } + + forEach(action: (value: T, key: string) => void): void { + for (const key in this.data) { + action(this.data[key], key); + } + } + } + } + export function createFileMap(keyMapper?: (key: string) => string): FileMap { - let files = createMap(); + const files = createMap(); return { get, set, @@ -59,39 +156,34 @@ namespace ts { }; function forEachValueInMap(f: (key: Path, value: T) => void) { - for (const key in files) { - f(key, files[key]); - } + files.forEach((file, key) => { + f(key, file); + }); } function getKeys() { - const keys: Path[] = []; - for (const key in files) { - keys.push(key); - } - return keys; + return arrayFrom(files.keys()) as Path[]; } // path should already be well-formed so it does not need to be normalized function get(path: Path): T { - return files[toKey(path)]; + return files.get(toKey(path)); } function set(path: Path, value: T) { - files[toKey(path)] = value; + files.set(toKey(path), value); } function contains(path: Path) { - return toKey(path) in files; + return files.has(toKey(path)); } function remove(path: Path) { - const key = toKey(path); - delete files[key]; + files.delete(toKey(path)); } function clear() { - files = createMap(); + files.clear(); } function toKey(path: Path): string { @@ -112,6 +204,10 @@ namespace ts { GreaterThan = 1 } + export function length(array: any[]) { + return array ? array.length : 0; + } + /** * Iterates through 'array' by index and performs the callback on each element of array until the callback * returns a truthy value, then returns that value. @@ -164,6 +260,16 @@ namespace ts { return undefined; } + /** Works like Array.prototype.findIndex, returning `-1` if no element satisfying the predicate is found. */ + export function findIndex(array: T[], predicate: (element: T, index: number) => boolean): number { + for (let i = 0; i < array.length; i++) { + if (predicate(array[i], i)) { + return i; + } + } + return -1; + } + /** * Returns the first truthy result of `callback`, or else fails. * This is like `forEach`, but never returns undefined. @@ -420,17 +526,16 @@ namespace ts { return result; } - export function mapObject(object: MapLike, f: (key: string, x: T) => [string, U]): MapLike { - let result: MapLike; - if (object) { - result = {}; - for (const v of getOwnKeys(object)) { - const [key, value]: [string, U] = f(v, object[v]) || [undefined, undefined]; - if (key !== undefined) { - result[key] = value; - } - } + export function mapEntries(map: Map, f: (key: string, value: T) => [string, U]): Map { + if (!map) { + return undefined; } + + const result = createMap(); + map.forEach((value, key) => { + const [newKey, newValue] = f(key, value); + result.set(newKey, newValue); + }); return result; } @@ -748,9 +853,6 @@ namespace ts { /** * Indicates whether a map-like contains an own property with the specified key. * - * NOTE: This is intended for use only with MapLike objects. For Map objects, use - * the 'in' operator. - * * @param map A map-like. * @param key A property key. */ @@ -761,9 +863,6 @@ namespace ts { /** * Gets the value of an owned property in a map-like. * - * NOTE: This is intended for use only with MapLike objects. For Map objects, use - * an indexer. - * * @param map A map-like. * @param key A property key. */ @@ -787,50 +886,48 @@ namespace ts { return keys; } - /** - * Enumerates the properties of a Map, invoking a callback and returning the first truthy result. - * - * @param map A map for which properties should be enumerated. - * @param callback A callback to invoke for each property. - */ - export function forEachProperty(map: Map, callback: (value: T, key: string) => U): U { - let result: U; - for (const key in map) { - if (result = callback(map[key], key)) break; + /** Shims `Array.from`. */ + export function arrayFrom(iterator: Iterator): T[] { + const result: T[] = []; + for (let { value, done } = iterator.next(); !done; { value, done } = iterator.next()) { + result.push(value); } return result; } /** - * Returns true if a Map has some matching property. - * - * @param map A map whose properties should be tested. - * @param predicate An optional callback used to test each property. + * Calls `callback` for each entry in the map, returning the first truthy result. + * Use `map.forEach` instead for normal iteration. */ - export function someProperties(map: Map, predicate?: (value: T, key: string) => boolean) { - for (const key in map) { - if (!predicate || predicate(map[key], key)) return true; + export function forEachEntry(map: Map, callback: (value: T, key: string) => U | undefined): U | undefined { + const iterator = map.entries(); + for (let { value: pair, done } = iterator.next(); !done; { value: pair, done } = iterator.next()) { + const [key, value] = pair; + const result = callback(value, key); + if (result) { + return result; + } } - return false; + return undefined; } - /** - * Performs a shallow copy of the properties from a source Map to a target MapLike - * - * @param source A map from which properties should be copied. - * @param target A map to which properties should be copied. - */ - export function copyProperties(source: Map, target: MapLike): void { - for (const key in source) { - target[key] = source[key]; + /** `forEachEntry` for just keys. */ + export function forEachKey(map: Map<{}>, callback: (key: string) => T | undefined): T | undefined { + const iterator = map.keys(); + for (let { value: key, done } = iterator.next(); !done; { value: key, done } = iterator.next()) { + const result = callback(key); + if (result) { + return result; + } } + return undefined; } - export function appendProperty(map: Map, key: string | number, value: T): Map { - if (key === undefined || value === undefined) return map; - if (map === undefined) map = createMap(); - map[key] = value; - return map; + /** Copy entries from `source` to `target`. */ + export function copyEntries(source: Map, target: Map): void { + source.forEach((value, key) => { + target.set(key, value); + }); } export function assign, T2, T3>(t: T1, arg1: T2, arg2: T3): T1 & T2 & T3; @@ -845,24 +942,6 @@ namespace ts { return t; } - /** - * Reduce the properties of a map. - * - * NOTE: This is intended for use with Map objects. For MapLike objects, use - * reduceOwnProperties instead as it offers better runtime safety. - * - * @param map The map to reduce - * @param callback An aggregation function that is called for each entry in the map - * @param initial The initial value for the reduction. - */ - export function reduceProperties(map: Map, callback: (aggregate: U, value: T, key: string) => U, initial: U): U { - let result = initial; - for (const key in map) { - result = callback(result, map[key], String(key)); - } - return result; - } - /** * Performs a shallow equality comparison of the contents of two map-likes. * @@ -897,23 +976,14 @@ namespace ts { export function arrayToMap(array: T[], makeKey: (value: T) => string, makeValue?: (value: T) => U): Map { const result = createMap(); for (const value of array) { - result[makeKey(value)] = makeValue ? makeValue(value) : value; + result.set(makeKey(value), makeValue ? makeValue(value) : value); } return result; } - export function isEmpty(map: Map) { - for (const id in map) { - if (hasProperty(map, id)) { - return false; - } - } - return true; - } - export function cloneMap(map: Map) { const clone = createMap(); - copyProperties(map, clone); + copyEntries(map, clone); return clone; } @@ -938,32 +1008,43 @@ namespace ts { return result; } - /** - * Adds the value to an array of values associated with the key, and returns the array. - * Creates the array if it does not already exist. - */ - export function multiMapAdd(map: Map, key: string | number, value: V): V[] { - const values = map[key]; - if (values) { - values.push(value); - return values; - } - else { - return map[key] = [value]; - } + export interface MultiMap extends Map { + /** + * Adds the value to an array of values associated with the key, and returns the array. + * Creates the array if it does not already exist. + */ + add(key: string, value: T): T[]; + /** + * Removes a value from an array of values associated with the key. + * Does not preserve the order of those values. + * Does nothing if `key` is not in `map`, or `value` is not in `map[key]`. + */ + remove(key: string, value: T): void; } - /** - * Removes a value from an array of values associated with the key. - * Does not preserve the order of those values. - * Does nothing if `key` is not in `map`, or `value` is not in `map[key]`. - */ - export function multiMapRemove(map: Map, key: string, value: V): void { - const values = map[key]; + export function createMultiMap(): MultiMap { + const map = createMap() as MultiMap; + map.add = multiMapAdd; + map.remove = multiMapRemove; + return map; + } + function multiMapAdd(this: MultiMap, key: string, value: T) { + let values = this.get(key); + if (values) { + values.push(value); + } + else { + this.set(key, values = [value]); + } + return values; + + } + function multiMapRemove(this: MultiMap, key: string, value: T) { + const values = this.get(key); if (values) { unorderedRemoveItem(values, value); if (!values.length) { - delete map[key]; + this.delete(key); } } } @@ -1066,7 +1147,7 @@ namespace ts { return text.replace(/{(\d+)}/g, (_match, index?) => args[+index + baseIndex]); } - export let localizedDiagnosticMessages: Map = undefined; + export let localizedDiagnosticMessages: MapLike = undefined; export function getLocaleSpecificMessage(message: DiagnosticMessage) { return localizedDiagnosticMessages && localizedDiagnosticMessages[message.key] || message.message; @@ -1182,9 +1263,12 @@ namespace ts { if (a === undefined) return Comparison.LessThan; if (b === undefined) return Comparison.GreaterThan; if (ignoreCase) { - if (collator && String.prototype.localeCompare) { - // accent means a ≠ b, a ≠ á, a = A - const result = a.localeCompare(b, /*locales*/ undefined, { usage: "sort", sensitivity: "accent" }); + // Checking if "collator exists indicates that Intl is available. + // We still have to check if "collator.compare" is correct. If it is not, use "String.localeComapre" + if (collator) { + const result = localeCompareIsCorrect ? + collator.compare(a, b) : + a.localeCompare(b, /*locales*/ undefined, { usage: "sort", sensitivity: "accent" }); // accent means a ≠ b, a ≠ á, a = A return result < 0 ? Comparison.LessThan : result > 0 ? Comparison.GreaterThan : Comparison.EqualTo; } @@ -1363,7 +1447,7 @@ namespace ts { return /^\.\.?($|[\\/])/.test(moduleName); } - export function getEmitScriptTarget(compilerOptions: CompilerOptions) { + export function getEmitScriptTarget(compilerOptions: CompilerOptions | PrinterOptions) { return compilerOptions.target || ScriptTarget.ES3; } @@ -1650,7 +1734,19 @@ namespace ts { const singleAsteriskRegexFragmentFiles = "([^./]|(\\.(?!min\\.js$))?)*"; const singleAsteriskRegexFragmentOther = "[^/]*"; - export function getRegularExpressionForWildcard(specs: string[], basePath: string, usage: "files" | "directories" | "exclude") { + export function getRegularExpressionForWildcard(specs: string[], basePath: string, usage: "files" | "directories" | "exclude"): string | undefined { + const patterns = getRegularExpressionsForWildcards(specs, basePath, usage); + if (!patterns || !patterns.length) { + return undefined; + } + + const pattern = patterns.map(pattern => `(${pattern})`).join("|"); + // If excluding, match "foo/bar/baz...", but if including, only allow "foo". + const terminator = usage === "exclude" ? "($|/)" : "$"; + return `^(${pattern})${terminator}`; + } + + function getRegularExpressionsForWildcards(specs: string[], basePath: string, usage: "files" | "directories" | "exclude"): string[] | undefined { if (specs === undefined || specs.length === 0) { return undefined; } @@ -1664,33 +1760,8 @@ namespace ts { */ const doubleAsteriskRegexFragment = usage === "exclude" ? "(/.+?)?" : "(/[^/.][^/]*)*?"; - let pattern = ""; - let hasWrittenSubpattern = false; - for (const spec of specs) { - if (!spec) { - continue; - } - - const subPattern = getSubPatternFromSpec(spec, basePath, usage, singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter); - if (subPattern === undefined) { - continue; - } - - if (hasWrittenSubpattern) { - pattern += "|"; - } - - pattern += "(" + subPattern + ")"; - hasWrittenSubpattern = true; - } - - if (!pattern) { - return undefined; - } - - // If excluding, match "foo/bar/baz...", but if including, only allow "foo". - const terminator = usage === "exclude" ? "($|/)" : "$"; - return `^(${pattern})${terminator}`; + return flatMap(specs, spec => + spec && getSubPatternFromSpec(spec, basePath, usage, singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter)); } /** @@ -1785,6 +1856,9 @@ namespace ts { } export interface FileMatcherPatterns { + /** One pattern for each "include" spec. */ + includeFilePatterns: string[]; + /** One pattern matching one of any of the "include" specs. */ includeFilePattern: string; includeDirectoryPattern: string; excludePattern: string; @@ -1797,6 +1871,7 @@ namespace ts { const absolutePath = combinePaths(currentDirectory, path); return { + includeFilePatterns: map(getRegularExpressionsForWildcards(includes, absolutePath, "files"), pattern => `^${pattern}$`), includeFilePattern: getRegularExpressionForWildcard(includes, absolutePath, "files"), includeDirectoryPattern: getRegularExpressionForWildcard(includes, absolutePath, "directories"), excludePattern: getRegularExpressionForWildcard(excludes, absolutePath, "exclude"), @@ -1811,26 +1886,39 @@ namespace ts { const patterns = getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory); const regexFlag = useCaseSensitiveFileNames ? "" : "i"; - const includeFileRegex = patterns.includeFilePattern && new RegExp(patterns.includeFilePattern, regexFlag); + const includeFileRegexes = patterns.includeFilePatterns && patterns.includeFilePatterns.map(pattern => new RegExp(pattern, regexFlag)); const includeDirectoryRegex = patterns.includeDirectoryPattern && new RegExp(patterns.includeDirectoryPattern, regexFlag); const excludeRegex = patterns.excludePattern && new RegExp(patterns.excludePattern, regexFlag); - const result: string[] = []; + // Associate an array of results with each include regex. This keeps results in order of the "include" order. + // If there are no "includes", then just put everything in results[0]. + const results: string[][] = includeFileRegexes ? includeFileRegexes.map(() => []) : [[]]; + + const comparer = useCaseSensitiveFileNames ? compareStrings : compareStringsCaseInsensitive; for (const basePath of patterns.basePaths) { visitDirectory(basePath, combinePaths(currentDirectory, basePath)); } - return result; + + return flatten(results); function visitDirectory(path: string, absolutePath: string) { - const { files, directories } = getFileSystemEntries(path); + let { files, directories } = getFileSystemEntries(path); + files = files.slice().sort(comparer); + directories = directories.slice().sort(comparer); for (const current of files) { const name = combinePaths(path, current); const absoluteName = combinePaths(absolutePath, current); - if ((!extensions || fileExtensionIsAny(name, extensions)) && - (!includeFileRegex || includeFileRegex.test(absoluteName)) && - (!excludeRegex || !excludeRegex.test(absoluteName))) { - result.push(name); + if (extensions && !fileExtensionIsAny(name, extensions)) continue; + if (excludeRegex && excludeRegex.test(absoluteName)) continue; + if (!includeFileRegexes) { + results[0].push(name); + } + else { + const includeIndex = findIndex(includeFileRegexes, re => re.test(absoluteName)); + if (includeIndex !== -1) { + results[includeIndex].push(name); + } } } diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index cd98622e080..4b878adaff5 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -32,16 +32,18 @@ namespace ts { export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, targetSourceFile: SourceFile): Diagnostic[] { const declarationDiagnostics = createDiagnosticCollection(); - forEachExpectedEmitFile(host, getDeclarationDiagnosticsFromFile, targetSourceFile); + 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(); @@ -156,9 +158,9 @@ namespace ts { }); if (usedTypeDirectiveReferences) { - for (const directive in usedTypeDirectiveReferences) { + forEachKey(usedTypeDirectiveReferences, directive => { referencesOutput += `/// ${newLine}`; - } + }); } return { @@ -271,8 +273,8 @@ namespace ts { usedTypeDirectiveReferences = createMap(); } for (const directive of typeReferenceDirectives) { - if (!(directive in usedTypeDirectiveReferences)) { - usedTypeDirectiveReferences[directive] = directive; + if (!usedTypeDirectiveReferences.has(directive)) { + usedTypeDirectiveReferences.set(directive, directive); } } } @@ -390,6 +392,7 @@ namespace ts { case SyntaxKind.StringKeyword: case SyntaxKind.NumberKeyword: case SyntaxKind.BooleanKeyword: + case SyntaxKind.ObjectKeyword: case SyntaxKind.SymbolKeyword: case SyntaxKind.VoidKeyword: case SyntaxKind.UndefinedKeyword: @@ -581,14 +584,14 @@ namespace ts { // do not need to keep track of created temp names. function getExportDefaultTempVariableName(): string { const baseName = "_default"; - if (!(baseName in currentIdentifiers)) { + if (!currentIdentifiers.has(baseName)) { return baseName; } let count = 0; while (true) { count++; const name = baseName + "_" + count; - if (!(name in currentIdentifiers)) { + if (!currentIdentifiers.has(name)) { return name; } } @@ -1787,7 +1790,7 @@ namespace ts { } else { // Get the declaration file path - forEachExpectedEmitFile(host, getDeclFileName, referencedFile, emitOnlyDtsFiles); + forEachEmittedFile(host, getDeclFileName, referencedFile, emitOnlyDtsFiles); } if (declFileName) { @@ -1802,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; } @@ -1816,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/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 9a67f34cb9a..c9d387ab15c 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1795,18 +1795,22 @@ "category": "Error", "code": 2544 }, - "The type returned by the 'next()' method of an async iterator must be a promise for a type with a 'value' property.": { + "A mixin class must have a constructor with a single rest parameter of type 'any[]'.": { "category": "Error", "code": 2545 }, - "Type '{0}' is not an array type or does not have a '[Symbol.iterator]()' method that returns an iterator.": { + "The type returned by the 'next()' method of an async iterator must be a promise for a type with a 'value' property.": { "category": "Error", "code": 2546 }, - "Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]()' method that returns an iterator.": { + "Type '{0}' is not an array type or does not have a '[Symbol.iterator]()' method that returns an iterator.": { "category": "Error", "code": 2547 }, + "Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]()' method that returns an iterator.": { + "category": "Error", + "code": 2548 + }, "JSX element attributes type '{0}' may not be a union type.": { "category": "Error", "code": 2600 @@ -1847,6 +1851,10 @@ "category": "Error", "code": 2609 }, + "Cannot augment module '{0}' with value exports because it resolves to a non-module entity.": { + "category": "Error", + "code": 2649 + }, "Cannot emit namespaced JSX elements in React": { "category": "Error", "code": 2650 @@ -2039,6 +2047,10 @@ "category": "Error", "code": 2698 }, + "Static property '{0}' conflicts with built-in property 'Function.{0}' of constructor function '{1}'.": { + "category": "Error", + "code": 2699 + }, "Rest types may only be created from object types.": { "category": "Error", "code": 2700 @@ -2733,7 +2745,7 @@ "category": "Message", "code": 6079 }, - "Specify JSX code generation: 'preserve' or 'react'": { + "Specify JSX code generation: 'preserve', 'react-native', or 'react'": { "category": "Message", "code": 6080 }, @@ -3287,6 +3299,10 @@ "category": "Message", "code": 90007 }, + "Add 'this.' to unresolved variable.": { + "category": "Message", + "code": 90008 + }, "Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig": { "category": "Error", "code": 90009 diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 9afe97bd1f0..596b583b52d 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"); - forEachTransformedEmitFile(host, transformed, emitFile, 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: string, sourceMapFilePath: string, declarationFilePath: string, 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); @@ -1054,9 +1124,11 @@ namespace ts { // Also emit a dot if expression is a integer const enum value - it will appear in generated code as numeric literal function needsDotDotForPropertyAccess(expression: Expression) { if (expression.kind === SyntaxKind.NumericLiteral) { - // check if numeric literal was originally written with a dot + // check if numeric literal is a decimal literal that was originally written with a dot const text = getLiteralTextOfNode(expression); - return text.indexOf(tokenToString(SyntaxKind.DotToken)) < 0; + return getNumericLiteralFlags(text, /*hint*/ NumericLiteralFlags.All) === NumericLiteralFlags.None + && !(expression).isOctalLiteral + && text.indexOf(tokenToString(SyntaxKind.DotToken)) < 0; } else if (isPropertyAccessExpression(expression) || isElementAccessExpression(expression)) { // check if constant enum value is integer @@ -1064,7 +1136,7 @@ namespace ts { // isFinite handles cases when constantValue is undefined return isFinite(constantValue) && Math.floor(constantValue) === constantValue - && compilerOptions.removeComments; + && printerOptions.removeComments; } } @@ -1095,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); } @@ -1448,7 +1517,6 @@ namespace ts { writeLineOrSpace(node); emit(node.catchClause); } - if (node.finallyBlock) { writeLineOrSpace(node); write("finally "); @@ -1502,11 +1570,10 @@ namespace ts { emitBlockFunctionBody(body); } else { - const savedTempFlags = tempFlags; - tempFlags = 0; + pushNameGenerationScope(); emitSignatureHead(node); emitBlockFunctionBody(body); - tempFlags = savedTempFlags; + popNameGenerationScope(); } if (indentedFlag) { @@ -1574,10 +1641,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 +1658,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 +1688,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 +1726,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 +1754,12 @@ namespace ts { write("{ }"); } else { - const savedTempFlags = tempFlags; - tempFlags = 0; + pushNameGenerationScope(); write("{"); increaseIndent(); emitBlockStatements(node); write("}"); - tempFlags = savedTempFlags; + popNameGenerationScope(); } } @@ -1947,11 +2008,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); } @@ -1986,17 +2046,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 @@ -2026,81 +2085,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[helper.name]) { - continue; - } - - bundledHelpers[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) { - 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(); @@ -2258,15 +2248,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) { @@ -2302,6 +2294,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(" "); @@ -2311,26 +2343,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) { @@ -2456,6 +2494,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; @@ -2466,7 +2514,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); @@ -2495,27 +2543,63 @@ 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, getTextOfNode); + } + 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, getTextOfNode: (node: Node, includeTrivia?: boolean) => string) { + const nodeId = getNodeId(node); + return nodeIdToGeneratedName[nodeId] || (nodeIdToGeneratedName[nodeId] = unescapeIdentifier(generateNameForNode(node, getTextOfNode))); + } + + /** + * 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) && - !hasProperty(currentFileIdentifiers, name) && - !hasProperty(generatedNameSet, 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 && hasProperty(node.locals, name)) { + if (node.locals) { + const local = node.locals.get(name); // We conservatively include alias symbols to cover cases where they're emitted as locals - if (node.locals[name].flags & (SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias)) { + if (local && local.flags & (SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias)) { return false; } } @@ -2524,10 +2608,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"; @@ -2551,10 +2635,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._) { @@ -2564,18 +2650,25 @@ namespace ts { while (true) { const generatedName = baseName + i; if (isUniqueName(generatedName)) { - return generatedNameSet[generatedName] = generatedName; + generatedNames.set(generatedName, generatedName); + return generatedName; } i++; } } - function generateNameForModuleOrEnum(node: ModuleDeclaration | EnumDeclaration) { + /** + * Generates a unique name for a ModuleDeclaration or EnumDeclaration. + */ + function generateNameForModuleOrEnum(node: ModuleDeclaration | EnumDeclaration, getTextOfNode: (node: Node, includeTrivia?: boolean) => string) { 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 ? @@ -2583,33 +2676,37 @@ 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) { + function generateNameForMethodOrAccessor(node: MethodDeclaration | AccessorDeclaration, getTextOfNode: (node: Node, includeTrivia?: boolean) => string) { if (isIdentifier(node.name)) { - return generateNameForNodeCached(node.name); + return generateNameCached(node.name, getTextOfNode); } return makeTempVariableName(TempFlags.Auto); } /** * Generates a unique name from a node. - * - * @param node A node. */ - function generateNameForNode(node: Node): string { + function generateNameForNode(node: Node, getTextOfNode: (node: Node, includeTrivia?: boolean) => string): string { switch (node.kind) { case SyntaxKind.Identifier: return makeUniqueName(getTextOfNode(node)); case SyntaxKind.ModuleDeclaration: case SyntaxKind.EnumDeclaration: - return generateNameForModuleOrEnum(node); + return generateNameForModuleOrEnum(node, getTextOfNode); case SyntaxKind.ImportDeclaration: case SyntaxKind.ExportDeclaration: return generateNameForImportOrExportDeclaration(node); @@ -2622,7 +2719,7 @@ namespace ts { case SyntaxKind.MethodDeclaration: case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: - return generateNameForMethodOrAccessor(node); + return generateNameForMethodOrAccessor(node, getTextOfNode); default: return makeTempVariableName(TempFlags.Auto); } @@ -2630,10 +2727,8 @@ 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); @@ -2648,10 +2743,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; @@ -2672,61 +2765,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 { @@ -2753,7 +2828,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 "]". diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 0d067b7f00d..f5e691a01f8 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1,4 +1,4 @@ -/// +/// /// /* @internal */ @@ -1536,6 +1536,19 @@ namespace ts { 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; + } + // Compound nodes export function createComma(left: Expression, right: Expression) { @@ -2779,9 +2792,11 @@ namespace ts { return destEmitNode; } - function mergeTokenSourceMapRanges(sourceRanges: Map, destRanges: Map) { - if (!destRanges) destRanges = createMap(); - copyProperties(sourceRanges, destRanges); + function mergeTokenSourceMapRanges(sourceRanges: TextRange[], destRanges: TextRange[]) { + if (!destRanges) destRanges = []; + for (const key in sourceRanges) { + destRanges[key] = sourceRanges[key]; + } return destRanges; } @@ -2895,7 +2910,7 @@ namespace ts { */ export function setTokenSourceMapRange(node: T, token: SyntaxKind, range: TextRange) { const emitNode = getOrCreateEmitNode(node); - const tokenSourceMapRanges = emitNode.tokenSourceMapRanges || (emitNode.tokenSourceMapRanges = createMap()); + const tokenSourceMapRanges = emitNode.tokenSourceMapRanges || (emitNode.tokenSourceMapRanges = []); tokenSourceMapRanges[token] = range; return node; } @@ -3110,10 +3125,8 @@ namespace ts { * Here we check if alternative name was provided for a given moduleName and return it if possible. */ function tryRenameExternalModule(moduleName: LiteralExpression, sourceFile: SourceFile) { - if (sourceFile.renamedDependencies && hasProperty(sourceFile.renamedDependencies, moduleName.text)) { - return createLiteral(sourceFile.renamedDependencies[moduleName.text]); - } - return undefined; + const rename = sourceFile.renamedDependencies && sourceFile.renamedDependencies.get(moduleName.text); + return rename && createLiteral(rename); } /** @@ -3413,7 +3426,7 @@ namespace ts { externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[]; // imports of other external modules externalHelpersImportDeclaration: ImportDeclaration | undefined; // import of external helpers exportSpecifiers: Map; // export specifiers by name - exportedBindings: Map; // exported names of local declarations + exportedBindings: Identifier[][]; // exported names of local declarations exportedNames: Identifier[]; // all exported names local to module exportEquals: ExportAssignment | undefined; // an export= declaration if one was present hasExportStarsToExportValues: boolean; // whether this module contains export* @@ -3421,8 +3434,8 @@ namespace ts { export function collectExternalModuleInfo(sourceFile: SourceFile, resolver: EmitResolver, compilerOptions: CompilerOptions): ExternalModuleInfo { const externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[] = []; - const exportSpecifiers = createMap(); - const exportedBindings = createMap(); + const exportSpecifiers = createMultiMap(); + const exportedBindings: Identifier[][] = []; const uniqueExports = createMap(); let exportedNames: Identifier[]; let hasExportDefault = false; @@ -3473,18 +3486,18 @@ namespace ts { else { // export { x, y } for (const specifier of (node).exportClause.elements) { - if (!uniqueExports[specifier.name.text]) { + if (!uniqueExports.get(specifier.name.text)) { const name = specifier.propertyName || specifier.name; - multiMapAdd(exportSpecifiers, name.text, specifier); + exportSpecifiers.add(name.text, specifier); const decl = resolver.getReferencedImportDeclaration(name) || resolver.getReferencedValueDeclaration(name); if (decl) { - multiMapAdd(exportedBindings, getOriginalNodeId(decl), specifier.name); + multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(decl), specifier.name); } - uniqueExports[specifier.name.text] = true; + uniqueExports.set(specifier.name.text, true); exportedNames = append(exportedNames, specifier.name); } } @@ -3511,16 +3524,16 @@ namespace ts { if (hasModifier(node, ModifierFlags.Default)) { // export default function() { } if (!hasExportDefault) { - multiMapAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(node)); + multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(node)); hasExportDefault = true; } } else { // export function x() { } const name = (node).name; - if (!uniqueExports[name.text]) { - multiMapAdd(exportedBindings, getOriginalNodeId(node), name); - uniqueExports[name.text] = true; + if (!uniqueExports.get(name.text)) { + multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name); + uniqueExports.set(name.text, true); exportedNames = append(exportedNames, name); } } @@ -3532,16 +3545,16 @@ namespace ts { if (hasModifier(node, ModifierFlags.Default)) { // export default class { } if (!hasExportDefault) { - multiMapAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(node)); + multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(node)); hasExportDefault = true; } } else { // export class x { } const name = (node).name; - if (!uniqueExports[name.text]) { - multiMapAdd(exportedBindings, getOriginalNodeId(node), name); - uniqueExports[name.text] = true; + if (!uniqueExports.get(name.text)) { + multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name); + uniqueExports.set(name.text, true); exportedNames = append(exportedNames, name); } } @@ -3562,11 +3575,23 @@ namespace ts { } } else if (!isGeneratedIdentifier(decl.name)) { - if (!uniqueExports[decl.name.text]) { - uniqueExports[decl.name.text] = true; + if (!uniqueExports.get(decl.name.text)) { + uniqueExports.set(decl.name.text, true); exportedNames = append(exportedNames, decl.name); } } return exportedNames; } + + /** Use a sparse array as a multi-map. */ + function multiMapSparseArrayAdd(map: V[][], key: number, value: V): V[] { + let values = map[key]; + if (values) { + values.push(value); + } + else { + map[key] = values = [value]; + } + return values; + } } diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 1bb0eaa991a..0300ff71ec5 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -336,9 +336,10 @@ namespace ts { if (!moduleHasNonRelativeName(nonRelativeModuleName)) { return undefined; } - let perModuleNameCache = moduleNameToDirectoryMap[nonRelativeModuleName]; + let perModuleNameCache = moduleNameToDirectoryMap.get(nonRelativeModuleName); if (!perModuleNameCache) { - moduleNameToDirectoryMap[nonRelativeModuleName] = perModuleNameCache = createPerModuleNameCache(); + perModuleNameCache = createPerModuleNameCache(); + moduleNameToDirectoryMap.set(nonRelativeModuleName, perModuleNameCache); } return perModuleNameCache; } @@ -422,7 +423,7 @@ namespace ts { } const containingDirectory = getDirectoryPath(containingFile); const perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory); - let result = perFolderCache && perFolderCache[moduleName]; + let result = perFolderCache && perFolderCache.get(moduleName); if (result) { if (traceEnabled) { @@ -453,7 +454,7 @@ namespace ts { } if (perFolderCache) { - perFolderCache[moduleName] = result; + perFolderCache.set(moduleName, result); // put result in per-module name cache const perModuleNameCache = cache.getOrCreateCacheForModuleName(moduleName); if (perModuleNameCache) { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 19531c0850d..900b8a3fcdd 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1135,7 +1135,11 @@ namespace ts { function internIdentifier(text: string): string { text = escapeIdentifier(text); - return identifiers[text] || (identifiers[text] = text); + let identifier = identifiers.get(text); + if (identifier === undefined) { + identifiers.set(text, identifier = text); + } + return identifier; } // An identifier that starts with two underscores has an extra underscore character prepended to it to avoid issues @@ -6692,10 +6696,15 @@ namespace ts { typedefTag.fullName = parseJSDocTypeNameWithNamespace(/*flags*/ 0); if (typedefTag.fullName) { let rightNode = typedefTag.fullName; - while (rightNode.kind !== SyntaxKind.Identifier) { + while (true) { + if (rightNode.kind === SyntaxKind.Identifier || !rightNode.body) { + // if node is identifier - use it as name + // otherwise use name of the rightmost part that we were able to parse + typedefTag.name = rightNode.kind === SyntaxKind.Identifier ? rightNode : rightNode.name; + break; + } rightNode = rightNode.body; } - typedefTag.name = rightNode; } typedefTag.typeExpression = typeExpression; skipWhitespace(); diff --git a/src/compiler/performance.ts b/src/compiler/performance.ts index a48eb117e28..8c24b3b9f1b 100644 --- a/src/compiler/performance.ts +++ b/src/compiler/performance.ts @@ -27,8 +27,8 @@ namespace ts.performance { */ export function mark(markName: string) { if (enabled) { - marks[markName] = timestamp(); - counts[markName] = (counts[markName] || 0) + 1; + marks.set(markName, timestamp()); + counts.set(markName, (counts.get(markName) || 0) + 1); profilerEvent(markName); } } @@ -44,9 +44,9 @@ namespace ts.performance { */ export function measure(measureName: string, startMarkName?: string, endMarkName?: string) { if (enabled) { - const end = endMarkName && marks[endMarkName] || timestamp(); - const start = startMarkName && marks[startMarkName] || profilerStart; - measures[measureName] = (measures[measureName] || 0) + (end - start); + const end = endMarkName && marks.get(endMarkName) || timestamp(); + const start = startMarkName && marks.get(startMarkName) || profilerStart; + measures.set(measureName, (measures.get(measureName) || 0) + (end - start)); } } @@ -56,7 +56,7 @@ namespace ts.performance { * @param markName The name of the mark. */ export function getCount(markName: string) { - return counts && counts[markName] || 0; + return counts && counts.get(markName) || 0; } /** @@ -65,7 +65,7 @@ namespace ts.performance { * @param measureName The name of the measure whose durations should be accumulated. */ export function getDuration(measureName: string) { - return measures && measures[measureName] || 0; + return measures && measures.get(measureName) || 0; } /** @@ -74,9 +74,9 @@ namespace ts.performance { * @param cb The action to perform for each measure */ export function forEachMeasure(cb: (measureName: string, duration: number) => void) { - for (const key in measures) { - cb(key, measures[key]); - } + measures.forEach((measure, key) => { + cb(key, measure); + }); } /** Enables (and resets) performance measurements for the compiler. */ diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 1099e126912..650711afc79 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -111,11 +111,11 @@ namespace ts { } function directoryExists(directoryPath: string): boolean { - if (directoryPath in existingDirectories) { + if (existingDirectories.has(directoryPath)) { return true; } if (sys.directoryExists(directoryPath)) { - existingDirectories[directoryPath] = true; + existingDirectories.set(directoryPath, true); return true; } return false; @@ -139,11 +139,11 @@ namespace ts { const hash = sys.createHash(data); const mtimeBefore = sys.getModifiedTime(fileName); - if (mtimeBefore && fileName in outputFingerprints) { - const fingerprint = outputFingerprints[fileName]; - + if (mtimeBefore) { + const fingerprint = outputFingerprints.get(fileName); // If output has not been changed, and the file has no external modification - if (fingerprint.byteOrderMark === writeByteOrderMark && + if (fingerprint && + fingerprint.byteOrderMark === writeByteOrderMark && fingerprint.hash === hash && fingerprint.mtime.getTime() === mtimeBefore.getTime()) { return; @@ -154,11 +154,11 @@ namespace ts { const mtimeAfter = sys.getModifiedTime(fileName); - outputFingerprints[fileName] = { + outputFingerprints.set(fileName, { hash, byteOrderMark: writeByteOrderMark, mtime: mtimeAfter - }; + }); } function writeFile(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void) { @@ -278,9 +278,13 @@ namespace ts { const resolutions: T[] = []; const cache = createMap(); for (const name of names) { - const result = name in cache - ? cache[name] - : cache[name] = loader(name, containingFile); + let result: T; + if (cache.has(name)) { + result = cache.get(name); + } + else { + cache.set(name, result = loader(name, containingFile)); + } resolutions.push(result); } return resolutions; @@ -435,7 +439,7 @@ namespace ts { function getCommonSourceDirectory() { if (commonSourceDirectory === undefined) { - const emittedFiles = filterSourceFilesInDirectory(files, isSourceFileFromExternalLibrary); + const emittedFiles = filter(files, file => sourceFileMayBeEmitted(file, options, isSourceFileFromExternalLibrary)); if (options.rootDir && checkSourceFilesBelongToPath(emittedFiles, options.rootDir)) { // If a rootDir is specified and is valid use it as the commonSourceDirectory commonSourceDirectory = getNormalizedAbsolutePath(options.rootDir, currentDirectory); @@ -460,7 +464,7 @@ namespace ts { classifiableNames = createMap(); for (const sourceFile of files) { - copyProperties(sourceFile.classifiableNames, classifiableNames); + copyEntries(sourceFile.classifiableNames, classifiableNames); } } @@ -735,7 +739,7 @@ namespace ts { } function isSourceFileFromExternalLibrary(file: SourceFile): boolean { - return sourceFilesFoundSearchingNodeModules[file.path]; + return sourceFilesFoundSearchingNodeModules.get(file.path); } function getDiagnosticsProducingTypeChecker() { @@ -1298,20 +1302,20 @@ namespace ts { // If the file was previously found via a node_modules search, but is now being processed as a root file, // then everything it sucks in may also be marked incorrectly, and needs to be checked again. - if (file && sourceFilesFoundSearchingNodeModules[file.path] && currentNodeModulesDepth == 0) { - sourceFilesFoundSearchingNodeModules[file.path] = false; + if (file && sourceFilesFoundSearchingNodeModules.get(file.path) && currentNodeModulesDepth == 0) { + sourceFilesFoundSearchingNodeModules.set(file.path, false); if (!options.noResolve) { processReferencedFiles(file, isDefaultLib); processTypeReferenceDirectives(file); } - modulesWithElidedImports[file.path] = false; + modulesWithElidedImports.set(file.path, false); processImportedModules(file); } // See if we need to reprocess the imports due to prior skipped imports - else if (file && modulesWithElidedImports[file.path]) { + else if (file && modulesWithElidedImports.get(file.path)) { if (currentNodeModulesDepth < maxNodeModuleJsDepth) { - modulesWithElidedImports[file.path] = false; + modulesWithElidedImports.set(file.path, false); processImportedModules(file); } } @@ -1332,7 +1336,7 @@ namespace ts { filesByName.set(path, file); if (file) { - sourceFilesFoundSearchingNodeModules[path] = (currentNodeModulesDepth > 0); + sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0); file.path = path; if (host.useCaseSensitiveFileNames()) { @@ -1393,7 +1397,7 @@ namespace ts { refFile?: SourceFile, refPos?: number, refEnd?: number): void { // If we already found this library as a primary reference - nothing to do - const previousResolution = resolvedTypeReferenceDirectives[typeReferenceDirective]; + const previousResolution = resolvedTypeReferenceDirectives.get(typeReferenceDirective); if (previousResolution && previousResolution.primary) { return; } @@ -1433,7 +1437,7 @@ namespace ts { } if (saveResolution) { - resolvedTypeReferenceDirectives[typeReferenceDirective] = resolvedTypeReferenceDirective; + resolvedTypeReferenceDirectives.set(typeReferenceDirective, resolvedTypeReferenceDirective); } } @@ -1486,7 +1490,7 @@ namespace ts { const shouldAddFile = resolvedFileName && !getResolutionDiagnostic(options, resolution) && !options.noResolve && i < file.imports.length && !elideImport; if (elideImport) { - modulesWithElidedImports[file.path] = true; + modulesWithElidedImports.set(file.path, true); } else if (shouldAddFile) { const path = toPath(resolvedFileName, currentDirectory, getCanonicalFileName); @@ -1703,7 +1707,7 @@ namespace ts { if (!options.noEmit && !options.suppressOutputPathCheck) { const emitHost = getEmitHost(); const emitFilesSeen = createFileMap(!host.useCaseSensitiveFileNames() ? key => key.toLocaleLowerCase() : undefined); - forEachExpectedEmitFile(emitHost, (emitFileNames) => { + forEachEmittedFile(emitHost, (emitFileNames) => { verifyEmitFilePath(emitFileNames.jsFilePath, emitFilesSeen); verifyEmitFilePath(emitFileNames.declarationFilePath, emitFilesSeen); }); diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index da7308ecb89..52c75a37005 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -56,7 +56,7 @@ namespace ts { tryScan(callback: () => T): T; } - const textToToken = createMap({ + const textToToken = createMapFromTemplate({ "abstract": SyntaxKind.AbstractKeyword, "any": SyntaxKind.AnyKeyword, "as": SyntaxKind.AsKeyword, @@ -276,9 +276,9 @@ namespace ts { function makeReverseMap(source: Map): string[] { const result: string[] = []; - for (const name in source) { - result[source[name]] = name; - } + source.forEach((value, name) => { + result[value] = name; + }); return result; } @@ -290,7 +290,7 @@ namespace ts { /* @internal */ export function stringToToken(s: string): SyntaxKind { - return textToToken[s]; + return textToToken.get(s); } /* @internal */ @@ -364,8 +364,6 @@ namespace ts { return computeLineAndCharacterOfPosition(getLineStarts(sourceFile), position); } - const hasOwnProperty = Object.prototype.hasOwnProperty; - export function isWhiteSpace(ch: number): boolean { return isWhiteSpaceSingleLine(ch) || isLineBreak(ch); } @@ -1184,8 +1182,11 @@ namespace ts { const len = tokenValue.length; if (len >= 2 && len <= 11) { const ch = tokenValue.charCodeAt(0); - if (ch >= CharacterCodes.a && ch <= CharacterCodes.z && hasOwnProperty.call(textToToken, tokenValue)) { - return token = textToToken[tokenValue]; + if (ch >= CharacterCodes.a && ch <= CharacterCodes.z) { + token = textToToken.get(tokenValue); + if (token !== undefined) { + return token; + } } } return token = SyntaxKind.Identifier; 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/sys.ts b/src/compiler/sys.ts index 966f0e0cd03..71ff4485343 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -1,4 +1,7 @@ -/// +/// + +declare function setTimeout(handler: (...args: any[]) => void, timeout: number): any; +declare function clearTimeout(handle: any): void; namespace ts { export type FileWatcherCallback = (fileName: string, removed?: boolean) => void; @@ -243,23 +246,23 @@ namespace ts { function createWatchedFileSet() { const dirWatchers = createMap(); // One file can have multiple watchers - const fileWatcherCallbacks = createMap(); + const fileWatcherCallbacks = createMultiMap(); return { addFile, removeFile }; function reduceDirWatcherRefCountForFile(fileName: string) { const dirName = getDirectoryPath(fileName); - const watcher = dirWatchers[dirName]; + const watcher = dirWatchers.get(dirName); if (watcher) { watcher.referenceCount -= 1; if (watcher.referenceCount <= 0) { watcher.close(); - delete dirWatchers[dirName]; + dirWatchers.delete(dirName); } } } function addDirWatcher(dirPath: string): void { - let watcher = dirWatchers[dirPath]; + let watcher = dirWatchers.get(dirPath); if (watcher) { watcher.referenceCount += 1; return; @@ -270,12 +273,12 @@ namespace ts { (eventName: string, relativeFileName: string) => fileEventHandler(eventName, relativeFileName, dirPath) ); watcher.referenceCount = 1; - dirWatchers[dirPath] = watcher; + dirWatchers.set(dirPath, watcher); return; } function addFileWatcherCallback(filePath: string, callback: FileWatcherCallback): void { - multiMapAdd(fileWatcherCallbacks, filePath, callback); + fileWatcherCallbacks.add(filePath, callback); } function addFile(fileName: string, callback: FileWatcherCallback): WatchedFile { @@ -291,7 +294,7 @@ namespace ts { } function removeFileWatcherCallback(filePath: string, callback: FileWatcherCallback) { - multiMapRemove(fileWatcherCallbacks, filePath, callback); + fileWatcherCallbacks.remove(filePath, callback); } function fileEventHandler(eventName: string, relativeFileName: string, baseDirPath: string) { @@ -300,9 +303,12 @@ namespace ts { ? undefined : ts.getNormalizedAbsolutePath(relativeFileName, baseDirPath); // Some applications save a working file via rename operations - if ((eventName === "change" || eventName === "rename") && fileWatcherCallbacks[fileName]) { - for (const fileCallback of fileWatcherCallbacks[fileName]) { - fileCallback(fileName); + if ((eventName === "change" || eventName === "rename")) { + const callbacks = fileWatcherCallbacks.get(fileName); + if (callbacks) { + for (const fileCallback of callbacks) { + fileCallback(fileName); + } } } } diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index 10a718448e9..62469df79c1 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -1,4 +1,4 @@ -/// +/// /// /// /// @@ -13,14 +13,16 @@ /* @internal */ namespace ts { - const moduleTransformerMap = createMap({ - [ModuleKind.ES2015]: transformES2015Module, - [ModuleKind.System]: transformSystemModule, - [ModuleKind.AMD]: transformModule, - [ModuleKind.CommonJS]: transformModule, - [ModuleKind.UMD]: transformModule, - [ModuleKind.None]: transformModule, - }); + function getModuleTransformer(moduleKind: ModuleKind): Transformer { + switch (moduleKind) { + case ModuleKind.ES2015: + return transformES2015Module; + case ModuleKind.System: + return transformSystemModule; + default: + return transformModule; + } + } const enum SyntaxKindFeatureFlags { Substitution = 1 << 0, @@ -56,7 +58,7 @@ namespace ts { transformers.push(transformGenerators); } - transformers.push(moduleTransformerMap[moduleKind] || moduleTransformerMap[ModuleKind.None]); + transformers.push(getModuleTransformer(moduleKind)); // The ES5 transformer is last so that it can substitute expressions like `exports.default` // for ES3. @@ -103,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); @@ -120,6 +124,9 @@ namespace ts { // Disable modification of the lexical environment. lexicalEnvironmentDisabled = true; + performance.mark("afterTransform"); + performance.measure("transformTime", "beforeTransform", "afterTransform"); + return { transformed, emitNodeWithSubstitution, @@ -157,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); } } @@ -194,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/es2015.ts b/src/compiler/transformers/es2015.ts index 92f1bb3de83..917c5266df2 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -587,7 +587,7 @@ namespace ts { if (isGeneratedIdentifier(node)) { return node; } - if (node.text !== "arguments" && !resolver.isArgumentsLocalBinding(node)) { + if (node.text !== "arguments" || !resolver.isArgumentsLocalBinding(node)) { return node; } return convertedLoopState.argumentsName || (convertedLoopState.argumentsName = createUniqueName("arguments")); @@ -601,7 +601,7 @@ namespace ts { // - break/continue is non-labeled and located in non-converted loop/switch statement const jump = node.kind === SyntaxKind.BreakStatement ? Jump.Break : Jump.Continue; const canUseBreakOrContinue = - (node.label && convertedLoopState.labels && convertedLoopState.labels[node.label.text]) || + (node.label && convertedLoopState.labels && convertedLoopState.labels.get(node.label.text)) || (!node.label && (convertedLoopState.allowedNonLabeledJumps & jump)); if (!canUseBreakOrContinue) { @@ -2144,11 +2144,11 @@ namespace ts { } function recordLabel(node: LabeledStatement) { - convertedLoopState.labels[node.label.text] = node.label.text; + convertedLoopState.labels.set(node.label.text, node.label.text); } function resetLabel(node: LabeledStatement) { - convertedLoopState.labels[node.label.text] = undefined; + convertedLoopState.labels.set(node.label.text, undefined); } function visitLabeledStatement(node: LabeledStatement): VisitResult { @@ -2294,7 +2294,7 @@ namespace ts { addRange(statements, convertedLoopBodyStatements); } else { - const statement = visitNode(node.statement, visitor, isStatement); + const statement = visitNode(node.statement, visitor, isStatement, /*optional*/ false, liftToBlock); if (isBlock(statement)) { addRange(statements, statement.statements); bodyLocation = statement; @@ -2903,13 +2903,13 @@ namespace ts { if (!state.labeledNonLocalBreaks) { state.labeledNonLocalBreaks = createMap(); } - state.labeledNonLocalBreaks[labelText] = labelMarker; + state.labeledNonLocalBreaks.set(labelText, labelMarker); } else { if (!state.labeledNonLocalContinues) { state.labeledNonLocalContinues = createMap(); } - state.labeledNonLocalContinues[labelText] = labelMarker; + state.labeledNonLocalContinues.set(labelText, labelMarker); } } @@ -2917,13 +2917,12 @@ namespace ts { if (!table) { return; } - for (const labelText in table) { - const labelMarker = table[labelText]; + table.forEach((labelMarker, labelText) => { const statements: Statement[] = []; // if there are no outer converted loop or outer label in question is located inside outer converted loop // then emit labeled break\continue // otherwise propagate pair 'label -> marker' to outer converted loop and emit 'return labelMarker' so outer loop can later decide what to do - if (!outerLoop || (outerLoop.labels && outerLoop.labels[labelText])) { + if (!outerLoop || (outerLoop.labels && outerLoop.labels.get(labelText))) { const label = createIdentifier(labelText); statements.push(isBreak ? createBreak(label) : createContinue(label)); } @@ -2932,7 +2931,7 @@ namespace ts { statements.push(createReturn(loopResultName)); } caseClauses.push(createCaseClause(createLiteral(labelMarker), statements)); - } + }); } function processLoopVariableDeclaration(decl: VariableDeclaration | BindingElement, loopParameters: ParameterDeclaration[], loopOutParameters: LoopOutParameter[]) { @@ -3556,9 +3555,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( @@ -3566,11 +3567,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); } /** @@ -3605,13 +3606,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); } diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index b15d39e1636..f17b026cf9d 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -315,10 +315,11 @@ 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)) { @@ -326,24 +327,23 @@ namespace ts { if (superContainerFlags !== enclosingSuperContainerFlags) { const savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags; enclosingSuperContainerFlags = superContainerFlags; - previousOnEmitNode(emitContext, node, emitCallback); + previousOnEmitNode(hint, node, emitCallback); enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags; return; } } - 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 && enclosingSuperContainerFlags) { + function onSubstituteNode(hint: EmitHint, node: Node) { + node = previousOnSubstituteNode(hint, node); + if (hint === EmitHint.Expression && enclosingSuperContainerFlags) { return substituteExpression(node); } diff --git a/src/compiler/transformers/es5.ts b/src/compiler/transformers/es5.ts index 6dd875965d9..8b030642a89 100644 --- a/src/compiler/transformers/es5.ts +++ b/src/compiler/transformers/es5.ts @@ -11,10 +11,10 @@ namespace ts { export function transformES5(context: TransformationContext) { const compilerOptions = context.getCompilerOptions(); - // enable emit notification only if using --jsx preserve - let previousOnEmitNode: (emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) => void; + // enable emit notification only if using --jsx preserve or react-native + let previousOnEmitNode: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void; let noSubstitution: boolean[]; - if (compilerOptions.jsx === JsxEmit.Preserve) { + if (compilerOptions.jsx === JsxEmit.Preserve || compilerOptions.jsx === JsxEmit.ReactNative) { previousOnEmitNode = context.onEmitNode; context.onEmitNode = onEmitNode; context.enableEmitNotification(SyntaxKind.JsxOpeningElement); @@ -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); } @@ -116,4 +118,4 @@ namespace ts { return undefined; } } -} \ No newline at end of file +} diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index 5ae49496952..50446a5f2b7 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -700,12 +700,13 @@ namespace ts { } /** - * Hook for node emit. + * Called by the printer just before a node is printed. * - * @param node The node to emit. - * @param emit A callback used to emit the node in the printer. + * @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): void { + function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) { // If we need to support substitutions for `super` in an async method, // we should track it here. if (enabledSubstitutions & ESNextSubstitutionFlags.AsyncMethodsWithSuper && isSuperContainer(node)) { @@ -713,25 +714,24 @@ namespace ts { if (superContainerFlags !== enclosingSuperContainerFlags) { const savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags; enclosingSuperContainerFlags = superContainerFlags; - previousOnEmitNode(emitContext, node, emitCallback); + previousOnEmitNode(hint, node, emitCallback); enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags; return; } } - previousOnEmitNode(emitContext, node, emitCallback); + previousOnEmitNode(hint, node, emitCallback); } /** * Hooks node substitutions. * + * @param hint The context for the emitter. * @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 && enclosingSuperContainerFlags) { + function onSubstituteNode(hint: EmitHint, node: Node) { + node = previousOnSubstituteNode(hint, node); + if (hint === EmitHint.Expression && enclosingSuperContainerFlags) { return substituteExpression(node); } return node; @@ -835,6 +835,11 @@ namespace ts { }; export function createAssignHelper(context: TransformationContext, attributesSegments: Expression[]) { + if (context.getCompilerOptions().target >= ScriptTarget.ES2015) { + return createCall(createPropertyAccess(createIdentifier("Object"), "assign"), + /*typeArguments*/ undefined, + attributesSegments); + } context.requestEmitHelper(assignHelper); return createCall( getHelperName("__assign"), diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 5f7c76b37fb..e503fb51b12 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -1,4 +1,4 @@ -/// +/// /// // Transforms generator functions into a compatible ES5 representation with similar runtime @@ -217,13 +217,15 @@ namespace ts { Endfinally = 7, } - const instructionNames = createMap({ - [Instruction.Return]: "return", - [Instruction.Break]: "break", - [Instruction.Yield]: "yield", - [Instruction.YieldStar]: "yield*", - [Instruction.Endfinally]: "endfinally", - }); + function getInstructionName(instruction: Instruction): string { + switch (instruction) { + case Instruction.Return: return "return"; + case Instruction.Break: return "break"; + case Instruction.Yield: return "yield"; + case Instruction.YieldStar: return "yield*"; + case Instruction.Endfinally: return "endfinally"; + } + } export function transformGenerators(context: TransformationContext) { const { @@ -241,7 +243,7 @@ namespace ts { let currentSourceFile: SourceFile; let renamedCatchVariables: Map; - let renamedCatchVariableDeclarations: Map; + let renamedCatchVariableDeclarations: Identifier[]; let inGeneratorFunctionBody: boolean; let inStatementContainingYield: boolean; @@ -1911,9 +1913,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; @@ -1927,12 +1929,12 @@ namespace ts { } function substituteExpressionIdentifier(node: Identifier) { - if (renamedCatchVariables && hasProperty(renamedCatchVariables, node.text)) { + if (renamedCatchVariables && renamedCatchVariables.has(node.text)) { const original = getOriginalNode(node); if (isIdentifier(original) && original.parent) { const declaration = resolver.getReferencedValueDeclaration(original); if (declaration) { - const name = getProperty(renamedCatchVariableDeclarations, String(getOriginalNodeId(declaration))); + const name = renamedCatchVariableDeclarations[getOriginalNodeId(declaration)]; if (name) { const clone = getMutableClone(name); setSourceMapRange(clone, node); @@ -2098,11 +2100,11 @@ namespace ts { if (!renamedCatchVariables) { renamedCatchVariables = createMap(); - renamedCatchVariableDeclarations = createMap(); + renamedCatchVariableDeclarations = []; context.enableSubstitution(SyntaxKind.Identifier); } - renamedCatchVariables[text] = true; + renamedCatchVariables.set(text, true); renamedCatchVariableDeclarations[getOriginalNodeId(variable)] = name; const exception = peekBlock(); @@ -2407,7 +2409,7 @@ namespace ts { */ function createInstruction(instruction: Instruction): NumericLiteral { const literal = createLiteral(instruction); - literal.trailingComment = instructionNames[instruction]; + literal.trailingComment = getInstructionName(instruction); return literal; } diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index 5ed14376511..ad2cfc92cf3 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -233,7 +233,7 @@ namespace ts { return String.fromCharCode(parseInt(hex, 16)); } else { - const ch = entities[word]; + const ch = entities.get(word); // If this is not a valid entity, then just use `match` (replace it with itself, i.e. don't replace) return ch ? String.fromCharCode(ch) : match; } @@ -281,7 +281,7 @@ namespace ts { } } - const entities = createMap({ + const entities = createMapFromTemplate({ "quot": 0x0022, "amp": 0x0026, "apos": 0x0027, diff --git a/src/compiler/transformers/module/es2015.ts b/src/compiler/transformers/module/es2015.ts index 7b7e7d410d3..2f1ae2fa314 100644 --- a/src/compiler/transformers/module/es2015.ts +++ b/src/compiler/transformers/module/es2015.ts @@ -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); } diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 7b146f3803e..cef09ed16c6 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -1,4 +1,4 @@ -/// +/// /// /// @@ -11,12 +11,13 @@ namespace ts { importAliasNames: ParameterDeclaration[]; } - const transformModuleDelegates = createMap<(node: SourceFile) => SourceFile>({ - [ModuleKind.None]: transformCommonJSModule, - [ModuleKind.CommonJS]: transformCommonJSModule, - [ModuleKind.AMD]: transformAMDModule, - [ModuleKind.UMD]: transformUMDModule, - }); + function getTransformModuleDelegate(moduleKind: ModuleKind): (node: SourceFile) => SourceFile { + switch (moduleKind) { + case ModuleKind.AMD: return transformAMDModule; + case ModuleKind.UMD: return transformUMDModule; + default: return transformCommonJSModule; + } + } const { startLexicalEnvironment, @@ -39,12 +40,12 @@ namespace ts { context.enableSubstitution(SyntaxKind.ShorthandPropertyAssignment); // Substitutes shorthand property assignments for imported/exported symbols. context.enableEmitNotification(SyntaxKind.SourceFile); // Restore state when substituting nodes in a file. - const moduleInfoMap = createMap(); // The ExternalModuleInfo for each file. - const deferredExports = createMap(); // Exports to defer until an EndOfDeclarationMarker is found. + const moduleInfoMap: ExternalModuleInfo[] = []; // The ExternalModuleInfo for each file. + const deferredExports: Statement[][] = []; // Exports to defer until an EndOfDeclarationMarker is found. let currentSourceFile: SourceFile; // The current file. let currentModuleInfo: ExternalModuleInfo; // The ExternalModuleInfo for the current file. - let noSubstitution: Map; // Set of nodes for which substitution rules should be ignored. + let noSubstitution: boolean[]; // Set of nodes for which substitution rules should be ignored. return transformSourceFile; @@ -61,10 +62,11 @@ namespace ts { } currentSourceFile = node; - currentModuleInfo = moduleInfoMap[getOriginalNodeId(node)] = collectExternalModuleInfo(node, resolver, compilerOptions); + currentModuleInfo = collectExternalModuleInfo(node, resolver, compilerOptions); + moduleInfoMap[getOriginalNodeId(node)] = currentModuleInfo; // Perform the transformation. - const transformModule = transformModuleDelegates[moduleKind] || transformModuleDelegates[ModuleKind.None]; + const transformModule = getTransformModuleDelegate(moduleKind); const updated = transformModule(node); currentSourceFile = undefined; @@ -1086,7 +1088,7 @@ namespace ts { */ function appendExportsOfDeclaration(statements: Statement[] | undefined, decl: Declaration): Statement[] | undefined { const name = getDeclarationName(decl); - const exportSpecifiers = currentModuleInfo.exportSpecifiers[name.text]; + const exportSpecifiers = currentModuleInfo.exportSpecifiers.get(name.text); if (exportSpecifiers) { for (const exportSpecifier of exportSpecifiers) { statements = appendExportStatement(statements, exportSpecifier.name, name, /*location*/ exportSpecifier.name); @@ -1110,7 +1112,7 @@ namespace ts { function appendExportStatement(statements: Statement[] | undefined, exportName: Identifier, expression: Expression, location?: TextRange, allowComments?: boolean): Statement[] | undefined { if (exportName.text === "default") { const sourceFile = getOriginalNode(currentSourceFile, isSourceFile); - if (sourceFile && !sourceFile.symbol.exports["___esModule"]) { + if (sourceFile && !sourceFile.symbol.exports.get("___esModule")) { if (languageVersion === ScriptTarget.ES3) { statements = append(statements, createStatement( @@ -1208,24 +1210,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 = createMap(); + noSubstitution = []; - previousOnEmitNode(emitContext, node, emitCallback); + previousOnEmitNode(hint, node, emitCallback); currentSourceFile = undefined; currentModuleInfo = undefined; noSubstitution = undefined; } else { - previousOnEmitNode(emitContext, node, emitCallback); + previousOnEmitNode(hint, node, emitCallback); } } @@ -1236,16 +1238,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)) { diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 7a4322b7c52..26c5e469c9e 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -1,4 +1,4 @@ -/// +/// /// /// @@ -29,10 +29,10 @@ namespace ts { context.enableSubstitution(SyntaxKind.PostfixUnaryExpression); // Substitutes updates to exported symbols. context.enableEmitNotification(SyntaxKind.SourceFile); // Restore state when substituting nodes in a file. - const moduleInfoMap = createMap(); // The ExternalModuleInfo for each file. - const deferredExports = createMap(); // Exports to defer until an EndOfDeclarationMarker is found. - const exportFunctionsMap = createMap(); // The export function associated with a source file. - const noSubstitutionMap = createMap>(); // Set of nodes for which substitution rules should be ignored for each file. + const moduleInfoMap: ExternalModuleInfo[] = []; // The ExternalModuleInfo for each file. + const deferredExports: Statement[][] = []; // Exports to defer until an EndOfDeclarationMarker is found. + const exportFunctionsMap: Identifier[] = []; // The export function associated with a source file. + const noSubstitutionMap: boolean[][] = []; // Set of nodes for which substitution rules should be ignored for each file. let currentSourceFile: SourceFile; // The current file. let moduleInfo: ExternalModuleInfo; // ExternalModuleInfo for the current file. @@ -40,7 +40,7 @@ namespace ts { let contextObject: Identifier; // The context object for the current file. let hoistedStatements: Statement[]; let enclosingBlockScopedContainer: Node; - let noSubstitution: Map; // Set of nodes for which substitution rules should be ignored. + let noSubstitution: boolean[]; // Set of nodes for which substitution rules should be ignored. return transformSourceFile; @@ -78,7 +78,8 @@ namespace ts { // Make sure that the name of the 'exports' function does not conflict with // existing identifiers. - exportFunction = exportFunctionsMap[id] = createUniqueName("exports"); + exportFunction = createUniqueName("exports"); + exportFunctionsMap[id] = exportFunction; contextObject = createUniqueName("context"); // Add the body of the module. @@ -148,13 +149,13 @@ namespace ts { const externalImport = externalImports[i]; const externalModuleName = getExternalModuleNameLiteral(externalImport, currentSourceFile, host, resolver, compilerOptions); const text = externalModuleName.text; - if (hasProperty(groupIndices, text)) { + const groupIndex = groupIndices.get(text); + if (groupIndex !== undefined) { // deduplicate/group entries in dependency list by the dependency name - const groupIndex = groupIndices[text]; dependencyGroups[groupIndex].externalImports.push(externalImport); } else { - groupIndices[text] = dependencyGroups.length; + groupIndices.set(text, dependencyGroups.length); dependencyGroups.push({ name: externalModuleName, externalImports: [externalImport] @@ -306,7 +307,7 @@ namespace ts { // this set is used to filter names brought by star expors. // local names set should only be added if we have anything exported - if (!moduleInfo.exportedNames && isEmpty(moduleInfo.exportSpecifiers)) { + if (!moduleInfo.exportedNames && moduleInfo.exportSpecifiers.size === 0) { // no exported declarations (export var ...) or export specifiers (export {x}) // check if we have any non star export declarations. let hasExportDeclarationWithExportClause = false; @@ -1082,7 +1083,7 @@ namespace ts { } const name = getDeclarationName(decl); - const exportSpecifiers = moduleInfo.exportSpecifiers[name.text]; + const exportSpecifiers = moduleInfo.exportSpecifiers.get(name.text); if (exportSpecifiers) { for (const exportSpecifier of exportSpecifiers) { if (exportSpecifier.name.text !== excludeName) { @@ -1549,11 +1550,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; @@ -1565,7 +1566,7 @@ namespace ts { delete noSubstitutionMap[id]; } - previousOnEmitNode(emitContext, node, emitCallback); + previousOnEmitNode(hint, node, emitCallback); currentSourceFile = undefined; moduleInfo = undefined; @@ -1573,7 +1574,7 @@ namespace ts { noSubstitution = undefined; } else { - previousOnEmitNode(emitContext, node, emitCallback); + previousOnEmitNode(hint, node, emitCallback); } } @@ -1584,16 +1585,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); } @@ -1773,7 +1774,7 @@ namespace ts { * @param node The node which should not be substituted. */ function preventSubstitution(node: T): T { - if (noSubstitution === undefined) noSubstitution = createMap(); + if (noSubstitution === undefined) noSubstitution = []; noSubstitution[getNodeId(node)] = true; return node; } diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index eea12c27b3a..2521791460b 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -1,4 +1,4 @@ -/// +/// /// /// @@ -60,7 +60,7 @@ namespace ts { * A map that keeps track of aliases created for classes with decorators to avoid issues * with the double-binding behavior of classes. */ - let classAliases: Map; + let classAliases: Identifier[]; /** * Keeps track of whether we are within any containing namespaces when performing @@ -2547,8 +2547,8 @@ namespace ts { currentScopeFirstDeclarationsOfName = createMap(); } - if (!(name in currentScopeFirstDeclarationsOfName)) { - currentScopeFirstDeclarationsOfName[name] = node; + if (!currentScopeFirstDeclarationsOfName.has(name)) { + currentScopeFirstDeclarationsOfName.set(name, node); } } } @@ -2561,7 +2561,7 @@ namespace ts { if (currentScopeFirstDeclarationsOfName) { const name = node.symbol && node.symbol.name; if (name) { - return currentScopeFirstDeclarationsOfName[name] === node; + return currentScopeFirstDeclarationsOfName.get(name) === node; } } @@ -3134,7 +3134,7 @@ namespace ts { context.enableSubstitution(SyntaxKind.Identifier); // Keep track of class aliases. - classAliases = createMap(); + classAliases = []; } } @@ -3163,11 +3163,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; const savedCurrentSourceFile = currentSourceFile; @@ -3183,7 +3183,7 @@ namespace ts { applicableSubstitutions |= TypeScriptSubstitutionFlags.NonQualifiedEnumMembers; } - previousOnEmitNode(emitContext, node, emitCallback); + previousOnEmitNode(hint, node, emitCallback); applicableSubstitutions = savedApplicableSubstitutions; currentSourceFile = savedCurrentSourceFile; @@ -3192,12 +3192,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)) { diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index a7304eebe4b..b1ffcff43a4 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -1,4 +1,4 @@ -/// +/// /// namespace ts { @@ -67,11 +67,13 @@ namespace ts { const gutterSeparator = " "; const resetEscapeSequence = "\u001b[0m"; const ellipsis = "..."; - const categoryFormatMap = createMap({ - [DiagnosticCategory.Warning]: yellowForegroundEscapeSequence, - [DiagnosticCategory.Error]: redForegroundEscapeSequence, - [DiagnosticCategory.Message]: blueForegroundEscapeSequence, - }); + function getCategoryFormat(category: DiagnosticCategory): string { + switch (category) { + case DiagnosticCategory.Warning: return yellowForegroundEscapeSequence; + case DiagnosticCategory.Error: return redForegroundEscapeSequence; + case DiagnosticCategory.Message: return blueForegroundEscapeSequence; + } + } function formatAndReset(text: string, formatStyle: string) { return formatStyle + text + resetEscapeSequence; @@ -139,7 +141,7 @@ namespace ts { output += `${ relativeFileName }(${ firstLine + 1 },${ firstLineChar + 1 }): `; } - const categoryColor = categoryFormatMap[diagnostic.category]; + const categoryColor = getCategoryFormat(diagnostic.category); const category = DiagnosticCategory[diagnostic.category].toLowerCase(); output += `${ formatAndReset(category, categoryColor) } TS${ diagnostic.code }: ${ flattenDiagnosticMessageText(diagnostic.messageText, sys.newLine) }`; output += sys.newLine + sys.newLine; @@ -155,7 +157,7 @@ namespace ts { output += `${ diagnostic.file.fileName }(${ loc.line + 1 },${ loc.character + 1 }): `; } - output += `${ flattenDiagnosticMessageText(diagnostic.messageText, sys.newLine) }${ sys.newLine }`; + output += `${ flattenDiagnosticMessageText(diagnostic.messageText, sys.newLine) }${ sys.newLine + sys.newLine + sys.newLine }`; sys.write(output); } @@ -378,9 +380,11 @@ namespace ts { } function cachedFileExists(fileName: string): boolean { - return fileName in cachedExistingFiles - ? cachedExistingFiles[fileName] - : cachedExistingFiles[fileName] = hostFileExists(fileName); + let fileExists = cachedExistingFiles.get(fileName); + if (fileExists === undefined) { + cachedExistingFiles.set(fileName, fileExists = hostFileExists(fileName)); + } + return fileExists; } function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void) { @@ -674,13 +678,9 @@ namespace ts { if (option.name === "lib") { description = getDiagnosticText(option.description); - const options: string[] = []; const element = (option).element; const typeMap = >element.type; - for (const key in typeMap) { - options.push(`'${key}'`); - } - optionsDescriptionMap[description] = options; + optionsDescriptionMap.set(description, arrayFrom(typeMap.keys()).map(key => `'${key}'`)); } else { description = getDiagnosticText(option.description); @@ -702,7 +702,7 @@ namespace ts { for (let i = 0; i < usageColumn.length; i++) { const usage = usageColumn[i]; const description = descriptionColumn[i]; - const kindsList = optionsDescriptionMap[description]; + const kindsList = optionsDescriptionMap.get(description); output.push(usage + makePadding(marginLength - usage.length + 2) + description + sys.newLine); if (kindsList) { diff --git a/src/compiler/tsconfig.json b/src/compiler/tsconfig.json index 1ed009444b1..52bb92ee1f0 100644 --- a/src/compiler/tsconfig.json +++ b/src/compiler/tsconfig.json @@ -3,8 +3,7 @@ "compilerOptions": { "removeComments": true, "outFile": "../../built/local/tsc.js", - "declaration": true, - "types": [ ] + "declaration": true }, "files": [ "core.ts", diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 3ec39ed7fca..432b6d25cc6 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1,11 +1,30 @@ -namespace ts { - +namespace ts { + /** + * Type of objects whose values are all of the same type. + * The `in` and `for-in` operators can *not* be safely used, + * since `Object.prototype` may be modified by outside code. + */ export interface MapLike { [index: string]: T; } - export interface Map extends MapLike { - __mapBrand: any; + /** ES6 Map interface. */ + export interface Map { + get(key: string): T; + has(key: string): boolean; + set(key: string, value: T): this; + delete(key: string): boolean; + clear(): void; + forEach(action: (value: T, key: string) => void): void; + readonly size: number; + keys(): Iterator; + values(): Iterator; + entries(): Iterator<[string, T]>; + } + + /** ES6 Iterator type. */ + export interface Iterator { + next(): { value: T, done: false } | { value: never, done: true }; } // branded string type used to store absolute, normalized and canonicalized paths @@ -329,6 +348,7 @@ namespace ts { EnumMember, // Top-level nodes SourceFile, + Bundle, // JSDoc nodes JSDocTypeExpression, @@ -402,7 +422,7 @@ namespace ts { LastBinaryOperator = CaretEqualsToken, FirstNode = QualifiedName, FirstJSDocNode = JSDocTypeExpression, - LastJSDocNode = JSDocLiteralType, + LastJSDocNode = JSDocNeverKeyword, FirstJSDocTagNode = JSDocComment, LastJSDocTagNode = JSDocNeverKeyword } @@ -2190,6 +2210,11 @@ namespace ts { /* @internal */ ambientModuleNames: string[]; } + export interface Bundle extends Node { + kind: SyntaxKind.Bundle; + sourceFiles: SourceFile[]; + } + export interface ScriptReferenceHost { getCompilerOptions(): CompilerOptions; getSourceFile(fileName: string): SourceFile; @@ -2347,8 +2372,13 @@ namespace ts { getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo; getSignaturesOfType(type: Type, kind: SignatureKind): Signature[]; getIndexTypeOfType(type: Type, kind: IndexKind): Type; - getBaseTypes(type: InterfaceType): ObjectType[]; + getBaseTypes(type: InterfaceType): BaseType[]; getReturnTypeOfSignature(signature: Signature): Type; + /** + * Gets the type of a parameter at a given position in a signature. + * Returns `any` if the index is not valid. + */ + /* @internal */ getParameterType(signature: Signature, parameterIndex: number): Type; getNonNullableType(type: Type): Type; getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; @@ -2696,6 +2726,7 @@ namespace ts { containingType?: UnionOrIntersectionType; // Containing union or intersection type for synthetic property leftSpread?: Symbol; // Left source for synthetic spread property rightSpread?: Symbol; // Right source for synthetic spread property + mappedTypeOrigin?: Symbol; // For a property on a mapped type, points back to the orignal 'T' from 'keyof T'. hasNonUniformType?: boolean; // True if constituents have non-uniform types isPartial?: boolean; // True if syntheric property of union type occurs in some but not all constituents isDiscriminantProperty?: boolean; // True if discriminant synthetic property @@ -2857,7 +2888,7 @@ namespace ts { // Enum types (TypeFlags.Enum) export interface EnumType extends Type { - memberTypes: Map; + memberTypes: EnumLiteralType[]; } // Enum types (TypeFlags.EnumLiteral) @@ -2894,9 +2925,12 @@ namespace ts { /* @internal */ resolvedBaseConstructorType?: Type; // Resolved base constructor type of class /* @internal */ - resolvedBaseTypes: ObjectType[]; // Resolved base types + resolvedBaseTypes: BaseType[]; // Resolved base types } + // Object type or intersection of object types + export type BaseType = ObjectType | IntersectionType; + export interface InterfaceTypeWithDeclaredMembers extends InterfaceType { declaredProperties: Symbol[]; // Declared members declaredCallSignatures: Signature[]; // Declared call signatures @@ -2929,7 +2963,9 @@ namespace ts { export interface UnionOrIntersectionType extends Type { types: Type[]; // Constituent types /* @internal */ - resolvedProperties: SymbolTable; // Cache of resolved properties + propertyCache: SymbolTable; // Cache of resolved properties + /* @internal */ + resolvedProperties: Symbol[]; /* @internal */ resolvedIndexType: IndexType; /* @internal */ @@ -2940,7 +2976,10 @@ namespace ts { export interface UnionType extends UnionOrIntersectionType { } - export interface IntersectionType extends UnionOrIntersectionType { } + export interface IntersectionType extends UnionOrIntersectionType { + /* @internal */ + resolvedApparentType: Type; + } export type StructuredType = ObjectType | UnionType | IntersectionType; @@ -3284,7 +3323,8 @@ namespace ts { export const enum JsxEmit { None = 0, Preserve = 1, - React = 2 + React = 2, + ReactNative = 3 } export const enum NewLineKind { @@ -3702,7 +3742,7 @@ namespace ts { flags?: EmitFlags; // Flags that customize emit commentRange?: TextRange; // The text range to use when emitting leading or trailing comments sourceMapRange?: TextRange; // The text range to use when emitting leading or trailing source mappings - tokenSourceMapRanges?: Map; // The text range to use when emitting source mappings for tokens + tokenSourceMapRanges?: TextRange[]; // The text range to use when emitting source mappings for tokens constantValue?: number; // The constant value of an expression externalHelpersModuleName?: Identifier; // The local name for an imported helpers module helpers?: EmitHelper[]; // Emit helpers for the node @@ -3779,8 +3819,7 @@ namespace ts { LastEmitHelper = AsyncValues } - /* @internal */ - export const enum EmitContext { + export const enum EmitHint { SourceFile, // Emitting a SourceFile Expression, // Emitting an Expression IdentifierName, // Emitting an IdentifierName @@ -3855,7 +3894,7 @@ namespace ts { * 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 @@ -3873,7 +3912,7 @@ namespace ts { * 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 */ @@ -3886,25 +3925,132 @@ namespace ts { /** * 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 f4748a09903..088dfe8a32b 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1,4 +1,4 @@ -/// +/// /* @internal */ namespace ts { @@ -70,11 +70,11 @@ namespace ts { } export function hasResolvedModule(sourceFile: SourceFile, moduleNameText: string): boolean { - return !!(sourceFile && sourceFile.resolvedModules && sourceFile.resolvedModules[moduleNameText]); + return !!(sourceFile && sourceFile.resolvedModules && sourceFile.resolvedModules.get(moduleNameText)); } export function getResolvedModule(sourceFile: SourceFile, moduleNameText: string): ResolvedModuleFull { - return hasResolvedModule(sourceFile, moduleNameText) ? sourceFile.resolvedModules[moduleNameText] : undefined; + return hasResolvedModule(sourceFile, moduleNameText) ? sourceFile.resolvedModules.get(moduleNameText) : undefined; } export function setResolvedModule(sourceFile: SourceFile, moduleNameText: string, resolvedModule: ResolvedModuleFull): void { @@ -82,7 +82,7 @@ namespace ts { sourceFile.resolvedModules = createMap(); } - sourceFile.resolvedModules[moduleNameText] = resolvedModule; + sourceFile.resolvedModules.set(moduleNameText, resolvedModule); } export function setResolvedTypeReferenceDirective(sourceFile: SourceFile, typeReferenceDirectiveName: string, resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective): void { @@ -90,7 +90,7 @@ namespace ts { sourceFile.resolvedTypeReferenceDirectiveNames = createMap(); } - sourceFile.resolvedTypeReferenceDirectiveNames[typeReferenceDirectiveName] = resolvedTypeReferenceDirective; + sourceFile.resolvedTypeReferenceDirectiveNames.set(typeReferenceDirectiveName, resolvedTypeReferenceDirective); } /* @internal */ @@ -112,7 +112,7 @@ namespace ts { } for (let i = 0; i < names.length; i++) { const newResolution = newResolutions[i]; - const oldResolution = oldResolutions && oldResolutions[names[i]]; + const oldResolution = oldResolutions && oldResolutions.get(names[i]); const changed = oldResolution ? !newResolution || !comparer(oldResolution, newResolution) @@ -341,16 +341,52 @@ namespace ts { } export function isBinaryOrOctalIntegerLiteral(node: LiteralLikeNode, text: string) { - if (node.kind === SyntaxKind.NumericLiteral && text.length > 1) { + return node.kind === SyntaxKind.NumericLiteral + && (getNumericLiteralFlags(text, /*hint*/ NumericLiteralFlags.BinaryOrOctal) & NumericLiteralFlags.BinaryOrOctal) !== 0; + } + + export const enum NumericLiteralFlags { + None = 0, + Hexadecimal = 1 << 0, + Binary = 1 << 1, + Octal = 1 << 2, + Scientific = 1 << 3, + + BinaryOrOctal = Binary | Octal, + BinaryOrOctalOrHexadecimal = BinaryOrOctal | Hexadecimal, + All = Hexadecimal | Binary | Octal | Scientific, + } + + /** + * Scans a numeric literal string to determine the form of the number. + * @param text Numeric literal text + * @param hint If `Scientific` or `All` is specified, performs a more expensive check to scan for scientific notation. + */ + export function getNumericLiteralFlags(text: string, hint?: NumericLiteralFlags) { + if (text.length > 1) { switch (text.charCodeAt(1)) { case CharacterCodes.b: case CharacterCodes.B: + return NumericLiteralFlags.Binary; case CharacterCodes.o: case CharacterCodes.O: - return true; + return NumericLiteralFlags.Octal; + case CharacterCodes.x: + case CharacterCodes.X: + return NumericLiteralFlags.Hexadecimal; + } + + if (hint & NumericLiteralFlags.Scientific) { + for (let i = text.length - 1; i >= 0; i--) { + switch (text.charCodeAt(i)) { + case CharacterCodes.e: + case CharacterCodes.E: + return NumericLiteralFlags.Scientific; + } + } } } - return false; + return NumericLiteralFlags.None; } function getQuotedEscapedLiteralText(leftQuote: string, text: string, rightQuote: string) { @@ -395,7 +431,7 @@ namespace ts { function isShorthandAmbientModule(node: Node): boolean { // The only kind of module that can be missing a body is a shorthand ambient module. - return node.kind === SyntaxKind.ModuleDeclaration && (!(node).body); + return node && node.kind === SyntaxKind.ModuleDeclaration && (!(node).body); } export function isBlockScopedContainerTopLevel(node: Node): boolean { @@ -1662,11 +1698,15 @@ namespace ts { node = parent; break; case SyntaxKind.ShorthandPropertyAssignment: - if ((parent).name !== node) { + if ((parent as ShorthandPropertyAssignment).name !== node) { return AssignmentKind.None; } - // Fall through + node = parent.parent; + break; case SyntaxKind.PropertyAssignment: + if ((parent as ShorthandPropertyAssignment).name === node) { + return AssignmentKind.None; + } node = parent.parent; break; default: @@ -1678,7 +1718,8 @@ namespace ts { // A node is an assignment target if it is on the left hand side of an '=' token, if it is parented by a property // assignment in an object literal that is an assignment target, or if it is parented by an array literal that is - // an assignment target. Examples include 'a = xxx', '{ p: a } = xxx', '[{ p: a}] = xxx'. + // an assignment target. Examples include 'a = xxx', '{ p: a } = xxx', '[{ a }] = xxx'. + // (Note that `p` is not a target in the above examples, only `a`.) export function isAssignmentTarget(node: Node): boolean { return getAssignmentTargetKind(node) !== AssignmentKind.None; } @@ -2095,16 +2136,19 @@ namespace ts { return undefined; } - export function getOriginalSourceFiles(sourceFiles: SourceFile[]) { - const originalSourceFiles: SourceFile[] = []; - for (const sourceFile of sourceFiles) { - const originalSourceFile = getParseTreeNode(sourceFile, isSourceFile); - if (originalSourceFile) { - originalSourceFiles.push(originalSourceFile); - } + export function getOriginalSourceFileOrBundle(sourceFileOrBundle: SourceFile | Bundle) { + if (sourceFileOrBundle.kind === SyntaxKind.Bundle) { + return updateBundle(sourceFileOrBundle, sameMap(sourceFileOrBundle.sourceFiles, getOriginalSourceFile)); } + return getOriginalSourceFile(sourceFileOrBundle); + } - return originalSourceFiles; + function getOriginalSourceFile(sourceFile: SourceFile) { + return getParseTreeNode(sourceFile, isSourceFile) || sourceFile; + } + + export function getOriginalSourceFiles(sourceFiles: SourceFile[]) { + return sameMap(sourceFiles, getOriginalSourceFile); } export function getOriginalNodeId(node: Node) { @@ -2328,22 +2372,16 @@ namespace ts { } function reattachFileDiagnostics(newFile: SourceFile): void { - if (!hasProperty(fileDiagnostics, newFile.fileName)) { - return; - } - - for (const diagnostic of fileDiagnostics[newFile.fileName]) { - diagnostic.file = newFile; - } + forEach(fileDiagnostics.get(newFile.fileName), diagnostic => diagnostic.file = newFile); } function add(diagnostic: Diagnostic): void { let diagnostics: Diagnostic[]; if (diagnostic.file) { - diagnostics = fileDiagnostics[diagnostic.file.fileName]; + diagnostics = fileDiagnostics.get(diagnostic.file.fileName); if (!diagnostics) { diagnostics = []; - fileDiagnostics[diagnostic.file.fileName] = diagnostics; + fileDiagnostics.set(diagnostic.file.fileName, diagnostics); } } else { @@ -2363,7 +2401,7 @@ namespace ts { function getDiagnostics(fileName?: string): Diagnostic[] { sortAndDeduplicate(); if (fileName) { - return fileDiagnostics[fileName] || []; + return fileDiagnostics.get(fileName) || []; } const allDiagnostics: Diagnostic[] = []; @@ -2373,9 +2411,9 @@ namespace ts { forEach(nonFileDiagnostics, pushDiagnostic); - for (const key in fileDiagnostics) { - forEach(fileDiagnostics[key], pushDiagnostic); - } + fileDiagnostics.forEach(diagnostics => { + forEach(diagnostics, pushDiagnostic); + }); return sortAndDeduplicateDiagnostics(allDiagnostics); } @@ -2388,9 +2426,9 @@ namespace ts { diagnosticsModified = false; nonFileDiagnostics = sortAndDeduplicateDiagnostics(nonFileDiagnostics); - for (const key in fileDiagnostics) { - fileDiagnostics[key] = sortAndDeduplicateDiagnostics(fileDiagnostics[key]); - } + fileDiagnostics.forEach((diagnostics, key) => { + fileDiagnostics.set(key, sortAndDeduplicateDiagnostics(diagnostics)); + }); } } @@ -2400,7 +2438,7 @@ namespace ts { // the map below must be updated. Note that this regexp *does not* include the 'delete' character. // There is no reason for this other than that JSON.stringify does not handle it either. const escapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; - const escapedCharsMap = createMap({ + const escapedCharsMap = createMapFromTemplate({ "\0": "\\0", "\t": "\\t", "\v": "\\v", @@ -2426,7 +2464,7 @@ namespace ts { } function getReplacement(c: string) { - return escapedCharsMap[c] || get16BitUnicodeEscapeSequence(c.charCodeAt(0)); + return escapedCharsMap.get(c) || get16BitUnicodeEscapeSequence(c.charCodeAt(0)); } export function isIntrinsicJsxName(name: string) { @@ -2449,23 +2487,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) { @@ -2617,102 +2638,57 @@ namespace ts { * @param host An EmitHost. * @param targetSourceFile An optional target source file to emit. */ - export function getSourceFilesToEmit(host: EmitHost, targetSourceFile?: SourceFile) { + export function getSourceFilesToEmit(host: EmitHost, targetSourceFile?: SourceFile): SourceFile[] { const options = host.getCompilerOptions(); + const isSourceFileFromExternalLibrary = (file: SourceFile) => host.isSourceFileFromExternalLibrary(file); if (options.outFile || options.out) { const moduleKind = getEmitModuleKind(options); const moduleEmitEnabled = moduleKind === ModuleKind.AMD || moduleKind === ModuleKind.System; - const sourceFiles = getAllEmittableSourceFiles(); // Can emit only sources that are not declaration file and are either non module code or module with --module or --target es6 specified - return filter(sourceFiles, moduleEmitEnabled ? isNonDeclarationFile : isBundleEmitNonExternalModule); + return filter(host.getSourceFiles(), sourceFile => + (moduleEmitEnabled || !isExternalModule(sourceFile)) && sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary)); } else { - const sourceFiles = targetSourceFile === undefined ? getAllEmittableSourceFiles() : [targetSourceFile]; - return filterSourceFilesInDirectory(sourceFiles, file => host.isSourceFileFromExternalLibrary(file)); - } - - function getAllEmittableSourceFiles() { - return options.noEmitForJsFiles ? filter(host.getSourceFiles(), sourceFile => !isSourceFileJavaScript(sourceFile)) : host.getSourceFiles(); + const sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile]; + return filter(sourceFiles, sourceFile => sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary)); } } - /** Don't call this for `--outFile`, just for `--outDir` or plain emit. */ - export function filterSourceFilesInDirectory(sourceFiles: SourceFile[], isSourceFileFromExternalLibrary: (file: SourceFile) => boolean): SourceFile[] { - return filter(sourceFiles, file => shouldEmitInDirectory(file, isSourceFileFromExternalLibrary)); - } - - function isNonDeclarationFile(sourceFile: SourceFile) { - return !isDeclarationFile(sourceFile); + /** Don't call this for `--outFile`, just for `--outDir` or plain emit. `--outFile` needs additional checks. */ + export function sourceFileMayBeEmitted(sourceFile: SourceFile, options: CompilerOptions, isSourceFileFromExternalLibrary: (file: SourceFile) => boolean) { + return !(options.noEmitForJsFiles && isSourceFileJavaScript(sourceFile)) && !isDeclarationFile(sourceFile) && !isSourceFileFromExternalLibrary(sourceFile); } /** - * Whether a file should be emitted in a non-`--outFile` case. - * Don't emit if source file is a declaration file, or was located under node_modules - */ - function shouldEmitInDirectory(sourceFile: SourceFile, isSourceFileFromExternalLibrary: (file: SourceFile) => boolean): boolean { - return isNonDeclarationFile(sourceFile) && !isSourceFileFromExternalLibrary(sourceFile); - } - - function isBundleEmitNonExternalModule(sourceFile: SourceFile) { - return isNonDeclarationFile(sourceFile) && !isExternalModule(sourceFile); - } - - /** - * Iterates over each source file to emit. The source files are expected to have been - * transformed for use by the pretty printer. - * - * Originally part of `forEachExpectedEmitFile`, this functionality was extracted to support - * transformations. + * Iterates over the source files that are expected to have an emit output. * * @param host An EmitHost. - * @param sourceFiles The transformed source files to emit. * @param action The action to execute. + * @param sourceFilesOrTargetSourceFile + * If an array, the full list of source files to emit. + * Else, calls `getSourceFilesToEmit` with the (optional) target source file to determine the list of source files to emit. */ - export function forEachTransformedEmitFile(host: EmitHost, sourceFiles: SourceFile[], - action: (jsFilePath: string, sourceMapFilePath: string, declarationFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) => void, + export function forEachEmittedFile( + host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle, emitOnlyDtsFiles: boolean) => void, + sourceFilesOrTargetSourceFile?: SourceFile[] | SourceFile, emitOnlyDtsFiles?: boolean) { + + const sourceFiles = isArray(sourceFilesOrTargetSourceFile) ? sourceFilesOrTargetSourceFile : getSourceFilesToEmit(host, sourceFilesOrTargetSourceFile); const options = host.getCompilerOptions(); - // Emit on each source file if (options.outFile || options.out) { - onBundledEmit(sourceFiles); - } - else { - for (const sourceFile of sourceFiles) { - // Don't emit if source file is a declaration file, or was located under node_modules - if (!isDeclarationFile(sourceFile) && !host.isSourceFileFromExternalLibrary(sourceFile)) { - onSingleFileEmit(host, sourceFile); - } - } - } - - function onSingleFileEmit(host: EmitHost, sourceFile: SourceFile) { - // JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also. - // So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve. - // For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve - let extension = ".js"; - if (options.jsx === JsxEmit.Preserve) { - if (isSourceFileJavaScript(sourceFile)) { - if (fileExtensionIs(sourceFile.fileName, ".jsx")) { - extension = ".jsx"; - } - } - else if (sourceFile.languageVariant === LanguageVariant.JSX) { - // TypeScript source file preserving JSX syntax - extension = ".jsx"; - } - } - const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, extension); - const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options); - const declarationFilePath = !isSourceFileJavaScript(sourceFile) && (options.declaration || emitOnlyDtsFiles) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined; - action(jsFilePath, sourceMapFilePath, declarationFilePath, [sourceFile], /*isBundledEmit*/ false); - } - - function onBundledEmit(sourceFiles: SourceFile[]) { if (sourceFiles.length) { 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); + action({ jsFilePath, sourceMapFilePath, declarationFilePath }, createBundle(sourceFiles), emitOnlyDtsFiles); + } + } + else { + for (const sourceFile of sourceFiles) { + 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, emitOnlyDtsFiles); } } } @@ -2721,77 +2697,22 @@ namespace ts { return options.sourceMap ? jsFilePath + ".map" : undefined; } - /** - * Iterates over the source files that are expected to have an emit output. This function - * is used by the legacy emitter and the declaration emitter and should not be used by - * the tree transforming emitter. - * - * @param host An EmitHost. - * @param action The action to execute. - * @param targetSourceFile An optional target source file to emit. - */ - export function forEachExpectedEmitFile(host: EmitHost, - action: (emitFileNames: EmitFileNames, sourceFiles: SourceFile[], isBundledEmit: boolean, emitOnlyDtsFiles: boolean) => void, - targetSourceFile?: SourceFile, - emitOnlyDtsFiles?: boolean) { - const options = host.getCompilerOptions(); - // Emit on each source file - if (options.outFile || options.out) { - onBundledEmit(host); - } - else { - const sourceFiles = targetSourceFile === undefined ? getSourceFilesToEmit(host) : [targetSourceFile]; - for (const sourceFile of sourceFiles) { - if (shouldEmitInDirectory(sourceFile, file => host.isSourceFileFromExternalLibrary(file))) { - onSingleFileEmit(host, sourceFile); + // JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also. + // So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve. + // For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve + function getOutputExtension(sourceFile: SourceFile, options: CompilerOptions): string { + if (options.jsx === JsxEmit.Preserve) { + if (isSourceFileJavaScript(sourceFile)) { + if (fileExtensionIs(sourceFile.fileName, ".jsx")) { + return ".jsx"; } } - } - - function onSingleFileEmit(host: EmitHost, sourceFile: SourceFile) { - // JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also. - // So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve. - // For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve - let extension = ".js"; - if (options.jsx === JsxEmit.Preserve) { - if (isSourceFileJavaScript(sourceFile)) { - if (fileExtensionIs(sourceFile.fileName, ".jsx")) { - extension = ".jsx"; - } - } - else if (sourceFile.languageVariant === LanguageVariant.JSX) { - // TypeScript source file preserving JSX syntax - extension = ".jsx"; - } - } - const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, extension); - const declarationFilePath = !isSourceFileJavaScript(sourceFile) && (emitOnlyDtsFiles || options.declaration) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined; - const emitFileNames: EmitFileNames = { - jsFilePath, - sourceMapFilePath: getSourceMapFilePath(jsFilePath, options), - declarationFilePath - }; - action(emitFileNames, [sourceFile], /*isBundledEmit*/false, emitOnlyDtsFiles); - } - - function onBundledEmit(host: EmitHost) { - // Can emit only sources that are not declaration file and are either non module code or module with - // --module or --target es6 specified. Files included by searching under node_modules are also not emitted. - const bundledSources = filter(getSourceFilesToEmit(host), - sourceFile => !isDeclarationFile(sourceFile) && - !host.isSourceFileFromExternalLibrary(sourceFile) && - (!isExternalModule(sourceFile) || - !!getEmitModuleKind(options))); - if (bundledSources.length) { - const jsFilePath = options.outFile || options.out; - const emitFileNames: EmitFileNames = { - jsFilePath, - sourceMapFilePath: getSourceMapFilePath(jsFilePath, options), - declarationFilePath: options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : undefined - }; - action(emitFileNames, bundledSources, /*isBundledEmit*/true, emitOnlyDtsFiles); + else if (sourceFile.languageVariant === LanguageVariant.JSX) { + // TypeScript source file preserving JSX syntax + return ".jsx"; } } + return ".js"; } export function getSourceFilePathInNewDir(sourceFile: SourceFile, host: EmitHost, newDirPath: string) { @@ -3253,7 +3174,11 @@ namespace ts { } export function getLocalSymbolForExportDefault(symbol: Symbol) { - return symbol && symbol.valueDeclaration && hasModifier(symbol.valueDeclaration, ModifierFlags.Default) ? symbol.valueDeclaration.localSymbol : undefined; + return isExportDefaultSymbol(symbol) ? symbol.valueDeclaration.localSymbol : undefined; + } + + export function isExportDefaultSymbol(symbol: Symbol): boolean { + return symbol && symbol.valueDeclaration && hasModifier(symbol.valueDeclaration, ModifierFlags.Default); } /** Return ".ts", ".d.ts", or ".tsx", if that is the extension. */ @@ -3338,7 +3263,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; } @@ -3426,18 +3351,21 @@ namespace ts { return false; } - const syntaxKindCache = createMap(); + const syntaxKindCache: string[] = []; export function formatSyntaxKind(kind: SyntaxKind): string { const syntaxKindEnum = (ts).SyntaxKind; if (syntaxKindEnum) { - if (syntaxKindCache[kind]) { - return syntaxKindCache[kind]; + const cached = syntaxKindCache[kind]; + if (cached !== undefined) { + return cached; } for (const name in syntaxKindEnum) { if (syntaxKindEnum[name] === kind) { - return syntaxKindCache[kind] = kind.toString() + " (" + name + ")"; + const result = `${kind} (${name})`; + syntaxKindCache[kind] = result; + return result; } } } diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 6432670cea1..49c3b0208d5 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -1,4 +1,4 @@ -/// +/// /// /// @@ -46,54 +46,56 @@ namespace ts { * supplant the existing `forEachChild` implementation if performance is not * significantly impacted. */ - const nodeEdgeTraversalMap = createMap({ - [SyntaxKind.QualifiedName]: [ - { name: "left", test: isEntityName }, - { name: "right", test: isIdentifier } - ], - [SyntaxKind.Decorator]: [ - { name: "expression", test: isLeftHandSideExpression } - ], - [SyntaxKind.TypeAssertionExpression]: [ - { name: "type", test: isTypeNode }, - { name: "expression", test: isUnaryExpression } - ], - [SyntaxKind.AsExpression]: [ - { name: "expression", test: isExpression }, - { name: "type", test: isTypeNode } - ], - [SyntaxKind.NonNullExpression]: [ - { name: "expression", test: isLeftHandSideExpression } - ], - [SyntaxKind.EnumDeclaration]: [ - { name: "decorators", test: isDecorator }, - { name: "modifiers", test: isModifier }, - { name: "name", test: isIdentifier }, - { name: "members", test: isEnumMember } - ], - [SyntaxKind.ModuleDeclaration]: [ - { name: "decorators", test: isDecorator }, - { name: "modifiers", test: isModifier }, - { name: "name", test: isModuleName }, - { name: "body", test: isModuleBody } - ], - [SyntaxKind.ModuleBlock]: [ - { name: "statements", test: isStatement } - ], - [SyntaxKind.ImportEqualsDeclaration]: [ - { name: "decorators", test: isDecorator }, - { name: "modifiers", test: isModifier }, - { name: "name", test: isIdentifier }, - { name: "moduleReference", test: isModuleReference } - ], - [SyntaxKind.ExternalModuleReference]: [ - { name: "expression", test: isExpression, optional: true } - ], - [SyntaxKind.EnumMember]: [ - { name: "name", test: isPropertyName }, - { name: "initializer", test: isExpression, optional: true, parenthesize: parenthesizeExpressionForList } - ] - }); + 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; @@ -530,7 +532,7 @@ namespace ts { break; default: - const edgeTraversalPath = nodeEdgeTraversalMap[kind]; + const edgeTraversalPath = getNodeEdgeTraversal(kind); if (edgeTraversalPath) { for (const edge of edgeTraversalPath) { const value = (>node)[edge.name]; @@ -1192,10 +1194,10 @@ namespace ts { default: let updated: Node & MapLike; - const edgeTraversalPath = nodeEdgeTraversalMap[kind]; + const edgeTraversalPath = getNodeEdgeTraversal(kind); if (edgeTraversalPath) { for (const edge of edgeTraversalPath) { - const value = >(>node)[edge.name]; + const value = >(>node)[edge.name]; if (value !== undefined) { const visited = isArray(value) ? visitNodes(value, visitor, edge.test, 0, value.length, edge.parenthesize, node) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index f0f2f87175e..721647df0cd 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -40,7 +40,7 @@ namespace FourSlash { files: FourSlashFile[]; // A mapping from marker names to name/position pairs - markerPositions: { [index: string]: Marker; }; + markerPositions: ts.Map; markers: Marker[]; @@ -61,10 +61,6 @@ namespace FourSlash { data?: any; } - interface MarkerMap { - [index: string]: Marker; - } - export interface Range { fileName: string; start: number; @@ -94,7 +90,7 @@ namespace FourSlash { export import IndentStyle = ts.IndentStyle; - const entityMap = ts.createMap({ + const entityMap = ts.createMapFromTemplate({ "&": "&", "\"": """, "'": "'", @@ -104,7 +100,7 @@ namespace FourSlash { }); export function escapeXmlAttributeValue(s: string) { - return s.replace(/[&<>"'\/]/g, ch => entityMap[ch]); + return s.replace(/[&<>"'\/]/g, ch => entityMap.get(ch)); } // Name of testcase metadata including ts.CompilerOptions properties that will be used by globalOptions @@ -230,7 +226,7 @@ namespace FourSlash { } function tryAdd(path: string) { - const inputFile = inputFiles[path]; + const inputFile = inputFiles.get(path); if (inputFile && !Harness.isDefaultLibraryFile(path)) { languageServiceAdapterHost.addScript(path, inputFile, /*isRootFile*/ true); return true; @@ -265,7 +261,7 @@ namespace FourSlash { let configFileName: string; ts.forEach(testData.files, file => { // Create map between fileName and its content for easily looking up when resolveReference flag is specified - this.inputFiles[file.fileName] = file.content; + this.inputFiles.set(file.fileName, file.content); if (ts.getBaseFileName(file.fileName).toLowerCase() === "tsconfig.json") { configFileName = file.fileName; } @@ -283,7 +279,7 @@ namespace FourSlash { const baseDir = ts.normalizePath(ts.getDirectoryPath(configFileName)); const host = new Utils.MockParseConfigHost(baseDir, /*ignoreCase*/ false, this.inputFiles); - const configJsonObj = ts.parseConfigFileTextToJson(configFileName, this.inputFiles[configFileName]); + const configJsonObj = ts.parseConfigFileTextToJson(configFileName, this.inputFiles.get(configFileName)); assert.isTrue(configJsonObj.config !== undefined); const { options, errors } = ts.parseJsonConfigFileContent(configJsonObj.config, host, baseDir); @@ -334,11 +330,11 @@ namespace FourSlash { } else { // resolveReference file-option is not specified then do not resolve any files and include all inputFiles - for (const fileName in this.inputFiles) { + this.inputFiles.forEach((file, fileName) => { if (!Harness.isDefaultLibraryFile(fileName)) { - this.languageServiceAdapterHost.addScript(fileName, this.inputFiles[fileName], /*isRootFile*/ true); + this.languageServiceAdapterHost.addScript(fileName, file, /*isRootFile*/ true); } - } + }); this.languageServiceAdapterHost.addScript(Harness.Compiler.defaultLibFileName, Harness.Compiler.getDefaultLibrarySourceFile().text, /*isRootFile*/ false); } @@ -376,8 +372,8 @@ namespace FourSlash { } // Entry points from fourslash.ts - public goToMarker(name = "") { - const marker = this.getMarkerByName(name); + public goToMarker(name: string | Marker = "") { + const marker = typeof name === "string" ? this.getMarkerByName(name) : name; if (this.activeFile.fileName !== marker.fileName) { this.openFile(marker.fileName); } @@ -386,10 +382,37 @@ namespace FourSlash { if (marker.position === -1 || marker.position > content.length) { throw new Error(`Marker "${name}" has been invalidated by unrecoverable edits to the file.`); } - this.lastKnownMarker = name; + const mName = typeof name === "string" ? name : this.markerName(marker); + this.lastKnownMarker = mName; this.goToPosition(marker.position); } + public goToEachMarker(action: () => void) { + const markers = this.getMarkers(); + assert(markers.length); + for (const marker of markers) { + this.goToMarker(marker); + action(); + } + } + + public goToEachRange(action: () => void) { + const ranges = this.getRanges(); + assert(ranges.length); + for (const range of ranges) { + this.goToRangeStart(range); + action(); + } + } + + private markerName(m: Marker): string { + return ts.forEachEntry(this.testData.markerPositions, (marker, name) => { + if (marker === m) { + return name; + } + })!; + } + public goToPosition(pos: number) { this.currentCaretPosition = pos; } @@ -684,11 +707,12 @@ namespace FourSlash { const completions = this.getCompletionListAtCaret(); const uniqueItems = ts.createMap(); for (const item of completions.entries) { - if (!(item.name in uniqueItems)) { - uniqueItems[item.name] = item.kind; + const uniqueItem = uniqueItems.get(item.name); + if (!uniqueItem) { + uniqueItems.set(item.name, item.kind); } else { - assert.equal(item.kind, uniqueItems[item.name], `Items should have the same kind, got ${item.kind} and ${uniqueItems[item.name]}`); + assert.equal(item.kind, uniqueItem, `Items should have the same kind, got ${item.kind} and ${uniqueItem}`); } } } @@ -862,9 +886,8 @@ namespace FourSlash { } } - public verifyReferencesOf({fileName, start}: Range, references: Range[]) { - this.openFile(fileName); - this.goToPosition(start); + public verifyReferencesOf(range: Range, references: Range[]) { + this.goToRangeStart(range); this.verifyReferencesAre(references); } @@ -877,7 +900,7 @@ namespace FourSlash { } public verifyRangesWithSameTextReferenceEachOther() { - ts.forEachProperty(this.rangesByText(), ranges => this.verifyRangesReferenceEachOther(ranges)); + this.rangesByText().forEach(ranges => this.verifyRangesReferenceEachOther(ranges)); } public verifyDisplayPartsOfReferencedSymbol(expected: ts.SymbolDisplayPart[]) { @@ -949,7 +972,8 @@ namespace FourSlash { } public verifyQuickInfos(namesAndTexts: { [name: string]: string | [string, string] }) { - ts.forEachProperty(ts.createMap(namesAndTexts), (text, name) => { + for (const name in namesAndTexts) if (ts.hasProperty(namesAndTexts, name)) { + const text = namesAndTexts[name]; if (text instanceof Array) { assert(text.length === 2); const [expectedText, expectedDocumentation] = text; @@ -958,7 +982,7 @@ namespace FourSlash { else { this.verifyQuickInfoAt(name, text); } - }); + } } public verifyQuickInfoString(expectedText: string, expectedDocumentation?: string) { @@ -1671,6 +1695,11 @@ namespace FourSlash { this.goToPosition(len); } + public goToRangeStart({fileName, start}: Range) { + this.openFile(fileName); + this.goToPosition(start); + } + public goToTypeDefinition(definitionIndex: number) { const definitions = this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); if (!definitions || !definitions.length) { @@ -1796,7 +1825,7 @@ namespace FourSlash { } public getMarkerNames(): string[] { - return Object.keys(this.testData.markerPositions); + return ts.arrayFrom(this.testData.markerPositions.keys()); } public getRanges(): Range[] { @@ -1804,10 +1833,10 @@ namespace FourSlash { } public rangesByText(): ts.Map { - const result = ts.createMap(); + const result = ts.createMultiMap(); for (const range of this.getRanges()) { const text = this.rangeText(range); - ts.multiMapAdd(result, text, range); + result.add(text, range); } return result; } @@ -2163,7 +2192,7 @@ namespace FourSlash { public verifyBraceCompletionAtPosition(negative: boolean, openingBrace: string) { - const openBraceMap = ts.createMap({ + const openBraceMap = ts.createMapFromTemplate({ "(": ts.CharacterCodes.openParen, "{": ts.CharacterCodes.openBrace, "[": ts.CharacterCodes.openBracket, @@ -2173,7 +2202,7 @@ namespace FourSlash { "<": ts.CharacterCodes.lessThan }); - const charCode = openBraceMap[openingBrace]; + const charCode = openBraceMap.get(openingBrace); if (!charCode) { this.raiseError(`Invalid openingBrace '${openingBrace}' specified.`); @@ -2363,40 +2392,60 @@ namespace FourSlash { return this.languageService.getDocumentHighlights(this.activeFile.fileName, this.currentCaretPosition, filesToSearch); } - public verifyDocumentHighlightsAtPositionListContains(fileName: string, start: number, end: number, fileNamesToSearch: string[], kind?: string) { - const documentHighlights = this.getDocumentHighlightsAtCurrentPosition(fileNamesToSearch); - - if (!documentHighlights || documentHighlights.length === 0) { - this.raiseError("verifyDocumentHighlightsAtPositionListContains failed - found 0 highlights, expected at least one."); + public verifyRangesAreOccurrences(isWriteAccess?: boolean) { + const ranges = this.getRanges(); + for (const r of ranges) { + this.goToRangeStart(r); + this.verifyOccurrencesAtPositionListCount(ranges.length); + for (const range of ranges) { + this.verifyOccurrencesAtPositionListContains(range.fileName, range.start, range.end, isWriteAccess); + } } + } - for (const documentHighlight of documentHighlights) { - if (documentHighlight.fileName === fileName) { - const { highlightSpans } = documentHighlight; + public verifyRangesAreRenameLocations(findInStrings: boolean, findInComments: boolean) { + this.goToEachRange(() => this.verifyRenameLocations(findInStrings, findInComments)); + } - for (const highlight of highlightSpans) { - if (highlight && highlight.textSpan.start === start && ts.textSpanEnd(highlight.textSpan) === end) { - if (typeof kind !== "undefined" && highlight.kind !== kind) { - this.raiseError(`verifyDocumentHighlightsAtPositionListContains failed - item "kind" value does not match, actual: ${highlight.kind}, expected: ${kind}.`); - } - return; - } - } + public verifyRangesWithSameTextAreDocumentHighlights() { + this.rangesByText().forEach(ranges => this.verifyRangesAreDocumentHighlights(ranges)); + } + + public verifyRangesAreDocumentHighlights(ranges?: Range[]) { + ranges = ranges || this.getRanges(); + const fileNames = unique(ranges, range => range.fileName); + for (const range of ranges) { + this.goToRangeStart(range); + this.verifyDocumentHighlights(ranges, fileNames); + } + } + + private verifyDocumentHighlights(expectedRanges: Range[], fileNames: string[] = [this.activeFile.fileName]) { + const documentHighlights = this.getDocumentHighlightsAtCurrentPosition(fileNames) || []; + + for (const dh of documentHighlights) { + if (fileNames.indexOf(dh.fileName) === -1) { + this.raiseError(`verifyDocumentHighlights failed - got highlights in unexpected file name ${dh.fileName}`); } } - const missingItem = { fileName: fileName, start: start, end: end, kind: kind }; - this.raiseError(`verifyDocumentHighlightsAtPositionListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(documentHighlights)})`); - } + for (const fileName of fileNames) { + const expectedRangesInFile = expectedRanges.filter(r => r.fileName === fileName); + const highlights = ts.find(documentHighlights, dh => dh.fileName === fileName); + if (!highlights) { + this.raiseError(`verifyDocumentHighlights failed - found no highlights in ${fileName}`); + } + const spansInFile = highlights.highlightSpans.sort((s1, s2) => s1.textSpan.start - s2.textSpan.start); - public verifyDocumentHighlightsAtPositionListCount(expectedCount: number, fileNamesToSearch: string[]) { - const documentHighlights = this.getDocumentHighlightsAtCurrentPosition(fileNamesToSearch); - const actualCount = documentHighlights - ? documentHighlights.reduce((currentCount, { highlightSpans }) => currentCount + highlightSpans.length, 0) - : 0; + if (expectedRangesInFile.length !== spansInFile.length) { + this.raiseError(`verifyDocumentHighlights failed - In ${fileName}, expected ${expectedRangesInFile.length} highlights, got ${spansInFile.length}`); + } - if (expectedCount !== actualCount) { - this.raiseError("verifyDocumentHighlightsAtPositionListCount failed - actual: " + actualCount + ", expected:" + expectedCount); + ts.zipWith(expectedRangesInFile, spansInFile, (expectedRange, span) => { + if (span.textSpan.start !== expectedRange.start || ts.textSpanEnd(span.textSpan) !== expectedRange.end) { + this.raiseError(`verifyDocumentHighlights failed - span does not match, actual: ${JSON.stringify(span.textSpan)}, expected: ${expectedRange.start}--${expectedRange.end}`); + } + }); } } @@ -2529,11 +2578,9 @@ namespace FourSlash { } public getMarkerByName(markerName: string) { - const markerPos = this.testData.markerPositions[markerName]; + const markerPos = this.testData.markerPositions.get(markerName); if (markerPos === undefined) { - const markerNames: string[] = []; - for (const m in this.testData.markerPositions) markerNames.push(m); - throw new Error(`Unknown marker "${markerName}" Available markers: ${markerNames.map(m => "\"" + m + "\"").join(", ")}`); + throw new Error(`Unknown marker "${markerName}" Available markers: ${this.getMarkerNames().map(m => "\"" + m + "\"").join(", ")}`); } else { return markerPos; @@ -2626,7 +2673,7 @@ ${code} // we have to string-based splitting instead and try to figure out the delimiting chars const lines = contents.split("\n"); - const markerPositions: MarkerMap = {}; + const markerPositions = ts.createMap(); const markers: Marker[] = []; const ranges: Range[] = []; @@ -2765,7 +2812,7 @@ ${code} throw new Error(errorMessage); } - function recordObjectMarker(fileName: string, location: LocationInformation, text: string, markerMap: MarkerMap, markers: Marker[]): Marker { + function recordObjectMarker(fileName: string, location: LocationInformation, text: string, markerMap: ts.Map, markers: Marker[]): Marker { let markerValue: any = undefined; try { // Attempt to parse the marker value as JSON @@ -2788,7 +2835,7 @@ ${code} // Object markers can be anonymous if (markerValue.name) { - markerMap[markerValue.name] = marker; + markerMap.set(markerValue.name, marker); } markers.push(marker); @@ -2796,26 +2843,26 @@ ${code} return marker; } - function recordMarker(fileName: string, location: LocationInformation, name: string, markerMap: MarkerMap, markers: Marker[]): Marker { + function recordMarker(fileName: string, location: LocationInformation, name: string, markerMap: ts.Map, markers: Marker[]): Marker { const marker: Marker = { fileName, position: location.position }; // Verify markers for uniqueness - if (markerMap[name] !== undefined) { + if (markerMap.has(name)) { const message = "Marker '" + name + "' is duplicated in the source file contents."; reportError(marker.fileName, location.sourceLine, location.sourceColumn, message); return undefined; } else { - markerMap[name] = marker; + markerMap.set(name, marker); markers.push(marker); return marker; } } - function parseFileContent(content: string, fileName: string, markerMap: MarkerMap, markers: Marker[], ranges: Range[]): FourSlashFile { + function parseFileContent(content: string, fileName: string, markerMap: ts.Map, markers: Marker[], ranges: Range[]): FourSlashFile { content = chompLeadingSpace(content); // Any slash-star comment with a character not in this string is not a marker. @@ -3025,6 +3072,16 @@ ${code} function stringify(data: any, replacer?: (key: string, value: any) => any): string { return JSON.stringify(data, replacer, 2); } + + /** Collects an array of unique outputs. */ + function unique(inputs: T[], getOutput: (t: T) => string): string[] { + const set = ts.createMap(); + for (const input of inputs) { + const out = getOutput(input); + set.set(out, true); + } + return ts.arrayFrom(set.keys()); + } } namespace FourSlashInterface { @@ -3063,10 +3120,22 @@ namespace FourSlashInterface { // Moves the caret to the specified marker, // or the anonymous marker ('/**/') if no name // is given - public marker(name?: string) { + public marker(name?: string | FourSlash.Marker) { this.state.goToMarker(name); } + public eachMarker(action: () => void) { + this.state.goToEachMarker(action); + } + + public rangeStart(range: FourSlash.Range) { + this.state.goToRangeStart(range); + } + + public eachRange(action: () => void) { + this.state.goToEachRange(action); + } + public bof() { this.state.goToBOF(); } @@ -3417,12 +3486,20 @@ namespace FourSlashInterface { this.state.verifyOccurrencesAtPositionListCount(expectedCount); } - public documentHighlightsAtPositionContains(range: FourSlash.Range, fileNamesToSearch: string[], kind?: string) { - this.state.verifyDocumentHighlightsAtPositionListContains(range.fileName, range.start, range.end, fileNamesToSearch, kind); + public rangesAreOccurrences(isWriteAccess?: boolean) { + this.state.verifyRangesAreOccurrences(isWriteAccess); } - public documentHighlightsAtPositionCount(expectedCount: number, fileNamesToSearch: string[]) { - this.state.verifyDocumentHighlightsAtPositionListCount(expectedCount, fileNamesToSearch); + public rangesAreRenameLocations(findInStrings = false, findInComments = false) { + this.state.verifyRangesAreRenameLocations(findInStrings, findInComments); + } + + public rangesAreDocumentHighlights(ranges?: FourSlash.Range[]) { + this.state.verifyRangesAreDocumentHighlights(ranges); + } + + public rangesWithSameTextAreDocumentHighlights() { + this.state.verifyRangesWithSameTextAreDocumentHighlights(); } public completionEntryDetailIs(entryName: string, text: string, documentation?: string, kind?: string) { diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 4094fc773ea..1dd41f9d81c 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -40,6 +40,19 @@ declare namespace NodeJS { ActiveXObject: typeof ActiveXObject; } } + +declare var window: {}; +declare var XMLHttpRequest: { + new(): XMLHttpRequest; +} +interface XMLHttpRequest { + readonly readyState: number; + readonly responseText: string; + readonly status: number; + open(method: string, url: string, async?: boolean, user?: string, password?: string): void; + send(data?: string): void; + setRequestHeader(header: string, value: string): void; +} /* tslint:enable:no-var-keyword */ namespace Utils { @@ -909,7 +922,7 @@ namespace Harness { export const defaultLibFileName = "lib.d.ts"; export const es2015DefaultLibFileName = "lib.es2015.d.ts"; - const libFileNameSourceFileMap = ts.createMap({ + const libFileNameSourceFileMap = ts.createMapFromTemplate({ [defaultLibFileName]: createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.es5.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest) }); @@ -918,10 +931,11 @@ namespace Harness { return undefined; } - if (!libFileNameSourceFileMap[fileName]) { - libFileNameSourceFileMap[fileName] = createSourceFileAndAssertInvariants(fileName, IO.readFile(libFolder + fileName), ts.ScriptTarget.Latest); + let sourceFile = libFileNameSourceFileMap.get(fileName); + if (!sourceFile) { + libFileNameSourceFileMap.set(fileName, sourceFile = createSourceFileAndAssertInvariants(fileName, IO.readFile(libFolder + fileName), ts.ScriptTarget.Latest)); } - return libFileNameSourceFileMap[fileName]; + return sourceFile; } export function getDefaultLibFileName(options: ts.CompilerOptions): string { @@ -1103,10 +1117,10 @@ namespace Harness { optionsIndex = ts.createMap(); const optionDeclarations = harnessOptionDeclarations.concat(ts.optionDeclarations); for (const option of optionDeclarations) { - optionsIndex[option.name.toLowerCase()] = option; + optionsIndex.set(option.name.toLowerCase(), option); } } - return optionsIndex[name.toLowerCase()]; + return optionsIndex.get(name.toLowerCase()); } export function setCompilerOptionsFromHarnessSetting(settings: Harness.TestCaseParser.CompilerSettings, options: ts.CompilerOptions & HarnessOptions): void { @@ -1466,7 +1480,7 @@ namespace Harness { const fullResults = ts.createMap(); for (const sourceFile of allFiles) { - fullResults[sourceFile.unitName] = fullWalker.getTypeAndSymbols(sourceFile.unitName); + fullResults.set(sourceFile.unitName, fullWalker.getTypeAndSymbols(sourceFile.unitName)); } // Produce baselines. The first gives the types for all expressions. @@ -1519,7 +1533,7 @@ namespace Harness { allFiles.forEach(file => { const codeLines = file.content.split("\n"); - typeWriterResults[file.unitName].forEach(result => { + typeWriterResults.get(file.unitName).forEach(result => { if (isSymbolBaseline && !result.symbol) { return; } diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index a49f8926729..cd44fbf7a3a 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -262,7 +262,7 @@ namespace Harness.LanguageService { this.getModuleResolutionsForFile = (fileName) => { const scriptInfo = this.getScriptInfo(fileName); const preprocessInfo = ts.preProcessFile(scriptInfo.content, /*readImportFiles*/ true); - const imports = ts.createMap(); + const imports: ts.MapLike = {}; for (const module of preprocessInfo.importedFiles) { const resolutionInfo = ts.resolveModuleName(module.fileName, fileName, compilerOptions, moduleResolutionHost); if (resolutionInfo.resolvedModule) { @@ -275,7 +275,7 @@ namespace Harness.LanguageService { const scriptInfo = this.getScriptInfo(fileName); if (scriptInfo) { const preprocessInfo = ts.preProcessFile(scriptInfo.content, /*readImportFiles*/ false); - const resolutions = ts.createMap(); + const resolutions: ts.MapLike = {}; const settings = this.nativeHost.getCompilationSettings(); for (const typeReferenceDirective of preprocessInfo.typeReferenceDirectives) { const resolutionInfo = ts.resolveTypeReferenceDirective(typeReferenceDirective.fileName, fileName, settings, moduleResolutionHost); diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index f7541dc9bfe..f1cc992c4a7 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -256,17 +256,20 @@ class ProjectRunner extends RunnerBase { // Set the values specified using json const optionNameMap = ts.arrayToMap(ts.optionDeclarations, option => option.name); for (const name in testCase) { - if (name !== "mapRoot" && name !== "sourceRoot" && name in optionNameMap) { - const option = optionNameMap[name]; - const optType = option.type; - let value = testCase[name]; - if (typeof optType !== "string") { - const key = value.toLowerCase(); - if (key in optType) { - value = optType[key]; + if (name !== "mapRoot" && name !== "sourceRoot") { + const option = optionNameMap.get(name); + if (option) { + const optType = option.type; + let value = testCase[name]; + if (typeof optType !== "string") { + const key = value.toLowerCase(); + const optTypeValue = optType.get(key); + if (optTypeValue) { + value = optTypeValue; + } } + compilerOptions[option.name] = value; } - compilerOptions[option.name] = value; } } 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/cachingInServerLSHost.ts b/src/harness/unittests/cachingInServerLSHost.ts index 4286d3555d8..caeab18958e 100644 --- a/src/harness/unittests/cachingInServerLSHost.ts +++ b/src/harness/unittests/cachingInServerLSHost.ts @@ -1,4 +1,4 @@ -/// +/// namespace ts { interface File { @@ -8,25 +8,28 @@ namespace ts { function createDefaultServerHost(fileMap: Map): server.ServerHost { const existingDirectories = createMap(); - for (const name in fileMap) { + forEachKey(fileMap, name => { let dir = getDirectoryPath(name); let previous: string; do { - existingDirectories[dir] = true; + existingDirectories.set(dir, true); previous = dir; dir = getDirectoryPath(dir); } while (dir !== previous); - } + }); return { args: [], newLine: "\r\n", useCaseSensitiveFileNames: false, write: noop, - readFile: path => path in fileMap ? fileMap[path].content : undefined, + readFile: path => { + const file = fileMap.get(path); + return file && file.content; + }, writeFile: notImplemented, resolvePath: notImplemented, - fileExists: path => path in fileMap, - directoryExists: path => existingDirectories[path] || false, + fileExists: path => fileMap.has(path), + directoryExists: path => existingDirectories.get(path) || false, createDirectory: noop, getExecutingFilePath: () => "", getCurrentDirectory: () => "", @@ -83,7 +86,7 @@ namespace ts { content: `foo()` }; - const serverHost = createDefaultServerHost(createMap({ [root.name]: root, [imported.name]: imported })); + const serverHost = createDefaultServerHost(createMapFromTemplate({ [root.name]: root, [imported.name]: imported })); const { project, rootScriptInfo } = createProject(root.name, serverHost); // ensure that imported file was found @@ -167,7 +170,7 @@ namespace ts { content: `export var y = 1` }; - const fileMap = createMap({ [root.name]: root }); + const fileMap = createMapFromTemplate({ [root.name]: root }); const serverHost = createDefaultServerHost(fileMap); const originalFileExists = serverHost.fileExists; @@ -191,7 +194,7 @@ namespace ts { assert.isTrue(typeof diags[0].messageText === "string" && ((diags[0].messageText).indexOf("Cannot find module") === 0), "should be 'cannot find module' message"); // assert that import will success once file appear on disk - fileMap[imported.name] = imported; + fileMap.set(imported.name, imported); fileExistsCalledForBar = false; rootScriptInfo.editContent(0, root.content.length, `import {y} from "bar"`); diff --git a/src/harness/unittests/commandLineParsing.ts b/src/harness/unittests/commandLineParsing.ts index bb8be78d68a..8e5ed5f3534 100644 --- a/src/harness/unittests/commandLineParsing.ts +++ b/src/harness/unittests/commandLineParsing.ts @@ -87,7 +87,7 @@ namespace ts { start: undefined, length: undefined, }, { - messageText: "Argument for '--jsx' option must be: 'preserve', 'react'", + messageText: "Argument for '--jsx' option must be: 'preserve', 'react-native', 'react'", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, diff --git a/src/harness/unittests/configurationExtension.ts b/src/harness/unittests/configurationExtension.ts index 8e845925eb2..886ee5d54b5 100644 --- a/src/harness/unittests/configurationExtension.ts +++ b/src/harness/unittests/configurationExtension.ts @@ -2,7 +2,7 @@ /// namespace ts { - const testContents = { + const testContents = createMapFromTemplate({ "/dev/tsconfig.json": `{ "extends": "./configs/base", "files": [ @@ -86,10 +86,10 @@ namespace ts { "/dev/tests/utils.ts": "", "/dev/tests/scenarios/first.json": "", "/dev/tests/baselines/first/output.ts": "" - }; + }); const caseInsensitiveBasePath = "c:/dev/"; - const caseInsensitiveHost = new Utils.MockParseConfigHost(caseInsensitiveBasePath, /*useCaseSensitiveFileNames*/ false, mapObject(testContents, (key, content) => [`c:${key}`, content])); + const caseInsensitiveHost = new Utils.MockParseConfigHost(caseInsensitiveBasePath, /*useCaseSensitiveFileNames*/ false, mapEntries(testContents, (key, content) => [`c:${key}`, content])); const caseSensitiveBasePath = "/dev/"; const caseSensitiveHost = new Utils.MockParseConfigHost(caseSensitiveBasePath, /*useCaseSensitiveFileNames*/ true, testContents); diff --git a/src/harness/unittests/convertCompilerOptionsFromJson.ts b/src/harness/unittests/convertCompilerOptionsFromJson.ts index 42a915c50fb..26ca8e26df1 100644 --- a/src/harness/unittests/convertCompilerOptionsFromJson.ts +++ b/src/harness/unittests/convertCompilerOptionsFromJson.ts @@ -94,7 +94,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--jsx' option must be: 'preserve', 'react'", + messageText: "Argument for '--jsx' option must be: 'preserve', 'react-native', 'react'", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] diff --git a/src/harness/unittests/jsDocParsing.ts b/src/harness/unittests/jsDocParsing.ts index addd01b0e0a..98c32c77778 100644 --- a/src/harness/unittests/jsDocParsing.ts +++ b/src/harness/unittests/jsDocParsing.ts @@ -288,5 +288,24 @@ namespace ts { */`); }); }); + describe("getFirstToken", () => { + it("gets jsdoc", () => { + const root = ts.createSourceFile("foo.ts", "/** comment */var a = true;", ts.ScriptTarget.ES5, /*setParentNodes*/ true); + assert.isDefined(root); + assert.equal(root.kind, ts.SyntaxKind.SourceFile); + const first = root.getFirstToken(); + assert.isDefined(first); + assert.equal(first.kind, ts.SyntaxKind.VarKeyword); + }); + }); + describe("getLastToken", () => { + it("gets jsdoc", () => { + const root = ts.createSourceFile("foo.ts", "var a = true;/** comment */", ts.ScriptTarget.ES5, /*setParentNodes*/ true); + assert.isDefined(root); + const last = root.getLastToken(); + assert.isDefined(last); + assert.equal(last.kind, ts.SyntaxKind.EndOfFileToken); + }); + }); }); } diff --git a/src/harness/unittests/matchFiles.ts b/src/harness/unittests/matchFiles.ts index c562fcefe91..0a450c50151 100644 --- a/src/harness/unittests/matchFiles.ts +++ b/src/harness/unittests/matchFiles.ts @@ -346,9 +346,9 @@ namespace ts { fileNames: [ "c:/dev/a.ts", "c:/dev/b.ts", + "c:/dev/node_modules/a.ts", "c:/dev/bower_components/a.ts", - "c:/dev/jspm_packages/a.ts", - "c:/dev/node_modules/a.ts" + "c:/dev/jspm_packages/a.ts" ], wildcardDirectories: {}, }; @@ -373,9 +373,9 @@ namespace ts { options: {}, errors: [], fileNames: [ + "c:/dev/node_modules/a.ts", "c:/dev/bower_components/a.ts", - "c:/dev/jspm_packages/a.ts", - "c:/dev/node_modules/a.ts" + "c:/dev/jspm_packages/a.ts" ], wildcardDirectories: {}, }; @@ -398,9 +398,9 @@ namespace ts { fileNames: [ "c:/dev/a.ts", "c:/dev/b.ts", + "c:/dev/node_modules/a.ts", "c:/dev/bower_components/a.ts", - "c:/dev/jspm_packages/a.ts", - "c:/dev/node_modules/a.ts" + "c:/dev/jspm_packages/a.ts" ], wildcardDirectories: {}, }; @@ -410,6 +410,36 @@ namespace ts { }); describe("with wildcard include list", () => { + it("is sorted in include order, then in alphabetical order", () => { + const json = { + include: [ + "z/*.ts", + "x/*.ts" + ] + }; + const expected: ts.ParsedCommandLine = { + options: {}, + errors: [], + fileNames: [ + "c:/dev/z/a.ts", + "c:/dev/z/aba.ts", + "c:/dev/z/abz.ts", + "c:/dev/z/b.ts", + "c:/dev/z/bba.ts", + "c:/dev/z/bbz.ts", + "c:/dev/x/a.ts", + "c:/dev/x/aa.ts", + "c:/dev/x/b.ts" + ], + wildcardDirectories: { + "c:/dev/z": ts.WatchDirectoryFlags.None, + "c:/dev/x": ts.WatchDirectoryFlags.None + }, + }; + const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath); + assertParsed(actual, expected); + }); + it("same named declarations are excluded", () => { const json = { include: [ @@ -506,8 +536,8 @@ namespace ts { options: {}, errors: [], fileNames: [ - "c:/dev/x/a.ts", "c:/dev/x/y/a.ts", + "c:/dev/x/a.ts", "c:/dev/z/a.ts" ], wildcardDirectories: { @@ -909,6 +939,31 @@ namespace ts { const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); assertParsed(actual, expected); }); + it("with jsx=react-native, allowJs=false", () => { + const json = { + compilerOptions: { + jsx: "react-native", + allowJs: false + } + }; + const expected: ts.ParsedCommandLine = { + options: { + jsx: ts.JsxEmit.ReactNative, + allowJs: false + }, + errors: [], + fileNames: [ + "c:/dev/a.ts", + "c:/dev/b.tsx", + "c:/dev/c.tsx", + ], + wildcardDirectories: { + "c:/dev": ts.WatchDirectoryFlags.Recursive + } + }; + const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); + assertParsed(actual, expected); + }); it("with jsx=none, allowJs=true", () => { const json = { compilerOptions: { @@ -961,6 +1016,33 @@ namespace ts { const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); assertParsed(actual, expected); }); + it("with jsx=react-native, allowJs=true", () => { + const json = { + compilerOptions: { + jsx: "react-native", + allowJs: true + } + }; + const expected: ts.ParsedCommandLine = { + options: { + jsx: ts.JsxEmit.ReactNative, + allowJs: true + }, + errors: [], + fileNames: [ + "c:/dev/a.ts", + "c:/dev/b.tsx", + "c:/dev/c.tsx", + "c:/dev/d.js", + "c:/dev/e.jsx", + ], + wildcardDirectories: { + "c:/dev": ts.WatchDirectoryFlags.Recursive + } + }; + const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); + assertParsed(actual, expected); + }); it("exclude .min.js files using wildcards", () => { const json = { compilerOptions: { @@ -1230,8 +1312,8 @@ namespace ts { options: {}, errors: [], fileNames: [ - "c:/dev/.z/.b.ts", - "c:/dev/x/.y/a.ts" + "c:/dev/x/.y/a.ts", + "c:/dev/.z/.b.ts" ], wildcardDirectories: {} }; @@ -1271,8 +1353,8 @@ namespace ts { options: {}, errors: [], fileNames: [ - "c:/dev/.z/.b.ts", - "c:/dev/x/.y/a.ts" + "c:/dev/x/.y/a.ts", + "c:/dev/.z/.b.ts" ], wildcardDirectories: { "c:/dev/.z": ts.WatchDirectoryFlags.Recursive, @@ -1306,4 +1388,4 @@ namespace ts { }); }); }); -} \ No newline at end of file +} diff --git a/src/harness/unittests/moduleResolution.ts b/src/harness/unittests/moduleResolution.ts index 35313e15308..aa30f1e01e2 100644 --- a/src/harness/unittests/moduleResolution.ts +++ b/src/harness/unittests/moduleResolution.ts @@ -36,7 +36,7 @@ namespace ts { for (const f of files) { let name = getDirectoryPath(f.name); while (true) { - directories[name] = name; + directories.set(name, name); const baseName = getDirectoryPath(name); if (baseName === name) { break; @@ -46,20 +46,19 @@ namespace ts { } return { readFile, - directoryExists: path => { - return path in directories; - }, + directoryExists: path => directories.has(path), fileExists: path => { - assert.isTrue(getDirectoryPath(path) in directories, `'fileExists' '${path}' request in non-existing directory`); - return path in map; + assert.isTrue(directories.has(getDirectoryPath(path)), `'fileExists' '${path}' request in non-existing directory`); + return map.has(path); } }; } else { - return { readFile, fileExists: path => path in map, }; + return { readFile, fileExists: path => map.has(path) }; } function readFile(path: string): string { - return path in map ? map[path].content : undefined; + const file = map.get(path); + return file && file.content; } } @@ -300,7 +299,8 @@ namespace ts { const host: CompilerHost = { getSourceFile: (fileName: string, languageVersion: ScriptTarget) => { const path = normalizePath(combinePaths(currentDirectory, fileName)); - return path in files ? createSourceFile(fileName, files[path], languageVersion) : undefined; + const file = files.get(path); + return file && createSourceFile(fileName, file, languageVersion); }, getDefaultLibFileName: () => "lib.d.ts", writeFile: notImplemented, @@ -311,7 +311,7 @@ namespace ts { useCaseSensitiveFileNames: () => false, fileExists: fileName => { const path = normalizePath(combinePaths(currentDirectory, fileName)); - return path in files; + return files.has(path); }, readFile: notImplemented }; @@ -331,7 +331,7 @@ namespace ts { } it("should find all modules", () => { - const files = createMap({ + const files = createMapFromTemplate({ "/a/b/c/first/shared.ts": ` class A {} export = A`, @@ -350,7 +350,7 @@ export = C; }); it("should find modules in node_modules", () => { - const files = createMap({ + const files = createMapFromTemplate({ "/parent/node_modules/mod/index.d.ts": "export var x", "/parent/app/myapp.ts": `import {x} from "mod"` }); @@ -358,7 +358,7 @@ export = C; }); it("should find file referenced via absolute and relative names", () => { - const files = createMap({ + const files = createMapFromTemplate({ "/a/b/c.ts": `/// `, "/a/b/b.ts": "var x" }); @@ -371,7 +371,11 @@ export = C; function test(files: Map, options: CompilerOptions, currentDirectory: string, useCaseSensitiveFileNames: boolean, rootFiles: string[], diagnosticCodes: number[]): void { const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames); if (!useCaseSensitiveFileNames) { - files = reduceProperties(files, (files, file, fileName) => (files[getCanonicalFileName(fileName)] = file, files), createMap()); + const oldFiles = files; + files = createMap(); + oldFiles.forEach((file, fileName) => { + files.set(getCanonicalFileName(fileName), file); + }); } const host: CompilerHost = { @@ -380,7 +384,8 @@ export = C; return library; } const path = getCanonicalFileName(normalizePath(combinePaths(currentDirectory, fileName))); - return path in files ? createSourceFile(fileName, files[path], languageVersion) : undefined; + const file = files.get(path); + return file && createSourceFile(fileName, file, languageVersion); }, getDefaultLibFileName: () => "lib.d.ts", writeFile: notImplemented, @@ -391,7 +396,7 @@ export = C; useCaseSensitiveFileNames: () => useCaseSensitiveFileNames, fileExists: fileName => { const path = getCanonicalFileName(normalizePath(combinePaths(currentDirectory, fileName))); - return path in files; + return files.has(path); }, readFile: notImplemented }; @@ -404,7 +409,7 @@ export = C; } it("should succeed when the same file is referenced using absolute and relative names", () => { - const files = createMap({ + const files = createMapFromTemplate({ "/a/b/c.ts": `/// `, "/a/b/d.ts": "var x" }); @@ -412,7 +417,7 @@ export = C; }); it("should fail when two files used in program differ only in casing (tripleslash references)", () => { - const files = createMap({ + const files = createMapFromTemplate({ "/a/b/c.ts": `/// `, "/a/b/d.ts": "var x" }); @@ -420,7 +425,7 @@ export = C; }); it("should fail when two files used in program differ only in casing (imports)", () => { - const files = createMap({ + const files = createMapFromTemplate({ "/a/b/c.ts": `import {x} from "D"`, "/a/b/d.ts": "export var x" }); @@ -428,7 +433,7 @@ export = C; }); it("should fail when two files used in program differ only in casing (imports, relative module names)", () => { - const files = createMap({ + const files = createMapFromTemplate({ "moduleA.ts": `import {x} from "./ModuleB"`, "moduleB.ts": "export var x" }); @@ -436,7 +441,7 @@ export = C; }); it("should fail when two files exist on disk that differs only in casing", () => { - const files = createMap({ + const files = createMapFromTemplate({ "/a/b/c.ts": `import {x} from "D"`, "/a/b/D.ts": "export var x", "/a/b/d.ts": "export var y" @@ -445,7 +450,7 @@ export = C; }); it("should fail when module name in 'require' calls has inconsistent casing", () => { - const files = createMap({ + const files = createMapFromTemplate({ "moduleA.ts": `import a = require("./ModuleC")`, "moduleB.ts": `import a = require("./moduleC")`, "moduleC.ts": "export var x" @@ -454,7 +459,7 @@ export = C; }); it("should fail when module names in 'require' calls has inconsistent casing and current directory has uppercase chars", () => { - const files = createMap({ + const files = createMapFromTemplate({ "/a/B/c/moduleA.ts": `import a = require("./ModuleC")`, "/a/B/c/moduleB.ts": `import a = require("./moduleC")`, "/a/B/c/moduleC.ts": "export var x", @@ -466,7 +471,7 @@ import b = require("./moduleB"); test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", /*useCaseSensitiveFileNames*/ false, ["moduleD.ts"], [1149]); }); it("should not fail when module names in 'require' calls has consistent casing and current directory has uppercase chars", () => { - const files = createMap({ + const files = createMapFromTemplate({ "/a/B/c/moduleA.ts": `import a = require("./moduleC")`, "/a/B/c/moduleB.ts": `import a = require("./moduleC")`, "/a/B/c/moduleC.ts": "export var x", @@ -1020,8 +1025,8 @@ import b = require("./moduleB"); const names = map(files, f => f.name); const sourceFiles = arrayToMap(map(files, f => createSourceFile(f.name, f.content, ScriptTarget.ES2015)), f => f.fileName); const compilerHost: CompilerHost = { - fileExists : fileName => fileName in sourceFiles, - getSourceFile: fileName => sourceFiles[fileName], + fileExists : fileName => sourceFiles.has(fileName), + getSourceFile: fileName => sourceFiles.get(fileName), getDefaultLibFileName: () => "lib.d.ts", writeFile: notImplemented, getCurrentDirectory: () => "/", @@ -1029,7 +1034,10 @@ import b = require("./moduleB"); getCanonicalFileName: f => f.toLowerCase(), getNewLine: () => "\r\n", useCaseSensitiveFileNames: () => false, - readFile: fileName => fileName in sourceFiles ? sourceFiles[fileName].text : undefined + readFile: fileName => { + const file = sourceFiles.get(fileName); + return file && file.text; + } }; const program1 = createProgram(names, {}, compilerHost); const diagnostics1 = program1.getFileProcessingDiagnostics().getDiagnostics(); 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/reuseProgramStructure.ts b/src/harness/unittests/reuseProgramStructure.ts index 6dbd74e71d2..d13dd7a26fa 100644 --- a/src/harness/unittests/reuseProgramStructure.ts +++ b/src/harness/unittests/reuseProgramStructure.ts @@ -1,4 +1,4 @@ -/// +/// /// namespace ts { @@ -122,7 +122,7 @@ namespace ts { trace: s => trace.push(s), getTrace: () => trace, getSourceFile(fileName): SourceFile { - return files[fileName]; + return files.get(fileName); }, getDefaultLibFileName(): string { return "lib.d.ts"; @@ -143,9 +143,10 @@ namespace ts { getNewLine(): string { return sys ? sys.newLine : newLine; }, - fileExists: fileName => fileName in files, + fileExists: fileName => files.has(fileName), readFile: fileName => { - return fileName in files ? files[fileName].text : undefined; + const file = files.get(fileName); + return file && file.text; }, }; } @@ -188,10 +189,24 @@ namespace ts { } else { assert.isTrue(cache !== undefined, `expected ${caption} to be set`); - assert.isTrue(equalOwnProperties(expectedContent, cache, entryChecker), `contents of ${caption} did not match the expected contents.`); + assert.isTrue(mapsAreEqual(expectedContent, cache, entryChecker), `contents of ${caption} did not match the expected contents.`); } } + /** True if the maps have the same keys and values. */ + function mapsAreEqual(left: Map, right: Map, valuesAreEqual?: (left: T, right: T) => boolean): boolean { + if (left === right) return true; + if (!left || !right) return false; + const someInLeftHasNoMatch = forEachEntry(left, (leftValue, leftKey) => { + if (!right.has(leftKey)) return true; + const rightValue = right.get(leftKey); + return !(valuesAreEqual ? valuesAreEqual(leftValue, rightValue) : leftValue === rightValue); + }); + if (someInLeftHasNoMatch) return false; + const someInRightHasNoMatch = forEachKey(right, rightKey => !left.has(rightKey)); + return !someInRightHasNoMatch; + } + function checkResolvedModulesCache(program: Program, fileName: string, expectedContent: Map): void { checkCache("resolved modules", program, fileName, expectedContent, f => f.resolvedModules, checkResolvedModule); } @@ -307,7 +322,7 @@ namespace ts { const options: CompilerOptions = { target }; const program_1 = newProgram(files, ["a.ts"], options); - checkResolvedModulesCache(program_1, "a.ts", createMap({ "b": createResolvedModule("b.ts") })); + checkResolvedModulesCache(program_1, "a.ts", createMapFromTemplate({ "b": createResolvedModule("b.ts") })); checkResolvedModulesCache(program_1, "b.ts", undefined); const program_2 = updateProgram(program_1, ["a.ts"], options, files => { @@ -316,7 +331,7 @@ namespace ts { assert.isTrue(program_1.structureIsReused); // content of resolution cache should not change - checkResolvedModulesCache(program_1, "a.ts", createMap({ "b": createResolvedModule("b.ts") })); + checkResolvedModulesCache(program_1, "a.ts", createMapFromTemplate({ "b": createResolvedModule("b.ts") })); checkResolvedModulesCache(program_1, "b.ts", undefined); // imports has changed - program is not reused @@ -333,7 +348,7 @@ namespace ts { files[0].text = files[0].text.updateImportsAndExports(newImports); }); assert.isTrue(!program_3.structureIsReused); - checkResolvedModulesCache(program_4, "a.ts", createMap({ "b": createResolvedModule("b.ts"), "c": undefined })); + checkResolvedModulesCache(program_4, "a.ts", createMapFromTemplate({ "b": createResolvedModule("b.ts"), "c": undefined })); }); it("resolved type directives cache follows type directives", () => { @@ -344,7 +359,7 @@ namespace ts { const options: CompilerOptions = { target, typeRoots: ["/types"] }; const program_1 = newProgram(files, ["/a.ts"], options); - checkResolvedTypeDirectivesCache(program_1, "/a.ts", createMap({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); + checkResolvedTypeDirectivesCache(program_1, "/a.ts", createMapFromTemplate({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); checkResolvedTypeDirectivesCache(program_1, "/types/typedefs/index.d.ts", undefined); const program_2 = updateProgram(program_1, ["/a.ts"], options, files => { @@ -353,7 +368,7 @@ namespace ts { assert.isTrue(program_1.structureIsReused); // content of resolution cache should not change - checkResolvedTypeDirectivesCache(program_1, "/a.ts", createMap({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); + checkResolvedTypeDirectivesCache(program_1, "/a.ts", createMapFromTemplate({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); checkResolvedTypeDirectivesCache(program_1, "/types/typedefs/index.d.ts", undefined); // type reference directives has changed - program is not reused @@ -371,7 +386,7 @@ namespace ts { files[0].text = files[0].text.updateReferences(newReferences); }); assert.isTrue(!program_3.structureIsReused); - checkResolvedTypeDirectivesCache(program_1, "/a.ts", createMap({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); + checkResolvedTypeDirectivesCache(program_1, "/a.ts", createMapFromTemplate({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); }); it("can reuse ambient module declarations from non-modified files", () => { diff --git a/src/harness/unittests/session.ts b/src/harness/unittests/session.ts index 8800e84474b..15c43d9e76b 100644 --- a/src/harness/unittests/session.ts +++ b/src/harness/unittests/session.ts @@ -1,4 +1,4 @@ -/// +/// const expect: typeof _chai.expect = _chai.expect; @@ -416,14 +416,15 @@ namespace ts.server { class InProcClient { private server: InProcSession; private seq = 0; - private callbacks = createMap<(resp: protocol.Response) => void>(); + private callbacks: Array<(resp: protocol.Response) => void> = []; private eventHandlers = createMap<(args: any) => void>(); handle(msg: protocol.Message): void { if (msg.type === "response") { const response = msg; - if (response.request_seq in this.callbacks) { - this.callbacks[response.request_seq](response); + const handler = this.callbacks[response.request_seq]; + if (handler) { + handler(response); delete this.callbacks[response.request_seq]; } } @@ -434,13 +435,14 @@ namespace ts.server { } emit(name: string, args: any): void { - if (name in this.eventHandlers) { - this.eventHandlers[name](args); + const handler = this.eventHandlers.get(name); + if (handler) { + handler(args); } } on(name: string, handler: (args: any) => void): void { - this.eventHandlers[name] = handler; + this.eventHandlers.set(name, handler); } connect(session: InProcSession): void { diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 1844b0743ca..5ed0d981511 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -1,4 +1,4 @@ -/// +/// /// namespace ts.projectSystem { @@ -244,9 +244,9 @@ namespace ts.projectSystem { } export function checkMapKeys(caption: string, map: Map, expectedKeys: string[]) { - assert.equal(reduceProperties(map, count => count + 1, 0), expectedKeys.length, `${caption}: incorrect size of map`); + assert.equal(map.size, expectedKeys.length, `${caption}: incorrect size of map`); for (const name of expectedKeys) { - assert.isTrue(name in map, `${caption} is expected to contain ${name}, actual keys: ${Object.keys(map)}`); + assert.isTrue(map.has(name), `${caption} is expected to contain ${name}, actual keys: ${arrayFrom(map.keys())}`); } } @@ -292,7 +292,7 @@ namespace ts.projectSystem { } export class Callbacks { - private map: { [n: number]: TimeOutCallback } = {}; + private map: TimeOutCallback[] = []; private nextId = 1; register(cb: (...args: any[]) => void, args: any[]) { @@ -310,20 +310,16 @@ namespace ts.projectSystem { count() { let n = 0; for (const _ in this.map) { - // TODO: GH#11734 - _; n++; } return n; } invoke() { - for (const id in this.map) { - if (hasProperty(this.map, id)) { - this.map[id](); - } + for (const key in this.map) { + this.map[key](); } - this.map = {}; + this.map = []; } } @@ -338,8 +334,8 @@ namespace ts.projectSystem { private timeoutCallbacks = new Callbacks(); private immediateCallbacks = new Callbacks(); - readonly watchedDirectories = createMap<{ cb: DirectoryWatcherCallback, recursive: boolean }[]>(); - readonly watchedFiles = createMap(); + readonly watchedDirectories = createMultiMap<{ cb: DirectoryWatcherCallback, recursive: boolean }>(); + readonly watchedFiles = createMultiMap(); private filesOrFolders: FileOrFolder[]; @@ -425,11 +421,11 @@ namespace ts.projectSystem { watchDirectory(directoryName: string, callback: DirectoryWatcherCallback, recursive: boolean): DirectoryWatcher { const path = this.toPath(directoryName); const cbWithRecursive = { cb: callback, recursive }; - multiMapAdd(this.watchedDirectories, path, cbWithRecursive); + this.watchedDirectories.add(path, cbWithRecursive); return { referenceCount: 0, directoryName, - close: () => multiMapRemove(this.watchedDirectories, path, cbWithRecursive) + close: () => this.watchedDirectories.remove(path, cbWithRecursive) }; } @@ -439,7 +435,7 @@ namespace ts.projectSystem { triggerDirectoryWatcherCallback(directoryName: string, fileName: string): void { const path = this.toPath(directoryName); - const callbacks = this.watchedDirectories[path]; + const callbacks = this.watchedDirectories.get(path); if (callbacks) { for (const callback of callbacks) { callback.cb(fileName); @@ -449,7 +445,7 @@ namespace ts.projectSystem { triggerFileWatcherCallback(fileName: string, removed?: boolean): void { const path = this.toPath(fileName); - const callbacks = this.watchedFiles[path]; + const callbacks = this.watchedFiles.get(path); if (callbacks) { for (const callback of callbacks) { callback(path, removed); @@ -459,8 +455,8 @@ namespace ts.projectSystem { watchFile(fileName: string, callback: FileWatcherCallback) { const path = this.toPath(fileName); - multiMapAdd(this.watchedFiles, path, callback); - return { close: () => multiMapRemove(this.watchedFiles, path, callback) }; + this.watchedFiles.add(path, callback); + return { close: () => this.watchedFiles.remove(path, callback) }; } // TOOD: record and invoke callbacks to simulate timer events diff --git a/src/harness/unittests/typingsInstaller.ts b/src/harness/unittests/typingsInstaller.ts index 62d2f7ac801..2b79141c3e3 100644 --- a/src/harness/unittests/typingsInstaller.ts +++ b/src/harness/unittests/typingsInstaller.ts @@ -14,7 +14,7 @@ namespace ts.projectSystem { function createTypesRegistry(...list: string[]): Map { const map = createMap(); for (const l of list) { - map[l] = undefined; + map.set(l, undefined); } return map; } @@ -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 { @@ -944,7 +946,7 @@ namespace ts.projectSystem { content: "" }; const host = createServerHost([f, node]); - const cache = createMap({ "node": node.path }); + const cache = createMapFromTemplate({ "node": node.path }); const result = JsTyping.discoverTypings(host, [f.path], getDirectoryPath(f.path), /*safeListPath*/ undefined, cache, { enable: true }, ["fs", "bar"]); assert.deepEqual(result.cachedTypingPaths, [node.path]); assert.deepEqual(result.newTypingNames, ["bar"]); @@ -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/harness/virtualFileSystem.ts b/src/harness/virtualFileSystem.ts index 852363b3658..e409af9d4e7 100644 --- a/src/harness/virtualFileSystem.ts +++ b/src/harness/virtualFileSystem.ts @@ -195,11 +195,17 @@ namespace Utils { } export class MockParseConfigHost extends VirtualFileSystem implements ts.ParseConfigHost { - constructor(currentDirectory: string, ignoreCase: boolean, files: ts.MapLike | string[]) { + constructor(currentDirectory: string, ignoreCase: boolean, files: ts.Map | string[]) { super(currentDirectory, ignoreCase); - const fileNames = (files instanceof Array) ? files : ts.getOwnKeys(files); - for (const file of fileNames) { - this.addFile(file, new Harness.LanguageService.ScriptInfo(file, (files as ts.MapLike)[file], /*isRootFile*/false)); + if (files instanceof Array) { + for (const file of files) { + this.addFile(file, new Harness.LanguageService.ScriptInfo(file, undefined, /*isRootFile*/false)); + } + } + else { + files.forEach((fileContent, fileName) => { + this.addFile(fileName, new Harness.LanguageService.ScriptInfo(fileName, fileContent, /*isRootFile*/false)); + }); } } diff --git a/src/lib/es2015.collection.d.ts b/src/lib/es2015.collection.d.ts index 6a2c43cd050..5b90333f1d5 100644 --- a/src/lib/es2015.collection.d.ts +++ b/src/lib/es2015.collection.d.ts @@ -4,7 +4,7 @@ interface Map { forEach(callbackfn: (value: V, key: K, map: Map) => void, thisArg?: any): void; get(key: K): V | undefined; has(key: K): boolean; - set(key: K, value?: V): this; + set(key: K, value: V): this; readonly size: number; } @@ -22,16 +22,16 @@ interface ReadonlyMap { readonly size: number; } -interface WeakMap { +interface WeakMap { delete(key: K): boolean; get(key: K): V | undefined; has(key: K): boolean; - set(key: K, value?: V): this; + set(key: K, value: V): this; } interface WeakMapConstructor { new (): WeakMap; - new (entries?: [K, V][]): WeakMap; + new (entries?: [K, V][]): WeakMap; readonly prototype: WeakMap; } declare var WeakMap: WeakMapConstructor; diff --git a/src/lib/es2015.core.d.ts b/src/lib/es2015.core.d.ts index 356512ecf58..eb23ce7901f 100644 --- a/src/lib/es2015.core.d.ts +++ b/src/lib/es2015.core.d.ts @@ -325,7 +325,7 @@ interface ObjectConstructor { * @param o The object to change its prototype. * @param proto The value of the new prototype or null. */ - setPrototypeOf(o: any, proto: any): any; + setPrototypeOf(o: any, proto: object | null): any; /** * Gets the own property descriptor of the specified object. diff --git a/src/lib/es2015.iterable.d.ts b/src/lib/es2015.iterable.d.ts index 1da0d9a638a..247017bae7d 100644 --- a/src/lib/es2015.iterable.d.ts +++ b/src/lib/es2015.iterable.d.ts @@ -99,10 +99,10 @@ interface MapConstructor { new (iterable: Iterable<[K, V]>): Map; } -interface WeakMap { } +interface WeakMap { } interface WeakMapConstructor { - new (iterable: Iterable<[K, V]>): WeakMap; + new (iterable: Iterable<[K, V]>): WeakMap; } interface Set { @@ -442,4 +442,4 @@ interface Float64ArrayConstructor { * @param thisArg Value of 'this' used to invoke the mapfn. */ from(arrayLike: Iterable, mapfn?: (v: number, k: number) => number, thisArg?: any): Float64Array; -} \ No newline at end of file +} diff --git a/src/lib/es2015.proxy.d.ts b/src/lib/es2015.proxy.d.ts index 34aedce0128..efccfd47cc5 100644 --- a/src/lib/es2015.proxy.d.ts +++ b/src/lib/es2015.proxy.d.ts @@ -1,5 +1,5 @@ interface ProxyHandler { - getPrototypeOf? (target: T): {} | null; + getPrototypeOf? (target: T): object | null; setPrototypeOf? (target: T, v: any): boolean; isExtensible? (target: T): boolean; preventExtensions? (target: T): boolean; @@ -12,7 +12,7 @@ interface ProxyHandler { enumerate? (target: T): PropertyKey[]; ownKeys? (target: T): PropertyKey[]; apply? (target: T, thisArg: any, argArray?: any): any; - construct? (target: T, argArray: any, newTarget?: any): {}; + construct? (target: T, argArray: any, newTarget?: any): object } interface ProxyConstructor { diff --git a/src/lib/es2015.symbol.d.ts b/src/lib/es2015.symbol.d.ts index cd7e45595f0..d7ea4fa0328 100644 --- a/src/lib/es2015.symbol.d.ts +++ b/src/lib/es2015.symbol.d.ts @@ -3,7 +3,7 @@ interface Symbol { toString(): string; /** Returns the primitive value of the specified object. */ - valueOf(): Object; + valueOf(): symbol; } interface SymbolConstructor { diff --git a/src/lib/es2015.symbol.wellknown.d.ts b/src/lib/es2015.symbol.wellknown.d.ts index 145d8af6b10..7177b78e483 100644 --- a/src/lib/es2015.symbol.wellknown.d.ts +++ b/src/lib/es2015.symbol.wellknown.d.ts @@ -110,7 +110,7 @@ interface Map { readonly [Symbol.toStringTag]: "Map"; } -interface WeakMap{ +interface WeakMap{ readonly [Symbol.toStringTag]: "WeakMap"; } @@ -324,4 +324,4 @@ interface Float32Array { */ interface Float64Array { readonly [Symbol.toStringTag]: "Float64Array"; -} \ No newline at end of file +} diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index e5eabe950a2..038d0344fda 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -146,14 +146,14 @@ interface ObjectConstructor { * Creates an object that has the specified prototype, and that optionally contains specified properties. * @param o Object to use as a prototype. May be null */ - create(o: T): T; + create(o: T): T; /** * Creates an object that has the specified prototype, and that optionally contains specified properties. * @param o Object to use as a prototype. May be null * @param properties JavaScript object that contains one or more property descriptors. */ - create(o: any, properties: PropertyDescriptorMap): any; + create(o: object | null, properties: PropertyDescriptorMap): any; /** * Adds a property to an object, or modifies attributes of an existing property. diff --git a/src/server/builder.ts b/src/server/builder.ts index 60f56dc3241..a5e7b06e64b 100644 --- a/src/server/builder.ts +++ b/src/server/builder.ts @@ -356,24 +356,24 @@ namespace ts.server { // Use slice to clone the array to avoid manipulating in place const queue = fileInfo.referencedBy.slice(0); const fileNameSet = createMap(); - fileNameSet[scriptInfo.fileName] = scriptInfo; + fileNameSet.set(scriptInfo.fileName, scriptInfo); while (queue.length > 0) { const processingFileInfo = queue.pop(); if (processingFileInfo.updateShapeSignature() && processingFileInfo.referencedBy.length > 0) { for (const potentialFileInfo of processingFileInfo.referencedBy) { - if (!fileNameSet[potentialFileInfo.scriptInfo.fileName]) { + if (!fileNameSet.has(potentialFileInfo.scriptInfo.fileName)) { queue.push(potentialFileInfo); } } } - fileNameSet[processingFileInfo.scriptInfo.fileName] = processingFileInfo.scriptInfo; + fileNameSet.set(processingFileInfo.scriptInfo.fileName, processingFileInfo.scriptInfo); } const result: string[] = []; - for (const fileName in fileNameSet) { - if (shouldEmitFile(fileNameSet[fileName])) { + fileNameSet.forEach((scriptInfo, fileName) => { + if (shouldEmitFile(scriptInfo)) { result.push(fileName); } - } + }); return result; } } diff --git a/src/server/client.ts b/src/server/client.ts index 3b09a926754..d9e93769bd9 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -31,10 +31,11 @@ namespace ts.server { } private getLineMap(fileName: string): number[] { - let lineMap = this.lineMaps[fileName]; + let lineMap = this.lineMaps.get(fileName); if (!lineMap) { const scriptSnapshot = this.host.getScriptSnapshot(fileName); - lineMap = this.lineMaps[fileName] = ts.computeLineStarts(scriptSnapshot.getText(0, scriptSnapshot.getLength())); + lineMap = ts.computeLineStarts(scriptSnapshot.getText(0, scriptSnapshot.getLength())); + this.lineMaps.set(fileName, lineMap); } return lineMap; } @@ -140,7 +141,7 @@ namespace ts.server { changeFile(fileName: string, start: number, end: number, newText: string): void { // clear the line map after an edit - this.lineMaps[fileName] = undefined; + this.lineMaps.set(fileName, undefined); const lineOffset = this.positionToOneBasedLineOffset(fileName, start); const endLineOffset = this.positionToOneBasedLineOffset(fileName, end); diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 38873a38aba..edc4fab9a19 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1,4 +1,4 @@ -/// +/// /// /// /// @@ -41,17 +41,17 @@ namespace ts.server { if (typeof option.type === "object") { const optionMap = >option.type; // verify that map contains only numbers - for (const id in optionMap) { - Debug.assert(typeof optionMap[id] === "number"); - } - map[option.name] = optionMap; + optionMap.forEach(value => { + Debug.assert(typeof value === "number"); + }); + map.set(option.name, optionMap); } } return map; } const compilerOptionConverters = prepareConvertersForEnumLikeCompilerOptions(optionDeclarations); - const indentStyle = createMap({ + const indentStyle = createMapFromTemplate({ "none": IndentStyle.None, "block": IndentStyle.Block, "smart": IndentStyle.Smart @@ -59,20 +59,19 @@ namespace ts.server { export function convertFormatOptions(protocolOptions: protocol.FormatCodeSettings): FormatCodeSettings { if (typeof protocolOptions.indentStyle === "string") { - protocolOptions.indentStyle = indentStyle[protocolOptions.indentStyle.toLowerCase()]; + protocolOptions.indentStyle = indentStyle.get(protocolOptions.indentStyle.toLowerCase()); Debug.assert(protocolOptions.indentStyle !== undefined); } return protocolOptions; } export function convertCompilerOptions(protocolOptions: protocol.ExternalProjectCompilerOptions): CompilerOptions & protocol.CompileOnSaveMixin { - for (const id in compilerOptionConverters) { + compilerOptionConverters.forEach((mappedValues, id) => { const propertyValue = protocolOptions[id]; if (typeof propertyValue === "string") { - const mappedValues = compilerOptionConverters[id]; - protocolOptions[id] = mappedValues[propertyValue.toLowerCase()]; + protocolOptions[id] = mappedValues.get(propertyValue.toLowerCase()); } - } + }); return protocolOptions; } @@ -193,11 +192,12 @@ namespace ts.server { stopWatchingDirectory(directory: string) { // if the ref count for this directory watcher drops to 0, it's time to close it - this.directoryWatchersRefCount[directory]--; - if (this.directoryWatchersRefCount[directory] === 0) { + const refCount = this.directoryWatchersRefCount.get(directory) - 1; + this.directoryWatchersRefCount.set(directory, refCount); + if (refCount === 0) { this.projectService.logger.info(`Close directory watcher for: ${directory}`); - this.directoryWatchersForTsconfig[directory].close(); - delete this.directoryWatchersForTsconfig[directory]; + this.directoryWatchersForTsconfig.get(directory).close(); + this.directoryWatchersForTsconfig.delete(directory); } } @@ -205,13 +205,13 @@ namespace ts.server { let currentPath = getDirectoryPath(fileName); let parentPath = getDirectoryPath(currentPath); while (currentPath != parentPath) { - if (!this.directoryWatchersForTsconfig[currentPath]) { + if (!this.directoryWatchersForTsconfig.has(currentPath)) { this.projectService.logger.info(`Add watcher for: ${currentPath}`); - this.directoryWatchersForTsconfig[currentPath] = this.projectService.host.watchDirectory(currentPath, callback); - this.directoryWatchersRefCount[currentPath] = 1; + this.directoryWatchersForTsconfig.set(currentPath, this.projectService.host.watchDirectory(currentPath, callback)); + this.directoryWatchersRefCount.set(currentPath, 1); } else { - this.directoryWatchersRefCount[currentPath] += 1; + this.directoryWatchersRefCount.set(currentPath, this.directoryWatchersRefCount.get(currentPath) + 1); } project.directoriesWatchedForTsconfig.push(currentPath); currentPath = parentPath; @@ -431,7 +431,7 @@ namespace ts.server { } else { if (info && (!info.isScriptOpen())) { - // file has been changed which might affect the set of referenced files in projects that include + // file has been changed which might affect the set of referenced files in projects that include // this file and set of inferred projects info.reloadFromFile(); this.updateProjectGraphs(info.containingProjects); @@ -450,7 +450,7 @@ namespace ts.server { this.filenameToScriptInfo.remove(info.path); this.lastDeletedFile = info; - // capture list of projects since detachAllProjects will wipe out original list + // capture list of projects since detachAllProjects will wipe out original list const containingProjects = info.containingProjects.slice(); info.detachAllProjects(); @@ -606,7 +606,7 @@ namespace ts.server { const inferredProject = this.createInferredProjectWithRootFileIfNecessary(info); if (!this.useSingleInferredProject) { // if useOneInferredProject is not set then try to fixup ownership of open files - // check 'defaultProject !== inferredProject' is necessary to handle cases + // check 'defaultProject !== inferredProject' is necessary to handle cases // when creation inferred project for some file has added other open files into this project (i.e. as referenced files) // we definitely don't want to delete the project that was just created for (const f of this.openFiles) { @@ -616,7 +616,7 @@ namespace ts.server { } const defaultProject = f.getDefaultProject(); if (isRootFileInInferredProject(info) && defaultProject !== inferredProject && inferredProject.containsScriptInfo(f)) { - // open file used to be root in inferred project, + // open file used to be root in inferred project, // this inferred project is different from the one we've just created for current file // and new inferred project references this open file. // We should delete old inferred project and attach open file to the new one @@ -845,7 +845,7 @@ namespace ts.server { files: parsedCommandLine.fileNames, compilerOptions: parsedCommandLine.options, configHasFilesProperty: config["files"] !== undefined, - wildcardDirectories: createMap(parsedCommandLine.wildcardDirectories), + wildcardDirectories: createMapFromTemplate(parsedCommandLine.wildcardDirectories), typeAcquisition: parsedCommandLine.typeAcquisition, compileOnSave: parsedCommandLine.compileOnSave }; @@ -1007,7 +1007,7 @@ namespace ts.server { if (toAdd) { for (const f of toAdd) { if (f.isScriptOpen() && isRootFileInInferredProject(f)) { - // if file is already root in some inferred project + // if file is already root in some inferred project // - remove the file from that project and delete the project if necessary const inferredProject = f.containingProjects[0]; inferredProject.removeFile(f); @@ -1160,7 +1160,7 @@ namespace ts.server { this.logger.info(`Host information ${args.hostInfo}`); } if (args.formatOptions) { - mergeMaps(this.hostConfiguration.formatCodeOptions, convertFormatOptions(args.formatOptions)); + mergeMapLikes(this.hostConfiguration.formatCodeOptions, convertFormatOptions(args.formatOptions)); this.logger.info("Format host information updated"); } if (args.extraFileExtensions) { @@ -1300,7 +1300,7 @@ namespace ts.server { for (const file of changedFiles) { const scriptInfo = this.getScriptInfo(file.fileName); Debug.assert(!!scriptInfo); - // apply changes in reverse order + // apply changes in reverse order for (let i = file.changes.length - 1; i >= 0; i--) { const change = file.changes[i]; scriptInfo.editContent(change.span.start, change.span.start + change.span.length, change.newText); @@ -1337,7 +1337,7 @@ namespace ts.server { closeExternalProject(uncheckedFileName: string, suppressRefresh = false): void { const fileName = toNormalizedPath(uncheckedFileName); - const configFiles = this.externalProjectToConfiguredProjectMap[fileName]; + const configFiles = this.externalProjectToConfiguredProjectMap.get(fileName); if (configFiles) { let shouldRefreshInferredProjects = false; for (const configFile of configFiles) { @@ -1345,7 +1345,7 @@ namespace ts.server { shouldRefreshInferredProjects = true; } } - delete this.externalProjectToConfiguredProjectMap[fileName]; + this.externalProjectToConfiguredProjectMap.delete(fileName); if (shouldRefreshInferredProjects && !suppressRefresh) { this.refreshInferredProjects(); } @@ -1365,20 +1365,20 @@ namespace ts.server { openExternalProjects(projects: protocol.ExternalProject[]): void { // record project list before the update const projectsToClose = arrayToMap(this.externalProjects, p => p.getProjectName(), _ => true); - for (const externalProjectName in this.externalProjectToConfiguredProjectMap) { - projectsToClose[externalProjectName] = true; - } + forEachKey(this.externalProjectToConfiguredProjectMap, externalProjectName => { + projectsToClose.set(externalProjectName, true); + }); for (const externalProject of projects) { this.openExternalProject(externalProject, /*suppressRefreshOfInferredProjects*/ true); // delete project that is present in input list - delete projectsToClose[externalProject.projectFileName]; + projectsToClose.delete(externalProject.projectFileName); } // close projects that were missing in the input list - for (const externalProjectName in projectsToClose) { + forEachKey(projectsToClose, externalProjectName => { this.closeExternalProject(externalProjectName, /*suppressRefresh*/ true) - } + }); this.refreshInferredProjects(); } @@ -1428,7 +1428,7 @@ namespace ts.server { // close existing project and later we'll open a set of configured projects for these files this.closeExternalProject(proj.projectFileName, /*suppressRefresh*/ true); } - else if (this.externalProjectToConfiguredProjectMap[proj.projectFileName]) { + else if (this.externalProjectToConfiguredProjectMap.get(proj.projectFileName)) { // this project used to include config files if (!tsConfigFiles) { // config files were removed from the project - close existing external project which in turn will close configured projects @@ -1436,7 +1436,7 @@ namespace ts.server { } else { // project previously had some config files - compare them with new set of files and close all configured projects that correspond to unused files - const oldConfigFiles = this.externalProjectToConfiguredProjectMap[proj.projectFileName]; + const oldConfigFiles = this.externalProjectToConfiguredProjectMap.get(proj.projectFileName); let iNew = 0; let iOld = 0; while (iNew < tsConfigFiles.length && iOld < oldConfigFiles.length) { @@ -1464,7 +1464,7 @@ namespace ts.server { } if (tsConfigFiles) { // store the list of tsconfig files that belong to the external project - this.externalProjectToConfiguredProjectMap[proj.projectFileName] = tsConfigFiles; + this.externalProjectToConfiguredProjectMap.set(proj.projectFileName, tsConfigFiles); for (const tsconfigFile of tsConfigFiles) { let project = this.findConfiguredProjectByProjectName(tsconfigFile); if (!project) { @@ -1480,7 +1480,7 @@ namespace ts.server { } else { // no config files - remove the item from the collection - delete this.externalProjectToConfiguredProjectMap[proj.projectFileName]; + this.externalProjectToConfiguredProjectMap.delete(proj.projectFileName); this.createAndAddExternalProject(proj.projectFileName, rootFiles, proj.options, proj.typeAcquisition); } if (!suppressRefreshOfInferredProjects) { diff --git a/src/server/lsHost.ts b/src/server/lsHost.ts index 98b3dd9a8c0..9d8c9c08cb6 100644 --- a/src/server/lsHost.ts +++ b/src/server/lsHost.ts @@ -75,15 +75,16 @@ namespace ts.server { for (const name of names) { // check if this is a duplicate entry in the list - let resolution = newResolutions[name]; + let resolution = newResolutions.get(name); if (!resolution) { - const existingResolution = currentResolutionsInFile && currentResolutionsInFile[name]; + const existingResolution = currentResolutionsInFile && currentResolutionsInFile.get(name); if (moduleResolutionIsValid(existingResolution)) { // ok, it is safe to use existing name resolution results resolution = existingResolution; } else { - newResolutions[name] = resolution = loader(name, containingFile, compilerOptions, this); + resolution = loader(name, containingFile, compilerOptions, this); + newResolutions.set(name, resolution); } if (logChanges && this.filesWithChangedSetOfUnresolvedImports && !resolutionIsEqualTo(existingResolution, resolution)) { this.filesWithChangedSetOfUnresolvedImports.push(path); diff --git a/src/server/project.ts b/src/server/project.ts index 3c6d9d7b33f..6042fd9a62b 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1,4 +1,4 @@ -/// +/// /// /// /// @@ -410,7 +410,7 @@ namespace ts.server { } registerFileUpdate(fileName: string) { - (this.updatedFileNames || (this.updatedFileNames = createMap()))[fileName] = fileName; + (this.updatedFileNames || (this.updatedFileNames = createMap())).set(fileName, fileName); } markAsDirty() { @@ -428,9 +428,9 @@ namespace ts.server { } let unresolvedImports: string[]; if (file.resolvedModules) { - for (const name in file.resolvedModules) { + file.resolvedModules.forEach((resolvedModule, name) => { // pick unresolved non-relative names - if (!file.resolvedModules[name] && !isExternalModuleNameRelative(name)) { + if (!resolvedModule && !isExternalModuleNameRelative(name)) { // for non-scoped names extract part up-to the first slash // for scoped names - extract up to the second slash let trimmed = name.trim(); @@ -444,7 +444,7 @@ namespace ts.server { (unresolvedImports || (unresolvedImports = [])).push(trimmed); result.push(trimmed); } - } + }); } this.cachedUnresolvedImportsPerFile.set(file.path, unresolvedImports || emptyArray); } @@ -466,7 +466,7 @@ namespace ts.server { } // 1. no changes in structure, no changes in unresolved imports - do nothing - // 2. no changes in structure, unresolved imports were changed - collect unresolved imports for all files + // 2. no changes in structure, unresolved imports were changed - collect unresolved imports for all files // (can reuse cached imports for files that were not changed) // 3. new files were added/removed, but compilation settings stays the same - collect unresolved imports for all new/modified files // (can reuse cached imports for files that were not changed) @@ -618,17 +618,18 @@ namespace ts.server { const added: string[] = []; const removed: string[] = []; - const updated: string[] = getOwnKeys(updatedFileNames); - for (const id in currentFiles) { - if (!hasProperty(lastReportedFileNames, id)) { + const updated: string[] = arrayFrom(updatedFileNames.keys()); + + forEachKey(currentFiles, id => { + if (!lastReportedFileNames.has(id)) { added.push(id); } - } - for (const id in lastReportedFileNames) { - if (!hasProperty(currentFiles, id)) { + }); + forEachKey(lastReportedFileNames, id => { + if (!currentFiles.has(id)) { removed.push(id); } - } + }); this.lastReportedFileNames = currentFiles; this.lastReportedVersion = this.projectStructureVersion; return { info, changes: { added, removed, updated }, projectErrors: this.projectErrors }; @@ -662,7 +663,7 @@ namespace ts.server { if (symbol && symbol.declarations && symbol.declarations[0]) { const declarationSourceFile = symbol.declarations[0].getSourceFile(); if (declarationSourceFile) { - referencedFiles[declarationSourceFile.path] = true; + referencedFiles.set(declarationSourceFile.path, true); } } } @@ -674,25 +675,24 @@ namespace ts.server { if (sourceFile.referencedFiles && sourceFile.referencedFiles.length > 0) { for (const referencedFile of sourceFile.referencedFiles) { const referencedPath = toPath(referencedFile.fileName, currentDirectory, getCanonicalFileName); - referencedFiles[referencedPath] = true; + referencedFiles.set(referencedPath, true); } } // Handle type reference directives if (sourceFile.resolvedTypeReferenceDirectiveNames) { - for (const typeName in sourceFile.resolvedTypeReferenceDirectiveNames) { - const resolvedTypeReferenceDirective = sourceFile.resolvedTypeReferenceDirectiveNames[typeName]; + sourceFile.resolvedTypeReferenceDirectiveNames.forEach((resolvedTypeReferenceDirective) => { if (!resolvedTypeReferenceDirective) { - continue; + return; } const fileName = resolvedTypeReferenceDirective.resolvedFileName; const typeFilePath = toPath(fileName, currentDirectory, getCanonicalFileName); - referencedFiles[typeFilePath] = true; - } + referencedFiles.set(typeFilePath, true); + }) } - const allFileNames = map(Object.keys(referencedFiles), key => key); + const allFileNames = arrayFrom(referencedFiles.keys()) as Path[]; return filter(allFileNames, file => this.projectService.host.fileExists(file)); } @@ -868,18 +868,19 @@ namespace ts.server { return; } const configDirectoryPath = getDirectoryPath(this.getConfigFilePath()); - this.directoriesWatchedForWildcards = reduceProperties(this.wildcardDirectories, (watchers, flag, directory) => { + + this.directoriesWatchedForWildcards = createMap(); + this.wildcardDirectories.forEach((flag, directory) => { if (comparePaths(configDirectoryPath, directory, ".", !this.projectService.host.useCaseSensitiveFileNames) !== Comparison.EqualTo) { const recursive = (flag & WatchDirectoryFlags.Recursive) !== 0; this.projectService.logger.info(`Add ${recursive ? "recursive " : ""}watcher for: ${directory}`); - watchers[directory] = this.projectService.host.watchDirectory( + this.directoriesWatchedForWildcards.set(directory, this.projectService.host.watchDirectory( directory, path => callback(this, path), recursive - ); + )); } - return watchers; - }, >{}); + }); } stopWatchingDirectory() { @@ -903,9 +904,9 @@ namespace ts.server { this.typeRootsWatchers = undefined; } - for (const id in this.directoriesWatchedForWildcards) { - this.directoriesWatchedForWildcards[id].close(); - } + this.directoriesWatchedForWildcards.forEach(watcher => { + watcher.close(); + }); this.directoriesWatchedForWildcards = undefined; this.stopWatchingDirectory(); diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 680b81dff99..e3fe17362d7 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -417,7 +417,7 @@ namespace ts.server.protocol { startOffset: number; /** - * Position (can be specified instead of line/offset pair) + * Position (can be specified instead of line/offset pair) */ /* @internal */ startPosition?: number; @@ -433,7 +433,7 @@ namespace ts.server.protocol { endOffset: number; /** - * Position (can be specified instead of line/offset pair) + * Position (can be specified instead of line/offset pair) */ /* @internal */ endPosition?: number; @@ -445,7 +445,7 @@ namespace ts.server.protocol { } /** - * Response for GetCodeFixes request. + * Response for GetCodeFixes request. */ export interface GetCodeFixesResponse extends Response { body?: CodeAction[]; @@ -2272,10 +2272,11 @@ namespace ts.server.protocol { export namespace JsxEmit { export type None = "None"; export type Preserve = "Preserve"; + export type ReactNative = "ReactNative"; export type React = "React"; } - export type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React; + export type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React | JsxEmit.ReactNative; export namespace ModuleKind { export type None = "None"; diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index a93600de1a8..be3ef34ce3a 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -278,7 +278,7 @@ namespace ts.server { if (!this.formatCodeSettings) { this.formatCodeSettings = getDefaultFormatCodeSettings(this.host); } - mergeMaps(this.formatCodeSettings, formatSettings); + mergeMapLikes(this.formatCodeSettings, formatSettings); } } diff --git a/src/server/session.ts b/src/server/session.ts index b8eeb9219db..825ad8506d7 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -484,18 +484,20 @@ namespace ts.server { private getImplementation(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.FileSpan[] | ImplementationLocation[] { const { file, project } = this.getFileAndProject(args); - const scriptInfo = project.getScriptInfoForNormalizedPath(file); - const position = this.getPosition(args, scriptInfo); + const position = this.getPosition(args, project.getScriptInfoForNormalizedPath(file)); const implementations = project.getLanguageService().getImplementationAtPosition(file, position); if (!implementations) { return []; } if (simplifiedResult) { - return implementations.map(impl => ({ - file: impl.fileName, - start: scriptInfo.positionToLineOffset(impl.textSpan.start), - end: scriptInfo.positionToLineOffset(ts.textSpanEnd(impl.textSpan)) - })); + return implementations.map(({ fileName, textSpan }) => { + const scriptInfo = project.getScriptInfo(fileName); + return { + file: fileName, + start: scriptInfo.positionToLineOffset(textSpan.start), + end: scriptInfo.positionToLineOffset(ts.textSpanEnd(textSpan)) + }; + }); } else { return implementations; @@ -1390,7 +1392,7 @@ namespace ts.server { return { response, responseRequired: true }; } - private handlers = createMap<(request: protocol.Request) => { response?: any, responseRequired?: boolean }>({ + private handlers = createMapFromTemplate<(request: protocol.Request) => { response?: any, responseRequired?: boolean }>({ [CommandNames.OpenExternalProject]: (request: protocol.OpenExternalProjectRequest) => { this.projectService.openExternalProject(request.arguments, /*suppressRefreshOfInferredProjects*/ false); // TODO: report errors @@ -1634,14 +1636,14 @@ namespace ts.server { }); public addProtocolHandler(command: string, handler: (request: protocol.Request) => { response?: any, responseRequired: boolean }) { - if (command in this.handlers) { + if (this.handlers.has(command)) { throw new Error(`Protocol handler already exists for command "${command}"`); } - this.handlers[command] = handler; + this.handlers.set(command, handler); } public executeCommand(request: protocol.Request): { response?: any, responseRequired?: boolean } { - const handler = this.handlers[request.command]; + const handler = this.handlers.get(request.command); if (handler) { return handler(request); } diff --git a/src/server/typingsCache.ts b/src/server/typingsCache.ts index 8b03d59003c..9379ae82d0e 100644 --- a/src/server/typingsCache.ts +++ b/src/server/typingsCache.ts @@ -35,17 +35,18 @@ namespace ts.server { let unique = 0; for (const v of arr1) { - if (set[v] !== true) { - set[v] = true; + if (set.get(v) !== true) { + set.set(v, true); unique++; } } for (const v of arr2) { - if (!hasProperty(set, v)) { + const isSet = set.get(v); + if (isSet === undefined) { return false; } - if (set[v] === true) { - set[v] = false; + if (isSet === true) { + set.set(v, false); unique--; } } @@ -83,7 +84,7 @@ namespace ts.server { return emptyArray; } - const entry = this.perProjectCache[project.getProjectName()]; + const entry = this.perProjectCache.get(project.getProjectName()); const result: SortedReadonlyArray = entry ? entry.typings : emptyArray; if (forceRefresh || !entry || @@ -92,13 +93,13 @@ namespace ts.server { unresolvedImportsChanged(unresolvedImports, entry.unresolvedImports)) { // Note: entry is now poisoned since it does not really contain typings for a given combination of compiler options\typings options. // instead it acts as a placeholder to prevent issuing multiple requests - this.perProjectCache[project.getProjectName()] = { + this.perProjectCache.set(project.getProjectName(), { compilerOptions: project.getCompilerOptions(), typeAcquisition, typings: result, unresolvedImports, poisoned: true - }; + }); // something has been changed, issue a request to update typings this.installer.enqueueInstallTypingsRequest(project, typeAcquisition, unresolvedImports); } @@ -106,21 +107,21 @@ namespace ts.server { } updateTypingsForProject(projectName: string, compilerOptions: CompilerOptions, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray, newTypings: string[]) { - this.perProjectCache[projectName] = { + this.perProjectCache.set(projectName, { compilerOptions, typeAcquisition, typings: toSortedReadonlyArray(newTypings), unresolvedImports, poisoned: false - }; + }); } deleteTypingsForProject(projectName: string) { - delete this.perProjectCache[projectName]; + this.perProjectCache.delete(projectName); } onProjectClosed(project: Project) { - delete this.perProjectCache[project.getProjectName()]; + this.perProjectCache.delete(project.getProjectName()); this.installer.onProjectClosed(project); } } diff --git a/src/server/typingsInstaller/nodeTypingsInstaller.ts b/src/server/typingsInstaller/nodeTypingsInstaller.ts index 19f794ad57c..ff20e89e2d7 100644 --- a/src/server/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/server/typingsInstaller/nodeTypingsInstaller.ts @@ -46,7 +46,7 @@ namespace ts.server.typingsInstaller { } try { const content = JSON.parse(host.readFile(typesRegistryFilePath)); - return createMap(content.entries); + return createMapFromTemplate(content.entries); } catch (e) { if (log.isEnabled()) { diff --git a/src/server/typingsInstaller/typingsInstaller.ts b/src/server/typingsInstaller/typingsInstaller.ts index f706943a0f5..e889f98789a 100644 --- a/src/server/typingsInstaller/typingsInstaller.ts +++ b/src/server/typingsInstaller/typingsInstaller.ts @@ -112,7 +112,7 @@ namespace ts.server.typingsInstaller { if (this.log.isEnabled()) { this.log.writeLine(`Closing file watchers for project '${projectName}'`); } - const watchers = this.projectWatchers[projectName]; + const watchers = this.projectWatchers.get(projectName); if (!watchers) { if (this.log.isEnabled()) { this.log.writeLine(`No watchers are registered for project '${projectName}'`); @@ -123,7 +123,7 @@ namespace ts.server.typingsInstaller { w.close(); } - delete this.projectWatchers[projectName]; + this.projectWatchers.delete(projectName); if (this.log.isEnabled()) { this.log.writeLine(`Closing file watchers for project '${projectName}' - done.`); @@ -177,7 +177,7 @@ namespace ts.server.typingsInstaller { if (this.log.isEnabled()) { this.log.writeLine(`Processing cache location '${cacheLocation}'`); } - if (this.knownCachesSet[cacheLocation]) { + if (this.knownCachesSet.get(cacheLocation)) { if (this.log.isEnabled()) { this.log.writeLine(`Cache location was already processed...`); } @@ -201,10 +201,10 @@ namespace ts.server.typingsInstaller { } const typingFile = typingToFileName(cacheLocation, packageName, this.installTypingHost, this.log); if (!typingFile) { - this.missingTypingsSet[packageName] = true; + this.missingTypingsSet.set(packageName, true); continue; } - const existingTypingFile = this.packageNameToTypingLocation[packageName]; + const existingTypingFile = this.packageNameToTypingLocation.get(packageName); if (existingTypingFile === typingFile) { continue; } @@ -216,14 +216,14 @@ namespace ts.server.typingsInstaller { if (this.log.isEnabled()) { this.log.writeLine(`Adding entry into typings cache: '${packageName}' => '${typingFile}'`); } - this.packageNameToTypingLocation[packageName] = typingFile; + this.packageNameToTypingLocation.set(packageName, typingFile); } } } if (this.log.isEnabled()) { this.log.writeLine(`Finished processing cache location '${cacheLocation}'`); } - this.knownCachesSet[cacheLocation] = true; + this.knownCachesSet.set(cacheLocation, true); } private filterTypings(typingsToInstall: string[]) { @@ -232,12 +232,12 @@ namespace ts.server.typingsInstaller { } const result: string[] = []; for (const typing of typingsToInstall) { - if (this.missingTypingsSet[typing] || this.packageNameToTypingLocation[typing]) { + if (this.missingTypingsSet.get(typing) || this.packageNameToTypingLocation.get(typing)) { continue; } const validationResult = validatePackageName(typing); if (validationResult === PackageNameValidationResult.Ok) { - if (typing in this.typesRegistry) { + if (this.typesRegistry.has(typing)) { result.push(typing); } else { @@ -248,7 +248,7 @@ namespace ts.server.typingsInstaller { } else { // add typing name to missing set so we won't process it again - this.missingTypingsSet[typing] = true; + this.missingTypingsSet.set(typing, true); if (this.log.isEnabled()) { switch (validationResult) { case PackageNameValidationResult.EmptyName: @@ -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) { @@ -323,7 +323,7 @@ namespace ts.server.typingsInstaller { this.log.writeLine(`install request failed, marking packages as missing to prevent repeated requests: ${JSON.stringify(filteredTypings)}`); } for (const typing of filteredTypings) { - this.missingTypingsSet[typing] = true; + this.missingTypingsSet.set(typing, true); } return; } @@ -336,11 +336,11 @@ namespace ts.server.typingsInstaller { for (const packageName of filteredTypings) { const typingFile = typingToFileName(cachePath, packageName, this.installTypingHost, this.log); if (!typingFile) { - this.missingTypingsSet[packageName] = true; + this.missingTypingsSet.set(packageName, true); continue; } - if (!this.packageNameToTypingLocation[packageName]) { - this.packageNameToTypingLocation[packageName] = typingFile; + if (!this.packageNameToTypingLocation.has(packageName)) { + this.packageNameToTypingLocation.set(packageName, typingFile); } installedTypingFiles.push(typingFile); } @@ -395,7 +395,7 @@ namespace ts.server.typingsInstaller { }, /*pollingInterval*/ 2000); watchers.push(w); } - this.projectWatchers[projectName] = watchers; + this.projectWatchers.set(projectName, watchers); } private createSetTypings(request: DiscoverTypings, typings: string[]): SetTypings { @@ -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/server/utilities.ts b/src/server/utilities.ts index 1889b055d29..af1f8e9826f 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -95,7 +95,7 @@ namespace ts.server { }; } - export function mergeMaps(target: MapLike, source: MapLike ): void { + export function mergeMapLikes(target: MapLike, source: MapLike ): void { for (const key in source) { if (hasProperty(source, key)) { target[key] = source[key]; @@ -145,20 +145,20 @@ namespace ts.server { export function createNormalizedPathMap(): NormalizedPathMap { /* tslint:disable:no-null-keyword */ - const map: Map = Object.create(null); + const map = createMap(); /* tslint:enable:no-null-keyword */ return { get(path) { - return map[path]; + return map.get(path); }, set(path, value) { - map[path] = value; + map.set(path, value); }, contains(path) { - return hasProperty(map, path); + return map.has(path); }, remove(path) { - delete map[path]; + map.delete(path); } }; } @@ -198,16 +198,17 @@ namespace ts.server { } public schedule(operationId: string, delay: number, cb: () => void) { - if (hasProperty(this.pendingTimeouts, operationId)) { + const pendingTimeout = this.pendingTimeouts.get(operationId); + if (pendingTimeout) { // another operation was already scheduled for this id - cancel it - this.host.clearTimeout(this.pendingTimeouts[operationId]); + this.host.clearTimeout(pendingTimeout); } // schedule new operation, pass arguments - this.pendingTimeouts[operationId] = this.host.setTimeout(ThrottledOperations.run, delay, this, operationId, cb); + this.pendingTimeouts.set(operationId, this.host.setTimeout(ThrottledOperations.run, delay, this, operationId, cb)); } private static run(self: ThrottledOperations, operationId: string, cb: () => void) { - delete self.pendingTimeouts[operationId]; + self.pendingTimeouts.delete(operationId); cb(); } } diff --git a/src/services/classifier.ts b/src/services/classifier.ts index 4f553924b99..c15b65b0c39 100644 --- a/src/services/classifier.ts +++ b/src/services/classifier.ts @@ -557,7 +557,7 @@ namespace ts { // Only bother calling into the typechecker if this is an identifier that // could possibly resolve to a type name. This makes classification run // in a third of the time it would normally take. - if (classifiableNames[identifier.text]) { + if (classifiableNames.get(identifier.text)) { const symbol = typeChecker.getSymbolAtLocation(node); if (symbol) { const type = classifySymbol(symbol, getMeaningFromLocation(node)); diff --git a/src/services/codeFixProvider.ts b/src/services/codeFixProvider.ts index e4489fc2dca..10d0b8eef34 100644 --- a/src/services/codeFixProvider.ts +++ b/src/services/codeFixProvider.ts @@ -16,7 +16,7 @@ namespace ts { } export namespace codefix { - const codeFixes = createMap(); + const codeFixes: CodeFix[][] = []; export function registerCodeFix(action: CodeFix) { forEach(action.errorCodes, error => { diff --git a/src/services/codefixes/fixForgottenThisPropertyAccess.ts b/src/services/codefixes/fixForgottenThisPropertyAccess.ts new file mode 100644 index 00000000000..c9d59dd8337 --- /dev/null +++ b/src/services/codefixes/fixForgottenThisPropertyAccess.ts @@ -0,0 +1,16 @@ +/* @internal */ +namespace ts.codefix { + registerCodeFix({ + errorCodes: [Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0.code], + getCodeActions: (context: CodeFixContext) => { + const sourceFile = context.sourceFile; + const token = getTokenAtPosition(sourceFile, context.span.start); + const start = token.getStart(sourceFile); + + return [{ + description: getLocaleSpecificMessage(Diagnostics.Add_this_to_unresolved_variable), + changes: [{ fileName: sourceFile.fileName, textChanges: [{ newText: "this.", span: { start, length: 0 } }] }] + }]; + } + }); +} \ No newline at end of file diff --git a/src/services/codefixes/fixes.ts b/src/services/codefixes/fixes.ts index 10d6fa50158..3bd173e04f6 100644 --- a/src/services/codefixes/fixes.ts +++ b/src/services/codefixes/fixes.ts @@ -3,7 +3,7 @@ /// /// /// +/// /// /// /// - diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index d539ef0d68b..7bee4f5a0ed 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -9,7 +9,7 @@ namespace ts.codefix { */ export function getMissingMembersInsertion(classDeclaration: ClassLikeDeclaration, possiblyMissingSymbols: Symbol[], checker: TypeChecker, newlineChar: string): string { const classMembers = classDeclaration.symbol.members; - const missingMembers = possiblyMissingSymbols.filter(symbol => !(symbol.getName() in classMembers)); + const missingMembers = possiblyMissingSymbols.filter(symbol => !classMembers.has(symbol.getName())); let insertion = ""; diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 8c6222ff845..3642e46612c 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -14,20 +14,21 @@ namespace ts.codefix { } class ImportCodeActionMap { - private symbolIdToActionMap = createMap(); + private symbolIdToActionMap: ImportCodeAction[][] = []; addAction(symbolId: number, newAction: ImportCodeAction) { if (!newAction) { return; } - if (!this.symbolIdToActionMap[symbolId]) { + const actions = this.symbolIdToActionMap[symbolId]; + if (!actions) { this.symbolIdToActionMap[symbolId] = [newAction]; return; } if (newAction.kind === "CodeChange") { - this.symbolIdToActionMap[symbolId].push(newAction); + actions.push(newAction); return; } @@ -73,8 +74,8 @@ namespace ts.codefix { getAllActions() { let result: ImportCodeAction[] = []; - for (const symbolId in this.symbolIdToActionMap) { - result = concatenate(result, this.symbolIdToActionMap[symbolId]); + for (const key in this.symbolIdToActionMap) { + result = concatenate(result, this.symbolIdToActionMap[key]) } return result; } @@ -127,7 +128,7 @@ namespace ts.codefix { const symbolIdActionMap = new ImportCodeActionMap(); // this is a module id -> module import declaration map - const cachedImportDeclarations = createMap<(ImportDeclaration | ImportEqualsDeclaration)[]>(); + const cachedImportDeclarations: (ImportDeclaration | ImportEqualsDeclaration)[][] = []; let cachedNewImportInsertPosition: number; const currentTokenMeaning = getMeaningFromLocation(token); @@ -170,8 +171,9 @@ namespace ts.codefix { function getImportDeclarations(moduleSymbol: Symbol) { const moduleSymbolId = getUniqueSymbolId(moduleSymbol); - if (cachedImportDeclarations[moduleSymbolId]) { - return cachedImportDeclarations[moduleSymbolId]; + const cached = cachedImportDeclarations[moduleSymbolId]; + if (cached) { + return cached; } const existingDeclarations: (ImportDeclaration | ImportEqualsDeclaration)[] = []; @@ -414,8 +416,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(); @@ -437,8 +439,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; } @@ -475,9 +476,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); @@ -544,9 +544,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; } @@ -562,20 +562,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/completions.ts b/src/services/completions.ts index bb5922af9ad..df78ab931d1 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1,12 +1,14 @@ /* @internal */ namespace ts.Completions { - export function getCompletionsAtPosition(host: LanguageServiceHost, typeChecker: TypeChecker, log: (message: string) => void, compilerOptions: CompilerOptions, sourceFile: SourceFile, position: number): CompletionInfo | undefined { + export type Log = (message: string) => void; + + export function getCompletionsAtPosition(host: LanguageServiceHost, typeChecker: TypeChecker, log: Log, compilerOptions: CompilerOptions, sourceFile: SourceFile, position: number): CompletionInfo | undefined { if (isInReferenceComment(sourceFile, position)) { - return getTripleSlashReferenceCompletion(sourceFile, position); + return getTripleSlashReferenceCompletion(sourceFile, position, compilerOptions, host); } if (isInString(sourceFile, position)) { - return getStringLiteralCompletionEntries(sourceFile, position); + return getStringLiteralCompletionEntries(sourceFile, position, typeChecker, compilerOptions, host, log); } const completionData = getCompletionData(typeChecker, log, sourceFile, position); @@ -24,8 +26,8 @@ namespace ts.Completions { const entries: CompletionEntry[] = []; if (isSourceFileJavaScript(sourceFile)) { - const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true); - addRange(entries, getJavaScriptCompletionEntries(sourceFile, location.pos, uniqueNames)); + const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log); + addRange(entries, getJavaScriptCompletionEntries(sourceFile, location.pos, uniqueNames, compilerOptions.target)); } else { if (!symbols || symbols.length === 0) { @@ -48,7 +50,7 @@ namespace ts.Completions { } } - getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true); + getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log); } // Add keywords if this is not a member completion list @@ -57,696 +59,703 @@ namespace ts.Completions { } return { isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, entries }; + } - function getJavaScriptCompletionEntries(sourceFile: SourceFile, position: number, uniqueNames: Map): CompletionEntry[] { - const entries: CompletionEntry[] = []; + function getJavaScriptCompletionEntries(sourceFile: SourceFile, position: number, uniqueNames: Map, target: ScriptTarget): CompletionEntry[] { + const entries: CompletionEntry[] = []; - const nameTable = getNameTable(sourceFile); - for (const name in nameTable) { - // Skip identifiers produced only from the current location - if (nameTable[name] === position) { - continue; - } - - if (!uniqueNames[name]) { - uniqueNames[name] = name; - const displayName = getCompletionEntryDisplayName(unescapeIdentifier(name), compilerOptions.target, /*performCharacterChecks*/ true); - if (displayName) { - const entry = { - name: displayName, - kind: ScriptElementKind.warning, - kindModifiers: "", - sortText: "1" - }; - entries.push(entry); - } - } - } - - return entries; - } - - function createCompletionEntry(symbol: Symbol, location: Node, performCharacterChecks: boolean): CompletionEntry { - // Try to get a valid display name for this symbol, if we could not find one, then ignore it. - // We would like to only show things that can be added after a dot, so for instance numeric properties can - // not be accessed with a dot (a.1 <- invalid) - const displayName = getCompletionEntryDisplayNameForSymbol(typeChecker, symbol, compilerOptions.target, performCharacterChecks, location); - if (!displayName) { - return undefined; - } - - // TODO(drosen): Right now we just permit *all* semantic meanings when calling - // 'getSymbolKind' which is permissible given that it is backwards compatible; but - // really we should consider passing the meaning for the node so that we don't report - // that a suggestion for a value is an interface. We COULD also just do what - // 'getSymbolModifiers' does, which is to use the first declaration. - - // Use a 'sortText' of 0' so that all symbol completion entries come before any other - // entries (like JavaScript identifier entries). - return { - name: displayName, - kind: SymbolDisplay.getSymbolKind(typeChecker, symbol, location), - kindModifiers: SymbolDisplay.getSymbolModifiers(symbol), - sortText: "0", - }; - - } - - function getCompletionEntriesFromSymbols(symbols: Symbol[], entries: CompletionEntry[], location: Node, performCharacterChecks: boolean): Map { - const start = timestamp(); - const uniqueNames = createMap(); - if (symbols) { - for (const symbol of symbols) { - const entry = createCompletionEntry(symbol, location, performCharacterChecks); - if (entry) { - const id = escapeIdentifier(entry.name); - if (!uniqueNames[id]) { - entries.push(entry); - uniqueNames[id] = id; - } - } - } - } - - log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (timestamp() - start)); - return uniqueNames; - } - - function getStringLiteralCompletionEntries(sourceFile: SourceFile, position: number): CompletionInfo | undefined { - const node = findPrecedingToken(position, sourceFile); - if (!node || node.kind !== SyntaxKind.StringLiteral) { - return undefined; - } - - if (node.parent.kind === SyntaxKind.PropertyAssignment && - node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression && - (node.parent).name === node) { - // Get quoted name of properties of the object literal expression - // i.e. interface ConfigFiles { - // 'jspm:dev': string - // } - // let files: ConfigFiles = { - // '/*completion position*/' - // } - // - // function foo(c: ConfigFiles) {} - // foo({ - // '/*completion position*/' - // }); - return getStringLiteralCompletionEntriesFromPropertyAssignment(node.parent); - } - else if (isElementAccessExpression(node.parent) && node.parent.argumentExpression === node) { - // Get all names of properties on the expression - // i.e. interface A { - // 'prop1': string - // } - // let a: A; - // a['/*completion position*/'] - return getStringLiteralCompletionEntriesFromElementAccess(node.parent); - } - else if (node.parent.kind === SyntaxKind.ImportDeclaration || isExpressionOfExternalModuleImportEqualsDeclaration(node) || isRequireCall(node.parent, false)) { - // Get all known external module names or complete a path to a module - // i.e. import * as ns from "/*completion position*/"; - // import x = require("/*completion position*/"); - // var y = require("/*completion position*/"); - return getStringLiteralCompletionEntriesFromModuleNames(node); - } - else { - const argumentInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile); - if (argumentInfo) { - // Get string literal completions from specialized signatures of the target - // i.e. declare function f(a: 'A'); - // f("/*completion position*/") - return getStringLiteralCompletionEntriesFromCallExpression(argumentInfo); - } - - // Get completion for string literal from string literal type - // i.e. var x: "hi" | "hello" = "/*completion position*/" - return getStringLiteralCompletionEntriesFromContextualType(node); - } - } - - function getStringLiteralCompletionEntriesFromPropertyAssignment(element: ObjectLiteralElement): CompletionInfo | undefined { - const type = typeChecker.getContextualType((element.parent)); - const entries: CompletionEntry[] = []; - if (type) { - getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, element, /*performCharacterChecks*/false); - if (entries.length) { - return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries }; - } - } - } - - function getStringLiteralCompletionEntriesFromCallExpression(argumentInfo: SignatureHelp.ArgumentListInfo): CompletionInfo | undefined { - const candidates: Signature[] = []; - const entries: CompletionEntry[] = []; - - typeChecker.getResolvedSignature(argumentInfo.invocation, candidates); - - for (const candidate of candidates) { - if (candidate.parameters.length > argumentInfo.argumentIndex) { - const parameter = candidate.parameters[argumentInfo.argumentIndex]; - addStringLiteralCompletionsFromType(typeChecker.getTypeAtLocation(parameter.valueDeclaration), entries); - } - } - - if (entries.length) { - return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: true, entries }; - } - - return undefined; - } - - function getStringLiteralCompletionEntriesFromElementAccess(node: ElementAccessExpression): CompletionInfo | undefined { - const type = typeChecker.getTypeAtLocation(node.expression); - const entries: CompletionEntry[] = []; - if (type) { - getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, node, /*performCharacterChecks*/false); - if (entries.length) { - return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries }; - } - } - return undefined; - } - - function getStringLiteralCompletionEntriesFromContextualType(node: StringLiteral): CompletionInfo | undefined { - const type = typeChecker.getContextualType(node); - if (type) { - const entries: CompletionEntry[] = []; - addStringLiteralCompletionsFromType(type, entries); - if (entries.length) { - return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries }; - } - } - return undefined; - } - - function addStringLiteralCompletionsFromType(type: Type, result: Push): void { - if (type && type.flags & TypeFlags.TypeParameter) { - type = typeChecker.getApparentType(type); - } - if (!type) { + const nameTable = getNameTable(sourceFile); + nameTable.forEach((pos, name) => { + // Skip identifiers produced only from the current location + if (pos === position) { return; } - if (type.flags & TypeFlags.Union) { - for (const t of (type).types) { - addStringLiteralCompletionsFromType(t, result); + + if (!uniqueNames.get(name)) { + uniqueNames.set(name, name); + const displayName = getCompletionEntryDisplayName(unescapeIdentifier(name), target, /*performCharacterChecks*/ true); + if (displayName) { + const entry = { + name: displayName, + kind: ScriptElementKind.warning, + kindModifiers: "", + sortText: "1" + }; + entries.push(entry); } } - else if (type.flags & TypeFlags.StringLiteral) { - result.push({ - name: (type).text, - kindModifiers: ScriptElementKindModifier.none, - kind: ScriptElementKind.variableElement, - sortText: "0" - }); + }); + + return entries; + } + + function createCompletionEntry(symbol: Symbol, location: Node, performCharacterChecks: boolean, typeChecker: TypeChecker, target: ScriptTarget): CompletionEntry { + // Try to get a valid display name for this symbol, if we could not find one, then ignore it. + // We would like to only show things that can be added after a dot, so for instance numeric properties can + // not be accessed with a dot (a.1 <- invalid) + const displayName = getCompletionEntryDisplayNameForSymbol(typeChecker, symbol, target, performCharacterChecks, location); + if (!displayName) { + return undefined; + } + + // TODO(drosen): Right now we just permit *all* semantic meanings when calling + // 'getSymbolKind' which is permissible given that it is backwards compatible; but + // really we should consider passing the meaning for the node so that we don't report + // that a suggestion for a value is an interface. We COULD also just do what + // 'getSymbolModifiers' does, which is to use the first declaration. + + // Use a 'sortText' of 0' so that all symbol completion entries come before any other + // entries (like JavaScript identifier entries). + return { + name: displayName, + kind: SymbolDisplay.getSymbolKind(typeChecker, symbol, location), + kindModifiers: SymbolDisplay.getSymbolModifiers(symbol), + sortText: "0", + }; + } + + function getCompletionEntriesFromSymbols(symbols: Symbol[], entries: Push, location: Node, performCharacterChecks: boolean, typeChecker: TypeChecker, target: ScriptTarget, log: Log): Map { + const start = timestamp(); + const uniqueNames = createMap(); + if (symbols) { + for (const symbol of symbols) { + const entry = createCompletionEntry(symbol, location, performCharacterChecks, typeChecker, target); + if (entry) { + const id = escapeIdentifier(entry.name); + if (!uniqueNames.get(id)) { + entries.push(entry); + uniqueNames.set(id, id); + } + } } } - function getStringLiteralCompletionEntriesFromModuleNames(node: StringLiteral): CompletionInfo { - const literalValue = normalizeSlashes(node.text); + log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (timestamp() - start)); + return uniqueNames; + } - const scriptPath = node.getSourceFile().path; - const scriptDirectory = getDirectoryPath(scriptPath); + function getStringLiteralCompletionEntries(sourceFile: SourceFile, position: number, typeChecker: TypeChecker, compilerOptions: CompilerOptions, host: LanguageServiceHost, log: Log): CompletionInfo | undefined { + const node = findPrecedingToken(position, sourceFile); + if (!node || node.kind !== SyntaxKind.StringLiteral) { + return undefined; + } - const span = getDirectoryFragmentTextSpan((node).text, node.getStart() + 1); - let entries: CompletionEntry[]; - if (isPathRelativeToScript(literalValue) || isRootedDiskPath(literalValue)) { - if (compilerOptions.rootDirs) { - entries = getCompletionEntriesForDirectoryFragmentWithRootDirs( - compilerOptions.rootDirs, literalValue, scriptDirectory, getSupportedExtensions(compilerOptions), /*includeExtensions*/false, span, scriptPath); - } - else { - entries = getCompletionEntriesForDirectoryFragment( - literalValue, scriptDirectory, getSupportedExtensions(compilerOptions), /*includeExtensions*/false, span, scriptPath); - } + if (node.parent.kind === SyntaxKind.PropertyAssignment && + node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression && + (node.parent).name === node) { + // Get quoted name of properties of the object literal expression + // i.e. interface ConfigFiles { + // 'jspm:dev': string + // } + // let files: ConfigFiles = { + // '/*completion position*/' + // } + // + // function foo(c: ConfigFiles) {} + // foo({ + // '/*completion position*/' + // }); + return getStringLiteralCompletionEntriesFromPropertyAssignment(node.parent, typeChecker, compilerOptions.target, log); + } + else if (isElementAccessExpression(node.parent) && node.parent.argumentExpression === node) { + // Get all names of properties on the expression + // i.e. interface A { + // 'prop1': string + // } + // let a: A; + // a['/*completion position*/'] + return getStringLiteralCompletionEntriesFromElementAccess(node.parent, typeChecker, compilerOptions.target, log); + } + else if (node.parent.kind === SyntaxKind.ImportDeclaration || isExpressionOfExternalModuleImportEqualsDeclaration(node) || isRequireCall(node.parent, false)) { + // Get all known external module names or complete a path to a module + // i.e. import * as ns from "/*completion position*/"; + // import x = require("/*completion position*/"); + // 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) { + // Get string literal completions from specialized signatures of the target + // i.e. declare function f(a: 'A'); + // f("/*completion position*/") + return getStringLiteralCompletionEntriesFromCallExpression(argumentInfo, typeChecker); + } + + // Get completion for string literal from string literal type + // i.e. var x: "hi" | "hello" = "/*completion position*/" + return getStringLiteralCompletionEntriesFromType(typeChecker.getContextualType(node), typeChecker); + } + } + + function getStringLiteralCompletionEntriesFromPropertyAssignment(element: ObjectLiteralElement, typeChecker: TypeChecker, target: ScriptTarget, log: Log): CompletionInfo | undefined { + const type = typeChecker.getContextualType((element.parent)); + const entries: CompletionEntry[] = []; + if (type) { + getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, element, /*performCharacterChecks*/false, typeChecker, target, log); + if (entries.length) { + return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries }; + } + } + } + + function getStringLiteralCompletionEntriesFromCallExpression(argumentInfo: SignatureHelp.ArgumentListInfo, typeChecker: TypeChecker): CompletionInfo | undefined { + const candidates: Signature[] = []; + const entries: CompletionEntry[] = []; + + typeChecker.getResolvedSignature(argumentInfo.invocation, candidates); + + for (const candidate of candidates) { + addStringLiteralCompletionsFromType(typeChecker.getParameterType(candidate, argumentInfo.argumentIndex), entries, typeChecker); + } + + if (entries.length) { + return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: true, entries }; + } + + return undefined; + } + + function getStringLiteralCompletionEntriesFromElementAccess(node: ElementAccessExpression, typeChecker: TypeChecker, target: ScriptTarget, log: Log): CompletionInfo | undefined { + const type = typeChecker.getTypeAtLocation(node.expression); + const entries: CompletionEntry[] = []; + if (type) { + getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, node, /*performCharacterChecks*/false, typeChecker, target, log); + if (entries.length) { + return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries }; + } + } + return undefined; + } + + function getStringLiteralCompletionEntriesFromType(type: Type, typeChecker: TypeChecker): CompletionInfo | undefined { + if (type) { + const entries: CompletionEntry[] = []; + addStringLiteralCompletionsFromType(type, entries, typeChecker); + if (entries.length) { + return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries }; + } + } + return undefined; + } + + function addStringLiteralCompletionsFromType(type: Type, result: Push, typeChecker: TypeChecker): void { + if (type && type.flags & TypeFlags.TypeParameter) { + type = typeChecker.getApparentType(type); + } + if (!type) { + return; + } + if (type.flags & TypeFlags.Union) { + for (const t of (type).types) { + addStringLiteralCompletionsFromType(t, result, typeChecker); + } + } + else if (type.flags & TypeFlags.StringLiteral) { + result.push({ + name: (type).text, + kindModifiers: ScriptElementKindModifier.none, + kind: ScriptElementKind.variableElement, + sortText: "0" + }); + } + } + + function getStringLiteralCompletionEntriesFromModuleNames(node: StringLiteral, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker): CompletionInfo { + const literalValue = normalizeSlashes(node.text); + + const scriptPath = node.getSourceFile().path; + const scriptDirectory = getDirectoryPath(scriptPath); + + const span = getDirectoryFragmentTextSpan((node).text, node.getStart() + 1); + let entries: CompletionEntry[]; + if (isPathRelativeToScript(literalValue) || isRootedDiskPath(literalValue)) { + const extensions = getSupportedExtensions(compilerOptions); + if (compilerOptions.rootDirs) { + entries = getCompletionEntriesForDirectoryFragmentWithRootDirs( + compilerOptions.rootDirs, literalValue, scriptDirectory, extensions, /*includeExtensions*/false, span, compilerOptions, host, scriptPath); } else { - // Check for node modules - entries = getCompletionEntriesForNonRelativeModules(literalValue, scriptDirectory, span); + entries = getCompletionEntriesForDirectoryFragment( + literalValue, scriptDirectory, extensions, /*includeExtensions*/false, span, host, scriptPath); } - return { - isGlobalCompletion: false, - isMemberCompletion: false, - isNewIdentifierLocation: true, - entries - }; } + else { + // Check for node modules + entries = getCompletionEntriesForNonRelativeModules(literalValue, scriptDirectory, span, compilerOptions, host, typeChecker); + } + return { + isGlobalCompletion: false, + isMemberCompletion: false, + isNewIdentifierLocation: true, + entries + }; + } + + /** + * Takes a script path and returns paths for all potential folders that could be merged with its + * containing folder via the "rootDirs" compiler option + */ + function getBaseDirectoriesFromRootDirs(rootDirs: string[], basePath: string, scriptPath: string, ignoreCase: boolean): string[] { + // Make all paths absolute/normalized if they are not already + rootDirs = map(rootDirs, rootDirectory => normalizePath(isRootedDiskPath(rootDirectory) ? rootDirectory : combinePaths(basePath, rootDirectory))); + + // Determine the path to the directory containing the script relative to the root directory it is contained within + let relativeDirectory: string; + for (const rootDirectory of rootDirs) { + if (containsPath(rootDirectory, scriptPath, basePath, ignoreCase)) { + relativeDirectory = scriptPath.substr(rootDirectory.length); + break; + } + } + + // Now find a path for each potential directory that is to be merged with the one containing the script + return deduplicate(map(rootDirs, rootDirectory => combinePaths(rootDirectory, relativeDirectory))); + } + + function getCompletionEntriesForDirectoryFragmentWithRootDirs(rootDirs: string[], fragment: string, scriptPath: string, extensions: string[], includeExtensions: boolean, span: TextSpan, compilerOptions: CompilerOptions, host: LanguageServiceHost, exclude?: string): CompletionEntry[] { + const basePath = compilerOptions.project || host.getCurrentDirectory(); + const ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames()); + const baseDirectories = getBaseDirectoriesFromRootDirs(rootDirs, basePath, scriptPath, ignoreCase); + + const result: CompletionEntry[] = []; + + for (const baseDirectory of baseDirectories) { + getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensions, includeExtensions, span, host, exclude, result); + } + + return result; + } + + /** + * Given a path ending at a directory, gets the completions for the path, and filters for those entries containing the basename. + */ + function getCompletionEntriesForDirectoryFragment(fragment: string, scriptPath: string, extensions: string[], includeExtensions: boolean, span: TextSpan, host: LanguageServiceHost, exclude?: string, result: CompletionEntry[] = []): CompletionEntry[] { + if (fragment === undefined) { + fragment = ""; + } + + fragment = normalizeSlashes(fragment); /** - * Takes a script path and returns paths for all potential folders that could be merged with its - * containing folder via the "rootDirs" compiler option + * Remove the basename from the path. Note that we don't use the basename to filter completions; + * the client is responsible for refining completions. */ - function getBaseDirectoriesFromRootDirs(rootDirs: string[], basePath: string, scriptPath: string, ignoreCase: boolean): string[] { - // Make all paths absolute/normalized if they are not already - rootDirs = map(rootDirs, rootDirectory => normalizePath(isRootedDiskPath(rootDirectory) ? rootDirectory : combinePaths(basePath, rootDirectory))); + fragment = getDirectoryPath(fragment); - // Determine the path to the directory containing the script relative to the root directory it is contained within - let relativeDirectory: string; - for (const rootDirectory of rootDirs) { - if (containsPath(rootDirectory, scriptPath, basePath, ignoreCase)) { - relativeDirectory = scriptPath.substr(rootDirectory.length); - break; - } - } - - // Now find a path for each potential directory that is to be merged with the one containing the script - return deduplicate(map(rootDirs, rootDirectory => combinePaths(rootDirectory, relativeDirectory))); + if (fragment === "") { + fragment = "." + directorySeparator; } - function getCompletionEntriesForDirectoryFragmentWithRootDirs(rootDirs: string[], fragment: string, scriptPath: string, extensions: string[], includeExtensions: boolean, span: TextSpan, exclude?: string): CompletionEntry[] { - const basePath = compilerOptions.project || host.getCurrentDirectory(); - const ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames()); - const baseDirectories = getBaseDirectoriesFromRootDirs(rootDirs, basePath, scriptPath, ignoreCase); + fragment = ensureTrailingDirectorySeparator(fragment); - const result: CompletionEntry[] = []; + const absolutePath = normalizeAndPreserveTrailingSlash(isRootedDiskPath(fragment) ? fragment : combinePaths(scriptPath, fragment)); + const baseDirectory = getDirectoryPath(absolutePath); + const ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames()); - for (const baseDirectory of baseDirectories) { - getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensions, includeExtensions, span, exclude, result); - } + if (tryDirectoryExists(host, baseDirectory)) { + // Enumerate the available files if possible + const files = tryReadDirectory(host, baseDirectory, extensions, /*exclude*/undefined, /*include*/["./*"]); - return result; - } - - /** - * Given a path ending at a directory, gets the completions for the path, and filters for those entries containing the basename. - */ - function getCompletionEntriesForDirectoryFragment(fragment: string, scriptPath: string, extensions: string[], includeExtensions: boolean, span: TextSpan, exclude?: string, result: CompletionEntry[] = []): CompletionEntry[] { - if (fragment === undefined) { - fragment = ""; - } - - fragment = normalizeSlashes(fragment); - - /** - * Remove the basename from the path. Note that we don't use the basename to filter completions; - * the client is responsible for refining completions. - */ - fragment = getDirectoryPath(fragment); - - if (fragment === "") { - fragment = "." + directorySeparator; - } - - fragment = ensureTrailingDirectorySeparator(fragment); - - const absolutePath = normalizeAndPreserveTrailingSlash(isRootedDiskPath(fragment) ? fragment : combinePaths(scriptPath, fragment)); - const baseDirectory = getDirectoryPath(absolutePath); - const ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames()); - - if (tryDirectoryExists(host, baseDirectory)) { - // Enumerate the available files if possible - const files = tryReadDirectory(host, baseDirectory, extensions, /*exclude*/undefined, /*include*/["./*"]); - - if (files) { - /** - * Multiple file entries might map to the same truncated name once we remove extensions - * (happens iff includeExtensions === false)so we use a set-like data structure. Eg: - * - * both foo.ts and foo.tsx become foo - */ - const foundFiles = createMap(); - for (let filePath of files) { - filePath = normalizePath(filePath); - if (exclude && comparePaths(filePath, exclude, scriptPath, ignoreCase) === Comparison.EqualTo) { - continue; - } - - const foundFileName = includeExtensions ? getBaseFileName(filePath) : removeFileExtension(getBaseFileName(filePath)); - - if (!foundFiles[foundFileName]) { - foundFiles[foundFileName] = true; - } + if (files) { + /** + * Multiple file entries might map to the same truncated name once we remove extensions + * (happens iff includeExtensions === false)so we use a set-like data structure. Eg: + * + * both foo.ts and foo.tsx become foo + */ + const foundFiles = createMap(); + for (let filePath of files) { + filePath = normalizePath(filePath); + if (exclude && comparePaths(filePath, exclude, scriptPath, ignoreCase) === Comparison.EqualTo) { + continue; } - for (const foundFile in foundFiles) { - result.push(createCompletionEntryForModule(foundFile, ScriptElementKind.scriptElement, span)); + const foundFileName = includeExtensions ? getBaseFileName(filePath) : removeFileExtension(getBaseFileName(filePath)); + + if (!foundFiles.get(foundFileName)) { + foundFiles.set(foundFileName, true); } } - // If possible, get folder completion as well - const directories = tryGetDirectories(host, baseDirectory); - - if (directories) { - for (const directory of directories) { - const directoryName = getBaseFileName(normalizePath(directory)); - - result.push(createCompletionEntryForModule(directoryName, ScriptElementKind.directory, span)); - } - } + forEachKey(foundFiles, foundFile => { + result.push(createCompletionEntryForModule(foundFile, ScriptElementKind.scriptElement, span)); + }); } - return result; + // If possible, get folder completion as well + const directories = tryGetDirectories(host, baseDirectory); + + if (directories) { + for (const directory of directories) { + const directoryName = getBaseFileName(normalizePath(directory)); + + result.push(createCompletionEntryForModule(directoryName, ScriptElementKind.directory, span)); + } + } } - /** - * Check all of the declared modules and those in node modules. Possible sources of modules: - * Modules that are found by the type checker - * Modules found relative to "baseUrl" compliler options (including patterns from "paths" compiler option) - * Modules from node_modules (i.e. those listed in package.json) - * This includes all files that are found in node_modules/moduleName/ with acceptable file extensions - */ - function getCompletionEntriesForNonRelativeModules(fragment: string, scriptPath: string, span: TextSpan): CompletionEntry[] { - const { baseUrl, paths } = compilerOptions; + return result; + } - let result: CompletionEntry[]; + /** + * Check all of the declared modules and those in node modules. Possible sources of modules: + * Modules that are found by the type checker + * Modules found relative to "baseUrl" compliler options (including patterns from "paths" compiler option) + * Modules from node_modules (i.e. those listed in package.json) + * This includes all files that are found in node_modules/moduleName/ with acceptable file extensions + */ + function getCompletionEntriesForNonRelativeModules(fragment: string, scriptPath: string, span: TextSpan, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker): CompletionEntry[] { + const { baseUrl, paths } = compilerOptions; - if (baseUrl) { - const fileExtensions = getSupportedExtensions(compilerOptions); - const projectDir = compilerOptions.project || host.getCurrentDirectory(); - const absolute = isRootedDiskPath(baseUrl) ? baseUrl : combinePaths(projectDir, baseUrl); - result = getCompletionEntriesForDirectoryFragment(fragment, normalizePath(absolute), fileExtensions, /*includeExtensions*/false, span); + let result: CompletionEntry[]; - if (paths) { - for (const path in paths) { - if (paths.hasOwnProperty(path)) { - if (path === "*") { - if (paths[path]) { - for (const pattern of paths[path]) { - for (const match of getModulesForPathsPattern(fragment, baseUrl, pattern, fileExtensions)) { - result.push(createCompletionEntryForModule(match, ScriptElementKind.externalModuleName, span)); - } + if (baseUrl) { + const fileExtensions = getSupportedExtensions(compilerOptions); + const projectDir = compilerOptions.project || host.getCurrentDirectory(); + const absolute = isRootedDiskPath(baseUrl) ? baseUrl : combinePaths(projectDir, baseUrl); + result = getCompletionEntriesForDirectoryFragment(fragment, normalizePath(absolute), fileExtensions, /*includeExtensions*/false, span, host); + + if (paths) { + for (const path in paths) { + if (paths.hasOwnProperty(path)) { + if (path === "*") { + if (paths[path]) { + for (const pattern of paths[path]) { + for (const match of getModulesForPathsPattern(fragment, baseUrl, pattern, fileExtensions, host)) { + result.push(createCompletionEntryForModule(match, ScriptElementKind.externalModuleName, span)); } } } - else if (startsWith(path, fragment)) { - const entry = paths[path] && paths[path].length === 1 && paths[path][0]; - if (entry) { - result.push(createCompletionEntryForModule(path, ScriptElementKind.externalModuleName, span)); - } + } + else if (startsWith(path, fragment)) { + const entry = paths[path] && paths[path].length === 1 && paths[path][0]; + if (entry) { + result.push(createCompletionEntryForModule(path, ScriptElementKind.externalModuleName, span)); } } } } } - else { - result = []; - } - - getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span, result); - - for (const moduleName of enumeratePotentialNonRelativeModules(fragment, scriptPath, compilerOptions)) { - result.push(createCompletionEntryForModule(moduleName, ScriptElementKind.externalModuleName, span)); - } - - return result; + } + else { + result = []; } - function getModulesForPathsPattern(fragment: string, baseUrl: string, pattern: string, fileExtensions: string[]): string[] { - if (host.readDirectory) { - const parsed = hasZeroOrOneAsteriskCharacter(pattern) ? tryParsePattern(pattern) : undefined; - if (parsed) { - // The prefix has two effective parts: the directory path and the base component after the filepath that is not a - // full directory component. For example: directory/path/of/prefix/base* - const normalizedPrefix = normalizeAndPreserveTrailingSlash(parsed.prefix); - const normalizedPrefixDirectory = getDirectoryPath(normalizedPrefix); - const normalizedPrefixBase = getBaseFileName(normalizedPrefix); + getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span, result); - const fragmentHasPath = fragment.indexOf(directorySeparator) !== -1; + for (const moduleName of enumeratePotentialNonRelativeModules(fragment, scriptPath, compilerOptions, typeChecker, host)) { + result.push(createCompletionEntryForModule(moduleName, ScriptElementKind.externalModuleName, span)); + } - // Try and expand the prefix to include any path from the fragment so that we can limit the readDirectory call - const expandedPrefixDirectory = fragmentHasPath ? combinePaths(normalizedPrefixDirectory, normalizedPrefixBase + getDirectoryPath(fragment)) : normalizedPrefixDirectory; + return result; + } - const normalizedSuffix = normalizePath(parsed.suffix); - const baseDirectory = combinePaths(baseUrl, expandedPrefixDirectory); - const completePrefix = fragmentHasPath ? baseDirectory : ensureTrailingDirectorySeparator(baseDirectory) + normalizedPrefixBase; + function getModulesForPathsPattern(fragment: string, baseUrl: string, pattern: string, fileExtensions: string[], host: LanguageServiceHost): string[] { + if (host.readDirectory) { + const parsed = hasZeroOrOneAsteriskCharacter(pattern) ? tryParsePattern(pattern) : undefined; + if (parsed) { + // The prefix has two effective parts: the directory path and the base component after the filepath that is not a + // full directory component. For example: directory/path/of/prefix/base* + const normalizedPrefix = normalizeAndPreserveTrailingSlash(parsed.prefix); + const normalizedPrefixDirectory = getDirectoryPath(normalizedPrefix); + const normalizedPrefixBase = getBaseFileName(normalizedPrefix); - // If we have a suffix, then we need to read the directory all the way down. We could create a glob - // that encodes the suffix, but we would have to escape the character "?" which readDirectory - // doesn't support. For now, this is safer but slower - const includeGlob = normalizedSuffix ? "**/*" : "./*"; + const fragmentHasPath = fragment.indexOf(directorySeparator) !== -1; - const matches = tryReadDirectory(host, baseDirectory, fileExtensions, undefined, [includeGlob]); - if (matches) { - const result: string[] = []; + // Try and expand the prefix to include any path from the fragment so that we can limit the readDirectory call + const expandedPrefixDirectory = fragmentHasPath ? combinePaths(normalizedPrefixDirectory, normalizedPrefixBase + getDirectoryPath(fragment)) : normalizedPrefixDirectory; - // Trim away prefix and suffix - for (const match of matches) { - const normalizedMatch = normalizePath(match); - if (!endsWith(normalizedMatch, normalizedSuffix) || !startsWith(normalizedMatch, completePrefix)) { - continue; - } + const normalizedSuffix = normalizePath(parsed.suffix); + const baseDirectory = combinePaths(baseUrl, expandedPrefixDirectory); + const completePrefix = fragmentHasPath ? baseDirectory : ensureTrailingDirectorySeparator(baseDirectory) + normalizedPrefixBase; - const start = completePrefix.length; - const length = normalizedMatch.length - start - normalizedSuffix.length; + // If we have a suffix, then we need to read the directory all the way down. We could create a glob + // that encodes the suffix, but we would have to escape the character "?" which readDirectory + // doesn't support. For now, this is safer but slower + const includeGlob = normalizedSuffix ? "**/*" : "./*"; - result.push(removeFileExtension(normalizedMatch.substr(start, length))); + const matches = tryReadDirectory(host, baseDirectory, fileExtensions, undefined, [includeGlob]); + if (matches) { + const result: string[] = []; + + // Trim away prefix and suffix + for (const match of matches) { + const normalizedMatch = normalizePath(match); + if (!endsWith(normalizedMatch, normalizedSuffix) || !startsWith(normalizedMatch, completePrefix)) { + continue; + } + + const start = completePrefix.length; + const length = normalizedMatch.length - start - normalizedSuffix.length; + + result.push(removeFileExtension(normalizedMatch.substr(start, length))); + } + return result; + } + } + } + + return undefined; + } + + function enumeratePotentialNonRelativeModules(fragment: string, scriptPath: string, options: CompilerOptions, typeChecker: TypeChecker, host: LanguageServiceHost): string[] { + // Check If this is a nested module + const isNestedModule = fragment.indexOf(directorySeparator) !== -1; + const moduleNameFragment = isNestedModule ? fragment.substr(0, fragment.lastIndexOf(directorySeparator)) : undefined; + + // Get modules that the type checker picked up + const ambientModules = map(typeChecker.getAmbientModules(), sym => stripQuotes(sym.name)); + let nonRelativeModules = filter(ambientModules, moduleName => startsWith(moduleName, fragment)); + + // Nested modules of the form "module-name/sub" need to be adjusted to only return the string + // after the last '/' that appears in the fragment because that's where the replacement span + // starts + if (isNestedModule) { + const moduleNameWithSeperator = ensureTrailingDirectorySeparator(moduleNameFragment); + nonRelativeModules = map(nonRelativeModules, moduleName => { + if (startsWith(fragment, moduleNameWithSeperator)) { + return moduleName.substr(moduleNameWithSeperator.length); + } + return moduleName; + }); + } + + + if (!options.moduleResolution || options.moduleResolution === ModuleResolutionKind.NodeJs) { + for (const visibleModule of enumerateNodeModulesVisibleToScript(host, scriptPath)) { + if (!isNestedModule) { + nonRelativeModules.push(visibleModule.moduleName); + } + else if (startsWith(visibleModule.moduleName, moduleNameFragment)) { + const nestedFiles = tryReadDirectory(host, visibleModule.moduleDir, supportedTypeScriptExtensions, /*exclude*/undefined, /*include*/["./*"]); + if (nestedFiles) { + for (let f of nestedFiles) { + f = normalizePath(f); + const nestedModule = removeFileExtension(getBaseFileName(f)); + nonRelativeModules.push(nestedModule); } - return result; } } } + } + return deduplicate(nonRelativeModules); + } + + function getTripleSlashReferenceCompletion(sourceFile: SourceFile, position: number, compilerOptions: CompilerOptions, host: LanguageServiceHost): CompletionInfo { + const token = getTokenAtPosition(sourceFile, position); + if (!token) { + return undefined; + } + const commentRanges: CommentRange[] = getLeadingCommentRanges(sourceFile.text, token.pos); + + if (!commentRanges || !commentRanges.length) { return undefined; } - function enumeratePotentialNonRelativeModules(fragment: string, scriptPath: string, options: CompilerOptions): string[] { - // Check If this is a nested module - const isNestedModule = fragment.indexOf(directorySeparator) !== -1; - const moduleNameFragment = isNestedModule ? fragment.substr(0, fragment.lastIndexOf(directorySeparator)) : undefined; + const range = forEach(commentRanges, commentRange => position >= commentRange.pos && position <= commentRange.end && commentRange); - // Get modules that the type checker picked up - const ambientModules = map(typeChecker.getAmbientModules(), sym => stripQuotes(sym.name)); - let nonRelativeModules = filter(ambientModules, moduleName => startsWith(moduleName, fragment)); - - // Nested modules of the form "module-name/sub" need to be adjusted to only return the string - // after the last '/' that appears in the fragment because that's where the replacement span - // starts - if (isNestedModule) { - const moduleNameWithSeperator = ensureTrailingDirectorySeparator(moduleNameFragment); - nonRelativeModules = map(nonRelativeModules, moduleName => { - if (startsWith(fragment, moduleNameWithSeperator)) { - return moduleName.substr(moduleNameWithSeperator.length); - } - return moduleName; - }); - } - - - if (!options.moduleResolution || options.moduleResolution === ModuleResolutionKind.NodeJs) { - for (const visibleModule of enumerateNodeModulesVisibleToScript(host, scriptPath)) { - if (!isNestedModule) { - nonRelativeModules.push(visibleModule.moduleName); - } - else if (startsWith(visibleModule.moduleName, moduleNameFragment)) { - const nestedFiles = tryReadDirectory(host, visibleModule.moduleDir, supportedTypeScriptExtensions, /*exclude*/undefined, /*include*/["./*"]); - if (nestedFiles) { - for (let f of nestedFiles) { - f = normalizePath(f); - const nestedModule = removeFileExtension(getBaseFileName(f)); - nonRelativeModules.push(nestedModule); - } - } - } - } - } - - return deduplicate(nonRelativeModules); + if (!range) { + return undefined; } - function getTripleSlashReferenceCompletion(sourceFile: SourceFile, position: number): CompletionInfo { - const token = getTokenAtPosition(sourceFile, position); - if (!token) { - return undefined; + const completionInfo: CompletionInfo = { + /** + * We don't want the editor to offer any other completions, such as snippets, inside a comment. + */ + isGlobalCompletion: false, + isMemberCompletion: false, + /** + * The user may type in a path that doesn't yet exist, creating a "new identifier" + * with respect to the collection of identifiers the server is aware of. + */ + isNewIdentifierLocation: true, + + entries: [] + }; + + const text = sourceFile.text.substr(range.pos, position - range.pos); + + const match = tripleSlashDirectiveFragmentRegex.exec(text); + + if (match) { + const prefix = match[1]; + const kind = match[2]; + const toComplete = match[3]; + + const scriptPath = getDirectoryPath(sourceFile.path); + if (kind === "path") { + // Give completions for a relative path + const span: TextSpan = getDirectoryFragmentTextSpan(toComplete, range.pos + prefix.length); + completionInfo.entries = getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(compilerOptions), /*includeExtensions*/true, span, host, sourceFile.path); } - const commentRanges: CommentRange[] = getLeadingCommentRanges(sourceFile.text, token.pos); - - if (!commentRanges || !commentRanges.length) { - return undefined; + else { + // Give completions based on the typings available + const span: TextSpan = { start: range.pos + prefix.length, length: match[0].length - prefix.length }; + completionInfo.entries = getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span); } - - const range = forEach(commentRanges, commentRange => position >= commentRange.pos && position <= commentRange.end && commentRange); - - if (!range) { - return undefined; - } - - const completionInfo: CompletionInfo = { - /** - * We don't want the editor to offer any other completions, such as snippets, inside a comment. - */ - isGlobalCompletion: false, - isMemberCompletion: false, - /** - * The user may type in a path that doesn't yet exist, creating a "new identifier" - * with respect to the collection of identifiers the server is aware of. - */ - isNewIdentifierLocation: true, - - entries: [] - }; - - const text = sourceFile.text.substr(range.pos, position - range.pos); - - const match = tripleSlashDirectiveFragmentRegex.exec(text); - - if (match) { - const prefix = match[1]; - const kind = match[2]; - const toComplete = match[3]; - - const scriptPath = getDirectoryPath(sourceFile.path); - if (kind === "path") { - // Give completions for a relative path - const span: TextSpan = getDirectoryFragmentTextSpan(toComplete, range.pos + prefix.length); - completionInfo.entries = getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(compilerOptions), /*includeExtensions*/true, span, sourceFile.path); - } - else { - // Give completions based on the typings available - const span: TextSpan = { start: range.pos + prefix.length, length: match[0].length - prefix.length }; - completionInfo.entries = getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span); - } - } - - return completionInfo; } - function getCompletionEntriesFromTypings(host: LanguageServiceHost, options: CompilerOptions, scriptPath: string, span: TextSpan, result: CompletionEntry[] = []): CompletionEntry[] { - // Check for typings specified in compiler options - if (options.types) { - for (const moduleName of options.types) { - result.push(createCompletionEntryForModule(moduleName, ScriptElementKind.externalModuleName, span)); - } - } - else if (host.getDirectories) { - let typeRoots: string[]; - try { - // Wrap in try catch because getEffectiveTypeRoots touches the filesystem - typeRoots = getEffectiveTypeRoots(options, host); - } - catch (e) {} + return completionInfo; + } - if (typeRoots) { - for (const root of typeRoots) { - getCompletionEntriesFromDirectories(host, root, span, result); - } - } + function getCompletionEntriesFromTypings(host: LanguageServiceHost, options: CompilerOptions, scriptPath: string, span: TextSpan, result: CompletionEntry[] = []): CompletionEntry[] { + // Check for typings specified in compiler options + if (options.types) { + for (const moduleName of options.types) { + result.push(createCompletionEntryForModule(moduleName, ScriptElementKind.externalModuleName, span)); } - - if (host.getDirectories) { - // Also get all @types typings installed in visible node_modules directories - for (const packageJson of findPackageJsons(scriptPath)) { - const typesDir = combinePaths(getDirectoryPath(packageJson), "node_modules/@types"); - getCompletionEntriesFromDirectories(host, typesDir, span, result); - } - } - - return result; } + else if (host.getDirectories) { + let typeRoots: string[]; + try { + // Wrap in try catch because getEffectiveTypeRoots touches the filesystem + typeRoots = getEffectiveTypeRoots(options, host); + } + catch (e) {} - function getCompletionEntriesFromDirectories(host: LanguageServiceHost, directory: string, span: TextSpan, result: CompletionEntry[]) { - if (host.getDirectories && tryDirectoryExists(host, directory)) { - const directories = tryGetDirectories(host, directory); - if (directories) { - for (let typeDirectory of directories) { - typeDirectory = normalizePath(typeDirectory); - result.push(createCompletionEntryForModule(getBaseFileName(typeDirectory), ScriptElementKind.externalModuleName, span)); - } + if (typeRoots) { + for (const root of typeRoots) { + getCompletionEntriesFromDirectories(host, root, span, result); } } } - function findPackageJsons(currentDir: string): string[] { - const paths: string[] = []; - let currentConfigPath: string; - while (true) { - currentConfigPath = findConfigFile(currentDir, (f) => tryFileExists(host, f), "package.json"); - if (currentConfigPath) { - paths.push(currentConfigPath); + if (host.getDirectories) { + // Also get all @types typings installed in visible node_modules directories + for (const packageJson of findPackageJsons(scriptPath, host)) { + const typesDir = combinePaths(getDirectoryPath(packageJson), "node_modules/@types"); + getCompletionEntriesFromDirectories(host, typesDir, span, result); + } + } - currentDir = getDirectoryPath(currentConfigPath); - const parent = getDirectoryPath(currentDir); - if (currentDir === parent) { - break; - } - currentDir = parent; + return result; + } + + function getCompletionEntriesFromDirectories(host: LanguageServiceHost, directory: string, span: TextSpan, result: Push) { + if (host.getDirectories && tryDirectoryExists(host, directory)) { + const directories = tryGetDirectories(host, directory); + if (directories) { + for (let typeDirectory of directories) { + typeDirectory = normalizePath(typeDirectory); + result.push(createCompletionEntryForModule(getBaseFileName(typeDirectory), ScriptElementKind.externalModuleName, span)); } - else { + } + } + } + + function findPackageJsons(currentDir: string, host: LanguageServiceHost): string[] { + const paths: string[] = []; + let currentConfigPath: string; + while (true) { + currentConfigPath = findConfigFile(currentDir, (f) => tryFileExists(host, f), "package.json"); + if (currentConfigPath) { + paths.push(currentConfigPath); + + currentDir = getDirectoryPath(currentConfigPath); + const parent = getDirectoryPath(currentDir); + if (currentDir === parent) { break; } + currentDir = parent; + } + else { + break; } - - return paths; } + return paths; + } - function enumerateNodeModulesVisibleToScript(host: LanguageServiceHost, scriptPath: string) { - const result: VisibleModuleInfo[] = []; + function enumerateNodeModulesVisibleToScript(host: LanguageServiceHost, scriptPath: string) { + const result: VisibleModuleInfo[] = []; - if (host.readFile && host.fileExists) { - for (const packageJson of findPackageJsons(scriptPath)) { - const contents = tryReadingPackageJson(packageJson); - if (!contents) { - return; - } - - const nodeModulesDir = combinePaths(getDirectoryPath(packageJson), "node_modules"); - const foundModuleNames: string[] = []; - - // Provide completions for all non @types dependencies - for (const key of nodeModulesDependencyKeys) { - addPotentialPackageNames(contents[key], foundModuleNames); - } - - for (const moduleName of foundModuleNames) { - const moduleDir = combinePaths(nodeModulesDir, moduleName); - result.push({ - moduleName, - moduleDir - }); - } + if (host.readFile && host.fileExists) { + for (const packageJson of findPackageJsons(scriptPath, host)) { + const contents = tryReadingPackageJson(packageJson); + if (!contents) { + return; } - } - return result; + const nodeModulesDir = combinePaths(getDirectoryPath(packageJson), "node_modules"); + const foundModuleNames: string[] = []; - function tryReadingPackageJson(filePath: string) { - try { - const fileText = tryReadFile(host, filePath); - return fileText ? JSON.parse(fileText) : undefined; + // Provide completions for all non @types dependencies + for (const key of nodeModulesDependencyKeys) { + addPotentialPackageNames(contents[key], foundModuleNames); } - catch (e) { - return undefined; - } - } - function addPotentialPackageNames(dependencies: any, result: string[]) { - if (dependencies) { - for (const dep in dependencies) { - if (dependencies.hasOwnProperty(dep) && !startsWith(dep, "@types/")) { - result.push(dep); - } - } + for (const moduleName of foundModuleNames) { + const moduleDir = combinePaths(nodeModulesDir, moduleName); + result.push({ + moduleName, + moduleDir + }); } } } - function createCompletionEntryForModule(name: string, kind: string, replacementSpan: TextSpan): CompletionEntry { - return { name, kind, kindModifiers: ScriptElementKindModifier.none, sortText: name, replacementSpan }; - } + return result; - // Replace everything after the last directory seperator that appears - function getDirectoryFragmentTextSpan(text: string, textStart: number): TextSpan { - const index = text.lastIndexOf(directorySeparator); - const offset = index !== -1 ? index + 1 : 0; - return { start: textStart + offset, length: text.length - offset }; - } - - // Returns true if the path is explicitly relative to the script (i.e. relative to . or ..) - function isPathRelativeToScript(path: string) { - if (path && path.length >= 2 && path.charCodeAt(0) === CharacterCodes.dot) { - const slashIndex = path.length >= 3 && path.charCodeAt(1) === CharacterCodes.dot ? 2 : 1; - const slashCharCode = path.charCodeAt(slashIndex); - return slashCharCode === CharacterCodes.slash || slashCharCode === CharacterCodes.backslash; + function tryReadingPackageJson(filePath: string) { + try { + const fileText = tryReadFile(host, filePath); + return fileText ? JSON.parse(fileText) : undefined; + } + catch (e) { + return undefined; } - return false; } - function normalizeAndPreserveTrailingSlash(path: string) { - return hasTrailingDirectorySeparator(path) ? ensureTrailingDirectorySeparator(normalizePath(path)) : normalizePath(path); + function addPotentialPackageNames(dependencies: any, result: string[]) { + if (dependencies) { + for (const dep in dependencies) { + if (dependencies.hasOwnProperty(dep) && !startsWith(dep, "@types/")) { + result.push(dep); + } + } + } } } + function createCompletionEntryForModule(name: string, kind: string, replacementSpan: TextSpan): CompletionEntry { + return { name, kind, kindModifiers: ScriptElementKindModifier.none, sortText: name, replacementSpan }; + } + + // Replace everything after the last directory seperator that appears + function getDirectoryFragmentTextSpan(text: string, textStart: number): TextSpan { + const index = text.lastIndexOf(directorySeparator); + const offset = index !== -1 ? index + 1 : 0; + return { start: textStart + offset, length: text.length - offset }; + } + + // Returns true if the path is explicitly relative to the script (i.e. relative to . or ..) + function isPathRelativeToScript(path: string) { + if (path && path.length >= 2 && path.charCodeAt(0) === CharacterCodes.dot) { + const slashIndex = path.length >= 3 && path.charCodeAt(1) === CharacterCodes.dot ? 2 : 1; + const slashCharCode = path.charCodeAt(slashIndex); + return slashCharCode === CharacterCodes.slash || slashCharCode === CharacterCodes.backslash; + } + return false; + } + + function normalizeAndPreserveTrailingSlash(path: string) { + return hasTrailingDirectorySeparator(path) ? ensureTrailingDirectorySeparator(normalizePath(path)) : normalizePath(path); + } + export function getCompletionEntryDetails(typeChecker: TypeChecker, log: (message: string) => void, compilerOptions: CompilerOptions, sourceFile: SourceFile, position: number, entryName: string): CompletionEntryDetails { // Compute all the completion symbols again. const completionData = getCompletionData(typeChecker, log, sourceFile, position); @@ -1564,14 +1573,14 @@ namespace ts.Completions { } const name = element.propertyName || element.name; - existingImportsOrExports[name.text] = true; + existingImportsOrExports.set(name.text, true); } - if (!someProperties(existingImportsOrExports)) { + if (existingImportsOrExports.size === 0) { return filter(exportsOfModule, e => e.name !== "default"); } - return filter(exportsOfModule, e => e.name !== "default" && !existingImportsOrExports[e.name]); + return filter(exportsOfModule, e => e.name !== "default" && !existingImportsOrExports.get(e.name)); } /** @@ -1617,10 +1626,10 @@ namespace ts.Completions { existingName = (m.name).text; } - existingMemberNames[existingName] = true; + existingMemberNames.set(existingName, true); } - return filter(contextualMemberSymbols, m => !existingMemberNames[m.name]); + return filter(contextualMemberSymbols, m => !existingMemberNames.get(m.name)); } /** @@ -1638,11 +1647,11 @@ namespace ts.Completions { } if (attr.kind === SyntaxKind.JsxAttribute) { - seenNames[(attr).name.text] = true; + seenNames.set((attr).name.text, true); } } - return filter(symbols, a => !seenNames[a.name]); + return filter(symbols, a => !seenNames.get(a.name)); } } @@ -1758,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/documentHighlights.ts b/src/services/documentHighlights.ts index 0f18427e568..ff2b819ec26 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -2,626 +2,606 @@ namespace ts.DocumentHighlights { export function getDocumentHighlights(typeChecker: TypeChecker, cancellationToken: CancellationToken, sourceFile: SourceFile, position: number, sourceFilesToSearch: SourceFile[]): DocumentHighlights[] { const node = getTouchingWord(sourceFile, position); + return node && (getSemanticDocumentHighlights(node, typeChecker, cancellationToken, sourceFilesToSearch) || getSyntacticDocumentHighlights(node, sourceFile)); + } + + function getHighlightSpanForNode(node: Node, sourceFile: SourceFile): HighlightSpan { + const start = node.getStart(sourceFile); + const end = node.getEnd(); + + return { + fileName: sourceFile.fileName, + textSpan: createTextSpanFromBounds(start, end), + kind: HighlightSpanKind.none + }; + } + + function getSemanticDocumentHighlights(node: Node, typeChecker: TypeChecker, cancellationToken: CancellationToken, sourceFilesToSearch: SourceFile[]): DocumentHighlights[] { + const referencedSymbols = FindAllReferences.getReferencedSymbolsForNode(typeChecker, cancellationToken, node, sourceFilesToSearch); + return referencedSymbols && convertReferencedSymbols(referencedSymbols); + } + + function convertReferencedSymbols(referencedSymbols: ReferencedSymbol[]): DocumentHighlights[] { + const fileNameToDocumentHighlights = createMap(); + const result: DocumentHighlights[] = []; + for (const referencedSymbol of referencedSymbols) { + for (const referenceEntry of referencedSymbol.references) { + const fileName = referenceEntry.fileName; + let documentHighlights = fileNameToDocumentHighlights.get(fileName); + if (!documentHighlights) { + documentHighlights = { fileName, highlightSpans: [] }; + + fileNameToDocumentHighlights.set(fileName, documentHighlights); + result.push(documentHighlights); + } + + documentHighlights.highlightSpans.push({ + textSpan: referenceEntry.textSpan, + kind: referenceEntry.isWriteAccess ? HighlightSpanKind.writtenReference : HighlightSpanKind.reference + }); + } + } + + return result; + } + + function getSyntacticDocumentHighlights(node: Node, sourceFile: SourceFile): DocumentHighlights[] { + const highlightSpans = getHighlightSpans(node, sourceFile); + if (!highlightSpans || highlightSpans.length === 0) { + return undefined; + } + + return [{ fileName: sourceFile.fileName, highlightSpans }]; + } + + // returns true if 'node' is defined and has a matching 'kind'. + function hasKind(node: Node, kind: SyntaxKind) { + return node !== undefined && node.kind === kind; + } + + // Null-propagating 'parent' function. + function parent(node: Node): Node { + return node && node.parent; + } + + function getHighlightSpans(node: Node, sourceFile: SourceFile): HighlightSpan[] { if (!node) { return undefined; } - return getSemanticDocumentHighlights(node) || getSyntacticDocumentHighlights(node); - - function getHighlightSpanForNode(node: Node): HighlightSpan { - const start = node.getStart(); - const end = node.getEnd(); - - return { - fileName: sourceFile.fileName, - textSpan: createTextSpanFromBounds(start, end), - kind: HighlightSpanKind.none - }; + switch (node.kind) { + case SyntaxKind.IfKeyword: + case SyntaxKind.ElseKeyword: + if (hasKind(node.parent, SyntaxKind.IfStatement)) { + return getIfElseOccurrences(node.parent, sourceFile); + } + break; + case SyntaxKind.ReturnKeyword: + if (hasKind(node.parent, SyntaxKind.ReturnStatement)) { + return highlightSpans(getReturnOccurrences(node.parent)); + } + break; + case SyntaxKind.ThrowKeyword: + if (hasKind(node.parent, SyntaxKind.ThrowStatement)) { + return highlightSpans(getThrowOccurrences(node.parent)); + } + break; + case SyntaxKind.TryKeyword: + case SyntaxKind.CatchKeyword: + case SyntaxKind.FinallyKeyword: + const tryStatement = node.kind === SyntaxKind.CatchKeyword ? parent(parent(node)) : parent(node); + if (hasKind(tryStatement, SyntaxKind.TryStatement)) { + return highlightSpans(getTryCatchFinallyOccurrences(tryStatement, sourceFile)); + } + break; + case SyntaxKind.SwitchKeyword: + if (hasKind(node.parent, SyntaxKind.SwitchStatement)) { + return highlightSpans(getSwitchCaseDefaultOccurrences(node.parent)); + } + break; + case SyntaxKind.CaseKeyword: + case SyntaxKind.DefaultKeyword: + if (hasKind(parent(parent(parent(node))), SyntaxKind.SwitchStatement)) { + return highlightSpans(getSwitchCaseDefaultOccurrences(node.parent.parent.parent)); + } + break; + case SyntaxKind.BreakKeyword: + case SyntaxKind.ContinueKeyword: + if (hasKind(node.parent, SyntaxKind.BreakStatement) || hasKind(node.parent, SyntaxKind.ContinueStatement)) { + return highlightSpans(getBreakOrContinueStatementOccurrences(node.parent)); + } + break; + case SyntaxKind.ForKeyword: + if (hasKind(node.parent, SyntaxKind.ForStatement) || + hasKind(node.parent, SyntaxKind.ForInStatement) || + hasKind(node.parent, SyntaxKind.ForOfStatement)) { + return highlightSpans(getLoopBreakContinueOccurrences(node.parent)); + } + break; + case SyntaxKind.WhileKeyword: + case SyntaxKind.DoKeyword: + if (hasKind(node.parent, SyntaxKind.WhileStatement) || hasKind(node.parent, SyntaxKind.DoStatement)) { + return highlightSpans(getLoopBreakContinueOccurrences(node.parent)); + } + break; + case SyntaxKind.ConstructorKeyword: + if (hasKind(node.parent, SyntaxKind.Constructor)) { + return highlightSpans(getConstructorOccurrences(node.parent)); + } + break; + case SyntaxKind.GetKeyword: + case SyntaxKind.SetKeyword: + if (hasKind(node.parent, SyntaxKind.GetAccessor) || hasKind(node.parent, SyntaxKind.SetAccessor)) { + return highlightSpans(getGetAndSetOccurrences(node.parent)); + } + break; + default: + if (isModifierKind(node.kind) && node.parent && + (isDeclaration(node.parent) || node.parent.kind === SyntaxKind.VariableStatement)) { + return highlightSpans(getModifierOccurrences(node.kind, node.parent)); + } } - function getSemanticDocumentHighlights(node: Node): DocumentHighlights[] { - if (node.kind === SyntaxKind.Identifier || - node.kind === SyntaxKind.ThisKeyword || - node.kind === SyntaxKind.ThisType || - node.kind === SyntaxKind.SuperKeyword || - node.kind === SyntaxKind.StringLiteral || - isLiteralNameOfPropertyDeclarationOrIndexAccess(node)) { - - const referencedSymbols = FindAllReferences.getReferencedSymbolsForNode(typeChecker, cancellationToken, node, sourceFilesToSearch, /*findInStrings*/ false, /*findInComments*/ false, /*implementations*/false); - return convertReferencedSymbols(referencedSymbols); - - } - - return undefined; - - function convertReferencedSymbols(referencedSymbols: ReferencedSymbol[]): DocumentHighlights[] { - if (!referencedSymbols) { - return undefined; - } - - const fileNameToDocumentHighlights = createMap(); - const result: DocumentHighlights[] = []; - for (const referencedSymbol of referencedSymbols) { - for (const referenceEntry of referencedSymbol.references) { - const fileName = referenceEntry.fileName; - let documentHighlights = fileNameToDocumentHighlights[fileName]; - if (!documentHighlights) { - documentHighlights = { fileName, highlightSpans: [] }; - - fileNameToDocumentHighlights[fileName] = documentHighlights; - result.push(documentHighlights); - } - - documentHighlights.highlightSpans.push({ - textSpan: referenceEntry.textSpan, - kind: referenceEntry.isWriteAccess ? HighlightSpanKind.writtenReference : HighlightSpanKind.reference - }); - } - } - - return result; - } + function highlightSpans(nodes: Node[]): HighlightSpan[] { + return nodes && nodes.map(node => getHighlightSpanForNode(node, sourceFile)); } + } - function getSyntacticDocumentHighlights(node: Node): DocumentHighlights[] { - const fileName = sourceFile.fileName; + /** + * Aggregates all throw-statements within this node *without* crossing + * into function boundaries and try-blocks with catch-clauses. + */ + function aggregateOwnedThrowStatements(node: Node): ThrowStatement[] { + const statementAccumulator: ThrowStatement[] = []; + aggregate(node); + return statementAccumulator; - const highlightSpans = getHighlightSpans(node); - if (!highlightSpans || highlightSpans.length === 0) { - return undefined; + function aggregate(node: Node): void { + if (node.kind === SyntaxKind.ThrowStatement) { + statementAccumulator.push(node); } - - return [{ fileName, highlightSpans }]; - - // returns true if 'node' is defined and has a matching 'kind'. - function hasKind(node: Node, kind: SyntaxKind) { - return node !== undefined && node.kind === kind; - } - - // Null-propagating 'parent' function. - function parent(node: Node): Node { - return node && node.parent; - } - - function getHighlightSpans(node: Node): HighlightSpan[] { - if (node) { - switch (node.kind) { - case SyntaxKind.IfKeyword: - case SyntaxKind.ElseKeyword: - if (hasKind(node.parent, SyntaxKind.IfStatement)) { - return getIfElseOccurrences(node.parent); - } - break; - case SyntaxKind.ReturnKeyword: - if (hasKind(node.parent, SyntaxKind.ReturnStatement)) { - return getReturnOccurrences(node.parent); - } - break; - case SyntaxKind.ThrowKeyword: - if (hasKind(node.parent, SyntaxKind.ThrowStatement)) { - return getThrowOccurrences(node.parent); - } - break; - case SyntaxKind.CatchKeyword: - if (hasKind(parent(parent(node)), SyntaxKind.TryStatement)) { - return getTryCatchFinallyOccurrences(node.parent.parent); - } - break; - case SyntaxKind.TryKeyword: - case SyntaxKind.FinallyKeyword: - if (hasKind(parent(node), SyntaxKind.TryStatement)) { - return getTryCatchFinallyOccurrences(node.parent); - } - break; - case SyntaxKind.SwitchKeyword: - if (hasKind(node.parent, SyntaxKind.SwitchStatement)) { - return getSwitchCaseDefaultOccurrences(node.parent); - } - break; - case SyntaxKind.CaseKeyword: - case SyntaxKind.DefaultKeyword: - if (hasKind(parent(parent(parent(node))), SyntaxKind.SwitchStatement)) { - return getSwitchCaseDefaultOccurrences(node.parent.parent.parent); - } - break; - case SyntaxKind.BreakKeyword: - case SyntaxKind.ContinueKeyword: - if (hasKind(node.parent, SyntaxKind.BreakStatement) || hasKind(node.parent, SyntaxKind.ContinueStatement)) { - return getBreakOrContinueStatementOccurrences(node.parent); - } - break; - case SyntaxKind.ForKeyword: - if (hasKind(node.parent, SyntaxKind.ForStatement) || - hasKind(node.parent, SyntaxKind.ForInStatement) || - hasKind(node.parent, SyntaxKind.ForOfStatement)) { - return getLoopBreakContinueOccurrences(node.parent); - } - break; - case SyntaxKind.WhileKeyword: - case SyntaxKind.DoKeyword: - if (hasKind(node.parent, SyntaxKind.WhileStatement) || hasKind(node.parent, SyntaxKind.DoStatement)) { - return getLoopBreakContinueOccurrences(node.parent); - } - break; - case SyntaxKind.ConstructorKeyword: - if (hasKind(node.parent, SyntaxKind.Constructor)) { - return getConstructorOccurrences(node.parent); - } - break; - case SyntaxKind.GetKeyword: - case SyntaxKind.SetKeyword: - if (hasKind(node.parent, SyntaxKind.GetAccessor) || hasKind(node.parent, SyntaxKind.SetAccessor)) { - return getGetAndSetOccurrences(node.parent); - } - break; - default: - if (isModifierKind(node.kind) && node.parent && - (isDeclaration(node.parent) || node.parent.kind === SyntaxKind.VariableStatement)) { - return getModifierOccurrences(node.kind, node.parent); - } - } - } - - return undefined; - } - - /** - * Aggregates all throw-statements within this node *without* crossing - * into function boundaries and try-blocks with catch-clauses. - */ - function aggregateOwnedThrowStatements(node: Node): ThrowStatement[] { - const statementAccumulator: ThrowStatement[] = []; - aggregate(node); - return statementAccumulator; - - function aggregate(node: Node): void { - if (node.kind === SyntaxKind.ThrowStatement) { - statementAccumulator.push(node); - } - else if (node.kind === SyntaxKind.TryStatement) { - const tryStatement = node; - - if (tryStatement.catchClause) { - aggregate(tryStatement.catchClause); - } - else { - // Exceptions thrown within a try block lacking a catch clause - // are "owned" in the current context. - aggregate(tryStatement.tryBlock); - } - - if (tryStatement.finallyBlock) { - aggregate(tryStatement.finallyBlock); - } - } - // Do not cross function boundaries. - else if (!isFunctionLike(node)) { - forEachChild(node, aggregate); - } - } - } - - /** - * For lack of a better name, this function takes a throw statement and returns the - * nearest ancestor that is a try-block (whose try statement has a catch clause), - * function-block, or source file. - */ - function getThrowStatementOwner(throwStatement: ThrowStatement): Node { - let child: Node = throwStatement; - - while (child.parent) { - const parent = child.parent; - - if (isFunctionBlock(parent) || parent.kind === SyntaxKind.SourceFile) { - return parent; - } - - // A throw-statement is only owned by a try-statement if the try-statement has - // a catch clause, and if the throw-statement occurs within the try block. - if (parent.kind === SyntaxKind.TryStatement) { - const tryStatement = parent; - - if (tryStatement.tryBlock === child && tryStatement.catchClause) { - return child; - } - } - - child = parent; - } - - return undefined; - } - - function aggregateAllBreakAndContinueStatements(node: Node): BreakOrContinueStatement[] { - const statementAccumulator: BreakOrContinueStatement[] = []; - aggregate(node); - return statementAccumulator; - - function aggregate(node: Node): void { - if (node.kind === SyntaxKind.BreakStatement || node.kind === SyntaxKind.ContinueStatement) { - statementAccumulator.push(node); - } - // Do not cross function boundaries. - else if (!isFunctionLike(node)) { - forEachChild(node, aggregate); - } - } - } - - function ownsBreakOrContinueStatement(owner: Node, statement: BreakOrContinueStatement): boolean { - const actualOwner = getBreakOrContinueOwner(statement); - - return actualOwner && actualOwner === owner; - } - - function getBreakOrContinueOwner(statement: BreakOrContinueStatement): Node { - for (let node = statement.parent; node; node = node.parent) { - switch (node.kind) { - case SyntaxKind.SwitchStatement: - if (statement.kind === SyntaxKind.ContinueStatement) { - continue; - } - // Fall through. - case SyntaxKind.ForStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.WhileStatement: - case SyntaxKind.DoStatement: - if (!statement.label || isLabeledBy(node, statement.label.text)) { - return node; - } - break; - default: - // Don't cross function boundaries. - if (isFunctionLike(node)) { - return undefined; - } - break; - } - } - - return undefined; - } - - function getModifierOccurrences(modifier: SyntaxKind, declaration: Node): HighlightSpan[] { - const container = declaration.parent; - - // Make sure we only highlight the keyword when it makes sense to do so. - if (isAccessibilityModifier(modifier)) { - if (!(container.kind === SyntaxKind.ClassDeclaration || - container.kind === SyntaxKind.ClassExpression || - (declaration.kind === SyntaxKind.Parameter && hasKind(container, SyntaxKind.Constructor)))) { - return undefined; - } - } - else if (modifier === SyntaxKind.StaticKeyword) { - if (!(container.kind === SyntaxKind.ClassDeclaration || container.kind === SyntaxKind.ClassExpression)) { - return undefined; - } - } - else if (modifier === SyntaxKind.ExportKeyword || modifier === SyntaxKind.DeclareKeyword) { - if (!(container.kind === SyntaxKind.ModuleBlock || container.kind === SyntaxKind.SourceFile)) { - return undefined; - } - } - else if (modifier === SyntaxKind.AbstractKeyword) { - if (!(container.kind === SyntaxKind.ClassDeclaration || declaration.kind === SyntaxKind.ClassDeclaration)) { - return undefined; - } - } - else { - // unsupported modifier - return undefined; - } - - const keywords: Node[] = []; - const modifierFlag: ModifierFlags = getFlagFromModifier(modifier); - - let nodes: Node[]; - switch (container.kind) { - case SyntaxKind.ModuleBlock: - case SyntaxKind.SourceFile: - // Container is either a class declaration or the declaration is a classDeclaration - if (modifierFlag & ModifierFlags.Abstract) { - nodes = ((declaration).members).concat(declaration); - } - else { - nodes = (container).statements; - } - break; - case SyntaxKind.Constructor: - nodes = ((container).parameters).concat( - (container.parent).members); - break; - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - nodes = (container).members; - - // If we're an accessibility modifier, we're in an instance member and should search - // the constructor's parameter list for instance members as well. - if (modifierFlag & ModifierFlags.AccessibilityModifier) { - const constructor = forEach((container).members, member => { - return member.kind === SyntaxKind.Constructor && member; - }); - - if (constructor) { - nodes = nodes.concat(constructor.parameters); - } - } - else if (modifierFlag & ModifierFlags.Abstract) { - nodes = nodes.concat(container); - } - break; - default: - Debug.fail("Invalid container kind."); - } - - forEach(nodes, node => { - if (getModifierFlags(node) & modifierFlag) { - forEach(node.modifiers, child => pushKeywordIf(keywords, child, modifier)); - } - }); - - return map(keywords, getHighlightSpanForNode); - - function getFlagFromModifier(modifier: SyntaxKind) { - switch (modifier) { - case SyntaxKind.PublicKeyword: - return ModifierFlags.Public; - case SyntaxKind.PrivateKeyword: - return ModifierFlags.Private; - case SyntaxKind.ProtectedKeyword: - return ModifierFlags.Protected; - case SyntaxKind.StaticKeyword: - return ModifierFlags.Static; - case SyntaxKind.ExportKeyword: - return ModifierFlags.Export; - case SyntaxKind.DeclareKeyword: - return ModifierFlags.Ambient; - case SyntaxKind.AbstractKeyword: - return ModifierFlags.Abstract; - default: - Debug.fail(); - } - } - } - - function pushKeywordIf(keywordList: Node[], token: Node, ...expected: SyntaxKind[]): boolean { - if (token && contains(expected, token.kind)) { - keywordList.push(token); - return true; - } - - return false; - } - - function getGetAndSetOccurrences(accessorDeclaration: AccessorDeclaration): HighlightSpan[] { - const keywords: Node[] = []; - - tryPushAccessorKeyword(accessorDeclaration.symbol, SyntaxKind.GetAccessor); - tryPushAccessorKeyword(accessorDeclaration.symbol, SyntaxKind.SetAccessor); - - return map(keywords, getHighlightSpanForNode); - - function tryPushAccessorKeyword(accessorSymbol: Symbol, accessorKind: SyntaxKind): void { - const accessor = getDeclarationOfKind(accessorSymbol, accessorKind); - - if (accessor) { - forEach(accessor.getChildren(), child => pushKeywordIf(keywords, child, SyntaxKind.GetKeyword, SyntaxKind.SetKeyword)); - } - } - } - - function getConstructorOccurrences(constructorDeclaration: ConstructorDeclaration): HighlightSpan[] { - const declarations = constructorDeclaration.symbol.getDeclarations(); - - const keywords: Node[] = []; - - forEach(declarations, declaration => { - forEach(declaration.getChildren(), token => { - return pushKeywordIf(keywords, token, SyntaxKind.ConstructorKeyword); - }); - }); - - return map(keywords, getHighlightSpanForNode); - } - - function getLoopBreakContinueOccurrences(loopNode: IterationStatement): HighlightSpan[] { - const keywords: Node[] = []; - - if (pushKeywordIf(keywords, loopNode.getFirstToken(), SyntaxKind.ForKeyword, SyntaxKind.WhileKeyword, SyntaxKind.DoKeyword)) { - // If we succeeded and got a do-while loop, then start looking for a 'while' keyword. - if (loopNode.kind === SyntaxKind.DoStatement) { - const loopTokens = loopNode.getChildren(); - - for (let i = loopTokens.length - 1; i >= 0; i--) { - if (pushKeywordIf(keywords, loopTokens[i], SyntaxKind.WhileKeyword)) { - break; - } - } - } - } - - const breaksAndContinues = aggregateAllBreakAndContinueStatements(loopNode.statement); - - forEach(breaksAndContinues, statement => { - if (ownsBreakOrContinueStatement(loopNode, statement)) { - pushKeywordIf(keywords, statement.getFirstToken(), SyntaxKind.BreakKeyword, SyntaxKind.ContinueKeyword); - } - }); - - return map(keywords, getHighlightSpanForNode); - } - - function getBreakOrContinueStatementOccurrences(breakOrContinueStatement: BreakOrContinueStatement): HighlightSpan[] { - const owner = getBreakOrContinueOwner(breakOrContinueStatement); - - if (owner) { - switch (owner.kind) { - case SyntaxKind.ForStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.DoStatement: - case SyntaxKind.WhileStatement: - return getLoopBreakContinueOccurrences(owner); - case SyntaxKind.SwitchStatement: - return getSwitchCaseDefaultOccurrences(owner); - - } - } - - return undefined; - } - - function getSwitchCaseDefaultOccurrences(switchStatement: SwitchStatement): HighlightSpan[] { - const keywords: Node[] = []; - - pushKeywordIf(keywords, switchStatement.getFirstToken(), SyntaxKind.SwitchKeyword); - - // Go through each clause in the switch statement, collecting the 'case'/'default' keywords. - forEach(switchStatement.caseBlock.clauses, clause => { - pushKeywordIf(keywords, clause.getFirstToken(), SyntaxKind.CaseKeyword, SyntaxKind.DefaultKeyword); - - const breaksAndContinues = aggregateAllBreakAndContinueStatements(clause); - - forEach(breaksAndContinues, statement => { - if (ownsBreakOrContinueStatement(switchStatement, statement)) { - pushKeywordIf(keywords, statement.getFirstToken(), SyntaxKind.BreakKeyword); - } - }); - }); - - return map(keywords, getHighlightSpanForNode); - } - - function getTryCatchFinallyOccurrences(tryStatement: TryStatement): HighlightSpan[] { - const keywords: Node[] = []; - - pushKeywordIf(keywords, tryStatement.getFirstToken(), SyntaxKind.TryKeyword); + else if (node.kind === SyntaxKind.TryStatement) { + const tryStatement = node; if (tryStatement.catchClause) { - pushKeywordIf(keywords, tryStatement.catchClause.getFirstToken(), SyntaxKind.CatchKeyword); + aggregate(tryStatement.catchClause); + } + else { + // Exceptions thrown within a try block lacking a catch clause + // are "owned" in the current context. + aggregate(tryStatement.tryBlock); } if (tryStatement.finallyBlock) { - const finallyKeyword = findChildOfKind(tryStatement, SyntaxKind.FinallyKeyword, sourceFile); - pushKeywordIf(keywords, finallyKeyword, SyntaxKind.FinallyKeyword); + aggregate(tryStatement.finallyBlock); } - - return map(keywords, getHighlightSpanForNode); } - - function getThrowOccurrences(throwStatement: ThrowStatement): HighlightSpan[] { - const owner = getThrowStatementOwner(throwStatement); - - if (!owner) { - return undefined; - } - - const keywords: Node[] = []; - - forEach(aggregateOwnedThrowStatements(owner), throwStatement => { - pushKeywordIf(keywords, throwStatement.getFirstToken(), SyntaxKind.ThrowKeyword); - }); - - // If the "owner" is a function, then we equate 'return' and 'throw' statements in their - // ability to "jump out" of the function, and include occurrences for both. - if (isFunctionBlock(owner)) { - forEachReturnStatement(owner, returnStatement => { - pushKeywordIf(keywords, returnStatement.getFirstToken(), SyntaxKind.ReturnKeyword); - }); - } - - return map(keywords, getHighlightSpanForNode); - } - - function getReturnOccurrences(returnStatement: ReturnStatement): HighlightSpan[] { - const func = getContainingFunction(returnStatement); - - // If we didn't find a containing function with a block body, bail out. - if (!(func && hasKind(func.body, SyntaxKind.Block))) { - return undefined; - } - - const keywords: Node[] = []; - forEachReturnStatement(func.body, returnStatement => { - pushKeywordIf(keywords, returnStatement.getFirstToken(), SyntaxKind.ReturnKeyword); - }); - - // Include 'throw' statements that do not occur within a try block. - forEach(aggregateOwnedThrowStatements(func.body), throwStatement => { - pushKeywordIf(keywords, throwStatement.getFirstToken(), SyntaxKind.ThrowKeyword); - }); - - return map(keywords, getHighlightSpanForNode); - } - - function getIfElseOccurrences(ifStatement: IfStatement): HighlightSpan[] { - const keywords: Node[] = []; - - // Traverse upwards through all parent if-statements linked by their else-branches. - while (hasKind(ifStatement.parent, SyntaxKind.IfStatement) && (ifStatement.parent).elseStatement === ifStatement) { - ifStatement = ifStatement.parent; - } - - // Now traverse back down through the else branches, aggregating if/else keywords of if-statements. - while (ifStatement) { - const children = ifStatement.getChildren(); - pushKeywordIf(keywords, children[0], SyntaxKind.IfKeyword); - - // Generally the 'else' keyword is second-to-last, so we traverse backwards. - for (let i = children.length - 1; i >= 0; i--) { - if (pushKeywordIf(keywords, children[i], SyntaxKind.ElseKeyword)) { - break; - } - } - - if (!hasKind(ifStatement.elseStatement, SyntaxKind.IfStatement)) { - break; - } - - ifStatement = ifStatement.elseStatement; - } - - const result: HighlightSpan[] = []; - - // We'd like to highlight else/ifs together if they are only separated by whitespace - // (i.e. the keywords are separated by no comments, no newlines). - for (let i = 0; i < keywords.length; i++) { - if (keywords[i].kind === SyntaxKind.ElseKeyword && i < keywords.length - 1) { - const elseKeyword = keywords[i]; - const ifKeyword = keywords[i + 1]; // this *should* always be an 'if' keyword. - - let shouldCombindElseAndIf = true; - - // Avoid recalculating getStart() by iterating backwards. - for (let j = ifKeyword.getStart() - 1; j >= elseKeyword.end; j--) { - if (!isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(j))) { - shouldCombindElseAndIf = false; - break; - } - } - - if (shouldCombindElseAndIf) { - result.push({ - fileName: fileName, - textSpan: createTextSpanFromBounds(elseKeyword.getStart(), ifKeyword.end), - kind: HighlightSpanKind.reference - }); - i++; // skip the next keyword - continue; - } - } - - // Ordinary case: just highlight the keyword. - result.push(getHighlightSpanForNode(keywords[i])); - } - - return result; + // Do not cross function boundaries. + else if (!isFunctionLike(node)) { + forEachChild(node, aggregate); } } } + /** + * For lack of a better name, this function takes a throw statement and returns the + * nearest ancestor that is a try-block (whose try statement has a catch clause), + * function-block, or source file. + */ + function getThrowStatementOwner(throwStatement: ThrowStatement): Node { + let child: Node = throwStatement; + + while (child.parent) { + const parent = child.parent; + + if (isFunctionBlock(parent) || parent.kind === SyntaxKind.SourceFile) { + return parent; + } + + // A throw-statement is only owned by a try-statement if the try-statement has + // a catch clause, and if the throw-statement occurs within the try block. + if (parent.kind === SyntaxKind.TryStatement) { + const tryStatement = parent; + + if (tryStatement.tryBlock === child && tryStatement.catchClause) { + return child; + } + } + + child = parent; + } + + return undefined; + } + + function aggregateAllBreakAndContinueStatements(node: Node): BreakOrContinueStatement[] { + const statementAccumulator: BreakOrContinueStatement[] = []; + aggregate(node); + return statementAccumulator; + + function aggregate(node: Node): void { + if (node.kind === SyntaxKind.BreakStatement || node.kind === SyntaxKind.ContinueStatement) { + statementAccumulator.push(node); + } + // Do not cross function boundaries. + else if (!isFunctionLike(node)) { + forEachChild(node, aggregate); + } + } + } + + function ownsBreakOrContinueStatement(owner: Node, statement: BreakOrContinueStatement): boolean { + const actualOwner = getBreakOrContinueOwner(statement); + + return actualOwner && actualOwner === owner; + } + + function getBreakOrContinueOwner(statement: BreakOrContinueStatement): Node { + for (let node = statement.parent; node; node = node.parent) { + switch (node.kind) { + case SyntaxKind.SwitchStatement: + if (statement.kind === SyntaxKind.ContinueStatement) { + continue; + } + // Fall through. + case SyntaxKind.ForStatement: + case SyntaxKind.ForInStatement: + case SyntaxKind.ForOfStatement: + case SyntaxKind.WhileStatement: + case SyntaxKind.DoStatement: + if (!statement.label || isLabeledBy(node, statement.label.text)) { + return node; + } + break; + default: + // Don't cross function boundaries. + if (isFunctionLike(node)) { + return undefined; + } + break; + } + } + + return undefined; + } + + function getModifierOccurrences(modifier: SyntaxKind, declaration: Node): Node[] { + const container = declaration.parent; + + // Make sure we only highlight the keyword when it makes sense to do so. + if (isAccessibilityModifier(modifier)) { + if (!(container.kind === SyntaxKind.ClassDeclaration || + container.kind === SyntaxKind.ClassExpression || + (declaration.kind === SyntaxKind.Parameter && hasKind(container, SyntaxKind.Constructor)))) { + return undefined; + } + } + else if (modifier === SyntaxKind.StaticKeyword) { + if (!(container.kind === SyntaxKind.ClassDeclaration || container.kind === SyntaxKind.ClassExpression)) { + return undefined; + } + } + else if (modifier === SyntaxKind.ExportKeyword || modifier === SyntaxKind.DeclareKeyword) { + if (!(container.kind === SyntaxKind.ModuleBlock || container.kind === SyntaxKind.SourceFile)) { + return undefined; + } + } + else if (modifier === SyntaxKind.AbstractKeyword) { + if (!(container.kind === SyntaxKind.ClassDeclaration || declaration.kind === SyntaxKind.ClassDeclaration)) { + return undefined; + } + } + else { + // unsupported modifier + return undefined; + } + + const keywords: Node[] = []; + const modifierFlag: ModifierFlags = getFlagFromModifier(modifier); + + let nodes: Node[]; + switch (container.kind) { + case SyntaxKind.ModuleBlock: + case SyntaxKind.SourceFile: + // Container is either a class declaration or the declaration is a classDeclaration + if (modifierFlag & ModifierFlags.Abstract) { + nodes = ((declaration).members).concat(declaration); + } + else { + nodes = (container).statements; + } + break; + case SyntaxKind.Constructor: + nodes = ((container).parameters).concat( + (container.parent).members); + break; + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: + nodes = (container).members; + + // If we're an accessibility modifier, we're in an instance member and should search + // the constructor's parameter list for instance members as well. + if (modifierFlag & ModifierFlags.AccessibilityModifier) { + const constructor = forEach((container).members, member => { + return member.kind === SyntaxKind.Constructor && member; + }); + + if (constructor) { + nodes = nodes.concat(constructor.parameters); + } + } + else if (modifierFlag & ModifierFlags.Abstract) { + nodes = nodes.concat(container); + } + break; + default: + Debug.fail("Invalid container kind."); + } + + forEach(nodes, node => { + if (getModifierFlags(node) & modifierFlag) { + forEach(node.modifiers, child => pushKeywordIf(keywords, child, modifier)); + } + }); + + return keywords; + + function getFlagFromModifier(modifier: SyntaxKind) { + switch (modifier) { + case SyntaxKind.PublicKeyword: + return ModifierFlags.Public; + case SyntaxKind.PrivateKeyword: + return ModifierFlags.Private; + case SyntaxKind.ProtectedKeyword: + return ModifierFlags.Protected; + case SyntaxKind.StaticKeyword: + return ModifierFlags.Static; + case SyntaxKind.ExportKeyword: + return ModifierFlags.Export; + case SyntaxKind.DeclareKeyword: + return ModifierFlags.Ambient; + case SyntaxKind.AbstractKeyword: + return ModifierFlags.Abstract; + default: + Debug.fail(); + } + } + } + + function pushKeywordIf(keywordList: Node[], token: Node, ...expected: SyntaxKind[]): boolean { + if (token && contains(expected, token.kind)) { + keywordList.push(token); + return true; + } + + return false; + } + + function getGetAndSetOccurrences(accessorDeclaration: AccessorDeclaration): Node[] { + const keywords: Node[] = []; + + tryPushAccessorKeyword(accessorDeclaration.symbol, SyntaxKind.GetAccessor); + tryPushAccessorKeyword(accessorDeclaration.symbol, SyntaxKind.SetAccessor); + + return keywords; + + function tryPushAccessorKeyword(accessorSymbol: Symbol, accessorKind: SyntaxKind): void { + const accessor = getDeclarationOfKind(accessorSymbol, accessorKind); + + if (accessor) { + forEach(accessor.getChildren(), child => pushKeywordIf(keywords, child, SyntaxKind.GetKeyword, SyntaxKind.SetKeyword)); + } + } + } + + function getConstructorOccurrences(constructorDeclaration: ConstructorDeclaration): Node[] { + const declarations = constructorDeclaration.symbol.getDeclarations(); + + const keywords: Node[] = []; + + forEach(declarations, declaration => { + forEach(declaration.getChildren(), token => { + return pushKeywordIf(keywords, token, SyntaxKind.ConstructorKeyword); + }); + }); + + return keywords; + } + + function getLoopBreakContinueOccurrences(loopNode: IterationStatement): Node[] { + const keywords: Node[] = []; + + if (pushKeywordIf(keywords, loopNode.getFirstToken(), SyntaxKind.ForKeyword, SyntaxKind.WhileKeyword, SyntaxKind.DoKeyword)) { + // If we succeeded and got a do-while loop, then start looking for a 'while' keyword. + if (loopNode.kind === SyntaxKind.DoStatement) { + const loopTokens = loopNode.getChildren(); + + for (let i = loopTokens.length - 1; i >= 0; i--) { + if (pushKeywordIf(keywords, loopTokens[i], SyntaxKind.WhileKeyword)) { + break; + } + } + } + } + + const breaksAndContinues = aggregateAllBreakAndContinueStatements(loopNode.statement); + + forEach(breaksAndContinues, statement => { + if (ownsBreakOrContinueStatement(loopNode, statement)) { + pushKeywordIf(keywords, statement.getFirstToken(), SyntaxKind.BreakKeyword, SyntaxKind.ContinueKeyword); + } + }); + + return keywords; + } + + function getBreakOrContinueStatementOccurrences(breakOrContinueStatement: BreakOrContinueStatement): Node[] { + const owner = getBreakOrContinueOwner(breakOrContinueStatement); + + if (owner) { + switch (owner.kind) { + case SyntaxKind.ForStatement: + case SyntaxKind.ForInStatement: + case SyntaxKind.ForOfStatement: + case SyntaxKind.DoStatement: + case SyntaxKind.WhileStatement: + return getLoopBreakContinueOccurrences(owner); + case SyntaxKind.SwitchStatement: + return getSwitchCaseDefaultOccurrences(owner); + + } + } + + return undefined; + } + + function getSwitchCaseDefaultOccurrences(switchStatement: SwitchStatement): Node[] { + const keywords: Node[] = []; + + pushKeywordIf(keywords, switchStatement.getFirstToken(), SyntaxKind.SwitchKeyword); + + // Go through each clause in the switch statement, collecting the 'case'/'default' keywords. + forEach(switchStatement.caseBlock.clauses, clause => { + pushKeywordIf(keywords, clause.getFirstToken(), SyntaxKind.CaseKeyword, SyntaxKind.DefaultKeyword); + + const breaksAndContinues = aggregateAllBreakAndContinueStatements(clause); + + forEach(breaksAndContinues, statement => { + if (ownsBreakOrContinueStatement(switchStatement, statement)) { + pushKeywordIf(keywords, statement.getFirstToken(), SyntaxKind.BreakKeyword); + } + }); + }); + + return keywords; + } + + function getTryCatchFinallyOccurrences(tryStatement: TryStatement, sourceFile: SourceFile): Node[] { + const keywords: Node[] = []; + + pushKeywordIf(keywords, tryStatement.getFirstToken(), SyntaxKind.TryKeyword); + + if (tryStatement.catchClause) { + pushKeywordIf(keywords, tryStatement.catchClause.getFirstToken(), SyntaxKind.CatchKeyword); + } + + if (tryStatement.finallyBlock) { + const finallyKeyword = findChildOfKind(tryStatement, SyntaxKind.FinallyKeyword, sourceFile); + pushKeywordIf(keywords, finallyKeyword, SyntaxKind.FinallyKeyword); + } + + return keywords; + } + + function getThrowOccurrences(throwStatement: ThrowStatement): Node[] { + const owner = getThrowStatementOwner(throwStatement); + + if (!owner) { + return undefined; + } + + const keywords: Node[] = []; + + forEach(aggregateOwnedThrowStatements(owner), throwStatement => { + pushKeywordIf(keywords, throwStatement.getFirstToken(), SyntaxKind.ThrowKeyword); + }); + + // If the "owner" is a function, then we equate 'return' and 'throw' statements in their + // ability to "jump out" of the function, and include occurrences for both. + if (isFunctionBlock(owner)) { + forEachReturnStatement(owner, returnStatement => { + pushKeywordIf(keywords, returnStatement.getFirstToken(), SyntaxKind.ReturnKeyword); + }); + } + + return keywords; + } + + function getReturnOccurrences(returnStatement: ReturnStatement): Node[] { + const func = getContainingFunction(returnStatement); + + // If we didn't find a containing function with a block body, bail out. + if (!(func && hasKind(func.body, SyntaxKind.Block))) { + return undefined; + } + + const keywords: Node[] = []; + forEachReturnStatement(func.body, returnStatement => { + pushKeywordIf(keywords, returnStatement.getFirstToken(), SyntaxKind.ReturnKeyword); + }); + + // Include 'throw' statements that do not occur within a try block. + forEach(aggregateOwnedThrowStatements(func.body), throwStatement => { + pushKeywordIf(keywords, throwStatement.getFirstToken(), SyntaxKind.ThrowKeyword); + }); + + return keywords; + } + + function getIfElseOccurrences(ifStatement: IfStatement, sourceFile: SourceFile): HighlightSpan[] { + const keywords: Node[] = []; + + // Traverse upwards through all parent if-statements linked by their else-branches. + while (hasKind(ifStatement.parent, SyntaxKind.IfStatement) && (ifStatement.parent).elseStatement === ifStatement) { + ifStatement = ifStatement.parent; + } + + // Now traverse back down through the else branches, aggregating if/else keywords of if-statements. + while (ifStatement) { + const children = ifStatement.getChildren(); + pushKeywordIf(keywords, children[0], SyntaxKind.IfKeyword); + + // Generally the 'else' keyword is second-to-last, so we traverse backwards. + for (let i = children.length - 1; i >= 0; i--) { + if (pushKeywordIf(keywords, children[i], SyntaxKind.ElseKeyword)) { + break; + } + } + + if (!hasKind(ifStatement.elseStatement, SyntaxKind.IfStatement)) { + break; + } + + ifStatement = ifStatement.elseStatement; + } + + const result: HighlightSpan[] = []; + + // We'd like to highlight else/ifs together if they are only separated by whitespace + // (i.e. the keywords are separated by no comments, no newlines). + for (let i = 0; i < keywords.length; i++) { + if (keywords[i].kind === SyntaxKind.ElseKeyword && i < keywords.length - 1) { + const elseKeyword = keywords[i]; + const ifKeyword = keywords[i + 1]; // this *should* always be an 'if' keyword. + + let shouldCombindElseAndIf = true; + + // Avoid recalculating getStart() by iterating backwards. + for (let j = ifKeyword.getStart() - 1; j >= elseKeyword.end; j--) { + if (!isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(j))) { + shouldCombindElseAndIf = false; + break; + } + } + + if (shouldCombindElseAndIf) { + result.push({ + fileName: sourceFile.fileName, + textSpan: createTextSpanFromBounds(elseKeyword.getStart(), ifKeyword.end), + kind: HighlightSpanKind.reference + }); + i++; // skip the next keyword + continue; + } + } + + // Ordinary case: just highlight the keyword. + result.push(getHighlightSpanForNode(keywords[i], sourceFile)); + } + + return result; + } + /** * Whether or not a 'node' is preceded by a label of the given string. * Note: 'node' cannot be a SourceFile. diff --git a/src/services/documentRegistry.ts b/src/services/documentRegistry.ts index d73e4d3b0a1..80b0133ccfe 100644 --- a/src/services/documentRegistry.ts +++ b/src/services/documentRegistry.ts @@ -1,4 +1,4 @@ -namespace ts { +namespace ts { /** * The document registry represents a store of SourceFile objects that can be shared between * multiple LanguageService instances. A LanguageService instance holds on the SourceFile (AST) @@ -113,16 +113,16 @@ namespace ts { } function getBucketForCompilationSettings(key: DocumentRegistryBucketKey, createIfMissing: boolean): FileMap { - let bucket = buckets[key]; + let bucket = buckets.get(key); if (!bucket && createIfMissing) { - buckets[key] = bucket = createFileMap(); + buckets.set(key, bucket = createFileMap()); } return bucket; } function reportStats() { - const bucketInfoArray = Object.keys(buckets).filter(name => name && name.charAt(0) === "_").map(name => { - const entries = buckets[name]; + const bucketInfoArray = arrayFrom(buckets.keys()).filter(name => name && name.charAt(0) === "_").map(name => { + const entries = buckets.get(name); const sourceFiles: { name: string; refCount: number; references: string[]; }[] = []; entries.forEachValue((key, entry) => { sourceFiles.push({ diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 287c16d5e7e..28474839cf3 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -1,63 +1,27 @@ -/* @internal */ +/* @internal */ namespace ts.FindAllReferences { - export function findReferencedSymbols(typeChecker: TypeChecker, cancellationToken: CancellationToken, sourceFiles: SourceFile[], sourceFile: SourceFile, position: number, findInStrings: boolean, findInComments: boolean): ReferencedSymbol[] { + export function findReferencedSymbols(typeChecker: TypeChecker, cancellationToken: CancellationToken, sourceFiles: SourceFile[], sourceFile: SourceFile, position: number, findInStrings: boolean, findInComments: boolean, isForRename: boolean): ReferencedSymbol[] | undefined { const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); - if (node === sourceFile) { - return undefined; - } - - switch (node.kind) { - case SyntaxKind.NumericLiteral: - if (!isLiteralNameOfPropertyDeclarationOrIndexAccess(node)) { - break; - } - // Fallthrough - case SyntaxKind.Identifier: - case SyntaxKind.ThisKeyword: - // case SyntaxKind.SuperKeyword: TODO:GH#9268 - case SyntaxKind.ConstructorKeyword: - case SyntaxKind.StringLiteral: - return getReferencedSymbolsForNode(typeChecker, cancellationToken, node, sourceFiles, findInStrings, findInComments, /*implementations*/false); - } - return undefined; + return getReferencedSymbolsForNode(typeChecker, cancellationToken, node, sourceFiles, findInStrings, findInComments, isForRename); } - export function getReferencedSymbolsForNode(typeChecker: TypeChecker, cancellationToken: CancellationToken, node: Node, sourceFiles: SourceFile[], findInStrings: boolean, findInComments: boolean, implementations: boolean): ReferencedSymbol[] { + export function getReferencedSymbolsForNode(typeChecker: TypeChecker, cancellationToken: CancellationToken, node: Node, sourceFiles: SourceFile[], findInStrings?: boolean, findInComments?: boolean, isForRename?: boolean, implementations?: boolean): ReferencedSymbol[] | undefined { if (!implementations) { - // Labels - if (isLabelName(node)) { - if (isJumpStatementTarget(node)) { - const labelDefinition = getTargetLabel((node.parent), (node).text); - // if we have a label definition, look within its statement for references, if not, then - // the label is undefined and we have no results.. - return labelDefinition ? getLabelReferencesInNode(labelDefinition.parent, labelDefinition) : undefined; - } - else { - // it is a label definition and not a target, search within the parent labeledStatement - return getLabelReferencesInNode(node.parent, node); - } - } - - if (isThis(node)) { - return getReferencesForThisKeyword(node, sourceFiles); - } - - if (node.kind === SyntaxKind.SuperKeyword) { - return getReferencesForSuperKeyword(node); + const special = getReferencedSymbolsSpecial(node, sourceFiles, typeChecker, cancellationToken); + if (special) { + return special; } } // `getSymbolAtLocation` normally returns the symbol of the class when given the constructor keyword, // so we have to specify that we want the constructor symbol. - const symbol = typeChecker.getSymbolAtLocation(node); - - if (!implementations && !symbol && node.kind === SyntaxKind.StringLiteral) { - return getReferencesForStringLiteral(node, sourceFiles); - } - + let symbol = typeChecker.getSymbolAtLocation(node); // Could not find a symbol e.g. unknown identifier if (!symbol) { + if (!implementations && node.kind === SyntaxKind.StringLiteral) { + return getReferencesForStringLiteral(node, sourceFiles, typeChecker, cancellationToken); + } // Can't have references to something that we have no symbol for. return undefined; } @@ -69,11 +33,23 @@ namespace ts.FindAllReferences { return undefined; } - let result: ReferencedSymbol[]; + const { symbol: aliasedSymbol, shorthandModuleSymbol } = followAliases(symbol, node, typeChecker, isForRename); + symbol = aliasedSymbol; + + // Build the set of symbols to search for, initially it has only the current symbol + const searchSymbols = populateSearchSymbolSet(symbol, node, typeChecker, implementations); + if (shorthandModuleSymbol) { + searchSymbols.push(shorthandModuleSymbol); + } // Compute the meaning from the location and the symbol it references const searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), declarations); + const result: ReferencedSymbol[] = []; + // Maps from a symbol ID to the ReferencedSymbol entry in 'result'. + const symbolToIndex: number[] = []; + const inheritsFromCache: Map = createMap(); + // Get the text to search for. // Note: if this is an external module symbol, the name doesn't include quotes. const declaredName = stripQuotes(getDeclaredName(typeChecker, symbol, node)); @@ -81,1175 +57,1263 @@ namespace ts.FindAllReferences { // Try to get the smallest valid scope that we can limit our search to; // otherwise we'll need to search globally (i.e. include each file). const scope = getSymbolScope(symbol); - - // Maps from a symbol ID to the ReferencedSymbol entry in 'result'. - const symbolToIndex: number[] = []; - if (scope) { - result = []; - getReferencesInNode(scope, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result, symbolToIndex); + getRefs(scope, declaredName); } else { - const internedName = getInternedName(symbol, node); + const isDefault = isExportDefaultSymbol(symbol); + const internedName = isDefault ? symbol.valueDeclaration.localSymbol.name : getInternedName(symbol, node); for (const sourceFile of sourceFiles) { cancellationToken.throwIfCancellationRequested(); - - const nameTable = getNameTable(sourceFile); - - if (nameTable[internedName] !== undefined) { - result = result || []; - getReferencesInNode(sourceFile, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result, symbolToIndex); + const searchName = (isDefault ? getDefaultImportName(symbol, sourceFile, typeChecker) : undefined) || + (sourceFileHasName(sourceFile, internedName) ? declaredName : undefined); + if (searchName !== undefined) { + getRefs(sourceFile, searchName); } } } return result; - function getDefinition(symbol: Symbol): ReferencedSymbolDefinitionInfo { - const info = SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, node.getSourceFile(), getContainerNode(node), node); - const name = map(info.displayParts, p => p.text).join(""); - const declarations = symbol.declarations; - if (!declarations || declarations.length === 0) { - return undefined; - } + function getRefs(scope: ts.Node, searchName: string): void { + getReferencesInNode(scope, symbol, searchName, node, searchMeaning, findInStrings, findInComments, result, + symbolToIndex, implementations, typeChecker, cancellationToken, searchSymbols, inheritsFromCache); + } + } - return { - containerKind: "", - containerName: "", - name, - kind: info.symbolKind, - fileName: declarations[0].getSourceFile().fileName, - textSpan: createTextSpan(declarations[0].getStart(), 0), - displayParts: info.displayParts - }; + /** getReferencedSymbols for special node kinds. */ + function getReferencedSymbolsSpecial(node: Node, sourceFiles: SourceFile[], typeChecker: TypeChecker, cancellationToken: CancellationToken): ReferencedSymbol[] | undefined { + if (isTypeKeyword(node.kind)) { + return getAllReferencesForKeyword(sourceFiles, node.kind, cancellationToken); } - function getAliasSymbolForPropertyNameSymbol(symbol: Symbol, location: Node): Symbol | undefined { - if (symbol.flags & SymbolFlags.Alias) { - // Default import get alias - const defaultImport = getDeclarationOfKind(symbol, SyntaxKind.ImportClause); - if (defaultImport) { - return typeChecker.getAliasedSymbol(symbol); - } - - const importOrExportSpecifier = forEach(symbol.declarations, - declaration => (declaration.kind === SyntaxKind.ImportSpecifier || - declaration.kind === SyntaxKind.ExportSpecifier) ? declaration : undefined); - if (importOrExportSpecifier && - // export { a } - (!importOrExportSpecifier.propertyName || - // export {a as class } where a is location - importOrExportSpecifier.propertyName === location)) { - // If Import specifier -> get alias - // else Export specifier -> get local target - return importOrExportSpecifier.kind === SyntaxKind.ImportSpecifier ? - typeChecker.getAliasedSymbol(symbol) : - typeChecker.getExportSpecifierLocalTargetSymbol(importOrExportSpecifier); - } + // Labels + if (isLabelName(node)) { + if (isJumpStatementTarget(node)) { + const labelDefinition = getTargetLabel((node.parent), (node).text); + // if we have a label definition, look within its statement for references, if not, then + // the label is undefined and we have no results.. + return labelDefinition && getLabelReferencesInNode(labelDefinition.parent, labelDefinition, cancellationToken); } + else { + // it is a label definition and not a target, search within the parent labeledStatement + return getLabelReferencesInNode(node.parent, node, cancellationToken); + } + } + + if (isThis(node)) { + return getReferencesForThisKeyword(node, sourceFiles, typeChecker, cancellationToken); + } + + if (node.kind === SyntaxKind.SuperKeyword) { + return getReferencesForSuperKeyword(node, typeChecker, cancellationToken); + } + + return undefined; + } + + /** + * Follows aliases to get to the original declaration of a symbol. + * For a shorthand ambient module, we don't follow the alias to it, but we will need to add it to the set of search symbols. + */ + function followAliases(symbol: Symbol, node: Node, typeChecker: TypeChecker, isForRename: boolean): { symbol: Symbol, shorthandModuleSymbol?: Symbol } { + while (true) { + // When renaming a default import, only rename in the current file + if (isForRename && isImportDefaultSymbol(symbol)) { + return { symbol }; + } + + const aliasedSymbol = getAliasSymbolForPropertyNameSymbol(symbol, node, typeChecker); + // Don't follow alias if it goes to unknown symbol. This can happen if it points to an untyped module. + if (!aliasedSymbol || !aliasedSymbol.declarations) { + return { symbol }; + } + + if (ts.isShorthandAmbientModuleSymbol(aliasedSymbol)) { + return { symbol, shorthandModuleSymbol: aliasedSymbol }; + } + + symbol = aliasedSymbol; + } + } + + function sourceFileHasName(sourceFile: SourceFile, name: string): boolean { + return getNameTable(sourceFile).get(name) !== undefined; + } + + /** + * Given a symbol, see if any of the imports in a source file reference it. + * Only call this if `symbol` is a default export. + */ + function getDefaultImportName(symbol: Symbol, sourceFile: SourceFile, checker: ts.TypeChecker): string | undefined { + for (const importSpecifier of sourceFile.imports) { + const importDecl = importSpecifier.parent as ts.ImportDeclaration; + Debug.assert(importDecl.moduleSpecifier === importSpecifier); + const defaultName = importDecl.importClause.name; + const defaultReferencedSymbol = checker.getAliasedSymbol(checker.getSymbolAtLocation(defaultName)); + if (symbol === defaultReferencedSymbol) { + return defaultName.text; + } + } + return undefined; + } + + function getDefinition(symbol: Symbol, node: Node, typeChecker: TypeChecker): ReferencedSymbolDefinitionInfo { + const { displayParts, symbolKind } = SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, node.getSourceFile(), getContainerNode(node), node); + const name = displayParts.map(p => p.text).join(""); + const declarations = symbol.declarations; + if (!declarations || declarations.length === 0) { return undefined; } - function followAliasIfNecessary(symbol: Symbol, location: Node): Symbol { - return getAliasSymbolForPropertyNameSymbol(symbol, location) || symbol; + return { + containerKind: "", + containerName: "", + name, + kind: symbolKind, + fileName: declarations[0].getSourceFile().fileName, + textSpan: createTextSpan(declarations[0].getStart(), 0), + displayParts + }; + } + + function getAliasSymbolForPropertyNameSymbol(symbol: Symbol, location: Node, typeChecker: TypeChecker): Symbol | undefined { + if (!(symbol.flags & SymbolFlags.Alias)) { + return undefined; } - function getPropertySymbolOfDestructuringAssignment(location: Node) { - return isArrayLiteralOrObjectLiteralDestructuringPattern(location.parent.parent) && - typeChecker.getPropertySymbolOfDestructuringAssignment(location); + // Default import get alias + const defaultImport = getDeclarationOfKind(symbol, SyntaxKind.ImportClause); + if (defaultImport) { + return typeChecker.getAliasedSymbol(symbol); } - function isObjectBindingPatternElementWithoutPropertyName(symbol: Symbol) { + const importOrExportSpecifier = forEach(symbol.declarations, + declaration => (declaration.kind === SyntaxKind.ImportSpecifier || + declaration.kind === SyntaxKind.ExportSpecifier) ? declaration : undefined); + if (importOrExportSpecifier && + // export { a } + (!importOrExportSpecifier.propertyName || + // export {a as class } where a is location + importOrExportSpecifier.propertyName === location)) { + // If Import specifier -> get alias + // else Export specifier -> get local target + return importOrExportSpecifier.kind === SyntaxKind.ImportSpecifier ? + typeChecker.getAliasedSymbol(symbol) : + typeChecker.getExportSpecifierLocalTargetSymbol(importOrExportSpecifier); + } + } + + function followAliasIfNecessary(symbol: Symbol, location: Node, typeChecker: TypeChecker): Symbol { + return getAliasSymbolForPropertyNameSymbol(symbol, location, typeChecker) || symbol; + } + + function getPropertySymbolOfDestructuringAssignment(location: Node, typeChecker: TypeChecker) { + return isArrayLiteralOrObjectLiteralDestructuringPattern(location.parent.parent) && + typeChecker.getPropertySymbolOfDestructuringAssignment(location); + } + + function isObjectBindingPatternElementWithoutPropertyName(symbol: Symbol) { + const bindingElement = getDeclarationOfKind(symbol, SyntaxKind.BindingElement); + return bindingElement && + bindingElement.parent.kind === SyntaxKind.ObjectBindingPattern && + !bindingElement.propertyName; + } + + function getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol: Symbol, typeChecker: TypeChecker) { + if (isObjectBindingPatternElementWithoutPropertyName(symbol)) { const bindingElement = getDeclarationOfKind(symbol, SyntaxKind.BindingElement); - return bindingElement && - bindingElement.parent.kind === SyntaxKind.ObjectBindingPattern && - !bindingElement.propertyName; + const typeOfPattern = typeChecker.getTypeAtLocation(bindingElement.parent); + return typeOfPattern && typeChecker.getPropertyOfType(typeOfPattern, (bindingElement.name).text); + } + return undefined; + } + + function getInternedName(symbol: Symbol, location: Node): string { + // If this is an export or import specifier it could have been renamed using the 'as' syntax. + // If so we want to search for whatever under the cursor. + if (isImportOrExportSpecifierName(location)) { + return location.text; } - function getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol: Symbol) { - if (isObjectBindingPatternElementWithoutPropertyName(symbol)) { - const bindingElement = getDeclarationOfKind(symbol, SyntaxKind.BindingElement); - const typeOfPattern = typeChecker.getTypeAtLocation(bindingElement.parent); - return typeOfPattern && typeChecker.getPropertyOfType(typeOfPattern, (bindingElement.name).text); + return stripQuotes(symbol.name); + } + + /** + * Determines the smallest scope in which a symbol may have named references. + * Note that not every construct has been accounted for. This function can + * probably be improved. + * + * @returns undefined if the scope cannot be determined, implying that + * a reference to a symbol can occur anywhere. + */ + function getSymbolScope(symbol: Symbol): Node { + // If this is the symbol of a named function expression or named class expression, + // then named references are limited to its own scope. + const valueDeclaration = symbol.valueDeclaration; + if (valueDeclaration && (valueDeclaration.kind === SyntaxKind.FunctionExpression || valueDeclaration.kind === SyntaxKind.ClassExpression)) { + return valueDeclaration; + } + + // If this is private property or method, the scope is the containing class + if (symbol.flags & (SymbolFlags.Property | SymbolFlags.Method)) { + const privateDeclaration = forEach(symbol.getDeclarations(), d => (getModifierFlags(d) & ModifierFlags.Private) ? d : undefined); + if (privateDeclaration) { + return getAncestor(privateDeclaration, SyntaxKind.ClassDeclaration); } + } + + // If the symbol is an import we would like to find it if we are looking for what it imports. + // So consider it visible outside its declaration scope. + if (symbol.flags & SymbolFlags.Alias) { return undefined; } - function getInternedName(symbol: Symbol, location: Node): string { - // If this is an export or import specifier it could have been renamed using the 'as' syntax. - // If so we want to search for whatever under the cursor. - if (isImportOrExportSpecifierName(location)) { - return location.getText(); - } - - // Try to get the local symbol if we're dealing with an 'export default' - // since that symbol has the "true" name. - const localExportDefaultSymbol = getLocalSymbolForExportDefault(symbol); - symbol = localExportDefaultSymbol || symbol; - - return stripQuotes(symbol.name); + // If symbol is of object binding pattern element without property name we would want to + // look for property too and that could be anywhere + if (isObjectBindingPatternElementWithoutPropertyName(symbol)) { + return undefined; } - /** - * Determines the smallest scope in which a symbol may have named references. - * Note that not every construct has been accounted for. This function can - * probably be improved. - * - * @returns undefined if the scope cannot be determined, implying that - * a reference to a symbol can occur anywhere. - */ - function getSymbolScope(symbol: Symbol): Node { - // If this is the symbol of a named function expression or named class expression, - // then named references are limited to its own scope. - const valueDeclaration = symbol.valueDeclaration; - if (valueDeclaration && (valueDeclaration.kind === SyntaxKind.FunctionExpression || valueDeclaration.kind === SyntaxKind.ClassExpression)) { - return valueDeclaration; - } - - // If this is private property or method, the scope is the containing class - if (symbol.flags & (SymbolFlags.Property | SymbolFlags.Method)) { - const privateDeclaration = forEach(symbol.getDeclarations(), d => (getModifierFlags(d) & ModifierFlags.Private) ? d : undefined); - if (privateDeclaration) { - return getAncestor(privateDeclaration, SyntaxKind.ClassDeclaration); - } - } - - // If the symbol is an import we would like to find it if we are looking for what it imports. - // So consider it visible outside its declaration scope. - if (symbol.flags & SymbolFlags.Alias) { - return undefined; - } - - // If symbol is of object binding pattern element without property name we would want to - // look for property too and that could be anywhere - if (isObjectBindingPatternElementWithoutPropertyName(symbol)) { - return undefined; - } - - // if this symbol is visible from its parent container, e.g. exported, then bail out - // if symbol correspond to the union property - bail out - if (symbol.parent || (symbol.flags & SymbolFlags.SyntheticProperty)) { - return undefined; - } - - let scope: Node; - - const declarations = symbol.getDeclarations(); - if (declarations) { - for (const declaration of declarations) { - const container = getContainerNode(declaration); - - if (!container) { - return undefined; - } - - if (scope && scope !== container) { - // Different declarations have different containers, bail out - return undefined; - } - - if (container.kind === SyntaxKind.SourceFile && !isExternalModule(container)) { - // This is a global variable and not an external module, any declaration defined - // within this scope is visible outside the file - return undefined; - } - - // The search scope is the container node - scope = container; - } - } - - return scope; + // if this symbol is visible from its parent container, e.g. exported, then bail out + // if symbol correspond to the union property - bail out + if (symbol.parent || (symbol.flags & SymbolFlags.SyntheticProperty)) { + return undefined; } - function getPossibleSymbolReferencePositions(sourceFile: SourceFile, symbolName: string, start: number, end: number): number[] { - const positions: number[] = []; + let scope: Node; - /// TODO: Cache symbol existence for files to save text search - // Also, need to make this work for unicode escapes. + const declarations = symbol.getDeclarations(); + if (declarations) { + for (const declaration of declarations) { + const container = getContainerNode(declaration); - // Be resilient in the face of a symbol with no name or zero length name - if (!symbolName || !symbolName.length) { - return positions; - } - - const text = sourceFile.text; - const sourceLength = text.length; - const symbolNameLength = symbolName.length; - - let position = text.indexOf(symbolName, start); - while (position >= 0) { - cancellationToken.throwIfCancellationRequested(); - - // If we are past the end, stop looking - if (position > end) break; - - // We found a match. Make sure it's not part of a larger word (i.e. the char - // before and after it have to be a non-identifier char). - const endPosition = position + symbolNameLength; - - if ((position === 0 || !isIdentifierPart(text.charCodeAt(position - 1), ScriptTarget.Latest)) && - (endPosition === sourceLength || !isIdentifierPart(text.charCodeAt(endPosition), ScriptTarget.Latest))) { - // Found a real match. Keep searching. - positions.push(position); + if (!container) { + return undefined; } - position = text.indexOf(symbolName, position + symbolNameLength + 1); - } + if (scope && scope !== container) { + // Different declarations have different containers, bail out + return undefined; + } + + if (container.kind === SyntaxKind.SourceFile && !isExternalModule(container)) { + // This is a global variable and not an external module, any declaration defined + // within this scope is visible outside the file + return undefined; + } + + // The search scope is the container node + scope = container; + } + } + + return scope; + } + + function getPossibleSymbolReferencePositions(sourceFile: SourceFile, symbolName: string, start: number, end: number, cancellationToken: CancellationToken): number[] { + const positions: number[] = []; + + /// TODO: Cache symbol existence for files to save text search + // Also, need to make this work for unicode escapes. + + // Be resilient in the face of a symbol with no name or zero length name + if (!symbolName || !symbolName.length) { return positions; } - function getLabelReferencesInNode(container: Node, targetLabel: Identifier): ReferencedSymbol[] { - const references: ReferenceEntry[] = []; - const sourceFile = container.getSourceFile(); - const labelName = targetLabel.text; - const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container.getStart(), container.getEnd()); - forEach(possiblePositions, position => { - cancellationToken.throwIfCancellationRequested(); + const text = sourceFile.text; + const sourceLength = text.length; + const symbolNameLength = symbolName.length; - const node = getTouchingWord(sourceFile, position); - if (!node || node.getWidth() !== labelName.length) { - return; - } + let position = text.indexOf(symbolName, start); + while (position >= 0) { + cancellationToken.throwIfCancellationRequested(); - // Only pick labels that are either the target label, or have a target that is the target label - if (node === targetLabel || - (isJumpStatementTarget(node) && getTargetLabel(node, labelName) === targetLabel)) { - references.push(getReferenceEntryFromNode(node)); - } - }); + // If we are past the end, stop looking + if (position > end) break; - const definition: ReferencedSymbolDefinitionInfo = { - containerKind: "", - containerName: "", - fileName: targetLabel.getSourceFile().fileName, - kind: ScriptElementKind.label, - name: labelName, - textSpan: createTextSpanFromNode(targetLabel, sourceFile), - displayParts: [displayPart(labelName, SymbolDisplayPartKind.text)] - }; + // We found a match. Make sure it's not part of a larger word (i.e. the char + // before and after it have to be a non-identifier char). + const endPosition = position + symbolNameLength; - return [{ definition, references }]; + if ((position === 0 || !isIdentifierPart(text.charCodeAt(position - 1), ScriptTarget.Latest)) && + (endPosition === sourceLength || !isIdentifierPart(text.charCodeAt(endPosition), ScriptTarget.Latest))) { + // Found a real match. Keep searching. + positions.push(position); + } + position = text.indexOf(symbolName, position + symbolNameLength + 1); } - function isValidReferencePosition(node: Node, searchSymbolName: string): boolean { - if (node) { - // Compare the length so we filter out strict superstrings of the symbol we are looking for - switch (node.kind) { - case SyntaxKind.Identifier: - return node.getWidth() === searchSymbolName.length; + return positions; + } - case SyntaxKind.StringLiteral: - if (isLiteralNameOfPropertyDeclarationOrIndexAccess(node) || - isNameOfExternalModuleImportOrDeclaration(node)) { - // For string literals we have two additional chars for the quotes - return node.getWidth() === searchSymbolName.length + 2; - } - break; + function getLabelReferencesInNode(container: Node, targetLabel: Identifier, cancellationToken: CancellationToken): ReferencedSymbol[] { + const references: ReferenceEntry[] = []; + const sourceFile = container.getSourceFile(); + const labelName = targetLabel.text; + const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container.getStart(), container.getEnd(), cancellationToken); + forEach(possiblePositions, position => { + cancellationToken.throwIfCancellationRequested(); - case SyntaxKind.NumericLiteral: - if (isLiteralNameOfPropertyDeclarationOrIndexAccess(node)) { - return node.getWidth() === searchSymbolName.length; - } - break; - } + const node = getTouchingWord(sourceFile, position); + if (!node || node.getWidth() !== labelName.length) { + return; } - return false; + // Only pick labels that are either the target label, or have a target that is the target label + if (node === targetLabel || + (isJumpStatementTarget(node) && getTargetLabel(node, labelName) === targetLabel)) { + references.push(getReferenceEntryFromNode(node)); + } + }); + + const definition: ReferencedSymbolDefinitionInfo = { + containerKind: "", + containerName: "", + fileName: targetLabel.getSourceFile().fileName, + kind: ScriptElementKind.label, + name: labelName, + textSpan: createTextSpanFromNode(targetLabel, sourceFile), + displayParts: [displayPart(labelName, SymbolDisplayPartKind.text)] + }; + + return [{ definition, references }]; + } + + function isValidReferencePosition(node: Node, searchSymbolName: string): boolean { + // Compare the length so we filter out strict superstrings of the symbol we are looking for + switch (node && node.kind) { + case SyntaxKind.Identifier: + return node.getWidth() === searchSymbolName.length; + + case SyntaxKind.StringLiteral: + return (isLiteralNameOfPropertyDeclarationOrIndexAccess(node) || isNameOfExternalModuleImportOrDeclaration(node)) && + // For string literals we have two additional chars for the quotes + node.getWidth() === searchSymbolName.length + 2; + + case SyntaxKind.NumericLiteral: + return isLiteralNameOfPropertyDeclarationOrIndexAccess(node) && node.getWidth() === searchSymbolName.length; + + default: + return false; + } + } + + function getAllReferencesForKeyword(sourceFiles: SourceFile[], keywordKind: ts.SyntaxKind, cancellationToken: CancellationToken): ReferencedSymbol[] { + const name = tokenToString(keywordKind); + const definition: ReferencedSymbolDefinitionInfo = { + containerKind: "", + containerName: "", + fileName: "", + kind: ScriptElementKind.keyword, + name, + textSpan: createTextSpan(0, 1), + displayParts: [{ text: name, kind: ScriptElementKind.keyword }] } - /** Search within node "container" for references for a search value, where the search value is defined as a - * tuple of(searchSymbol, searchText, searchLocation, and searchMeaning). - * searchLocation: a node where the search value - */ - function getReferencesInNode(container: Node, - searchSymbol: Symbol, - searchText: string, - searchLocation: Node, - searchMeaning: SemanticMeaning, - findInStrings: boolean, - findInComments: boolean, - result: ReferencedSymbol[], - symbolToIndex: number[]): void { + const references: ReferenceEntry[] = []; + for (const sourceFile of sourceFiles) { + cancellationToken.throwIfCancellationRequested(); + addReferencesForKeywordInFile(sourceFile, keywordKind, name, cancellationToken, references); + } - const sourceFile = container.getSourceFile(); + return [{ definition, references }]; + } - const start = findInComments ? container.getFullStart() : container.getStart(); - const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, searchText, start, container.getEnd()); + function addReferencesForKeywordInFile(sourceFile: SourceFile, kind: SyntaxKind, searchText: string, cancellationToken: CancellationToken, references: Push): void { + const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, searchText, sourceFile.getStart(), sourceFile.getEnd(), cancellationToken); + for (const position of possiblePositions) { + cancellationToken.throwIfCancellationRequested(); + const referenceLocation = getTouchingPropertyName(sourceFile, position); + if (referenceLocation.kind === kind) { + references.push({ + textSpan: createTextSpanFromNode(referenceLocation), + fileName: sourceFile.fileName, + isWriteAccess: false, + isDefinition: false, + }); + } + } + } - const parents = getParentSymbolsOfPropertyAccess(); - const inheritsFromCache: Map = createMap(); + /** Search within node "container" for references for a search value, where the search value is defined as a + * tuple of(searchSymbol, searchText, searchLocation, and searchMeaning). + * searchLocation: a node where the search value + */ + function getReferencesInNode(container: Node, + searchSymbol: Symbol, + searchText: string, + searchLocation: Node, + searchMeaning: SemanticMeaning, + findInStrings: boolean, + findInComments: boolean, + result: ReferencedSymbol[], + symbolToIndex: number[], + implementations: boolean, + typeChecker: TypeChecker, + cancellationToken: CancellationToken, + searchSymbols: Symbol[], + inheritsFromCache: Map): void { - if (possiblePositions.length) { - // Build the set of symbols to search for, initially it has only the current symbol - const searchSymbols = populateSearchSymbolSet(searchSymbol, searchLocation); + const sourceFile = container.getSourceFile(); - forEach(possiblePositions, position => { - cancellationToken.throwIfCancellationRequested(); + const start = findInComments ? container.getFullStart() : container.getStart(); + const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, searchText, start, container.getEnd(), cancellationToken); - const referenceLocation = getTouchingPropertyName(sourceFile, position); - if (!isValidReferencePosition(referenceLocation, searchText)) { - // This wasn't the start of a token. Check to see if it might be a - // match in a comment or string if that's what the caller is asking - // for. - if (!implementations && ((findInStrings && isInString(sourceFile, position)) || - (findInComments && isInNonReferenceComment(sourceFile, position)))) { + const parents = getParentSymbolsOfPropertyAccess(); - // In the case where we're looking inside comments/strings, we don't have - // an actual definition. So just use 'undefined' here. Features like - // 'Rename' won't care (as they ignore the definitions), and features like - // 'FindReferences' will just filter out these results. - result.push({ - definition: undefined, - references: [{ - fileName: sourceFile.fileName, - textSpan: createTextSpan(position, searchText.length), - isWriteAccess: false, - isDefinition: false - }] - }); + for (const position of possiblePositions) { + cancellationToken.throwIfCancellationRequested(); + + const referenceLocation = getTouchingPropertyName(sourceFile, position); + if (!isValidReferencePosition(referenceLocation, searchText)) { + // This wasn't the start of a token. Check to see if it might be a + // match in a comment or string if that's what the caller is asking + // for. + if (!implementations && ((findInStrings && isInString(sourceFile, position)) || + (findInComments && isInNonReferenceComment(sourceFile, position)))) { + + // In the case where we're looking inside comments/strings, we don't have + // an actual definition. So just use 'undefined' here. Features like + // 'Rename' won't care (as they ignore the definitions), and features like + // 'FindReferences' will just filter out these results. + result.push({ + definition: undefined, + references: [{ + fileName: sourceFile.fileName, + textSpan: createTextSpan(position, searchText.length), + isWriteAccess: false, + isDefinition: false + }] + }); + } + continue; + } + + if (!(getMeaningFromLocation(referenceLocation) & searchMeaning)) { + continue; + } + + const referenceSymbol = typeChecker.getSymbolAtLocation(referenceLocation); + if (referenceSymbol) { + const referenceSymbolDeclaration = referenceSymbol.valueDeclaration; + const shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration); + const relatedSymbol = getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation, + /*searchLocationIsConstructor*/ searchLocation.kind === SyntaxKind.ConstructorKeyword, parents, inheritsFromCache, typeChecker); + + if (relatedSymbol) { + addReferenceToRelatedSymbol(referenceLocation, relatedSymbol); + } + /* Because in short-hand property assignment, an identifier which stored as name of the short-hand property assignment + * has two meanings: property name and property value. Therefore when we do findAllReference at the position where + * an identifier is declared, the language service should return the position of the variable declaration as well as + * the position in short-hand property assignment excluding property accessing. However, if we do findAllReference at the + * position of property accessing, the referenceEntry of such position will be handled in the first case. + */ + else if (!(referenceSymbol.flags & SymbolFlags.Transient) && contains(searchSymbols, shorthandValueSymbol)) { + addReferenceToRelatedSymbol(referenceSymbolDeclaration.name, shorthandValueSymbol); + } + else if (searchLocation.kind === SyntaxKind.ConstructorKeyword) { + findAdditionalConstructorReferences(referenceSymbol, referenceLocation); + } + } + } + return; + + /* If we are just looking for implementations and this is a property access expression, we need to get the + * symbol of the local type of the symbol the property is being accessed on. This is because our search + * symbol may have a different parent symbol if the local type's symbol does not declare the property + * being accessed (i.e. it is declared in some parent class or interface) + */ + function getParentSymbolsOfPropertyAccess(): Symbol[] | undefined { + if (implementations) { + const propertyAccessExpression = getPropertyAccessExpressionFromRightHandSide(searchLocation); + if (propertyAccessExpression) { + const localParentType = typeChecker.getTypeAtLocation(propertyAccessExpression.expression); + if (localParentType) { + if (localParentType.symbol && localParentType.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) && localParentType.symbol !== searchSymbol.parent) { + return [localParentType.symbol]; + } + else if (localParentType.flags & TypeFlags.UnionOrIntersection) { + return getSymbolsForClassAndInterfaceComponents(localParentType); } - return; } + } + } + } - if (!(getMeaningFromLocation(referenceLocation) & searchMeaning)) { - return; - } + /** Adds references when a constructor is used with `new this()` in its own class and `super()` calls in subclasses. */ + function findAdditionalConstructorReferences(referenceSymbol: Symbol, referenceLocation: Node): void { + Debug.assert(isClassLike(searchSymbol.valueDeclaration)); - const referenceSymbol = typeChecker.getSymbolAtLocation(referenceLocation); - if (referenceSymbol) { - const referenceSymbolDeclaration = referenceSymbol.valueDeclaration; - const shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration); - const relatedSymbol = getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation, - /*searchLocationIsConstructor*/ searchLocation.kind === SyntaxKind.ConstructorKeyword, parents, inheritsFromCache); + const referenceClass = referenceLocation.parent; + if (referenceSymbol === searchSymbol && isClassLike(referenceClass)) { + Debug.assert(referenceClass.name === referenceLocation); + // This is the class declaration containing the constructor. + addReferences(findOwnConstructorCalls(searchSymbol, sourceFile)); + } + else { + // If this class appears in `extends C`, then the extending class' "super" calls are references. + const classExtending = tryGetClassByExtendingIdentifier(referenceLocation); + if (classExtending && isClassLike(classExtending) && followAliasIfNecessary(referenceSymbol, referenceLocation, typeChecker) === searchSymbol) { + addReferences(superConstructorAccesses(classExtending)); + } + } + } - if (relatedSymbol) { - addReferenceToRelatedSymbol(referenceLocation, relatedSymbol); - } - /* Because in short-hand property assignment, an identifier which stored as name of the short-hand property assignment - * has two meaning : property name and property value. Therefore when we do findAllReference at the position where - * an identifier is declared, the language service should return the position of the variable declaration as well as - * the position in short-hand property assignment excluding property accessing. However, if we do findAllReference at the - * position of property accessing, the referenceEntry of such position will be handled in the first case. - */ - else if (!(referenceSymbol.flags & SymbolFlags.Transient) && searchSymbols.indexOf(shorthandValueSymbol) >= 0) { - addReferenceToRelatedSymbol(referenceSymbolDeclaration.name, shorthandValueSymbol); - } - else if (searchLocation.kind === SyntaxKind.ConstructorKeyword) { - findAdditionalConstructorReferences(referenceSymbol, referenceLocation); + function addReferences(references: Node[]): void { + if (references.length) { + const referencedSymbol = getReferencedSymbol(searchSymbol); + addRange(referencedSymbol.references, map(references, getReferenceEntryFromNode)); + } + } + + function getReferencedSymbol(symbol: Symbol): ReferencedSymbol { + const symbolId = getSymbolId(symbol); + let index = symbolToIndex[symbolId]; + if (index === undefined) { + index = result.length; + symbolToIndex[symbolId] = index; + + result.push({ + definition: getDefinition(symbol, searchLocation, typeChecker), + references: [] + }); + } + + return result[index]; + } + + function addReferenceToRelatedSymbol(node: Node, relatedSymbol: Symbol) { + const references = getReferencedSymbol(relatedSymbol).references; + if (implementations) { + getImplementationReferenceEntryForNode(node, references, typeChecker); + } + else { + references.push(getReferenceEntryFromNode(node)); + } + } + } + + function getPropertyAccessExpressionFromRightHandSide(node: Node): PropertyAccessExpression { + return isRightSideOfPropertyAccess(node) && node.parent; + } + + /** `classSymbol` is the class where the constructor was defined. + * Reference the constructor and all calls to `new this()`. + */ + function findOwnConstructorCalls(classSymbol: Symbol, sourceFile: SourceFile): Node[] { + const result: Node[] = []; + + for (const decl of classSymbol.members.get("__constructor").declarations) { + const ctrKeyword = ts.findChildOfKind(decl, ts.SyntaxKind.ConstructorKeyword, sourceFile)! + Debug.assert(decl.kind === SyntaxKind.Constructor && !!ctrKeyword); + result.push(ctrKeyword); + } + + classSymbol.exports.forEach(member => { + const decl = member.valueDeclaration; + if (decl && decl.kind === SyntaxKind.MethodDeclaration) { + const body = (decl).body; + if (body) { + forEachDescendantOfKind(body, SyntaxKind.ThisKeyword, thisKeyword => { + if (isNewExpressionTarget(thisKeyword)) { + result.push(thisKeyword); } + }); + } + } + }); + + return result; + } + + /** Find references to `super` in the constructor of an extending class. */ + function superConstructorAccesses(cls: ClassLikeDeclaration): Node[] { + const symbol = cls.symbol; + const ctr = symbol.members.get("__constructor"); + if (!ctr) { + return []; + } + + const result: Node[] = []; + for (const decl of ctr.declarations) { + Debug.assert(decl.kind === SyntaxKind.Constructor); + const body = (decl).body; + if (body) { + forEachDescendantOfKind(body, SyntaxKind.SuperKeyword, node => { + if (isCallExpressionTarget(node)) { + result.push(node); } }); } - return; + }; + return result; + } - /* If we are just looking for implementations and this is a property access expression, we need to get the - * symbol of the local type of the symbol the property is being accessed on. This is because our search - * symbol may have a different parent symbol if the local type's symbol does not declare the property - * being accessed (i.e. it is declared in some parent class or interface) - */ - function getParentSymbolsOfPropertyAccess(): Symbol[] | undefined { - if (implementations) { - const propertyAccessExpression = getPropertyAccessExpressionFromRightHandSide(searchLocation); - if (propertyAccessExpression) { - const localParentType = typeChecker.getTypeAtLocation(propertyAccessExpression.expression); - if (localParentType) { - if (localParentType.symbol && localParentType.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) && localParentType.symbol !== searchSymbol.parent) { - return [localParentType.symbol]; - } - else if (localParentType.flags & TypeFlags.UnionOrIntersection) { - return getSymbolsForClassAndInterfaceComponents(localParentType); - } - } - } - } + function getImplementationReferenceEntryForNode(refNode: Node, result: ReferenceEntry[], typeChecker: TypeChecker): void { + // Check if we found a function/propertyAssignment/method with an implementation or initializer + if (isDeclarationName(refNode) && isImplementation(refNode.parent)) { + result.push(getReferenceEntryFromNode(refNode.parent)); + } + else if (refNode.kind === SyntaxKind.Identifier) { + if (refNode.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { + // Go ahead and dereference the shorthand assignment by going to its definition + getReferenceEntriesForShorthandPropertyAssignment(refNode, typeChecker, result); } - function getPropertyAccessExpressionFromRightHandSide(node: Node): PropertyAccessExpression { - return isRightSideOfPropertyAccess(node) && node.parent; + // Check if the node is within an extends or implements clause + const containingClass = getContainingClassIfInHeritageClause(refNode); + if (containingClass) { + result.push(getReferenceEntryFromNode(containingClass)); + return; } - /** Adds references when a constructor is used with `new this()` in its own class and `super()` calls in subclasses. */ - function findAdditionalConstructorReferences(referenceSymbol: Symbol, referenceLocation: Node): void { - Debug.assert(isClassLike(searchSymbol.valueDeclaration)); - - const referenceClass = referenceLocation.parent; - if (referenceSymbol === searchSymbol && isClassLike(referenceClass)) { - Debug.assert(referenceClass.name === referenceLocation); - // This is the class declaration containing the constructor. - addReferences(findOwnConstructorCalls(searchSymbol)); + // If we got a type reference, try and see if the reference applies to any expressions that can implement an interface + const containingTypeReference = getContainingTypeReference(refNode); + if (containingTypeReference) { + const parent = containingTypeReference.parent; + if (isVariableLike(parent) && parent.type === containingTypeReference && parent.initializer && isImplementationExpression(parent.initializer)) { + maybeAdd(getReferenceEntryFromNode(parent.initializer)); } - else { - // If this class appears in `extends C`, then the extending class' "super" calls are references. - const classExtending = tryGetClassByExtendingIdentifier(referenceLocation); - if (classExtending && isClassLike(classExtending) && followAliasIfNecessary(referenceSymbol, referenceLocation) === searchSymbol) { - addReferences(superConstructorAccesses(classExtending)); - } - } - } - - function addReferences(references: Node[]): void { - if (references.length) { - const referencedSymbol = getReferencedSymbol(searchSymbol); - addRange(referencedSymbol.references, map(references, getReferenceEntryFromNode)); - } - } - - /** `classSymbol` is the class where the constructor was defined. - * Reference the constructor and all calls to `new this()`. - */ - function findOwnConstructorCalls(classSymbol: Symbol): Node[] { - const result: Node[] = []; - - for (const decl of classSymbol.members["__constructor"].declarations) { - const ctrKeyword = ts.findChildOfKind(decl, ts.SyntaxKind.ConstructorKeyword, sourceFile)! - Debug.assert(decl.kind === SyntaxKind.Constructor && !!ctrKeyword); - result.push(ctrKeyword); - } - - forEachProperty(classSymbol.exports, member => { - const decl = member.valueDeclaration; - if (decl && decl.kind === SyntaxKind.MethodDeclaration) { - const body = (decl).body; - if (body) { - forEachDescendantOfKind(body, SyntaxKind.ThisKeyword, thisKeyword => { - if (isNewExpressionTarget(thisKeyword)) { - result.push(thisKeyword); - } - }); - } - } - }); - - return result; - } - - /** Find references to `super` in the constructor of an extending class. */ - function superConstructorAccesses(cls: ClassLikeDeclaration): Node[] { - const symbol = cls.symbol; - const ctr = symbol.members["__constructor"]; - if (!ctr) { - return []; - } - - const result: Node[] = []; - for (const decl of ctr.declarations) { - Debug.assert(decl.kind === SyntaxKind.Constructor); - const body = (decl).body; - if (body) { - forEachDescendantOfKind(body, SyntaxKind.SuperKeyword, node => { - if (isCallExpressionTarget(node)) { - result.push(node); + else if (isFunctionLike(parent) && parent.type === containingTypeReference && parent.body) { + if (parent.body.kind === SyntaxKind.Block) { + forEachReturnStatement(parent.body, returnStatement => { + if (returnStatement.expression && isImplementationExpression(returnStatement.expression)) { + maybeAdd(getReferenceEntryFromNode(returnStatement.expression)); } }); } - }; - return result; - } - - function getReferencedSymbol(symbol: Symbol): ReferencedSymbol { - const symbolId = getSymbolId(symbol); - let index = symbolToIndex[symbolId]; - if (index === undefined) { - index = result.length; - symbolToIndex[symbolId] = index; - - result.push({ - definition: getDefinition(symbol), - references: [] - }); - } - - return result[index]; - } - - function addReferenceToRelatedSymbol(node: Node, relatedSymbol: Symbol) { - const references = getReferencedSymbol(relatedSymbol).references; - if (implementations) { - getImplementationReferenceEntryForNode(node, references); - } - else { - references.push(getReferenceEntryFromNode(node)); - } - } - } - - function getImplementationReferenceEntryForNode(refNode: Node, result: ReferenceEntry[]): void { - // Check if we found a function/propertyAssignment/method with an implementation or initializer - if (isDeclarationName(refNode) && isImplementation(refNode.parent)) { - result.push(getReferenceEntryFromNode(refNode.parent)); - } - else if (refNode.kind === SyntaxKind.Identifier) { - if (refNode.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { - // Go ahead and dereference the shorthand assignment by going to its definition - getReferenceEntriesForShorthandPropertyAssignment(refNode, typeChecker, result); - } - - // Check if the node is within an extends or implements clause - const containingClass = getContainingClassIfInHeritageClause(refNode); - if (containingClass) { - result.push(getReferenceEntryFromNode(containingClass)); - return; - } - - // If we got a type reference, try and see if the reference applies to any expressions that can implement an interface - const containingTypeReference = getContainingTypeReference(refNode); - if (containingTypeReference) { - const parent = containingTypeReference.parent; - if (isVariableLike(parent) && parent.type === containingTypeReference && parent.initializer && isImplementationExpression(parent.initializer)) { - maybeAdd(getReferenceEntryFromNode(parent.initializer)); - } - else if (isFunctionLike(parent) && parent.type === containingTypeReference && parent.body) { - if (parent.body.kind === SyntaxKind.Block) { - forEachReturnStatement(parent.body, returnStatement => { - if (returnStatement.expression && isImplementationExpression(returnStatement.expression)) { - maybeAdd(getReferenceEntryFromNode(returnStatement.expression)); - } - }); - } - else if (isImplementationExpression(parent.body)) { - maybeAdd(getReferenceEntryFromNode(parent.body)); - } - } - else if (isAssertionExpression(parent) && isImplementationExpression(parent.expression)) { - maybeAdd(getReferenceEntryFromNode(parent.expression)); + else if (isImplementationExpression(parent.body)) { + maybeAdd(getReferenceEntryFromNode(parent.body)); } } - } - - // Type nodes can contain multiple references to the same type. For example: - // let x: Foo & (Foo & Bar) = ... - // Because we are returning the implementation locations and not the identifier locations, - // duplicate entries would be returned here as each of the type references is part of - // the same implementation. For that reason, check before we add a new entry - function maybeAdd(a: ReferenceEntry) { - if (!forEach(result, b => a.fileName === b.fileName && a.textSpan.start === b.textSpan.start && a.textSpan.length === b.textSpan.length)) { - result.push(a); + else if (isAssertionExpression(parent) && isImplementationExpression(parent.expression)) { + maybeAdd(getReferenceEntryFromNode(parent.expression)); } } } - function getSymbolsForClassAndInterfaceComponents(type: UnionOrIntersectionType, result: Symbol[] = []): Symbol[] { - for (const componentType of type.types) { - if (componentType.symbol && componentType.symbol.getFlags() & (SymbolFlags.Class | SymbolFlags.Interface)) { - result.push(componentType.symbol); - } - if (componentType.getFlags() & TypeFlags.UnionOrIntersection) { - getSymbolsForClassAndInterfaceComponents(componentType, result); - } + // Type nodes can contain multiple references to the same type. For example: + // let x: Foo & (Foo & Bar) = ... + // Because we are returning the implementation locations and not the identifier locations, + // duplicate entries would be returned here as each of the type references is part of + // the same implementation. For that reason, check before we add a new entry + function maybeAdd(a: ReferenceEntry) { + if (!forEach(result, b => a.fileName === b.fileName && a.textSpan.start === b.textSpan.start && a.textSpan.length === b.textSpan.length)) { + result.push(a); } - return result; + } + } + + function getSymbolsForClassAndInterfaceComponents(type: UnionOrIntersectionType, result: Symbol[] = []): Symbol[] { + for (const componentType of type.types) { + if (componentType.symbol && componentType.symbol.getFlags() & (SymbolFlags.Class | SymbolFlags.Interface)) { + result.push(componentType.symbol); + } + if (componentType.getFlags() & TypeFlags.UnionOrIntersection) { + getSymbolsForClassAndInterfaceComponents(componentType, result); + } + } + return result; + } + + function getContainingTypeReference(node: Node): Node { + let topLevelTypeReference: Node = undefined; + + while (node) { + if (isTypeNode(node)) { + topLevelTypeReference = node; + } + node = node.parent; } - function getContainingTypeReference(node: Node): Node { - let topLevelTypeReference: Node = undefined; + return topLevelTypeReference; + } - while (node) { - if (isTypeNode(node)) { - topLevelTypeReference = node; - } - node = node.parent; + function getContainingClassIfInHeritageClause(node: Node): ClassLikeDeclaration { + if (node && node.parent) { + if (node.kind === SyntaxKind.ExpressionWithTypeArguments + && node.parent.kind === SyntaxKind.HeritageClause + && isClassLike(node.parent.parent)) { + return node.parent.parent; } - return topLevelTypeReference; - } - - function getContainingClassIfInHeritageClause(node: Node): ClassLikeDeclaration { - if (node && node.parent) { - if (node.kind === SyntaxKind.ExpressionWithTypeArguments - && node.parent.kind === SyntaxKind.HeritageClause - && isClassLike(node.parent.parent)) { - return node.parent.parent; - } - - else if (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PropertyAccessExpression) { - return getContainingClassIfInHeritageClause(node.parent); - } + else if (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PropertyAccessExpression) { + return getContainingClassIfInHeritageClause(node.parent); } - return undefined; } + return undefined; + } - /** - * Returns true if this is an expression that can be considered an implementation - */ - function isImplementationExpression(node: Expression): boolean { - // Unwrap parentheses - if (node.kind === SyntaxKind.ParenthesizedExpression) { + /** + * Returns true if this is an expression that can be considered an implementation + */ + function isImplementationExpression(node: Expression): boolean { + switch (node.kind) { + case SyntaxKind.ParenthesizedExpression: return isImplementationExpression((node).expression); + case SyntaxKind.ArrowFunction: + case SyntaxKind.FunctionExpression: + case SyntaxKind.ObjectLiteralExpression: + case SyntaxKind.ClassExpression: + case SyntaxKind.ArrayLiteralExpression: + return true; + default: + return false; + } + } + + /** + * Determines if the parent symbol occurs somewhere in the child's ancestry. If the parent symbol + * is an interface, determines if some ancestor of the child symbol extends or inherits from it. + * Also takes in a cache of previous results which makes this slightly more efficient and is + * necessary to avoid potential loops like so: + * class A extends B { } + * class B extends A { } + * + * We traverse the AST rather than using the type checker because users are typically only interested + * in explicit implementations of an interface/class when calling "Go to Implementation". Sibling + * implementations of types that share a common ancestor with the type whose implementation we are + * searching for need to be filtered out of the results. The type checker doesn't let us make the + * distinction between structurally compatible implementations and explicit implementations, so we + * must use the AST. + * + * @param child A class or interface Symbol + * @param parent Another class or interface Symbol + * @param cachedResults A map of symbol id pairs (i.e. "child,parent") to booleans indicating previous results + */ + function explicitlyInheritsFrom(child: Symbol, parent: Symbol, cachedResults: Map, typeChecker: TypeChecker): boolean { + const parentIsInterface = parent.getFlags() & SymbolFlags.Interface; + return searchHierarchy(child); + + function searchHierarchy(symbol: Symbol): boolean { + if (symbol === parent) { + return true; } - return node.kind === SyntaxKind.ArrowFunction || - node.kind === SyntaxKind.FunctionExpression || - node.kind === SyntaxKind.ObjectLiteralExpression || - node.kind === SyntaxKind.ClassExpression || - node.kind === SyntaxKind.ArrayLiteralExpression; - } + const key = getSymbolId(symbol) + "," + getSymbolId(parent); + const cached = cachedResults.get(key); + if (cached !== undefined) { + return cached; + } - /** - * Determines if the parent symbol occurs somewhere in the child's ancestry. If the parent symbol - * is an interface, determines if some ancestor of the child symbol extends or inherits from it. - * Also takes in a cache of previous results which makes this slightly more efficient and is - * necessary to avoid potential loops like so: - * class A extends B { } - * class B extends A { } - * - * We traverse the AST rather than using the type checker because users are typically only interested - * in explicit implementations of an interface/class when calling "Go to Implementation". Sibling - * implementations of types that share a common ancestor with the type whose implementation we are - * searching for need to be filtered out of the results. The type checker doesn't let us make the - * distinction between structurally compatible implementations and explicit implementations, so we - * must use the AST. - * - * @param child A class or interface Symbol - * @param parent Another class or interface Symbol - * @param cachedResults A map of symbol id pairs (i.e. "child,parent") to booleans indicating previous results - */ - function explicitlyInheritsFrom(child: Symbol, parent: Symbol, cachedResults: Map): boolean { - const parentIsInterface = parent.getFlags() & SymbolFlags.Interface; - return searchHierarchy(child); + // Set the key so that we don't infinitely recurse + cachedResults.set(key, false); - function searchHierarchy(symbol: Symbol): boolean { - if (symbol === parent) { - return true; - } - - const key = getSymbolId(symbol) + "," + getSymbolId(parent); - if (key in cachedResults) { - return cachedResults[key]; - } - - // Set the key so that we don't infinitely recurse - cachedResults[key] = false; - - const inherits = forEach(symbol.getDeclarations(), declaration => { - if (isClassLike(declaration)) { - if (parentIsInterface) { - const interfaceReferences = getClassImplementsHeritageClauseElements(declaration); - if (interfaceReferences) { - for (const typeReference of interfaceReferences) { - if (searchTypeReference(typeReference)) { - return true; - } + const inherits = forEach(symbol.getDeclarations(), declaration => { + if (isClassLike(declaration)) { + if (parentIsInterface) { + const interfaceReferences = getClassImplementsHeritageClauseElements(declaration); + if (interfaceReferences) { + for (const typeReference of interfaceReferences) { + if (searchTypeReference(typeReference)) { + return true; } } } - return searchTypeReference(getClassExtendsHeritageClauseElement(declaration)); } - else if (declaration.kind === SyntaxKind.InterfaceDeclaration) { - if (parentIsInterface) { - return forEach(getInterfaceBaseTypeNodes(declaration), searchTypeReference); - } - } - return false; - }); - - cachedResults[key] = inherits; - return inherits; - } - - function searchTypeReference(typeReference: ExpressionWithTypeArguments): boolean { - if (typeReference) { - const type = typeChecker.getTypeAtLocation(typeReference); - if (type && type.symbol) { - return searchHierarchy(type.symbol); + return searchTypeReference(getClassExtendsHeritageClauseElement(declaration)); + } + else if (declaration.kind === SyntaxKind.InterfaceDeclaration) { + if (parentIsInterface) { + return forEach(getInterfaceBaseTypeNodes(declaration), searchTypeReference); } } return false; + }); + + cachedResults.set(key, inherits); + return inherits; + } + + function searchTypeReference(typeReference: ExpressionWithTypeArguments): boolean { + if (typeReference) { + const type = typeChecker.getTypeAtLocation(typeReference); + if (type && type.symbol) { + return searchHierarchy(type.symbol); + } + } + return false; + } + } + + function getReferencesForSuperKeyword(superKeyword: Node, typeChecker: TypeChecker, cancellationToken: CancellationToken): ReferencedSymbol[] { + let searchSpaceNode = getSuperContainer(superKeyword, /*stopOnFunctions*/ false); + if (!searchSpaceNode) { + return undefined; + } + // Whether 'super' occurs in a static context within a class. + let staticFlag = ModifierFlags.Static; + + switch (searchSpaceNode.kind) { + case SyntaxKind.PropertyDeclaration: + case SyntaxKind.PropertySignature: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.MethodSignature: + case SyntaxKind.Constructor: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + staticFlag &= getModifierFlags(searchSpaceNode); + searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class + break; + default: + return undefined; + } + + const references: ReferenceEntry[] = []; + + const sourceFile = searchSpaceNode.getSourceFile(); + const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "super", searchSpaceNode.getStart(), searchSpaceNode.getEnd(), cancellationToken); + for (const position of possiblePositions) { + cancellationToken.throwIfCancellationRequested(); + + const node = getTouchingWord(sourceFile, position); + + if (!node || node.kind !== SyntaxKind.SuperKeyword) { + continue; + } + + const container = getSuperContainer(node, /*stopOnFunctions*/ false); + + // If we have a 'super' container, we must have an enclosing class. + // Now make sure the owning class is the same as the search-space + // and has the same static qualifier as the original 'super's owner. + if (container && (ModifierFlags.Static & getModifierFlags(container)) === staticFlag && container.parent.symbol === searchSpaceNode.symbol) { + references.push(getReferenceEntryFromNode(node)); } } - function getReferencesForSuperKeyword(superKeyword: Node): ReferencedSymbol[] { - let searchSpaceNode = getSuperContainer(superKeyword, /*stopOnFunctions*/ false); - if (!searchSpaceNode) { - return undefined; - } - // Whether 'super' occurs in a static context within a class. - let staticFlag = ModifierFlags.Static; + const definition = getDefinition(searchSpaceNode.symbol, superKeyword, typeChecker); + return [{ definition, references }]; + } - switch (searchSpaceNode.kind) { - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.Constructor: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - staticFlag &= getModifierFlags(searchSpaceNode); - searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class + function getReferencesForThisKeyword(thisOrSuperKeyword: Node, sourceFiles: SourceFile[], typeChecker: TypeChecker, cancellationToken: CancellationToken): ReferencedSymbol[] { + let searchSpaceNode = getThisContainer(thisOrSuperKeyword, /* includeArrowFunctions */ false); + + // Whether 'this' occurs in a static context within a class. + let staticFlag = ModifierFlags.Static; + + switch (searchSpaceNode.kind) { + case SyntaxKind.MethodDeclaration: + case SyntaxKind.MethodSignature: + if (isObjectLiteralMethod(searchSpaceNode)) { break; - default: + } + // fall through + case SyntaxKind.PropertyDeclaration: + case SyntaxKind.PropertySignature: + case SyntaxKind.Constructor: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + staticFlag &= getModifierFlags(searchSpaceNode); + searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class + break; + case SyntaxKind.SourceFile: + if (isExternalModule(searchSpaceNode)) { return undefined; - } + } + // Fall through + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.FunctionExpression: + break; + // Computed properties in classes are not handled here because references to this are illegal, + // so there is no point finding references to them. + default: + return undefined; + } - const references: ReferenceEntry[] = []; + const references: ReferenceEntry[] = []; + let possiblePositions: number[]; + if (searchSpaceNode.kind === SyntaxKind.SourceFile) { + forEach(sourceFiles, sourceFile => { + possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", sourceFile.getStart(), sourceFile.getEnd(), cancellationToken); + getThisReferencesInFile(sourceFile, sourceFile, possiblePositions, references); + }); + } + else { const sourceFile = searchSpaceNode.getSourceFile(); - const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "super", searchSpaceNode.getStart(), searchSpaceNode.getEnd()); + possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", searchSpaceNode.getStart(), searchSpaceNode.getEnd(), cancellationToken); + getThisReferencesInFile(sourceFile, searchSpaceNode, possiblePositions, references); + } + + const thisOrSuperSymbol = typeChecker.getSymbolAtLocation(thisOrSuperKeyword); + + const displayParts = thisOrSuperSymbol && SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind( + typeChecker, thisOrSuperSymbol, thisOrSuperKeyword.getSourceFile(), getContainerNode(thisOrSuperKeyword), thisOrSuperKeyword).displayParts; + + return [{ + definition: { + containerKind: "", + containerName: "", + fileName: thisOrSuperKeyword.getSourceFile().fileName, + kind: ScriptElementKind.variableElement, + name: "this", + textSpan: createTextSpanFromNode(thisOrSuperKeyword), + displayParts + }, + references: references + }]; + + function getThisReferencesInFile(sourceFile: SourceFile, searchSpaceNode: Node, possiblePositions: number[], result: ReferenceEntry[]): void { forEach(possiblePositions, position => { cancellationToken.throwIfCancellationRequested(); const node = getTouchingWord(sourceFile, position); - - if (!node || node.kind !== SyntaxKind.SuperKeyword) { + if (!node || !isThis(node)) { return; } - const container = getSuperContainer(node, /*stopOnFunctions*/ false); + const container = getThisContainer(node, /* includeArrowFunctions */ false); - // If we have a 'super' container, we must have an enclosing class. - // Now make sure the owning class is the same as the search-space - // and has the same static qualifier as the original 'super's owner. - if (container && (ModifierFlags.Static & getModifierFlags(container)) === staticFlag && container.parent.symbol === searchSpaceNode.symbol) { - references.push(getReferenceEntryFromNode(node)); - } - }); - - const definition = getDefinition(searchSpaceNode.symbol); - return [{ definition, references }]; - } - - function getReferencesForThisKeyword(thisOrSuperKeyword: Node, sourceFiles: SourceFile[]): ReferencedSymbol[] { - let searchSpaceNode = getThisContainer(thisOrSuperKeyword, /* includeArrowFunctions */ false); - - // Whether 'this' occurs in a static context within a class. - let staticFlag = ModifierFlags.Static; - - switch (searchSpaceNode.kind) { - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - if (isObjectLiteralMethod(searchSpaceNode)) { + switch (searchSpaceNode.kind) { + case SyntaxKind.FunctionExpression: + case SyntaxKind.FunctionDeclaration: + if (searchSpaceNode.symbol === container.symbol) { + result.push(getReferenceEntryFromNode(node)); + } + break; + case SyntaxKind.MethodDeclaration: + case SyntaxKind.MethodSignature: + if (isObjectLiteralMethod(searchSpaceNode) && searchSpaceNode.symbol === container.symbol) { + result.push(getReferenceEntryFromNode(node)); + } + break; + case SyntaxKind.ClassExpression: + case SyntaxKind.ClassDeclaration: + // Make sure the container belongs to the same class + // and has the appropriate static modifier from the original container. + if (container.parent && searchSpaceNode.symbol === container.parent.symbol && (getModifierFlags(container) & ModifierFlags.Static) === staticFlag) { + result.push(getReferenceEntryFromNode(node)); + } + break; + case SyntaxKind.SourceFile: + if (container.kind === SyntaxKind.SourceFile && !isExternalModule(container)) { + result.push(getReferenceEntryFromNode(node)); + } break; - } - // fall through - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - case SyntaxKind.Constructor: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - staticFlag &= getModifierFlags(searchSpaceNode); - searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class - break; - case SyntaxKind.SourceFile: - if (isExternalModule(searchSpaceNode)) { - return undefined; - } - // Fall through - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - break; - // Computed properties in classes are not handled here because references to this are illegal, - // so there is no point finding references to them. - default: - return undefined; - } - - const references: ReferenceEntry[] = []; - - let possiblePositions: number[]; - if (searchSpaceNode.kind === SyntaxKind.SourceFile) { - forEach(sourceFiles, sourceFile => { - possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", sourceFile.getStart(), sourceFile.getEnd()); - getThisReferencesInFile(sourceFile, sourceFile, possiblePositions, references); - }); - } - else { - const sourceFile = searchSpaceNode.getSourceFile(); - possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", searchSpaceNode.getStart(), searchSpaceNode.getEnd()); - getThisReferencesInFile(sourceFile, searchSpaceNode, possiblePositions, references); - } - - const thisOrSuperSymbol = typeChecker.getSymbolAtLocation(thisOrSuperKeyword); - - const displayParts = thisOrSuperSymbol && SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind( - typeChecker, thisOrSuperSymbol, thisOrSuperKeyword.getSourceFile(), getContainerNode(thisOrSuperKeyword), thisOrSuperKeyword).displayParts; - - return [{ - definition: { - containerKind: "", - containerName: "", - fileName: node.getSourceFile().fileName, - kind: ScriptElementKind.variableElement, - name: "this", - textSpan: createTextSpanFromNode(node), - displayParts - }, - references: references - }]; - - function getThisReferencesInFile(sourceFile: SourceFile, searchSpaceNode: Node, possiblePositions: number[], result: ReferenceEntry[]): void { - forEach(possiblePositions, position => { - cancellationToken.throwIfCancellationRequested(); - - const node = getTouchingWord(sourceFile, position); - if (!node || !isThis(node)) { - return; - } - - const container = getThisContainer(node, /* includeArrowFunctions */ false); - - switch (searchSpaceNode.kind) { - case SyntaxKind.FunctionExpression: - case SyntaxKind.FunctionDeclaration: - if (searchSpaceNode.symbol === container.symbol) { - result.push(getReferenceEntryFromNode(node)); - } - break; - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - if (isObjectLiteralMethod(searchSpaceNode) && searchSpaceNode.symbol === container.symbol) { - result.push(getReferenceEntryFromNode(node)); - } - break; - case SyntaxKind.ClassExpression: - case SyntaxKind.ClassDeclaration: - // Make sure the container belongs to the same class - // and has the appropriate static modifier from the original container. - if (container.parent && searchSpaceNode.symbol === container.parent.symbol && (getModifierFlags(container) & ModifierFlags.Static) === staticFlag) { - result.push(getReferenceEntryFromNode(node)); - } - break; - case SyntaxKind.SourceFile: - if (container.kind === SyntaxKind.SourceFile && !isExternalModule(container)) { - result.push(getReferenceEntryFromNode(node)); - } - break; - } - }); - } - } - - - function getReferencesForStringLiteral(node: StringLiteral, sourceFiles: SourceFile[]): ReferencedSymbol[] { - const type = getStringLiteralTypeForNode(node, typeChecker); - - if (!type) { - // nothing to do here. moving on - return undefined; - } - - const references: ReferenceEntry[] = []; - - for (const sourceFile of sourceFiles) { - const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, type.text, sourceFile.getStart(), sourceFile.getEnd()); - getReferencesForStringLiteralInFile(sourceFile, type, possiblePositions, references); - } - - return [{ - definition: { - containerKind: "", - containerName: "", - fileName: node.getSourceFile().fileName, - kind: ScriptElementKind.variableElement, - name: type.text, - textSpan: createTextSpanFromNode(node), - displayParts: [displayPart(getTextOfNode(node), SymbolDisplayPartKind.stringLiteral)] - }, - references: references - }]; - - function getReferencesForStringLiteralInFile(sourceFile: SourceFile, searchType: Type, possiblePositions: number[], references: ReferenceEntry[]): void { - for (const position of possiblePositions) { - cancellationToken.throwIfCancellationRequested(); - - const node = getTouchingWord(sourceFile, position); - if (!node || node.kind !== SyntaxKind.StringLiteral) { - return; - } - - const type = getStringLiteralTypeForNode(node, typeChecker); - if (type === searchType) { - references.push(getReferenceEntryFromNode(node)); - } - } - } - } - - function populateSearchSymbolSet(symbol: Symbol, location: Node): Symbol[] { - // The search set contains at least the current symbol - let result = [symbol]; - - // If the location is name of property symbol from object literal destructuring pattern - // Search the property symbol - // for ( { property: p2 } of elems) { } - const containingObjectLiteralElement = getContainingObjectLiteralElement(location); - if (containingObjectLiteralElement && containingObjectLiteralElement.kind !== SyntaxKind.ShorthandPropertyAssignment) { - const propertySymbol = getPropertySymbolOfDestructuringAssignment(location); - if (propertySymbol) { - result.push(propertySymbol); - } - } - - // If the symbol is an alias, add what it aliases to the list - // import {a} from "mod"; - // export {a} - // If the symbol is an alias to default declaration, add what it aliases to the list - // declare "mod" { export default class B { } } - // import B from "mod"; - //// For export specifiers, the exported name can be referring to a local symbol, e.g.: - //// import {a} from "mod"; - //// export {a as somethingElse} - //// We want the *local* declaration of 'a' as declared in the import, - //// *not* as declared within "mod" (or farther) - const aliasSymbol = getAliasSymbolForPropertyNameSymbol(symbol, location); - if (aliasSymbol) { - result = result.concat(populateSearchSymbolSet(aliasSymbol, location)); - } - - // If the location is in a context sensitive location (i.e. in an object literal) try - // to get a contextual type for it, and add the property symbol from the contextual - // type to the search set - if (containingObjectLiteralElement) { - forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement), contextualSymbol => { - addRange(result, typeChecker.getRootSymbols(contextualSymbol)); - }); - - /* Because in short-hand property assignment, location has two meaning : property name and as value of the property - * When we do findAllReference at the position of the short-hand property assignment, we would want to have references to position of - * property name and variable declaration of the identifier. - * Like in below example, when querying for all references for an identifier 'name', of the property assignment, the language service - * should show both 'name' in 'obj' and 'name' in variable declaration - * const name = "Foo"; - * const obj = { name }; - * In order to do that, we will populate the search set with the value symbol of the identifier as a value of the property assignment - * so that when matching with potential reference symbol, both symbols from property declaration and variable declaration - * will be included correctly. - */ - const shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(location.parent); - if (shorthandValueSymbol) { - result.push(shorthandValueSymbol); - } - } - - // If the symbol.valueDeclaration is a property parameter declaration, - // we should include both parameter declaration symbol and property declaration symbol - // Parameter Declaration symbol is only visible within function scope, so the symbol is stored in constructor.locals. - // Property Declaration symbol is a member of the class, so the symbol is stored in its class Declaration.symbol.members - if (symbol.valueDeclaration && symbol.valueDeclaration.kind === SyntaxKind.Parameter && - isParameterPropertyDeclaration(symbol.valueDeclaration)) { - result = result.concat(typeChecker.getSymbolsOfParameterPropertyDeclaration(symbol.valueDeclaration, symbol.name)); - } - - // If this is symbol of binding element without propertyName declaration in Object binding pattern - // Include the property in the search - const bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol); - if (bindingElementPropertySymbol) { - result.push(bindingElementPropertySymbol); - } - - // If this is a union property, add all the symbols from all its source symbols in all unioned types. - // If the symbol is an instantiation from a another symbol (e.g. widened symbol) , add the root the list - forEach(typeChecker.getRootSymbols(symbol), rootSymbol => { - if (rootSymbol !== symbol) { - result.push(rootSymbol); - } - - // Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions - if (!implementations && rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { - getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, /*previousIterationSymbolsCache*/ createMap()); } }); - - return result; } + } - /** - * Find symbol of the given property-name and add the symbol to the given result array - * @param symbol a symbol to start searching for the given propertyName - * @param propertyName a name of property to search for - * @param result an array of symbol of found property symbols - * @param previousIterationSymbolsCache a cache of symbol from previous iterations of calling this function to prevent infinite revisiting of the same symbol. - * The value of previousIterationSymbol is undefined when the function is first called. - */ - function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, result: Symbol[], - previousIterationSymbolsCache: SymbolTable): void { - if (!symbol) { - return; - } + function getReferencesForStringLiteral(node: StringLiteral, sourceFiles: SourceFile[], typeChecker: TypeChecker, cancellationToken: CancellationToken): ReferencedSymbol[] { + const type = getStringLiteralTypeForNode(node, typeChecker); - // If the current symbol is the same as the previous-iteration symbol, we can just return the symbol that has already been visited - // This is particularly important for the following cases, so that we do not infinitely visit the same symbol. - // For example: - // interface C extends C { - // /*findRef*/propName: string; - // } - // The first time getPropertySymbolsFromBaseTypes is called when finding-all-references at propName, - // the symbol argument will be the symbol of an interface "C" and previousIterationSymbol is undefined, - // the function will add any found symbol of the property-name, then its sub-routine will call - // getPropertySymbolsFromBaseTypes again to walk up any base types to prevent revisiting already - // visited symbol, interface "C", the sub-routine will pass the current symbol as previousIterationSymbol. - if (symbol.name in previousIterationSymbolsCache) { - return; - } - - if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { - forEach(symbol.getDeclarations(), declaration => { - if (isClassLike(declaration)) { - getPropertySymbolFromTypeReference(getClassExtendsHeritageClauseElement(declaration)); - forEach(getClassImplementsHeritageClauseElements(declaration), getPropertySymbolFromTypeReference); - } - else if (declaration.kind === SyntaxKind.InterfaceDeclaration) { - forEach(getInterfaceBaseTypeNodes(declaration), getPropertySymbolFromTypeReference); - } - }); - } - return; - - function getPropertySymbolFromTypeReference(typeReference: ExpressionWithTypeArguments) { - if (typeReference) { - const type = typeChecker.getTypeAtLocation(typeReference); - if (type) { - const propertySymbol = typeChecker.getPropertyOfType(type, propertyName); - if (propertySymbol) { - result.push(...typeChecker.getRootSymbols(propertySymbol)); - } - - // Visit the typeReference as well to see if it directly or indirectly use that property - previousIterationSymbolsCache[symbol.name] = symbol; - getPropertySymbolsFromBaseTypes(type.symbol, propertyName, result, previousIterationSymbolsCache); - } - } - } - } - - function getRelatedSymbol(searchSymbols: Symbol[], referenceSymbol: Symbol, referenceLocation: Node, searchLocationIsConstructor: boolean, parents: Symbol[] | undefined, cache: Map): Symbol { - if (contains(searchSymbols, referenceSymbol)) { - // If we are searching for constructor uses, they must be 'new' expressions. - return (!searchLocationIsConstructor || isNewExpressionTarget(referenceLocation)) && referenceSymbol; - } - - // If the reference symbol is an alias, check if what it is aliasing is one of the search - // symbols but by looking up for related symbol of this alias so it can handle multiple level of indirectness. - const aliasSymbol = getAliasSymbolForPropertyNameSymbol(referenceSymbol, referenceLocation); - if (aliasSymbol) { - return getRelatedSymbol(searchSymbols, aliasSymbol, referenceLocation, searchLocationIsConstructor, parents, cache); - } - - // If the reference location is in an object literal, try to get the contextual type for the - // object literal, lookup the property symbol in the contextual type, and use this symbol to - // compare to our searchSymbol - const containingObjectLiteralElement = getContainingObjectLiteralElement(referenceLocation); - if (containingObjectLiteralElement) { - const contextualSymbol = forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement), contextualSymbol => { - return forEach(typeChecker.getRootSymbols(contextualSymbol), s => searchSymbols.indexOf(s) >= 0 ? s : undefined); - }); - - if (contextualSymbol) { - return contextualSymbol; - } - - // If the reference location is the name of property from object literal destructuring pattern - // Get the property symbol from the object literal's type and look if thats the search symbol - // In below eg. get 'property' from type of elems iterating type - // for ( { property: p2 } of elems) { } - const propertySymbol = getPropertySymbolOfDestructuringAssignment(referenceLocation); - if (propertySymbol && searchSymbols.indexOf(propertySymbol) >= 0) { - return propertySymbol; - } - } - - // If the reference location is the binding element and doesn't have property name - // then include the binding element in the related symbols - // let { a } : { a }; - const bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(referenceSymbol); - if (bindingElementPropertySymbol && searchSymbols.indexOf(bindingElementPropertySymbol) >= 0) { - return bindingElementPropertySymbol; - } - - // Unwrap symbols to get to the root (e.g. transient symbols as a result of widening) - // Or a union property, use its underlying unioned symbols - return forEach(typeChecker.getRootSymbols(referenceSymbol), rootSymbol => { - // if it is in the list, then we are done - if (searchSymbols.indexOf(rootSymbol) >= 0) { - return rootSymbol; - } - - // Finally, try all properties with the same name in any type the containing type extended or implemented, and - // see if any is in the list. If we were passed a parent symbol, only include types that are subtypes of the - // parent symbol - if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { - // Parents will only be defined if implementations is true - if (parents) { - if (!forEach(parents, parent => explicitlyInheritsFrom(rootSymbol.parent, parent, cache))) { - return undefined; - } - } - - const result: Symbol[] = []; - getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, /*previousIterationSymbolsCache*/ createMap()); - return forEach(result, s => searchSymbols.indexOf(s) >= 0 ? s : undefined); - } - - return undefined; - }); - } - - function getNameFromObjectLiteralElement(node: ObjectLiteralElement) { - if (node.name.kind === SyntaxKind.ComputedPropertyName) { - const nameExpression = (node.name).expression; - // treat computed property names where expression is string/numeric literal as just string/numeric literal - if (isStringOrNumericLiteral(nameExpression)) { - return (nameExpression).text; - } - return undefined; - } - return (node.name).text; - } - - function getPropertySymbolsFromContextualType(node: ObjectLiteralElement): Symbol[] { - const objectLiteral = node.parent; - const contextualType = typeChecker.getContextualType(objectLiteral); - const name = getNameFromObjectLiteralElement(node); - if (name && contextualType) { - const result: Symbol[] = []; - const symbol = contextualType.getProperty(name); - if (symbol) { - result.push(symbol); - } - - if (contextualType.flags & TypeFlags.Union) { - forEach((contextualType).types, t => { - const symbol = t.getProperty(name); - if (symbol) { - result.push(symbol); - } - }); - } - return result; - } + if (!type) { + // nothing to do here. moving on return undefined; } - /** Given an initial searchMeaning, extracted from a location, widen the search scope based on the declarations - * of the corresponding symbol. e.g. if we are searching for "Foo" in value position, but "Foo" references a class - * then we need to widen the search to include type positions as well. - * On the contrary, if we are searching for "Bar" in type position and we trace bar to an interface, and an uninstantiated - * module, we want to keep the search limited to only types, as the two declarations (interface and uninstantiated module) - * do not intersect in any of the three spaces. - */ - function getIntersectingMeaningFromDeclarations(meaning: SemanticMeaning, declarations: Declaration[]): SemanticMeaning { - if (declarations) { - let lastIterationMeaning: SemanticMeaning; - do { - // The result is order-sensitive, for instance if initialMeaning === Namespace, and declarations = [class, instantiated module] - // we need to consider both as they initialMeaning intersects with the module in the namespace space, and the module - // intersects with the class in the value space. - // To achieve that we will keep iterating until the result stabilizes. + const references: ReferenceEntry[] = []; - // Remember the last meaning - lastIterationMeaning = meaning; + for (const sourceFile of sourceFiles) { + const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, type.text, sourceFile.getStart(), sourceFile.getEnd(), cancellationToken); + getReferencesForStringLiteralInFile(sourceFile, type, possiblePositions, references); + } - for (const declaration of declarations) { - const declarationMeaning = getMeaningFromDeclaration(declaration); + return [{ + definition: { + containerKind: "", + containerName: "", + fileName: node.getSourceFile().fileName, + kind: ScriptElementKind.variableElement, + name: type.text, + textSpan: createTextSpanFromNode(node), + displayParts: [displayPart(getTextOfNode(node), SymbolDisplayPartKind.stringLiteral)] + }, + references: references + }]; - if (declarationMeaning & meaning) { - meaning |= declarationMeaning; - } + function getReferencesForStringLiteralInFile(sourceFile: SourceFile, searchType: Type, possiblePositions: number[], references: ReferenceEntry[]): void { + for (const position of possiblePositions) { + cancellationToken.throwIfCancellationRequested(); + + const node = getTouchingWord(sourceFile, position); + if (!node || node.kind !== SyntaxKind.StringLiteral) { + return; + } + + const type = getStringLiteralTypeForNode(node, typeChecker); + if (type === searchType) { + references.push(getReferenceEntryFromNode(node)); + } + } + } + } + + function populateSearchSymbolSet(symbol: Symbol, location: Node, typeChecker: TypeChecker, implementations: boolean): Symbol[] { + // The search set contains at least the current symbol + const result = [symbol]; + + // If the location is name of property symbol from object literal destructuring pattern + // Search the property symbol + // for ( { property: p2 } of elems) { } + const containingObjectLiteralElement = getContainingObjectLiteralElement(location); + if (containingObjectLiteralElement && containingObjectLiteralElement.kind !== SyntaxKind.ShorthandPropertyAssignment) { + const propertySymbol = getPropertySymbolOfDestructuringAssignment(location, typeChecker); + if (propertySymbol) { + result.push(propertySymbol); + } + } + + // If the location is in a context sensitive location (i.e. in an object literal) try + // to get a contextual type for it, and add the property symbol from the contextual + // type to the search set + if (containingObjectLiteralElement) { + forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement, typeChecker), contextualSymbol => { + addRange(result, typeChecker.getRootSymbols(contextualSymbol)); + }); + + /* Because in short-hand property assignment, location has two meaning : property name and as value of the property + * When we do findAllReference at the position of the short-hand property assignment, we would want to have references to position of + * property name and variable declaration of the identifier. + * Like in below example, when querying for all references for an identifier 'name', of the property assignment, the language service + * should show both 'name' in 'obj' and 'name' in variable declaration + * const name = "Foo"; + * const obj = { name }; + * In order to do that, we will populate the search set with the value symbol of the identifier as a value of the property assignment + * so that when matching with potential reference symbol, both symbols from property declaration and variable declaration + * will be included correctly. + */ + const shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(location.parent); + if (shorthandValueSymbol) { + result.push(shorthandValueSymbol); + } + } + + // If the symbol.valueDeclaration is a property parameter declaration, + // we should include both parameter declaration symbol and property declaration symbol + // Parameter Declaration symbol is only visible within function scope, so the symbol is stored in constructor.locals. + // Property Declaration symbol is a member of the class, so the symbol is stored in its class Declaration.symbol.members + if (symbol.valueDeclaration && symbol.valueDeclaration.kind === SyntaxKind.Parameter && + isParameterPropertyDeclaration(symbol.valueDeclaration)) { + addRange(result, typeChecker.getSymbolsOfParameterPropertyDeclaration(symbol.valueDeclaration, symbol.name)); + } + + // If this is symbol of binding element without propertyName declaration in Object binding pattern + // Include the property in the search + const bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol, typeChecker); + if (bindingElementPropertySymbol) { + result.push(bindingElementPropertySymbol); + } + + // If this is a union property, add all the symbols from all its source symbols in all unioned types. + // If the symbol is an instantiation from a another symbol (e.g. widened symbol) , add the root the list + for (const rootSymbol of typeChecker.getRootSymbols(symbol)) { + if (rootSymbol !== symbol) { + result.push(rootSymbol); + } + + // Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions + if (!implementations && rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { + getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, /*previousIterationSymbolsCache*/ createMap(), typeChecker); + } + } + + return result; + } + + /** + * Find symbol of the given property-name and add the symbol to the given result array + * @param symbol a symbol to start searching for the given propertyName + * @param propertyName a name of property to search for + * @param result an array of symbol of found property symbols + * @param previousIterationSymbolsCache a cache of symbol from previous iterations of calling this function to prevent infinite revisiting of the same symbol. + * The value of previousIterationSymbol is undefined when the function is first called. + */ + function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, result: Symbol[], + previousIterationSymbolsCache: SymbolTable, typeChecker: TypeChecker): void { + if (!symbol) { + return; + } + + // If the current symbol is the same as the previous-iteration symbol, we can just return the symbol that has already been visited + // This is particularly important for the following cases, so that we do not infinitely visit the same symbol. + // For example: + // interface C extends C { + // /*findRef*/propName: string; + // } + // The first time getPropertySymbolsFromBaseTypes is called when finding-all-references at propName, + // the symbol argument will be the symbol of an interface "C" and previousIterationSymbol is undefined, + // the function will add any found symbol of the property-name, then its sub-routine will call + // getPropertySymbolsFromBaseTypes again to walk up any base types to prevent revisiting already + // visited symbol, interface "C", the sub-routine will pass the current symbol as previousIterationSymbol. + if (previousIterationSymbolsCache.has(symbol.name)) { + return; + } + + if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { + forEach(symbol.getDeclarations(), declaration => { + if (isClassLike(declaration)) { + getPropertySymbolFromTypeReference(getClassExtendsHeritageClauseElement(declaration)); + forEach(getClassImplementsHeritageClauseElements(declaration), getPropertySymbolFromTypeReference); + } + else if (declaration.kind === SyntaxKind.InterfaceDeclaration) { + forEach(getInterfaceBaseTypeNodes(declaration), getPropertySymbolFromTypeReference); + } + }); + } + return; + + function getPropertySymbolFromTypeReference(typeReference: ExpressionWithTypeArguments) { + if (typeReference) { + const type = typeChecker.getTypeAtLocation(typeReference); + if (type) { + const propertySymbol = typeChecker.getPropertyOfType(type, propertyName); + if (propertySymbol) { + result.push(...typeChecker.getRootSymbols(propertySymbol)); + } + + // Visit the typeReference as well to see if it directly or indirectly use that property + previousIterationSymbolsCache.set(symbol.name, symbol); + getPropertySymbolsFromBaseTypes(type.symbol, propertyName, result, previousIterationSymbolsCache, typeChecker); + } + } + } + } + + function getRelatedSymbol(searchSymbols: Symbol[], referenceSymbol: Symbol, referenceLocation: Node, searchLocationIsConstructor: boolean, parents: Symbol[] | undefined, cache: Map, typeChecker: TypeChecker): Symbol | undefined { + if (contains(searchSymbols, referenceSymbol)) { + // If we are searching for constructor uses, they must be 'new' expressions. + return (!searchLocationIsConstructor || isNewExpressionTarget(referenceLocation)) ? referenceSymbol : undefined; + } + + // If the reference symbol is an alias, check if what it is aliasing is one of the search + // symbols but by looking up for related symbol of this alias so it can handle multiple level of indirectness. + const aliasSymbol = getAliasSymbolForPropertyNameSymbol(referenceSymbol, referenceLocation, typeChecker); + if (aliasSymbol) { + return getRelatedSymbol(searchSymbols, aliasSymbol, referenceLocation, searchLocationIsConstructor, parents, cache, typeChecker); + } + + // If the reference location is in an object literal, try to get the contextual type for the + // object literal, lookup the property symbol in the contextual type, and use this symbol to + // compare to our searchSymbol + const containingObjectLiteralElement = getContainingObjectLiteralElement(referenceLocation); + if (containingObjectLiteralElement) { + const contextualSymbol = forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement, typeChecker), contextualSymbol => + find(typeChecker.getRootSymbols(contextualSymbol), symbol => contains(searchSymbols, symbol))); + + if (contextualSymbol) { + return contextualSymbol; + } + + // If the reference location is the name of property from object literal destructuring pattern + // Get the property symbol from the object literal's type and look if thats the search symbol + // In below eg. get 'property' from type of elems iterating type + // for ( { property: p2 } of elems) { } + const propertySymbol = getPropertySymbolOfDestructuringAssignment(referenceLocation, typeChecker); + if (propertySymbol && contains(searchSymbols, propertySymbol)) { + return propertySymbol; + } + } + + // If the reference location is the binding element and doesn't have property name + // then include the binding element in the related symbols + // let { a } : { a }; + const bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(referenceSymbol, typeChecker); + if (bindingElementPropertySymbol && contains(searchSymbols, bindingElementPropertySymbol)) { + return bindingElementPropertySymbol; + } + + // Unwrap symbols to get to the root (e.g. transient symbols as a result of widening) + // Or a union property, use its underlying unioned symbols + return forEach(typeChecker.getRootSymbols(referenceSymbol), rootSymbol => { + // if it is in the list, then we are done + if (contains(searchSymbols, rootSymbol)) { + return rootSymbol; + } + + // Finally, try all properties with the same name in any type the containing type extended or implemented, and + // see if any is in the list. If we were passed a parent symbol, only include types that are subtypes of the + // parent symbol + if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { + // Parents will only be defined if implementations is true + if (parents) { + if (!forEach(parents, parent => explicitlyInheritsFrom(rootSymbol.parent, parent, cache, typeChecker))) { + return undefined; } } - while (meaning !== lastIterationMeaning); + + const result: Symbol[] = []; + getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, /*previousIterationSymbolsCache*/ createMap(), typeChecker); + return find(result, symbol => contains(searchSymbols, symbol)); } - return meaning; + + return undefined; + }); + } + + function getNameFromObjectLiteralElement(node: ObjectLiteralElement) { + if (node.name.kind === SyntaxKind.ComputedPropertyName) { + const nameExpression = (node.name).expression; + // treat computed property names where expression is string/numeric literal as just string/numeric literal + if (isStringOrNumericLiteral(nameExpression)) { + return (nameExpression).text; + } + return undefined; } + return (node.name).text; + } + + /** Gets all symbols for one property. Does not get symbols for every property. */ + function getPropertySymbolsFromContextualType(node: ObjectLiteralElement, typeChecker: TypeChecker): Symbol[] | undefined { + const objectLiteral = node.parent; + const contextualType = typeChecker.getContextualType(objectLiteral); + const name = getNameFromObjectLiteralElement(node); + if (name && contextualType) { + const result: Symbol[] = []; + const symbol = contextualType.getProperty(name); + if (symbol) { + result.push(symbol); + } + + if (contextualType.flags & TypeFlags.Union) { + forEach((contextualType).types, t => { + const symbol = t.getProperty(name); + if (symbol) { + result.push(symbol); + } + }); + } + return result; + } + return undefined; + } + + /** + * Given an initial searchMeaning, extracted from a location, widen the search scope based on the declarations + * of the corresponding symbol. e.g. if we are searching for "Foo" in value position, but "Foo" references a class + * then we need to widen the search to include type positions as well. + * On the contrary, if we are searching for "Bar" in type position and we trace bar to an interface, and an uninstantiated + * module, we want to keep the search limited to only types, as the two declarations (interface and uninstantiated module) + * do not intersect in any of the three spaces. + */ + function getIntersectingMeaningFromDeclarations(meaning: SemanticMeaning, declarations: Declaration[]): SemanticMeaning { + if (declarations) { + let lastIterationMeaning: SemanticMeaning; + do { + // The result is order-sensitive, for instance if initialMeaning === Namespace, and declarations = [class, instantiated module] + // we need to consider both as they initialMeaning intersects with the module in the namespace space, and the module + // intersects with the class in the value space. + // To achieve that we will keep iterating until the result stabilizes. + + // Remember the last meaning + lastIterationMeaning = meaning; + + for (const declaration of declarations) { + const declarationMeaning = getMeaningFromDeclaration(declaration); + + if (declarationMeaning & meaning) { + meaning |= declarationMeaning; + } + } + } + while (meaning !== lastIterationMeaning); + } + return meaning; } export function convertReferences(referenceSymbols: ReferencedSymbol[]): ReferenceEntry[] { @@ -1401,4 +1465,8 @@ namespace ts.FindAllReferences { return false; } + + function isImportDefaultSymbol(symbol: Symbol): boolean { + return symbol.declarations[0].kind === SyntaxKind.ImportClause; + } } diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index b9cf85b5b60..b182b8e01f3 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -4,7 +4,7 @@ namespace ts.formatting { export class Rules { public getRuleName(rule: Rule) { - const o: ts.Map = this; + const o: ts.MapLike = this; for (const name in o) { if (o[name] === rule) { return name; diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 65421888061..73cf06d31ef 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -14,7 +14,7 @@ namespace ts.GoToDefinition { // Type reference directives const typeReferenceDirective = findReferenceInPosition(sourceFile.typeReferenceDirectives, position); if (typeReferenceDirective) { - const referenceFile = program.getResolvedTypeReferenceDirectives()[typeReferenceDirective.fileName]; + const referenceFile = program.getResolvedTypeReferenceDirectives().get(typeReferenceDirective.fileName); return referenceFile && referenceFile.resolvedFileName && [getDefinitionInfoForFileReference(typeReferenceDirective.fileName, referenceFile.resolvedFileName)]; } @@ -187,7 +187,15 @@ namespace ts.GoToDefinition { } function isSignatureDeclaration(node: Node): boolean { - return node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature + switch (node.kind) { + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + return true; + default: + return false; + } } /** Creates a DefinitionInfo from a Declaration, using the declaration's name if possible. */ @@ -254,6 +262,11 @@ namespace ts.GoToDefinition { function tryGetSignatureDeclaration(typeChecker: TypeChecker, node: Node): SignatureDeclaration | undefined { const callLike = getAncestorCallLikeExpression(node); - return callLike && typeChecker.getResolvedSignature(callLike).declaration; + const decl = callLike && typeChecker.getResolvedSignature(callLike).declaration; + if (decl && isSignatureDeclaration(decl)) { + return decl; + } + // Don't go to a function type, go to the value having that type. + return undefined; } } diff --git a/src/services/goToImplementation.ts b/src/services/goToImplementation.ts index 123d29630ad..9135e1fe0f0 100644 --- a/src/services/goToImplementation.ts +++ b/src/services/goToImplementation.ts @@ -17,7 +17,7 @@ namespace ts.GoToImplementation { else { // Perform "Find all References" and retrieve only those that are implementations const referencedSymbols = FindAllReferences.getReferencedSymbolsForNode(typeChecker, cancellationToken, - node, sourceFiles, /*findInStrings*/false, /*findInComments*/false, /*implementations*/true); + node, sourceFiles, /*findInStrings*/false, /*findInComments*/false, /*isForRename*/false, /*implementations*/true); const result = flatMap(referencedSymbols, symbol => map(symbol.references, ({ textSpan, fileName }) => ({ textSpan, fileName }))); diff --git a/src/services/jsTyping.ts b/src/services/jsTyping.ts index 04ac60c4e74..248ceef1bd3 100644 --- a/src/services/jsTyping.ts +++ b/src/services/jsTyping.ts @@ -17,11 +17,11 @@ namespace ts.JsTyping { interface PackageJson { _requiredBy?: string[]; - dependencies?: Map; - devDependencies?: Map; + dependencies?: MapLike; + devDependencies?: MapLike; name?: string; - optionalDependencies?: Map; - peerDependencies?: Map; + optionalDependencies?: MapLike; + peerDependencies?: MapLike; typings?: string; }; @@ -76,7 +76,7 @@ namespace ts.JsTyping { if (!safeList) { const result = readConfigFile(safeListPath, (path: string) => host.readFile(path)); - safeList = result.config ? createMap(result.config) : EmptySafeList; + safeList = result.config ? createMapFromTemplate(result.config) : EmptySafeList; } const filesToWatch: string[] = []; @@ -107,34 +107,34 @@ namespace ts.JsTyping { // add typings for unresolved imports if (unresolvedImports) { for (const moduleId of unresolvedImports) { - const typingName = moduleId in nodeCoreModules ? "node" : moduleId; - if (!(typingName in inferredTypings)) { - inferredTypings[typingName] = undefined; + const typingName = nodeCoreModules.has(moduleId) ? "node" : moduleId; + if (!inferredTypings.has(typingName)) { + inferredTypings.set(typingName, undefined); } } } // Add the cached typing locations for inferred typings that are already installed - for (const name in packageNameToTypingLocation) { - if (name in inferredTypings && !inferredTypings[name]) { - inferredTypings[name] = packageNameToTypingLocation[name]; + packageNameToTypingLocation.forEach((typingLocation, name) => { + if (inferredTypings.has(name) && inferredTypings.get(name) === undefined) { + inferredTypings.set(name, typingLocation); } - } + }); // Remove typings that the user has added to the exclude list for (const excludeTypingName of exclude) { - delete inferredTypings[excludeTypingName]; + inferredTypings.delete(excludeTypingName); } const newTypingNames: string[] = []; const cachedTypingPaths: string[] = []; - for (const typing in inferredTypings) { - if (inferredTypings[typing] !== undefined) { - cachedTypingPaths.push(inferredTypings[typing]); + inferredTypings.forEach((inferred, typing) => { + if (inferred !== undefined) { + cachedTypingPaths.push(inferred); } else { newTypingNames.push(typing); } - } + }); return { cachedTypingPaths, newTypingNames, filesToWatch }; /** @@ -146,8 +146,8 @@ namespace ts.JsTyping { } for (const typing of typingNames) { - if (!(typing in inferredTypings)) { - inferredTypings[typing] = undefined; + if (!inferredTypings.has(typing)) { + inferredTypings.set(typing, undefined); } } } @@ -189,7 +189,7 @@ namespace ts.JsTyping { const cleanedTypingNames = map(inferredTypingNames, f => f.replace(/((?:\.|-)min(?=\.|$))|((?:-|\.)\d+)/g, "")); if (safeList !== EmptySafeList) { - mergeTypings(filter(cleanedTypingNames, f => f in safeList)); + mergeTypings(filter(cleanedTypingNames, f => safeList.has(f))); } const hasJsxFile = forEach(fileNames, f => ensureScriptKind(f, getScriptKindFromFileName(f)) === ScriptKind.JSX); @@ -236,7 +236,7 @@ namespace ts.JsTyping { } if (packageJson.typings) { const absolutePath = getNormalizedAbsolutePath(packageJson.typings, getDirectoryPath(normalizedFileName)); - inferredTypings[packageJson.name] = absolutePath; + inferredTypings.set(packageJson.name, absolutePath); } else { typingNames.push(packageJson.name); diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index 7dab7b504cd..05ccbcc71f4 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -1,4 +1,4 @@ -/* @internal */ +/* @internal */ namespace ts.NavigateTo { type RawNavigateToItem = { name: string; fileName: string; matchKind: PatternMatchKind; isCaseSensitive: boolean; declaration: Declaration }; @@ -7,23 +7,21 @@ namespace ts.NavigateTo { let rawItems: RawNavigateToItem[] = []; // Search the declarations in all files and output matched NavigateToItem into array of NavigateToItem[] - forEach(sourceFiles, sourceFile => { + for (const sourceFile of sourceFiles) { cancellationToken.throwIfCancellationRequested(); if (excludeDtsFiles && fileExtensionIs(sourceFile.fileName, ".d.ts")) { - return; + continue; } - const nameToDeclarations = sourceFile.getNamedDeclarations(); - for (const name in nameToDeclarations) { - const declarations = nameToDeclarations[name]; + forEachEntry(sourceFile.getNamedDeclarations(), (declarations, name) => { if (declarations) { // First do a quick check to see if the name of the declaration matches the // last portion of the (possibly) dotted name they're searching for. let matches = patternMatcher.getMatchesForLastSegmentOfPattern(name); if (!matches) { - continue; + return; // continue to next named declarations } for (const declaration of declarations) { @@ -32,13 +30,13 @@ namespace ts.NavigateTo { if (patternMatcher.patternContainsDots) { const containers = getContainers(declaration); if (!containers) { - return undefined; + return true; // Break out of named declarations and go to the next source file. } matches = patternMatcher.getMatches(containers, name); if (!matches) { - continue; + return; // continue to next named declarations } } @@ -47,8 +45,8 @@ namespace ts.NavigateTo { rawItems.push({ name, fileName, matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration }); } } - } - }); + }); + } // Remove imports when the imported declaration is already in the list and has the same name. rawItems = filter(rawItems, item => { diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 9735ce4528b..25059d1f57d 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -248,9 +248,9 @@ namespace ts.NavigationBar { return true; } - const itemsWithSameName = nameToItems[name]; + const itemsWithSameName = nameToItems.get(name); if (!itemsWithSameName) { - nameToItems[name] = child; + nameToItems.set(name, child); return true; } @@ -268,7 +268,7 @@ namespace ts.NavigationBar { if (tryMerge(itemWithSameName, child)) { return false; } - nameToItems[name] = [itemWithSameName, child]; + nameToItems.set(name, [itemWithSameName, child]); return true; } @@ -322,7 +322,7 @@ namespace ts.NavigationBar { function compareChildren(child1: NavigationBarNode, child2: NavigationBarNode): number { const name1 = tryGetName(child1.node), name2 = tryGetName(child2.node); if (name1 && name2) { - const cmp = localeCompareFix(name1, name2); + const cmp = ts.compareStringsCaseInsensitive(name1, name2); return cmp !== 0 ? cmp : navigationBarNodeKind(child1) - navigationBarNodeKind(child2); } else { @@ -330,26 +330,6 @@ namespace ts.NavigationBar { } } - // Intl is missing in Safari, and node 0.10 treats "a" as greater than "B". - const localeCompareIsCorrect = ts.collator && ts.collator.compare("a", "B") < 0; - const localeCompareFix: (a: string, b: string) => number = localeCompareIsCorrect ? collator.compare : function(a, b) { - // This isn't perfect, but it passes all of our tests. - for (let i = 0; i < Math.min(a.length, b.length); i++) { - const chA = a.charAt(i), chB = b.charAt(i); - if (chA === "\"" && chB === "'") { - return 1; - } - if (chA === "'" && chB === "\"") { - return -1; - } - const cmp = ts.compareStrings(chA.toLocaleLowerCase(), chB.toLocaleLowerCase()); - if (cmp !== 0) { - return cmp; - } - } - return a.length - b.length; - }; - /** * This differs from getItemName because this is just used for sorting. * We only sort nodes by name that have a more-or-less "direct" name, as opposed to `new()` and the like. diff --git a/src/services/patternMatcher.ts b/src/services/patternMatcher.ts index ad638099695..396e53810ce 100644 --- a/src/services/patternMatcher.ts +++ b/src/services/patternMatcher.ts @@ -188,11 +188,11 @@ namespace ts { } function getWordSpans(word: string): TextSpan[] { - if (!(word in stringToWordSpans)) { - stringToWordSpans[word] = breakIntoWordSpans(word); + let spans = stringToWordSpans.get(word); + if (!spans) { + stringToWordSpans.set(word, spans = breakIntoWordSpans(word)); } - - return stringToWordSpans[word]; + return spans; } function matchTextChunk(candidate: string, chunk: TextChunk, punctuationStripped: boolean): PatternMatch { diff --git a/src/services/rename.ts b/src/services/rename.ts index 6f28e505f79..2e9396888ef 100644 --- a/src/services/rename.ts +++ b/src/services/rename.ts @@ -1,98 +1,92 @@ /* @internal */ namespace ts.Rename { export function getRenameInfo(typeChecker: TypeChecker, defaultLibFileName: string, getCanonicalFileName: (fileName: string) => string, sourceFile: SourceFile, position: number): RenameInfo { - const canonicalDefaultLibName = getCanonicalFileName(ts.normalizePath(defaultLibFileName)); - + const getCanonicalDefaultLibName = memoize(() => getCanonicalFileName(ts.normalizePath(defaultLibFileName))); const node = getTouchingWord(sourceFile, position, /*includeJsDocComment*/ true); - - if (node) { - if (node.kind === SyntaxKind.Identifier || - node.kind === SyntaxKind.StringLiteral || - isLiteralNameOfPropertyDeclarationOrIndexAccess(node) || - isThis(node)) { - const symbol = typeChecker.getSymbolAtLocation(node); - - // Only allow a symbol to be renamed if it actually has at least one declaration. - if (symbol) { - const declarations = symbol.getDeclarations(); - if (declarations && declarations.length > 0) { - // Disallow rename for elements that are defined in the standard TypeScript library. - if (forEach(declarations, isDefinedInLibraryFile)) { - return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library)); - } - - const displayName = stripQuotes(getDeclaredName(typeChecker, symbol, node)); - const kind = SymbolDisplay.getSymbolKind(typeChecker, symbol, node); - if (kind) { - return { - canRename: true, - kind, - displayName, - localizedErrorMessage: undefined, - fullDisplayName: typeChecker.getFullyQualifiedName(symbol), - kindModifiers: SymbolDisplay.getSymbolModifiers(symbol), - triggerSpan: createTriggerSpanForNode(node, sourceFile) - }; - } - } - } - else if (node.kind === SyntaxKind.StringLiteral) { - const type = getStringLiteralTypeForNode(node, typeChecker); - if (type) { - if (isDefinedInLibraryFile(node)) { - return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library)); - } - else { - const displayName = stripQuotes(type.text); - return { - canRename: true, - kind: ScriptElementKind.variableElement, - displayName, - localizedErrorMessage: undefined, - fullDisplayName: displayName, - kindModifiers: ScriptElementKindModifier.none, - triggerSpan: createTriggerSpanForNode(node, sourceFile) - }; - } - } - } - } - } - - return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_this_element)); - - function getRenameInfoError(localizedErrorMessage: string): RenameInfo { - return { - canRename: false, - localizedErrorMessage: localizedErrorMessage, - displayName: undefined, - fullDisplayName: undefined, - kind: undefined, - kindModifiers: undefined, - triggerSpan: undefined - }; - } + const renameInfo = node && nodeIsEligibleForRename(node) + ? getRenameInfoForNode(node, typeChecker, sourceFile, isDefinedInLibraryFile) + : undefined; + return renameInfo || getRenameInfoError(Diagnostics.You_cannot_rename_this_element); function isDefinedInLibraryFile(declaration: Node) { - if (defaultLibFileName) { - const sourceFile = declaration.getSourceFile(); - const canonicalName = getCanonicalFileName(ts.normalizePath(sourceFile.fileName)); - if (canonicalName === canonicalDefaultLibName) { - return true; - } + if (!defaultLibFileName) { + return false; } - return false; - } - function createTriggerSpanForNode(node: Node, sourceFile: SourceFile) { - let start = node.getStart(sourceFile); - let width = node.getWidth(sourceFile); - if (node.kind === SyntaxKind.StringLiteral) { - // Exclude the quotes - start += 1; - width -= 2; - } - return createTextSpan(start, width); + const sourceFile = declaration.getSourceFile(); + const canonicalName = getCanonicalFileName(ts.normalizePath(sourceFile.fileName)); + return canonicalName === getCanonicalDefaultLibName(); } } + + function getRenameInfoForNode(node: Node, typeChecker: TypeChecker, sourceFile: SourceFile, isDefinedInLibraryFile: (declaration: Node) => boolean): RenameInfo | undefined { + const symbol = typeChecker.getSymbolAtLocation(node); + + // Only allow a symbol to be renamed if it actually has at least one declaration. + if (symbol) { + const declarations = symbol.getDeclarations(); + if (declarations && declarations.length > 0) { + // Disallow rename for elements that are defined in the standard TypeScript library. + if (some(declarations, isDefinedInLibraryFile)) { + return getRenameInfoError(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library); + } + + const displayName = stripQuotes(getDeclaredName(typeChecker, symbol, node)); + const kind = SymbolDisplay.getSymbolKind(typeChecker, symbol, node); + return kind ? getRenameInfoSuccess(displayName, typeChecker.getFullyQualifiedName(symbol), kind, SymbolDisplay.getSymbolModifiers(symbol), node, sourceFile) : undefined; + } + } + else if (node.kind === SyntaxKind.StringLiteral) { + const type = getStringLiteralTypeForNode(node, typeChecker); + if (type) { + if (isDefinedInLibraryFile(node)) { + return getRenameInfoError(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library); + } + + const displayName = stripQuotes(type.text); + return getRenameInfoSuccess(displayName, displayName, ScriptElementKind.variableElement, ScriptElementKindModifier.none, node, sourceFile); + } + } + } + + function getRenameInfoSuccess(displayName: string, fullDisplayName: string, kind: string, kindModifiers: string, node: Node, sourceFile: SourceFile): RenameInfo { + return { + canRename: true, + kind, + displayName, + localizedErrorMessage: undefined, + fullDisplayName, + kindModifiers, + triggerSpan: createTriggerSpanForNode(node, sourceFile) + }; + } + + function getRenameInfoError(diagnostic: DiagnosticMessage): RenameInfo { + return { + canRename: false, + localizedErrorMessage: getLocaleSpecificMessage(diagnostic), + displayName: undefined, + fullDisplayName: undefined, + kind: undefined, + kindModifiers: undefined, + triggerSpan: undefined + }; + } + + function createTriggerSpanForNode(node: Node, sourceFile: SourceFile) { + let start = node.getStart(sourceFile); + let width = node.getWidth(sourceFile); + if (node.kind === SyntaxKind.StringLiteral) { + // Exclude the quotes + start += 1; + width -= 2; + } + return createTextSpan(start, width); + } + + function nodeIsEligibleForRename(node: Node) { + return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.StringLiteral || + isLiteralNameOfPropertyDeclarationOrIndexAccess(node) || + isThis(node); + } } diff --git a/src/services/services.ts b/src/services/services.ts index fac7715033b..b3e3093cddb 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -193,9 +193,10 @@ namespace ts { return undefined; } - const child = children[0]; - - return child.kind < SyntaxKind.FirstNode ? child : child.getFirstToken(sourceFile); + const child = ts.find(children, kid => kid.kind < SyntaxKind.FirstJSDocNode || kid.kind > SyntaxKind.LastJSDocNode); + return child.kind < SyntaxKind.FirstNode ? + child : + child.getFirstToken(sourceFile); } public getLastToken(sourceFile?: SourceFile): Node { @@ -379,7 +380,7 @@ namespace ts { getNumberIndexType(): Type { return this.checker.getIndexTypeOfType(this, IndexKind.Number); } - getBaseTypes(): ObjectType[] { + getBaseTypes(): BaseType[] { return this.flags & TypeFlags.Object && this.objectFlags & (ObjectFlags.Class | ObjectFlags.Interface) ? this.checker.getBaseTypes(this) : undefined; @@ -518,7 +519,7 @@ namespace ts { } private computeNamedDeclarations(): Map { - const result = createMap(); + const result = createMultiMap(); forEachChild(this, visit); @@ -527,12 +528,16 @@ namespace ts { function addDeclaration(declaration: Declaration) { const name = getDeclarationName(declaration); if (name) { - multiMapAdd(result, name, declaration); + result.add(name, declaration); } } function getDeclarations(name: string) { - return result[name] || (result[name] = []); + let declarations = result.get(name); + if (!declarations) { + result.set(name, declarations = []); + } + return declarations; } function getDeclarationName(declaration: Declaration) { @@ -1399,25 +1404,25 @@ namespace ts { } function findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[] { - const referencedSymbols = findReferencedSymbols(fileName, position, findInStrings, findInComments); + const referencedSymbols = findReferencedSymbols(fileName, position, findInStrings, findInComments, /*isForRename*/true); return FindAllReferences.convertReferences(referencedSymbols); } function getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[] { - const referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false); + const referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false, /*isForRename*/false); return FindAllReferences.convertReferences(referencedSymbols); } function findReferences(fileName: string, position: number): ReferencedSymbol[] { - const referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false); + const referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false, /*isForRename*/false); // Only include referenced symbols that have a valid definition. return filter(referencedSymbols, rs => !!rs.definition); } - function findReferencedSymbols(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): ReferencedSymbol[] { + function findReferencedSymbols(fileName: string, position: number, findInStrings: boolean, findInComments: boolean, isForRename: boolean): ReferencedSymbol[] { synchronizeHostData(); - return FindAllReferences.findReferencedSymbols(program.getTypeChecker(), cancellationToken, program.getSourceFiles(), getValidSourceFile(fileName), position, findInStrings, findInComments); + return FindAllReferences.findReferencedSymbols(program.getTypeChecker(), cancellationToken, program.getSourceFiles(), getValidSourceFile(fileName), position, findInStrings, findInComments, isForRename); } /// NavigateTo @@ -1956,7 +1961,7 @@ namespace ts { function walk(node: Node) { switch (node.kind) { case SyntaxKind.Identifier: - nameTable[(node).text] = nameTable[(node).text] === undefined ? node.pos : -1; + setNameTable((node).text, node); break; case SyntaxKind.StringLiteral: case SyntaxKind.NumericLiteral: @@ -1968,8 +1973,7 @@ namespace ts { node.parent.kind === SyntaxKind.ExternalModuleReference || isArgumentOfElementAccessExpression(node) || isLiteralComputedPropertyDeclarationName(node)) { - - nameTable[(node).text] = nameTable[(node).text] === undefined ? node.pos : -1; + setNameTable((node).text, node); } break; default: @@ -1981,6 +1985,10 @@ namespace ts { } } } + + function setNameTable(text: string, node: ts.Node): void { + nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1); + } } function isArgumentOfElementAccessExpression(node: Node) { diff --git a/src/services/shims.ts b/src/services/shims.ts index cf6bceb816c..487947ee458 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -385,7 +385,10 @@ namespace ts { if (settingsJson == null || settingsJson == "") { throw Error("LanguageServiceShimHostAdapter.getCompilationSettings: empty compilationSettings"); } - return JSON.parse(settingsJson); + const compilerOptions = JSON.parse(settingsJson); + // permit language service to handle all files (filtering should be performed on the host side) + compilerOptions.allowNonTsExtensions = true; + return compilerOptions; } public getScriptFileNames(): string[] { @@ -1061,12 +1064,6 @@ namespace ts { const compilerOptions = JSON.parse(compilerOptionsJson); const result = resolveModuleName(moduleName, normalizeSlashes(fileName), compilerOptions, this.host); const resolvedFileName = result.resolvedModule ? result.resolvedModule.resolvedFileName : undefined; - if (resolvedFileName && !compilerOptions.allowJs && fileExtensionIs(resolvedFileName, ".js")) { - return { - resolvedFileName: undefined, - failedLookupLocations: [] - }; - } return { resolvedFileName, failedLookupLocations: result.failedLookupLocations diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 9e4d906d300..a78370dba72 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -237,7 +237,7 @@ namespace ts.SignatureHelp { const typeChecker = program.getTypeChecker(); for (const sourceFile of program.getSourceFiles()) { const nameToDeclarations = sourceFile.getNamedDeclarations(); - const declarations = nameToDeclarations[name.text]; + const declarations = nameToDeclarations.get(name.text); if (declarations) { for (const declaration of declarations) { diff --git a/src/services/transpile.ts b/src/services/transpile.ts index da54faed1a2..0b90e9d030b 100644 --- a/src/services/transpile.ts +++ b/src/services/transpile.ts @@ -1,4 +1,4 @@ -namespace ts { +namespace ts { export interface TranspileOptions { compilerOptions?: CompilerOptions; fileName?: string; @@ -63,7 +63,7 @@ namespace ts { } if (transpileOptions.renamedDependencies) { - sourceFile.renamedDependencies = createMap(transpileOptions.renamedDependencies); + sourceFile.renamedDependencies = createMapFromTemplate(transpileOptions.renamedDependencies); } const newLine = getNewLineCharacter(options); @@ -126,7 +126,7 @@ namespace ts { function fixupCompilerOptions(options: CompilerOptions, diagnostics: Diagnostic[]): CompilerOptions { // Lazily create this value to fix module loading errors. commandLineOptionsStringToEnum = commandLineOptionsStringToEnum || filter(optionDeclarations, o => - typeof o.type === "object" && !forEachProperty(o.type, v => typeof v !== "number")); + typeof o.type === "object" && !forEachEntry(o.type, v => typeof v !== "number")); options = clone(options); @@ -142,7 +142,7 @@ namespace ts { options[opt.name] = parseCustomTypeOption(opt, value, diagnostics); } else { - if (!forEachProperty(opt.type, v => v === value)) { + if (!forEachEntry(opt.type, v => v === value)) { // Supplied value isn't a valid enum value. diagnostics.push(createCompilerDiagnosticForInvalidCustomType(opt)); } diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index 13686d232a1..b4e8289f367 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -3,8 +3,7 @@ "compilerOptions": { "removeComments": false, "outFile": "../../built/local/typescriptServices.js", - "declaration": true, - "types": [] + "declaration": true }, "files": [ "../compiler/core.ts", @@ -84,6 +83,7 @@ "codefixes/fixClassDoesntImplementInheritedAbstractMember.ts", "codefixes/fixClassSuperMustPrecedeThisAccess.ts", "codefixes/fixConstructorForDerivedNeedSuperCall.ts", + "codefixes/fixForgottenThisPropertyAccess.ts", "codefixes/fixes.ts", "codefixes/helpers.ts", "codefixes/importFixes.ts", diff --git a/src/services/types.ts b/src/services/types.ts index 88ffe2950ce..b4210538518 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -33,7 +33,7 @@ namespace ts { getConstructSignatures(): Signature[]; getStringIndexType(): Type; getNumberIndexType(): Type; - getBaseTypes(): ObjectType[]; + getBaseTypes(): BaseType[]; getNonNullableType(): Type; } @@ -495,7 +495,7 @@ namespace ts { export interface SymbolDisplayPart { text: string; - kind: string; + kind: string; // A ScriptElementKind } export interface QuickInfo { diff --git a/src/services/utilities.ts b/src/services/utilities.ts index def7ab8e4bd..f83f9ef8231 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1,4 +1,4 @@ -// These utilities are common to multiple language service features. +// These utilities are common to multiple language service features. /* @internal */ namespace ts { export const scanner: Scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true); @@ -71,7 +71,10 @@ namespace ts { } export function getMeaningFromLocation(node: Node): SemanticMeaning { - if (node.parent.kind === SyntaxKind.ExportAssignment) { + if (node.kind === SyntaxKind.SourceFile) { + return SemanticMeaning.Value; + } + else if (node.parent.kind === SyntaxKind.ExportAssignment) { return SemanticMeaning.Value | SemanticMeaning.Type | SemanticMeaning.Namespace; } else if (isInRightSideOfImport(node)) { @@ -1116,6 +1119,22 @@ namespace ts { export function createTextSpanFromNode(node: Node, sourceFile?: SourceFile): TextSpan { return createTextSpanFromBounds(node.getStart(sourceFile), node.getEnd()); } + + export function isTypeKeyword(kind: SyntaxKind): boolean { + switch (kind) { + case SyntaxKind.AnyKeyword: + case SyntaxKind.BooleanKeyword: + case SyntaxKind.NeverKeyword: + case SyntaxKind.NumberKeyword: + case SyntaxKind.ObjectKeyword: + case SyntaxKind.StringKeyword: + case SyntaxKind.SymbolKeyword: + case SyntaxKind.VoidKeyword: + return true; + default: + return false; + } + } } // Display-part writer helpers @@ -1300,7 +1319,7 @@ namespace ts { return name; } - export function isImportOrExportSpecifierName(location: Node): boolean { + export function isImportOrExportSpecifierName(location: Node): location is Identifier { return location.parent && (location.parent.kind === SyntaxKind.ImportSpecifier || location.parent.kind === SyntaxKind.ExportSpecifier) && (location.parent).propertyName === location; diff --git a/src/tsconfig-base.json b/src/tsconfig-base.json index b4c82dbeeee..078fdcc91e7 100644 --- a/src/tsconfig-base.json +++ b/src/tsconfig-base.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "lib": ["es5", "scripthost"], "noEmitOnError": true, "noImplicitAny": true, "noImplicitThis": true, @@ -9,6 +10,7 @@ "preserveConstEnums": true, "stripInternal": true, "sourceMap": true, - "target": "es5" + "target": "es5", + "types": [] } } \ No newline at end of file diff --git a/tests/baselines/reference/additionOperatorWithNullValueAndInvalidOperator.errors.txt b/tests/baselines/reference/additionOperatorWithNullValueAndInvalidOperator.errors.txt index d18a9a13d8c..5f0d78c59d5 100644 --- a/tests/baselines/reference/additionOperatorWithNullValueAndInvalidOperator.errors.txt +++ b/tests/baselines/reference/additionOperatorWithNullValueAndInvalidOperator.errors.txt @@ -1,14 +1,14 @@ -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(11,10): error TS2365: Operator '+' cannot be applied to types 'boolean' and 'boolean'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(12,10): error TS2365: Operator '+' cannot be applied to types 'Object' and 'Object'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(13,10): error TS2365: Operator '+' cannot be applied to types 'void' and 'void'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(14,10): error TS2365: Operator '+' cannot be applied to types 'boolean' and 'boolean'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(15,10): error TS2365: Operator '+' cannot be applied to types 'Object' and 'Object'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(16,10): error TS2365: Operator '+' cannot be applied to types 'void' and 'void'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(19,10): error TS2365: Operator '+' cannot be applied to types 'Number' and 'Number'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(20,10): error TS2365: Operator '+' cannot be applied to types 'true' and 'true'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(21,10): error TS2365: Operator '+' cannot be applied to types '{ a: string; }' and '{ a: string; }'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(22,11): error TS2365: Operator '+' cannot be applied to types 'void' and 'void'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(23,11): error TS2365: Operator '+' cannot be applied to types '() => void' and '() => void'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(11,10): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(12,10): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(13,10): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(14,14): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(15,14): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(16,10): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(19,10): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(20,10): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(21,10): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(22,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(23,11): error TS2531: Object is possibly 'null'. ==== tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts (11 errors) ==== @@ -23,37 +23,37 @@ tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOpe // null + boolean/Object var r1 = null + a; - ~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'boolean' and 'boolean'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var r2 = null + b; - ~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'Object' and 'Object'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var r3 = null + c; - ~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'void' and 'void'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var r4 = a + null; - ~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'boolean' and 'boolean'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var r5 = b + null; - ~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'Object' and 'Object'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var r6 = null + c; - ~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'void' and 'void'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. // other cases var r7 = null + d; - ~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'Number' and 'Number'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var r8 = null + true; - ~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'true' and 'true'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var r9 = null + { a: '' }; - ~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types '{ a: string; }' and '{ a: string; }'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var r10 = null + foo(); - ~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'void' and 'void'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var r11 = null + (() => { }); - ~~~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types '() => void' and '() => void'. \ No newline at end of file + ~~~~ +!!! error TS2531: Object is possibly 'null'. \ No newline at end of file diff --git a/tests/baselines/reference/additionOperatorWithNullValueAndValidOperator.errors.txt b/tests/baselines/reference/additionOperatorWithNullValueAndValidOperator.errors.txt new file mode 100644 index 00000000000..db01a42c8bd --- /dev/null +++ b/tests/baselines/reference/additionOperatorWithNullValueAndValidOperator.errors.txt @@ -0,0 +1,63 @@ +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndValidOperator.ts(15,10): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndValidOperator.ts(16,10): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndValidOperator.ts(17,10): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndValidOperator.ts(18,10): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndValidOperator.ts(19,10): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndValidOperator.ts(20,14): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndValidOperator.ts(21,14): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndValidOperator.ts(22,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndValidOperator.ts(23,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndValidOperator.ts(24,20): error TS2531: Object is possibly 'null'. + + +==== tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndValidOperator.ts (10 errors) ==== + // If one operand is the null or undefined value, it is treated as having the type of the other operand. + + enum E { a, b, c } + + var a: any; + var b: number; + var c: E; + var d: string; + + // null + any + var r1: any = null + a; + var r2: any = a + null; + + // null + number/enum + var r3 = null + b; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r4 = null + 1; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r5 = null + c; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r6 = null + E.a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r7 = null + E['a']; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r8 = b + null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r9 = 1 + null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r10 = c + null + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r11 = E.a + null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r12 = E['a'] + null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + + // null + string + var r13 = null + d; + var r14 = null + ''; + var r15 = d + null; + var r16 = '' + null; \ No newline at end of file diff --git a/tests/baselines/reference/additionOperatorWithOnlyNullValueOrUndefinedValue.errors.txt b/tests/baselines/reference/additionOperatorWithOnlyNullValueOrUndefinedValue.errors.txt index 9e7e4c01ad2..aef66891be0 100644 --- a/tests/baselines/reference/additionOperatorWithOnlyNullValueOrUndefinedValue.errors.txt +++ b/tests/baselines/reference/additionOperatorWithOnlyNullValueOrUndefinedValue.errors.txt @@ -1,20 +1,32 @@ -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithOnlyNullValueOrUndefinedValue.ts(2,10): error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithOnlyNullValueOrUndefinedValue.ts(3,10): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithOnlyNullValueOrUndefinedValue.ts(4,10): error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithOnlyNullValueOrUndefinedValue.ts(5,10): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithOnlyNullValueOrUndefinedValue.ts(2,10): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithOnlyNullValueOrUndefinedValue.ts(2,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithOnlyNullValueOrUndefinedValue.ts(3,10): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithOnlyNullValueOrUndefinedValue.ts(3,17): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithOnlyNullValueOrUndefinedValue.ts(4,10): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithOnlyNullValueOrUndefinedValue.ts(4,22): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithOnlyNullValueOrUndefinedValue.ts(5,10): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithOnlyNullValueOrUndefinedValue.ts(5,22): error TS2532: Object is possibly 'undefined'. -==== tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithOnlyNullValueOrUndefinedValue.ts (4 errors) ==== +==== tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithOnlyNullValueOrUndefinedValue.ts (8 errors) ==== // bug 819721 var r1 = null + null; - ~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var r2 = null + undefined; - ~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var r3 = undefined + null; - ~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var r4 = undefined + undefined; - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. \ No newline at end of file + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. \ No newline at end of file diff --git a/tests/baselines/reference/additionOperatorWithTypeParameter.errors.txt b/tests/baselines/reference/additionOperatorWithTypeParameter.errors.txt index ff7120c145d..478c4fdee3f 100644 --- a/tests/baselines/reference/additionOperatorWithTypeParameter.errors.txt +++ b/tests/baselines/reference/additionOperatorWithTypeParameter.errors.txt @@ -8,8 +8,8 @@ tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOpe tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithTypeParameter.ts(27,15): error TS2365: Operator '+' cannot be applied to types 'Object' and 'T'. tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithTypeParameter.ts(28,15): error TS2365: Operator '+' cannot be applied to types 'E' and 'T'. tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithTypeParameter.ts(29,15): error TS2365: Operator '+' cannot be applied to types 'void' and 'T'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithTypeParameter.ts(32,15): error TS2365: Operator '+' cannot be applied to types 'T' and 'T'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithTypeParameter.ts(33,15): error TS2365: Operator '+' cannot be applied to types 'T' and 'T'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithTypeParameter.ts(32,19): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithTypeParameter.ts(33,19): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithTypeParameter.ts(34,15): error TS2365: Operator '+' cannot be applied to types 'T' and 'T'. tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithTypeParameter.ts(35,15): error TS2365: Operator '+' cannot be applied to types 'T' and 'U'. tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithTypeParameter.ts(36,15): error TS2365: Operator '+' cannot be applied to types 'T' and '() => void'. @@ -69,11 +69,11 @@ tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOpe // other cases var r15 = t + null; - ~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'T' and 'T'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var r16 = t + undefined; - ~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'T' and 'T'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var r17 = t + t; ~~~~~ !!! error TS2365: Operator '+' cannot be applied to types 'T' and 'T'. diff --git a/tests/baselines/reference/additionOperatorWithUndefinedValueAndInvalidOperands.errors.txt b/tests/baselines/reference/additionOperatorWithUndefinedValueAndInvalidOperands.errors.txt index d61f101a544..06e8c67b105 100644 --- a/tests/baselines/reference/additionOperatorWithUndefinedValueAndInvalidOperands.errors.txt +++ b/tests/baselines/reference/additionOperatorWithUndefinedValueAndInvalidOperands.errors.txt @@ -1,14 +1,14 @@ -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(11,10): error TS2365: Operator '+' cannot be applied to types 'boolean' and 'boolean'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(12,10): error TS2365: Operator '+' cannot be applied to types 'Object' and 'Object'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(13,10): error TS2365: Operator '+' cannot be applied to types 'void' and 'void'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(14,10): error TS2365: Operator '+' cannot be applied to types 'boolean' and 'boolean'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(15,10): error TS2365: Operator '+' cannot be applied to types 'Object' and 'Object'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(16,10): error TS2365: Operator '+' cannot be applied to types 'void' and 'void'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(19,10): error TS2365: Operator '+' cannot be applied to types 'Number' and 'Number'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(20,10): error TS2365: Operator '+' cannot be applied to types 'true' and 'true'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(21,10): error TS2365: Operator '+' cannot be applied to types '{ a: string; }' and '{ a: string; }'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(22,11): error TS2365: Operator '+' cannot be applied to types 'void' and 'void'. -tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(23,11): error TS2365: Operator '+' cannot be applied to types '() => void' and '() => void'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(11,10): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(12,10): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(13,10): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(14,14): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(15,14): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(16,10): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(19,10): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(20,10): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(21,10): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(22,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(23,11): error TS2532: Object is possibly 'undefined'. ==== tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts (11 errors) ==== @@ -23,37 +23,37 @@ tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOpe // undefined + boolean/Object var r1 = undefined + a; - ~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'boolean' and 'boolean'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var r2 = undefined + b; - ~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'Object' and 'Object'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var r3 = undefined + c; - ~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'void' and 'void'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var r4 = a + undefined; - ~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'boolean' and 'boolean'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var r5 = b + undefined; - ~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'Object' and 'Object'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var r6 = undefined + c; - ~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'void' and 'void'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. // other cases var r7 = undefined + d; - ~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'Number' and 'Number'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var r8 = undefined + true; - ~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'true' and 'true'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var r9 = undefined + { a: '' }; - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types '{ a: string; }' and '{ a: string; }'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var r10 = undefined + foo(); - ~~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'void' and 'void'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var r11 = undefined + (() => { }); - ~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types '() => void' and '() => void'. \ No newline at end of file + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. \ No newline at end of file diff --git a/tests/baselines/reference/additionOperatorWithUndefinedValueAndValidOperator.errors.txt b/tests/baselines/reference/additionOperatorWithUndefinedValueAndValidOperator.errors.txt new file mode 100644 index 00000000000..04c0e2f3266 --- /dev/null +++ b/tests/baselines/reference/additionOperatorWithUndefinedValueAndValidOperator.errors.txt @@ -0,0 +1,63 @@ +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndValidOperator.ts(15,10): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndValidOperator.ts(16,10): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndValidOperator.ts(17,10): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndValidOperator.ts(18,10): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndValidOperator.ts(19,10): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndValidOperator.ts(20,14): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndValidOperator.ts(21,14): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndValidOperator.ts(22,15): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndValidOperator.ts(23,17): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndValidOperator.ts(24,20): error TS2532: Object is possibly 'undefined'. + + +==== tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndValidOperator.ts (10 errors) ==== + // If one operand is the null or undefined value, it is treated as having the type of the other operand. + + enum E { a, b, c } + + var a: any; + var b: number; + var c: E; + var d: string; + + // undefined + any + var r1: any = undefined + a; + var r2: any = a + undefined; + + // undefined + number/enum + var r3 = undefined + b; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var r4 = undefined + 1; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var r5 = undefined + c; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var r6 = undefined + E.a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var r7 = undefined + E['a']; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var r8 = b + undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var r9 = 1 + undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var r10 = c + undefined + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var r11 = E.a + undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var r12 = E['a'] + undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + // undefined + string + var r13 = undefined + d; + var r14 = undefined + ''; + var r15 = d + undefined; + var r16 = '' + undefined; \ No newline at end of file diff --git a/tests/baselines/reference/ambientWithStatements.errors.txt b/tests/baselines/reference/ambientWithStatements.errors.txt index 6fb6aafd864..3e134970a1f 100644 --- a/tests/baselines/reference/ambientWithStatements.errors.txt +++ b/tests/baselines/reference/ambientWithStatements.errors.txt @@ -1,6 +1,6 @@ tests/cases/compiler/ambientWithStatements.ts(2,5): error TS1036: Statements are not allowed in ambient contexts. tests/cases/compiler/ambientWithStatements.ts(3,5): error TS1104: A 'continue' statement can only be used within an enclosing iteration statement. -tests/cases/compiler/ambientWithStatements.ts(7,15): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter. +tests/cases/compiler/ambientWithStatements.ts(7,15): error TS2531: Object is possibly 'null'. tests/cases/compiler/ambientWithStatements.ts(11,5): error TS1108: A 'return' statement can only be used within a function body. tests/cases/compiler/ambientWithStatements.ts(25,5): error TS2410: The 'with' statement is not supported. All symbols in a 'with' block will have type 'any'. @@ -18,7 +18,7 @@ tests/cases/compiler/ambientWithStatements.ts(25,5): error TS2410: The 'with' st var x; for (x in null) { } ~~~~ -!!! error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter. +!!! error TS2531: Object is possibly 'null'. if (true) { } else { } 1; L: var y; diff --git a/tests/baselines/reference/argumentsAsPropertyName.js b/tests/baselines/reference/argumentsAsPropertyName.js new file mode 100644 index 00000000000..a4197c0a1d2 --- /dev/null +++ b/tests/baselines/reference/argumentsAsPropertyName.js @@ -0,0 +1,29 @@ +//// [argumentsAsPropertyName.ts] +// target: es5 +type MyType = { + arguments: Array +} + +declare function use(s: any); + +function myFunction(myType: MyType) { + for (let i = 0; i < 10; i++) { + use(myType.arguments[i]); + // create closure so that tsc will turn loop body into function + const x = 5; + [1, 2, 3].forEach(function(j) { use(x); }) + } +} + +//// [argumentsAsPropertyName.js] +function myFunction(myType) { + var _loop_1 = function (i) { + use(myType.arguments[i]); + // create closure so that tsc will turn loop body into function + var x = 5; + [1, 2, 3].forEach(function (j) { use(x); }); + }; + for (var i = 0; i < 10; i++) { + _loop_1(i); + } +} diff --git a/tests/baselines/reference/argumentsAsPropertyName.symbols b/tests/baselines/reference/argumentsAsPropertyName.symbols new file mode 100644 index 00000000000..1e3e41abb6e --- /dev/null +++ b/tests/baselines/reference/argumentsAsPropertyName.symbols @@ -0,0 +1,43 @@ +=== tests/cases/compiler/argumentsAsPropertyName.ts === +// target: es5 +type MyType = { +>MyType : Symbol(MyType, Decl(argumentsAsPropertyName.ts, 0, 0)) + + arguments: Array +>arguments : Symbol(arguments, Decl(argumentsAsPropertyName.ts, 1, 15)) +>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +} + +declare function use(s: any); +>use : Symbol(use, Decl(argumentsAsPropertyName.ts, 3, 1)) +>s : Symbol(s, Decl(argumentsAsPropertyName.ts, 5, 21)) + +function myFunction(myType: MyType) { +>myFunction : Symbol(myFunction, Decl(argumentsAsPropertyName.ts, 5, 29)) +>myType : Symbol(myType, Decl(argumentsAsPropertyName.ts, 7, 20)) +>MyType : Symbol(MyType, Decl(argumentsAsPropertyName.ts, 0, 0)) + + for (let i = 0; i < 10; i++) { +>i : Symbol(i, Decl(argumentsAsPropertyName.ts, 8, 12)) +>i : Symbol(i, Decl(argumentsAsPropertyName.ts, 8, 12)) +>i : Symbol(i, Decl(argumentsAsPropertyName.ts, 8, 12)) + + use(myType.arguments[i]); +>use : Symbol(use, Decl(argumentsAsPropertyName.ts, 3, 1)) +>myType.arguments : Symbol(arguments, Decl(argumentsAsPropertyName.ts, 1, 15)) +>myType : Symbol(myType, Decl(argumentsAsPropertyName.ts, 7, 20)) +>arguments : Symbol(arguments, Decl(argumentsAsPropertyName.ts, 1, 15)) +>i : Symbol(i, Decl(argumentsAsPropertyName.ts, 8, 12)) + + // create closure so that tsc will turn loop body into function + const x = 5; +>x : Symbol(x, Decl(argumentsAsPropertyName.ts, 11, 13)) + + [1, 2, 3].forEach(function(j) { use(x); }) +>[1, 2, 3].forEach : Symbol(Array.forEach, Decl(lib.d.ts, --, --)) +>forEach : Symbol(Array.forEach, Decl(lib.d.ts, --, --)) +>j : Symbol(j, Decl(argumentsAsPropertyName.ts, 12, 35)) +>use : Symbol(use, Decl(argumentsAsPropertyName.ts, 3, 1)) +>x : Symbol(x, Decl(argumentsAsPropertyName.ts, 11, 13)) + } +} diff --git a/tests/baselines/reference/argumentsAsPropertyName.types b/tests/baselines/reference/argumentsAsPropertyName.types new file mode 100644 index 00000000000..d0aaaa1cc72 --- /dev/null +++ b/tests/baselines/reference/argumentsAsPropertyName.types @@ -0,0 +1,57 @@ +=== tests/cases/compiler/argumentsAsPropertyName.ts === +// target: es5 +type MyType = { +>MyType : MyType + + arguments: Array +>arguments : string[] +>Array : T[] +} + +declare function use(s: any); +>use : (s: any) => any +>s : any + +function myFunction(myType: MyType) { +>myFunction : (myType: MyType) => void +>myType : MyType +>MyType : MyType + + for (let i = 0; i < 10; i++) { +>i : number +>0 : 0 +>i < 10 : boolean +>i : number +>10 : 10 +>i++ : number +>i : number + + use(myType.arguments[i]); +>use(myType.arguments[i]) : any +>use : (s: any) => any +>myType.arguments[i] : string +>myType.arguments : string[] +>myType : MyType +>arguments : string[] +>i : number + + // create closure so that tsc will turn loop body into function + const x = 5; +>x : 5 +>5 : 5 + + [1, 2, 3].forEach(function(j) { use(x); }) +>[1, 2, 3].forEach(function(j) { use(x); }) : void +>[1, 2, 3].forEach : (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void +>[1, 2, 3] : number[] +>1 : 1 +>2 : 2 +>3 : 3 +>forEach : (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void +>function(j) { use(x); } : (j: number) => void +>j : number +>use(x) : any +>use : (s: any) => any +>x : 5 + } +} diff --git a/tests/baselines/reference/arithmeticOperatorWithNullValueAndInvalidOperands.errors.txt b/tests/baselines/reference/arithmeticOperatorWithNullValueAndInvalidOperands.errors.txt index c043cda8e68..16a0264a805 100644 --- a/tests/baselines/reference/arithmeticOperatorWithNullValueAndInvalidOperands.errors.txt +++ b/tests/baselines/reference/arithmeticOperatorWithNullValueAndInvalidOperands.errors.txt @@ -1,234 +1,246 @@ -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(9,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(9,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(9,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(10,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(10,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(10,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(11,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(11,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(11,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(13,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(13,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(13,16): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(14,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(14,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(14,16): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(15,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(15,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(17,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(15,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(17,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(17,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(18,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(18,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(18,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(19,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(19,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(19,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(21,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(21,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(21,19): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(22,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(22,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(22,17): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(23,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(23,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(26,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(23,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(26,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(26,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(27,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(27,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(27,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(28,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(28,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(28,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(30,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(30,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(30,16): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(31,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(31,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(31,16): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(32,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(32,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(34,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(32,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(34,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(34,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(35,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(35,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(35,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(36,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(36,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(36,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(38,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(38,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(38,19): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(39,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(39,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(39,17): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(40,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(40,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(43,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(40,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(43,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(43,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(44,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(44,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(44,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(45,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(45,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(45,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(47,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(47,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(47,16): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(48,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(48,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(48,16): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(49,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(49,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(51,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(49,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(51,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(51,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(52,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(52,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(52,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(53,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(53,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(53,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(55,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(55,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(55,19): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(56,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(56,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(56,17): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(57,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(57,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(60,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(57,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(60,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(60,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(61,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(61,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(61,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(62,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(62,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(62,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(64,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(64,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(64,16): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(65,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(65,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(65,16): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(66,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(66,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(68,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(66,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(68,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(68,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(69,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(69,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(69,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(70,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(70,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(70,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(72,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(72,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(72,19): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(73,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(73,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(73,17): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(74,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(74,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(77,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(74,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(77,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(77,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(78,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(78,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(78,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(79,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(79,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(79,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(81,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(81,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(81,17): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(82,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(82,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(82,17): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(83,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(83,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(85,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(83,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(85,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(85,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(86,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(86,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(86,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(87,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(87,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(87,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(89,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(89,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(89,20): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(90,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(90,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(90,18): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(91,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(91,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(94,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(91,18): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(94,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(94,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(95,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(95,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(95,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(96,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(96,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(96,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(98,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(98,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(98,17): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(99,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(99,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(99,17): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(100,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(100,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(102,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(100,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(102,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(102,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(103,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(103,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(103,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(104,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(104,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(104,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(106,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(106,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(106,20): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(107,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(107,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(107,18): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(108,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(108,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(111,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(108,18): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(111,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(111,21): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(112,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(112,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(112,21): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(113,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(113,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(113,21): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(115,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(115,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(115,18): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(116,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(116,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(116,18): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(117,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(117,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(119,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(117,18): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(119,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(119,21): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(120,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(120,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(120,21): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(121,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(121,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(121,21): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(123,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(123,21): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(123,21): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(124,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(124,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(124,19): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(125,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(125,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(128,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(129,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(125,19): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(128,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(128,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(129,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(129,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(130,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(130,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(130,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(132,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(132,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(132,16): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(133,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(133,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(133,16): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(134,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(134,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(136,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(137,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(134,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(136,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(136,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(137,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(137,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(138,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(138,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(138,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(140,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(140,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(140,19): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(141,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(141,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(141,17): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(142,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(142,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(145,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(146,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(142,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(145,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(145,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(146,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(146,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(147,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(147,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(147,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(149,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(149,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(149,16): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(150,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(150,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(150,16): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(151,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(151,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(153,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(154,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(151,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(153,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(153,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(154,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(154,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(155,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(155,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(155,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(157,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(157,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(157,19): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(158,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(158,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(158,17): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(159,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(159,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(162,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(163,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(159,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(162,13): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(162,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(163,13): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(163,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(164,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(164,13): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(164,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(166,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(166,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(166,17): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(167,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(167,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(167,17): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(168,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(168,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(170,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(171,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(168,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(170,13): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(170,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(171,13): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(171,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(172,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(172,13): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(172,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(174,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(174,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(174,20): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(175,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(175,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(175,18): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(176,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(176,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(176,18): error TS2531: Object is possibly 'null'. -==== tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts (228 errors) ==== +==== tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts (240 errors) ==== // If one operand is the null or undefined value, it is treated as having the type of the // other operand. @@ -239,17 +251,17 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti // operator * var r1a1 = null * a; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r1a2 = null * b; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r1a3 = null * c; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -257,31 +269,31 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r1b2 = b * null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r1b3 = c * null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r1c1 = null * true; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r1c2 = null * ''; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r1c3 = null * {}; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -289,32 +301,32 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r1d2 = '' * null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r1d3 = {} * null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. // operator / var r2a1 = null / a; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r2a2 = null / b; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r2a3 = null / c; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -322,31 +334,31 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r2b2 = b / null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r2b3 = c / null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r2c1 = null / true; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r2c2 = null / ''; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r2c3 = null / {}; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -354,32 +366,32 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r2d2 = '' / null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r2d3 = {} / null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. // operator % var r3a1 = null % a; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r3a2 = null % b; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r3a3 = null % c; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -387,31 +399,31 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r3b2 = b % null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r3b3 = c % null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r3c1 = null % true; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r3c2 = null % ''; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r3c3 = null % {}; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -419,32 +431,32 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r3d2 = '' % null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r3d3 = {} % null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. // operator - var r4a1 = null - a; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r4a2 = null - b; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r4a3 = null - c; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -452,31 +464,31 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r4b2 = b - null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r4b3 = c - null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r4c1 = null - true; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r4c2 = null - ''; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r4c3 = null - {}; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -484,32 +496,32 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r4d2 = '' - null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r4d3 = {} - null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. // operator << var r5a1 = null << a; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r5a2 = null << b; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r5a3 = null << c; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -517,31 +529,31 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r5b2 = b << null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r5b3 = c << null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r5c1 = null << true; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r5c2 = null << ''; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r5c3 = null << {}; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -549,32 +561,32 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r5d2 = '' << null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r5d3 = {} << null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. // operator >> var r6a1 = null >> a; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r6a2 = null >> b; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r6a3 = null >> c; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -582,31 +594,31 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r6b2 = b >> null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r6b3 = c >> null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r6c1 = null >> true; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r6c2 = null >> ''; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r6c3 = null >> {}; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -614,32 +626,32 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r6d2 = '' >> null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r6d3 = {} >> null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. // operator >>> var r7a1 = null >>> a; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r7a2 = null >>> b; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r7a3 = null >>> c; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -647,31 +659,31 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r7b2 = b >>> null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r7b3 = c >>> null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r7c1 = null >>> true; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r7c2 = null >>> ''; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r7c3 = null >>> {}; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -679,185 +691,209 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r7d2 = '' >>> null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r7d3 = {} >>> null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. // operator & var r8a1 = null & a; - ~~~~~~~~ -!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~ +!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r8a2 = null & b; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r8a3 = null & c; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r8b1 = a & null; - ~~~~~~~~ -!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. + ~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var r8b2 = b & null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r8b3 = c & null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r8c1 = null & true; - ~~~~~~~~~~~ -!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~ +!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r8c2 = null & ''; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r8c3 = null & {}; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r8d1 = true & null; - ~~~~~~~~~~~ -!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. + ~~~~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var r8d2 = '' & null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r8d3 = {} & null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. // operator ^ var r9a1 = null ^ a; - ~~~~~~~~ -!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~ +!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r9a2 = null ^ b; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r9a3 = null ^ c; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r9b1 = a ^ null; - ~~~~~~~~ -!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. + ~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var r9b2 = b ^ null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r9b3 = c ^ null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r9c1 = null ^ true; - ~~~~~~~~~~~ -!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~ +!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r9c2 = null ^ ''; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r9c3 = null ^ {}; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r9d1 = true ^ null; - ~~~~~~~~~~~ -!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. + ~~~~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var r9d2 = '' ^ null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r9d3 = {} ^ null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. // operator | var r10a1 = null | a; - ~~~~~~~~ -!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~ +!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r10a2 = null | b; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r10a3 = null | c; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r10b1 = a | null; - ~~~~~~~~ -!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. + ~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var r10b2 = b | null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r10b3 = c | null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r10c1 = null | true; - ~~~~~~~~~~~ -!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~ +!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r10c2 = null | ''; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r10c3 = null | {}; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r10d1 = true | null; - ~~~~~~~~~~~ -!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. + ~~~~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var r10d2 = '' | null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r10d3 = {} | null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. \ No newline at end of file +!!! error TS2531: Object is possibly 'null'. \ No newline at end of file diff --git a/tests/baselines/reference/arithmeticOperatorWithNullValueAndValidOperands.errors.txt b/tests/baselines/reference/arithmeticOperatorWithNullValueAndValidOperands.errors.txt new file mode 100644 index 00000000000..426db291224 --- /dev/null +++ b/tests/baselines/reference/arithmeticOperatorWithNullValueAndValidOperands.errors.txt @@ -0,0 +1,353 @@ +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(13,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(14,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(15,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(16,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(17,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(18,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(19,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(20,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(23,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(24,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(25,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(26,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(27,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(28,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(29,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(30,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(33,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(34,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(35,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(36,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(37,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(38,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(39,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(40,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(43,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(44,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(45,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(46,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(47,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(48,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(49,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(50,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(53,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(54,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(55,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(56,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(57,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(58,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(59,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(60,18): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(63,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(64,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(65,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(66,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(67,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(68,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(69,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(70,18): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(73,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(74,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(75,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(76,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(77,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(78,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(79,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(80,19): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(83,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(84,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(85,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(86,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(87,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(88,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(89,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(90,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(93,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(94,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(95,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(96,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(97,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(98,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(99,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(100,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(103,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(104,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(105,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(106,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(107,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(108,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(109,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts(110,17): error TS2531: Object is possibly 'null'. + + +==== tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndValidOperands.ts (80 errors) ==== + // If one operand is the null or undefined value, it is treated as having the type of the + // other operand. + + enum E { + a, + b + } + + var a: any; + var b: number; + + // operator * + var ra1 = null * a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var ra2 = null * b; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var ra3 = null * 1; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var ra4 = null * E.a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var ra5 = a * null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var ra6 = b * null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var ra7 = 0 * null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var ra8 = E.b * null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + + // operator / + var rb1 = null / a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rb2 = null / b; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rb3 = null / 1; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rb4 = null / E.a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rb5 = a / null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rb6 = b / null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rb7 = 0 / null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rb8 = E.b / null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + + // operator % + var rc1 = null % a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rc2 = null % b; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rc3 = null % 1; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rc4 = null % E.a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rc5 = a % null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rc6 = b % null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rc7 = 0 % null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rc8 = E.b % null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + + // operator - + var rd1 = null - a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rd2 = null - b; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rd3 = null - 1; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rd4 = null - E.a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rd5 = a - null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rd6 = b - null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rd7 = 0 - null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rd8 = E.b - null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + + // operator << + var re1 = null << a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var re2 = null << b; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var re3 = null << 1; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var re4 = null << E.a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var re5 = a << null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var re6 = b << null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var re7 = 0 << null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var re8 = E.b << null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + + // operator >> + var rf1 = null >> a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rf2 = null >> b; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rf3 = null >> 1; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rf4 = null >> E.a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rf5 = a >> null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rf6 = b >> null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rf7 = 0 >> null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rf8 = E.b >> null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + + // operator >>> + var rg1 = null >>> a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rg2 = null >>> b; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rg3 = null >>> 1; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rg4 = null >>> E.a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rg5 = a >>> null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rg6 = b >>> null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rg7 = 0 >>> null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rg8 = E.b >>> null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + + // operator & + var rh1 = null & a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rh2 = null & b; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rh3 = null & 1; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rh4 = null & E.a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rh5 = a & null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rh6 = b & null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rh7 = 0 & null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rh8 = E.b & null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + + // operator ^ + var ri1 = null ^ a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var ri2 = null ^ b; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var ri3 = null ^ 1; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var ri4 = null ^ E.a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var ri5 = a ^ null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var ri6 = b ^ null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var ri7 = 0 ^ null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var ri8 = E.b ^ null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + + // operator | + var rj1 = null | a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rj2 = null | b; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rj3 = null | 1; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rj4 = null | E.a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rj5 = a | null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rj6 = b | null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rj7 = 0 | null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rj8 = E.b | null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. \ No newline at end of file diff --git a/tests/baselines/reference/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.errors.txt b/tests/baselines/reference/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.errors.txt index d00eee1d4dd..e67db44a780 100644 --- a/tests/baselines/reference/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.errors.txt +++ b/tests/baselines/reference/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.errors.txt @@ -1,302 +1,302 @@ -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(2,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(2,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(3,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(3,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(4,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(4,23): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(5,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(5,23): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(8,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(8,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(9,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(9,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(10,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(10,23): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(11,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(11,23): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(14,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(14,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(15,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(15,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(16,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(16,23): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(17,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(17,23): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(20,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(20,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(21,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(21,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(22,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(22,23): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(23,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(23,23): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(26,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(26,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(27,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(27,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(28,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(28,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(29,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(29,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(32,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(32,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(33,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(33,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(34,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(34,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(35,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(35,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(38,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(38,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(39,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(39,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(40,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(40,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(41,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(41,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(44,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(44,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(45,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(45,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(46,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(46,23): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(47,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(47,23): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(50,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(50,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(51,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(51,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(52,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(52,23): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(53,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(53,23): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(56,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(56,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(57,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(57,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(58,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(58,23): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(59,11): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(59,23): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(2,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(2,18): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(3,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(3,18): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(4,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(4,23): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(5,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(5,23): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(8,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(8,18): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(9,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(9,18): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(10,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(10,23): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(11,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(11,23): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(14,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(14,18): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(15,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(15,18): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(16,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(16,23): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(17,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(17,23): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(20,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(20,18): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(21,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(21,18): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(22,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(22,23): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(23,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(23,23): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(26,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(26,19): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(27,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(27,19): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(28,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(28,24): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(29,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(29,24): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(32,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(32,19): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(33,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(33,19): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(34,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(34,24): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(35,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(35,24): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(38,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(38,20): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(39,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(39,20): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(40,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(40,25): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(41,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(41,25): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(44,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(44,18): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(45,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(45,18): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(46,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(46,23): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(47,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(47,23): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(50,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(50,18): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(51,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(51,18): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(52,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(52,23): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(53,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(53,23): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(56,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(56,18): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(57,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(57,18): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(58,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(58,23): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(59,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts(59,23): error TS2532: Object is possibly 'undefined'. ==== tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithOnlyNullValueOrUndefinedValue.ts (80 errors) ==== // operator * var ra1 = null * null; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var ra2 = null * undefined; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var ra3 = undefined * null; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var ra4 = undefined * undefined; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. // operator / var rb1 = null / null; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var rb2 = null / undefined; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var rb3 = undefined / null; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var rb4 = undefined / undefined; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. // operator % var rc1 = null % null; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var rc2 = null % undefined; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var rc3 = undefined % null; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var rc4 = undefined % undefined; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. // operator - var rd1 = null - null; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var rd2 = null - undefined; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var rd3 = undefined - null; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var rd4 = undefined - undefined; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. // operator << var re1 = null << null; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var re2 = null << undefined; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var re3 = undefined << null; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var re4 = undefined << undefined; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. // operator >> var rf1 = null >> null; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var rf2 = null >> undefined; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var rf3 = undefined >> null; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var rf4 = undefined >> undefined; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. // operator >>> var rg1 = null >>> null; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var rg2 = null >>> undefined; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var rg3 = undefined >>> null; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var rg4 = undefined >>> undefined; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. // operator & var rh1 = null & null; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var rh2 = null & undefined; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var rh3 = undefined & null; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var rh4 = undefined & undefined; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. // operator ^ var ri1 = null ^ null; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var ri2 = null ^ undefined; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var ri3 = undefined ^ null; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var ri4 = undefined ^ undefined; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. // operator | var rj1 = null | null; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var rj2 = null | undefined; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var rj3 = undefined | null; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var rj4 = undefined | undefined; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. \ No newline at end of file +!!! error TS2532: Object is possibly 'undefined'. \ No newline at end of file diff --git a/tests/baselines/reference/arithmeticOperatorWithUndefinedValueAndInvalidOperands.errors.txt b/tests/baselines/reference/arithmeticOperatorWithUndefinedValueAndInvalidOperands.errors.txt index 9ee53c2f15c..8a9d014f2c2 100644 --- a/tests/baselines/reference/arithmeticOperatorWithUndefinedValueAndInvalidOperands.errors.txt +++ b/tests/baselines/reference/arithmeticOperatorWithUndefinedValueAndInvalidOperands.errors.txt @@ -1,234 +1,246 @@ -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(9,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(9,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(9,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(10,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(10,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(10,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(11,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(11,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(11,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(13,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(13,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(13,16): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(14,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(14,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(14,16): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(15,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(15,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(17,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(15,16): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(17,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(17,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(18,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(18,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(18,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(19,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(19,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(19,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(21,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(21,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(21,19): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(22,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(22,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(22,17): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(23,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(23,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(26,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(23,17): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(26,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(26,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(27,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(27,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(27,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(28,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(28,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(28,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(30,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(30,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(30,16): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(31,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(31,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(31,16): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(32,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(32,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(34,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(32,16): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(34,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(34,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(35,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(35,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(35,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(36,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(36,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(36,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(38,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(38,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(38,19): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(39,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(39,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(39,17): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(40,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(40,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(43,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(40,17): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(43,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(43,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(44,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(44,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(44,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(45,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(45,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(45,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(47,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(47,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(47,16): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(48,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(48,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(48,16): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(49,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(49,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(51,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(49,16): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(51,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(51,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(52,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(52,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(52,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(53,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(53,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(53,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(55,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(55,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(55,19): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(56,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(56,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(56,17): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(57,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(57,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(60,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(57,17): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(60,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(60,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(61,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(61,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(61,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(62,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(62,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(62,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(64,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(64,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(64,16): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(65,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(65,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(65,16): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(66,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(66,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(68,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(66,16): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(68,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(68,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(69,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(69,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(69,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(70,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(70,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(70,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(72,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(72,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(72,19): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(73,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(73,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(73,17): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(74,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(74,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(77,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(74,17): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(77,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(77,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(78,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(78,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(78,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(79,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(79,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(79,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(81,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(81,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(81,17): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(82,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(82,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(82,17): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(83,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(83,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(85,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(83,17): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(85,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(85,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(86,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(86,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(86,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(87,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(87,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(87,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(89,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(89,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(89,20): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(90,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(90,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(90,18): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(91,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(91,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(94,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(91,18): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(94,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(94,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(95,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(95,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(95,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(96,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(96,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(96,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(98,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(98,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(98,17): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(99,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(99,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(99,17): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(100,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(100,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(102,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(100,17): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(102,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(102,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(103,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(103,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(103,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(104,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(104,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(104,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(106,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(106,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(106,20): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(107,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(107,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(107,18): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(108,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(108,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(111,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(108,18): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(111,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(111,26): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(112,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(112,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(112,26): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(113,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(113,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(113,26): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(115,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(115,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(115,18): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(116,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(116,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(116,18): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(117,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(117,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(119,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(117,18): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(119,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(119,26): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(120,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(120,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(120,26): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(121,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(121,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(121,26): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(123,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(123,21): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(123,21): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(124,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(124,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(124,19): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(125,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(125,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(128,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(129,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(125,19): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(128,12): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(128,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(129,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(129,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(130,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(130,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(130,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(132,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(132,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(132,16): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(133,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(133,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(133,16): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(134,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(134,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(136,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(137,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(134,16): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(136,12): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(136,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(137,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(137,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(138,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(138,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(138,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(140,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(140,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(140,19): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(141,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(141,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(141,17): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(142,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(142,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(145,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(146,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(142,17): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(145,12): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(145,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(146,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(146,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(147,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(147,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(147,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(149,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(149,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(149,16): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(150,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(150,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(150,16): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(151,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(151,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(153,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(154,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(151,16): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(153,12): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(153,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(154,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(154,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(155,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(155,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(155,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(157,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(157,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(157,19): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(158,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(158,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(158,17): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(159,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(159,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(162,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(163,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(159,17): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(162,13): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(162,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(163,13): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(163,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(164,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(164,13): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(164,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(166,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(166,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(166,17): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(167,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(167,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(167,17): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(168,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(168,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(170,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(171,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(168,17): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(170,13): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(170,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(171,13): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(171,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(172,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(172,13): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(172,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(174,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(174,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(174,20): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(175,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(175,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(175,18): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(176,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(176,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(176,18): error TS2532: Object is possibly 'undefined'. -==== tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts (228 errors) ==== +==== tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts (240 errors) ==== // If one operand is the undefined or undefined value, it is treated as having the type of the // other operand. @@ -239,17 +251,17 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti // operator * var r1a1 = undefined * a; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r1a2 = undefined * b; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r1a3 = undefined * c; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -257,31 +269,31 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r1b2 = b * undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r1b3 = c * undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r1c1 = undefined * true; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r1c2 = undefined * ''; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r1c3 = undefined * {}; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -289,32 +301,32 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r1d2 = '' * undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r1d3 = {} * undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. // operator / var r2a1 = undefined / a; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r2a2 = undefined / b; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r2a3 = undefined / c; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -322,31 +334,31 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r2b2 = b / undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r2b3 = c / undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r2c1 = undefined / true; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r2c2 = undefined / ''; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r2c3 = undefined / {}; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -354,32 +366,32 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r2d2 = '' / undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r2d3 = {} / undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. // operator % var r3a1 = undefined % a; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r3a2 = undefined % b; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r3a3 = undefined % c; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -387,31 +399,31 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r3b2 = b % undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r3b3 = c % undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r3c1 = undefined % true; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r3c2 = undefined % ''; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r3c3 = undefined % {}; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -419,32 +431,32 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r3d2 = '' % undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r3d3 = {} % undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. // operator - var r4a1 = undefined - a; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r4a2 = undefined - b; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r4a3 = undefined - c; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -452,31 +464,31 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r4b2 = b - undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r4b3 = c - undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r4c1 = undefined - true; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r4c2 = undefined - ''; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r4c3 = undefined - {}; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -484,32 +496,32 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r4d2 = '' - undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r4d3 = {} - undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. // operator << var r5a1 = undefined << a; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r5a2 = undefined << b; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r5a3 = undefined << c; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -517,31 +529,31 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r5b2 = b << undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r5b3 = c << undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r5c1 = undefined << true; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r5c2 = undefined << ''; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r5c3 = undefined << {}; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -549,32 +561,32 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r5d2 = '' << undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r5d3 = {} << undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. // operator >> var r6a1 = undefined >> a; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r6a2 = undefined >> b; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r6a3 = undefined >> c; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -582,31 +594,31 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r6b2 = b >> undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r6b3 = c >> undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r6c1 = undefined >> true; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r6c2 = undefined >> ''; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r6c3 = undefined >> {}; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -614,32 +626,32 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r6d2 = '' >> undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r6d3 = {} >> undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. // operator >>> var r7a1 = undefined >>> a; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r7a2 = undefined >>> b; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r7a3 = undefined >>> c; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -647,31 +659,31 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r7b2 = b >>> undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r7b3 = c >>> undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r7c1 = undefined >>> true; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r7c2 = undefined >>> ''; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r7c3 = undefined >>> {}; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -679,185 +691,209 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r7d2 = '' >>> undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r7d3 = {} >>> undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. // operator & var r8a1 = undefined & a; - ~~~~~~~~~~~~~ -!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~ +!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r8a2 = undefined & b; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r8a3 = undefined & c; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r8b1 = a & undefined; - ~~~~~~~~~~~~~ -!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. + ~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var r8b2 = b & undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r8b3 = c & undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r8c1 = undefined & true; - ~~~~~~~~~~~~~~~~ -!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~ +!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r8c2 = undefined & ''; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r8c3 = undefined & {}; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r8d1 = true & undefined; - ~~~~~~~~~~~~~~~~ -!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. + ~~~~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var r8d2 = '' & undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r8d3 = {} & undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. // operator ^ var r9a1 = undefined ^ a; - ~~~~~~~~~~~~~ -!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~ +!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r9a2 = undefined ^ b; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r9a3 = undefined ^ c; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r9b1 = a ^ undefined; - ~~~~~~~~~~~~~ -!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. + ~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var r9b2 = b ^ undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r9b3 = c ^ undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r9c1 = undefined ^ true; - ~~~~~~~~~~~~~~~~ -!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~ +!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r9c2 = undefined ^ ''; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r9c3 = undefined ^ {}; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r9d1 = true ^ undefined; - ~~~~~~~~~~~~~~~~ -!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. + ~~~~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var r9d2 = '' ^ undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r9d3 = {} ^ undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. // operator | var r10a1 = undefined | a; - ~~~~~~~~~~~~~ -!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~ +!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r10a2 = undefined | b; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r10a3 = undefined | c; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r10b1 = a | undefined; - ~~~~~~~~~~~~~ -!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. + ~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var r10b2 = b | undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r10b3 = c | undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r10c1 = undefined | true; - ~~~~~~~~~~~~~~~~ -!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~ +!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r10c2 = undefined | ''; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r10c3 = undefined | {}; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r10d1 = true | undefined; - ~~~~~~~~~~~~~~~~ -!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. + ~~~~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var r10d2 = '' | undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r10d3 = {} | undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. \ No newline at end of file +!!! error TS2532: Object is possibly 'undefined'. \ No newline at end of file diff --git a/tests/baselines/reference/arithmeticOperatorWithUndefinedValueAndValidOperands.errors.txt b/tests/baselines/reference/arithmeticOperatorWithUndefinedValueAndValidOperands.errors.txt new file mode 100644 index 00000000000..246b642603c --- /dev/null +++ b/tests/baselines/reference/arithmeticOperatorWithUndefinedValueAndValidOperands.errors.txt @@ -0,0 +1,353 @@ +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(13,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(14,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(15,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(16,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(17,15): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(18,15): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(19,15): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(20,17): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(23,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(24,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(25,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(26,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(27,15): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(28,15): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(29,15): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(30,17): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(33,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(34,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(35,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(36,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(37,15): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(38,15): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(39,15): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(40,17): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(43,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(44,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(45,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(46,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(47,15): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(48,15): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(49,15): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(50,17): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(53,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(54,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(55,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(56,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(57,16): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(58,16): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(59,16): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(60,18): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(63,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(64,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(65,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(66,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(67,16): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(68,16): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(69,16): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(70,18): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(73,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(74,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(75,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(76,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(77,17): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(78,17): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(79,17): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(80,19): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(83,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(84,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(85,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(86,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(87,15): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(88,15): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(89,15): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(90,17): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(93,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(94,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(95,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(96,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(97,15): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(98,15): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(99,15): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(100,17): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(103,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(104,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(105,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(106,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(107,15): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(108,15): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(109,15): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts(110,17): error TS2532: Object is possibly 'undefined'. + + +==== tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndValidOperands.ts (80 errors) ==== + // If one operand is the undefined or undefined value, it is treated as having the type of the + // other operand. + + enum E { + a, + b + } + + var a: any; + var b: number; + + // operator * + var ra1 = undefined * a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var ra2 = undefined * b; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var ra3 = undefined * 1; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var ra4 = undefined * E.a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var ra5 = a * undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var ra6 = b * undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var ra7 = 0 * undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var ra8 = E.b * undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + // operator / + var rb1 = undefined / a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rb2 = undefined / b; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rb3 = undefined / 1; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rb4 = undefined / E.a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rb5 = a / undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rb6 = b / undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rb7 = 0 / undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rb8 = E.b / undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + // operator % + var rc1 = undefined % a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rc2 = undefined % b; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rc3 = undefined % 1; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rc4 = undefined % E.a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rc5 = a % undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rc6 = b % undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rc7 = 0 % undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rc8 = E.b % undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + // operator - + var rd1 = undefined - a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rd2 = undefined - b; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rd3 = undefined - 1; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rd4 = undefined - E.a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rd5 = a - undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rd6 = b - undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rd7 = 0 - undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rd8 = E.b - undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + // operator << + var re1 = undefined << a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var re2 = undefined << b; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var re3 = undefined << 1; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var re4 = undefined << E.a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var re5 = a << undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var re6 = b << undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var re7 = 0 << undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var re8 = E.b << undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + // operator >> + var rf1 = undefined >> a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rf2 = undefined >> b; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rf3 = undefined >> 1; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rf4 = undefined >> E.a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rf5 = a >> undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rf6 = b >> undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rf7 = 0 >> undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rf8 = E.b >> undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + // operator >>> + var rg1 = undefined >>> a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rg2 = undefined >>> b; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rg3 = undefined >>> 1; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rg4 = undefined >>> E.a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rg5 = a >>> undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rg6 = b >>> undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rg7 = 0 >>> undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rg8 = E.b >>> undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + // operator & + var rh1 = undefined & a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rh2 = undefined & b; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rh3 = undefined & 1; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rh4 = undefined & E.a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rh5 = a & undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rh6 = b & undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rh7 = 0 & undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rh8 = E.b & undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + // operator ^ + var ri1 = undefined ^ a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var ri2 = undefined ^ b; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var ri3 = undefined ^ 1; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var ri4 = undefined ^ E.a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var ri5 = a ^ undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var ri6 = b ^ undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var ri7 = 0 ^ undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var ri8 = E.b ^ undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + // operator | + var rj1 = undefined | a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rj2 = undefined | b; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rj3 = undefined | 1; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rj4 = undefined | E.a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rj5 = a | undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rj6 = b | undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rj7 = 0 | undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rj8 = E.b | undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. \ No newline at end of file diff --git a/tests/baselines/reference/asyncFunctionDeclaration10_es2017.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration10_es2017.errors.txt index d5da3432264..33cd913a2eb 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration10_es2017.errors.txt +++ b/tests/baselines/reference/asyncFunctionDeclaration10_es2017.errors.txt @@ -4,10 +4,11 @@ tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclarati tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,33): error TS2304: Cannot find name 'await'. tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,38): error TS1005: ';' expected. tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,39): error TS1128: Declaration or statement expected. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,49): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,53): error TS1109: Expression expected. -==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts (7 errors) ==== +==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts (8 errors) ==== async function foo(a = await => await): Promise { ~~~~~~~~~ !!! error TS2371: A parameter initializer is only allowed in a function or constructor implementation. @@ -21,6 +22,8 @@ tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclarati !!! error TS1005: ';' expected. ~ !!! error TS1128: Declaration or statement expected. + ~~~~ +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS1109: Expression expected. } \ No newline at end of file diff --git a/tests/baselines/reference/asyncFunctionDeclaration10_es5.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration10_es5.errors.txt index dc814e9c887..b974eacd882 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration10_es5.errors.txt +++ b/tests/baselines/reference/asyncFunctionDeclaration10_es5.errors.txt @@ -4,10 +4,11 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration1 tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,33): error TS2304: Cannot find name 'await'. tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,38): error TS1005: ';' expected. tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,39): error TS1128: Declaration or statement expected. +tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,49): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,53): error TS1109: Expression expected. -==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts (7 errors) ==== +==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts (8 errors) ==== async function foo(a = await => await): Promise { ~~~~~~~~~ !!! error TS2371: A parameter initializer is only allowed in a function or constructor implementation. @@ -21,6 +22,8 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration1 !!! error TS1005: ';' expected. ~ !!! error TS1128: Declaration or statement expected. + ~~~~ +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS1109: Expression expected. } \ No newline at end of file diff --git a/tests/baselines/reference/asyncFunctionDeclaration10_es6.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration10_es6.errors.txt index 15ceb3e60c7..b752ec94a45 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration10_es6.errors.txt +++ b/tests/baselines/reference/asyncFunctionDeclaration10_es6.errors.txt @@ -4,10 +4,11 @@ tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration1 tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,33): error TS2304: Cannot find name 'await'. tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,38): error TS1005: ';' expected. tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,39): error TS1128: Declaration or statement expected. +tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,49): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,53): error TS1109: Expression expected. -==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts (7 errors) ==== +==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts (8 errors) ==== async function foo(a = await => await): Promise { ~~~~~~~~~ !!! error TS2371: A parameter initializer is only allowed in a function or constructor implementation. @@ -21,6 +22,8 @@ tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration1 !!! error TS1005: ';' expected. ~ !!! error TS1128: Declaration or statement expected. + ~~~~ +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS1109: Expression expected. } \ No newline at end of file diff --git a/tests/baselines/reference/asyncFunctionDeclaration5_es2017.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration5_es2017.errors.txt index ad8c0280206..1fc74dfa0a2 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration5_es2017.errors.txt +++ b/tests/baselines/reference/asyncFunctionDeclaration5_es2017.errors.txt @@ -2,10 +2,11 @@ tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclarati tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts(1,20): error TS2304: Cannot find name 'await'. tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts(1,25): error TS1005: ';' expected. tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts(1,26): error TS1128: Declaration or statement expected. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts(1,36): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts(1,40): error TS1109: Expression expected. -==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts (5 errors) ==== +==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts (6 errors) ==== async function foo(await): Promise { ~~~~~ !!! error TS1138: Parameter declaration expected. @@ -15,6 +16,8 @@ tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclarati !!! error TS1005: ';' expected. ~ !!! error TS1128: Declaration or statement expected. + ~~~~ +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS1109: Expression expected. } \ No newline at end of file diff --git a/tests/baselines/reference/asyncFunctionDeclaration5_es5.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration5_es5.errors.txt index 3060c2c836b..48299773218 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration5_es5.errors.txt +++ b/tests/baselines/reference/asyncFunctionDeclaration5_es5.errors.txt @@ -2,10 +2,11 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5 tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5_es5.ts(1,20): error TS2304: Cannot find name 'await'. tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5_es5.ts(1,25): error TS1005: ';' expected. tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5_es5.ts(1,26): error TS1128: Declaration or statement expected. +tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5_es5.ts(1,36): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5_es5.ts(1,40): error TS1109: Expression expected. -==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5_es5.ts (5 errors) ==== +==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5_es5.ts (6 errors) ==== async function foo(await): Promise { ~~~~~ !!! error TS1138: Parameter declaration expected. @@ -15,6 +16,8 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5 !!! error TS1005: ';' expected. ~ !!! error TS1128: Declaration or statement expected. + ~~~~ +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS1109: Expression expected. } \ No newline at end of file diff --git a/tests/baselines/reference/asyncFunctionDeclaration5_es6.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration5_es6.errors.txt index a6944e0c6e6..2e907d13400 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration5_es6.errors.txt +++ b/tests/baselines/reference/asyncFunctionDeclaration5_es6.errors.txt @@ -2,10 +2,11 @@ tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5 tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5_es6.ts(1,20): error TS2304: Cannot find name 'await'. tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5_es6.ts(1,25): error TS1005: ';' expected. tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5_es6.ts(1,26): error TS1128: Declaration or statement expected. +tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5_es6.ts(1,36): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5_es6.ts(1,40): error TS1109: Expression expected. -==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5_es6.ts (5 errors) ==== +==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5_es6.ts (6 errors) ==== async function foo(await): Promise { ~~~~~ !!! error TS1138: Parameter declaration expected. @@ -15,6 +16,8 @@ tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5 !!! error TS1005: ';' expected. ~ !!! error TS1128: Declaration or statement expected. + ~~~~ +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS1109: Expression expected. } \ No newline at end of file diff --git a/tests/baselines/reference/augmentExportEquals7.errors.txt b/tests/baselines/reference/augmentExportEquals7.errors.txt new file mode 100644 index 00000000000..e13cf037023 --- /dev/null +++ b/tests/baselines/reference/augmentExportEquals7.errors.txt @@ -0,0 +1,16 @@ +/node_modules/@types/lib-extender/index.d.ts(2,16): error TS2649: Cannot augment module 'lib' with value exports because it resolves to a non-module entity. + + +==== /node_modules/lib/index.d.ts (0 errors) ==== + declare var lib: () => void; + declare namespace lib {} + export = lib; + +==== /node_modules/@types/lib-extender/index.d.ts (1 errors) ==== + import * as lib from "lib"; + declare module "lib" { + ~~~~~ +!!! error TS2649: Cannot augment module 'lib' with value exports because it resolves to a non-module entity. + export function fn(): void; + } + \ No newline at end of file diff --git a/tests/baselines/reference/binaryArithmatic1.errors.txt b/tests/baselines/reference/binaryArithmatic1.errors.txt new file mode 100644 index 00000000000..51c0b649890 --- /dev/null +++ b/tests/baselines/reference/binaryArithmatic1.errors.txt @@ -0,0 +1,7 @@ +tests/cases/compiler/binaryArithmatic1.ts(1,13): error TS2531: Object is possibly 'null'. + + +==== tests/cases/compiler/binaryArithmatic1.ts (1 errors) ==== + var v = 4 | null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. \ No newline at end of file diff --git a/tests/baselines/reference/binaryArithmatic2.errors.txt b/tests/baselines/reference/binaryArithmatic2.errors.txt new file mode 100644 index 00000000000..28f379c30e2 --- /dev/null +++ b/tests/baselines/reference/binaryArithmatic2.errors.txt @@ -0,0 +1,7 @@ +tests/cases/compiler/binaryArithmatic2.ts(1,13): error TS2532: Object is possibly 'undefined'. + + +==== tests/cases/compiler/binaryArithmatic2.ts (1 errors) ==== + var v = 4 | undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. \ No newline at end of file diff --git a/tests/baselines/reference/binaryArithmatic3.errors.txt b/tests/baselines/reference/binaryArithmatic3.errors.txt index 6dffe5e150c..1457407a7b8 100644 --- a/tests/baselines/reference/binaryArithmatic3.errors.txt +++ b/tests/baselines/reference/binaryArithmatic3.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/binaryArithmatic3.ts(1,9): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/compiler/binaryArithmatic3.ts(1,21): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/compiler/binaryArithmatic3.ts(1,9): error TS2532: Object is possibly 'undefined'. +tests/cases/compiler/binaryArithmatic3.ts(1,21): error TS2532: Object is possibly 'undefined'. ==== tests/cases/compiler/binaryArithmatic3.ts (2 errors) ==== var v = undefined | undefined; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. \ No newline at end of file +!!! error TS2532: Object is possibly 'undefined'. \ No newline at end of file diff --git a/tests/baselines/reference/binaryArithmatic4.errors.txt b/tests/baselines/reference/binaryArithmatic4.errors.txt index f72c23073ca..fe7523e0884 100644 --- a/tests/baselines/reference/binaryArithmatic4.errors.txt +++ b/tests/baselines/reference/binaryArithmatic4.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/binaryArithmatic4.ts(1,9): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/compiler/binaryArithmatic4.ts(1,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/compiler/binaryArithmatic4.ts(1,9): error TS2531: Object is possibly 'null'. +tests/cases/compiler/binaryArithmatic4.ts(1,16): error TS2531: Object is possibly 'null'. ==== tests/cases/compiler/binaryArithmatic4.ts (2 errors) ==== var v = null | null; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. \ No newline at end of file +!!! error TS2531: Object is possibly 'null'. \ No newline at end of file diff --git a/tests/baselines/reference/bitwiseNotOperatorWithAnyOtherType.errors.txt b/tests/baselines/reference/bitwiseNotOperatorWithAnyOtherType.errors.txt index 66d4cbb628e..c3e9f220a3a 100644 --- a/tests/baselines/reference/bitwiseNotOperatorWithAnyOtherType.errors.txt +++ b/tests/baselines/reference/bitwiseNotOperatorWithAnyOtherType.errors.txt @@ -1,9 +1,14 @@ -tests/cases/conformance/expressions/unaryOperators/bitwiseNotOperator/bitwiseNotOperatorWithAnyOtherType.ts(47,26): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. -tests/cases/conformance/expressions/unaryOperators/bitwiseNotOperator/bitwiseNotOperatorWithAnyOtherType.ts(48,26): error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. -tests/cases/conformance/expressions/unaryOperators/bitwiseNotOperator/bitwiseNotOperatorWithAnyOtherType.ts(49,26): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. +tests/cases/conformance/expressions/unaryOperators/bitwiseNotOperator/bitwiseNotOperatorWithAnyOtherType.ts(35,24): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/unaryOperators/bitwiseNotOperator/bitwiseNotOperatorWithAnyOtherType.ts(36,24): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/bitwiseNotOperator/bitwiseNotOperatorWithAnyOtherType.ts(47,26): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/bitwiseNotOperator/bitwiseNotOperatorWithAnyOtherType.ts(47,33): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/unaryOperators/bitwiseNotOperator/bitwiseNotOperatorWithAnyOtherType.ts(48,26): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/bitwiseNotOperator/bitwiseNotOperatorWithAnyOtherType.ts(48,33): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/bitwiseNotOperator/bitwiseNotOperatorWithAnyOtherType.ts(49,26): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/unaryOperators/bitwiseNotOperator/bitwiseNotOperatorWithAnyOtherType.ts(49,38): error TS2532: Object is possibly 'undefined'. -==== tests/cases/conformance/expressions/unaryOperators/bitwiseNotOperator/bitwiseNotOperatorWithAnyOtherType.ts (3 errors) ==== +==== tests/cases/conformance/expressions/unaryOperators/bitwiseNotOperator/bitwiseNotOperatorWithAnyOtherType.ts (8 errors) ==== // ~ operator on any type @@ -39,7 +44,11 @@ tests/cases/conformance/expressions/unaryOperators/bitwiseNotOperator/bitwiseNot // any type literal var ResultIsNumber6 = ~undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var ResultIsNumber7 = ~null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. // any type expressions var ResultIsNumber8 = ~ANY2[0] @@ -51,14 +60,20 @@ tests/cases/conformance/expressions/unaryOperators/bitwiseNotOperator/bitwiseNot var ResultIsNumber14 = ~A.foo(); var ResultIsNumber15 = ~(ANY + ANY1); var ResultIsNumber16 = ~(null + undefined); - ~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var ResultIsNumber17 = ~(null + null); - ~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var ResultIsNumber18 = ~(undefined + undefined); - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. // multiple ~ operators var ResultIsNumber19 = ~~ANY; diff --git a/tests/baselines/reference/comparisonOperatorWithIdenticalPrimitiveType.errors.txt b/tests/baselines/reference/comparisonOperatorWithIdenticalPrimitiveType.errors.txt new file mode 100644 index 00000000000..ad41a280aad --- /dev/null +++ b/tests/baselines/reference/comparisonOperatorWithIdenticalPrimitiveType.errors.txt @@ -0,0 +1,130 @@ +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(15,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(15,18): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(16,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(16,23): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(24,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(24,18): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(25,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(25,23): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(33,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(33,19): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(34,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(34,24): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(42,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(42,19): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(43,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(43,24): error TS2532: Object is possibly 'undefined'. + + +==== tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts (16 errors) ==== + enum E { a, b, c } + + var a: number; + var b: boolean; + var c: string; + var d: void; + var e: E; + + // operator < + var ra1 = a < a; + var ra2 = b < b; + var ra3 = c < c; + var ra4 = d < d; + var ra5 = e < e; + var ra6 = null < null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var ra7 = undefined < undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + // operator > + var rb1 = a > a; + var rb2 = b > b; + var rb3 = c > c; + var rb4 = d > d; + var rb5 = e > e; + var rb6 = null > null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rb7 = undefined > undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + // operator <= + var rc1 = a <= a; + var rc2 = b <= b; + var rc3 = c <= c; + var rc4 = d <= d; + var rc5 = e <= e; + var rc6 = null <= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rc7 = undefined <= undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + // operator >= + var rd1 = a >= a; + var rd2 = b >= b; + var rd3 = c >= c; + var rd4 = d >= d; + var rd5 = e >= e; + var rd6 = null >= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var rd7 = undefined >= undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + // operator == + var re1 = a == a; + var re2 = b == b; + var re3 = c == c; + var re4 = d == d; + var re5 = e == e; + var re6 = null == null; + var re7 = undefined == undefined; + + // operator != + var rf1 = a != a; + var rf2 = b != b; + var rf3 = c != c; + var rf4 = d != d; + var rf5 = e != e; + var rf6 = null != null; + var rf7 = undefined != undefined; + + // operator === + var rg1 = a === a; + var rg2 = b === b; + var rg3 = c === c; + var rg4 = d === d; + var rg5 = e === e; + var rg6 = null === null; + var rg7 = undefined === undefined; + + // operator !== + var rh1 = a !== a; + var rh2 = b !== b; + var rh3 = c !== c; + var rh4 = d !== d; + var rh5 = e !== e; + var rh6 = null !== null; + var rh7 = undefined !== undefined; \ No newline at end of file diff --git a/tests/baselines/reference/comparisonOperatorWithOneOperandIsNull.errors.txt b/tests/baselines/reference/comparisonOperatorWithOneOperandIsNull.errors.txt new file mode 100644 index 00000000000..c74ab997a59 --- /dev/null +++ b/tests/baselines/reference/comparisonOperatorWithOneOperandIsNull.errors.txt @@ -0,0 +1,360 @@ +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(4,22): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(5,22): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(6,23): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(7,23): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(13,18): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(14,18): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(15,18): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(16,18): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(32,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(33,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(34,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(35,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(36,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(37,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(38,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(40,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(41,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(42,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(43,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(44,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(45,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(46,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(49,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(50,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(51,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(52,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(53,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(54,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(55,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(57,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(58,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(59,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(60,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(61,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(62,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(63,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(66,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(67,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(68,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(69,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(70,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(71,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(72,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(74,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(75,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(76,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(77,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(78,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(79,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(80,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(83,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(84,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(85,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(86,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(87,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(88,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(89,12): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(91,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(92,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(93,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(94,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(95,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(96,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts(97,17): error TS2531: Object is possibly 'null'. + + +==== tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithOneOperandIsNull.ts (64 errors) ==== + enum E { a, b, c } + + function foo(t: T) { + var foo_r1 = t < null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var foo_r2 = t > null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var foo_r3 = t <= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var foo_r4 = t >= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var foo_r5 = t == null; + var foo_r6 = t != null; + var foo_r7 = t === null; + var foo_r8 = t !== null; + + var foo_r1 = null < t; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var foo_r2 = null > t; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var foo_r3 = null <= t; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var foo_r4 = null >= t; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var foo_r5 = null == t; + var foo_r6 = null != t; + var foo_r7 = null === t; + var foo_r8 = null !== t; + } + + var a: boolean; + var b: number; + var c: string; + var d: void; + var e: E; + var f: {}; + var g: string[]; + + // operator < + var r1a1 = null < a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r1a2 = null < b; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r1a3 = null < c; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r1a4 = null < d; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r1a5 = null < e; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r1a6 = null < f; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r1a7 = null < g; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + + var r1b1 = a < null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r1b2 = b < null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r1b3 = c < null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r1b4 = d < null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r1b5 = e < null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r1b6 = f < null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r1b7 = g < null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + + // operator > + var r2a1 = null > a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r2a2 = null > b; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r2a3 = null > c; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r2a4 = null > d; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r2a5 = null > e; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r2a6 = null > f; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r2a7 = null > g; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + + var r2b1 = a > null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r2b2 = b > null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r2b3 = c > null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r2b4 = d > null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r2b5 = e > null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r2b6 = f > null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r2b7 = g > null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + + // operator <= + var r3a1 = null <= a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r3a2 = null <= b; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r3a3 = null <= c; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r3a4 = null <= d; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r3a5 = null <= e; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r3a6 = null <= f; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r3a7 = null <= g; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + + var r3b1 = a <= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r3b2 = b <= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r3b3 = c <= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r3b4 = d <= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r3b5 = e <= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r3b6 = f <= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r3b7 = g <= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + + // operator >= + var r4a1 = null >= a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r4a2 = null >= b; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r4a3 = null >= c; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r4a4 = null >= d; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r4a5 = null >= e; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r4a6 = null >= f; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r4a7 = null >= g; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + + var r4b1 = a >= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r4b2 = b >= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r4b3 = c >= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r4b4 = d >= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r4b5 = e >= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r4b6 = f >= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r4b7 = g >= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + + // operator == + var r5a1 = null == a; + var r5a2 = null == b; + var r5a3 = null == c; + var r5a4 = null == d; + var r5a5 = null == e; + var r5a6 = null == f; + var r5a7 = null == g; + + var r5b1 = a == null; + var r5b2 = b == null; + var r5b3 = c == null; + var r5b4 = d == null; + var r5b5 = e == null; + var r5b6 = f == null; + var r5b7 = g == null; + + // operator != + var r6a1 = null != a; + var r6a2 = null != b; + var r6a3 = null != c; + var r6a4 = null != d; + var r6a5 = null != e; + var r6a6 = null != f; + var r6a7 = null != g; + + var r6b1 = a != null; + var r6b2 = b != null; + var r6b3 = c != null; + var r6b4 = d != null; + var r6b5 = e != null; + var r6b6 = f != null; + var r6b7 = g != null; + + // operator === + var r7a1 = null === a; + var r7a2 = null === b; + var r7a3 = null === c; + var r7a4 = null === d; + var r7a5 = null === e; + var r7a6 = null === f; + var r7a7 = null === g; + + var r7b1 = a === null; + var r7b2 = b === null; + var r7b3 = c === null; + var r7b4 = d === null; + var r7b5 = e === null; + var r7b6 = f === null; + var r7b7 = g === null; + + // operator !== + var r8a1 = null !== a; + var r8a2 = null !== b; + var r8a3 = null !== c; + var r8a4 = null !== d; + var r8a5 = null !== e; + var r8a6 = null !== f; + var r8a7 = null !== g; + + var r8b1 = a !== null; + var r8b2 = b !== null; + var r8b3 = c !== null; + var r8b4 = d !== null; + var r8b5 = e !== null; + var r8b6 = f !== null; + var r8b7 = g !== null; \ No newline at end of file diff --git a/tests/baselines/reference/compoundAdditionAssignmentLHSCanBeAssigned.errors.txt b/tests/baselines/reference/compoundAdditionAssignmentLHSCanBeAssigned.errors.txt new file mode 100644 index 00000000000..08d8fd0c6d3 --- /dev/null +++ b/tests/baselines/reference/compoundAdditionAssignmentLHSCanBeAssigned.errors.txt @@ -0,0 +1,65 @@ +tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentLHSCanBeAssigned.ts(32,7): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentLHSCanBeAssigned.ts(33,7): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentLHSCanBeAssigned.ts(39,7): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentLHSCanBeAssigned.ts(40,7): error TS2532: Object is possibly 'undefined'. + + +==== tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentLHSCanBeAssigned.ts (4 errors) ==== + enum E { a, b } + + var a: any; + var b: void; + + var x1: any; + x1 += a; + x1 += b; + x1 += true; + x1 += 0; + x1 += ''; + x1 += E.a; + x1 += {}; + x1 += null; + x1 += undefined; + + var x2: string; + x2 += a; + x2 += b; + x2 += true; + x2 += 0; + x2 += ''; + x2 += E.a; + x2 += {}; + x2 += null; + x2 += undefined; + + var x3: number; + x3 += a; + x3 += 0; + x3 += E.a; + x3 += null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + x3 += undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + var x4: E; + x4 += a; + x4 += 0; + x4 += E.a; + x4 += null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + x4 += undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + var x5: boolean; + x5 += a; + + var x6: {}; + x6 += a; + x6 += ''; + + var x7: void; + x7 += a; \ No newline at end of file diff --git a/tests/baselines/reference/compoundAdditionAssignmentWithInvalidOperands.errors.txt b/tests/baselines/reference/compoundAdditionAssignmentWithInvalidOperands.errors.txt index cadc5c945d1..1812065f149 100644 --- a/tests/baselines/reference/compoundAdditionAssignmentWithInvalidOperands.errors.txt +++ b/tests/baselines/reference/compoundAdditionAssignmentWithInvalidOperands.errors.txt @@ -3,22 +3,22 @@ tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmen tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(8,1): error TS2365: Operator '+=' cannot be applied to types 'boolean' and '0'. tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(9,1): error TS2365: Operator '+=' cannot be applied to types 'boolean' and 'E.a'. tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(10,1): error TS2365: Operator '+=' cannot be applied to types 'boolean' and '{}'. -tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(11,1): error TS2365: Operator '+=' cannot be applied to types 'boolean' and 'boolean'. -tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(12,1): error TS2365: Operator '+=' cannot be applied to types 'boolean' and 'boolean'. +tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(11,7): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(12,7): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(15,1): error TS2365: Operator '+=' cannot be applied to types '{}' and 'void'. tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(16,1): error TS2365: Operator '+=' cannot be applied to types '{}' and 'true'. tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(17,1): error TS2365: Operator '+=' cannot be applied to types '{}' and '0'. tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(18,1): error TS2365: Operator '+=' cannot be applied to types '{}' and 'E.a'. tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(19,1): error TS2365: Operator '+=' cannot be applied to types '{}' and '{}'. -tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(20,1): error TS2365: Operator '+=' cannot be applied to types '{}' and '{}'. -tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(21,1): error TS2365: Operator '+=' cannot be applied to types '{}' and '{}'. +tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(20,7): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(21,7): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(24,1): error TS2365: Operator '+=' cannot be applied to types 'void' and 'void'. tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(25,1): error TS2365: Operator '+=' cannot be applied to types 'void' and 'true'. tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(26,1): error TS2365: Operator '+=' cannot be applied to types 'void' and '0'. tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(27,1): error TS2365: Operator '+=' cannot be applied to types 'void' and 'E.a'. tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(28,1): error TS2365: Operator '+=' cannot be applied to types 'void' and '{}'. -tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(29,1): error TS2365: Operator '+=' cannot be applied to types 'void' and 'void'. -tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(30,1): error TS2365: Operator '+=' cannot be applied to types 'void' and 'void'. +tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(29,7): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(30,7): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(33,1): error TS2365: Operator '+=' cannot be applied to types 'number' and 'void'. tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(34,1): error TS2365: Operator '+=' cannot be applied to types 'number' and 'true'. tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmentWithInvalidOperands.ts(35,1): error TS2365: Operator '+=' cannot be applied to types 'number' and '{}'. @@ -49,11 +49,11 @@ tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmen ~~~~~~~~ !!! error TS2365: Operator '+=' cannot be applied to types 'boolean' and '{}'. x1 += null; - ~~~~~~~~~~ -!!! error TS2365: Operator '+=' cannot be applied to types 'boolean' and 'boolean'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. x1 += undefined; - ~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+=' cannot be applied to types 'boolean' and 'boolean'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var x2: {}; x2 += a; @@ -72,11 +72,11 @@ tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmen ~~~~~~~~ !!! error TS2365: Operator '+=' cannot be applied to types '{}' and '{}'. x2 += null; - ~~~~~~~~~~ -!!! error TS2365: Operator '+=' cannot be applied to types '{}' and '{}'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. x2 += undefined; - ~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+=' cannot be applied to types '{}' and '{}'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var x3: void; x3 += a; @@ -95,11 +95,11 @@ tests/cases/conformance/expressions/assignmentOperator/compoundAdditionAssignmen ~~~~~~~~ !!! error TS2365: Operator '+=' cannot be applied to types 'void' and '{}'. x3 += null; - ~~~~~~~~~~ -!!! error TS2365: Operator '+=' cannot be applied to types 'void' and 'void'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. x3 += undefined; - ~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+=' cannot be applied to types 'void' and 'void'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var x4: number; x4 += a; diff --git a/tests/baselines/reference/compoundArithmeticAssignmentLHSCanBeAssigned.errors.txt b/tests/baselines/reference/compoundArithmeticAssignmentLHSCanBeAssigned.errors.txt new file mode 100644 index 00000000000..f438045a45f --- /dev/null +++ b/tests/baselines/reference/compoundArithmeticAssignmentLHSCanBeAssigned.errors.txt @@ -0,0 +1,47 @@ +tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentLHSCanBeAssigned.ts(11,7): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentLHSCanBeAssigned.ts(12,7): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentLHSCanBeAssigned.ts(18,7): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentLHSCanBeAssigned.ts(19,7): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentLHSCanBeAssigned.ts(25,7): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentLHSCanBeAssigned.ts(26,7): error TS2532: Object is possibly 'undefined'. + + +==== tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentLHSCanBeAssigned.ts (6 errors) ==== + enum E { a, b, c } + + var a: any; + var b: number; + var c: E; + + var x1: any; + x1 *= a; + x1 *= b; + x1 *= c; + x1 *= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + x1 *= undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + var x2: number; + x2 *= a; + x2 *= b; + x2 *= c; + x2 *= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + x2 *= undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + var x3: E; + x3 *= a; + x3 *= b; + x3 *= c; + x3 *= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + x3 *= undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. \ No newline at end of file diff --git a/tests/baselines/reference/compoundArithmeticAssignmentWithInvalidOperands.errors.txt b/tests/baselines/reference/compoundArithmeticAssignmentWithInvalidOperands.errors.txt index 9367285ef93..7429445b422 100644 --- a/tests/baselines/reference/compoundArithmeticAssignmentWithInvalidOperands.errors.txt +++ b/tests/baselines/reference/compoundArithmeticAssignmentWithInvalidOperands.errors.txt @@ -10,9 +10,9 @@ tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignm tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(13,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(13,7): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(14,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(14,7): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(14,7): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(15,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(15,7): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(15,7): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(18,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(19,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(19,7): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -25,9 +25,9 @@ tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignm tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(24,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(24,7): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(25,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(25,7): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(25,7): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(26,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(26,7): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(26,7): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(29,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(30,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(30,7): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -40,9 +40,9 @@ tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignm tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(35,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(35,7): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(36,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(36,7): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(36,7): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(37,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(37,7): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(37,7): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(40,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(41,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(41,7): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -55,9 +55,9 @@ tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignm tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(46,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(46,7): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(47,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(47,7): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(47,7): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(48,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(48,7): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(48,7): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(51,7): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(52,7): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignmentWithInvalidOperands.ts(53,7): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -108,12 +108,12 @@ tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignm ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. x1 *= undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var x2: string; x2 *= a; @@ -149,12 +149,12 @@ tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignm ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. x2 *= undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var x3: {}; x3 *= a; @@ -190,12 +190,12 @@ tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignm ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. x3 *= undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var x4: void; x4 *= a; @@ -231,12 +231,12 @@ tests/cases/conformance/expressions/assignmentOperator/compoundArithmeticAssignm ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. x4 *= undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var x5: number; x5 *= b; diff --git a/tests/baselines/reference/compoundAssignmentLHSIsValue.errors.txt b/tests/baselines/reference/compoundAssignmentLHSIsValue.errors.txt index bc6bb41b27f..8948467c590 100644 --- a/tests/baselines/reference/compoundAssignmentLHSIsValue.errors.txt +++ b/tests/baselines/reference/compoundAssignmentLHSIsValue.errors.txt @@ -17,6 +17,7 @@ tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsVa tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts(41,1): error TS2539: Cannot assign to 'foo' because it is not a variable. tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts(42,1): error TS2539: Cannot assign to 'foo' because it is not a variable. tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts(45,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. +tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts(45,1): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts(46,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts(47,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts(48,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. @@ -55,6 +56,7 @@ tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsVa tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts(104,2): error TS2539: Cannot assign to 'foo' because it is not a variable. tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts(105,2): error TS2539: Cannot assign to 'foo' because it is not a variable. tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts(106,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. +tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts(106,1): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts(107,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts(108,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts(109,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. @@ -74,7 +76,7 @@ tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsVa tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts(123,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. -==== tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts (74 errors) ==== +==== tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsValue.ts (76 errors) ==== // expected error for all the LHS of compound assignments (arithmetic and addition) var value: any; @@ -158,6 +160,8 @@ tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsVa null *= value; ~~~~ !!! error TS2364: The left-hand side of an assignment expression must be a variable or a property access. + ~~~~ +!!! error TS2531: Object is possibly 'null'. null += value; ~~~~ !!! error TS2364: The left-hand side of an assignment expression must be a variable or a property access. @@ -295,6 +299,8 @@ tests/cases/conformance/expressions/assignmentOperator/compoundAssignmentLHSIsVa (null) *= value; ~~~~~~ !!! error TS2364: The left-hand side of an assignment expression must be a variable or a property access. + ~~~~~~ +!!! error TS2531: Object is possibly 'null'. (null) += value; ~~~~~~ !!! error TS2364: The left-hand side of an assignment expression must be a variable or a property access. diff --git a/tests/baselines/reference/compoundExponentiationAssignmentLHSCanBeAssigned1.errors.txt b/tests/baselines/reference/compoundExponentiationAssignmentLHSCanBeAssigned1.errors.txt new file mode 100644 index 00000000000..26f23028dfa --- /dev/null +++ b/tests/baselines/reference/compoundExponentiationAssignmentLHSCanBeAssigned1.errors.txt @@ -0,0 +1,47 @@ +tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCanBeAssigned1.ts(11,8): error TS2531: Object is possibly 'null'. +tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCanBeAssigned1.ts(12,8): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCanBeAssigned1.ts(18,8): error TS2531: Object is possibly 'null'. +tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCanBeAssigned1.ts(19,8): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCanBeAssigned1.ts(25,8): error TS2531: Object is possibly 'null'. +tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCanBeAssigned1.ts(26,8): error TS2532: Object is possibly 'undefined'. + + +==== tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCanBeAssigned1.ts (6 errors) ==== + enum E { a, b, c } + + var a: any; + var b: number; + var c: E; + + var x1: any; + x1 **= a; + x1 **= b; + x1 **= c; + x1 **= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + x1 **= undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + var x2: number; + x2 **= a; + x2 **= b; + x2 **= c; + x2 **= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + x2 **= undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + var x3: E; + x3 **= a; + x3 **= b; + x3 **= c; + x3 **= null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + x3 **= undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. \ No newline at end of file diff --git a/tests/baselines/reference/compoundExponentiationAssignmentLHSCannotBeAssigned.errors.txt b/tests/baselines/reference/compoundExponentiationAssignmentLHSCannotBeAssigned.errors.txt index 8d152712808..6d48d968638 100644 --- a/tests/baselines/reference/compoundExponentiationAssignmentLHSCannotBeAssigned.errors.txt +++ b/tests/baselines/reference/compoundExponentiationAssignmentLHSCannotBeAssigned.errors.txt @@ -10,9 +10,9 @@ tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignm tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(13,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(13,8): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(14,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(14,8): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(14,8): error TS2531: Object is possibly 'null'. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(15,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(15,8): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(15,8): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(18,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(19,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(19,8): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -25,9 +25,9 @@ tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignm tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(24,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(24,8): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(25,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(25,8): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(25,8): error TS2531: Object is possibly 'null'. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(26,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(26,8): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(26,8): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(29,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(30,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(30,8): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -40,9 +40,9 @@ tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignm tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(35,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(35,8): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(36,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(36,8): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(36,8): error TS2531: Object is possibly 'null'. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(37,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(37,8): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(37,8): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(40,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(41,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(41,8): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -55,9 +55,9 @@ tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignm tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(46,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(46,8): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(47,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(47,8): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(47,8): error TS2531: Object is possibly 'null'. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(48,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(48,8): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(48,8): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(51,8): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(52,8): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSCannotBeAssigned.ts(53,8): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -108,12 +108,12 @@ tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignm ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. x1 **= undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var x2: string; x2 **= a; @@ -149,12 +149,12 @@ tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignm ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. x2 **= undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var x3: {}; x3 **= a; @@ -190,12 +190,12 @@ tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignm ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. x3 **= undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var x4: void; x4 **= a; @@ -231,12 +231,12 @@ tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignm ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. x4 **= undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var x5: number; x5 **= b; diff --git a/tests/baselines/reference/compoundExponentiationAssignmentLHSIsValue.errors.txt b/tests/baselines/reference/compoundExponentiationAssignmentLHSIsValue.errors.txt index 22eeb18ac4a..51b69f81620 100644 --- a/tests/baselines/reference/compoundExponentiationAssignmentLHSIsValue.errors.txt +++ b/tests/baselines/reference/compoundExponentiationAssignmentLHSIsValue.errors.txt @@ -8,6 +8,7 @@ tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignm tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(30,1): error TS2539: Cannot assign to 'E' because it is not a variable. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(32,1): error TS2539: Cannot assign to 'foo' because it is not a variable. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(35,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. +tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(35,1): error TS2531: Object is possibly 'null'. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(36,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(37,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(38,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. @@ -28,6 +29,7 @@ tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignm tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(75,2): error TS2539: Cannot assign to 'E' because it is not a variable. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(76,2): error TS2539: Cannot assign to 'foo' because it is not a variable. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(77,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. +tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(77,1): error TS2531: Object is possibly 'null'. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(78,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(79,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(80,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -38,7 +40,7 @@ tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignm tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(85,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -==== tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts (38 errors) ==== +==== tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts (40 errors) ==== // expected error for all the LHS of compound assignments (arithmetic and addition) var value: any; @@ -94,6 +96,8 @@ tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignm null **= value; ~~~~ !!! error TS2364: The left-hand side of an assignment expression must be a variable or a property access. + ~~~~ +!!! error TS2531: Object is possibly 'null'. true **= value; ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -176,6 +180,8 @@ tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignm (null) **= value; ~~~~~~ !!! error TS2364: The left-hand side of an assignment expression must be a variable or a property access. + ~~~~~~ +!!! error TS2531: Object is possibly 'null'. (true) **= value; ~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. diff --git a/tests/baselines/reference/computedPropertyNames10_ES5.types b/tests/baselines/reference/computedPropertyNames10_ES5.types index 650890fb10e..96130979298 100644 --- a/tests/baselines/reference/computedPropertyNames10_ES5.types +++ b/tests/baselines/reference/computedPropertyNames10_ES5.types @@ -9,8 +9,8 @@ var a: any; >a : any var v = { ->v : { [x: string]: () => void; [x: number]: () => void; [0](): void; [""](): void; } ->{ [s]() { }, [n]() { }, [s + s]() { }, [s + n]() { }, [+s]() { }, [""]() { }, [0]() { }, [a]() { }, [true]() { }, [`hello bye`]() { }, [`hello ${a} bye`]() { }} : { [x: string]: () => void; [x: number]: () => void; [0](): void; [""](): void; } +>v : { [x: string]: () => void; [x: number]: () => void; [""](): void; [0](): void; } +>{ [s]() { }, [n]() { }, [s + s]() { }, [s + n]() { }, [+s]() { }, [""]() { }, [0]() { }, [a]() { }, [true]() { }, [`hello bye`]() { }, [`hello ${a} bye`]() { }} : { [x: string]: () => void; [x: number]: () => void; [""](): void; [0](): void; } [s]() { }, >s : string diff --git a/tests/baselines/reference/computedPropertyNames10_ES6.types b/tests/baselines/reference/computedPropertyNames10_ES6.types index 2ff86ed9712..5bbda2e8f19 100644 --- a/tests/baselines/reference/computedPropertyNames10_ES6.types +++ b/tests/baselines/reference/computedPropertyNames10_ES6.types @@ -9,8 +9,8 @@ var a: any; >a : any var v = { ->v : { [x: string]: () => void; [x: number]: () => void; [0](): void; [""](): void; } ->{ [s]() { }, [n]() { }, [s + s]() { }, [s + n]() { }, [+s]() { }, [""]() { }, [0]() { }, [a]() { }, [true]() { }, [`hello bye`]() { }, [`hello ${a} bye`]() { }} : { [x: string]: () => void; [x: number]: () => void; [0](): void; [""](): void; } +>v : { [x: string]: () => void; [x: number]: () => void; [""](): void; [0](): void; } +>{ [s]() { }, [n]() { }, [s + s]() { }, [s + n]() { }, [+s]() { }, [""]() { }, [0]() { }, [a]() { }, [true]() { }, [`hello bye`]() { }, [`hello ${a} bye`]() { }} : { [x: string]: () => void; [x: number]: () => void; [""](): void; [0](): void; } [s]() { }, >s : string diff --git a/tests/baselines/reference/computedPropertyNames11_ES5.types b/tests/baselines/reference/computedPropertyNames11_ES5.types index 0787a889f40..88fbc690323 100644 --- a/tests/baselines/reference/computedPropertyNames11_ES5.types +++ b/tests/baselines/reference/computedPropertyNames11_ES5.types @@ -9,8 +9,8 @@ var a: any; >a : any var v = { ->v : { [x: string]: any; [x: number]: any; readonly [0]: number; [""]: any; } ->{ get [s]() { return 0; }, set [n](v) { }, get [s + s]() { return 0; }, set [s + n](v) { }, get [+s]() { return 0; }, set [""](v) { }, get [0]() { return 0; }, set [a](v) { }, get [true]() { return 0; }, set [`hello bye`](v) { }, get [`hello ${a} bye`]() { return 0; }} : { [x: string]: any; [x: number]: any; readonly [0]: number; [""]: any; } +>v : { [x: string]: any; [x: number]: any; [""]: any; readonly [0]: number; } +>{ get [s]() { return 0; }, set [n](v) { }, get [s + s]() { return 0; }, set [s + n](v) { }, get [+s]() { return 0; }, set [""](v) { }, get [0]() { return 0; }, set [a](v) { }, get [true]() { return 0; }, set [`hello bye`](v) { }, get [`hello ${a} bye`]() { return 0; }} : { [x: string]: any; [x: number]: any; [""]: any; readonly [0]: number; } get [s]() { return 0; }, >s : string diff --git a/tests/baselines/reference/computedPropertyNames11_ES6.types b/tests/baselines/reference/computedPropertyNames11_ES6.types index 4783d07a2af..458d6d1de49 100644 --- a/tests/baselines/reference/computedPropertyNames11_ES6.types +++ b/tests/baselines/reference/computedPropertyNames11_ES6.types @@ -9,8 +9,8 @@ var a: any; >a : any var v = { ->v : { [x: string]: any; [x: number]: any; readonly [0]: number; [""]: any; } ->{ get [s]() { return 0; }, set [n](v) { }, get [s + s]() { return 0; }, set [s + n](v) { }, get [+s]() { return 0; }, set [""](v) { }, get [0]() { return 0; }, set [a](v) { }, get [true]() { return 0; }, set [`hello bye`](v) { }, get [`hello ${a} bye`]() { return 0; }} : { [x: string]: any; [x: number]: any; readonly [0]: number; [""]: any; } +>v : { [x: string]: any; [x: number]: any; [""]: any; readonly [0]: number; } +>{ get [s]() { return 0; }, set [n](v) { }, get [s + s]() { return 0; }, set [s + n](v) { }, get [+s]() { return 0; }, set [""](v) { }, get [0]() { return 0; }, set [a](v) { }, get [true]() { return 0; }, set [`hello bye`](v) { }, get [`hello ${a} bye`]() { return 0; }} : { [x: string]: any; [x: number]: any; [""]: any; readonly [0]: number; } get [s]() { return 0; }, >s : string diff --git a/tests/baselines/reference/computedPropertyNames4_ES5.types b/tests/baselines/reference/computedPropertyNames4_ES5.types index 64ef5f6a611..6f875aaddac 100644 --- a/tests/baselines/reference/computedPropertyNames4_ES5.types +++ b/tests/baselines/reference/computedPropertyNames4_ES5.types @@ -9,8 +9,8 @@ var a: any; >a : any var v = { ->v : { [x: string]: string | number; [x: number]: string | number; [0]: number; [""]: number; } ->{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : { [x: string]: string | number; [x: number]: string | number; [0]: number; [""]: number; } +>v : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; } +>{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; } [s]: 0, >s : string diff --git a/tests/baselines/reference/computedPropertyNames4_ES6.types b/tests/baselines/reference/computedPropertyNames4_ES6.types index 0c608e21601..e9feac0a81f 100644 --- a/tests/baselines/reference/computedPropertyNames4_ES6.types +++ b/tests/baselines/reference/computedPropertyNames4_ES6.types @@ -9,8 +9,8 @@ var a: any; >a : any var v = { ->v : { [x: string]: string | number; [x: number]: string | number; [0]: number; [""]: number; } ->{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : { [x: string]: string | number; [x: number]: string | number; [0]: number; [""]: number; } +>v : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; } +>{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : { [x: string]: string | number; [x: number]: string | number; [""]: number; [0]: number; } [s]: 0, >s : string diff --git a/tests/baselines/reference/computedPropertyNamesContextualType6_ES5.types b/tests/baselines/reference/computedPropertyNamesContextualType6_ES5.types index 91ad88c8ade..f144bb9d020 100644 --- a/tests/baselines/reference/computedPropertyNamesContextualType6_ES5.types +++ b/tests/baselines/reference/computedPropertyNamesContextualType6_ES5.types @@ -19,7 +19,7 @@ declare function foo(obj: I): T foo({ >foo({ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : string | number | boolean | (() => void) | number[] >foo : (obj: I) => T ->{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: true | "" | (() => void) | 0 | number[]; [x: number]: (() => void) | 0 | number[]; 0: () => void; p: ""; } +>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: true | "" | (() => void) | 0 | number[]; [x: number]: (() => void) | 0 | number[]; p: ""; 0: () => void; } p: "", >p : string diff --git a/tests/baselines/reference/computedPropertyNamesContextualType6_ES6.types b/tests/baselines/reference/computedPropertyNamesContextualType6_ES6.types index 131e49dd173..6b8c8ae2e34 100644 --- a/tests/baselines/reference/computedPropertyNamesContextualType6_ES6.types +++ b/tests/baselines/reference/computedPropertyNamesContextualType6_ES6.types @@ -19,7 +19,7 @@ declare function foo(obj: I): T foo({ >foo({ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : string | number | boolean | (() => void) | number[] >foo : (obj: I) => T ->{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: true | "" | (() => void) | 0 | number[]; [x: number]: (() => void) | 0 | number[]; 0: () => void; p: ""; } +>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: true | "" | (() => void) | 0 | number[]; [x: number]: (() => void) | 0 | number[]; p: ""; 0: () => void; } p: "", >p : string diff --git a/tests/baselines/reference/contextuallyTypedIifeStrict.errors.txt b/tests/baselines/reference/contextuallyTypedIifeStrict.errors.txt new file mode 100644 index 00000000000..220204fc536 --- /dev/null +++ b/tests/baselines/reference/contextuallyTypedIifeStrict.errors.txt @@ -0,0 +1,45 @@ +tests/cases/conformance/expressions/functions/contextuallyTypedIifeStrict.ts(14,10): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/functions/contextuallyTypedIifeStrict.ts(15,10): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/functions/contextuallyTypedIifeStrict.ts(16,17): error TS2532: Object is possibly 'undefined'. + + +==== tests/cases/conformance/expressions/functions/contextuallyTypedIifeStrict.ts (3 errors) ==== + // arrow + (jake => { })("build"); + // function expression + (function (cats) { })("lol"); + // Lots of Irritating Superfluous Parentheses + (function (x) { } ("!")); + ((((function (y) { }))))("-"); + // multiple arguments + ((a, b, c) => { })("foo", 101, false); + // default parameters + ((m = 10) => m + 1)(12); + ((n = 10) => n + 1)(); + // optional parameters + ((j?) => j + 1)(12); + ~ +!!! error TS2532: Object is possibly 'undefined'. + ((k?) => k + 1)(); + ~ +!!! error TS2532: Object is possibly 'undefined'. + ((l, o?) => l + o)(12); // o should be any + ~ +!!! error TS2532: Object is possibly 'undefined'. + // rest parameters + ((...numbers) => numbers.every(n => n > 0))(5,6,7); + ((...mixed) => mixed.every(n => !!n))(5,'oops','oh no'); + ((...noNumbers) => noNumbers.some(n => n > 0))(); + ((first, ...rest) => first ? [] : rest.map(n => n > 0))(8,9,10); + // destructuring parameters (with defaults too!) + (({ q }) => q)({ q : 13 }); + (({ p = 14 }) => p)({ p : 15 }); + (({ r = 17 } = { r: 18 }) => r)({r : 19}); + (({ u = 22 } = { u: 23 }) => u)(); + // contextually typed parameters. + let twelve = (f => f(12))(i => i); + let eleven = (o => o.a(11))({ a: function(n) { return n; } }); + // missing arguments + (function(x, undefined) { return x; })(42); + ((x, y, z) => 42)(); + \ No newline at end of file diff --git a/tests/baselines/reference/decrementOperatorWithAnyOtherTypeInvalidOperations.errors.txt b/tests/baselines/reference/decrementOperatorWithAnyOtherTypeInvalidOperations.errors.txt index e42b6ff67b4..33e31bc9478 100644 --- a/tests/baselines/reference/decrementOperatorWithAnyOtherTypeInvalidOperations.errors.txt +++ b/tests/baselines/reference/decrementOperatorWithAnyOtherTypeInvalidOperations.errors.txt @@ -9,29 +9,37 @@ tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOp tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(33,23): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(34,24): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(37,26): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(38,26): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(38,26): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. +tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(38,26): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(39,26): error TS2539: Cannot assign to 'undefined' because it is not a variable. -tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(41,24): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(41,24): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. +tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(41,24): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(42,24): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(43,24): error TS2539: Cannot assign to 'undefined' because it is not a variable. tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(46,26): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(47,26): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(48,26): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. -tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(48,27): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. +tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(48,27): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(48,34): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(49,26): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. -tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(49,27): error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. +tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(49,27): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(49,34): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(50,26): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. -tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(50,27): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. +tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(50,27): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(50,39): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(51,26): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(52,26): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(54,24): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(55,24): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(56,24): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. -tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(56,25): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. +tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(56,25): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(56,32): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(57,24): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. -tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(57,25): error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. +tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(57,25): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(57,32): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(58,24): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. -tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(58,25): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. +tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(58,25): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(58,37): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(59,24): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(60,24): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(63,3): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. @@ -50,7 +58,7 @@ tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOp tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts(72,12): error TS1109: Expression expected. -==== tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts (50 errors) ==== +==== tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithAnyOtherTypeInvalidOperations.ts (58 errors) ==== // -- operator on any type var ANY1: any; var ANY2: any[] = ["", ""]; @@ -112,14 +120,18 @@ tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOp !!! error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. var ResultIsNumber12 = --null; ~~~~ -!!! error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. +!!! error TS2357: The operand of an increment or decrement operator must be a variable or a property access. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var ResultIsNumber13 = --undefined; ~~~~~~~~~ !!! error TS2539: Cannot assign to 'undefined' because it is not a variable. var ResultIsNumber14 = null--; ~~~~ -!!! error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. +!!! error TS2357: The operand of an increment or decrement operator must be a variable or a property access. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var ResultIsNumber15 = {}--; ~~ !!! error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. @@ -137,18 +149,24 @@ tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOp var ResultIsNumber19 = --(null + undefined); ~~~~~~~~~~~~~~~~~~ !!! error TS2357: The operand of an increment or decrement operator must be a variable or a property access. - ~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var ResultIsNumber20 = --(null + null); ~~~~~~~~~~~~~ !!! error TS2357: The operand of an increment or decrement operator must be a variable or a property access. - ~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var ResultIsNumber21 = --(undefined + undefined); ~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2357: The operand of an increment or decrement operator must be a variable or a property access. - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var ResultIsNumber22 = --obj1.x; ~~~~~~ !!! error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. @@ -165,18 +183,24 @@ tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOp var ResultIsNumber26 = (null + undefined)--; ~~~~~~~~~~~~~~~~~~ !!! error TS2357: The operand of an increment or decrement operator must be a variable or a property access. - ~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var ResultIsNumber27 = (null + null)--; ~~~~~~~~~~~~~ !!! error TS2357: The operand of an increment or decrement operator must be a variable or a property access. - ~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var ResultIsNumber28 = (undefined + undefined)--; ~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2357: The operand of an increment or decrement operator must be a variable or a property access. - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var ResultIsNumber29 = obj1.x--; ~~~~~~ !!! error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. diff --git a/tests/baselines/reference/deleteOperatorWithAnyOtherType.errors.txt b/tests/baselines/reference/deleteOperatorWithAnyOtherType.errors.txt index 69153fc235c..819f1c39050 100644 --- a/tests/baselines/reference/deleteOperatorWithAnyOtherType.errors.txt +++ b/tests/baselines/reference/deleteOperatorWithAnyOtherType.errors.txt @@ -9,12 +9,15 @@ tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperator tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(42,32): error TS2703: The operand of a delete operator must be a property reference tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(43,32): error TS2703: The operand of a delete operator must be a property reference tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(44,33): error TS2703: The operand of a delete operator must be a property reference -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(45,33): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(45,33): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(45,33): error TS2703: The operand of a delete operator must be a property reference -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(46,33): error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(45,40): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(46,33): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(46,33): error TS2703: The operand of a delete operator must be a property reference -tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(47,33): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(46,40): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(47,33): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(47,33): error TS2703: The operand of a delete operator must be a property reference +tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(47,45): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(50,32): error TS2703: The operand of a delete operator must be a property reference tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(50,39): error TS2703: The operand of a delete operator must be a property reference tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(51,32): error TS2703: The operand of a delete operator must be a property reference @@ -25,7 +28,7 @@ tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperator tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts(57,8): error TS2703: The operand of a delete operator must be a property reference -==== tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts (25 errors) ==== +==== tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperatorWithAnyOtherType.ts (28 errors) ==== // delete operator on any type var ANY: any; @@ -93,20 +96,26 @@ tests/cases/conformance/expressions/unaryOperators/deleteOperator/deleteOperator ~~~~~~~~~~ !!! error TS2703: The operand of a delete operator must be a property reference var ResultIsBoolean17 = delete (null + undefined); - ~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. ~~~~~~~~~~~~~~~~ !!! error TS2703: The operand of a delete operator must be a property reference + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var ResultIsBoolean18 = delete (null + null); - ~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. ~~~~~~~~~~~ !!! error TS2703: The operand of a delete operator must be a property reference + ~~~~ +!!! error TS2531: Object is possibly 'null'. var ResultIsBoolean19 = delete (undefined + undefined); - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. ~~~~~~~~~~~~~~~~~~~~~ !!! error TS2703: The operand of a delete operator must be a property reference + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. // multiple delete operators var ResultIsBoolean20 = delete delete ANY; diff --git a/tests/baselines/reference/destructuringPropertyAssignmentNameIsNotAssignmentTarget.js b/tests/baselines/reference/destructuringPropertyAssignmentNameIsNotAssignmentTarget.js new file mode 100644 index 00000000000..b2ba970ef51 --- /dev/null +++ b/tests/baselines/reference/destructuringPropertyAssignmentNameIsNotAssignmentTarget.js @@ -0,0 +1,17 @@ +//// [destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts] +// test for #10668 +function qux(bar: { value: number }) { + let foo: number; + ({ value: foo } = bar); + let x = () => bar; +} + + + +//// [destructuringPropertyAssignmentNameIsNotAssignmentTarget.js] +// test for #10668 +function qux(bar) { + var foo; + (foo = bar.value); + var x = function () { return bar; }; +} diff --git a/tests/baselines/reference/destructuringPropertyAssignmentNameIsNotAssignmentTarget.symbols b/tests/baselines/reference/destructuringPropertyAssignmentNameIsNotAssignmentTarget.symbols new file mode 100644 index 00000000000..b9ebe219f65 --- /dev/null +++ b/tests/baselines/reference/destructuringPropertyAssignmentNameIsNotAssignmentTarget.symbols @@ -0,0 +1,21 @@ +=== tests/cases/compiler/destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts === +// test for #10668 +function qux(bar: { value: number }) { +>qux : Symbol(qux, Decl(destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts, 0, 0)) +>bar : Symbol(bar, Decl(destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts, 1, 13)) +>value : Symbol(value, Decl(destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts, 1, 19)) + + let foo: number; +>foo : Symbol(foo, Decl(destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts, 2, 7)) + + ({ value: foo } = bar); +>value : Symbol(value, Decl(destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts, 3, 6)) +>foo : Symbol(foo, Decl(destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts, 2, 7)) +>bar : Symbol(bar, Decl(destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts, 1, 13)) + + let x = () => bar; +>x : Symbol(x, Decl(destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts, 4, 7)) +>bar : Symbol(bar, Decl(destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts, 1, 13)) +} + + diff --git a/tests/baselines/reference/destructuringPropertyAssignmentNameIsNotAssignmentTarget.types b/tests/baselines/reference/destructuringPropertyAssignmentNameIsNotAssignmentTarget.types new file mode 100644 index 00000000000..e0428fc959f --- /dev/null +++ b/tests/baselines/reference/destructuringPropertyAssignmentNameIsNotAssignmentTarget.types @@ -0,0 +1,25 @@ +=== tests/cases/compiler/destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts === +// test for #10668 +function qux(bar: { value: number }) { +>qux : (bar: { value: number; }) => void +>bar : { value: number; } +>value : number + + let foo: number; +>foo : number + + ({ value: foo } = bar); +>({ value: foo } = bar) : { value: number; } +>{ value: foo } = bar : { value: number; } +>{ value: foo } : { value: number; } +>value : number +>foo : number +>bar : { value: number; } + + let x = () => bar; +>x : () => { value: number; } +>() => bar : () => { value: number; } +>bar : { value: number; } +} + + diff --git a/tests/baselines/reference/emitCompoundExponentiationAssignmentWithIndexingOnLHS3.types b/tests/baselines/reference/emitCompoundExponentiationAssignmentWithIndexingOnLHS3.types index 94a5f2173aa..32e5b33e411 100644 --- a/tests/baselines/reference/emitCompoundExponentiationAssignmentWithIndexingOnLHS3.types +++ b/tests/baselines/reference/emitCompoundExponentiationAssignmentWithIndexingOnLHS3.types @@ -1,8 +1,8 @@ === tests/cases/conformance/es7/exponentiationOperator/emitCompoundExponentiationAssignmentWithIndexingOnLHS3.ts === var object = { ->object : { 0: number; _0: number; } ->{ _0: 2, get 0() { return this._0; }, set 0(x: number) { this._0 = x; },} : { 0: number; _0: number; } +>object : { _0: number; 0: number; } +>{ _0: 2, get 0() { return this._0; }, set 0(x: number) { this._0 = x; },} : { _0: number; 0: number; } _0: 2, >_0 : number @@ -30,31 +30,31 @@ var object = { object[0] **= object[0]; >object[0] **= object[0] : number >object[0] : number ->object : { 0: number; _0: number; } +>object : { _0: number; 0: number; } >0 : 0 >object[0] : number ->object : { 0: number; _0: number; } +>object : { _0: number; 0: number; } >0 : 0 object[0] **= object[0] **= 2; >object[0] **= object[0] **= 2 : number >object[0] : number ->object : { 0: number; _0: number; } +>object : { _0: number; 0: number; } >0 : 0 >object[0] **= 2 : number >object[0] : number ->object : { 0: number; _0: number; } +>object : { _0: number; 0: number; } >0 : 0 >2 : 2 object[0] **= object[0] ** 2; >object[0] **= object[0] ** 2 : number >object[0] : number ->object : { 0: number; _0: number; } +>object : { _0: number; 0: number; } >0 : 0 >object[0] ** 2 : number >object[0] : number ->object : { 0: number; _0: number; } +>object : { _0: number; 0: number; } >0 : 0 >2 : 2 diff --git a/tests/baselines/reference/emitExponentiationOperator4.errors.txt b/tests/baselines/reference/emitExponentiationOperator4.errors.txt new file mode 100644 index 00000000000..e8f46874ad8 --- /dev/null +++ b/tests/baselines/reference/emitExponentiationOperator4.errors.txt @@ -0,0 +1,70 @@ +tests/cases/conformance/es7/exponentiationOperator/emitExponentiationOperator4.ts(14,1): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/es7/exponentiationOperator/emitExponentiationOperator4.ts(15,1): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/es7/exponentiationOperator/emitExponentiationOperator4.ts(16,1): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/es7/exponentiationOperator/emitExponentiationOperator4.ts(17,1): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/es7/exponentiationOperator/emitExponentiationOperator4.ts(18,1): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/es7/exponentiationOperator/emitExponentiationOperator4.ts(21,6): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/es7/exponentiationOperator/emitExponentiationOperator4.ts(22,6): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/es7/exponentiationOperator/emitExponentiationOperator4.ts(23,6): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/es7/exponentiationOperator/emitExponentiationOperator4.ts(24,6): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/es7/exponentiationOperator/emitExponentiationOperator4.ts(25,6): error TS2532: Object is possibly 'undefined'. + + +==== tests/cases/conformance/es7/exponentiationOperator/emitExponentiationOperator4.ts (10 errors) ==== + var temp: any; + + (temp) ** 3; + (--temp) ** 3; + (++temp) ** 3; + (temp--) ** 3; + (temp++) ** 3; + + 1 ** (--temp) ** 3; + 1 ** (++temp) ** 3; + 1 ** (temp--) ** 3; + 1 ** (temp++) ** 3; + + (void --temp) ** 3; + ~~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + (void temp--) ** 3; + ~~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + (void 3) ** 4; + ~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + (void temp++) ** 4; + ~~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + (void temp--) ** 4; + ~~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + + 1 ** (void --temp) ** 3; + ~~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + 1 ** (void temp--) ** 3; + ~~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + 1 ** (void 3) ** 4; + ~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + 1 ** (void temp++) ** 4; + ~~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + 1 ** (void temp--) ** 4; + ~~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + + (~ --temp) ** 3; + (~ temp--) ** 3; + (~ 3) ** 4; + (~ temp++) ** 4; + (~ temp--) ** 4; + + 1 ** (~ --temp) ** 3; + 1 ** (~ temp--) ** 3; + 1 ** (~ 3) ** 4; + 1 ** (~ temp++) ** 4; + 1 ** (~ temp--) ** 4; \ No newline at end of file diff --git a/tests/baselines/reference/equalityStrictNulls.errors.txt b/tests/baselines/reference/equalityStrictNulls.errors.txt index e0793542b84..16772d8eeab 100644 --- a/tests/baselines/reference/equalityStrictNulls.errors.txt +++ b/tests/baselines/reference/equalityStrictNulls.errors.txt @@ -1,7 +1,7 @@ -tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts(60,9): error TS2365: Operator '>' cannot be applied to types 'number' and 'undefined'. -tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts(62,9): error TS2365: Operator '<' cannot be applied to types 'number' and 'undefined'. -tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts(64,9): error TS2365: Operator '>=' cannot be applied to types 'number' and 'undefined'. -tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts(66,9): error TS2365: Operator '<=' cannot be applied to types 'number' and 'undefined'. +tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts(60,13): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts(62,13): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts(64,14): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts(66,14): error TS2532: Object is possibly 'undefined'. ==== tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts (4 errors) ==== @@ -65,20 +65,20 @@ tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.t function f4(x: number) { if (x > undefined) { - ~~~~~~~~~~~~~ -!!! error TS2365: Operator '>' cannot be applied to types 'number' and 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. } if (x < undefined) { - ~~~~~~~~~~~~~ -!!! error TS2365: Operator '<' cannot be applied to types 'number' and 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. } if (x >= undefined) { - ~~~~~~~~~~~~~~ -!!! error TS2365: Operator '>=' cannot be applied to types 'number' and 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. } if (x <= undefined) { - ~~~~~~~~~~~~~~ -!!! error TS2365: Operator '<=' cannot be applied to types 'number' and 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. } } function f5(x: string) { diff --git a/tests/baselines/reference/es3-jsx-preserve.js b/tests/baselines/reference/es3-jsx-preserve.js new file mode 100644 index 00000000000..cb1ba2a887d --- /dev/null +++ b/tests/baselines/reference/es3-jsx-preserve.js @@ -0,0 +1,11 @@ +//// [es3-jsx-preserve.tsx] + +const React: any = null; + +const elem =
; + + + +//// [es3-jsx-preserve.jsx] +var React = null; +var elem =
; diff --git a/tests/baselines/reference/es3-jsx-preserve.symbols b/tests/baselines/reference/es3-jsx-preserve.symbols new file mode 100644 index 00000000000..61c9260223f --- /dev/null +++ b/tests/baselines/reference/es3-jsx-preserve.symbols @@ -0,0 +1,11 @@ +=== tests/cases/compiler/es3-jsx-preserve.tsx === + +const React: any = null; +>React : Symbol(React, Decl(es3-jsx-preserve.tsx, 1, 5)) + +const elem =
; +>elem : Symbol(elem, Decl(es3-jsx-preserve.tsx, 3, 5)) +>div : Symbol(unknown) +>div : Symbol(unknown) + + diff --git a/tests/baselines/reference/es3-jsx-preserve.types b/tests/baselines/reference/es3-jsx-preserve.types new file mode 100644 index 00000000000..b37fe8af567 --- /dev/null +++ b/tests/baselines/reference/es3-jsx-preserve.types @@ -0,0 +1,13 @@ +=== tests/cases/compiler/es3-jsx-preserve.tsx === + +const React: any = null; +>React : any +>null : null + +const elem =
; +>elem : any +>
: any +>div : any +>div : any + + diff --git a/tests/baselines/reference/es3-jsx-react-native.js b/tests/baselines/reference/es3-jsx-react-native.js new file mode 100644 index 00000000000..08e6e25502b --- /dev/null +++ b/tests/baselines/reference/es3-jsx-react-native.js @@ -0,0 +1,11 @@ +//// [es3-jsx-react-native.tsx] + +const React: any = null; + +const elem =
; + + + +//// [es3-jsx-react-native.js] +var React = null; +var elem =
; diff --git a/tests/baselines/reference/es3-jsx-react-native.symbols b/tests/baselines/reference/es3-jsx-react-native.symbols new file mode 100644 index 00000000000..e7f010bd2ea --- /dev/null +++ b/tests/baselines/reference/es3-jsx-react-native.symbols @@ -0,0 +1,11 @@ +=== tests/cases/compiler/es3-jsx-react-native.tsx === + +const React: any = null; +>React : Symbol(React, Decl(es3-jsx-react-native.tsx, 1, 5)) + +const elem =
; +>elem : Symbol(elem, Decl(es3-jsx-react-native.tsx, 3, 5)) +>div : Symbol(unknown) +>div : Symbol(unknown) + + diff --git a/tests/baselines/reference/es3-jsx-react-native.types b/tests/baselines/reference/es3-jsx-react-native.types new file mode 100644 index 00000000000..1bf199606f2 --- /dev/null +++ b/tests/baselines/reference/es3-jsx-react-native.types @@ -0,0 +1,13 @@ +=== tests/cases/compiler/es3-jsx-react-native.tsx === + +const React: any = null; +>React : any +>null : null + +const elem =
; +>elem : any +>
: any +>div : any +>div : any + + diff --git a/tests/baselines/reference/es3-jsx-react.js b/tests/baselines/reference/es3-jsx-react.js new file mode 100644 index 00000000000..861dde74c86 --- /dev/null +++ b/tests/baselines/reference/es3-jsx-react.js @@ -0,0 +1,11 @@ +//// [es3-jsx-react.tsx] + +const React: any = null; + +const elem =
; + + + +//// [es3-jsx-react.js] +var React = null; +var elem = React.createElement("div", null); diff --git a/tests/baselines/reference/es3-jsx-react.symbols b/tests/baselines/reference/es3-jsx-react.symbols new file mode 100644 index 00000000000..465cfab7ea9 --- /dev/null +++ b/tests/baselines/reference/es3-jsx-react.symbols @@ -0,0 +1,11 @@ +=== tests/cases/compiler/es3-jsx-react.tsx === + +const React: any = null; +>React : Symbol(React, Decl(es3-jsx-react.tsx, 1, 5)) + +const elem =
; +>elem : Symbol(elem, Decl(es3-jsx-react.tsx, 3, 5)) +>div : Symbol(unknown) +>div : Symbol(unknown) + + diff --git a/tests/baselines/reference/es3-jsx-react.types b/tests/baselines/reference/es3-jsx-react.types new file mode 100644 index 00000000000..b7734ffc1f0 --- /dev/null +++ b/tests/baselines/reference/es3-jsx-react.types @@ -0,0 +1,13 @@ +=== tests/cases/compiler/es3-jsx-react.tsx === + +const React: any = null; +>React : any +>null : null + +const elem =
; +>elem : any +>
: any +>div : any +>div : any + + diff --git a/tests/baselines/reference/exponentiationOperatorSyntaxError2.errors.txt b/tests/baselines/reference/exponentiationOperatorSyntaxError2.errors.txt index 6ac93ecf27a..1075c505794 100644 --- a/tests/baselines/reference/exponentiationOperatorSyntaxError2.errors.txt +++ b/tests/baselines/reference/exponentiationOperatorSyntaxError2.errors.txt @@ -42,15 +42,25 @@ tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxE tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(25,6): error TS17006: An unary expression with the 'typeof' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(26,6): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(26,6): error TS17006: An unary expression with the 'typeof' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(28,1): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(28,1): error TS17006: An unary expression with the 'void' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(29,1): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(29,1): error TS17006: An unary expression with the 'void' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(30,1): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(30,1): error TS17006: An unary expression with the 'void' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(31,1): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(31,1): error TS17006: An unary expression with the 'void' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(32,1): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(32,1): error TS17006: An unary expression with the 'void' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(34,6): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(34,6): error TS17006: An unary expression with the 'void' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(35,6): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(35,6): error TS17006: An unary expression with the 'void' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(36,6): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(36,6): error TS17006: An unary expression with the 'void' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(37,6): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(37,6): error TS17006: An unary expression with the 'void' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(38,6): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(38,6): error TS17006: An unary expression with the 'void' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(40,1): error TS17006: An unary expression with the '~' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(41,1): error TS17006: An unary expression with the '~' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. @@ -89,7 +99,7 @@ tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxE tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts(68,1): error TS17007: A type assertion expression is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. -==== tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts (89 errors) ==== +==== tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxError2.ts (99 errors) ==== // Error: early syntax error using ES7 SimpleUnaryExpression on left-hand side without () var temp: any; @@ -207,34 +217,54 @@ tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorSyntaxE void --temp ** 3; ~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~~~ !!! error TS17006: An unary expression with the 'void' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. void temp-- ** 3; ~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~~~ !!! error TS17006: An unary expression with the 'void' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. void 3 ** 4; ~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~ !!! error TS17006: An unary expression with the 'void' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. void temp++ ** 4; ~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~~~ !!! error TS17006: An unary expression with the 'void' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. void temp-- ** 4; ~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~~~ !!! error TS17006: An unary expression with the 'void' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. 1 ** void --temp ** 3; ~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~~~ !!! error TS17006: An unary expression with the 'void' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. 1 ** void temp-- ** 3; ~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~~~ !!! error TS17006: An unary expression with the 'void' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. 1 ** void 3 ** 4; ~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~ !!! error TS17006: An unary expression with the 'void' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. 1 ** void temp++ ** 4; ~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~~~ !!! error TS17006: An unary expression with the 'void' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. 1 ** void temp-- ** 4 ; ~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~~~ !!! error TS17006: An unary expression with the 'void' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses. ~ --temp ** 3; diff --git a/tests/baselines/reference/exponentiationOperatorWithNullValueAndInvalidOperands.errors.txt b/tests/baselines/reference/exponentiationOperatorWithNullValueAndInvalidOperands.errors.txt index 99535985628..2d0b76f28cc 100644 --- a/tests/baselines/reference/exponentiationOperatorWithNullValueAndInvalidOperands.errors.txt +++ b/tests/baselines/reference/exponentiationOperatorWithNullValueAndInvalidOperands.errors.txt @@ -1,27 +1,27 @@ -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(9,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(9,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(9,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(10,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(10,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(10,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(11,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(11,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(11,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(13,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(13,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(13,17): error TS2531: Object is possibly 'null'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(14,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(14,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(14,17): error TS2531: Object is possibly 'null'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(15,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(15,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(17,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(15,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(17,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(17,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(18,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(18,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(18,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(19,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(19,12): error TS2531: Object is possibly 'null'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(19,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(21,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(21,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(21,20): error TS2531: Object is possibly 'null'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(22,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(22,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(22,18): error TS2531: Object is possibly 'null'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(23,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(23,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts(23,18): error TS2531: Object is possibly 'null'. ==== tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndInvalidOperands.ts (24 errors) ==== @@ -35,17 +35,17 @@ tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNul // operator ** var r1a1 = null ** a; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r1a2 = null ** b; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r1a3 = null ** c; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -53,31 +53,31 @@ tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNul ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r1b2 = b ** null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r1b3 = c ** null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r1c1 = null ** true; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r1c2 = null ** ''; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r1c3 = null ** {}; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -85,14 +85,14 @@ tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNul ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r1d2 = '' ** null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r1d3 = {} ** null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. \ No newline at end of file +!!! error TS2531: Object is possibly 'null'. \ No newline at end of file diff --git a/tests/baselines/reference/exponentiationOperatorWithNullValueAndValidOperands.errors.txt b/tests/baselines/reference/exponentiationOperatorWithNullValueAndValidOperands.errors.txt new file mode 100644 index 00000000000..c8a462c0f54 --- /dev/null +++ b/tests/baselines/reference/exponentiationOperatorWithNullValueAndValidOperands.errors.txt @@ -0,0 +1,47 @@ +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndValidOperands.ts(13,10): error TS2531: Object is possibly 'null'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndValidOperands.ts(14,10): error TS2531: Object is possibly 'null'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndValidOperands.ts(15,10): error TS2531: Object is possibly 'null'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndValidOperands.ts(16,10): error TS2531: Object is possibly 'null'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndValidOperands.ts(17,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndValidOperands.ts(18,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndValidOperands.ts(19,15): error TS2531: Object is possibly 'null'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndValidOperands.ts(20,17): error TS2531: Object is possibly 'null'. + + +==== tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithNullValueAndValidOperands.ts (8 errors) ==== + // If one operand is the null or undefined value, it is treated as having the type of the + // other operand. + + enum E { + a, + b + } + + var a: any; + var b: number; + + // operator ** + var r1 = null ** a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r2 = null ** b; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r3 = null ** 1; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r4 = null ** E.a; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r5 = a ** null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r6 = b ** null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r7 = 0 ** null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var r8 = E.b ** null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. \ No newline at end of file diff --git a/tests/baselines/reference/exponentiationOperatorWithOnlyNullValueOrUndefinedValue.errors.txt b/tests/baselines/reference/exponentiationOperatorWithOnlyNullValueOrUndefinedValue.errors.txt index 86f4930e77c..20b004625ca 100644 --- a/tests/baselines/reference/exponentiationOperatorWithOnlyNullValueOrUndefinedValue.errors.txt +++ b/tests/baselines/reference/exponentiationOperatorWithOnlyNullValueOrUndefinedValue.errors.txt @@ -1,33 +1,33 @@ -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithOnlyNullValueOrUndefinedValue.ts(2,10): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithOnlyNullValueOrUndefinedValue.ts(2,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithOnlyNullValueOrUndefinedValue.ts(3,10): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithOnlyNullValueOrUndefinedValue.ts(3,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithOnlyNullValueOrUndefinedValue.ts(4,10): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithOnlyNullValueOrUndefinedValue.ts(4,23): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithOnlyNullValueOrUndefinedValue.ts(5,10): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithOnlyNullValueOrUndefinedValue.ts(5,23): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithOnlyNullValueOrUndefinedValue.ts(2,10): error TS2531: Object is possibly 'null'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithOnlyNullValueOrUndefinedValue.ts(2,18): error TS2531: Object is possibly 'null'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithOnlyNullValueOrUndefinedValue.ts(3,10): error TS2531: Object is possibly 'null'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithOnlyNullValueOrUndefinedValue.ts(3,18): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithOnlyNullValueOrUndefinedValue.ts(4,10): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithOnlyNullValueOrUndefinedValue.ts(4,23): error TS2531: Object is possibly 'null'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithOnlyNullValueOrUndefinedValue.ts(5,10): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithOnlyNullValueOrUndefinedValue.ts(5,23): error TS2532: Object is possibly 'undefined'. ==== tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithOnlyNullValueOrUndefinedValue.ts (8 errors) ==== // operator ** var r1 = null ** null; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r2 = null ** undefined; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r3 = undefined ** null; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var r4 = undefined ** undefined; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. \ No newline at end of file diff --git a/tests/baselines/reference/exponentiationOperatorWithUndefinedValueAndInvalidOperands.errors.txt b/tests/baselines/reference/exponentiationOperatorWithUndefinedValueAndInvalidOperands.errors.txt index f456e0f554f..ce14298d02d 100644 --- a/tests/baselines/reference/exponentiationOperatorWithUndefinedValueAndInvalidOperands.errors.txt +++ b/tests/baselines/reference/exponentiationOperatorWithUndefinedValueAndInvalidOperands.errors.txt @@ -1,27 +1,27 @@ -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(9,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(9,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(9,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(10,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(10,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(10,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(11,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(11,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(11,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(13,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(13,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(13,17): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(14,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(14,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(14,17): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(15,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(15,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(17,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(15,17): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(17,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(17,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(18,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(18,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(18,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(19,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(19,12): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(19,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(21,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(21,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(21,20): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(22,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(22,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(22,18): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(23,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(23,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts(23,18): error TS2532: Object is possibly 'undefined'. ==== tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndInvalidOperands.ts (24 errors) ==== @@ -35,17 +35,17 @@ tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUnd // operator ** var r1a1 = undefined ** a; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r1a2 = undefined ** b; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r1a3 = undefined ** c; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -53,31 +53,31 @@ tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUnd ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r1b2 = b ** undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r1b3 = c ** undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r1c1 = undefined ** true; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r1c2 = undefined ** ''; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r1c3 = undefined ** {}; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -85,14 +85,14 @@ tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUnd ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r1d2 = '' ** undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var r1d3 = {} ** undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. \ No newline at end of file +!!! error TS2532: Object is possibly 'undefined'. \ No newline at end of file diff --git a/tests/baselines/reference/exponentiationOperatorWithUndefinedValueAndValidOperands.errors.txt b/tests/baselines/reference/exponentiationOperatorWithUndefinedValueAndValidOperands.errors.txt new file mode 100644 index 00000000000..ce9843a9612 --- /dev/null +++ b/tests/baselines/reference/exponentiationOperatorWithUndefinedValueAndValidOperands.errors.txt @@ -0,0 +1,47 @@ +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndValidOperands.ts(13,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndValidOperands.ts(14,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndValidOperands.ts(15,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndValidOperands.ts(16,11): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndValidOperands.ts(17,16): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndValidOperands.ts(18,16): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndValidOperands.ts(19,16): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndValidOperands.ts(20,18): error TS2532: Object is possibly 'undefined'. + + +==== tests/cases/conformance/es7/exponentiationOperator/exponentiationOperatorWithUndefinedValueAndValidOperands.ts (8 errors) ==== + // If one operand is the undefined or undefined value, it is treated as having the type of the + // other operand. + + enum E { + a, + b + } + + var a: any; + var b: number; + + // operator * + var rk1 = undefined ** a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rk2 = undefined ** b; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rk3 = undefined ** 1; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rk4 = undefined ** E.a; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rk5 = a ** undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rk6 = b ** undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rk7 = 0 ** undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + var rk8 = E.b ** undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. \ No newline at end of file diff --git a/tests/baselines/reference/functionsMissingReturnStatementsAndExpressions.errors.txt b/tests/baselines/reference/functionsMissingReturnStatementsAndExpressions.errors.txt index 1ccc296b75b..e0c552141b2 100644 --- a/tests/baselines/reference/functionsMissingReturnStatementsAndExpressions.errors.txt +++ b/tests/baselines/reference/functionsMissingReturnStatementsAndExpressions.errors.txt @@ -1,10 +1,11 @@ tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts(3,16): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts(101,17): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts(106,16): error TS2378: A 'get' accessor must return a value. +tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts(128,15): error TS2532: Object is possibly 'undefined'. tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts(129,5): error TS1003: Identifier expected. -==== tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts (4 errors) ==== +==== tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts (5 errors) ==== function f1(): string { @@ -139,6 +140,8 @@ tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts(129,5): e // if no return statements are present but we are a get accessor. throw null; throw undefined. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. } ~ !!! error TS1003: Identifier expected. diff --git a/tests/baselines/reference/globalAugmentationModuleResolution.types b/tests/baselines/reference/globalAugmentationModuleResolution.types index c057ea2943d..75f23b0cd6b 100644 --- a/tests/baselines/reference/globalAugmentationModuleResolution.types +++ b/tests/baselines/reference/globalAugmentationModuleResolution.types @@ -3,7 +3,7 @@ export { }; declare global { ->global : any +>global : typeof global var x: number; >x : number diff --git a/tests/baselines/reference/importHelpersES6.js b/tests/baselines/reference/importHelpersES6.js index 209f3c34588..bc17939e2cc 100644 --- a/tests/baselines/reference/importHelpersES6.js +++ b/tests/baselines/reference/importHelpersES6.js @@ -5,10 +5,12 @@ declare var dec: any; @dec export class A { } + +const o = { a: 1 }; +const y = { ...o }; //// [tslib.d.ts] export declare function __extends(d: Function, b: Function): void; -export declare function __assign(t: any, ...sources: any[]): any; export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any; export declare function __param(paramIndex: number, decorator: Function): Function; export declare function __metadata(metadataKey: any, metadataValue: any): Function; @@ -23,3 +25,5 @@ A = tslib_1.__decorate([ dec ], A); export { A }; +const o = { a: 1 }; +const y = Object.assign({}, o); diff --git a/tests/baselines/reference/importHelpersES6.symbols b/tests/baselines/reference/importHelpersES6.symbols index 284a2251a6b..66a8b131aec 100644 --- a/tests/baselines/reference/importHelpersES6.symbols +++ b/tests/baselines/reference/importHelpersES6.symbols @@ -8,6 +8,14 @@ declare var dec: any; } +const o = { a: 1 }; +>o : Symbol(o, Decl(a.ts, 5, 5)) +>a : Symbol(a, Decl(a.ts, 5, 11)) + +const y = { ...o }; +>y : Symbol(y, Decl(a.ts, 6, 5)) +>o : Symbol(o, Decl(a.ts, 5, 5)) + === tests/cases/compiler/tslib.d.ts === export declare function __extends(d: Function, b: Function): void; >__extends : Symbol(__extends, Decl(tslib.d.ts, --, --)) @@ -16,11 +24,6 @@ export declare function __extends(d: Function, b: Function): void; >b : Symbol(b, Decl(tslib.d.ts, --, --)) >Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) -export declare function __assign(t: any, ...sources: any[]): any; ->__assign : Symbol(__assign, Decl(tslib.d.ts, --, --)) ->t : Symbol(t, Decl(tslib.d.ts, --, --)) ->sources : Symbol(sources, Decl(tslib.d.ts, --, --)) - export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any; >__decorate : Symbol(__decorate, Decl(tslib.d.ts, --, --)) >decorators : Symbol(decorators, Decl(tslib.d.ts, --, --)) diff --git a/tests/baselines/reference/importHelpersES6.types b/tests/baselines/reference/importHelpersES6.types index ebfd5a5a2a5..26f30e32e58 100644 --- a/tests/baselines/reference/importHelpersES6.types +++ b/tests/baselines/reference/importHelpersES6.types @@ -8,6 +8,17 @@ declare var dec: any; } +const o = { a: 1 }; +>o : { a: number; } +>{ a: 1 } : { a: number; } +>a : number +>1 : 1 + +const y = { ...o }; +>y : { a: number; } +>{ ...o } : { a: number; } +>o : { a: number; } + === tests/cases/compiler/tslib.d.ts === export declare function __extends(d: Function, b: Function): void; >__extends : (d: Function, b: Function) => void @@ -16,11 +27,6 @@ export declare function __extends(d: Function, b: Function): void; >b : Function >Function : Function -export declare function __assign(t: any, ...sources: any[]): any; ->__assign : (t: any, ...sources: any[]) => any ->t : any ->sources : any[] - export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any; >__decorate : (decorators: Function[], target: any, key?: string | symbol, desc?: any) => any >decorators : Function[] diff --git a/tests/baselines/reference/inOperatorWithInvalidOperands.errors.txt b/tests/baselines/reference/inOperatorWithInvalidOperands.errors.txt index 5aeae5f160e..7615008d89c 100644 --- a/tests/baselines/reference/inOperatorWithInvalidOperands.errors.txt +++ b/tests/baselines/reference/inOperatorWithInvalidOperands.errors.txt @@ -1,6 +1,8 @@ tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(12,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'. tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(13,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'. tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(14,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'. +tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(16,11): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(17,11): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(19,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'. tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(20,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'. tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(30,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter @@ -11,13 +13,13 @@ tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInv tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(35,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(36,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(37,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter -tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(38,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter -tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(39,17): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter +tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(38,16): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(39,17): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(43,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'. tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(43,17): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter -==== tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts (17 errors) ==== +==== tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts (19 errors) ==== enum E { a } var x: any; @@ -40,7 +42,11 @@ tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInv !!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'. var ra4 = a4 in x; var ra5 = null in x; + ~~~~ +!!! error TS2531: Object is possibly 'null'. var ra6 = undefined in x; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var ra7 = E.a in x; var ra8 = false in x; ~~~~~ @@ -83,10 +89,10 @@ tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInv !!! error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter var rb9 = x in null; ~~~~ -!!! error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter +!!! error TS2531: Object is possibly 'null'. var rb10 = x in undefined; ~~~~~~~~~ -!!! error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter +!!! error TS2532: Object is possibly 'undefined'. // both operands are invalid diff --git a/tests/baselines/reference/incrementOperatorWithAnyOtherTypeInvalidOperations.errors.txt b/tests/baselines/reference/incrementOperatorWithAnyOtherTypeInvalidOperations.errors.txt index 0a303d12bf3..afdddab86a7 100644 --- a/tests/baselines/reference/incrementOperatorWithAnyOtherTypeInvalidOperations.errors.txt +++ b/tests/baselines/reference/incrementOperatorWithAnyOtherTypeInvalidOperations.errors.txt @@ -9,29 +9,37 @@ tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOp tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(33,23): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(34,24): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(37,26): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(38,26): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(38,26): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. +tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(38,26): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(39,26): error TS2539: Cannot assign to 'undefined' because it is not a variable. -tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(41,24): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(41,24): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. +tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(41,24): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(42,24): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(43,24): error TS2539: Cannot assign to 'undefined' because it is not a variable. tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(46,26): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(47,26): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(48,26): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. -tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(48,27): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. +tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(48,27): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(48,34): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(49,26): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. -tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(49,27): error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. +tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(49,27): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(49,34): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(50,26): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. -tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(50,27): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. +tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(50,27): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(50,39): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(51,26): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(52,26): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(54,24): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(55,24): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(56,24): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. -tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(56,25): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. +tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(56,25): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(56,32): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(57,24): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. -tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(57,25): error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. +tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(57,25): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(57,32): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(58,24): error TS2357: The operand of an increment or decrement operator must be a variable or a property access. -tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(58,25): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. +tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(58,25): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(58,37): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(59,24): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(60,24): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(63,3): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. @@ -45,7 +53,7 @@ tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOp tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts(69,12): error TS1109: Expression expected. -==== tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts (45 errors) ==== +==== tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithAnyOtherTypeInvalidOperations.ts (53 errors) ==== // ++ operator on any type var ANY1: any; var ANY2: any[] = [1, 2]; @@ -107,14 +115,18 @@ tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOp !!! error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. var ResultIsNumber12 = ++null; ~~~~ -!!! error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. +!!! error TS2357: The operand of an increment or decrement operator must be a variable or a property access. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var ResultIsNumber13 = ++undefined; ~~~~~~~~~ !!! error TS2539: Cannot assign to 'undefined' because it is not a variable. var ResultIsNumber14 = null++; ~~~~ -!!! error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. +!!! error TS2357: The operand of an increment or decrement operator must be a variable or a property access. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var ResultIsNumber15 = {}++; ~~ !!! error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. @@ -132,18 +144,24 @@ tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOp var ResultIsNumber19 = ++(null + undefined); ~~~~~~~~~~~~~~~~~~ !!! error TS2357: The operand of an increment or decrement operator must be a variable or a property access. - ~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var ResultIsNumber20 = ++(null + null); ~~~~~~~~~~~~~ !!! error TS2357: The operand of an increment or decrement operator must be a variable or a property access. - ~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var ResultIsNumber21 = ++(undefined + undefined); ~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2357: The operand of an increment or decrement operator must be a variable or a property access. - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var ResultIsNumber22 = ++obj1.x; ~~~~~~ !!! error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. @@ -160,18 +178,24 @@ tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOp var ResultIsNumber26 = (null + undefined)++; ~~~~~~~~~~~~~~~~~~ !!! error TS2357: The operand of an increment or decrement operator must be a variable or a property access. - ~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var ResultIsNumber27 = (null + null)++; ~~~~~~~~~~~~~ !!! error TS2357: The operand of an increment or decrement operator must be a variable or a property access. - ~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var ResultIsNumber28 = (undefined + undefined)++; ~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2357: The operand of an increment or decrement operator must be a variable or a property access. - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var ResultIsNumber29 = obj1.x++; ~~~~~~ !!! error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. diff --git a/tests/baselines/reference/interfaceExtendsObjectIntersection.js b/tests/baselines/reference/interfaceExtendsObjectIntersection.js new file mode 100644 index 00000000000..a6fb62f5070 --- /dev/null +++ b/tests/baselines/reference/interfaceExtendsObjectIntersection.js @@ -0,0 +1,145 @@ +//// [interfaceExtendsObjectIntersection.ts] + +type T1 = { a: number }; +type T2 = T1 & { b: number }; +type T3 = () => void; +type T4 = new () => { a: number }; +type T5 = number[]; +type T6 = [string, number]; +type T7 = { [P in 'a' | 'b' | 'c']: string }; + +interface I1 extends T1 { x: string } +interface I2 extends T2 { x: string } +interface I3 extends T3 { x: string } +interface I4 extends T4 { x: string } +interface I5 extends T5 { x: string } +interface I6 extends T6 { x: string } +interface I7 extends T7 { x: string } + +type Constructor = new () => T; +declare function Constructor(): Constructor; + +class C1 extends Constructor() { x: string } +class C2 extends Constructor() { x: string } +class C3 extends Constructor() { x: string } +class C4 extends Constructor() { x: string } +class C5 extends Constructor() { x: string } +class C6 extends Constructor() { x: string } +class C7 extends Constructor() { x: string } + +declare function fx(x: string): string; +declare class CX { a: number } +declare enum EX { A, B, C } +declare namespace NX { export const a = 1 } + +type T10 = typeof fx; +type T11 = typeof CX; +type T12 = typeof EX; +type T13 = typeof NX; + +interface I10 extends T10 { x: string } +interface I11 extends T11 { x: string } +interface I12 extends T12 { x: string } +interface I13 extends T13 { x: string } + +type Identifiable = { _id: string } & T; + +interface I20 extends Partial { x: string } +interface I21 extends Readonly { x: string } +interface I22 extends Identifiable { x: string } +interface I23 extends Identifiable { x: string } + +class C20 extends Constructor>() { x: string } +class C21 extends Constructor>() { x: string } +class C22 extends Constructor>() { x: string } +class C23 extends Constructor>() { x: string } + + +//// [interfaceExtendsObjectIntersection.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var C1 = (function (_super) { + __extends(C1, _super); + function C1() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C1; +}(Constructor())); +var C2 = (function (_super) { + __extends(C2, _super); + function C2() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C2; +}(Constructor())); +var C3 = (function (_super) { + __extends(C3, _super); + function C3() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C3; +}(Constructor())); +var C4 = (function (_super) { + __extends(C4, _super); + function C4() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C4; +}(Constructor())); +var C5 = (function (_super) { + __extends(C5, _super); + function C5() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C5; +}(Constructor())); +var C6 = (function (_super) { + __extends(C6, _super); + function C6() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C6; +}(Constructor())); +var C7 = (function (_super) { + __extends(C7, _super); + function C7() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C7; +}(Constructor())); +var C20 = (function (_super) { + __extends(C20, _super); + function C20() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C20; +}(Constructor())); +var C21 = (function (_super) { + __extends(C21, _super); + function C21() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C21; +}(Constructor())); +var C22 = (function (_super) { + __extends(C22, _super); + function C22() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C22; +}(Constructor())); +var C23 = (function (_super) { + __extends(C23, _super); + function C23() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C23; +}(Constructor())); diff --git a/tests/baselines/reference/interfaceExtendsObjectIntersection.symbols b/tests/baselines/reference/interfaceExtendsObjectIntersection.symbols new file mode 100644 index 00000000000..16c8c51cf47 --- /dev/null +++ b/tests/baselines/reference/interfaceExtendsObjectIntersection.symbols @@ -0,0 +1,230 @@ +=== tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersection.ts === + +type T1 = { a: number }; +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>a : Symbol(a, Decl(interfaceExtendsObjectIntersection.ts, 1, 11)) + +type T2 = T1 & { b: number }; +>T2 : Symbol(T2, Decl(interfaceExtendsObjectIntersection.ts, 1, 24)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>b : Symbol(b, Decl(interfaceExtendsObjectIntersection.ts, 2, 16)) + +type T3 = () => void; +>T3 : Symbol(T3, Decl(interfaceExtendsObjectIntersection.ts, 2, 29)) + +type T4 = new () => { a: number }; +>T4 : Symbol(T4, Decl(interfaceExtendsObjectIntersection.ts, 3, 21)) +>a : Symbol(a, Decl(interfaceExtendsObjectIntersection.ts, 4, 21)) + +type T5 = number[]; +>T5 : Symbol(T5, Decl(interfaceExtendsObjectIntersection.ts, 4, 34)) + +type T6 = [string, number]; +>T6 : Symbol(T6, Decl(interfaceExtendsObjectIntersection.ts, 5, 19)) + +type T7 = { [P in 'a' | 'b' | 'c']: string }; +>T7 : Symbol(T7, Decl(interfaceExtendsObjectIntersection.ts, 6, 27)) +>P : Symbol(P, Decl(interfaceExtendsObjectIntersection.ts, 7, 13)) + +interface I1 extends T1 { x: string } +>I1 : Symbol(I1, Decl(interfaceExtendsObjectIntersection.ts, 7, 45)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>x : Symbol(I1.x, Decl(interfaceExtendsObjectIntersection.ts, 9, 25)) + +interface I2 extends T2 { x: string } +>I2 : Symbol(I2, Decl(interfaceExtendsObjectIntersection.ts, 9, 37)) +>T2 : Symbol(T2, Decl(interfaceExtendsObjectIntersection.ts, 1, 24)) +>x : Symbol(I2.x, Decl(interfaceExtendsObjectIntersection.ts, 10, 25)) + +interface I3 extends T3 { x: string } +>I3 : Symbol(I3, Decl(interfaceExtendsObjectIntersection.ts, 10, 37)) +>T3 : Symbol(T3, Decl(interfaceExtendsObjectIntersection.ts, 2, 29)) +>x : Symbol(I3.x, Decl(interfaceExtendsObjectIntersection.ts, 11, 25)) + +interface I4 extends T4 { x: string } +>I4 : Symbol(I4, Decl(interfaceExtendsObjectIntersection.ts, 11, 37)) +>T4 : Symbol(T4, Decl(interfaceExtendsObjectIntersection.ts, 3, 21)) +>x : Symbol(I4.x, Decl(interfaceExtendsObjectIntersection.ts, 12, 25)) + +interface I5 extends T5 { x: string } +>I5 : Symbol(I5, Decl(interfaceExtendsObjectIntersection.ts, 12, 37)) +>T5 : Symbol(T5, Decl(interfaceExtendsObjectIntersection.ts, 4, 34)) +>x : Symbol(I5.x, Decl(interfaceExtendsObjectIntersection.ts, 13, 25)) + +interface I6 extends T6 { x: string } +>I6 : Symbol(I6, Decl(interfaceExtendsObjectIntersection.ts, 13, 37)) +>T6 : Symbol(T6, Decl(interfaceExtendsObjectIntersection.ts, 5, 19)) +>x : Symbol(I6.x, Decl(interfaceExtendsObjectIntersection.ts, 14, 25)) + +interface I7 extends T7 { x: string } +>I7 : Symbol(I7, Decl(interfaceExtendsObjectIntersection.ts, 14, 37)) +>T7 : Symbol(T7, Decl(interfaceExtendsObjectIntersection.ts, 6, 27)) +>x : Symbol(I7.x, Decl(interfaceExtendsObjectIntersection.ts, 15, 25)) + +type Constructor = new () => T; +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>T : Symbol(T, Decl(interfaceExtendsObjectIntersection.ts, 17, 17)) +>T : Symbol(T, Decl(interfaceExtendsObjectIntersection.ts, 17, 17)) + +declare function Constructor(): Constructor; +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>T : Symbol(T, Decl(interfaceExtendsObjectIntersection.ts, 18, 29)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>T : Symbol(T, Decl(interfaceExtendsObjectIntersection.ts, 18, 29)) + +class C1 extends Constructor() { x: string } +>C1 : Symbol(C1, Decl(interfaceExtendsObjectIntersection.ts, 18, 50)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>I1 : Symbol(I1, Decl(interfaceExtendsObjectIntersection.ts, 7, 45)) +>x : Symbol(C1.x, Decl(interfaceExtendsObjectIntersection.ts, 20, 36)) + +class C2 extends Constructor() { x: string } +>C2 : Symbol(C2, Decl(interfaceExtendsObjectIntersection.ts, 20, 48)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>I2 : Symbol(I2, Decl(interfaceExtendsObjectIntersection.ts, 9, 37)) +>x : Symbol(C2.x, Decl(interfaceExtendsObjectIntersection.ts, 21, 36)) + +class C3 extends Constructor() { x: string } +>C3 : Symbol(C3, Decl(interfaceExtendsObjectIntersection.ts, 21, 48)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>I3 : Symbol(I3, Decl(interfaceExtendsObjectIntersection.ts, 10, 37)) +>x : Symbol(C3.x, Decl(interfaceExtendsObjectIntersection.ts, 22, 36)) + +class C4 extends Constructor() { x: string } +>C4 : Symbol(C4, Decl(interfaceExtendsObjectIntersection.ts, 22, 48)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>I4 : Symbol(I4, Decl(interfaceExtendsObjectIntersection.ts, 11, 37)) +>x : Symbol(C4.x, Decl(interfaceExtendsObjectIntersection.ts, 23, 36)) + +class C5 extends Constructor() { x: string } +>C5 : Symbol(C5, Decl(interfaceExtendsObjectIntersection.ts, 23, 48)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>I5 : Symbol(I5, Decl(interfaceExtendsObjectIntersection.ts, 12, 37)) +>x : Symbol(C5.x, Decl(interfaceExtendsObjectIntersection.ts, 24, 36)) + +class C6 extends Constructor() { x: string } +>C6 : Symbol(C6, Decl(interfaceExtendsObjectIntersection.ts, 24, 48)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>I6 : Symbol(I6, Decl(interfaceExtendsObjectIntersection.ts, 13, 37)) +>x : Symbol(C6.x, Decl(interfaceExtendsObjectIntersection.ts, 25, 36)) + +class C7 extends Constructor() { x: string } +>C7 : Symbol(C7, Decl(interfaceExtendsObjectIntersection.ts, 25, 48)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>I7 : Symbol(I7, Decl(interfaceExtendsObjectIntersection.ts, 14, 37)) +>x : Symbol(C7.x, Decl(interfaceExtendsObjectIntersection.ts, 26, 36)) + +declare function fx(x: string): string; +>fx : Symbol(fx, Decl(interfaceExtendsObjectIntersection.ts, 26, 48)) +>x : Symbol(x, Decl(interfaceExtendsObjectIntersection.ts, 28, 20)) + +declare class CX { a: number } +>CX : Symbol(CX, Decl(interfaceExtendsObjectIntersection.ts, 28, 39)) +>a : Symbol(CX.a, Decl(interfaceExtendsObjectIntersection.ts, 29, 18)) + +declare enum EX { A, B, C } +>EX : Symbol(EX, Decl(interfaceExtendsObjectIntersection.ts, 29, 30)) +>A : Symbol(EX.A, Decl(interfaceExtendsObjectIntersection.ts, 30, 17)) +>B : Symbol(EX.B, Decl(interfaceExtendsObjectIntersection.ts, 30, 20)) +>C : Symbol(EX.C, Decl(interfaceExtendsObjectIntersection.ts, 30, 23)) + +declare namespace NX { export const a = 1 } +>NX : Symbol(NX, Decl(interfaceExtendsObjectIntersection.ts, 30, 27)) +>a : Symbol(a, Decl(interfaceExtendsObjectIntersection.ts, 31, 35)) + +type T10 = typeof fx; +>T10 : Symbol(T10, Decl(interfaceExtendsObjectIntersection.ts, 31, 43)) +>fx : Symbol(fx, Decl(interfaceExtendsObjectIntersection.ts, 26, 48)) + +type T11 = typeof CX; +>T11 : Symbol(T11, Decl(interfaceExtendsObjectIntersection.ts, 33, 21)) +>CX : Symbol(CX, Decl(interfaceExtendsObjectIntersection.ts, 28, 39)) + +type T12 = typeof EX; +>T12 : Symbol(T12, Decl(interfaceExtendsObjectIntersection.ts, 34, 21)) +>EX : Symbol(EX, Decl(interfaceExtendsObjectIntersection.ts, 29, 30)) + +type T13 = typeof NX; +>T13 : Symbol(T13, Decl(interfaceExtendsObjectIntersection.ts, 35, 21)) +>NX : Symbol(NX, Decl(interfaceExtendsObjectIntersection.ts, 30, 27)) + +interface I10 extends T10 { x: string } +>I10 : Symbol(I10, Decl(interfaceExtendsObjectIntersection.ts, 36, 21)) +>T10 : Symbol(T10, Decl(interfaceExtendsObjectIntersection.ts, 31, 43)) +>x : Symbol(I10.x, Decl(interfaceExtendsObjectIntersection.ts, 38, 27)) + +interface I11 extends T11 { x: string } +>I11 : Symbol(I11, Decl(interfaceExtendsObjectIntersection.ts, 38, 39)) +>T11 : Symbol(T11, Decl(interfaceExtendsObjectIntersection.ts, 33, 21)) +>x : Symbol(I11.x, Decl(interfaceExtendsObjectIntersection.ts, 39, 27)) + +interface I12 extends T12 { x: string } +>I12 : Symbol(I12, Decl(interfaceExtendsObjectIntersection.ts, 39, 39)) +>T12 : Symbol(T12, Decl(interfaceExtendsObjectIntersection.ts, 34, 21)) +>x : Symbol(I12.x, Decl(interfaceExtendsObjectIntersection.ts, 40, 27)) + +interface I13 extends T13 { x: string } +>I13 : Symbol(I13, Decl(interfaceExtendsObjectIntersection.ts, 40, 39)) +>T13 : Symbol(T13, Decl(interfaceExtendsObjectIntersection.ts, 35, 21)) +>x : Symbol(I13.x, Decl(interfaceExtendsObjectIntersection.ts, 41, 27)) + +type Identifiable = { _id: string } & T; +>Identifiable : Symbol(Identifiable, Decl(interfaceExtendsObjectIntersection.ts, 41, 39)) +>T : Symbol(T, Decl(interfaceExtendsObjectIntersection.ts, 43, 18)) +>_id : Symbol(_id, Decl(interfaceExtendsObjectIntersection.ts, 43, 24)) +>T : Symbol(T, Decl(interfaceExtendsObjectIntersection.ts, 43, 18)) + +interface I20 extends Partial { x: string } +>I20 : Symbol(I20, Decl(interfaceExtendsObjectIntersection.ts, 43, 43)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>x : Symbol(I20.x, Decl(interfaceExtendsObjectIntersection.ts, 45, 35)) + +interface I21 extends Readonly { x: string } +>I21 : Symbol(I21, Decl(interfaceExtendsObjectIntersection.ts, 45, 47)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>x : Symbol(I21.x, Decl(interfaceExtendsObjectIntersection.ts, 46, 36)) + +interface I22 extends Identifiable { x: string } +>I22 : Symbol(I22, Decl(interfaceExtendsObjectIntersection.ts, 46, 48)) +>Identifiable : Symbol(Identifiable, Decl(interfaceExtendsObjectIntersection.ts, 41, 39)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>x : Symbol(I22.x, Decl(interfaceExtendsObjectIntersection.ts, 47, 40)) + +interface I23 extends Identifiable { x: string } +>I23 : Symbol(I23, Decl(interfaceExtendsObjectIntersection.ts, 47, 52)) +>Identifiable : Symbol(Identifiable, Decl(interfaceExtendsObjectIntersection.ts, 41, 39)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>b : Symbol(b, Decl(interfaceExtendsObjectIntersection.ts, 48, 41)) +>x : Symbol(I23.x, Decl(interfaceExtendsObjectIntersection.ts, 48, 55)) + +class C20 extends Constructor>() { x: string } +>C20 : Symbol(C20, Decl(interfaceExtendsObjectIntersection.ts, 48, 67)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>x : Symbol(C20.x, Decl(interfaceExtendsObjectIntersection.ts, 50, 46)) + +class C21 extends Constructor>() { x: string } +>C21 : Symbol(C21, Decl(interfaceExtendsObjectIntersection.ts, 50, 58)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>x : Symbol(C21.x, Decl(interfaceExtendsObjectIntersection.ts, 51, 47)) + +class C22 extends Constructor>() { x: string } +>C22 : Symbol(C22, Decl(interfaceExtendsObjectIntersection.ts, 51, 59)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>Identifiable : Symbol(Identifiable, Decl(interfaceExtendsObjectIntersection.ts, 41, 39)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>x : Symbol(C22.x, Decl(interfaceExtendsObjectIntersection.ts, 52, 51)) + +class C23 extends Constructor>() { x: string } +>C23 : Symbol(C23, Decl(interfaceExtendsObjectIntersection.ts, 52, 63)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>Identifiable : Symbol(Identifiable, Decl(interfaceExtendsObjectIntersection.ts, 41, 39)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>b : Symbol(b, Decl(interfaceExtendsObjectIntersection.ts, 53, 49)) +>x : Symbol(C23.x, Decl(interfaceExtendsObjectIntersection.ts, 53, 66)) + diff --git a/tests/baselines/reference/interfaceExtendsObjectIntersection.types b/tests/baselines/reference/interfaceExtendsObjectIntersection.types new file mode 100644 index 00000000000..1ff550df7b4 --- /dev/null +++ b/tests/baselines/reference/interfaceExtendsObjectIntersection.types @@ -0,0 +1,242 @@ +=== tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersection.ts === + +type T1 = { a: number }; +>T1 : T1 +>a : number + +type T2 = T1 & { b: number }; +>T2 : T2 +>T1 : T1 +>b : number + +type T3 = () => void; +>T3 : T3 + +type T4 = new () => { a: number }; +>T4 : T4 +>a : number + +type T5 = number[]; +>T5 : number[] + +type T6 = [string, number]; +>T6 : [string, number] + +type T7 = { [P in 'a' | 'b' | 'c']: string }; +>T7 : T7 +>P : P + +interface I1 extends T1 { x: string } +>I1 : I1 +>T1 : T1 +>x : string + +interface I2 extends T2 { x: string } +>I2 : I2 +>T2 : T2 +>x : string + +interface I3 extends T3 { x: string } +>I3 : I3 +>T3 : T3 +>x : string + +interface I4 extends T4 { x: string } +>I4 : I4 +>T4 : T4 +>x : string + +interface I5 extends T5 { x: string } +>I5 : I5 +>T5 : number[] +>x : string + +interface I6 extends T6 { x: string } +>I6 : I6 +>T6 : [string, number] +>x : string + +interface I7 extends T7 { x: string } +>I7 : I7 +>T7 : T7 +>x : string + +type Constructor = new () => T; +>Constructor : Constructor +>T : T +>T : T + +declare function Constructor(): Constructor; +>Constructor : () => Constructor +>T : T +>Constructor : Constructor +>T : T + +class C1 extends Constructor() { x: string } +>C1 : C1 +>Constructor() : I1 +>Constructor : () => Constructor +>I1 : I1 +>x : string + +class C2 extends Constructor() { x: string } +>C2 : C2 +>Constructor() : I2 +>Constructor : () => Constructor +>I2 : I2 +>x : string + +class C3 extends Constructor() { x: string } +>C3 : C3 +>Constructor() : I3 +>Constructor : () => Constructor +>I3 : I3 +>x : string + +class C4 extends Constructor() { x: string } +>C4 : C4 +>Constructor() : I4 +>Constructor : () => Constructor +>I4 : I4 +>x : string + +class C5 extends Constructor() { x: string } +>C5 : C5 +>Constructor() : I5 +>Constructor : () => Constructor +>I5 : I5 +>x : string + +class C6 extends Constructor() { x: string } +>C6 : C6 +>Constructor() : I6 +>Constructor : () => Constructor +>I6 : I6 +>x : string + +class C7 extends Constructor() { x: string } +>C7 : C7 +>Constructor() : I7 +>Constructor : () => Constructor +>I7 : I7 +>x : string + +declare function fx(x: string): string; +>fx : (x: string) => string +>x : string + +declare class CX { a: number } +>CX : CX +>a : number + +declare enum EX { A, B, C } +>EX : EX +>A : EX +>B : EX +>C : EX + +declare namespace NX { export const a = 1 } +>NX : typeof NX +>a : 1 +>1 : 1 + +type T10 = typeof fx; +>T10 : (x: string) => string +>fx : (x: string) => string + +type T11 = typeof CX; +>T11 : typeof CX +>CX : typeof CX + +type T12 = typeof EX; +>T12 : typeof EX +>EX : typeof EX + +type T13 = typeof NX; +>T13 : typeof NX +>NX : typeof NX + +interface I10 extends T10 { x: string } +>I10 : I10 +>T10 : (x: string) => string +>x : string + +interface I11 extends T11 { x: string } +>I11 : I11 +>T11 : typeof CX +>x : string + +interface I12 extends T12 { x: string } +>I12 : I12 +>T12 : typeof EX +>x : string + +interface I13 extends T13 { x: string } +>I13 : I13 +>T13 : typeof NX +>x : string + +type Identifiable = { _id: string } & T; +>Identifiable : Identifiable +>T : T +>_id : string +>T : T + +interface I20 extends Partial { x: string } +>I20 : I20 +>Partial : Partial +>T1 : T1 +>x : string + +interface I21 extends Readonly { x: string } +>I21 : I21 +>Readonly : Readonly +>T1 : T1 +>x : string + +interface I22 extends Identifiable { x: string } +>I22 : I22 +>Identifiable : Identifiable +>T1 : T1 +>x : string + +interface I23 extends Identifiable { x: string } +>I23 : I23 +>Identifiable : Identifiable +>T1 : T1 +>b : number +>x : string + +class C20 extends Constructor>() { x: string } +>C20 : C20 +>Constructor>() : Partial +>Constructor : () => Constructor +>Partial : Partial +>T1 : T1 +>x : string + +class C21 extends Constructor>() { x: string } +>C21 : C21 +>Constructor>() : Readonly +>Constructor : () => Constructor +>Readonly : Readonly +>T1 : T1 +>x : string + +class C22 extends Constructor>() { x: string } +>C22 : C22 +>Constructor>() : Identifiable +>Constructor : () => Constructor +>Identifiable : Identifiable +>T1 : T1 +>x : string + +class C23 extends Constructor>() { x: string } +>C23 : C23 +>Constructor>() : Identifiable +>Constructor : () => Constructor +>Identifiable : Identifiable +>T1 : T1 +>b : number +>x : string + diff --git a/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt b/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt new file mode 100644 index 00000000000..839474b3bdc --- /dev/null +++ b/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt @@ -0,0 +1,197 @@ +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(8,11): error TS2430: Interface 'I1' incorrectly extends interface 'T1'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(9,11): error TS2430: Interface 'I2' incorrectly extends interface 'T2'. + Type 'I2' is not assignable to type '{ b: number; }'. + Types of property 'b' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(10,11): error TS2430: Interface 'I3' incorrectly extends interface 'number[]'. + Types of property 'length' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(11,11): error TS2430: Interface 'I4' incorrectly extends interface '[string, number]'. + Types of property '0' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(12,11): error TS2430: Interface 'I5' incorrectly extends interface 'T5'. + Types of property 'c' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(17,7): error TS2415: Class 'C1' incorrectly extends base class 'T1'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(18,7): error TS2415: Class 'C2' incorrectly extends base class 'T2'. + Type 'C2' is not assignable to type '{ b: number; }'. + Types of property 'b' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(19,7): error TS2415: Class 'C3' incorrectly extends base class 'number[]'. + Types of property 'length' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(20,7): error TS2415: Class 'C4' incorrectly extends base class '[string, number]'. + Types of property '0' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(21,7): error TS2415: Class 'C5' incorrectly extends base class 'T5'. + Types of property 'c' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(31,11): error TS2430: Interface 'I10' incorrectly extends interface 'typeof CX'. + Types of property 'a' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(32,11): error TS2430: Interface 'I11' incorrectly extends interface 'typeof EX'. + Types of property 'C' are incompatible. + Type 'string' is not assignable to type 'EX'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(33,11): error TS2430: Interface 'I12' incorrectly extends interface 'typeof NX'. + Types of property 'a' are incompatible. + Type 'number' is not assignable to type '"hello"'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(34,29): error TS2411: Property 'a' of type 'string' is not assignable to string index type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(34,29): error TS2411: Property 'prototype' of type 'CX' is not assignable to string index type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(35,29): error TS2413: Numeric index type 'string' is not assignable to string index type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(36,29): error TS2411: Property 'a' of type '"hello"' is not assignable to string index type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(40,11): error TS2430: Interface 'I20' incorrectly extends interface 'Partial'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'number | undefined'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(41,11): error TS2430: Interface 'I21' incorrectly extends interface 'Readonly'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(42,11): error TS2430: Interface 'I22' incorrectly extends interface 'Identifiable'. + Type 'I22' is not assignable to type 'T1'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(43,11): error TS2430: Interface 'I23' incorrectly extends interface 'Identifiable'. + Type 'I23' is not assignable to type 'T1'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(47,23): error TS2312: An interface may only extend a class or another interface. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(48,26): error TS2312: An interface may only extend a class or another interface. + + +==== tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts (23 errors) ==== + + type T1 = { a: number }; + type T2 = T1 & { b: number }; + type T3 = number[]; + type T4 = [string, number]; + type T5 = { [P in 'a' | 'b' | 'c']: string }; + + interface I1 extends T1 { a: string } + ~~ +!!! error TS2430: Interface 'I1' incorrectly extends interface 'T1'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'number'. + interface I2 extends T2 { b: string } + ~~ +!!! error TS2430: Interface 'I2' incorrectly extends interface 'T2'. +!!! error TS2430: Type 'I2' is not assignable to type '{ b: number; }'. +!!! error TS2430: Types of property 'b' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'number'. + interface I3 extends T3 { length: string } + ~~ +!!! error TS2430: Interface 'I3' incorrectly extends interface 'number[]'. +!!! error TS2430: Types of property 'length' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'number'. + interface I4 extends T4 { 0: number } + ~~ +!!! error TS2430: Interface 'I4' incorrectly extends interface '[string, number]'. +!!! error TS2430: Types of property '0' are incompatible. +!!! error TS2430: Type 'number' is not assignable to type 'string'. + interface I5 extends T5 { c: number } + ~~ +!!! error TS2430: Interface 'I5' incorrectly extends interface 'T5'. +!!! error TS2430: Types of property 'c' are incompatible. +!!! error TS2430: Type 'number' is not assignable to type 'string'. + + type Constructor = new () => T; + declare function Constructor(): Constructor; + + class C1 extends Constructor() { a: string } + ~~ +!!! error TS2415: Class 'C1' incorrectly extends base class 'T1'. +!!! error TS2415: Types of property 'a' are incompatible. +!!! error TS2415: Type 'string' is not assignable to type 'number'. + class C2 extends Constructor() { b: string } + ~~ +!!! error TS2415: Class 'C2' incorrectly extends base class 'T2'. +!!! error TS2415: Type 'C2' is not assignable to type '{ b: number; }'. +!!! error TS2415: Types of property 'b' are incompatible. +!!! error TS2415: Type 'string' is not assignable to type 'number'. + class C3 extends Constructor() { length: string } + ~~ +!!! error TS2415: Class 'C3' incorrectly extends base class 'number[]'. +!!! error TS2415: Types of property 'length' are incompatible. +!!! error TS2415: Type 'string' is not assignable to type 'number'. + class C4 extends Constructor() { 0: number } + ~~ +!!! error TS2415: Class 'C4' incorrectly extends base class '[string, number]'. +!!! error TS2415: Types of property '0' are incompatible. +!!! error TS2415: Type 'number' is not assignable to type 'string'. + class C5 extends Constructor() { c: number } + ~~ +!!! error TS2415: Class 'C5' incorrectly extends base class 'T5'. +!!! error TS2415: Types of property 'c' are incompatible. +!!! error TS2415: Type 'number' is not assignable to type 'string'. + + declare class CX { static a: string } + declare enum EX { A, B, C } + declare namespace NX { export const a = "hello" } + + type TCX = typeof CX; + type TEX = typeof EX; + type TNX = typeof NX; + + interface I10 extends TCX { a: number } + ~~~ +!!! error TS2430: Interface 'I10' incorrectly extends interface 'typeof CX'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'number' is not assignable to type 'string'. + interface I11 extends TEX { C: string } + ~~~ +!!! error TS2430: Interface 'I11' incorrectly extends interface 'typeof EX'. +!!! error TS2430: Types of property 'C' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'EX'. + interface I12 extends TNX { a: number } + ~~~ +!!! error TS2430: Interface 'I12' incorrectly extends interface 'typeof NX'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'number' is not assignable to type '"hello"'. + interface I14 extends TCX { [x: string]: number } + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'a' of type 'string' is not assignable to string index type 'number'. + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'prototype' of type 'CX' is not assignable to string index type 'number'. + interface I15 extends TEX { [x: string]: number } + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2413: Numeric index type 'string' is not assignable to string index type 'number'. + interface I16 extends TNX { [x: string]: number } + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'a' of type '"hello"' is not assignable to string index type 'number'. + + type Identifiable = { _id: string } & T; + + interface I20 extends Partial { a: string } + ~~~ +!!! error TS2430: Interface 'I20' incorrectly extends interface 'Partial'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'number | undefined'. + interface I21 extends Readonly { a: string } + ~~~ +!!! error TS2430: Interface 'I21' incorrectly extends interface 'Readonly'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'number'. + interface I22 extends Identifiable { a: string } + ~~~ +!!! error TS2430: Interface 'I22' incorrectly extends interface 'Identifiable'. +!!! error TS2430: Type 'I22' is not assignable to type 'T1'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'number'. + interface I23 extends Identifiable { a: string } + ~~~ +!!! error TS2430: Interface 'I23' incorrectly extends interface 'Identifiable'. +!!! error TS2430: Type 'I23' is not assignable to type 'T1'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'number'. + + type U = { a: number } | { b: string }; + + interface I30 extends U { x: string } + ~ +!!! error TS2312: An interface may only extend a class or another interface. + interface I31 extends T { x: string } + ~ +!!! error TS2312: An interface may only extend a class or another interface. + \ No newline at end of file diff --git a/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.js b/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.js new file mode 100644 index 00000000000..61f84b2f7fe --- /dev/null +++ b/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.js @@ -0,0 +1,97 @@ +//// [interfaceExtendsObjectIntersectionErrors.ts] + +type T1 = { a: number }; +type T2 = T1 & { b: number }; +type T3 = number[]; +type T4 = [string, number]; +type T5 = { [P in 'a' | 'b' | 'c']: string }; + +interface I1 extends T1 { a: string } +interface I2 extends T2 { b: string } +interface I3 extends T3 { length: string } +interface I4 extends T4 { 0: number } +interface I5 extends T5 { c: number } + +type Constructor = new () => T; +declare function Constructor(): Constructor; + +class C1 extends Constructor() { a: string } +class C2 extends Constructor() { b: string } +class C3 extends Constructor() { length: string } +class C4 extends Constructor() { 0: number } +class C5 extends Constructor() { c: number } + +declare class CX { static a: string } +declare enum EX { A, B, C } +declare namespace NX { export const a = "hello" } + +type TCX = typeof CX; +type TEX = typeof EX; +type TNX = typeof NX; + +interface I10 extends TCX { a: number } +interface I11 extends TEX { C: string } +interface I12 extends TNX { a: number } +interface I14 extends TCX { [x: string]: number } +interface I15 extends TEX { [x: string]: number } +interface I16 extends TNX { [x: string]: number } + +type Identifiable = { _id: string } & T; + +interface I20 extends Partial { a: string } +interface I21 extends Readonly { a: string } +interface I22 extends Identifiable { a: string } +interface I23 extends Identifiable { a: string } + +type U = { a: number } | { b: string }; + +interface I30 extends U { x: string } +interface I31 extends T { x: string } + + +//// [interfaceExtendsObjectIntersectionErrors.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var C1 = (function (_super) { + __extends(C1, _super); + function C1() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C1; +}(Constructor())); +var C2 = (function (_super) { + __extends(C2, _super); + function C2() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C2; +}(Constructor())); +var C3 = (function (_super) { + __extends(C3, _super); + function C3() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C3; +}(Constructor())); +var C4 = (function (_super) { + __extends(C4, _super); + function C4() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C4; +}(Constructor())); +var C5 = (function (_super) { + __extends(C5, _super); + function C5() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C5; +}(Constructor())); diff --git a/tests/baselines/reference/intersectionThisTypes.js b/tests/baselines/reference/intersectionThisTypes.js new file mode 100644 index 00000000000..9c7be09eeb8 --- /dev/null +++ b/tests/baselines/reference/intersectionThisTypes.js @@ -0,0 +1,57 @@ +//// [intersectionThisTypes.ts] +interface Thing1 { + a: number; + self(): this; +} + +interface Thing2 { + b: number; + me(): this; +} + +type Thing3 = Thing1 & Thing2; +type Thing4 = Thing3 & string[]; + +function f1(t: Thing3) { + t = t.self(); + t = t.me().self().me(); +} + +interface Thing5 extends Thing4 { + c: string; +} + +function f2(t: Thing5) { + t = t.self(); + t = t.me().self().me(); +} + +interface Component { + extend(props: T): this & T; +} + +interface Label extends Component { + title: string; +} + +function test(label: Label) { + const extended = label.extend({ id: 67 }).extend({ tag: "hello" }); + extended.id; // Ok + extended.tag; // Ok +} + + +//// [intersectionThisTypes.js] +function f1(t) { + t = t.self(); + t = t.me().self().me(); +} +function f2(t) { + t = t.self(); + t = t.me().self().me(); +} +function test(label) { + var extended = label.extend({ id: 67 }).extend({ tag: "hello" }); + extended.id; // Ok + extended.tag; // Ok +} diff --git a/tests/baselines/reference/intersectionThisTypes.symbols b/tests/baselines/reference/intersectionThisTypes.symbols new file mode 100644 index 00000000000..8a8a6cd5496 --- /dev/null +++ b/tests/baselines/reference/intersectionThisTypes.symbols @@ -0,0 +1,127 @@ +=== tests/cases/conformance/types/intersection/intersectionThisTypes.ts === +interface Thing1 { +>Thing1 : Symbol(Thing1, Decl(intersectionThisTypes.ts, 0, 0)) + + a: number; +>a : Symbol(Thing1.a, Decl(intersectionThisTypes.ts, 0, 18)) + + self(): this; +>self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) +} + +interface Thing2 { +>Thing2 : Symbol(Thing2, Decl(intersectionThisTypes.ts, 3, 1)) + + b: number; +>b : Symbol(Thing2.b, Decl(intersectionThisTypes.ts, 5, 18)) + + me(): this; +>me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +} + +type Thing3 = Thing1 & Thing2; +>Thing3 : Symbol(Thing3, Decl(intersectionThisTypes.ts, 8, 1)) +>Thing1 : Symbol(Thing1, Decl(intersectionThisTypes.ts, 0, 0)) +>Thing2 : Symbol(Thing2, Decl(intersectionThisTypes.ts, 3, 1)) + +type Thing4 = Thing3 & string[]; +>Thing4 : Symbol(Thing4, Decl(intersectionThisTypes.ts, 10, 30)) +>Thing3 : Symbol(Thing3, Decl(intersectionThisTypes.ts, 8, 1)) + +function f1(t: Thing3) { +>f1 : Symbol(f1, Decl(intersectionThisTypes.ts, 11, 32)) +>t : Symbol(t, Decl(intersectionThisTypes.ts, 13, 12)) +>Thing3 : Symbol(Thing3, Decl(intersectionThisTypes.ts, 8, 1)) + + t = t.self(); +>t : Symbol(t, Decl(intersectionThisTypes.ts, 13, 12)) +>t.self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) +>t : Symbol(t, Decl(intersectionThisTypes.ts, 13, 12)) +>self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) + + t = t.me().self().me(); +>t : Symbol(t, Decl(intersectionThisTypes.ts, 13, 12)) +>t.me().self().me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +>t.me().self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) +>t.me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +>t : Symbol(t, Decl(intersectionThisTypes.ts, 13, 12)) +>me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +>self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) +>me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +} + +interface Thing5 extends Thing4 { +>Thing5 : Symbol(Thing5, Decl(intersectionThisTypes.ts, 16, 1)) +>Thing4 : Symbol(Thing4, Decl(intersectionThisTypes.ts, 10, 30)) + + c: string; +>c : Symbol(Thing5.c, Decl(intersectionThisTypes.ts, 18, 33)) +} + +function f2(t: Thing5) { +>f2 : Symbol(f2, Decl(intersectionThisTypes.ts, 20, 1)) +>t : Symbol(t, Decl(intersectionThisTypes.ts, 22, 12)) +>Thing5 : Symbol(Thing5, Decl(intersectionThisTypes.ts, 16, 1)) + + t = t.self(); +>t : Symbol(t, Decl(intersectionThisTypes.ts, 22, 12)) +>t.self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) +>t : Symbol(t, Decl(intersectionThisTypes.ts, 22, 12)) +>self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) + + t = t.me().self().me(); +>t : Symbol(t, Decl(intersectionThisTypes.ts, 22, 12)) +>t.me().self().me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +>t.me().self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) +>t.me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +>t : Symbol(t, Decl(intersectionThisTypes.ts, 22, 12)) +>me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +>self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) +>me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +} + +interface Component { +>Component : Symbol(Component, Decl(intersectionThisTypes.ts, 25, 1)) + + extend(props: T): this & T; +>extend : Symbol(Component.extend, Decl(intersectionThisTypes.ts, 27, 21)) +>T : Symbol(T, Decl(intersectionThisTypes.ts, 28, 11)) +>props : Symbol(props, Decl(intersectionThisTypes.ts, 28, 14)) +>T : Symbol(T, Decl(intersectionThisTypes.ts, 28, 11)) +>T : Symbol(T, Decl(intersectionThisTypes.ts, 28, 11)) +} + +interface Label extends Component { +>Label : Symbol(Label, Decl(intersectionThisTypes.ts, 29, 1)) +>Component : Symbol(Component, Decl(intersectionThisTypes.ts, 25, 1)) + + title: string; +>title : Symbol(Label.title, Decl(intersectionThisTypes.ts, 31, 35)) +} + +function test(label: Label) { +>test : Symbol(test, Decl(intersectionThisTypes.ts, 33, 1)) +>label : Symbol(label, Decl(intersectionThisTypes.ts, 35, 14)) +>Label : Symbol(Label, Decl(intersectionThisTypes.ts, 29, 1)) + + const extended = label.extend({ id: 67 }).extend({ tag: "hello" }); +>extended : Symbol(extended, Decl(intersectionThisTypes.ts, 36, 9)) +>label.extend({ id: 67 }).extend : Symbol(Component.extend, Decl(intersectionThisTypes.ts, 27, 21)) +>label.extend : Symbol(Component.extend, Decl(intersectionThisTypes.ts, 27, 21)) +>label : Symbol(label, Decl(intersectionThisTypes.ts, 35, 14)) +>extend : Symbol(Component.extend, Decl(intersectionThisTypes.ts, 27, 21)) +>id : Symbol(id, Decl(intersectionThisTypes.ts, 36, 35)) +>extend : Symbol(Component.extend, Decl(intersectionThisTypes.ts, 27, 21)) +>tag : Symbol(tag, Decl(intersectionThisTypes.ts, 36, 54)) + + extended.id; // Ok +>extended.id : Symbol(id, Decl(intersectionThisTypes.ts, 36, 35)) +>extended : Symbol(extended, Decl(intersectionThisTypes.ts, 36, 9)) +>id : Symbol(id, Decl(intersectionThisTypes.ts, 36, 35)) + + extended.tag; // Ok +>extended.tag : Symbol(tag, Decl(intersectionThisTypes.ts, 36, 54)) +>extended : Symbol(extended, Decl(intersectionThisTypes.ts, 36, 9)) +>tag : Symbol(tag, Decl(intersectionThisTypes.ts, 36, 54)) +} + diff --git a/tests/baselines/reference/intersectionThisTypes.types b/tests/baselines/reference/intersectionThisTypes.types new file mode 100644 index 00000000000..285609cdfdc --- /dev/null +++ b/tests/baselines/reference/intersectionThisTypes.types @@ -0,0 +1,145 @@ +=== tests/cases/conformance/types/intersection/intersectionThisTypes.ts === +interface Thing1 { +>Thing1 : Thing1 + + a: number; +>a : number + + self(): this; +>self : () => this +} + +interface Thing2 { +>Thing2 : Thing2 + + b: number; +>b : number + + me(): this; +>me : () => this +} + +type Thing3 = Thing1 & Thing2; +>Thing3 : Thing3 +>Thing1 : Thing1 +>Thing2 : Thing2 + +type Thing4 = Thing3 & string[]; +>Thing4 : Thing4 +>Thing3 : Thing3 + +function f1(t: Thing3) { +>f1 : (t: Thing3) => void +>t : Thing3 +>Thing3 : Thing3 + + t = t.self(); +>t = t.self() : Thing3 +>t : Thing3 +>t.self() : Thing3 +>t.self : () => Thing3 +>t : Thing3 +>self : () => Thing3 + + t = t.me().self().me(); +>t = t.me().self().me() : Thing3 +>t : Thing3 +>t.me().self().me() : Thing3 +>t.me().self().me : () => Thing3 +>t.me().self() : Thing3 +>t.me().self : () => Thing3 +>t.me() : Thing3 +>t.me : () => Thing3 +>t : Thing3 +>me : () => Thing3 +>self : () => Thing3 +>me : () => Thing3 +} + +interface Thing5 extends Thing4 { +>Thing5 : Thing5 +>Thing4 : Thing4 + + c: string; +>c : string +} + +function f2(t: Thing5) { +>f2 : (t: Thing5) => void +>t : Thing5 +>Thing5 : Thing5 + + t = t.self(); +>t = t.self() : Thing5 +>t : Thing5 +>t.self() : Thing5 +>t.self : () => Thing5 +>t : Thing5 +>self : () => Thing5 + + t = t.me().self().me(); +>t = t.me().self().me() : Thing5 +>t : Thing5 +>t.me().self().me() : Thing5 +>t.me().self().me : () => Thing5 +>t.me().self() : Thing5 +>t.me().self : () => Thing5 +>t.me() : Thing5 +>t.me : () => Thing5 +>t : Thing5 +>me : () => Thing5 +>self : () => Thing5 +>me : () => Thing5 +} + +interface Component { +>Component : Component + + extend(props: T): this & T; +>extend : (props: T) => this & T +>T : T +>props : T +>T : T +>T : T +} + +interface Label extends Component { +>Label : Label +>Component : Component + + title: string; +>title : string +} + +function test(label: Label) { +>test : (label: Label) => void +>label : Label +>Label : Label + + const extended = label.extend({ id: 67 }).extend({ tag: "hello" }); +>extended : Label & { id: number; } & { tag: string; } +>label.extend({ id: 67 }).extend({ tag: "hello" }) : Label & { id: number; } & { tag: string; } +>label.extend({ id: 67 }).extend : (props: T) => Label & { id: number; } & T +>label.extend({ id: 67 }) : Label & { id: number; } +>label.extend : (props: T) => Label & T +>label : Label +>extend : (props: T) => Label & T +>{ id: 67 } : { id: number; } +>id : number +>67 : 67 +>extend : (props: T) => Label & { id: number; } & T +>{ tag: "hello" } : { tag: string; } +>tag : string +>"hello" : "hello" + + extended.id; // Ok +>extended.id : number +>extended : Label & { id: number; } & { tag: string; } +>id : number + + extended.tag; // Ok +>extended.tag : string +>extended : Label & { id: number; } & { tag: string; } +>tag : string +} + diff --git a/tests/baselines/reference/keyofAndIndexedAccess.js b/tests/baselines/reference/keyofAndIndexedAccess.js index 05658d50515..2b1b22d3595 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.js +++ b/tests/baselines/reference/keyofAndIndexedAccess.js @@ -500,6 +500,59 @@ function updateIds2( var x = obj[key]; stringMap[x]; // Should be OK. } + +// Repro from #13514 + +declare function head>(list: T): T[0]; + +// Repro from #13604 + +class A { + props: T & { foo: string }; +} + +class B extends A<{ x: number}> { + f(p: this["props"]) { + p.x; + } +} + +// Repro from #13749 + +class Form { + private childFormFactories: {[K in keyof T]: (v: T[K]) => Form} + + public set(prop: K, value: T[K]) { + 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] @@ -830,6 +883,52 @@ function updateIds2(obj, key, stringMap) { var x = obj[key]; stringMap[x]; // Should be OK. } +// Repro from #13604 +var A = (function () { + function A() { + } + return A; +}()); +var B = (function (_super) { + __extends(B, _super); + function B() { + return _super !== null && _super.apply(this, arguments) || this; + } + B.prototype.f = function (p) { + p.x; + }; + return B; +}(A)); +// Repro from #13749 +var Form = (function () { + function Form() { + } + Form.prototype.set = function (prop, value) { + this.childFormFactories[prop](value); + }; + 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] @@ -1061,3 +1160,30 @@ declare function updateIds2(obj: T, key: K, stringMap: { [oldId: string]: string; }): void; +declare function head>(list: T): T[0]; +declare class A { + props: T & { + foo: string; + }; +} +declare class B extends A<{ + x: number; +}> { + f(p: this["props"]): void; +} +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 d7bc419af24..f6425b5ed0e 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccess.symbols @@ -1806,3 +1806,160 @@ function updateIds2( >x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 498, 7)) } +// Repro from #13514 + +declare function head>(list: T): T[0]; +>head : Symbol(head, Decl(keyofAndIndexedAccess.ts, 500, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 504, 22)) +>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>list : Symbol(list, Decl(keyofAndIndexedAccess.ts, 504, 44)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 504, 22)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 504, 22)) + +// Repro from #13604 + +class A { +>A : Symbol(A, Decl(keyofAndIndexedAccess.ts, 504, 59)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 508, 8)) + + props: T & { foo: string }; +>props : Symbol(A.props, Decl(keyofAndIndexedAccess.ts, 508, 12)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 508, 8)) +>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 509, 13)) +} + +class B extends A<{ x: number}> { +>B : Symbol(B, Decl(keyofAndIndexedAccess.ts, 510, 1)) +>A : Symbol(A, Decl(keyofAndIndexedAccess.ts, 504, 59)) +>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 512, 19)) + + f(p: this["props"]) { +>f : Symbol(B.f, Decl(keyofAndIndexedAccess.ts, 512, 33)) +>p : Symbol(p, Decl(keyofAndIndexedAccess.ts, 513, 3)) + + p.x; +>p.x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 512, 19)) +>p : Symbol(p, Decl(keyofAndIndexedAccess.ts, 513, 3)) +>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 512, 19)) + } +} + +// Repro from #13749 + +class Form { +>Form : Symbol(Form, Decl(keyofAndIndexedAccess.ts, 516, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 520, 11)) + + private childFormFactories: {[K in keyof T]: (v: T[K]) => Form} +>childFormFactories : Symbol(Form.childFormFactories, Decl(keyofAndIndexedAccess.ts, 520, 15)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 521, 34)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 520, 11)) +>v : Symbol(v, Decl(keyofAndIndexedAccess.ts, 521, 50)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 520, 11)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 521, 34)) +>Form : Symbol(Form, Decl(keyofAndIndexedAccess.ts, 516, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 520, 11)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 521, 34)) + + public set(prop: K, value: T[K]) { +>set : Symbol(Form.set, Decl(keyofAndIndexedAccess.ts, 521, 73)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 523, 15)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 520, 11)) +>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 523, 34)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 523, 15)) +>value : Symbol(value, Decl(keyofAndIndexedAccess.ts, 523, 42)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 520, 11)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 523, 15)) + + this.childFormFactories[prop](value) +>this.childFormFactories : Symbol(Form.childFormFactories, Decl(keyofAndIndexedAccess.ts, 520, 15)) +>this : Symbol(Form, Decl(keyofAndIndexedAccess.ts, 516, 1)) +>childFormFactories : Symbol(Form.childFormFactories, Decl(keyofAndIndexedAccess.ts, 520, 15)) +>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 523, 34)) +>value : Symbol(value, Decl(keyofAndIndexedAccess.ts, 523, 42)) + } +} + +// 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 543c39b3c92..86469efc284 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -2128,3 +2128,170 @@ function updateIds2( >x : T[K] } +// Repro from #13514 + +declare function head>(list: T): T[0]; +>head : (list: T) => T[0] +>T : T +>Array : T[] +>list : T +>T : T +>T : T + +// Repro from #13604 + +class A { +>A : A +>T : T + + props: T & { foo: string }; +>props : T & { foo: string; } +>T : T +>foo : string +} + +class B extends A<{ x: number}> { +>B : B +>A : A<{ x: number; }> +>x : number + + f(p: this["props"]) { +>f : (p: this["props"]) => void +>p : this["props"] + + p.x; +>p.x : number +>p : this["props"] +>x : number + } +} + +// Repro from #13749 + +class Form { +>Form : Form +>T : T + + private childFormFactories: {[K in keyof T]: (v: T[K]) => Form} +>childFormFactories : { [K in keyof T]: (v: T[K]) => Form; } +>K : K +>T : T +>v : T[K] +>T : T +>K : K +>Form : Form +>T : T +>K : K + + public set(prop: K, value: T[K]) { +>set : (prop: K, value: T[K]) => void +>K : K +>T : T +>prop : K +>K : K +>value : T[K] +>T : T +>K : K + + this.childFormFactories[prop](value) +>this.childFormFactories[prop](value) : Form +>this.childFormFactories[prop] : (v: T[K]) => Form +>this.childFormFactories : { [K in keyof T]: (v: T[K]) => Form; } +>this : this +>childFormFactories : { [K in keyof T]: (v: T[K]) => Form; } +>prop : K +>value : T[K] + } +} + +// 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/literals.errors.txt b/tests/baselines/reference/literals.errors.txt index 6fa1d7d3abd..ae058e0b530 100644 --- a/tests/baselines/reference/literals.errors.txt +++ b/tests/baselines/reference/literals.errors.txt @@ -1,7 +1,7 @@ -tests/cases/conformance/expressions/literals/literals.ts(9,10): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/literals/literals.ts(9,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/literals/literals.ts(10,9): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/literals/literals.ts(10,21): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/literals/literals.ts(9,10): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/literals/literals.ts(9,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/literals/literals.ts(10,9): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/literals/literals.ts(10,21): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/literals/literals.ts(20,9): error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '0o1'. tests/cases/conformance/expressions/literals/literals.ts(25,9): error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '-0o3'. @@ -17,14 +17,14 @@ tests/cases/conformance/expressions/literals/literals.ts(25,9): error TS1085: Oc var nu = null / null; ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var u = undefined / undefined; ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var b: boolean; var b = true; diff --git a/tests/baselines/reference/logicalNotOperatorWithAnyOtherType.errors.txt b/tests/baselines/reference/logicalNotOperatorWithAnyOtherType.errors.txt index 02b4bf16fd2..0cb9869ca4c 100644 --- a/tests/baselines/reference/logicalNotOperatorWithAnyOtherType.errors.txt +++ b/tests/baselines/reference/logicalNotOperatorWithAnyOtherType.errors.txt @@ -1,10 +1,13 @@ -tests/cases/conformance/expressions/unaryOperators/logicalNotOperator/logicalNotOperatorWithAnyOtherType.ts(45,27): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. -tests/cases/conformance/expressions/unaryOperators/logicalNotOperator/logicalNotOperatorWithAnyOtherType.ts(46,27): error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. -tests/cases/conformance/expressions/unaryOperators/logicalNotOperator/logicalNotOperatorWithAnyOtherType.ts(47,27): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. +tests/cases/conformance/expressions/unaryOperators/logicalNotOperator/logicalNotOperatorWithAnyOtherType.ts(45,27): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/logicalNotOperator/logicalNotOperatorWithAnyOtherType.ts(45,34): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/unaryOperators/logicalNotOperator/logicalNotOperatorWithAnyOtherType.ts(46,27): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/logicalNotOperator/logicalNotOperatorWithAnyOtherType.ts(46,34): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/logicalNotOperator/logicalNotOperatorWithAnyOtherType.ts(47,27): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/unaryOperators/logicalNotOperator/logicalNotOperatorWithAnyOtherType.ts(47,39): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/unaryOperators/logicalNotOperator/logicalNotOperatorWithAnyOtherType.ts(57,1): error TS2695: Left side of comma operator is unused and has no side effects. -==== tests/cases/conformance/expressions/unaryOperators/logicalNotOperator/logicalNotOperatorWithAnyOtherType.ts (4 errors) ==== +==== tests/cases/conformance/expressions/unaryOperators/logicalNotOperator/logicalNotOperatorWithAnyOtherType.ts (7 errors) ==== // ! operator on any type var ANY: any; @@ -50,14 +53,20 @@ tests/cases/conformance/expressions/unaryOperators/logicalNotOperator/logicalNot var ResultIsBoolean15 = !A.foo(); var ResultIsBoolean16 = !(ANY + ANY1); var ResultIsBoolean17 = !(null + undefined); - ~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var ResultIsBoolean18 = !(null + null); - ~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var ResultIsBoolean19 = !(undefined + undefined); - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. // multiple ! operators var ResultIsBoolean20 = !!ANY; diff --git a/tests/baselines/reference/mappedTypes1.js b/tests/baselines/reference/mappedTypes1.js index 1998ad5ab6b..4dd8f172179 100644 --- a/tests/baselines/reference/mappedTypes1.js +++ b/tests/baselines/reference/mappedTypes1.js @@ -139,9 +139,9 @@ declare let x2: string; declare let x3: number; declare let x4: { toString: void; - valueOf: void; toFixed: void; toExponential: void; toPrecision: void; + valueOf: void; toLocaleString: void; }; diff --git a/tests/baselines/reference/mappedTypes1.types b/tests/baselines/reference/mappedTypes1.types index 35d13143bab..a9a7f53a899 100644 --- a/tests/baselines/reference/mappedTypes1.types +++ b/tests/baselines/reference/mappedTypes1.types @@ -165,7 +165,7 @@ let x3 = f3(); >f3 : () => { [P in keyof T1]: void; } let x4 = f4(); ->x4 : { toString: void; valueOf: void; toFixed: void; toExponential: void; toPrecision: void; toLocaleString: void; } ->f4() : { toString: void; valueOf: void; toFixed: void; toExponential: void; toPrecision: void; toLocaleString: void; } +>x4 : { toString: void; toFixed: void; toExponential: void; toPrecision: void; valueOf: void; toLocaleString: void; } +>f4() : { toString: void; toFixed: void; toExponential: void; toPrecision: void; valueOf: void; toLocaleString: void; } >f4 : () => { [P in keyof T1]: void; } diff --git a/tests/baselines/reference/mappedTypesAndObjects.js b/tests/baselines/reference/mappedTypesAndObjects.js index 53b39209693..f320cc9624e 100644 --- a/tests/baselines/reference/mappedTypesAndObjects.js +++ b/tests/baselines/reference/mappedTypesAndObjects.js @@ -12,26 +12,37 @@ function f2(x: Partial, y: Readonly) { obj = y; } +function f3(x: Partial) { + x = {}; +} + // Repro from #12900 interface Base { - foo: { [key: string]: any }; - bar: any; - baz: any; + foo: { [key: string]: any }; + bar: any; + baz: any; } interface E1 extends Base { - foo: T; + foo: T; } interface Something { name: string, value: string }; interface E2 extends Base { - foo: Partial; // or other mapped type + foo: Partial; // or other mapped type } interface E3 extends Base { - foo: Partial; // or other mapped type -} + foo: Partial; // or other mapped type +} + +// Repro from #13747 + +class Form { + private values: {[P in keyof T]?: T[P]} = {} +} + //// [mappedTypesAndObjects.js] function f1(x, y) { @@ -44,12 +55,23 @@ function f2(x, y) { obj = x; obj = y; } +function f3(x) { + x = {}; +} ; +// Repro from #13747 +var Form = (function () { + function Form() { + this.values = {}; + } + return Form; +}()); //// [mappedTypesAndObjects.d.ts] declare function f1(x: Partial, y: Readonly): void; declare function f2(x: Partial, y: Readonly): void; +declare function f3(x: Partial): void; interface Base { foo: { [key: string]: any; @@ -70,3 +92,6 @@ interface E2 extends Base { interface E3 extends Base { foo: Partial; } +declare class Form { + private values; +} diff --git a/tests/baselines/reference/mappedTypesAndObjects.symbols b/tests/baselines/reference/mappedTypesAndObjects.symbols index 1690f1b6b04..6fb5d720fb3 100644 --- a/tests/baselines/reference/mappedTypesAndObjects.symbols +++ b/tests/baselines/reference/mappedTypesAndObjects.symbols @@ -45,54 +45,80 @@ function f2(x: Partial, y: Readonly) { >y : Symbol(y, Decl(mappedTypesAndObjects.ts, 7, 29)) } +function f3(x: Partial) { +>f3 : Symbol(f3, Decl(mappedTypesAndObjects.ts, 11, 1)) +>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 13, 12)) +>x : Symbol(x, Decl(mappedTypesAndObjects.ts, 13, 15)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 13, 12)) + + x = {}; +>x : Symbol(x, Decl(mappedTypesAndObjects.ts, 13, 15)) +} + // Repro from #12900 interface Base { ->Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 11, 1)) +>Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 15, 1)) - foo: { [key: string]: any }; ->foo : Symbol(Base.foo, Decl(mappedTypesAndObjects.ts, 15, 16)) ->key : Symbol(key, Decl(mappedTypesAndObjects.ts, 16, 11)) + foo: { [key: string]: any }; +>foo : Symbol(Base.foo, Decl(mappedTypesAndObjects.ts, 19, 16)) +>key : Symbol(key, Decl(mappedTypesAndObjects.ts, 20, 12)) - bar: any; ->bar : Symbol(Base.bar, Decl(mappedTypesAndObjects.ts, 16, 31)) + bar: any; +>bar : Symbol(Base.bar, Decl(mappedTypesAndObjects.ts, 20, 32)) - baz: any; ->baz : Symbol(Base.baz, Decl(mappedTypesAndObjects.ts, 17, 12)) + baz: any; +>baz : Symbol(Base.baz, Decl(mappedTypesAndObjects.ts, 21, 13)) } interface E1 extends Base { ->E1 : Symbol(E1, Decl(mappedTypesAndObjects.ts, 19, 1)) ->T : Symbol(T, Decl(mappedTypesAndObjects.ts, 21, 13)) ->Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 11, 1)) +>E1 : Symbol(E1, Decl(mappedTypesAndObjects.ts, 23, 1)) +>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 25, 13)) +>Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 15, 1)) - foo: T; ->foo : Symbol(E1.foo, Decl(mappedTypesAndObjects.ts, 21, 30)) ->T : Symbol(T, Decl(mappedTypesAndObjects.ts, 21, 13)) + foo: T; +>foo : Symbol(E1.foo, Decl(mappedTypesAndObjects.ts, 25, 30)) +>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 25, 13)) } interface Something { name: string, value: string }; ->Something : Symbol(Something, Decl(mappedTypesAndObjects.ts, 23, 1)) ->name : Symbol(Something.name, Decl(mappedTypesAndObjects.ts, 25, 21)) ->value : Symbol(Something.value, Decl(mappedTypesAndObjects.ts, 25, 35)) +>Something : Symbol(Something, Decl(mappedTypesAndObjects.ts, 27, 1)) +>name : Symbol(Something.name, Decl(mappedTypesAndObjects.ts, 29, 21)) +>value : Symbol(Something.value, Decl(mappedTypesAndObjects.ts, 29, 35)) interface E2 extends Base { ->E2 : Symbol(E2, Decl(mappedTypesAndObjects.ts, 25, 52)) ->Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 11, 1)) +>E2 : Symbol(E2, Decl(mappedTypesAndObjects.ts, 29, 52)) +>Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 15, 1)) - foo: Partial; // or other mapped type ->foo : Symbol(E2.foo, Decl(mappedTypesAndObjects.ts, 26, 27)) + foo: Partial; // or other mapped type +>foo : Symbol(E2.foo, Decl(mappedTypesAndObjects.ts, 30, 27)) >Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) ->Something : Symbol(Something, Decl(mappedTypesAndObjects.ts, 23, 1)) +>Something : Symbol(Something, Decl(mappedTypesAndObjects.ts, 27, 1)) } interface E3 extends Base { ->E3 : Symbol(E3, Decl(mappedTypesAndObjects.ts, 28, 1)) ->T : Symbol(T, Decl(mappedTypesAndObjects.ts, 30, 13)) ->Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 11, 1)) +>E3 : Symbol(E3, Decl(mappedTypesAndObjects.ts, 32, 1)) +>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 34, 13)) +>Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 15, 1)) - foo: Partial; // or other mapped type ->foo : Symbol(E3.foo, Decl(mappedTypesAndObjects.ts, 30, 30)) + foo: Partial; // or other mapped type +>foo : Symbol(E3.foo, Decl(mappedTypesAndObjects.ts, 34, 30)) >Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) ->T : Symbol(T, Decl(mappedTypesAndObjects.ts, 30, 13)) +>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 34, 13)) } + +// Repro from #13747 + +class Form { +>Form : Symbol(Form, Decl(mappedTypesAndObjects.ts, 36, 1)) +>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 40, 11)) + + private values: {[P in keyof T]?: T[P]} = {} +>values : Symbol(Form.values, Decl(mappedTypesAndObjects.ts, 40, 15)) +>P : Symbol(P, Decl(mappedTypesAndObjects.ts, 41, 22)) +>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 40, 11)) +>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 40, 11)) +>P : Symbol(P, Decl(mappedTypesAndObjects.ts, 41, 22)) +} + diff --git a/tests/baselines/reference/mappedTypesAndObjects.types b/tests/baselines/reference/mappedTypesAndObjects.types index e6f8e53f558..75f71082f31 100644 --- a/tests/baselines/reference/mappedTypesAndObjects.types +++ b/tests/baselines/reference/mappedTypesAndObjects.types @@ -49,19 +49,32 @@ function f2(x: Partial, y: Readonly) { >y : Readonly } +function f3(x: Partial) { +>f3 : (x: Partial) => void +>T : T +>x : Partial +>Partial : Partial +>T : T + + x = {}; +>x = {} : {} +>x : Partial +>{} : {} +} + // Repro from #12900 interface Base { >Base : Base - foo: { [key: string]: any }; + foo: { [key: string]: any }; >foo : { [key: string]: any; } >key : string - bar: any; + bar: any; >bar : any - baz: any; + baz: any; >baz : any } @@ -70,7 +83,7 @@ interface E1 extends Base { >T : T >Base : Base - foo: T; + foo: T; >foo : T >T : T } @@ -84,7 +97,7 @@ interface E2 extends Base { >E2 : E2 >Base : Base - foo: Partial; // or other mapped type + foo: Partial; // or other mapped type >foo : Partial >Partial : Partial >Something : Something @@ -95,8 +108,24 @@ interface E3 extends Base { >T : T >Base : Base - foo: Partial; // or other mapped type + foo: Partial; // or other mapped type >foo : Partial >Partial : Partial >T : T } + +// Repro from #13747 + +class Form { +>Form : Form +>T : T + + private values: {[P in keyof T]?: T[P]} = {} +>values : { [P in keyof T]?: T[P] | undefined; } +>P : P +>T : T +>T : T +>P : P +>{} : {} +} + diff --git a/tests/baselines/reference/mergedDeclarations7.errors.txt b/tests/baselines/reference/mergedDeclarations7.errors.txt new file mode 100644 index 00000000000..cd9b3a5e939 --- /dev/null +++ b/tests/baselines/reference/mergedDeclarations7.errors.txt @@ -0,0 +1,32 @@ +tests/cases/compiler/test.ts(4,5): error TS2322: Type 'PassportStatic' is not assignable to type 'Passport'. + Types of property 'use' are incompatible. + Type '() => PassportStatic' is not assignable to type '() => this'. + Type 'PassportStatic' is not assignable to type 'this'. + + +==== tests/cases/compiler/passport.d.ts (0 errors) ==== + declare module 'passport' { + namespace passport { + interface Passport { + use(): this; + } + + interface PassportStatic extends Passport { + Passport: {new(): Passport}; + } + } + + const passport: passport.PassportStatic; + export = passport; + } + +==== tests/cases/compiler/test.ts (1 errors) ==== + import * as passport from "passport"; + import { Passport } from "passport"; + + let p: Passport = passport.use(); + ~ +!!! error TS2322: Type 'PassportStatic' is not assignable to type 'Passport'. +!!! error TS2322: Types of property 'use' are incompatible. +!!! error TS2322: Type '() => PassportStatic' is not assignable to type '() => this'. +!!! error TS2322: Type 'PassportStatic' is not assignable to type 'this'. \ No newline at end of file diff --git a/tests/baselines/reference/mergedDeclarations7.js b/tests/baselines/reference/mergedDeclarations7.js new file mode 100644 index 00000000000..e3d1ddc6e0e --- /dev/null +++ b/tests/baselines/reference/mergedDeclarations7.js @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/mergedDeclarations7.ts] //// + +//// [passport.d.ts] +declare module 'passport' { + namespace passport { + interface Passport { + use(): this; + } + + interface PassportStatic extends Passport { + Passport: {new(): Passport}; + } + } + + const passport: passport.PassportStatic; + export = passport; +} + +//// [test.ts] +import * as passport from "passport"; +import { Passport } from "passport"; + +let p: Passport = passport.use(); + +//// [test.js] +"use strict"; +var passport = require("passport"); +var p = passport.use(); diff --git a/tests/baselines/reference/metadataOfEventAlias.js b/tests/baselines/reference/metadataOfEventAlias.js new file mode 100644 index 00000000000..8a22a90bc2e --- /dev/null +++ b/tests/baselines/reference/metadataOfEventAlias.js @@ -0,0 +1,38 @@ +//// [tests/cases/compiler/metadataOfEventAlias.ts] //// + +//// [event.ts] + +export interface Event { title: string }; + +//// [test.ts] +import { Event } from './event'; +function Input(target: any, key: string): void { } +export class SomeClass { + @Input event: Event; +} + +//// [event.js] +"use strict"; +; +//// [test.js] +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +function Input(target, key) { } +var SomeClass = (function () { + function SomeClass() { + } + return SomeClass; +}()); +__decorate([ + Input, + __metadata("design:type", Object) +], SomeClass.prototype, "event", void 0); +exports.SomeClass = SomeClass; diff --git a/tests/baselines/reference/metadataOfEventAlias.symbols b/tests/baselines/reference/metadataOfEventAlias.symbols new file mode 100644 index 00000000000..441714e63e6 --- /dev/null +++ b/tests/baselines/reference/metadataOfEventAlias.symbols @@ -0,0 +1,23 @@ +=== tests/cases/compiler/event.ts === + +export interface Event { title: string }; +>Event : Symbol(Event, Decl(event.ts, 0, 0)) +>title : Symbol(Event.title, Decl(event.ts, 1, 24)) + +=== tests/cases/compiler/test.ts === +import { Event } from './event'; +>Event : Symbol(Event, Decl(test.ts, 0, 8)) + +function Input(target: any, key: string): void { } +>Input : Symbol(Input, Decl(test.ts, 0, 32)) +>target : Symbol(target, Decl(test.ts, 1, 15)) +>key : Symbol(key, Decl(test.ts, 1, 27)) + +export class SomeClass { +>SomeClass : Symbol(SomeClass, Decl(test.ts, 1, 50)) + + @Input event: Event; +>Input : Symbol(Input, Decl(test.ts, 0, 32)) +>event : Symbol(SomeClass.event, Decl(test.ts, 2, 24)) +>Event : Symbol(Event, Decl(test.ts, 0, 8)) +} diff --git a/tests/baselines/reference/metadataOfEventAlias.types b/tests/baselines/reference/metadataOfEventAlias.types new file mode 100644 index 00000000000..b644552f9c2 --- /dev/null +++ b/tests/baselines/reference/metadataOfEventAlias.types @@ -0,0 +1,23 @@ +=== tests/cases/compiler/event.ts === + +export interface Event { title: string }; +>Event : Event +>title : string + +=== tests/cases/compiler/test.ts === +import { Event } from './event'; +>Event : any + +function Input(target: any, key: string): void { } +>Input : (target: any, key: string) => void +>target : any +>key : string + +export class SomeClass { +>SomeClass : SomeClass + + @Input event: Event; +>Input : (target: any, key: string) => void +>event : Event +>Event : Event +} diff --git a/tests/baselines/reference/misspelledJsDocTypedefTags.symbols b/tests/baselines/reference/misspelledJsDocTypedefTags.symbols new file mode 100644 index 00000000000..bf3f6e7fab0 --- /dev/null +++ b/tests/baselines/reference/misspelledJsDocTypedefTags.symbols @@ -0,0 +1,8 @@ +=== tests/cases/compiler/a.js === + +No type information for this code./** @typedef {{ endTime: number, screenshots: number}} A.*/ +No type information for this code.Animation.AnimationModel.ScreenshotCapture.Request; +No type information for this code. +No type information for this code./** @typedef {{ endTime: number, screenshots: !B.}} */ +No type information for this code.Animation.AnimationModel.ScreenshotCapture.Request; +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/misspelledJsDocTypedefTags.types b/tests/baselines/reference/misspelledJsDocTypedefTags.types new file mode 100644 index 00000000000..70cc011ea69 --- /dev/null +++ b/tests/baselines/reference/misspelledJsDocTypedefTags.types @@ -0,0 +1,22 @@ +=== tests/cases/compiler/a.js === + +/** @typedef {{ endTime: number, screenshots: number}} A.*/ +Animation.AnimationModel.ScreenshotCapture.Request; +>Animation.AnimationModel.ScreenshotCapture.Request : any +>Animation.AnimationModel.ScreenshotCapture : any +>Animation.AnimationModel : any +>Animation : any +>AnimationModel : any +>ScreenshotCapture : any +>Request : any + +/** @typedef {{ endTime: number, screenshots: !B.}} */ +Animation.AnimationModel.ScreenshotCapture.Request; +>Animation.AnimationModel.ScreenshotCapture.Request : any +>Animation.AnimationModel.ScreenshotCapture : any +>Animation.AnimationModel : any +>Animation : any +>AnimationModel : any +>ScreenshotCapture : any +>Request : any + diff --git a/tests/baselines/reference/mixinClassesAnnotated.js b/tests/baselines/reference/mixinClassesAnnotated.js new file mode 100644 index 00000000000..e3a781033ff --- /dev/null +++ b/tests/baselines/reference/mixinClassesAnnotated.js @@ -0,0 +1,183 @@ +//// [mixinClassesAnnotated.ts] + +type Constructor = new(...args: any[]) => T; + +class Base { + constructor(public x: number, public y: number) {} +} + +class Derived extends Base { + constructor(x: number, y: number, public z: number) { + super(x, y); + } +} + +interface Printable { + print(): void; +} + +const Printable = >(superClass: T): Constructor & { message: string } & T => + class extends superClass { + static message = "hello"; + print() { + const output = this.x + "," + this.y; + } + } + +interface Tagged { + _tag: string; +} + +function Tagged>(superClass: T): Constructor & T { + class C extends superClass { + _tag: string; + constructor(...args: any[]) { + super(...args); + this._tag = "hello"; + } + } + return C; +} + +const Thing1 = Tagged(Derived); +const Thing2 = Tagged(Printable(Derived)); +Thing2.message; + +function f1() { + const thing = new Thing1(1, 2, 3); + thing.x; + thing._tag; +} + +function f2() { + const thing = new Thing2(1, 2, 3); + thing.x; + thing._tag; + thing.print(); +} + +class Thing3 extends Thing2 { + constructor(tag: string) { + super(10, 20, 30); + this._tag = tag; + } + test() { + this.print(); + } +} + + +//// [mixinClassesAnnotated.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var Base = (function () { + function Base(x, y) { + this.x = x; + this.y = y; + } + return Base; +}()); +var Derived = (function (_super) { + __extends(Derived, _super); + function Derived(x, y, z) { + var _this = _super.call(this, x, y) || this; + _this.z = z; + return _this; + } + return Derived; +}(Base)); +var Printable = function (superClass) { return _a = (function (_super) { + __extends(class_1, _super); + function class_1() { + return _super !== null && _super.apply(this, arguments) || this; + } + class_1.prototype.print = function () { + var output = this.x + "," + this.y; + }; + return class_1; + }(superClass)), + _a.message = "hello", + _a; var _a; }; +function Tagged(superClass) { + var C = (function (_super) { + __extends(C, _super); + function C() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + var _this = _super.apply(this, args) || this; + _this._tag = "hello"; + return _this; + } + return C; + }(superClass)); + return C; +} +var Thing1 = Tagged(Derived); +var Thing2 = Tagged(Printable(Derived)); +Thing2.message; +function f1() { + var thing = new Thing1(1, 2, 3); + thing.x; + thing._tag; +} +function f2() { + var thing = new Thing2(1, 2, 3); + thing.x; + thing._tag; + thing.print(); +} +var Thing3 = (function (_super) { + __extends(Thing3, _super); + function Thing3(tag) { + var _this = _super.call(this, 10, 20, 30) || this; + _this._tag = tag; + return _this; + } + Thing3.prototype.test = function () { + this.print(); + }; + return Thing3; +}(Thing2)); + + +//// [mixinClassesAnnotated.d.ts] +declare type Constructor = new (...args: any[]) => T; +declare class Base { + x: number; + y: number; + constructor(x: number, y: number); +} +declare class Derived extends Base { + z: number; + constructor(x: number, y: number, z: number); +} +interface Printable { + print(): void; +} +declare const Printable: >(superClass: T) => Constructor & { + message: string; +} & T; +interface Tagged { + _tag: string; +} +declare function Tagged>(superClass: T): Constructor & T; +declare const Thing1: Constructor & typeof Derived; +declare const Thing2: Constructor & Constructor & { + message: string; +} & typeof Derived; +declare function f1(): void; +declare function f2(): void; +declare class Thing3 extends Thing2 { + constructor(tag: string); + test(): void; +} diff --git a/tests/baselines/reference/mixinClassesAnnotated.symbols b/tests/baselines/reference/mixinClassesAnnotated.symbols new file mode 100644 index 00000000000..5a03789e2e6 --- /dev/null +++ b/tests/baselines/reference/mixinClassesAnnotated.symbols @@ -0,0 +1,193 @@ +=== tests/cases/conformance/classes/mixinClassesAnnotated.ts === + +type Constructor = new(...args: any[]) => T; +>Constructor : Symbol(Constructor, Decl(mixinClassesAnnotated.ts, 0, 0)) +>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 1, 17)) +>args : Symbol(args, Decl(mixinClassesAnnotated.ts, 1, 26)) +>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 1, 17)) + +class Base { +>Base : Symbol(Base, Decl(mixinClassesAnnotated.ts, 1, 47)) + + constructor(public x: number, public y: number) {} +>x : Symbol(Base.x, Decl(mixinClassesAnnotated.ts, 4, 16)) +>y : Symbol(Base.y, Decl(mixinClassesAnnotated.ts, 4, 33)) +} + +class Derived extends Base { +>Derived : Symbol(Derived, Decl(mixinClassesAnnotated.ts, 5, 1)) +>Base : Symbol(Base, Decl(mixinClassesAnnotated.ts, 1, 47)) + + constructor(x: number, y: number, public z: number) { +>x : Symbol(x, Decl(mixinClassesAnnotated.ts, 8, 16)) +>y : Symbol(y, Decl(mixinClassesAnnotated.ts, 8, 26)) +>z : Symbol(Derived.z, Decl(mixinClassesAnnotated.ts, 8, 37)) + + super(x, y); +>super : Symbol(Base, Decl(mixinClassesAnnotated.ts, 1, 47)) +>x : Symbol(x, Decl(mixinClassesAnnotated.ts, 8, 16)) +>y : Symbol(y, Decl(mixinClassesAnnotated.ts, 8, 26)) + } +} + +interface Printable { +>Printable : Symbol(Printable, Decl(mixinClassesAnnotated.ts, 11, 1), Decl(mixinClassesAnnotated.ts, 17, 5)) + + print(): void; +>print : Symbol(Printable.print, Decl(mixinClassesAnnotated.ts, 13, 21)) +} + +const Printable = >(superClass: T): Constructor & { message: string } & T => +>Printable : Symbol(Printable, Decl(mixinClassesAnnotated.ts, 11, 1), Decl(mixinClassesAnnotated.ts, 17, 5)) +>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 17, 19)) +>Constructor : Symbol(Constructor, Decl(mixinClassesAnnotated.ts, 0, 0)) +>Base : Symbol(Base, Decl(mixinClassesAnnotated.ts, 1, 47)) +>superClass : Symbol(superClass, Decl(mixinClassesAnnotated.ts, 17, 48)) +>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 17, 19)) +>Constructor : Symbol(Constructor, Decl(mixinClassesAnnotated.ts, 0, 0)) +>Printable : Symbol(Printable, Decl(mixinClassesAnnotated.ts, 11, 1), Decl(mixinClassesAnnotated.ts, 17, 5)) +>message : Symbol(message, Decl(mixinClassesAnnotated.ts, 17, 90)) +>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 17, 19)) + + class extends superClass { +>superClass : Symbol(superClass, Decl(mixinClassesAnnotated.ts, 17, 48)) + + static message = "hello"; +>message : Symbol((Anonymous class).message, Decl(mixinClassesAnnotated.ts, 18, 30)) + + print() { +>print : Symbol((Anonymous class).print, Decl(mixinClassesAnnotated.ts, 19, 33)) + + const output = this.x + "," + this.y; +>output : Symbol(output, Decl(mixinClassesAnnotated.ts, 21, 17)) +>this.x : Symbol(Base.x, Decl(mixinClassesAnnotated.ts, 4, 16)) +>this : Symbol((Anonymous class), Decl(mixinClassesAnnotated.ts, 17, 115)) +>x : Symbol(Base.x, Decl(mixinClassesAnnotated.ts, 4, 16)) +>this.y : Symbol(Base.y, Decl(mixinClassesAnnotated.ts, 4, 33)) +>this : Symbol((Anonymous class), Decl(mixinClassesAnnotated.ts, 17, 115)) +>y : Symbol(Base.y, Decl(mixinClassesAnnotated.ts, 4, 33)) + } + } + +interface Tagged { +>Tagged : Symbol(Tagged, Decl(mixinClassesAnnotated.ts, 23, 5), Decl(mixinClassesAnnotated.ts, 27, 1)) + + _tag: string; +>_tag : Symbol(Tagged._tag, Decl(mixinClassesAnnotated.ts, 25, 18)) +} + +function Tagged>(superClass: T): Constructor & T { +>Tagged : Symbol(Tagged, Decl(mixinClassesAnnotated.ts, 23, 5), Decl(mixinClassesAnnotated.ts, 27, 1)) +>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 29, 16)) +>Constructor : Symbol(Constructor, Decl(mixinClassesAnnotated.ts, 0, 0)) +>superClass : Symbol(superClass, Decl(mixinClassesAnnotated.ts, 29, 43)) +>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 29, 16)) +>Constructor : Symbol(Constructor, Decl(mixinClassesAnnotated.ts, 0, 0)) +>Tagged : Symbol(Tagged, Decl(mixinClassesAnnotated.ts, 23, 5), Decl(mixinClassesAnnotated.ts, 27, 1)) +>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 29, 16)) + + class C extends superClass { +>C : Symbol(C, Decl(mixinClassesAnnotated.ts, 29, 84)) +>superClass : Symbol(superClass, Decl(mixinClassesAnnotated.ts, 29, 43)) + + _tag: string; +>_tag : Symbol(C._tag, Decl(mixinClassesAnnotated.ts, 30, 32)) + + constructor(...args: any[]) { +>args : Symbol(args, Decl(mixinClassesAnnotated.ts, 32, 20)) + + super(...args); +>super : Symbol(T, Decl(mixinClassesAnnotated.ts, 29, 16)) +>args : Symbol(args, Decl(mixinClassesAnnotated.ts, 32, 20)) + + this._tag = "hello"; +>this._tag : Symbol(C._tag, Decl(mixinClassesAnnotated.ts, 30, 32)) +>this : Symbol(C, Decl(mixinClassesAnnotated.ts, 29, 84)) +>_tag : Symbol(C._tag, Decl(mixinClassesAnnotated.ts, 30, 32)) + } + } + return C; +>C : Symbol(C, Decl(mixinClassesAnnotated.ts, 29, 84)) +} + +const Thing1 = Tagged(Derived); +>Thing1 : Symbol(Thing1, Decl(mixinClassesAnnotated.ts, 40, 5)) +>Tagged : Symbol(Tagged, Decl(mixinClassesAnnotated.ts, 23, 5), Decl(mixinClassesAnnotated.ts, 27, 1)) +>Derived : Symbol(Derived, Decl(mixinClassesAnnotated.ts, 5, 1)) + +const Thing2 = Tagged(Printable(Derived)); +>Thing2 : Symbol(Thing2, Decl(mixinClassesAnnotated.ts, 41, 5)) +>Tagged : Symbol(Tagged, Decl(mixinClassesAnnotated.ts, 23, 5), Decl(mixinClassesAnnotated.ts, 27, 1)) +>Printable : Symbol(Printable, Decl(mixinClassesAnnotated.ts, 11, 1), Decl(mixinClassesAnnotated.ts, 17, 5)) +>Derived : Symbol(Derived, Decl(mixinClassesAnnotated.ts, 5, 1)) + +Thing2.message; +>Thing2.message : Symbol(message, Decl(mixinClassesAnnotated.ts, 17, 90)) +>Thing2 : Symbol(Thing2, Decl(mixinClassesAnnotated.ts, 41, 5)) +>message : Symbol(message, Decl(mixinClassesAnnotated.ts, 17, 90)) + +function f1() { +>f1 : Symbol(f1, Decl(mixinClassesAnnotated.ts, 42, 15)) + + const thing = new Thing1(1, 2, 3); +>thing : Symbol(thing, Decl(mixinClassesAnnotated.ts, 45, 9)) +>Thing1 : Symbol(Thing1, Decl(mixinClassesAnnotated.ts, 40, 5)) + + thing.x; +>thing.x : Symbol(Base.x, Decl(mixinClassesAnnotated.ts, 4, 16)) +>thing : Symbol(thing, Decl(mixinClassesAnnotated.ts, 45, 9)) +>x : Symbol(Base.x, Decl(mixinClassesAnnotated.ts, 4, 16)) + + thing._tag; +>thing._tag : Symbol(Tagged._tag, Decl(mixinClassesAnnotated.ts, 25, 18)) +>thing : Symbol(thing, Decl(mixinClassesAnnotated.ts, 45, 9)) +>_tag : Symbol(Tagged._tag, Decl(mixinClassesAnnotated.ts, 25, 18)) +} + +function f2() { +>f2 : Symbol(f2, Decl(mixinClassesAnnotated.ts, 48, 1)) + + const thing = new Thing2(1, 2, 3); +>thing : Symbol(thing, Decl(mixinClassesAnnotated.ts, 51, 9)) +>Thing2 : Symbol(Thing2, Decl(mixinClassesAnnotated.ts, 41, 5)) + + thing.x; +>thing.x : Symbol(Base.x, Decl(mixinClassesAnnotated.ts, 4, 16)) +>thing : Symbol(thing, Decl(mixinClassesAnnotated.ts, 51, 9)) +>x : Symbol(Base.x, Decl(mixinClassesAnnotated.ts, 4, 16)) + + thing._tag; +>thing._tag : Symbol(Tagged._tag, Decl(mixinClassesAnnotated.ts, 25, 18)) +>thing : Symbol(thing, Decl(mixinClassesAnnotated.ts, 51, 9)) +>_tag : Symbol(Tagged._tag, Decl(mixinClassesAnnotated.ts, 25, 18)) + + thing.print(); +>thing.print : Symbol(Printable.print, Decl(mixinClassesAnnotated.ts, 13, 21)) +>thing : Symbol(thing, Decl(mixinClassesAnnotated.ts, 51, 9)) +>print : Symbol(Printable.print, Decl(mixinClassesAnnotated.ts, 13, 21)) +} + +class Thing3 extends Thing2 { +>Thing3 : Symbol(Thing3, Decl(mixinClassesAnnotated.ts, 55, 1)) +>Thing2 : Symbol(Thing2, Decl(mixinClassesAnnotated.ts, 41, 5)) + + constructor(tag: string) { +>tag : Symbol(tag, Decl(mixinClassesAnnotated.ts, 58, 16)) + + super(10, 20, 30); + this._tag = tag; +>this._tag : Symbol(Tagged._tag, Decl(mixinClassesAnnotated.ts, 25, 18)) +>this : Symbol(Thing3, Decl(mixinClassesAnnotated.ts, 55, 1)) +>_tag : Symbol(Tagged._tag, Decl(mixinClassesAnnotated.ts, 25, 18)) +>tag : Symbol(tag, Decl(mixinClassesAnnotated.ts, 58, 16)) + } + test() { +>test : Symbol(Thing3.test, Decl(mixinClassesAnnotated.ts, 61, 5)) + + this.print(); +>this.print : Symbol(Printable.print, Decl(mixinClassesAnnotated.ts, 13, 21)) +>this : Symbol(Thing3, Decl(mixinClassesAnnotated.ts, 55, 1)) +>print : Symbol(Printable.print, Decl(mixinClassesAnnotated.ts, 13, 21)) + } +} + diff --git a/tests/baselines/reference/mixinClassesAnnotated.types b/tests/baselines/reference/mixinClassesAnnotated.types new file mode 100644 index 00000000000..afaf4c4d25e --- /dev/null +++ b/tests/baselines/reference/mixinClassesAnnotated.types @@ -0,0 +1,224 @@ +=== tests/cases/conformance/classes/mixinClassesAnnotated.ts === + +type Constructor = new(...args: any[]) => T; +>Constructor : Constructor +>T : T +>args : any[] +>T : T + +class Base { +>Base : Base + + constructor(public x: number, public y: number) {} +>x : number +>y : number +} + +class Derived extends Base { +>Derived : Derived +>Base : Base + + constructor(x: number, y: number, public z: number) { +>x : number +>y : number +>z : number + + super(x, y); +>super(x, y) : void +>super : typeof Base +>x : number +>y : number + } +} + +interface Printable { +>Printable : Printable + + print(): void; +>print : () => void +} + +const Printable = >(superClass: T): Constructor & { message: string } & T => +>Printable : >(superClass: T) => Constructor & { message: string; } & T +>>(superClass: T): Constructor & { message: string } & T => class extends superClass { static message = "hello"; print() { const output = this.x + "," + this.y; } } : >(superClass: T) => Constructor & { message: string; } & T +>T : T +>Constructor : Constructor +>Base : Base +>superClass : T +>T : T +>Constructor : Constructor +>Printable : Printable +>message : string +>T : T + + class extends superClass { +>class extends superClass { static message = "hello"; print() { const output = this.x + "," + this.y; } } : { new (...args: any[]): (Anonymous class); prototype: .(Anonymous class); message: string; } & T +>superClass : Base + + static message = "hello"; +>message : string +>"hello" : "hello" + + print() { +>print : () => void + + const output = this.x + "," + this.y; +>output : string +>this.x + "," + this.y : string +>this.x + "," : string +>this.x : number +>this : this +>x : number +>"," : "," +>this.y : number +>this : this +>y : number + } + } + +interface Tagged { +>Tagged : Tagged + + _tag: string; +>_tag : string +} + +function Tagged>(superClass: T): Constructor & T { +>Tagged : >(superClass: T) => Constructor & T +>T : T +>Constructor : Constructor +>superClass : T +>T : T +>Constructor : Constructor +>Tagged : Tagged +>T : T + + class C extends superClass { +>C : C +>superClass : {} + + _tag: string; +>_tag : string + + constructor(...args: any[]) { +>args : any[] + + super(...args); +>super(...args) : void +>super : T +>...args : any +>args : any[] + + this._tag = "hello"; +>this._tag = "hello" : "hello" +>this._tag : string +>this : this +>_tag : string +>"hello" : "hello" + } + } + return C; +>C : { new (...args: any[]): C; prototype: Tagged.C; } & T +} + +const Thing1 = Tagged(Derived); +>Thing1 : Constructor & typeof Derived +>Tagged(Derived) : Constructor & typeof Derived +>Tagged : >(superClass: T) => Constructor & T +>Derived : typeof Derived + +const Thing2 = Tagged(Printable(Derived)); +>Thing2 : Constructor & Constructor & { message: string; } & typeof Derived +>Tagged(Printable(Derived)) : Constructor & Constructor & { message: string; } & typeof Derived +>Tagged : >(superClass: T) => Constructor & T +>Printable(Derived) : Constructor & { message: string; } & typeof Derived +>Printable : >(superClass: T) => Constructor & { message: string; } & T +>Derived : typeof Derived + +Thing2.message; +>Thing2.message : string +>Thing2 : Constructor & Constructor & { message: string; } & typeof Derived +>message : string + +function f1() { +>f1 : () => void + + const thing = new Thing1(1, 2, 3); +>thing : Tagged & Derived +>new Thing1(1, 2, 3) : Tagged & Derived +>Thing1 : Constructor & typeof Derived +>1 : 1 +>2 : 2 +>3 : 3 + + thing.x; +>thing.x : number +>thing : Tagged & Derived +>x : number + + thing._tag; +>thing._tag : string +>thing : Tagged & Derived +>_tag : string +} + +function f2() { +>f2 : () => void + + const thing = new Thing2(1, 2, 3); +>thing : Tagged & Printable & Derived +>new Thing2(1, 2, 3) : Tagged & Printable & Derived +>Thing2 : Constructor & Constructor & { message: string; } & typeof Derived +>1 : 1 +>2 : 2 +>3 : 3 + + thing.x; +>thing.x : number +>thing : Tagged & Printable & Derived +>x : number + + thing._tag; +>thing._tag : string +>thing : Tagged & Printable & Derived +>_tag : string + + thing.print(); +>thing.print() : void +>thing.print : () => void +>thing : Tagged & Printable & Derived +>print : () => void +} + +class Thing3 extends Thing2 { +>Thing3 : Thing3 +>Thing2 : Tagged & Printable & Derived + + constructor(tag: string) { +>tag : string + + super(10, 20, 30); +>super(10, 20, 30) : void +>super : Constructor & Constructor & { message: string; } & typeof Derived +>10 : 10 +>20 : 20 +>30 : 30 + + this._tag = tag; +>this._tag = tag : string +>this._tag : string +>this : this +>_tag : string +>tag : string + } + test() { +>test : () => void + + this.print(); +>this.print() : void +>this.print : () => void +>this : this +>print : () => void + } +} + diff --git a/tests/baselines/reference/mixinClassesAnonymous.js b/tests/baselines/reference/mixinClassesAnonymous.js new file mode 100644 index 00000000000..aa148c25acf --- /dev/null +++ b/tests/baselines/reference/mixinClassesAnonymous.js @@ -0,0 +1,160 @@ +//// [mixinClassesAnonymous.ts] +type Constructor = new(...args: any[]) => T; + +class Base { + constructor(public x: number, public y: number) {} +} + +class Derived extends Base { + constructor(x: number, y: number, public z: number) { + super(x, y); + } +} + +const Printable = >(superClass: T) => class extends superClass { + static message = "hello"; + print() { + const output = this.x + "," + this.y; + } +} + +function Tagged>(superClass: T) { + class C extends superClass { + _tag: string; + constructor(...args: any[]) { + super(...args); + this._tag = "hello"; + } + } + return C; +} + +const Thing1 = Tagged(Derived); +const Thing2 = Tagged(Printable(Derived)); +Thing2.message; + +function f1() { + const thing = new Thing1(1, 2, 3); + thing.x; + thing._tag; +} + +function f2() { + const thing = new Thing2(1, 2, 3); + thing.x; + thing._tag; + thing.print(); +} + +class Thing3 extends Thing2 { + constructor(tag: string) { + super(10, 20, 30); + this._tag = tag; + } + test() { + this.print(); + } +} + +// Repro from #13805 + +const Timestamped = >(Base: CT) => { + return class extends Base { + timestamp = new Date(); + }; +} + + +//// [mixinClassesAnonymous.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var Base = (function () { + function Base(x, y) { + this.x = x; + this.y = y; + } + return Base; +}()); +var Derived = (function (_super) { + __extends(Derived, _super); + function Derived(x, y, z) { + var _this = _super.call(this, x, y) || this; + _this.z = z; + return _this; + } + return Derived; +}(Base)); +var Printable = function (superClass) { return _a = (function (_super) { + __extends(class_1, _super); + function class_1() { + return _super !== null && _super.apply(this, arguments) || this; + } + class_1.prototype.print = function () { + var output = this.x + "," + this.y; + }; + return class_1; + }(superClass)), + _a.message = "hello", + _a; var _a; }; +function Tagged(superClass) { + var C = (function (_super) { + __extends(C, _super); + function C() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + var _this = _super.apply(this, args) || this; + _this._tag = "hello"; + return _this; + } + return C; + }(superClass)); + return C; +} +var Thing1 = Tagged(Derived); +var Thing2 = Tagged(Printable(Derived)); +Thing2.message; +function f1() { + var thing = new Thing1(1, 2, 3); + thing.x; + thing._tag; +} +function f2() { + var thing = new Thing2(1, 2, 3); + thing.x; + thing._tag; + thing.print(); +} +var Thing3 = (function (_super) { + __extends(Thing3, _super); + function Thing3(tag) { + var _this = _super.call(this, 10, 20, 30) || this; + _this._tag = tag; + return _this; + } + Thing3.prototype.test = function () { + this.print(); + }; + 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 new file mode 100644 index 00000000000..bd709501f31 --- /dev/null +++ b/tests/baselines/reference/mixinClassesAnonymous.symbols @@ -0,0 +1,188 @@ +=== tests/cases/conformance/classes/mixinClassesAnonymous.ts === +type Constructor = new(...args: any[]) => T; +>Constructor : Symbol(Constructor, Decl(mixinClassesAnonymous.ts, 0, 0)) +>T : Symbol(T, Decl(mixinClassesAnonymous.ts, 0, 17)) +>args : Symbol(args, Decl(mixinClassesAnonymous.ts, 0, 26)) +>T : Symbol(T, Decl(mixinClassesAnonymous.ts, 0, 17)) + +class Base { +>Base : Symbol(Base, Decl(mixinClassesAnonymous.ts, 0, 47)) + + constructor(public x: number, public y: number) {} +>x : Symbol(Base.x, Decl(mixinClassesAnonymous.ts, 3, 16)) +>y : Symbol(Base.y, Decl(mixinClassesAnonymous.ts, 3, 33)) +} + +class Derived extends Base { +>Derived : Symbol(Derived, Decl(mixinClassesAnonymous.ts, 4, 1)) +>Base : Symbol(Base, Decl(mixinClassesAnonymous.ts, 0, 47)) + + constructor(x: number, y: number, public z: number) { +>x : Symbol(x, Decl(mixinClassesAnonymous.ts, 7, 16)) +>y : Symbol(y, Decl(mixinClassesAnonymous.ts, 7, 26)) +>z : Symbol(Derived.z, Decl(mixinClassesAnonymous.ts, 7, 37)) + + super(x, y); +>super : Symbol(Base, Decl(mixinClassesAnonymous.ts, 0, 47)) +>x : Symbol(x, Decl(mixinClassesAnonymous.ts, 7, 16)) +>y : Symbol(y, Decl(mixinClassesAnonymous.ts, 7, 26)) + } +} + +const Printable = >(superClass: T) => class extends superClass { +>Printable : Symbol(Printable, Decl(mixinClassesAnonymous.ts, 12, 5)) +>T : Symbol(T, Decl(mixinClassesAnonymous.ts, 12, 19)) +>Constructor : Symbol(Constructor, Decl(mixinClassesAnonymous.ts, 0, 0)) +>Base : Symbol(Base, Decl(mixinClassesAnonymous.ts, 0, 47)) +>superClass : Symbol(superClass, Decl(mixinClassesAnonymous.ts, 12, 48)) +>T : Symbol(T, Decl(mixinClassesAnonymous.ts, 12, 19)) +>superClass : Symbol(superClass, Decl(mixinClassesAnonymous.ts, 12, 48)) + + static message = "hello"; +>message : Symbol((Anonymous class).message, Decl(mixinClassesAnonymous.ts, 12, 92)) + + print() { +>print : Symbol((Anonymous class).print, Decl(mixinClassesAnonymous.ts, 13, 29)) + + const output = this.x + "," + this.y; +>output : Symbol(output, Decl(mixinClassesAnonymous.ts, 15, 13)) +>this.x : Symbol(Base.x, Decl(mixinClassesAnonymous.ts, 3, 16)) +>this : Symbol((Anonymous class), Decl(mixinClassesAnonymous.ts, 12, 65)) +>x : Symbol(Base.x, Decl(mixinClassesAnonymous.ts, 3, 16)) +>this.y : Symbol(Base.y, Decl(mixinClassesAnonymous.ts, 3, 33)) +>this : Symbol((Anonymous class), Decl(mixinClassesAnonymous.ts, 12, 65)) +>y : Symbol(Base.y, Decl(mixinClassesAnonymous.ts, 3, 33)) + } +} + +function Tagged>(superClass: T) { +>Tagged : Symbol(Tagged, Decl(mixinClassesAnonymous.ts, 17, 1)) +>T : Symbol(T, Decl(mixinClassesAnonymous.ts, 19, 16)) +>Constructor : Symbol(Constructor, Decl(mixinClassesAnonymous.ts, 0, 0)) +>superClass : Symbol(superClass, Decl(mixinClassesAnonymous.ts, 19, 43)) +>T : Symbol(T, Decl(mixinClassesAnonymous.ts, 19, 16)) + + class C extends superClass { +>C : Symbol(C, Decl(mixinClassesAnonymous.ts, 19, 59)) +>superClass : Symbol(superClass, Decl(mixinClassesAnonymous.ts, 19, 43)) + + _tag: string; +>_tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32)) + + constructor(...args: any[]) { +>args : Symbol(args, Decl(mixinClassesAnonymous.ts, 22, 20)) + + super(...args); +>super : Symbol(T, Decl(mixinClassesAnonymous.ts, 19, 16)) +>args : Symbol(args, Decl(mixinClassesAnonymous.ts, 22, 20)) + + this._tag = "hello"; +>this._tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32)) +>this : Symbol(C, Decl(mixinClassesAnonymous.ts, 19, 59)) +>_tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32)) + } + } + return C; +>C : Symbol(C, Decl(mixinClassesAnonymous.ts, 19, 59)) +} + +const Thing1 = Tagged(Derived); +>Thing1 : Symbol(Thing1, Decl(mixinClassesAnonymous.ts, 30, 5)) +>Tagged : Symbol(Tagged, Decl(mixinClassesAnonymous.ts, 17, 1)) +>Derived : Symbol(Derived, Decl(mixinClassesAnonymous.ts, 4, 1)) + +const Thing2 = Tagged(Printable(Derived)); +>Thing2 : Symbol(Thing2, Decl(mixinClassesAnonymous.ts, 31, 5)) +>Tagged : Symbol(Tagged, Decl(mixinClassesAnonymous.ts, 17, 1)) +>Printable : Symbol(Printable, Decl(mixinClassesAnonymous.ts, 12, 5)) +>Derived : Symbol(Derived, Decl(mixinClassesAnonymous.ts, 4, 1)) + +Thing2.message; +>Thing2.message : Symbol((Anonymous class).message, Decl(mixinClassesAnonymous.ts, 12, 92)) +>Thing2 : Symbol(Thing2, Decl(mixinClassesAnonymous.ts, 31, 5)) +>message : Symbol((Anonymous class).message, Decl(mixinClassesAnonymous.ts, 12, 92)) + +function f1() { +>f1 : Symbol(f1, Decl(mixinClassesAnonymous.ts, 32, 15)) + + const thing = new Thing1(1, 2, 3); +>thing : Symbol(thing, Decl(mixinClassesAnonymous.ts, 35, 9)) +>Thing1 : Symbol(Thing1, Decl(mixinClassesAnonymous.ts, 30, 5)) + + thing.x; +>thing.x : Symbol(Base.x, Decl(mixinClassesAnonymous.ts, 3, 16)) +>thing : Symbol(thing, Decl(mixinClassesAnonymous.ts, 35, 9)) +>x : Symbol(Base.x, Decl(mixinClassesAnonymous.ts, 3, 16)) + + thing._tag; +>thing._tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32)) +>thing : Symbol(thing, Decl(mixinClassesAnonymous.ts, 35, 9)) +>_tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32)) +} + +function f2() { +>f2 : Symbol(f2, Decl(mixinClassesAnonymous.ts, 38, 1)) + + const thing = new Thing2(1, 2, 3); +>thing : Symbol(thing, Decl(mixinClassesAnonymous.ts, 41, 9)) +>Thing2 : Symbol(Thing2, Decl(mixinClassesAnonymous.ts, 31, 5)) + + thing.x; +>thing.x : Symbol(Base.x, Decl(mixinClassesAnonymous.ts, 3, 16)) +>thing : Symbol(thing, Decl(mixinClassesAnonymous.ts, 41, 9)) +>x : Symbol(Base.x, Decl(mixinClassesAnonymous.ts, 3, 16)) + + thing._tag; +>thing._tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32)) +>thing : Symbol(thing, Decl(mixinClassesAnonymous.ts, 41, 9)) +>_tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32)) + + thing.print(); +>thing.print : Symbol((Anonymous class).print, Decl(mixinClassesAnonymous.ts, 13, 29)) +>thing : Symbol(thing, Decl(mixinClassesAnonymous.ts, 41, 9)) +>print : Symbol((Anonymous class).print, Decl(mixinClassesAnonymous.ts, 13, 29)) +} + +class Thing3 extends Thing2 { +>Thing3 : Symbol(Thing3, Decl(mixinClassesAnonymous.ts, 45, 1)) +>Thing2 : Symbol(Thing2, Decl(mixinClassesAnonymous.ts, 31, 5)) + + constructor(tag: string) { +>tag : Symbol(tag, Decl(mixinClassesAnonymous.ts, 48, 16)) + + super(10, 20, 30); + this._tag = tag; +>this._tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32)) +>this : Symbol(Thing3, Decl(mixinClassesAnonymous.ts, 45, 1)) +>_tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32)) +>tag : Symbol(tag, Decl(mixinClassesAnonymous.ts, 48, 16)) + } + test() { +>test : Symbol(Thing3.test, Decl(mixinClassesAnonymous.ts, 51, 5)) + + this.print(); +>this.print : Symbol((Anonymous class).print, Decl(mixinClassesAnonymous.ts, 13, 29)) +>this : Symbol(Thing3, Decl(mixinClassesAnonymous.ts, 45, 1)) +>print : Symbol((Anonymous class).print, Decl(mixinClassesAnonymous.ts, 13, 29)) + } +} + +// 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 new file mode 100644 index 00000000000..516b15af2f3 --- /dev/null +++ b/tests/baselines/reference/mixinClassesAnonymous.types @@ -0,0 +1,222 @@ +=== tests/cases/conformance/classes/mixinClassesAnonymous.ts === +type Constructor = new(...args: any[]) => T; +>Constructor : Constructor +>T : T +>args : any[] +>T : T + +class Base { +>Base : Base + + constructor(public x: number, public y: number) {} +>x : number +>y : number +} + +class Derived extends Base { +>Derived : Derived +>Base : Base + + constructor(x: number, y: number, public z: number) { +>x : number +>y : number +>z : number + + super(x, y); +>super(x, y) : void +>super : typeof Base +>x : number +>y : number + } +} + +const Printable = >(superClass: T) => class extends superClass { +>Printable : >(superClass: T) => { new (...args: any[]): (Anonymous class); prototype: .(Anonymous class); message: string; } & T +>>(superClass: T) => class extends superClass { static message = "hello"; print() { const output = this.x + "," + this.y; }} : >(superClass: T) => { new (...args: any[]): (Anonymous class); prototype: .(Anonymous class); message: string; } & T +>T : T +>Constructor : Constructor +>Base : Base +>superClass : T +>T : T +>class extends superClass { static message = "hello"; print() { const output = this.x + "," + this.y; }} : { new (...args: any[]): (Anonymous class); prototype: .(Anonymous class); message: string; } & T +>superClass : Base + + static message = "hello"; +>message : string +>"hello" : "hello" + + print() { +>print : () => void + + const output = this.x + "," + this.y; +>output : string +>this.x + "," + this.y : string +>this.x + "," : string +>this.x : number +>this : this +>x : number +>"," : "," +>this.y : number +>this : this +>y : number + } +} + +function Tagged>(superClass: T) { +>Tagged : >(superClass: T) => { new (...args: any[]): C; prototype: Tagged.C; } & T +>T : T +>Constructor : Constructor +>superClass : T +>T : T + + class C extends superClass { +>C : C +>superClass : {} + + _tag: string; +>_tag : string + + constructor(...args: any[]) { +>args : any[] + + super(...args); +>super(...args) : void +>super : T +>...args : any +>args : any[] + + this._tag = "hello"; +>this._tag = "hello" : "hello" +>this._tag : string +>this : this +>_tag : string +>"hello" : "hello" + } + } + return C; +>C : { new (...args: any[]): C; prototype: Tagged.C; } & T +} + +const Thing1 = Tagged(Derived); +>Thing1 : { new (...args: any[]): Tagged.C; prototype: Tagged.C; } & typeof Derived +>Tagged(Derived) : { new (...args: any[]): Tagged.C; prototype: Tagged.C; } & typeof Derived +>Tagged : >(superClass: T) => { new (...args: any[]): C; prototype: Tagged.C; } & T +>Derived : typeof Derived + +const Thing2 = Tagged(Printable(Derived)); +>Thing2 : { new (...args: any[]): Tagged<{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived>.C; prototype: Tagged.C; } & { new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived +>Tagged(Printable(Derived)) : { new (...args: any[]): Tagged<{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived>.C; prototype: Tagged.C; } & { new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived +>Tagged : >(superClass: T) => { new (...args: any[]): C; prototype: Tagged.C; } & T +>Printable(Derived) : { new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived +>Printable : >(superClass: T) => { new (...args: any[]): (Anonymous class); prototype: .(Anonymous class); message: string; } & T +>Derived : typeof Derived + +Thing2.message; +>Thing2.message : string +>Thing2 : { new (...args: any[]): Tagged<{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived>.C; prototype: Tagged.C; } & { new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived +>message : string + +function f1() { +>f1 : () => void + + const thing = new Thing1(1, 2, 3); +>thing : Tagged.C & Derived +>new Thing1(1, 2, 3) : Tagged.C & Derived +>Thing1 : { new (...args: any[]): Tagged.C; prototype: Tagged.C; } & typeof Derived +>1 : 1 +>2 : 2 +>3 : 3 + + thing.x; +>thing.x : number +>thing : Tagged.C & Derived +>x : number + + thing._tag; +>thing._tag : string +>thing : Tagged.C & Derived +>_tag : string +} + +function f2() { +>f2 : () => void + + const thing = new Thing2(1, 2, 3); +>thing : Tagged<{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived>.C & .(Anonymous class) & Derived +>new Thing2(1, 2, 3) : Tagged<{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived>.C & .(Anonymous class) & Derived +>Thing2 : { new (...args: any[]): Tagged<{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived>.C; prototype: Tagged.C; } & { new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived +>1 : 1 +>2 : 2 +>3 : 3 + + thing.x; +>thing.x : number +>thing : Tagged<{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived>.C & .(Anonymous class) & Derived +>x : number + + thing._tag; +>thing._tag : string +>thing : Tagged<{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived>.C & .(Anonymous class) & Derived +>_tag : string + + thing.print(); +>thing.print() : void +>thing.print : () => void +>thing : Tagged<{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived>.C & .(Anonymous class) & Derived +>print : () => void +} + +class Thing3 extends Thing2 { +>Thing3 : Thing3 +>Thing2 : Tagged<{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived>.C & .(Anonymous class) & Derived + + constructor(tag: string) { +>tag : string + + super(10, 20, 30); +>super(10, 20, 30) : void +>super : { new (...args: any[]): Tagged<{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived>.C; prototype: Tagged.C; } & { new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived +>10 : 10 +>20 : 20 +>30 : 30 + + this._tag = tag; +>this._tag = tag : string +>this._tag : string +>this : this +>_tag : string +>tag : string + } + test() { +>test : () => void + + this.print(); +>this.print() : void +>this.print : () => void +>this : this +>print : () => void + } +} + +// 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/mixinClassesMembers.js b/tests/baselines/reference/mixinClassesMembers.js new file mode 100644 index 00000000000..01fc1bb0032 --- /dev/null +++ b/tests/baselines/reference/mixinClassesMembers.js @@ -0,0 +1,220 @@ +//// [mixinClassesMembers.ts] + +declare class C1 { + public a: number; + protected b: number; + private c: number; + constructor(s: string); + constructor(n: number); +} + +declare class M1 { + constructor(...args: any[]); + p: number; + static p: number; +} + +declare class M2 { + constructor(...args: any[]); + f(): number; + static f(): number; +} + +declare const Mixed1: typeof M1 & typeof C1; +declare const Mixed2: typeof C1 & typeof M1; +declare const Mixed3: typeof M2 & typeof M1 & typeof C1; +declare const Mixed4: typeof C1 & typeof M1 & typeof M2; +declare const Mixed5: typeof M1 & typeof M2; + +function f1() { + let x1 = new Mixed1("hello"); + let x2 = new Mixed1(42); + let x3 = new Mixed2("hello"); + let x4 = new Mixed2(42); + let x5 = new Mixed3("hello"); + let x6 = new Mixed3(42); + let x7 = new Mixed4("hello"); + let x8 = new Mixed4(42); + let x9 = new Mixed5(); +} + +function f2() { + let x = new Mixed1("hello"); + x.a; + x.p; + Mixed1.p; +} + +function f3() { + let x = new Mixed2("hello"); + x.a; + x.p; + Mixed2.p; +} + +function f4() { + let x = new Mixed3("hello"); + x.a; + x.p; + x.f(); + Mixed3.p; + Mixed3.f(); +} + +function f5() { + let x = new Mixed4("hello"); + x.a; + x.p; + x.f(); + Mixed4.p; + Mixed4.f(); +} + +function f6() { + let x = new Mixed5(); + x.p; + x.f(); + Mixed5.p; + Mixed5.f(); +} + +class C2 extends Mixed1 { + constructor() { + super("hello"); + this.a; + this.b; + this.p; + } +} + +class C3 extends Mixed3 { + constructor() { + super(42); + this.a; + this.b; + this.p; + this.f(); + } + f() { return super.f(); } +} + + +//// [mixinClassesMembers.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +function f1() { + var x1 = new Mixed1("hello"); + var x2 = new Mixed1(42); + var x3 = new Mixed2("hello"); + var x4 = new Mixed2(42); + var x5 = new Mixed3("hello"); + var x6 = new Mixed3(42); + var x7 = new Mixed4("hello"); + var x8 = new Mixed4(42); + var x9 = new Mixed5(); +} +function f2() { + var x = new Mixed1("hello"); + x.a; + x.p; + Mixed1.p; +} +function f3() { + var x = new Mixed2("hello"); + x.a; + x.p; + Mixed2.p; +} +function f4() { + var x = new Mixed3("hello"); + x.a; + x.p; + x.f(); + Mixed3.p; + Mixed3.f(); +} +function f5() { + var x = new Mixed4("hello"); + x.a; + x.p; + x.f(); + Mixed4.p; + Mixed4.f(); +} +function f6() { + var x = new Mixed5(); + x.p; + x.f(); + Mixed5.p; + Mixed5.f(); +} +var C2 = (function (_super) { + __extends(C2, _super); + function C2() { + var _this = _super.call(this, "hello") || this; + _this.a; + _this.b; + _this.p; + return _this; + } + return C2; +}(Mixed1)); +var C3 = (function (_super) { + __extends(C3, _super); + function C3() { + var _this = _super.call(this, 42) || this; + _this.a; + _this.b; + _this.p; + _this.f(); + return _this; + } + C3.prototype.f = function () { return _super.prototype.f.call(this); }; + return C3; +}(Mixed3)); + + +//// [mixinClassesMembers.d.ts] +declare class C1 { + a: number; + protected b: number; + private c; + constructor(s: string); + constructor(n: number); +} +declare class M1 { + constructor(...args: any[]); + p: number; + static p: number; +} +declare class M2 { + constructor(...args: any[]); + f(): number; + static f(): number; +} +declare const Mixed1: typeof M1 & typeof C1; +declare const Mixed2: typeof C1 & typeof M1; +declare const Mixed3: typeof M2 & typeof M1 & typeof C1; +declare const Mixed4: typeof C1 & typeof M1 & typeof M2; +declare const Mixed5: typeof M1 & typeof M2; +declare function f1(): void; +declare function f2(): void; +declare function f3(): void; +declare function f4(): void; +declare function f5(): void; +declare function f6(): void; +declare class C2 extends Mixed1 { + constructor(); +} +declare class C3 extends Mixed3 { + constructor(); + f(): number; +} diff --git a/tests/baselines/reference/mixinClassesMembers.symbols b/tests/baselines/reference/mixinClassesMembers.symbols new file mode 100644 index 00000000000..fabfe7e6d86 --- /dev/null +++ b/tests/baselines/reference/mixinClassesMembers.symbols @@ -0,0 +1,309 @@ +=== tests/cases/conformance/classes/mixinClassesMembers.ts === + +declare class C1 { +>C1 : Symbol(C1, Decl(mixinClassesMembers.ts, 0, 0)) + + public a: number; +>a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) + + protected b: number; +>b : Symbol(C1.b, Decl(mixinClassesMembers.ts, 2, 21)) + + private c: number; +>c : Symbol(C1.c, Decl(mixinClassesMembers.ts, 3, 24)) + + constructor(s: string); +>s : Symbol(s, Decl(mixinClassesMembers.ts, 5, 16)) + + constructor(n: number); +>n : Symbol(n, Decl(mixinClassesMembers.ts, 6, 16)) +} + +declare class M1 { +>M1 : Symbol(M1, Decl(mixinClassesMembers.ts, 7, 1)) + + constructor(...args: any[]); +>args : Symbol(args, Decl(mixinClassesMembers.ts, 10, 16)) + + p: number; +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) + + static p: number; +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14)) +} + +declare class M2 { +>M2 : Symbol(M2, Decl(mixinClassesMembers.ts, 13, 1)) + + constructor(...args: any[]); +>args : Symbol(args, Decl(mixinClassesMembers.ts, 16, 16)) + + f(): number; +>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32)) + + static f(): number; +>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 17, 16)) +} + +declare const Mixed1: typeof M1 & typeof C1; +>Mixed1 : Symbol(Mixed1, Decl(mixinClassesMembers.ts, 21, 13)) +>M1 : Symbol(M1, Decl(mixinClassesMembers.ts, 7, 1)) +>C1 : Symbol(C1, Decl(mixinClassesMembers.ts, 0, 0)) + +declare const Mixed2: typeof C1 & typeof M1; +>Mixed2 : Symbol(Mixed2, Decl(mixinClassesMembers.ts, 22, 13)) +>C1 : Symbol(C1, Decl(mixinClassesMembers.ts, 0, 0)) +>M1 : Symbol(M1, Decl(mixinClassesMembers.ts, 7, 1)) + +declare const Mixed3: typeof M2 & typeof M1 & typeof C1; +>Mixed3 : Symbol(Mixed3, Decl(mixinClassesMembers.ts, 23, 13)) +>M2 : Symbol(M2, Decl(mixinClassesMembers.ts, 13, 1)) +>M1 : Symbol(M1, Decl(mixinClassesMembers.ts, 7, 1)) +>C1 : Symbol(C1, Decl(mixinClassesMembers.ts, 0, 0)) + +declare const Mixed4: typeof C1 & typeof M1 & typeof M2; +>Mixed4 : Symbol(Mixed4, Decl(mixinClassesMembers.ts, 24, 13)) +>C1 : Symbol(C1, Decl(mixinClassesMembers.ts, 0, 0)) +>M1 : Symbol(M1, Decl(mixinClassesMembers.ts, 7, 1)) +>M2 : Symbol(M2, Decl(mixinClassesMembers.ts, 13, 1)) + +declare const Mixed5: typeof M1 & typeof M2; +>Mixed5 : Symbol(Mixed5, Decl(mixinClassesMembers.ts, 25, 13)) +>M1 : Symbol(M1, Decl(mixinClassesMembers.ts, 7, 1)) +>M2 : Symbol(M2, Decl(mixinClassesMembers.ts, 13, 1)) + +function f1() { +>f1 : Symbol(f1, Decl(mixinClassesMembers.ts, 25, 44)) + + let x1 = new Mixed1("hello"); +>x1 : Symbol(x1, Decl(mixinClassesMembers.ts, 28, 7)) +>Mixed1 : Symbol(Mixed1, Decl(mixinClassesMembers.ts, 21, 13)) + + let x2 = new Mixed1(42); +>x2 : Symbol(x2, Decl(mixinClassesMembers.ts, 29, 7)) +>Mixed1 : Symbol(Mixed1, Decl(mixinClassesMembers.ts, 21, 13)) + + let x3 = new Mixed2("hello"); +>x3 : Symbol(x3, Decl(mixinClassesMembers.ts, 30, 7)) +>Mixed2 : Symbol(Mixed2, Decl(mixinClassesMembers.ts, 22, 13)) + + let x4 = new Mixed2(42); +>x4 : Symbol(x4, Decl(mixinClassesMembers.ts, 31, 7)) +>Mixed2 : Symbol(Mixed2, Decl(mixinClassesMembers.ts, 22, 13)) + + let x5 = new Mixed3("hello"); +>x5 : Symbol(x5, Decl(mixinClassesMembers.ts, 32, 7)) +>Mixed3 : Symbol(Mixed3, Decl(mixinClassesMembers.ts, 23, 13)) + + let x6 = new Mixed3(42); +>x6 : Symbol(x6, Decl(mixinClassesMembers.ts, 33, 7)) +>Mixed3 : Symbol(Mixed3, Decl(mixinClassesMembers.ts, 23, 13)) + + let x7 = new Mixed4("hello"); +>x7 : Symbol(x7, Decl(mixinClassesMembers.ts, 34, 7)) +>Mixed4 : Symbol(Mixed4, Decl(mixinClassesMembers.ts, 24, 13)) + + let x8 = new Mixed4(42); +>x8 : Symbol(x8, Decl(mixinClassesMembers.ts, 35, 7)) +>Mixed4 : Symbol(Mixed4, Decl(mixinClassesMembers.ts, 24, 13)) + + let x9 = new Mixed5(); +>x9 : Symbol(x9, Decl(mixinClassesMembers.ts, 36, 7)) +>Mixed5 : Symbol(Mixed5, Decl(mixinClassesMembers.ts, 25, 13)) +} + +function f2() { +>f2 : Symbol(f2, Decl(mixinClassesMembers.ts, 37, 1)) + + let x = new Mixed1("hello"); +>x : Symbol(x, Decl(mixinClassesMembers.ts, 40, 7)) +>Mixed1 : Symbol(Mixed1, Decl(mixinClassesMembers.ts, 21, 13)) + + x.a; +>x.a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 40, 7)) +>a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) + + x.p; +>x.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 40, 7)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) + + Mixed1.p; +>Mixed1.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14)) +>Mixed1 : Symbol(Mixed1, Decl(mixinClassesMembers.ts, 21, 13)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14)) +} + +function f3() { +>f3 : Symbol(f3, Decl(mixinClassesMembers.ts, 44, 1)) + + let x = new Mixed2("hello"); +>x : Symbol(x, Decl(mixinClassesMembers.ts, 47, 7)) +>Mixed2 : Symbol(Mixed2, Decl(mixinClassesMembers.ts, 22, 13)) + + x.a; +>x.a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 47, 7)) +>a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) + + x.p; +>x.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 47, 7)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) + + Mixed2.p; +>Mixed2.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14)) +>Mixed2 : Symbol(Mixed2, Decl(mixinClassesMembers.ts, 22, 13)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14)) +} + +function f4() { +>f4 : Symbol(f4, Decl(mixinClassesMembers.ts, 51, 1)) + + let x = new Mixed3("hello"); +>x : Symbol(x, Decl(mixinClassesMembers.ts, 54, 7)) +>Mixed3 : Symbol(Mixed3, Decl(mixinClassesMembers.ts, 23, 13)) + + x.a; +>x.a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 54, 7)) +>a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) + + x.p; +>x.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 54, 7)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) + + x.f(); +>x.f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 54, 7)) +>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32)) + + Mixed3.p; +>Mixed3.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14)) +>Mixed3 : Symbol(Mixed3, Decl(mixinClassesMembers.ts, 23, 13)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14)) + + Mixed3.f(); +>Mixed3.f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 17, 16)) +>Mixed3 : Symbol(Mixed3, Decl(mixinClassesMembers.ts, 23, 13)) +>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 17, 16)) +} + +function f5() { +>f5 : Symbol(f5, Decl(mixinClassesMembers.ts, 60, 1)) + + let x = new Mixed4("hello"); +>x : Symbol(x, Decl(mixinClassesMembers.ts, 63, 7)) +>Mixed4 : Symbol(Mixed4, Decl(mixinClassesMembers.ts, 24, 13)) + + x.a; +>x.a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 63, 7)) +>a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) + + x.p; +>x.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 63, 7)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) + + x.f(); +>x.f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 63, 7)) +>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32)) + + Mixed4.p; +>Mixed4.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14)) +>Mixed4 : Symbol(Mixed4, Decl(mixinClassesMembers.ts, 24, 13)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14)) + + Mixed4.f(); +>Mixed4.f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 17, 16)) +>Mixed4 : Symbol(Mixed4, Decl(mixinClassesMembers.ts, 24, 13)) +>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 17, 16)) +} + +function f6() { +>f6 : Symbol(f6, Decl(mixinClassesMembers.ts, 69, 1)) + + let x = new Mixed5(); +>x : Symbol(x, Decl(mixinClassesMembers.ts, 72, 7)) +>Mixed5 : Symbol(Mixed5, Decl(mixinClassesMembers.ts, 25, 13)) + + x.p; +>x.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 72, 7)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) + + x.f(); +>x.f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 72, 7)) +>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32)) + + Mixed5.p; +>Mixed5.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14)) +>Mixed5 : Symbol(Mixed5, Decl(mixinClassesMembers.ts, 25, 13)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14)) + + Mixed5.f(); +>Mixed5.f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 17, 16)) +>Mixed5 : Symbol(Mixed5, Decl(mixinClassesMembers.ts, 25, 13)) +>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 17, 16)) +} + +class C2 extends Mixed1 { +>C2 : Symbol(C2, Decl(mixinClassesMembers.ts, 77, 1)) +>Mixed1 : Symbol(Mixed1, Decl(mixinClassesMembers.ts, 21, 13)) + + constructor() { + super("hello"); + this.a; +>this.a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) +>this : Symbol(C2, Decl(mixinClassesMembers.ts, 77, 1)) +>a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) + + this.b; +>this.b : Symbol(C1.b, Decl(mixinClassesMembers.ts, 2, 21)) +>this : Symbol(C2, Decl(mixinClassesMembers.ts, 77, 1)) +>b : Symbol(C1.b, Decl(mixinClassesMembers.ts, 2, 21)) + + this.p; +>this.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) +>this : Symbol(C2, Decl(mixinClassesMembers.ts, 77, 1)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) + } +} + +class C3 extends Mixed3 { +>C3 : Symbol(C3, Decl(mixinClassesMembers.ts, 86, 1)) +>Mixed3 : Symbol(Mixed3, Decl(mixinClassesMembers.ts, 23, 13)) + + constructor() { + super(42); + this.a; +>this.a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) +>this : Symbol(C3, Decl(mixinClassesMembers.ts, 86, 1)) +>a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) + + this.b; +>this.b : Symbol(C1.b, Decl(mixinClassesMembers.ts, 2, 21)) +>this : Symbol(C3, Decl(mixinClassesMembers.ts, 86, 1)) +>b : Symbol(C1.b, Decl(mixinClassesMembers.ts, 2, 21)) + + this.p; +>this.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) +>this : Symbol(C3, Decl(mixinClassesMembers.ts, 86, 1)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) + + this.f(); +>this.f : Symbol(C3.f, Decl(mixinClassesMembers.ts, 95, 5)) +>this : Symbol(C3, Decl(mixinClassesMembers.ts, 86, 1)) +>f : Symbol(C3.f, Decl(mixinClassesMembers.ts, 95, 5)) + } + f() { return super.f(); } +>f : Symbol(C3.f, Decl(mixinClassesMembers.ts, 95, 5)) +>super.f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32)) +>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32)) +} + diff --git a/tests/baselines/reference/mixinClassesMembers.types b/tests/baselines/reference/mixinClassesMembers.types new file mode 100644 index 00000000000..c8b29175415 --- /dev/null +++ b/tests/baselines/reference/mixinClassesMembers.types @@ -0,0 +1,352 @@ +=== tests/cases/conformance/classes/mixinClassesMembers.ts === + +declare class C1 { +>C1 : C1 + + public a: number; +>a : number + + protected b: number; +>b : number + + private c: number; +>c : number + + constructor(s: string); +>s : string + + constructor(n: number); +>n : number +} + +declare class M1 { +>M1 : M1 + + constructor(...args: any[]); +>args : any[] + + p: number; +>p : number + + static p: number; +>p : number +} + +declare class M2 { +>M2 : M2 + + constructor(...args: any[]); +>args : any[] + + f(): number; +>f : () => number + + static f(): number; +>f : () => number +} + +declare const Mixed1: typeof M1 & typeof C1; +>Mixed1 : typeof M1 & typeof C1 +>M1 : typeof M1 +>C1 : typeof C1 + +declare const Mixed2: typeof C1 & typeof M1; +>Mixed2 : typeof C1 & typeof M1 +>C1 : typeof C1 +>M1 : typeof M1 + +declare const Mixed3: typeof M2 & typeof M1 & typeof C1; +>Mixed3 : typeof M2 & typeof M1 & typeof C1 +>M2 : typeof M2 +>M1 : typeof M1 +>C1 : typeof C1 + +declare const Mixed4: typeof C1 & typeof M1 & typeof M2; +>Mixed4 : typeof C1 & typeof M1 & typeof M2 +>C1 : typeof C1 +>M1 : typeof M1 +>M2 : typeof M2 + +declare const Mixed5: typeof M1 & typeof M2; +>Mixed5 : typeof M1 & typeof M2 +>M1 : typeof M1 +>M2 : typeof M2 + +function f1() { +>f1 : () => void + + let x1 = new Mixed1("hello"); +>x1 : M1 & C1 +>new Mixed1("hello") : M1 & C1 +>Mixed1 : typeof M1 & typeof C1 +>"hello" : "hello" + + let x2 = new Mixed1(42); +>x2 : M1 & C1 +>new Mixed1(42) : M1 & C1 +>Mixed1 : typeof M1 & typeof C1 +>42 : 42 + + let x3 = new Mixed2("hello"); +>x3 : C1 & M1 +>new Mixed2("hello") : C1 & M1 +>Mixed2 : typeof C1 & typeof M1 +>"hello" : "hello" + + let x4 = new Mixed2(42); +>x4 : C1 & M1 +>new Mixed2(42) : C1 & M1 +>Mixed2 : typeof C1 & typeof M1 +>42 : 42 + + let x5 = new Mixed3("hello"); +>x5 : M2 & M1 & C1 +>new Mixed3("hello") : M2 & M1 & C1 +>Mixed3 : typeof M2 & typeof M1 & typeof C1 +>"hello" : "hello" + + let x6 = new Mixed3(42); +>x6 : M2 & M1 & C1 +>new Mixed3(42) : M2 & M1 & C1 +>Mixed3 : typeof M2 & typeof M1 & typeof C1 +>42 : 42 + + let x7 = new Mixed4("hello"); +>x7 : C1 & M1 & M2 +>new Mixed4("hello") : C1 & M1 & M2 +>Mixed4 : typeof C1 & typeof M1 & typeof M2 +>"hello" : "hello" + + let x8 = new Mixed4(42); +>x8 : C1 & M1 & M2 +>new Mixed4(42) : C1 & M1 & M2 +>Mixed4 : typeof C1 & typeof M1 & typeof M2 +>42 : 42 + + let x9 = new Mixed5(); +>x9 : M1 & M2 +>new Mixed5() : M1 & M2 +>Mixed5 : typeof M1 & typeof M2 +} + +function f2() { +>f2 : () => void + + let x = new Mixed1("hello"); +>x : M1 & C1 +>new Mixed1("hello") : M1 & C1 +>Mixed1 : typeof M1 & typeof C1 +>"hello" : "hello" + + x.a; +>x.a : number +>x : M1 & C1 +>a : number + + x.p; +>x.p : number +>x : M1 & C1 +>p : number + + Mixed1.p; +>Mixed1.p : number +>Mixed1 : typeof M1 & typeof C1 +>p : number +} + +function f3() { +>f3 : () => void + + let x = new Mixed2("hello"); +>x : C1 & M1 +>new Mixed2("hello") : C1 & M1 +>Mixed2 : typeof C1 & typeof M1 +>"hello" : "hello" + + x.a; +>x.a : number +>x : C1 & M1 +>a : number + + x.p; +>x.p : number +>x : C1 & M1 +>p : number + + Mixed2.p; +>Mixed2.p : number +>Mixed2 : typeof C1 & typeof M1 +>p : number +} + +function f4() { +>f4 : () => void + + let x = new Mixed3("hello"); +>x : M2 & M1 & C1 +>new Mixed3("hello") : M2 & M1 & C1 +>Mixed3 : typeof M2 & typeof M1 & typeof C1 +>"hello" : "hello" + + x.a; +>x.a : number +>x : M2 & M1 & C1 +>a : number + + x.p; +>x.p : number +>x : M2 & M1 & C1 +>p : number + + x.f(); +>x.f() : number +>x.f : () => number +>x : M2 & M1 & C1 +>f : () => number + + Mixed3.p; +>Mixed3.p : number +>Mixed3 : typeof M2 & typeof M1 & typeof C1 +>p : number + + Mixed3.f(); +>Mixed3.f() : number +>Mixed3.f : () => number +>Mixed3 : typeof M2 & typeof M1 & typeof C1 +>f : () => number +} + +function f5() { +>f5 : () => void + + let x = new Mixed4("hello"); +>x : C1 & M1 & M2 +>new Mixed4("hello") : C1 & M1 & M2 +>Mixed4 : typeof C1 & typeof M1 & typeof M2 +>"hello" : "hello" + + x.a; +>x.a : number +>x : C1 & M1 & M2 +>a : number + + x.p; +>x.p : number +>x : C1 & M1 & M2 +>p : number + + x.f(); +>x.f() : number +>x.f : () => number +>x : C1 & M1 & M2 +>f : () => number + + Mixed4.p; +>Mixed4.p : number +>Mixed4 : typeof C1 & typeof M1 & typeof M2 +>p : number + + Mixed4.f(); +>Mixed4.f() : number +>Mixed4.f : () => number +>Mixed4 : typeof C1 & typeof M1 & typeof M2 +>f : () => number +} + +function f6() { +>f6 : () => void + + let x = new Mixed5(); +>x : M1 & M2 +>new Mixed5() : M1 & M2 +>Mixed5 : typeof M1 & typeof M2 + + x.p; +>x.p : number +>x : M1 & M2 +>p : number + + x.f(); +>x.f() : number +>x.f : () => number +>x : M1 & M2 +>f : () => number + + Mixed5.p; +>Mixed5.p : number +>Mixed5 : typeof M1 & typeof M2 +>p : number + + Mixed5.f(); +>Mixed5.f() : number +>Mixed5.f : () => number +>Mixed5 : typeof M1 & typeof M2 +>f : () => number +} + +class C2 extends Mixed1 { +>C2 : C2 +>Mixed1 : M1 & C1 + + constructor() { + super("hello"); +>super("hello") : void +>super : typeof M1 & typeof C1 +>"hello" : "hello" + + this.a; +>this.a : number +>this : this +>a : number + + this.b; +>this.b : number +>this : this +>b : number + + this.p; +>this.p : number +>this : this +>p : number + } +} + +class C3 extends Mixed3 { +>C3 : C3 +>Mixed3 : M2 & M1 & C1 + + constructor() { + super(42); +>super(42) : void +>super : typeof M2 & typeof M1 & typeof C1 +>42 : 42 + + this.a; +>this.a : number +>this : this +>a : number + + this.b; +>this.b : number +>this : this +>b : number + + this.p; +>this.p : number +>this : this +>p : number + + this.f(); +>this.f() : number +>this.f : () => number +>this : this +>f : () => number + } + f() { return super.f(); } +>f : () => number +>super.f() : number +>super.f : () => number +>super : M2 & M1 & C1 +>f : () => number +} + diff --git a/tests/baselines/reference/moduleVariableArrayIndexer.errors.txt b/tests/baselines/reference/moduleVariableArrayIndexer.errors.txt new file mode 100644 index 00000000000..f0c070375f6 --- /dev/null +++ b/tests/baselines/reference/moduleVariableArrayIndexer.errors.txt @@ -0,0 +1,11 @@ +tests/cases/compiler/moduleVariableArrayIndexer.ts(3,13): error TS2532: Object is possibly 'undefined'. + + +==== tests/cases/compiler/moduleVariableArrayIndexer.ts (1 errors) ==== + module Bar { + export var a = 1; + var t = undefined[a][a]; // CG: var t = undefined[Bar.a][a]; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/negateOperatorInvalidOperations.errors.txt b/tests/baselines/reference/negateOperatorInvalidOperations.errors.txt index 3bc5689d170..e0f818ba9c1 100644 --- a/tests/baselines/reference/negateOperatorInvalidOperations.errors.txt +++ b/tests/baselines/reference/negateOperatorInvalidOperations.errors.txt @@ -1,12 +1,12 @@ tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorInvalidOperations.ts(4,15): error TS1109: Expression expected. tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorInvalidOperations.ts(4,25): error TS1005: '=' expected. tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorInvalidOperations.ts(4,26): error TS1109: Expression expected. -tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorInvalidOperations.ts(7,17): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorInvalidOperations.ts(7,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorInvalidOperations.ts(8,17): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorInvalidOperations.ts(8,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorInvalidOperations.ts(9,17): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorInvalidOperations.ts(9,29): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorInvalidOperations.ts(7,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorInvalidOperations.ts(7,24): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorInvalidOperations.ts(8,17): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorInvalidOperations.ts(8,24): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorInvalidOperations.ts(9,17): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorInvalidOperations.ts(9,29): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorInvalidOperations.ts(12,14): error TS1109: Expression expected. @@ -25,19 +25,19 @@ tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperator // invalid expressions var NUMBER2 = -(null - undefined); ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. var NUMBER3 = -(null - null); ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2531: Object is possibly 'null'. var NUMBER4 = -(undefined - undefined); ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +!!! error TS2532: Object is possibly 'undefined'. // miss operand var NUMBER =-; diff --git a/tests/baselines/reference/negateOperatorWithAnyOtherType.errors.txt b/tests/baselines/reference/negateOperatorWithAnyOtherType.errors.txt index 03e596aca41..0fbf89fb7ec 100644 --- a/tests/baselines/reference/negateOperatorWithAnyOtherType.errors.txt +++ b/tests/baselines/reference/negateOperatorWithAnyOtherType.errors.txt @@ -1,7 +1,9 @@ +tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorWithAnyOtherType.ts(34,24): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorWithAnyOtherType.ts(35,23): error TS2531: Object is possibly 'null'. tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorWithAnyOtherType.ts(51,1): error TS2695: Left side of comma operator is unused and has no side effects. -==== tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorWithAnyOtherType.ts (1 errors) ==== +==== tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperatorWithAnyOtherType.ts (3 errors) ==== // - operator on any type var ANY: any; @@ -36,7 +38,11 @@ tests/cases/conformance/expressions/unaryOperators/negateOperator/negateOperator // any type literal var ResultIsNumber7 = -undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var ResultIsNumber = -null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. // any type expressions var ResultIsNumber8 = -ANY2[0]; diff --git a/tests/baselines/reference/nestedLoopWithOnlyInnerLetCaptured.js b/tests/baselines/reference/nestedLoopWithOnlyInnerLetCaptured.js new file mode 100644 index 00000000000..ee17bb53eec --- /dev/null +++ b/tests/baselines/reference/nestedLoopWithOnlyInnerLetCaptured.js @@ -0,0 +1,18 @@ +//// [nestedLoopWithOnlyInnerLetCaptured.ts] +declare let doSomething; + +for (let a1 of []) + for (let a2 of a1.someArray) + doSomething(() => a2); + +//// [nestedLoopWithOnlyInnerLetCaptured.js] +for (var _i = 0, _a = []; _i < _a.length; _i++) { + var a1 = _a[_i]; + var _loop_1 = function (a2) { + doSomething(function () { return a2; }); + }; + for (var _b = 0, _c = a1.someArray; _b < _c.length; _b++) { + var a2 = _c[_b]; + _loop_1(a2); + } +} diff --git a/tests/baselines/reference/nestedLoopWithOnlyInnerLetCaptured.symbols b/tests/baselines/reference/nestedLoopWithOnlyInnerLetCaptured.symbols new file mode 100644 index 00000000000..f134dcbffa9 --- /dev/null +++ b/tests/baselines/reference/nestedLoopWithOnlyInnerLetCaptured.symbols @@ -0,0 +1,15 @@ +=== tests/cases/compiler/nestedLoopWithOnlyInnerLetCaptured.ts === +declare let doSomething; +>doSomething : Symbol(doSomething, Decl(nestedLoopWithOnlyInnerLetCaptured.ts, 0, 11)) + +for (let a1 of []) +>a1 : Symbol(a1, Decl(nestedLoopWithOnlyInnerLetCaptured.ts, 2, 8)) + + for (let a2 of a1.someArray) +>a2 : Symbol(a2, Decl(nestedLoopWithOnlyInnerLetCaptured.ts, 3, 12)) +>a1 : Symbol(a1, Decl(nestedLoopWithOnlyInnerLetCaptured.ts, 2, 8)) + + doSomething(() => a2); +>doSomething : Symbol(doSomething, Decl(nestedLoopWithOnlyInnerLetCaptured.ts, 0, 11)) +>a2 : Symbol(a2, Decl(nestedLoopWithOnlyInnerLetCaptured.ts, 3, 12)) + diff --git a/tests/baselines/reference/nestedLoopWithOnlyInnerLetCaptured.types b/tests/baselines/reference/nestedLoopWithOnlyInnerLetCaptured.types new file mode 100644 index 00000000000..6be9dbf6abf --- /dev/null +++ b/tests/baselines/reference/nestedLoopWithOnlyInnerLetCaptured.types @@ -0,0 +1,20 @@ +=== tests/cases/compiler/nestedLoopWithOnlyInnerLetCaptured.ts === +declare let doSomething; +>doSomething : any + +for (let a1 of []) +>a1 : any +>[] : undefined[] + + for (let a2 of a1.someArray) +>a2 : any +>a1.someArray : any +>a1 : any +>someArray : any + + doSomething(() => a2); +>doSomething(() => a2) : any +>doSomething : any +>() => a2 : () => any +>a2 : any + diff --git a/tests/baselines/reference/noBundledEmitFromNodeModules.js b/tests/baselines/reference/noBundledEmitFromNodeModules.js new file mode 100644 index 00000000000..67216a408af --- /dev/null +++ b/tests/baselines/reference/noBundledEmitFromNodeModules.js @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/noBundledEmitFromNodeModules.ts] //// + +//// [index.ts] + +export class C {} + +//// [a.ts] +import { C } from "projB"; + + +//// [out.js] +System.register("a", [], function (exports_1, context_1) { + "use strict"; + var __moduleName = context_1 && context_1.id; + return { + setters: [], + execute: function () { + } + }; +}); diff --git a/tests/baselines/reference/noBundledEmitFromNodeModules.symbols b/tests/baselines/reference/noBundledEmitFromNodeModules.symbols new file mode 100644 index 00000000000..a1f6c67e4b4 --- /dev/null +++ b/tests/baselines/reference/noBundledEmitFromNodeModules.symbols @@ -0,0 +1,9 @@ +=== /a.ts === +import { C } from "projB"; +>C : Symbol(C, Decl(a.ts, 0, 8)) + +=== /node_modules/projB/index.ts === + +export class C {} +>C : Symbol(C, Decl(index.ts, 0, 0)) + diff --git a/tests/baselines/reference/noBundledEmitFromNodeModules.types b/tests/baselines/reference/noBundledEmitFromNodeModules.types new file mode 100644 index 00000000000..a11bad24aaf --- /dev/null +++ b/tests/baselines/reference/noBundledEmitFromNodeModules.types @@ -0,0 +1,9 @@ +=== /a.ts === +import { C } from "projB"; +>C : typeof C + +=== /node_modules/projB/index.ts === + +export class C {} +>C : C + diff --git a/tests/baselines/reference/nonPrimitiveAccessProperty.errors.txt b/tests/baselines/reference/nonPrimitiveAccessProperty.errors.txt index 8ef94c64448..0a6dfa66b86 100644 --- a/tests/baselines/reference/nonPrimitiveAccessProperty.errors.txt +++ b/tests/baselines/reference/nonPrimitiveAccessProperty.errors.txt @@ -1,10 +1,16 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts(3,3): error TS2339: Property 'nonExist' does not exist on type 'object'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts(5,7): error TS2459: Type 'object' has no property 'destructuring' and no string index signature. -==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts (1 errors) ==== +==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts (2 errors) ==== var a: object; a.toString(); a.nonExist(); // error ~~~~~~~~ !!! error TS2339: Property 'nonExist' does not exist on type 'object'. + + var { destructuring } = a; // error + ~~~~~~~~~~~~~ +!!! error TS2459: Type 'object' has no property 'destructuring' and no string index signature. + var { ...rest } = a; // ok \ No newline at end of file diff --git a/tests/baselines/reference/nonPrimitiveAccessProperty.js b/tests/baselines/reference/nonPrimitiveAccessProperty.js index a71b2aba865..abfe2605e32 100644 --- a/tests/baselines/reference/nonPrimitiveAccessProperty.js +++ b/tests/baselines/reference/nonPrimitiveAccessProperty.js @@ -2,9 +2,23 @@ var a: object; a.toString(); a.nonExist(); // error + +var { destructuring } = a; // error +var { ...rest } = a; // ok //// [nonPrimitiveAccessProperty.js] +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; var a; a.toString(); a.nonExist(); // error +var destructuring = a.destructuring; // error +var rest = __rest(a, []); // ok diff --git a/tests/baselines/reference/nonPrimitiveAsProperty.js b/tests/baselines/reference/nonPrimitiveAsProperty.js index f51a9b35435..d3e1b072a06 100644 --- a/tests/baselines/reference/nonPrimitiveAsProperty.js +++ b/tests/baselines/reference/nonPrimitiveAsProperty.js @@ -11,3 +11,11 @@ var b: WithNonPrimitive = {foo: "bar"}; // expect error //// [nonPrimitiveAsProperty.js] var a = { foo: { bar: "bar" } }; var b = { foo: "bar" }; // expect error + + +//// [nonPrimitiveAsProperty.d.ts] +interface WithNonPrimitive { + foo: object; +} +declare var a: WithNonPrimitive; +declare var b: WithNonPrimitive; 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/nonPrimitiveInFunction.js b/tests/baselines/reference/nonPrimitiveInFunction.js index a67b68542dd..1d2a2462502 100644 --- a/tests/baselines/reference/nonPrimitiveInFunction.js +++ b/tests/baselines/reference/nonPrimitiveInFunction.js @@ -34,3 +34,11 @@ function returnError() { var ret = 123; return ret; // expect error } + + +//// [nonPrimitiveInFunction.d.ts] +declare function takeObject(o: object): void; +declare function returnObject(): object; +declare var nonPrimitive: object; +declare var primitive: boolean; +declare function returnError(): object; diff --git a/tests/baselines/reference/nonPrimitiveInGeneric.js b/tests/baselines/reference/nonPrimitiveInGeneric.js index 2db357c3eb5..d7e013c71f1 100644 --- a/tests/baselines/reference/nonPrimitiveInGeneric.js +++ b/tests/baselines/reference/nonPrimitiveInGeneric.js @@ -73,3 +73,21 @@ var x; // error var y; // ok var z; // ok var u; // ok + + +//// [nonPrimitiveInGeneric.d.ts] +declare function generic(t: T): void; +declare var a: {}; +declare var b: string; +declare function bound(t: T): void; +declare function bound2(): void; +declare function bound3(t: T): void; +interface Proxy { +} +declare var x: Proxy; +declare var y: Proxy; +declare var z: Proxy; +interface Blah { + foo: number; +} +declare var u: Proxy; diff --git a/tests/baselines/reference/nonPrimitiveStrictNull.errors.txt b/tests/baselines/reference/nonPrimitiveStrictNull.errors.txt index de6fbfcf698..473011aaa7f 100644 --- a/tests/baselines/reference/nonPrimitiveStrictNull.errors.txt +++ b/tests/baselines/reference/nonPrimitiveStrictNull.errors.txt @@ -12,21 +12,17 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(22,5): erro Type 'null' is not assignable to type 'object'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(27,5): error TS2531: Object is possibly 'null'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(29,5): error TS2532: Object is possibly 'undefined'. -tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(29,7): error TS2339: Property 'toString' does not exist on type 'never'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(33,5): error TS2533: Object is possibly 'null' or 'undefined'. -tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(33,7): error TS2339: Property 'toString' does not exist on type 'never'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(39,5): error TS2531: Object is possibly 'null'. -tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(39,7): error TS2339: Property 'toString' does not exist on type 'never'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(41,5): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(45,5): error TS2532: Object is possibly 'undefined'. -tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(45,7): error TS2339: Property 'toString' does not exist on type 'never'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(47,5): error TS2531: Object is possibly 'null'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(52,14): error TS2344: Type 'number' does not satisfy the constraint 'object'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(53,14): error TS2344: Type 'null' does not satisfy the constraint 'object'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(54,14): error TS2344: Type 'undefined' does not satisfy the constraint 'object'. -==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts (22 errors) ==== +==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts (18 errors) ==== var a: object declare var b: object | null @@ -80,16 +76,12 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(54,14): err d.toString(); // error, undefined ~ !!! error TS2532: Object is possibly 'undefined'. - ~~~~~~~~ -!!! error TS2339: Property 'toString' does not exist on type 'never'. } if (d == null) { d.toString(); // error, undefined | null ~ !!! error TS2533: Object is possibly 'null' or 'undefined'. - ~~~~~~~~ -!!! error TS2339: Property 'toString' does not exist on type 'never'. } else { d.toString(); // object } @@ -98,8 +90,6 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(54,14): err d.toString(); // error, null ~ !!! error TS2531: Object is possibly 'null'. - ~~~~~~~~ -!!! error TS2339: Property 'toString' does not exist on type 'never'. } else { d.toString(); // error, object | undefined ~ @@ -110,8 +100,6 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveStrictNull.ts(54,14): err d.toString(); // error, undefined ~ !!! error TS2532: Object is possibly 'undefined'. - ~~~~~~~~ -!!! error TS2339: Property 'toString' does not exist on type 'never'. } else { d.toString(); // error, object | null ~ diff --git a/tests/baselines/reference/nonPrimitiveUnionIntersection.js b/tests/baselines/reference/nonPrimitiveUnionIntersection.js index c50a2330018..7f4b46c42ed 100644 --- a/tests/baselines/reference/nonPrimitiveUnionIntersection.js +++ b/tests/baselines/reference/nonPrimitiveUnionIntersection.js @@ -10,3 +10,8 @@ var a = ""; // error var b = ""; // ok a = b; // error b = a; // ok + + +//// [nonPrimitiveUnionIntersection.d.ts] +declare var a: object & string; +declare var b: object | string; diff --git a/tests/baselines/reference/null.errors.txt b/tests/baselines/reference/null.errors.txt new file mode 100644 index 00000000000..f957507438c --- /dev/null +++ b/tests/baselines/reference/null.errors.txt @@ -0,0 +1,28 @@ +tests/cases/compiler/null.ts(4,9): error TS2531: Object is possibly 'null'. + + +==== tests/cases/compiler/null.ts (1 errors) ==== + + var x=null; + var y=3+x; + var z=3+null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. + class C { + } + function f() { + return null; + return new C(); + } + function g() { + return null; + return 3; + } + interface I { + x:any; + y:number; + } + var w:I={x:null,y:3}; + + + \ No newline at end of file diff --git a/tests/baselines/reference/nullKeyword.errors.txt b/tests/baselines/reference/nullKeyword.errors.txt index a140fce0b0f..b815b61b676 100644 --- a/tests/baselines/reference/nullKeyword.errors.txt +++ b/tests/baselines/reference/nullKeyword.errors.txt @@ -1,7 +1,7 @@ -tests/cases/compiler/nullKeyword.ts(1,6): error TS2339: Property 'foo' does not exist on type 'null'. +tests/cases/compiler/nullKeyword.ts(1,1): error TS2531: Object is possibly 'null'. ==== tests/cases/compiler/nullKeyword.ts (1 errors) ==== null.foo; - ~~~ -!!! error TS2339: Property 'foo' does not exist on type 'null'. \ No newline at end of file + ~~~~ +!!! error TS2531: Object is possibly 'null'. \ No newline at end of file diff --git a/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations.errors.txt b/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations.errors.txt index ec0f330f1a3..f532bd23755 100644 --- a/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations.errors.txt +++ b/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations.errors.txt @@ -5,7 +5,7 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerCo tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(36,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(50,5): error TS2412: Property '2.0' of type 'number' is not assignable to numeric index type 'string'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(68,5): error TS2412: Property '2.0' of type 'number' is not assignable to numeric index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(79,5): error TS2322: Type '{ 1.0: string; 2.0: number; a: string; b: number; c: () => void; "d": string; "e": number; "3.0": string; "4.0": number; f: any; X: string; foo(): string; }' is not assignable to type '{ [x: number]: string; }'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(79,5): error TS2322: Type '{ a: string; b: number; c: () => void; "d": string; "e": number; 1.0: string; 2.0: number; "3.0": string; "4.0": number; f: any; X: string; foo(): string; }' is not assignable to type '{ [x: number]: string; }'. Object literal may only specify known properties, and 'a' does not exist in type '{ [x: number]: string; }'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(88,9): error TS2304: Cannot find name 'Myn'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(90,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. @@ -107,7 +107,7 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerCo var b: { [x: number]: string; } = { a: '', ~~~~~ -!!! error TS2322: Type '{ 1.0: string; 2.0: number; a: string; b: number; c: () => void; "d": string; "e": number; "3.0": string; "4.0": number; f: any; X: string; foo(): string; }' is not assignable to type '{ [x: number]: string; }'. +!!! error TS2322: Type '{ a: string; b: number; c: () => void; "d": string; "e": number; 1.0: string; 2.0: number; "3.0": string; "4.0": number; f: any; X: string; foo(): string; }' is not assignable to type '{ [x: number]: string; }'. !!! error TS2322: Object literal may only specify known properties, and 'a' does not exist in type '{ [x: number]: string; }'. b: 1, c: () => { }, diff --git a/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations2.errors.txt b/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations2.errors.txt index e6d22ff0712..74cd032c40e 100644 --- a/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations2.errors.txt +++ b/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations2.errors.txt @@ -1,7 +1,7 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(16,5): error TS2412: Property '3.0' of type 'number' is not assignable to numeric index type 'A'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(25,5): error TS2412: Property '3.0' of type 'number' is not assignable to numeric index type 'A'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(34,5): error TS2412: Property '3.0' of type 'number' is not assignable to numeric index type 'A'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(44,5): error TS2322: Type '{ 1.0: A; 2.0: B; 3.0: number; "2.5": B; "4.0": string; }' is not assignable to type '{ [x: number]: A; }'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(44,5): error TS2322: Type '{ 1.0: A; 2.0: B; "2.5": B; 3.0: number; "4.0": string; }' is not assignable to type '{ [x: number]: A; }'. Object literal may only specify known properties, and '"4.0"' does not exist in type '{ [x: number]: A; }'. @@ -57,6 +57,6 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerCo 3.0: 1, "4.0": '' ~~~~~~~~~ -!!! error TS2322: Type '{ 1.0: A; 2.0: B; 3.0: number; "2.5": B; "4.0": string; }' is not assignable to type '{ [x: number]: A; }'. +!!! error TS2322: Type '{ 1.0: A; 2.0: B; "2.5": B; 3.0: number; "4.0": string; }' is not assignable to type '{ [x: number]: A; }'. !!! error TS2322: Object literal may only specify known properties, and '"4.0"' does not exist in type '{ [x: number]: A; }'. } \ No newline at end of file diff --git a/tests/baselines/reference/numericIndexerConstraint5.errors.txt b/tests/baselines/reference/numericIndexerConstraint5.errors.txt index cb888de08c4..04b7e0dc337 100644 --- a/tests/baselines/reference/numericIndexerConstraint5.errors.txt +++ b/tests/baselines/reference/numericIndexerConstraint5.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/numericIndexerConstraint5.ts(2,5): error TS2322: Type '{ 0: Date; name: string; }' is not assignable to type '{ [name: number]: string; }'. +tests/cases/compiler/numericIndexerConstraint5.ts(2,5): error TS2322: Type '{ name: string; 0: Date; }' is not assignable to type '{ [name: number]: string; }'. Property '0' is incompatible with index signature. Type 'Date' is not assignable to type 'string'. @@ -7,6 +7,6 @@ tests/cases/compiler/numericIndexerConstraint5.ts(2,5): error TS2322: Type '{ 0: var x = { name: "x", 0: new Date() }; var z: { [name: number]: string } = x; ~ -!!! error TS2322: Type '{ 0: Date; name: string; }' is not assignable to type '{ [name: number]: string; }'. +!!! error TS2322: Type '{ name: string; 0: Date; }' is not assignable to type '{ [name: number]: string; }'. !!! error TS2322: Property '0' is incompatible with index signature. !!! error TS2322: Type 'Date' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/objectLiteralIndexerErrors.errors.txt b/tests/baselines/reference/objectLiteralIndexerErrors.errors.txt index 9d5ff7ea0a2..53abb5b7658 100644 --- a/tests/baselines/reference/objectLiteralIndexerErrors.errors.txt +++ b/tests/baselines/reference/objectLiteralIndexerErrors.errors.txt @@ -1,8 +1,8 @@ -tests/cases/compiler/objectLiteralIndexerErrors.ts(13,5): error TS2322: Type '{ 0: A; x: B; }' is not assignable to type '{ [s: string]: A; [n: number]: B; }'. +tests/cases/compiler/objectLiteralIndexerErrors.ts(13,5): error TS2322: Type '{ x: B; 0: A; }' is not assignable to type '{ [s: string]: A; [n: number]: B; }'. Property '0' is incompatible with index signature. Type 'A' is not assignable to type 'B'. Property 'y' is missing in type 'A'. -tests/cases/compiler/objectLiteralIndexerErrors.ts(14,1): error TS2322: Type '{ 0: A; x: any; }' is not assignable to type '{ [s: string]: A; [n: number]: B; }'. +tests/cases/compiler/objectLiteralIndexerErrors.ts(14,1): error TS2322: Type '{ x: any; 0: A; }' is not assignable to type '{ [s: string]: A; [n: number]: B; }'. Property '0' is incompatible with index signature. Type 'A' is not assignable to type 'B'. @@ -22,12 +22,12 @@ tests/cases/compiler/objectLiteralIndexerErrors.ts(14,1): error TS2322: Type '{ var o1: { [s: string]: A;[n: number]: B; } = { x: b, 0: a }; // both indexers are A ~~ -!!! error TS2322: Type '{ 0: A; x: B; }' is not assignable to type '{ [s: string]: A; [n: number]: B; }'. +!!! error TS2322: Type '{ x: B; 0: A; }' is not assignable to type '{ [s: string]: A; [n: number]: B; }'. !!! error TS2322: Property '0' is incompatible with index signature. !!! error TS2322: Type 'A' is not assignable to type 'B'. !!! error TS2322: Property 'y' is missing in type 'A'. o1 = { x: c, 0: a }; // string indexer is any, number indexer is A ~~ -!!! error TS2322: Type '{ 0: A; x: any; }' is not assignable to type '{ [s: string]: A; [n: number]: B; }'. +!!! error TS2322: Type '{ x: any; 0: A; }' is not assignable to type '{ [s: string]: A; [n: number]: B; }'. !!! error TS2322: Property '0' is incompatible with index signature. !!! error TS2322: Type 'A' is not assignable to type 'B'. \ No newline at end of file diff --git a/tests/baselines/reference/objectLiteralIndexers.types b/tests/baselines/reference/objectLiteralIndexers.types index 9e3aa4bac49..ef242fd1fe3 100644 --- a/tests/baselines/reference/objectLiteralIndexers.types +++ b/tests/baselines/reference/objectLiteralIndexers.types @@ -31,23 +31,23 @@ var o1: { [s: string]: A;[n: number]: B; } = { x: a, 0: b }; // string indexer i >A : A >n : number >B : B ->{ x: a, 0: b } : { 0: B; x: A; } +>{ x: a, 0: b } : { x: A; 0: B; } >x : A >a : A >b : B o1 = { x: b, 0: c }; // both indexers are any ->o1 = { x: b, 0: c } : { 0: any; x: B; } +>o1 = { x: b, 0: c } : { x: B; 0: any; } >o1 : { [s: string]: A; [n: number]: B; } ->{ x: b, 0: c } : { 0: any; x: B; } +>{ x: b, 0: c } : { x: B; 0: any; } >x : B >b : B >c : any o1 = { x: c, 0: b }; // string indexer is any, number indexer is B ->o1 = { x: c, 0: b } : { 0: B; x: any; } +>o1 = { x: c, 0: b } : { x: any; 0: B; } >o1 : { [s: string]: A; [n: number]: B; } ->{ x: c, 0: b } : { 0: B; x: any; } +>{ x: c, 0: b } : { x: any; 0: B; } >x : any >c : any >b : B diff --git a/tests/baselines/reference/objectRest.js b/tests/baselines/reference/objectRest.js index 59eb11542c0..3576ffb286c 100644 --- a/tests/baselines/reference/objectRest.js +++ b/tests/baselines/reference/objectRest.js @@ -44,7 +44,7 @@ let computed2 = 'a'; var { [computed]: stillNotGreat, [computed2]: soSo, ...o } = o; ({ [computed]: stillNotGreat, [computed2]: soSo, ...o } = o); -var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject['anythingGoes']; +var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject.anythingGoes; //// [objectRest.js] @@ -89,6 +89,6 @@ var _g = computed, stillNotGreat = o[_g], _h = computed2, soSo = o[_h], o = __re (_j = computed, stillNotGreat = o[_j], _k = computed2, soSo = o[_k], o = __rest(o, [typeof _j === "symbol" ? _j : _j + "", typeof _k === "symbol" ? _k : _k + ""])); var noContextualType = (_a) => { var { aNumber = 12 } = _a, notEmptyObject = __rest(_a, ["aNumber"]); - return aNumber + notEmptyObject['anythingGoes']; + return aNumber + notEmptyObject.anythingGoes; }; var _d, _f, _j, _k; diff --git a/tests/baselines/reference/objectRest.symbols b/tests/baselines/reference/objectRest.symbols index 2992220d8b2..41226bd99fc 100644 --- a/tests/baselines/reference/objectRest.symbols +++ b/tests/baselines/reference/objectRest.symbols @@ -191,7 +191,7 @@ var { [computed]: stillNotGreat, [computed2]: soSo, ...o } = o; >o : Symbol(o, Decl(objectRest.ts, 0, 3), Decl(objectRest.ts, 42, 51)) >o : Symbol(o, Decl(objectRest.ts, 0, 3), Decl(objectRest.ts, 42, 51)) -var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject['anythingGoes']; +var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject.anythingGoes; >noContextualType : Symbol(noContextualType, Decl(objectRest.ts, 45, 3)) >aNumber : Symbol(aNumber, Decl(objectRest.ts, 45, 25)) >notEmptyObject : Symbol(notEmptyObject, Decl(objectRest.ts, 45, 39)) diff --git a/tests/baselines/reference/objectRest.types b/tests/baselines/reference/objectRest.types index 5347f09f5a3..2fff9a3c729 100644 --- a/tests/baselines/reference/objectRest.types +++ b/tests/baselines/reference/objectRest.types @@ -217,15 +217,15 @@ var { [computed]: stillNotGreat, [computed2]: soSo, ...o } = o; >o : { a: number; b: string; } >o : { a: number; b: string; } -var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject['anythingGoes']; +var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject.anythingGoes; >noContextualType : ({aNumber, ...notEmptyObject}: { [x: string]: any; aNumber?: number; }) => any ->({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject['anythingGoes'] : ({aNumber, ...notEmptyObject}: { [x: string]: any; aNumber?: number; }) => any +>({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject.anythingGoes : ({aNumber, ...notEmptyObject}: { [x: string]: any; aNumber?: number; }) => any >aNumber : number >12 : 12 >notEmptyObject : { [x: string]: any; } ->aNumber + notEmptyObject['anythingGoes'] : any +>aNumber + notEmptyObject.anythingGoes : any >aNumber : number ->notEmptyObject['anythingGoes'] : any +>notEmptyObject.anythingGoes : any >notEmptyObject : { [x: string]: any; } ->'anythingGoes' : "anythingGoes" +>anythingGoes : any diff --git a/tests/baselines/reference/objectRest2.js b/tests/baselines/reference/objectRest2.js index 6abff9e56a1..e46d22db80a 100644 --- a/tests/baselines/reference/objectRest2.js +++ b/tests/baselines/reference/objectRest2.js @@ -15,14 +15,6 @@ rootConnection('test'); //// [objectRest2.js] -var __assign = (this && this.__assign) || Object.assign || function(t) { - for (var s, i = 1, n = arguments.length; i < n; i++) { - s = arguments[i]; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) - t[p] = s[p]; - } - return t; -}; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } @@ -35,7 +27,7 @@ function rootConnection(name) { return { resolve: (context, args) => __awaiter(this, void 0, void 0, function* () { const { objects } = yield { objects: 12 }; - return __assign({}, connectionFromArray(objects, args)); + return Object.assign({}, connectionFromArray(objects, args)); }) }; } diff --git a/tests/baselines/reference/objectRestForOf.js b/tests/baselines/reference/objectRestForOf.js index fd81f77512e..f8a88fe2868 100644 --- a/tests/baselines/reference/objectRestForOf.js +++ b/tests/baselines/reference/objectRestForOf.js @@ -15,14 +15,6 @@ for (const norest of array.map(a => ({ ...a, x: 'a string' }))) { //// [objectRestForOf.js] -var __assign = (this && this.__assign) || Object.assign || function(t) { - for (var s, i = 1, n = arguments.length; i < n; i++) { - s = arguments[i]; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) - t[p] = s[p]; - } - return t; -}; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) @@ -43,6 +35,6 @@ for (let _b of array) { ({ x: xx } = _b, rrestOff = __rest(_b, ["x"])); [xx, rrestOff]; } -for (const norest of array.map(a => (__assign({}, a, { x: 'a string' })))) { +for (const norest of array.map(a => (Object.assign({}, a, { x: 'a string' })))) { [norest.x, norest.y]; } diff --git a/tests/baselines/reference/objectRestNegative.errors.txt b/tests/baselines/reference/objectRestNegative.errors.txt index 6e65af4bdc1..56de8aaccb6 100644 --- a/tests/baselines/reference/objectRestNegative.errors.txt +++ b/tests/baselines/reference/objectRestNegative.errors.txt @@ -7,10 +7,9 @@ tests/cases/conformance/types/rest/objectRestNegative.ts(11,30): error TS7008: M tests/cases/conformance/types/rest/objectRestNegative.ts(11,33): error TS7008: Member 'y' implicitly has an 'any' type. tests/cases/conformance/types/rest/objectRestNegative.ts(12,17): error TS2700: Rest types may only be created from object types. tests/cases/conformance/types/rest/objectRestNegative.ts(17,9): error TS2701: The target of an object rest assignment must be a variable or a property access. -tests/cases/conformance/types/rest/objectRestNegative.ts(19,90): error TS2339: Property 'anythingGoes' does not exist on type '{ [x: string]: any; }'. -==== tests/cases/conformance/types/rest/objectRestNegative.ts (8 errors) ==== +==== tests/cases/conformance/types/rest/objectRestNegative.ts (7 errors) ==== let o = { a: 1, b: 'no' }; var { ...mustBeLast, a } = o; ~~~~~~~~~~ @@ -44,8 +43,4 @@ tests/cases/conformance/types/rest/objectRestNegative.ts(19,90): error TS2339: P ({a, ...rest.b + rest.b} = o); ~~~~~~~~~~~~~~~ !!! error TS2701: The target of an object rest assignment must be a variable or a property access. - - var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject.anythingGoes; - ~~~~~~~~~~~~ -!!! error TS2339: Property 'anythingGoes' does not exist on type '{ [x: string]: any; }'. \ No newline at end of file diff --git a/tests/baselines/reference/objectRestNegative.js b/tests/baselines/reference/objectRestNegative.js index 19559e865f2..915e0a0e867 100644 --- a/tests/baselines/reference/objectRestNegative.js +++ b/tests/baselines/reference/objectRestNegative.js @@ -16,8 +16,6 @@ function generic(t: T) { let rest: { b: string } ({a, ...rest.b + rest.b} = o); - -var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject.anythingGoes; //// [objectRestNegative.js] @@ -44,7 +42,3 @@ function generic(t) { } var rest; (a = o.a, o, rest.b + rest.b = __rest(o, ["a"])); -var noContextualType = function (_a) { - var _b = _a.aNumber, aNumber = _b === void 0 ? 12 : _b, notEmptyObject = __rest(_a, ["aNumber"]); - return aNumber + notEmptyObject.anythingGoes; -}; diff --git a/tests/baselines/reference/objectSpread.js b/tests/baselines/reference/objectSpread.js index 4305e17ab31..2bc3b9e11bd 100644 --- a/tests/baselines/reference/objectSpread.js +++ b/tests/baselines/reference/objectSpread.js @@ -78,7 +78,8 @@ let computedAfter: { a: number, b: string, "at the end": number } = // shortcut syntax let a = 12; let shortCutted: { a: number, b: string } = { ...o, a } - +// non primitive +let spreadNonPrimitive = { ...{}}; //// [objectSpread.js] @@ -148,4 +149,6 @@ var computedAfter = __assign({}, o, (_c = { b: 'yeah' }, _c['at the end'] = 14, // shortcut syntax var a = 12; var shortCutted = __assign({}, o, { a: a }); +// non primitive +var spreadNonPrimitive = __assign({}, {}); var _a, _b, _c; diff --git a/tests/baselines/reference/objectSpread.symbols b/tests/baselines/reference/objectSpread.symbols index 35c10faa9c0..1ec2520e166 100644 --- a/tests/baselines/reference/objectSpread.symbols +++ b/tests/baselines/reference/objectSpread.symbols @@ -316,4 +316,7 @@ let shortCutted: { a: number, b: string } = { ...o, a } >o : Symbol(o, Decl(objectSpread.ts, 0, 3)) >a : Symbol(a, Decl(objectSpread.ts, 78, 51)) +// non primitive +let spreadNonPrimitive = { ...{}}; +>spreadNonPrimitive : Symbol(spreadNonPrimitive, Decl(objectSpread.ts, 80, 3)) diff --git a/tests/baselines/reference/objectSpread.types b/tests/baselines/reference/objectSpread.types index a571bd0bb63..950dab43465 100644 --- a/tests/baselines/reference/objectSpread.types +++ b/tests/baselines/reference/objectSpread.types @@ -407,4 +407,10 @@ let shortCutted: { a: number, b: string } = { ...o, a } >o : { a: number; b: string; } >a : number +// non primitive +let spreadNonPrimitive = { ...{}}; +>spreadNonPrimitive : {} +>{ ...{}} : {} +>{} : object +>{} : {} diff --git a/tests/baselines/reference/objectSpreadNegative.errors.txt b/tests/baselines/reference/objectSpreadNegative.errors.txt index 17f07bc06a2..d9106d651a3 100644 --- a/tests/baselines/reference/objectSpreadNegative.errors.txt +++ b/tests/baselines/reference/objectSpreadNegative.errors.txt @@ -14,11 +14,12 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(37,19): error TS269 tests/cases/conformance/types/spread/objectSpreadNegative.ts(42,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{}' has no compatible call signatures. tests/cases/conformance/types/spread/objectSpreadNegative.ts(46,12): error TS2339: Property 'b' does not exist on type '{}'. tests/cases/conformance/types/spread/objectSpreadNegative.ts(52,9): error TS2339: Property 'm' does not exist on type '{ p: number; }'. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(56,14): error TS2698: Spread types may only be created from object types. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(59,14): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(57,11): error TS2339: Property 'a' does not exist on type '{}'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(61,14): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(64,14): error TS2698: Spread types may only be created from object types. -==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (15 errors) ==== +==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (16 errors) ==== let o = { a: 1, b: 'no' } /// private propagates @@ -101,6 +102,13 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(59,14): error TS269 ~ !!! error TS2339: Property 'm' does not exist on type '{ p: number; }'. + // non primitive + let obj: object = { a: 123 }; + let spreadObj = { ...obj }; + spreadObj.a; // error 'a' is not in {} + ~ +!!! error TS2339: Property 'a' does not exist on type '{}'. + // generics function f(t: T, u: U) { return { ...t, ...u, id: 'id' }; diff --git a/tests/baselines/reference/objectSpreadNegative.js b/tests/baselines/reference/objectSpreadNegative.js index dff84355370..fd834b6ef9c 100644 --- a/tests/baselines/reference/objectSpreadNegative.js +++ b/tests/baselines/reference/objectSpreadNegative.js @@ -52,6 +52,11 @@ let c: C = new C() let spreadC = { ...c } spreadC.m(); // error 'm' is not in '{ ... c }' +// non primitive +let obj: object = { a: 123 }; +let spreadObj = { ...obj }; +spreadObj.a; // error 'a' is not in {} + // generics function f(t: T, u: U) { return { ...t, ...u, id: 'id' }; @@ -132,6 +137,10 @@ var C = (function () { var c = new C(); var spreadC = __assign({}, c); spreadC.m(); // error 'm' is not in '{ ... c }' +// non primitive +var obj = { a: 123 }; +var spreadObj = __assign({}, obj); +spreadObj.a; // error 'a' is not in {} // generics function f(t, u) { return __assign({}, t, u, { id: 'id' }); diff --git a/tests/baselines/reference/objectTypeWithStringNamedNumericProperty.types b/tests/baselines/reference/objectTypeWithStringNamedNumericProperty.types index e050d33024c..1f34c4fafac 100644 --- a/tests/baselines/reference/objectTypeWithStringNamedNumericProperty.types +++ b/tests/baselines/reference/objectTypeWithStringNamedNumericProperty.types @@ -267,7 +267,7 @@ var r13 = i[-01] >01 : 1 var a: { ->a : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; } +>a : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; } "0.1": void; ".1": Object; @@ -289,19 +289,19 @@ var a: { var r1 = a['0.1']; >r1 : void >a['0.1'] : void ->a : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; } +>a : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; } >'0.1' : "0.1" var r2 = a['.1']; >r2 : Object >a['.1'] : Object ->a : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; } +>a : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; } >'.1' : ".1" var r3 = a['1']; >r3 : number >a['1'] : number ->a : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; } +>a : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; } >'1' : "1" var r3 = c[1]; @@ -313,7 +313,7 @@ var r3 = c[1]; var r4 = a['1.']; >r4 : string >a['1.'] : string ->a : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; } +>a : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; } >'1.' : "1." var r3 = c[1.]; // same as indexing by 1 when done numerically @@ -325,13 +325,13 @@ var r3 = c[1.]; // same as indexing by 1 when done numerically var r5 = a['1..']; >r5 : boolean >a['1..'] : boolean ->a : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; } +>a : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; } >'1..' : "1.." var r6 = a['1.0']; >r6 : Date >a['1.0'] : Date ->a : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; } +>a : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": Date; } >'1.0' : "1.0" var r3 = c[1.0]; // same as indexing by 1 when done numerically @@ -394,8 +394,8 @@ var r13 = i[-01] >01 : 1 var b = { ->b : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; } ->{ "0.1": null, ".1": new Object(), "1": 1, "1.": "", "1..": true, "1.0": new Date(), "-1.0": /123/, "-1": Date} : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; } +>b : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; } +>{ "0.1": null, ".1": new Object(), "1": 1, "1.": "", "1..": true, "1.0": new Date(), "-1.0": /123/, "-1": Date} : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; } "0.1": null, >null : void @@ -429,19 +429,19 @@ var b = { var r1 = b['0.1']; >r1 : void >b['0.1'] : void ->b : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; } +>b : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; } >'0.1' : "0.1" var r2 = b['.1']; >r2 : Object >b['.1'] : Object ->b : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; } +>b : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; } >'.1' : ".1" var r3 = b['1']; >r3 : number >b['1'] : number ->b : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; } +>b : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; } >'1' : "1" var r3 = c[1]; @@ -453,7 +453,7 @@ var r3 = c[1]; var r4 = b['1.']; >r4 : string >b['1.'] : string ->b : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; } +>b : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; } >'1.' : "1." var r3 = c[1.]; // same as indexing by 1 when done numerically @@ -465,13 +465,13 @@ var r3 = c[1.]; // same as indexing by 1 when done numerically var r5 = b['1..']; >r5 : boolean >b['1..'] : boolean ->b : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; } +>b : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; } >'1..' : "1.." var r6 = b['1.0']; >r6 : Date >b['1.0'] : Date ->b : { "1": number; "0.1": void; ".1": Object; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; } +>b : { "0.1": void; ".1": Object; "1": number; "1.": string; "1..": boolean; "1.0": Date; "-1.0": RegExp; "-1": DateConstructor; } >'1.0' : "1.0" var r3 = c[1.0]; // same as indexing by 1 when done numerically diff --git a/tests/baselines/reference/operatorAddNullUndefined.errors.txt b/tests/baselines/reference/operatorAddNullUndefined.errors.txt index 269ee0a5166..871ef3fc98f 100644 --- a/tests/baselines/reference/operatorAddNullUndefined.errors.txt +++ b/tests/baselines/reference/operatorAddNullUndefined.errors.txt @@ -1,32 +1,68 @@ -tests/cases/compiler/operatorAddNullUndefined.ts(2,10): error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. -tests/cases/compiler/operatorAddNullUndefined.ts(3,10): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. -tests/cases/compiler/operatorAddNullUndefined.ts(4,10): error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. -tests/cases/compiler/operatorAddNullUndefined.ts(5,10): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. +tests/cases/compiler/operatorAddNullUndefined.ts(2,10): error TS2531: Object is possibly 'null'. +tests/cases/compiler/operatorAddNullUndefined.ts(2,17): error TS2531: Object is possibly 'null'. +tests/cases/compiler/operatorAddNullUndefined.ts(3,10): error TS2531: Object is possibly 'null'. +tests/cases/compiler/operatorAddNullUndefined.ts(3,17): error TS2532: Object is possibly 'undefined'. +tests/cases/compiler/operatorAddNullUndefined.ts(4,10): error TS2532: Object is possibly 'undefined'. +tests/cases/compiler/operatorAddNullUndefined.ts(4,22): error TS2531: Object is possibly 'null'. +tests/cases/compiler/operatorAddNullUndefined.ts(5,10): error TS2532: Object is possibly 'undefined'. +tests/cases/compiler/operatorAddNullUndefined.ts(5,22): error TS2532: Object is possibly 'undefined'. +tests/cases/compiler/operatorAddNullUndefined.ts(6,14): error TS2531: Object is possibly 'null'. +tests/cases/compiler/operatorAddNullUndefined.ts(7,14): error TS2532: Object is possibly 'undefined'. +tests/cases/compiler/operatorAddNullUndefined.ts(8,10): error TS2531: Object is possibly 'null'. +tests/cases/compiler/operatorAddNullUndefined.ts(9,10): error TS2532: Object is possibly 'undefined'. +tests/cases/compiler/operatorAddNullUndefined.ts(14,11): error TS2531: Object is possibly 'null'. +tests/cases/compiler/operatorAddNullUndefined.ts(15,11): error TS2532: Object is possibly 'undefined'. +tests/cases/compiler/operatorAddNullUndefined.ts(16,17): error TS2531: Object is possibly 'null'. +tests/cases/compiler/operatorAddNullUndefined.ts(17,17): error TS2532: Object is possibly 'undefined'. -==== tests/cases/compiler/operatorAddNullUndefined.ts (4 errors) ==== +==== tests/cases/compiler/operatorAddNullUndefined.ts (16 errors) ==== enum E { x } var x1 = null + null; - ~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var x2 = null + undefined; - ~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var x3 = undefined + null; - ~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var x4 = undefined + undefined; - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var x5 = 1 + null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. var x6 = 1 + undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var x7 = null + 1; + ~~~~ +!!! error TS2531: Object is possibly 'null'. var x8 = undefined + 1; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var x9 = "test" + null; var x10 = "test" + undefined; var x11 = null + "test"; var x12 = undefined + "test"; var x13 = null + E.x + ~~~~ +!!! error TS2531: Object is possibly 'null'. var x14 = undefined + E.x + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var x15 = E.x + null - var x16 = E.x + undefined \ No newline at end of file + ~~~~ +!!! error TS2531: Object is possibly 'null'. + var x16 = E.x + undefined + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. \ No newline at end of file diff --git a/tests/baselines/reference/plusOperatorWithAnyOtherType.errors.txt b/tests/baselines/reference/plusOperatorWithAnyOtherType.errors.txt index 6c0f113b17b..d693aaa17d9 100644 --- a/tests/baselines/reference/plusOperatorWithAnyOtherType.errors.txt +++ b/tests/baselines/reference/plusOperatorWithAnyOtherType.errors.txt @@ -1,10 +1,15 @@ -tests/cases/conformance/expressions/unaryOperators/plusOperator/plusOperatorWithAnyOtherType.ts(46,26): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. -tests/cases/conformance/expressions/unaryOperators/plusOperator/plusOperatorWithAnyOtherType.ts(47,26): error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. -tests/cases/conformance/expressions/unaryOperators/plusOperator/plusOperatorWithAnyOtherType.ts(48,26): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. +tests/cases/conformance/expressions/unaryOperators/plusOperator/plusOperatorWithAnyOtherType.ts(34,24): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/unaryOperators/plusOperator/plusOperatorWithAnyOtherType.ts(35,24): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/plusOperator/plusOperatorWithAnyOtherType.ts(46,26): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/plusOperator/plusOperatorWithAnyOtherType.ts(46,33): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/unaryOperators/plusOperator/plusOperatorWithAnyOtherType.ts(47,26): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/plusOperator/plusOperatorWithAnyOtherType.ts(47,33): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/plusOperator/plusOperatorWithAnyOtherType.ts(48,26): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/unaryOperators/plusOperator/plusOperatorWithAnyOtherType.ts(48,38): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/unaryOperators/plusOperator/plusOperatorWithAnyOtherType.ts(54,1): error TS2695: Left side of comma operator is unused and has no side effects. -==== tests/cases/conformance/expressions/unaryOperators/plusOperator/plusOperatorWithAnyOtherType.ts (4 errors) ==== +==== tests/cases/conformance/expressions/unaryOperators/plusOperator/plusOperatorWithAnyOtherType.ts (9 errors) ==== // + operator on any type var ANY: any; @@ -39,7 +44,11 @@ tests/cases/conformance/expressions/unaryOperators/plusOperator/plusOperatorWith // any type literal var ResultIsNumber7 = +undefined; + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var ResultIsNumber8 = +null; + ~~~~ +!!! error TS2531: Object is possibly 'null'. // any type expressions var ResultIsNumber9 = +ANY2[0]; @@ -51,14 +60,20 @@ tests/cases/conformance/expressions/unaryOperators/plusOperator/plusOperatorWith var ResultIsNumber15 = +A.foo(); var ResultIsNumber16 = +(ANY + ANY1); var ResultIsNumber17 = +(null + undefined); - ~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var ResultIsNumber18 = +(null + null); - ~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var ResultIsNumber19 = +(undefined + undefined); - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. // miss assignment operators +ANY; 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/baselines/reference/project/nodeModulesMaxDepthExceeded/amd/nodeModulesMaxDepthExceeded.errors.txt b/tests/baselines/reference/project/nodeModulesMaxDepthExceeded/amd/nodeModulesMaxDepthExceeded.errors.txt index 99e7b193f0c..5b5199ad7ae 100644 --- a/tests/baselines/reference/project/nodeModulesMaxDepthExceeded/amd/nodeModulesMaxDepthExceeded.errors.txt +++ b/tests/baselines/reference/project/nodeModulesMaxDepthExceeded/amd/nodeModulesMaxDepthExceeded.errors.txt @@ -2,19 +2,10 @@ maxDepthExceeded/root.ts(3,1): error TS2322: Type '"10"' is not assignable to ty maxDepthExceeded/root.ts(4,4): error TS2540: Cannot assign to 'rel' because it is a constant or a read-only property. -==== entry.js (0 errors) ==== - var m3 = require("m3"); - - module.exports = { - "a": 42, - "b": "hello, world", - "person": m3.person - }; - ==== relative.js (0 errors) ==== exports.relativeProp = true; -==== maxDepthExceeded/node_modules/m1/index.js (0 errors) ==== +==== index.js (0 errors) ==== var m2 = require('m2'); var rel = require('./relative'); @@ -40,4 +31,13 @@ maxDepthExceeded/root.ts(4,4): error TS2540: Cannot assign to 'rel' because it i !!! error TS2540: Cannot assign to 'rel' because it is a constant or a read-only property. m1.f2.person.age = "10"; // OK if stopped at 2 modules: person will be "any". + +==== entry.js (0 errors) ==== + var m3 = require("m3"); + + module.exports = { + "a": 42, + "b": "hello, world", + "person": m3.person + }; \ No newline at end of file diff --git a/tests/baselines/reference/project/nodeModulesMaxDepthExceeded/amd/nodeModulesMaxDepthExceeded.json b/tests/baselines/reference/project/nodeModulesMaxDepthExceeded/amd/nodeModulesMaxDepthExceeded.json index 86e856dc7b8..9efa0e936ac 100644 --- a/tests/baselines/reference/project/nodeModulesMaxDepthExceeded/amd/nodeModulesMaxDepthExceeded.json +++ b/tests/baselines/reference/project/nodeModulesMaxDepthExceeded/amd/nodeModulesMaxDepthExceeded.json @@ -7,10 +7,10 @@ "project": "maxDepthExceeded", "resolvedInputFiles": [ "lib.d.ts", - "maxDepthExceeded/node_modules/m2/entry.js", "maxDepthExceeded/node_modules/m1/relative.js", "maxDepthExceeded/node_modules/m1/index.js", - "maxDepthExceeded/root.ts" + "maxDepthExceeded/root.ts", + "maxDepthExceeded/node_modules/m2/entry.js" ], "emittedFiles": [ "maxDepthExceeded/built/node_modules/m1/relative.js", diff --git a/tests/baselines/reference/project/nodeModulesMaxDepthExceeded/node/nodeModulesMaxDepthExceeded.errors.txt b/tests/baselines/reference/project/nodeModulesMaxDepthExceeded/node/nodeModulesMaxDepthExceeded.errors.txt index 99e7b193f0c..5b5199ad7ae 100644 --- a/tests/baselines/reference/project/nodeModulesMaxDepthExceeded/node/nodeModulesMaxDepthExceeded.errors.txt +++ b/tests/baselines/reference/project/nodeModulesMaxDepthExceeded/node/nodeModulesMaxDepthExceeded.errors.txt @@ -2,19 +2,10 @@ maxDepthExceeded/root.ts(3,1): error TS2322: Type '"10"' is not assignable to ty maxDepthExceeded/root.ts(4,4): error TS2540: Cannot assign to 'rel' because it is a constant or a read-only property. -==== entry.js (0 errors) ==== - var m3 = require("m3"); - - module.exports = { - "a": 42, - "b": "hello, world", - "person": m3.person - }; - ==== relative.js (0 errors) ==== exports.relativeProp = true; -==== maxDepthExceeded/node_modules/m1/index.js (0 errors) ==== +==== index.js (0 errors) ==== var m2 = require('m2'); var rel = require('./relative'); @@ -40,4 +31,13 @@ maxDepthExceeded/root.ts(4,4): error TS2540: Cannot assign to 'rel' because it i !!! error TS2540: Cannot assign to 'rel' because it is a constant or a read-only property. m1.f2.person.age = "10"; // OK if stopped at 2 modules: person will be "any". + +==== entry.js (0 errors) ==== + var m3 = require("m3"); + + module.exports = { + "a": 42, + "b": "hello, world", + "person": m3.person + }; \ No newline at end of file diff --git a/tests/baselines/reference/project/nodeModulesMaxDepthExceeded/node/nodeModulesMaxDepthExceeded.json b/tests/baselines/reference/project/nodeModulesMaxDepthExceeded/node/nodeModulesMaxDepthExceeded.json index 86e856dc7b8..9efa0e936ac 100644 --- a/tests/baselines/reference/project/nodeModulesMaxDepthExceeded/node/nodeModulesMaxDepthExceeded.json +++ b/tests/baselines/reference/project/nodeModulesMaxDepthExceeded/node/nodeModulesMaxDepthExceeded.json @@ -7,10 +7,10 @@ "project": "maxDepthExceeded", "resolvedInputFiles": [ "lib.d.ts", - "maxDepthExceeded/node_modules/m2/entry.js", "maxDepthExceeded/node_modules/m1/relative.js", "maxDepthExceeded/node_modules/m1/index.js", - "maxDepthExceeded/root.ts" + "maxDepthExceeded/root.ts", + "maxDepthExceeded/node_modules/m2/entry.js" ], "emittedFiles": [ "maxDepthExceeded/built/node_modules/m1/relative.js", diff --git a/tests/baselines/reference/propertyAccess4.errors.txt b/tests/baselines/reference/propertyAccess4.errors.txt index cdc772ba528..fc491d8c7a9 100644 --- a/tests/baselines/reference/propertyAccess4.errors.txt +++ b/tests/baselines/reference/propertyAccess4.errors.txt @@ -1,7 +1,7 @@ -tests/cases/compiler/propertyAccess4.ts(1,6): error TS2339: Property 'toBAZ' does not exist on type 'null'. +tests/cases/compiler/propertyAccess4.ts(1,1): error TS2531: Object is possibly 'null'. ==== tests/cases/compiler/propertyAccess4.ts (1 errors) ==== null.toBAZ(); - ~~~~~ -!!! error TS2339: Property 'toBAZ' does not exist on type 'null'. \ No newline at end of file + ~~~~ +!!! error TS2531: Object is possibly 'null'. \ No newline at end of file diff --git a/tests/baselines/reference/propertyAccess5.errors.txt b/tests/baselines/reference/propertyAccess5.errors.txt index 81c05c5342b..4f7e7f4bcd6 100644 --- a/tests/baselines/reference/propertyAccess5.errors.txt +++ b/tests/baselines/reference/propertyAccess5.errors.txt @@ -1,7 +1,7 @@ -tests/cases/compiler/propertyAccess5.ts(1,11): error TS2339: Property 'toBAZ' does not exist on type 'undefined'. +tests/cases/compiler/propertyAccess5.ts(1,1): error TS2532: Object is possibly 'undefined'. ==== tests/cases/compiler/propertyAccess5.ts (1 errors) ==== undefined.toBAZ(); - ~~~~~ -!!! error TS2339: Property 'toBAZ' does not exist on type 'undefined'. \ No newline at end of file + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. \ No newline at end of file diff --git a/tests/baselines/reference/propertyAccessNumericLiterals.es6.js b/tests/baselines/reference/propertyAccessNumericLiterals.es6.js new file mode 100644 index 00000000000..66ac4178155 --- /dev/null +++ b/tests/baselines/reference/propertyAccessNumericLiterals.es6.js @@ -0,0 +1,14 @@ +//// [propertyAccessNumericLiterals.es6.ts] +0xffffffff.toString(); +0o01234.toString(); +0b01101101.toString(); +1234..toString(); +1e0.toString(); + + +//// [propertyAccessNumericLiterals.es6.js] +0xffffffff.toString(); +0o01234.toString(); +0b01101101.toString(); +1234..toString(); +1e0.toString(); diff --git a/tests/baselines/reference/propertyAccessNumericLiterals.es6.symbols b/tests/baselines/reference/propertyAccessNumericLiterals.es6.symbols new file mode 100644 index 00000000000..dc0be21d84f --- /dev/null +++ b/tests/baselines/reference/propertyAccessNumericLiterals.es6.symbols @@ -0,0 +1,21 @@ +=== tests/cases/conformance/es6/propertyAccess/propertyAccessNumericLiterals.es6.ts === +0xffffffff.toString(); +>0xffffffff.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) +>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) + +0o01234.toString(); +>0o01234.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) +>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) + +0b01101101.toString(); +>0b01101101.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) +>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) + +1234..toString(); +>1234..toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) +>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) + +1e0.toString(); +>1e0.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) +>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) + diff --git a/tests/baselines/reference/propertyAccessNumericLiterals.es6.types b/tests/baselines/reference/propertyAccessNumericLiterals.es6.types new file mode 100644 index 00000000000..9d32cc5b6e8 --- /dev/null +++ b/tests/baselines/reference/propertyAccessNumericLiterals.es6.types @@ -0,0 +1,31 @@ +=== tests/cases/conformance/es6/propertyAccess/propertyAccessNumericLiterals.es6.ts === +0xffffffff.toString(); +>0xffffffff.toString() : string +>0xffffffff.toString : (radix?: number) => string +>0xffffffff : 4294967295 +>toString : (radix?: number) => string + +0o01234.toString(); +>0o01234.toString() : string +>0o01234.toString : (radix?: number) => string +>0o01234 : 668 +>toString : (radix?: number) => string + +0b01101101.toString(); +>0b01101101.toString() : string +>0b01101101.toString : (radix?: number) => string +>0b01101101 : 109 +>toString : (radix?: number) => string + +1234..toString(); +>1234..toString() : string +>1234..toString : (radix?: number) => string +>1234. : 1234 +>toString : (radix?: number) => string + +1e0.toString(); +>1e0.toString() : string +>1e0.toString : (radix?: number) => string +>1e0 : 1 +>toString : (radix?: number) => string + diff --git a/tests/baselines/reference/propertyAccessNumericLiterals.js b/tests/baselines/reference/propertyAccessNumericLiterals.js new file mode 100644 index 00000000000..1a7eb6c0a21 --- /dev/null +++ b/tests/baselines/reference/propertyAccessNumericLiterals.js @@ -0,0 +1,15 @@ +//// [propertyAccessNumericLiterals.ts] +0xffffffff.toString(); +0o01234.toString(); +0b01101101.toString(); +1234..toString(); +1e0.toString(); +000.toString(); + +//// [propertyAccessNumericLiterals.js] +0xffffffff.toString(); +668..toString(); +109..toString(); +1234..toString(); +1e0.toString(); +000.toString(); diff --git a/tests/baselines/reference/propertyAccessNumericLiterals.symbols b/tests/baselines/reference/propertyAccessNumericLiterals.symbols new file mode 100644 index 00000000000..5be13615e90 --- /dev/null +++ b/tests/baselines/reference/propertyAccessNumericLiterals.symbols @@ -0,0 +1,25 @@ +=== tests/cases/conformance/expressions/propertyAccess/propertyAccessNumericLiterals.ts === +0xffffffff.toString(); +>0xffffffff.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) + +0o01234.toString(); +>0o01234.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) + +0b01101101.toString(); +>0b01101101.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) + +1234..toString(); +>1234..toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) + +1e0.toString(); +>1e0.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) + +000.toString(); +>000.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) + diff --git a/tests/baselines/reference/propertyAccessNumericLiterals.types b/tests/baselines/reference/propertyAccessNumericLiterals.types new file mode 100644 index 00000000000..a2567ff2537 --- /dev/null +++ b/tests/baselines/reference/propertyAccessNumericLiterals.types @@ -0,0 +1,37 @@ +=== tests/cases/conformance/expressions/propertyAccess/propertyAccessNumericLiterals.ts === +0xffffffff.toString(); +>0xffffffff.toString() : string +>0xffffffff.toString : (radix?: number) => string +>0xffffffff : 4294967295 +>toString : (radix?: number) => string + +0o01234.toString(); +>0o01234.toString() : string +>0o01234.toString : (radix?: number) => string +>0o01234 : 668 +>toString : (radix?: number) => string + +0b01101101.toString(); +>0b01101101.toString() : string +>0b01101101.toString : (radix?: number) => string +>0b01101101 : 109 +>toString : (radix?: number) => string + +1234..toString(); +>1234..toString() : string +>1234..toString : (radix?: number) => string +>1234. : 1234 +>toString : (radix?: number) => string + +1e0.toString(); +>1e0.toString() : string +>1e0.toString : (radix?: number) => string +>1e0 : 1 +>toString : (radix?: number) => string + +000.toString(); +>000.toString() : string +>000.toString : (radix?: number) => string +>000 : 0 +>toString : (radix?: number) => string + diff --git a/tests/baselines/reference/propertyAccessStringIndexSignature.errors.txt b/tests/baselines/reference/propertyAccessStringIndexSignature.errors.txt new file mode 100644 index 00000000000..d376551d91d --- /dev/null +++ b/tests/baselines/reference/propertyAccessStringIndexSignature.errors.txt @@ -0,0 +1,18 @@ +tests/cases/conformance/expressions/propertyAccess/propertyAccessStringIndexSignature.ts(10,7): error TS2339: Property 'nope' does not exist on type 'Empty'. + + +==== tests/cases/conformance/expressions/propertyAccess/propertyAccessStringIndexSignature.ts (1 errors) ==== + interface Flags { [name: string]: boolean }; + let flags: Flags; + flags.b; + flags.f; + flags.isNotNecessarilyNeverFalse; + flags['this is fine']; + + interface Empty { } + let empty: Empty; + empty.nope; + ~~~~ +!!! error TS2339: Property 'nope' does not exist on type 'Empty'. + empty["that's ok"]; + \ No newline at end of file diff --git a/tests/baselines/reference/propertyAccessStringIndexSignature.js b/tests/baselines/reference/propertyAccessStringIndexSignature.js new file mode 100644 index 00000000000..d37a8bfea0e --- /dev/null +++ b/tests/baselines/reference/propertyAccessStringIndexSignature.js @@ -0,0 +1,24 @@ +//// [propertyAccessStringIndexSignature.ts] +interface Flags { [name: string]: boolean }; +let flags: Flags; +flags.b; +flags.f; +flags.isNotNecessarilyNeverFalse; +flags['this is fine']; + +interface Empty { } +let empty: Empty; +empty.nope; +empty["that's ok"]; + + +//// [propertyAccessStringIndexSignature.js] +; +var flags; +flags.b; +flags.f; +flags.isNotNecessarilyNeverFalse; +flags['this is fine']; +var empty; +empty.nope; +empty["that's ok"]; diff --git a/tests/baselines/reference/propertyAccessStringIndexSignatureNoImplicitAny.errors.txt b/tests/baselines/reference/propertyAccessStringIndexSignatureNoImplicitAny.errors.txt new file mode 100644 index 00000000000..d5fda181096 --- /dev/null +++ b/tests/baselines/reference/propertyAccessStringIndexSignatureNoImplicitAny.errors.txt @@ -0,0 +1,21 @@ +tests/cases/conformance/expressions/propertyAccess/propertyAccessStringIndexSignatureNoImplicitAny.ts(10,7): error TS2339: Property 'nope' does not exist on type 'Empty'. +tests/cases/conformance/expressions/propertyAccess/propertyAccessStringIndexSignatureNoImplicitAny.ts(11,1): error TS7017: Element implicitly has an 'any' type because type 'Empty' has no index signature. + + +==== tests/cases/conformance/expressions/propertyAccess/propertyAccessStringIndexSignatureNoImplicitAny.ts (2 errors) ==== + interface Flags { [name: string]: boolean } + let flags: Flags; + flags.b; + flags.f; + flags.isNotNecessarilyNeverFalse; + flags['this is fine']; + + interface Empty { } + let empty: Empty; + empty.nope; + ~~~~ +!!! error TS2339: Property 'nope' does not exist on type 'Empty'. + empty["not allowed either"]; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS7017: Element implicitly has an 'any' type because type 'Empty' has no index signature. + \ No newline at end of file diff --git a/tests/baselines/reference/propertyAccessStringIndexSignatureNoImplicitAny.js b/tests/baselines/reference/propertyAccessStringIndexSignatureNoImplicitAny.js new file mode 100644 index 00000000000..3c2abcc182b --- /dev/null +++ b/tests/baselines/reference/propertyAccessStringIndexSignatureNoImplicitAny.js @@ -0,0 +1,23 @@ +//// [propertyAccessStringIndexSignatureNoImplicitAny.ts] +interface Flags { [name: string]: boolean } +let flags: Flags; +flags.b; +flags.f; +flags.isNotNecessarilyNeverFalse; +flags['this is fine']; + +interface Empty { } +let empty: Empty; +empty.nope; +empty["not allowed either"]; + + +//// [propertyAccessStringIndexSignatureNoImplicitAny.js] +var flags; +flags.b; +flags.f; +flags.isNotNecessarilyNeverFalse; +flags['this is fine']; +var empty; +empty.nope; +empty["not allowed either"]; diff --git a/tests/baselines/reference/propertyNamedPrototype.errors.txt b/tests/baselines/reference/propertyNamedPrototype.errors.txt new file mode 100644 index 00000000000..d80e1c95c8d --- /dev/null +++ b/tests/baselines/reference/propertyNamedPrototype.errors.txt @@ -0,0 +1,10 @@ +tests/cases/conformance/classes/propertyMemberDeclarations/propertyNamedPrototype.ts(3,12): error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function 'C'. + + +==== tests/cases/conformance/classes/propertyMemberDeclarations/propertyNamedPrototype.ts (1 errors) ==== + class C { + prototype: number; // ok + static prototype: C; // error + ~~~~~~~~~ +!!! error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function 'C'. + } \ No newline at end of file diff --git a/tests/baselines/reference/reactImportDropped.js b/tests/baselines/reference/reactImportDropped.js new file mode 100644 index 00000000000..7ada76b42f4 --- /dev/null +++ b/tests/baselines/reference/reactImportDropped.js @@ -0,0 +1,48 @@ +//// [tests/cases/compiler/reactImportDropped.ts] //// + +//// [react.d.ts] + +export = React; +export as namespace React; + +declare namespace React { + + function createClass(spec: any): ClassicComponentClass; + + interface ClassicComponentClass { + new (props?: any): ClassicComponentClass; + } +} + +declare global { + namespace JSX { + interface ElementAttributesProperty { } + } +} + + +//// [TabBar.js] +export default React.createClass({ + render() { + return ( + null + ); + } +}); + +//// [NavigationView.js] +import TabBar from '../../components/TabBar'; +import {layout} from '../../utils/theme'; // <- DO NOT DROP this import +const x = ; + + +//// [TabBar.js] +export default React.createClass({ + render() { + return (null); + } +}); +//// [NavigationView.js] +import TabBar from '../../components/TabBar'; +import { layout } from '../../utils/theme'; // <- DO NOT DROP this import +const x = React.createElement(TabBar, { height: layout.footerHeight }); diff --git a/tests/baselines/reference/reactImportDropped.symbols b/tests/baselines/reference/reactImportDropped.symbols new file mode 100644 index 00000000000..d7374df044e --- /dev/null +++ b/tests/baselines/reference/reactImportDropped.symbols @@ -0,0 +1,65 @@ +=== tests/cases/compiler/react.d.ts === + +export = React; +>React : Symbol(React, Decl(react.d.ts, 2, 26)) + +export as namespace React; +>React : Symbol(React, Decl(react.d.ts, 1, 15)) + +declare namespace React { +>React : Symbol(React, Decl(react.d.ts, 2, 26)) + + function createClass(spec: any): ClassicComponentClass; +>createClass : Symbol(createClass, Decl(react.d.ts, 4, 25)) +>spec : Symbol(spec, Decl(react.d.ts, 6, 25)) +>ClassicComponentClass : Symbol(ClassicComponentClass, Decl(react.d.ts, 6, 59)) + + interface ClassicComponentClass { +>ClassicComponentClass : Symbol(ClassicComponentClass, Decl(react.d.ts, 6, 59)) + + new (props?: any): ClassicComponentClass; +>props : Symbol(props, Decl(react.d.ts, 9, 13)) +>ClassicComponentClass : Symbol(ClassicComponentClass, Decl(react.d.ts, 6, 59)) + } +} + +declare global { +>global : Symbol(global, Decl(react.d.ts, 11, 1)) + + namespace JSX { +>JSX : Symbol(JSX, Decl(react.d.ts, 13, 16)) + + interface ElementAttributesProperty { } +>ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(react.d.ts, 14, 19)) + } +} + + +=== tests/cases/compiler/src/components/TabBar.js === +export default React.createClass({ +>React.createClass : Symbol(React.createClass, Decl(react.d.ts, 4, 25)) +>React : Symbol(React, Decl(react.d.ts, 1, 15)) +>createClass : Symbol(React.createClass, Decl(react.d.ts, 4, 25)) + + render() { +>render : Symbol(render, Decl(TabBar.js, 0, 34)) + + return ( + null + ); + } +}); + +=== tests/cases/compiler/src/modules/navigation/NavigationView.js === +import TabBar from '../../components/TabBar'; +>TabBar : Symbol(TabBar, Decl(NavigationView.js, 0, 6)) + +import {layout} from '../../utils/theme'; // <- DO NOT DROP this import +>layout : Symbol(layout, Decl(NavigationView.js, 1, 8)) + +const x = ; +>x : Symbol(x, Decl(NavigationView.js, 2, 5)) +>TabBar : Symbol(TabBar, Decl(NavigationView.js, 0, 6)) +>height : Symbol(layout) +>layout : Symbol(layout, Decl(NavigationView.js, 1, 8)) + diff --git a/tests/baselines/reference/reactImportDropped.types b/tests/baselines/reference/reactImportDropped.types new file mode 100644 index 00000000000..36f1a6a4779 --- /dev/null +++ b/tests/baselines/reference/reactImportDropped.types @@ -0,0 +1,74 @@ +=== tests/cases/compiler/react.d.ts === + +export = React; +>React : typeof React + +export as namespace React; +>React : typeof React + +declare namespace React { +>React : typeof React + + function createClass(spec: any): ClassicComponentClass; +>createClass : (spec: any) => ClassicComponentClass +>spec : any +>ClassicComponentClass : ClassicComponentClass + + interface ClassicComponentClass { +>ClassicComponentClass : ClassicComponentClass + + new (props?: any): ClassicComponentClass; +>props : any +>ClassicComponentClass : ClassicComponentClass + } +} + +declare global { +>global : any + + namespace JSX { +>JSX : any + + interface ElementAttributesProperty { } +>ElementAttributesProperty : ElementAttributesProperty + } +} + + +=== tests/cases/compiler/src/components/TabBar.js === +export default React.createClass({ +>React.createClass({ render() { return ( null ); }}) : React.ClassicComponentClass +>React.createClass : (spec: any) => React.ClassicComponentClass +>React : typeof React +>createClass : (spec: any) => React.ClassicComponentClass +>{ render() { return ( null ); }} : { render(): any; } + + render() { +>render : () => any + + return ( +>( null ) : null + + null +>null : null + + ); + } +}); + +=== tests/cases/compiler/src/modules/navigation/NavigationView.js === +import TabBar from '../../components/TabBar'; +>TabBar : React.ClassicComponentClass + +import {layout} from '../../utils/theme'; // <- DO NOT DROP this import +>layout : any + +const x = ; +>x : any +> : any +>TabBar : React.ClassicComponentClass +>height : any +>layout.footerHeight : any +>layout : any +>footerHeight : any + diff --git a/tests/baselines/reference/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.errors.txt b/tests/baselines/reference/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.errors.txt index 59626540806..36ead708331 100644 --- a/tests/baselines/reference/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.errors.txt +++ b/tests/baselines/reference/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.errors.txt @@ -1,43 +1,43 @@ tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts(12,1): error TS2322: Type 'C' is not assignable to type 'A'. - Property 'name' is missing in type 'C'. + Property 'prop' is missing in type 'C'. tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts(13,1): error TS2322: Type 'typeof B' is not assignable to type 'A'. - Property 'name' is missing in type 'typeof B'. + Property 'prop' is missing in type 'typeof B'. tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts(16,5): error TS2322: Type 'C' is not assignable to type 'B'. - Property 'name' is missing in type 'C'. + Property 'prop' is missing in type 'C'. tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts(17,1): error TS2322: Type 'typeof B' is not assignable to type 'B'. - Property 'name' is missing in type 'typeof B'. + Property 'prop' is missing in type 'typeof B'. ==== tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts (4 errors) ==== interface A { - name(); + prop(); } class B { - public name() { } + public prop() { } } class C { - public static name() { } + public static prop() { } } var a: A = new B(); - a = new C(); // error name is missing + a = new C(); // error prop is missing ~ !!! error TS2322: Type 'C' is not assignable to type 'A'. -!!! error TS2322: Property 'name' is missing in type 'C'. - a = B; // error name is missing +!!! error TS2322: Property 'prop' is missing in type 'C'. + a = B; // error prop is missing ~ !!! error TS2322: Type 'typeof B' is not assignable to type 'A'. -!!! error TS2322: Property 'name' is missing in type 'typeof B'. +!!! error TS2322: Property 'prop' is missing in type 'typeof B'. a = C; - var b: B = new C(); // error name is missing + var b: B = new C(); // error prop is missing ~ !!! error TS2322: Type 'C' is not assignable to type 'B'. -!!! error TS2322: Property 'name' is missing in type 'C'. - b = B; // error name is missing +!!! error TS2322: Property 'prop' is missing in type 'C'. + b = B; // error prop is missing ~ !!! error TS2322: Type 'typeof B' is not assignable to type 'B'. -!!! error TS2322: Property 'name' is missing in type 'typeof B'. +!!! error TS2322: Property 'prop' is missing in type 'typeof B'. b = C; b = a; diff --git a/tests/baselines/reference/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.js b/tests/baselines/reference/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.js index 1b98daa226d..00de82a4f6d 100644 --- a/tests/baselines/reference/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.js +++ b/tests/baselines/reference/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.js @@ -1,21 +1,21 @@ //// [staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts] interface A { - name(); + prop(); } class B { - public name() { } + public prop() { } } class C { - public static name() { } + public static prop() { } } var a: A = new B(); -a = new C(); // error name is missing -a = B; // error name is missing +a = new C(); // error prop is missing +a = B; // error prop is missing a = C; -var b: B = new C(); // error name is missing -b = B; // error name is missing +var b: B = new C(); // error prop is missing +b = B; // error prop is missing b = C; b = a; @@ -29,21 +29,21 @@ c = a; var B = (function () { function B() { } - B.prototype.name = function () { }; + B.prototype.prop = function () { }; return B; }()); var C = (function () { function C() { } - C.name = function () { }; + C.prop = function () { }; return C; }()); var a = new B(); -a = new C(); // error name is missing -a = B; // error name is missing +a = new C(); // error prop is missing +a = B; // error prop is missing a = C; -var b = new C(); // error name is missing -b = B; // error name is missing +var b = new C(); // error prop is missing +b = B; // error prop is missing b = C; b = a; var c = new B(); diff --git a/tests/baselines/reference/staticPropertyNameConflicts.errors.txt b/tests/baselines/reference/staticPropertyNameConflicts.errors.txt new file mode 100644 index 00000000000..4c051ace0ac --- /dev/null +++ b/tests/baselines/reference/staticPropertyNameConflicts.errors.txt @@ -0,0 +1,293 @@ +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(3,12): error TS2699: Static property 'name' conflicts with built-in property 'Function.name' of constructor function 'StaticName'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(8,12): error TS2699: Static property 'name' conflicts with built-in property 'Function.name' of constructor function 'StaticNameFn'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(14,12): error TS2699: Static property 'length' conflicts with built-in property 'Function.length' of constructor function 'StaticLength'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(19,12): error TS2699: Static property 'length' conflicts with built-in property 'Function.length' of constructor function 'StaticLengthFn'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(25,12): error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function 'StaticPrototype'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(30,12): error TS2300: Duplicate identifier 'prototype'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(30,12): error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function 'StaticPrototypeFn'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(36,12): error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function 'StaticCaller'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(41,12): error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function 'StaticCallerFn'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(47,12): error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function 'StaticArguments'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(52,12): error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function 'StaticArgumentsFn'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(62,12): error TS2699: Static property 'name' conflicts with built-in property 'Function.name' of constructor function '(Anonymous class)'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(67,12): error TS2699: Static property 'name' conflicts with built-in property 'Function.name' of constructor function '(Anonymous class)'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(73,12): error TS2699: Static property 'length' conflicts with built-in property 'Function.length' of constructor function '(Anonymous class)'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(78,12): error TS2699: Static property 'length' conflicts with built-in property 'Function.length' of constructor function '(Anonymous class)'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(84,12): error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function '(Anonymous class)'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(89,12): error TS2300: Duplicate identifier 'prototype'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(89,12): error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function '(Anonymous class)'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(95,12): error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function '(Anonymous class)'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(100,12): error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function '(Anonymous class)'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(106,12): error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function '(Anonymous class)'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(111,12): error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function '(Anonymous class)'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(121,16): error TS2699: Static property 'name' conflicts with built-in property 'Function.name' of constructor function 'StaticName'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(128,16): error TS2699: Static property 'name' conflicts with built-in property 'Function.name' of constructor function 'StaticNameFn'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(136,16): error TS2699: Static property 'length' conflicts with built-in property 'Function.length' of constructor function 'StaticLength'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(143,16): error TS2699: Static property 'length' conflicts with built-in property 'Function.length' of constructor function 'StaticLengthFn'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(151,16): error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function 'StaticPrototype'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(158,16): error TS2300: Duplicate identifier 'prototype'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(158,16): error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function 'StaticPrototypeFn'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(166,16): error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function 'StaticCaller'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(173,16): error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function 'StaticCallerFn'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(181,16): error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function 'StaticArguments'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(188,16): error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function 'StaticArgumentsFn'. + + +==== tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts (33 errors) ==== + // name + class StaticName { + static name: number; // error + ~~~~ +!!! error TS2699: Static property 'name' conflicts with built-in property 'Function.name' of constructor function 'StaticName'. + name: string; // ok + } + + class StaticNameFn { + static name() {} // error + ~~~~ +!!! error TS2699: Static property 'name' conflicts with built-in property 'Function.name' of constructor function 'StaticNameFn'. + name() {} // ok + } + + // length + class StaticLength { + static length: number; // error + ~~~~~~ +!!! error TS2699: Static property 'length' conflicts with built-in property 'Function.length' of constructor function 'StaticLength'. + length: string; // ok + } + + class StaticLengthFn { + static length() {} // error + ~~~~~~ +!!! error TS2699: Static property 'length' conflicts with built-in property 'Function.length' of constructor function 'StaticLengthFn'. + length() {} // ok + } + + // prototype + class StaticPrototype { + static prototype: number; // error + ~~~~~~~~~ +!!! error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function 'StaticPrototype'. + prototype: string; // ok + } + + class StaticPrototypeFn { + static prototype() {} // error + ~~~~~~~~~ +!!! error TS2300: Duplicate identifier 'prototype'. + ~~~~~~~~~ +!!! error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function 'StaticPrototypeFn'. + prototype() {} // ok + } + + // caller + class StaticCaller { + static caller: number; // error + ~~~~~~ +!!! error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function 'StaticCaller'. + caller: string; // ok + } + + class StaticCallerFn { + static caller() {} // error + ~~~~~~ +!!! error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function 'StaticCallerFn'. + caller() {} // ok + } + + // arguments + class StaticArguments { + static arguments: number; // error + ~~~~~~~~~ +!!! error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function 'StaticArguments'. + arguments: string; // ok + } + + class StaticArgumentsFn { + static arguments() {} // error + ~~~~~~~~~ +!!! error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function 'StaticArgumentsFn'. + arguments() {} // ok + } + + + + // === Static properties on anonymous classes === + + // name + var StaticName_Anonymous = class { + static name: number; // error + ~~~~ +!!! error TS2699: Static property 'name' conflicts with built-in property 'Function.name' of constructor function '(Anonymous class)'. + name: string; // ok + } + + var StaticNameFn_Anonymous = class { + static name() {} // error + ~~~~ +!!! error TS2699: Static property 'name' conflicts with built-in property 'Function.name' of constructor function '(Anonymous class)'. + name() {} // ok + } + + // length + var StaticLength_Anonymous = class { + static length: number; // error + ~~~~~~ +!!! error TS2699: Static property 'length' conflicts with built-in property 'Function.length' of constructor function '(Anonymous class)'. + length: string; // ok + } + + var StaticLengthFn_Anonymous = class { + static length() {} // error + ~~~~~~ +!!! error TS2699: Static property 'length' conflicts with built-in property 'Function.length' of constructor function '(Anonymous class)'. + length() {} // ok + } + + // prototype + var StaticPrototype_Anonymous = class { + static prototype: number; // error + ~~~~~~~~~ +!!! error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function '(Anonymous class)'. + prototype: string; // ok + } + + var StaticPrototypeFn_Anonymous = class { + static prototype() {} // error + ~~~~~~~~~ +!!! error TS2300: Duplicate identifier 'prototype'. + ~~~~~~~~~ +!!! error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function '(Anonymous class)'. + prototype() {} // ok + } + + // caller + var StaticCaller_Anonymous = class { + static caller: number; // error + ~~~~~~ +!!! error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function '(Anonymous class)'. + caller: string; // ok + } + + var StaticCallerFn_Anonymous = class { + static caller() {} // error + ~~~~~~ +!!! error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function '(Anonymous class)'. + caller() {} // ok + } + + // arguments + var StaticArguments_Anonymous = class { + static arguments: number; // error + ~~~~~~~~~ +!!! error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function '(Anonymous class)'. + arguments: string; // ok + } + + var StaticArgumentsFn_Anonymous = class { + static arguments() {} // error + ~~~~~~~~~ +!!! error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function '(Anonymous class)'. + arguments() {} // ok + } + + + // === Static properties on default exported classes === + + // name + module TestOnDefaultExportedClass_1 { + class StaticName { + static name: number; // error + ~~~~ +!!! error TS2699: Static property 'name' conflicts with built-in property 'Function.name' of constructor function 'StaticName'. + name: string; // ok + } + } + + module TestOnDefaultExportedClass_2 { + class StaticNameFn { + static name() {} // error + ~~~~ +!!! error TS2699: Static property 'name' conflicts with built-in property 'Function.name' of constructor function 'StaticNameFn'. + name() {} // ok + } + } + + // length + module TestOnDefaultExportedClass_3 { + export default class StaticLength { + static length: number; // error + ~~~~~~ +!!! error TS2699: Static property 'length' conflicts with built-in property 'Function.length' of constructor function 'StaticLength'. + length: string; // ok + } + } + + module TestOnDefaultExportedClass_4 { + export default class StaticLengthFn { + static length() {} // error + ~~~~~~ +!!! error TS2699: Static property 'length' conflicts with built-in property 'Function.length' of constructor function 'StaticLengthFn'. + length() {} // ok + } + } + + // prototype + module TestOnDefaultExportedClass_5 { + export default class StaticPrototype { + static prototype: number; // error + ~~~~~~~~~ +!!! error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function 'StaticPrototype'. + prototype: string; // ok + } + } + + module TestOnDefaultExportedClass_6 { + export default class StaticPrototypeFn { + static prototype() {} // error + ~~~~~~~~~ +!!! error TS2300: Duplicate identifier 'prototype'. + ~~~~~~~~~ +!!! error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function 'StaticPrototypeFn'. + prototype() {} // ok + } + } + + // caller + module TestOnDefaultExportedClass_7 { + export default class StaticCaller { + static caller: number; // error + ~~~~~~ +!!! error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function 'StaticCaller'. + caller: string; // ok + } + } + + module TestOnDefaultExportedClass_8 { + export default class StaticCallerFn { + static caller() {} // error + ~~~~~~ +!!! error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function 'StaticCallerFn'. + caller() {} // ok + } + } + + // arguments + module TestOnDefaultExportedClass_9 { + export default class StaticArguments { + static arguments: number; // error + ~~~~~~~~~ +!!! error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function 'StaticArguments'. + arguments: string; // ok + } + } + + module TestOnDefaultExportedClass_10 { + export default class StaticArgumentsFn { + static arguments() {} // error + ~~~~~~~~~ +!!! error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function 'StaticArgumentsFn'. + arguments() {} // ok + } + } \ No newline at end of file diff --git a/tests/baselines/reference/staticPropertyNameConflicts.js b/tests/baselines/reference/staticPropertyNameConflicts.js new file mode 100644 index 00000000000..b93b16550f0 --- /dev/null +++ b/tests/baselines/reference/staticPropertyNameConflicts.js @@ -0,0 +1,429 @@ +//// [staticPropertyNameConflicts.ts] +// name +class StaticName { + static name: number; // error + name: string; // ok +} + +class StaticNameFn { + static name() {} // error + name() {} // ok +} + +// length +class StaticLength { + static length: number; // error + length: string; // ok +} + +class StaticLengthFn { + static length() {} // error + length() {} // ok +} + +// prototype +class StaticPrototype { + static prototype: number; // error + prototype: string; // ok +} + +class StaticPrototypeFn { + static prototype() {} // error + prototype() {} // ok +} + +// caller +class StaticCaller { + static caller: number; // error + caller: string; // ok +} + +class StaticCallerFn { + static caller() {} // error + caller() {} // ok +} + +// arguments +class StaticArguments { + static arguments: number; // error + arguments: string; // ok +} + +class StaticArgumentsFn { + static arguments() {} // error + arguments() {} // ok +} + + + +// === Static properties on anonymous classes === + +// name +var StaticName_Anonymous = class { + static name: number; // error + name: string; // ok +} + +var StaticNameFn_Anonymous = class { + static name() {} // error + name() {} // ok +} + +// length +var StaticLength_Anonymous = class { + static length: number; // error + length: string; // ok +} + +var StaticLengthFn_Anonymous = class { + static length() {} // error + length() {} // ok +} + +// prototype +var StaticPrototype_Anonymous = class { + static prototype: number; // error + prototype: string; // ok +} + +var StaticPrototypeFn_Anonymous = class { + static prototype() {} // error + prototype() {} // ok +} + +// caller +var StaticCaller_Anonymous = class { + static caller: number; // error + caller: string; // ok +} + +var StaticCallerFn_Anonymous = class { + static caller() {} // error + caller() {} // ok +} + +// arguments +var StaticArguments_Anonymous = class { + static arguments: number; // error + arguments: string; // ok +} + +var StaticArgumentsFn_Anonymous = class { + static arguments() {} // error + arguments() {} // ok +} + + +// === Static properties on default exported classes === + +// name +module TestOnDefaultExportedClass_1 { + class StaticName { + static name: number; // error + name: string; // ok + } +} + +module TestOnDefaultExportedClass_2 { + class StaticNameFn { + static name() {} // error + name() {} // ok + } +} + +// length +module TestOnDefaultExportedClass_3 { + export default class StaticLength { + static length: number; // error + length: string; // ok + } +} + +module TestOnDefaultExportedClass_4 { + export default class StaticLengthFn { + static length() {} // error + length() {} // ok + } +} + +// prototype +module TestOnDefaultExportedClass_5 { + export default class StaticPrototype { + static prototype: number; // error + prototype: string; // ok + } +} + +module TestOnDefaultExportedClass_6 { + export default class StaticPrototypeFn { + static prototype() {} // error + prototype() {} // ok + } +} + +// caller +module TestOnDefaultExportedClass_7 { + export default class StaticCaller { + static caller: number; // error + caller: string; // ok + } +} + +module TestOnDefaultExportedClass_8 { + export default class StaticCallerFn { + static caller() {} // error + caller() {} // ok + } +} + +// arguments +module TestOnDefaultExportedClass_9 { + export default class StaticArguments { + static arguments: number; // error + arguments: string; // ok + } +} + +module TestOnDefaultExportedClass_10 { + export default class StaticArgumentsFn { + static arguments() {} // error + arguments() {} // ok + } +} + +//// [staticPropertyNameConflicts.js] +// name +var StaticName = (function () { + function StaticName() { + } + return StaticName; +}()); +var StaticNameFn = (function () { + function StaticNameFn() { + } + StaticNameFn.name = function () { }; // error + StaticNameFn.prototype.name = function () { }; // ok + return StaticNameFn; +}()); +// length +var StaticLength = (function () { + function StaticLength() { + } + return StaticLength; +}()); +var StaticLengthFn = (function () { + function StaticLengthFn() { + } + StaticLengthFn.length = function () { }; // error + StaticLengthFn.prototype.length = function () { }; // ok + return StaticLengthFn; +}()); +// prototype +var StaticPrototype = (function () { + function StaticPrototype() { + } + return StaticPrototype; +}()); +var StaticPrototypeFn = (function () { + function StaticPrototypeFn() { + } + StaticPrototypeFn.prototype = function () { }; // error + StaticPrototypeFn.prototype.prototype = function () { }; // ok + return StaticPrototypeFn; +}()); +// caller +var StaticCaller = (function () { + function StaticCaller() { + } + return StaticCaller; +}()); +var StaticCallerFn = (function () { + function StaticCallerFn() { + } + StaticCallerFn.caller = function () { }; // error + StaticCallerFn.prototype.caller = function () { }; // ok + return StaticCallerFn; +}()); +// arguments +var StaticArguments = (function () { + function StaticArguments() { + } + return StaticArguments; +}()); +var StaticArgumentsFn = (function () { + function StaticArgumentsFn() { + } + StaticArgumentsFn.arguments = function () { }; // error + StaticArgumentsFn.prototype.arguments = function () { }; // ok + return StaticArgumentsFn; +}()); +// === Static properties on anonymous classes === +// name +var StaticName_Anonymous = (function () { + function class_1() { + } + return class_1; +}()); +var StaticNameFn_Anonymous = (function () { + function class_2() { + } + class_2.name = function () { }; // error + class_2.prototype.name = function () { }; // ok + return class_2; +}()); +// length +var StaticLength_Anonymous = (function () { + function class_3() { + } + return class_3; +}()); +var StaticLengthFn_Anonymous = (function () { + function class_4() { + } + class_4.length = function () { }; // error + class_4.prototype.length = function () { }; // ok + return class_4; +}()); +// prototype +var StaticPrototype_Anonymous = (function () { + function class_5() { + } + return class_5; +}()); +var StaticPrototypeFn_Anonymous = (function () { + function class_6() { + } + class_6.prototype = function () { }; // error + class_6.prototype.prototype = function () { }; // ok + return class_6; +}()); +// caller +var StaticCaller_Anonymous = (function () { + function class_7() { + } + return class_7; +}()); +var StaticCallerFn_Anonymous = (function () { + function class_8() { + } + class_8.caller = function () { }; // error + class_8.prototype.caller = function () { }; // ok + return class_8; +}()); +// arguments +var StaticArguments_Anonymous = (function () { + function class_9() { + } + return class_9; +}()); +var StaticArgumentsFn_Anonymous = (function () { + function class_10() { + } + class_10.arguments = function () { }; // error + class_10.prototype.arguments = function () { }; // ok + return class_10; +}()); +// === Static properties on default exported classes === +// name +var TestOnDefaultExportedClass_1; +(function (TestOnDefaultExportedClass_1) { + var StaticName = (function () { + function StaticName() { + } + return StaticName; + }()); +})(TestOnDefaultExportedClass_1 || (TestOnDefaultExportedClass_1 = {})); +var TestOnDefaultExportedClass_2; +(function (TestOnDefaultExportedClass_2) { + var StaticNameFn = (function () { + function StaticNameFn() { + } + StaticNameFn.name = function () { }; // error + StaticNameFn.prototype.name = function () { }; // ok + return StaticNameFn; + }()); +})(TestOnDefaultExportedClass_2 || (TestOnDefaultExportedClass_2 = {})); +// length +var TestOnDefaultExportedClass_3; +(function (TestOnDefaultExportedClass_3) { + var StaticLength = (function () { + function StaticLength() { + } + return StaticLength; + }()); + TestOnDefaultExportedClass_3.StaticLength = StaticLength; +})(TestOnDefaultExportedClass_3 || (TestOnDefaultExportedClass_3 = {})); +var TestOnDefaultExportedClass_4; +(function (TestOnDefaultExportedClass_4) { + var StaticLengthFn = (function () { + function StaticLengthFn() { + } + StaticLengthFn.length = function () { }; // error + StaticLengthFn.prototype.length = function () { }; // ok + return StaticLengthFn; + }()); + TestOnDefaultExportedClass_4.StaticLengthFn = StaticLengthFn; +})(TestOnDefaultExportedClass_4 || (TestOnDefaultExportedClass_4 = {})); +// prototype +var TestOnDefaultExportedClass_5; +(function (TestOnDefaultExportedClass_5) { + var StaticPrototype = (function () { + function StaticPrototype() { + } + return StaticPrototype; + }()); + TestOnDefaultExportedClass_5.StaticPrototype = StaticPrototype; +})(TestOnDefaultExportedClass_5 || (TestOnDefaultExportedClass_5 = {})); +var TestOnDefaultExportedClass_6; +(function (TestOnDefaultExportedClass_6) { + var StaticPrototypeFn = (function () { + function StaticPrototypeFn() { + } + StaticPrototypeFn.prototype = function () { }; // error + StaticPrototypeFn.prototype.prototype = function () { }; // ok + return StaticPrototypeFn; + }()); + TestOnDefaultExportedClass_6.StaticPrototypeFn = StaticPrototypeFn; +})(TestOnDefaultExportedClass_6 || (TestOnDefaultExportedClass_6 = {})); +// caller +var TestOnDefaultExportedClass_7; +(function (TestOnDefaultExportedClass_7) { + var StaticCaller = (function () { + function StaticCaller() { + } + return StaticCaller; + }()); + TestOnDefaultExportedClass_7.StaticCaller = StaticCaller; +})(TestOnDefaultExportedClass_7 || (TestOnDefaultExportedClass_7 = {})); +var TestOnDefaultExportedClass_8; +(function (TestOnDefaultExportedClass_8) { + var StaticCallerFn = (function () { + function StaticCallerFn() { + } + StaticCallerFn.caller = function () { }; // error + StaticCallerFn.prototype.caller = function () { }; // ok + return StaticCallerFn; + }()); + TestOnDefaultExportedClass_8.StaticCallerFn = StaticCallerFn; +})(TestOnDefaultExportedClass_8 || (TestOnDefaultExportedClass_8 = {})); +// arguments +var TestOnDefaultExportedClass_9; +(function (TestOnDefaultExportedClass_9) { + var StaticArguments = (function () { + function StaticArguments() { + } + return StaticArguments; + }()); + TestOnDefaultExportedClass_9.StaticArguments = StaticArguments; +})(TestOnDefaultExportedClass_9 || (TestOnDefaultExportedClass_9 = {})); +var TestOnDefaultExportedClass_10; +(function (TestOnDefaultExportedClass_10) { + var StaticArgumentsFn = (function () { + function StaticArgumentsFn() { + } + StaticArgumentsFn.arguments = function () { }; // error + StaticArgumentsFn.prototype.arguments = function () { }; // ok + return StaticArgumentsFn; + }()); + TestOnDefaultExportedClass_10.StaticArgumentsFn = StaticArgumentsFn; +})(TestOnDefaultExportedClass_10 || (TestOnDefaultExportedClass_10 = {})); diff --git a/tests/baselines/reference/staticPropertyNameConflictsInAmbientContext.symbols b/tests/baselines/reference/staticPropertyNameConflictsInAmbientContext.symbols new file mode 100644 index 00000000000..46297eab86a --- /dev/null +++ b/tests/baselines/reference/staticPropertyNameConflictsInAmbientContext.symbols @@ -0,0 +1,107 @@ +=== tests/cases/conformance/classes/propertyMemberDeclarations/decl.d.ts === + +// name +declare class StaticName { +>StaticName : Symbol(StaticName, Decl(decl.d.ts, 0, 0)) + + static name: number; // ok +>name : Symbol(StaticName.name, Decl(decl.d.ts, 2, 26)) + + name: string; // ok +>name : Symbol(StaticName.name, Decl(decl.d.ts, 3, 24)) +} + +declare class StaticNameFn { +>StaticNameFn : Symbol(StaticNameFn, Decl(decl.d.ts, 5, 1)) + + static name(): string; // ok +>name : Symbol(StaticNameFn.name, Decl(decl.d.ts, 7, 28)) + + name(): string; // ok +>name : Symbol(StaticNameFn.name, Decl(decl.d.ts, 8, 26)) +} + +// length +declare class StaticLength { +>StaticLength : Symbol(StaticLength, Decl(decl.d.ts, 10, 1)) + + static length: number; // ok +>length : Symbol(StaticLength.length, Decl(decl.d.ts, 13, 28)) + + length: string; // ok +>length : Symbol(StaticLength.length, Decl(decl.d.ts, 14, 26)) +} + +declare class StaticLengthFn { +>StaticLengthFn : Symbol(StaticLengthFn, Decl(decl.d.ts, 16, 1)) + + static length(): number; // ok +>length : Symbol(StaticLengthFn.length, Decl(decl.d.ts, 18, 30)) + + length(): number; // ok +>length : Symbol(StaticLengthFn.length, Decl(decl.d.ts, 19, 28)) +} + +// prototype +declare class StaticPrototype { +>StaticPrototype : Symbol(StaticPrototype, Decl(decl.d.ts, 21, 1)) + + static prototype: number; // ok +>prototype : Symbol(StaticPrototype.prototype, Decl(decl.d.ts, 24, 31)) + + prototype: string; // ok +>prototype : Symbol(StaticPrototype.prototype, Decl(decl.d.ts, 25, 29)) +} + +declare class StaticPrototypeFn { +>StaticPrototypeFn : Symbol(StaticPrototypeFn, Decl(decl.d.ts, 27, 1)) + + static prototype: any; // ok +>prototype : Symbol(StaticPrototypeFn.prototype, Decl(decl.d.ts, 29, 33)) + + prototype(): any; // ok +>prototype : Symbol(StaticPrototypeFn.prototype, Decl(decl.d.ts, 30, 26)) +} + +// caller +declare class StaticCaller { +>StaticCaller : Symbol(StaticCaller, Decl(decl.d.ts, 32, 1)) + + static caller: number; // ok +>caller : Symbol(StaticCaller.caller, Decl(decl.d.ts, 35, 28)) + + caller: string; // ok +>caller : Symbol(StaticCaller.caller, Decl(decl.d.ts, 36, 26)) +} + +declare class StaticCallerFn { +>StaticCallerFn : Symbol(StaticCallerFn, Decl(decl.d.ts, 38, 1)) + + static caller(): any; // ok +>caller : Symbol(StaticCallerFn.caller, Decl(decl.d.ts, 40, 30)) + + caller(): any; // ok +>caller : Symbol(StaticCallerFn.caller, Decl(decl.d.ts, 41, 25)) +} + +// arguments +declare class StaticArguments { +>StaticArguments : Symbol(StaticArguments, Decl(decl.d.ts, 43, 1)) + + static arguments: number; // ok +>arguments : Symbol(StaticArguments.arguments, Decl(decl.d.ts, 46, 31)) + + arguments: string; // ok +>arguments : Symbol(StaticArguments.arguments, Decl(decl.d.ts, 47, 29)) +} + +declare class StaticArgumentsFn { +>StaticArgumentsFn : Symbol(StaticArgumentsFn, Decl(decl.d.ts, 49, 1)) + + static arguments(): any; // ok +>arguments : Symbol(StaticArgumentsFn.arguments, Decl(decl.d.ts, 51, 33)) + + arguments(): any; // ok +>arguments : Symbol(StaticArgumentsFn.arguments, Decl(decl.d.ts, 52, 28)) +} + diff --git a/tests/baselines/reference/staticPropertyNameConflictsInAmbientContext.types b/tests/baselines/reference/staticPropertyNameConflictsInAmbientContext.types new file mode 100644 index 00000000000..233bd8a46fc --- /dev/null +++ b/tests/baselines/reference/staticPropertyNameConflictsInAmbientContext.types @@ -0,0 +1,107 @@ +=== tests/cases/conformance/classes/propertyMemberDeclarations/decl.d.ts === + +// name +declare class StaticName { +>StaticName : StaticName + + static name: number; // ok +>name : number + + name: string; // ok +>name : string +} + +declare class StaticNameFn { +>StaticNameFn : StaticNameFn + + static name(): string; // ok +>name : () => string + + name(): string; // ok +>name : () => string +} + +// length +declare class StaticLength { +>StaticLength : StaticLength + + static length: number; // ok +>length : number + + length: string; // ok +>length : string +} + +declare class StaticLengthFn { +>StaticLengthFn : StaticLengthFn + + static length(): number; // ok +>length : () => number + + length(): number; // ok +>length : () => number +} + +// prototype +declare class StaticPrototype { +>StaticPrototype : StaticPrototype + + static prototype: number; // ok +>prototype : StaticPrototype + + prototype: string; // ok +>prototype : string +} + +declare class StaticPrototypeFn { +>StaticPrototypeFn : StaticPrototypeFn + + static prototype: any; // ok +>prototype : StaticPrototypeFn + + prototype(): any; // ok +>prototype : () => any +} + +// caller +declare class StaticCaller { +>StaticCaller : StaticCaller + + static caller: number; // ok +>caller : number + + caller: string; // ok +>caller : string +} + +declare class StaticCallerFn { +>StaticCallerFn : StaticCallerFn + + static caller(): any; // ok +>caller : () => any + + caller(): any; // ok +>caller : () => any +} + +// arguments +declare class StaticArguments { +>StaticArguments : StaticArguments + + static arguments: number; // ok +>arguments : number + + arguments: string; // ok +>arguments : string +} + +declare class StaticArgumentsFn { +>StaticArgumentsFn : StaticArgumentsFn + + static arguments(): any; // ok +>arguments : () => any + + arguments(): any; // ok +>arguments : () => any +} + diff --git a/tests/baselines/reference/staticPrototypeProperty.errors.txt b/tests/baselines/reference/staticPrototypeProperty.errors.txt index c3f5cb99c96..c131b7a774d 100644 --- a/tests/baselines/reference/staticPrototypeProperty.errors.txt +++ b/tests/baselines/reference/staticPrototypeProperty.errors.txt @@ -1,13 +1,19 @@ tests/cases/compiler/staticPrototypeProperty.ts(2,11): error TS2300: Duplicate identifier 'prototype'. +tests/cases/compiler/staticPrototypeProperty.ts(2,11): error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function 'C'. +tests/cases/compiler/staticPrototypeProperty.ts(6,11): error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function 'C2'. -==== tests/cases/compiler/staticPrototypeProperty.ts (1 errors) ==== +==== tests/cases/compiler/staticPrototypeProperty.ts (3 errors) ==== class C { static prototype() { } ~~~~~~~~~ !!! error TS2300: Duplicate identifier 'prototype'. + ~~~~~~~~~ +!!! error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function 'C'. } class C2 { static prototype; + ~~~~~~~~~ +!!! error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function 'C2'. } \ No newline at end of file diff --git a/tests/baselines/reference/stringIndexerConstrainsPropertyDeclarations.errors.txt b/tests/baselines/reference/stringIndexerConstrainsPropertyDeclarations.errors.txt index 8f4bbe2025a..606cc39afef 100644 --- a/tests/baselines/reference/stringIndexerConstrainsPropertyDeclarations.errors.txt +++ b/tests/baselines/reference/stringIndexerConstrainsPropertyDeclarations.errors.txt @@ -22,8 +22,8 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerCon tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(71,5): error TS2411: Property 'foo' of type '() => string' is not assignable to string index type 'string'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(73,5): error TS2411: Property '"4.0"' of type 'number' is not assignable to string index type 'string'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(74,5): error TS2411: Property 'f' of type 'MyString' is not assignable to string index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(78,5): error TS2322: Type '{ 1.0: string; 2.0: number; a: string; b: number; c: () => void; "d": string; "e": number; "3.0": string; "4.0": number; f: MyString; X: string; foo(): string; }' is not assignable to type '{ [x: string]: string; }'. - Property '2.0' is incompatible with index signature. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(78,5): error TS2322: Type '{ a: string; b: number; c: () => void; "d": string; "e": number; 1.0: string; 2.0: number; "3.0": string; "4.0": number; f: MyString; X: string; foo(): string; }' is not assignable to type '{ [x: string]: string; }'. + Property 'b' is incompatible with index signature. Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(90,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(93,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. @@ -157,8 +157,8 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerCon // error var b: { [x: string]: string; } = { ~ -!!! error TS2322: Type '{ 1.0: string; 2.0: number; a: string; b: number; c: () => void; "d": string; "e": number; "3.0": string; "4.0": number; f: MyString; X: string; foo(): string; }' is not assignable to type '{ [x: string]: string; }'. -!!! error TS2322: Property '2.0' is incompatible with index signature. +!!! error TS2322: Type '{ a: string; b: number; c: () => void; "d": string; "e": number; 1.0: string; 2.0: number; "3.0": string; "4.0": number; f: MyString; X: string; foo(): string; }' is not assignable to type '{ [x: string]: string; }'. +!!! error TS2322: Property 'b' is incompatible with index signature. !!! error TS2322: Type 'number' is not assignable to type 'string'. a: '', b: 1, diff --git a/tests/baselines/reference/superHasMethodsFromMergedInterface.js b/tests/baselines/reference/superHasMethodsFromMergedInterface.js new file mode 100644 index 00000000000..e7086106210 --- /dev/null +++ b/tests/baselines/reference/superHasMethodsFromMergedInterface.js @@ -0,0 +1,37 @@ +//// [superHasMethodsFromMergedInterface.ts] +class C { m1() { } } +interface C { m2(): void } +class Sub extends C { + m3() { + super.m2(); + } +} + + +//// [superHasMethodsFromMergedInterface.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var C = (function () { + function C() { + } + C.prototype.m1 = function () { }; + return C; +}()); +var Sub = (function (_super) { + __extends(Sub, _super); + function Sub() { + return _super !== null && _super.apply(this, arguments) || this; + } + Sub.prototype.m3 = function () { + _super.prototype.m2.call(this); + }; + return Sub; +}(C)); diff --git a/tests/baselines/reference/superHasMethodsFromMergedInterface.symbols b/tests/baselines/reference/superHasMethodsFromMergedInterface.symbols new file mode 100644 index 00000000000..ec0af8064ed --- /dev/null +++ b/tests/baselines/reference/superHasMethodsFromMergedInterface.symbols @@ -0,0 +1,23 @@ +=== tests/cases/compiler/superHasMethodsFromMergedInterface.ts === +class C { m1() { } } +>C : Symbol(C, Decl(superHasMethodsFromMergedInterface.ts, 0, 0), Decl(superHasMethodsFromMergedInterface.ts, 0, 20)) +>m1 : Symbol(C.m1, Decl(superHasMethodsFromMergedInterface.ts, 0, 9)) + +interface C { m2(): void } +>C : Symbol(C, Decl(superHasMethodsFromMergedInterface.ts, 0, 0), Decl(superHasMethodsFromMergedInterface.ts, 0, 20)) +>m2 : Symbol(C.m2, Decl(superHasMethodsFromMergedInterface.ts, 1, 13)) + +class Sub extends C { +>Sub : Symbol(Sub, Decl(superHasMethodsFromMergedInterface.ts, 1, 26)) +>C : Symbol(C, Decl(superHasMethodsFromMergedInterface.ts, 0, 0), Decl(superHasMethodsFromMergedInterface.ts, 0, 20)) + + m3() { +>m3 : Symbol(Sub.m3, Decl(superHasMethodsFromMergedInterface.ts, 2, 21)) + + super.m2(); +>super.m2 : Symbol(C.m2, Decl(superHasMethodsFromMergedInterface.ts, 1, 13)) +>super : Symbol(C, Decl(superHasMethodsFromMergedInterface.ts, 0, 0), Decl(superHasMethodsFromMergedInterface.ts, 0, 20)) +>m2 : Symbol(C.m2, Decl(superHasMethodsFromMergedInterface.ts, 1, 13)) + } +} + diff --git a/tests/baselines/reference/superHasMethodsFromMergedInterface.types b/tests/baselines/reference/superHasMethodsFromMergedInterface.types new file mode 100644 index 00000000000..7f314d90bed --- /dev/null +++ b/tests/baselines/reference/superHasMethodsFromMergedInterface.types @@ -0,0 +1,24 @@ +=== tests/cases/compiler/superHasMethodsFromMergedInterface.ts === +class C { m1() { } } +>C : C +>m1 : () => void + +interface C { m2(): void } +>C : C +>m2 : () => void + +class Sub extends C { +>Sub : Sub +>C : C + + m3() { +>m3 : () => void + + super.m2(); +>super.m2() : void +>super.m2 : () => void +>super : C +>m2 : () => void + } +} + diff --git a/tests/baselines/reference/typeAliasesForObjectTypes.errors.txt b/tests/baselines/reference/typeAliasesForObjectTypes.errors.txt index d5bc01f93ba..b4ae5978049 100644 --- a/tests/baselines/reference/typeAliasesForObjectTypes.errors.txt +++ b/tests/baselines/reference/typeAliasesForObjectTypes.errors.txt @@ -1,19 +1,13 @@ -tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts(4,22): error TS2312: An interface may only extend a class or another interface. -tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts(5,21): error TS2422: A class may only implement another class or interface. tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts(10,6): error TS2300: Duplicate identifier 'T2'. tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts(11,6): error TS2300: Duplicate identifier 'T2'. -==== tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts (4 errors) ==== +==== tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts (2 errors) ==== type T1 = { x: string } // An interface can be named in an extends or implements clause, but a type alias for an object type literal cannot. interface I1 extends T1 { y: string } - ~~ -!!! error TS2312: An interface may only extend a class or another interface. class C1 implements T1 { - ~~ -!!! error TS2422: A class may only implement another class or interface. x: string; } diff --git a/tests/baselines/reference/typeofOperatorWithAnyOtherType.errors.txt b/tests/baselines/reference/typeofOperatorWithAnyOtherType.errors.txt index 94bca545609..3680b1be60f 100644 --- a/tests/baselines/reference/typeofOperatorWithAnyOtherType.errors.txt +++ b/tests/baselines/reference/typeofOperatorWithAnyOtherType.errors.txt @@ -1,6 +1,9 @@ -tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(46,32): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. -tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(47,32): error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. -tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(48,32): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. +tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(46,32): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(46,39): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(47,32): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(47,39): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(48,32): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(48,44): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(58,1): error TS2695: Left side of comma operator is unused and has no side effects. tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(68,1): error TS7028: Unused label. tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(69,1): error TS7028: Unused label. @@ -11,7 +14,7 @@ tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperator tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(74,1): error TS7028: Unused label. -==== tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts (11 errors) ==== +==== tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts (14 errors) ==== // typeof operator on any type var ANY: any; @@ -58,14 +61,20 @@ tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperator var ResultIsString15 = typeof A.foo(); var ResultIsString16 = typeof (ANY + ANY1); var ResultIsString17 = typeof (null + undefined); - ~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var ResultIsString18 = typeof (null + null); - ~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var ResultIsString19 = typeof (undefined + undefined); - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. // multiple typeof operators var ResultIsString20 = typeof typeof ANY; diff --git a/tests/baselines/reference/voidOperatorWithAnyOtherType.errors.txt b/tests/baselines/reference/voidOperatorWithAnyOtherType.errors.txt index 8796f316303..5867a7ad6f5 100644 --- a/tests/baselines/reference/voidOperatorWithAnyOtherType.errors.txt +++ b/tests/baselines/reference/voidOperatorWithAnyOtherType.errors.txt @@ -1,9 +1,12 @@ -tests/cases/conformance/expressions/unaryOperators/voidOperator/voidOperatorWithAnyOtherType.ts(46,27): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. -tests/cases/conformance/expressions/unaryOperators/voidOperator/voidOperatorWithAnyOtherType.ts(47,27): error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. -tests/cases/conformance/expressions/unaryOperators/voidOperator/voidOperatorWithAnyOtherType.ts(48,27): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. +tests/cases/conformance/expressions/unaryOperators/voidOperator/voidOperatorWithAnyOtherType.ts(46,27): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/voidOperator/voidOperatorWithAnyOtherType.ts(46,34): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/unaryOperators/voidOperator/voidOperatorWithAnyOtherType.ts(47,27): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/voidOperator/voidOperatorWithAnyOtherType.ts(47,34): error TS2531: Object is possibly 'null'. +tests/cases/conformance/expressions/unaryOperators/voidOperator/voidOperatorWithAnyOtherType.ts(48,27): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/expressions/unaryOperators/voidOperator/voidOperatorWithAnyOtherType.ts(48,39): error TS2532: Object is possibly 'undefined'. -==== tests/cases/conformance/expressions/unaryOperators/voidOperator/voidOperatorWithAnyOtherType.ts (3 errors) ==== +==== tests/cases/conformance/expressions/unaryOperators/voidOperator/voidOperatorWithAnyOtherType.ts (6 errors) ==== // void operator on any type var ANY: any; @@ -50,14 +53,20 @@ tests/cases/conformance/expressions/unaryOperators/voidOperator/voidOperatorWith var ResultIsAny15 = void A.foo(); var ResultIsAny16 = void (ANY + ANY1); var ResultIsAny17 = void (null + undefined); - ~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var ResultIsAny18 = void (null + null); - ~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. + ~~~~ +!!! error TS2531: Object is possibly 'null'. var ResultIsAny19 = void (undefined + undefined); - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. // multiple void operators var ResultIsAny20 = void void ANY; diff --git a/tests/baselines/reference/widenedTypes.errors.txt b/tests/baselines/reference/widenedTypes.errors.txt index 5ea097acf2e..f0e3ec33f50 100644 --- a/tests/baselines/reference/widenedTypes.errors.txt +++ b/tests/baselines/reference/widenedTypes.errors.txt @@ -1,6 +1,7 @@ tests/cases/compiler/widenedTypes.ts(2,1): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. -tests/cases/compiler/widenedTypes.ts(6,7): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter -tests/cases/compiler/widenedTypes.ts(8,15): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter. +tests/cases/compiler/widenedTypes.ts(5,1): error TS2531: Object is possibly 'null'. +tests/cases/compiler/widenedTypes.ts(6,7): error TS2531: Object is possibly 'null'. +tests/cases/compiler/widenedTypes.ts(8,15): error TS2531: Object is possibly 'null'. tests/cases/compiler/widenedTypes.ts(10,14): error TS2695: Left side of comma operator is unused and has no side effects. tests/cases/compiler/widenedTypes.ts(11,1): error TS2322: Type '""' is not assignable to type 'number'. tests/cases/compiler/widenedTypes.ts(18,1): error TS2322: Type '""' is not assignable to type 'number'. @@ -11,7 +12,7 @@ tests/cases/compiler/widenedTypes.ts(24,5): error TS2322: Type '{ x: number; y: Type 'number' is not assignable to type 'string'. -==== tests/cases/compiler/widenedTypes.ts (8 errors) ==== +==== tests/cases/compiler/widenedTypes.ts (9 errors) ==== null instanceof (() => { }); ~~~~ @@ -19,13 +20,15 @@ tests/cases/compiler/widenedTypes.ts(24,5): error TS2322: Type '{ x: number; y: ({}) instanceof null; // Ok because null is a subtype of function null in {}; + ~~~~ +!!! error TS2531: Object is possibly 'null'. "" in null; ~~~~ -!!! error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter +!!! error TS2531: Object is possibly 'null'. for (var a in null) { } ~~~~ -!!! error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter. +!!! error TS2531: Object is possibly 'null'. var t = [3, (3, null)]; ~ diff --git a/tests/cases/compiler/argumentsAsPropertyName.ts b/tests/cases/compiler/argumentsAsPropertyName.ts new file mode 100644 index 00000000000..ffecdaa1301 --- /dev/null +++ b/tests/cases/compiler/argumentsAsPropertyName.ts @@ -0,0 +1,15 @@ +// target: es5 +type MyType = { + arguments: Array +} + +declare function use(s: any); + +function myFunction(myType: MyType) { + for (let i = 0; i < 10; i++) { + use(myType.arguments[i]); + // create closure so that tsc will turn loop body into function + const x = 5; + [1, 2, 3].forEach(function(j) { use(x); }) + } +} \ No newline at end of file diff --git a/tests/cases/compiler/augmentExportEquals7.ts b/tests/cases/compiler/augmentExportEquals7.ts new file mode 100644 index 00000000000..c287bcbe8c4 --- /dev/null +++ b/tests/cases/compiler/augmentExportEquals7.ts @@ -0,0 +1,10 @@ +// @Filename: /node_modules/lib/index.d.ts +declare var lib: () => void; +declare namespace lib {} +export = lib; + +// @Filename: /node_modules/@types/lib-extender/index.d.ts +import * as lib from "lib"; +declare module "lib" { + export function fn(): void; +} diff --git a/tests/cases/compiler/destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts b/tests/cases/compiler/destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts new file mode 100644 index 00000000000..c0002f3e80a --- /dev/null +++ b/tests/cases/compiler/destructuringPropertyAssignmentNameIsNotAssignmentTarget.ts @@ -0,0 +1,7 @@ +// test for #10668 +function qux(bar: { value: number }) { + let foo: number; + ({ value: foo } = bar); + let x = () => bar; +} + diff --git a/tests/cases/compiler/es3-jsx-preserve.tsx b/tests/cases/compiler/es3-jsx-preserve.tsx new file mode 100644 index 00000000000..f6092e692b4 --- /dev/null +++ b/tests/cases/compiler/es3-jsx-preserve.tsx @@ -0,0 +1,9 @@ +// @target: ES3 +// @sourcemap: false +// @declaration: false +// @jsx: preserve + +const React: any = null; + +const elem =
; + diff --git a/tests/cases/compiler/es3-jsx-react-native.tsx b/tests/cases/compiler/es3-jsx-react-native.tsx new file mode 100644 index 00000000000..9ed0f9e003d --- /dev/null +++ b/tests/cases/compiler/es3-jsx-react-native.tsx @@ -0,0 +1,9 @@ +// @target: ES3 +// @sourcemap: false +// @declaration: false +// @jsx: react-native + +const React: any = null; + +const elem =
; + diff --git a/tests/cases/compiler/es3-jsx-react.tsx b/tests/cases/compiler/es3-jsx-react.tsx new file mode 100644 index 00000000000..d47aea9613f --- /dev/null +++ b/tests/cases/compiler/es3-jsx-react.tsx @@ -0,0 +1,9 @@ +// @target: ES3 +// @sourcemap: false +// @declaration: false +// @jsx: react + +const React: any = null; + +const elem =
; + diff --git a/tests/cases/compiler/importHelpersES6.ts b/tests/cases/compiler/importHelpersES6.ts index 9be680a88d6..0267156cf7e 100644 --- a/tests/cases/compiler/importHelpersES6.ts +++ b/tests/cases/compiler/importHelpersES6.ts @@ -7,9 +7,11 @@ declare var dec: any; } +const o = { a: 1 }; +const y = { ...o }; + // @filename: tslib.d.ts export declare function __extends(d: Function, b: Function): void; -export declare function __assign(t: any, ...sources: any[]): any; export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any; export declare function __param(paramIndex: number, decorator: Function): Function; export declare function __metadata(metadataKey: any, metadataValue: any): Function; diff --git a/tests/cases/compiler/mergedDeclarations7.ts b/tests/cases/compiler/mergedDeclarations7.ts new file mode 100644 index 00000000000..fc0945f4419 --- /dev/null +++ b/tests/cases/compiler/mergedDeclarations7.ts @@ -0,0 +1,21 @@ +// @filename: passport.d.ts +declare module 'passport' { + namespace passport { + interface Passport { + use(): this; + } + + interface PassportStatic extends Passport { + Passport: {new(): Passport}; + } + } + + const passport: passport.PassportStatic; + export = passport; +} + +//@filename: test.ts +import * as passport from "passport"; +import { Passport } from "passport"; + +let p: Passport = passport.use(); \ No newline at end of file diff --git a/tests/cases/compiler/metadataOfEventAlias.ts b/tests/cases/compiler/metadataOfEventAlias.ts new file mode 100644 index 00000000000..c62e1480c89 --- /dev/null +++ b/tests/cases/compiler/metadataOfEventAlias.ts @@ -0,0 +1,14 @@ +// @experimentalDecorators: true +// @emitDecoratorMetadata: true +// @target: es5 +// @includeBuiltFile: lib.d.ts + +// @filename: event.ts +export interface Event { title: string }; + +// @filename: test.ts +import { Event } from './event'; +function Input(target: any, key: string): void { } +export class SomeClass { + @Input event: Event; +} \ No newline at end of file diff --git a/tests/cases/compiler/misspelledJsDocTypedefTags.ts b/tests/cases/compiler/misspelledJsDocTypedefTags.ts new file mode 100644 index 00000000000..3f3221020bd --- /dev/null +++ b/tests/cases/compiler/misspelledJsDocTypedefTags.ts @@ -0,0 +1,9 @@ +// @allowJs: true +// @noEmit: true + +// @filename: a.js +/** @typedef {{ endTime: number, screenshots: number}} A.*/ +Animation.AnimationModel.ScreenshotCapture.Request; + +/** @typedef {{ endTime: number, screenshots: !B.}} */ +Animation.AnimationModel.ScreenshotCapture.Request; \ No newline at end of file diff --git a/tests/cases/compiler/nestedLoopWithOnlyInnerLetCaptured.ts b/tests/cases/compiler/nestedLoopWithOnlyInnerLetCaptured.ts new file mode 100644 index 00000000000..210465b13da --- /dev/null +++ b/tests/cases/compiler/nestedLoopWithOnlyInnerLetCaptured.ts @@ -0,0 +1,6 @@ +// @target: es5 +declare let doSomething; + +for (let a1 of []) + for (let a2 of a1.someArray) + doSomething(() => a2); \ No newline at end of file diff --git a/tests/cases/compiler/noBundledEmitFromNodeModules.ts b/tests/cases/compiler/noBundledEmitFromNodeModules.ts new file mode 100644 index 00000000000..66c71a58489 --- /dev/null +++ b/tests/cases/compiler/noBundledEmitFromNodeModules.ts @@ -0,0 +1,10 @@ +// @outFile: out.js +// @module: system +// @moduleResolution: node +// @noImplicitReferences: true + +// @fileName: /node_modules/projB/index.ts +export class C {} + +// @fileName: /a.ts +import { C } from "projB"; diff --git a/tests/cases/compiler/reactImportDropped.ts b/tests/cases/compiler/reactImportDropped.ts new file mode 100644 index 00000000000..a345e7c74fd --- /dev/null +++ b/tests/cases/compiler/reactImportDropped.ts @@ -0,0 +1,42 @@ +//@module: es6 +//@moduleResolution: node +//@target: es6 +//@noImplicitAny: false +//@allowSyntheticDefaultImports: true +//@allowJs: true +//@jsx: react +//@outDir: "build" + +//@filename: react.d.ts +export = React; +export as namespace React; + +declare namespace React { + + function createClass(spec: any): ClassicComponentClass; + + interface ClassicComponentClass { + new (props?: any): ClassicComponentClass; + } +} + +declare global { + namespace JSX { + interface ElementAttributesProperty { } + } +} + + +//@filename: src/components/TabBar.js +export default React.createClass({ + render() { + return ( + null + ); + } +}); + +//@filename: src/modules/navigation/NavigationView.js +import TabBar from '../../components/TabBar'; +import {layout} from '../../utils/theme'; // <- DO NOT DROP this import +const x = ; diff --git a/tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts b/tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts index c8ebc312104..aa78d4333c6 100644 --- a/tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts +++ b/tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts @@ -1,20 +1,20 @@ interface A { - name(); + prop(); } class B { - public name() { } + public prop() { } } class C { - public static name() { } + public static prop() { } } var a: A = new B(); -a = new C(); // error name is missing -a = B; // error name is missing +a = new C(); // error prop is missing +a = B; // error prop is missing a = C; -var b: B = new C(); // error name is missing -b = B; // error name is missing +var b: B = new C(); // error prop is missing +b = B; // error prop is missing b = C; b = a; diff --git a/tests/cases/compiler/superHasMethodsFromMergedInterface.ts b/tests/cases/compiler/superHasMethodsFromMergedInterface.ts new file mode 100644 index 00000000000..cdca6ae65bf --- /dev/null +++ b/tests/cases/compiler/superHasMethodsFromMergedInterface.ts @@ -0,0 +1,7 @@ +class C { m1() { } } +interface C { m2(): void } +class Sub extends C { + m3() { + super.m2(); + } +} diff --git a/tests/cases/conformance/classes/mixinClassesAnnotated.ts b/tests/cases/conformance/classes/mixinClassesAnnotated.ts new file mode 100644 index 00000000000..62f5e30c9a0 --- /dev/null +++ b/tests/cases/conformance/classes/mixinClassesAnnotated.ts @@ -0,0 +1,67 @@ +// @declaration: true + +type Constructor = new(...args: any[]) => T; + +class Base { + constructor(public x: number, public y: number) {} +} + +class Derived extends Base { + constructor(x: number, y: number, public z: number) { + super(x, y); + } +} + +interface Printable { + print(): void; +} + +const Printable = >(superClass: T): Constructor & { message: string } & T => + class extends superClass { + static message = "hello"; + print() { + const output = this.x + "," + this.y; + } + } + +interface Tagged { + _tag: string; +} + +function Tagged>(superClass: T): Constructor & T { + class C extends superClass { + _tag: string; + constructor(...args: any[]) { + super(...args); + this._tag = "hello"; + } + } + return C; +} + +const Thing1 = Tagged(Derived); +const Thing2 = Tagged(Printable(Derived)); +Thing2.message; + +function f1() { + const thing = new Thing1(1, 2, 3); + thing.x; + thing._tag; +} + +function f2() { + const thing = new Thing2(1, 2, 3); + thing.x; + thing._tag; + thing.print(); +} + +class Thing3 extends Thing2 { + constructor(tag: string) { + super(10, 20, 30); + this._tag = tag; + } + test() { + this.print(); + } +} diff --git a/tests/cases/conformance/classes/mixinClassesAnonymous.ts b/tests/cases/conformance/classes/mixinClassesAnonymous.ts new file mode 100644 index 00000000000..0e422888087 --- /dev/null +++ b/tests/cases/conformance/classes/mixinClassesAnonymous.ts @@ -0,0 +1,64 @@ +type Constructor = new(...args: any[]) => T; + +class Base { + constructor(public x: number, public y: number) {} +} + +class Derived extends Base { + constructor(x: number, y: number, public z: number) { + super(x, y); + } +} + +const Printable = >(superClass: T) => class extends superClass { + static message = "hello"; + print() { + const output = this.x + "," + this.y; + } +} + +function Tagged>(superClass: T) { + class C extends superClass { + _tag: string; + constructor(...args: any[]) { + super(...args); + this._tag = "hello"; + } + } + return C; +} + +const Thing1 = Tagged(Derived); +const Thing2 = Tagged(Printable(Derived)); +Thing2.message; + +function f1() { + const thing = new Thing1(1, 2, 3); + thing.x; + thing._tag; +} + +function f2() { + const thing = new Thing2(1, 2, 3); + thing.x; + thing._tag; + thing.print(); +} + +class Thing3 extends Thing2 { + constructor(tag: string) { + super(10, 20, 30); + this._tag = tag; + } + test() { + this.print(); + } +} + +// Repro from #13805 + +const Timestamped = >(Base: CT) => { + return class extends Base { + timestamp = new Date(); + }; +} diff --git a/tests/cases/conformance/classes/mixinClassesMembers.ts b/tests/cases/conformance/classes/mixinClassesMembers.ts new file mode 100644 index 00000000000..905518c88f8 --- /dev/null +++ b/tests/cases/conformance/classes/mixinClassesMembers.ts @@ -0,0 +1,99 @@ +// @declaration: true + +declare class C1 { + public a: number; + protected b: number; + private c: number; + constructor(s: string); + constructor(n: number); +} + +declare class M1 { + constructor(...args: any[]); + p: number; + static p: number; +} + +declare class M2 { + constructor(...args: any[]); + f(): number; + static f(): number; +} + +declare const Mixed1: typeof M1 & typeof C1; +declare const Mixed2: typeof C1 & typeof M1; +declare const Mixed3: typeof M2 & typeof M1 & typeof C1; +declare const Mixed4: typeof C1 & typeof M1 & typeof M2; +declare const Mixed5: typeof M1 & typeof M2; + +function f1() { + let x1 = new Mixed1("hello"); + let x2 = new Mixed1(42); + let x3 = new Mixed2("hello"); + let x4 = new Mixed2(42); + let x5 = new Mixed3("hello"); + let x6 = new Mixed3(42); + let x7 = new Mixed4("hello"); + let x8 = new Mixed4(42); + let x9 = new Mixed5(); +} + +function f2() { + let x = new Mixed1("hello"); + x.a; + x.p; + Mixed1.p; +} + +function f3() { + let x = new Mixed2("hello"); + x.a; + x.p; + Mixed2.p; +} + +function f4() { + let x = new Mixed3("hello"); + x.a; + x.p; + x.f(); + Mixed3.p; + Mixed3.f(); +} + +function f5() { + let x = new Mixed4("hello"); + x.a; + x.p; + x.f(); + Mixed4.p; + Mixed4.f(); +} + +function f6() { + let x = new Mixed5(); + x.p; + x.f(); + Mixed5.p; + Mixed5.f(); +} + +class C2 extends Mixed1 { + constructor() { + super("hello"); + this.a; + this.b; + this.p; + } +} + +class C3 extends Mixed3 { + constructor() { + super(42); + this.a; + this.b; + this.p; + this.f(); + } + f() { return super.f(); } +} diff --git a/tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts b/tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts new file mode 100644 index 00000000000..86755cb016d --- /dev/null +++ b/tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts @@ -0,0 +1,192 @@ +// @target: es5 +// name +class StaticName { + static name: number; // error + name: string; // ok +} + +class StaticNameFn { + static name() {} // error + name() {} // ok +} + +// length +class StaticLength { + static length: number; // error + length: string; // ok +} + +class StaticLengthFn { + static length() {} // error + length() {} // ok +} + +// prototype +class StaticPrototype { + static prototype: number; // error + prototype: string; // ok +} + +class StaticPrototypeFn { + static prototype() {} // error + prototype() {} // ok +} + +// caller +class StaticCaller { + static caller: number; // error + caller: string; // ok +} + +class StaticCallerFn { + static caller() {} // error + caller() {} // ok +} + +// arguments +class StaticArguments { + static arguments: number; // error + arguments: string; // ok +} + +class StaticArgumentsFn { + static arguments() {} // error + arguments() {} // ok +} + + + +// === Static properties on anonymous classes === + +// name +var StaticName_Anonymous = class { + static name: number; // error + name: string; // ok +} + +var StaticNameFn_Anonymous = class { + static name() {} // error + name() {} // ok +} + +// length +var StaticLength_Anonymous = class { + static length: number; // error + length: string; // ok +} + +var StaticLengthFn_Anonymous = class { + static length() {} // error + length() {} // ok +} + +// prototype +var StaticPrototype_Anonymous = class { + static prototype: number; // error + prototype: string; // ok +} + +var StaticPrototypeFn_Anonymous = class { + static prototype() {} // error + prototype() {} // ok +} + +// caller +var StaticCaller_Anonymous = class { + static caller: number; // error + caller: string; // ok +} + +var StaticCallerFn_Anonymous = class { + static caller() {} // error + caller() {} // ok +} + +// arguments +var StaticArguments_Anonymous = class { + static arguments: number; // error + arguments: string; // ok +} + +var StaticArgumentsFn_Anonymous = class { + static arguments() {} // error + arguments() {} // ok +} + + +// === Static properties on default exported classes === + +// name +module TestOnDefaultExportedClass_1 { + class StaticName { + static name: number; // error + name: string; // ok + } +} + +module TestOnDefaultExportedClass_2 { + class StaticNameFn { + static name() {} // error + name() {} // ok + } +} + +// length +module TestOnDefaultExportedClass_3 { + export default class StaticLength { + static length: number; // error + length: string; // ok + } +} + +module TestOnDefaultExportedClass_4 { + export default class StaticLengthFn { + static length() {} // error + length() {} // ok + } +} + +// prototype +module TestOnDefaultExportedClass_5 { + export default class StaticPrototype { + static prototype: number; // error + prototype: string; // ok + } +} + +module TestOnDefaultExportedClass_6 { + export default class StaticPrototypeFn { + static prototype() {} // error + prototype() {} // ok + } +} + +// caller +module TestOnDefaultExportedClass_7 { + export default class StaticCaller { + static caller: number; // error + caller: string; // ok + } +} + +module TestOnDefaultExportedClass_8 { + export default class StaticCallerFn { + static caller() {} // error + caller() {} // ok + } +} + +// arguments +module TestOnDefaultExportedClass_9 { + export default class StaticArguments { + static arguments: number; // error + arguments: string; // ok + } +} + +module TestOnDefaultExportedClass_10 { + export default class StaticArgumentsFn { + static arguments() {} // error + arguments() {} // ok + } +} \ No newline at end of file diff --git a/tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflictsInAmbientContext.ts b/tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflictsInAmbientContext.ts new file mode 100644 index 00000000000..198c923b0dd --- /dev/null +++ b/tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflictsInAmbientContext.ts @@ -0,0 +1,56 @@ + +//@Filename: decl.d.ts +// name +declare class StaticName { + static name: number; // ok + name: string; // ok +} + +declare class StaticNameFn { + static name(): string; // ok + name(): string; // ok +} + +// length +declare class StaticLength { + static length: number; // ok + length: string; // ok +} + +declare class StaticLengthFn { + static length(): number; // ok + length(): number; // ok +} + +// prototype +declare class StaticPrototype { + static prototype: number; // ok + prototype: string; // ok +} + +declare class StaticPrototypeFn { + static prototype: any; // ok + prototype(): any; // ok +} + +// caller +declare class StaticCaller { + static caller: number; // ok + caller: string; // ok +} + +declare class StaticCallerFn { + static caller(): any; // ok + caller(): any; // ok +} + +// arguments +declare class StaticArguments { + static arguments: number; // ok + arguments: string; // ok +} + +declare class StaticArgumentsFn { + static arguments(): any; // ok + arguments(): any; // ok +} diff --git a/tests/cases/conformance/es6/propertyAccess/propertyAccessNumericLiterals.es6.ts b/tests/cases/conformance/es6/propertyAccess/propertyAccessNumericLiterals.es6.ts new file mode 100644 index 00000000000..81e39965a6a --- /dev/null +++ b/tests/cases/conformance/es6/propertyAccess/propertyAccessNumericLiterals.es6.ts @@ -0,0 +1,6 @@ +// @target: es6 +0xffffffff.toString(); +0o01234.toString(); +0b01101101.toString(); +1234..toString(); +1e0.toString(); diff --git a/tests/cases/conformance/expressions/propertyAccess/propertyAccessNumericLiterals.ts b/tests/cases/conformance/expressions/propertyAccess/propertyAccessNumericLiterals.ts new file mode 100644 index 00000000000..318b05fc0b5 --- /dev/null +++ b/tests/cases/conformance/expressions/propertyAccess/propertyAccessNumericLiterals.ts @@ -0,0 +1,7 @@ +// @target: es3 +0xffffffff.toString(); +0o01234.toString(); +0b01101101.toString(); +1234..toString(); +1e0.toString(); +000.toString(); \ No newline at end of file diff --git a/tests/cases/conformance/expressions/propertyAccess/propertyAccessStringIndexSignature.ts b/tests/cases/conformance/expressions/propertyAccess/propertyAccessStringIndexSignature.ts new file mode 100644 index 00000000000..7faf758bc9f --- /dev/null +++ b/tests/cases/conformance/expressions/propertyAccess/propertyAccessStringIndexSignature.ts @@ -0,0 +1,11 @@ +interface Flags { [name: string]: boolean }; +let flags: Flags; +flags.b; +flags.f; +flags.isNotNecessarilyNeverFalse; +flags['this is fine']; + +interface Empty { } +let empty: Empty; +empty.nope; +empty["that's ok"]; diff --git a/tests/cases/conformance/expressions/propertyAccess/propertyAccessStringIndexSignatureNoImplicitAny.ts b/tests/cases/conformance/expressions/propertyAccess/propertyAccessStringIndexSignatureNoImplicitAny.ts new file mode 100644 index 00000000000..bfb64c6098a --- /dev/null +++ b/tests/cases/conformance/expressions/propertyAccess/propertyAccessStringIndexSignatureNoImplicitAny.ts @@ -0,0 +1,12 @@ +// @noImplicitAny: true +interface Flags { [name: string]: boolean } +let flags: Flags; +flags.b; +flags.f; +flags.isNotNecessarilyNeverFalse; +flags['this is fine']; + +interface Empty { } +let empty: Empty; +empty.nope; +empty["not allowed either"]; diff --git a/tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersection.ts b/tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersection.ts new file mode 100644 index 00000000000..003976a2b27 --- /dev/null +++ b/tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersection.ts @@ -0,0 +1,55 @@ +// @strictNullChecks: true + +type T1 = { a: number }; +type T2 = T1 & { b: number }; +type T3 = () => void; +type T4 = new () => { a: number }; +type T5 = number[]; +type T6 = [string, number]; +type T7 = { [P in 'a' | 'b' | 'c']: string }; + +interface I1 extends T1 { x: string } +interface I2 extends T2 { x: string } +interface I3 extends T3 { x: string } +interface I4 extends T4 { x: string } +interface I5 extends T5 { x: string } +interface I6 extends T6 { x: string } +interface I7 extends T7 { x: string } + +type Constructor = new () => T; +declare function Constructor(): Constructor; + +class C1 extends Constructor() { x: string } +class C2 extends Constructor() { x: string } +class C3 extends Constructor() { x: string } +class C4 extends Constructor() { x: string } +class C5 extends Constructor() { x: string } +class C6 extends Constructor() { x: string } +class C7 extends Constructor() { x: string } + +declare function fx(x: string): string; +declare class CX { a: number } +declare enum EX { A, B, C } +declare namespace NX { export const a = 1 } + +type T10 = typeof fx; +type T11 = typeof CX; +type T12 = typeof EX; +type T13 = typeof NX; + +interface I10 extends T10 { x: string } +interface I11 extends T11 { x: string } +interface I12 extends T12 { x: string } +interface I13 extends T13 { x: string } + +type Identifiable = { _id: string } & T; + +interface I20 extends Partial { x: string } +interface I21 extends Readonly { x: string } +interface I22 extends Identifiable { x: string } +interface I23 extends Identifiable { x: string } + +class C20 extends Constructor>() { x: string } +class C21 extends Constructor>() { x: string } +class C22 extends Constructor>() { x: string } +class C23 extends Constructor>() { x: string } diff --git a/tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts b/tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts new file mode 100644 index 00000000000..5a2a37fc227 --- /dev/null +++ b/tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts @@ -0,0 +1,49 @@ +// @strictNullChecks: true + +type T1 = { a: number }; +type T2 = T1 & { b: number }; +type T3 = number[]; +type T4 = [string, number]; +type T5 = { [P in 'a' | 'b' | 'c']: string }; + +interface I1 extends T1 { a: string } +interface I2 extends T2 { b: string } +interface I3 extends T3 { length: string } +interface I4 extends T4 { 0: number } +interface I5 extends T5 { c: number } + +type Constructor = new () => T; +declare function Constructor(): Constructor; + +class C1 extends Constructor() { a: string } +class C2 extends Constructor() { b: string } +class C3 extends Constructor() { length: string } +class C4 extends Constructor() { 0: number } +class C5 extends Constructor() { c: number } + +declare class CX { static a: string } +declare enum EX { A, B, C } +declare namespace NX { export const a = "hello" } + +type TCX = typeof CX; +type TEX = typeof EX; +type TNX = typeof NX; + +interface I10 extends TCX { a: number } +interface I11 extends TEX { C: string } +interface I12 extends TNX { a: number } +interface I14 extends TCX { [x: string]: number } +interface I15 extends TEX { [x: string]: number } +interface I16 extends TNX { [x: string]: number } + +type Identifiable = { _id: string } & T; + +interface I20 extends Partial { a: string } +interface I21 extends Readonly { a: string } +interface I22 extends Identifiable { a: string } +interface I23 extends Identifiable { a: string } + +type U = { a: number } | { b: string }; + +interface I30 extends U { x: string } +interface I31 extends T { x: string } diff --git a/tests/cases/conformance/types/intersection/intersectionThisTypes.ts b/tests/cases/conformance/types/intersection/intersectionThisTypes.ts new file mode 100644 index 00000000000..8819148dc9e --- /dev/null +++ b/tests/cases/conformance/types/intersection/intersectionThisTypes.ts @@ -0,0 +1,40 @@ +interface Thing1 { + a: number; + self(): this; +} + +interface Thing2 { + b: number; + me(): this; +} + +type Thing3 = Thing1 & Thing2; +type Thing4 = Thing3 & string[]; + +function f1(t: Thing3) { + t = t.self(); + t = t.me().self().me(); +} + +interface Thing5 extends Thing4 { + c: string; +} + +function f2(t: Thing5) { + t = t.self(); + t = t.me().self().me(); +} + +interface Component { + extend(props: T): this & T; +} + +interface Label extends Component { + title: string; +} + +function test(label: Label) { + const extended = label.extend({ id: 67 }).extend({ tag: "hello" }); + extended.id; // Ok + extended.tag; // Ok +} diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts index 27e47da177c..70b70dff6ea 100644 --- a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts @@ -501,3 +501,56 @@ function updateIds2( var x = obj[key]; stringMap[x]; // Should be OK. } + +// Repro from #13514 + +declare function head>(list: T): T[0]; + +// Repro from #13604 + +class A { + props: T & { foo: string }; +} + +class B extends A<{ x: number}> { + f(p: this["props"]) { + p.x; + } +} + +// Repro from #13749 + +class Form { + private childFormFactories: {[K in keyof T]: (v: T[K]) => Form} + + public set(prop: K, value: T[K]) { + 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/conformance/types/mapped/mappedTypesAndObjects.ts b/tests/cases/conformance/types/mapped/mappedTypesAndObjects.ts index 8023f6e7d8d..b3530b46965 100644 --- a/tests/cases/conformance/types/mapped/mappedTypesAndObjects.ts +++ b/tests/cases/conformance/types/mapped/mappedTypesAndObjects.ts @@ -13,23 +13,33 @@ function f2(x: Partial, y: Readonly) { obj = y; } +function f3(x: Partial) { + x = {}; +} + // Repro from #12900 interface Base { - foo: { [key: string]: any }; - bar: any; - baz: any; + foo: { [key: string]: any }; + bar: any; + baz: any; } interface E1 extends Base { - foo: T; + foo: T; } interface Something { name: string, value: string }; interface E2 extends Base { - foo: Partial; // or other mapped type + foo: Partial; // or other mapped type } interface E3 extends Base { - foo: Partial; // or other mapped type -} \ No newline at end of file + foo: Partial; // or other mapped type +} + +// Repro from #13747 + +class Form { + private values: {[P in keyof T]?: T[P]} = {} +} diff --git a/tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts index 2febbb1e2ca..cf902c12e65 100644 --- a/tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts +++ b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveAccessProperty.ts @@ -1,3 +1,6 @@ var a: object; a.toString(); a.nonExist(); // error + +var { destructuring } = a; // error +var { ...rest } = a; // ok diff --git a/tests/cases/conformance/types/nonPrimitive/nonPrimitiveAsProperty.ts b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveAsProperty.ts index ee4011ecf7d..3cd2ce4cef5 100644 --- a/tests/cases/conformance/types/nonPrimitive/nonPrimitiveAsProperty.ts +++ b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveAsProperty.ts @@ -1,3 +1,4 @@ +// @declaration: true interface WithNonPrimitive { foo: object } diff --git a/tests/cases/conformance/types/nonPrimitive/nonPrimitiveInFunction.ts b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveInFunction.ts index c38693dbfb1..d56c02fafe9 100644 --- a/tests/cases/conformance/types/nonPrimitive/nonPrimitiveInFunction.ts +++ b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveInFunction.ts @@ -1,3 +1,4 @@ +// @declaration: true function takeObject(o: object) {} function returnObject(): object { return {}; diff --git a/tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts index 836896b5a57..490a9f88135 100644 --- a/tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts +++ b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveInGeneric.ts @@ -1,3 +1,4 @@ +// @declaration: true function generic(t: T) { var o: object = t; // expect error } diff --git a/tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts index c1667c7a32e..a9d5872705c 100644 --- a/tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts +++ b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts @@ -1,3 +1,4 @@ +// @declaration: true var a: object & string = ""; // error var b: object | string = ""; // ok a = b; // error diff --git a/tests/cases/conformance/types/rest/objectRest.ts b/tests/cases/conformance/types/rest/objectRest.ts index 77f0fca1ed7..7403340c7cb 100644 --- a/tests/cases/conformance/types/rest/objectRest.ts +++ b/tests/cases/conformance/types/rest/objectRest.ts @@ -44,4 +44,4 @@ let computed2 = 'a'; var { [computed]: stillNotGreat, [computed2]: soSo, ...o } = o; ({ [computed]: stillNotGreat, [computed2]: soSo, ...o } = o); -var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject['anythingGoes']; +var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject.anythingGoes; diff --git a/tests/cases/conformance/types/rest/objectRestNegative.ts b/tests/cases/conformance/types/rest/objectRestNegative.ts index 4f4667fe65a..13d214e453d 100644 --- a/tests/cases/conformance/types/rest/objectRestNegative.ts +++ b/tests/cases/conformance/types/rest/objectRestNegative.ts @@ -16,5 +16,3 @@ function generic(t: T) { let rest: { b: string } ({a, ...rest.b + rest.b} = o); - -var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject.anythingGoes; diff --git a/tests/cases/conformance/types/spread/objectSpread.ts b/tests/cases/conformance/types/spread/objectSpread.ts index ebf2bdb2ade..59b93bdd9e4 100644 --- a/tests/cases/conformance/types/spread/objectSpread.ts +++ b/tests/cases/conformance/types/spread/objectSpread.ts @@ -78,4 +78,5 @@ let computedAfter: { a: number, b: string, "at the end": number } = // shortcut syntax let a = 12; let shortCutted: { a: number, b: string } = { ...o, a } - +// non primitive +let spreadNonPrimitive = { ...{}}; diff --git a/tests/cases/conformance/types/spread/objectSpreadNegative.ts b/tests/cases/conformance/types/spread/objectSpreadNegative.ts index 6d1e0dde429..c3b42b31aa9 100644 --- a/tests/cases/conformance/types/spread/objectSpreadNegative.ts +++ b/tests/cases/conformance/types/spread/objectSpreadNegative.ts @@ -52,6 +52,11 @@ let c: C = new C() let spreadC = { ...c } spreadC.m(); // error 'm' is not in '{ ... c }' +// non primitive +let obj: object = { a: 123 }; +let spreadObj = { ...obj }; +spreadObj.a; // error 'a' is not in {} + // generics function f(t: T, u: U) { return { ...t, ...u, id: 'id' }; diff --git a/tests/cases/fourslash/codeFixAddForgottenThis01.ts b/tests/cases/fourslash/codeFixAddForgottenThis01.ts new file mode 100644 index 00000000000..90d191b6ba5 --- /dev/null +++ b/tests/cases/fourslash/codeFixAddForgottenThis01.ts @@ -0,0 +1,10 @@ +/// + +////class C { +//// foo: number; +//// constructor() { +//// [|foo = 10|]; +//// } +////} + +verify.rangeAfterCodeFix("this.foo = 10"); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixAddForgottenThis02.ts b/tests/cases/fourslash/codeFixAddForgottenThis02.ts new file mode 100644 index 00000000000..b387f349073 --- /dev/null +++ b/tests/cases/fourslash/codeFixAddForgottenThis02.ts @@ -0,0 +1,9 @@ +/// + +////class C { +//// constructor(public foo) { +//// } +//// bar() { [|foo = 10|] }; +////} + +verify.rangeAfterCodeFix("this.foo = 10"); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyLiterals.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyLiterals.ts index 465f9a5b4f1..341b4e59814 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyLiterals.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyLiterals.ts @@ -10,12 +10,12 @@ //// class C implements I {[| |]} verify.rangeAfterCodeFix(` - [1](): string { - throw new Error('Method not implemented.'); - } - [2]: boolean; ["foo"](o: any): boolean { throw new Error('Method not implemented.'); } ["x"]: boolean; + [1](): string { + throw new Error('Method not implemented.'); + } + [2]: boolean; `); \ No newline at end of file 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/completionForStringLiteral7.ts b/tests/cases/fourslash/completionForStringLiteral7.ts new file mode 100644 index 00000000000..b2d250ac3fd --- /dev/null +++ b/tests/cases/fourslash/completionForStringLiteral7.ts @@ -0,0 +1,10 @@ +/// + +////type T = "foo" | "bar"; +////type U = "oof" | "rab"; +////function f(x: T, ...args: U[]) { }; +////f("/*1*/", "/*2*/", "/*3*/"); + +verify.completionsAt("1", ["foo", "bar"]); +verify.completionsAt("2", ["oof", "rab"]); +verify.completionsAt("3", ["oof", "rab"]); 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/completionListAtIdentifierDefinitionLocations_Generics.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_Generics.ts index 0e92a3ae995..784fc8c499c 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_Generics.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_Generics.ts @@ -11,8 +11,4 @@ ////function A { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); \ No newline at end of file +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_catch.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_catch.ts index bdf13c1d97f..bfbfa1bb160 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_catch.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_catch.ts @@ -6,8 +6,4 @@ //// try {} catch(a/*catchVariable2*/ - -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_classes.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_classes.ts index 60a108cf1e6..5d96c565719 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_classes.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_classes.ts @@ -6,7 +6,4 @@ ////class a/*className2*/ -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_destructuring.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_destructuring.ts index 7f8ef32e1ad..d2ecdf29426 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_destructuring.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_destructuring.ts @@ -16,7 +16,4 @@ //// function func2({ a, b/*parameter2*/ -test.markers().forEach(m => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enumMembers.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enumMembers.ts index 6c0472be546..f0818108301 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enumMembers.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enumMembers.ts @@ -4,8 +4,4 @@ ////enum a { /*enumValueName1*/ - -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enumMembers2.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enumMembers2.ts index ee2f3e71032..11aa276bb5a 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enumMembers2.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enumMembers2.ts @@ -3,7 +3,4 @@ ////var aa = 1; ////enum a { foo, /*enumValueName3*/ -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enums.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enums.ts index 183f8a22c63..c740218e27e 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enums.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_enums.ts @@ -8,7 +8,4 @@ ////var x = 0; enum /*enumName4*/ -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_functions.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_functions.ts index 24231174727..2f55f9527bc 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_functions.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_functions.ts @@ -6,8 +6,4 @@ ////function a/*functionName2*/ - -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers.ts index 266b0b78c9c..9998f38c255 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers.ts @@ -4,7 +4,4 @@ ////interface a { /*interfaceValue1*/ -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers2.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers2.ts index 82a30325948..234e41bfb71 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers2.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers2.ts @@ -4,7 +4,4 @@ ////interface a { f/*interfaceValue2*/ -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers3.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers3.ts index ed640dd3f1a..f0a596ef8b1 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers3.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaceMembers3.ts @@ -4,7 +4,4 @@ ////interface a { f; /*interfaceValue3*/ -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaces.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaces.ts index ec2732fe2fe..d4be268eb7d 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaces.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_interfaces.ts @@ -6,8 +6,4 @@ ////interface a/*interfaceName2*/ - -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_parameters.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_parameters.ts index 10293c41a64..474859129db 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_parameters.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_parameters.ts @@ -22,8 +22,4 @@ ////class bar10{ constructor(...a/*constructorParamter6*/ - -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_properties.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_properties.ts index 58fdc1d2342..3ba0df0c31d 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_properties.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_properties.ts @@ -30,8 +30,7 @@ //// private a/*property7*/ ////} -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); +goTo.eachMarker(() => { verify.not.completionListIsEmpty(); verify.completionListAllowsNewIdentifier(); }); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_varDeclarations.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_varDeclarations.ts index 2e85364ce3c..9a2c9ba664a 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_varDeclarations.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_varDeclarations.ts @@ -11,7 +11,4 @@ ////var a2, a/*varName4*/ -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListAtInvalidLocations.ts b/tests/cases/fourslash/completionListAtInvalidLocations.ts index 6e4b4056a7d..0660f0e183b 100644 --- a/tests/cases/fourslash/completionListAtInvalidLocations.ts +++ b/tests/cases/fourslash/completionListAtInvalidLocations.ts @@ -25,7 +25,4 @@ ////foo; ////var v10 = /reg/*inRegExp1*/ex/; -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListBuilderLocations_VariableDeclarations.ts b/tests/cases/fourslash/completionListBuilderLocations_VariableDeclarations.ts index d069b9a722e..2562b840995 100644 --- a/tests/cases/fourslash/completionListBuilderLocations_VariableDeclarations.ts +++ b/tests/cases/fourslash/completionListBuilderLocations_VariableDeclarations.ts @@ -11,7 +11,7 @@ //// var y : any = "", x = (a/*var5*/ ////class C{} -////var y = new C( +////var y = new C( //// class C{} //// var y = new C(0, /*var7*/ @@ -26,9 +26,4 @@ ////var y = 10; y=/*var12*/ -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListAllowsNewIdentifier(); -}); - - +goTo.eachMarker(() => verify.completionListAllowsNewIdentifier()); diff --git a/tests/cases/fourslash/completionListBuilderLocations_parameters.ts b/tests/cases/fourslash/completionListBuilderLocations_parameters.ts index 12dba953d3d..607ca0d9819 100644 --- a/tests/cases/fourslash/completionListBuilderLocations_parameters.ts +++ b/tests/cases/fourslash/completionListBuilderLocations_parameters.ts @@ -14,9 +14,7 @@ ////class bar7{ constructor(private a, /*constructorParamter6*/ - -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); +goTo.eachMarker(() => { verify.not.completionListIsEmpty(); verify.completionListAllowsNewIdentifier(); }); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListBuilderLocations_properties.ts b/tests/cases/fourslash/completionListBuilderLocations_properties.ts index 287ffd6746b..806d8c1de4f 100644 --- a/tests/cases/fourslash/completionListBuilderLocations_properties.ts +++ b/tests/cases/fourslash/completionListBuilderLocations_properties.ts @@ -10,7 +10,4 @@ //// public static a/*property2*/ ////} -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.completionListIsEmpty(); -}); \ No newline at end of file +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListInIndexSignature01.ts b/tests/cases/fourslash/completionListInIndexSignature01.ts index 2db28505b3e..aaf97fee1a5 100644 --- a/tests/cases/fourslash/completionListInIndexSignature01.ts +++ b/tests/cases/fourslash/completionListInIndexSignature01.ts @@ -14,7 +14,4 @@ //// [x/*5*/yz: number]: boolean; //// [/*6*/ -for (let marker of test.markers()) { - goTo.position(marker.position); - verify.completionListAllowsNewIdentifier(); -} \ No newline at end of file +goTo.eachMarker(() => verify.completionListAllowsNewIdentifier()); diff --git a/tests/cases/fourslash/completionListInIndexSignature02.ts b/tests/cases/fourslash/completionListInIndexSignature02.ts index d3b65dc7759..ce1f8b38e24 100644 --- a/tests/cases/fourslash/completionListInIndexSignature02.ts +++ b/tests/cases/fourslash/completionListInIndexSignature02.ts @@ -13,7 +13,4 @@ ////type T = { //// [xyz: /*5*/ -for (let marker of test.markers()) { - goTo.position(marker.position); - verify.not.completionListAllowsNewIdentifier(); -} \ No newline at end of file +goTo.eachMarker(() => verify.not.completionListAllowsNewIdentifier()); diff --git a/tests/cases/fourslash/completionListInObjectLiteral4.ts b/tests/cases/fourslash/completionListInObjectLiteral4.ts index c00462c8255..3094b4db6ad 100644 --- a/tests/cases/fourslash/completionListInObjectLiteral4.ts +++ b/tests/cases/fourslash/completionListInObjectLiteral4.ts @@ -20,9 +20,7 @@ ////funcE({ /*E*/ }); ////funcF({ /*F*/ }); - -for (const marker of test.markers()) { - goTo.position(marker.position); +goTo.eachMarker(() => { verify.completionListContains("hello"); verify.completionListContains("world"); -} +}); diff --git a/tests/cases/fourslash/completionListInStringLiterals1.ts b/tests/cases/fourslash/completionListInStringLiterals1.ts index e394e8dfe7c..aabcc82eba5 100644 --- a/tests/cases/fourslash/completionListInStringLiterals1.ts +++ b/tests/cases/fourslash/completionListInStringLiterals1.ts @@ -3,8 +3,4 @@ ////"/*1*/ /*2*/\/*3*/ //// /*4*/ \\/*5*/ -test.markers().forEach(marker => { - goTo.position(marker.position); - - verify.completionListIsEmpty() -}); \ No newline at end of file +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListInStringLiterals2.ts b/tests/cases/fourslash/completionListInStringLiterals2.ts index 10cb05a4f91..4ffd5eb8a9b 100644 --- a/tests/cases/fourslash/completionListInStringLiterals2.ts +++ b/tests/cases/fourslash/completionListInStringLiterals2.ts @@ -4,8 +4,4 @@ //// /*4*/ \\\/*5*/ //// /*6*/ -test.markers().forEach(marker => { - goTo.position(marker.position); - - verify.completionListIsEmpty() -}); \ No newline at end of file +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListInTemplateLiteralParts1.ts b/tests/cases/fourslash/completionListInTemplateLiteralParts1.ts index 0166546f63e..9de7b6a6a5b 100644 --- a/tests/cases/fourslash/completionListInTemplateLiteralParts1.ts +++ b/tests/cases/fourslash/completionListInTemplateLiteralParts1.ts @@ -4,8 +4,4 @@ //// /////*6*/`asdasd${/*7*/ 2 + 1.1 /*8*/} 12312 { -test.markers().forEach(marker => { - goTo.position(marker.position); - - verify.completionListItemsCountIsGreaterThan(0) -}); \ No newline at end of file +goTo.eachMarker(() => verify.completionListItemsCountIsGreaterThan(0)); diff --git a/tests/cases/fourslash/completionListInTemplateLiteralPartsNegatives1.ts b/tests/cases/fourslash/completionListInTemplateLiteralPartsNegatives1.ts index ac64a41fb56..30af0678e7d 100644 --- a/tests/cases/fourslash/completionListInTemplateLiteralPartsNegatives1.ts +++ b/tests/cases/fourslash/completionListInTemplateLiteralPartsNegatives1.ts @@ -4,8 +4,4 @@ //// ////`asdasd$/*7*/{ 2 + 1.1 }/*8*/ 12312 /*9*/{/*10*/ -test.markers().forEach(marker => { - goTo.position(marker.position); - - verify.completionListIsEmpty() -}); \ No newline at end of file +goTo.eachMarker(() => verify.completionListIsEmpty()); diff --git a/tests/cases/fourslash/completionListNewIdentifierFunctionDeclaration.ts b/tests/cases/fourslash/completionListNewIdentifierFunctionDeclaration.ts index 8a9a5bfb9ed..1f8b24d1cf1 100644 --- a/tests/cases/fourslash/completionListNewIdentifierFunctionDeclaration.ts +++ b/tests/cases/fourslash/completionListNewIdentifierFunctionDeclaration.ts @@ -2,8 +2,7 @@ ////function F(pref: (a/*1*/ -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); +goTo.eachMarker(() => { verify.not.completionListIsEmpty(); verify.completionListAllowsNewIdentifier(); }); diff --git a/tests/cases/fourslash/completionListNewIdentifierVariableDeclaration.ts b/tests/cases/fourslash/completionListNewIdentifierVariableDeclaration.ts index 534011b7ee1..a4126ebe8be 100644 --- a/tests/cases/fourslash/completionListNewIdentifierVariableDeclaration.ts +++ b/tests/cases/fourslash/completionListNewIdentifierVariableDeclaration.ts @@ -4,8 +4,7 @@ ////var y : (s:string, list/*2*/ -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); +goTo.eachMarker(() => { verify.not.completionListIsEmpty(); verify.completionListAllowsNewIdentifier(); -}); \ No newline at end of file +}); diff --git a/tests/cases/fourslash/docCommentTemplateInSingleLineComment.ts b/tests/cases/fourslash/docCommentTemplateInSingleLineComment.ts index 52925870a66..65e9c17014e 100644 --- a/tests/cases/fourslash/docCommentTemplateInSingleLineComment.ts +++ b/tests/cases/fourslash/docCommentTemplateInSingleLineComment.ts @@ -3,12 +3,9 @@ // @Filename: justAComment.ts //// // We want to check off-by-one errors in assessing the end of the comment, so we check twice, //// // first with a trailing space and then without. -//// // /*0*/ +//// // /*0*/ //// // /*1*/ //// // We also want to check EOF handling at the end of a comment //// // /*2*/ -test.markers().forEach((marker) => { - goTo.position(marker.position); - verify.noDocCommentTemplate(); -}); \ No newline at end of file +goTo.eachMarker(() => verify.noDocCommentTemplate()); diff --git a/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts b/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts index 9c803301526..dd58a1bfd5f 100644 --- a/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts +++ b/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts @@ -3,7 +3,4 @@ // @Filename: functionDecl.ts ////f/*0*/unction /*1*/foo/*2*/(/*3*/) /*4*/{ /*5*/} -test.markers().forEach((marker) => { - goTo.position(marker.position); - verify.noDocCommentTemplate(); -}); +goTo.eachMarker(() => verify.noDocCommentTemplate()); diff --git a/tests/cases/fourslash/docCommentTemplateRegex.ts b/tests/cases/fourslash/docCommentTemplateRegex.ts index 0bf50f5e85a..62d200dee10 100644 --- a/tests/cases/fourslash/docCommentTemplateRegex.ts +++ b/tests/cases/fourslash/docCommentTemplateRegex.ts @@ -3,7 +3,4 @@ // @Filename: regex.ts ////var regex = /*0*///*1*/asdf/*2*/ /*3*///*4*/; -test.markers().forEach((marker) => { - goTo.position(marker.position); - verify.noDocCommentTemplate(); -}); \ No newline at end of file +goTo.eachMarker(() => verify.noDocCommentTemplate()); diff --git a/tests/cases/fourslash/documentHighlightAtInheritedProperties1.ts b/tests/cases/fourslash/documentHighlightAtInheritedProperties1.ts index 23f6445a004..0c07edea506 100644 --- a/tests/cases/fourslash/documentHighlightAtInheritedProperties1.ts +++ b/tests/cases/fourslash/documentHighlightAtInheritedProperties1.ts @@ -2,12 +2,8 @@ // @Filename: file1.ts //// interface interface1 extends interface1 { -//// /*1*/doStuff(): void; -//// /*2*/propName: string; +//// [|doStuff|](): void; +//// [|propName|]: string; //// } -let markers = test.markers() -for (let marker of markers) { - goTo.position(marker.position); - verify.documentHighlightsAtPositionCount(1, ["file1.ts"]); -} +verify.rangesWithSameTextAreDocumentHighlights(); diff --git a/tests/cases/fourslash/documentHighlightAtInheritedProperties2.ts b/tests/cases/fourslash/documentHighlightAtInheritedProperties2.ts index d4aadf96ed6..3327c36b760 100644 --- a/tests/cases/fourslash/documentHighlightAtInheritedProperties2.ts +++ b/tests/cases/fourslash/documentHighlightAtInheritedProperties2.ts @@ -2,12 +2,8 @@ // @Filename: file1.ts //// class class1 extends class1 { -//// /*1*/doStuff() { } -//// /*2*/propName: string; +//// [|doStuff|]() { } +//// [|propName|]: string; //// } -let markers = test.markers() -for (let marker of markers) { - goTo.position(marker.position); - verify.documentHighlightsAtPositionCount(1, ["file1.ts"]); -} \ No newline at end of file +verify.rangesWithSameTextAreDocumentHighlights(); diff --git a/tests/cases/fourslash/documentHighlightAtInheritedProperties3.ts b/tests/cases/fourslash/documentHighlightAtInheritedProperties3.ts index 5e94bb387cd..11625df1442 100644 --- a/tests/cases/fourslash/documentHighlightAtInheritedProperties3.ts +++ b/tests/cases/fourslash/documentHighlightAtInheritedProperties3.ts @@ -2,16 +2,12 @@ // @Filename: file1.ts //// interface interface1 extends interface1 { -//// /*1*/doStuff(): void; -//// /*2*/propName: string; +//// [|doStuff|](): void; +//// [|propName|]: string; //// } //// //// var v: interface1; -//// v./*3*/propName; -//// v./*4*/doStuff(); +//// v.[|propName|]; +//// v.[|doStuff|](); -let markers = test.markers() -for (let marker of markers) { - goTo.position(marker.position); - verify.documentHighlightsAtPositionCount(2, ["file1.ts"]); -} +verify.rangesWithSameTextAreDocumentHighlights(); diff --git a/tests/cases/fourslash/documentHighlightAtInheritedProperties4.ts b/tests/cases/fourslash/documentHighlightAtInheritedProperties4.ts index 50f459ebfdb..1c78233554a 100644 --- a/tests/cases/fourslash/documentHighlightAtInheritedProperties4.ts +++ b/tests/cases/fourslash/documentHighlightAtInheritedProperties4.ts @@ -2,16 +2,12 @@ // @Filename: file1.ts //// class class1 extends class1 { -//// /*1*/doStuff() { } -//// /*2*/propName: string; +//// [|doStuff|]() { } +//// [|propName|]: string; //// } //// //// var c: class1; -//// c./*3*/doStuff(); -//// c./*4*/propName; +//// c.[|doStuff|](); +//// c.[|propName|]; -let markers = test.markers() -for (let marker of markers) { - goTo.position(marker.position); - verify.documentHighlightsAtPositionCount(2, ["file1.ts"]); -} +verify.rangesWithSameTextAreDocumentHighlights(); diff --git a/tests/cases/fourslash/documentHighlightAtInheritedProperties5.ts b/tests/cases/fourslash/documentHighlightAtInheritedProperties5.ts index b5f4cbb00a7..4fdf4a689ac 100644 --- a/tests/cases/fourslash/documentHighlightAtInheritedProperties5.ts +++ b/tests/cases/fourslash/documentHighlightAtInheritedProperties5.ts @@ -2,29 +2,16 @@ // @Filename: file1.ts //// interface C extends D { -//// /*0*/prop0: string; -//// /*1*/prop1: number; +//// [|prop0|]: string; +//// [|prop1|]: number; //// } -//// +//// //// interface D extends C { -//// /*2*/prop0: string; -//// /*3*/prop1: number; +//// [|prop0|]: string; +//// [|prop1|]: number; //// } -//// +//// //// var d: D; -//// d./*4*/prop1; +//// d.[|prop1|]; -goTo.marker("0"); -verify.documentHighlightsAtPositionCount(2, ["file1.ts"]); - -goTo.marker("1"); -verify.documentHighlightsAtPositionCount(3, ["file1.ts"]); - -goTo.marker("2"); -verify.documentHighlightsAtPositionCount(2, ["file1.ts"]); - -goTo.marker("3"); -verify.documentHighlightsAtPositionCount(3, ["file1.ts"]); - -goTo.marker("4"); -verify.documentHighlightsAtPositionCount(3, ["file1.ts"]); \ No newline at end of file +verify.rangesWithSameTextAreDocumentHighlights(); diff --git a/tests/cases/fourslash/documentHighlightAtInheritedProperties6.ts b/tests/cases/fourslash/documentHighlightAtInheritedProperties6.ts index 8f1089e567d..6eb7ae16723 100644 --- a/tests/cases/fourslash/documentHighlightAtInheritedProperties6.ts +++ b/tests/cases/fourslash/documentHighlightAtInheritedProperties6.ts @@ -2,29 +2,20 @@ // @Filename: file1.ts //// class C extends D { -//// /*0*/prop0: string; -//// /*1*/prop1: string; +//// [|prop0|]: string; +//// [|prop1|]: string; //// } -//// +//// //// class D extends C { -//// /*2*/prop0: string; -//// /*3*/prop1: string; +//// [|prop0|]: string; +//// [|prop1|]: string; //// } -//// +//// //// var d: D; -//// d./*4*/prop1; +//// d.[|prop1|]; -goTo.marker("0"); -verify.documentHighlightsAtPositionCount(1, ["file1.ts"]); - -goTo.marker("1"); -verify.documentHighlightsAtPositionCount(1, ["file1.ts"]); - -goTo.marker("2"); -verify.documentHighlightsAtPositionCount(1, ["file1.ts"]); - -goTo.marker("3"); -verify.documentHighlightsAtPositionCount(2, ["file1.ts"]); - -goTo.marker("4"); -verify.documentHighlightsAtPositionCount(2, ["file1.ts"]); \ No newline at end of file +const [Cprop0, Cprop1, Dprop0, Dprop1, prop1Use] = test.ranges(); +verify.rangesAreDocumentHighlights([Cprop0]); +verify.rangesAreDocumentHighlights([Dprop0]); +verify.rangesAreDocumentHighlights([Cprop1]); +verify.rangesAreDocumentHighlights([Dprop1, prop1Use]); diff --git a/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration1.ts b/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration1.ts index aeccd252fe9..219ea427b9c 100644 --- a/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration1.ts +++ b/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration1.ts @@ -2,23 +2,19 @@ // @Filename: file1.ts //// class Foo { -//// constructor(private /*0*/privateParam: number, -//// public /*1*/publicParam: string, -//// protected /*2*/protectedParam: boolean) { -//// -//// let localPrivate = /*3*/privateParam; -//// this./*4*/privateParam += 10; -//// -//// let localPublic = /*5*/publicParam; -//// this./*6*/publicParam += " Hello!"; -//// -//// let localProtected = /*7*/protectedParam; -//// this./*8*/protectedParam = false; +//// constructor(private [|privateParam|]: number, +//// public [|publicParam|]: string, +//// protected [|protectedParam|]: boolean) { +//// +//// let localPrivate = [|privateParam|]; +//// this.[|privateParam|] += 10; +//// +//// let localPublic = [|publicParam|]; +//// this.[|publicParam|] += " Hello!"; +//// +//// let localProtected = [|protectedParam|]; +//// this.[|protectedParam|] = false; //// } //// } -let markers = test.markers() -for (let marker of markers) { - goTo.position(marker.position); - verify.documentHighlightsAtPositionCount(3, ["file1.ts"]); -} \ No newline at end of file +verify.rangesWithSameTextAreDocumentHighlights(); diff --git a/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration2.ts b/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration2.ts index f5d6764205b..199f59fc8a3 100644 --- a/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration2.ts +++ b/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration2.ts @@ -2,23 +2,20 @@ // @Filename: file1.ts //// class Foo { -//// constructor(private {/*0*/privateParam}: number, -//// public {/*1*/publicParam}: string, -//// protected {/*2*/protectedParam}: boolean) { -//// -//// let localPrivate = /*3*/privateParam; -//// this.privateParam += 10; // this is not valid syntax -//// -//// let localPublic = /*4*/publicParam; -//// this.publicParam += " Hello!"; // this is not valid syntax -//// -//// let localProtected = /*5*/protectedParam; -//// this.protectedParam = false; // this is not valid syntax +//// // This is not valid syntax: parameter property can't be binding pattern +//// constructor(private {[|privateParam|]}: number, +//// public {[|publicParam|]}: string, +//// protected {[|protectedParam|]}: boolean) { +//// +//// let localPrivate = [|privateParam|]; +//// this.privateParam += 10; +//// +//// let localPublic = [|publicParam|]; +//// this.publicParam += " Hello!"; +//// +//// let localProtected = [|protectedParam|]; +//// this.protectedParam = false; //// } //// } -let markers = test.markers() -for (let marker of markers) { - goTo.position(marker.position); - verify.documentHighlightsAtPositionCount(2, ["file1.ts"]); -} \ No newline at end of file +verify.rangesWithSameTextAreDocumentHighlights(); diff --git a/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration3.ts b/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration3.ts index 958e3bb45c9..7bcd44a5425 100644 --- a/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration3.ts +++ b/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration3.ts @@ -2,23 +2,20 @@ // @Filename: file1.ts //// class Foo { -//// constructor(private [/*0*/privateParam]: number, -//// public [/*1*/publicParam]: string, -//// protected [/*2*/protectedParam]: boolean) { -//// -//// let localPrivate = /*3*/privateParam; -//// this.privateParam += 10; // this is not valid syntax -//// -//// let localPublic = /*4*/publicParam; -//// this.publicParam += " Hello!"; // this is not valid syntax -//// -//// let localProtected = /*5*/protectedParam; -//// this.protectedParam = false; // this is not valid syntax +//// // This is not valid syntax: parameter property can't be binding pattern +//// constructor(private [[|privateParam|]]: number, +//// public [[|publicParam|]]: string, +//// protected [[|protectedParam|]]: boolean) { +//// +//// let localPrivate = [|privateParam|]; +//// this.privateParam += 10; +//// +//// let localPublic = [|publicParam|]; +//// this.publicParam += " Hello!"; +//// +//// let localProtected = [|protectedParam|]; +//// this.protectedParam = false; //// } //// } -let markers = test.markers() -for (let marker of markers) { - goTo.position(marker.position); - verify.documentHighlightsAtPositionCount(2, ["file1.ts"]); -} \ No newline at end of file +verify.rangesWithSameTextAreDocumentHighlights(); diff --git a/tests/cases/fourslash/findAllRefsForDefaultExport.ts b/tests/cases/fourslash/findAllRefsForDefaultExport.ts new file mode 100644 index 00000000000..a27227b907a --- /dev/null +++ b/tests/cases/fourslash/findAllRefsForDefaultExport.ts @@ -0,0 +1,11 @@ +/// + +// @Filename: a.ts +////export default function /*def*/[|f|]() {} + +// @Filename: b.ts +////import [|g|] from "./a"; +/////*ref*/[|g|](); + +verify.rangesReferenceEachOther(); +verify.goToDefinition("ref", "def"); diff --git a/tests/cases/fourslash/findAllRefsForMappedType.ts b/tests/cases/fourslash/findAllRefsForMappedType.ts new file mode 100644 index 00000000000..38fb3a226c6 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsForMappedType.ts @@ -0,0 +1,9 @@ +/// + +////interface T { [|a|]: number }; +////type U = { [K in keyof T]: string }; +////type V = { [K in keyof U]: boolean }; +////const u: U = { [|a|]: "" } +////const v: V = { [|a|]: true } + +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsForRest.ts b/tests/cases/fourslash/findAllRefsForRest.ts index c3a970e9e73..65d6a3c60e3 100644 --- a/tests/cases/fourslash/findAllRefsForRest.ts +++ b/tests/cases/fourslash/findAllRefsForRest.ts @@ -7,6 +7,5 @@ ////let t: Gen; ////var { x, ...rest } = t; ////rest.[|parent|]; -const ranges = test.ranges(); -verify.referencesOf(ranges[0], ranges); -verify.referencesOf(ranges[1], ranges); + +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsPrimitive.ts b/tests/cases/fourslash/findAllRefsPrimitive.ts new file mode 100644 index 00000000000..51c463843e1 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsPrimitive.ts @@ -0,0 +1,31 @@ +// @noLib: true + +/// + +// @Filename: a.ts +////const x: [|any|] = 0; +////const any = 2; +////const y: [|any|] = any; + +////function f(b: [|boolean|]): [|boolean|]; + +////type T = [|never|]; type U = [|never|]; + +////function n(x: [|number|]): [|number|]; + +////function o(x: [|object|]): [|object|]; + +////function s(x: [|string|]): [|string|]; + +////function sy(s: [|symbol|]): [|symbol|]; + +////function v(v: [|void|]): [|void|]; + +// @Filename: b.ts +// const z: [|any|] = 0; + +verify.rangesWithSameTextReferenceEachOther(); +verify.rangesWithSameTextAreDocumentHighlights(); + +goTo.rangeStart(test.ranges()[0]); +verify.renameInfoFailed(); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 0de303238f1..6685bbc19c0 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -43,6 +43,16 @@ // TODO: figure out a better solution to the API exposure problem. declare module ts { + export type MapKey = string | number; + export interface Map { + forEach(action: (value: T, key: string) => void): void; + get(key: MapKey): T; + has(key: MapKey): boolean; + set(key: MapKey, value: T): this; + delete(key: MapKey): boolean; + clear(): void; + } + interface SymbolDisplayPart { text: string; kind: string; @@ -103,11 +113,14 @@ declare namespace FourSlashInterface { markerNames(): string[]; marker(name?: string): Marker; ranges(): Range[]; - rangesByText(): { [text: string]: Range[] }; + rangesByText(): ts.Map; markerByName(s: string): Marker; } class goTo { - marker(name?: string): void; + marker(name?: string | Marker): void; + eachMarker(action: () => void): void; + rangeStart(range: Range): void; + eachRange(action: () => void): void; bof(): void; eof(): void; implementation(): void; @@ -181,6 +194,8 @@ declare namespace FourSlashInterface { * `start` should be included in `references`. */ referencesOf(start: Range, references: Range[]): void; + rangesAreOccurrences(isWriteAccess?: boolean): void; + rangesAreRenameLocations(findInStrings?: boolean, findInComments?: boolean): void; /** * Performs `referencesOf` for every range on the whole set. * If `ranges` is omitted, this is `test.ranges()`. @@ -219,8 +234,8 @@ declare namespace FourSlashInterface { navigationItemsListContains(name: string, kind: string, searchValue: string, matchKind: string, fileName?: string, parentName?: string): void; occurrencesAtPositionContains(range: Range, isWriteAccess?: boolean): void; occurrencesAtPositionCount(expectedCount: number): void; - documentHighlightsAtPositionContains(range: Range, fileNamesToSearch: string[], kind?: string): void; - documentHighlightsAtPositionCount(expectedCount: number, fileNamesToSearch: string[]): void; + rangesAreDocumentHighlights(ranges?: Range[]): void; + rangesWithSameTextAreDocumentHighlights(): void; completionEntryDetailIs(entryName: string, text: string, documentation?: string, kind?: string): void; /** * This method *requires* a contiguous, complete, and ordered stream of classifications for a file. diff --git a/tests/cases/fourslash/getOccurrencesAbstract01.ts b/tests/cases/fourslash/getOccurrencesAbstract01.ts index 3e48ba4841a..b2ccc815e05 100644 --- a/tests/cases/fourslash/getOccurrencesAbstract01.ts +++ b/tests/cases/fourslash/getOccurrencesAbstract01.ts @@ -12,13 +12,4 @@ //// abstract bar(): void; ////} -const ranges = test.ranges(); - -for (let r of ranges) { - goTo.position(r.start); - verify.occurrencesAtPositionCount(ranges.length); - - for (let range of ranges) { - verify.occurrencesAtPositionContains(range, false); - } -} +verify.rangesAreOccurrences(false); \ No newline at end of file diff --git a/tests/cases/fourslash/getOccurrencesAbstract02.ts b/tests/cases/fourslash/getOccurrencesAbstract02.ts index 8daafdbdc8e..1decdaaf69c 100644 --- a/tests/cases/fourslash/getOccurrencesAbstract02.ts +++ b/tests/cases/fourslash/getOccurrencesAbstract02.ts @@ -11,16 +11,7 @@ //// abstract bar(): void; ////} -const ranges = test.ranges(); - -for (let r of ranges) { - goTo.position(r.start); - verify.occurrencesAtPositionCount(ranges.length); - - for (let range of ranges) { - verify.occurrencesAtPositionContains(range, false); - } -} +verify.rangesAreOccurrences(false); goTo.marker("1"); verify.occurrencesAtPositionCount(0); diff --git a/tests/cases/fourslash/getOccurrencesClassExpressionConstructor.ts b/tests/cases/fourslash/getOccurrencesClassExpressionConstructor.ts index 5fa778ef8cd..d092c1dfd92 100644 --- a/tests/cases/fourslash/getOccurrencesClassExpressionConstructor.ts +++ b/tests/cases/fourslash/getOccurrencesClassExpressionConstructor.ts @@ -13,11 +13,4 @@ //// } ////} -const ranges = test.ranges(); -for (let r of ranges) { - goTo.position(r.start); - - for (let range of ranges) { - verify.occurrencesAtPositionContains(range, false); - } -} +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesClassExpressionPrivate.ts b/tests/cases/fourslash/getOccurrencesClassExpressionPrivate.ts index b008ec237b8..2bc18d2eb25 100644 --- a/tests/cases/fourslash/getOccurrencesClassExpressionPrivate.ts +++ b/tests/cases/fourslash/getOccurrencesClassExpressionPrivate.ts @@ -17,11 +17,4 @@ //// public test2() {} ////} -const ranges = test.ranges(); -for (let r of ranges) { - goTo.position(r.start); - - for (let range of ranges) { - verify.occurrencesAtPositionContains(range, false); - } -} +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesClassExpressionPublic.ts b/tests/cases/fourslash/getOccurrencesClassExpressionPublic.ts index 3070fd4f6ca..c54dbd289e0 100644 --- a/tests/cases/fourslash/getOccurrencesClassExpressionPublic.ts +++ b/tests/cases/fourslash/getOccurrencesClassExpressionPublic.ts @@ -17,11 +17,4 @@ //// public test2() {} ////} -const ranges = test.ranges(); -for (let r of ranges) { - goTo.position(r.start); - - for (let range of ranges) { - verify.occurrencesAtPositionContains(range, false); - } -} +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesClassExpressionStatic.ts b/tests/cases/fourslash/getOccurrencesClassExpressionStatic.ts index 567c0c4eccd..d4851ad86ef 100644 --- a/tests/cases/fourslash/getOccurrencesClassExpressionStatic.ts +++ b/tests/cases/fourslash/getOccurrencesClassExpressionStatic.ts @@ -1,7 +1,7 @@ /// ////let A = class Foo { -//// public static foo; +//// public [|static|] foo; //// [|static|] a; //// constructor(public y: string, private x: string) { //// } @@ -19,11 +19,4 @@ //// public static test2() {} ////} -const ranges = test.ranges(); -for (let r of ranges) { - goTo.position(r.start); - - for (let range of ranges) { - verify.occurrencesAtPositionContains(range, false); - } -} +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesClassExpressionStaticThis.ts b/tests/cases/fourslash/getOccurrencesClassExpressionStaticThis.ts index 5444ab9acdd..53c1a69bead 100644 --- a/tests/cases/fourslash/getOccurrencesClassExpressionStaticThis.ts +++ b/tests/cases/fourslash/getOccurrencesClassExpressionStaticThis.ts @@ -46,11 +46,4 @@ //// } ////} -const ranges = test.ranges(); -for (let r of ranges) { - goTo.position(r.start); - - for (let range of ranges) { - verify.occurrencesAtPositionContains(range, false); - } -} +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesClassExpressionThis.ts b/tests/cases/fourslash/getOccurrencesClassExpressionThis.ts index ed8f8cb1d0e..d1331e54a43 100644 --- a/tests/cases/fourslash/getOccurrencesClassExpressionThis.ts +++ b/tests/cases/fourslash/getOccurrencesClassExpressionThis.ts @@ -44,11 +44,4 @@ //// } ////} -const ranges = test.ranges(); -for (let r of ranges) { - goTo.position(r.start); - - for (let range of ranges) { - verify.occurrencesAtPositionContains(range, false); - } -} +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesConst02.ts b/tests/cases/fourslash/getOccurrencesConst02.ts index 0dc96fcca6c..57d75f88e22 100644 --- a/tests/cases/fourslash/getOccurrencesConst02.ts +++ b/tests/cases/fourslash/getOccurrencesConst02.ts @@ -10,7 +10,4 @@ ////declare [|const|] enum E { ////} -test.ranges().forEach(range => { - goTo.position(range.start); - verify.occurrencesAtPositionCount(0); -}); \ No newline at end of file +goTo.eachRange(() => verify.occurrencesAtPositionCount(0)); diff --git a/tests/cases/fourslash/getOccurrencesConst03.ts b/tests/cases/fourslash/getOccurrencesConst03.ts index 404ff655044..a86481ed72a 100644 --- a/tests/cases/fourslash/getOccurrencesConst03.ts +++ b/tests/cases/fourslash/getOccurrencesConst03.ts @@ -10,7 +10,4 @@ ////export [|const|] enum E { ////} -test.ranges().forEach(range => { - goTo.position(range.start); - verify.occurrencesAtPositionCount(0); -}); \ No newline at end of file +goTo.eachRange(() => verify.occurrencesAtPositionCount(0)); \ No newline at end of file diff --git a/tests/cases/fourslash/getOccurrencesConstructor.ts b/tests/cases/fourslash/getOccurrencesConstructor.ts index 0a6b84a5770..41d72c533a3 100644 --- a/tests/cases/fourslash/getOccurrencesConstructor.ts +++ b/tests/cases/fourslash/getOccurrencesConstructor.ts @@ -18,15 +18,9 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesConstructor2.ts b/tests/cases/fourslash/getOccurrencesConstructor2.ts index 049c25b7f52..b34ffa4a190 100644 --- a/tests/cases/fourslash/getOccurrencesConstructor2.ts +++ b/tests/cases/fourslash/getOccurrencesConstructor2.ts @@ -18,15 +18,9 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesDeclare1.ts b/tests/cases/fourslash/getOccurrencesDeclare1.ts index 4207a92b5a6..96114d3fc9d 100644 --- a/tests/cases/fourslash/getOccurrencesDeclare1.ts +++ b/tests/cases/fourslash/getOccurrencesDeclare1.ts @@ -53,11 +53,4 @@ //// [|declare|] function foo(): string; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesDeclare2.ts b/tests/cases/fourslash/getOccurrencesDeclare2.ts index 3d719e5d035..78028d94996 100644 --- a/tests/cases/fourslash/getOccurrencesDeclare2.ts +++ b/tests/cases/fourslash/getOccurrencesDeclare2.ts @@ -54,11 +54,4 @@ //// declare function foo(): string; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesDeclare3.ts b/tests/cases/fourslash/getOccurrencesDeclare3.ts index 2dee0af4b14..8c1bf7e9658 100644 --- a/tests/cases/fourslash/getOccurrencesDeclare3.ts +++ b/tests/cases/fourslash/getOccurrencesDeclare3.ts @@ -61,11 +61,4 @@ ////[|declare|] module dm { } ////export class EC { } -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesExport1.ts b/tests/cases/fourslash/getOccurrencesExport1.ts index bc82e8a1bea..71202a820a7 100644 --- a/tests/cases/fourslash/getOccurrencesExport1.ts +++ b/tests/cases/fourslash/getOccurrencesExport1.ts @@ -53,11 +53,4 @@ //// declare function foo(): string; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesExport2.ts b/tests/cases/fourslash/getOccurrencesExport2.ts index a8e43e744b9..442642d77ec 100644 --- a/tests/cases/fourslash/getOccurrencesExport2.ts +++ b/tests/cases/fourslash/getOccurrencesExport2.ts @@ -54,11 +54,4 @@ //// declare function foo(): string; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesExport3.ts b/tests/cases/fourslash/getOccurrencesExport3.ts index 215cbf8f48a..04ee55bb1e6 100644 --- a/tests/cases/fourslash/getOccurrencesExport3.ts +++ b/tests/cases/fourslash/getOccurrencesExport3.ts @@ -61,11 +61,4 @@ ////declare module dm { } ////[|export|] class EC { } -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesIfElse.ts b/tests/cases/fourslash/getOccurrencesIfElse.ts index 96c70d404ab..9251a59d130 100644 --- a/tests/cases/fourslash/getOccurrencesIfElse.ts +++ b/tests/cases/fourslash/getOccurrencesIfElse.ts @@ -22,15 +22,9 @@ ////} ////[|else|] { } -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesIfElse2.ts b/tests/cases/fourslash/getOccurrencesIfElse2.ts index 012e7a96efd..df77687aac6 100644 --- a/tests/cases/fourslash/getOccurrencesIfElse2.ts +++ b/tests/cases/fourslash/getOccurrencesIfElse2.ts @@ -22,11 +22,4 @@ ////} ////else { } - -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); \ No newline at end of file +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesIfElse3.ts b/tests/cases/fourslash/getOccurrencesIfElse3.ts index b0ca3615648..aec1a6911af 100644 --- a/tests/cases/fourslash/getOccurrencesIfElse3.ts +++ b/tests/cases/fourslash/getOccurrencesIfElse3.ts @@ -22,11 +22,4 @@ ////} ////else { } - -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); \ No newline at end of file +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesIfElseBroken.ts b/tests/cases/fourslash/getOccurrencesIfElseBroken.ts index a9e1e94f42d..c5460b3e634 100644 --- a/tests/cases/fourslash/getOccurrencesIfElseBroken.ts +++ b/tests/cases/fourslash/getOccurrencesIfElseBroken.ts @@ -12,13 +12,7 @@ // It would be nice if in the future, // We could include that last 'else'. -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); verify.occurrencesAtPositionCount(2); \ No newline at end of file diff --git a/tests/cases/fourslash/getOccurrencesIsWriteAccess.ts b/tests/cases/fourslash/getOccurrencesIsWriteAccess.ts index 1ba4c39041c..e31b199217f 100644 --- a/tests/cases/fourslash/getOccurrencesIsWriteAccess.ts +++ b/tests/cases/fourslash/getOccurrencesIsWriteAccess.ts @@ -18,10 +18,8 @@ ////[|{| "isWriteAccess": true |}x|] += 1; ////[|{| "isWriteAccess": true |}x|] <<= 1; +goTo.rangeStart(test.ranges()[0]); -var firstRange = test.ranges()[0]; -goTo.position(firstRange.start, firstRange.fileName); - -test.ranges().forEach((range) => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, range.marker.data.isWriteAccess); -}); +} diff --git a/tests/cases/fourslash/getOccurrencesLoopBreakContinue.ts b/tests/cases/fourslash/getOccurrencesLoopBreakContinue.ts index 81aaaed5c58..88621cd4cf4 100644 --- a/tests/cases/fourslash/getOccurrencesLoopBreakContinue.ts +++ b/tests/cases/fourslash/getOccurrencesLoopBreakContinue.ts @@ -46,7 +46,7 @@ //// default: //// continue; //// } -//// +//// //// // these cross function boundaries //// break label1; //// continue label1; @@ -63,17 +63,10 @@ //// ////label7: while (true) continue label5; -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); verify.occurrencesAtPositionCount(test.ranges().length); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesLoopBreakContinue2.ts b/tests/cases/fourslash/getOccurrencesLoopBreakContinue2.ts index 51d4d89b657..225346f8077 100644 --- a/tests/cases/fourslash/getOccurrencesLoopBreakContinue2.ts +++ b/tests/cases/fourslash/getOccurrencesLoopBreakContinue2.ts @@ -46,7 +46,7 @@ //// default: //// continue; //// } -//// +//// //// // these cross function boundaries //// break label1; //// continue label1; @@ -63,17 +63,10 @@ //// ////label7: while (true) continue label5; -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); verify.occurrencesAtPositionCount(test.ranges().length); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesLoopBreakContinue3.ts b/tests/cases/fourslash/getOccurrencesLoopBreakContinue3.ts index 8777c912afd..c1aeef315f9 100644 --- a/tests/cases/fourslash/getOccurrencesLoopBreakContinue3.ts +++ b/tests/cases/fourslash/getOccurrencesLoopBreakContinue3.ts @@ -46,7 +46,7 @@ //// default: //// continue; //// } -//// +//// //// // these cross function boundaries //// break label1; //// continue label1; @@ -63,16 +63,9 @@ //// ////label7: while (true) continue label5; -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesLoopBreakContinue4.ts b/tests/cases/fourslash/getOccurrencesLoopBreakContinue4.ts index 1bca62ba013..b183b2b3fde 100644 --- a/tests/cases/fourslash/getOccurrencesLoopBreakContinue4.ts +++ b/tests/cases/fourslash/getOccurrencesLoopBreakContinue4.ts @@ -46,7 +46,7 @@ //// default: //// [|continue|]; //// } -//// +//// //// // these cross function boundaries //// break label1; //// continue label1; @@ -63,17 +63,10 @@ //// ////label7: while (true) continue label5; -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); verify.occurrencesAtPositionCount(test.ranges().length); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesLoopBreakContinue5.ts b/tests/cases/fourslash/getOccurrencesLoopBreakContinue5.ts index f4e62c554e4..3353d6c96dc 100644 --- a/tests/cases/fourslash/getOccurrencesLoopBreakContinue5.ts +++ b/tests/cases/fourslash/getOccurrencesLoopBreakContinue5.ts @@ -46,7 +46,7 @@ //// default: //// continue; //// } -//// +//// //// // these cross function boundaries //// break label1; //// continue label1; @@ -63,17 +63,10 @@ //// ////label7: while (true) continue label5; -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); verify.occurrencesAtPositionCount(test.ranges().length); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesLoopBreakContinue6.ts b/tests/cases/fourslash/getOccurrencesLoopBreakContinue6.ts index 0127245dd50..957f8c4af01 100644 --- a/tests/cases/fourslash/getOccurrencesLoopBreakContinue6.ts +++ b/tests/cases/fourslash/getOccurrencesLoopBreakContinue6.ts @@ -46,7 +46,7 @@ //// default: //// continue; //// } -//// +//// //// // these cross function boundaries //// br/*5*/eak label1; //// co/*6*/ntinue label1; @@ -63,8 +63,4 @@ //// ////label7: while (true) co/*10*/ntinue label5; -test.markers().forEach(m => { - goTo.position(m.position); - - verify.occurrencesAtPositionCount(0); -}); +goTo.eachMarker(() => verify.occurrencesAtPositionCount(0)); diff --git a/tests/cases/fourslash/getOccurrencesLoopBreakContinueNegatives.ts b/tests/cases/fourslash/getOccurrencesLoopBreakContinueNegatives.ts index 0127245dd50..957f8c4af01 100644 --- a/tests/cases/fourslash/getOccurrencesLoopBreakContinueNegatives.ts +++ b/tests/cases/fourslash/getOccurrencesLoopBreakContinueNegatives.ts @@ -46,7 +46,7 @@ //// default: //// continue; //// } -//// +//// //// // these cross function boundaries //// br/*5*/eak label1; //// co/*6*/ntinue label1; @@ -63,8 +63,4 @@ //// ////label7: while (true) co/*10*/ntinue label5; -test.markers().forEach(m => { - goTo.position(m.position); - - verify.occurrencesAtPositionCount(0); -}); +goTo.eachMarker(() => verify.occurrencesAtPositionCount(0)); diff --git a/tests/cases/fourslash/getOccurrencesModifiersNegatives1.ts b/tests/cases/fourslash/getOccurrencesModifiersNegatives1.ts index 51d5907a5d6..836d87fa9be 100644 --- a/tests/cases/fourslash/getOccurrencesModifiersNegatives1.ts +++ b/tests/cases/fourslash/getOccurrencesModifiersNegatives1.ts @@ -34,8 +34,4 @@ ////[|public|] [|static|] [|protected|] [|private|] f; ////[|protected|] [|static|] [|public|] g; - -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(0); -}); +goTo.eachRange(() => verify.occurrencesAtPositionCount(0)); diff --git a/tests/cases/fourslash/getOccurrencesOfAnonymousFunction.ts b/tests/cases/fourslash/getOccurrencesOfAnonymousFunction.ts index 96354df6b05..8ce60b21306 100644 --- a/tests/cases/fourslash/getOccurrencesOfAnonymousFunction.ts +++ b/tests/cases/fourslash/getOccurrencesOfAnonymousFunction.ts @@ -5,12 +5,4 @@ //// return 0; ////}) - -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(2); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range); - }); -}); \ No newline at end of file +verify.rangesAreOccurrences(); diff --git a/tests/cases/fourslash/getOccurrencesOfAny.ts b/tests/cases/fourslash/getOccurrencesOfAny.ts deleted file mode 100644 index c28dd83b422..00000000000 --- a/tests/cases/fourslash/getOccurrencesOfAny.ts +++ /dev/null @@ -1,12 +0,0 @@ -/// - -////var obj1: { -//// (bar: any): any; -//// new (bar: any): any; -//// [bar: any]: any; -//// bar: any; -//// foob(bar: any): an/**/y; -////}; - -goTo.marker(); -verify.occurrencesAtPositionCount(0); diff --git a/tests/cases/fourslash/getOccurrencesPrivate1.ts b/tests/cases/fourslash/getOccurrencesPrivate1.ts index 991ed3ea31c..bb601451507 100644 --- a/tests/cases/fourslash/getOccurrencesPrivate1.ts +++ b/tests/cases/fourslash/getOccurrencesPrivate1.ts @@ -54,11 +54,4 @@ //// declare function foo(): string; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesPrivate2.ts b/tests/cases/fourslash/getOccurrencesPrivate2.ts index 19397443af5..914db1a15a9 100644 --- a/tests/cases/fourslash/getOccurrencesPrivate2.ts +++ b/tests/cases/fourslash/getOccurrencesPrivate2.ts @@ -54,11 +54,4 @@ //// declare function foo(): string; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesPropertyInAliasedInterface.ts b/tests/cases/fourslash/getOccurrencesPropertyInAliasedInterface.ts index 87ec260601b..3a9078cfc63 100644 --- a/tests/cases/fourslash/getOccurrencesPropertyInAliasedInterface.ts +++ b/tests/cases/fourslash/getOccurrencesPropertyInAliasedInterface.ts @@ -15,11 +15,5 @@ ////} //// ////(new C()).[|abc|]; -test.ranges().forEach(r => { - goTo.position(r.start); - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range); - }); - verify.occurrencesAtPositionCount(test.ranges().length); -}); \ No newline at end of file +verify.rangesAreOccurrences(); diff --git a/tests/cases/fourslash/getOccurrencesProtected1.ts b/tests/cases/fourslash/getOccurrencesProtected1.ts index af9e3302968..b5b3442ec00 100644 --- a/tests/cases/fourslash/getOccurrencesProtected1.ts +++ b/tests/cases/fourslash/getOccurrencesProtected1.ts @@ -54,11 +54,4 @@ //// declare function foo(): string; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesProtected2.ts b/tests/cases/fourslash/getOccurrencesProtected2.ts index 666736eee16..365d78dc9f6 100644 --- a/tests/cases/fourslash/getOccurrencesProtected2.ts +++ b/tests/cases/fourslash/getOccurrencesProtected2.ts @@ -54,11 +54,4 @@ //// declare function foo(): string; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesPublic1.ts b/tests/cases/fourslash/getOccurrencesPublic1.ts index a451a70c1cb..1ecc816dac5 100644 --- a/tests/cases/fourslash/getOccurrencesPublic1.ts +++ b/tests/cases/fourslash/getOccurrencesPublic1.ts @@ -54,11 +54,4 @@ //// declare function foo(): string; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesPublic2.ts b/tests/cases/fourslash/getOccurrencesPublic2.ts index b4887e18e80..6d5b4e53c0e 100644 --- a/tests/cases/fourslash/getOccurrencesPublic2.ts +++ b/tests/cases/fourslash/getOccurrencesPublic2.ts @@ -54,11 +54,4 @@ //// declare function foo(): string; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesReturn.ts b/tests/cases/fourslash/getOccurrencesReturn.ts index 613e1645fb5..44b3679ba2e 100644 --- a/tests/cases/fourslash/getOccurrencesReturn.ts +++ b/tests/cases/fourslash/getOccurrencesReturn.ts @@ -19,15 +19,9 @@ //// [|return|] true; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesReturn2.ts b/tests/cases/fourslash/getOccurrencesReturn2.ts index 15a062433fe..750648838a2 100644 --- a/tests/cases/fourslash/getOccurrencesReturn2.ts +++ b/tests/cases/fourslash/getOccurrencesReturn2.ts @@ -19,15 +19,9 @@ //// return true; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesReturn3.ts b/tests/cases/fourslash/getOccurrencesReturn3.ts index 030d700ef6e..ee739efef39 100644 --- a/tests/cases/fourslash/getOccurrencesReturn3.ts +++ b/tests/cases/fourslash/getOccurrencesReturn3.ts @@ -19,10 +19,4 @@ //// return true; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); \ No newline at end of file +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesReturnBroken.ts b/tests/cases/fourslash/getOccurrencesReturnBroken.ts index 2327a62d12c..c8d7fad0635 100644 --- a/tests/cases/fourslash/getOccurrencesReturnBroken.ts +++ b/tests/cases/fourslash/getOccurrencesReturnBroken.ts @@ -26,17 +26,11 @@ //// r/*4*/eturn 8675309; ////} -// Note: For this test, these 'return's get highlighted as a result of a parse recovery +// Note: For this test, these 'return's get highlighted as a result of a parse recovery // where if an arrow function starts with a statement, we try to parse a body // as if it was missing curly braces. If the behavior changes in the future, // a change to this test is very much welcome. -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); for (var i = 1; i <= test.markers().length; i++) { goTo.marker("" + i); diff --git a/tests/cases/fourslash/getOccurrencesSetAndGet.ts b/tests/cases/fourslash/getOccurrencesSetAndGet.ts index ddeaf8f26ff..2d28328800c 100644 --- a/tests/cases/fourslash/getOccurrencesSetAndGet.ts +++ b/tests/cases/fourslash/getOccurrencesSetAndGet.ts @@ -23,12 +23,4 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); - - verify.occurrencesAtPositionCount(test.ranges().length); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesSetAndGet2.ts b/tests/cases/fourslash/getOccurrencesSetAndGet2.ts index 3e05f511efc..541efc80509 100644 --- a/tests/cases/fourslash/getOccurrencesSetAndGet2.ts +++ b/tests/cases/fourslash/getOccurrencesSetAndGet2.ts @@ -23,12 +23,4 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); - - verify.occurrencesAtPositionCount(test.ranges().length); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesSetAndGet3.ts b/tests/cases/fourslash/getOccurrencesSetAndGet3.ts index 777a62db6a5..32c4d72c1a5 100644 --- a/tests/cases/fourslash/getOccurrencesSetAndGet3.ts +++ b/tests/cases/fourslash/getOccurrencesSetAndGet3.ts @@ -23,12 +23,4 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); - - verify.occurrencesAtPositionCount(test.ranges().length); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesStatic1.ts b/tests/cases/fourslash/getOccurrencesStatic1.ts index 8be9862d5ec..d853f16017d 100644 --- a/tests/cases/fourslash/getOccurrencesStatic1.ts +++ b/tests/cases/fourslash/getOccurrencesStatic1.ts @@ -54,11 +54,4 @@ //// declare function foo(): string; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesStringLiteralTypes.ts b/tests/cases/fourslash/getOccurrencesStringLiteralTypes.ts index 56af87497d5..a115ee82211 100644 --- a/tests/cases/fourslash/getOccurrencesStringLiteralTypes.ts +++ b/tests/cases/fourslash/getOccurrencesStringLiteralTypes.ts @@ -3,11 +3,4 @@ ////function foo(a: "[|option 1|]") { } ////foo("[|option 1|]"); -const ranges = test.ranges(); -for (let r of ranges) { - goTo.position(r.start); - - for (let range of ranges) { - verify.occurrencesAtPositionContains(range, false); - } -} +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesStringLiterals.ts b/tests/cases/fourslash/getOccurrencesStringLiterals.ts index 827828acd24..cf17481e0eb 100644 --- a/tests/cases/fourslash/getOccurrencesStringLiterals.ts +++ b/tests/cases/fourslash/getOccurrencesStringLiterals.ts @@ -3,8 +3,4 @@ ////var x = "[|string|]"; ////function f(a = "[|initial value|]") { } -const ranges = test.ranges(); -for (let r of ranges) { - goTo.position(r.start); - verify.occurrencesAtPositionCount(1); -} +goTo.eachRange(() => verify.occurrencesAtPositionCount(1)); diff --git a/tests/cases/fourslash/getOccurrencesSuper.ts b/tests/cases/fourslash/getOccurrencesSuper.ts index f53d9aca62e..6f5c51715f3 100644 --- a/tests/cases/fourslash/getOccurrencesSuper.ts +++ b/tests/cases/fourslash/getOccurrencesSuper.ts @@ -27,7 +27,7 @@ //// //// public method3() { //// var x = () => [|super|].superMethod(); -//// +//// //// // Bad but still gets highlighted //// function f() { //// [|super|].superMethod(); @@ -50,15 +50,9 @@ //// static super = 20; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} \ No newline at end of file diff --git a/tests/cases/fourslash/getOccurrencesSuper2.ts b/tests/cases/fourslash/getOccurrencesSuper2.ts index 1392170ae18..2da702acbc6 100644 --- a/tests/cases/fourslash/getOccurrencesSuper2.ts +++ b/tests/cases/fourslash/getOccurrencesSuper2.ts @@ -27,7 +27,7 @@ //// //// public method3() { //// var x = () => super.superMethod(); -//// +//// //// // Bad but still gets highlighted //// function f() { //// super.superMethod(); @@ -50,15 +50,9 @@ //// static super = 20; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} \ No newline at end of file diff --git a/tests/cases/fourslash/getOccurrencesSuper3.ts b/tests/cases/fourslash/getOccurrencesSuper3.ts index bceac02a392..88275975004 100644 --- a/tests/cases/fourslash/getOccurrencesSuper3.ts +++ b/tests/cases/fourslash/getOccurrencesSuper3.ts @@ -14,7 +14,7 @@ ////} function checkRange(r: FourSlashInterface.Range, expectedOccurences: FourSlashInterface.Range[]): void { - goTo.position(r.start); + goTo.rangeStart(r); if (expectedOccurences.length) { for (const expected of expectedOccurences) { verify.occurrencesAtPositionContains(expected); diff --git a/tests/cases/fourslash/getOccurrencesSuperNegatives.ts b/tests/cases/fourslash/getOccurrencesSuperNegatives.ts index 8c76da33c12..e2bb248efc4 100644 --- a/tests/cases/fourslash/getOccurrencesSuperNegatives.ts +++ b/tests/cases/fourslash/getOccurrencesSuperNegatives.ts @@ -20,8 +20,4 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - verify.occurrencesAtPositionCount(0); -}); +goTo.eachRange(() => verify.occurrencesAtPositionCount(0)); diff --git a/tests/cases/fourslash/getOccurrencesSwitchCaseDefault.ts b/tests/cases/fourslash/getOccurrencesSwitchCaseDefault.ts index f32ff0e8f82..34f9ebcd112 100644 --- a/tests/cases/fourslash/getOccurrencesSwitchCaseDefault.ts +++ b/tests/cases/fourslash/getOccurrencesSwitchCaseDefault.ts @@ -18,12 +18,4 @@ //// [|case|] 16: ////} - -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesSwitchCaseDefault2.ts b/tests/cases/fourslash/getOccurrencesSwitchCaseDefault2.ts index dd4577faa1f..1f265f079f8 100644 --- a/tests/cases/fourslash/getOccurrencesSwitchCaseDefault2.ts +++ b/tests/cases/fourslash/getOccurrencesSwitchCaseDefault2.ts @@ -18,12 +18,4 @@ //// case 16: ////} - -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesSwitchCaseDefault3.ts b/tests/cases/fourslash/getOccurrencesSwitchCaseDefault3.ts index 24330ca1912..887e17c2b29 100644 --- a/tests/cases/fourslash/getOccurrencesSwitchCaseDefault3.ts +++ b/tests/cases/fourslash/getOccurrencesSwitchCaseDefault3.ts @@ -16,11 +16,4 @@ //// [|break|]; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesSwitchCaseDefault4.ts b/tests/cases/fourslash/getOccurrencesSwitchCaseDefault4.ts index 039009746dd..38b3fbfc7dd 100644 --- a/tests/cases/fourslash/getOccurrencesSwitchCaseDefault4.ts +++ b/tests/cases/fourslash/getOccurrencesSwitchCaseDefault4.ts @@ -10,16 +10,5 @@ //// contin/*2*/ue foo; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); - -test.markers().forEach(m => { - goTo.position(m.position); - verify.occurrencesAtPositionCount(0); -}); \ No newline at end of file +verify.rangesAreOccurrences(false); +goTo.eachMarker(() => verify.occurrencesAtPositionCount(0)); diff --git a/tests/cases/fourslash/getOccurrencesThis.ts b/tests/cases/fourslash/getOccurrencesThis.ts index e4b059b9cf9..156fde2c4ac 100644 --- a/tests/cases/fourslash/getOccurrencesThis.ts +++ b/tests/cases/fourslash/getOccurrencesThis.ts @@ -89,7 +89,7 @@ //// } //// //// public static staticB = this.staticMethod1; -//// +//// //// public static staticMethod1() { //// this; //// this; @@ -140,15 +140,9 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesThis2.ts b/tests/cases/fourslash/getOccurrencesThis2.ts index 3df30369e3e..9a40eb39fb0 100644 --- a/tests/cases/fourslash/getOccurrencesThis2.ts +++ b/tests/cases/fourslash/getOccurrencesThis2.ts @@ -89,7 +89,7 @@ //// } //// //// public static staticB = this.staticMethod1; -//// +//// //// public static staticMethod1() { //// this; //// this; @@ -140,15 +140,9 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesThis3.ts b/tests/cases/fourslash/getOccurrencesThis3.ts index 7ee18a31286..66c80241e4a 100644 --- a/tests/cases/fourslash/getOccurrencesThis3.ts +++ b/tests/cases/fourslash/getOccurrencesThis3.ts @@ -89,7 +89,7 @@ //// } //// //// public static staticB = this.staticMethod1; -//// +//// //// public static staticMethod1() { //// this; //// this; @@ -140,15 +140,9 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesThis4.ts b/tests/cases/fourslash/getOccurrencesThis4.ts index 75a9383f88e..42ddd7984a8 100644 --- a/tests/cases/fourslash/getOccurrencesThis4.ts +++ b/tests/cases/fourslash/getOccurrencesThis4.ts @@ -89,7 +89,7 @@ //// } //// //// public static staticB = this.staticMethod1; -//// +//// //// public static staticMethod1() { //// this; //// this; @@ -140,15 +140,9 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesThis5.ts b/tests/cases/fourslash/getOccurrencesThis5.ts index 86ce16b16be..845e8342fa5 100644 --- a/tests/cases/fourslash/getOccurrencesThis5.ts +++ b/tests/cases/fourslash/getOccurrencesThis5.ts @@ -89,7 +89,7 @@ //// } //// //// public static staticB = [|this|].staticMethod1; -//// +//// //// public static staticMethod1() { //// [|this|]; //// [|this|]; @@ -140,15 +140,9 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); \ No newline at end of file +} diff --git a/tests/cases/fourslash/getOccurrencesThisNegatives2.ts b/tests/cases/fourslash/getOccurrencesThisNegatives2.ts index 0a8b5860feb..3f840e8311a 100644 --- a/tests/cases/fourslash/getOccurrencesThisNegatives2.ts +++ b/tests/cases/fourslash/getOccurrencesThisNegatives2.ts @@ -89,7 +89,7 @@ //// } //// //// public static staticB = this.staticMethod1; -//// +//// //// public static staticMethod1() { //// this; //// this; @@ -140,8 +140,4 @@ //// } ////} - -test.markers().forEach(m => { - goTo.position(m.position, m.fileName) - verify.occurrencesAtPositionCount(0); -}); +goTo.eachMarker(() => verify.occurrencesAtPositionCount(0)); diff --git a/tests/cases/fourslash/getOccurrencesThrow.ts b/tests/cases/fourslash/getOccurrencesThrow.ts index 19f10dbfb9f..db80e3c51a0 100644 --- a/tests/cases/fourslash/getOccurrencesThrow.ts +++ b/tests/cases/fourslash/getOccurrencesThrow.ts @@ -3,7 +3,7 @@ ////function f(a: number) { //// try { //// throw "Hello"; -//// +//// //// try { //// throw 10; //// } @@ -42,17 +42,9 @@ //// [|throw|] false; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); - - verify.occurrencesAtPositionCount(test.ranges().length); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); +} diff --git a/tests/cases/fourslash/getOccurrencesThrow2.ts b/tests/cases/fourslash/getOccurrencesThrow2.ts index 9bd2f82e638..21425990e2f 100644 --- a/tests/cases/fourslash/getOccurrencesThrow2.ts +++ b/tests/cases/fourslash/getOccurrencesThrow2.ts @@ -3,7 +3,7 @@ ////function f(a: number) { //// try { //// throw "Hello"; -//// +//// //// try { //// [|t/**/hrow|] 10; //// } @@ -42,17 +42,9 @@ //// throw false; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); - - verify.occurrencesAtPositionCount(test.ranges().length); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); +} diff --git a/tests/cases/fourslash/getOccurrencesThrow3.ts b/tests/cases/fourslash/getOccurrencesThrow3.ts index 359b783df07..d601123f7bd 100644 --- a/tests/cases/fourslash/getOccurrencesThrow3.ts +++ b/tests/cases/fourslash/getOccurrencesThrow3.ts @@ -3,7 +3,7 @@ ////function f(a: number) { //// try { //// [|throw|] "Hello"; -//// +//// //// try { //// throw 10; //// } @@ -42,17 +42,9 @@ //// throw false; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); - - verify.occurrencesAtPositionCount(test.ranges().length); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); +} diff --git a/tests/cases/fourslash/getOccurrencesThrow4.ts b/tests/cases/fourslash/getOccurrencesThrow4.ts index ab2375907ee..c348685b4ed 100644 --- a/tests/cases/fourslash/getOccurrencesThrow4.ts +++ b/tests/cases/fourslash/getOccurrencesThrow4.ts @@ -3,7 +3,7 @@ ////function f(a: number) { //// try { //// throw "Hello"; -//// +//// //// try { //// throw 10; //// } @@ -42,17 +42,9 @@ //// throw false; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); - - verify.occurrencesAtPositionCount(test.ranges().length); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); +} diff --git a/tests/cases/fourslash/getOccurrencesThrow5.ts b/tests/cases/fourslash/getOccurrencesThrow5.ts index 9ba28191752..b4b51b677bc 100644 --- a/tests/cases/fourslash/getOccurrencesThrow5.ts +++ b/tests/cases/fourslash/getOccurrencesThrow5.ts @@ -3,7 +3,7 @@ ////function f(a: number) { //// try { //// throw "Hello"; -//// +//// //// try { //// throw 10; //// } @@ -42,17 +42,9 @@ //// throw false; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); - - verify.occurrencesAtPositionCount(test.ranges().length); -}); +verify.rangesAreOccurrences(false); goTo.marker(); -test.ranges().forEach(range => { +for (const range of test.ranges()) { verify.occurrencesAtPositionContains(range, false); -}); +} diff --git a/tests/cases/fourslash/getOccurrencesThrow6.ts b/tests/cases/fourslash/getOccurrencesThrow6.ts index 8b58347ed8a..21509659cd8 100644 --- a/tests/cases/fourslash/getOccurrencesThrow6.ts +++ b/tests/cases/fourslash/getOccurrencesThrow6.ts @@ -14,15 +14,4 @@ //// [|throw|] 300; ////} - - -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); - - verify.occurrencesAtPositionCount(test.ranges().length); -}); - +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesThrow7.ts b/tests/cases/fourslash/getOccurrencesThrow7.ts index 48ab981d762..7a35daeb775 100644 --- a/tests/cases/fourslash/getOccurrencesThrow7.ts +++ b/tests/cases/fourslash/getOccurrencesThrow7.ts @@ -19,13 +19,4 @@ //// ////[|throw|] 10; -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); - - verify.occurrencesAtPositionCount(test.ranges().length); -}); - +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getOccurrencesThrow8.ts b/tests/cases/fourslash/getOccurrencesThrow8.ts index cc527720dc4..0e57520d492 100644 --- a/tests/cases/fourslash/getOccurrencesThrow8.ts +++ b/tests/cases/fourslash/getOccurrencesThrow8.ts @@ -19,13 +19,4 @@ //// ////throw 10; -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.occurrencesAtPositionContains(range, false); - }); - - verify.occurrencesAtPositionCount(test.ranges().length); -}); - +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/getPropertySymbolsFromBaseTypesDoesntCrash.ts b/tests/cases/fourslash/getPropertySymbolsFromBaseTypesDoesntCrash.ts index 0c89de63a43..e141a257f2e 100644 --- a/tests/cases/fourslash/getPropertySymbolsFromBaseTypesDoesntCrash.ts +++ b/tests/cases/fourslash/getPropertySymbolsFromBaseTypesDoesntCrash.ts @@ -2,8 +2,7 @@ // @Filename: file1.ts //// class ClassA implements IInterface { -//// private /*1*/value: number; +//// private [|value|]: number; //// } -goTo.marker("1"); -verify.documentHighlightsAtPositionCount(1, ["file1.ts"]); \ No newline at end of file +verify.rangesAreDocumentHighlights(); 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/goToDefinitionFunctionType.ts b/tests/cases/fourslash/goToDefinitionFunctionType.ts new file mode 100644 index 00000000000..1b50de3af6d --- /dev/null +++ b/tests/cases/fourslash/goToDefinitionFunctionType.ts @@ -0,0 +1,17 @@ +/// + +// Tests that goToDefinition does not go to a function type; it goes to the value. + +////const /*constDefinition*/c: () => void; +/////*constReference*/c(); +////function test(/*cbDefinition*/cb: () => void) { +//// /*cbReference*/cb(); +////} +////class C { +//// /*propDefinition*/prop: () => void; +//// m() { +//// this./*propReference*/prop(); +//// } +////} + +verify.goToDefinitionForMarkers("const", "cb", "prop"); 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/localGetReferences.ts b/tests/cases/fourslash/localGetReferences.ts index b05346a366a..d8e64be1ada 100644 --- a/tests/cases/fourslash/localGetReferences.ts +++ b/tests/cases/fourslash/localGetReferences.ts @@ -3,7 +3,7 @@ // @Filename: localGetReferences_1.ts ////// Comment Refence Test: g/*1*/lobalVar ////// References to a variable declared in global. -////var [|globalVar|]: n/*2*/umber = 2; +////var [|globalVar|]: number = 2; //// ////class fooCls { //// // References to static variable declared in a class. @@ -189,10 +189,6 @@ goTo.marker("1"); verify.referencesAre([]); -// References to type. -goTo.marker("2"); -verify.referencesAre([]); - // References to unresolved symbol. goTo.marker("3"); verify.referencesAre([]); @@ -202,15 +198,14 @@ goTo.marker("4"); verify.referencesAre([]); const rangesByText = test.rangesByText(); -for (const text in rangesByText) { - const ranges = rangesByText[text]; +rangesByText.forEach((ranges, text) => { if (text === "globalVar") { verify.rangesReferenceEachOther(ranges.filter(isShadow)); verify.rangesReferenceEachOther(ranges.filter(r => !isShadow(r))); } else { verify.rangesReferenceEachOther(ranges); } -} +}); function isShadow(r) { return r.marker && r.marker.data && r.marker.data.shadow; diff --git a/tests/cases/fourslash/quickInfoInvalidLocations.ts b/tests/cases/fourslash/quickInfoInvalidLocations.ts index 81845e27672..c70be23f387 100644 --- a/tests/cases/fourslash/quickInfoInvalidLocations.ts +++ b/tests/cases/fourslash/quickInfoInvalidLocations.ts @@ -27,13 +27,13 @@ //// ////mod/*invlaid10*/ule m1 { //// va/*invlaid11*/r varibale = 0; -//// +//// //// func/*invlaid12*/tion foo(arg1: number) { //// ret/*invlaid13*/urn string; //// } //// //// class foo { -//// +//// //// } //// //// var object = { @@ -44,9 +44,5 @@ //// }; ////} - -test.markers().forEach((marker) => { - goTo.position(marker.position, marker.fileName); - verify.not.quickInfoExists(); -}); +goTo.eachMarker(() => verify.not.quickInfoExists()); diff --git a/tests/cases/fourslash/referencesForIndexProperty2.ts b/tests/cases/fourslash/referencesForIndexProperty2.ts index 0aa099c9622..35c9d7cdd64 100644 --- a/tests/cases/fourslash/referencesForIndexProperty2.ts +++ b/tests/cases/fourslash/referencesForIndexProperty2.ts @@ -5,6 +5,4 @@ ////var a; ////a["[|blah|]"]; -goTo.position(test.ranges()[0].start, test.ranges()[0].fileName); -verify.referencesAre(test.ranges()); - +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/referencesInComment.ts b/tests/cases/fourslash/referencesInComment.ts index c53a2e6d9b3..eabf74d2f23 100644 --- a/tests/cases/fourslash/referencesInComment.ts +++ b/tests/cases/fourslash/referencesInComment.ts @@ -5,6 +5,4 @@ ////class foo { } ////var bar = 0; -for (const marker of test.markers()) { - verify.referencesAre([]); -} +goTo.eachMarker(() => verify.referencesAre([])); diff --git a/tests/cases/fourslash/renameAlias.ts b/tests/cases/fourslash/renameAlias.ts index e0408af656f..3869b1522b5 100644 --- a/tests/cases/fourslash/renameAlias.ts +++ b/tests/cases/fourslash/renameAlias.ts @@ -4,8 +4,4 @@ ////import [|M|] = SomeModule; ////import C = [|M|].SomeClass; -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameAlias2.ts b/tests/cases/fourslash/renameAlias2.ts index da1bcf8248d..f97121f5f7d 100644 --- a/tests/cases/fourslash/renameAlias2.ts +++ b/tests/cases/fourslash/renameAlias2.ts @@ -4,8 +4,4 @@ ////import M = [|SomeModule|]; ////import C = M.SomeClass; -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); \ No newline at end of file diff --git a/tests/cases/fourslash/renameAlias3.ts b/tests/cases/fourslash/renameAlias3.ts index 9172f052abb..af3bafef115 100644 --- a/tests/cases/fourslash/renameAlias3.ts +++ b/tests/cases/fourslash/renameAlias3.ts @@ -4,8 +4,4 @@ ////import M = SomeModule; ////import C = M.[|SomeClass|]; -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameAliasExternalModule.ts b/tests/cases/fourslash/renameAliasExternalModule.ts index 54277fd6e64..49cc6396717 100644 --- a/tests/cases/fourslash/renameAliasExternalModule.ts +++ b/tests/cases/fourslash/renameAliasExternalModule.ts @@ -8,9 +8,4 @@ ////import [|M|] = require("./a"); ////import C = [|M|].SomeClass; -let ranges = test.ranges() -for (let range of ranges) { - goTo.file(range.fileName); - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameAliasExternalModule2.ts b/tests/cases/fourslash/renameAliasExternalModule2.ts index 2d9d07efb68..35916295a8e 100644 --- a/tests/cases/fourslash/renameAliasExternalModule2.ts +++ b/tests/cases/fourslash/renameAliasExternalModule2.ts @@ -8,9 +8,4 @@ ////import M = require("./a"); ////import C = M.SomeClass; -let ranges = test.ranges() -for (let range of ranges) { - goTo.file(range.fileName); - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameAliasExternalModule3.ts b/tests/cases/fourslash/renameAliasExternalModule3.ts index acff9371c77..53b28e7983e 100644 --- a/tests/cases/fourslash/renameAliasExternalModule3.ts +++ b/tests/cases/fourslash/renameAliasExternalModule3.ts @@ -8,9 +8,4 @@ ////import M = require("./a"); ////import C = M.[|SomeClass|]; -let ranges = test.ranges() -for (let range of ranges) { - goTo.file(range.fileName); - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameContextuallyTypedProperties.ts b/tests/cases/fourslash/renameContextuallyTypedProperties.ts index 4feed49256f..4ce3c2b0738 100644 --- a/tests/cases/fourslash/renameContextuallyTypedProperties.ts +++ b/tests/cases/fourslash/renameContextuallyTypedProperties.ts @@ -55,9 +55,4 @@ //// set ["prop2"](v) { } ////}; -let ranges = test.ranges() -for (let range of ranges) { - goTo.file(range.fileName); - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameContextuallyTypedProperties2.ts b/tests/cases/fourslash/renameContextuallyTypedProperties2.ts index 1887c7751a5..01e638395a0 100644 --- a/tests/cases/fourslash/renameContextuallyTypedProperties2.ts +++ b/tests/cases/fourslash/renameContextuallyTypedProperties2.ts @@ -55,9 +55,4 @@ //// set ["[|prop2|]"](v) { } ////}; -let ranges = test.ranges() -for (let range of ranges) { - goTo.file(range.fileName); - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDefaultImport.ts b/tests/cases/fourslash/renameDefaultImport.ts index fd9534e65f7..ff297ffa147 100644 --- a/tests/cases/fourslash/renameDefaultImport.ts +++ b/tests/cases/fourslash/renameDefaultImport.ts @@ -1,19 +1,27 @@ /// -// @Filename: B.ts -////export default class [|B|] { -//// test() { -//// } -////} +// @Filename: B.ts +////export default class /*1*/[|B|] { +//// test() { +//// } +////} -// @Filename: A.ts -////import [|B|] from "./B"; -////let b = new [|B|](); +// @Filename: A.ts +////import [|B|] from "./B"; +////let b = new [|B|](); ////b.test(); -let ranges = test.ranges() -for (let range of ranges) { - goTo.file(range.fileName); - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +goTo.marker("1"); +verify.occurrencesAtPositionCount(1); + +const [C, B0, B1] = test.ranges(); +verify.rangesReferenceEachOther(); + +goTo.rangeStart(C); +verify.renameLocations(false, false, [C, B0, B1]); + +const rangesInB = [B0, B1]; +for (const r of rangesInB) { + goTo.rangeStart(r); + verify.renameLocations(false, false, rangesInB); } diff --git a/tests/cases/fourslash/renameDefaultImportDifferentName.ts b/tests/cases/fourslash/renameDefaultImportDifferentName.ts index 5965f1a63e9..be968c9b883 100644 --- a/tests/cases/fourslash/renameDefaultImportDifferentName.ts +++ b/tests/cases/fourslash/renameDefaultImportDifferentName.ts @@ -1,23 +1,27 @@ /// -// @Filename: B.ts -////export default class /*1*/C { -//// test() { -//// } -////} +// @Filename: B.ts +////export default class /*1*/[|C|] { +//// test() { +//// } +////} -// @Filename: A.ts -////import [|B|] from "./B"; -////let b = new [|B|](); +// @Filename: A.ts +////import [|B|] from "./B"; +////let b = new [|B|](); ////b.test(); -goTo.file("B.ts"); goTo.marker("1"); verify.occurrencesAtPositionCount(1); -goTo.file("A.ts"); -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +const [C, B0, B1] = test.ranges(); +verify.rangesReferenceEachOther(); + +goTo.rangeStart(C); +verify.renameLocations(false, false, [C, B0, B1]); + +const rangesInB = [B0, B1]; +for (const r of rangesInB) { + goTo.rangeStart(r); + verify.renameLocations(false, false, rangesInB); } diff --git a/tests/cases/fourslash/renameDestructuringAssignment.ts b/tests/cases/fourslash/renameDestructuringAssignment.ts index b7b18f661d2..89a44a3a9d9 100644 --- a/tests/cases/fourslash/renameDestructuringAssignment.ts +++ b/tests/cases/fourslash/renameDestructuringAssignment.ts @@ -1,14 +1,10 @@ /// -////interface I { -//// [|x|]: number; -////} -////var a: I; -////var x; +////interface I { +//// [|x|]: number; +////} +////var a: I; +////var x; ////({ [|x|]: x } = a); -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDestructuringAssignmentInFor2.ts b/tests/cases/fourslash/renameDestructuringAssignmentInFor2.ts index ca75e42394b..4d79b47a267 100644 --- a/tests/cases/fourslash/renameDestructuringAssignmentInFor2.ts +++ b/tests/cases/fourslash/renameDestructuringAssignmentInFor2.ts @@ -1,20 +1,16 @@ /// -////interface I { -//// property1: number; -//// property2: string; -////} -////var elems: I[]; -//// -////var p2: number, [|property1|]: number; -////for ({ [|property1|] } = elems[0]; p2 < 100; p2++) { -//// p2 = [|property1|]++; +////interface I { +//// property1: number; +//// property2: string; ////} -////for ({ property1: p2 } = elems[0]; p2 < 100; p2++) { +////var elems: I[]; +//// +////var p2: number, [|property1|]: number; +////for ({ [|property1|] } = elems[0]; p2 < 100; p2++) { +//// p2 = [|property1|]++; +////} +////for ({ property1: p2 } = elems[0]; p2 < 100; p2++) { ////} -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDestructuringAssignmentInForOf2.ts b/tests/cases/fourslash/renameDestructuringAssignmentInForOf2.ts index 401b6776d2e..9987a17d36e 100644 --- a/tests/cases/fourslash/renameDestructuringAssignmentInForOf2.ts +++ b/tests/cases/fourslash/renameDestructuringAssignmentInForOf2.ts @@ -1,20 +1,16 @@ /// -////interface I { -//// property1: number; -//// property2: string; -////} -////var elems: I[]; -//// -////var [|property1|]: number, p2: number; -////for ({ [|property1|] } of elems) { -//// [|property1|]++; +////interface I { +//// property1: number; +//// property2: string; ////} -////for ({ property1: p2 } of elems) { +////var elems: I[]; +//// +////var [|property1|]: number, p2: number; +////for ({ [|property1|] } of elems) { +//// [|property1|]++; +////} +////for ({ property1: p2 } of elems) { ////} -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDestructuringAssignmentNestedInArrayLiteral2.ts b/tests/cases/fourslash/renameDestructuringAssignmentNestedInArrayLiteral2.ts index c4db2de512f..e45ae3349a4 100644 --- a/tests/cases/fourslash/renameDestructuringAssignmentNestedInArrayLiteral2.ts +++ b/tests/cases/fourslash/renameDestructuringAssignmentNestedInArrayLiteral2.ts @@ -1,15 +1,11 @@ /// -////interface I { -//// property1: number; -//// property2: string; -////} -////var elems: I[], p1: number, [|property1|]: number; -////[{ property1: p1 }] = elems; -////[{ [|property1|] }] = elems; +////interface I { +//// property1: number; +//// property2: string; +////} +////var elems: I[], p1: number, [|property1|]: number; +////[{ property1: p1 }] = elems; +////[{ [|property1|] }] = elems; -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDestructuringAssignmentNestedInFor2.ts b/tests/cases/fourslash/renameDestructuringAssignmentNestedInFor2.ts index 89dc899c5bf..2ec7d906ad1 100644 --- a/tests/cases/fourslash/renameDestructuringAssignmentNestedInFor2.ts +++ b/tests/cases/fourslash/renameDestructuringAssignmentNestedInFor2.ts @@ -1,5 +1,5 @@ -/// - +/// + ////interface MultiRobot { //// name: string; //// skills: { @@ -14,10 +14,5 @@ ////for ({ skills: { [|primary|], secondary } } = multiRobot, i = 0; i < 1; i++) { //// console.log([|primary|]); ////} - -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} - + +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDestructuringAssignmentNestedInForOf2.ts b/tests/cases/fourslash/renameDestructuringAssignmentNestedInForOf2.ts index b684e6b6a81..5364cffebb9 100644 --- a/tests/cases/fourslash/renameDestructuringAssignmentNestedInForOf2.ts +++ b/tests/cases/fourslash/renameDestructuringAssignmentNestedInForOf2.ts @@ -1,5 +1,5 @@ -/// - +/// + ////interface MultiRobot { //// name: string; //// skills: { @@ -14,10 +14,6 @@ ////for ({ skills: { [|primary|], secondary } } of multiRobots) { //// console.log([|primary|]); ////} - - -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} + + +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDestructuringClassProperty.ts b/tests/cases/fourslash/renameDestructuringClassProperty.ts index acc58f999c4..11261a4df78 100644 --- a/tests/cases/fourslash/renameDestructuringClassProperty.ts +++ b/tests/cases/fourslash/renameDestructuringClassProperty.ts @@ -1,5 +1,5 @@ -/// - +/// + ////class A { //// [|foo|]: string; ////} @@ -14,10 +14,6 @@ //// let { [|foo|] } = a; //// [|foo|] = "newString"; //// } -////} - -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +////} + +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDestructuringDeclarationInFor.ts b/tests/cases/fourslash/renameDestructuringDeclarationInFor.ts index 0edf9085092..0338433ae72 100644 --- a/tests/cases/fourslash/renameDestructuringDeclarationInFor.ts +++ b/tests/cases/fourslash/renameDestructuringDeclarationInFor.ts @@ -1,20 +1,16 @@ /// -////interface I { -//// [|property1|]: number; -//// property2: string; -////} -////var elems: I[]; -//// -////var p2: number, property1: number; -////for (let { [|property1|]: p2 } = elems[0]; p2 < 100; p2++) { +////interface I { +//// [|property1|]: number; +//// property2: string; ////} -////for (let { [|property1|] } = elems[0]; p2 < 100; p2++) { -//// [|property1|] = p2; +////var elems: I[]; +//// +////var p2: number, property1: number; +////for (let { [|property1|]: p2 } = elems[0]; p2 < 100; p2++) { +////} +////for (let { [|property1|] } = elems[0]; p2 < 100; p2++) { +//// [|property1|] = p2; ////} -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDestructuringDeclarationInForOf.ts b/tests/cases/fourslash/renameDestructuringDeclarationInForOf.ts index 1c2b04b7ab5..fcd55a5bc20 100644 --- a/tests/cases/fourslash/renameDestructuringDeclarationInForOf.ts +++ b/tests/cases/fourslash/renameDestructuringDeclarationInForOf.ts @@ -1,19 +1,15 @@ /// -////interface I { -//// [|property1|]: number; -//// property2: string; -////} -////var elems: I[]; -//// -////for (let { [|property1|] } of elems) { -//// [|property1|]++; +////interface I { +//// [|property1|]: number; +//// property2: string; ////} -////for (let { [|property1|]: p2 } of elems) { +////var elems: I[]; +//// +////for (let { [|property1|] } of elems) { +//// [|property1|]++; +////} +////for (let { [|property1|]: p2 } of elems) { ////} -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDestructuringFunctionParameter.ts b/tests/cases/fourslash/renameDestructuringFunctionParameter.ts index d1df0f58275..4abbabc3723 100644 --- a/tests/cases/fourslash/renameDestructuringFunctionParameter.ts +++ b/tests/cases/fourslash/renameDestructuringFunctionParameter.ts @@ -1,10 +1,7 @@ /// -////function f({[|a|]}: {[|a|]}) { -//// f({[|a|]}); +////function f({[|a|]}: {[|a|]}) { +//// f({[|a|]}); ////} -let ranges = test.ranges(); -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} + +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameDestructuringNestedBindingElement.ts b/tests/cases/fourslash/renameDestructuringNestedBindingElement.ts index 1c4254b14ae..7557744ecee 100644 --- a/tests/cases/fourslash/renameDestructuringNestedBindingElement.ts +++ b/tests/cases/fourslash/renameDestructuringNestedBindingElement.ts @@ -1,5 +1,5 @@ -/// - +/// + ////interface MultiRobot { //// name: string; //// skills: { @@ -13,10 +13,6 @@ ////} ////for (let { skills: {[|primary|], secondary } } of multiRobots) { //// console.log([|primary|]); -////} - -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +////} + +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameForDefaultExport01.ts b/tests/cases/fourslash/renameForDefaultExport01.ts index 809c127a727..96f0d6e54e8 100644 --- a/tests/cases/fourslash/renameForDefaultExport01.ts +++ b/tests/cases/fourslash/renameForDefaultExport01.ts @@ -10,9 +10,4 @@ //// ////var y = new /*3*/[|DefaultExportedClass|]; -let markers = test.markers() -for (let marker of markers) { - goTo.position(marker.position); - - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ true); -} \ No newline at end of file +goTo.eachMarker(() => verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ true)); \ No newline at end of file diff --git a/tests/cases/fourslash/renameForDefaultExport02.ts b/tests/cases/fourslash/renameForDefaultExport02.ts index ddf4b224023..471b10e32b2 100644 --- a/tests/cases/fourslash/renameForDefaultExport02.ts +++ b/tests/cases/fourslash/renameForDefaultExport02.ts @@ -11,9 +11,4 @@ //// ////var y = /*4*/[|DefaultExportedFunction|](); -let markers = test.markers() -for (let marker of markers) { - goTo.position(marker.position); - - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ true); -} \ No newline at end of file +goTo.eachMarker(() => verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ true)); \ No newline at end of file diff --git a/tests/cases/fourslash/renameForDefaultExport03.ts b/tests/cases/fourslash/renameForDefaultExport03.ts index 6f82d96fe5e..1da6ff20b0b 100644 --- a/tests/cases/fourslash/renameForDefaultExport03.ts +++ b/tests/cases/fourslash/renameForDefaultExport03.ts @@ -17,9 +17,4 @@ //// var local = 100; ////} -let markers = test.markers() -for (let marker of markers) { - goTo.position(marker.position); - - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ true); -} \ No newline at end of file +goTo.eachMarker(() => verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ true)); \ No newline at end of file diff --git a/tests/cases/fourslash/renameImportAndExport.ts b/tests/cases/fourslash/renameImportAndExport.ts index 495e15c1e7e..fe8bce4b208 100644 --- a/tests/cases/fourslash/renameImportAndExport.ts +++ b/tests/cases/fourslash/renameImportAndExport.ts @@ -3,8 +3,4 @@ ////import [|a|] from "module"; ////export { [|a|] }; -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameImportAndShorthand.ts b/tests/cases/fourslash/renameImportAndShorthand.ts index bc4746aebdd..4836d8c14fe 100644 --- a/tests/cases/fourslash/renameImportAndShorthand.ts +++ b/tests/cases/fourslash/renameImportAndShorthand.ts @@ -3,8 +3,4 @@ ////import [|foo|] from 'bar'; ////const bar = { [|foo|] }; -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameImportNamespaceAndShorthand.ts b/tests/cases/fourslash/renameImportNamespaceAndShorthand.ts index a6b06c11408..21cdc0fa820 100644 --- a/tests/cases/fourslash/renameImportNamespaceAndShorthand.ts +++ b/tests/cases/fourslash/renameImportNamespaceAndShorthand.ts @@ -3,8 +3,4 @@ ////import * as [|foo|] from 'bar'; ////const bar = { [|foo|] }; -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameImportOfExportEquals.ts b/tests/cases/fourslash/renameImportOfExportEquals.ts index 9d71ee907c8..192acefd6fd 100644 --- a/tests/cases/fourslash/renameImportOfExportEquals.ts +++ b/tests/cases/fourslash/renameImportOfExportEquals.ts @@ -11,8 +11,4 @@ //// export { [|N|] }; // Renaming N here would rename ////} -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameImportRequire.ts b/tests/cases/fourslash/renameImportRequire.ts index c26cc80b616..8a9aeebc328 100644 --- a/tests/cases/fourslash/renameImportRequire.ts +++ b/tests/cases/fourslash/renameImportRequire.ts @@ -1,12 +1,8 @@ /// -////import [|e|] = require("mod4"); -////[|e|]; -////a = { [|e|] }; +////import [|e|] = require("mod4"); +////[|e|]; +////a = { [|e|] }; ////export { [|e|] }; -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameInheritedProperties1.ts b/tests/cases/fourslash/renameInheritedProperties1.ts index 4698fe3d97b..b42335277a9 100644 --- a/tests/cases/fourslash/renameInheritedProperties1.ts +++ b/tests/cases/fourslash/renameInheritedProperties1.ts @@ -7,9 +7,4 @@ //// var v: class1; //// v.[|propName|]; -const ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (const range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameInheritedProperties2.ts b/tests/cases/fourslash/renameInheritedProperties2.ts index ed99ec3e013..bcc4c5fc323 100644 --- a/tests/cases/fourslash/renameInheritedProperties2.ts +++ b/tests/cases/fourslash/renameInheritedProperties2.ts @@ -7,9 +7,4 @@ //// var v: class1; //// v.[|doStuff|](); -let ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameInheritedProperties3.ts b/tests/cases/fourslash/renameInheritedProperties3.ts index 17e7785fbc7..f1ec547d6ed 100644 --- a/tests/cases/fourslash/renameInheritedProperties3.ts +++ b/tests/cases/fourslash/renameInheritedProperties3.ts @@ -7,9 +7,4 @@ //// var v: interface1; //// v.[|propName|]; -let ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameInheritedProperties4.ts b/tests/cases/fourslash/renameInheritedProperties4.ts index ea2f7c40fbf..42d9acfdb53 100644 --- a/tests/cases/fourslash/renameInheritedProperties4.ts +++ b/tests/cases/fourslash/renameInheritedProperties4.ts @@ -7,9 +7,4 @@ //// var v: interface1; //// v.[|doStuff|](); -let ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameInheritedProperties5.ts b/tests/cases/fourslash/renameInheritedProperties5.ts index 45058827747..e153742d4ed 100644 --- a/tests/cases/fourslash/renameInheritedProperties5.ts +++ b/tests/cases/fourslash/renameInheritedProperties5.ts @@ -9,9 +9,5 @@ //// var d: D; //// d.[|propD|]; -const ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (const range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); + diff --git a/tests/cases/fourslash/renameInheritedProperties6.ts b/tests/cases/fourslash/renameInheritedProperties6.ts index 6bdd32ce3e0..59318334cb0 100644 --- a/tests/cases/fourslash/renameInheritedProperties6.ts +++ b/tests/cases/fourslash/renameInheritedProperties6.ts @@ -9,9 +9,4 @@ //// var d: D; //// d.[|propC|]; -const ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (const range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameInheritedProperties7.ts b/tests/cases/fourslash/renameInheritedProperties7.ts index a2f8c5a2b51..bc0521458f8 100644 --- a/tests/cases/fourslash/renameInheritedProperties7.ts +++ b/tests/cases/fourslash/renameInheritedProperties7.ts @@ -3,17 +3,12 @@ //// class C extends D { //// [|prop1|]: string; //// } -//// +//// //// class D extends C { //// prop1: string; //// } -//// +//// //// var c: C; //// c.[|prop1|]; -const ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (const range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameInheritedProperties8.ts b/tests/cases/fourslash/renameInheritedProperties8.ts index 119e1a477aa..7cde300bf0b 100644 --- a/tests/cases/fourslash/renameInheritedProperties8.ts +++ b/tests/cases/fourslash/renameInheritedProperties8.ts @@ -3,17 +3,12 @@ //// class C implements D { //// [|prop1|]: string; //// } -//// +//// //// interface D extends C { //// [|prop1|]: string; //// } -//// +//// //// var c: C; //// c.[|prop1|]; -const ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (const range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameLocationsForClassExpression01.ts b/tests/cases/fourslash/renameLocationsForClassExpression01.ts index b95040085c9..b0f2f509500 100644 --- a/tests/cases/fourslash/renameLocationsForClassExpression01.ts +++ b/tests/cases/fourslash/renameLocationsForClassExpression01.ts @@ -11,7 +11,7 @@ //// static doItStatically() { //// return [|Foo|].y; //// } -////} +////} //// ////var y = class { //// getSomeName() { @@ -20,8 +20,4 @@ ////} ////var z = class Foo {} -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameLocationsForFunctionExpression01.ts b/tests/cases/fourslash/renameLocationsForFunctionExpression01.ts index e884783d960..1e02e3f5284 100644 --- a/tests/cases/fourslash/renameLocationsForFunctionExpression01.ts +++ b/tests/cases/fourslash/renameLocationsForFunctionExpression01.ts @@ -4,9 +4,4 @@ //// [|f|]([|f|], g); ////} -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameLocationsForFunctionExpression02.ts b/tests/cases/fourslash/renameLocationsForFunctionExpression02.ts index 8186611cb64..a258bcd803d 100644 --- a/tests/cases/fourslash/renameLocationsForFunctionExpression02.ts +++ b/tests/cases/fourslash/renameLocationsForFunctionExpression02.ts @@ -1,7 +1,7 @@ /// ////function f() { -//// +//// ////} ////var x = function [|f|](g: any, h: any) { //// @@ -10,9 +10,4 @@ //// let foo = () => [|f|]([|f|], g); ////} -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameObjectBindingElementPropertyName01.ts b/tests/cases/fourslash/renameObjectBindingElementPropertyName01.ts index 535dbd3d5a3..4ae87f19db5 100644 --- a/tests/cases/fourslash/renameObjectBindingElementPropertyName01.ts +++ b/tests/cases/fourslash/renameObjectBindingElementPropertyName01.ts @@ -8,7 +8,4 @@ ////var foo: I; ////var { [|property1|]: prop1 } = foo; -for (let range of test.ranges()) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameObjectSpread.ts b/tests/cases/fourslash/renameObjectSpread.ts index eba148c0e39..f56c22dd42f 100644 --- a/tests/cases/fourslash/renameObjectSpread.ts +++ b/tests/cases/fourslash/renameObjectSpread.ts @@ -10,11 +10,11 @@ const ranges = test.ranges(); verify.assertHasRanges(ranges); // A1 unions with A2, so rename A1.a and a12.a -goTo.position(ranges[0].start); +goTo.rangeStart(ranges[0]); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, [ranges[0], ranges[2]]); // A1 unions with A2, so rename A2.a and a12.a -goTo.position(ranges[1].start); +goTo.rangeStart(ranges[1]); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, [ranges[1], ranges[2]]); // a12.a unions A1.a and A2.a, so rename A1.a, A2.a and a12.a -goTo.position(ranges[2].start); +goTo.rangeStart(ranges[2]); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, [ranges[0], ranges[1], ranges[2]]); diff --git a/tests/cases/fourslash/renameObjectSpreadAssignment.ts b/tests/cases/fourslash/renameObjectSpreadAssignment.ts index 9cf0b6ebf81..2ddebb6e18b 100644 --- a/tests/cases/fourslash/renameObjectSpreadAssignment.ts +++ b/tests/cases/fourslash/renameObjectSpreadAssignment.ts @@ -5,16 +5,18 @@ ////let [|a1|]: A1; ////let [|a2|]: A2; ////let a12 = { ...[|a1|], ...[|a2|] }; + const ranges = test.ranges(); verify.assertHasRanges(ranges); + // rename a1 -goTo.position(ranges[0].start); +goTo.rangeStart(ranges[0]); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, [ranges[0], ranges[2]]); -goTo.position(ranges[2].start); +goTo.rangeStart(ranges[2]); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, [ranges[0], ranges[2]]); // rename a2 -goTo.position(ranges[1].start); +goTo.rangeStart(ranges[1]); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, [ranges[1], ranges[3]]); -goTo.position(ranges[3].start); +goTo.rangeStart(ranges[3]); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, [ranges[1], ranges[3]]); diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration1.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration1.ts index 42bfbf63a47..14f8a240bfb 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration1.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration1.ts @@ -7,9 +7,4 @@ //// } //// } -let ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration2.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration2.ts index e7ef9d1c1a2..ce31ad6c9c5 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration2.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration2.ts @@ -7,9 +7,4 @@ //// } //// } -let ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration3.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration3.ts index 9446e2aeb75..6291eff2605 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration3.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration3.ts @@ -7,9 +7,4 @@ //// } //// } -let ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts index 7fb4b8c757d..ca201d28b2c 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts @@ -6,9 +6,4 @@ //// } //// } -let ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts index b7c47a4c0d7..f989e7c3fd9 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts @@ -6,9 +6,4 @@ //// } //// } -let ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameRest.ts b/tests/cases/fourslash/renameRest.ts index a5cc2c38683..60fc1bbb227 100644 --- a/tests/cases/fourslash/renameRest.ts +++ b/tests/cases/fourslash/renameRest.ts @@ -7,9 +7,5 @@ ////let t: Gen; ////var { x, ...rest } = t; ////rest.[|parent|]; -const ranges = test.ranges(); -verify.assertHasRanges(ranges); -goTo.position(ranges[0].start); -verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, ranges); -goTo.position(ranges[1].start); -verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, ranges); + +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameStingPropertyNames.ts b/tests/cases/fourslash/renameStingPropertyNames.ts index a948220efad..13863b043e7 100644 --- a/tests/cases/fourslash/renameStingPropertyNames.ts +++ b/tests/cases/fourslash/renameStingPropertyNames.ts @@ -12,9 +12,4 @@ ////o['[|prop|]']; ////o.[|prop|]; - -let ranges = test.ranges(); -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameStringLiteralTypes.ts b/tests/cases/fourslash/renameStringLiteralTypes.ts index f9df83371c1..d0e7368f25d 100644 --- a/tests/cases/fourslash/renameStringLiteralTypes.ts +++ b/tests/cases/fourslash/renameStringLiteralTypes.ts @@ -11,8 +11,4 @@ //// ////animate({ deltaX: 100, deltaY: 100, easing: "[|ease-in-out|]" }); -let ranges = test.ranges(); -for (let range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/renameThis.ts b/tests/cases/fourslash/renameThis.ts index f567cace70d..c4e5d932261 100644 --- a/tests/cases/fourslash/renameThis.ts +++ b/tests/cases/fourslash/renameThis.ts @@ -8,7 +8,7 @@ let [r0, r1, r2, r3] = test.ranges() for (let range of [r0, r1]) { - goTo.position(range.start); + goTo.rangeStart(range); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, [r0, r1]); } @@ -17,6 +17,6 @@ goTo.marker(); verify.renameInfoFailed("You cannot rename this element."); for (let range of [r2, r3]) { - goTo.position(range.start); + goTo.rangeStart(range); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, [r2, r3]); } diff --git a/tests/cases/fourslash/renameUMDModuleAlias1.ts b/tests/cases/fourslash/renameUMDModuleAlias1.ts index 94aabcdbde5..c44e459b008 100644 --- a/tests/cases/fourslash/renameUMDModuleAlias1.ts +++ b/tests/cases/fourslash/renameUMDModuleAlias1.ts @@ -10,8 +10,4 @@ //// /// //// [|myLib|].doThing(); -const ranges = test.ranges() -for (const range of ranges) { - goTo.position(range.start); - verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); -} \ No newline at end of file +verify.rangesAreRenameLocations(); diff --git a/tests/cases/fourslash/server/documentHighlights01.ts b/tests/cases/fourslash/server/documentHighlights01.ts index d4be88f9357..0acfbcb9d11 100644 --- a/tests/cases/fourslash/server/documentHighlights01.ts +++ b/tests/cases/fourslash/server/documentHighlights01.ts @@ -5,14 +5,4 @@ //// [|f|]([|f|]); ////} -let ranges = test.ranges(); - -for (let r of ranges) { - goTo.position(r.start); - verify.documentHighlightsAtPositionCount(ranges.length, ["a.ts"]); - - for (let range of ranges) { - verify.documentHighlightsAtPositionContains(range, ["a.ts"]); - } -} - +verify.rangesAreDocumentHighlights(); diff --git a/tests/cases/fourslash/server/documentHighlights02.ts b/tests/cases/fourslash/server/documentHighlights02.ts index 357f82e9c2d..3fd71d4a65d 100644 --- a/tests/cases/fourslash/server/documentHighlights02.ts +++ b/tests/cases/fourslash/server/documentHighlights02.ts @@ -8,28 +8,10 @@ // @Filename: b.ts /////// -////foo(); +////[|foo|](); // open two files goTo.file("a.ts"); goTo.file("b.ts"); -let ranges = test.ranges(); - -for (let i = 0; i < ranges.length; ++i) { - let r = ranges[i]; - - if (i < 2) { - goTo.file("a.ts"); - } - else { - goTo.file("b.ts"); - } - - goTo.position(r.start); - verify.documentHighlightsAtPositionCount(3, ["a.ts", "b.ts"]); - - for (let range of ranges) { - verify.documentHighlightsAtPositionContains(range, ["a.ts", "b.ts"]); - } -} +verify.rangesAreDocumentHighlights(); diff --git a/tests/cases/fourslash/server/goToImplementation_inDifferentFiles.ts b/tests/cases/fourslash/server/goToImplementation_inDifferentFiles.ts new file mode 100644 index 00000000000..e4289b83102 --- /dev/null +++ b/tests/cases/fourslash/server/goToImplementation_inDifferentFiles.ts @@ -0,0 +1,19 @@ +/// + +// @Filename: /bar.ts +////import {Foo} from './foo' +//// +////[|class A implements Foo { +//// func() {} +////}|] +//// +////[|class B implements Foo { +//// func() {} +////}|] + +// @Filename: /foo.ts +////export interface /**/Foo { +//// func(); +////} + +verify.allRangesAppearInImplementationList(""); diff --git a/tests/cases/fourslash/server/occurrences01.ts b/tests/cases/fourslash/server/occurrences01.ts index db2fa64f38d..f6e39d55b91 100644 --- a/tests/cases/fourslash/server/occurrences01.ts +++ b/tests/cases/fourslash/server/occurrences01.ts @@ -10,13 +10,4 @@ //// continue foo; ////} -let ranges = test.ranges(); - -for (let r of ranges) { - goTo.position(r.start); - verify.occurrencesAtPositionCount(ranges.length); - - for (let range of ranges) { - verify.occurrencesAtPositionContains(range, /*isWriteAccess*/ false); - } -} \ No newline at end of file +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/server/occurrences02.ts b/tests/cases/fourslash/server/occurrences02.ts index e0d39cb92fd..4cf8f1bcac3 100644 --- a/tests/cases/fourslash/server/occurrences02.ts +++ b/tests/cases/fourslash/server/occurrences02.ts @@ -4,13 +4,4 @@ //// [|f|]([|f|]); ////} -let ranges = test.ranges(); - -for (let r of ranges) { - goTo.position(r.start); - verify.occurrencesAtPositionCount(ranges.length); - - for (let range of ranges) { - verify.occurrencesAtPositionContains(range); - } -} \ No newline at end of file +verify.rangesAreOccurrences(); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplates1.ts b/tests/cases/fourslash/signatureHelpTaggedTemplates1.ts index 39644ba8c24..87c9262f893 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplates1.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplates1.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f `/*1*/ qwe/*2*/rty /*3*/$/*4*/{ 123 }/*5*/ as/*6*/df /*7*/$/*8*/{ 41234 }/*9*/ zxc/*10*/vb /*11*/$/*12*/{ g ` ` }/*13*/ /*14*/ /*15*/` -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(4); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplates2.ts b/tests/cases/fourslash/signatureHelpTaggedTemplates2.ts index 123a6cc4c2c..ef306a22934 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplates2.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplates2.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f `/*1*/ qwe/*2*/rty /*3*/$/*4*/{ 123 }/*5*/ as/*6*/df /*7*/$/*8*/{ 41234 }/*9*/ zxc/*10*/vb /*11*/$/*12*/{ g ` ` }/*13*/ /*14*/ /*15*/ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(4); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplates3.ts b/tests/cases/fourslash/signatureHelpTaggedTemplates3.ts index f203468ca04..7859fd6f457 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplates3.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplates3.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f ` qwerty ${/*1*/ /*2*/123/*3*/ /*4*/} asdf ${ 41234 } zxcvb ${ g ` ` } ` -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(4); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplates4.ts b/tests/cases/fourslash/signatureHelpTaggedTemplates4.ts index 13ee47a3309..4c8ce2cd917 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplates4.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplates4.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f ` qwerty ${ 123 } asdf ${/*1*/ /*2*/ /*3*/41/*4*/234/*5*/ /*6*/} zxcvb ${ g ` ` } ` -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(4); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplates5.ts b/tests/cases/fourslash/signatureHelpTaggedTemplates5.ts index 7cd2affd675..03ef244e719 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplates5.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplates5.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f ` qwerty ${ 123 } asdf ${ 41234 } zxcvb ${/*1*/ /*2*/g/*3*/ /*4*/` `/*5*/ /*6*/} ` -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(4); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplates6.ts b/tests/cases/fourslash/signatureHelpTaggedTemplates6.ts index 7671666bb54..67ab1199be8 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplates6.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplates6.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f ` qwerty ${ 123 } asdf ${ 41234 } zxcvb ${ g `/*1*/ /*2*/ /*3*/` } ` -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(1); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplates7.ts b/tests/cases/fourslash/signatureHelpTaggedTemplates7.ts index 35bed336f39..cd17ddd1027 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplates7.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplates7.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f `/*1*/ /*2*/ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(1); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete1.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete1.ts index 1da96ea5c1b..2995c6cdcd8 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete1.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete1.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// -//// f `/*1*/ /*2*/${ - -test.markers().forEach(m => { - goTo.position(m.position); +//// +//// f `/*1*/ /*2*/${ +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(2); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete2.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete2.ts index 68ff7202f01..d1ceebfb1b0 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete2.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete2.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f ` ${/*1*/ /*2*/ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(2); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete3.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete3.ts index 8165da7f67b..211fa66f594 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete3.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete3.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f ` ${ }/*1*/ /*2*/ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(2); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete4.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete4.ts index 8c970b60c77..79432077ce9 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete4.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete4.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f ` ${ } ${/*1*/ /*2*/ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(3); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete5.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete5.ts index f93da36ce5c..18ffdbe3bf0 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete5.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete5.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f ` ${ } ${ }/*1*/ /*2*/ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(3); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete6.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete6.ts index 10d81eb80f4..fdd6f22554d 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete6.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete6.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f ` ${ 123 } ${/*1*/ } ` -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(3); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete7.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete7.ts index a8afe2d9c6d..9bc4a535564 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete7.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete7.ts @@ -2,15 +2,13 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f ` ${ 123 } /*1*/${ } /*2*/\/*3*/ //// /*4*/\\/*5*/ //// /*6*/\\\/*7*/ //// /*8*/ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(3); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete8.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete8.ts index 86455a65ccd..05ab05c3e6c 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete8.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete8.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f `/*1*/\/*2*/`/*3*/ /*4*/ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(1); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete9.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete9.ts index de42a33b397..597ec928bb9 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete9.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesIncomplete9.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f `/*1*/ \\\/*2*/`/*3*/ /*4*/ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.signatureHelpArgumentCountIs(1); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives1.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives1.ts index c61f1a871e4..10f9f81fa61 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives1.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives1.ts @@ -2,10 +2,7 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// /*1*/f/*2*/ /*3*/` qwerty ${ 123 } asdf ${ 41234 } zxcvb ${ g ` ` } `/*4*/ -test.markers().forEach(m => { - goTo.position(m.position); - verify.not.signatureHelpPresent(); -}); \ No newline at end of file +goTo.eachMarker(() => verify.not.signatureHelpPresent()); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives2.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives2.ts index e7a5078dcd0..da21fda631c 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives2.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives2.ts @@ -2,10 +2,7 @@ //// function foo(strs, ...rest) { //// } -//// +//// //// /*1*/fo/*2*/o /*3*/`abcd${0 + 1}abcd{1 + 1}`/*4*/ /*5*/ -test.markers().forEach(m => { - goTo.position(m.position); - verify.not.signatureHelpPresent(); -}); \ No newline at end of file +goTo.eachMarker(() => verify.not.signatureHelpPresent()); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives3.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives3.ts index c84b92fee4f..9ccbe927a57 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives3.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives3.ts @@ -2,10 +2,7 @@ //// function foo(strs, ...rest) { //// } -//// +//// //// /*1*/fo/*2*/o /*3*/`abcd${0 + 1}abcd{1 + 1}abcd`/*4*/ /*5*/ -test.markers().forEach(m => { - goTo.position(m.position); - verify.not.signatureHelpPresent(); -}); \ No newline at end of file +goTo.eachMarker(() => verify.not.signatureHelpPresent()); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives4.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives4.ts index 338a8dc65ca..825afd265ab 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives4.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives4.ts @@ -2,10 +2,7 @@ //// function foo(strs, ...rest) { //// } -//// +//// //// /*1*/fo/*2*/o /*3*/``/*4*/ /*5*/ -test.markers().forEach(m => { - goTo.position(m.position); - verify.not.signatureHelpPresent(); -}); \ No newline at end of file +goTo.eachMarker(() => verify.not.signatureHelpPresent()); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives5.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives5.ts index 02383df9267..5b14b627f6a 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives5.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesNegatives5.ts @@ -2,10 +2,7 @@ //// function foo(strs, ...rest) { //// } -//// +//// //// /*1*/fo/*2*/o /*3*/`abcd`/*4*/ -test.markers().forEach(m => { - goTo.position(m.position); - verify.not.signatureHelpPresent(); -}); \ No newline at end of file +goTo.eachMarker(() => verify.not.signatureHelpPresent()); \ No newline at end of file diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesNested1.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesNested1.ts index a3c9f7ccce4..313e55bf517 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesNested1.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesNested1.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f `a ${ g `/*1*/alpha/*2*/ ${/*3*/ 12/*4*/3 /*5*/} beta /*6*/${ /*7*/456 /*8*/} gamma/*9*/` } b ${ g `/*10*/txt/*11*/` } c ${ g `/*12*/aleph /*13*/$/*14*/{ 12/*15*/3 } beit/*16*/` } d`; -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.currentSignatureParameterCountIs(4); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesNested2.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesNested2.ts index d72fa74d985..aa04e425998 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesNested2.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesNested2.ts @@ -2,12 +2,10 @@ //// function f(templateStrings, x, y, z) { return 10; } //// function g(templateStrings, x, y, z) { return ""; } -//// +//// //// f `/*1*/a $/*2*/{ /*3*/g /*4*/`alpha ${ 123 } beta ${ 456 } gamma`/*5*/ }/*6*/ b $/*7*/{ /*8*/g /*9*/`txt`/*10*/ } /*11*/c ${ /*12*/g /*13*/`aleph ${ 123 } beit`/*14*/ } d/*15*/`; -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(1); verify.currentSignatureParameterCountIs(4); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags1.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags1.ts index 6850b1bc54f..54aee5887b8 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags1.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags1.ts @@ -4,12 +4,10 @@ //// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; //// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; //// function f(...foo[]: any) { return ""; } -//// +//// //// f `/*1*/ /*2*/$/*3*/{ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(3); verify.signatureHelpArgumentCountIs(2); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags2.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags2.ts index 8466c6b05f2..9cbd20a49d2 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags2.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags2.ts @@ -4,12 +4,10 @@ //// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; //// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; //// function f(...foo[]: any) { return ""; } -//// +//// //// f `${/*1*/ /*2*/ /*3*/ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(3); verify.signatureHelpArgumentCountIs(2); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags3.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags3.ts index b919afc7703..a9b91dbf438 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags3.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags3.ts @@ -4,12 +4,10 @@ //// function f(templateStrings: TemplateStringsArray, p1_o2: number, p2_o2: number, p3_o2: number): string; //// function f(templateStrings: TemplateStringsArray, p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; //// function f(...foo[]: any) { return ""; } -//// +//// //// f `${/*1*/ "s/*2*/tring" /*3*/ } ${ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(3); verify.signatureHelpArgumentCountIs(3); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags4.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags4.ts index a1072366a98..96ff7c4683a 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags4.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags4.ts @@ -4,12 +4,10 @@ //// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; //// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; //// function f(...foo[]: any) { return ""; } -//// +//// //// f `${/*1*/ 123.456/*2*/ /*3*/ } ${ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(3); verify.signatureHelpArgumentCountIs(3); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags5.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags5.ts index 2646e70b39c..52a1e3f74be 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags5.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags5.ts @@ -4,12 +4,10 @@ //// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; //// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; //// function f(...foo[]: any) { return ""; } -//// +//// //// f `${ } ${/*1*/ /*2*/ /*3*/ -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(3); verify.signatureHelpArgumentCountIs(3); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags6.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags6.ts index 62410a5fda3..b34df14e926 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags6.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags6.ts @@ -4,12 +4,10 @@ //// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; //// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; //// function f(...foo[]: any) { return ""; } -//// +//// //// f `${ } ${/*1*/ /*2*/ /*3*/} -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(3); verify.signatureHelpArgumentCountIs(3); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags7.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags7.ts index 5f706b8c0fa..26a80e36f6f 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags7.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags7.ts @@ -4,12 +4,10 @@ //// function f(templateStrings: TemplateStringsArray, p1_o2: number, p2_o2: number, p3_o2: number): string; //// function f(templateStrings: TemplateStringsArray, p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; //// function f(...foo[]: any) { return ""; } -//// +//// //// f `${ } ${/*1*/ fa/*2*/lse /*3*/} -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(3); verify.signatureHelpArgumentCountIs(3); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags8.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags8.ts index 8000f15d3c6..6b9daa60dcc 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags8.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags8.ts @@ -4,12 +4,10 @@ //// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; //// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; //// function f(...foo[]: any) { return ""; } -//// +//// //// f `${ undefined } ${ undefined } ${/*1*/ 10/*2*/./*3*/01 /*4*/} ` -test.markers().forEach(m => { - goTo.position(m.position); - +goTo.eachMarker(() => { verify.signatureHelpCountIs(3); verify.signatureHelpArgumentCountIs(4); diff --git a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags9.ts b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags9.ts index aee06c1df53..cbcc55a2f22 100644 --- a/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags9.ts +++ b/tests/cases/fourslash/signatureHelpTaggedTemplatesWithOverloadedTags9.ts @@ -4,12 +4,10 @@ //// function f(templateStrings: string[], p1_o2: number, p2_o2: number, p3_o2: number): string; //// function f(templateStrings: string[], p1_o3: string, p2_o3: boolean, p3_o3: number): boolean; //// function f(...foo[]: any) { return ""; } -//// -//// f `${/*1*/ /*2*/ /*3*/} ${ - -test.markers().forEach(m => { - goTo.position(m.position); +//// +//// f `${/*1*/ /*2*/ /*3*/} ${ +goTo.eachMarker(() => { verify.signatureHelpCountIs(3); verify.signatureHelpArgumentCountIs(3); diff --git a/tests/cases/fourslash_old/completionListGenericConstraintsNames.ts b/tests/cases/fourslash_old/completionListGenericConstraintsNames.ts index 3e60456f389..92d288dcb2a 100644 --- a/tests/cases/fourslash_old/completionListGenericConstraintsNames.ts +++ b/tests/cases/fourslash_old/completionListGenericConstraintsNames.ts @@ -17,9 +17,8 @@ //// } ////} - test.markers().forEach((marker) => { - goTo.position(marker.position, marker.fileName); - verify.memberListContains("T"); - verify.memberListContains("U"); - verify.memberListContains("M"); +goTo.eachMarker(() => { + verify.memberListContains("T"); + verify.memberListContains("U"); + verify.memberListContains("M"); }); diff --git a/tests/cases/unittests/matchFiles.ts b/tests/cases/unittests/matchFiles.ts index 91be2de8747..e3448136c08 100644 --- a/tests/cases/unittests/matchFiles.ts +++ b/tests/cases/unittests/matchFiles.ts @@ -898,6 +898,33 @@ namespace ts { assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories); assert.deepEqual(actual.errors, expected.errors); }); + it("with jsx=react-native, allowJs=false", () => { + const json = { + compilerOptions: { + jsx: "react-native", + allowJs: false + } + }; + const expected: ts.ParsedCommandLine = { + options: { + jsx: ts.JsxEmit.ReactNative, + allowJs: false + }, + errors: [], + fileNames: [ + "c:/dev/a.ts", + "c:/dev/b.tsx", + "c:/dev/c.tsx", + ], + wildcardDirectories: { + "c:/dev": ts.WatchDirectoryFlags.Recursive + } + }; + const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); + assert.deepEqual(actual.fileNames, expected.fileNames); + assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories); + assert.deepEqual(actual.errors, expected.errors); + }); it("with jsx=none, allowJs=true", () => { const json = { compilerOptions: { @@ -954,6 +981,35 @@ namespace ts { assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories); assert.deepEqual(actual.errors, expected.errors); }); + it("with jsx=react-native, allowJs=true", () => { + const json = { + compilerOptions: { + jsx: "react-native", + allowJs: true + } + }; + const expected: ts.ParsedCommandLine = { + options: { + jsx: ts.JsxEmit.ReactNative, + allowJs: true + }, + errors: [], + fileNames: [ + "c:/dev/a.ts", + "c:/dev/b.tsx", + "c:/dev/c.tsx", + "c:/dev/d.js", + "c:/dev/e.jsx", + ], + wildcardDirectories: { + "c:/dev": ts.WatchDirectoryFlags.Recursive + } + }; + const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); + assert.deepEqual(actual.fileNames, expected.fileNames); + assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories); + assert.deepEqual(actual.errors, expected.errors); + }); describe("with trailing recursive directory", () => { it("in includes", () => { const json = { @@ -1149,4 +1205,4 @@ namespace ts { }); }); }); -} \ No newline at end of file +} diff --git a/tests/webTestServer.ts b/tests/webTestServer.ts index 67bbce2a472..abfd71a8fff 100644 --- a/tests/webTestServer.ts +++ b/tests/webTestServer.ts @@ -315,7 +315,6 @@ if (browser === "chrome") { let defaultChromePath = ""; switch (os.platform()) { case "win32": - case "win64": defaultChromePath = "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe"; break; case "darwin": diff --git a/tslint.json b/tslint.json index 26657981a63..13de7acec63 100644 --- a/tslint.json +++ b/tslint.json @@ -46,6 +46,7 @@ "prefer-const": true, "no-increment-decrement": true, "object-literal-surrounding-space": true, - "no-type-assertion-whitespace": true + "no-type-assertion-whitespace": true, + "no-in-operator": true } }