diff --git a/Jakefile.js b/Jakefile.js index 1b5f698529b..424d18c6ec8 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -210,7 +210,7 @@ var librarySourceMap = [ { target: "lib.es2015.d.ts", sources: ["header.d.ts", "es2015.d.ts"] }, { target: "lib.es2016.d.ts", sources: ["header.d.ts", "es2016.d.ts"] }, { target: "lib.es2017.d.ts", sources: ["header.d.ts", "es2017.d.ts"] }, - + // JavaScript + all host library { target: "lib.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(hostsLibrarySources) }, { target: "lib.es6.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") } @@ -523,7 +523,7 @@ compileFile(servicesFileInBrowserTest, servicesSources,[builtLocalDirectory, cop var i = content.lastIndexOf("\n"); fs.writeFileSync(servicesFileInBrowserTest, content.substring(0, i) + "\r\n//# sourceURL=../built/local/typeScriptServices.js" + content.substring(i)); }); - + var serverFile = path.join(builtLocalDirectory, "tsserver.js"); compileFile(serverFile, serverSources,[builtLocalDirectory, copyright].concat(serverSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true); @@ -743,10 +743,10 @@ function runConsoleTests(defaultReporter, runInParallel) { }, function(e, status) { finish(status); }); - + } else { - // run task to load all tests and partition them between workers + // run task to load all tests and partition them between workers var cmd = "mocha " + " -R min " + colors + run; console.log(cmd); exec(cmd, function() { @@ -759,9 +759,9 @@ function runConsoleTests(defaultReporter, runInParallel) { var configPath = path.join(taskConfigsFolder, f); var workerCmd = "mocha" + " -t " + testTimeout + " -R " + reporter + " " + colors + " " + run + " --config='" + configPath + "'"; console.log(workerCmd); - exec(workerCmd, finishWorker, finishWorker) + exec(workerCmd, finishWorker, finishWorker) }); - + function finishWorker(e, errorStatus) { counter--; if (firstErrorStatus === undefined && errorStatus !== undefined) { @@ -785,11 +785,11 @@ function runConsoleTests(defaultReporter, runInParallel) { } }); } - + function failWithStatus(status) { fail("Process exited with code " + status); } - + function finish(errorStatus) { deleteTemporaryProjectOutput(); if (errorStatus !== undefined) { @@ -857,7 +857,7 @@ task("runtests-browser", ["tests", "browserify", builtLocalDirectory, servicesFi } tests = tests ? tests : ''; - var cmd = host + " tests/webTestServer.js " + port + " " + browser + " " + tests; + var cmd = host + " tests/webTestServer.js " + port + " " + browser + " " + JSON.stringify(tests); console.log(cmd); exec(cmd); }, {async: true}); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b8f078ea9a5..650bc488b0e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8091,13 +8091,22 @@ namespace ts { return expression; } + function getControlFlowContainer(node: Node): Node { + while (true) { + node = node.parent; + if (isFunctionLike(node) || node.kind === SyntaxKind.ModuleBlock || node.kind === SyntaxKind.SourceFile || node.kind === SyntaxKind.PropertyDeclaration) { + return node; + } + } + } + function isDeclarationIncludedInFlow(reference: Node, declaration: Declaration, includeOuterFunctions: boolean) { - const declarationContainer = getContainingFunctionOrModule(declaration); - let container = getContainingFunctionOrModule(reference); + const declarationContainer = getControlFlowContainer(declaration); + let container = getControlFlowContainer(reference); while (container !== declarationContainer && (container.kind === SyntaxKind.FunctionExpression || container.kind === SyntaxKind.ArrowFunction) && (includeOuterFunctions || getImmediatelyInvokedFunctionExpression(container))) { - container = getContainingFunctionOrModule(container); + container = getControlFlowContainer(container); } return container === declarationContainer; } @@ -9991,24 +10000,14 @@ namespace ts { } const propType = getTypeOfSymbol(prop); + // Only compute control flow type if this is a property access expression that isn't an + // assignment target, and the referenced property was declared as a variable, property, + // accessor, or optional method. if (node.kind !== SyntaxKind.PropertyAccessExpression || isAssignmentTarget(node) || - !(propType.flags & TypeFlags.Union) && !(prop.flags & (SymbolFlags.Variable | SymbolFlags.Property | SymbolFlags.Accessor))) { + !(prop.flags & (SymbolFlags.Variable | SymbolFlags.Property | SymbolFlags.Accessor)) && + !(prop.flags & SymbolFlags.Method && propType.flags & TypeFlags.Union)) { return propType; } - const leftmostNode = getLeftmostIdentifierOrThis(node); - if (!leftmostNode) { - return propType; - } - if (leftmostNode.kind === SyntaxKind.Identifier) { - const leftmostSymbol = getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(leftmostNode)); - if (!leftmostSymbol) { - return propType; - } - const declaration = leftmostSymbol.valueDeclaration; - if (!declaration || declaration.kind !== SyntaxKind.VariableDeclaration && declaration.kind !== SyntaxKind.Parameter && declaration.kind !== SyntaxKind.BindingElement) { - return propType; - } - } return getFlowTypeOfReference(node, propType, /*assumeInitialized*/ true, /*includeOuterFunctions*/ false); } @@ -10323,8 +10322,8 @@ namespace ts { return -1; } - function hasCorrectArity(node: CallLikeExpression, args: Expression[], signature: Signature) { - let adjustedArgCount: number; // Apparent number of arguments we will have in this call + function hasCorrectArity(node: CallLikeExpression, args: Expression[], signature: Signature, signatureHelpTrailingComma = false) { + let argCount: number; // Apparent number of arguments we will have in this call let typeArguments: NodeArray; // Type arguments (undefined if none) let callIsIncomplete: boolean; // In incomplete call we want to be lenient when we have too few arguments let isDecorator: boolean; @@ -10335,7 +10334,7 @@ namespace ts { // Even if the call is incomplete, we'll have a missing expression as our last argument, // so we can say the count is just the arg list length - adjustedArgCount = args.length; + argCount = args.length; typeArguments = undefined; if (tagExpression.template.kind === SyntaxKind.TemplateExpression) { @@ -10358,7 +10357,7 @@ namespace ts { else if (node.kind === SyntaxKind.Decorator) { isDecorator = true; typeArguments = undefined; - adjustedArgCount = getEffectiveArgumentCount(node, /*args*/ undefined, signature); + argCount = getEffectiveArgumentCount(node, /*args*/ undefined, signature); } else { const callExpression = node; @@ -10369,8 +10368,7 @@ namespace ts { return signature.minArgumentCount === 0; } - // For IDE scenarios we may have an incomplete call, so a trailing comma is tantamount to adding another argument. - adjustedArgCount = callExpression.arguments.hasTrailingComma ? args.length + 1 : args.length; + argCount = signatureHelpTrailingComma ? args.length + 1 : args.length; // If we are missing the close paren, the call is incomplete. callIsIncomplete = (callExpression).arguments.end === callExpression.end; @@ -10394,12 +10392,12 @@ namespace ts { } // Too many arguments implies incorrect arity. - if (!signature.hasRestParameter && adjustedArgCount > signature.parameters.length) { + if (!signature.hasRestParameter && argCount > signature.parameters.length) { return false; } // If the call is incomplete, we should skip the lower bound check. - const hasEnoughArguments = adjustedArgCount >= signature.minArgumentCount; + const hasEnoughArguments = argCount >= signature.minArgumentCount; return callIsIncomplete || hasEnoughArguments; } @@ -10971,6 +10969,11 @@ namespace ts { let resultOfFailedInference: InferenceContext; let result: Signature; + // If we are in signature help, a trailing comma indicates that we intend to provide another argument, + // so we will only accept overloads with arity at least 1 higher than the current number of provided arguments. + const signatureHelpTrailingComma = + candidatesOutArray && node.kind === SyntaxKind.CallExpression && (node).arguments.hasTrailingComma; + // Section 4.12.1: // if the candidate list contains one or more signatures for which the type of each argument // expression is a subtype of each corresponding parameter type, the return type of the first @@ -10982,14 +10985,14 @@ namespace ts { // is just important for choosing the best signature. So in the case where there is only one // signature, the subtype pass is useless. So skipping it is an optimization. if (candidates.length > 1) { - result = chooseOverload(candidates, subtypeRelation); + result = chooseOverload(candidates, subtypeRelation, signatureHelpTrailingComma); } if (!result) { // Reinitialize these pointers for round two candidateForArgumentError = undefined; candidateForTypeArgumentError = undefined; resultOfFailedInference = undefined; - result = chooseOverload(candidates, assignableRelation); + result = chooseOverload(candidates, assignableRelation, signatureHelpTrailingComma); } if (result) { return result; @@ -11060,9 +11063,9 @@ namespace ts { diagnostics.add(createDiagnosticForNodeFromMessageChain(node, errorInfo)); } - function chooseOverload(candidates: Signature[], relation: Map) { + function chooseOverload(candidates: Signature[], relation: Map, signatureHelpTrailingComma = false) { for (const originalCandidate of candidates) { - if (!hasCorrectArity(node, args, originalCandidate)) { + if (!hasCorrectArity(node, args, originalCandidate, signatureHelpTrailingComma)) { continue; } @@ -11279,7 +11282,7 @@ namespace ts { const declaringClassDeclaration = getClassLikeDeclarationOfSymbol(declaration.parent.symbol); const declaringClass = getDeclaredTypeOfSymbol(declaration.parent.symbol); - // A private or protected constructor can only be instantiated within it's own class + // A private or protected constructor can only be instantiated within it's own class if (!isNodeWithinClass(node, declaringClassDeclaration)) { if (flags & NodeFlags.Private) { error(node, Diagnostics.Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration, typeToString(declaringClass)); @@ -15107,7 +15110,7 @@ namespace ts { // In a 'switch' statement, each 'case' expression must be of a type that is comparable // to or from the type of the 'switch' expression. const caseType = checkExpression(caseClause.expression); - if (!isTypeComparableTo(expressionType, caseType)) { + if (!isTypeEqualityComparableTo(expressionType, caseType)) { // expressionType is not comparable to caseType, try the reversed check and report errors if it fails checkTypeComparableTo(caseType, expressionType, caseClause.expression, /*headMessage*/ undefined); } @@ -16142,12 +16145,12 @@ namespace ts { const symbol = getSymbolOfNode(node); const target = resolveAlias(symbol); if (target !== unknownSymbol) { - // For external modules symbol represent local symbol for an alias. + // For external modules symbol represent local symbol for an alias. // This local symbol will merge any other local declarations (excluding other aliases) // and symbol.flags will contains combined representation for all merged declaration. // Based on symbol.flags we can compute a set of excluded meanings (meaning that resolved alias should not have, - // otherwise it will conflict with some local declaration). Note that in addition to normal flags we include matching SymbolFlags.Export* - // in order to prevent collisions with declarations that were exported from the current module (they still contribute to local names). + // otherwise it will conflict with some local declaration). Note that in addition to normal flags we include matching SymbolFlags.Export* + // in order to prevent collisions with declarations that were exported from the current module (they still contribute to local names). const excludedMeanings = (symbol.flags & (SymbolFlags.Value | SymbolFlags.ExportValue) ? SymbolFlags.Value : 0) | (symbol.flags & SymbolFlags.Type ? SymbolFlags.Type : 0) | @@ -16346,7 +16349,7 @@ namespace ts { continue; } const { declarations, flags } = exports[id]; - // ECMA262: 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries. + // 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; @@ -17051,10 +17054,10 @@ namespace ts { } // Gets the type of object literal or array literal of destructuring assignment. - // { a } from + // { a } from // for ( { a } of elems) { // } - // [ a ] from + // [ a ] from // [a] = [ some array ...] function getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(expr: Expression): Type { Debug.assert(expr.kind === SyntaxKind.ObjectLiteralExpression || expr.kind === SyntaxKind.ArrayLiteralExpression); @@ -17087,10 +17090,10 @@ namespace ts { } // Gets the property symbol corresponding to the property in destructuring assignment - // 'property1' from + // 'property1' from // for ( { property1: a } of elems) { // } - // 'property1' at location 'a' from: + // 'property1' at location 'a' from: // [a] = [ property1, property2 ] function getPropertySymbolOfDestructuringAssignment(location: Identifier) { // Get the type of the object or array literal and then look for property of given name in the type @@ -18029,10 +18032,6 @@ namespace ts { } function checkGrammarParameterList(parameters: NodeArray) { - if (checkGrammarForDisallowedTrailingComma(parameters)) { - return true; - } - let seenOptionalParameter = false; const parameterCount = parameters.length; @@ -18151,8 +18150,7 @@ namespace ts { } function checkGrammarArguments(node: CallExpression, args: NodeArray): boolean { - return checkGrammarForDisallowedTrailingComma(args) || - checkGrammarForOmittedArgument(node, args); + return checkGrammarForOmittedArgument(node, args); } function checkGrammarHeritageClause(node: HeritageClause): boolean { diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 397b135bf23..bda1c7c0cb6 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -95,7 +95,7 @@ namespace ts { // Emit reference in dts, if the file reference was not already emitted if (referencedFile && !contains(emittedReferencedFiles, referencedFile)) { // Add a reference to generated dts file, - // global file reference is added only + // global file reference is added only // - if it is not bundled emit (because otherwise it would be self reference) // - and it is not already added if (writeReferencePath(referencedFile, !isBundledEmit && !addedGlobalFileReference)) { @@ -148,7 +148,7 @@ namespace ts { if (!isBundledEmit && isExternalModule(sourceFile) && sourceFile.moduleAugmentations.length && !resultHasExternalModuleIndicator) { // if file was external module with augmentations - this fact should be preserved in .d.ts as well. - // in case if we didn't write any external module specifiers in .d.ts we need to emit something + // in case if we didn't write any external module specifiers in .d.ts we need to emit something // that will force compiler to think that this file is an external module - 'export {}' is a reasonable choice here. write("export {};"); writeLine(); @@ -766,7 +766,7 @@ namespace ts { function emitExternalModuleSpecifier(parent: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration) { // emitExternalModuleSpecifier is usually called when we emit something in the.d.ts file that will make it an external module (i.e. import/export declarations). - // the only case when it is not true is when we call it to emit correct name for module augmentation - d.ts files with just module augmentations are not considered + // the only case when it is not true is when we call it to emit correct name for module augmentation - d.ts files with just module augmentations are not considered // external modules since they are indistinguishable from script files with ambient modules. To fix this in such d.ts files we'll emit top level 'export {}' // so compiler will treat them as external modules. resultHasExternalModuleIndicator = resultHasExternalModuleIndicator || parent.kind !== SyntaxKind.ModuleDeclaration; diff --git a/src/compiler/sourcemap.ts b/src/compiler/sourcemap.ts index 86bad38cb6e..cf7c3d1eaae 100644 --- a/src/compiler/sourcemap.ts +++ b/src/compiler/sourcemap.ts @@ -168,7 +168,7 @@ namespace ts { sourceMapData.sourceMapDecodedMappings[sourceMapData.sourceMapDecodedMappings.length - 1] : defaultLastEncodedSourceMapSpan; - // TODO: Update lastEncodedNameIndex + // TODO: Update lastEncodedNameIndex // Since we dont support this any more, lets not worry about it right now. // When we start supporting nameIndex, we will get back to this diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 4c0e7a036db..a86b1ed708d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2218,7 +2218,10 @@ namespace ts { ObjectType = Class | Interface | Reference | Tuple | Anonymous, UnionOrIntersection = Union | Intersection, StructuredType = ObjectType | Union | Intersection, - Narrowable = Any | ObjectType | Union | TypeParameter, + + // 'Narrowable' types are types where narrowing actually narrows. + // This *should* be every type other than null, undefined, void, and never + Narrowable = Any | StructuredType | TypeParameter | StringLike | NumberLike | Boolean | ESSymbol, /* @internal */ RequiresWidening = ContainsWideningType | ContainsObjectLiteral, /* @internal */ diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 74ea3459b23..721a94e8137 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -302,8 +302,8 @@ namespace ts { return getTokenPosOfNode(node.jsDocComments[0]); } - // For a syntax list, it is possible that one of its children has JSDocComment nodes, while - // the syntax list itself considers them as normal trivia. Therefore if we simply skip + // For a syntax list, it is possible that one of its children has JSDocComment nodes, while + // the syntax list itself considers them as normal trivia. Therefore if we simply skip // trivia for the list, we may have skipped the JSDocComment as well. So we should process its // first child to determine the actual position of its first token. if (node.kind === SyntaxKind.SyntaxList && (node)._children.length > 0) { @@ -880,15 +880,6 @@ namespace ts { } } - export function getContainingFunctionOrModule(node: Node): Node { - while (true) { - node = node.parent; - if (isFunctionLike(node) || node.kind === SyntaxKind.ModuleDeclaration || node.kind === SyntaxKind.SourceFile) { - return node; - } - } - } - export function getContainingClass(node: Node): ClassLikeDeclaration { while (true) { node = node.parent; diff --git a/src/harness/compilerRunner.ts b/src/harness/compilerRunner.ts index e822b31584e..1834b0b3bbc 100644 --- a/src/harness/compilerRunner.ts +++ b/src/harness/compilerRunner.ts @@ -154,7 +154,7 @@ class CompilerBaselineRunner extends RunnerBase { it (`Correct module resolution tracing for ${fileName}`, () => { if (options.traceResolution) { - Harness.Baseline.runBaseline("Correct sourcemap content for " + fileName, justName.replace(/\.tsx?$/, ".trace.json"), () => { + Harness.Baseline.runBaseline("Correct module resolution tracing for " + fileName, justName.replace(/\.tsx?$/, ".trace.json"), () => { return JSON.stringify(result.traceResults || [], undefined, 4); }); } diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index bd556c659c7..c05fca5bb47 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -746,7 +746,7 @@ namespace FourSlash { } const missingItem = { fileName: fileName, start: start, end: end, isWriteAccess: isWriteAccess }; - this.raiseError(`verifyReferencesAtPositionListContains failed - could not find the item: ${JSON.stringify(missingItem, undefined, 2)} in the returned list: (${JSON.stringify(references, undefined, 2)})`); + this.raiseError(`verifyReferencesAtPositionListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(references)})`); } public verifyReferencesCountIs(count: number, localFilesOnly = true) { @@ -800,7 +800,7 @@ namespace FourSlash { private testDiagnostics(expected: string, diagnostics: ts.Diagnostic[]) { const realized = ts.realizeDiagnostics(diagnostics, "\r\n"); - const actual = JSON.stringify(realized, undefined, 2); + const actual = stringify(realized); assert.equal(actual, expected); } @@ -875,7 +875,7 @@ namespace FourSlash { } if (ranges.length !== references.length) { - this.raiseError("Rename location count does not match result.\n\nExpected: " + JSON.stringify(ranges, undefined, 2) + "\n\nActual:" + JSON.stringify(references, undefined, 2)); + this.raiseError("Rename location count does not match result.\n\nExpected: " + stringify(ranges) + "\n\nActual:" + stringify(references)); } ranges = ranges.sort((r1, r2) => r1.start - r2.start); @@ -888,7 +888,7 @@ namespace FourSlash { if (reference.textSpan.start !== range.start || ts.textSpanEnd(reference.textSpan) !== range.end) { - this.raiseError("Rename location results do not match.\n\nExpected: " + JSON.stringify(ranges, undefined, 2) + "\n\nActual:" + JSON.stringify(references, undefined, 2)); + this.raiseError("Rename location results do not match.\n\nExpected: " + stringify(ranges) + "\n\nActual:" + JSON.stringify(references)); } } } @@ -972,7 +972,7 @@ namespace FourSlash { } else { if (actual) { - this.raiseError(`Expected no signature help, but got "${JSON.stringify(actual, undefined, 2)}"`); + this.raiseError(`Expected no signature help, but got "${stringify(actual)}"`); } } } @@ -1176,7 +1176,7 @@ namespace FourSlash { public printCurrentParameterHelp() { const help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); - Harness.IO.log(JSON.stringify(help, undefined, 2)); + Harness.IO.log(stringify(help)); } public printCurrentQuickInfo() { @@ -1218,7 +1218,7 @@ namespace FourSlash { public printCurrentSignatureHelp() { const sigHelp = this.getActiveSignatureHelpItem(); - Harness.IO.log(JSON.stringify(sigHelp, undefined, 2)); + Harness.IO.log(stringify(sigHelp)); } public printMemberListMembers() { @@ -1248,7 +1248,7 @@ namespace FourSlash { public printReferences() { const references = this.getReferencesAtCaret(); ts.forEach(references, entry => { - Harness.IO.log(JSON.stringify(entry, undefined, 2)); + Harness.IO.log(stringify(entry)); }); } @@ -1745,8 +1745,8 @@ namespace FourSlash { function jsonMismatchString() { return Harness.IO.newLine() + - "expected: '" + Harness.IO.newLine() + JSON.stringify(expected, undefined, 2) + "'" + Harness.IO.newLine() + - "actual: '" + Harness.IO.newLine() + JSON.stringify(actual, undefined, 2) + "'"; + "expected: '" + Harness.IO.newLine() + stringify(expected) + "'" + Harness.IO.newLine() + + "actual: '" + Harness.IO.newLine() + stringify(actual) + "'"; } } @@ -1961,14 +1961,14 @@ namespace FourSlash { // if there was an explicit match kind specified, then it should be validated. if (matchKind !== undefined) { const missingItem = { name: name, kind: kind, searchValue: searchValue, matchKind: matchKind, fileName: fileName, parentName: parentName }; - this.raiseError(`verifyNavigationItemsListContains failed - could not find the item: ${JSON.stringify(missingItem, undefined, 2)} in the returned list: (${JSON.stringify(items, undefined, 2)})`); + this.raiseError(`verifyNavigationItemsListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(items)})`); } } public verifyNavigationBar(json: any) { const items = this.languageService.getNavigationBarItems(this.activeFile.fileName); if (JSON.stringify(items, replacer) !== JSON.stringify(json)) { - this.raiseError(`verifyNavigationBar failed - expected: ${JSON.stringify(json, undefined, 2)}, got: ${JSON.stringify(items, replacer, 2)}`); + this.raiseError(`verifyNavigationBar failed - expected: ${stringify(json)}, got: ${stringify(items, replacer)}`); } // Make the data easier to read. @@ -2031,7 +2031,7 @@ namespace FourSlash { } const missingItem = { fileName: fileName, start: start, end: end, isWriteAccess: isWriteAccess }; - this.raiseError(`verifyOccurrencesAtPositionListContains failed - could not find the item: ${JSON.stringify(missingItem, undefined, 2)} in the returned list: (${JSON.stringify(occurrences, undefined, 2)})`); + this.raiseError(`verifyOccurrencesAtPositionListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(occurrences)})`); } public verifyOccurrencesAtPositionListCount(expectedCount: number) { @@ -2070,7 +2070,7 @@ namespace FourSlash { } const missingItem = { fileName: fileName, start: start, end: end, kind: kind }; - this.raiseError(`verifyDocumentHighlightsAtPositionListContains failed - could not find the item: ${JSON.stringify(missingItem, undefined, 2)} in the returned list: (${JSON.stringify(documentHighlights, undefined, 2)})`); + this.raiseError(`verifyDocumentHighlightsAtPositionListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(documentHighlights)})`); } public verifyDocumentHighlightsAtPositionListCount(expectedCount: number, fileNamesToSearch: string[]) { @@ -2136,9 +2136,9 @@ namespace FourSlash { } } - const itemsString = items.map((item) => JSON.stringify({ name: item.name, kind: item.kind }, undefined, 2)).join(",\n"); + const itemsString = items.map(item => stringify({ name: item.name, kind: item.kind })).join(",\n"); - this.raiseError(`Expected "${JSON.stringify({ name, text, documentation, kind }, undefined, 2)}" to be in list [${itemsString}]`); + this.raiseError(`Expected "${stringify({ name, text, documentation, kind })}" to be in list [${itemsString}]`); } private findFile(indexOrName: any) { @@ -2701,6 +2701,10 @@ ${code} } return result; } + + function stringify(data: any, replacer?: (key: string, value: any) => any): string { + return JSON.stringify(data, replacer, 2); + } } namespace FourSlashInterface { diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index 60a0813b05d..64d07b1d88a 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -244,7 +244,7 @@ class ProjectRunner extends RunnerBase { mapRoot: testCase.resolveMapRoot && testCase.mapRoot ? Harness.IO.resolvePath(testCase.mapRoot) : testCase.mapRoot, sourceRoot: testCase.resolveSourceRoot && testCase.sourceRoot ? Harness.IO.resolvePath(testCase.sourceRoot) : testCase.sourceRoot, module: moduleKind, - moduleResolution: ts.ModuleResolutionKind.Classic, // currently all tests use classic module resolution kind, this will change in the future + moduleResolution: ts.ModuleResolutionKind.Classic, // currently all tests use classic module resolution kind, this will change in the future }; // Set the values specified using json const optionNameMap: ts.Map = {}; diff --git a/src/harness/runnerbase.ts b/src/harness/runnerbase.ts index 81da0907714..a16eddcbeec 100644 --- a/src/harness/runnerbase.ts +++ b/src/harness/runnerbase.ts @@ -24,7 +24,7 @@ abstract class RunnerBase { abstract enumerateTestFiles(): string[]; - /** Setup the runner's tests so that they are ready to be executed by the harness + /** Setup the runner's tests so that they are ready to be executed by the harness * The first test should be a describe/it block that sets up the harness's compiler instance appropriately */ public abstract initializeTests(): void; diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index dfd2bd4ff0c..8447b31fc89 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -136,12 +136,24 @@ interface ObjectConstructor { */ getOwnPropertyNames(o: any): string[]; + /** + * Creates an object that has null prototype. + * @param o Object to use as a prototype. May be null + */ + create(o: null): any; + + /** + * 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; + /** * 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: any, properties: PropertyDescriptorMap): any; /** * Adds a property to an object, or modifies attributes of an existing property. diff --git a/src/server/client.ts b/src/server/client.ts index 5c576347d19..b0a1a8ec9e9 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -459,7 +459,7 @@ namespace ts.server { kindModifiers: item.kindModifiers || "", spans: item.spans.map(span => createTextSpanFromBounds(this.lineOffsetToPosition(fileName, span.start), this.lineOffsetToPosition(fileName, span.end))), childItems: this.decodeNavigationBarItems(item.childItems, fileName), - indent: 0, + indent: item.indent, bolded: false, grayed: false })); diff --git a/src/server/protocol.d.ts b/src/server/protocol.d.ts index ad2b7cd07ee..4702265e663 100644 --- a/src/server/protocol.d.ts +++ b/src/server/protocol.d.ts @@ -1263,6 +1263,11 @@ declare namespace ts.server.protocol { * Optional children. */ childItems?: NavigationBarItem[]; + + /** + * Number of levels deep this item should appear. + */ + indent: number; } export interface NavBarResponse extends Response { diff --git a/src/server/session.ts b/src/server/session.ts index d943acc0ef1..c7f3a08dea0 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -879,7 +879,8 @@ namespace ts.server { start: scriptInfo.positionToLineOffset(span.start), end: scriptInfo.positionToLineOffset(ts.textSpanEnd(span)) })), - childItems: this.decorateNavigationBarItem(project, fileName, item.childItems) + childItems: this.decorateNavigationBarItem(project, fileName, item.childItems), + indent: item.indent })); } diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index 12b127ffd2d..fea4ae6bffa 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0. +// Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0. // See LICENSE.txt in the project root for complete license information. /// @@ -19,8 +19,8 @@ namespace ts.BreakpointResolver { if (sourceFile.getLineAndCharacterOfPosition(tokenAtLocation.getStart(sourceFile)).line > lineOfPosition) { // Get previous token if the token is returned starts on new line // eg: let x =10; |--- cursor is here - // let y = 10; - // token at position will return let keyword on second line as the token but we would like to use + // let y = 10; + // token at position will return let keyword on second line as the token but we would like to use // token on same line if trailing trivia (comments or white spaces on same line) part of the last token on that line tokenAtLocation = findPrecedingToken(tokenAtLocation.pos, sourceFile); @@ -261,7 +261,7 @@ namespace ts.BreakpointResolver { } // Set breakpoint on identifier element of destructuring pattern - // a or ...c or d: x from + // a or ...c or d: x from // [a, b, ...c] or { a, b } or { d: x } from destructuring pattern if ((node.kind === SyntaxKind.Identifier || node.kind == SyntaxKind.SpreadElementExpression || @@ -275,7 +275,7 @@ namespace ts.BreakpointResolver { const binaryExpression = node; // Set breakpoint in destructuring pattern if its destructuring assignment // [a, b, c] or {a, b, c} of - // [a, b, c] = expression or + // [a, b, c] = expression or // {a, b, c} = expression if (isArrayLiteralOrObjectLiteralDestructuringPattern(binaryExpression.left)) { return spanInArrayLiteralOrObjectLiteralDestructuringPattern( @@ -285,8 +285,8 @@ namespace ts.BreakpointResolver { if (binaryExpression.operatorToken.kind === SyntaxKind.EqualsToken && isArrayLiteralOrObjectLiteralDestructuringPattern(binaryExpression.parent)) { // Set breakpoint on assignment expression element of destructuring pattern - // a = expression of - // [a = expression, b, c] = someExpression or + // a = expression of + // [a = expression, b, c] = someExpression or // { a = expression, b, c } = someExpression return textSpan(node); } @@ -403,7 +403,7 @@ namespace ts.BreakpointResolver { const declarations = variableDeclaration.parent.declarations; if (declarations && declarations[0] !== variableDeclaration) { // If we cannot set breakpoint on this declaration, set it on previous one - // Because the variable declaration may be binding pattern and + // Because the variable declaration may be binding pattern and // we would like to set breakpoint in last binding element if that's the case, // use preceding token instead return spanInNode(findPrecedingToken(variableDeclaration.pos, sourceFile, variableDeclaration.parent)); @@ -549,7 +549,7 @@ namespace ts.BreakpointResolver { return spanInNode(firstBindingElement); } - // Could be ArrayLiteral from destructuring assignment or + // Could be ArrayLiteral from destructuring assignment or // just nested element in another destructuring assignment // set breakpoint on assignment when parent is destructuring assignment // Otherwise set breakpoint for this element diff --git a/src/services/formatting/formattingScanner.ts b/src/services/formatting/formattingScanner.ts index ff003e08007..babf0db3fd5 100644 --- a/src/services/formatting/formattingScanner.ts +++ b/src/services/formatting/formattingScanner.ts @@ -268,9 +268,9 @@ namespace ts.formatting { return startPos < endPos && current !== SyntaxKind.EndOfFileToken && !isTrivia(current); } - // when containing node in the tree is token + // when containing node in the tree is token // but its kind differs from the kind that was returned by the scanner, - // then kind needs to be fixed. This might happen in cases + // then kind needs to be fixed. This might happen in cases // when parser interprets token differently, i.e keyword treated as identifier function fixTokenKind(tokenInfo: TokenInfo, container: Node): TokenInfo { if (isToken(container) && tokenInfo.token.kind !== container.kind) { diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 47a204a5b7e..b4916025af2 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -554,17 +554,17 @@ namespace ts.formatting { static IsSameLineTokenOrBeforeMultilineBlockContext(context: FormattingContext): boolean { //// This check is mainly used inside SpaceBeforeOpenBraceInControl and SpaceBeforeOpenBraceInFunction. //// - //// Ex: + //// Ex: //// if (1) { .... //// * ) and { are on the same line so apply the rule. Here we don't care whether it's same or multi block context //// - //// Ex: + //// Ex: //// if (1) //// { ... } //// * ) and { are on different lines. We only need to format if the block is multiline context. So in this case we don't format. //// //// Ex: - //// if (1) + //// if (1) //// { ... //// } //// * ) and { are on different lines. We only need to format if the block is multiline context. So in this case we format. diff --git a/src/services/formatting/rulesMap.ts b/src/services/formatting/rulesMap.ts index 7f635ea07e3..703ca566bd2 100644 --- a/src/services/formatting/rulesMap.ts +++ b/src/services/formatting/rulesMap.ts @@ -95,9 +95,9 @@ namespace ts.formatting { //// 4- Context rules with any token combination //// 5- Non-context rules with specific token combination //// 6- Non-context rules with any token combination - //// + //// //// The member rulesInsertionIndexBitmap is used to describe the number of rules - //// in each sub-bucket (above) hence can be used to know the index of where to insert + //// in each sub-bucket (above) hence can be used to know the index of where to insert //// the next rule. It's a bitmap which contains 6 different sections each is given 5 bits. //// //// Example: diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index 49707263c1f..e9afb6925b5 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -9,7 +9,7 @@ namespace ts.NavigateTo { // This means "compare in a case insensitive manner." const baseSensitivity: Intl.CollatorOptions = { sensitivity: "base" }; - // Search the declarations in all files and output matched NavigateToItem into array of NavigateToItem[] + // Search the declarations in all files and output matched NavigateToItem into array of NavigateToItem[] forEach(program.getSourceFiles(), sourceFile => { cancellationToken.throwIfCancellationRequested(); @@ -17,7 +17,7 @@ namespace ts.NavigateTo { for (const name in nameToDeclarations) { const declarations = getProperty(nameToDeclarations, name); if (declarations) { - // First do a quick check to see if the name of the declaration matches the + // 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); @@ -26,7 +26,7 @@ namespace ts.NavigateTo { } for (const declaration of declarations) { - // It was a match! If the pattern has dots in it, then also see if the + // It was a match! If the pattern has dots in it, then also see if the // declaration container matches as well. if (patternMatcher.patternContainsDots) { const containers = getContainers(declaration); diff --git a/src/services/services.ts b/src/services/services.ts index b05ab9d2e32..9932a136383 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2657,7 +2657,7 @@ namespace ts { return false; } - /** + /** * Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 } */ function getContainingObjectLiteralElement(node: Node): ObjectLiteralElement { @@ -7606,11 +7606,11 @@ namespace ts { function isValidBraceCompletionAtPostion(fileName: string, position: number, openingBrace: number): boolean { - // '<' is currently not supported, figuring out if we're in a Generic Type vs. a comparison is too + // '<' is currently not supported, figuring out if we're in a Generic Type vs. a comparison is too // expensive to do during typing scenarios // i.e. whether we're dealing with: // var x = new foo<| ( with class foo{} ) - // or + // or // var y = 3 <| if (openingBrace === CharacterCodes.lessThan) { return false; diff --git a/src/services/shims.ts b/src/services/shims.ts index eb9c28ff7ac..94ff3367e3c 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -295,7 +295,7 @@ namespace ts { constructor(private shimHost: LanguageServiceShimHost) { // if shimHost is a COM object then property check will become method call with no arguments. - // 'in' does not have this effect. + // 'in' does not have this effect. if ("getModuleResolutionsForFile" in this.shimHost) { this.resolveModuleNames = (moduleNames: string[], containingFile: string) => { const resolutionsInFile = >JSON.parse(this.shimHost.getModuleResolutionsForFile(containingFile)); @@ -966,7 +966,7 @@ namespace ts { return this.forwardJSONCall( "getPreProcessedFileInfo('" + fileName + "')", () => { - // for now treat files as JavaScript + // for now treat files as JavaScript const result = preProcessFile(sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength()), /* readImportFiles */ true, /* detectJavaScriptImports */ true); return { referencedFiles: this.convertFileReferences(result.referencedFiles), diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 53fb7a474a7..27077406489 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -3,9 +3,9 @@ namespace ts.SignatureHelp { // A partially written generic type expression is not guaranteed to have the correct syntax tree. the expression could be parsed as less than/greater than expression or a comma expression - // or some other combination depending on what the user has typed so far. For the purposes of signature help we need to consider any location after "<" as a possible generic type reference. - // To do this, the method will back parse the expression starting at the position required. it will try to parse the current expression as a generic type expression, if it did succeed it - // will return the generic identifier that started the expression (e.g. "foo" in "foo'. So, in the case where the last child is a comma, we increase the // arg count by one to compensate. // - // Note: this subtlety only applies to the last comma. If you had "Foo(a,," then - // we'll have: 'a' '' '' + // Note: this subtlety only applies to the last comma. If you had "Foo(a,," then + // we'll have: 'a' '' '' // That will give us 2 non-commas. We then add one for the last comma, givin us an // arg count of 3. const listChildren = argumentsList.getChildren(); diff --git a/tests/baselines/reference/ArrowFunction2.errors.txt b/tests/baselines/reference/ArrowFunction2.errors.txt deleted file mode 100644 index 3b9ba21f15a..00000000000 --- a/tests/baselines/reference/ArrowFunction2.errors.txt +++ /dev/null @@ -1,12 +0,0 @@ -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/ArrowFunction2.ts(1,13): error TS2304: Cannot find name 'b'. -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/ArrowFunction2.ts(1,14): error TS1009: Trailing comma not allowed. - - -==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/ArrowFunction2.ts (2 errors) ==== - var v = (a: b,) => { - ~ -!!! error TS2304: Cannot find name 'b'. - ~ -!!! error TS1009: Trailing comma not allowed. - - }; \ No newline at end of file diff --git a/tests/baselines/reference/ArrowFunction2.js b/tests/baselines/reference/ArrowFunction2.js deleted file mode 100644 index fa6b8bf3b9e..00000000000 --- a/tests/baselines/reference/ArrowFunction2.js +++ /dev/null @@ -1,8 +0,0 @@ -//// [ArrowFunction2.ts] -var v = (a: b,) => { - -}; - -//// [ArrowFunction2.js] -var v = function (a) { -}; diff --git a/tests/baselines/reference/classStaticPropertyTypeGuard.js b/tests/baselines/reference/classStaticPropertyTypeGuard.js new file mode 100644 index 00000000000..872f78db4c4 --- /dev/null +++ b/tests/baselines/reference/classStaticPropertyTypeGuard.js @@ -0,0 +1,32 @@ +//// [classStaticPropertyTypeGuard.ts] + +// Repro from #8923 + +class A { + private static _a: string | undefined; + + public get a(): string { + if (A._a) { + return A._a; // is possibly null or undefined. + } + return A._a = 'helloworld'; + } +} + +//// [classStaticPropertyTypeGuard.js] +// Repro from #8923 +var A = (function () { + function A() { + } + Object.defineProperty(A.prototype, "a", { + get: function () { + if (A._a) { + return A._a; // is possibly null or undefined. + } + return A._a = 'helloworld'; + }, + enumerable: true, + configurable: true + }); + return A; +}()); diff --git a/tests/baselines/reference/classStaticPropertyTypeGuard.symbols b/tests/baselines/reference/classStaticPropertyTypeGuard.symbols new file mode 100644 index 00000000000..c4d2acd50b0 --- /dev/null +++ b/tests/baselines/reference/classStaticPropertyTypeGuard.symbols @@ -0,0 +1,29 @@ +=== tests/cases/compiler/classStaticPropertyTypeGuard.ts === + +// Repro from #8923 + +class A { +>A : Symbol(A, Decl(classStaticPropertyTypeGuard.ts, 0, 0)) + + private static _a: string | undefined; +>_a : Symbol(A._a, Decl(classStaticPropertyTypeGuard.ts, 3, 9)) + + public get a(): string { +>a : Symbol(A.a, Decl(classStaticPropertyTypeGuard.ts, 4, 42)) + + if (A._a) { +>A._a : Symbol(A._a, Decl(classStaticPropertyTypeGuard.ts, 3, 9)) +>A : Symbol(A, Decl(classStaticPropertyTypeGuard.ts, 0, 0)) +>_a : Symbol(A._a, Decl(classStaticPropertyTypeGuard.ts, 3, 9)) + + return A._a; // is possibly null or undefined. +>A._a : Symbol(A._a, Decl(classStaticPropertyTypeGuard.ts, 3, 9)) +>A : Symbol(A, Decl(classStaticPropertyTypeGuard.ts, 0, 0)) +>_a : Symbol(A._a, Decl(classStaticPropertyTypeGuard.ts, 3, 9)) + } + return A._a = 'helloworld'; +>A._a : Symbol(A._a, Decl(classStaticPropertyTypeGuard.ts, 3, 9)) +>A : Symbol(A, Decl(classStaticPropertyTypeGuard.ts, 0, 0)) +>_a : Symbol(A._a, Decl(classStaticPropertyTypeGuard.ts, 3, 9)) + } +} diff --git a/tests/baselines/reference/classStaticPropertyTypeGuard.types b/tests/baselines/reference/classStaticPropertyTypeGuard.types new file mode 100644 index 00000000000..f89854c919d --- /dev/null +++ b/tests/baselines/reference/classStaticPropertyTypeGuard.types @@ -0,0 +1,31 @@ +=== tests/cases/compiler/classStaticPropertyTypeGuard.ts === + +// Repro from #8923 + +class A { +>A : A + + private static _a: string | undefined; +>_a : string | undefined + + public get a(): string { +>a : string + + if (A._a) { +>A._a : string | undefined +>A : typeof A +>_a : string | undefined + + return A._a; // is possibly null or undefined. +>A._a : string +>A : typeof A +>_a : string + } + return A._a = 'helloworld'; +>A._a = 'helloworld' : string +>A._a : string | undefined +>A : typeof A +>_a : string | undefined +>'helloworld' : string + } +} diff --git a/tests/baselines/reference/controlFlowPropertyInitializer.js b/tests/baselines/reference/controlFlowPropertyInitializer.js new file mode 100644 index 00000000000..5d8e10651fa --- /dev/null +++ b/tests/baselines/reference/controlFlowPropertyInitializer.js @@ -0,0 +1,19 @@ +//// [controlFlowPropertyInitializer.ts] + +// Repro from #8967 + +const LANG = "Turbo Pascal" + +class BestLanguage { + name = LANG; +} + +//// [controlFlowPropertyInitializer.js] +// Repro from #8967 +var LANG = "Turbo Pascal"; +var BestLanguage = (function () { + function BestLanguage() { + this.name = LANG; + } + return BestLanguage; +}()); diff --git a/tests/baselines/reference/controlFlowPropertyInitializer.symbols b/tests/baselines/reference/controlFlowPropertyInitializer.symbols new file mode 100644 index 00000000000..70e6c2da8a1 --- /dev/null +++ b/tests/baselines/reference/controlFlowPropertyInitializer.symbols @@ -0,0 +1,14 @@ +=== tests/cases/compiler/controlFlowPropertyInitializer.ts === + +// Repro from #8967 + +const LANG = "Turbo Pascal" +>LANG : Symbol(LANG, Decl(controlFlowPropertyInitializer.ts, 3, 5)) + +class BestLanguage { +>BestLanguage : Symbol(BestLanguage, Decl(controlFlowPropertyInitializer.ts, 3, 27)) + + name = LANG; +>name : Symbol(BestLanguage.name, Decl(controlFlowPropertyInitializer.ts, 5, 20)) +>LANG : Symbol(LANG, Decl(controlFlowPropertyInitializer.ts, 3, 5)) +} diff --git a/tests/baselines/reference/controlFlowPropertyInitializer.types b/tests/baselines/reference/controlFlowPropertyInitializer.types new file mode 100644 index 00000000000..d35a4c13698 --- /dev/null +++ b/tests/baselines/reference/controlFlowPropertyInitializer.types @@ -0,0 +1,15 @@ +=== tests/cases/compiler/controlFlowPropertyInitializer.ts === + +// Repro from #8967 + +const LANG = "Turbo Pascal" +>LANG : string +>"Turbo Pascal" : string + +class BestLanguage { +>BestLanguage : BestLanguage + + name = LANG; +>name : string +>LANG : string +} diff --git a/tests/baselines/reference/equalityStrictNulls.errors.txt b/tests/baselines/reference/equalityStrictNulls.errors.txt index 54b581c87e6..e0793542b84 100644 --- a/tests/baselines/reference/equalityStrictNulls.errors.txt +++ b/tests/baselines/reference/equalityStrictNulls.errors.txt @@ -81,4 +81,14 @@ tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.t !!! error TS2365: Operator '<=' cannot be applied to types 'number' and 'undefined'. } } + function f5(x: string) { + switch(x) { + case null: + break; + case undefined: + break; + default: + return; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/equalityStrictNulls.js b/tests/baselines/reference/equalityStrictNulls.js index 99ff801a52c..e34e9fe9989 100644 --- a/tests/baselines/reference/equalityStrictNulls.js +++ b/tests/baselines/reference/equalityStrictNulls.js @@ -67,6 +67,16 @@ function f4(x: number) { if (x <= undefined) { } } +function f5(x: string) { + switch(x) { + case null: + break; + case undefined: + break; + default: + return; + } +} //// [equalityStrictNulls.js] @@ -134,3 +144,13 @@ function f4(x) { if (x <= undefined) { } } +function f5(x) { + switch (x) { + case null: + break; + case undefined: + break; + default: + return; + } +} diff --git a/tests/baselines/reference/parserErrorRecovery_ArgumentList5.errors.txt b/tests/baselines/reference/parserErrorRecovery_ArgumentList5.errors.txt deleted file mode 100644 index 5113807faa8..00000000000 --- a/tests/baselines/reference/parserErrorRecovery_ArgumentList5.errors.txt +++ /dev/null @@ -1,16 +0,0 @@ -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList5.ts(2,4): error TS2304: Cannot find name 'bar'. -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList5.ts(2,8): error TS2304: Cannot find name 'a'. -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList5.ts(2,9): error TS1009: Trailing comma not allowed. - - -==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList5.ts (3 errors) ==== - function foo() { - bar(a,) - ~~~ -!!! error TS2304: Cannot find name 'bar'. - ~ -!!! error TS2304: Cannot find name 'a'. - ~ -!!! error TS1009: Trailing comma not allowed. - return; - } \ No newline at end of file diff --git a/tests/baselines/reference/parserErrorRecovery_ArgumentList5.js b/tests/baselines/reference/parserErrorRecovery_ArgumentList5.js deleted file mode 100644 index bbb65a44e07..00000000000 --- a/tests/baselines/reference/parserErrorRecovery_ArgumentList5.js +++ /dev/null @@ -1,11 +0,0 @@ -//// [parserErrorRecovery_ArgumentList5.ts] -function foo() { - bar(a,) - return; -} - -//// [parserErrorRecovery_ArgumentList5.js] -function foo() { - bar(a); - return; -} diff --git a/tests/baselines/reference/parserErrorRecovery_ParameterList3.errors.txt b/tests/baselines/reference/parserErrorRecovery_ParameterList3.errors.txt deleted file mode 100644 index df73dc51ce1..00000000000 --- a/tests/baselines/reference/parserErrorRecovery_ParameterList3.errors.txt +++ /dev/null @@ -1,8 +0,0 @@ -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList3.ts(1,13): error TS1009: Trailing comma not allowed. - - -==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList3.ts (1 errors) ==== - function f(a,) { - ~ -!!! error TS1009: Trailing comma not allowed. - } \ No newline at end of file diff --git a/tests/baselines/reference/parserErrorRecovery_ParameterList3.js b/tests/baselines/reference/parserErrorRecovery_ParameterList3.js deleted file mode 100644 index 4c20e676f40..00000000000 --- a/tests/baselines/reference/parserErrorRecovery_ParameterList3.js +++ /dev/null @@ -1,7 +0,0 @@ -//// [parserErrorRecovery_ParameterList3.ts] -function f(a,) { -} - -//// [parserErrorRecovery_ParameterList3.js] -function f(a) { -} diff --git a/tests/baselines/reference/parserParameterList12.errors.txt b/tests/baselines/reference/parserParameterList12.errors.txt deleted file mode 100644 index 686b29f63b1..00000000000 --- a/tests/baselines/reference/parserParameterList12.errors.txt +++ /dev/null @@ -1,8 +0,0 @@ -tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList12.ts(1,13): error TS1009: Trailing comma not allowed. - - -==== tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList12.ts (1 errors) ==== - function F(a,) { - ~ -!!! error TS1009: Trailing comma not allowed. - } \ No newline at end of file diff --git a/tests/baselines/reference/parserParameterList12.symbols b/tests/baselines/reference/parserParameterList12.symbols new file mode 100644 index 00000000000..efaab7d1b13 --- /dev/null +++ b/tests/baselines/reference/parserParameterList12.symbols @@ -0,0 +1,5 @@ +=== tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList12.ts === +function F(a,) { +>F : Symbol(F, Decl(parserParameterList12.ts, 0, 0)) +>a : Symbol(a, Decl(parserParameterList12.ts, 0, 11)) +} diff --git a/tests/baselines/reference/parserParameterList12.types b/tests/baselines/reference/parserParameterList12.types new file mode 100644 index 00000000000..7ff43cd6a15 --- /dev/null +++ b/tests/baselines/reference/parserParameterList12.types @@ -0,0 +1,5 @@ +=== tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList12.ts === +function F(a,) { +>F : (a: any) => void +>a : any +} diff --git a/tests/baselines/reference/parserX_ArrowFunction2.errors.txt b/tests/baselines/reference/parserX_ArrowFunction2.errors.txt deleted file mode 100644 index 20b4cb45e45..00000000000 --- a/tests/baselines/reference/parserX_ArrowFunction2.errors.txt +++ /dev/null @@ -1,12 +0,0 @@ -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/parserX_ArrowFunction2.ts(1,13): error TS2304: Cannot find name 'b'. -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/parserX_ArrowFunction2.ts(1,14): error TS1009: Trailing comma not allowed. - - -==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/parserX_ArrowFunction2.ts (2 errors) ==== - var v = (a: b,) => { - ~ -!!! error TS2304: Cannot find name 'b'. - ~ -!!! error TS1009: Trailing comma not allowed. - - }; \ No newline at end of file diff --git a/tests/baselines/reference/parserX_ArrowFunction2.js b/tests/baselines/reference/parserX_ArrowFunction2.js deleted file mode 100644 index a30294b658b..00000000000 --- a/tests/baselines/reference/parserX_ArrowFunction2.js +++ /dev/null @@ -1,8 +0,0 @@ -//// [parserX_ArrowFunction2.ts] -var v = (a: b,) => { - -}; - -//// [parserX_ArrowFunction2.js] -var v = function (a) { -}; diff --git a/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.js b/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.js new file mode 100644 index 00000000000..6f30140c63e --- /dev/null +++ b/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.js @@ -0,0 +1,56 @@ +//// [trailingCommasInFunctionParametersAndArguments.ts] + +function f1(x,) {} + +f1(1,); + +function f2(...args,) {} + +f2(...[],); + +// Not confused by overloads +declare function f3(x, ): number; +declare function f3(x, y,): string; + +f3(1,); +f3(1, 2,); + +// Works for constructors too +class X { + constructor(a,) { } + // See trailingCommasInGetter.ts + set x(value,) { } +} +interface Y { + new(x,); + (x,); +} + +new X(1,); + + +//// [trailingCommasInFunctionParametersAndArguments.js] +function f1(x) { } +f1(1); +function f2() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i - 0] = arguments[_i]; + } +} +f2.apply(void 0, []); +f3(1); +f3(1, 2); +// Works for constructors too +var X = (function () { + function X(a) { + } + Object.defineProperty(X.prototype, "x", { + // See trailingCommasInGetter.ts + set: function (value) { }, + enumerable: true, + configurable: true + }); + return X; +}()); +new X(1); diff --git a/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.symbols b/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.symbols new file mode 100644 index 00000000000..2ee58a747b7 --- /dev/null +++ b/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.symbols @@ -0,0 +1,57 @@ +=== tests/cases/conformance/es7/trailingCommasInFunctionParametersAndArguments.ts === + +function f1(x,) {} +>f1 : Symbol(f1, Decl(trailingCommasInFunctionParametersAndArguments.ts, 0, 0)) +>x : Symbol(x, Decl(trailingCommasInFunctionParametersAndArguments.ts, 1, 12)) + +f1(1,); +>f1 : Symbol(f1, Decl(trailingCommasInFunctionParametersAndArguments.ts, 0, 0)) + +function f2(...args,) {} +>f2 : Symbol(f2, Decl(trailingCommasInFunctionParametersAndArguments.ts, 3, 7)) +>args : Symbol(args, Decl(trailingCommasInFunctionParametersAndArguments.ts, 5, 12)) + +f2(...[],); +>f2 : Symbol(f2, Decl(trailingCommasInFunctionParametersAndArguments.ts, 3, 7)) + +// Not confused by overloads +declare function f3(x, ): number; +>f3 : Symbol(f3, Decl(trailingCommasInFunctionParametersAndArguments.ts, 7, 11), Decl(trailingCommasInFunctionParametersAndArguments.ts, 10, 33)) +>x : Symbol(x, Decl(trailingCommasInFunctionParametersAndArguments.ts, 10, 20)) + +declare function f3(x, y,): string; +>f3 : Symbol(f3, Decl(trailingCommasInFunctionParametersAndArguments.ts, 7, 11), Decl(trailingCommasInFunctionParametersAndArguments.ts, 10, 33)) +>x : Symbol(x, Decl(trailingCommasInFunctionParametersAndArguments.ts, 11, 20)) +>y : Symbol(y, Decl(trailingCommasInFunctionParametersAndArguments.ts, 11, 22)) + +f3(1,); +>f3 : Symbol(f3, Decl(trailingCommasInFunctionParametersAndArguments.ts, 7, 11), Decl(trailingCommasInFunctionParametersAndArguments.ts, 10, 33)) + +f3(1, 2,); +>f3 : Symbol(f3, Decl(trailingCommasInFunctionParametersAndArguments.ts, 7, 11), Decl(trailingCommasInFunctionParametersAndArguments.ts, 10, 33)) + +// Works for constructors too +class X { +>X : Symbol(X, Decl(trailingCommasInFunctionParametersAndArguments.ts, 14, 18)) + + constructor(a,) { } +>a : Symbol(a, Decl(trailingCommasInFunctionParametersAndArguments.ts, 18, 16)) + + // See trailingCommasInGetter.ts + set x(value,) { } +>x : Symbol(X.x, Decl(trailingCommasInFunctionParametersAndArguments.ts, 18, 23)) +>value : Symbol(value, Decl(trailingCommasInFunctionParametersAndArguments.ts, 20, 10)) +} +interface Y { +>Y : Symbol(Y, Decl(trailingCommasInFunctionParametersAndArguments.ts, 21, 1)) + + new(x,); +>x : Symbol(x, Decl(trailingCommasInFunctionParametersAndArguments.ts, 23, 8)) + + (x,); +>x : Symbol(x, Decl(trailingCommasInFunctionParametersAndArguments.ts, 24, 5)) +} + +new X(1,); +>X : Symbol(X, Decl(trailingCommasInFunctionParametersAndArguments.ts, 14, 18)) + diff --git a/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.types b/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.types new file mode 100644 index 00000000000..9e2aa0abd8a --- /dev/null +++ b/tests/baselines/reference/trailingCommasInFunctionParametersAndArguments.types @@ -0,0 +1,71 @@ +=== tests/cases/conformance/es7/trailingCommasInFunctionParametersAndArguments.ts === + +function f1(x,) {} +>f1 : (x: any) => void +>x : any + +f1(1,); +>f1(1,) : void +>f1 : (x: any) => void +>1 : number + +function f2(...args,) {} +>f2 : (...args: any[]) => void +>args : any[] + +f2(...[],); +>f2(...[],) : void +>f2 : (...args: any[]) => void +>...[] : undefined +>[] : undefined[] + +// Not confused by overloads +declare function f3(x, ): number; +>f3 : { (x: any): number; (x: any, y: any): string; } +>x : any + +declare function f3(x, y,): string; +>f3 : { (x: any): number; (x: any, y: any): string; } +>x : any +>y : any + +f3(1,); +>f3(1,) : number +>f3(1,) : number +>f3 : { (x: any): number; (x: any, y: any): string; } +>1 : number + +f3(1, 2,); +>f3(1, 2,) : string +>f3(1, 2,) : string +>f3 : { (x: any): number; (x: any, y: any): string; } +>1 : number +>2 : number + +// Works for constructors too +class X { +>X : X + + constructor(a,) { } +>a : any + + // See trailingCommasInGetter.ts + set x(value,) { } +>x : any +>value : any +} +interface Y { +>Y : Y + + new(x,); +>x : any + + (x,); +>x : any +} + +new X(1,); +>new X(1,) : X +>X : typeof X +>1 : number + diff --git a/tests/baselines/reference/trailingCommasInGetter.errors.txt b/tests/baselines/reference/trailingCommasInGetter.errors.txt new file mode 100644 index 00000000000..c4c491a73b7 --- /dev/null +++ b/tests/baselines/reference/trailingCommasInGetter.errors.txt @@ -0,0 +1,10 @@ +tests/cases/conformance/es7/trailingCommasInGetter.ts(2,11): error TS1138: Parameter declaration expected. + + +==== tests/cases/conformance/es7/trailingCommasInGetter.ts (1 errors) ==== + class X { + get x(,) { return 0; } + ~ +!!! error TS1138: Parameter declaration expected. + } + \ No newline at end of file diff --git a/tests/baselines/reference/trailingCommasInGetter.js b/tests/baselines/reference/trailingCommasInGetter.js new file mode 100644 index 00000000000..926545a8cba --- /dev/null +++ b/tests/baselines/reference/trailingCommasInGetter.js @@ -0,0 +1,17 @@ +//// [trailingCommasInGetter.ts] +class X { + get x(,) { return 0; } +} + + +//// [trailingCommasInGetter.js] +var X = (function () { + function X() { + } + Object.defineProperty(X.prototype, "x", { + get: function () { return 0; }, + enumerable: true, + configurable: true + }); + return X; +}()); diff --git a/tests/baselines/reference/trailingSeparatorInFunctionCall.errors.txt b/tests/baselines/reference/trailingSeparatorInFunctionCall.errors.txt deleted file mode 100644 index 76e09a1a4de..00000000000 --- a/tests/baselines/reference/trailingSeparatorInFunctionCall.errors.txt +++ /dev/null @@ -1,24 +0,0 @@ -tests/cases/compiler/trailingSeparatorInFunctionCall.ts(4,1): error TS2346: Supplied parameters do not match any signature of call target. -tests/cases/compiler/trailingSeparatorInFunctionCall.ts(4,7): error TS1009: Trailing comma not allowed. -tests/cases/compiler/trailingSeparatorInFunctionCall.ts(9,1): error TS2346: Supplied parameters do not match any signature of call target. -tests/cases/compiler/trailingSeparatorInFunctionCall.ts(9,8): error TS1009: Trailing comma not allowed. - - -==== tests/cases/compiler/trailingSeparatorInFunctionCall.ts (4 errors) ==== - function f(x, y) { - } - - f(1, 2, ); - ~~~~~~~~~ -!!! error TS2346: Supplied parameters do not match any signature of call target. - ~ -!!! error TS1009: Trailing comma not allowed. - - function f2(x: T, y: T) { - } - - f2(1, 2, ); - ~~~~~~~~~~ -!!! error TS2346: Supplied parameters do not match any signature of call target. - ~ -!!! error TS1009: Trailing comma not allowed. \ No newline at end of file diff --git a/tests/baselines/reference/trailingSeparatorInFunctionCall.js b/tests/baselines/reference/trailingSeparatorInFunctionCall.js deleted file mode 100644 index 4b531479837..00000000000 --- a/tests/baselines/reference/trailingSeparatorInFunctionCall.js +++ /dev/null @@ -1,18 +0,0 @@ -//// [trailingSeparatorInFunctionCall.ts] -function f(x, y) { -} - -f(1, 2, ); - -function f2(x: T, y: T) { -} - -f2(1, 2, ); - -//// [trailingSeparatorInFunctionCall.js] -function f(x, y) { -} -f(1, 2); -function f2(x, y) { -} -f2(1, 2); diff --git a/tests/baselines/reference/typeGuardNarrowsPrimitiveIntersection.js b/tests/baselines/reference/typeGuardNarrowsPrimitiveIntersection.js new file mode 100644 index 00000000000..a4cba6f4ab5 --- /dev/null +++ b/tests/baselines/reference/typeGuardNarrowsPrimitiveIntersection.js @@ -0,0 +1,38 @@ +//// [typeGuardNarrowsPrimitiveIntersection.ts] +type Tag = {__tag: any}; +declare function isNonBlank(value: string) : value is (string & Tag); +declare function doThis(value: string & Tag): void; +declare function doThat(value: string) : void; +let value: string; +if (isNonBlank(value)) { + doThis(value); +} else { + doThat(value); +} + + +const enum Tag2 {} +declare function isNonBlank2(value: string) : value is (string & Tag2); +declare function doThis2(value: string & Tag2): void; +declare function doThat2(value: string) : void; +if (isNonBlank2(value)) { + doThis2(value); +} else { + doThat2(value); +} + + +//// [typeGuardNarrowsPrimitiveIntersection.js] +var value; +if (isNonBlank(value)) { + doThis(value); +} +else { + doThat(value); +} +if (isNonBlank2(value)) { + doThis2(value); +} +else { + doThat2(value); +} diff --git a/tests/baselines/reference/typeGuardNarrowsPrimitiveIntersection.symbols b/tests/baselines/reference/typeGuardNarrowsPrimitiveIntersection.symbols new file mode 100644 index 00000000000..da507fb94c5 --- /dev/null +++ b/tests/baselines/reference/typeGuardNarrowsPrimitiveIntersection.symbols @@ -0,0 +1,70 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardNarrowsPrimitiveIntersection.ts === +type Tag = {__tag: any}; +>Tag : Symbol(Tag, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 0, 0)) +>__tag : Symbol(__tag, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 0, 12)) + +declare function isNonBlank(value: string) : value is (string & Tag); +>isNonBlank : Symbol(isNonBlank, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 0, 24)) +>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 1, 28)) +>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 1, 28)) +>Tag : Symbol(Tag, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 0, 0)) + +declare function doThis(value: string & Tag): void; +>doThis : Symbol(doThis, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 1, 69)) +>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 2, 24)) +>Tag : Symbol(Tag, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 0, 0)) + +declare function doThat(value: string) : void; +>doThat : Symbol(doThat, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 2, 51)) +>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 3, 24)) + +let value: string; +>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 4, 3)) + +if (isNonBlank(value)) { +>isNonBlank : Symbol(isNonBlank, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 0, 24)) +>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 4, 3)) + + doThis(value); +>doThis : Symbol(doThis, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 1, 69)) +>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 4, 3)) + +} else { + doThat(value); +>doThat : Symbol(doThat, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 2, 51)) +>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 4, 3)) +} + + +const enum Tag2 {} +>Tag2 : Symbol(Tag2, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 9, 1)) + +declare function isNonBlank2(value: string) : value is (string & Tag2); +>isNonBlank2 : Symbol(isNonBlank2, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 12, 18)) +>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 13, 29)) +>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 13, 29)) +>Tag2 : Symbol(Tag2, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 9, 1)) + +declare function doThis2(value: string & Tag2): void; +>doThis2 : Symbol(doThis2, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 13, 71)) +>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 14, 25)) +>Tag2 : Symbol(Tag2, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 9, 1)) + +declare function doThat2(value: string) : void; +>doThat2 : Symbol(doThat2, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 14, 53)) +>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 15, 25)) + +if (isNonBlank2(value)) { +>isNonBlank2 : Symbol(isNonBlank2, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 12, 18)) +>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 4, 3)) + + doThis2(value); +>doThis2 : Symbol(doThis2, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 13, 71)) +>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 4, 3)) + +} else { + doThat2(value); +>doThat2 : Symbol(doThat2, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 14, 53)) +>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 4, 3)) +} + diff --git a/tests/baselines/reference/typeGuardNarrowsPrimitiveIntersection.types b/tests/baselines/reference/typeGuardNarrowsPrimitiveIntersection.types new file mode 100644 index 00000000000..478363669b4 --- /dev/null +++ b/tests/baselines/reference/typeGuardNarrowsPrimitiveIntersection.types @@ -0,0 +1,76 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardNarrowsPrimitiveIntersection.ts === +type Tag = {__tag: any}; +>Tag : { __tag: any; } +>__tag : any + +declare function isNonBlank(value: string) : value is (string & Tag); +>isNonBlank : (value: string) => value is string & { __tag: any; } +>value : string +>value : any +>Tag : { __tag: any; } + +declare function doThis(value: string & Tag): void; +>doThis : (value: string & { __tag: any; }) => void +>value : string & { __tag: any; } +>Tag : { __tag: any; } + +declare function doThat(value: string) : void; +>doThat : (value: string) => void +>value : string + +let value: string; +>value : string + +if (isNonBlank(value)) { +>isNonBlank(value) : boolean +>isNonBlank : (value: string) => value is string & { __tag: any; } +>value : string + + doThis(value); +>doThis(value) : void +>doThis : (value: string & { __tag: any; }) => void +>value : string & { __tag: any; } + +} else { + doThat(value); +>doThat(value) : void +>doThat : (value: string) => void +>value : string +} + + +const enum Tag2 {} +>Tag2 : Tag2 + +declare function isNonBlank2(value: string) : value is (string & Tag2); +>isNonBlank2 : (value: string) => value is string & Tag2 +>value : string +>value : any +>Tag2 : Tag2 + +declare function doThis2(value: string & Tag2): void; +>doThis2 : (value: string & Tag2) => void +>value : string & Tag2 +>Tag2 : Tag2 + +declare function doThat2(value: string) : void; +>doThat2 : (value: string) => void +>value : string + +if (isNonBlank2(value)) { +>isNonBlank2(value) : boolean +>isNonBlank2 : (value: string) => value is string & Tag2 +>value : string + + doThis2(value); +>doThis2(value) : void +>doThis2 : (value: string & Tag2) => void +>value : string & Tag2 + +} else { + doThat2(value); +>doThat2(value) : void +>doThat2 : (value: string) => void +>value : string +} + diff --git a/tests/baselines/reference/typeGuardNarrowsToLiteralType.js b/tests/baselines/reference/typeGuardNarrowsToLiteralType.js new file mode 100644 index 00000000000..fdd2ee3fb7f --- /dev/null +++ b/tests/baselines/reference/typeGuardNarrowsToLiteralType.js @@ -0,0 +1,21 @@ +//// [typeGuardNarrowsToLiteralType.ts] +declare function isFoo(value: string) : value is "foo"; +declare function doThis(value: "foo"): void; +declare function doThat(value: string) : void; +let value: string; +if (isFoo(value)) { + doThis(value); +} else { + doThat(value); +} + + + +//// [typeGuardNarrowsToLiteralType.js] +var value; +if (isFoo(value)) { + doThis(value); +} +else { + doThat(value); +} diff --git a/tests/baselines/reference/typeGuardNarrowsToLiteralType.symbols b/tests/baselines/reference/typeGuardNarrowsToLiteralType.symbols new file mode 100644 index 00000000000..0d0ddc5f00d --- /dev/null +++ b/tests/baselines/reference/typeGuardNarrowsToLiteralType.symbols @@ -0,0 +1,32 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardNarrowsToLiteralType.ts === +declare function isFoo(value: string) : value is "foo"; +>isFoo : Symbol(isFoo, Decl(typeGuardNarrowsToLiteralType.ts, 0, 0)) +>value : Symbol(value, Decl(typeGuardNarrowsToLiteralType.ts, 0, 23)) +>value : Symbol(value, Decl(typeGuardNarrowsToLiteralType.ts, 0, 23)) + +declare function doThis(value: "foo"): void; +>doThis : Symbol(doThis, Decl(typeGuardNarrowsToLiteralType.ts, 0, 55)) +>value : Symbol(value, Decl(typeGuardNarrowsToLiteralType.ts, 1, 24)) + +declare function doThat(value: string) : void; +>doThat : Symbol(doThat, Decl(typeGuardNarrowsToLiteralType.ts, 1, 44)) +>value : Symbol(value, Decl(typeGuardNarrowsToLiteralType.ts, 2, 24)) + +let value: string; +>value : Symbol(value, Decl(typeGuardNarrowsToLiteralType.ts, 3, 3)) + +if (isFoo(value)) { +>isFoo : Symbol(isFoo, Decl(typeGuardNarrowsToLiteralType.ts, 0, 0)) +>value : Symbol(value, Decl(typeGuardNarrowsToLiteralType.ts, 3, 3)) + + doThis(value); +>doThis : Symbol(doThis, Decl(typeGuardNarrowsToLiteralType.ts, 0, 55)) +>value : Symbol(value, Decl(typeGuardNarrowsToLiteralType.ts, 3, 3)) + +} else { + doThat(value); +>doThat : Symbol(doThat, Decl(typeGuardNarrowsToLiteralType.ts, 1, 44)) +>value : Symbol(value, Decl(typeGuardNarrowsToLiteralType.ts, 3, 3)) +} + + diff --git a/tests/baselines/reference/typeGuardNarrowsToLiteralType.types b/tests/baselines/reference/typeGuardNarrowsToLiteralType.types new file mode 100644 index 00000000000..9835206deb9 --- /dev/null +++ b/tests/baselines/reference/typeGuardNarrowsToLiteralType.types @@ -0,0 +1,35 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardNarrowsToLiteralType.ts === +declare function isFoo(value: string) : value is "foo"; +>isFoo : (value: string) => value is "foo" +>value : string +>value : any + +declare function doThis(value: "foo"): void; +>doThis : (value: "foo") => void +>value : "foo" + +declare function doThat(value: string) : void; +>doThat : (value: string) => void +>value : string + +let value: string; +>value : string + +if (isFoo(value)) { +>isFoo(value) : boolean +>isFoo : (value: string) => value is "foo" +>value : string + + doThis(value); +>doThis(value) : void +>doThis : (value: "foo") => void +>value : "foo" + +} else { + doThat(value); +>doThat(value) : void +>doThat : (value: string) => void +>value : string +} + + diff --git a/tests/baselines/reference/typeGuardNarrowsToLiteralTypeUnion.js b/tests/baselines/reference/typeGuardNarrowsToLiteralTypeUnion.js new file mode 100644 index 00000000000..715b362c8e0 --- /dev/null +++ b/tests/baselines/reference/typeGuardNarrowsToLiteralTypeUnion.js @@ -0,0 +1,21 @@ +//// [typeGuardNarrowsToLiteralTypeUnion.ts] +declare function isFoo(value: string) : value is ("foo" | "bar"); +declare function doThis(value: "foo" | "bar"): void; +declare function doThat(value: string) : void; +let value: string; +if (isFoo(value)) { + doThis(value); +} else { + doThat(value); +} + + + +//// [typeGuardNarrowsToLiteralTypeUnion.js] +var value; +if (isFoo(value)) { + doThis(value); +} +else { + doThat(value); +} diff --git a/tests/baselines/reference/typeGuardNarrowsToLiteralTypeUnion.symbols b/tests/baselines/reference/typeGuardNarrowsToLiteralTypeUnion.symbols new file mode 100644 index 00000000000..356fa06a06c --- /dev/null +++ b/tests/baselines/reference/typeGuardNarrowsToLiteralTypeUnion.symbols @@ -0,0 +1,32 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardNarrowsToLiteralTypeUnion.ts === +declare function isFoo(value: string) : value is ("foo" | "bar"); +>isFoo : Symbol(isFoo, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 0, 0)) +>value : Symbol(value, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 0, 23)) +>value : Symbol(value, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 0, 23)) + +declare function doThis(value: "foo" | "bar"): void; +>doThis : Symbol(doThis, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 0, 65)) +>value : Symbol(value, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 1, 24)) + +declare function doThat(value: string) : void; +>doThat : Symbol(doThat, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 1, 52)) +>value : Symbol(value, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 2, 24)) + +let value: string; +>value : Symbol(value, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 3, 3)) + +if (isFoo(value)) { +>isFoo : Symbol(isFoo, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 0, 0)) +>value : Symbol(value, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 3, 3)) + + doThis(value); +>doThis : Symbol(doThis, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 0, 65)) +>value : Symbol(value, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 3, 3)) + +} else { + doThat(value); +>doThat : Symbol(doThat, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 1, 52)) +>value : Symbol(value, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 3, 3)) +} + + diff --git a/tests/baselines/reference/typeGuardNarrowsToLiteralTypeUnion.types b/tests/baselines/reference/typeGuardNarrowsToLiteralTypeUnion.types new file mode 100644 index 00000000000..321a8861d55 --- /dev/null +++ b/tests/baselines/reference/typeGuardNarrowsToLiteralTypeUnion.types @@ -0,0 +1,35 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardNarrowsToLiteralTypeUnion.ts === +declare function isFoo(value: string) : value is ("foo" | "bar"); +>isFoo : (value: string) => value is "foo" | "bar" +>value : string +>value : any + +declare function doThis(value: "foo" | "bar"): void; +>doThis : (value: "foo" | "bar") => void +>value : "foo" | "bar" + +declare function doThat(value: string) : void; +>doThat : (value: string) => void +>value : string + +let value: string; +>value : string + +if (isFoo(value)) { +>isFoo(value) : boolean +>isFoo : (value: string) => value is "foo" | "bar" +>value : string + + doThis(value); +>doThis(value) : void +>doThis : (value: "foo" | "bar") => void +>value : "foo" | "bar" + +} else { + doThat(value); +>doThat(value) : void +>doThat : (value: string) => void +>value : string +} + + diff --git a/tests/cases/compiler/classStaticPropertyTypeGuard.ts b/tests/cases/compiler/classStaticPropertyTypeGuard.ts new file mode 100644 index 00000000000..93655cfb092 --- /dev/null +++ b/tests/cases/compiler/classStaticPropertyTypeGuard.ts @@ -0,0 +1,15 @@ +// @strictNullChecks: true +// @target: ES5 + +// Repro from #8923 + +class A { + private static _a: string | undefined; + + public get a(): string { + if (A._a) { + return A._a; // is possibly null or undefined. + } + return A._a = 'helloworld'; + } +} \ No newline at end of file diff --git a/tests/cases/compiler/controlFlowPropertyInitializer.ts b/tests/cases/compiler/controlFlowPropertyInitializer.ts new file mode 100644 index 00000000000..0b75f280b1d --- /dev/null +++ b/tests/cases/compiler/controlFlowPropertyInitializer.ts @@ -0,0 +1,9 @@ +// @strictNullChecks: true + +// Repro from #8967 + +const LANG = "Turbo Pascal" + +class BestLanguage { + name = LANG; +} \ No newline at end of file diff --git a/tests/cases/compiler/trailingSeparatorInFunctionCall.ts b/tests/cases/compiler/trailingSeparatorInFunctionCall.ts deleted file mode 100644 index b9f62e1e8cc..00000000000 --- a/tests/cases/compiler/trailingSeparatorInFunctionCall.ts +++ /dev/null @@ -1,9 +0,0 @@ -function f(x, y) { -} - -f(1, 2, ); - -function f2(x: T, y: T) { -} - -f2(1, 2, ); \ No newline at end of file diff --git a/tests/cases/conformance/es7/trailingCommasInFunctionParametersAndArguments.ts b/tests/cases/conformance/es7/trailingCommasInFunctionParametersAndArguments.ts new file mode 100644 index 00000000000..6b57235cbeb --- /dev/null +++ b/tests/cases/conformance/es7/trailingCommasInFunctionParametersAndArguments.ts @@ -0,0 +1,29 @@ +// @target: es5 + +function f1(x,) {} + +f1(1,); + +function f2(...args,) {} + +f2(...[],); + +// Not confused by overloads +declare function f3(x, ): number; +declare function f3(x, y,): string; + +f3(1,); +f3(1, 2,); + +// Works for constructors too +class X { + constructor(a,) { } + // See trailingCommasInGetter.ts + set x(value,) { } +} +interface Y { + new(x,); + (x,); +} + +new X(1,); diff --git a/tests/cases/conformance/es7/trailingCommasInGetter.ts b/tests/cases/conformance/es7/trailingCommasInGetter.ts new file mode 100644 index 00000000000..a1b2cf60b2c --- /dev/null +++ b/tests/cases/conformance/es7/trailingCommasInGetter.ts @@ -0,0 +1,3 @@ +class X { + get x(,) { return 0; } +} diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardNarrowsPrimitiveIntersection.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardNarrowsPrimitiveIntersection.ts new file mode 100644 index 00000000000..376a78275c8 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardNarrowsPrimitiveIntersection.ts @@ -0,0 +1,21 @@ +type Tag = {__tag: any}; +declare function isNonBlank(value: string) : value is (string & Tag); +declare function doThis(value: string & Tag): void; +declare function doThat(value: string) : void; +let value: string; +if (isNonBlank(value)) { + doThis(value); +} else { + doThat(value); +} + + +const enum Tag2 {} +declare function isNonBlank2(value: string) : value is (string & Tag2); +declare function doThis2(value: string & Tag2): void; +declare function doThat2(value: string) : void; +if (isNonBlank2(value)) { + doThis2(value); +} else { + doThat2(value); +} diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardNarrowsToLiteralType.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardNarrowsToLiteralType.ts new file mode 100644 index 00000000000..3b7d5bba21a --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardNarrowsToLiteralType.ts @@ -0,0 +1,10 @@ +declare function isFoo(value: string) : value is "foo"; +declare function doThis(value: "foo"): void; +declare function doThat(value: string) : void; +let value: string; +if (isFoo(value)) { + doThis(value); +} else { + doThat(value); +} + diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardNarrowsToLiteralTypeUnion.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardNarrowsToLiteralTypeUnion.ts new file mode 100644 index 00000000000..8f4726160f4 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardNarrowsToLiteralTypeUnion.ts @@ -0,0 +1,10 @@ +declare function isFoo(value: string) : value is ("foo" | "bar"); +declare function doThis(value: "foo" | "bar"): void; +declare function doThat(value: string) : void; +let value: string; +if (isFoo(value)) { + doThis(value); +} else { + doThat(value); +} + diff --git a/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList5.ts b/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList5.ts deleted file mode 100644 index 0270f766fef..00000000000 --- a/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList5.ts +++ /dev/null @@ -1,4 +0,0 @@ -function foo() { - bar(a,) - return; -} \ No newline at end of file diff --git a/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/ArrowFunction2.ts b/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/ArrowFunction2.ts deleted file mode 100644 index 8b4d99e2ef5..00000000000 --- a/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/ArrowFunction2.ts +++ /dev/null @@ -1,3 +0,0 @@ -var v = (a: b,) => { - -}; \ No newline at end of file diff --git a/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/parserX_ArrowFunction2.ts b/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/parserX_ArrowFunction2.ts deleted file mode 100644 index 8b4d99e2ef5..00000000000 --- a/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/parserX_ArrowFunction2.ts +++ /dev/null @@ -1,3 +0,0 @@ -var v = (a: b,) => { - -}; \ No newline at end of file diff --git a/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList3.ts b/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList3.ts deleted file mode 100644 index c51a52ef83e..00000000000 --- a/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList3.ts +++ /dev/null @@ -1,2 +0,0 @@ -function f(a,) { -} \ No newline at end of file diff --git a/tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts b/tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts index 6b2744e8849..da46ab37a2a 100644 --- a/tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts +++ b/tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts @@ -67,3 +67,13 @@ function f4(x: number) { if (x <= undefined) { } } +function f5(x: string) { + switch(x) { + case null: + break; + case undefined: + break; + default: + return; + } +} diff --git a/tests/cases/fourslash/quickInfoOnNarrowedTypeInModule.ts b/tests/cases/fourslash/quickInfoOnNarrowedTypeInModule.ts index 1f95de35403..cfeaabfbb86 100644 --- a/tests/cases/fourslash/quickInfoOnNarrowedTypeInModule.ts +++ b/tests/cases/fourslash/quickInfoOnNarrowedTypeInModule.ts @@ -50,14 +50,26 @@ goTo.marker('6'); verify.quickInfoIs('var m.exportedStrOrNum: string'); verify.completionListContains("exportedStrOrNum", "var m.exportedStrOrNum: string"); -['7', '8', '9'].forEach((marker, index, arr) => { - goTo.marker(marker); - verify.quickInfoIs('var m.exportedStrOrNum: string | number'); - verify.completionListContains("exportedStrOrNum", "var m.exportedStrOrNum: string | number"); -}); +goTo.marker('7'); +verify.quickInfoIs('var m.exportedStrOrNum: string | number'); +verify.completionListContains("exportedStrOrNum", "var m.exportedStrOrNum: string | number"); -['7', '8', '9'].forEach((marker, index, arr) => { - goTo.marker(marker); - verify.quickInfoIs('var m.exportedStrOrNum: string | number'); - verify.memberListContains("exportedStrOrNum", "var m.exportedStrOrNum: string | number"); -}); \ No newline at end of file +goTo.marker('8'); +verify.quickInfoIs('var m.exportedStrOrNum: number'); +verify.completionListContains("exportedStrOrNum", "var m.exportedStrOrNum: number"); + +goTo.marker('9'); +verify.quickInfoIs('var m.exportedStrOrNum: string'); +verify.completionListContains("exportedStrOrNum", "var m.exportedStrOrNum: string"); + +goTo.marker('7'); +verify.quickInfoIs('var m.exportedStrOrNum: string | number'); +verify.memberListContains("exportedStrOrNum", "var m.exportedStrOrNum: string | number"); + +goTo.marker('8'); +verify.quickInfoIs('var m.exportedStrOrNum: number'); +verify.memberListContains("exportedStrOrNum", "var m.exportedStrOrNum: number"); + +goTo.marker('9'); +verify.quickInfoIs('var m.exportedStrOrNum: string'); +verify.memberListContains("exportedStrOrNum", "var m.exportedStrOrNum: string"); \ No newline at end of file diff --git a/tests/cases/fourslash/server/navbar01.ts b/tests/cases/fourslash/server/navbar01.ts index 7f2229fcb81..9e0f2a36396 100644 --- a/tests/cases/fourslash/server/navbar01.ts +++ b/tests/cases/fourslash/server/navbar01.ts @@ -85,7 +85,8 @@ verify.navigationBar([ "text": "prop", "kind": "property" } - ] + ], + "indent": 1 }, { "text": "Shapes", @@ -100,7 +101,8 @@ verify.navigationBar([ "text": "Values", "kind": "enum" } - ] + ], + "indent": 1 }, { "text": "Point", @@ -143,7 +145,8 @@ verify.navigationBar([ "kind": "property", "kindModifiers": "public" } - ] + ], + "indent": 2 }, { "text": "Values", @@ -161,6 +164,7 @@ verify.navigationBar([ "text": "value3", "kind": "property" } - ] + ], + "indent": 2 } ]); diff --git a/tests/cases/fourslash/trailingCommaSignatureHelp.ts b/tests/cases/fourslash/trailingCommaSignatureHelp.ts new file mode 100644 index 00000000000..4881571cd2b --- /dev/null +++ b/tests/cases/fourslash/trailingCommaSignatureHelp.ts @@ -0,0 +1,15 @@ +/// + +////function str(n: number): string; +/////** +//// * Stringifies a number with radix +//// * @param radix The radix +//// */ +////function str(n: number, radix: number): string; +////function str(n: number, radix?: number): string { return ""; } + +edit.insert("str(1,"); +verify.currentParameterHelpArgumentNameIs("radix"); +verify.currentParameterHelpArgumentDocCommentIs("The radix"); +verify.currentSignatureHelpIs("str(n: number, radix: number): string"); +verify.currentSignatureHelpDocCommentIs("Stringifies a number with radix");