diff --git a/.gitignore b/.gitignore index e1492c2cd73..79fefb71a85 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,8 @@ tests/cases/perf/* !tests/cases/webharness/compilerToString.js test-args.txt ~*.docx +\#*\# +.\#* tests/baselines/local/* tests/services/baselines/local/* tests/baselines/prototyping/local/* diff --git a/Jakefile.js b/Jakefile.js index 1d017d5100f..3e0512de452 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -203,7 +203,7 @@ var librarySourceMap = [ // 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), }, + { target: "lib.es6.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts"), }, ].concat(es2015LibrarySourceMap, es2016LibrarySourceMap); var libraryTargets = librarySourceMap.map(function (f) { diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 0dab05691fa..c96aa9ad140 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -11,19 +11,11 @@ namespace ts { ConstEnumOnly = 2 } - const enum Reachability { - Uninitialized = 1 << 0, - Reachable = 1 << 1, - Unreachable = 1 << 2, - ReportedUnreachable = 1 << 3 - } - - function or(state1: Reachability, state2: Reachability): Reachability { - return (state1 | state2) & Reachability.Reachable - ? Reachability.Reachable - : (state1 & state2) & Reachability.ReportedUnreachable - ? Reachability.ReportedUnreachable - : Reachability.Unreachable; + interface ActiveLabel { + name: string; + breakTarget: FlowLabel; + continueTarget: FlowLabel; + referenced: boolean; } export function getModuleInstanceState(node: Node): ModuleInstanceState { @@ -113,10 +105,13 @@ namespace ts { // state used by reachability checks let hasExplicitReturn: boolean; - let currentReachabilityState: Reachability; - let labelStack: Reachability[]; - let labelIndexMap: Map; - let implicitLabels: number[]; + let currentFlow: FlowNode; + let currentBreakTarget: FlowLabel; + let currentContinueTarget: FlowLabel; + let currentTrueTarget: FlowLabel; + let currentFalseTarget: FlowLabel; + let preSwitchCaseFlow: FlowNode; + let activeLabels: ActiveLabel[]; // state used for emit helpers let hasClassExtends: boolean; @@ -134,6 +129,9 @@ namespace ts { let Symbol: { new (flags: SymbolFlags, name: string): Symbol }; let classifiableNames: Map; + const unreachableFlow: FlowNode = { kind: FlowKind.Unreachable }; + const reportedUnreachableFlow: FlowNode = { kind: FlowKind.Unreachable }; + function bindSourceFile(f: SourceFile, opts: CompilerOptions) { file = f; options = opts; @@ -158,9 +156,12 @@ namespace ts { lastContainer = undefined; seenThisKeyword = false; hasExplicitReturn = false; - labelStack = undefined; - labelIndexMap = undefined; - implicitLabels = undefined; + currentFlow = undefined; + currentBreakTarget = undefined; + currentContinueTarget = undefined; + currentTrueTarget = undefined; + currentFalseTarget = undefined; + activeLabels = undefined; hasClassExtends = false; hasAsyncFunctions = false; hasDecorators = false; @@ -450,11 +451,11 @@ namespace ts { blockScopeContainer.locals = undefined; } - let savedReachabilityState: Reachability; - let savedLabelStack: Reachability[]; - let savedLabels: Map; - let savedImplicitLabels: number[]; let savedHasExplicitReturn: boolean; + let savedCurrentFlow: FlowNode; + let savedBreakTarget: FlowLabel; + let savedContinueTarget: FlowLabel; + let savedActiveLabels: ActiveLabel[]; const kind = node.kind; let flags = node.flags; @@ -471,20 +472,22 @@ namespace ts { const saveState = kind === SyntaxKind.SourceFile || kind === SyntaxKind.ModuleBlock || isFunctionLikeKind(kind); if (saveState) { - savedReachabilityState = currentReachabilityState; - savedLabelStack = labelStack; - savedLabels = labelIndexMap; - savedImplicitLabels = implicitLabels; savedHasExplicitReturn = hasExplicitReturn; + savedCurrentFlow = currentFlow; + savedBreakTarget = currentBreakTarget; + savedContinueTarget = currentContinueTarget; + savedActiveLabels = activeLabels; - currentReachabilityState = Reachability.Reachable; hasExplicitReturn = false; - labelStack = labelIndexMap = implicitLabels = undefined; + currentFlow = { kind: FlowKind.Start }; + currentBreakTarget = undefined; + currentContinueTarget = undefined; + activeLabels = undefined; } bindReachableStatement(node); - if (currentReachabilityState === Reachability.Reachable && isFunctionLikeKind(kind) && nodeIsPresent((node).body)) { + if (currentFlow.kind !== FlowKind.Unreachable && isFunctionLikeKind(kind) && nodeIsPresent((node).body)) { flags |= NodeFlags.HasImplicitReturn; if (hasExplicitReturn) { flags |= NodeFlags.HasExplicitReturn; @@ -517,10 +520,10 @@ namespace ts { if (saveState) { hasExplicitReturn = savedHasExplicitReturn; - currentReachabilityState = savedReachabilityState; - labelStack = savedLabelStack; - labelIndexMap = savedLabels; - implicitLabels = savedImplicitLabels; + currentFlow = savedCurrentFlow; + currentBreakTarget = savedBreakTarget; + currentContinueTarget = savedContinueTarget; + activeLabels = savedActiveLabels; } container = saveContainer; @@ -575,174 +578,502 @@ namespace ts { case SyntaxKind.LabeledStatement: bindLabeledStatement(node); break; + case SyntaxKind.PrefixUnaryExpression: + bindPrefixUnaryExpressionFlow(node); + break; + case SyntaxKind.BinaryExpression: + bindBinaryExpressionFlow(node); + break; + case SyntaxKind.ConditionalExpression: + bindConditionalExpressionFlow(node); + break; + case SyntaxKind.VariableDeclaration: + bindVariableDeclarationFlow(node); + break; default: forEachChild(node, bind); break; } } - function bindWhileStatement(n: WhileStatement): void { - const preWhileState = - n.expression.kind === SyntaxKind.FalseKeyword ? Reachability.Unreachable : currentReachabilityState; - const postWhileState = - n.expression.kind === SyntaxKind.TrueKeyword ? Reachability.Unreachable : currentReachabilityState; - - // bind expressions (don't affect reachability) - bind(n.expression); - - currentReachabilityState = preWhileState; - const postWhileLabel = pushImplicitLabel(); - bind(n.statement); - popImplicitLabel(postWhileLabel, postWhileState); + function isNarrowableReference(expr: Expression): boolean { + return expr.kind === SyntaxKind.Identifier || + expr.kind === SyntaxKind.ThisKeyword || + expr.kind === SyntaxKind.PropertyAccessExpression && isNarrowableReference((expr).expression); } - function bindDoStatement(n: DoStatement): void { - const preDoState = currentReachabilityState; - - const postDoLabel = pushImplicitLabel(); - bind(n.statement); - const postDoState = n.expression.kind === SyntaxKind.TrueKeyword ? Reachability.Unreachable : preDoState; - popImplicitLabel(postDoLabel, postDoState); - - // bind expressions (don't affect reachability) - bind(n.expression); - } - - function bindForStatement(n: ForStatement): void { - const preForState = currentReachabilityState; - const postForLabel = pushImplicitLabel(); - - // bind expressions (don't affect reachability) - bind(n.initializer); - bind(n.condition); - bind(n.incrementor); - - bind(n.statement); - - // for statement is considered infinite when it condition is either omitted or is true keyword - // - for(..;;..) - // - for(..;true;..) - const isInfiniteLoop = (!n.condition || n.condition.kind === SyntaxKind.TrueKeyword); - const postForState = isInfiniteLoop ? Reachability.Unreachable : preForState; - popImplicitLabel(postForLabel, postForState); - } - - function bindForInOrForOfStatement(n: ForInStatement | ForOfStatement): void { - const preStatementState = currentReachabilityState; - const postStatementLabel = pushImplicitLabel(); - - // bind expressions (don't affect reachability) - bind(n.initializer); - bind(n.expression); - - bind(n.statement); - popImplicitLabel(postStatementLabel, preStatementState); - } - - function bindIfStatement(n: IfStatement): void { - // denotes reachability state when entering 'thenStatement' part of the if statement: - // i.e. if condition is false then thenStatement is unreachable - const ifTrueState = n.expression.kind === SyntaxKind.FalseKeyword ? Reachability.Unreachable : currentReachabilityState; - // denotes reachability state when entering 'elseStatement': - // i.e. if condition is true then elseStatement is unreachable - const ifFalseState = n.expression.kind === SyntaxKind.TrueKeyword ? Reachability.Unreachable : currentReachabilityState; - - currentReachabilityState = ifTrueState; - - // bind expression (don't affect reachability) - bind(n.expression); - - bind(n.thenStatement); - if (n.elseStatement) { - const preElseState = currentReachabilityState; - currentReachabilityState = ifFalseState; - bind(n.elseStatement); - currentReachabilityState = or(currentReachabilityState, preElseState); + function isNarrowingExpression(expr: Expression): boolean { + switch (expr.kind) { + case SyntaxKind.Identifier: + case SyntaxKind.ThisKeyword: + case SyntaxKind.PropertyAccessExpression: + return isNarrowableReference(expr); + case SyntaxKind.CallExpression: + return true; + case SyntaxKind.ParenthesizedExpression: + return isNarrowingExpression((expr).expression); + case SyntaxKind.BinaryExpression: + return isNarrowingBinaryExpression(expr); + case SyntaxKind.PrefixUnaryExpression: + return (expr).operator === SyntaxKind.ExclamationToken && isNarrowingExpression((expr).operand); } - else { - currentReachabilityState = or(currentReachabilityState, ifFalseState); + return false; + } + + function isNarrowingBinaryExpression(expr: BinaryExpression) { + switch (expr.operatorToken.kind) { + case SyntaxKind.EqualsToken: + return isNarrowableReference(expr.left); + case SyntaxKind.EqualsEqualsToken: + case SyntaxKind.ExclamationEqualsToken: + case SyntaxKind.EqualsEqualsEqualsToken: + case SyntaxKind.ExclamationEqualsEqualsToken: + if (isNarrowingExpression(expr.left) && (expr.right.kind === SyntaxKind.NullKeyword || expr.right.kind === SyntaxKind.Identifier)) { + return true; + } + if (expr.left.kind === SyntaxKind.TypeOfExpression && isNarrowingExpression((expr.left).expression) && expr.right.kind === SyntaxKind.StringLiteral) { + return true; + } + return false; + case SyntaxKind.InstanceOfKeyword: + return isNarrowingExpression(expr.left); + case SyntaxKind.CommaToken: + return isNarrowingExpression(expr.right); + } + return false; + } + + function createFlowLabel(): FlowLabel { + return { + kind: FlowKind.Label, + antecedents: undefined + }; + } + + function addAntecedent(label: FlowLabel, antecedent: FlowNode): void { + if (antecedent.kind !== FlowKind.Unreachable && !contains(label.antecedents, antecedent)) { + (label.antecedents || (label.antecedents = [])).push(antecedent); } } - function bindReturnOrThrow(n: ReturnStatement | ThrowStatement): void { - // bind expression (don't affect reachability) - bind(n.expression); - if (n.kind === SyntaxKind.ReturnStatement) { - hasExplicitReturn = true; + function createFlowCondition(antecedent: FlowNode, expression: Expression, assumeTrue: boolean): FlowNode { + if (antecedent.kind === FlowKind.Unreachable) { + return antecedent; } - currentReachabilityState = Reachability.Unreachable; - } - - function bindBreakOrContinueStatement(n: BreakOrContinueStatement): void { - // call bind on label (don't affect reachability) - bind(n.label); - // for continue case touch label so it will be marked a used - const isValidJump = jumpToLabel(n.label, n.kind === SyntaxKind.BreakStatement ? currentReachabilityState : Reachability.Unreachable); - if (isValidJump) { - currentReachabilityState = Reachability.Unreachable; + if (!expression) { + return assumeTrue ? antecedent : unreachableFlow; } + if (expression.kind === SyntaxKind.TrueKeyword && !assumeTrue || expression.kind === SyntaxKind.FalseKeyword && assumeTrue) { + return unreachableFlow; + } + if (!isNarrowingExpression(expression)) { + return antecedent; + } + return { + kind: FlowKind.Condition, + antecedent, + expression, + assumeTrue + }; } - function bindTryStatement(n: TryStatement): void { - // catch\finally blocks has the same reachability as try block - const preTryState = currentReachabilityState; - bind(n.tryBlock); - const postTryState = currentReachabilityState; - - currentReachabilityState = preTryState; - bind(n.catchClause); - const postCatchState = currentReachabilityState; - - currentReachabilityState = preTryState; - bind(n.finallyBlock); - - // post catch/finally state is reachable if - // - post try state is reachable - control flow can fall out of try block - // - post catch state is reachable - control flow can fall out of catch block - currentReachabilityState = n.catchClause ? or(postTryState, postCatchState) : postTryState; + function createFlowAssignment(antecedent: FlowNode, node: Expression | VariableDeclaration | BindingElement): FlowNode { + return { + kind: FlowKind.Assignment, + antecedent, + node + }; } - function bindSwitchStatement(n: SwitchStatement): void { - const preSwitchState = currentReachabilityState; - const postSwitchLabel = pushImplicitLabel(); - - // bind expression (don't affect reachability) - bind(n.expression); - - bind(n.caseBlock); - - const hasDefault = forEach(n.caseBlock.clauses, c => c.kind === SyntaxKind.DefaultClause); - - // post switch state is unreachable if switch is exhaustive (has a default case ) and does not have fallthrough from the last case - const postSwitchState = hasDefault && currentReachabilityState !== Reachability.Reachable ? Reachability.Unreachable : preSwitchState; - - popImplicitLabel(postSwitchLabel, postSwitchState); + function finishFlowLabel(flow: FlowLabel): FlowNode { + const antecedents = flow.antecedents; + if (!antecedents) { + return unreachableFlow; + } + if (antecedents.length === 1) { + return antecedents[0]; + } + return flow; } - function bindCaseBlock(n: CaseBlock): void { - const startState = currentReachabilityState; + function isStatementCondition(node: Node) { + const parent = node.parent; + switch (parent.kind) { + case SyntaxKind.IfStatement: + case SyntaxKind.WhileStatement: + case SyntaxKind.DoStatement: + return (parent).expression === node; + case SyntaxKind.ForStatement: + case SyntaxKind.ConditionalExpression: + return (parent).condition === node; + } + return false; + } - for (let i = 0; i < n.clauses.length; i++) { - const clause = n.clauses[i]; - currentReachabilityState = startState; - bind(clause); - if (clause.statements.length && - i !== n.clauses.length - 1 && // allow fallthrough from the last case - currentReachabilityState === Reachability.Reachable && - options.noFallthroughCasesInSwitch) { - errorOnFirstToken(clause, Diagnostics.Fallthrough_case_in_switch); + function isLogicalExpression(node: Node) { + while (true) { + if (node.kind === SyntaxKind.ParenthesizedExpression) { + node = (node).expression; + } + else if (node.kind === SyntaxKind.PrefixUnaryExpression && (node).operator === SyntaxKind.ExclamationToken) { + node = (node).operand; + } + else { + return node.kind === SyntaxKind.BinaryExpression && ( + (node).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken || + (node).operatorToken.kind === SyntaxKind.BarBarToken); } } } - function bindLabeledStatement(n: LabeledStatement): void { - // call bind on label (don't affect reachability) - bind(n.label); + function isTopLevelLogicalExpression(node: Node): boolean { + while (node.parent.kind === SyntaxKind.ParenthesizedExpression || + node.parent.kind === SyntaxKind.PrefixUnaryExpression && + (node.parent).operator === SyntaxKind.ExclamationToken) { + node = node.parent; + } + return !isStatementCondition(node) && !isLogicalExpression(node.parent); + } - const ok = pushNamedLabel(n.label); - bind(n.statement); - if (ok) { - popNamedLabel(n.label, currentReachabilityState); + function bindCondition(node: Expression, trueTarget: FlowLabel, falseTarget: FlowLabel) { + const saveTrueTarget = currentTrueTarget; + const saveFalseTarget = currentFalseTarget; + currentTrueTarget = trueTarget; + currentFalseTarget = falseTarget; + bind(node); + currentTrueTarget = saveTrueTarget; + currentFalseTarget = saveFalseTarget; + if (!node || !isLogicalExpression(node)) { + addAntecedent(trueTarget, createFlowCondition(currentFlow, node, /*assumeTrue*/ true)); + addAntecedent(falseTarget, createFlowCondition(currentFlow, node, /*assumeTrue*/ false)); + } + } + + function bindIterativeStatement(node: Statement, breakTarget: FlowLabel, continueTarget: FlowLabel): void { + const saveBreakTarget = currentBreakTarget; + const saveContinueTarget = currentContinueTarget; + currentBreakTarget = breakTarget; + currentContinueTarget = continueTarget; + bind(node); + currentBreakTarget = saveBreakTarget; + currentContinueTarget = saveContinueTarget; + } + + function bindWhileStatement(node: WhileStatement): void { + const preWhileLabel = createFlowLabel(); + const preBodyLabel = createFlowLabel(); + const postWhileLabel = createFlowLabel(); + addAntecedent(preWhileLabel, currentFlow); + currentFlow = preWhileLabel; + bindCondition(node.expression, preBodyLabel, postWhileLabel); + currentFlow = finishFlowLabel(preBodyLabel); + bindIterativeStatement(node.statement, postWhileLabel, preWhileLabel); + addAntecedent(preWhileLabel, currentFlow); + currentFlow = finishFlowLabel(postWhileLabel); + } + + function bindDoStatement(node: DoStatement): void { + const preDoLabel = createFlowLabel(); + const preConditionLabel = createFlowLabel(); + const postDoLabel = createFlowLabel(); + addAntecedent(preDoLabel, currentFlow); + currentFlow = preDoLabel; + bindIterativeStatement(node.statement, postDoLabel, preConditionLabel); + addAntecedent(preConditionLabel, currentFlow); + currentFlow = finishFlowLabel(preConditionLabel); + bindCondition(node.expression, preDoLabel, postDoLabel); + currentFlow = finishFlowLabel(postDoLabel); + } + + function bindForStatement(node: ForStatement): void { + const preLoopLabel = createFlowLabel(); + const preBodyLabel = createFlowLabel(); + const postLoopLabel = createFlowLabel(); + bind(node.initializer); + addAntecedent(preLoopLabel, currentFlow); + currentFlow = preLoopLabel; + bindCondition(node.condition, preBodyLabel, postLoopLabel); + currentFlow = finishFlowLabel(preBodyLabel); + bindIterativeStatement(node.statement, postLoopLabel, preLoopLabel); + bind(node.incrementor); + addAntecedent(preLoopLabel, currentFlow); + currentFlow = finishFlowLabel(postLoopLabel); + } + + function bindForInOrForOfStatement(node: ForInStatement | ForOfStatement): void { + const preLoopLabel = createFlowLabel(); + const postLoopLabel = createFlowLabel(); + addAntecedent(preLoopLabel, currentFlow); + currentFlow = preLoopLabel; + bind(node.expression); + addAntecedent(postLoopLabel, currentFlow); + bind(node.initializer); + if (node.initializer.kind !== SyntaxKind.VariableDeclarationList) { + bindAssignmentTargetFlow(node.initializer); + } + bindIterativeStatement(node.statement, postLoopLabel, preLoopLabel); + addAntecedent(preLoopLabel, currentFlow); + currentFlow = finishFlowLabel(postLoopLabel); + } + + function bindIfStatement(node: IfStatement): void { + const thenLabel = createFlowLabel(); + const elseLabel = createFlowLabel(); + const postIfLabel = createFlowLabel(); + bindCondition(node.expression, thenLabel, elseLabel); + currentFlow = finishFlowLabel(thenLabel); + bind(node.thenStatement); + addAntecedent(postIfLabel, currentFlow); + currentFlow = finishFlowLabel(elseLabel); + bind(node.elseStatement); + addAntecedent(postIfLabel, currentFlow); + currentFlow = finishFlowLabel(postIfLabel); + } + + function bindReturnOrThrow(node: ReturnStatement | ThrowStatement): void { + bind(node.expression); + if (node.kind === SyntaxKind.ReturnStatement) { + hasExplicitReturn = true; + } + currentFlow = unreachableFlow; + } + + function findActiveLabel(name: string) { + if (activeLabels) { + for (const label of activeLabels) { + if (label.name === name) { + return label; + } + } + } + return undefined; + } + + function bindbreakOrContinueFlow(node: BreakOrContinueStatement, breakTarget: FlowLabel, continueTarget: FlowLabel) { + const flowLabel = node.kind === SyntaxKind.BreakStatement ? breakTarget : continueTarget; + if (flowLabel) { + addAntecedent(flowLabel, currentFlow); + currentFlow = unreachableFlow; + } + } + + function bindBreakOrContinueStatement(node: BreakOrContinueStatement): void { + bind(node.label); + if (node.label) { + const activeLabel = findActiveLabel(node.label.text); + if (activeLabel) { + activeLabel.referenced = true; + bindbreakOrContinueFlow(node, activeLabel.breakTarget, activeLabel.continueTarget); + } + } + else { + bindbreakOrContinueFlow(node, currentBreakTarget, currentContinueTarget); + } + } + + function bindTryStatement(node: TryStatement): void { + const postFinallyLabel = createFlowLabel(); + const preTryFlow = currentFlow; + // TODO: Every statement in try block is potentially an exit point! + bind(node.tryBlock); + addAntecedent(postFinallyLabel, currentFlow); + if (node.catchClause) { + currentFlow = preTryFlow; + bind(node.catchClause); + addAntecedent(postFinallyLabel, currentFlow); + } + if (node.finallyBlock) { + currentFlow = preTryFlow; + bind(node.finallyBlock); + } + currentFlow = finishFlowLabel(postFinallyLabel); + } + + function bindSwitchStatement(node: SwitchStatement): void { + const postSwitchLabel = createFlowLabel(); + bind(node.expression); + const saveBreakTarget = currentBreakTarget; + const savePreSwitchCaseFlow = preSwitchCaseFlow; + currentBreakTarget = postSwitchLabel; + preSwitchCaseFlow = currentFlow; + bind(node.caseBlock); + addAntecedent(postSwitchLabel, currentFlow); + const hasDefault = forEach(node.caseBlock.clauses, c => c.kind === SyntaxKind.DefaultClause); + if (!hasDefault) { + addAntecedent(postSwitchLabel, preSwitchCaseFlow); + } + currentBreakTarget = saveBreakTarget; + preSwitchCaseFlow = savePreSwitchCaseFlow; + currentFlow = finishFlowLabel(postSwitchLabel); + } + + function bindCaseBlock(node: CaseBlock): void { + const clauses = node.clauses; + for (let i = 0; i < clauses.length; i++) { + const clause = clauses[i]; + if (clause.statements.length) { + if (currentFlow.kind === FlowKind.Unreachable) { + currentFlow = preSwitchCaseFlow; + } + else { + const preCaseLabel = createFlowLabel(); + addAntecedent(preCaseLabel, preSwitchCaseFlow); + addAntecedent(preCaseLabel, currentFlow); + currentFlow = finishFlowLabel(preCaseLabel); + } + bind(clause); + if (currentFlow.kind !== FlowKind.Unreachable && i !== clauses.length - 1 && options.noFallthroughCasesInSwitch) { + errorOnFirstToken(clause, Diagnostics.Fallthrough_case_in_switch); + } + } + else { + bind(clause); + } + } + } + + function pushActiveLabel(name: string, breakTarget: FlowLabel, continueTarget: FlowLabel): ActiveLabel { + const activeLabel = { + name, + breakTarget, + continueTarget, + referenced: false + }; + (activeLabels || (activeLabels = [])).push(activeLabel); + return activeLabel; + } + + function popActiveLabel() { + activeLabels.pop(); + } + + function bindLabeledStatement(node: LabeledStatement): void { + const preStatementLabel = createFlowLabel(); + const postStatementLabel = createFlowLabel(); + bind(node.label); + addAntecedent(preStatementLabel, currentFlow); + const activeLabel = pushActiveLabel(node.label.text, postStatementLabel, preStatementLabel); + bind(node.statement); + popActiveLabel(); + if (!activeLabel.referenced && !options.allowUnusedLabels) { + file.bindDiagnostics.push(createDiagnosticForNode(node.label, Diagnostics.Unused_label)); + } + addAntecedent(postStatementLabel, currentFlow); + currentFlow = finishFlowLabel(postStatementLabel); + } + + function bindDestructuringTargetFlow(node: Expression) { + if (node.kind === SyntaxKind.BinaryExpression && (node).operatorToken.kind === SyntaxKind.EqualsToken) { + bindAssignmentTargetFlow((node).left); + } + else { + bindAssignmentTargetFlow(node); + } + } + + function bindAssignmentTargetFlow(node: Expression) { + if (isNarrowableReference(node)) { + currentFlow = createFlowAssignment(currentFlow, node); + } + else if (node.kind === SyntaxKind.ArrayLiteralExpression) { + for (const e of (node).elements) { + if (e.kind === SyntaxKind.SpreadElementExpression) { + bindAssignmentTargetFlow((e).expression); + } + else { + bindDestructuringTargetFlow(e); + } + } + } + else if (node.kind === SyntaxKind.ObjectLiteralExpression) { + for (const p of (node).properties) { + if (p.kind === SyntaxKind.PropertyAssignment) { + bindDestructuringTargetFlow((p).initializer); + } + else if (p.kind === SyntaxKind.ShorthandPropertyAssignment) { + bindAssignmentTargetFlow((p).name); + } + } + } + } + + function bindLogicalExpression(node: BinaryExpression, trueTarget: FlowLabel, falseTarget: FlowLabel) { + const preRightLabel = createFlowLabel(); + if (node.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) { + bindCondition(node.left, preRightLabel, falseTarget); + } + else { + bindCondition(node.left, trueTarget, preRightLabel); + } + currentFlow = finishFlowLabel(preRightLabel); + bind(node.operatorToken); + bindCondition(node.right, trueTarget, falseTarget); + } + + function bindPrefixUnaryExpressionFlow(node: PrefixUnaryExpression) { + if (node.operator === SyntaxKind.ExclamationToken) { + const saveTrueTarget = currentTrueTarget; + currentTrueTarget = currentFalseTarget; + currentFalseTarget = saveTrueTarget; + forEachChild(node, bind); + currentFalseTarget = currentTrueTarget; + currentTrueTarget = saveTrueTarget; + } + else { + forEachChild(node, bind); + } + } + + function bindBinaryExpressionFlow(node: BinaryExpression) { + const operator = node.operatorToken.kind; + if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.BarBarToken) { + if (isTopLevelLogicalExpression(node)) { + const postExpressionLabel = createFlowLabel(); + bindLogicalExpression(node, postExpressionLabel, postExpressionLabel); + currentFlow = finishFlowLabel(postExpressionLabel); + } + else { + bindLogicalExpression(node, currentTrueTarget, currentFalseTarget); + } + } + else { + forEachChild(node, bind); + if (operator === SyntaxKind.EqualsToken && !isAssignmentTarget(node)) { + bindAssignmentTargetFlow(node.left); + } + } + } + + function bindConditionalExpressionFlow(node: ConditionalExpression) { + const trueLabel = createFlowLabel(); + const falseLabel = createFlowLabel(); + const postExpressionLabel = createFlowLabel(); + bindCondition(node.condition, trueLabel, falseLabel); + currentFlow = finishFlowLabel(trueLabel); + bind(node.whenTrue); + addAntecedent(postExpressionLabel, currentFlow); + currentFlow = finishFlowLabel(falseLabel); + bind(node.whenFalse); + addAntecedent(postExpressionLabel, currentFlow); + currentFlow = finishFlowLabel(postExpressionLabel); + } + + function bindInitializedVariableFlow(node: VariableDeclaration | BindingElement) { + const name = node.name; + if (isBindingPattern(name)) { + for (const child of name.elements) { + bindInitializedVariableFlow(child); + } + } + else { + currentFlow = createFlowAssignment(currentFlow, node); + } + } + + function bindVariableDeclarationFlow(node: VariableDeclaration) { + forEachChild(node, bind); + if (node.initializer || node.parent.parent.kind === SyntaxKind.ForInStatement || node.parent.parent.kind === SyntaxKind.ForOfStatement) { + bindInitializedVariableFlow(node); } } @@ -1283,7 +1614,16 @@ namespace ts { switch (node.kind) { /* Strict mode checks */ case SyntaxKind.Identifier: + case SyntaxKind.ThisKeyword: + if (currentFlow && (isExpression(node) || parent.kind === SyntaxKind.ShorthandPropertyAssignment)) { + node.flowNode = currentFlow; + } return checkStrictModeIdentifier(node); + case SyntaxKind.PropertyAccessExpression: + if (currentFlow && isNarrowableReference(node)) { + node.flowNode = currentFlow; + } + break; case SyntaxKind.BinaryExpression: if (isInJavaScriptFile(node)) { const specialKind = getSpecialPropertyAssignmentKind(node); @@ -1720,132 +2060,53 @@ namespace ts { // reachability checks - function pushNamedLabel(name: Identifier): boolean { - initializeReachabilityStateIfNecessary(); - - if (hasProperty(labelIndexMap, name.text)) { - return false; - } - labelIndexMap[name.text] = labelStack.push(Reachability.Uninitialized) - 1; - return true; - } - - function pushImplicitLabel(): number { - initializeReachabilityStateIfNecessary(); - - const index = labelStack.push(Reachability.Uninitialized) - 1; - implicitLabels.push(index); - return index; - } - - function popNamedLabel(label: Identifier, outerState: Reachability): void { - const index = labelIndexMap[label.text]; - Debug.assert(index !== undefined); - Debug.assert(labelStack.length == index + 1); - - labelIndexMap[label.text] = undefined; - - setCurrentStateAtLabel(labelStack.pop(), outerState, label); - } - - function popImplicitLabel(implicitLabelIndex: number, outerState: Reachability): void { - if (labelStack.length !== implicitLabelIndex + 1) { - Debug.assert(false, `Label stack: ${labelStack.length}, index:${implicitLabelIndex}`); - } - - const i = implicitLabels.pop(); - - if (implicitLabelIndex !== i) { - Debug.assert(false, `i: ${i}, index: ${implicitLabelIndex}`); - } - - setCurrentStateAtLabel(labelStack.pop(), outerState, /*name*/ undefined); - } - - function setCurrentStateAtLabel(innerMergedState: Reachability, outerState: Reachability, label: Identifier): void { - if (innerMergedState === Reachability.Uninitialized) { - if (label && !options.allowUnusedLabels) { - file.bindDiagnostics.push(createDiagnosticForNode(label, Diagnostics.Unused_label)); - } - currentReachabilityState = outerState; - } - else { - currentReachabilityState = or(innerMergedState, outerState); - } - } - - function jumpToLabel(label: Identifier, outerState: Reachability): boolean { - initializeReachabilityStateIfNecessary(); - - const index = label ? labelIndexMap[label.text] : lastOrUndefined(implicitLabels); - if (index === undefined) { - // reference to unknown label or - // break/continue used outside of loops - return false; - } - const stateAtLabel = labelStack[index]; - labelStack[index] = stateAtLabel === Reachability.Uninitialized ? outerState : or(stateAtLabel, outerState); - return true; + function shouldReportErrorOnModuleDeclaration(node: ModuleDeclaration): boolean { + const instanceState = getModuleInstanceState(node); + return instanceState === ModuleInstanceState.Instantiated || (instanceState === ModuleInstanceState.ConstEnumOnly && options.preserveConstEnums); } function checkUnreachable(node: Node): boolean { - switch (currentReachabilityState) { - case Reachability.Unreachable: - const reportError = - // report error on all statements except empty ones - (isStatement(node) && node.kind !== SyntaxKind.EmptyStatement) || - // report error on class declarations - node.kind === SyntaxKind.ClassDeclaration || - // report error on instantiated modules or const-enums only modules if preserveConstEnums is set - (node.kind === SyntaxKind.ModuleDeclaration && shouldReportErrorOnModuleDeclaration(node)) || - // report error on regular enums and const enums if preserveConstEnums is set - (node.kind === SyntaxKind.EnumDeclaration && (!isConstEnumDeclaration(node) || options.preserveConstEnums)); + if (currentFlow.kind !== FlowKind.Unreachable) { + return false; + } + if (currentFlow === unreachableFlow) { + const reportError = + // report error on all statements except empty ones + (isStatement(node) && node.kind !== SyntaxKind.EmptyStatement) || + // report error on class declarations + node.kind === SyntaxKind.ClassDeclaration || + // report error on instantiated modules or const-enums only modules if preserveConstEnums is set + (node.kind === SyntaxKind.ModuleDeclaration && shouldReportErrorOnModuleDeclaration(node)) || + // report error on regular enums and const enums if preserveConstEnums is set + (node.kind === SyntaxKind.EnumDeclaration && (!isConstEnumDeclaration(node) || options.preserveConstEnums)); - if (reportError) { - currentReachabilityState = Reachability.ReportedUnreachable; + if (reportError) { + currentFlow = reportedUnreachableFlow; - // unreachable code is reported if - // - user has explicitly asked about it AND - // - statement is in not ambient context (statements in ambient context is already an error - // so we should not report extras) AND - // - node is not variable statement OR - // - node is block scoped variable statement OR - // - node is not block scoped variable statement and at least one variable declaration has initializer - // Rationale: we don't want to report errors on non-initialized var's since they are hoisted - // On the other side we do want to report errors on non-initialized 'lets' because of TDZ - const reportUnreachableCode = - !options.allowUnreachableCode && - !isInAmbientContext(node) && - ( - node.kind !== SyntaxKind.VariableStatement || - getCombinedNodeFlags((node).declarationList) & NodeFlags.BlockScoped || - forEach((node).declarationList.declarations, d => d.initializer) - ); + // unreachable code is reported if + // - user has explicitly asked about it AND + // - statement is in not ambient context (statements in ambient context is already an error + // so we should not report extras) AND + // - node is not variable statement OR + // - node is block scoped variable statement OR + // - node is not block scoped variable statement and at least one variable declaration has initializer + // Rationale: we don't want to report errors on non-initialized var's since they are hoisted + // On the other side we do want to report errors on non-initialized 'lets' because of TDZ + const reportUnreachableCode = + !options.allowUnreachableCode && + !isInAmbientContext(node) && + ( + node.kind !== SyntaxKind.VariableStatement || + getCombinedNodeFlags((node).declarationList) & NodeFlags.BlockScoped || + forEach((node).declarationList.declarations, d => d.initializer) + ); - if (reportUnreachableCode) { - errorOnFirstToken(node, Diagnostics.Unreachable_code_detected); - } + if (reportUnreachableCode) { + errorOnFirstToken(node, Diagnostics.Unreachable_code_detected); } - case Reachability.ReportedUnreachable: - return true; - default: - return false; + } } - - function shouldReportErrorOnModuleDeclaration(node: ModuleDeclaration): boolean { - const instanceState = getModuleInstanceState(node); - return instanceState === ModuleInstanceState.Instantiated || (instanceState === ModuleInstanceState.ConstEnumOnly && options.preserveConstEnums); - } - } - - function initializeReachabilityStateIfNecessary(): void { - if (labelIndexMap) { - return; - } - currentReachabilityState = Reachability.Reachable; - labelIndexMap = {}; - labelStack = []; - implicitLabels = []; + return true; } } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2cc5fb123ee..99618654182 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5,6 +5,7 @@ namespace ts { let nextSymbolId = 1; let nextNodeId = 1; let nextMergeId = 1; + let nextFlowId = 1; export function getNodeId(node: Node): number { if (!node.id) { @@ -121,7 +122,7 @@ namespace ts { const unknownType = createIntrinsicType(TypeFlags.Any, "unknown"); const emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); - const emptyUnionType = emptyObjectType; + const emptyUnionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); const emptyGenericType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); emptyGenericType.instantiations = {}; @@ -180,6 +181,9 @@ namespace ts { let deferredNodes: Node[]; + let flowStackStart = 0; + let flowStackCount = 0; + const tupleTypes: Map = {}; const unionTypes: Map = {}; const intersectionTypes: Map = {}; @@ -192,32 +196,84 @@ namespace ts { const mergedSymbols: Symbol[] = []; const symbolLinks: SymbolLinks[] = []; const nodeLinks: NodeLinks[] = []; + const flowTypeCaches: Map[] = []; + const flowStackNodes: FlowNode[] = []; + const flowStackCacheKeys: string[] = []; const potentialThisCollisions: Node[] = []; const awaitedTypeStack: number[] = []; const diagnostics = createDiagnosticCollection(); - const primitiveTypeInfo: Map<{ type: Type; flags: TypeFlags }> = { - "string": { - type: stringType, - flags: TypeFlags.StringLike - }, - "number": { - type: numberType, - flags: TypeFlags.NumberLike - }, - "boolean": { - type: booleanType, - flags: TypeFlags.Boolean - }, - "symbol": { - type: esSymbolType, - flags: TypeFlags.ESSymbol - }, - "undefined": { - type: undefinedType, - flags: TypeFlags.ContainsUndefinedOrNull - } + const enum TypeFacts { + None = 0, + TypeofEQString = 1 << 0, // typeof x === "string" + TypeofEQNumber = 1 << 1, // typeof x === "number" + TypeofEQBoolean = 1 << 2, // typeof x === "boolean" + TypeofEQSymbol = 1 << 3, // typeof x === "symbol" + TypeofEQObject = 1 << 4, // typeof x === "object" + TypeofEQFunction = 1 << 5, // typeof x === "function" + TypeofEQHostObject = 1 << 6, // typeof x === "xxx" + TypeofNEString = 1 << 7, // typeof x !== "string" + TypeofNENumber = 1 << 8, // typeof x !== "number" + TypeofNEBoolean = 1 << 9, // typeof x !== "boolean" + TypeofNESymbol = 1 << 10, // typeof x !== "symbol" + TypeofNEObject = 1 << 11, // typeof x !== "object" + TypeofNEFunction = 1 << 12, // typeof x !== "function" + TypeofNEHostObject = 1 << 13, // typeof x !== "xxx" + EQUndefined = 1 << 14, // x === undefined + EQNull = 1 << 15, // x === null + EQUndefinedOrNull = 1 << 16, // x == undefined / x == null + NEUndefined = 1 << 17, // x !== undefined + NENull = 1 << 18, // x !== null + NEUndefinedOrNull = 1 << 19, // x != undefined / x != null + Truthy = 1 << 20, // x + Falsy = 1 << 21, // !x + All = (1 << 22) - 1, + // The following members encode facts about particular kinds of types for use in the getTypeFacts function. + // The presence of a particular fact means that the given test is true for some (and possibly all) values + // of that kind of type. + StringStrictFacts = TypeofEQString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull | Truthy | Falsy, + StringFacts = StringStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull, + NumberStrictFacts = TypeofEQNumber | TypeofNEString | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull | Truthy | Falsy, + NumberFacts = NumberStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull, + BooleanStrictFacts = TypeofEQBoolean | TypeofNEString | TypeofNENumber | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull | Truthy | Falsy, + BooleanFacts = BooleanStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull, + SymbolStrictFacts = TypeofEQSymbol | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull | Truthy, + SymbolFacts = SymbolStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, + ObjectStrictFacts = TypeofEQObject | TypeofEQHostObject | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | NEUndefined | NENull | NEUndefinedOrNull | Truthy, + ObjectFacts = ObjectStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, + FunctionStrictFacts = TypeofEQFunction | TypeofEQHostObject | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | NEUndefined | NENull | NEUndefinedOrNull | Truthy, + FunctionFacts = FunctionStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, + UndefinedFacts = TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | EQUndefined | EQUndefinedOrNull | NENull | Falsy, + NullFacts = TypeofEQObject | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | TypeofNEHostObject | EQNull | EQUndefinedOrNull | NEUndefined | Falsy, + } + + const typeofEQFacts: Map = { + "string": TypeFacts.TypeofEQString, + "number": TypeFacts.TypeofEQNumber, + "boolean": TypeFacts.TypeofEQBoolean, + "symbol": TypeFacts.TypeofEQSymbol, + "undefined": TypeFacts.EQUndefined, + "object": TypeFacts.TypeofEQObject, + "function": TypeFacts.TypeofEQFunction + }; + + const typeofNEFacts: Map = { + "string": TypeFacts.TypeofNEString, + "number": TypeFacts.TypeofNENumber, + "boolean": TypeFacts.TypeofNEBoolean, + "symbol": TypeFacts.TypeofNESymbol, + "undefined": TypeFacts.NEUndefined, + "object": TypeFacts.TypeofNEObject, + "function": TypeFacts.TypeofNEFunction + }; + + const typeofTypesByName: Map = { + "string": stringType, + "number": numberType, + "boolean": booleanType, + "symbol": esSymbolType, + "undefined": undefinedType }; let jsxElementType: ObjectType; @@ -398,7 +454,11 @@ namespace ts { } else { // find a module that about to be augmented - let mainModule = resolveExternalModuleNameWorker(moduleName, moduleName, Diagnostics.Invalid_module_name_in_augmentation_module_0_cannot_be_found); + // do not validate names of augmentations that are defined in ambient context + const moduleNotFoundError = !isInAmbientContext(moduleName.parent.parent) + ? Diagnostics.Invalid_module_name_in_augmentation_module_0_cannot_be_found + : undefined; + let mainModule = resolveExternalModuleNameWorker(moduleName, moduleName, moduleNotFoundError); if (!mainModule) { return; } @@ -1808,12 +1868,38 @@ namespace ts { /** * Writes only the name of the symbol out to the writer. Uses the original source text - * for the name of the symbol if it is available to match how the user inputted the name. + * for the name of the symbol if it is available to match how the user wrote the name. */ function appendSymbolNameOnly(symbol: Symbol, writer: SymbolWriter): void { writer.writeSymbol(getNameOfSymbol(symbol), symbol); } + /** + * Writes a property access or element access with the name of the symbol out to the writer. + * Uses the original source text for the name of the symbol if it is available to match how the user wrote the name, + * ensuring that any names written with literals use element accesses. + */ + function appendPropertyOrElementAccessForSymbol(symbol: Symbol, writer: SymbolWriter): void { + const symbolName = getNameOfSymbol(symbol); + const firstChar = symbolName.charCodeAt(0); + const needsElementAccess = !isIdentifierStart(firstChar, languageVersion); + + if (needsElementAccess) { + writePunctuation(writer, SyntaxKind.OpenBracketToken); + if (isSingleOrDoubleQuote(firstChar)) { + writer.writeStringLiteral(symbolName); + } + else { + writer.writeSymbol(symbolName, symbol); + } + writePunctuation(writer, SyntaxKind.CloseBracketToken); + } + else { + writePunctuation(writer, SyntaxKind.DotToken); + writer.writeSymbol(symbolName, symbol); + } + } + /** * Enclosing declaration is optional when we don't want to get qualified name in the enclosing declaration scope * Meaning needs to be specified if the enclosing declaration is given @@ -1832,10 +1918,12 @@ namespace ts { buildTypeParameterDisplayFromSymbol(parentSymbol, writer, enclosingDeclaration); } } - writePunctuation(writer, SyntaxKind.DotToken); + appendPropertyOrElementAccessForSymbol(symbol, writer); + } + else { + appendSymbolNameOnly(symbol, writer); } parentSymbol = symbol; - appendSymbolNameOnly(symbol, writer); } // const the writer know we just wrote out a symbol. The declaration emitter writer uses @@ -1962,7 +2050,7 @@ namespace ts { } if (pos < end) { writePunctuation(writer, SyntaxKind.LessThanToken); - writeType(typeArguments[pos], TypeFormatFlags.None); + writeType(typeArguments[pos], TypeFormatFlags.InFirstTypeArgument); pos++; while (pos < end) { writePunctuation(writer, SyntaxKind.CommaToken); @@ -2030,10 +2118,10 @@ namespace ts { if (symbol) { // Always use 'typeof T' for type of class, enum, and module objects if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.ValueModule)) { - writeTypeofSymbol(type, flags); + writeTypeOfSymbol(type, flags); } else if (shouldWriteTypeOfFunctionSymbol()) { - writeTypeofSymbol(type, flags); + writeTypeOfSymbol(type, flags); } else if (contains(symbolStack, symbol)) { // If type is an anonymous type literal in a type alias declaration, use type alias name @@ -2078,7 +2166,7 @@ namespace ts { } } - function writeTypeofSymbol(type: ObjectType, typeFormatFlags?: TypeFormatFlags) { + function writeTypeOfSymbol(type: ObjectType, typeFormatFlags?: TypeFormatFlags) { writeKeyword(writer, SyntaxKind.TypeOfKeyword); writeSpace(writer); buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Value, SymbolFormatFlags.None, typeFormatFlags); @@ -2115,6 +2203,19 @@ namespace ts { } } + function shouldAddParenthesisAroundFunctionType(callSignature: Signature, flags: TypeFormatFlags) { + if (flags & TypeFormatFlags.InElementType) { + return true; + } + else if (flags & TypeFormatFlags.InFirstTypeArgument) { + // Add parenthesis around function type for the first type argument to avoid ambiguity + const typeParameters = callSignature.target && (flags & TypeFormatFlags.WriteTypeArgumentsOfSignature) ? + callSignature.target.typeParameters : callSignature.typeParameters; + return typeParameters && typeParameters.length !== 0; + } + return false; + } + function writeLiteralType(type: ObjectType, flags: TypeFormatFlags) { const resolved = resolveStructuredTypeMembers(type); if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { @@ -2125,11 +2226,12 @@ namespace ts { } if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) { - if (flags & TypeFormatFlags.InElementType) { + const parenthesizeSignature = shouldAddParenthesisAroundFunctionType(resolved.callSignatures[0], flags); + if (parenthesizeSignature) { writePunctuation(writer, SyntaxKind.OpenParenToken); } buildSignatureDisplay(resolved.callSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | TypeFormatFlags.WriteArrowStyleSignature, /*kind*/ undefined, symbolStack); - if (flags & TypeFormatFlags.InElementType) { + if (parenthesizeSignature) { writePunctuation(writer, SyntaxKind.CloseParenToken); } return; @@ -2289,12 +2391,14 @@ namespace ts { function buildDisplayForTypeArgumentsAndDelimiters(typeParameters: TypeParameter[], mapper: TypeMapper, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { if (typeParameters && typeParameters.length) { writePunctuation(writer, SyntaxKind.LessThanToken); + let flags = TypeFormatFlags.InFirstTypeArgument; for (let i = 0; i < typeParameters.length; i++) { if (i > 0) { writePunctuation(writer, SyntaxKind.CommaToken); writeSpace(writer); + flags = TypeFormatFlags.None; } - buildTypeDisplay(mapper(typeParameters[i]), writer, enclosingDeclaration, TypeFormatFlags.None); + buildTypeDisplay(mapper(typeParameters[i]), writer, enclosingDeclaration, flags); } writePunctuation(writer, SyntaxKind.GreaterThanToken); } @@ -2719,7 +2823,7 @@ namespace ts { // In strict null checking mode, if a default value of a non-undefined type is specified, remove // undefined from the final type. if (strictNullChecks && declaration.initializer && !(getNullableKind(checkExpressionCached(declaration.initializer)) & TypeFlags.Undefined)) { - type = removeNullableKind(type, TypeFlags.Undefined); + type = getTypeWithFacts(type, TypeFacts.NEUndefined); } return type; } @@ -4856,7 +4960,7 @@ namespace ts { if (type.flags & TypeFlags.Undefined) typeSet.containsUndefined = true; if (type.flags & TypeFlags.Null) typeSet.containsNull = true; } - else if (!contains(typeSet, type)) { + else if (type !== emptyUnionType && !contains(typeSet, type)) { typeSet.push(type); } } @@ -4912,7 +5016,9 @@ namespace ts { removeSubtypes(typeSet); } if (typeSet.length === 0) { - return typeSet.containsNull ? nullType : undefinedType; + return typeSet.containsNull ? nullType : + typeSet.containsUndefined ? undefinedType : + emptyUnionType; } else if (typeSet.length === 1) { return typeSet[0]; @@ -5701,7 +5807,7 @@ namespace ts { return isIdenticalTo(source, target); } - if (isTypeAny(target)) return Ternary.True; + if (target.flags & TypeFlags.Any) return Ternary.True; if (source.flags & TypeFlags.Undefined) { if (!strictNullChecks || target.flags & (TypeFlags.Undefined | TypeFlags.Void) || source === emptyArrayElementType) return Ternary.True; } @@ -6633,11 +6739,6 @@ namespace ts { return flags & TypeFlags.Nullable; } - function getNullableTypeOfKind(kind: TypeFlags) { - return kind & TypeFlags.Null ? kind & TypeFlags.Undefined ? - getUnionType([nullType, undefinedType]) : nullType : undefinedType; - } - function addNullableKind(type: Type, kind: TypeFlags): Type { if ((getNullableKind(type) & kind) !== kind) { const types = [type]; @@ -6652,32 +6753,8 @@ namespace ts { return type; } - function removeNullableKind(type: Type, kind: TypeFlags) { - if (type.flags & TypeFlags.Union && getNullableKind(type) & kind) { - let firstType: Type; - let types: Type[]; - for (const t of (type as UnionType).types) { - if (!(t.flags & kind)) { - if (!firstType) { - firstType = t; - } - else { - if (!types) { - types = [firstType]; - } - types.push(t); - } - } - } - if (firstType) { - type = types ? getUnionType(types) : firstType; - } - } - return type; - } - function getNonNullableType(type: Type): Type { - return strictNullChecks ? removeNullableKind(type, TypeFlags.Nullable) : type; + return strictNullChecks ? getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type; } /** @@ -7174,19 +7251,7 @@ namespace ts { // EXPRESSION TYPE CHECKING - function createTransientIdentifier(symbol: Symbol, location: Node): Identifier { - const result = createNode(SyntaxKind.Identifier); - result.text = symbol.name; - result.resolvedSymbol = symbol; - result.parent = location; - result.id = -1; - return result; - } - function getResolvedSymbol(node: Identifier): Symbol { - if (node.id === -1) { - return (node).resolvedSymbol; - } const links = getNodeLinks(node); if (!links.resolvedSymbol) { links.resolvedSymbol = !nodeIsMissing(node) && resolveName(node, node.text, SymbolFlags.Value | SymbolFlags.ExportValue, Diagnostics.Cannot_find_name_0, node) || unknownSymbol; @@ -7213,11 +7278,11 @@ namespace ts { Debug.fail("should not get here"); } - // Return the assignment key for a "dotted name" (i.e. a sequence of identifiers + // Return the flow cache key for a "dotted name" (i.e. a sequence of identifiers // separated by dots). The key consists of the id of the symbol referenced by the // leftmost identifier followed by zero or more property names separated by dots. // The result is undefined if the reference isn't a dotted name. - function getAssignmentKey(node: Node): string { + function getFlowCacheKey(node: Node): string { if (node.kind === SyntaxKind.Identifier) { const symbol = getResolvedSymbol(node); return symbol !== unknownSymbol ? "" + getSymbolId(symbol) : undefined; @@ -7226,125 +7291,12 @@ namespace ts { return "0"; } if (node.kind === SyntaxKind.PropertyAccessExpression) { - const key = getAssignmentKey((node).expression); + const key = getFlowCacheKey((node).expression); return key && key + "." + (node).name.text; } return undefined; } - function hasInitializer(node: VariableLikeDeclaration): boolean { - return !!(node.initializer || isBindingPattern(node.parent) && hasInitializer(node.parent.parent)); - } - - // For a given node compute a map of which dotted names are assigned within - // the node. - function getAssignmentMap(node: Node): Map { - const assignmentMap: Map = {}; - visit(node); - return assignmentMap; - - function visitReference(node: Identifier | PropertyAccessExpression) { - if (isAssignmentTarget(node) || isCompoundAssignmentTarget(node)) { - const key = getAssignmentKey(node); - if (key) { - assignmentMap[key] = true; - } - } - forEachChild(node, visit); - } - - function visitVariableDeclaration(node: VariableLikeDeclaration) { - if (!isBindingPattern(node.name) && hasInitializer(node)) { - assignmentMap[getSymbolId(getSymbolOfNode(node))] = true; - } - forEachChild(node, visit); - } - - function visit(node: Node) { - switch (node.kind) { - case SyntaxKind.Identifier: - case SyntaxKind.PropertyAccessExpression: - visitReference(node); - break; - case SyntaxKind.VariableDeclaration: - case SyntaxKind.BindingElement: - visitVariableDeclaration(node); - break; - case SyntaxKind.BinaryExpression: - case SyntaxKind.ObjectBindingPattern: - case SyntaxKind.ArrayBindingPattern: - case SyntaxKind.ArrayLiteralExpression: - case SyntaxKind.ObjectLiteralExpression: - case SyntaxKind.ElementAccessExpression: - case SyntaxKind.CallExpression: - case SyntaxKind.NewExpression: - case SyntaxKind.TypeAssertionExpression: - case SyntaxKind.AsExpression: - case SyntaxKind.NonNullExpression: - case SyntaxKind.ParenthesizedExpression: - case SyntaxKind.PrefixUnaryExpression: - case SyntaxKind.DeleteExpression: - case SyntaxKind.AwaitExpression: - case SyntaxKind.TypeOfExpression: - case SyntaxKind.VoidExpression: - case SyntaxKind.PostfixUnaryExpression: - case SyntaxKind.YieldExpression: - case SyntaxKind.ConditionalExpression: - case SyntaxKind.SpreadElementExpression: - case SyntaxKind.Block: - case SyntaxKind.VariableStatement: - case SyntaxKind.ExpressionStatement: - case SyntaxKind.IfStatement: - case SyntaxKind.DoStatement: - case SyntaxKind.WhileStatement: - case SyntaxKind.ForStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.ReturnStatement: - case SyntaxKind.WithStatement: - case SyntaxKind.SwitchStatement: - case SyntaxKind.CaseBlock: - case SyntaxKind.CaseClause: - case SyntaxKind.DefaultClause: - case SyntaxKind.LabeledStatement: - case SyntaxKind.ThrowStatement: - case SyntaxKind.TryStatement: - case SyntaxKind.CatchClause: - case SyntaxKind.JsxElement: - case SyntaxKind.JsxSelfClosingElement: - case SyntaxKind.JsxAttribute: - case SyntaxKind.JsxSpreadAttribute: - case SyntaxKind.JsxOpeningElement: - case SyntaxKind.JsxExpression: - forEachChild(node, visit); - break; - } - } - } - - function isReferenceAssignedWithin(reference: Node, node: Node): boolean { - if (reference.kind !== SyntaxKind.ThisKeyword) { - const key = getAssignmentKey(reference); - if (key) { - const links = getNodeLinks(node); - return (links.assignmentMap || (links.assignmentMap = getAssignmentMap(node)))[key]; - } - } - return false; - } - - function isAnyPartOfReferenceAssignedWithin(reference: Node, node: Node) { - while (true) { - if (isReferenceAssignedWithin(reference, node)) { - return true; - } - if (reference.kind !== SyntaxKind.PropertyAccessExpression) { - return false; - } - reference = (reference).expression; - } - } - function isNullOrUndefinedLiteral(node: Expression) { return node.kind === SyntaxKind.NullKeyword || node.kind === SyntaxKind.Identifier && getResolvedSymbol(node) === undefinedSymbol; @@ -7376,16 +7328,245 @@ namespace ts { return false; } - // Get the narrowed type of a given symbol at a given location + function containsMatchingReference(source: Node, target: Node) { + while (true) { + if (isMatchingReference(source, target)) { + return true; + } + if (source.kind !== SyntaxKind.PropertyAccessExpression) { + return false; + } + source = (source).expression; + } + } + + function hasMatchingArgument(callExpression: CallExpression, target: Node) { + if (callExpression.arguments) { + for (const argument of callExpression.arguments) { + if (isMatchingReference(argument, target)) { + return true; + } + } + } + if (callExpression.expression.kind === SyntaxKind.PropertyAccessExpression && + isMatchingReference((callExpression.expression).expression, target)) { + return true; + } + return false; + } + + function getFlowTypeCache(flow: FlowNode): Map { + if (!flow.id) { + flow.id = nextFlowId; + nextFlowId++; + } + return flowTypeCaches[flow.id] || (flowTypeCaches[flow.id] = {}); + } + + function isNarrowableReference(expr: Node): boolean { + return expr.kind === SyntaxKind.Identifier || + expr.kind === SyntaxKind.ThisKeyword || + expr.kind === SyntaxKind.PropertyAccessExpression && isNarrowableReference((expr).expression); + } + + function typeMaybeAssignableTo(source: Type, target: Type) { + if (!(source.flags & TypeFlags.Union)) { + return isTypeAssignableTo(source, target); + } + for (const t of (source).types) { + if (isTypeAssignableTo(t, target)) { + return true; + } + } + return false; + } + + // Remove those constituent types of declaredType to which no constituent type of assignedType is assignable. + // For example, when a variable of type number | string | boolean is assigned a value of type number | boolean, + // we remove type string. + function getAssignmentReducedType(declaredType: UnionType, assignedType: Type) { + if (declaredType !== assignedType && declaredType.flags & TypeFlags.Union) { + const reducedTypes = filter(declaredType.types, t => typeMaybeAssignableTo(assignedType, t)); + if (reducedTypes.length) { + return reducedTypes.length === 1 ? reducedTypes[0] : getUnionType(reducedTypes); + } + } + return declaredType; + } + + function getTypeFacts(type: Type): TypeFacts { + const flags = type.flags; + if (flags & TypeFlags.StringLike) { + return strictNullChecks ? TypeFacts.StringStrictFacts : TypeFacts.StringFacts; + } + if (flags & TypeFlags.NumberLike) { + return strictNullChecks ? TypeFacts.NumberStrictFacts : TypeFacts.NumberFacts; + } + if (flags & TypeFlags.Boolean) { + return strictNullChecks ? TypeFacts.BooleanStrictFacts : TypeFacts.BooleanFacts; + } + if (flags & TypeFlags.ObjectType) { + const resolved = resolveStructuredTypeMembers(type); + return resolved.callSignatures.length || resolved.constructSignatures.length || isTypeSubtypeOf(type, globalFunctionType) ? + strictNullChecks ? TypeFacts.FunctionStrictFacts : TypeFacts.FunctionFacts : + strictNullChecks ? TypeFacts.ObjectStrictFacts : TypeFacts.ObjectFacts; + } + if (flags & (TypeFlags.Void | TypeFlags.Undefined)) { + return TypeFacts.UndefinedFacts; + } + if (flags & TypeFlags.Null) { + return TypeFacts.NullFacts; + } + if (flags & TypeFlags.ESSymbol) { + return strictNullChecks ? TypeFacts.SymbolStrictFacts : TypeFacts.SymbolFacts; + } + if (flags & TypeFlags.TypeParameter) { + const constraint = getConstraintOfTypeParameter(type); + return constraint ? getTypeFacts(constraint) : TypeFacts.All; + } + if (flags & TypeFlags.Intersection) { + return reduceLeft((type).types, (flags, type) => flags |= getTypeFacts(type), TypeFacts.None); + } + return TypeFacts.All; + } + + function getTypeWithFacts(type: Type, include: TypeFacts) { + if (!(type.flags & TypeFlags.Union)) { + return getTypeFacts(type) & include ? type : emptyUnionType; + } + let firstType: Type; + let types: Type[]; + for (const t of (type as UnionType).types) { + if (getTypeFacts(t) & include) { + if (!firstType) { + firstType = t; + } + else { + if (!types) { + types = [firstType]; + } + types.push(t); + } + } + } + return firstType ? types ? getUnionType(types, /*noSubtypeReduction*/ true) : firstType : emptyUnionType; + } + + function getTypeWithDefault(type: Type, defaultExpression: Expression) { + if (defaultExpression) { + const defaultType = checkExpression(defaultExpression); + return getUnionType([getTypeWithFacts(type, TypeFacts.NEUndefined), defaultType]); + } + return type; + } + + function getTypeOfDestructuredProperty(type: Type, name: Identifier | LiteralExpression | ComputedPropertyName) { + const text = getTextOfPropertyName(name); + return getTypeOfPropertyOfType(type, text) || + isNumericLiteralName(text) && getIndexTypeOfType(type, IndexKind.Number) || + getIndexTypeOfType(type, IndexKind.String) || + unknownType; + } + + function getTypeOfDestructuredArrayElement(type: Type, index: number) { + return isTupleLikeType(type) && getTypeOfPropertyOfType(type, "" + index) || + checkIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false) || + unknownType; + } + + function getTypeOfDestructuredSpreadElement(type: Type) { + return createArrayType(checkIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false) || unknownType); + } + + function getAssignedTypeOfBinaryExpression(node: BinaryExpression): Type { + return node.parent.kind === SyntaxKind.ArrayLiteralExpression || node.parent.kind === SyntaxKind.PropertyAssignment ? + getTypeWithDefault(getAssignedType(node), node.right) : + checkExpression(node.right); + } + + function getAssignedTypeOfArrayLiteralElement(node: ArrayLiteralExpression, element: Expression): Type { + return getTypeOfDestructuredArrayElement(getAssignedType(node), indexOf(node.elements, element)); + } + + function getAssignedTypeOfSpreadElement(node: SpreadElementExpression): Type { + return getTypeOfDestructuredSpreadElement(getAssignedType(node.parent)); + } + + function getAssignedTypeOfPropertyAssignment(node: PropertyAssignment | ShorthandPropertyAssignment): Type { + return getTypeOfDestructuredProperty(getAssignedType(node.parent), node.name); + } + + function getAssignedTypeOfShorthandPropertyAssignment(node: ShorthandPropertyAssignment): Type { + return getTypeWithDefault(getAssignedTypeOfPropertyAssignment(node), node.objectAssignmentInitializer); + } + + function getAssignedType(node: Expression): Type { + const parent = node.parent; + switch (parent.kind) { + case SyntaxKind.ForInStatement: + return stringType; + case SyntaxKind.ForOfStatement: + return checkRightHandSideOfForOf((parent).expression) || unknownType; + case SyntaxKind.BinaryExpression: + return getAssignedTypeOfBinaryExpression(parent); + case SyntaxKind.ArrayLiteralExpression: + return getAssignedTypeOfArrayLiteralElement(parent, node); + case SyntaxKind.SpreadElementExpression: + return getAssignedTypeOfSpreadElement(parent); + case SyntaxKind.PropertyAssignment: + return getAssignedTypeOfPropertyAssignment(parent); + case SyntaxKind.ShorthandPropertyAssignment: + return getAssignedTypeOfShorthandPropertyAssignment(parent); + } + return unknownType; + } + + function getInitialTypeOfBindingElement(node: BindingElement): Type { + const pattern = node.parent; + const parentType = getInitialType(pattern.parent); + const type = pattern.kind === SyntaxKind.ObjectBindingPattern ? + getTypeOfDestructuredProperty(parentType, node.propertyName || node.name) : + !node.dotDotDotToken ? + getTypeOfDestructuredArrayElement(parentType, indexOf(pattern.elements, node)) : + getTypeOfDestructuredSpreadElement(parentType); + return getTypeWithDefault(type, node.initializer); + } + + function getTypeOfInitializer(node: Expression) { + // Return the cached type if one is available. If the type of the variable was inferred + // from its initializer, we'll already have cached the type. Otherwise we compute it now + // without caching such that transient types are reflected. + const links = getNodeLinks(node); + return links.resolvedType || checkExpression(node); + } + + function getInitialTypeOfVariableDeclaration(node: VariableDeclaration) { + if (node.initializer) { + return getTypeOfInitializer(node.initializer); + } + if (node.parent.parent.kind === SyntaxKind.ForInStatement) { + return stringType; + } + if (node.parent.parent.kind === SyntaxKind.ForOfStatement) { + return checkRightHandSideOfForOf((node.parent.parent).expression) || unknownType; + } + return unknownType; + } + + function getInitialType(node: VariableDeclaration | BindingElement) { + return node.kind === SyntaxKind.VariableDeclaration ? + getInitialTypeOfVariableDeclaration(node) : + getInitialTypeOfBindingElement(node); + } + function getNarrowedTypeOfReference(type: Type, reference: Node) { - if (!(type.flags & (TypeFlags.Any | TypeFlags.ObjectType | TypeFlags.Union | TypeFlags.TypeParameter))) { + if (!(type.flags & TypeFlags.Narrowable) || !isNarrowableReference(reference)) { return type; } const leftmostNode = getLeftmostIdentifierOrThis(reference); if (!leftmostNode) { return type; } - let top: Node; if (leftmostNode.kind === SyntaxKind.Identifier) { const leftmostSymbol = getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(leftmostNode)); if (!leftmostSymbol) { @@ -7395,81 +7576,133 @@ namespace ts { if (!declaration || declaration.kind !== SyntaxKind.VariableDeclaration && declaration.kind !== SyntaxKind.Parameter && declaration.kind !== SyntaxKind.BindingElement) { return type; } - top = getDeclarationContainer(declaration); - } - const originalType = type; - const nodeStack: { node: Node, child: Node }[] = []; - let node: Node = reference; - loop: while (node.parent) { - const child = node; - node = node.parent; - switch (node.kind) { - case SyntaxKind.IfStatement: - case SyntaxKind.ConditionalExpression: - case SyntaxKind.BinaryExpression: - nodeStack.push({node, child}); - break; - case SyntaxKind.SourceFile: - case SyntaxKind.ModuleDeclaration: - break loop; - default: - if (node === top || isFunctionLikeKind(node.kind)) { - break loop; - } - break; - } } + return getFlowTypeOfReference(reference, type, type); + } - let nodes: { node: Node, child: Node }; - while (nodes = nodeStack.pop()) { - const {node, child} = nodes; - switch (node.kind) { - case SyntaxKind.IfStatement: - // In a branch of an if statement, narrow based on controlling expression - if (child !== (node).expression) { - type = narrowType(type, (node).expression, /*assumeTrue*/ child === (node).thenStatement); - } - break; - case SyntaxKind.ConditionalExpression: - // In a branch of a conditional expression, narrow based on controlling condition - if (child !== (node).condition) { - type = narrowType(type, (node).condition, /*assumeTrue*/ child === (node).whenTrue); - } - break; - case SyntaxKind.BinaryExpression: - // In the right operand of an && or ||, narrow based on left operand - if (child === (node).right) { - if ((node).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) { - type = narrowType(type, (node).left, /*assumeTrue*/ true); + function getFlowTypeOfReference(reference: Node, declaredType: Type, initialType: Type) { + let key: string; + return reference.flowNode ? getTypeAtFlowNode(reference.flowNode) : declaredType; + + function getTypeAtFlowNode(flow: FlowNode): Type { + while (true) { + switch (flow.kind) { + case FlowKind.Assignment: + const type = getTypeAtFlowAssignment(flow); + if (!type) { + flow = (flow).antecedent; + continue; } - else if ((node).operatorToken.kind === SyntaxKind.BarBarToken) { - type = narrowType(type, (node).left, /*assumeTrue*/ false); + return type; + case FlowKind.Condition: + return getTypeAtFlowCondition(flow); + case FlowKind.Label: + if ((flow).antecedents.length === 1) { + flow = (flow).antecedents[0]; + continue; } + return getTypeAtFlowLabel(flow); + case FlowKind.Unreachable: + // Unreachable code errors are reported in the binding phase. Here we + // simply return the declared type to reduce follow-on errors. + return declaredType; + } + // At the top of the flow we have the initial type + return initialType; + } + } + + function getTypeAtFlowAssignment(flow: FlowAssignment) { + const node = flow.node; + // Assignments only narrow the computed type if the declared type is a union type. Thus, we + // only need to evaluate the assigned type if the declared type is a union type. + if ((node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement) && + reference.kind === SyntaxKind.Identifier && + getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(reference)) === getSymbolOfNode(node)) { + return declaredType.flags & TypeFlags.Union ? + getAssignmentReducedType(declaredType, getInitialType(node)) : + declaredType; + } + // If the node is not a variable declaration or binding element, it is an identifier + // or a dotted name that is the target of an assignment. If we have a match, reduce + // the declared type by the assigned type. + if (isMatchingReference(reference, node)) { + return declaredType.flags & TypeFlags.Union ? + getAssignmentReducedType(declaredType, getAssignedType(node)) : + declaredType; + } + // We didn't have a direct match. However, if the reference is a dotted name, this + // may be an assignment to a left hand part of the reference. For example, for a + // reference 'x.y.z', we may be at an assignment to 'x.y' or 'x'. In that case, + // return the declared type. + if (reference.kind === SyntaxKind.PropertyAccessExpression && + containsMatchingReference((reference).expression, node)) { + return declaredType; + } + // Assignment doesn't affect reference + return undefined; + } + + function getTypeAtFlowCondition(flow: FlowCondition) { + return narrowType(getTypeAtFlowNode(flow.antecedent), flow.expression, flow.assumeTrue); + } + + function getTypeAtFlowNodeCached(flow: FlowNode) { + const cache = getFlowTypeCache(flow); + if (!key) { + key = getFlowCacheKey(reference); + } + const cached = cache[key]; + if (cached) { + return cached; + } + // Return undefined if we're already processing the given node. + for (let i = flowStackStart; i < flowStackCount; i++) { + if (flowStackNodes[i] === flow && flowStackCacheKeys[i] === key) { + return undefined; + } + } + // Record node and key on stack of nodes being processed. + flowStackNodes[flowStackCount] = flow; + flowStackCacheKeys[flowStackCount] = key; + flowStackCount++; + const type = getTypeAtFlowNode(flow); + flowStackCount--; + // Record the result only if the cache is still empty. If checkExpressionCached was called + // during processing it is possible we've already recorded a result. + return cache[key] || (cache[key] = type); + } + + function getTypeAtFlowLabel(flow: FlowLabel) { + const antecedentTypes: Type[] = []; + for (const antecedent of flow.antecedents) { + const type = getTypeAtFlowNodeCached(antecedent); + if (type) { + // If the type at a particular antecedent path is the declared type and the + // reference is known to always be assigned (i.e. when declared and initial types + // are the same), there is no reason to process more antecedents since the only + // possible outcome is subtypes that will be removed in the final union type anyway. + if (type === declaredType && declaredType === initialType) { + return type; } - break; - default: - Debug.fail("Unreachable!"); - } - - // Use original type if construct contains assignments to variable - if (type !== originalType && isAnyPartOfReferenceAssignedWithin(reference, node)) { - type = originalType; + if (!contains(antecedentTypes, type)) { + antecedentTypes.push(type); + } + } } + return antecedentTypes.length === 0 ? declaredType : + antecedentTypes.length === 1 ? antecedentTypes[0] : + getUnionType(antecedentTypes); } - // Preserve old top-level behavior - if the branch is really an empty set, revert to prior type - if (type === emptyUnionType) { - type = originalType; - } - - return type; - function narrowTypeByTruthiness(type: Type, expr: Expression, assumeTrue: boolean): Type { - return strictNullChecks && assumeTrue && isMatchingReference(expr, reference) ? getNonNullableType(type) : type; + return isMatchingReference(expr, reference) ? getTypeWithFacts(type, assumeTrue ? TypeFacts.Truthy : TypeFacts.Falsy) : type; } function narrowTypeByBinaryExpression(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type { switch (expr.operatorToken.kind) { + case SyntaxKind.EqualsToken: + return narrowTypeByTruthiness(type, expr.left, assumeTrue); case SyntaxKind.EqualsEqualsToken: case SyntaxKind.ExclamationEqualsToken: case SyntaxKind.EqualsEqualsEqualsToken: @@ -7481,12 +7714,10 @@ namespace ts { return narrowTypeByTypeof(type, expr, assumeTrue); } break; - case SyntaxKind.AmpersandAmpersandToken: - return narrowTypeByAnd(type, expr, assumeTrue); - case SyntaxKind.BarBarToken: - return narrowTypeByOr(type, expr, assumeTrue); case SyntaxKind.InstanceOfKeyword: return narrowTypeByInstanceof(type, expr, assumeTrue); + case SyntaxKind.CommaToken: + return narrowType(type, expr.right, assumeTrue); } return type; } @@ -7501,13 +7732,12 @@ namespace ts { return type; } const doubleEquals = operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsToken; - const exprNullableKind = doubleEquals ? TypeFlags.Nullable : - expr.right.kind === SyntaxKind.NullKeyword ? TypeFlags.Null : TypeFlags.Undefined; - if (assumeTrue) { - const nullableKind = getNullableKind(type) & exprNullableKind; - return nullableKind ? getNullableTypeOfKind(nullableKind) : type; - } - return removeNullableKind(type, exprNullableKind); + const facts = doubleEquals ? + assumeTrue ? TypeFacts.EQUndefinedOrNull : TypeFacts.NEUndefinedOrNull : + expr.right.kind === SyntaxKind.NullKeyword ? + assumeTrue ? TypeFacts.EQNull : TypeFacts.NENull : + assumeTrue ? TypeFacts.EQUndefined : TypeFacts.NEUndefined; + return getTypeWithFacts(type, facts); } function narrowTypeByTypeof(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type { @@ -7522,63 +7752,19 @@ namespace ts { expr.operatorToken.kind === SyntaxKind.ExclamationEqualsEqualsToken) { assumeTrue = !assumeTrue; } - const typeInfo = primitiveTypeInfo[right.text]; - // Don't narrow `undefined` - if (typeInfo && typeInfo.type === undefinedType) { - return type; - } - let flags: TypeFlags; - if (typeInfo) { - flags = typeInfo.flags; - } - else { - assumeTrue = !assumeTrue; - flags = TypeFlags.NumberLike | TypeFlags.StringLike | TypeFlags.ESSymbol | TypeFlags.Boolean; - } - // At this point we can bail if it's not a union - if (!(type.flags & TypeFlags.Union)) { - // If we're on the true branch and the type is a subtype, we should return the primitive type - if (assumeTrue && typeInfo && isTypeSubtypeOf(typeInfo.type, type)) { - return typeInfo.type; + if (assumeTrue && !(type.flags & TypeFlags.Union)) { + // We narrow a non-union type to an exact primitive type if the non-union type + // is a supertype of that primtive type. For example, type 'any' can be narrowed + // to one of the primitive types. + const targetType = getProperty(typeofTypesByName, right.text); + if (targetType && isTypeSubtypeOf(targetType, type)) { + return targetType; } - // If the active non-union type would be removed from a union by this type guard, return an empty union - return filterUnion(type) ? type : emptyUnionType; - } - return getUnionType(filter((type as UnionType).types, filterUnion), /*noSubtypeReduction*/ true); - - function filterUnion(type: Type) { - return assumeTrue === !!(type.flags & flags); - } - } - - function narrowTypeByAnd(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type { - if (assumeTrue) { - // The assumed result is true, therefore we narrow assuming each operand to be true. - return narrowType(narrowType(type, expr.left, /*assumeTrue*/ true), expr.right, /*assumeTrue*/ true); - } - else { - // The assumed result is false. This means either the first operand was false, or the first operand was true - // and the second operand was false. We narrow with those assumptions and union the two resulting types. - return getUnionType([ - narrowType(type, expr.left, /*assumeTrue*/ false), - narrowType(type, expr.right, /*assumeTrue*/ false) - ]); - } - } - - function narrowTypeByOr(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type { - if (assumeTrue) { - // The assumed result is true. This means either the first operand was true, or the first operand was false - // and the second operand was true. We narrow with those assumptions and union the two resulting types. - return getUnionType([ - narrowType(type, expr.left, /*assumeTrue*/ true), - narrowType(type, expr.right, /*assumeTrue*/ true) - ]); - } - else { - // The assumed result is false, therefore we narrow assuming each operand to be false. - return narrowType(narrowType(type, expr.left, /*assumeTrue*/ false), expr.right, /*assumeTrue*/ false); } + const facts = assumeTrue ? + getProperty(typeofEQFacts, right.text) || TypeFacts.TypeofEQHostObject : + getProperty(typeofNEFacts, right.text) || TypeFacts.TypeofNEHostObject; + return getTypeWithFacts(type, facts); } function narrowTypeByInstanceof(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type { @@ -7624,34 +7810,31 @@ namespace ts { return type; } - function getNarrowedType(originalType: Type, narrowedTypeCandidate: Type, assumeTrue: boolean) { + function getNarrowedType(type: Type, candidate: Type, assumeTrue: boolean) { if (!assumeTrue) { - if (originalType.flags & TypeFlags.Union) { - return getUnionType(filter((originalType).types, t => !isTypeSubtypeOf(t, narrowedTypeCandidate))); - } - return originalType; + return type.flags & TypeFlags.Union ? + getUnionType(filter((type).types, t => !isTypeSubtypeOf(t, candidate))) : + type; } - - // If the current type is a union type, remove all constituents that aren't assignable to target. If that produces - // 0 candidates, fall back to the assignability check - if (originalType.flags & TypeFlags.Union) { - const assignableConstituents = filter((originalType).types, t => isTypeAssignableTo(t, narrowedTypeCandidate)); + // If the current type is a union type, remove all constituents that aren't assignable to + // the candidate type. If one or more constituents remain, return a union of those. + if (type.flags & TypeFlags.Union) { + const assignableConstituents = filter((type).types, t => isTypeAssignableTo(t, candidate)); if (assignableConstituents.length) { return getUnionType(assignableConstituents); } } - - const targetType = originalType.flags & TypeFlags.TypeParameter ? getApparentType(originalType) : originalType; - if (isTypeAssignableTo(narrowedTypeCandidate, targetType)) { - // Narrow to the target type if it's assignable to the current type - return narrowedTypeCandidate; - } - - return originalType; + // If the candidate type is assignable to the target type, narrow to the candidate type. + // Otherwise, if the current type is assignable to the candidate, keep the current type. + // Otherwise, the types are completely unrelated, so narrow to the empty type. + const targetType = type.flags & TypeFlags.TypeParameter ? getApparentType(type) : type; + return isTypeAssignableTo(candidate, targetType) ? candidate : + isTypeAssignableTo(type, candidate) ? type : + emptyUnionType; } function narrowTypeByTypePredicate(type: Type, callExpression: CallExpression, assumeTrue: boolean): Type { - if (type.flags & TypeFlags.Any) { + if (type.flags & TypeFlags.Any || !hasMatchingArgument(callExpression, reference)) { return type; } const signature = getResolvedSignature(callExpression); @@ -7712,18 +7895,19 @@ namespace ts { } // If location is an identifier or property access that references the given // symbol, use the location as the reference with respect to which we narrow. - if (isExpression(location)) { + if (isExpression(location) && !isAssignmentTarget(location)) { checkExpression(location); - if (getNodeLinks(location).resolvedSymbol === symbol) { + if (getExportSymbolOfValueSymbolIfExported(getNodeLinks(location).resolvedSymbol) === symbol) { return getNarrowedTypeOfReference(type, location); } } } // The location isn't a reference to the given symbol, meaning we're being asked // a hypothetical question of what type the symbol would have if there was a reference - // to it at the given location. To answer that question we manufacture a transient - // identifier at the location and narrow with respect to that identifier. - return getNarrowedTypeOfReference(type, createTransientIdentifier(symbol, location)); + // to it at the given location. Since we have no control flow information for the + // hypotherical reference (control flow information is created and attached by the + // binder), we simply return the declared type of the symbol. + return type; } function skipParenthesizedNodes(expression: Expression): Expression { @@ -7733,98 +7917,6 @@ namespace ts { return expression; } - function findFirstAssignment(symbol: Symbol, container: Node): Node { - return visit(isFunctionLike(container) ? (container).body : container); - - function visit(node: Node): Node { - switch (node.kind) { - case SyntaxKind.Identifier: - const assignment = getAssignmentRoot(node); - return assignment && getResolvedSymbol(node) === symbol ? assignment : undefined; - case SyntaxKind.BinaryExpression: - case SyntaxKind.VariableDeclaration: - case SyntaxKind.BindingElement: - case SyntaxKind.ObjectBindingPattern: - case SyntaxKind.ArrayBindingPattern: - case SyntaxKind.ArrayLiteralExpression: - case SyntaxKind.ObjectLiteralExpression: - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: - case SyntaxKind.CallExpression: - case SyntaxKind.NewExpression: - case SyntaxKind.TypeAssertionExpression: - case SyntaxKind.AsExpression: - case SyntaxKind.NonNullExpression: - case SyntaxKind.ParenthesizedExpression: - case SyntaxKind.PrefixUnaryExpression: - case SyntaxKind.DeleteExpression: - case SyntaxKind.AwaitExpression: - case SyntaxKind.TypeOfExpression: - case SyntaxKind.VoidExpression: - case SyntaxKind.PostfixUnaryExpression: - case SyntaxKind.YieldExpression: - case SyntaxKind.ConditionalExpression: - case SyntaxKind.SpreadElementExpression: - case SyntaxKind.VariableStatement: - case SyntaxKind.ExpressionStatement: - case SyntaxKind.IfStatement: - case SyntaxKind.DoStatement: - case SyntaxKind.WhileStatement: - case SyntaxKind.ForStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.ReturnStatement: - case SyntaxKind.WithStatement: - case SyntaxKind.SwitchStatement: - case SyntaxKind.CaseBlock: - case SyntaxKind.CaseClause: - case SyntaxKind.DefaultClause: - case SyntaxKind.LabeledStatement: - case SyntaxKind.ThrowStatement: - case SyntaxKind.TryStatement: - case SyntaxKind.CatchClause: - case SyntaxKind.JsxElement: - case SyntaxKind.JsxSelfClosingElement: - case SyntaxKind.JsxAttribute: - case SyntaxKind.JsxSpreadAttribute: - case SyntaxKind.JsxOpeningElement: - case SyntaxKind.JsxExpression: - case SyntaxKind.Block: - case SyntaxKind.SourceFile: - return forEachChild(node, visit); - } - return undefined; - } - } - - function checkVariableAssignedBefore(symbol: Symbol, reference: Node) { - if (!(symbol.flags & SymbolFlags.Variable)) { - return; - } - const declaration = symbol.valueDeclaration; - if (!declaration || declaration.kind !== SyntaxKind.VariableDeclaration || (declaration).initializer || isInAmbientContext(declaration)) { - return; - } - const parentParentKind = declaration.parent.parent.kind; - if (parentParentKind === SyntaxKind.ForOfStatement || parentParentKind === SyntaxKind.ForInStatement) { - return; - } - const declarationContainer = getContainingFunction(declaration) || getSourceFileOfNode(declaration); - const referenceContainer = getContainingFunction(reference) || getSourceFileOfNode(reference); - if (declarationContainer !== referenceContainer) { - return; - } - const links = getSymbolLinks(symbol); - if (!links.firstAssignmentChecked) { - links.firstAssignmentChecked = true; - links.firstAssignment = findFirstAssignment(symbol, declarationContainer); - } - if (links.firstAssignment && links.firstAssignment.end <= reference.pos) { - return; - } - error(reference, Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol)); - } - function checkIdentifier(node: Identifier): Type { const symbol = getResolvedSymbol(node); @@ -7877,10 +7969,23 @@ namespace ts { checkNestedBlockScopedBinding(node, symbol); const type = getTypeOfSymbol(localOrExportSymbol); - if (strictNullChecks && !isAssignmentTarget(node) && !(type.flags & TypeFlags.Any) && !(getNullableKind(type) & TypeFlags.Undefined)) { - checkVariableAssignedBefore(symbol, node); + if (!(localOrExportSymbol.flags & SymbolFlags.Variable) || isAssignmentTarget(node)) { + return type; } - return getNarrowedTypeOfReference(type, node); + const declaration = localOrExportSymbol.valueDeclaration; + const defaultsToDeclaredType = !strictNullChecks || !declaration || + declaration.kind === SyntaxKind.Parameter || isInAmbientContext(declaration) || + getContainingFunctionOrModule(declaration) !== getContainingFunctionOrModule(node); + if (defaultsToDeclaredType && !(type.flags & TypeFlags.Narrowable)) { + return type; + } + const flowType = getFlowTypeOfReference(node, type, defaultsToDeclaredType ? type : undefinedType); + if (strictNullChecks && !(type.flags & TypeFlags.Any) && !(getNullableKind(type) & TypeFlags.Undefined) && getNullableKind(flowType) & TypeFlags.Undefined) { + error(node, Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol)); + // Return the declared type to reduce follow-on errors + return type; + } + return flowType; } function isInsideFunction(node: Node, threshold: Node): boolean { @@ -8501,7 +8606,7 @@ namespace ts { const args = getEffectiveCallArguments(callTarget); const argIndex = indexOf(args, arg); if (argIndex >= 0) { - const signature = getResolvedSignature(callTarget); + const signature = getResolvedOrAnySignature(callTarget); return getTypeAtPosition(signature, argIndex); } return undefined; @@ -8826,44 +8931,6 @@ namespace ts { return mapper && mapper.context; } - // Return the root assignment node of an assignment target - function getAssignmentRoot(node: Node): Node { - while (node.parent.kind === SyntaxKind.ParenthesizedExpression) { - node = node.parent; - } - while (true) { - if (node.parent.kind === SyntaxKind.PropertyAssignment) { - node = node.parent.parent; - } - else if (node.parent.kind === SyntaxKind.ArrayLiteralExpression) { - node = node.parent; - } - else { - break; - } - } - const parent = node.parent; - return parent.kind === SyntaxKind.BinaryExpression && - (parent).operatorToken.kind === SyntaxKind.EqualsToken && - (parent).left === node ? parent : undefined; - } - - // 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'. - function isAssignmentTarget(node: Node): boolean { - return !!getAssignmentRoot(node); - } - - function isCompoundAssignmentTarget(node: Node) { - const parent = node.parent; - if (parent.kind === SyntaxKind.BinaryExpression && (parent).left === node) { - const operator = (parent).operatorToken.kind; - return operator >= SyntaxKind.FirstAssignment && operator <= SyntaxKind.LastAssignment; - } - return false; - } - function checkSpreadElementExpression(node: SpreadElementExpression, contextualMapper?: TypeMapper): Type { // It is usually not safe to call checkExpressionCached if we can be contextually typing. // You can tell that we are contextually typing because of the contextualMapper parameter. @@ -9671,8 +9738,14 @@ namespace ts { function checkNonNullExpression(node: Expression | QualifiedName) { const type = checkExpression(node); - if (strictNullChecks && getNullableKind(type)) { - error(node, Diagnostics.Object_is_possibly_null_or_undefined); + if (strictNullChecks) { + const kind = getNullableKind(type); + 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 type; @@ -9712,7 +9785,7 @@ namespace ts { } const propType = getTypeOfSymbol(prop); - return node.kind === SyntaxKind.PropertyAccessExpression && prop.flags & SymbolFlags.Property ? + return node.kind === SyntaxKind.PropertyAccessExpression && prop.flags & (SymbolFlags.Variable | SymbolFlags.Property) && !isAssignmentTarget(node) ? getNarrowedTypeOfReference(propType, node) : propType; } @@ -11067,6 +11140,20 @@ namespace ts { return resolveCall(node, callSignatures, candidatesOutArray, headMessage); } + function resolveSignature(node: CallLikeExpression, candidatesOutArray?: Signature[]): Signature { + switch (node.kind) { + case SyntaxKind.CallExpression: + return resolveCallExpression(node, candidatesOutArray); + case SyntaxKind.NewExpression: + return resolveNewExpression(node, candidatesOutArray); + case SyntaxKind.TaggedTemplateExpression: + return resolveTaggedTemplateExpression(node, candidatesOutArray); + case SyntaxKind.Decorator: + return resolveDecorator(node, candidatesOutArray); + } + Debug.fail("Branch in 'resolveSignature' should be unreachable."); + } + // candidatesOutArray is passed by signature help in the language service, and collectCandidates // must fill it up with the appropriate candidate signatures function getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[]): Signature { @@ -11075,26 +11162,23 @@ namespace ts { // However, it is possible that either candidatesOutArray was not passed in the first time, // or that a different candidatesOutArray was passed in. Therefore, we need to redo the work // to correctly fill the candidatesOutArray. - if (!links.resolvedSignature || candidatesOutArray) { - links.resolvedSignature = anySignature; - - if (node.kind === SyntaxKind.CallExpression) { - links.resolvedSignature = resolveCallExpression(node, candidatesOutArray); - } - else if (node.kind === SyntaxKind.NewExpression) { - links.resolvedSignature = resolveNewExpression(node, candidatesOutArray); - } - else if (node.kind === SyntaxKind.TaggedTemplateExpression) { - links.resolvedSignature = resolveTaggedTemplateExpression(node, candidatesOutArray); - } - else if (node.kind === SyntaxKind.Decorator) { - links.resolvedSignature = resolveDecorator(node, candidatesOutArray); - } - else { - Debug.fail("Branch in 'getResolvedSignature' should be unreachable."); - } + const cached = links.resolvedSignature; + if (cached && cached !== anySignature && !candidatesOutArray) { + return cached; } - return links.resolvedSignature; + links.resolvedSignature = anySignature; + const result = resolveSignature(node, candidatesOutArray); + // If signature resolution originated in control flow type analysis (for example to compute the + // assigned type in a flow assignment) we don't cache the result as it may be based on temporary + // types from the control flow analysis. + links.resolvedSignature = flowStackStart === flowStackCount ? result : cached; + return result; + } + + function getResolvedOrAnySignature(node: CallLikeExpression) { + // If we're already in the process of resolving the given signature, don't resolve again as + // that could cause infinite recursion. Instead, return anySignature. + return getNodeLinks(node).resolvedSignature === anySignature ? anySignature : getResolvedSignature(node); } function getInferredClassType(symbol: Symbol) { @@ -12237,7 +12321,13 @@ namespace ts { function checkExpressionCached(node: Expression, contextualMapper?: TypeMapper): Type { const links = getNodeLinks(node); if (!links.resolvedType) { + // When computing a type that we're going to cache, we need to ignore any ongoing control flow + // analysis because variables may have transient types in indeterminable states. Moving flowStackStart + // to the top of the stack ensures all transient types are computed from a known point. + const saveFlowStackStart = flowStackStart; + flowStackStart = flowStackCount; links.resolvedType = checkExpression(node, contextualMapper); + flowStackStart = saveFlowStackStart; } return links.resolvedType; } @@ -13772,7 +13862,7 @@ namespace ts { function checkCollisionWithArgumentsInGeneratedCode(node: SignatureDeclaration) { // no rest parameters \ declaration context \ overload - no codegen impact - if (!hasRestParameter(node) || isInAmbientContext(node) || nodeIsMissing((node).body)) { + if (!hasDeclaredRestParameter(node) || isInAmbientContext(node) || nodeIsMissing((node).body)) { return; } @@ -14283,23 +14373,21 @@ namespace ts { if (isTypeAny(inputType)) { return inputType; } - if (languageVersion >= ScriptTarget.ES6) { return checkElementTypeOfIterable(inputType, errorNode); } - if (allowStringInput) { return checkElementTypeOfArrayOrString(inputType, errorNode); } - if (isArrayLikeType(inputType)) { const indexType = getIndexTypeOfType(inputType, IndexKind.Number); if (indexType) { return indexType; } } - - error(errorNode, Diagnostics.Type_0_is_not_an_array_type, typeToString(inputType)); + if (errorNode) { + error(errorNode, Diagnostics.Type_0_is_not_an_array_type, typeToString(inputType)); + } return unknownType; } @@ -14484,7 +14572,7 @@ namespace ts { // Now that we've removed all the StringLike types, if no constituents remain, then the entire // arrayOrStringType was a string. - if (arrayType === emptyObjectType) { + if (arrayType === emptyUnionType) { return stringType; } } @@ -15577,7 +15665,9 @@ namespace ts { break; case SyntaxKind.ImportEqualsDeclaration: if ((node).moduleReference.kind !== SyntaxKind.StringLiteral) { - error((node).name, Diagnostics.Module_augmentation_cannot_introduce_new_names_in_the_top_level_scope); + if (!isGlobalAugmentation) { + error((node).name, Diagnostics.Module_augmentation_cannot_introduce_new_names_in_the_top_level_scope); + } break; } // fallthrough @@ -15601,6 +15691,9 @@ namespace ts { case SyntaxKind.InterfaceDeclaration: case SyntaxKind.ModuleDeclaration: case SyntaxKind.TypeAliasDeclaration: + if (isGlobalAugmentation) { + return; + } const symbol = getSymbolOfNode(node); if (symbol) { // module augmentations cannot introduce new names on the top level scope of the module @@ -15609,14 +15702,8 @@ namespace ts { // 2. main check - report error if value declaration of the parent symbol is module augmentation) let reportError = !(symbol.flags & SymbolFlags.Merged); if (!reportError) { - if (isGlobalAugmentation) { - // global symbol should not have parent since it is not explicitly exported - reportError = symbol.parent !== undefined; - } - else { - // symbol should not originate in augmentation - reportError = isExternalModuleAugmentation(symbol.parent.declarations[0]); - } + // symbol should not originate in augmentation + reportError = isExternalModuleAugmentation(symbol.parent.declarations[0]); } if (reportError) { error(node, Diagnostics.Module_augmentation_cannot_introduce_new_names_in_the_top_level_scope); @@ -15807,7 +15894,7 @@ namespace ts { const symbol = resolveName(exportedName, exportedName.text, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined); if (symbol && (symbol === undefinedSymbol || isGlobalSourceFile(getDeclarationContainer(symbol.declarations[0])))) { - error(exportedName, Diagnostics.Cannot_re_export_name_that_is_not_defined_in_the_module); + error(exportedName, Diagnostics.Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module, exportedName.text); } else { markExportAsReferenced(node); diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 76306e290ca..79b6249539d 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -91,10 +91,10 @@ namespace ts { return undefined; } - export function contains(array: T[], value: T): boolean { + export function contains(array: T[], value: T, areEqual?: (a: T, b: T) => boolean): boolean { if (array) { for (const v of array) { - if (v === value) { + if (areEqual ? areEqual(v, value) : v === value) { return true; } } @@ -156,12 +156,12 @@ namespace ts { return array1.concat(array2); } - export function deduplicate(array: T[]): T[] { + export function deduplicate(array: T[], areEqual?: (a: T, b: T) => boolean): T[] { let result: T[]; if (array) { result = []; for (const item of array) { - if (!contains(result, item)) { + if (!contains(result, item, areEqual)) { result.push(item); } } diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 38df2e45d48..58ce2286627 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -1377,6 +1377,7 @@ namespace ts { function emitSignatureDeclaration(node: SignatureDeclaration) { const prevEnclosingDeclaration = enclosingDeclaration; enclosingDeclaration = node; + let closeParenthesizedFunctionType = false; if (node.kind === SyntaxKind.IndexSignature) { // Index signature can have readonly modifier @@ -1388,6 +1389,16 @@ namespace ts { if (node.kind === SyntaxKind.ConstructSignature || node.kind === SyntaxKind.ConstructorType) { write("new "); } + else if (node.kind === SyntaxKind.FunctionType) { + const currentOutput = writer.getText(); + // Do not generate incorrect type when function type with type parameters is type argument + // This could happen if user used space between two '<' making it error free + // e.g var x: A< (a: Tany)=>Tany>; + if (node.typeParameters && currentOutput.charAt(currentOutput.length - 1) === "<") { + closeParenthesizedFunctionType = true; + write("("); + } + } emitTypeParameters(node.typeParameters); write("("); } @@ -1421,6 +1432,9 @@ namespace ts { write(";"); writeLine(); } + else if (closeParenthesizedFunctionType) { + write(")"); + } function getReturnTypeVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic { let diagnosticMessage: DiagnosticMessage; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 942eb588b4f..732e5a0987b 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1743,10 +1743,18 @@ "category": "Error", "code": 2530 }, - "Object is possibly 'null' or 'undefined'.": { + "Object is possibly 'null'.": { "category": "Error", "code": 2531 }, + "Object is possibly 'undefined'.": { + "category": "Error", + "code": 2532 + }, + "Object is possibly 'null' or 'undefined'.": { + "category": "Error", + "code": 2533 + }, "JSX element attributes type '{0}' may not be a union type.": { "category": "Error", "code": 2600 @@ -1823,7 +1831,7 @@ "category": "Error", "code": 2660 }, - "Cannot re-export name that is not defined in the module.": { + "Cannot export '{0}'. Only local declarations can be exported from a module.": { "category": "Error", "code": 2661 }, @@ -2296,7 +2304,14 @@ "category": "Error", "code": 5062 }, - + "Substututions for pattern '{0}' should be an array.": { + "category": "Error", + "code": 5063 + }, + "Substitution '{0}' for pattern '{1}' has incorrect type, expected 'string', got '{2}'.": { + "category": "Error", + "code": 5064 + }, "Concatenate and emit output to single file.": { "category": "Message", "code": 6001 diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 254b8d7e61b..c4e3c8668fd 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -4487,7 +4487,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } function emitRestParameter(node: FunctionLikeDeclaration) { - if (languageVersion < ScriptTarget.ES6 && hasRestParameter(node)) { + if (languageVersion < ScriptTarget.ES6 && hasDeclaredRestParameter(node)) { const restIndex = node.parameters.length - 1; const restParam = node.parameters[restIndex]; @@ -4644,7 +4644,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge if (node) { const parameters = node.parameters; const skipCount = node.parameters.length && (node.parameters[0].name).text === "this" ? 1 : 0; - const omitCount = languageVersion < ScriptTarget.ES6 && hasRestParameter(node) ? 1 : 0; + const omitCount = languageVersion < ScriptTarget.ES6 && hasDeclaredRestParameter(node) ? 1 : 0; emitList(parameters, skipCount, parameters.length - omitCount - skipCount, /*multiLine*/ false, /*trailingComma*/ false); } write(")"); @@ -7879,7 +7879,7 @@ const _super = (function (geti, seti) { node.parent && node.parent.kind === SyntaxKind.ArrowFunction && (node.parent).body === node && - compilerOptions.target <= ScriptTarget.ES5) { + languageVersion <= ScriptTarget.ES5) { return false; } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 3a1c3c62f41..b9662126e65 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1825,7 +1825,7 @@ namespace ts { function parseEntityName(allowReservedWords: boolean, diagnosticMessage?: DiagnosticMessage): EntityName { let entity: EntityName = parseIdentifier(diagnosticMessage); while (parseOptional(SyntaxKind.DotToken)) { - const node = createNode(SyntaxKind.QualifiedName, entity.pos); + const node: QualifiedName = createNode(SyntaxKind.QualifiedName, entity.pos); // !!! node.left = entity; node.right = parseRightSideOfDot(allowReservedWords); entity = finishNode(node); @@ -3657,7 +3657,7 @@ namespace ts { let elementName: EntityName = parseIdentifierName(); while (parseOptional(SyntaxKind.DotToken)) { scanJsxIdentifier(); - const node = createNode(SyntaxKind.QualifiedName, elementName.pos); + const node: QualifiedName = createNode(SyntaxKind.QualifiedName, elementName.pos); // !!! node.left = elementName; node.right = parseIdentifierName(); elementName = finishNode(node); @@ -6141,7 +6141,7 @@ namespace ts { atToken.end = scanner.getTextPos(); nextJSDocToken(); - const tagName = parseJSDocIdentifier(); + const tagName = parseJSDocIdentifierName(); if (!tagName) { return; } @@ -6236,7 +6236,7 @@ namespace ts { let isBracketed: boolean; // Looking for something like '[foo]' or 'foo' if (parseOptionalToken(SyntaxKind.OpenBracketToken)) { - name = parseJSDocIdentifier(); + name = parseJSDocIdentifierName(); isBracketed = true; // May have an optional default, e.g. '[foo = 42]' @@ -6246,8 +6246,8 @@ namespace ts { parseExpected(SyntaxKind.CloseBracketToken); } - else if (token === SyntaxKind.Identifier) { - name = parseJSDocIdentifier(); + else if (tokenIsIdentifierOrKeyword(token)) { + name = parseJSDocIdentifierName(); } if (!name) { @@ -6400,7 +6400,7 @@ namespace ts { typeParameters.pos = scanner.getStartPos(); while (true) { - const name = parseJSDocIdentifier(); + const name = parseJSDocIdentifierName(); if (!name) { parseErrorAtPosition(scanner.getStartPos(), 0, Diagnostics.Identifier_expected); return undefined; @@ -6433,8 +6433,12 @@ namespace ts { return token = scanner.scanJSDocToken(); } - function parseJSDocIdentifier(): Identifier { - if (token !== SyntaxKind.Identifier) { + function parseJSDocIdentifierName(): Identifier { + return createJSDocIdentifier(tokenIsIdentifierOrKeyword(token)); + } + + function createJSDocIdentifier(isIdentifier: boolean): Identifier { + if (!isIdentifier) { parseErrorAtCurrentToken(Diagnostics.Identifier_expected); return undefined; } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 8d0e8b296e1..658d6946a39 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1985,11 +1985,22 @@ namespace ts { if (!hasZeroOrOneAsteriskCharacter(key)) { programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, key)); } - for (const subst of options.paths[key]) { - if (!hasZeroOrOneAsteriskCharacter(subst)) { - programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character, subst, key)); + if (isArray(options.paths[key])) { + for (const subst of options.paths[key]) { + const typeOfSubst = typeof subst; + if (typeOfSubst === "string") { + if (!hasZeroOrOneAsteriskCharacter(subst)) { + programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character, subst, key)); + } + } + else { + programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2, subst, key, typeOfSubst)); + } } } + else { + programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Substututions_for_pattern_0_should_be_an_array, key)); + } } } diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index c2199cf7345..2e40cfdc53c 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -44,11 +44,9 @@ namespace ts { const territory = matchResult[3]; // First try the entire locale, then fall back to just language if that's all we have. - if (!trySetLanguageAndTerritory(language, territory, errors) && - !trySetLanguageAndTerritory(language, undefined, errors)) { - - errors.push(createCompilerDiagnostic(Diagnostics.Unsupported_locale_0, locale)); - return false; + // Either ways do not fail, and fallback to the English diagnostic strings. + if (!trySetLanguageAndTerritory(language, territory, errors)) { + trySetLanguageAndTerritory(language, undefined, errors); } return true; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f40237ba47e..88b71e4c5c3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -455,6 +455,7 @@ namespace ts { /* @internal */ locals?: SymbolTable; // Locals associated with node (initialized by binding) /* @internal */ nextContainer?: Node; // Next container in declaration order (initialized by binding) /* @internal */ localSymbol?: Symbol; // Local symbol declared by node (initialized by binding only for exported nodes) + /* @internal */ flowNode?: FlowNode; // Associated FlowNode (initialized by binding) } export interface NodeArray extends Array, TextRange { @@ -483,11 +484,6 @@ namespace ts { originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later } - // Transient identifier node (marked by id === -1) - export interface TransientIdentifier extends Identifier { - resolvedSymbol: Symbol; - } - // @kind(SyntaxKind.QualifiedName) export interface QualifiedName extends Node { // Must have same layout as PropertyAccess @@ -1551,6 +1547,39 @@ namespace ts { isBracketed: boolean; } + export const enum FlowKind { + Unreachable, + Start, + Label, + Assignment, + Condition + } + + export interface FlowNode { + kind: FlowKind; // Node kind + id?: number; // Node id used by flow type cache in checker + } + + // FlowLabel represents a junction with multiple possible preceding control flows. + export interface FlowLabel extends FlowNode { + antecedents: FlowNode[]; + } + + // FlowAssignment represents a node that assigns a value to a narrowable reference, + // i.e. an identifier or a dotted name that starts with an identifier or 'this'. + export interface FlowAssignment extends FlowNode { + node: Expression | VariableDeclaration | BindingElement; + antecedent: FlowNode; + } + + // FlowCondition represents a condition that is known to be true or false at the + // node's location in the control flow. + export interface FlowCondition extends FlowNode { + expression: Expression; + assumeTrue: boolean; + antecedent: FlowNode; + } + export interface AmdDependency { path: string; name: string; @@ -1852,6 +1881,7 @@ namespace ts { WriteTypeArgumentsOfSignature = 0x00000020, // Write the type arguments instead of type parameters of the signature InElementType = 0x00000040, // Writing an array or union element type UseFullyQualifiedType = 0x00000080, // Write out the fully qualified type name (eg. Module.Type, instead of Type) + InFirstTypeArgument = 0x00000100, // Writing first type argument of the instantiated type } export const enum SymbolFormatFlags { @@ -2085,8 +2115,6 @@ namespace ts { isDeclarationWithCollidingName?: boolean; // True if symbol is block scoped redeclaration bindingElement?: BindingElement; // Binding element associated with property symbol exportsSomeValue?: boolean; // True if module exports some value (not just types) - firstAssignmentChecked?: boolean; // True if first assignment node has been computed - firstAssignment?: Node; // First assignment node (undefined if no assignments) } /* @internal */ @@ -2120,18 +2148,13 @@ namespace ts { /* @internal */ export interface NodeLinks { resolvedType?: Type; // Cached type of type node - resolvedAwaitedType?: Type; // Cached awaited type of type node resolvedSignature?: Signature; // Cached signature of signature node or call expression resolvedSymbol?: Symbol; // Cached name resolution result resolvedIndexInfo?: IndexInfo; // Cached indexing info resolution result flags?: NodeCheckFlags; // Set of flags specific to Node enumMemberValue?: number; // Constant value of enum member isVisible?: boolean; // Is this node visible - generatedName?: string; // Generated name for module, enum, or import declaration - generatedNames?: Map; // Generated names table for source file - assignmentMap?: Map; // Cached map of references assigned within this node hasReportedStatementInAmbientContext?: boolean; // Cache boolean if we report statements in ambient context - importOnRightSide?: Symbol; // for import declarations - import that appear on the right side jsxFlags?: JsxFlags; // flags for knowing what kind of element/attributes we're dealing with resolvedJsxType?: Type; // resolved element attributes type of a JSX openinglike element hasSuperCall?: boolean; // recorded result when we try to find super-call. We only try to find one if this flag is undefined, indicating that we haven't made an attempt. @@ -2183,6 +2206,7 @@ namespace ts { ObjectType = Class | Interface | Reference | Tuple | Anonymous, UnionOrIntersection = Union | Intersection, StructuredType = ObjectType | Union | Intersection, + Narrowable = Any | ObjectType | Union | TypeParameter, /* @internal */ RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral, /* @internal */ diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 2f29e477d69..388271f9275 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -455,7 +455,7 @@ namespace ts { const { line: startLine } = getLineAndCharacterOfPosition(sourceFile, node.body.pos); const { line: endLine } = getLineAndCharacterOfPosition(sourceFile, node.body.end); if (startLine < endLine) { - // The arrow function spans multiple lines, + // The arrow function spans multiple lines, // make the error span be the first line, inclusive. return createTextSpan(pos, getEndLinePosition(startLine, sourceFile) - pos + 1); } @@ -860,6 +860,15 @@ 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; @@ -1216,6 +1225,10 @@ namespace ts { return isRequire && (!checkArgumentIsStringLiteral || (expression).arguments[0].kind === SyntaxKind.StringLiteral); } + export function isSingleOrDoubleQuote(charCode: number) { + return charCode === CharacterCodes.singleQuote || charCode === CharacterCodes.doubleQuote; + } + /// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property /// assignments we treat as special in the binder export function getSpecialPropertyAssignmentKind(expression: Node): SpecialPropertyAssignmentKind { @@ -1397,23 +1410,26 @@ namespace ts { return isRestParameter(lastOrUndefined(s.parameters)); } - export function isRestParameter(node: ParameterDeclaration) { - if (node) { - if (node.flags & NodeFlags.JavaScriptFile) { - if (node.type && node.type.kind === SyntaxKind.JSDocVariadicType) { - return true; - } + export function hasDeclaredRestParameter(s: SignatureDeclaration): boolean { + return isDeclaredRestParam(lastOrUndefined(s.parameters)); + } - const paramTag = getCorrespondingJSDocParameterTag(node); - if (paramTag && paramTag.typeExpression) { - return paramTag.typeExpression.type.kind === SyntaxKind.JSDocVariadicType; - } + export function isRestParameter(node: ParameterDeclaration) { + if (node && (node.flags & NodeFlags.JavaScriptFile)) { + if (node.type && node.type.kind === SyntaxKind.JSDocVariadicType) { + return true; } - return node.dotDotDotToken !== undefined; + const paramTag = getCorrespondingJSDocParameterTag(node); + if (paramTag && paramTag.typeExpression) { + return paramTag.typeExpression.type.kind === SyntaxKind.JSDocVariadicType; + } } + return isDeclaredRestParam(node); + } - return false; + export function isDeclaredRestParam(node: ParameterDeclaration) { + return node && node.dotDotDotToken !== undefined; } export function isLiteralKind(kind: SyntaxKind): boolean { @@ -1432,6 +1448,31 @@ namespace ts { return !!node && (node.kind === SyntaxKind.ArrayBindingPattern || node.kind === SyntaxKind.ObjectBindingPattern); } + // 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'. + export function isAssignmentTarget(node: Node): boolean { + while (node.parent.kind === SyntaxKind.ParenthesizedExpression) { + node = node.parent; + } + while (true) { + const parent = node.parent; + if (parent.kind === SyntaxKind.ArrayLiteralExpression || parent.kind === SyntaxKind.SpreadElementExpression) { + node = parent; + continue; + } + if (parent.kind === SyntaxKind.PropertyAssignment || parent.kind === SyntaxKind.ShorthandPropertyAssignment) { + node = parent.parent; + continue; + } + return parent.kind === SyntaxKind.BinaryExpression && + (parent).operatorToken.kind === SyntaxKind.EqualsToken && + (parent).left === node || + (parent.kind === SyntaxKind.ForInStatement || parent.kind === SyntaxKind.ForOfStatement) && + (parent).initializer === node; + } + } + export function isNodeDescendentOf(node: Node, ancestor: Node): boolean { while (node) { if (node === ancestor) return true; @@ -1529,7 +1570,7 @@ namespace ts { } // True if the given identifier, string literal, or number literal is the name of a declaration node - export function isDeclarationName(name: Node): name is Identifier | StringLiteral | LiteralExpression { + export function isDeclarationName(name: Node): boolean { if (name.kind !== SyntaxKind.Identifier && name.kind !== SyntaxKind.StringLiteral && name.kind !== SyntaxKind.NumericLiteral) { return false; } diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 48b79017f8d..c6cf82a6834 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -362,14 +362,14 @@ namespace FourSlash { } // Opens a file given its 0-based index or fileName - public openFile(index: number, content?: string): void; - public openFile(name: string, content?: string): void; - public openFile(indexOrName: any, content?: string) { + public openFile(index: number, content?: string, scriptKindName?: string): void; + public openFile(name: string, content?: string, scriptKindName?: string): void; + public openFile(indexOrName: any, content?: string, scriptKindName?: string) { const fileToOpen: FourSlashFile = this.findFile(indexOrName); fileToOpen.fileName = ts.normalizeSlashes(fileToOpen.fileName); this.activeFile = fileToOpen; // Let the host know that this file is now open - this.languageServiceAdapterHost.openFile(fileToOpen.fileName, content); + this.languageServiceAdapterHost.openFile(fileToOpen.fileName, content, scriptKindName); } public verifyErrorExistsBetweenMarkers(startMarkerName: string, endMarkerName: string, negative: boolean) { @@ -655,7 +655,7 @@ namespace FourSlash { this.assertItemInCompletionList(completions.entries, symbol, text, documentation, kind); } else { - this.raiseError(`No completions at position '${ this.currentCaretPosition }' when looking for '${ symbol }'.`); + this.raiseError(`No completions at position '${this.currentCaretPosition}' when looking for '${symbol}'.`); } } @@ -1758,13 +1758,13 @@ namespace FourSlash { const actual = (this.languageService).getProjectInfo( this.activeFile.fileName, /* needFileNameList */ true - ); + ); assert.equal( expected.join(","), - actual.fileNames.map( file => { + actual.fileNames.map(file => { return file.replace(this.basePath + "/", ""); - }).join(",") - ); + }).join(",") + ); } } @@ -1850,6 +1850,37 @@ namespace FourSlash { }); } + public verifyBraceCompletionAtPostion(negative: boolean, openingBrace: string) { + + const openBraceMap: ts.Map = { + "(": ts.CharacterCodes.openParen, + "{": ts.CharacterCodes.openBrace, + "[": ts.CharacterCodes.openBracket, + "'": ts.CharacterCodes.singleQuote, + '"': ts.CharacterCodes.doubleQuote, + "`": ts.CharacterCodes.backtick, + "<": ts.CharacterCodes.lessThan + }; + + const charCode = openBraceMap[openingBrace]; + + if (!charCode) { + this.raiseError(`Invalid openingBrace '${openingBrace}' specified.`); + } + + const position = this.currentCaretPosition; + + const validBraceCompletion = this.languageService.isValidBraceCompletionAtPostion(this.activeFile.fileName, position, charCode); + + if (!negative && !validBraceCompletion) { + this.raiseError(`${position} is not a valid brace completion position for ${openingBrace}`); + } + + if (negative && validBraceCompletion) { + this.raiseError(`${position} is a valid brace completion position for ${openingBrace}`); + } + } + public verifyMatchingBracePosition(bracePosition: number, expectedMatchPosition: number) { const actual = this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, bracePosition); @@ -2239,7 +2270,7 @@ namespace FourSlash { }; const host = Harness.Compiler.createCompilerHost( - [ fourslashFile, testFile ], + [fourslashFile, testFile], (fn, contents) => result = contents, ts.ScriptTarget.Latest, Harness.IO.useCaseSensitiveFileNames(), @@ -2264,7 +2295,7 @@ namespace FourSlash { function runCode(code: string, state: TestState): void { // Compile and execute the test const wrappedCode = -`(function(test, goTo, verify, edit, debug, format, cancellation, classification, verifyOperationIsCancelled) { + `(function(test, goTo, verify, edit, debug, format, cancellation, classification, verifyOperationIsCancelled) { ${code} })`; try { @@ -2378,7 +2409,7 @@ ${code} } } } - // TODO: should be '==='? + // TODO: should be '==='? } else if (line == "" || lineLength === 0) { // Previously blank lines between fourslash content caused it to be considered as 2 files, @@ -2759,10 +2790,10 @@ namespace FourSlashInterface { // Opens a file, given either its index as it // appears in the test source, or its filename // as specified in the test metadata - public file(index: number, content?: string): void; - public file(name: string, content?: string): void; - public file(indexOrName: any, content?: string): void { - this.state.openFile(indexOrName, content); + public file(index: number, content?: string, scriptKindName?: string): void; + public file(name: string, content?: string, scriptKindName?: string): void; + public file(indexOrName: any, content?: string, scriptKindName?: string): void { + this.state.openFile(indexOrName, content, scriptKindName); } } @@ -2870,6 +2901,10 @@ namespace FourSlashInterface { public verifyDefinitionsName(name: string, containerName: string) { this.state.verifyDefinitionsName(this.negative, name, containerName); } + + public isValidBraceCompletionAtPostion(openingBrace: string) { + this.state.verifyBraceCompletionAtPostion(this.negative, openingBrace); + } } export class Verify extends VerifyNegatable { @@ -3088,7 +3123,7 @@ namespace FourSlashInterface { this.state.getSemanticDiagnostics(expected); } - public ProjectInfo(expected: string []) { + public ProjectInfo(expected: string[]) { this.state.verifyProjectInfo(expected); } } diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index b27d746390b..8aaff65febc 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -163,7 +163,7 @@ namespace Harness.LanguageService { throw new Error("No script with name '" + fileName + "'"); } - public openFile(fileName: string, content?: string): void { + public openFile(fileName: string, content?: string, scriptKindName?: string): void { } /** @@ -437,6 +437,9 @@ namespace Harness.LanguageService { getDocCommentTemplateAtPosition(fileName: string, position: number): ts.TextInsertion { return unwrapJSONCallResult(this.shim.getDocCommentTemplateAtPosition(fileName, position)); } + isValidBraceCompletionAtPostion(fileName: string, position: number, openingBrace: number): boolean { + return unwrapJSONCallResult(this.shim.isValidBraceCompletionAtPostion(fileName, position, openingBrace)); + } getEmitOutput(fileName: string): ts.EmitOutput { return unwrapJSONCallResult(this.shim.getEmitOutput(fileName)); } @@ -525,9 +528,9 @@ namespace Harness.LanguageService { this.client = client; } - openFile(fileName: string, content?: string): void { - super.openFile(fileName, content); - this.client.openFile(fileName, content); + openFile(fileName: string, content?: string, scriptKindName?: "TS" | "JS" | "TSX" | "JSX"): void { + super.openFile(fileName, content, scriptKindName); + this.client.openFile(fileName, content, scriptKindName); } editScript(fileName: string, start: number, end: number, newText: string) { diff --git a/src/harness/loggedIO.ts b/src/harness/loggedIO.ts index 0002a6af288..d468b371fbe 100644 --- a/src/harness/loggedIO.ts +++ b/src/harness/loggedIO.ts @@ -149,7 +149,7 @@ namespace Playback { recordLog = createEmptyLog(); if (typeof underlying.args !== "function") { - recordLog.arguments = underlying.args; + recordLog.arguments = underlying.args; } }; diff --git a/src/harness/rwcRunner.ts b/src/harness/rwcRunner.ts index 8c3b3c70a1f..39231435bf5 100644 --- a/src/harness/rwcRunner.ts +++ b/src/harness/rwcRunner.ts @@ -190,8 +190,9 @@ namespace RWC { if (compilerResult.errors.length === 0) { return null; } - - return Harness.Compiler.getErrorBaseline(inputFiles.concat(otherFiles), compilerResult.errors); + // Do not include the library in the baselines to avoid noise + const baselineFiles = inputFiles.concat(otherFiles).filter(f => !Harness.isDefaultLibraryFile(f.unitName)); + return Harness.Compiler.getErrorBaseline(baselineFiles, compilerResult.errors); }, false, baselineOpts); }); diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 1bcf528640b..17916d5548e 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1064,7 +1064,7 @@ interface ReadonlyArray { * @param callbackfn A function that accepts up to three arguments. The filter method calls the callbackfn function one time for each element in the array. * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value. */ - filter(callbackfn: (value: T, index: number, array: ReadonlyArray) => boolean, thisArg?: any): T[]; + filter(callbackfn: (value: T, index: number, array: ReadonlyArray) => any, thisArg?: any): T[]; /** * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array. @@ -1199,7 +1199,7 @@ interface Array { * @param callbackfn A function that accepts up to three arguments. The filter method calls the callbackfn function one time for each element in the array. * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value. */ - filter(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): T[]; + filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; /** * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array. @@ -1511,7 +1511,7 @@ interface Int8Array { * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ - filter(callbackfn: (value: number, index: number, array: Int8Array) => boolean, thisArg?: any): Int8Array; + filter(callbackfn: (value: number, index: number, array: Int8Array) => any, thisArg?: any): Int8Array; /** * Returns the value of the first element in the array where predicate is true, and undefined @@ -1784,7 +1784,7 @@ interface Uint8Array { * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ - filter(callbackfn: (value: number, index: number, array: Uint8Array) => boolean, thisArg?: any): Uint8Array; + filter(callbackfn: (value: number, index: number, array: Uint8Array) => any, thisArg?: any): Uint8Array; /** * Returns the value of the first element in the array where predicate is true, and undefined @@ -2058,7 +2058,7 @@ interface Uint8ClampedArray { * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ - filter(callbackfn: (value: number, index: number, array: Uint8ClampedArray) => boolean, thisArg?: any): Uint8ClampedArray; + filter(callbackfn: (value: number, index: number, array: Uint8ClampedArray) => any, thisArg?: any): Uint8ClampedArray; /** * Returns the value of the first element in the array where predicate is true, and undefined @@ -2331,7 +2331,7 @@ interface Int16Array { * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ - filter(callbackfn: (value: number, index: number, array: Int16Array) => boolean, thisArg?: any): Int16Array; + filter(callbackfn: (value: number, index: number, array: Int16Array) => any, thisArg?: any): Int16Array; /** * Returns the value of the first element in the array where predicate is true, and undefined @@ -2605,7 +2605,7 @@ interface Uint16Array { * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ - filter(callbackfn: (value: number, index: number, array: Uint16Array) => boolean, thisArg?: any): Uint16Array; + filter(callbackfn: (value: number, index: number, array: Uint16Array) => any, thisArg?: any): Uint16Array; /** * Returns the value of the first element in the array where predicate is true, and undefined @@ -2878,7 +2878,7 @@ interface Int32Array { * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ - filter(callbackfn: (value: number, index: number, array: Int32Array) => boolean, thisArg?: any): Int32Array; + filter(callbackfn: (value: number, index: number, array: Int32Array) => any, thisArg?: any): Int32Array; /** * Returns the value of the first element in the array where predicate is true, and undefined @@ -3151,7 +3151,7 @@ interface Uint32Array { * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ - filter(callbackfn: (value: number, index: number, array: Uint32Array) => boolean, thisArg?: any): Uint32Array; + filter(callbackfn: (value: number, index: number, array: Uint32Array) => any, thisArg?: any): Uint32Array; /** * Returns the value of the first element in the array where predicate is true, and undefined @@ -3424,7 +3424,7 @@ interface Float32Array { * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ - filter(callbackfn: (value: number, index: number, array: Float32Array) => boolean, thisArg?: any): Float32Array; + filter(callbackfn: (value: number, index: number, array: Float32Array) => any, thisArg?: any): Float32Array; /** * Returns the value of the first element in the array where predicate is true, and undefined @@ -3698,7 +3698,7 @@ interface Float64Array { * @param thisArg An object to which the this keyword can refer in the callbackfn function. * If thisArg is omitted, undefined is used as the this value. */ - filter(callbackfn: (value: number, index: number, array: Float64Array) => boolean, thisArg?: any): Float64Array; + filter(callbackfn: (value: number, index: number, array: Float64Array) => any, thisArg?: any): Float64Array; /** * Returns the value of the first element in the array where predicate is true, and undefined diff --git a/src/server/client.ts b/src/server/client.ts index 957d36e4a3a..caeab6e3f3c 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -120,8 +120,8 @@ namespace ts.server { return response; } - openFile(fileName: string, content?: string): void { - var args: protocol.OpenRequestArgs = { file: fileName, fileContent: content }; + openFile(fileName: string, content?: string, scriptKindName?: "TS" | "JS" | "TSX" | "JSX"): void { + var args: protocol.OpenRequestArgs = { file: fileName, fileContent: content, scriptKindName }; this.processRequest(CommandNames.Open, args); } @@ -568,6 +568,10 @@ namespace ts.server { throw new Error("Not Implemented Yet."); } + isValidBraceCompletionAtPostion(fileName: string, position: number, openingBrace: number): boolean { + throw new Error("Not Implemented Yet."); + } + getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[] { var lineOffset = this.positionToOneBasedLineOffset(fileName, position); var args: protocol.FileLocationRequestArgs = { diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 4c054664a18..c4d4a23ebfa 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -34,6 +34,7 @@ namespace ts.server { fileWatcher: FileWatcher; formatCodeOptions = ts.clone(CompilerService.defaultFormatCodeOptions); path: Path; + scriptKind: ScriptKind; constructor(private host: ServerHost, public fileName: string, public content: string, public isOpen = false) { this.path = toPath(fileName, host.getCurrentDirectory(), createGetCanonicalFileName(host.useCaseSensitiveFileNames)); @@ -215,8 +216,16 @@ namespace ts.server { return this.roots.map(root => root.fileName); } - getScriptKind() { - return ScriptKind.Unknown; + getScriptKind(fileName: string) { + const info = this.getScriptInfo(fileName); + if (!info) { + return undefined; + } + + if (!info.scriptKind) { + info.scriptKind = getScriptKindFromFileName(fileName); + } + return info.scriptKind; } getScriptVersion(filename: string) { @@ -489,6 +498,14 @@ namespace ts.server { return copiedList; } + /** + * This helper funciton processes a list of projects and return the concatenated, sortd and deduplicated output of processing each project. + */ + export function combineProjectOutput(projects: Project[], action: (project: Project) => T[], comparer?: (a: T, b: T) => number, areEqual?: (a: T, b: T) => boolean) { + const result = projects.reduce((previous, current) => concatenate(previous, action(current)), []).sort(comparer); + return projects.length > 1 ? deduplicate(result, areEqual) : result; + } + export interface ProjectServiceEventHandler { (eventName: string, project: Project, fileName: string): void; } @@ -1013,7 +1030,7 @@ namespace ts.server { * @param filename is absolute pathname * @param fileContent is a known version of the file content that is more up to date than the one on disk */ - openFile(fileName: string, openedByClient: boolean, fileContent?: string) { + openFile(fileName: string, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind) { fileName = ts.normalizePath(fileName); let info = ts.lookUp(this.filenameToScriptInfo, fileName); if (!info) { @@ -1028,6 +1045,7 @@ namespace ts.server { } if (content !== undefined) { info = new ScriptInfo(this.host, fileName, content, openedByClient); + info.scriptKind = scriptKind; info.setFormatOptions(this.getFormatCodeOptions()); this.filenameToScriptInfo[fileName] = info; if (!info.isOpen) { @@ -1077,9 +1095,9 @@ namespace ts.server { * @param filename is absolute pathname * @param fileContent is a known version of the file content that is more up to date than the one on disk */ - openClientFile(fileName: string, fileContent?: string) { + openClientFile(fileName: string, fileContent?: string, scriptKind?: ScriptKind) { this.openOrUpdateConfiguredProjectForFile(fileName); - const info = this.openFile(fileName, /*openedByClient*/ true, fileContent); + const info = this.openFile(fileName, /*openedByClient*/ true, fileContent, scriptKind); this.addOpenFile(info); this.printProjects(); return info; diff --git a/src/server/protocol.d.ts b/src/server/protocol.d.ts index 5ed227ebaa7..10cebb2ddb7 100644 --- a/src/server/protocol.d.ts +++ b/src/server/protocol.d.ts @@ -518,6 +518,11 @@ declare namespace ts.server.protocol { * Then the known content will be used upon opening instead of the disk copy */ fileContent?: string; + /** + * Used to specify the script kind of the file explicitly. It could be one of the following: + * "TS", "JS", "TSX", "JSX" + */ + scriptKindName?: "TS" | "JS" | "TSX" | "JSX"; } /** diff --git a/src/server/session.ts b/src/server/session.ts index f0975a3f947..df8273116c1 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -141,8 +141,8 @@ namespace ts.server { ) { this.projectService = new ProjectService(host, logger, (eventName, project, fileName) => { - this.handleEvent(eventName, project, fileName); - }); + this.handleEvent(eventName, project, fileName); + }); } private handleEvent(eventName: string, project: Project, fileName: string) { @@ -412,14 +412,17 @@ namespace ts.server { private getRenameLocations(line: number, offset: number, fileName: string, findInComments: boolean, findInStrings: boolean): protocol.RenameResponseBody { const file = ts.normalizePath(fileName); - const project = this.projectService.getProjectForFile(file); - if (!project) { + const info = this.projectService.getScriptInfo(file); + const projects = this.projectService.findReferencingProjects(info); + if (!projects.length) { throw Errors.NoProject; } - const compilerService = project.compilerService; - const position = compilerService.host.lineOffsetToPosition(file, line, offset); - const renameInfo = compilerService.languageService.getRenameInfo(file, position); + const defaultProject = projects[0]; + // The rename info should be the same for every project + const defaultProjectCompilerService = defaultProject.compilerService; + const position = defaultProjectCompilerService.host.lineOffsetToPosition(file, line, offset); + const renameInfo = defaultProjectCompilerService.languageService.getRenameInfo(file, position); if (!renameInfo) { return undefined; } @@ -431,16 +434,43 @@ namespace ts.server { }; } - const renameLocations = compilerService.languageService.findRenameLocations(file, position, findInStrings, findInComments); - if (!renameLocations) { - return undefined; - } + const fileSpans = combineProjectOutput( + projects, + (project: Project) => { + const compilerService = project.compilerService; + const renameLocations = compilerService.languageService.findRenameLocations(file, position, findInStrings, findInComments); + if (!renameLocations) { + return []; + } - const bakedRenameLocs = renameLocations.map(location => ({ - file: location.fileName, - start: compilerService.host.positionToLineOffset(location.fileName, location.textSpan.start), - end: compilerService.host.positionToLineOffset(location.fileName, ts.textSpanEnd(location.textSpan)), - })).sort((a, b) => { + return renameLocations.map(location => ({ + file: location.fileName, + start: compilerService.host.positionToLineOffset(location.fileName, location.textSpan.start), + end: compilerService.host.positionToLineOffset(location.fileName, ts.textSpanEnd(location.textSpan)), + })); + }, + compareRenameLocation, + (a, b) => a.file === b.file && a.start.line === b.start.line && a.start.offset === b.start.offset + ); + const locs = fileSpans.reduce((accum, cur) => { + let curFileAccum: protocol.SpanGroup; + if (accum.length > 0) { + curFileAccum = accum[accum.length - 1]; + if (curFileAccum.file !== cur.file) { + curFileAccum = undefined; + } + } + if (!curFileAccum) { + curFileAccum = { file: cur.file, locs: [] }; + accum.push(curFileAccum); + } + curFileAccum.locs.push({ start: cur.start, end: cur.end }); + return accum; + }, []); + + return { info: renameInfo, locs }; + + function compareRenameLocation(a: protocol.FileSpan, b: protocol.FileSpan) { if (a.file < b.file) { return -1; } @@ -459,79 +489,79 @@ namespace ts.server { return b.start.offset - a.start.offset; } } - }).reduce((accum: protocol.SpanGroup[], cur: protocol.FileSpan) => { - let curFileAccum: protocol.SpanGroup; - if (accum.length > 0) { - curFileAccum = accum[accum.length - 1]; - if (curFileAccum.file != cur.file) { - curFileAccum = undefined; - } - } - if (!curFileAccum) { - curFileAccum = { file: cur.file, locs: [] }; - accum.push(curFileAccum); - } - curFileAccum.locs.push({ start: cur.start, end: cur.end }); - return accum; - }, []); - - return { info: renameInfo, locs: bakedRenameLocs }; + } } private getReferences(line: number, offset: number, fileName: string): protocol.ReferencesResponseBody { - // TODO: get all projects for this file; report refs for all projects deleting duplicates - // can avoid duplicates by eliminating same ref file from subsequent projects const file = ts.normalizePath(fileName); - const project = this.projectService.getProjectForFile(file); - if (!project) { + const info = this.projectService.getScriptInfo(file); + const projects = this.projectService.findReferencingProjects(info); + if (!projects.length) { throw Errors.NoProject; } - const compilerService = project.compilerService; - const position = compilerService.host.lineOffsetToPosition(file, line, offset); - - const references = compilerService.languageService.getReferencesAtPosition(file, position); - if (!references) { - return undefined; - } - - const nameInfo = compilerService.languageService.getQuickInfoAtPosition(file, position); + const defaultProject = projects[0]; + const position = defaultProject.compilerService.host.lineOffsetToPosition(file, line, offset); + const nameInfo = defaultProject.compilerService.languageService.getQuickInfoAtPosition(file, position); if (!nameInfo) { return undefined; } const displayString = ts.displayPartsToString(nameInfo.displayParts); const nameSpan = nameInfo.textSpan; - const nameColStart = compilerService.host.positionToLineOffset(file, nameSpan.start).offset; - const nameText = compilerService.host.getScriptSnapshot(file).getText(nameSpan.start, ts.textSpanEnd(nameSpan)); - const bakedRefs: protocol.ReferencesResponseItem[] = references.map(ref => { - const start = compilerService.host.positionToLineOffset(ref.fileName, ref.textSpan.start); - const refLineSpan = compilerService.host.lineToTextSpan(ref.fileName, start.line - 1); - const snap = compilerService.host.getScriptSnapshot(ref.fileName); - const lineText = snap.getText(refLineSpan.start, ts.textSpanEnd(refLineSpan)).replace(/\r|\n/g, ""); - return { - file: ref.fileName, - start: start, - lineText: lineText, - end: compilerService.host.positionToLineOffset(ref.fileName, ts.textSpanEnd(ref.textSpan)), - isWriteAccess: ref.isWriteAccess - }; - }).sort(compareFileStart); + const nameColStart = defaultProject.compilerService.host.positionToLineOffset(file, nameSpan.start).offset; + const nameText = defaultProject.compilerService.host.getScriptSnapshot(file).getText(nameSpan.start, ts.textSpanEnd(nameSpan)); + const refs = combineProjectOutput( + projects, + (project: Project) => { + const compilerService = project.compilerService; + const references = compilerService.languageService.getReferencesAtPosition(file, position); + if (!references) { + return []; + } + + return references.map(ref => { + const start = compilerService.host.positionToLineOffset(ref.fileName, ref.textSpan.start); + const refLineSpan = compilerService.host.lineToTextSpan(ref.fileName, start.line - 1); + const snap = compilerService.host.getScriptSnapshot(ref.fileName); + const lineText = snap.getText(refLineSpan.start, ts.textSpanEnd(refLineSpan)).replace(/\r|\n/g, ""); + return { + file: ref.fileName, + start: start, + lineText: lineText, + end: compilerService.host.positionToLineOffset(ref.fileName, ts.textSpanEnd(ref.textSpan)), + isWriteAccess: ref.isWriteAccess + }; + }); + }, + compareFileStart, + areReferencesResponseItemsForTheSameLocation + ); + return { - refs: bakedRefs, + refs, symbolName: nameText, symbolStartOffset: nameColStart, symbolDisplayString: displayString }; + + function areReferencesResponseItemsForTheSameLocation(a: protocol.ReferencesResponseItem, b: protocol.ReferencesResponseItem) { + if (a && b) { + return a.file === b.file && + a.start === b.start && + a.end === b.end; + } + return false; + } } /** * @param fileName is the name of the file to be opened * @param fileContent is a version of the file content that is known to be more up to date than the one on disk */ - private openClientFile(fileName: string, fileContent?: string) { + private openClientFile(fileName: string, fileContent?: string, scriptKind?: ScriptKind) { const file = ts.normalizePath(fileName); - this.projectService.openClientFile(file, fileContent); + this.projectService.openClientFile(file, fileContent, scriptKind); } private getQuickInfo(line: number, offset: number, fileName: string): protocol.QuickInfoResponseBody { @@ -836,41 +866,60 @@ namespace ts.server { private getNavigateToItems(searchValue: string, fileName: string, maxResultCount?: number): protocol.NavtoItem[] { const file = ts.normalizePath(fileName); - const project = this.projectService.getProjectForFile(file); - if (!project) { + const info = this.projectService.getScriptInfo(file); + const projects = this.projectService.findReferencingProjects(info); + const defaultProject = projects[0]; + if (!defaultProject) { throw Errors.NoProject; } - const compilerService = project.compilerService; - const navItems = compilerService.languageService.getNavigateToItems(searchValue, maxResultCount); - if (!navItems) { - return undefined; - } + const allNavToItems = combineProjectOutput( + projects, + (project: Project) => { + const compilerService = project.compilerService; + const navItems = compilerService.languageService.getNavigateToItems(searchValue, maxResultCount); + if (!navItems) { + return []; + } - return navItems.map((navItem) => { - const start = compilerService.host.positionToLineOffset(navItem.fileName, navItem.textSpan.start); - const end = compilerService.host.positionToLineOffset(navItem.fileName, ts.textSpanEnd(navItem.textSpan)); - const bakedItem: protocol.NavtoItem = { - name: navItem.name, - kind: navItem.kind, - file: navItem.fileName, - start: start, - end: end, - }; - if (navItem.kindModifiers && (navItem.kindModifiers != "")) { - bakedItem.kindModifiers = navItem.kindModifiers; + return navItems.map((navItem) => { + const start = compilerService.host.positionToLineOffset(navItem.fileName, navItem.textSpan.start); + const end = compilerService.host.positionToLineOffset(navItem.fileName, ts.textSpanEnd(navItem.textSpan)); + const bakedItem: protocol.NavtoItem = { + name: navItem.name, + kind: navItem.kind, + file: navItem.fileName, + start: start, + end: end, + }; + if (navItem.kindModifiers && (navItem.kindModifiers !== "")) { + bakedItem.kindModifiers = navItem.kindModifiers; + } + if (navItem.matchKind !== "none") { + bakedItem.matchKind = navItem.matchKind; + } + if (navItem.containerName && (navItem.containerName.length > 0)) { + bakedItem.containerName = navItem.containerName; + } + if (navItem.containerKind && (navItem.containerKind.length > 0)) { + bakedItem.containerKind = navItem.containerKind; + } + return bakedItem; + }); + }, + /*comparer*/ undefined, + areNavToItemsForTheSameLocation + ); + return allNavToItems; + + function areNavToItemsForTheSameLocation(a: protocol.NavtoItem, b: protocol.NavtoItem) { + if (a && b) { + return a.file === b.file && + a.start === b.start && + a.end === b.end; } - if (navItem.matchKind !== "none") { - bakedItem.matchKind = navItem.matchKind; - } - if (navItem.containerName && (navItem.containerName.length > 0)) { - bakedItem.containerName = navItem.containerName; - } - if (navItem.containerKind && (navItem.containerKind.length > 0)) { - bakedItem.containerKind = navItem.containerKind; - } - return bakedItem; - }); + return false; + } } private getBraceMatching(line: number, offset: number, fileName: string): protocol.TextSpan[] { @@ -944,129 +993,146 @@ namespace ts.server { exit() { } - private handlers: Map<(request: protocol.Request) => {response?: any, responseRequired?: boolean}> = { + private handlers: Map<(request: protocol.Request) => { response?: any, responseRequired?: boolean }> = { [CommandNames.Exit]: () => { this.exit(); - return { responseRequired: false}; + return { responseRequired: false }; }, [CommandNames.Definition]: (request: protocol.Request) => { const defArgs = request.arguments; - return {response: this.getDefinition(defArgs.line, defArgs.offset, defArgs.file), responseRequired: true}; + return { response: this.getDefinition(defArgs.line, defArgs.offset, defArgs.file), responseRequired: true }; }, [CommandNames.TypeDefinition]: (request: protocol.Request) => { const defArgs = request.arguments; - return {response: this.getTypeDefinition(defArgs.line, defArgs.offset, defArgs.file), responseRequired: true}; + return { response: this.getTypeDefinition(defArgs.line, defArgs.offset, defArgs.file), responseRequired: true }; }, [CommandNames.References]: (request: protocol.Request) => { const defArgs = request.arguments; - return {response: this.getReferences(defArgs.line, defArgs.offset, defArgs.file), responseRequired: true}; + return { response: this.getReferences(defArgs.line, defArgs.offset, defArgs.file), responseRequired: true }; }, [CommandNames.Rename]: (request: protocol.Request) => { const renameArgs = request.arguments; - return {response: this.getRenameLocations(renameArgs.line, renameArgs.offset, renameArgs.file, renameArgs.findInComments, renameArgs.findInStrings), responseRequired: true}; + return { response: this.getRenameLocations(renameArgs.line, renameArgs.offset, renameArgs.file, renameArgs.findInComments, renameArgs.findInStrings), responseRequired: true }; }, [CommandNames.Open]: (request: protocol.Request) => { const openArgs = request.arguments; - this.openClientFile(openArgs.file, openArgs.fileContent); - return {responseRequired: false}; + let scriptKind: ScriptKind; + switch (openArgs.scriptKindName) { + case "TS": + scriptKind = ScriptKind.TS; + break; + case "JS": + scriptKind = ScriptKind.JS; + break; + case "TSX": + scriptKind = ScriptKind.TSX; + break; + case "JSX": + scriptKind = ScriptKind.JSX; + break; + } + this.openClientFile(openArgs.file, openArgs.fileContent, scriptKind); + return { responseRequired: false }; }, [CommandNames.Quickinfo]: (request: protocol.Request) => { const quickinfoArgs = request.arguments; - return {response: this.getQuickInfo(quickinfoArgs.line, quickinfoArgs.offset, quickinfoArgs.file), responseRequired: true}; + return { response: this.getQuickInfo(quickinfoArgs.line, quickinfoArgs.offset, quickinfoArgs.file), responseRequired: true }; }, [CommandNames.Format]: (request: protocol.Request) => { const formatArgs = request.arguments; - return {response: this.getFormattingEditsForRange(formatArgs.line, formatArgs.offset, formatArgs.endLine, formatArgs.endOffset, formatArgs.file), responseRequired: true}; + return { response: this.getFormattingEditsForRange(formatArgs.line, formatArgs.offset, formatArgs.endLine, formatArgs.endOffset, formatArgs.file), responseRequired: true }; }, [CommandNames.Formatonkey]: (request: protocol.Request) => { const formatOnKeyArgs = request.arguments; - return {response: this.getFormattingEditsAfterKeystroke(formatOnKeyArgs.line, formatOnKeyArgs.offset, formatOnKeyArgs.key, formatOnKeyArgs.file), responseRequired: true}; + return { response: this.getFormattingEditsAfterKeystroke(formatOnKeyArgs.line, formatOnKeyArgs.offset, formatOnKeyArgs.key, formatOnKeyArgs.file), responseRequired: true }; }, [CommandNames.Completions]: (request: protocol.Request) => { const completionsArgs = request.arguments; - return {response: this.getCompletions(completionsArgs.line, completionsArgs.offset, completionsArgs.prefix, completionsArgs.file), responseRequired: true}; + return { response: this.getCompletions(completionsArgs.line, completionsArgs.offset, completionsArgs.prefix, completionsArgs.file), responseRequired: true }; }, [CommandNames.CompletionDetails]: (request: protocol.Request) => { const completionDetailsArgs = request.arguments; - return {response: this.getCompletionEntryDetails(completionDetailsArgs.line, completionDetailsArgs.offset, - completionDetailsArgs.entryNames, completionDetailsArgs.file), responseRequired: true}; + return { + response: this.getCompletionEntryDetails(completionDetailsArgs.line, completionDetailsArgs.offset, + completionDetailsArgs.entryNames, completionDetailsArgs.file), responseRequired: true + }; }, [CommandNames.SignatureHelp]: (request: protocol.Request) => { const signatureHelpArgs = request.arguments; - return {response: this.getSignatureHelpItems(signatureHelpArgs.line, signatureHelpArgs.offset, signatureHelpArgs.file), responseRequired: true}; + return { response: this.getSignatureHelpItems(signatureHelpArgs.line, signatureHelpArgs.offset, signatureHelpArgs.file), responseRequired: true }; }, [CommandNames.Geterr]: (request: protocol.Request) => { const geterrArgs = request.arguments; - return {response: this.getDiagnostics(geterrArgs.delay, geterrArgs.files), responseRequired: false}; + return { response: this.getDiagnostics(geterrArgs.delay, geterrArgs.files), responseRequired: false }; }, [CommandNames.GeterrForProject]: (request: protocol.Request) => { const { file, delay } = request.arguments; - return {response: this.getDiagnosticsForProject(delay, file), responseRequired: false}; + return { response: this.getDiagnosticsForProject(delay, file), responseRequired: false }; }, [CommandNames.Change]: (request: protocol.Request) => { const changeArgs = request.arguments; this.change(changeArgs.line, changeArgs.offset, changeArgs.endLine, changeArgs.endOffset, - changeArgs.insertString, changeArgs.file); - return {responseRequired: false}; + changeArgs.insertString, changeArgs.file); + return { responseRequired: false }; }, [CommandNames.Configure]: (request: protocol.Request) => { const configureArgs = request.arguments; this.projectService.setHostConfiguration(configureArgs); this.output(undefined, CommandNames.Configure, request.seq); - return {responseRequired: false}; + return { responseRequired: false }; }, [CommandNames.Reload]: (request: protocol.Request) => { const reloadArgs = request.arguments; this.reload(reloadArgs.file, reloadArgs.tmpfile, request.seq); - return {responseRequired: false}; + return {response: { reloadFinished: true }, responseRequired: true}; }, [CommandNames.Saveto]: (request: protocol.Request) => { const savetoArgs = request.arguments; this.saveToTmp(savetoArgs.file, savetoArgs.tmpfile); - return {responseRequired: false}; + return { responseRequired: false }; }, [CommandNames.Close]: (request: protocol.Request) => { const closeArgs = request.arguments; this.closeClientFile(closeArgs.file); - return {responseRequired: false}; + return { responseRequired: false }; }, [CommandNames.Navto]: (request: protocol.Request) => { const navtoArgs = request.arguments; - return {response: this.getNavigateToItems(navtoArgs.searchValue, navtoArgs.file, navtoArgs.maxResultCount), responseRequired: true}; + return { response: this.getNavigateToItems(navtoArgs.searchValue, navtoArgs.file, navtoArgs.maxResultCount), responseRequired: true }; }, [CommandNames.Brace]: (request: protocol.Request) => { const braceArguments = request.arguments; - return {response: this.getBraceMatching(braceArguments.line, braceArguments.offset, braceArguments.file), responseRequired: true}; + return { response: this.getBraceMatching(braceArguments.line, braceArguments.offset, braceArguments.file), responseRequired: true }; }, [CommandNames.NavBar]: (request: protocol.Request) => { const navBarArgs = request.arguments; - return {response: this.getNavigationBarItems(navBarArgs.file), responseRequired: true}; + return { response: this.getNavigationBarItems(navBarArgs.file), responseRequired: true }; }, [CommandNames.Occurrences]: (request: protocol.Request) => { const { line, offset, file: fileName } = request.arguments; - return {response: this.getOccurrences(line, offset, fileName), responseRequired: true}; + return { response: this.getOccurrences(line, offset, fileName), responseRequired: true }; }, [CommandNames.DocumentHighlights]: (request: protocol.Request) => { const { line, offset, file: fileName, filesToSearch } = request.arguments; - return {response: this.getDocumentHighlights(line, offset, fileName, filesToSearch), responseRequired: true}; + return { response: this.getDocumentHighlights(line, offset, fileName, filesToSearch), responseRequired: true }; }, [CommandNames.ProjectInfo]: (request: protocol.Request) => { const { file, needFileNameList } = request.arguments; - return {response: this.getProjectInfo(file, needFileNameList), responseRequired: true}; + return { response: this.getProjectInfo(file, needFileNameList), responseRequired: true }; }, [CommandNames.ReloadProjects]: (request: protocol.ReloadProjectsRequest) => { this.reloadProjects(); - return {responseRequired: false}; + return { responseRequired: false }; } }; - public addProtocolHandler(command: string, handler: (request: protocol.Request) => {response?: any, responseRequired: boolean}) { + public addProtocolHandler(command: string, handler: (request: protocol.Request) => { response?: any, responseRequired: boolean }) { if (this.handlers[command]) { throw new Error(`Protocol handler already exists for command "${command}"`); } this.handlers[command] = handler; } - public executeCommand(request: protocol.Request): {response?: any, responseRequired?: boolean} { + public executeCommand(request: protocol.Request): { response?: any, responseRequired?: boolean } { const handler = this.handlers[request.command]; if (handler) { return handler(request); @@ -1074,7 +1140,7 @@ namespace ts.server { else { this.projectService.log("Unrecognized JSON command: " + JSON.stringify(request)); this.output(undefined, CommandNames.Unknown, request.seq, "Unrecognized JSON command: " + request.command); - return {responseRequired: false}; + return { responseRequired: false }; } } diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 066bcf7cda6..58e3ed1b356 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -728,25 +728,24 @@ namespace ts.formatting { dynamicIndentation.getIndentationForToken(tokenStart.line, currentTokenInfo.token.kind, container) : Constants.Unknown; + let indentNextTokenOrTrivia = true; if (currentTokenInfo.leadingTrivia) { let commentIndentation = dynamicIndentation.getIndentationForComment(currentTokenInfo.token.kind, tokenIndentation, container); - let indentNextTokenOrTrivia = true; for (let triviaItem of currentTokenInfo.leadingTrivia) { - if (!rangeContainsRange(originalRange, triviaItem)) { - continue; - } - + const triviaInRange = rangeContainsRange(originalRange, triviaItem); switch (triviaItem.kind) { case SyntaxKind.MultiLineCommentTrivia: - indentMultilineComment(triviaItem, commentIndentation, /*firstLineIsIndented*/ !indentNextTokenOrTrivia); + if (triviaInRange) { + indentMultilineComment(triviaItem, commentIndentation, /*firstLineIsIndented*/ !indentNextTokenOrTrivia); + } indentNextTokenOrTrivia = false; break; case SyntaxKind.SingleLineCommentTrivia: - if (indentNextTokenOrTrivia) { + if (indentNextTokenOrTrivia && triviaInRange) { insertIndentation(triviaItem.pos, commentIndentation, /*lineAdded*/ false); - indentNextTokenOrTrivia = false; } + indentNextTokenOrTrivia = false; break; case SyntaxKind.NewLineTrivia: indentNextTokenOrTrivia = true; @@ -756,7 +755,7 @@ namespace ts.formatting { } // indent token only if is it is in target range and does not overlap with any error ranges - if (tokenIndentation !== Constants.Unknown) { + if (tokenIndentation !== Constants.Unknown && indentNextTokenOrTrivia) { insertIndentation(currentTokenInfo.token.pos, tokenIndentation, lineAdded); lastIndentedLine = tokenStart.line; diff --git a/src/services/services.ts b/src/services/services.ts index ffbb174fe8c..c37224d6984 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -13,7 +13,7 @@ namespace ts { /** The version of the language service API */ - export const servicesVersion = "0.4"; + export const servicesVersion = "0.5"; export interface Node { getSourceFile(): SourceFile; @@ -1135,6 +1135,8 @@ namespace ts { getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion; + isValidBraceCompletionAtPostion(fileName: string, position: number, openingBrace: number): boolean; + getEmitOutput(fileName: string): EmitOutput; getProgram(): Program; @@ -5694,7 +5696,7 @@ namespace ts { declaration => (declaration.kind === SyntaxKind.ImportSpecifier || declaration.kind === SyntaxKind.ExportSpecifier) ? declaration : undefined); if (importOrExportSpecifier && - // export { a } + // export { a } (!importOrExportSpecifier.propertyName || // export {a as class } where a is location importOrExportSpecifier.propertyName === location)) { @@ -5774,7 +5776,7 @@ namespace ts { return undefined; } - // If symbol is of object binding pattern element without property name we would want to + // 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; @@ -6236,7 +6238,7 @@ namespace ts { result = result.concat(typeChecker.getSymbolsOfParameterPropertyDeclaration(symbol.valueDeclaration, symbol.name)); } - // If this is symbol of binding element without propertyName declaration in Object binding pattern + // 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) { @@ -6290,7 +6292,7 @@ namespace ts { if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { forEach(symbol.getDeclarations(), declaration => { - if (declaration.kind === SyntaxKind.ClassDeclaration) { + if (isClassLike(declaration)) { getPropertySymbolFromTypeReference(getClassExtendsHeritageClauseElement(declaration)); forEach(getClassImplementsHeritageClauseElements(declaration), getPropertySymbolFromTypeReference); } @@ -6307,7 +6309,7 @@ namespace ts { if (type) { const propertySymbol = typeChecker.getPropertyOfType(type, propertyName); if (propertySymbol) { - result.push(propertySymbol); + result.push(...typeChecker.getRootSymbols(propertySymbol)); } // Visit the typeReference as well to see if it directly or indirectly use that property @@ -6352,7 +6354,7 @@ namespace ts { } } - // If the reference location is the binding element and doesn't have property name + // 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); @@ -7469,6 +7471,36 @@ namespace ts { return { newText: result, caretOffset: preamble.length }; } + 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 + // expensive to do during typing scenarios + // i.e. whether we're dealing with: + // var x = new foo<| ( with class foo{} ) + // or + // var y = 3 <| + if (openingBrace === CharacterCodes.lessThan) { + return false; + } + + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + + // Check if in a context where we don't want to perform any insertion + if (isInString(sourceFile, position) || isInComment(sourceFile, position)) { + return false; + } + + if (isInsideJsxElementOrAttribute(sourceFile, position)) { + return openingBrace === CharacterCodes.openBrace; + } + + if (isInTemplateString(sourceFile, position)) { + return false; + } + + return true; + } + function getParametersForJsDocOwningNode(commentOwner: Node): ParameterDeclaration[] { if (isFunctionLike(commentOwner)) { return commentOwner.parameters; @@ -7763,6 +7795,7 @@ namespace ts { getFormattingEditsForDocument, getFormattingEditsAfterKeystroke, getDocCommentTemplateAtPosition, + isValidBraceCompletionAtPostion, getEmitOutput, getNonBoundSourceFile, getProgram diff --git a/src/services/shims.ts b/src/services/shims.ts index 77a9611ead1..b849407ebab 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -221,6 +221,13 @@ namespace ts { */ getDocCommentTemplateAtPosition(fileName: string, position: number): string; + /** + * Returns JSON-encoded boolean to indicate whether we should support brace location + * at the current position. + * E.g. we don't want brace completion inside string-literals, comments, etc. + */ + isValidBraceCompletionAtPostion(fileName: string, position: number, openingBrace: number): string; + getEmitOutput(fileName: string): string; } @@ -733,6 +740,13 @@ namespace ts { ); } + public isValidBraceCompletionAtPostion(fileName: string, position: number, openingBrace: number): string { + return this.forwardJSONCall( + `isValidBraceCompletionAtPostion('${fileName}', ${position}, ${openingBrace})`, + () => this.languageService.isValidBraceCompletionAtPostion(fileName, position, openingBrace) + ); + } + /// GET SMART INDENT public getIndentationAtPosition(fileName: string, position: number, options: string /*Services.EditorOptions*/): string { return this.forwardJSONCall( diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 0230195b0cc..bf90a023c14 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -428,13 +428,53 @@ namespace ts { export function isInString(sourceFile: SourceFile, position: number) { let token = getTokenAtPosition(sourceFile, position); - return token && (token.kind === SyntaxKind.StringLiteral || token.kind === SyntaxKind.StringLiteralType) && position > token.getStart(); + return token && (token.kind === SyntaxKind.StringLiteral || token.kind === SyntaxKind.StringLiteralType) && position > token.getStart(sourceFile); } export function isInComment(sourceFile: SourceFile, position: number) { return isInCommentHelper(sourceFile, position, /*predicate*/ undefined); } + /** + * returns true if the position is in between the open and close elements of an JSX expression. + */ + export function isInsideJsxElementOrAttribute(sourceFile: SourceFile, position: number) { + let token = getTokenAtPosition(sourceFile, position); + + if (!token) { + return false; + } + + //
Hello |
+ if (token.kind === SyntaxKind.LessThanToken && token.parent.kind === SyntaxKind.JsxText) { + return true; + } + + //
{ |
or
+ if (token.kind === SyntaxKind.LessThanToken && token.parent.kind === SyntaxKind.JsxExpression) { + return true; + } + + //
{ + // | + // } < /div> + if (token && token.kind === SyntaxKind.CloseBraceToken && token.parent.kind === SyntaxKind.JsxExpression) { + return true; + } + + //
|
+ if (token.kind === SyntaxKind.LessThanToken && token.parent.kind === SyntaxKind.JsxClosingElement) { + return true; + } + + return false; + } + + export function isInTemplateString(sourceFile: SourceFile, position: number) { + let token = getTokenAtPosition(sourceFile, position); + return isTemplateLiteralKind(token.kind) && position > token.getStart(sourceFile); + } + /** * Returns true if the cursor at position in sourceFile is within a comment that additionally * satisfies predicate, and false otherwise. @@ -442,7 +482,7 @@ namespace ts { export function isInCommentHelper(sourceFile: SourceFile, position: number, predicate?: (c: CommentRange) => boolean): boolean { let token = getTokenAtPosition(sourceFile, position); - if (token && position <= token.getStart()) { + if (token && position <= token.getStart(sourceFile)) { let commentRanges = getLeadingCommentRanges(sourceFile.text, token.pos); // The end marker of a single-line comment does not include the newline character. @@ -844,12 +884,15 @@ namespace ts { } export function getScriptKind(fileName: string, host?: LanguageServiceHost): ScriptKind { - // First check to see if the script kind can be determined from the file name - var scriptKind = getScriptKindFromFileName(fileName); - if (scriptKind === ScriptKind.Unknown && host && host.getScriptKind) { - // Next check to see if the host can resolve the script kind + // First check to see if the script kind was specified by the host. Chances are the host + // may override the default script kind for the file extension. + let scriptKind: ScriptKind; + if (host && host.getScriptKind) { scriptKind = host.getScriptKind(fileName); } + if (!scriptKind || scriptKind === ScriptKind.Unknown) { + scriptKind = getScriptKindFromFileName(fileName); + } return ensureScriptKind(fileName, scriptKind); } } \ No newline at end of file diff --git a/tests/baselines/reference/TypeGuardWithEnumUnion.types b/tests/baselines/reference/TypeGuardWithEnumUnion.types index 453ec220f02..05d55cb0dbb 100644 --- a/tests/baselines/reference/TypeGuardWithEnumUnion.types +++ b/tests/baselines/reference/TypeGuardWithEnumUnion.types @@ -55,7 +55,7 @@ function f2(x: Color | string | string[]) { if (typeof x === "number") { >typeof x === "number" : boolean >typeof x : string ->x : Color | string | string[] +>x : string[] | Color | string >"number" : string var z = x; @@ -68,16 +68,16 @@ function f2(x: Color | string | string[]) { } else { var w = x; ->w : string | string[] ->x : string | string[] +>w : string[] | string +>x : string[] | string var w: string | string[]; ->w : string | string[] +>w : string[] | string } if (typeof x === "string") { >typeof x === "string" : boolean >typeof x : string ->x : Color | string | string[] +>x : Color | string[] | string >"string" : string var a = x; diff --git a/tests/baselines/reference/arrayFilter.js b/tests/baselines/reference/arrayFilter.js new file mode 100644 index 00000000000..dd3b321b19c --- /dev/null +++ b/tests/baselines/reference/arrayFilter.js @@ -0,0 +1,16 @@ +//// [arrayFilter.ts] +var foo = [ + { name: 'bar' }, + { name: null }, + { name: 'baz' } +] + +foo.filter(x => x.name); //should accepted all possible types not only boolean! + +//// [arrayFilter.js] +var foo = [ + { name: 'bar' }, + { name: null }, + { name: 'baz' } +]; +foo.filter(function (x) { return x.name; }); //should accepted all possible types not only boolean! diff --git a/tests/baselines/reference/arrayFilter.symbols b/tests/baselines/reference/arrayFilter.symbols new file mode 100644 index 00000000000..fcdd39117a7 --- /dev/null +++ b/tests/baselines/reference/arrayFilter.symbols @@ -0,0 +1,24 @@ +=== tests/cases/compiler/arrayFilter.ts === +var foo = [ +>foo : Symbol(foo, Decl(arrayFilter.ts, 0, 3)) + + { name: 'bar' }, +>name : Symbol(name, Decl(arrayFilter.ts, 1, 5)) + + { name: null }, +>name : Symbol(name, Decl(arrayFilter.ts, 2, 5)) + + { name: 'baz' } +>name : Symbol(name, Decl(arrayFilter.ts, 3, 5)) + +] + +foo.filter(x => x.name); //should accepted all possible types not only boolean! +>foo.filter : Symbol(Array.filter, Decl(lib.d.ts, --, --)) +>foo : Symbol(foo, Decl(arrayFilter.ts, 0, 3)) +>filter : Symbol(Array.filter, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(arrayFilter.ts, 6, 11)) +>x.name : Symbol(name, Decl(arrayFilter.ts, 1, 5)) +>x : Symbol(x, Decl(arrayFilter.ts, 6, 11)) +>name : Symbol(name, Decl(arrayFilter.ts, 1, 5)) + diff --git a/tests/baselines/reference/arrayFilter.types b/tests/baselines/reference/arrayFilter.types new file mode 100644 index 00000000000..f3d6d421744 --- /dev/null +++ b/tests/baselines/reference/arrayFilter.types @@ -0,0 +1,33 @@ +=== tests/cases/compiler/arrayFilter.ts === +var foo = [ +>foo : { name: string; }[] +>[ { name: 'bar' }, { name: null }, { name: 'baz' }] : { name: string; }[] + + { name: 'bar' }, +>{ name: 'bar' } : { name: string; } +>name : string +>'bar' : string + + { name: null }, +>{ name: null } : { name: null; } +>name : null +>null : null + + { name: 'baz' } +>{ name: 'baz' } : { name: string; } +>name : string +>'baz' : string + +] + +foo.filter(x => x.name); //should accepted all possible types not only boolean! +>foo.filter(x => x.name) : { name: string; }[] +>foo.filter : (callbackfn: (value: { name: string; }, index: number, array: { name: string; }[]) => any, thisArg?: any) => { name: string; }[] +>foo : { name: string; }[] +>filter : (callbackfn: (value: { name: string; }, index: number, array: { name: string; }[]) => any, thisArg?: any) => { name: string; }[] +>x => x.name : (x: { name: string; }) => string +>x : { name: string; } +>x.name : string +>x : { name: string; } +>name : string + diff --git a/tests/baselines/reference/assignmentTypeNarrowing.js b/tests/baselines/reference/assignmentTypeNarrowing.js new file mode 100644 index 00000000000..7c10dde65cc --- /dev/null +++ b/tests/baselines/reference/assignmentTypeNarrowing.js @@ -0,0 +1,53 @@ +//// [assignmentTypeNarrowing.ts] +let x: string | number | boolean | RegExp; + +x = ""; +x; // string + +[x] = [true]; +x; // boolean + +[x = ""] = [1]; +x; // string | number + +({x} = {x: true}); +x; // boolean + +({y: x} = {y: 1}); +x; // number + +({x = ""} = {x: true}); +x; // string | boolean + +({y: x = /a/} = {y: 1}); +x; // number | RegExp + +let a: string[]; + +for (x of a) { + x; // string +} + + +//// [assignmentTypeNarrowing.js] +var x; +x = ""; +x; // string +x = [true][0]; +x; // boolean +_a = [1][0], x = _a === void 0 ? "" : _a; +x; // string | number +(_b = { x: true }, x = _b.x, _b); +x; // boolean +(_c = { y: 1 }, x = _c.y, _c); +x; // number +(_d = { x: true }, _e = _d.x, x = _e === void 0 ? "" : _e, _d); +x; // string | boolean +(_f = { y: 1 }, _g = _f.y, x = _g === void 0 ? /a/ : _g, _f); +x; // number | RegExp +var a; +for (var _i = 0, a_1 = a; _i < a_1.length; _i++) { + x = a_1[_i]; + x; // string +} +var _a, _b, _c, _d, _e, _f, _g; diff --git a/tests/baselines/reference/assignmentTypeNarrowing.symbols b/tests/baselines/reference/assignmentTypeNarrowing.symbols new file mode 100644 index 00000000000..7d638d6a76b --- /dev/null +++ b/tests/baselines/reference/assignmentTypeNarrowing.symbols @@ -0,0 +1,64 @@ +=== tests/cases/conformance/expressions/assignmentOperator/assignmentTypeNarrowing.ts === +let x: string | number | boolean | RegExp; +>x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 0, 3)) +>RegExp : Symbol(RegExp, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +x = ""; +>x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 0, 3)) + +x; // string +>x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 0, 3)) + +[x] = [true]; +>x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 0, 3)) + +x; // boolean +>x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 0, 3)) + +[x = ""] = [1]; +>x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 0, 3)) + +x; // string | number +>x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 0, 3)) + +({x} = {x: true}); +>x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 11, 2)) +>x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 11, 8)) + +x; // boolean +>x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 0, 3)) + +({y: x} = {y: 1}); +>y : Symbol(y, Decl(assignmentTypeNarrowing.ts, 14, 2)) +>x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 0, 3)) +>y : Symbol(y, Decl(assignmentTypeNarrowing.ts, 14, 11)) + +x; // number +>x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 0, 3)) + +({x = ""} = {x: true}); +>x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 17, 2)) +>x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 17, 13)) + +x; // string | boolean +>x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 0, 3)) + +({y: x = /a/} = {y: 1}); +>y : Symbol(y, Decl(assignmentTypeNarrowing.ts, 20, 2)) +>x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 0, 3)) +>y : Symbol(y, Decl(assignmentTypeNarrowing.ts, 20, 17)) + +x; // number | RegExp +>x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 0, 3)) + +let a: string[]; +>a : Symbol(a, Decl(assignmentTypeNarrowing.ts, 23, 3)) + +for (x of a) { +>x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 0, 3)) +>a : Symbol(a, Decl(assignmentTypeNarrowing.ts, 23, 3)) + + x; // string +>x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 0, 3)) +} + diff --git a/tests/baselines/reference/assignmentTypeNarrowing.types b/tests/baselines/reference/assignmentTypeNarrowing.types new file mode 100644 index 00000000000..be99a31501d --- /dev/null +++ b/tests/baselines/reference/assignmentTypeNarrowing.types @@ -0,0 +1,98 @@ +=== tests/cases/conformance/expressions/assignmentOperator/assignmentTypeNarrowing.ts === +let x: string | number | boolean | RegExp; +>x : string | number | boolean | RegExp +>RegExp : RegExp + +x = ""; +>x = "" : string +>x : string | number | boolean | RegExp +>"" : string + +x; // string +>x : string + +[x] = [true]; +>[x] = [true] : [boolean] +>[x] : [string | number | boolean | RegExp] +>x : string | number | boolean | RegExp +>[true] : [boolean] +>true : boolean + +x; // boolean +>x : boolean + +[x = ""] = [1]; +>[x = ""] = [1] : [number] +>[x = ""] : [string] +>x = "" : string +>x : string | number | boolean | RegExp +>"" : string +>[1] : [number] +>1 : number + +x; // string | number +>x : string | number + +({x} = {x: true}); +>({x} = {x: true}) : { x: boolean; } +>{x} = {x: true} : { x: boolean; } +>{x} : { x: string | number | boolean | RegExp; } +>x : string | number | boolean | RegExp +>{x: true} : { x: boolean; } +>x : boolean +>true : boolean + +x; // boolean +>x : boolean + +({y: x} = {y: 1}); +>({y: x} = {y: 1}) : { y: number; } +>{y: x} = {y: 1} : { y: number; } +>{y: x} : { y: string | number | boolean | RegExp; } +>y : string | number | boolean | RegExp +>x : string | number | boolean | RegExp +>{y: 1} : { y: number; } +>y : number +>1 : number + +x; // number +>x : number + +({x = ""} = {x: true}); +>({x = ""} = {x: true}) : { x?: boolean; } +>{x = ""} = {x: true} : { x?: boolean; } +>{x = ""} : { x?: string | number | boolean | RegExp; } +>x : string | number | boolean | RegExp +>{x: true} : { x?: boolean; } +>x : boolean +>true : boolean + +x; // string | boolean +>x : string | boolean + +({y: x = /a/} = {y: 1}); +>({y: x = /a/} = {y: 1}) : { y?: number; } +>{y: x = /a/} = {y: 1} : { y?: number; } +>{y: x = /a/} : { y?: RegExp; } +>y : RegExp +>x = /a/ : RegExp +>x : string | number | boolean | RegExp +>/a/ : RegExp +>{y: 1} : { y?: number; } +>y : number +>1 : number + +x; // number | RegExp +>x : number | RegExp + +let a: string[]; +>a : string[] + +for (x of a) { +>x : string | number | boolean | RegExp +>a : string[] + + x; // string +>x : string +} + diff --git a/tests/baselines/reference/constIndexedAccess.symbols b/tests/baselines/reference/constIndexedAccess.symbols index 2ccb7f11686..f7ce6b78c2d 100644 --- a/tests/baselines/reference/constIndexedAccess.symbols +++ b/tests/baselines/reference/constIndexedAccess.symbols @@ -24,12 +24,12 @@ let test: indexAccess; let s = test[0]; >s : Symbol(s, Decl(constIndexedAccess.ts, 13, 3)) >test : Symbol(test, Decl(constIndexedAccess.ts, 11, 3)) ->0 : Symbol(indexAccess.0, Decl(constIndexedAccess.ts, 6, 23)) +>0 : Symbol(indexAccess[0], Decl(constIndexedAccess.ts, 6, 23)) let n = test[1]; >n : Symbol(n, Decl(constIndexedAccess.ts, 14, 3)) >test : Symbol(test, Decl(constIndexedAccess.ts, 11, 3)) ->1 : Symbol(indexAccess.1, Decl(constIndexedAccess.ts, 7, 14)) +>1 : Symbol(indexAccess[1], Decl(constIndexedAccess.ts, 7, 14)) let s1 = test[numbers.zero]; >s1 : Symbol(s1, Decl(constIndexedAccess.ts, 16, 3)) diff --git a/tests/baselines/reference/controlFlowAssignmentExpression.js b/tests/baselines/reference/controlFlowAssignmentExpression.js new file mode 100644 index 00000000000..cf8d70b92de --- /dev/null +++ b/tests/baselines/reference/controlFlowAssignmentExpression.js @@ -0,0 +1,22 @@ +//// [controlFlowAssignmentExpression.ts] +let x: string | boolean | number; +let obj: any; + +x = ""; +x = x.length; +x; // number + +x = true; +(x = "", obj).foo = (x = x.length); +x; // number + + +//// [controlFlowAssignmentExpression.js] +var x; +var obj; +x = ""; +x = x.length; +x; // number +x = true; +(x = "", obj).foo = (x = x.length); +x; // number diff --git a/tests/baselines/reference/controlFlowAssignmentExpression.symbols b/tests/baselines/reference/controlFlowAssignmentExpression.symbols new file mode 100644 index 00000000000..470e3114ca8 --- /dev/null +++ b/tests/baselines/reference/controlFlowAssignmentExpression.symbols @@ -0,0 +1,33 @@ +=== tests/cases/conformance/controlFlow/controlFlowAssignmentExpression.ts === +let x: string | boolean | number; +>x : Symbol(x, Decl(controlFlowAssignmentExpression.ts, 0, 3)) + +let obj: any; +>obj : Symbol(obj, Decl(controlFlowAssignmentExpression.ts, 1, 3)) + +x = ""; +>x : Symbol(x, Decl(controlFlowAssignmentExpression.ts, 0, 3)) + +x = x.length; +>x : Symbol(x, Decl(controlFlowAssignmentExpression.ts, 0, 3)) +>x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowAssignmentExpression.ts, 0, 3)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) + +x; // number +>x : Symbol(x, Decl(controlFlowAssignmentExpression.ts, 0, 3)) + +x = true; +>x : Symbol(x, Decl(controlFlowAssignmentExpression.ts, 0, 3)) + +(x = "", obj).foo = (x = x.length); +>x : Symbol(x, Decl(controlFlowAssignmentExpression.ts, 0, 3)) +>obj : Symbol(obj, Decl(controlFlowAssignmentExpression.ts, 1, 3)) +>x : Symbol(x, Decl(controlFlowAssignmentExpression.ts, 0, 3)) +>x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowAssignmentExpression.ts, 0, 3)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) + +x; // number +>x : Symbol(x, Decl(controlFlowAssignmentExpression.ts, 0, 3)) + diff --git a/tests/baselines/reference/controlFlowAssignmentExpression.types b/tests/baselines/reference/controlFlowAssignmentExpression.types new file mode 100644 index 00000000000..24355fd8c4a --- /dev/null +++ b/tests/baselines/reference/controlFlowAssignmentExpression.types @@ -0,0 +1,47 @@ +=== tests/cases/conformance/controlFlow/controlFlowAssignmentExpression.ts === +let x: string | boolean | number; +>x : string | boolean | number + +let obj: any; +>obj : any + +x = ""; +>x = "" : string +>x : string | boolean | number +>"" : string + +x = x.length; +>x = x.length : number +>x : string | boolean | number +>x.length : number +>x : string +>length : number + +x; // number +>x : number + +x = true; +>x = true : boolean +>x : string | boolean | number +>true : boolean + +(x = "", obj).foo = (x = x.length); +>(x = "", obj).foo = (x = x.length) : number +>(x = "", obj).foo : any +>(x = "", obj) : any +>x = "", obj : any +>x = "" : string +>x : string | boolean | number +>"" : string +>obj : any +>foo : any +>(x = x.length) : number +>x = x.length : number +>x : string | boolean | number +>x.length : number +>x : string +>length : number + +x; // number +>x : number + diff --git a/tests/baselines/reference/controlFlowBinaryAndExpression.js b/tests/baselines/reference/controlFlowBinaryAndExpression.js new file mode 100644 index 00000000000..eb89d1a78cf --- /dev/null +++ b/tests/baselines/reference/controlFlowBinaryAndExpression.js @@ -0,0 +1,20 @@ +//// [controlFlowBinaryAndExpression.ts] +let x: string | number | boolean; +let cond: boolean; + +(x = "") && (x = 0); +x; // string | number + +x = ""; +cond && (x = 0); +x; // string | number + + +//// [controlFlowBinaryAndExpression.js] +var x; +var cond; +(x = "") && (x = 0); +x; // string | number +x = ""; +cond && (x = 0); +x; // string | number diff --git a/tests/baselines/reference/controlFlowBinaryAndExpression.symbols b/tests/baselines/reference/controlFlowBinaryAndExpression.symbols new file mode 100644 index 00000000000..5be553f6802 --- /dev/null +++ b/tests/baselines/reference/controlFlowBinaryAndExpression.symbols @@ -0,0 +1,24 @@ +=== tests/cases/conformance/controlFlow/controlFlowBinaryAndExpression.ts === +let x: string | number | boolean; +>x : Symbol(x, Decl(controlFlowBinaryAndExpression.ts, 0, 3)) + +let cond: boolean; +>cond : Symbol(cond, Decl(controlFlowBinaryAndExpression.ts, 1, 3)) + +(x = "") && (x = 0); +>x : Symbol(x, Decl(controlFlowBinaryAndExpression.ts, 0, 3)) +>x : Symbol(x, Decl(controlFlowBinaryAndExpression.ts, 0, 3)) + +x; // string | number +>x : Symbol(x, Decl(controlFlowBinaryAndExpression.ts, 0, 3)) + +x = ""; +>x : Symbol(x, Decl(controlFlowBinaryAndExpression.ts, 0, 3)) + +cond && (x = 0); +>cond : Symbol(cond, Decl(controlFlowBinaryAndExpression.ts, 1, 3)) +>x : Symbol(x, Decl(controlFlowBinaryAndExpression.ts, 0, 3)) + +x; // string | number +>x : Symbol(x, Decl(controlFlowBinaryAndExpression.ts, 0, 3)) + diff --git a/tests/baselines/reference/controlFlowBinaryAndExpression.types b/tests/baselines/reference/controlFlowBinaryAndExpression.types new file mode 100644 index 00000000000..8a1924c42eb --- /dev/null +++ b/tests/baselines/reference/controlFlowBinaryAndExpression.types @@ -0,0 +1,37 @@ +=== tests/cases/conformance/controlFlow/controlFlowBinaryAndExpression.ts === +let x: string | number | boolean; +>x : string | number | boolean + +let cond: boolean; +>cond : boolean + +(x = "") && (x = 0); +>(x = "") && (x = 0) : number +>(x = "") : string +>x = "" : string +>x : string | number | boolean +>"" : string +>(x = 0) : number +>x = 0 : number +>x : string | number | boolean +>0 : number + +x; // string | number +>x : string | number + +x = ""; +>x = "" : string +>x : string | number | boolean +>"" : string + +cond && (x = 0); +>cond && (x = 0) : number +>cond : boolean +>(x = 0) : number +>x = 0 : number +>x : string | number | boolean +>0 : number + +x; // string | number +>x : string | number + diff --git a/tests/baselines/reference/controlFlowBinaryOrExpression.js b/tests/baselines/reference/controlFlowBinaryOrExpression.js new file mode 100644 index 00000000000..fb48c5a23e0 --- /dev/null +++ b/tests/baselines/reference/controlFlowBinaryOrExpression.js @@ -0,0 +1,57 @@ +//// [controlFlowBinaryOrExpression.ts] +let x: string | number | boolean; +let cond: boolean; + +(x = "") || (x = 0); +x; // string | number + +x = ""; +cond || (x = 0); +x; // string | number + +export interface NodeList { + length: number; +} + +export interface HTMLCollection { + length: number; +} + +declare function isNodeList(sourceObj: any): sourceObj is NodeList; +declare function isHTMLCollection(sourceObj: any): sourceObj is HTMLCollection; + +type EventTargetLike = {a: string} | HTMLCollection | NodeList; + +var sourceObj: EventTargetLike = undefined; +if (isNodeList(sourceObj)) { + sourceObj.length; +} + +if (isHTMLCollection(sourceObj)) { + sourceObj.length; +} + +if (isNodeList(sourceObj) || isHTMLCollection(sourceObj)) { + sourceObj.length; +} + + +//// [controlFlowBinaryOrExpression.js] +"use strict"; +var x; +var cond; +(x = "") || (x = 0); +x; // string | number +x = ""; +cond || (x = 0); +x; // string | number +var sourceObj = undefined; +if (isNodeList(sourceObj)) { + sourceObj.length; +} +if (isHTMLCollection(sourceObj)) { + sourceObj.length; +} +if (isNodeList(sourceObj) || isHTMLCollection(sourceObj)) { + sourceObj.length; +} diff --git a/tests/baselines/reference/controlFlowBinaryOrExpression.symbols b/tests/baselines/reference/controlFlowBinaryOrExpression.symbols new file mode 100644 index 00000000000..e47bdb19d34 --- /dev/null +++ b/tests/baselines/reference/controlFlowBinaryOrExpression.symbols @@ -0,0 +1,93 @@ +=== tests/cases/conformance/controlFlow/controlFlowBinaryOrExpression.ts === +let x: string | number | boolean; +>x : Symbol(x, Decl(controlFlowBinaryOrExpression.ts, 0, 3)) + +let cond: boolean; +>cond : Symbol(cond, Decl(controlFlowBinaryOrExpression.ts, 1, 3)) + +(x = "") || (x = 0); +>x : Symbol(x, Decl(controlFlowBinaryOrExpression.ts, 0, 3)) +>x : Symbol(x, Decl(controlFlowBinaryOrExpression.ts, 0, 3)) + +x; // string | number +>x : Symbol(x, Decl(controlFlowBinaryOrExpression.ts, 0, 3)) + +x = ""; +>x : Symbol(x, Decl(controlFlowBinaryOrExpression.ts, 0, 3)) + +cond || (x = 0); +>cond : Symbol(cond, Decl(controlFlowBinaryOrExpression.ts, 1, 3)) +>x : Symbol(x, Decl(controlFlowBinaryOrExpression.ts, 0, 3)) + +x; // string | number +>x : Symbol(x, Decl(controlFlowBinaryOrExpression.ts, 0, 3)) + +export interface NodeList { +>NodeList : Symbol(NodeList, Decl(controlFlowBinaryOrExpression.ts, 8, 2)) + + length: number; +>length : Symbol(NodeList.length, Decl(controlFlowBinaryOrExpression.ts, 10, 27)) +} + +export interface HTMLCollection { +>HTMLCollection : Symbol(HTMLCollection, Decl(controlFlowBinaryOrExpression.ts, 12, 1)) + + length: number; +>length : Symbol(HTMLCollection.length, Decl(controlFlowBinaryOrExpression.ts, 14, 33)) +} + +declare function isNodeList(sourceObj: any): sourceObj is NodeList; +>isNodeList : Symbol(isNodeList, Decl(controlFlowBinaryOrExpression.ts, 16, 1)) +>sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 18, 28)) +>sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 18, 28)) +>NodeList : Symbol(NodeList, Decl(controlFlowBinaryOrExpression.ts, 8, 2)) + +declare function isHTMLCollection(sourceObj: any): sourceObj is HTMLCollection; +>isHTMLCollection : Symbol(isHTMLCollection, Decl(controlFlowBinaryOrExpression.ts, 18, 67)) +>sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 19, 34)) +>sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 19, 34)) +>HTMLCollection : Symbol(HTMLCollection, Decl(controlFlowBinaryOrExpression.ts, 12, 1)) + +type EventTargetLike = {a: string} | HTMLCollection | NodeList; +>EventTargetLike : Symbol(EventTargetLike, Decl(controlFlowBinaryOrExpression.ts, 19, 79)) +>a : Symbol(a, Decl(controlFlowBinaryOrExpression.ts, 21, 24)) +>HTMLCollection : Symbol(HTMLCollection, Decl(controlFlowBinaryOrExpression.ts, 12, 1)) +>NodeList : Symbol(NodeList, Decl(controlFlowBinaryOrExpression.ts, 8, 2)) + +var sourceObj: EventTargetLike = undefined; +>sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) +>EventTargetLike : Symbol(EventTargetLike, Decl(controlFlowBinaryOrExpression.ts, 19, 79)) +>undefined : Symbol(undefined) + +if (isNodeList(sourceObj)) { +>isNodeList : Symbol(isNodeList, Decl(controlFlowBinaryOrExpression.ts, 16, 1)) +>sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) + + sourceObj.length; +>sourceObj.length : Symbol(HTMLCollection.length, Decl(controlFlowBinaryOrExpression.ts, 14, 33)) +>sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) +>length : Symbol(HTMLCollection.length, Decl(controlFlowBinaryOrExpression.ts, 14, 33)) +} + +if (isHTMLCollection(sourceObj)) { +>isHTMLCollection : Symbol(isHTMLCollection, Decl(controlFlowBinaryOrExpression.ts, 18, 67)) +>sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) + + sourceObj.length; +>sourceObj.length : Symbol(HTMLCollection.length, Decl(controlFlowBinaryOrExpression.ts, 14, 33)) +>sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) +>length : Symbol(HTMLCollection.length, Decl(controlFlowBinaryOrExpression.ts, 14, 33)) +} + +if (isNodeList(sourceObj) || isHTMLCollection(sourceObj)) { +>isNodeList : Symbol(isNodeList, Decl(controlFlowBinaryOrExpression.ts, 16, 1)) +>sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) +>isHTMLCollection : Symbol(isHTMLCollection, Decl(controlFlowBinaryOrExpression.ts, 18, 67)) +>sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) + + sourceObj.length; +>sourceObj.length : Symbol(HTMLCollection.length, Decl(controlFlowBinaryOrExpression.ts, 14, 33)) +>sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) +>length : Symbol(HTMLCollection.length, Decl(controlFlowBinaryOrExpression.ts, 14, 33)) +} + diff --git a/tests/baselines/reference/controlFlowBinaryOrExpression.types b/tests/baselines/reference/controlFlowBinaryOrExpression.types new file mode 100644 index 00000000000..8c1cd32d8d9 --- /dev/null +++ b/tests/baselines/reference/controlFlowBinaryOrExpression.types @@ -0,0 +1,112 @@ +=== tests/cases/conformance/controlFlow/controlFlowBinaryOrExpression.ts === +let x: string | number | boolean; +>x : string | number | boolean + +let cond: boolean; +>cond : boolean + +(x = "") || (x = 0); +>(x = "") || (x = 0) : string | number +>(x = "") : string +>x = "" : string +>x : string | number | boolean +>"" : string +>(x = 0) : number +>x = 0 : number +>x : string | number | boolean +>0 : number + +x; // string | number +>x : string | number + +x = ""; +>x = "" : string +>x : string | number | boolean +>"" : string + +cond || (x = 0); +>cond || (x = 0) : boolean | number +>cond : boolean +>(x = 0) : number +>x = 0 : number +>x : string | number | boolean +>0 : number + +x; // string | number +>x : string | number + +export interface NodeList { +>NodeList : NodeList + + length: number; +>length : number +} + +export interface HTMLCollection { +>HTMLCollection : HTMLCollection + + length: number; +>length : number +} + +declare function isNodeList(sourceObj: any): sourceObj is NodeList; +>isNodeList : (sourceObj: any) => sourceObj is NodeList +>sourceObj : any +>sourceObj : any +>NodeList : NodeList + +declare function isHTMLCollection(sourceObj: any): sourceObj is HTMLCollection; +>isHTMLCollection : (sourceObj: any) => sourceObj is HTMLCollection +>sourceObj : any +>sourceObj : any +>HTMLCollection : HTMLCollection + +type EventTargetLike = {a: string} | HTMLCollection | NodeList; +>EventTargetLike : { a: string; } | HTMLCollection | NodeList +>a : string +>HTMLCollection : HTMLCollection +>NodeList : NodeList + +var sourceObj: EventTargetLike = undefined; +>sourceObj : { a: string; } | HTMLCollection | NodeList +>EventTargetLike : { a: string; } | HTMLCollection | NodeList +>undefined : any +>undefined : undefined + +if (isNodeList(sourceObj)) { +>isNodeList(sourceObj) : boolean +>isNodeList : (sourceObj: any) => sourceObj is NodeList +>sourceObj : { a: string; } | HTMLCollection + + sourceObj.length; +>sourceObj.length : number +>sourceObj : HTMLCollection +>length : number +} + +if (isHTMLCollection(sourceObj)) { +>isHTMLCollection(sourceObj) : boolean +>isHTMLCollection : (sourceObj: any) => sourceObj is HTMLCollection +>sourceObj : HTMLCollection | { a: string; } + + sourceObj.length; +>sourceObj.length : number +>sourceObj : HTMLCollection +>length : number +} + +if (isNodeList(sourceObj) || isHTMLCollection(sourceObj)) { +>isNodeList(sourceObj) || isHTMLCollection(sourceObj) : boolean +>isNodeList(sourceObj) : boolean +>isNodeList : (sourceObj: any) => sourceObj is NodeList +>sourceObj : HTMLCollection | { a: string; } +>isHTMLCollection(sourceObj) : boolean +>isHTMLCollection : (sourceObj: any) => sourceObj is HTMLCollection +>sourceObj : { a: string; } + + sourceObj.length; +>sourceObj.length : number +>sourceObj : HTMLCollection +>length : number +} + diff --git a/tests/baselines/reference/controlFlowCommaOperator.js b/tests/baselines/reference/controlFlowCommaOperator.js new file mode 100644 index 00000000000..55dcc77e075 --- /dev/null +++ b/tests/baselines/reference/controlFlowCommaOperator.js @@ -0,0 +1,48 @@ +//// [controlFlowCommaOperator.ts] +function f(x: string | number | boolean) { + let y: string | number | boolean = false; + let z: string | number | boolean = false; + if (y = "", typeof x === "string") { + x; // string + y; // string + z; // boolean + } + else if (z = 1, typeof x === "number") { + x; // number + y; // string + z; // number + } + else { + x; // boolean + y; // string + z; // number + } + x; // string | number | boolean + y; // string + z; // number | boolean +} + + +//// [controlFlowCommaOperator.js] +function f(x) { + var y = false; + var z = false; + if (y = "", typeof x === "string") { + x; // string + y; // string + z; // boolean + } + else if (z = 1, typeof x === "number") { + x; // number + y; // string + z; // number + } + else { + x; // boolean + y; // string + z; // number + } + x; // string | number | boolean + y; // string + z; // number | boolean +} diff --git a/tests/baselines/reference/controlFlowCommaOperator.symbols b/tests/baselines/reference/controlFlowCommaOperator.symbols new file mode 100644 index 00000000000..f1550b79a68 --- /dev/null +++ b/tests/baselines/reference/controlFlowCommaOperator.symbols @@ -0,0 +1,57 @@ +=== tests/cases/conformance/controlFlow/controlFlowCommaOperator.ts === +function f(x: string | number | boolean) { +>f : Symbol(f, Decl(controlFlowCommaOperator.ts, 0, 0)) +>x : Symbol(x, Decl(controlFlowCommaOperator.ts, 0, 11)) + + let y: string | number | boolean = false; +>y : Symbol(y, Decl(controlFlowCommaOperator.ts, 1, 7)) + + let z: string | number | boolean = false; +>z : Symbol(z, Decl(controlFlowCommaOperator.ts, 2, 7)) + + if (y = "", typeof x === "string") { +>y : Symbol(y, Decl(controlFlowCommaOperator.ts, 1, 7)) +>x : Symbol(x, Decl(controlFlowCommaOperator.ts, 0, 11)) + + x; // string +>x : Symbol(x, Decl(controlFlowCommaOperator.ts, 0, 11)) + + y; // string +>y : Symbol(y, Decl(controlFlowCommaOperator.ts, 1, 7)) + + z; // boolean +>z : Symbol(z, Decl(controlFlowCommaOperator.ts, 2, 7)) + } + else if (z = 1, typeof x === "number") { +>z : Symbol(z, Decl(controlFlowCommaOperator.ts, 2, 7)) +>x : Symbol(x, Decl(controlFlowCommaOperator.ts, 0, 11)) + + x; // number +>x : Symbol(x, Decl(controlFlowCommaOperator.ts, 0, 11)) + + y; // string +>y : Symbol(y, Decl(controlFlowCommaOperator.ts, 1, 7)) + + z; // number +>z : Symbol(z, Decl(controlFlowCommaOperator.ts, 2, 7)) + } + else { + x; // boolean +>x : Symbol(x, Decl(controlFlowCommaOperator.ts, 0, 11)) + + y; // string +>y : Symbol(y, Decl(controlFlowCommaOperator.ts, 1, 7)) + + z; // number +>z : Symbol(z, Decl(controlFlowCommaOperator.ts, 2, 7)) + } + x; // string | number | boolean +>x : Symbol(x, Decl(controlFlowCommaOperator.ts, 0, 11)) + + y; // string +>y : Symbol(y, Decl(controlFlowCommaOperator.ts, 1, 7)) + + z; // number | boolean +>z : Symbol(z, Decl(controlFlowCommaOperator.ts, 2, 7)) +} + diff --git a/tests/baselines/reference/controlFlowCommaOperator.types b/tests/baselines/reference/controlFlowCommaOperator.types new file mode 100644 index 00000000000..53014ceafa7 --- /dev/null +++ b/tests/baselines/reference/controlFlowCommaOperator.types @@ -0,0 +1,71 @@ +=== tests/cases/conformance/controlFlow/controlFlowCommaOperator.ts === +function f(x: string | number | boolean) { +>f : (x: string | number | boolean) => void +>x : string | number | boolean + + let y: string | number | boolean = false; +>y : string | number | boolean +>false : boolean + + let z: string | number | boolean = false; +>z : string | number | boolean +>false : boolean + + if (y = "", typeof x === "string") { +>y = "", typeof x === "string" : boolean +>y = "" : string +>y : string | number | boolean +>"" : string +>typeof x === "string" : boolean +>typeof x : string +>x : string | number | boolean +>"string" : string + + x; // string +>x : string + + y; // string +>y : string + + z; // boolean +>z : boolean + } + else if (z = 1, typeof x === "number") { +>z = 1, typeof x === "number" : boolean +>z = 1 : number +>z : string | number | boolean +>1 : number +>typeof x === "number" : boolean +>typeof x : string +>x : number | boolean +>"number" : string + + x; // number +>x : number + + y; // string +>y : string + + z; // number +>z : number + } + else { + x; // boolean +>x : boolean + + y; // string +>y : string + + z; // number +>z : number + } + x; // string | number | boolean +>x : string | number | boolean + + y; // string +>y : string + + z; // number | boolean +>z : boolean | number +} + diff --git a/tests/baselines/reference/controlFlowConditionalExpression.js b/tests/baselines/reference/controlFlowConditionalExpression.js new file mode 100644 index 00000000000..f39b999039b --- /dev/null +++ b/tests/baselines/reference/controlFlowConditionalExpression.js @@ -0,0 +1,13 @@ +//// [controlFlowConditionalExpression.ts] +let x: string | number | boolean; +let cond: boolean; + +cond ? x = "" : x = 3; +x; // string | number + + +//// [controlFlowConditionalExpression.js] +var x; +var cond; +cond ? x = "" : x = 3; +x; // string | number diff --git a/tests/baselines/reference/controlFlowConditionalExpression.symbols b/tests/baselines/reference/controlFlowConditionalExpression.symbols new file mode 100644 index 00000000000..b1a4074d08d --- /dev/null +++ b/tests/baselines/reference/controlFlowConditionalExpression.symbols @@ -0,0 +1,15 @@ +=== tests/cases/conformance/controlFlow/controlFlowConditionalExpression.ts === +let x: string | number | boolean; +>x : Symbol(x, Decl(controlFlowConditionalExpression.ts, 0, 3)) + +let cond: boolean; +>cond : Symbol(cond, Decl(controlFlowConditionalExpression.ts, 1, 3)) + +cond ? x = "" : x = 3; +>cond : Symbol(cond, Decl(controlFlowConditionalExpression.ts, 1, 3)) +>x : Symbol(x, Decl(controlFlowConditionalExpression.ts, 0, 3)) +>x : Symbol(x, Decl(controlFlowConditionalExpression.ts, 0, 3)) + +x; // string | number +>x : Symbol(x, Decl(controlFlowConditionalExpression.ts, 0, 3)) + diff --git a/tests/baselines/reference/controlFlowConditionalExpression.types b/tests/baselines/reference/controlFlowConditionalExpression.types new file mode 100644 index 00000000000..c6084e052b1 --- /dev/null +++ b/tests/baselines/reference/controlFlowConditionalExpression.types @@ -0,0 +1,20 @@ +=== tests/cases/conformance/controlFlow/controlFlowConditionalExpression.ts === +let x: string | number | boolean; +>x : string | number | boolean + +let cond: boolean; +>cond : boolean + +cond ? x = "" : x = 3; +>cond ? x = "" : x = 3 : string | number +>cond : boolean +>x = "" : string +>x : string | number | boolean +>"" : string +>x = 3 : number +>x : string | number | boolean +>3 : number + +x; // string | number +>x : string | number + diff --git a/tests/baselines/reference/controlFlowDestructuringDeclaration.js b/tests/baselines/reference/controlFlowDestructuringDeclaration.js new file mode 100644 index 00000000000..766fb6baeb2 --- /dev/null +++ b/tests/baselines/reference/controlFlowDestructuringDeclaration.js @@ -0,0 +1,113 @@ +//// [controlFlowDestructuringDeclaration.ts] + +function f1() { + let x: string | number = 1; + x; + let y: string | undefined = ""; + y; +} + +function f2() { + let [x]: [string | number] = [1]; + x; + let [y]: [string | undefined] = [""]; + y; + let [z = ""]: [string | undefined] = [undefined]; + z; +} + +function f3() { + let [x]: (string | number)[] = [1]; + x; + let [y]: (string | undefined)[] = [""]; + y; + let [z = ""]: (string | undefined)[] = [undefined]; + z; +} + +function f4() { + let { x }: { x: string | number } = { x: 1 }; + x; + let { y }: { y: string | undefined } = { y: "" }; + y; + let { z = "" }: { z: string | undefined } = { z: undefined }; + z; +} + +function f5() { + let { x }: { x?: string | number } = { x: 1 }; + x; + let { y }: { y?: string | undefined } = { y: "" }; + y; + let { z = "" }: { z?: string | undefined } = { z: undefined }; + z; +} + +function f6() { + let { x }: { x?: string | number } = {}; + x; + let { y }: { y?: string | undefined } = {}; + y; + let { z = "" }: { z?: string | undefined } = {}; + z; +} + +function f7() { + let o: { [x: string]: number } = { x: 1 }; + let { x }: { [x: string]: string | number } = o; + x; +} + + +//// [controlFlowDestructuringDeclaration.js] +function f1() { + var x = 1; + x; + var y = ""; + y; +} +function f2() { + var x = [1][0]; + x; + var y = [""][0]; + y; + var _a = [undefined][0], z = _a === void 0 ? "" : _a; + z; +} +function f3() { + var x = [1][0]; + x; + var y = [""][0]; + y; + var _a = [undefined][0], z = _a === void 0 ? "" : _a; + z; +} +function f4() { + var x = { x: 1 }.x; + x; + var y = { y: "" }.y; + y; + var _a = { z: undefined }.z, z = _a === void 0 ? "" : _a; + z; +} +function f5() { + var x = { x: 1 }.x; + x; + var y = { y: "" }.y; + y; + var _a = { z: undefined }.z, z = _a === void 0 ? "" : _a; + z; +} +function f6() { + var x = {}.x; + x; + var y = {}.y; + y; + var _a = {}.z, z = _a === void 0 ? "" : _a; + z; +} +function f7() { + var o = { x: 1 }; + var x = o.x; + x; +} diff --git a/tests/baselines/reference/controlFlowDestructuringDeclaration.symbols b/tests/baselines/reference/controlFlowDestructuringDeclaration.symbols new file mode 100644 index 00000000000..65f0e497942 --- /dev/null +++ b/tests/baselines/reference/controlFlowDestructuringDeclaration.symbols @@ -0,0 +1,164 @@ +=== tests/cases/conformance/controlFlow/controlFlowDestructuringDeclaration.ts === + +function f1() { +>f1 : Symbol(f1, Decl(controlFlowDestructuringDeclaration.ts, 0, 0)) + + let x: string | number = 1; +>x : Symbol(x, Decl(controlFlowDestructuringDeclaration.ts, 2, 7)) + + x; +>x : Symbol(x, Decl(controlFlowDestructuringDeclaration.ts, 2, 7)) + + let y: string | undefined = ""; +>y : Symbol(y, Decl(controlFlowDestructuringDeclaration.ts, 4, 7)) + + y; +>y : Symbol(y, Decl(controlFlowDestructuringDeclaration.ts, 4, 7)) +} + +function f2() { +>f2 : Symbol(f2, Decl(controlFlowDestructuringDeclaration.ts, 6, 1)) + + let [x]: [string | number] = [1]; +>x : Symbol(x, Decl(controlFlowDestructuringDeclaration.ts, 9, 9)) + + x; +>x : Symbol(x, Decl(controlFlowDestructuringDeclaration.ts, 9, 9)) + + let [y]: [string | undefined] = [""]; +>y : Symbol(y, Decl(controlFlowDestructuringDeclaration.ts, 11, 9)) + + y; +>y : Symbol(y, Decl(controlFlowDestructuringDeclaration.ts, 11, 9)) + + let [z = ""]: [string | undefined] = [undefined]; +>z : Symbol(z, Decl(controlFlowDestructuringDeclaration.ts, 13, 9)) +>undefined : Symbol(undefined) + + z; +>z : Symbol(z, Decl(controlFlowDestructuringDeclaration.ts, 13, 9)) +} + +function f3() { +>f3 : Symbol(f3, Decl(controlFlowDestructuringDeclaration.ts, 15, 1)) + + let [x]: (string | number)[] = [1]; +>x : Symbol(x, Decl(controlFlowDestructuringDeclaration.ts, 18, 9)) + + x; +>x : Symbol(x, Decl(controlFlowDestructuringDeclaration.ts, 18, 9)) + + let [y]: (string | undefined)[] = [""]; +>y : Symbol(y, Decl(controlFlowDestructuringDeclaration.ts, 20, 9)) + + y; +>y : Symbol(y, Decl(controlFlowDestructuringDeclaration.ts, 20, 9)) + + let [z = ""]: (string | undefined)[] = [undefined]; +>z : Symbol(z, Decl(controlFlowDestructuringDeclaration.ts, 22, 9)) +>undefined : Symbol(undefined) + + z; +>z : Symbol(z, Decl(controlFlowDestructuringDeclaration.ts, 22, 9)) +} + +function f4() { +>f4 : Symbol(f4, Decl(controlFlowDestructuringDeclaration.ts, 24, 1)) + + let { x }: { x: string | number } = { x: 1 }; +>x : Symbol(x, Decl(controlFlowDestructuringDeclaration.ts, 27, 9)) +>x : Symbol(x, Decl(controlFlowDestructuringDeclaration.ts, 27, 16)) +>x : Symbol(x, Decl(controlFlowDestructuringDeclaration.ts, 27, 41)) + + x; +>x : Symbol(x, Decl(controlFlowDestructuringDeclaration.ts, 27, 9)) + + let { y }: { y: string | undefined } = { y: "" }; +>y : Symbol(y, Decl(controlFlowDestructuringDeclaration.ts, 29, 9)) +>y : Symbol(y, Decl(controlFlowDestructuringDeclaration.ts, 29, 16)) +>y : Symbol(y, Decl(controlFlowDestructuringDeclaration.ts, 29, 44)) + + y; +>y : Symbol(y, Decl(controlFlowDestructuringDeclaration.ts, 29, 9)) + + let { z = "" }: { z: string | undefined } = { z: undefined }; +>z : Symbol(z, Decl(controlFlowDestructuringDeclaration.ts, 31, 9)) +>z : Symbol(z, Decl(controlFlowDestructuringDeclaration.ts, 31, 21)) +>z : Symbol(z, Decl(controlFlowDestructuringDeclaration.ts, 31, 49)) +>undefined : Symbol(undefined) + + z; +>z : Symbol(z, Decl(controlFlowDestructuringDeclaration.ts, 31, 9)) +} + +function f5() { +>f5 : Symbol(f5, Decl(controlFlowDestructuringDeclaration.ts, 33, 1)) + + let { x }: { x?: string | number } = { x: 1 }; +>x : Symbol(x, Decl(controlFlowDestructuringDeclaration.ts, 36, 9)) +>x : Symbol(x, Decl(controlFlowDestructuringDeclaration.ts, 36, 16)) +>x : Symbol(x, Decl(controlFlowDestructuringDeclaration.ts, 36, 42)) + + x; +>x : Symbol(x, Decl(controlFlowDestructuringDeclaration.ts, 36, 9)) + + let { y }: { y?: string | undefined } = { y: "" }; +>y : Symbol(y, Decl(controlFlowDestructuringDeclaration.ts, 38, 9)) +>y : Symbol(y, Decl(controlFlowDestructuringDeclaration.ts, 38, 16)) +>y : Symbol(y, Decl(controlFlowDestructuringDeclaration.ts, 38, 45)) + + y; +>y : Symbol(y, Decl(controlFlowDestructuringDeclaration.ts, 38, 9)) + + let { z = "" }: { z?: string | undefined } = { z: undefined }; +>z : Symbol(z, Decl(controlFlowDestructuringDeclaration.ts, 40, 9)) +>z : Symbol(z, Decl(controlFlowDestructuringDeclaration.ts, 40, 21)) +>z : Symbol(z, Decl(controlFlowDestructuringDeclaration.ts, 40, 50)) +>undefined : Symbol(undefined) + + z; +>z : Symbol(z, Decl(controlFlowDestructuringDeclaration.ts, 40, 9)) +} + +function f6() { +>f6 : Symbol(f6, Decl(controlFlowDestructuringDeclaration.ts, 42, 1)) + + let { x }: { x?: string | number } = {}; +>x : Symbol(x, Decl(controlFlowDestructuringDeclaration.ts, 45, 9)) +>x : Symbol(x, Decl(controlFlowDestructuringDeclaration.ts, 45, 16)) + + x; +>x : Symbol(x, Decl(controlFlowDestructuringDeclaration.ts, 45, 9)) + + let { y }: { y?: string | undefined } = {}; +>y : Symbol(y, Decl(controlFlowDestructuringDeclaration.ts, 47, 9)) +>y : Symbol(y, Decl(controlFlowDestructuringDeclaration.ts, 47, 16)) + + y; +>y : Symbol(y, Decl(controlFlowDestructuringDeclaration.ts, 47, 9)) + + let { z = "" }: { z?: string | undefined } = {}; +>z : Symbol(z, Decl(controlFlowDestructuringDeclaration.ts, 49, 9)) +>z : Symbol(z, Decl(controlFlowDestructuringDeclaration.ts, 49, 21)) + + z; +>z : Symbol(z, Decl(controlFlowDestructuringDeclaration.ts, 49, 9)) +} + +function f7() { +>f7 : Symbol(f7, Decl(controlFlowDestructuringDeclaration.ts, 51, 1)) + + let o: { [x: string]: number } = { x: 1 }; +>o : Symbol(o, Decl(controlFlowDestructuringDeclaration.ts, 54, 7)) +>x : Symbol(x, Decl(controlFlowDestructuringDeclaration.ts, 54, 14)) +>x : Symbol(x, Decl(controlFlowDestructuringDeclaration.ts, 54, 38)) + + let { x }: { [x: string]: string | number } = o; +>x : Symbol(x, Decl(controlFlowDestructuringDeclaration.ts, 55, 9)) +>x : Symbol(x, Decl(controlFlowDestructuringDeclaration.ts, 55, 18)) +>o : Symbol(o, Decl(controlFlowDestructuringDeclaration.ts, 54, 7)) + + x; +>x : Symbol(x, Decl(controlFlowDestructuringDeclaration.ts, 55, 9)) +} + diff --git a/tests/baselines/reference/controlFlowDestructuringDeclaration.types b/tests/baselines/reference/controlFlowDestructuringDeclaration.types new file mode 100644 index 00000000000..2e3b1f5647e --- /dev/null +++ b/tests/baselines/reference/controlFlowDestructuringDeclaration.types @@ -0,0 +1,196 @@ +=== tests/cases/conformance/controlFlow/controlFlowDestructuringDeclaration.ts === + +function f1() { +>f1 : () => void + + let x: string | number = 1; +>x : string | number +>1 : number + + x; +>x : number + + let y: string | undefined = ""; +>y : string | undefined +>"" : string + + y; +>y : string +} + +function f2() { +>f2 : () => void + + let [x]: [string | number] = [1]; +>x : string | number +>[1] : [number] +>1 : number + + x; +>x : number + + let [y]: [string | undefined] = [""]; +>y : string | undefined +>[""] : [string] +>"" : string + + y; +>y : string + + let [z = ""]: [string | undefined] = [undefined]; +>z : string +>"" : string +>[undefined] : [undefined] +>undefined : undefined + + z; +>z : string +} + +function f3() { +>f3 : () => void + + let [x]: (string | number)[] = [1]; +>x : string | number +>[1] : number[] +>1 : number + + x; +>x : number + + let [y]: (string | undefined)[] = [""]; +>y : string | undefined +>[""] : string[] +>"" : string + + y; +>y : string + + let [z = ""]: (string | undefined)[] = [undefined]; +>z : string +>"" : string +>[undefined] : undefined[] +>undefined : undefined + + z; +>z : string +} + +function f4() { +>f4 : () => void + + let { x }: { x: string | number } = { x: 1 }; +>x : string | number +>x : string | number +>{ x: 1 } : { x: number; } +>x : number +>1 : number + + x; +>x : number + + let { y }: { y: string | undefined } = { y: "" }; +>y : string | undefined +>y : string | undefined +>{ y: "" } : { y: string; } +>y : string +>"" : string + + y; +>y : string + + let { z = "" }: { z: string | undefined } = { z: undefined }; +>z : string +>"" : string +>z : string | undefined +>{ z: undefined } : { z: undefined; } +>z : undefined +>undefined : undefined + + z; +>z : string +} + +function f5() { +>f5 : () => void + + let { x }: { x?: string | number } = { x: 1 }; +>x : string | number | undefined +>x : string | number | undefined +>{ x: 1 } : { x: number; } +>x : number +>1 : number + + x; +>x : number + + let { y }: { y?: string | undefined } = { y: "" }; +>y : string | undefined +>y : string | undefined +>{ y: "" } : { y: string; } +>y : string +>"" : string + + y; +>y : string + + let { z = "" }: { z?: string | undefined } = { z: undefined }; +>z : string +>"" : string +>z : string | undefined +>{ z: undefined } : { z: undefined; } +>z : undefined +>undefined : undefined + + z; +>z : string +} + +function f6() { +>f6 : () => void + + let { x }: { x?: string | number } = {}; +>x : string | number | undefined +>x : string | number | undefined +>{} : {} + + x; +>x : string | number | undefined + + let { y }: { y?: string | undefined } = {}; +>y : string | undefined +>y : string | undefined +>{} : {} + + y; +>y : string | undefined + + let { z = "" }: { z?: string | undefined } = {}; +>z : string +>"" : string +>z : string | undefined +>{} : {} + + z; +>z : string +} + +function f7() { +>f7 : () => void + + let o: { [x: string]: number } = { x: 1 }; +>o : { [x: string]: number; } +>x : string +>{ x: 1 } : { x: number; } +>x : number +>1 : number + + let { x }: { [x: string]: string | number } = o; +>x : string | number +>x : string +>o : { [x: string]: number; } + + x; +>x : number +} + diff --git a/tests/baselines/reference/controlFlowDoWhileStatement.js b/tests/baselines/reference/controlFlowDoWhileStatement.js new file mode 100644 index 00000000000..635a5a59257 --- /dev/null +++ b/tests/baselines/reference/controlFlowDoWhileStatement.js @@ -0,0 +1,157 @@ +//// [controlFlowDoWhileStatement.ts] +let cond: boolean; +function a() { + let x: string | number; + x = ""; + do { + x; // string + } while (cond) +} +function b() { + let x: string | number; + x = ""; + do { + x; // string + x = 42; + break; + } while (cond) +} +function c() { + let x: string | number; + x = ""; + do { + x; // string + x = undefined; + if (typeof x === "string") continue; + break; + } while (cond) +} +function d() { + let x: string | number; + x = 1000; + do { + x; // number + x = ""; + } while (x = x.length) + x; // number +} +function e() { + let x: string | number; + x = ""; + do { + x = 42; + } while (cond) + x; // number +} +function f() { + let x: string | number | boolean | RegExp | Function; + x = ""; + do { + if (cond) { + x = 42; + break; + } + if (cond) { + x = true; + continue; + } + x = /a/; + } while (cond) + x; // number | boolean | RegExp +} +function g() { + let x: string | number | boolean | RegExp | Function; + x = ""; + do { + if (cond) { + x = 42; + break; + } + if (cond) { + x = true; + continue; + } + x = /a/; + } while (true) + x; // number +} + + +//// [controlFlowDoWhileStatement.js] +var cond; +function a() { + var x; + x = ""; + do { + x; // string + } while (cond); +} +function b() { + var x; + x = ""; + do { + x; // string + x = 42; + break; + } while (cond); +} +function c() { + var x; + x = ""; + do { + x; // string + x = undefined; + if (typeof x === "string") + continue; + break; + } while (cond); +} +function d() { + var x; + x = 1000; + do { + x; // number + x = ""; + } while (x = x.length); + x; // number +} +function e() { + var x; + x = ""; + do { + x = 42; + } while (cond); + x; // number +} +function f() { + var x; + x = ""; + do { + if (cond) { + x = 42; + break; + } + if (cond) { + x = true; + continue; + } + x = /a/; + } while (cond); + x; // number | boolean | RegExp +} +function g() { + var x; + x = ""; + do { + if (cond) { + x = 42; + break; + } + if (cond) { + x = true; + continue; + } + x = /a/; + } while (true); + x; // number +} diff --git a/tests/baselines/reference/controlFlowDoWhileStatement.symbols b/tests/baselines/reference/controlFlowDoWhileStatement.symbols new file mode 100644 index 00000000000..2a3f3858ec2 --- /dev/null +++ b/tests/baselines/reference/controlFlowDoWhileStatement.symbols @@ -0,0 +1,181 @@ +=== tests/cases/conformance/controlFlow/controlFlowDoWhileStatement.ts === +let cond: boolean; +>cond : Symbol(cond, Decl(controlFlowDoWhileStatement.ts, 0, 3)) + +function a() { +>a : Symbol(a, Decl(controlFlowDoWhileStatement.ts, 0, 18)) + + let x: string | number; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 2, 7)) + + x = ""; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 2, 7)) + + do { + x; // string +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 2, 7)) + + } while (cond) +>cond : Symbol(cond, Decl(controlFlowDoWhileStatement.ts, 0, 3)) +} +function b() { +>b : Symbol(b, Decl(controlFlowDoWhileStatement.ts, 7, 1)) + + let x: string | number; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 9, 7)) + + x = ""; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 9, 7)) + + do { + x; // string +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 9, 7)) + + x = 42; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 9, 7)) + + break; + } while (cond) +>cond : Symbol(cond, Decl(controlFlowDoWhileStatement.ts, 0, 3)) +} +function c() { +>c : Symbol(c, Decl(controlFlowDoWhileStatement.ts, 16, 1)) + + let x: string | number; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 18, 7)) + + x = ""; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 18, 7)) + + do { + x; // string +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 18, 7)) + + x = undefined; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 18, 7)) +>undefined : Symbol(undefined) + + if (typeof x === "string") continue; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 18, 7)) + + break; + } while (cond) +>cond : Symbol(cond, Decl(controlFlowDoWhileStatement.ts, 0, 3)) +} +function d() { +>d : Symbol(d, Decl(controlFlowDoWhileStatement.ts, 26, 1)) + + let x: string | number; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 28, 7)) + + x = 1000; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 28, 7)) + + do { + x; // number +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 28, 7)) + + x = ""; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 28, 7)) + + } while (x = x.length) +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 28, 7)) +>x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 28, 7)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) + + x; // number +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 28, 7)) +} +function e() { +>e : Symbol(e, Decl(controlFlowDoWhileStatement.ts, 35, 1)) + + let x: string | number; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 37, 7)) + + x = ""; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 37, 7)) + + do { + x = 42; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 37, 7)) + + } while (cond) +>cond : Symbol(cond, Decl(controlFlowDoWhileStatement.ts, 0, 3)) + + x; // number +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 37, 7)) +} +function f() { +>f : Symbol(f, Decl(controlFlowDoWhileStatement.ts, 43, 1)) + + let x: string | number | boolean | RegExp | Function; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 45, 7)) +>RegExp : Symbol(RegExp, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + x = ""; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 45, 7)) + + do { + if (cond) { +>cond : Symbol(cond, Decl(controlFlowDoWhileStatement.ts, 0, 3)) + + x = 42; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 45, 7)) + + break; + } + if (cond) { +>cond : Symbol(cond, Decl(controlFlowDoWhileStatement.ts, 0, 3)) + + x = true; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 45, 7)) + + continue; + } + x = /a/; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 45, 7)) + + } while (cond) +>cond : Symbol(cond, Decl(controlFlowDoWhileStatement.ts, 0, 3)) + + x; // number | boolean | RegExp +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 45, 7)) +} +function g() { +>g : Symbol(g, Decl(controlFlowDoWhileStatement.ts, 59, 1)) + + let x: string | number | boolean | RegExp | Function; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 61, 7)) +>RegExp : Symbol(RegExp, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + x = ""; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 61, 7)) + + do { + if (cond) { +>cond : Symbol(cond, Decl(controlFlowDoWhileStatement.ts, 0, 3)) + + x = 42; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 61, 7)) + + break; + } + if (cond) { +>cond : Symbol(cond, Decl(controlFlowDoWhileStatement.ts, 0, 3)) + + x = true; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 61, 7)) + + continue; + } + x = /a/; +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 61, 7)) + + } while (true) + x; // number +>x : Symbol(x, Decl(controlFlowDoWhileStatement.ts, 61, 7)) +} + diff --git a/tests/baselines/reference/controlFlowDoWhileStatement.types b/tests/baselines/reference/controlFlowDoWhileStatement.types new file mode 100644 index 00000000000..a82ae1b716e --- /dev/null +++ b/tests/baselines/reference/controlFlowDoWhileStatement.types @@ -0,0 +1,220 @@ +=== tests/cases/conformance/controlFlow/controlFlowDoWhileStatement.ts === +let cond: boolean; +>cond : boolean + +function a() { +>a : () => void + + let x: string | number; +>x : string | number + + x = ""; +>x = "" : string +>x : string | number +>"" : string + + do { + x; // string +>x : string + + } while (cond) +>cond : boolean +} +function b() { +>b : () => void + + let x: string | number; +>x : string | number + + x = ""; +>x = "" : string +>x : string | number +>"" : string + + do { + x; // string +>x : string + + x = 42; +>x = 42 : number +>x : string | number +>42 : number + + break; + } while (cond) +>cond : boolean +} +function c() { +>c : () => void + + let x: string | number; +>x : string | number + + x = ""; +>x = "" : string +>x : string | number +>"" : string + + do { + x; // string +>x : string + + x = undefined; +>x = undefined : undefined +>x : string | number +>undefined : undefined + + if (typeof x === "string") continue; +>typeof x === "string" : boolean +>typeof x : string +>x : string | number +>"string" : string + + break; + } while (cond) +>cond : boolean +} +function d() { +>d : () => void + + let x: string | number; +>x : string | number + + x = 1000; +>x = 1000 : number +>x : string | number +>1000 : number + + do { + x; // number +>x : number + + x = ""; +>x = "" : string +>x : string | number +>"" : string + + } while (x = x.length) +>x = x.length : number +>x : string | number +>x.length : number +>x : string +>length : number + + x; // number +>x : number +} +function e() { +>e : () => void + + let x: string | number; +>x : string | number + + x = ""; +>x = "" : string +>x : string | number +>"" : string + + do { + x = 42; +>x = 42 : number +>x : string | number +>42 : number + + } while (cond) +>cond : boolean + + x; // number +>x : number +} +function f() { +>f : () => void + + let x: string | number | boolean | RegExp | Function; +>x : string | number | boolean | RegExp | Function +>RegExp : RegExp +>Function : Function + + x = ""; +>x = "" : string +>x : string | number | boolean | RegExp | Function +>"" : string + + do { + if (cond) { +>cond : boolean + + x = 42; +>x = 42 : number +>x : string | number | boolean | RegExp | Function +>42 : number + + break; + } + if (cond) { +>cond : boolean + + x = true; +>x = true : boolean +>x : string | number | boolean | RegExp | Function +>true : boolean + + continue; + } + x = /a/; +>x = /a/ : RegExp +>x : string | number | boolean | RegExp | Function +>/a/ : RegExp + + } while (cond) +>cond : boolean + + x; // number | boolean | RegExp +>x : number | boolean | RegExp +} +function g() { +>g : () => void + + let x: string | number | boolean | RegExp | Function; +>x : string | number | boolean | RegExp | Function +>RegExp : RegExp +>Function : Function + + x = ""; +>x = "" : string +>x : string | number | boolean | RegExp | Function +>"" : string + + do { + if (cond) { +>cond : boolean + + x = 42; +>x = 42 : number +>x : string | number | boolean | RegExp | Function +>42 : number + + break; + } + if (cond) { +>cond : boolean + + x = true; +>x = true : boolean +>x : string | number | boolean | RegExp | Function +>true : boolean + + continue; + } + x = /a/; +>x = /a/ : RegExp +>x : string | number | boolean | RegExp | Function +>/a/ : RegExp + + } while (true) +>true : boolean + + x; // number +>x : number +} + diff --git a/tests/baselines/reference/controlFlowForInStatement.js b/tests/baselines/reference/controlFlowForInStatement.js new file mode 100644 index 00000000000..1d3f29de2ad --- /dev/null +++ b/tests/baselines/reference/controlFlowForInStatement.js @@ -0,0 +1,37 @@ +//// [controlFlowForInStatement.ts] +let x: string | number | boolean | RegExp | Function; +let obj: any; +let cond: boolean; + +x = /a/; +for (let y in obj) { + x = y; + if (cond) { + x = 42; + continue; + } + if (cond) { + x = true; + break; + } +} +x; // RegExp | string | number | boolean + + +//// [controlFlowForInStatement.js] +var x; +var obj; +var cond; +x = /a/; +for (var y in obj) { + x = y; + if (cond) { + x = 42; + continue; + } + if (cond) { + x = true; + break; + } +} +x; // RegExp | string | number | boolean diff --git a/tests/baselines/reference/controlFlowForInStatement.symbols b/tests/baselines/reference/controlFlowForInStatement.symbols new file mode 100644 index 00000000000..8d01ff50193 --- /dev/null +++ b/tests/baselines/reference/controlFlowForInStatement.symbols @@ -0,0 +1,43 @@ +=== tests/cases/conformance/controlFlow/controlFlowForInStatement.ts === +let x: string | number | boolean | RegExp | Function; +>x : Symbol(x, Decl(controlFlowForInStatement.ts, 0, 3)) +>RegExp : Symbol(RegExp, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +let obj: any; +>obj : Symbol(obj, Decl(controlFlowForInStatement.ts, 1, 3)) + +let cond: boolean; +>cond : Symbol(cond, Decl(controlFlowForInStatement.ts, 2, 3)) + +x = /a/; +>x : Symbol(x, Decl(controlFlowForInStatement.ts, 0, 3)) + +for (let y in obj) { +>y : Symbol(y, Decl(controlFlowForInStatement.ts, 5, 8)) +>obj : Symbol(obj, Decl(controlFlowForInStatement.ts, 1, 3)) + + x = y; +>x : Symbol(x, Decl(controlFlowForInStatement.ts, 0, 3)) +>y : Symbol(y, Decl(controlFlowForInStatement.ts, 5, 8)) + + if (cond) { +>cond : Symbol(cond, Decl(controlFlowForInStatement.ts, 2, 3)) + + x = 42; +>x : Symbol(x, Decl(controlFlowForInStatement.ts, 0, 3)) + + continue; + } + if (cond) { +>cond : Symbol(cond, Decl(controlFlowForInStatement.ts, 2, 3)) + + x = true; +>x : Symbol(x, Decl(controlFlowForInStatement.ts, 0, 3)) + + break; + } +} +x; // RegExp | string | number | boolean +>x : Symbol(x, Decl(controlFlowForInStatement.ts, 0, 3)) + diff --git a/tests/baselines/reference/controlFlowForInStatement.types b/tests/baselines/reference/controlFlowForInStatement.types new file mode 100644 index 00000000000..e46db37bb16 --- /dev/null +++ b/tests/baselines/reference/controlFlowForInStatement.types @@ -0,0 +1,50 @@ +=== tests/cases/conformance/controlFlow/controlFlowForInStatement.ts === +let x: string | number | boolean | RegExp | Function; +>x : string | number | boolean | RegExp | Function +>RegExp : RegExp +>Function : Function + +let obj: any; +>obj : any + +let cond: boolean; +>cond : boolean + +x = /a/; +>x = /a/ : RegExp +>x : string | number | boolean | RegExp | Function +>/a/ : RegExp + +for (let y in obj) { +>y : string +>obj : any + + x = y; +>x = y : string +>x : string | number | boolean | RegExp | Function +>y : string + + if (cond) { +>cond : boolean + + x = 42; +>x = 42 : number +>x : string | number | boolean | RegExp | Function +>42 : number + + continue; + } + if (cond) { +>cond : boolean + + x = true; +>x = true : boolean +>x : string | number | boolean | RegExp | Function +>true : boolean + + break; + } +} +x; // RegExp | string | number | boolean +>x : RegExp | number | string | boolean + diff --git a/tests/baselines/reference/controlFlowForOfStatement.js b/tests/baselines/reference/controlFlowForOfStatement.js new file mode 100644 index 00000000000..31ba7f1a346 --- /dev/null +++ b/tests/baselines/reference/controlFlowForOfStatement.js @@ -0,0 +1,24 @@ +//// [controlFlowForOfStatement.ts] +let obj: number[]; +let x: string | number | boolean | RegExp; + +function a() { + x = true; + for (x of obj) { + x = x.toExponential(); + } + x; // string | boolean +} + + +//// [controlFlowForOfStatement.js] +var obj; +var x; +function a() { + x = true; + for (var _i = 0, obj_1 = obj; _i < obj_1.length; _i++) { + x = obj_1[_i]; + x = x.toExponential(); + } + x; // string | boolean +} diff --git a/tests/baselines/reference/controlFlowForOfStatement.symbols b/tests/baselines/reference/controlFlowForOfStatement.symbols new file mode 100644 index 00000000000..0f1e754be41 --- /dev/null +++ b/tests/baselines/reference/controlFlowForOfStatement.symbols @@ -0,0 +1,28 @@ +=== tests/cases/conformance/controlFlow/controlFlowForOfStatement.ts === +let obj: number[]; +>obj : Symbol(obj, Decl(controlFlowForOfStatement.ts, 0, 3)) + +let x: string | number | boolean | RegExp; +>x : Symbol(x, Decl(controlFlowForOfStatement.ts, 1, 3)) +>RegExp : Symbol(RegExp, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +function a() { +>a : Symbol(a, Decl(controlFlowForOfStatement.ts, 1, 42)) + + x = true; +>x : Symbol(x, Decl(controlFlowForOfStatement.ts, 1, 3)) + + for (x of obj) { +>x : Symbol(x, Decl(controlFlowForOfStatement.ts, 1, 3)) +>obj : Symbol(obj, Decl(controlFlowForOfStatement.ts, 0, 3)) + + x = x.toExponential(); +>x : Symbol(x, Decl(controlFlowForOfStatement.ts, 1, 3)) +>x.toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowForOfStatement.ts, 1, 3)) +>toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --)) + } + x; // string | boolean +>x : Symbol(x, Decl(controlFlowForOfStatement.ts, 1, 3)) +} + diff --git a/tests/baselines/reference/controlFlowForOfStatement.types b/tests/baselines/reference/controlFlowForOfStatement.types new file mode 100644 index 00000000000..437576e51b6 --- /dev/null +++ b/tests/baselines/reference/controlFlowForOfStatement.types @@ -0,0 +1,32 @@ +=== tests/cases/conformance/controlFlow/controlFlowForOfStatement.ts === +let obj: number[]; +>obj : number[] + +let x: string | number | boolean | RegExp; +>x : string | number | boolean | RegExp +>RegExp : RegExp + +function a() { +>a : () => void + + x = true; +>x = true : boolean +>x : string | number | boolean | RegExp +>true : boolean + + for (x of obj) { +>x : string | number | boolean | RegExp +>obj : number[] + + x = x.toExponential(); +>x = x.toExponential() : string +>x : string | number | boolean | RegExp +>x.toExponential() : string +>x.toExponential : (fractionDigits?: number) => string +>x : number +>toExponential : (fractionDigits?: number) => string + } + x; // string | boolean +>x : boolean | string +} + diff --git a/tests/baselines/reference/controlFlowForStatement.js b/tests/baselines/reference/controlFlowForStatement.js new file mode 100644 index 00000000000..d9b1d0814fe --- /dev/null +++ b/tests/baselines/reference/controlFlowForStatement.js @@ -0,0 +1,87 @@ +//// [controlFlowForStatement.ts] +let cond: boolean; +function a() { + let x: string | number | boolean; + for (x = ""; cond; x = 5) { + x; // string | number + } +} +function b() { + let x: string | number | boolean; + for (x = 5; cond; x = x.length) { + x; // number + x = ""; + } +} +function c() { + let x: string | number | boolean; + for (x = 5; x = x.toExponential(); x = 5) { + x; // string + } +} +function d() { + let x: string | number | boolean; + for (x = ""; typeof x === "string"; x = 5) { + x; // string + } +} +function e() { + let x: string | number | boolean | RegExp; + for (x = "" || 0; typeof x !== "string"; x = "" || true) { + x; // number | boolean + } +} +function f() { + let x: string | number | boolean; + for (; typeof x !== "string";) { + x; // number | boolean + if (typeof x === "number") break; + x = undefined; + } + x; // string | number +} + + +//// [controlFlowForStatement.js] +var cond; +function a() { + var x; + for (x = ""; cond; x = 5) { + x; // string | number + } +} +function b() { + var x; + for (x = 5; cond; x = x.length) { + x; // number + x = ""; + } +} +function c() { + var x; + for (x = 5; x = x.toExponential(); x = 5) { + x; // string + } +} +function d() { + var x; + for (x = ""; typeof x === "string"; x = 5) { + x; // string + } +} +function e() { + var x; + for (x = "" || 0; typeof x !== "string"; x = "" || true) { + x; // number | boolean + } +} +function f() { + var x; + for (; typeof x !== "string";) { + x; // number | boolean + if (typeof x === "number") + break; + x = undefined; + } + x; // string | number +} diff --git a/tests/baselines/reference/controlFlowForStatement.symbols b/tests/baselines/reference/controlFlowForStatement.symbols new file mode 100644 index 00000000000..1918fe0ca33 --- /dev/null +++ b/tests/baselines/reference/controlFlowForStatement.symbols @@ -0,0 +1,112 @@ +=== tests/cases/conformance/controlFlow/controlFlowForStatement.ts === +let cond: boolean; +>cond : Symbol(cond, Decl(controlFlowForStatement.ts, 0, 3)) + +function a() { +>a : Symbol(a, Decl(controlFlowForStatement.ts, 0, 18)) + + let x: string | number | boolean; +>x : Symbol(x, Decl(controlFlowForStatement.ts, 2, 7)) + + for (x = ""; cond; x = 5) { +>x : Symbol(x, Decl(controlFlowForStatement.ts, 2, 7)) +>cond : Symbol(cond, Decl(controlFlowForStatement.ts, 0, 3)) +>x : Symbol(x, Decl(controlFlowForStatement.ts, 2, 7)) + + x; // string | number +>x : Symbol(x, Decl(controlFlowForStatement.ts, 2, 7)) + } +} +function b() { +>b : Symbol(b, Decl(controlFlowForStatement.ts, 6, 1)) + + let x: string | number | boolean; +>x : Symbol(x, Decl(controlFlowForStatement.ts, 8, 7)) + + for (x = 5; cond; x = x.length) { +>x : Symbol(x, Decl(controlFlowForStatement.ts, 8, 7)) +>cond : Symbol(cond, Decl(controlFlowForStatement.ts, 0, 3)) +>x : Symbol(x, Decl(controlFlowForStatement.ts, 8, 7)) +>x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowForStatement.ts, 8, 7)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) + + x; // number +>x : Symbol(x, Decl(controlFlowForStatement.ts, 8, 7)) + + x = ""; +>x : Symbol(x, Decl(controlFlowForStatement.ts, 8, 7)) + } +} +function c() { +>c : Symbol(c, Decl(controlFlowForStatement.ts, 13, 1)) + + let x: string | number | boolean; +>x : Symbol(x, Decl(controlFlowForStatement.ts, 15, 7)) + + for (x = 5; x = x.toExponential(); x = 5) { +>x : Symbol(x, Decl(controlFlowForStatement.ts, 15, 7)) +>x : Symbol(x, Decl(controlFlowForStatement.ts, 15, 7)) +>x.toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowForStatement.ts, 15, 7)) +>toExponential : Symbol(Number.toExponential, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowForStatement.ts, 15, 7)) + + x; // string +>x : Symbol(x, Decl(controlFlowForStatement.ts, 15, 7)) + } +} +function d() { +>d : Symbol(d, Decl(controlFlowForStatement.ts, 19, 1)) + + let x: string | number | boolean; +>x : Symbol(x, Decl(controlFlowForStatement.ts, 21, 7)) + + for (x = ""; typeof x === "string"; x = 5) { +>x : Symbol(x, Decl(controlFlowForStatement.ts, 21, 7)) +>x : Symbol(x, Decl(controlFlowForStatement.ts, 21, 7)) +>x : Symbol(x, Decl(controlFlowForStatement.ts, 21, 7)) + + x; // string +>x : Symbol(x, Decl(controlFlowForStatement.ts, 21, 7)) + } +} +function e() { +>e : Symbol(e, Decl(controlFlowForStatement.ts, 25, 1)) + + let x: string | number | boolean | RegExp; +>x : Symbol(x, Decl(controlFlowForStatement.ts, 27, 7)) +>RegExp : Symbol(RegExp, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + for (x = "" || 0; typeof x !== "string"; x = "" || true) { +>x : Symbol(x, Decl(controlFlowForStatement.ts, 27, 7)) +>x : Symbol(x, Decl(controlFlowForStatement.ts, 27, 7)) +>x : Symbol(x, Decl(controlFlowForStatement.ts, 27, 7)) + + x; // number | boolean +>x : Symbol(x, Decl(controlFlowForStatement.ts, 27, 7)) + } +} +function f() { +>f : Symbol(f, Decl(controlFlowForStatement.ts, 31, 1)) + + let x: string | number | boolean; +>x : Symbol(x, Decl(controlFlowForStatement.ts, 33, 7)) + + for (; typeof x !== "string";) { +>x : Symbol(x, Decl(controlFlowForStatement.ts, 33, 7)) + + x; // number | boolean +>x : Symbol(x, Decl(controlFlowForStatement.ts, 33, 7)) + + if (typeof x === "number") break; +>x : Symbol(x, Decl(controlFlowForStatement.ts, 33, 7)) + + x = undefined; +>x : Symbol(x, Decl(controlFlowForStatement.ts, 33, 7)) +>undefined : Symbol(undefined) + } + x; // string | number +>x : Symbol(x, Decl(controlFlowForStatement.ts, 33, 7)) +} + diff --git a/tests/baselines/reference/controlFlowForStatement.types b/tests/baselines/reference/controlFlowForStatement.types new file mode 100644 index 00000000000..cdf049b32d6 --- /dev/null +++ b/tests/baselines/reference/controlFlowForStatement.types @@ -0,0 +1,152 @@ +=== tests/cases/conformance/controlFlow/controlFlowForStatement.ts === +let cond: boolean; +>cond : boolean + +function a() { +>a : () => void + + let x: string | number | boolean; +>x : string | number | boolean + + for (x = ""; cond; x = 5) { +>x = "" : string +>x : string | number | boolean +>"" : string +>cond : boolean +>x = 5 : number +>x : string | number | boolean +>5 : number + + x; // string | number +>x : string | number + } +} +function b() { +>b : () => void + + let x: string | number | boolean; +>x : string | number | boolean + + for (x = 5; cond; x = x.length) { +>x = 5 : number +>x : string | number | boolean +>5 : number +>cond : boolean +>x = x.length : number +>x : string | number | boolean +>x.length : number +>x : string +>length : number + + x; // number +>x : number + + x = ""; +>x = "" : string +>x : string | number | boolean +>"" : string + } +} +function c() { +>c : () => void + + let x: string | number | boolean; +>x : string | number | boolean + + for (x = 5; x = x.toExponential(); x = 5) { +>x = 5 : number +>x : string | number | boolean +>5 : number +>x = x.toExponential() : string +>x : string | number | boolean +>x.toExponential() : string +>x.toExponential : (fractionDigits?: number) => string +>x : number +>toExponential : (fractionDigits?: number) => string +>x = 5 : number +>x : string | number | boolean +>5 : number + + x; // string +>x : string + } +} +function d() { +>d : () => void + + let x: string | number | boolean; +>x : string | number | boolean + + for (x = ""; typeof x === "string"; x = 5) { +>x = "" : string +>x : string | number | boolean +>"" : string +>typeof x === "string" : boolean +>typeof x : string +>x : string | number +>"string" : string +>x = 5 : number +>x : string | number | boolean +>5 : number + + x; // string +>x : string + } +} +function e() { +>e : () => void + + let x: string | number | boolean | RegExp; +>x : string | number | boolean | RegExp +>RegExp : RegExp + + for (x = "" || 0; typeof x !== "string"; x = "" || true) { +>x = "" || 0 : string | number +>x : string | number | boolean | RegExp +>"" || 0 : string | number +>"" : string +>0 : number +>typeof x !== "string" : boolean +>typeof x : string +>x : string | number | boolean +>"string" : string +>x = "" || true : string | boolean +>x : string | number | boolean | RegExp +>"" || true : string | boolean +>"" : string +>true : boolean + + x; // number | boolean +>x : number | boolean + } +} +function f() { +>f : () => void + + let x: string | number | boolean; +>x : string | number | boolean + + for (; typeof x !== "string";) { +>typeof x !== "string" : boolean +>typeof x : string +>x : string | number | boolean +>"string" : string + + x; // number | boolean +>x : number | boolean + + if (typeof x === "number") break; +>typeof x === "number" : boolean +>typeof x : string +>x : number | boolean +>"number" : string + + x = undefined; +>x = undefined : undefined +>x : string | number | boolean +>undefined : undefined + } + x; // string | number +>x : string | number +} + diff --git a/tests/baselines/reference/controlFlowIfStatement.js b/tests/baselines/reference/controlFlowIfStatement.js new file mode 100644 index 00000000000..a70c07d38dc --- /dev/null +++ b/tests/baselines/reference/controlFlowIfStatement.js @@ -0,0 +1,74 @@ +//// [controlFlowIfStatement.ts] +let x: string | number | boolean | RegExp; +let cond: boolean; + +x = /a/; +if (x /* RegExp */, (x = true)) { + x; // boolean + x = ""; +} +else { + x; // boolean + x = 42; +} +x; // string | number + +function a() { + let x: string | number; + if (cond) { + x = 42; + } + else { + x = ""; + return; + } + x; // number +} +function b() { + let x: string | number; + if (cond) { + x = 42; + throw ""; + } + else { + x = ""; + } + x; // string +} + + +//// [controlFlowIfStatement.js] +var x; +var cond; +x = /a/; +if (x /* RegExp */, (x = true)) { + x; // boolean + x = ""; +} +else { + x; // boolean + x = 42; +} +x; // string | number +function a() { + var x; + if (cond) { + x = 42; + } + else { + x = ""; + return; + } + x; // number +} +function b() { + var x; + if (cond) { + x = 42; + throw ""; + } + else { + x = ""; + } + x; // string +} diff --git a/tests/baselines/reference/controlFlowIfStatement.symbols b/tests/baselines/reference/controlFlowIfStatement.symbols new file mode 100644 index 00000000000..1d85b31c998 --- /dev/null +++ b/tests/baselines/reference/controlFlowIfStatement.symbols @@ -0,0 +1,74 @@ +=== tests/cases/conformance/controlFlow/controlFlowIfStatement.ts === +let x: string | number | boolean | RegExp; +>x : Symbol(x, Decl(controlFlowIfStatement.ts, 0, 3)) +>RegExp : Symbol(RegExp, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +let cond: boolean; +>cond : Symbol(cond, Decl(controlFlowIfStatement.ts, 1, 3)) + +x = /a/; +>x : Symbol(x, Decl(controlFlowIfStatement.ts, 0, 3)) + +if (x /* RegExp */, (x = true)) { +>x : Symbol(x, Decl(controlFlowIfStatement.ts, 0, 3)) +>x : Symbol(x, Decl(controlFlowIfStatement.ts, 0, 3)) + + x; // boolean +>x : Symbol(x, Decl(controlFlowIfStatement.ts, 0, 3)) + + x = ""; +>x : Symbol(x, Decl(controlFlowIfStatement.ts, 0, 3)) +} +else { + x; // boolean +>x : Symbol(x, Decl(controlFlowIfStatement.ts, 0, 3)) + + x = 42; +>x : Symbol(x, Decl(controlFlowIfStatement.ts, 0, 3)) +} +x; // string | number +>x : Symbol(x, Decl(controlFlowIfStatement.ts, 0, 3)) + +function a() { +>a : Symbol(a, Decl(controlFlowIfStatement.ts, 12, 2)) + + let x: string | number; +>x : Symbol(x, Decl(controlFlowIfStatement.ts, 15, 7)) + + if (cond) { +>cond : Symbol(cond, Decl(controlFlowIfStatement.ts, 1, 3)) + + x = 42; +>x : Symbol(x, Decl(controlFlowIfStatement.ts, 15, 7)) + } + else { + x = ""; +>x : Symbol(x, Decl(controlFlowIfStatement.ts, 15, 7)) + + return; + } + x; // number +>x : Symbol(x, Decl(controlFlowIfStatement.ts, 15, 7)) +} +function b() { +>b : Symbol(b, Decl(controlFlowIfStatement.ts, 24, 1)) + + let x: string | number; +>x : Symbol(x, Decl(controlFlowIfStatement.ts, 26, 7)) + + if (cond) { +>cond : Symbol(cond, Decl(controlFlowIfStatement.ts, 1, 3)) + + x = 42; +>x : Symbol(x, Decl(controlFlowIfStatement.ts, 26, 7)) + + throw ""; + } + else { + x = ""; +>x : Symbol(x, Decl(controlFlowIfStatement.ts, 26, 7)) + } + x; // string +>x : Symbol(x, Decl(controlFlowIfStatement.ts, 26, 7)) +} + diff --git a/tests/baselines/reference/controlFlowIfStatement.types b/tests/baselines/reference/controlFlowIfStatement.types new file mode 100644 index 00000000000..dc07e23275f --- /dev/null +++ b/tests/baselines/reference/controlFlowIfStatement.types @@ -0,0 +1,93 @@ +=== tests/cases/conformance/controlFlow/controlFlowIfStatement.ts === +let x: string | number | boolean | RegExp; +>x : string | number | boolean | RegExp +>RegExp : RegExp + +let cond: boolean; +>cond : boolean + +x = /a/; +>x = /a/ : RegExp +>x : string | number | boolean | RegExp +>/a/ : RegExp + +if (x /* RegExp */, (x = true)) { +>x /* RegExp */, (x = true) : boolean +>x : RegExp +>(x = true) : boolean +>x = true : boolean +>x : string | number | boolean | RegExp +>true : boolean + + x; // boolean +>x : boolean + + x = ""; +>x = "" : string +>x : string | number | boolean | RegExp +>"" : string +} +else { + x; // boolean +>x : boolean + + x = 42; +>x = 42 : number +>x : string | number | boolean | RegExp +>42 : number +} +x; // string | number +>x : string | number + +function a() { +>a : () => void + + let x: string | number; +>x : string | number + + if (cond) { +>cond : boolean + + x = 42; +>x = 42 : number +>x : string | number +>42 : number + } + else { + x = ""; +>x = "" : string +>x : string | number +>"" : string + + return; + } + x; // number +>x : number +} +function b() { +>b : () => void + + let x: string | number; +>x : string | number + + if (cond) { +>cond : boolean + + x = 42; +>x = 42 : number +>x : string | number +>42 : number + + throw ""; +>"" : string + } + else { + x = ""; +>x = "" : string +>x : string | number +>"" : string + } + x; // string +>x : string +} + diff --git a/tests/baselines/reference/controlFlowIterationErrors.errors.txt b/tests/baselines/reference/controlFlowIterationErrors.errors.txt new file mode 100644 index 00000000000..737a9e9557b --- /dev/null +++ b/tests/baselines/reference/controlFlowIterationErrors.errors.txt @@ -0,0 +1,132 @@ +tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(12,17): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'string'. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(23,17): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'string'. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(35,17): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(46,17): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(77,13): error TS7022: 'y' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. +tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(77,26): error TS2345: Argument of type 'string | number | boolean' is not assignable to parameter of type 'string | number'. + Type 'boolean' is not assignable to type 'string | number'. +tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(88,13): error TS7022: 'y' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. +tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(88,26): error TS2345: Argument of type 'string | number | boolean' is not assignable to parameter of type 'string | number'. + Type 'boolean' is not assignable to type 'string | number'. + + +==== tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts (8 errors) ==== + + let cond: boolean; + + function len(s: string) { + return s.length; + } + + function f1() { + let x: string | number | boolean; + x = ""; + while (cond) { + x = len(x); + ~ +!!! error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'string'. +!!! error TS2345: Type 'number' is not assignable to type 'string'. + x; + } + x; + } + + function f2() { + let x: string | number | boolean; + x = ""; + while (cond) { + x; + x = len(x); + ~ +!!! error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'string'. +!!! error TS2345: Type 'number' is not assignable to type 'string'. + } + x; + } + + declare function foo(x: string): number; + declare function foo(x: number): string; + + function g1() { + let x: string | number | boolean; + x = ""; + while (cond) { + x = foo(x); + ~ +!!! error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'. +!!! error TS2345: Type 'string' is not assignable to type 'number'. + x; + } + x; + } + + function g2() { + let x: string | number | boolean; + x = ""; + while (cond) { + x; + x = foo(x); + ~ +!!! error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'. +!!! error TS2345: Type 'string' is not assignable to type 'number'. + } + x; + } + + function asNumber(x: string | number): number { + return +x; + } + + function h1() { + let x: string | number | boolean; + x = "0"; + while (cond) { + x = +x + 1; + x; + } + } + + function h2() { + let x: string | number | boolean; + x = "0"; + while (cond) { + x = asNumber(x) + 1; + x; + } + } + + function h3() { + let x: string | number | boolean; + x = "0"; + while (cond) { + let y = asNumber(x); + ~ +!!! error TS7022: 'y' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. + ~ +!!! error TS2345: Argument of type 'string | number | boolean' is not assignable to parameter of type 'string | number'. +!!! error TS2345: Type 'boolean' is not assignable to type 'string | number'. + x = y + 1; + x; + } + } + + function h4() { + let x: string | number | boolean; + x = "0"; + while (cond) { + x; + let y = asNumber(x); + ~ +!!! error TS7022: 'y' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. + ~ +!!! error TS2345: Argument of type 'string | number | boolean' is not assignable to parameter of type 'string | number'. +!!! error TS2345: Type 'boolean' is not assignable to type 'string | number'. + x = y + 1; + x; + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/controlFlowIterationErrors.js b/tests/baselines/reference/controlFlowIterationErrors.js new file mode 100644 index 00000000000..eed54cc53a7 --- /dev/null +++ b/tests/baselines/reference/controlFlowIterationErrors.js @@ -0,0 +1,174 @@ +//// [controlFlowIterationErrors.ts] + +let cond: boolean; + +function len(s: string) { + return s.length; +} + +function f1() { + let x: string | number | boolean; + x = ""; + while (cond) { + x = len(x); + x; + } + x; +} + +function f2() { + let x: string | number | boolean; + x = ""; + while (cond) { + x; + x = len(x); + } + x; +} + +declare function foo(x: string): number; +declare function foo(x: number): string; + +function g1() { + let x: string | number | boolean; + x = ""; + while (cond) { + x = foo(x); + x; + } + x; +} + +function g2() { + let x: string | number | boolean; + x = ""; + while (cond) { + x; + x = foo(x); + } + x; +} + +function asNumber(x: string | number): number { + return +x; +} + +function h1() { + let x: string | number | boolean; + x = "0"; + while (cond) { + x = +x + 1; + x; + } +} + +function h2() { + let x: string | number | boolean; + x = "0"; + while (cond) { + x = asNumber(x) + 1; + x; + } +} + +function h3() { + let x: string | number | boolean; + x = "0"; + while (cond) { + let y = asNumber(x); + x = y + 1; + x; + } +} + +function h4() { + let x: string | number | boolean; + x = "0"; + while (cond) { + x; + let y = asNumber(x); + x = y + 1; + x; + } +} + + +//// [controlFlowIterationErrors.js] +var cond; +function len(s) { + return s.length; +} +function f1() { + var x; + x = ""; + while (cond) { + x = len(x); + x; + } + x; +} +function f2() { + var x; + x = ""; + while (cond) { + x; + x = len(x); + } + x; +} +function g1() { + var x; + x = ""; + while (cond) { + x = foo(x); + x; + } + x; +} +function g2() { + var x; + x = ""; + while (cond) { + x; + x = foo(x); + } + x; +} +function asNumber(x) { + return +x; +} +function h1() { + var x; + x = "0"; + while (cond) { + x = +x + 1; + x; + } +} +function h2() { + var x; + x = "0"; + while (cond) { + x = asNumber(x) + 1; + x; + } +} +function h3() { + var x; + x = "0"; + while (cond) { + var y = asNumber(x); + x = y + 1; + x; + } +} +function h4() { + var x; + x = "0"; + while (cond) { + x; + var y = asNumber(x); + x = y + 1; + x; + } +} diff --git a/tests/baselines/reference/controlFlowTruthiness.js b/tests/baselines/reference/controlFlowTruthiness.js new file mode 100644 index 00000000000..b595bcbd180 --- /dev/null +++ b/tests/baselines/reference/controlFlowTruthiness.js @@ -0,0 +1,134 @@ +//// [controlFlowTruthiness.ts] + +declare function foo(): string | undefined; + +function f1() { + let x = foo(); + if (x) { + x; // string + } + else { + x; // string | undefined + } +} + +function f2() { + let x: string | undefined; + x = foo(); + if (x) { + x; // string + } + else { + x; // string | undefined + } +} + +function f3() { + let x: string | undefined; + if (x = foo()) { + x; // string + } + else { + x; // string | undefined + } +} + +function f4() { + let x: string | undefined; + if (!(x = foo())) { + x; // string | undefined + } + else { + x; // string + } +} + +function f5() { + let x: string | undefined; + let y: string | undefined; + if (x = y = foo()) { + x; // string + y; // string | undefined + } + else { + x; // string | undefined + y; // string | undefined + } +} + +function f6() { + let x: string | undefined; + let y: string | undefined; + if (x = foo(), y = foo()) { + x; // string | undefined + y; // string + } + else { + x; // string | undefined + y; // string | undefined + } +} + + +//// [controlFlowTruthiness.js] +function f1() { + var x = foo(); + if (x) { + x; // string + } + else { + x; // string | undefined + } +} +function f2() { + var x; + x = foo(); + if (x) { + x; // string + } + else { + x; // string | undefined + } +} +function f3() { + var x; + if (x = foo()) { + x; // string + } + else { + x; // string | undefined + } +} +function f4() { + var x; + if (!(x = foo())) { + x; // string | undefined + } + else { + x; // string + } +} +function f5() { + var x; + var y; + if (x = y = foo()) { + x; // string + y; // string | undefined + } + else { + x; // string | undefined + y; // string | undefined + } +} +function f6() { + var x; + var y; + if (x = foo(), y = foo()) { + x; // string | undefined + y; // string + } + else { + x; // string | undefined + y; // string | undefined + } +} diff --git a/tests/baselines/reference/controlFlowTruthiness.symbols b/tests/baselines/reference/controlFlowTruthiness.symbols new file mode 100644 index 00000000000..37c1fb135f2 --- /dev/null +++ b/tests/baselines/reference/controlFlowTruthiness.symbols @@ -0,0 +1,143 @@ +=== tests/cases/conformance/controlFlow/controlFlowTruthiness.ts === + +declare function foo(): string | undefined; +>foo : Symbol(foo, Decl(controlFlowTruthiness.ts, 0, 0)) + +function f1() { +>f1 : Symbol(f1, Decl(controlFlowTruthiness.ts, 1, 43)) + + let x = foo(); +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 4, 7)) +>foo : Symbol(foo, Decl(controlFlowTruthiness.ts, 0, 0)) + + if (x) { +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 4, 7)) + + x; // string +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 4, 7)) + } + else { + x; // string | undefined +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 4, 7)) + } +} + +function f2() { +>f2 : Symbol(f2, Decl(controlFlowTruthiness.ts, 11, 1)) + + let x: string | undefined; +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 14, 7)) + + x = foo(); +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 14, 7)) +>foo : Symbol(foo, Decl(controlFlowTruthiness.ts, 0, 0)) + + if (x) { +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 14, 7)) + + x; // string +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 14, 7)) + } + else { + x; // string | undefined +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 14, 7)) + } +} + +function f3() { +>f3 : Symbol(f3, Decl(controlFlowTruthiness.ts, 22, 1)) + + let x: string | undefined; +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 25, 7)) + + if (x = foo()) { +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 25, 7)) +>foo : Symbol(foo, Decl(controlFlowTruthiness.ts, 0, 0)) + + x; // string +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 25, 7)) + } + else { + x; // string | undefined +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 25, 7)) + } +} + +function f4() { +>f4 : Symbol(f4, Decl(controlFlowTruthiness.ts, 32, 1)) + + let x: string | undefined; +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 35, 7)) + + if (!(x = foo())) { +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 35, 7)) +>foo : Symbol(foo, Decl(controlFlowTruthiness.ts, 0, 0)) + + x; // string | undefined +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 35, 7)) + } + else { + x; // string +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 35, 7)) + } +} + +function f5() { +>f5 : Symbol(f5, Decl(controlFlowTruthiness.ts, 42, 1)) + + let x: string | undefined; +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 45, 7)) + + let y: string | undefined; +>y : Symbol(y, Decl(controlFlowTruthiness.ts, 46, 7)) + + if (x = y = foo()) { +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 45, 7)) +>y : Symbol(y, Decl(controlFlowTruthiness.ts, 46, 7)) +>foo : Symbol(foo, Decl(controlFlowTruthiness.ts, 0, 0)) + + x; // string +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 45, 7)) + + y; // string | undefined +>y : Symbol(y, Decl(controlFlowTruthiness.ts, 46, 7)) + } + else { + x; // string | undefined +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 45, 7)) + + y; // string | undefined +>y : Symbol(y, Decl(controlFlowTruthiness.ts, 46, 7)) + } +} + +function f6() { +>f6 : Symbol(f6, Decl(controlFlowTruthiness.ts, 55, 1)) + + let x: string | undefined; +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 58, 7)) + + let y: string | undefined; +>y : Symbol(y, Decl(controlFlowTruthiness.ts, 59, 7)) + + if (x = foo(), y = foo()) { +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 58, 7)) +>foo : Symbol(foo, Decl(controlFlowTruthiness.ts, 0, 0)) +>y : Symbol(y, Decl(controlFlowTruthiness.ts, 59, 7)) +>foo : Symbol(foo, Decl(controlFlowTruthiness.ts, 0, 0)) + + x; // string | undefined +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 58, 7)) + + y; // string +>y : Symbol(y, Decl(controlFlowTruthiness.ts, 59, 7)) + } + else { + x; // string | undefined +>x : Symbol(x, Decl(controlFlowTruthiness.ts, 58, 7)) + + y; // string | undefined +>y : Symbol(y, Decl(controlFlowTruthiness.ts, 59, 7)) + } +} + diff --git a/tests/baselines/reference/controlFlowTruthiness.types b/tests/baselines/reference/controlFlowTruthiness.types new file mode 100644 index 00000000000..2d35856fe83 --- /dev/null +++ b/tests/baselines/reference/controlFlowTruthiness.types @@ -0,0 +1,160 @@ +=== tests/cases/conformance/controlFlow/controlFlowTruthiness.ts === + +declare function foo(): string | undefined; +>foo : () => string | undefined + +function f1() { +>f1 : () => void + + let x = foo(); +>x : string | undefined +>foo() : string | undefined +>foo : () => string | undefined + + if (x) { +>x : string | undefined + + x; // string +>x : string + } + else { + x; // string | undefined +>x : string | undefined + } +} + +function f2() { +>f2 : () => void + + let x: string | undefined; +>x : string | undefined + + x = foo(); +>x = foo() : string | undefined +>x : string | undefined +>foo() : string | undefined +>foo : () => string | undefined + + if (x) { +>x : string | undefined + + x; // string +>x : string + } + else { + x; // string | undefined +>x : string | undefined + } +} + +function f3() { +>f3 : () => void + + let x: string | undefined; +>x : string | undefined + + if (x = foo()) { +>x = foo() : string | undefined +>x : string | undefined +>foo() : string | undefined +>foo : () => string | undefined + + x; // string +>x : string + } + else { + x; // string | undefined +>x : string | undefined + } +} + +function f4() { +>f4 : () => void + + let x: string | undefined; +>x : string | undefined + + if (!(x = foo())) { +>!(x = foo()) : boolean +>(x = foo()) : string | undefined +>x = foo() : string | undefined +>x : string | undefined +>foo() : string | undefined +>foo : () => string | undefined + + x; // string | undefined +>x : string | undefined + } + else { + x; // string +>x : string + } +} + +function f5() { +>f5 : () => void + + let x: string | undefined; +>x : string | undefined + + let y: string | undefined; +>y : string | undefined + + if (x = y = foo()) { +>x = y = foo() : string | undefined +>x : string | undefined +>y = foo() : string | undefined +>y : string | undefined +>foo() : string | undefined +>foo : () => string | undefined + + x; // string +>x : string + + y; // string | undefined +>y : string | undefined + } + else { + x; // string | undefined +>x : string | undefined + + y; // string | undefined +>y : string | undefined + } +} + +function f6() { +>f6 : () => void + + let x: string | undefined; +>x : string | undefined + + let y: string | undefined; +>y : string | undefined + + if (x = foo(), y = foo()) { +>x = foo(), y = foo() : string | undefined +>x = foo() : string | undefined +>x : string | undefined +>foo() : string | undefined +>foo : () => string | undefined +>y = foo() : string | undefined +>y : string | undefined +>foo() : string | undefined +>foo : () => string | undefined + + x; // string | undefined +>x : string | undefined + + y; // string +>y : string + } + else { + x; // string | undefined +>x : string | undefined + + y; // string | undefined +>y : string | undefined + } +} + diff --git a/tests/baselines/reference/controlFlowWhileStatement.js b/tests/baselines/reference/controlFlowWhileStatement.js new file mode 100644 index 00000000000..d9faf9bd0ea --- /dev/null +++ b/tests/baselines/reference/controlFlowWhileStatement.js @@ -0,0 +1,216 @@ +//// [controlFlowWhileStatement.ts] +let cond: boolean; +function a() { + let x: string | number; + x = ""; + while (cond) { + x; // string + } +} +function b() { + let x: string | number; + x = ""; + while (cond) { + x; // string + x = 42; + break; + } +} +function c() { + let x: string | number; + x = ""; + while (cond) { + x; // string + x = undefined; + if (typeof x === "string") continue; + break; + } +} +function d() { + let x: string | number; + x = ""; + while (x = x.length) { + x; // number + x = ""; + } +} +function e() { + let x: string | number; + x = ""; + while (cond) { + x; // string | number + x = 42; + x; // number + } + x; // string | number +} +function f() { + let x: string | number | boolean | RegExp | Function; + x = ""; + while (cond) { + if (cond) { + x = 42; + break; + } + if (cond) { + x = true; + continue; + } + x = /a/; + } + x; // string | number | boolean | RegExp +} +function g() { + let x: string | number | boolean | RegExp | Function; + x = ""; + while (true) { + if (cond) { + x = 42; + break; + } + if (cond) { + x = true; + continue; + } + x = /a/; + } + x; // number +} +function h1() { + let x: string | number | boolean; + x = ""; + while (x > 1) { + x; // string | number + x = 1; + x; // number + } + x; // string | number +} +declare function len(s: string | number): number; +function h2() { + let x: string | number | boolean; + x = ""; + while (cond) { + x = len(x); + x; // number + } + x; // string | number +} +function h3() { + let x: string | number | boolean; + x = ""; + while (cond) { + x; // string | number + x = len(x); + } + x; // string | number +} + + +//// [controlFlowWhileStatement.js] +var cond; +function a() { + var x; + x = ""; + while (cond) { + x; // string + } +} +function b() { + var x; + x = ""; + while (cond) { + x; // string + x = 42; + break; + } +} +function c() { + var x; + x = ""; + while (cond) { + x; // string + x = undefined; + if (typeof x === "string") + continue; + break; + } +} +function d() { + var x; + x = ""; + while (x = x.length) { + x; // number + x = ""; + } +} +function e() { + var x; + x = ""; + while (cond) { + x; // string | number + x = 42; + x; // number + } + x; // string | number +} +function f() { + var x; + x = ""; + while (cond) { + if (cond) { + x = 42; + break; + } + if (cond) { + x = true; + continue; + } + x = /a/; + } + x; // string | number | boolean | RegExp +} +function g() { + var x; + x = ""; + while (true) { + if (cond) { + x = 42; + break; + } + if (cond) { + x = true; + continue; + } + x = /a/; + } + x; // number +} +function h1() { + var x; + x = ""; + while (x > 1) { + x; // string | number + x = 1; + x; // number + } + x; // string | number +} +function h2() { + var x; + x = ""; + while (cond) { + x = len(x); + x; // number + } + x; // string | number +} +function h3() { + var x; + x = ""; + while (cond) { + x; // string | number + x = len(x); + } + x; // string | number +} diff --git a/tests/baselines/reference/controlFlowWhileStatement.symbols b/tests/baselines/reference/controlFlowWhileStatement.symbols new file mode 100644 index 00000000000..3b4def93b45 --- /dev/null +++ b/tests/baselines/reference/controlFlowWhileStatement.symbols @@ -0,0 +1,257 @@ +=== tests/cases/conformance/controlFlow/controlFlowWhileStatement.ts === +let cond: boolean; +>cond : Symbol(cond, Decl(controlFlowWhileStatement.ts, 0, 3)) + +function a() { +>a : Symbol(a, Decl(controlFlowWhileStatement.ts, 0, 18)) + + let x: string | number; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 2, 7)) + + x = ""; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 2, 7)) + + while (cond) { +>cond : Symbol(cond, Decl(controlFlowWhileStatement.ts, 0, 3)) + + x; // string +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 2, 7)) + } +} +function b() { +>b : Symbol(b, Decl(controlFlowWhileStatement.ts, 7, 1)) + + let x: string | number; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 9, 7)) + + x = ""; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 9, 7)) + + while (cond) { +>cond : Symbol(cond, Decl(controlFlowWhileStatement.ts, 0, 3)) + + x; // string +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 9, 7)) + + x = 42; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 9, 7)) + + break; + } +} +function c() { +>c : Symbol(c, Decl(controlFlowWhileStatement.ts, 16, 1)) + + let x: string | number; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 18, 7)) + + x = ""; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 18, 7)) + + while (cond) { +>cond : Symbol(cond, Decl(controlFlowWhileStatement.ts, 0, 3)) + + x; // string +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 18, 7)) + + x = undefined; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 18, 7)) +>undefined : Symbol(undefined) + + if (typeof x === "string") continue; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 18, 7)) + + break; + } +} +function d() { +>d : Symbol(d, Decl(controlFlowWhileStatement.ts, 26, 1)) + + let x: string | number; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 28, 7)) + + x = ""; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 28, 7)) + + while (x = x.length) { +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 28, 7)) +>x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 28, 7)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) + + x; // number +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 28, 7)) + + x = ""; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 28, 7)) + } +} +function e() { +>e : Symbol(e, Decl(controlFlowWhileStatement.ts, 34, 1)) + + let x: string | number; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 36, 7)) + + x = ""; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 36, 7)) + + while (cond) { +>cond : Symbol(cond, Decl(controlFlowWhileStatement.ts, 0, 3)) + + x; // string | number +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 36, 7)) + + x = 42; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 36, 7)) + + x; // number +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 36, 7)) + } + x; // string | number +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 36, 7)) +} +function f() { +>f : Symbol(f, Decl(controlFlowWhileStatement.ts, 44, 1)) + + let x: string | number | boolean | RegExp | Function; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 46, 7)) +>RegExp : Symbol(RegExp, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + x = ""; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 46, 7)) + + while (cond) { +>cond : Symbol(cond, Decl(controlFlowWhileStatement.ts, 0, 3)) + + if (cond) { +>cond : Symbol(cond, Decl(controlFlowWhileStatement.ts, 0, 3)) + + x = 42; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 46, 7)) + + break; + } + if (cond) { +>cond : Symbol(cond, Decl(controlFlowWhileStatement.ts, 0, 3)) + + x = true; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 46, 7)) + + continue; + } + x = /a/; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 46, 7)) + } + x; // string | number | boolean | RegExp +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 46, 7)) +} +function g() { +>g : Symbol(g, Decl(controlFlowWhileStatement.ts, 60, 1)) + + let x: string | number | boolean | RegExp | Function; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 62, 7)) +>RegExp : Symbol(RegExp, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + x = ""; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 62, 7)) + + while (true) { + if (cond) { +>cond : Symbol(cond, Decl(controlFlowWhileStatement.ts, 0, 3)) + + x = 42; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 62, 7)) + + break; + } + if (cond) { +>cond : Symbol(cond, Decl(controlFlowWhileStatement.ts, 0, 3)) + + x = true; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 62, 7)) + + continue; + } + x = /a/; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 62, 7)) + } + x; // number +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 62, 7)) +} +function h1() { +>h1 : Symbol(h1, Decl(controlFlowWhileStatement.ts, 76, 1)) + + let x: string | number | boolean; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 78, 7)) + + x = ""; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 78, 7)) + + while (x > 1) { +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 78, 7)) + + x; // string | number +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 78, 7)) + + x = 1; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 78, 7)) + + x; // number +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 78, 7)) + } + x; // string | number +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 78, 7)) +} +declare function len(s: string | number): number; +>len : Symbol(len, Decl(controlFlowWhileStatement.ts, 86, 1)) +>s : Symbol(s, Decl(controlFlowWhileStatement.ts, 87, 21)) + +function h2() { +>h2 : Symbol(h2, Decl(controlFlowWhileStatement.ts, 87, 49)) + + let x: string | number | boolean; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 89, 7)) + + x = ""; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 89, 7)) + + while (cond) { +>cond : Symbol(cond, Decl(controlFlowWhileStatement.ts, 0, 3)) + + x = len(x); +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 89, 7)) +>len : Symbol(len, Decl(controlFlowWhileStatement.ts, 86, 1)) +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 89, 7)) + + x; // number +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 89, 7)) + } + x; // string | number +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 89, 7)) +} +function h3() { +>h3 : Symbol(h3, Decl(controlFlowWhileStatement.ts, 96, 1)) + + let x: string | number | boolean; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 98, 7)) + + x = ""; +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 98, 7)) + + while (cond) { +>cond : Symbol(cond, Decl(controlFlowWhileStatement.ts, 0, 3)) + + x; // string | number +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 98, 7)) + + x = len(x); +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 98, 7)) +>len : Symbol(len, Decl(controlFlowWhileStatement.ts, 86, 1)) +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 98, 7)) + } + x; // string | number +>x : Symbol(x, Decl(controlFlowWhileStatement.ts, 98, 7)) +} + diff --git a/tests/baselines/reference/controlFlowWhileStatement.types b/tests/baselines/reference/controlFlowWhileStatement.types new file mode 100644 index 00000000000..a17c084228b --- /dev/null +++ b/tests/baselines/reference/controlFlowWhileStatement.types @@ -0,0 +1,310 @@ +=== tests/cases/conformance/controlFlow/controlFlowWhileStatement.ts === +let cond: boolean; +>cond : boolean + +function a() { +>a : () => void + + let x: string | number; +>x : string | number + + x = ""; +>x = "" : string +>x : string | number +>"" : string + + while (cond) { +>cond : boolean + + x; // string +>x : string + } +} +function b() { +>b : () => void + + let x: string | number; +>x : string | number + + x = ""; +>x = "" : string +>x : string | number +>"" : string + + while (cond) { +>cond : boolean + + x; // string +>x : string + + x = 42; +>x = 42 : number +>x : string | number +>42 : number + + break; + } +} +function c() { +>c : () => void + + let x: string | number; +>x : string | number + + x = ""; +>x = "" : string +>x : string | number +>"" : string + + while (cond) { +>cond : boolean + + x; // string +>x : string + + x = undefined; +>x = undefined : undefined +>x : string | number +>undefined : undefined + + if (typeof x === "string") continue; +>typeof x === "string" : boolean +>typeof x : string +>x : string | number +>"string" : string + + break; + } +} +function d() { +>d : () => void + + let x: string | number; +>x : string | number + + x = ""; +>x = "" : string +>x : string | number +>"" : string + + while (x = x.length) { +>x = x.length : number +>x : string | number +>x.length : number +>x : string +>length : number + + x; // number +>x : number + + x = ""; +>x = "" : string +>x : string | number +>"" : string + } +} +function e() { +>e : () => void + + let x: string | number; +>x : string | number + + x = ""; +>x = "" : string +>x : string | number +>"" : string + + while (cond) { +>cond : boolean + + x; // string | number +>x : string | number + + x = 42; +>x = 42 : number +>x : string | number +>42 : number + + x; // number +>x : number + } + x; // string | number +>x : string | number +} +function f() { +>f : () => void + + let x: string | number | boolean | RegExp | Function; +>x : string | number | boolean | RegExp | Function +>RegExp : RegExp +>Function : Function + + x = ""; +>x = "" : string +>x : string | number | boolean | RegExp | Function +>"" : string + + while (cond) { +>cond : boolean + + if (cond) { +>cond : boolean + + x = 42; +>x = 42 : number +>x : string | number | boolean | RegExp | Function +>42 : number + + break; + } + if (cond) { +>cond : boolean + + x = true; +>x = true : boolean +>x : string | number | boolean | RegExp | Function +>true : boolean + + continue; + } + x = /a/; +>x = /a/ : RegExp +>x : string | number | boolean | RegExp | Function +>/a/ : RegExp + } + x; // string | number | boolean | RegExp +>x : string | boolean | RegExp | number +} +function g() { +>g : () => void + + let x: string | number | boolean | RegExp | Function; +>x : string | number | boolean | RegExp | Function +>RegExp : RegExp +>Function : Function + + x = ""; +>x = "" : string +>x : string | number | boolean | RegExp | Function +>"" : string + + while (true) { +>true : boolean + + if (cond) { +>cond : boolean + + x = 42; +>x = 42 : number +>x : string | number | boolean | RegExp | Function +>42 : number + + break; + } + if (cond) { +>cond : boolean + + x = true; +>x = true : boolean +>x : string | number | boolean | RegExp | Function +>true : boolean + + continue; + } + x = /a/; +>x = /a/ : RegExp +>x : string | number | boolean | RegExp | Function +>/a/ : RegExp + } + x; // number +>x : number +} +function h1() { +>h1 : () => void + + let x: string | number | boolean; +>x : string | number | boolean + + x = ""; +>x = "" : string +>x : string | number | boolean +>"" : string + + while (x > 1) { +>x > 1 : boolean +>x : string | number +>1 : number + + x; // string | number +>x : string | number + + x = 1; +>x = 1 : number +>x : string | number | boolean +>1 : number + + x; // number +>x : number + } + x; // string | number +>x : string | number +} +declare function len(s: string | number): number; +>len : (s: string | number) => number +>s : string | number + +function h2() { +>h2 : () => void + + let x: string | number | boolean; +>x : string | number | boolean + + x = ""; +>x = "" : string +>x : string | number | boolean +>"" : string + + while (cond) { +>cond : boolean + + x = len(x); +>x = len(x) : number +>x : string | number | boolean +>len(x) : number +>len : (s: string | number) => number +>x : string | number + + x; // number +>x : number + } + x; // string | number +>x : string | number +} +function h3() { +>h3 : () => void + + let x: string | number | boolean; +>x : string | number | boolean + + x = ""; +>x = "" : string +>x : string | number | boolean +>"" : string + + while (cond) { +>cond : boolean + + x; // string | number +>x : string | number + + x = len(x); +>x = len(x) : number +>x : string | number | boolean +>len(x) : number +>len : (s: string | number) => number +>x : string | number + } + x; // string | number +>x : string | number +} + diff --git a/tests/baselines/reference/declarationEmitFirstTypeArgumentGenericFunctionType.js b/tests/baselines/reference/declarationEmitFirstTypeArgumentGenericFunctionType.js new file mode 100644 index 00000000000..b2bca641a5a --- /dev/null +++ b/tests/baselines/reference/declarationEmitFirstTypeArgumentGenericFunctionType.js @@ -0,0 +1,66 @@ +//// [declarationEmitFirstTypeArgumentGenericFunctionType.ts] + +class X { +} +var prop11: X< () => Tany >; // spaces before the first type argument +var prop12: X<(() => Tany)>; // spaces before the first type argument +function f1() { // Inferred return type + return prop11; +} +function f2() { // Inferred return type + return prop12; +} +function f3(): X< () => Tany> { // written with space before type argument + return prop11; +} +function f4(): X<(() => Tany)> { // written type with parenthesis + return prop12; +} +class Y { +} +var prop2: Y() => Tany>; // No space after second type argument +var prop2: Y() => Tany>; // space after second type argument +var prop3: Y< () => Tany, () => Tany>; // space before first type argument +var prop4: Y<(() => Tany), () => Tany>; // parenthesized first type argument + + +//// [declarationEmitFirstTypeArgumentGenericFunctionType.js] +class X { +} +var prop11; // spaces before the first type argument +var prop12; // spaces before the first type argument +function f1() { + return prop11; +} +function f2() { + return prop12; +} +function f3() { + return prop11; +} +function f4() { + return prop12; +} +class Y { +} +var prop2; // No space after second type argument +var prop2; // space after second type argument +var prop3; // space before first type argument +var prop4; // parenthesized first type argument + + +//// [declarationEmitFirstTypeArgumentGenericFunctionType.d.ts] +declare class X { +} +declare var prop11: X<(() => Tany)>; +declare var prop12: X<(() => Tany)>; +declare function f1(): X<(() => Tany)>; +declare function f2(): X<(() => Tany)>; +declare function f3(): X<(() => Tany)>; +declare function f4(): X<(() => Tany)>; +declare class Y { +} +declare var prop2: Y() => Tany>; +declare var prop2: Y() => Tany>; +declare var prop3: Y<(() => Tany), () => Tany>; +declare var prop4: Y<(() => Tany), () => Tany>; diff --git a/tests/baselines/reference/declarationEmitFirstTypeArgumentGenericFunctionType.symbols b/tests/baselines/reference/declarationEmitFirstTypeArgumentGenericFunctionType.symbols new file mode 100644 index 00000000000..ebbc2b764b0 --- /dev/null +++ b/tests/baselines/reference/declarationEmitFirstTypeArgumentGenericFunctionType.symbols @@ -0,0 +1,81 @@ +=== tests/cases/compiler/declarationEmitFirstTypeArgumentGenericFunctionType.ts === + +class X { +>X : Symbol(X, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 0, 0)) +>A : Symbol(A, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 1, 8)) +} +var prop11: X< () => Tany >; // spaces before the first type argument +>prop11 : Symbol(prop11, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 3, 3)) +>X : Symbol(X, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 0, 0)) +>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 3, 16)) +>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 3, 16)) + +var prop12: X<(() => Tany)>; // spaces before the first type argument +>prop12 : Symbol(prop12, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 4, 3)) +>X : Symbol(X, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 0, 0)) +>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 4, 16)) +>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 4, 16)) + +function f1() { // Inferred return type +>f1 : Symbol(f1, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 4, 34)) + + return prop11; +>prop11 : Symbol(prop11, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 3, 3)) +} +function f2() { // Inferred return type +>f2 : Symbol(f2, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 7, 1)) + + return prop12; +>prop12 : Symbol(prop12, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 4, 3)) +} +function f3(): X< () => Tany> { // written with space before type argument +>f3 : Symbol(f3, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 10, 1)) +>X : Symbol(X, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 0, 0)) +>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 11, 19)) +>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 11, 19)) + + return prop11; +>prop11 : Symbol(prop11, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 3, 3)) +} +function f4(): X<(() => Tany)> { // written type with parenthesis +>f4 : Symbol(f4, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 13, 1)) +>X : Symbol(X, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 0, 0)) +>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 14, 19)) +>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 14, 19)) + + return prop12; +>prop12 : Symbol(prop12, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 4, 3)) +} +class Y { +>Y : Symbol(Y, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 16, 1)) +>A : Symbol(A, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 17, 8)) +>B : Symbol(B, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 17, 10)) +} +var prop2: Y() => Tany>; // No space after second type argument +>prop2 : Symbol(prop2, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 19, 3), Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 20, 3)) +>Y : Symbol(Y, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 16, 1)) +>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 19, 24)) +>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 19, 24)) + +var prop2: Y() => Tany>; // space after second type argument +>prop2 : Symbol(prop2, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 19, 3), Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 20, 3)) +>Y : Symbol(Y, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 16, 1)) +>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 20, 24)) +>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 20, 24)) + +var prop3: Y< () => Tany, () => Tany>; // space before first type argument +>prop3 : Symbol(prop3, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 21, 3)) +>Y : Symbol(Y, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 16, 1)) +>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 21, 15)) +>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 21, 15)) +>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 21, 33)) +>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 21, 33)) + +var prop4: Y<(() => Tany), () => Tany>; // parenthesized first type argument +>prop4 : Symbol(prop4, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 22, 3)) +>Y : Symbol(Y, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 16, 1)) +>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 22, 15)) +>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 22, 15)) +>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 22, 34)) +>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 22, 34)) + diff --git a/tests/baselines/reference/declarationEmitFirstTypeArgumentGenericFunctionType.types b/tests/baselines/reference/declarationEmitFirstTypeArgumentGenericFunctionType.types new file mode 100644 index 00000000000..4dd6ecba987 --- /dev/null +++ b/tests/baselines/reference/declarationEmitFirstTypeArgumentGenericFunctionType.types @@ -0,0 +1,81 @@ +=== tests/cases/compiler/declarationEmitFirstTypeArgumentGenericFunctionType.ts === + +class X { +>X : X +>A : A +} +var prop11: X< () => Tany >; // spaces before the first type argument +>prop11 : X<(() => Tany)> +>X : X +>Tany : Tany +>Tany : Tany + +var prop12: X<(() => Tany)>; // spaces before the first type argument +>prop12 : X<(() => Tany)> +>X : X +>Tany : Tany +>Tany : Tany + +function f1() { // Inferred return type +>f1 : () => X<(() => Tany)> + + return prop11; +>prop11 : X<(() => Tany)> +} +function f2() { // Inferred return type +>f2 : () => X<(() => Tany)> + + return prop12; +>prop12 : X<(() => Tany)> +} +function f3(): X< () => Tany> { // written with space before type argument +>f3 : () => X<(() => Tany)> +>X : X +>Tany : Tany +>Tany : Tany + + return prop11; +>prop11 : X<(() => Tany)> +} +function f4(): X<(() => Tany)> { // written type with parenthesis +>f4 : () => X<(() => Tany)> +>X : X +>Tany : Tany +>Tany : Tany + + return prop12; +>prop12 : X<(() => Tany)> +} +class Y { +>Y : Y +>A : A +>B : B +} +var prop2: Y() => Tany>; // No space after second type argument +>prop2 : Y() => Tany> +>Y : Y +>Tany : Tany +>Tany : Tany + +var prop2: Y() => Tany>; // space after second type argument +>prop2 : Y() => Tany> +>Y : Y +>Tany : Tany +>Tany : Tany + +var prop3: Y< () => Tany, () => Tany>; // space before first type argument +>prop3 : Y<(() => Tany), () => Tany> +>Y : Y +>Tany : Tany +>Tany : Tany +>Tany : Tany +>Tany : Tany + +var prop4: Y<(() => Tany), () => Tany>; // parenthesized first type argument +>prop4 : Y<(() => Tany), () => Tany> +>Y : Y +>Tany : Tany +>Tany : Tany +>Tany : Tany +>Tany : Tany + diff --git a/tests/baselines/reference/declarationEmitPromise.js b/tests/baselines/reference/declarationEmitPromise.js new file mode 100644 index 00000000000..a4bbdd74dde --- /dev/null +++ b/tests/baselines/reference/declarationEmitPromise.js @@ -0,0 +1,63 @@ +//// [declarationEmitPromise.ts] + +export class bluebird { + static all: Array>; +} + +export async function runSampleWorks( + a: bluebird, b?: bluebird, c?: bluebird, d?: bluebird, e?: bluebird) { + let result = await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el)); + let func = (f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T => + f.apply(this, result); + let rfunc: typeof func & {} = func as any; // <- This is the only difference + return rfunc +} + +export async function runSampleBreaks( + a: bluebird, b?: bluebird, c?: bluebird, d?: bluebird, e?: bluebird) { + let result = await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el)); + let func = (f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T => + f.apply(this, result); + let rfunc: typeof func = func as any; // <- This is the only difference + return rfunc +} + +//// [declarationEmitPromise.js] +"use strict"; +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); } } + function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments)).next()); + }); +}; +class bluebird { +} +exports.bluebird = bluebird; +function runSampleWorks(a, b, c, d, e) { + return __awaiter(this, void 0, void 0, function* () { + let result = yield bluebird.all([a, b, c, d, e].filter(el => !!el)); + let func = (f) => f.apply(this, result); + let rfunc = func; // <- This is the only difference + return rfunc; + }); +} +exports.runSampleWorks = runSampleWorks; +function runSampleBreaks(a, b, c, d, e) { + return __awaiter(this, void 0, void 0, function* () { + let result = yield bluebird.all([a, b, c, d, e].filter(el => !!el)); + let func = (f) => f.apply(this, result); + let rfunc = func; // <- This is the only difference + return rfunc; + }); +} +exports.runSampleBreaks = runSampleBreaks; + + +//// [declarationEmitPromise.d.ts] +export declare class bluebird { + static all: Array>; +} +export declare function runSampleWorks(a: bluebird, b?: bluebird, c?: bluebird, d?: bluebird, e?: bluebird): Promise<((f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T) & {}>; +export declare function runSampleBreaks(a: bluebird, b?: bluebird, c?: bluebird, d?: bluebird, e?: bluebird): Promise<((f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T)>; diff --git a/tests/baselines/reference/declarationEmitPromise.symbols b/tests/baselines/reference/declarationEmitPromise.symbols new file mode 100644 index 00000000000..894a20e03a6 --- /dev/null +++ b/tests/baselines/reference/declarationEmitPromise.symbols @@ -0,0 +1,155 @@ +=== tests/cases/compiler/declarationEmitPromise.ts === + +export class bluebird { +>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0)) +>T : Symbol(T, Decl(declarationEmitPromise.ts, 1, 22)) + + static all: Array>; +>all : Symbol(bluebird.all, Decl(declarationEmitPromise.ts, 1, 26)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0)) +} + +export async function runSampleWorks( +>runSampleWorks : Symbol(runSampleWorks, Decl(declarationEmitPromise.ts, 3, 1)) +>A : Symbol(A, Decl(declarationEmitPromise.ts, 5, 37)) +>B : Symbol(B, Decl(declarationEmitPromise.ts, 5, 39)) +>C : Symbol(C, Decl(declarationEmitPromise.ts, 5, 42)) +>D : Symbol(D, Decl(declarationEmitPromise.ts, 5, 45)) +>E : Symbol(E, Decl(declarationEmitPromise.ts, 5, 48)) + + a: bluebird, b?: bluebird, c?: bluebird, d?: bluebird, e?: bluebird) { +>a : Symbol(a, Decl(declarationEmitPromise.ts, 5, 52)) +>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0)) +>A : Symbol(A, Decl(declarationEmitPromise.ts, 5, 37)) +>b : Symbol(b, Decl(declarationEmitPromise.ts, 6, 19)) +>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0)) +>B : Symbol(B, Decl(declarationEmitPromise.ts, 5, 39)) +>c : Symbol(c, Decl(declarationEmitPromise.ts, 6, 36)) +>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0)) +>C : Symbol(C, Decl(declarationEmitPromise.ts, 5, 42)) +>d : Symbol(d, Decl(declarationEmitPromise.ts, 6, 53)) +>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0)) +>D : Symbol(D, Decl(declarationEmitPromise.ts, 5, 45)) +>e : Symbol(e, Decl(declarationEmitPromise.ts, 6, 70)) +>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0)) +>E : Symbol(E, Decl(declarationEmitPromise.ts, 5, 48)) + + let result = await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el)); +>result : Symbol(result, Decl(declarationEmitPromise.ts, 7, 7)) +>bluebird.all : Symbol(bluebird.all, Decl(declarationEmitPromise.ts, 1, 26)) +>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0)) +>all : Symbol(bluebird.all, Decl(declarationEmitPromise.ts, 1, 26)) +>[a, b, c, d, e].filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(declarationEmitPromise.ts, 5, 52)) +>b : Symbol(b, Decl(declarationEmitPromise.ts, 6, 19)) +>c : Symbol(c, Decl(declarationEmitPromise.ts, 6, 36)) +>d : Symbol(d, Decl(declarationEmitPromise.ts, 6, 53)) +>e : Symbol(e, Decl(declarationEmitPromise.ts, 6, 70)) +>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --)) +>el : Symbol(el, Decl(declarationEmitPromise.ts, 7, 68)) +>el : Symbol(el, Decl(declarationEmitPromise.ts, 7, 68)) + + let func = (f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T => +>func : Symbol(func, Decl(declarationEmitPromise.ts, 8, 7)) +>T : Symbol(T, Decl(declarationEmitPromise.ts, 8, 16)) +>f : Symbol(f, Decl(declarationEmitPromise.ts, 8, 19)) +>a : Symbol(a, Decl(declarationEmitPromise.ts, 8, 23)) +>A : Symbol(A, Decl(declarationEmitPromise.ts, 5, 37)) +>b : Symbol(b, Decl(declarationEmitPromise.ts, 8, 28)) +>B : Symbol(B, Decl(declarationEmitPromise.ts, 5, 39)) +>c : Symbol(c, Decl(declarationEmitPromise.ts, 8, 35)) +>C : Symbol(C, Decl(declarationEmitPromise.ts, 5, 42)) +>d : Symbol(d, Decl(declarationEmitPromise.ts, 8, 42)) +>D : Symbol(D, Decl(declarationEmitPromise.ts, 5, 45)) +>e : Symbol(e, Decl(declarationEmitPromise.ts, 8, 49)) +>E : Symbol(E, Decl(declarationEmitPromise.ts, 5, 48)) +>T : Symbol(T, Decl(declarationEmitPromise.ts, 8, 16)) +>T : Symbol(T, Decl(declarationEmitPromise.ts, 8, 16)) + + f.apply(this, result); +>f.apply : Symbol(Function.apply, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>f : Symbol(f, Decl(declarationEmitPromise.ts, 8, 19)) +>apply : Symbol(Function.apply, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>result : Symbol(result, Decl(declarationEmitPromise.ts, 7, 7)) + + let rfunc: typeof func & {} = func as any; // <- This is the only difference +>rfunc : Symbol(rfunc, Decl(declarationEmitPromise.ts, 10, 7)) +>func : Symbol(func, Decl(declarationEmitPromise.ts, 8, 7)) +>func : Symbol(func, Decl(declarationEmitPromise.ts, 8, 7)) + + return rfunc +>rfunc : Symbol(rfunc, Decl(declarationEmitPromise.ts, 10, 7)) +} + +export async function runSampleBreaks( +>runSampleBreaks : Symbol(runSampleBreaks, Decl(declarationEmitPromise.ts, 12, 1)) +>A : Symbol(A, Decl(declarationEmitPromise.ts, 14, 38)) +>B : Symbol(B, Decl(declarationEmitPromise.ts, 14, 40)) +>C : Symbol(C, Decl(declarationEmitPromise.ts, 14, 43)) +>D : Symbol(D, Decl(declarationEmitPromise.ts, 14, 46)) +>E : Symbol(E, Decl(declarationEmitPromise.ts, 14, 49)) + + a: bluebird, b?: bluebird, c?: bluebird, d?: bluebird, e?: bluebird) { +>a : Symbol(a, Decl(declarationEmitPromise.ts, 14, 53)) +>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0)) +>A : Symbol(A, Decl(declarationEmitPromise.ts, 14, 38)) +>b : Symbol(b, Decl(declarationEmitPromise.ts, 15, 19)) +>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0)) +>B : Symbol(B, Decl(declarationEmitPromise.ts, 14, 40)) +>c : Symbol(c, Decl(declarationEmitPromise.ts, 15, 36)) +>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0)) +>C : Symbol(C, Decl(declarationEmitPromise.ts, 14, 43)) +>d : Symbol(d, Decl(declarationEmitPromise.ts, 15, 53)) +>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0)) +>D : Symbol(D, Decl(declarationEmitPromise.ts, 14, 46)) +>e : Symbol(e, Decl(declarationEmitPromise.ts, 15, 70)) +>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0)) +>E : Symbol(E, Decl(declarationEmitPromise.ts, 14, 49)) + + let result = await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el)); +>result : Symbol(result, Decl(declarationEmitPromise.ts, 16, 7)) +>bluebird.all : Symbol(bluebird.all, Decl(declarationEmitPromise.ts, 1, 26)) +>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0)) +>all : Symbol(bluebird.all, Decl(declarationEmitPromise.ts, 1, 26)) +>[a, b, c, d, e].filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(declarationEmitPromise.ts, 14, 53)) +>b : Symbol(b, Decl(declarationEmitPromise.ts, 15, 19)) +>c : Symbol(c, Decl(declarationEmitPromise.ts, 15, 36)) +>d : Symbol(d, Decl(declarationEmitPromise.ts, 15, 53)) +>e : Symbol(e, Decl(declarationEmitPromise.ts, 15, 70)) +>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --)) +>el : Symbol(el, Decl(declarationEmitPromise.ts, 16, 68)) +>el : Symbol(el, Decl(declarationEmitPromise.ts, 16, 68)) + + let func = (f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T => +>func : Symbol(func, Decl(declarationEmitPromise.ts, 17, 7)) +>T : Symbol(T, Decl(declarationEmitPromise.ts, 17, 16)) +>f : Symbol(f, Decl(declarationEmitPromise.ts, 17, 19)) +>a : Symbol(a, Decl(declarationEmitPromise.ts, 17, 23)) +>A : Symbol(A, Decl(declarationEmitPromise.ts, 14, 38)) +>b : Symbol(b, Decl(declarationEmitPromise.ts, 17, 28)) +>B : Symbol(B, Decl(declarationEmitPromise.ts, 14, 40)) +>c : Symbol(c, Decl(declarationEmitPromise.ts, 17, 35)) +>C : Symbol(C, Decl(declarationEmitPromise.ts, 14, 43)) +>d : Symbol(d, Decl(declarationEmitPromise.ts, 17, 42)) +>D : Symbol(D, Decl(declarationEmitPromise.ts, 14, 46)) +>e : Symbol(e, Decl(declarationEmitPromise.ts, 17, 49)) +>E : Symbol(E, Decl(declarationEmitPromise.ts, 14, 49)) +>T : Symbol(T, Decl(declarationEmitPromise.ts, 17, 16)) +>T : Symbol(T, Decl(declarationEmitPromise.ts, 17, 16)) + + f.apply(this, result); +>f.apply : Symbol(Function.apply, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>f : Symbol(f, Decl(declarationEmitPromise.ts, 17, 19)) +>apply : Symbol(Function.apply, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>result : Symbol(result, Decl(declarationEmitPromise.ts, 16, 7)) + + let rfunc: typeof func = func as any; // <- This is the only difference +>rfunc : Symbol(rfunc, Decl(declarationEmitPromise.ts, 19, 7)) +>func : Symbol(func, Decl(declarationEmitPromise.ts, 17, 7)) +>func : Symbol(func, Decl(declarationEmitPromise.ts, 17, 7)) + + return rfunc +>rfunc : Symbol(rfunc, Decl(declarationEmitPromise.ts, 19, 7)) +} diff --git a/tests/baselines/reference/declarationEmitPromise.types b/tests/baselines/reference/declarationEmitPromise.types new file mode 100644 index 00000000000..0306c72762b --- /dev/null +++ b/tests/baselines/reference/declarationEmitPromise.types @@ -0,0 +1,181 @@ +=== tests/cases/compiler/declarationEmitPromise.ts === + +export class bluebird { +>bluebird : bluebird +>T : T + + static all: Array>; +>all : bluebird[] +>Array : T[] +>bluebird : bluebird +} + +export async function runSampleWorks( +>runSampleWorks : (a: bluebird, b?: bluebird, c?: bluebird, d?: bluebird, e?: bluebird) => Promise<((f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T) & {}> +>A : A +>B : B +>C : C +>D : D +>E : E + + a: bluebird, b?: bluebird, c?: bluebird, d?: bluebird, e?: bluebird) { +>a : bluebird +>bluebird : bluebird +>A : A +>b : bluebird +>bluebird : bluebird +>B : B +>c : bluebird +>bluebird : bluebird +>C : C +>d : bluebird +>bluebird : bluebird +>D : D +>e : bluebird +>bluebird : bluebird +>E : E + + let result = await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el)); +>result : any +>await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el)) : any +>(bluebird.all as any)([a, b, c, d, e].filter(el => !!el)) : any +>(bluebird.all as any) : any +>bluebird.all as any : any +>bluebird.all : bluebird[] +>bluebird : typeof bluebird +>all : bluebird[] +>[a, b, c, d, e].filter(el => !!el) : bluebird[] +>[a, b, c, d, e].filter : (callbackfn: (value: bluebird, index: number, array: bluebird[]) => any, thisArg?: any) => bluebird[] +>[a, b, c, d, e] : bluebird[] +>a : bluebird +>b : bluebird +>c : bluebird +>d : bluebird +>e : bluebird +>filter : (callbackfn: (value: bluebird, index: number, array: bluebird[]) => any, thisArg?: any) => bluebird[] +>el => !!el : (el: bluebird) => boolean +>el : bluebird +>!!el : boolean +>!el : boolean +>el : bluebird + + let func = (f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T => +>func : (f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T +>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T => f.apply(this, result) : (f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T +>T : T +>f : (a: A, b?: B, c?: C, d?: D, e?: E) => T +>a : A +>A : A +>b : B +>B : B +>c : C +>C : C +>d : D +>D : D +>e : E +>E : E +>T : T +>T : T + + f.apply(this, result); +>f.apply(this, result) : T +>f.apply : { (this: (this: T, ...argArray: any[]) => U, thisArg: T, argArray?: any): U; (this: Function, thisArg: any, argArray?: any): any; } +>f : (a: A, b?: B, c?: C, d?: D, e?: E) => T +>apply : { (this: (this: T, ...argArray: any[]) => U, thisArg: T, argArray?: any): U; (this: Function, thisArg: any, argArray?: any): any; } +>this : any +>result : any + + let rfunc: typeof func & {} = func as any; // <- This is the only difference +>rfunc : ((f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T) & {} +>func : (f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T +>func as any : any +>func : (f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T + + return rfunc +>rfunc : ((f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T) & {} +} + +export async function runSampleBreaks( +>runSampleBreaks : (a: bluebird, b?: bluebird, c?: bluebird, d?: bluebird, e?: bluebird) => Promise<((f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T)> +>A : A +>B : B +>C : C +>D : D +>E : E + + a: bluebird, b?: bluebird, c?: bluebird, d?: bluebird, e?: bluebird) { +>a : bluebird +>bluebird : bluebird +>A : A +>b : bluebird +>bluebird : bluebird +>B : B +>c : bluebird +>bluebird : bluebird +>C : C +>d : bluebird +>bluebird : bluebird +>D : D +>e : bluebird +>bluebird : bluebird +>E : E + + let result = await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el)); +>result : any +>await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el)) : any +>(bluebird.all as any)([a, b, c, d, e].filter(el => !!el)) : any +>(bluebird.all as any) : any +>bluebird.all as any : any +>bluebird.all : bluebird[] +>bluebird : typeof bluebird +>all : bluebird[] +>[a, b, c, d, e].filter(el => !!el) : bluebird[] +>[a, b, c, d, e].filter : (callbackfn: (value: bluebird, index: number, array: bluebird[]) => any, thisArg?: any) => bluebird[] +>[a, b, c, d, e] : bluebird[] +>a : bluebird +>b : bluebird +>c : bluebird +>d : bluebird +>e : bluebird +>filter : (callbackfn: (value: bluebird, index: number, array: bluebird[]) => any, thisArg?: any) => bluebird[] +>el => !!el : (el: bluebird) => boolean +>el : bluebird +>!!el : boolean +>!el : boolean +>el : bluebird + + let func = (f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T => +>func : (f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T +>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T => f.apply(this, result) : (f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T +>T : T +>f : (a: A, b?: B, c?: C, d?: D, e?: E) => T +>a : A +>A : A +>b : B +>B : B +>c : C +>C : C +>d : D +>D : D +>e : E +>E : E +>T : T +>T : T + + f.apply(this, result); +>f.apply(this, result) : T +>f.apply : { (this: (this: T, ...argArray: any[]) => U, thisArg: T, argArray?: any): U; (this: Function, thisArg: any, argArray?: any): any; } +>f : (a: A, b?: B, c?: C, d?: D, e?: E) => T +>apply : { (this: (this: T, ...argArray: any[]) => U, thisArg: T, argArray?: any): U; (this: Function, thisArg: any, argArray?: any): any; } +>this : any +>result : any + + let rfunc: typeof func = func as any; // <- This is the only difference +>rfunc : (f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T +>func : (f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T +>func as any : any +>func : (f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T + + return rfunc +>rfunc : (f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T +} diff --git a/tests/baselines/reference/equalityWithUnionTypes01.types b/tests/baselines/reference/equalityWithUnionTypes01.types index 27bf01c048b..61e38030949 100644 --- a/tests/baselines/reference/equalityWithUnionTypes01.types +++ b/tests/baselines/reference/equalityWithUnionTypes01.types @@ -35,36 +35,36 @@ var z: I1 = x; if (y === z || z === y) { >y === z || z === y : boolean >y === z : boolean ->y : number | I2 +>y : I2 >z : I1 >z === y : boolean >z : I1 ->y : number | I2 +>y : I2 } else if (y !== z || z !== y) { >y !== z || z !== y : boolean >y !== z : boolean ->y : number | I2 +>y : I2 >z : I1 >z !== y : boolean >z : I1 ->y : number | I2 +>y : I2 } else if (y == z || z == y) { >y == z || z == y : boolean >y == z : boolean ->y : number | I2 +>y : I2 >z : I1 >z == y : boolean >z : I1 ->y : number | I2 +>y : I2 } else if (y != z || z != y) { >y != z || z != y : boolean >y != z : boolean ->y : number | I2 +>y : I2 >z : I1 >z != y : boolean >z : I1 ->y : number | I2 +>y : I2 } diff --git a/tests/baselines/reference/exportSpecifierForAGlobal.errors.txt b/tests/baselines/reference/exportSpecifierForAGlobal.errors.txt index 6df9c6de1ef..559b9d5fbfe 100644 --- a/tests/baselines/reference/exportSpecifierForAGlobal.errors.txt +++ b/tests/baselines/reference/exportSpecifierForAGlobal.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/b.ts(1,9): error TS2661: Cannot re-export name that is not defined in the module. +tests/cases/compiler/b.ts(1,9): error TS2661: Cannot export 'X'. Only local declarations can be exported from a module. ==== tests/cases/compiler/a.d.ts (0 errors) ==== @@ -8,7 +8,7 @@ tests/cases/compiler/b.ts(1,9): error TS2661: Cannot re-export name that is not ==== tests/cases/compiler/b.ts (1 errors) ==== export {X}; ~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'X'. Only local declarations can be exported from a module. export function f() { var x: X; return x; diff --git a/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration1.errors.txt b/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration1.errors.txt index 7eb095b05f0..6ff2e71d26e 100644 --- a/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration1.errors.txt +++ b/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration1.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/exportSpecifierReferencingOuterDeclaration1.ts(3,14): error TS2661: Cannot re-export name that is not defined in the module. +tests/cases/compiler/exportSpecifierReferencingOuterDeclaration1.ts(3,14): error TS2661: Cannot export 'X'. Only local declarations can be exported from a module. ==== tests/cases/compiler/exportSpecifierReferencingOuterDeclaration1.ts (1 errors) ==== @@ -6,6 +6,6 @@ tests/cases/compiler/exportSpecifierReferencingOuterDeclaration1.ts(3,14): error declare module "m" { export { X }; ~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'X'. Only local declarations can be exported from a module. export function foo(): X.bar; } \ No newline at end of file diff --git a/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration2.errors.txt b/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration2.errors.txt index 00118010785..83b8366d40c 100644 --- a/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration2.errors.txt +++ b/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/exportSpecifierReferencingOuterDeclaration2_B.ts(1,10): error TS2661: Cannot re-export name that is not defined in the module. +tests/cases/compiler/exportSpecifierReferencingOuterDeclaration2_B.ts(1,10): error TS2661: Cannot export 'X'. Only local declarations can be exported from a module. ==== tests/cases/compiler/exportSpecifierReferencingOuterDeclaration2_A.ts (0 errors) ==== @@ -7,5 +7,5 @@ tests/cases/compiler/exportSpecifierReferencingOuterDeclaration2_B.ts(1,10): err ==== tests/cases/compiler/exportSpecifierReferencingOuterDeclaration2_B.ts (1 errors) ==== export { X }; ~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'X'. Only local declarations can be exported from a module. export declare function foo(): X.bar; \ No newline at end of file diff --git a/tests/baselines/reference/for-of45.types b/tests/baselines/reference/for-of45.types index b71e062eccf..7c853993b0a 100644 --- a/tests/baselines/reference/for-of45.types +++ b/tests/baselines/reference/for-of45.types @@ -13,7 +13,7 @@ var map = new Map([["", true]]); >true : boolean for ([k = "", v = false] of map) { ->[k = "", v = false] : (string | boolean)[] +>[k = "", v = false] : [string, boolean] >k = "" : string >k : string >"" : string diff --git a/tests/baselines/reference/genericMethodOverspecialization.types b/tests/baselines/reference/genericMethodOverspecialization.types index 0ad302da94e..375eefaa86c 100644 --- a/tests/baselines/reference/genericMethodOverspecialization.types +++ b/tests/baselines/reference/genericMethodOverspecialization.types @@ -53,9 +53,9 @@ var elements = names.map(function (name) { var xxx = elements.filter(function (e) { >xxx : HTMLElement[] >elements.filter(function (e) { return !e.isDisabled;}) : HTMLElement[] ->elements.filter : (callbackfn: (value: HTMLElement, index: number, array: HTMLElement[]) => boolean, thisArg?: any) => HTMLElement[] +>elements.filter : (callbackfn: (value: HTMLElement, index: number, array: HTMLElement[]) => any, thisArg?: any) => HTMLElement[] >elements : HTMLElement[] ->filter : (callbackfn: (value: HTMLElement, index: number, array: HTMLElement[]) => boolean, thisArg?: any) => HTMLElement[] +>filter : (callbackfn: (value: HTMLElement, index: number, array: HTMLElement[]) => any, thisArg?: any) => HTMLElement[] >function (e) { return !e.isDisabled;} : (e: HTMLElement) => boolean >e : HTMLElement diff --git a/tests/baselines/reference/indexersInClassType.symbols b/tests/baselines/reference/indexersInClassType.symbols index 27c64845e92..c57c7cf7522 100644 --- a/tests/baselines/reference/indexersInClassType.symbols +++ b/tests/baselines/reference/indexersInClassType.symbols @@ -36,12 +36,12 @@ var r = c.fn(); var r2 = r[1]; >r2 : Symbol(r2, Decl(indexersInClassType.ts, 13, 3)) >r : Symbol(r, Decl(indexersInClassType.ts, 12, 3)) ->1 : Symbol(C.1, Decl(indexersInClassType.ts, 2, 24)) +>1 : Symbol(C[1], Decl(indexersInClassType.ts, 2, 24)) var r3 = r.a >r3 : Symbol(r3, Decl(indexersInClassType.ts, 14, 3)) ->r.a : Symbol(C.'a', Decl(indexersInClassType.ts, 3, 12)) +>r.a : Symbol(C['a'], Decl(indexersInClassType.ts, 3, 12)) >r : Symbol(r, Decl(indexersInClassType.ts, 12, 3)) ->a : Symbol(C.'a', Decl(indexersInClassType.ts, 3, 12)) +>a : Symbol(C['a'], Decl(indexersInClassType.ts, 3, 12)) diff --git a/tests/baselines/reference/instanceOfAssignability.types b/tests/baselines/reference/instanceOfAssignability.types index 12b2d326062..5fa55aa6d88 100644 --- a/tests/baselines/reference/instanceOfAssignability.types +++ b/tests/baselines/reference/instanceOfAssignability.types @@ -133,8 +133,8 @@ function fn5(x: Derived1) { // 1.5: y: Derived1 // Want: ??? let y = x; ->y : Derived1 ->x : Derived1 +>y : {} +>x : {} } } diff --git a/tests/baselines/reference/jsFileCompilationRestParamJsDocFunction.js b/tests/baselines/reference/jsFileCompilationRestParamJsDocFunction.js new file mode 100644 index 00000000000..e1675ff7131 --- /dev/null +++ b/tests/baselines/reference/jsFileCompilationRestParamJsDocFunction.js @@ -0,0 +1,51 @@ +//// [_apply.js] + +/** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ +function apply(func, thisArg, args) { + var length = args.length; + switch (length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); +} + +export default apply; + +//// [apply.js] +define("_apply", ["require", "exports"], function (require, exports) { + "use strict"; + /** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ + function apply(func, thisArg, args) { + var length = args.length; + switch (length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); + } + exports.__esModule = true; + exports["default"] = apply; +}); diff --git a/tests/baselines/reference/jsFileCompilationRestParamJsDocFunction.symbols b/tests/baselines/reference/jsFileCompilationRestParamJsDocFunction.symbols new file mode 100644 index 00000000000..62e47c8a3c4 --- /dev/null +++ b/tests/baselines/reference/jsFileCompilationRestParamJsDocFunction.symbols @@ -0,0 +1,68 @@ +=== tests/cases/compiler/_apply.js === + +/** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ +function apply(func, thisArg, args) { +>apply : Symbol(apply, Decl(_apply.js, 0, 0)) +>func : Symbol(func, Decl(_apply.js, 11, 15)) +>thisArg : Symbol(thisArg, Decl(_apply.js, 11, 20)) +>args : Symbol(args, Decl(_apply.js, 11, 29)) + + var length = args.length; +>length : Symbol(length, Decl(_apply.js, 12, 7)) +>args.length : Symbol(Array.length, Decl(lib.d.ts, --, --)) +>args : Symbol(args, Decl(_apply.js, 11, 29)) +>length : Symbol(Array.length, Decl(lib.d.ts, --, --)) + + switch (length) { +>length : Symbol(length, Decl(_apply.js, 12, 7)) + + case 0: return func.call(thisArg); +>func.call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>func : Symbol(func, Decl(_apply.js, 11, 15)) +>call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>thisArg : Symbol(thisArg, Decl(_apply.js, 11, 20)) + + case 1: return func.call(thisArg, args[0]); +>func.call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>func : Symbol(func, Decl(_apply.js, 11, 15)) +>call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>thisArg : Symbol(thisArg, Decl(_apply.js, 11, 20)) +>args : Symbol(args, Decl(_apply.js, 11, 29)) + + case 2: return func.call(thisArg, args[0], args[1]); +>func.call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>func : Symbol(func, Decl(_apply.js, 11, 15)) +>call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>thisArg : Symbol(thisArg, Decl(_apply.js, 11, 20)) +>args : Symbol(args, Decl(_apply.js, 11, 29)) +>args : Symbol(args, Decl(_apply.js, 11, 29)) + + case 3: return func.call(thisArg, args[0], args[1], args[2]); +>func.call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>func : Symbol(func, Decl(_apply.js, 11, 15)) +>call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>thisArg : Symbol(thisArg, Decl(_apply.js, 11, 20)) +>args : Symbol(args, Decl(_apply.js, 11, 29)) +>args : Symbol(args, Decl(_apply.js, 11, 29)) +>args : Symbol(args, Decl(_apply.js, 11, 29)) + } + return func.apply(thisArg, args); +>func.apply : Symbol(Function.apply, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>func : Symbol(func, Decl(_apply.js, 11, 15)) +>apply : Symbol(Function.apply, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>thisArg : Symbol(thisArg, Decl(_apply.js, 11, 20)) +>args : Symbol(args, Decl(_apply.js, 11, 29)) +} + +export default apply; +>apply : Symbol(apply, Decl(_apply.js, 0, 0)) + diff --git a/tests/baselines/reference/jsFileCompilationRestParamJsDocFunction.types b/tests/baselines/reference/jsFileCompilationRestParamJsDocFunction.types new file mode 100644 index 00000000000..78d0fd1392b --- /dev/null +++ b/tests/baselines/reference/jsFileCompilationRestParamJsDocFunction.types @@ -0,0 +1,89 @@ +=== tests/cases/compiler/_apply.js === + +/** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ +function apply(func, thisArg, args) { +>apply : (func: Function, thisArg: any, ...args: any[]) => any +>func : Function +>thisArg : any +>args : any[] + + var length = args.length; +>length : number +>args.length : number +>args : any[] +>length : number + + switch (length) { +>length : number + + case 0: return func.call(thisArg); +>0 : number +>func.call(thisArg) : any +>func.call : { (this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; } +>func : Function +>call : { (this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; } +>thisArg : any + + case 1: return func.call(thisArg, args[0]); +>1 : number +>func.call(thisArg, args[0]) : any +>func.call : { (this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; } +>func : Function +>call : { (this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; } +>thisArg : any +>args[0] : any +>args : any[] +>0 : number + + case 2: return func.call(thisArg, args[0], args[1]); +>2 : number +>func.call(thisArg, args[0], args[1]) : any +>func.call : { (this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; } +>func : Function +>call : { (this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; } +>thisArg : any +>args[0] : any +>args : any[] +>0 : number +>args[1] : any +>args : any[] +>1 : number + + case 3: return func.call(thisArg, args[0], args[1], args[2]); +>3 : number +>func.call(thisArg, args[0], args[1], args[2]) : any +>func.call : { (this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; } +>func : Function +>call : { (this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; } +>thisArg : any +>args[0] : any +>args : any[] +>0 : number +>args[1] : any +>args : any[] +>1 : number +>args[2] : any +>args : any[] +>2 : number + } + return func.apply(thisArg, args); +>func.apply(thisArg, args) : any +>func.apply : { (this: (this: T, ...argArray: any[]) => U, thisArg: T, argArray?: any): U; (this: Function, thisArg: any, argArray?: any): any; } +>func : Function +>apply : { (this: (this: T, ...argArray: any[]) => U, thisArg: T, argArray?: any): U; (this: Function, thisArg: any, argArray?: any): any; } +>thisArg : any +>args : any[] +} + +export default apply; +>apply : (func: Function, thisArg: any, ...args: any[]) => any + diff --git a/tests/baselines/reference/moduleAugmentationGlobal4.errors.txt b/tests/baselines/reference/moduleAugmentationGlobal4.errors.txt deleted file mode 100644 index fd3444f56b1..00000000000 --- a/tests/baselines/reference/moduleAugmentationGlobal4.errors.txt +++ /dev/null @@ -1,25 +0,0 @@ -tests/cases/compiler/f1.ts(3,15): error TS2665: Module augmentation cannot introduce new names in the top level scope. -tests/cases/compiler/f2.ts(3,15): error TS2665: Module augmentation cannot introduce new names in the top level scope. - - -==== tests/cases/compiler/f1.ts (1 errors) ==== - - declare global { - interface Something {x} - ~~~~~~~~~ -!!! error TS2665: Module augmentation cannot introduce new names in the top level scope. - } - export {}; -==== tests/cases/compiler/f2.ts (1 errors) ==== - - declare global { - interface Something {y} - ~~~~~~~~~ -!!! error TS2665: Module augmentation cannot introduce new names in the top level scope. - } - export {}; -==== tests/cases/compiler/f3.ts (0 errors) ==== - import "./f1"; - import "./f2"; - - \ No newline at end of file diff --git a/tests/baselines/reference/moduleAugmentationGlobal4.symbols b/tests/baselines/reference/moduleAugmentationGlobal4.symbols new file mode 100644 index 00000000000..f9cdac3fc2e --- /dev/null +++ b/tests/baselines/reference/moduleAugmentationGlobal4.symbols @@ -0,0 +1,26 @@ +=== tests/cases/compiler/f1.ts === + +declare global { +>global : Symbol(, Decl(f1.ts, 0, 0)) + + interface Something {x} +>Something : Symbol(Something, Decl(f1.ts, 1, 16), Decl(f2.ts, 1, 16)) +>x : Symbol(Something.x, Decl(f1.ts, 2, 25)) +} +export {}; +=== tests/cases/compiler/f2.ts === + +declare global { +>global : Symbol(, Decl(f2.ts, 0, 0)) + + interface Something {y} +>Something : Symbol(Something, Decl(f1.ts, 1, 16), Decl(f2.ts, 1, 16)) +>y : Symbol(Something.y, Decl(f2.ts, 2, 25)) +} +export {}; +=== tests/cases/compiler/f3.ts === +import "./f1"; +No type information for this code.import "./f2"; +No type information for this code. +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/moduleAugmentationGlobal4.types b/tests/baselines/reference/moduleAugmentationGlobal4.types new file mode 100644 index 00000000000..e3e780d69ff --- /dev/null +++ b/tests/baselines/reference/moduleAugmentationGlobal4.types @@ -0,0 +1,26 @@ +=== tests/cases/compiler/f1.ts === + +declare global { +>global : any + + interface Something {x} +>Something : Something +>x : any +} +export {}; +=== tests/cases/compiler/f2.ts === + +declare global { +>global : any + + interface Something {y} +>Something : Something +>y : any +} +export {}; +=== tests/cases/compiler/f3.ts === +import "./f1"; +No type information for this code.import "./f2"; +No type information for this code. +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/moduleAugmentationGlobal5.errors.txt b/tests/baselines/reference/moduleAugmentationGlobal5.errors.txt deleted file mode 100644 index 4f1f9133760..00000000000 --- a/tests/baselines/reference/moduleAugmentationGlobal5.errors.txt +++ /dev/null @@ -1,28 +0,0 @@ -tests/cases/compiler/f1.d.ts(4,19): error TS2665: Module augmentation cannot introduce new names in the top level scope. -tests/cases/compiler/f2.d.ts(3,19): error TS2665: Module augmentation cannot introduce new names in the top level scope. - - -==== tests/cases/compiler/f3.ts (0 errors) ==== - /// - /// - import "A"; - import "B"; - - -==== tests/cases/compiler/f1.d.ts (1 errors) ==== - - declare module "A" { - global { - interface Something {x} - ~~~~~~~~~ -!!! error TS2665: Module augmentation cannot introduce new names in the top level scope. - } - } -==== tests/cases/compiler/f2.d.ts (1 errors) ==== - declare module "B" { - global { - interface Something {y} - ~~~~~~~~~ -!!! error TS2665: Module augmentation cannot introduce new names in the top level scope. - } - } \ No newline at end of file diff --git a/tests/baselines/reference/moduleAugmentationGlobal5.symbols b/tests/baselines/reference/moduleAugmentationGlobal5.symbols new file mode 100644 index 00000000000..27548b05ef2 --- /dev/null +++ b/tests/baselines/reference/moduleAugmentationGlobal5.symbols @@ -0,0 +1,28 @@ +=== tests/cases/compiler/f3.ts === +/// +No type information for this code./// +No type information for this code.import "A"; +No type information for this code.import "B"; +No type information for this code. +No type information for this code. +No type information for this code.=== tests/cases/compiler/f1.d.ts === + +declare module "A" { + global { +>global : Symbol(, Decl(f1.d.ts, 1, 20)) + + interface Something {x} +>Something : Symbol(Something, Decl(f1.d.ts, 2, 12), Decl(f2.d.ts, 1, 12)) +>x : Symbol(Something.x, Decl(f1.d.ts, 3, 29)) + } +} +=== tests/cases/compiler/f2.d.ts === +declare module "B" { + global { +>global : Symbol(, Decl(f2.d.ts, 0, 20)) + + interface Something {y} +>Something : Symbol(Something, Decl(f1.d.ts, 2, 12), Decl(f2.d.ts, 1, 12)) +>y : Symbol(Something.y, Decl(f2.d.ts, 2, 29)) + } +} diff --git a/tests/baselines/reference/moduleAugmentationGlobal5.types b/tests/baselines/reference/moduleAugmentationGlobal5.types new file mode 100644 index 00000000000..b2e6139eb26 --- /dev/null +++ b/tests/baselines/reference/moduleAugmentationGlobal5.types @@ -0,0 +1,28 @@ +=== tests/cases/compiler/f3.ts === +/// +No type information for this code./// +No type information for this code.import "A"; +No type information for this code.import "B"; +No type information for this code. +No type information for this code. +No type information for this code.=== tests/cases/compiler/f1.d.ts === + +declare module "A" { + global { +>global : any + + interface Something {x} +>Something : Something +>x : any + } +} +=== tests/cases/compiler/f2.d.ts === +declare module "B" { + global { +>global : any + + interface Something {y} +>Something : Something +>y : any + } +} diff --git a/tests/baselines/reference/moduleAugmentationInDependency.js b/tests/baselines/reference/moduleAugmentationInDependency.js new file mode 100644 index 00000000000..1c5995339c3 --- /dev/null +++ b/tests/baselines/reference/moduleAugmentationInDependency.js @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/moduleAugmentationInDependency.ts] //// + +//// [index.d.ts] +declare module "ext" { +} +export {}; + +//// [app.ts] +import "A" + +//// [app.js] +"use strict"; +require("A"); diff --git a/tests/baselines/reference/moduleAugmentationInDependency.symbols b/tests/baselines/reference/moduleAugmentationInDependency.symbols new file mode 100644 index 00000000000..82f1faedbf5 --- /dev/null +++ b/tests/baselines/reference/moduleAugmentationInDependency.symbols @@ -0,0 +1,8 @@ +=== /node_modules/A/index.d.ts === +declare module "ext" { +No type information for this code.} +No type information for this code.export {}; +No type information for this code. +No type information for this code.=== /src/app.ts === +import "A" +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/moduleAugmentationInDependency.types b/tests/baselines/reference/moduleAugmentationInDependency.types new file mode 100644 index 00000000000..82f1faedbf5 --- /dev/null +++ b/tests/baselines/reference/moduleAugmentationInDependency.types @@ -0,0 +1,8 @@ +=== /node_modules/A/index.d.ts === +declare module "ext" { +No type information for this code.} +No type information for this code.export {}; +No type information for this code. +No type information for this code.=== /src/app.ts === +import "A" +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/moduleAugmentationInDependency2.errors.txt b/tests/baselines/reference/moduleAugmentationInDependency2.errors.txt new file mode 100644 index 00000000000..eb53c5265b6 --- /dev/null +++ b/tests/baselines/reference/moduleAugmentationInDependency2.errors.txt @@ -0,0 +1,12 @@ +/node_modules/A/index.ts(1,16): error TS2664: Invalid module name in augmentation, module 'ext' cannot be found. + + +==== /node_modules/A/index.ts (1 errors) ==== + declare module "ext" { + ~~~~~ +!!! error TS2664: Invalid module name in augmentation, module 'ext' cannot be found. + } + export {}; + +==== /src/app.ts (0 errors) ==== + import "A" \ No newline at end of file diff --git a/tests/baselines/reference/moduleAugmentationInDependency2.js b/tests/baselines/reference/moduleAugmentationInDependency2.js new file mode 100644 index 00000000000..381f1e72d8f --- /dev/null +++ b/tests/baselines/reference/moduleAugmentationInDependency2.js @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/moduleAugmentationInDependency2.ts] //// + +//// [index.ts] +declare module "ext" { +} +export {}; + +//// [app.ts] +import "A" + +//// [index.js] +"use strict"; +//// [app.js] +"use strict"; +require("A"); diff --git a/tests/baselines/reference/negateOperatorWithEnumType.symbols b/tests/baselines/reference/negateOperatorWithEnumType.symbols index 9d97cda0466..98af23bb121 100644 --- a/tests/baselines/reference/negateOperatorWithEnumType.symbols +++ b/tests/baselines/reference/negateOperatorWithEnumType.symbols @@ -26,7 +26,7 @@ var ResultIsNumber3 = -(ENUM1.B + ENUM1[""]); >ENUM1 : Symbol(ENUM1, Decl(negateOperatorWithEnumType.ts, 2, 14)) >B : Symbol(ENUM1.B, Decl(negateOperatorWithEnumType.ts, 3, 15)) >ENUM1 : Symbol(ENUM1, Decl(negateOperatorWithEnumType.ts, 2, 14)) ->"" : Symbol(ENUM1."", Decl(negateOperatorWithEnumType.ts, 3, 18)) +>"" : Symbol(ENUM1[""], Decl(negateOperatorWithEnumType.ts, 3, 18)) // miss assignment operators -ENUM; diff --git a/tests/baselines/reference/nestedBlockScopedBindings13.errors.txt b/tests/baselines/reference/nestedBlockScopedBindings13.errors.txt new file mode 100644 index 00000000000..0421583cff9 --- /dev/null +++ b/tests/baselines/reference/nestedBlockScopedBindings13.errors.txt @@ -0,0 +1,18 @@ +tests/cases/compiler/nestedBlockScopedBindings13.ts(2,5): error TS7027: Unreachable code detected. +tests/cases/compiler/nestedBlockScopedBindings13.ts(7,5): error TS7027: Unreachable code detected. + + +==== tests/cases/compiler/nestedBlockScopedBindings13.ts (2 errors) ==== + for (; false;) { + let x; + ~~~ +!!! error TS7027: Unreachable code detected. + () => x; + } + + for (; false;) { + let y; + ~~~ +!!! error TS7027: Unreachable code detected. + y = 1; + } \ No newline at end of file diff --git a/tests/baselines/reference/nestedBlockScopedBindings13.symbols b/tests/baselines/reference/nestedBlockScopedBindings13.symbols deleted file mode 100644 index a5bc7ed7866..00000000000 --- a/tests/baselines/reference/nestedBlockScopedBindings13.symbols +++ /dev/null @@ -1,16 +0,0 @@ -=== tests/cases/compiler/nestedBlockScopedBindings13.ts === -for (; false;) { - let x; ->x : Symbol(x, Decl(nestedBlockScopedBindings13.ts, 1, 7)) - - () => x; ->x : Symbol(x, Decl(nestedBlockScopedBindings13.ts, 1, 7)) -} - -for (; false;) { - let y; ->y : Symbol(y, Decl(nestedBlockScopedBindings13.ts, 6, 7)) - - y = 1; ->y : Symbol(y, Decl(nestedBlockScopedBindings13.ts, 6, 7)) -} diff --git a/tests/baselines/reference/nestedBlockScopedBindings13.types b/tests/baselines/reference/nestedBlockScopedBindings13.types deleted file mode 100644 index 2e7bc7de77e..00000000000 --- a/tests/baselines/reference/nestedBlockScopedBindings13.types +++ /dev/null @@ -1,23 +0,0 @@ -=== tests/cases/compiler/nestedBlockScopedBindings13.ts === -for (; false;) { ->false : boolean - - let x; ->x : any - - () => x; ->() => x : () => any ->x : any -} - -for (; false;) { ->false : boolean - - let y; ->y : any - - y = 1; ->y = 1 : number ->y : any ->1 : number -} diff --git a/tests/baselines/reference/nestedBlockScopedBindings14.errors.txt b/tests/baselines/reference/nestedBlockScopedBindings14.errors.txt new file mode 100644 index 00000000000..1b5babb4c25 --- /dev/null +++ b/tests/baselines/reference/nestedBlockScopedBindings14.errors.txt @@ -0,0 +1,20 @@ +tests/cases/compiler/nestedBlockScopedBindings14.ts(3,5): error TS7027: Unreachable code detected. +tests/cases/compiler/nestedBlockScopedBindings14.ts(9,5): error TS7027: Unreachable code detected. + + +==== tests/cases/compiler/nestedBlockScopedBindings14.ts (2 errors) ==== + var x; + for (; false;) { + let x; + ~~~ +!!! error TS7027: Unreachable code detected. + () => x; + } + + var y; + for (; false;) { + let y; + ~~~ +!!! error TS7027: Unreachable code detected. + y = 1; + } \ No newline at end of file diff --git a/tests/baselines/reference/nestedBlockScopedBindings14.symbols b/tests/baselines/reference/nestedBlockScopedBindings14.symbols deleted file mode 100644 index 4a13b296e88..00000000000 --- a/tests/baselines/reference/nestedBlockScopedBindings14.symbols +++ /dev/null @@ -1,22 +0,0 @@ -=== tests/cases/compiler/nestedBlockScopedBindings14.ts === -var x; ->x : Symbol(x, Decl(nestedBlockScopedBindings14.ts, 0, 3)) - -for (; false;) { - let x; ->x : Symbol(x, Decl(nestedBlockScopedBindings14.ts, 2, 7)) - - () => x; ->x : Symbol(x, Decl(nestedBlockScopedBindings14.ts, 2, 7)) -} - -var y; ->y : Symbol(y, Decl(nestedBlockScopedBindings14.ts, 6, 3)) - -for (; false;) { - let y; ->y : Symbol(y, Decl(nestedBlockScopedBindings14.ts, 8, 7)) - - y = 1; ->y : Symbol(y, Decl(nestedBlockScopedBindings14.ts, 8, 7)) -} diff --git a/tests/baselines/reference/nestedBlockScopedBindings14.types b/tests/baselines/reference/nestedBlockScopedBindings14.types deleted file mode 100644 index 966eaaaac7a..00000000000 --- a/tests/baselines/reference/nestedBlockScopedBindings14.types +++ /dev/null @@ -1,29 +0,0 @@ -=== tests/cases/compiler/nestedBlockScopedBindings14.ts === -var x; ->x : any - -for (; false;) { ->false : boolean - - let x; ->x : any - - () => x; ->() => x : () => any ->x : any -} - -var y; ->y : any - -for (; false;) { ->false : boolean - - let y; ->y : any - - y = 1; ->y = 1 : number ->y : any ->1 : number -} diff --git a/tests/baselines/reference/nestedBlockScopedBindings15.errors.txt b/tests/baselines/reference/nestedBlockScopedBindings15.errors.txt new file mode 100644 index 00000000000..b60a502b528 --- /dev/null +++ b/tests/baselines/reference/nestedBlockScopedBindings15.errors.txt @@ -0,0 +1,46 @@ +tests/cases/compiler/nestedBlockScopedBindings15.ts(3,9): error TS7027: Unreachable code detected. +tests/cases/compiler/nestedBlockScopedBindings15.ts(10,9): error TS7027: Unreachable code detected. +tests/cases/compiler/nestedBlockScopedBindings15.ts(16,5): error TS7027: Unreachable code detected. +tests/cases/compiler/nestedBlockScopedBindings15.ts(25,5): error TS7027: Unreachable code detected. + + +==== tests/cases/compiler/nestedBlockScopedBindings15.ts (4 errors) ==== + for (; false;) { + { + let x; + ~~~ +!!! error TS7027: Unreachable code detected. + () => x; + } + } + + for (; false;) { + { + let y; + ~~~ +!!! error TS7027: Unreachable code detected. + y = 1; + } + } + + for (; false;) { + switch (1){ + ~~~~~~ +!!! error TS7027: Unreachable code detected. + case 1: + let z0; + () => z0; + break; + } + } + + for (; false;) { + switch (1){ + ~~~~~~ +!!! error TS7027: Unreachable code detected. + case 1: + let z; + z = 1; + break; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/nestedBlockScopedBindings15.symbols b/tests/baselines/reference/nestedBlockScopedBindings15.symbols deleted file mode 100644 index 26ef28f6050..00000000000 --- a/tests/baselines/reference/nestedBlockScopedBindings15.symbols +++ /dev/null @@ -1,46 +0,0 @@ -=== tests/cases/compiler/nestedBlockScopedBindings15.ts === -for (; false;) { - { - let x; ->x : Symbol(x, Decl(nestedBlockScopedBindings15.ts, 2, 11)) - - () => x; ->x : Symbol(x, Decl(nestedBlockScopedBindings15.ts, 2, 11)) - } -} - -for (; false;) { - { - let y; ->y : Symbol(y, Decl(nestedBlockScopedBindings15.ts, 9, 11)) - - y = 1; ->y : Symbol(y, Decl(nestedBlockScopedBindings15.ts, 9, 11)) - } -} - -for (; false;) { - switch (1){ - case 1: - let z0; ->z0 : Symbol(z0, Decl(nestedBlockScopedBindings15.ts, 17, 15)) - - () => z0; ->z0 : Symbol(z0, Decl(nestedBlockScopedBindings15.ts, 17, 15)) - - break; - } -} - -for (; false;) { - switch (1){ - case 1: - let z; ->z : Symbol(z, Decl(nestedBlockScopedBindings15.ts, 26, 15)) - - z = 1; ->z : Symbol(z, Decl(nestedBlockScopedBindings15.ts, 26, 15)) - - break; - } -} diff --git a/tests/baselines/reference/nestedBlockScopedBindings15.types b/tests/baselines/reference/nestedBlockScopedBindings15.types deleted file mode 100644 index 5173c0c5600..00000000000 --- a/tests/baselines/reference/nestedBlockScopedBindings15.types +++ /dev/null @@ -1,66 +0,0 @@ -=== tests/cases/compiler/nestedBlockScopedBindings15.ts === -for (; false;) { ->false : boolean - { - let x; ->x : any - - () => x; ->() => x : () => any ->x : any - } -} - -for (; false;) { ->false : boolean - { - let y; ->y : any - - y = 1; ->y = 1 : number ->y : any ->1 : number - } -} - -for (; false;) { ->false : boolean - - switch (1){ ->1 : number - - case 1: ->1 : number - - let z0; ->z0 : any - - () => z0; ->() => z0 : () => any ->z0 : any - - break; - } -} - -for (; false;) { ->false : boolean - - switch (1){ ->1 : number - - case 1: ->1 : number - - let z; ->z : any - - z = 1; ->z = 1 : number ->z : any ->1 : number - - break; - } -} diff --git a/tests/baselines/reference/nestedBlockScopedBindings16.errors.txt b/tests/baselines/reference/nestedBlockScopedBindings16.errors.txt new file mode 100644 index 00000000000..806f58231a0 --- /dev/null +++ b/tests/baselines/reference/nestedBlockScopedBindings16.errors.txt @@ -0,0 +1,50 @@ +tests/cases/compiler/nestedBlockScopedBindings16.ts(4,9): error TS7027: Unreachable code detected. +tests/cases/compiler/nestedBlockScopedBindings16.ts(12,9): error TS7027: Unreachable code detected. +tests/cases/compiler/nestedBlockScopedBindings16.ts(19,5): error TS7027: Unreachable code detected. +tests/cases/compiler/nestedBlockScopedBindings16.ts(29,5): error TS7027: Unreachable code detected. + + +==== tests/cases/compiler/nestedBlockScopedBindings16.ts (4 errors) ==== + var x; + for (; false;) { + { + let x; + ~~~ +!!! error TS7027: Unreachable code detected. + () => x; + } + } + + var y; + for (; false;) { + { + let y; + ~~~ +!!! error TS7027: Unreachable code detected. + y = 1; + } + } + + var z0; + for (; false;) { + switch (1){ + ~~~~~~ +!!! error TS7027: Unreachable code detected. + case 1: + let z0; + () => z0; + break; + } + } + + var z; + for (; false;) { + switch (1){ + ~~~~~~ +!!! error TS7027: Unreachable code detected. + case 1: + let z; + z = 1; + break; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/nestedBlockScopedBindings16.symbols b/tests/baselines/reference/nestedBlockScopedBindings16.symbols deleted file mode 100644 index cbe8114cf14..00000000000 --- a/tests/baselines/reference/nestedBlockScopedBindings16.symbols +++ /dev/null @@ -1,58 +0,0 @@ -=== tests/cases/compiler/nestedBlockScopedBindings16.ts === -var x; ->x : Symbol(x, Decl(nestedBlockScopedBindings16.ts, 0, 3)) - -for (; false;) { - { - let x; ->x : Symbol(x, Decl(nestedBlockScopedBindings16.ts, 3, 11)) - - () => x; ->x : Symbol(x, Decl(nestedBlockScopedBindings16.ts, 3, 11)) - } -} - -var y; ->y : Symbol(y, Decl(nestedBlockScopedBindings16.ts, 8, 3)) - -for (; false;) { - { - let y; ->y : Symbol(y, Decl(nestedBlockScopedBindings16.ts, 11, 11)) - - y = 1; ->y : Symbol(y, Decl(nestedBlockScopedBindings16.ts, 11, 11)) - } -} - -var z0; ->z0 : Symbol(z0, Decl(nestedBlockScopedBindings16.ts, 16, 3)) - -for (; false;) { - switch (1){ - case 1: - let z0; ->z0 : Symbol(z0, Decl(nestedBlockScopedBindings16.ts, 20, 15)) - - () => z0; ->z0 : Symbol(z0, Decl(nestedBlockScopedBindings16.ts, 20, 15)) - - break; - } -} - -var z; ->z : Symbol(z, Decl(nestedBlockScopedBindings16.ts, 26, 3)) - -for (; false;) { - switch (1){ - case 1: - let z; ->z : Symbol(z, Decl(nestedBlockScopedBindings16.ts, 30, 15)) - - z = 1; ->z : Symbol(z, Decl(nestedBlockScopedBindings16.ts, 30, 15)) - - break; - } -} diff --git a/tests/baselines/reference/nestedBlockScopedBindings16.types b/tests/baselines/reference/nestedBlockScopedBindings16.types deleted file mode 100644 index 22698402a62..00000000000 --- a/tests/baselines/reference/nestedBlockScopedBindings16.types +++ /dev/null @@ -1,78 +0,0 @@ -=== tests/cases/compiler/nestedBlockScopedBindings16.ts === -var x; ->x : any - -for (; false;) { ->false : boolean - { - let x; ->x : any - - () => x; ->() => x : () => any ->x : any - } -} - -var y; ->y : any - -for (; false;) { ->false : boolean - { - let y; ->y : any - - y = 1; ->y = 1 : number ->y : any ->1 : number - } -} - -var z0; ->z0 : any - -for (; false;) { ->false : boolean - - switch (1){ ->1 : number - - case 1: ->1 : number - - let z0; ->z0 : any - - () => z0; ->() => z0 : () => any ->z0 : any - - break; - } -} - -var z; ->z : any - -for (; false;) { ->false : boolean - - switch (1){ ->1 : number - - case 1: ->1 : number - - let z; ->z : any - - z = 1; ->z = 1 : number ->z : any ->1 : number - - break; - } -} diff --git a/tests/baselines/reference/nestedBlockScopedBindings5.errors.txt b/tests/baselines/reference/nestedBlockScopedBindings5.errors.txt new file mode 100644 index 00000000000..a40f6a29aea --- /dev/null +++ b/tests/baselines/reference/nestedBlockScopedBindings5.errors.txt @@ -0,0 +1,92 @@ +tests/cases/compiler/nestedBlockScopedBindings5.ts(37,9): error TS7027: Unreachable code detected. +tests/cases/compiler/nestedBlockScopedBindings5.ts(54,9): error TS7027: Unreachable code detected. +tests/cases/compiler/nestedBlockScopedBindings5.ts(71,9): error TS7027: Unreachable code detected. + + +==== tests/cases/compiler/nestedBlockScopedBindings5.ts (3 errors) ==== + function a0() { + for (let x in []) { + x = x + 1; + } + for (let x;;) { + x = x + 2; + } + } + + function a1() { + for (let x in []) { + x = x + 1; + () => x; + } + for (let x;;) { + x = x + 2; + } + } + + function a2() { + for (let x in []) { + x = x + 1; + } + for (let x;;) { + x = x + 2; + () => x; + } + } + + + function a3() { + for (let x in []) { + x = x + 1; + () => x; + } + for (let x;false;) { + x = x + 2; + ~ +!!! error TS7027: Unreachable code detected. + () => x; + } + switch (1) { + case 1: + let x; + () => x; + break; + } + + } + + function a4() { + for (let x in []) { + x = x + 1; + } + for (let x;false;) { + x = x + 2; + ~ +!!! error TS7027: Unreachable code detected. + } + switch (1) { + case 1: + let x; + () => x; + break; + } + + } + + function a5() { + let y; + for (let x in []) { + x = x + 1; + } + for (let x;false;) { + x = x + 2; + ~ +!!! error TS7027: Unreachable code detected. + () => x; + } + switch (1) { + case 1: + let x; + break; + } + + } \ No newline at end of file diff --git a/tests/baselines/reference/nestedBlockScopedBindings5.symbols b/tests/baselines/reference/nestedBlockScopedBindings5.symbols deleted file mode 100644 index 202a1d2e83f..00000000000 --- a/tests/baselines/reference/nestedBlockScopedBindings5.symbols +++ /dev/null @@ -1,163 +0,0 @@ -=== tests/cases/compiler/nestedBlockScopedBindings5.ts === -function a0() { ->a0 : Symbol(a0, Decl(nestedBlockScopedBindings5.ts, 0, 0)) - - for (let x in []) { ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 1, 12)) - - x = x + 1; ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 1, 12)) ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 1, 12)) - } - for (let x;;) { ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 4, 12)) - - x = x + 2; ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 4, 12)) ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 4, 12)) - } -} - -function a1() { ->a1 : Symbol(a1, Decl(nestedBlockScopedBindings5.ts, 7, 1)) - - for (let x in []) { ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 10, 12)) - - x = x + 1; ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 10, 12)) ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 10, 12)) - - () => x; ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 10, 12)) - } - for (let x;;) { ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 14, 12)) - - x = x + 2; ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 14, 12)) ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 14, 12)) - } -} - -function a2() { ->a2 : Symbol(a2, Decl(nestedBlockScopedBindings5.ts, 17, 1)) - - for (let x in []) { ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 20, 12)) - - x = x + 1; ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 20, 12)) ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 20, 12)) - } - for (let x;;) { ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 23, 12)) - - x = x + 2; ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 23, 12)) ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 23, 12)) - - () => x; ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 23, 12)) - } -} - - -function a3() { ->a3 : Symbol(a3, Decl(nestedBlockScopedBindings5.ts, 27, 1)) - - for (let x in []) { ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 31, 12)) - - x = x + 1; ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 31, 12)) ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 31, 12)) - - () => x; ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 31, 12)) - } - for (let x;false;) { ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 35, 12)) - - x = x + 2; ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 35, 12)) ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 35, 12)) - - () => x; ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 35, 12)) - } - switch (1) { - case 1: - let x; ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 41, 15)) - - () => x; ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 41, 15)) - - break; - } - -} - -function a4() { ->a4 : Symbol(a4, Decl(nestedBlockScopedBindings5.ts, 46, 1)) - - for (let x in []) { ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 49, 12)) - - x = x + 1; ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 49, 12)) ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 49, 12)) - } - for (let x;false;) { ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 52, 12)) - - x = x + 2; ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 52, 12)) ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 52, 12)) - } - switch (1) { - case 1: - let x; ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 57, 15)) - - () => x; ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 57, 15)) - - break; - } - -} - -function a5() { ->a5 : Symbol(a5, Decl(nestedBlockScopedBindings5.ts, 62, 1)) - - let y; ->y : Symbol(y, Decl(nestedBlockScopedBindings5.ts, 65, 7)) - - for (let x in []) { ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 66, 12)) - - x = x + 1; ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 66, 12)) ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 66, 12)) - } - for (let x;false;) { ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 69, 12)) - - x = x + 2; ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 69, 12)) ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 69, 12)) - - () => x; ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 69, 12)) - } - switch (1) { - case 1: - let x; ->x : Symbol(x, Decl(nestedBlockScopedBindings5.ts, 75, 15)) - - break; - } - -} diff --git a/tests/baselines/reference/nestedBlockScopedBindings5.types b/tests/baselines/reference/nestedBlockScopedBindings5.types deleted file mode 100644 index 10ea0e5f902..00000000000 --- a/tests/baselines/reference/nestedBlockScopedBindings5.types +++ /dev/null @@ -1,227 +0,0 @@ -=== tests/cases/compiler/nestedBlockScopedBindings5.ts === -function a0() { ->a0 : () => void - - for (let x in []) { ->x : string ->[] : undefined[] - - x = x + 1; ->x = x + 1 : string ->x : string ->x + 1 : string ->x : string ->1 : number - } - for (let x;;) { ->x : any - - x = x + 2; ->x = x + 2 : any ->x : any ->x + 2 : any ->x : any ->2 : number - } -} - -function a1() { ->a1 : () => void - - for (let x in []) { ->x : string ->[] : undefined[] - - x = x + 1; ->x = x + 1 : string ->x : string ->x + 1 : string ->x : string ->1 : number - - () => x; ->() => x : () => string ->x : string - } - for (let x;;) { ->x : any - - x = x + 2; ->x = x + 2 : any ->x : any ->x + 2 : any ->x : any ->2 : number - } -} - -function a2() { ->a2 : () => void - - for (let x in []) { ->x : string ->[] : undefined[] - - x = x + 1; ->x = x + 1 : string ->x : string ->x + 1 : string ->x : string ->1 : number - } - for (let x;;) { ->x : any - - x = x + 2; ->x = x + 2 : any ->x : any ->x + 2 : any ->x : any ->2 : number - - () => x; ->() => x : () => any ->x : any - } -} - - -function a3() { ->a3 : () => void - - for (let x in []) { ->x : string ->[] : undefined[] - - x = x + 1; ->x = x + 1 : string ->x : string ->x + 1 : string ->x : string ->1 : number - - () => x; ->() => x : () => string ->x : string - } - for (let x;false;) { ->x : any ->false : boolean - - x = x + 2; ->x = x + 2 : any ->x : any ->x + 2 : any ->x : any ->2 : number - - () => x; ->() => x : () => any ->x : any - } - switch (1) { ->1 : number - - case 1: ->1 : number - - let x; ->x : any - - () => x; ->() => x : () => any ->x : any - - break; - } - -} - -function a4() { ->a4 : () => void - - for (let x in []) { ->x : string ->[] : undefined[] - - x = x + 1; ->x = x + 1 : string ->x : string ->x + 1 : string ->x : string ->1 : number - } - for (let x;false;) { ->x : any ->false : boolean - - x = x + 2; ->x = x + 2 : any ->x : any ->x + 2 : any ->x : any ->2 : number - } - switch (1) { ->1 : number - - case 1: ->1 : number - - let x; ->x : any - - () => x; ->() => x : () => any ->x : any - - break; - } - -} - -function a5() { ->a5 : () => void - - let y; ->y : any - - for (let x in []) { ->x : string ->[] : undefined[] - - x = x + 1; ->x = x + 1 : string ->x : string ->x + 1 : string ->x : string ->1 : number - } - for (let x;false;) { ->x : any ->false : boolean - - x = x + 2; ->x = x + 2 : any ->x : any ->x + 2 : any ->x : any ->2 : number - - () => x; ->() => x : () => any ->x : any - } - switch (1) { ->1 : number - - case 1: ->1 : number - - let x; ->x : any - - break; - } - -} diff --git a/tests/baselines/reference/nestedBlockScopedBindings7.errors.txt b/tests/baselines/reference/nestedBlockScopedBindings7.errors.txt new file mode 100644 index 00000000000..274ef8bf6c3 --- /dev/null +++ b/tests/baselines/reference/nestedBlockScopedBindings7.errors.txt @@ -0,0 +1,16 @@ +tests/cases/compiler/nestedBlockScopedBindings7.ts(2,5): error TS7027: Unreachable code detected. +tests/cases/compiler/nestedBlockScopedBindings7.ts(6,5): error TS7027: Unreachable code detected. + + +==== tests/cases/compiler/nestedBlockScopedBindings7.ts (2 errors) ==== + for (let x; false;) { + () => x; + ~ +!!! error TS7027: Unreachable code detected. + } + + for (let y; false;) { + y = 1; + ~ +!!! error TS7027: Unreachable code detected. + } \ No newline at end of file diff --git a/tests/baselines/reference/nestedBlockScopedBindings7.symbols b/tests/baselines/reference/nestedBlockScopedBindings7.symbols deleted file mode 100644 index 2d65af06a96..00000000000 --- a/tests/baselines/reference/nestedBlockScopedBindings7.symbols +++ /dev/null @@ -1,14 +0,0 @@ -=== tests/cases/compiler/nestedBlockScopedBindings7.ts === -for (let x; false;) { ->x : Symbol(x, Decl(nestedBlockScopedBindings7.ts, 0, 8)) - - () => x; ->x : Symbol(x, Decl(nestedBlockScopedBindings7.ts, 0, 8)) -} - -for (let y; false;) { ->y : Symbol(y, Decl(nestedBlockScopedBindings7.ts, 4, 8)) - - y = 1; ->y : Symbol(y, Decl(nestedBlockScopedBindings7.ts, 4, 8)) -} diff --git a/tests/baselines/reference/nestedBlockScopedBindings7.types b/tests/baselines/reference/nestedBlockScopedBindings7.types deleted file mode 100644 index 2fdb2d90e76..00000000000 --- a/tests/baselines/reference/nestedBlockScopedBindings7.types +++ /dev/null @@ -1,19 +0,0 @@ -=== tests/cases/compiler/nestedBlockScopedBindings7.ts === -for (let x; false;) { ->x : any ->false : boolean - - () => x; ->() => x : () => any ->x : any -} - -for (let y; false;) { ->y : any ->false : boolean - - y = 1; ->y = 1 : number ->y : any ->1 : number -} diff --git a/tests/baselines/reference/nestedBlockScopedBindings8.errors.txt b/tests/baselines/reference/nestedBlockScopedBindings8.errors.txt new file mode 100644 index 00000000000..73f580ae3cb --- /dev/null +++ b/tests/baselines/reference/nestedBlockScopedBindings8.errors.txt @@ -0,0 +1,18 @@ +tests/cases/compiler/nestedBlockScopedBindings8.ts(3,5): error TS7027: Unreachable code detected. +tests/cases/compiler/nestedBlockScopedBindings8.ts(8,5): error TS7027: Unreachable code detected. + + +==== tests/cases/compiler/nestedBlockScopedBindings8.ts (2 errors) ==== + var x; + for (let x; false; ) { + () => x; + ~ +!!! error TS7027: Unreachable code detected. + } + + var y; + for (let y; false; ) { + y = 1; + ~ +!!! error TS7027: Unreachable code detected. + } \ No newline at end of file diff --git a/tests/baselines/reference/nestedBlockScopedBindings8.symbols b/tests/baselines/reference/nestedBlockScopedBindings8.symbols deleted file mode 100644 index a61df0502ec..00000000000 --- a/tests/baselines/reference/nestedBlockScopedBindings8.symbols +++ /dev/null @@ -1,20 +0,0 @@ -=== tests/cases/compiler/nestedBlockScopedBindings8.ts === -var x; ->x : Symbol(x, Decl(nestedBlockScopedBindings8.ts, 0, 3)) - -for (let x; false; ) { ->x : Symbol(x, Decl(nestedBlockScopedBindings8.ts, 1, 8)) - - () => x; ->x : Symbol(x, Decl(nestedBlockScopedBindings8.ts, 1, 8)) -} - -var y; ->y : Symbol(y, Decl(nestedBlockScopedBindings8.ts, 5, 3)) - -for (let y; false; ) { ->y : Symbol(y, Decl(nestedBlockScopedBindings8.ts, 6, 8)) - - y = 1; ->y : Symbol(y, Decl(nestedBlockScopedBindings8.ts, 6, 8)) -} diff --git a/tests/baselines/reference/nestedBlockScopedBindings8.types b/tests/baselines/reference/nestedBlockScopedBindings8.types deleted file mode 100644 index 9e4b98ffbf2..00000000000 --- a/tests/baselines/reference/nestedBlockScopedBindings8.types +++ /dev/null @@ -1,25 +0,0 @@ -=== tests/cases/compiler/nestedBlockScopedBindings8.ts === -var x; ->x : any - -for (let x; false; ) { ->x : any ->false : boolean - - () => x; ->() => x : () => any ->x : any -} - -var y; ->y : any - -for (let y; false; ) { ->y : any ->false : boolean - - y = 1; ->y = 1 : number ->y : any ->1 : number -} diff --git a/tests/baselines/reference/newNamesInGlobalAugmentations1.js b/tests/baselines/reference/newNamesInGlobalAugmentations1.js new file mode 100644 index 00000000000..0400f4c3751 --- /dev/null +++ b/tests/baselines/reference/newNamesInGlobalAugmentations1.js @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/newNamesInGlobalAugmentations1.ts] //// + +//// [f1.d.ts] + +export {}; + +declare module M.M1 { + export let x: number; +} +declare global { + interface SymbolConstructor { + observable: symbol; + } + class Cls {x} + let [a, b]: number[]; + export import X = M.M1.x; +} + +//// [main.ts] + +Symbol.observable; +new Cls().x +let c = a + b + X; + +//// [main.js] +Symbol.observable; +new Cls().x; +let c = a + b + X; diff --git a/tests/baselines/reference/newNamesInGlobalAugmentations1.symbols b/tests/baselines/reference/newNamesInGlobalAugmentations1.symbols new file mode 100644 index 00000000000..6215132dd00 --- /dev/null +++ b/tests/baselines/reference/newNamesInGlobalAugmentations1.symbols @@ -0,0 +1,53 @@ +=== tests/cases/compiler/f1.d.ts === + +export {}; + +declare module M.M1 { +>M : Symbol(M, Decl(f1.d.ts, 1, 10)) +>M1 : Symbol(M1, Decl(f1.d.ts, 3, 17)) + + export let x: number; +>x : Symbol(x, Decl(f1.d.ts, 4, 14)) +} +declare global { +>global : Symbol(, Decl(f1.d.ts, 5, 1)) + + interface SymbolConstructor { +>SymbolConstructor : Symbol(SymbolConstructor, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(f1.d.ts, 6, 16)) + + observable: symbol; +>observable : Symbol(SymbolConstructor.observable, Decl(f1.d.ts, 7, 33)) + } + class Cls {x} +>Cls : Symbol(Cls, Decl(f1.d.ts, 9, 5)) +>x : Symbol(Cls.x, Decl(f1.d.ts, 10, 15)) + + let [a, b]: number[]; +>a : Symbol(a, Decl(f1.d.ts, 11, 9)) +>b : Symbol(b, Decl(f1.d.ts, 11, 11)) + + export import X = M.M1.x; +>X : Symbol(X, Decl(f1.d.ts, 11, 25)) +>M : Symbol(M, Decl(f1.d.ts, 1, 10)) +>M1 : Symbol(M.M1, Decl(f1.d.ts, 3, 17)) +>x : Symbol(X, Decl(f1.d.ts, 4, 14)) +} + +=== tests/cases/compiler/main.ts === + +Symbol.observable; +>Symbol.observable : Symbol(SymbolConstructor.observable, Decl(f1.d.ts, 7, 33)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>observable : Symbol(SymbolConstructor.observable, Decl(f1.d.ts, 7, 33)) + +new Cls().x +>new Cls().x : Symbol(Cls.x, Decl(f1.d.ts, 10, 15)) +>Cls : Symbol(Cls, Decl(f1.d.ts, 9, 5)) +>x : Symbol(Cls.x, Decl(f1.d.ts, 10, 15)) + +let c = a + b + X; +>c : Symbol(c, Decl(main.ts, 3, 3)) +>a : Symbol(a, Decl(f1.d.ts, 11, 9)) +>b : Symbol(b, Decl(f1.d.ts, 11, 11)) +>X : Symbol(X, Decl(f1.d.ts, 11, 25)) + diff --git a/tests/baselines/reference/newNamesInGlobalAugmentations1.types b/tests/baselines/reference/newNamesInGlobalAugmentations1.types new file mode 100644 index 00000000000..a9b879fb4c5 --- /dev/null +++ b/tests/baselines/reference/newNamesInGlobalAugmentations1.types @@ -0,0 +1,56 @@ +=== tests/cases/compiler/f1.d.ts === + +export {}; + +declare module M.M1 { +>M : typeof M +>M1 : typeof M1 + + export let x: number; +>x : number +} +declare global { +>global : any + + interface SymbolConstructor { +>SymbolConstructor : SymbolConstructor + + observable: symbol; +>observable : symbol + } + class Cls {x} +>Cls : Cls +>x : any + + let [a, b]: number[]; +>a : number +>b : number + + export import X = M.M1.x; +>X : number +>M : typeof M +>M1 : typeof M.M1 +>x : number +} + +=== tests/cases/compiler/main.ts === + +Symbol.observable; +>Symbol.observable : symbol +>Symbol : SymbolConstructor +>observable : symbol + +new Cls().x +>new Cls().x : any +>new Cls() : Cls +>Cls : typeof Cls +>x : any + +let c = a + b + X; +>c : number +>a + b + X : number +>a + b : number +>a : number +>b : number +>X : number + diff --git a/tests/baselines/reference/newWithSpreadES5.symbols b/tests/baselines/reference/newWithSpreadES5.symbols index 4494063e2fa..7db4e6f1063 100644 --- a/tests/baselines/reference/newWithSpreadES5.symbols +++ b/tests/baselines/reference/newWithSpreadES5.symbols @@ -202,61 +202,61 @@ new B(1, 2, ...a, "string"); // Property access expression new c["a-b"](1, 2, "string"); >c : Symbol(c, Decl(newWithSpreadES5.ts, 26, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES5.ts, 16, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES5.ts, 16, 13)) new c["a-b"](1, 2, ...a); >c : Symbol(c, Decl(newWithSpreadES5.ts, 26, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES5.ts, 16, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES5.ts, 16, 13)) >a : Symbol(a, Decl(newWithSpreadES5.ts, 24, 3)) new c["a-b"](1, 2, ...a, "string"); >c : Symbol(c, Decl(newWithSpreadES5.ts, 26, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES5.ts, 16, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES5.ts, 16, 13)) >a : Symbol(a, Decl(newWithSpreadES5.ts, 24, 3)) // Parenthesised expression new (c["a-b"])(1, 2, "string"); >c : Symbol(c, Decl(newWithSpreadES5.ts, 26, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES5.ts, 16, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES5.ts, 16, 13)) new (c["a-b"])(1, 2, ...a); >c : Symbol(c, Decl(newWithSpreadES5.ts, 26, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES5.ts, 16, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES5.ts, 16, 13)) >a : Symbol(a, Decl(newWithSpreadES5.ts, 24, 3)) new (c["a-b"])(1, 2, ...a, "string"); >c : Symbol(c, Decl(newWithSpreadES5.ts, 26, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES5.ts, 16, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES5.ts, 16, 13)) >a : Symbol(a, Decl(newWithSpreadES5.ts, 24, 3)) // Element access expression new g[1]["a-b"](1, 2, "string"); >g : Symbol(g, Decl(newWithSpreadES5.ts, 29, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES5.ts, 16, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES5.ts, 16, 13)) new g[1]["a-b"](1, 2, ...a); >g : Symbol(g, Decl(newWithSpreadES5.ts, 29, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES5.ts, 16, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES5.ts, 16, 13)) >a : Symbol(a, Decl(newWithSpreadES5.ts, 24, 3)) new g[1]["a-b"](1, 2, ...a, "string"); >g : Symbol(g, Decl(newWithSpreadES5.ts, 29, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES5.ts, 16, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES5.ts, 16, 13)) >a : Symbol(a, Decl(newWithSpreadES5.ts, 24, 3)) // Element access expression with a punctuated key new h["a-b"]["a-b"](1, 2, "string"); >h : Symbol(h, Decl(newWithSpreadES5.ts, 30, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES5.ts, 16, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES5.ts, 16, 13)) new h["a-b"]["a-b"](1, 2, ...a); >h : Symbol(h, Decl(newWithSpreadES5.ts, 30, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES5.ts, 16, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES5.ts, 16, 13)) >a : Symbol(a, Decl(newWithSpreadES5.ts, 24, 3)) new h["a-b"]["a-b"](1, 2, ...a, "string"); >h : Symbol(h, Decl(newWithSpreadES5.ts, 30, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES5.ts, 16, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES5.ts, 16, 13)) >a : Symbol(a, Decl(newWithSpreadES5.ts, 24, 3)) // Element access expression with a number diff --git a/tests/baselines/reference/newWithSpreadES6.symbols b/tests/baselines/reference/newWithSpreadES6.symbols index 14e52279a27..946aeeb5c1a 100644 --- a/tests/baselines/reference/newWithSpreadES6.symbols +++ b/tests/baselines/reference/newWithSpreadES6.symbols @@ -203,61 +203,61 @@ new B(1, 2, ...a, "string"); // Property access expression new c["a-b"](1, 2, "string"); >c : Symbol(c, Decl(newWithSpreadES6.ts, 27, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES6.ts, 17, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES6.ts, 17, 13)) new c["a-b"](1, 2, ...a); >c : Symbol(c, Decl(newWithSpreadES6.ts, 27, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES6.ts, 17, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES6.ts, 17, 13)) >a : Symbol(a, Decl(newWithSpreadES6.ts, 25, 3)) new c["a-b"](1, 2, ...a, "string"); >c : Symbol(c, Decl(newWithSpreadES6.ts, 27, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES6.ts, 17, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES6.ts, 17, 13)) >a : Symbol(a, Decl(newWithSpreadES6.ts, 25, 3)) // Parenthesised expression new (c["a-b"])(1, 2, "string"); >c : Symbol(c, Decl(newWithSpreadES6.ts, 27, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES6.ts, 17, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES6.ts, 17, 13)) new (c["a-b"])(1, 2, ...a); >c : Symbol(c, Decl(newWithSpreadES6.ts, 27, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES6.ts, 17, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES6.ts, 17, 13)) >a : Symbol(a, Decl(newWithSpreadES6.ts, 25, 3)) new (c["a-b"])(1, 2, ...a, "string"); >c : Symbol(c, Decl(newWithSpreadES6.ts, 27, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES6.ts, 17, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES6.ts, 17, 13)) >a : Symbol(a, Decl(newWithSpreadES6.ts, 25, 3)) // Element access expression new g[1]["a-b"](1, 2, "string"); >g : Symbol(g, Decl(newWithSpreadES6.ts, 30, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES6.ts, 17, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES6.ts, 17, 13)) new g[1]["a-b"](1, 2, ...a); >g : Symbol(g, Decl(newWithSpreadES6.ts, 30, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES6.ts, 17, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES6.ts, 17, 13)) >a : Symbol(a, Decl(newWithSpreadES6.ts, 25, 3)) new g[1]["a-b"](1, 2, ...a, "string"); >g : Symbol(g, Decl(newWithSpreadES6.ts, 30, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES6.ts, 17, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES6.ts, 17, 13)) >a : Symbol(a, Decl(newWithSpreadES6.ts, 25, 3)) // Element access expression with a punctuated key new h["a-b"]["a-b"](1, 2, "string"); >h : Symbol(h, Decl(newWithSpreadES6.ts, 31, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES6.ts, 17, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES6.ts, 17, 13)) new h["a-b"]["a-b"](1, 2, ...a); >h : Symbol(h, Decl(newWithSpreadES6.ts, 31, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES6.ts, 17, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES6.ts, 17, 13)) >a : Symbol(a, Decl(newWithSpreadES6.ts, 25, 3)) new h["a-b"]["a-b"](1, 2, ...a, "string"); >h : Symbol(h, Decl(newWithSpreadES6.ts, 31, 3)) ->"a-b" : Symbol(C."a-b", Decl(newWithSpreadES6.ts, 17, 13)) +>"a-b" : Symbol(C["a-b"], Decl(newWithSpreadES6.ts, 17, 13)) >a : Symbol(a, Decl(newWithSpreadES6.ts, 25, 3)) // Element access expression with a number diff --git a/tests/baselines/reference/numericIndexingResults.symbols b/tests/baselines/reference/numericIndexingResults.symbols index 16a6e9386da..49a38fef567 100644 --- a/tests/baselines/reference/numericIndexingResults.symbols +++ b/tests/baselines/reference/numericIndexingResults.symbols @@ -16,12 +16,12 @@ var c: C; var r1 = c['1']; >r1 : Symbol(r1, Decl(numericIndexingResults.ts, 7, 3), Decl(numericIndexingResults.ts, 21, 3), Decl(numericIndexingResults.ts, 34, 3)) >c : Symbol(c, Decl(numericIndexingResults.ts, 6, 3)) ->'1' : Symbol(C.1, Decl(numericIndexingResults.ts, 1, 24)) +>'1' : Symbol(C[1], Decl(numericIndexingResults.ts, 1, 24)) var r2 = c['2']; >r2 : Symbol(r2, Decl(numericIndexingResults.ts, 8, 3), Decl(numericIndexingResults.ts, 22, 3), Decl(numericIndexingResults.ts, 35, 3)) >c : Symbol(c, Decl(numericIndexingResults.ts, 6, 3)) ->'2' : Symbol(C."2", Decl(numericIndexingResults.ts, 2, 11)) +>'2' : Symbol(C["2"], Decl(numericIndexingResults.ts, 2, 11)) var r3 = c['3']; >r3 : Symbol(r3, Decl(numericIndexingResults.ts, 9, 3), Decl(numericIndexingResults.ts, 23, 3), Decl(numericIndexingResults.ts, 36, 3), Decl(numericIndexingResults.ts, 44, 3), Decl(numericIndexingResults.ts, 52, 3)) @@ -30,12 +30,12 @@ var r3 = c['3']; var r4 = c[1]; >r4 : Symbol(r4, Decl(numericIndexingResults.ts, 10, 3), Decl(numericIndexingResults.ts, 24, 3), Decl(numericIndexingResults.ts, 37, 3), Decl(numericIndexingResults.ts, 45, 3), Decl(numericIndexingResults.ts, 53, 3)) >c : Symbol(c, Decl(numericIndexingResults.ts, 6, 3)) ->1 : Symbol(C.1, Decl(numericIndexingResults.ts, 1, 24)) +>1 : Symbol(C[1], Decl(numericIndexingResults.ts, 1, 24)) var r5 = c[2]; >r5 : Symbol(r5, Decl(numericIndexingResults.ts, 11, 3), Decl(numericIndexingResults.ts, 25, 3), Decl(numericIndexingResults.ts, 38, 3), Decl(numericIndexingResults.ts, 46, 3), Decl(numericIndexingResults.ts, 54, 3)) >c : Symbol(c, Decl(numericIndexingResults.ts, 6, 3)) ->2 : Symbol(C."2", Decl(numericIndexingResults.ts, 2, 11)) +>2 : Symbol(C["2"], Decl(numericIndexingResults.ts, 2, 11)) var r6 = c[3]; >r6 : Symbol(r6, Decl(numericIndexingResults.ts, 12, 3), Decl(numericIndexingResults.ts, 26, 3), Decl(numericIndexingResults.ts, 39, 3), Decl(numericIndexingResults.ts, 47, 3), Decl(numericIndexingResults.ts, 55, 3)) @@ -58,12 +58,12 @@ var i: I var r1 = i['1']; >r1 : Symbol(r1, Decl(numericIndexingResults.ts, 7, 3), Decl(numericIndexingResults.ts, 21, 3), Decl(numericIndexingResults.ts, 34, 3)) >i : Symbol(i, Decl(numericIndexingResults.ts, 20, 3)) ->'1' : Symbol(I.1, Decl(numericIndexingResults.ts, 15, 24)) +>'1' : Symbol(I[1], Decl(numericIndexingResults.ts, 15, 24)) var r2 = i['2']; >r2 : Symbol(r2, Decl(numericIndexingResults.ts, 8, 3), Decl(numericIndexingResults.ts, 22, 3), Decl(numericIndexingResults.ts, 35, 3)) >i : Symbol(i, Decl(numericIndexingResults.ts, 20, 3)) ->'2' : Symbol(I."2", Decl(numericIndexingResults.ts, 16, 14)) +>'2' : Symbol(I["2"], Decl(numericIndexingResults.ts, 16, 14)) var r3 = i['3']; >r3 : Symbol(r3, Decl(numericIndexingResults.ts, 9, 3), Decl(numericIndexingResults.ts, 23, 3), Decl(numericIndexingResults.ts, 36, 3), Decl(numericIndexingResults.ts, 44, 3), Decl(numericIndexingResults.ts, 52, 3)) @@ -72,12 +72,12 @@ var r3 = i['3']; var r4 = i[1]; >r4 : Symbol(r4, Decl(numericIndexingResults.ts, 10, 3), Decl(numericIndexingResults.ts, 24, 3), Decl(numericIndexingResults.ts, 37, 3), Decl(numericIndexingResults.ts, 45, 3), Decl(numericIndexingResults.ts, 53, 3)) >i : Symbol(i, Decl(numericIndexingResults.ts, 20, 3)) ->1 : Symbol(I.1, Decl(numericIndexingResults.ts, 15, 24)) +>1 : Symbol(I[1], Decl(numericIndexingResults.ts, 15, 24)) var r5 = i[2]; >r5 : Symbol(r5, Decl(numericIndexingResults.ts, 11, 3), Decl(numericIndexingResults.ts, 25, 3), Decl(numericIndexingResults.ts, 38, 3), Decl(numericIndexingResults.ts, 46, 3), Decl(numericIndexingResults.ts, 54, 3)) >i : Symbol(i, Decl(numericIndexingResults.ts, 20, 3)) ->2 : Symbol(I."2", Decl(numericIndexingResults.ts, 16, 14)) +>2 : Symbol(I["2"], Decl(numericIndexingResults.ts, 16, 14)) var r6 = i[3]; >r6 : Symbol(r6, Decl(numericIndexingResults.ts, 12, 3), Decl(numericIndexingResults.ts, 26, 3), Decl(numericIndexingResults.ts, 39, 3), Decl(numericIndexingResults.ts, 47, 3), Decl(numericIndexingResults.ts, 55, 3)) diff --git a/tests/baselines/reference/objectTypeWithNumericProperty.symbols b/tests/baselines/reference/objectTypeWithNumericProperty.symbols index 20e54fe1c64..73ff7149d0f 100644 --- a/tests/baselines/reference/objectTypeWithNumericProperty.symbols +++ b/tests/baselines/reference/objectTypeWithNumericProperty.symbols @@ -15,22 +15,22 @@ var c: C; var r1 = c[1]; >r1 : Symbol(r1, Decl(objectTypeWithNumericProperty.ts, 8, 3), Decl(objectTypeWithNumericProperty.ts, 19, 3), Decl(objectTypeWithNumericProperty.ts, 29, 3), Decl(objectTypeWithNumericProperty.ts, 39, 3)) >c : Symbol(c, Decl(objectTypeWithNumericProperty.ts, 7, 3)) ->1 : Symbol(C.1, Decl(objectTypeWithNumericProperty.ts, 2, 9)) +>1 : Symbol(C[1], Decl(objectTypeWithNumericProperty.ts, 2, 9)) var r2 = c[1.1]; >r2 : Symbol(r2, Decl(objectTypeWithNumericProperty.ts, 9, 3), Decl(objectTypeWithNumericProperty.ts, 20, 3), Decl(objectTypeWithNumericProperty.ts, 30, 3), Decl(objectTypeWithNumericProperty.ts, 40, 3)) >c : Symbol(c, Decl(objectTypeWithNumericProperty.ts, 7, 3)) ->1.1 : Symbol(C.1.1, Decl(objectTypeWithNumericProperty.ts, 3, 14)) +>1.1 : Symbol(C[1.1], Decl(objectTypeWithNumericProperty.ts, 3, 14)) var r3 = c['1']; >r3 : Symbol(r3, Decl(objectTypeWithNumericProperty.ts, 10, 3), Decl(objectTypeWithNumericProperty.ts, 21, 3), Decl(objectTypeWithNumericProperty.ts, 31, 3), Decl(objectTypeWithNumericProperty.ts, 41, 3)) >c : Symbol(c, Decl(objectTypeWithNumericProperty.ts, 7, 3)) ->'1' : Symbol(C.1, Decl(objectTypeWithNumericProperty.ts, 2, 9)) +>'1' : Symbol(C[1], Decl(objectTypeWithNumericProperty.ts, 2, 9)) var r4 = c['1.1']; >r4 : Symbol(r4, Decl(objectTypeWithNumericProperty.ts, 11, 3), Decl(objectTypeWithNumericProperty.ts, 22, 3), Decl(objectTypeWithNumericProperty.ts, 32, 3), Decl(objectTypeWithNumericProperty.ts, 42, 3)) >c : Symbol(c, Decl(objectTypeWithNumericProperty.ts, 7, 3)) ->'1.1' : Symbol(C.1.1, Decl(objectTypeWithNumericProperty.ts, 3, 14)) +>'1.1' : Symbol(C[1.1], Decl(objectTypeWithNumericProperty.ts, 3, 14)) interface I { >I : Symbol(I, Decl(objectTypeWithNumericProperty.ts, 11, 18)) @@ -46,22 +46,22 @@ var i: I; var r1 = i[1]; >r1 : Symbol(r1, Decl(objectTypeWithNumericProperty.ts, 8, 3), Decl(objectTypeWithNumericProperty.ts, 19, 3), Decl(objectTypeWithNumericProperty.ts, 29, 3), Decl(objectTypeWithNumericProperty.ts, 39, 3)) >i : Symbol(i, Decl(objectTypeWithNumericProperty.ts, 18, 3)) ->1 : Symbol(I.1, Decl(objectTypeWithNumericProperty.ts, 13, 13)) +>1 : Symbol(I[1], Decl(objectTypeWithNumericProperty.ts, 13, 13)) var r2 = i[1.1]; >r2 : Symbol(r2, Decl(objectTypeWithNumericProperty.ts, 9, 3), Decl(objectTypeWithNumericProperty.ts, 20, 3), Decl(objectTypeWithNumericProperty.ts, 30, 3), Decl(objectTypeWithNumericProperty.ts, 40, 3)) >i : Symbol(i, Decl(objectTypeWithNumericProperty.ts, 18, 3)) ->1.1 : Symbol(I.1.1, Decl(objectTypeWithNumericProperty.ts, 14, 14)) +>1.1 : Symbol(I[1.1], Decl(objectTypeWithNumericProperty.ts, 14, 14)) var r3 = i['1']; >r3 : Symbol(r3, Decl(objectTypeWithNumericProperty.ts, 10, 3), Decl(objectTypeWithNumericProperty.ts, 21, 3), Decl(objectTypeWithNumericProperty.ts, 31, 3), Decl(objectTypeWithNumericProperty.ts, 41, 3)) >i : Symbol(i, Decl(objectTypeWithNumericProperty.ts, 18, 3)) ->'1' : Symbol(I.1, Decl(objectTypeWithNumericProperty.ts, 13, 13)) +>'1' : Symbol(I[1], Decl(objectTypeWithNumericProperty.ts, 13, 13)) var r4 = i['1.1']; >r4 : Symbol(r4, Decl(objectTypeWithNumericProperty.ts, 11, 3), Decl(objectTypeWithNumericProperty.ts, 22, 3), Decl(objectTypeWithNumericProperty.ts, 32, 3), Decl(objectTypeWithNumericProperty.ts, 42, 3)) >i : Symbol(i, Decl(objectTypeWithNumericProperty.ts, 18, 3)) ->'1.1' : Symbol(I.1.1, Decl(objectTypeWithNumericProperty.ts, 14, 14)) +>'1.1' : Symbol(I[1.1], Decl(objectTypeWithNumericProperty.ts, 14, 14)) var a: { >a : Symbol(a, Decl(objectTypeWithNumericProperty.ts, 24, 3)) diff --git a/tests/baselines/reference/objectTypeWithStringNamedNumericProperty.symbols b/tests/baselines/reference/objectTypeWithStringNamedNumericProperty.symbols index a3f316b1bbf..480886711d5 100644 --- a/tests/baselines/reference/objectTypeWithStringNamedNumericProperty.symbols +++ b/tests/baselines/reference/objectTypeWithStringNamedNumericProperty.symbols @@ -31,47 +31,47 @@ var c: C; var r1 = c['0.1']; >r1 : Symbol(r1, Decl(objectTypeWithStringNamedNumericProperty.ts, 17, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 48, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 78, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 108, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedNumericProperty.ts, 16, 3)) ->'0.1' : Symbol(C."0.1", Decl(objectTypeWithStringNamedNumericProperty.ts, 5, 9)) +>'0.1' : Symbol(C["0.1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 5, 9)) var r2 = c['.1']; >r2 : Symbol(r2, Decl(objectTypeWithStringNamedNumericProperty.ts, 18, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 49, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 79, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 109, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedNumericProperty.ts, 16, 3)) ->'.1' : Symbol(C.".1", Decl(objectTypeWithStringNamedNumericProperty.ts, 6, 16)) +>'.1' : Symbol(C[".1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 6, 16)) var r3 = c['1']; >r3 : Symbol(r3, Decl(objectTypeWithStringNamedNumericProperty.ts, 19, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 20, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 22, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 25, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 50, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 51, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 53, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 56, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 80, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 81, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 83, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 86, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 110, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 111, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 113, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 116, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedNumericProperty.ts, 16, 3)) ->'1' : Symbol(C."1", Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) +>'1' : Symbol(C["1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) var r3 = c[1]; >r3 : Symbol(r3, Decl(objectTypeWithStringNamedNumericProperty.ts, 19, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 20, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 22, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 25, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 50, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 51, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 53, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 56, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 80, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 81, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 83, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 86, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 110, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 111, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 113, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 116, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedNumericProperty.ts, 16, 3)) ->1 : Symbol(C."1", Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) +>1 : Symbol(C["1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) var r4 = c['1.']; >r4 : Symbol(r4, Decl(objectTypeWithStringNamedNumericProperty.ts, 21, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 52, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 82, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 112, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedNumericProperty.ts, 16, 3)) ->'1.' : Symbol(C."1.", Decl(objectTypeWithStringNamedNumericProperty.ts, 8, 16)) +>'1.' : Symbol(C["1."], Decl(objectTypeWithStringNamedNumericProperty.ts, 8, 16)) var r3 = c[1.]; // same as indexing by 1 when done numerically >r3 : Symbol(r3, Decl(objectTypeWithStringNamedNumericProperty.ts, 19, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 20, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 22, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 25, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 50, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 51, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 53, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 56, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 80, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 81, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 83, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 86, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 110, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 111, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 113, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 116, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedNumericProperty.ts, 16, 3)) ->1. : Symbol(C."1", Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) +>1. : Symbol(C["1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) var r5 = c['1..']; >r5 : Symbol(r5, Decl(objectTypeWithStringNamedNumericProperty.ts, 23, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 54, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 84, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 114, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedNumericProperty.ts, 16, 3)) ->'1..' : Symbol(C."1..", Decl(objectTypeWithStringNamedNumericProperty.ts, 9, 17)) +>'1..' : Symbol(C["1.."], Decl(objectTypeWithStringNamedNumericProperty.ts, 9, 17)) var r6 = c['1.0']; >r6 : Symbol(r6, Decl(objectTypeWithStringNamedNumericProperty.ts, 24, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 55, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 85, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 115, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedNumericProperty.ts, 16, 3)) ->'1.0' : Symbol(C."1.0", Decl(objectTypeWithStringNamedNumericProperty.ts, 10, 19)) +>'1.0' : Symbol(C["1.0"], Decl(objectTypeWithStringNamedNumericProperty.ts, 10, 19)) var r3 = c[1.0]; // same as indexing by 1 when done numerically >r3 : Symbol(r3, Decl(objectTypeWithStringNamedNumericProperty.ts, 19, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 20, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 22, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 25, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 50, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 51, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 53, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 56, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 80, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 81, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 83, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 86, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 110, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 111, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 113, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 116, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedNumericProperty.ts, 16, 3)) ->1.0 : Symbol(C."1", Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) +>1.0 : Symbol(C["1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) // BUG 823822 var r7 = i[-1]; @@ -85,17 +85,17 @@ var r7 = i[-1.0]; var r8 = i["-1.0"]; >r8 : Symbol(r8, Decl(objectTypeWithStringNamedNumericProperty.ts, 29, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 60, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 90, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 120, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedNumericProperty.ts, 47, 3)) ->"-1.0" : Symbol(I."-1.0", Decl(objectTypeWithStringNamedNumericProperty.ts, 42, 16)) +>"-1.0" : Symbol(I["-1.0"], Decl(objectTypeWithStringNamedNumericProperty.ts, 42, 16)) var r9 = i["-1"]; >r9 : Symbol(r9, Decl(objectTypeWithStringNamedNumericProperty.ts, 30, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 61, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 91, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 121, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedNumericProperty.ts, 47, 3)) ->"-1" : Symbol(I."-1", Decl(objectTypeWithStringNamedNumericProperty.ts, 43, 19)) +>"-1" : Symbol(I["-1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 43, 19)) var r10 = i[0x1] >r10 : Symbol(r10, Decl(objectTypeWithStringNamedNumericProperty.ts, 31, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 62, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 92, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 122, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedNumericProperty.ts, 47, 3)) ->0x1 : Symbol(I."1", Decl(objectTypeWithStringNamedNumericProperty.ts, 38, 17)) +>0x1 : Symbol(I["1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 38, 17)) var r11 = i[-0x1] >r11 : Symbol(r11, Decl(objectTypeWithStringNamedNumericProperty.ts, 32, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 63, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 93, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 123, 3)) @@ -104,7 +104,7 @@ var r11 = i[-0x1] var r12 = i[01] >r12 : Symbol(r12, Decl(objectTypeWithStringNamedNumericProperty.ts, 33, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 64, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 94, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 124, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedNumericProperty.ts, 47, 3)) ->01 : Symbol(I."1", Decl(objectTypeWithStringNamedNumericProperty.ts, 38, 17)) +>01 : Symbol(I["1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 38, 17)) var r13 = i[-01] >r13 : Symbol(r13, Decl(objectTypeWithStringNamedNumericProperty.ts, 34, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 65, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 95, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 125, 3)) @@ -137,47 +137,47 @@ var i: I; var r1 = i['0.1']; >r1 : Symbol(r1, Decl(objectTypeWithStringNamedNumericProperty.ts, 17, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 48, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 78, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 108, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedNumericProperty.ts, 47, 3)) ->'0.1' : Symbol(I."0.1", Decl(objectTypeWithStringNamedNumericProperty.ts, 36, 13)) +>'0.1' : Symbol(I["0.1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 36, 13)) var r2 = i['.1']; >r2 : Symbol(r2, Decl(objectTypeWithStringNamedNumericProperty.ts, 18, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 49, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 79, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 109, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedNumericProperty.ts, 47, 3)) ->'.1' : Symbol(I.".1", Decl(objectTypeWithStringNamedNumericProperty.ts, 37, 16)) +>'.1' : Symbol(I[".1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 37, 16)) var r3 = i['1']; >r3 : Symbol(r3, Decl(objectTypeWithStringNamedNumericProperty.ts, 19, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 20, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 22, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 25, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 50, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 51, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 53, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 56, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 80, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 81, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 83, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 86, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 110, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 111, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 113, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 116, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedNumericProperty.ts, 47, 3)) ->'1' : Symbol(I."1", Decl(objectTypeWithStringNamedNumericProperty.ts, 38, 17)) +>'1' : Symbol(I["1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 38, 17)) var r3 = c[1]; >r3 : Symbol(r3, Decl(objectTypeWithStringNamedNumericProperty.ts, 19, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 20, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 22, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 25, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 50, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 51, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 53, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 56, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 80, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 81, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 83, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 86, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 110, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 111, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 113, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 116, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedNumericProperty.ts, 16, 3)) ->1 : Symbol(C."1", Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) +>1 : Symbol(C["1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) var r4 = i['1.']; >r4 : Symbol(r4, Decl(objectTypeWithStringNamedNumericProperty.ts, 21, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 52, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 82, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 112, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedNumericProperty.ts, 47, 3)) ->'1.' : Symbol(I."1.", Decl(objectTypeWithStringNamedNumericProperty.ts, 39, 16)) +>'1.' : Symbol(I["1."], Decl(objectTypeWithStringNamedNumericProperty.ts, 39, 16)) var r3 = c[1.]; // same as indexing by 1 when done numerically >r3 : Symbol(r3, Decl(objectTypeWithStringNamedNumericProperty.ts, 19, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 20, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 22, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 25, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 50, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 51, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 53, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 56, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 80, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 81, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 83, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 86, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 110, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 111, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 113, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 116, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedNumericProperty.ts, 16, 3)) ->1. : Symbol(C."1", Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) +>1. : Symbol(C["1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) var r5 = i['1..']; >r5 : Symbol(r5, Decl(objectTypeWithStringNamedNumericProperty.ts, 23, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 54, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 84, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 114, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedNumericProperty.ts, 47, 3)) ->'1..' : Symbol(I."1..", Decl(objectTypeWithStringNamedNumericProperty.ts, 40, 17)) +>'1..' : Symbol(I["1.."], Decl(objectTypeWithStringNamedNumericProperty.ts, 40, 17)) var r6 = i['1.0']; >r6 : Symbol(r6, Decl(objectTypeWithStringNamedNumericProperty.ts, 24, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 55, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 85, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 115, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedNumericProperty.ts, 47, 3)) ->'1.0' : Symbol(I."1.0", Decl(objectTypeWithStringNamedNumericProperty.ts, 41, 19)) +>'1.0' : Symbol(I["1.0"], Decl(objectTypeWithStringNamedNumericProperty.ts, 41, 19)) var r3 = c[1.0]; // same as indexing by 1 when done numerically >r3 : Symbol(r3, Decl(objectTypeWithStringNamedNumericProperty.ts, 19, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 20, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 22, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 25, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 50, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 51, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 53, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 56, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 80, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 81, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 83, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 86, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 110, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 111, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 113, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 116, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedNumericProperty.ts, 16, 3)) ->1.0 : Symbol(C."1", Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) +>1.0 : Symbol(C["1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) // BUG 823822 var r7 = i[-1]; @@ -191,17 +191,17 @@ var r7 = i[-1.0]; var r8 = i["-1.0"]; >r8 : Symbol(r8, Decl(objectTypeWithStringNamedNumericProperty.ts, 29, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 60, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 90, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 120, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedNumericProperty.ts, 47, 3)) ->"-1.0" : Symbol(I."-1.0", Decl(objectTypeWithStringNamedNumericProperty.ts, 42, 16)) +>"-1.0" : Symbol(I["-1.0"], Decl(objectTypeWithStringNamedNumericProperty.ts, 42, 16)) var r9 = i["-1"]; >r9 : Symbol(r9, Decl(objectTypeWithStringNamedNumericProperty.ts, 30, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 61, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 91, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 121, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedNumericProperty.ts, 47, 3)) ->"-1" : Symbol(I."-1", Decl(objectTypeWithStringNamedNumericProperty.ts, 43, 19)) +>"-1" : Symbol(I["-1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 43, 19)) var r10 = i[0x1] >r10 : Symbol(r10, Decl(objectTypeWithStringNamedNumericProperty.ts, 31, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 62, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 92, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 122, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedNumericProperty.ts, 47, 3)) ->0x1 : Symbol(I."1", Decl(objectTypeWithStringNamedNumericProperty.ts, 38, 17)) +>0x1 : Symbol(I["1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 38, 17)) var r11 = i[-0x1] >r11 : Symbol(r11, Decl(objectTypeWithStringNamedNumericProperty.ts, 32, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 63, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 93, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 123, 3)) @@ -210,7 +210,7 @@ var r11 = i[-0x1] var r12 = i[01] >r12 : Symbol(r12, Decl(objectTypeWithStringNamedNumericProperty.ts, 33, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 64, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 94, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 124, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedNumericProperty.ts, 47, 3)) ->01 : Symbol(I."1", Decl(objectTypeWithStringNamedNumericProperty.ts, 38, 17)) +>01 : Symbol(I["1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 38, 17)) var r13 = i[-01] >r13 : Symbol(r13, Decl(objectTypeWithStringNamedNumericProperty.ts, 34, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 65, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 95, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 125, 3)) @@ -254,7 +254,7 @@ var r3 = a['1']; var r3 = c[1]; >r3 : Symbol(r3, Decl(objectTypeWithStringNamedNumericProperty.ts, 19, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 20, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 22, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 25, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 50, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 51, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 53, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 56, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 80, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 81, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 83, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 86, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 110, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 111, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 113, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 116, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedNumericProperty.ts, 16, 3)) ->1 : Symbol(C."1", Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) +>1 : Symbol(C["1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) var r4 = a['1.']; >r4 : Symbol(r4, Decl(objectTypeWithStringNamedNumericProperty.ts, 21, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 52, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 82, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 112, 3)) @@ -264,7 +264,7 @@ var r4 = a['1.']; var r3 = c[1.]; // same as indexing by 1 when done numerically >r3 : Symbol(r3, Decl(objectTypeWithStringNamedNumericProperty.ts, 19, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 20, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 22, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 25, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 50, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 51, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 53, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 56, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 80, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 81, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 83, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 86, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 110, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 111, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 113, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 116, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedNumericProperty.ts, 16, 3)) ->1. : Symbol(C."1", Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) +>1. : Symbol(C["1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) var r5 = a['1..']; >r5 : Symbol(r5, Decl(objectTypeWithStringNamedNumericProperty.ts, 23, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 54, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 84, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 114, 3)) @@ -279,7 +279,7 @@ var r6 = a['1.0']; var r3 = c[1.0]; // same as indexing by 1 when done numerically >r3 : Symbol(r3, Decl(objectTypeWithStringNamedNumericProperty.ts, 19, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 20, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 22, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 25, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 50, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 51, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 53, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 56, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 80, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 81, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 83, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 86, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 110, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 111, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 113, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 116, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedNumericProperty.ts, 16, 3)) ->1.0 : Symbol(C."1", Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) +>1.0 : Symbol(C["1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) // BUG 823822 var r7 = i[-1]; @@ -293,17 +293,17 @@ var r7 = i[-1.0]; var r8 = i["-1.0"]; >r8 : Symbol(r8, Decl(objectTypeWithStringNamedNumericProperty.ts, 29, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 60, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 90, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 120, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedNumericProperty.ts, 47, 3)) ->"-1.0" : Symbol(I."-1.0", Decl(objectTypeWithStringNamedNumericProperty.ts, 42, 16)) +>"-1.0" : Symbol(I["-1.0"], Decl(objectTypeWithStringNamedNumericProperty.ts, 42, 16)) var r9 = i["-1"]; >r9 : Symbol(r9, Decl(objectTypeWithStringNamedNumericProperty.ts, 30, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 61, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 91, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 121, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedNumericProperty.ts, 47, 3)) ->"-1" : Symbol(I."-1", Decl(objectTypeWithStringNamedNumericProperty.ts, 43, 19)) +>"-1" : Symbol(I["-1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 43, 19)) var r10 = i[0x1] >r10 : Symbol(r10, Decl(objectTypeWithStringNamedNumericProperty.ts, 31, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 62, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 92, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 122, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedNumericProperty.ts, 47, 3)) ->0x1 : Symbol(I."1", Decl(objectTypeWithStringNamedNumericProperty.ts, 38, 17)) +>0x1 : Symbol(I["1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 38, 17)) var r11 = i[-0x1] >r11 : Symbol(r11, Decl(objectTypeWithStringNamedNumericProperty.ts, 32, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 63, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 93, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 123, 3)) @@ -312,7 +312,7 @@ var r11 = i[-0x1] var r12 = i[01] >r12 : Symbol(r12, Decl(objectTypeWithStringNamedNumericProperty.ts, 33, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 64, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 94, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 124, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedNumericProperty.ts, 47, 3)) ->01 : Symbol(I."1", Decl(objectTypeWithStringNamedNumericProperty.ts, 38, 17)) +>01 : Symbol(I["1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 38, 17)) var r13 = i[-01] >r13 : Symbol(r13, Decl(objectTypeWithStringNamedNumericProperty.ts, 34, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 65, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 95, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 125, 3)) @@ -355,7 +355,7 @@ var r3 = b['1']; var r3 = c[1]; >r3 : Symbol(r3, Decl(objectTypeWithStringNamedNumericProperty.ts, 19, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 20, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 22, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 25, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 50, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 51, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 53, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 56, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 80, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 81, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 83, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 86, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 110, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 111, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 113, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 116, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedNumericProperty.ts, 16, 3)) ->1 : Symbol(C."1", Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) +>1 : Symbol(C["1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) var r4 = b['1.']; >r4 : Symbol(r4, Decl(objectTypeWithStringNamedNumericProperty.ts, 21, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 52, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 82, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 112, 3)) @@ -365,7 +365,7 @@ var r4 = b['1.']; var r3 = c[1.]; // same as indexing by 1 when done numerically >r3 : Symbol(r3, Decl(objectTypeWithStringNamedNumericProperty.ts, 19, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 20, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 22, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 25, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 50, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 51, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 53, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 56, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 80, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 81, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 83, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 86, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 110, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 111, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 113, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 116, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedNumericProperty.ts, 16, 3)) ->1. : Symbol(C."1", Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) +>1. : Symbol(C["1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) var r5 = b['1..']; >r5 : Symbol(r5, Decl(objectTypeWithStringNamedNumericProperty.ts, 23, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 54, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 84, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 114, 3)) @@ -380,7 +380,7 @@ var r6 = b['1.0']; var r3 = c[1.0]; // same as indexing by 1 when done numerically >r3 : Symbol(r3, Decl(objectTypeWithStringNamedNumericProperty.ts, 19, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 20, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 22, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 25, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 50, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 51, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 53, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 56, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 80, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 81, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 83, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 86, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 110, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 111, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 113, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 116, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedNumericProperty.ts, 16, 3)) ->1.0 : Symbol(C."1", Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) +>1.0 : Symbol(C["1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 7, 17)) // BUG 823822 var r7 = i[-1]; @@ -394,17 +394,17 @@ var r7 = i[-1.0]; var r8 = i["-1.0"]; >r8 : Symbol(r8, Decl(objectTypeWithStringNamedNumericProperty.ts, 29, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 60, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 90, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 120, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedNumericProperty.ts, 47, 3)) ->"-1.0" : Symbol(I."-1.0", Decl(objectTypeWithStringNamedNumericProperty.ts, 42, 16)) +>"-1.0" : Symbol(I["-1.0"], Decl(objectTypeWithStringNamedNumericProperty.ts, 42, 16)) var r9 = i["-1"]; >r9 : Symbol(r9, Decl(objectTypeWithStringNamedNumericProperty.ts, 30, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 61, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 91, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 121, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedNumericProperty.ts, 47, 3)) ->"-1" : Symbol(I."-1", Decl(objectTypeWithStringNamedNumericProperty.ts, 43, 19)) +>"-1" : Symbol(I["-1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 43, 19)) var r10 = i[0x1] >r10 : Symbol(r10, Decl(objectTypeWithStringNamedNumericProperty.ts, 31, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 62, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 92, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 122, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedNumericProperty.ts, 47, 3)) ->0x1 : Symbol(I."1", Decl(objectTypeWithStringNamedNumericProperty.ts, 38, 17)) +>0x1 : Symbol(I["1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 38, 17)) var r11 = i[-0x1] >r11 : Symbol(r11, Decl(objectTypeWithStringNamedNumericProperty.ts, 32, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 63, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 93, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 123, 3)) @@ -413,7 +413,7 @@ var r11 = i[-0x1] var r12 = i[01] >r12 : Symbol(r12, Decl(objectTypeWithStringNamedNumericProperty.ts, 33, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 64, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 94, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 124, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedNumericProperty.ts, 47, 3)) ->01 : Symbol(I."1", Decl(objectTypeWithStringNamedNumericProperty.ts, 38, 17)) +>01 : Symbol(I["1"], Decl(objectTypeWithStringNamedNumericProperty.ts, 38, 17)) var r13 = i[-01] >r13 : Symbol(r13, Decl(objectTypeWithStringNamedNumericProperty.ts, 34, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 65, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 95, 3), Decl(objectTypeWithStringNamedNumericProperty.ts, 125, 3)) diff --git a/tests/baselines/reference/objectTypeWithStringNamedPropertyOfIllegalCharacters.symbols b/tests/baselines/reference/objectTypeWithStringNamedPropertyOfIllegalCharacters.symbols index aa76e7e92c8..773fb3f5760 100644 --- a/tests/baselines/reference/objectTypeWithStringNamedPropertyOfIllegalCharacters.symbols +++ b/tests/baselines/reference/objectTypeWithStringNamedPropertyOfIllegalCharacters.symbols @@ -16,7 +16,7 @@ var c: C; var r = c[" "]; >r : Symbol(r, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 9, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 22, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 35, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 47, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 8, 3)) ->" " : Symbol(C." ", Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 0, 9)) +>" " : Symbol(C[" "], Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 0, 9)) var r2 = c[" "]; >r2 : Symbol(r2, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 10, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 23, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 36, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 48, 3)) @@ -25,13 +25,13 @@ var r2 = c[" "]; var r3 = c["a b"]; >r3 : Symbol(r3, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 11, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 24, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 37, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 49, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 8, 3)) ->"a b" : Symbol(C."a b", Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 1, 18)) +>"a b" : Symbol(C["a b"], Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 1, 18)) // BUG 817263 var r4 = c["~!@#$%^&*()_+{}|:'<>?\/.,`"]; >r4 : Symbol(r4, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 13, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 26, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 39, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 51, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 8, 3)) ->"~!@#$%^&*()_+{}|:'<>?\/.,`" : Symbol(C."~!@#$%^&*()_+{}|:'<>?\/.,`", Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 2, 20)) +>"~!@#$%^&*()_+{}|:'<>?\/.,`" : Symbol(C["~!@#$%^&*()_+{}|:'<>?\/.,`"], Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 2, 20)) interface I { >I : Symbol(I, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 13, 41)) @@ -48,7 +48,7 @@ var i: I; var r = i[" "]; >r : Symbol(r, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 9, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 22, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 35, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 47, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 21, 3)) ->" " : Symbol(I." ", Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 15, 13)) +>" " : Symbol(I[" "], Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 15, 13)) var r2 = i[" "]; >r2 : Symbol(r2, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 10, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 23, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 36, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 48, 3)) @@ -57,13 +57,13 @@ var r2 = i[" "]; var r3 = i["a b"]; >r3 : Symbol(r3, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 11, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 24, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 37, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 49, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 21, 3)) ->"a b" : Symbol(I."a b", Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 16, 18)) +>"a b" : Symbol(I["a b"], Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 16, 18)) // BUG 817263 var r4 = i["~!@#$%^&*()_+{}|:'<>?\/.,`"]; >r4 : Symbol(r4, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 13, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 26, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 39, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 51, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 21, 3)) ->"~!@#$%^&*()_+{}|:'<>?\/.,`" : Symbol(I."~!@#$%^&*()_+{}|:'<>?\/.,`", Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 17, 20)) +>"~!@#$%^&*()_+{}|:'<>?\/.,`" : Symbol(I["~!@#$%^&*()_+{}|:'<>?\/.,`"], Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 17, 20)) var a: { diff --git a/tests/baselines/reference/parser_duplicateLabel1.errors.txt b/tests/baselines/reference/parser_duplicateLabel1.errors.txt index a4319aaa7b9..c98ede21ecf 100644 --- a/tests/baselines/reference/parser_duplicateLabel1.errors.txt +++ b/tests/baselines/reference/parser_duplicateLabel1.errors.txt @@ -1,13 +1,16 @@ tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel1.ts(1,1): error TS7028: Unused label. tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel1.ts(2,1): error TS1114: Duplicate label 'target' +tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel1.ts(2,1): error TS7028: Unused label. -==== tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel1.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel1.ts (3 errors) ==== target: ~~~~~~ !!! error TS7028: Unused label. target: ~~~~~~ !!! error TS1114: Duplicate label 'target' + ~~~~~~ +!!! error TS7028: Unused label. while (true) { } \ No newline at end of file diff --git a/tests/baselines/reference/parser_duplicateLabel2.errors.txt b/tests/baselines/reference/parser_duplicateLabel2.errors.txt index 123949fa5aa..cbad8b73a21 100644 --- a/tests/baselines/reference/parser_duplicateLabel2.errors.txt +++ b/tests/baselines/reference/parser_duplicateLabel2.errors.txt @@ -1,8 +1,9 @@ tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel2.ts(1,1): error TS7028: Unused label. tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel2.ts(3,3): error TS1114: Duplicate label 'target' +tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel2.ts(3,3): error TS7028: Unused label. -==== tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel2.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel2.ts (3 errors) ==== target: ~~~~~~ !!! error TS7028: Unused label. @@ -10,6 +11,8 @@ tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_d target: ~~~~~~ !!! error TS1114: Duplicate label 'target' + ~~~~~~ +!!! error TS7028: Unused label. while (true) { } } \ No newline at end of file diff --git a/tests/baselines/reference/pathsValidation1.errors.txt b/tests/baselines/reference/pathsValidation1.errors.txt new file mode 100644 index 00000000000..c6193be67ac --- /dev/null +++ b/tests/baselines/reference/pathsValidation1.errors.txt @@ -0,0 +1,6 @@ +error TS5063: Substututions for pattern '*' should be an array. + + +!!! error TS5063: Substututions for pattern '*' should be an array. +==== tests/cases/compiler/a.ts (0 errors) ==== + let x = 1; \ No newline at end of file diff --git a/tests/baselines/reference/pathsValidation1.js b/tests/baselines/reference/pathsValidation1.js new file mode 100644 index 00000000000..bfffc647f63 --- /dev/null +++ b/tests/baselines/reference/pathsValidation1.js @@ -0,0 +1,5 @@ +//// [a.ts] +let x = 1; + +//// [a.js] +var x = 1; diff --git a/tests/baselines/reference/pathsValidation2.errors.txt b/tests/baselines/reference/pathsValidation2.errors.txt new file mode 100644 index 00000000000..8956b2fc159 --- /dev/null +++ b/tests/baselines/reference/pathsValidation2.errors.txt @@ -0,0 +1,6 @@ +error TS5064: Substitution '1' for pattern '*' has incorrect type, expected 'string', got 'number'. + + +!!! error TS5064: Substitution '1' for pattern '*' has incorrect type, expected 'string', got 'number'. +==== tests/cases/compiler/a.ts (0 errors) ==== + let x = 1; \ No newline at end of file diff --git a/tests/baselines/reference/pathsValidation2.js b/tests/baselines/reference/pathsValidation2.js new file mode 100644 index 00000000000..bfffc647f63 --- /dev/null +++ b/tests/baselines/reference/pathsValidation2.js @@ -0,0 +1,5 @@ +//// [a.ts] +let x = 1; + +//// [a.js] +var x = 1; diff --git a/tests/baselines/reference/privacyGloImportParseErrors.errors.txt b/tests/baselines/reference/privacyGloImportParseErrors.errors.txt index 05bb3559f1a..6f6c2e5f865 100644 --- a/tests/baselines/reference/privacyGloImportParseErrors.errors.txt +++ b/tests/baselines/reference/privacyGloImportParseErrors.errors.txt @@ -14,12 +14,11 @@ tests/cases/compiler/privacyGloImportParseErrors.ts(125,45): error TS1147: Impor tests/cases/compiler/privacyGloImportParseErrors.ts(133,9): error TS1038: A 'declare' modifier cannot be used in an already ambient context. tests/cases/compiler/privacyGloImportParseErrors.ts(133,24): error TS2435: Ambient modules cannot be nested in other modules or namespaces. tests/cases/compiler/privacyGloImportParseErrors.ts(138,16): error TS2435: Ambient modules cannot be nested in other modules or namespaces. -tests/cases/compiler/privacyGloImportParseErrors.ts(141,12): error TS2664: Invalid module name in augmentation, module 'abc3' cannot be found. tests/cases/compiler/privacyGloImportParseErrors.ts(146,25): error TS1147: Import declarations in a namespace cannot reference a module. tests/cases/compiler/privacyGloImportParseErrors.ts(149,29): error TS1147: Import declarations in a namespace cannot reference a module. -==== tests/cases/compiler/privacyGloImportParseErrors.ts (19 errors) ==== +==== tests/cases/compiler/privacyGloImportParseErrors.ts (18 errors) ==== module m1 { export module m1_M1_public { export class c1 { @@ -193,8 +192,6 @@ tests/cases/compiler/privacyGloImportParseErrors.ts(149,29): error TS1147: Impor } } module "abc3" { - ~~~~~~ -!!! error TS2664: Invalid module name in augmentation, module 'abc3' cannot be found. } } diff --git a/tests/baselines/reference/propertyNamesWithStringLiteral.symbols b/tests/baselines/reference/propertyNamesWithStringLiteral.symbols index 3844c0891e8..1851629c134 100644 --- a/tests/baselines/reference/propertyNamesWithStringLiteral.symbols +++ b/tests/baselines/reference/propertyNamesWithStringLiteral.symbols @@ -38,16 +38,16 @@ var a = Color.namedColors["azure"]; var a = Color.namedColors.blue; // Should not error >a : Symbol(a, Decl(propertyNamesWithStringLiteral.ts, 12, 3), Decl(propertyNamesWithStringLiteral.ts, 13, 3), Decl(propertyNamesWithStringLiteral.ts, 14, 3)) ->Color.namedColors.blue : Symbol(NamedColors."blue", Decl(propertyNamesWithStringLiteral.ts, 5, 18)) +>Color.namedColors.blue : Symbol(NamedColors["blue"], Decl(propertyNamesWithStringLiteral.ts, 5, 18)) >Color.namedColors : Symbol(Color.namedColors, Decl(propertyNamesWithStringLiteral.ts, 10, 14)) >Color : Symbol(Color, Decl(propertyNamesWithStringLiteral.ts, 8, 1)) >namedColors : Symbol(Color.namedColors, Decl(propertyNamesWithStringLiteral.ts, 10, 14)) ->blue : Symbol(NamedColors."blue", Decl(propertyNamesWithStringLiteral.ts, 5, 18)) +>blue : Symbol(NamedColors["blue"], Decl(propertyNamesWithStringLiteral.ts, 5, 18)) var a = Color.namedColors["pale blue"]; // should not error >a : Symbol(a, Decl(propertyNamesWithStringLiteral.ts, 12, 3), Decl(propertyNamesWithStringLiteral.ts, 13, 3), Decl(propertyNamesWithStringLiteral.ts, 14, 3)) >Color.namedColors : Symbol(Color.namedColors, Decl(propertyNamesWithStringLiteral.ts, 10, 14)) >Color : Symbol(Color, Decl(propertyNamesWithStringLiteral.ts, 8, 1)) >namedColors : Symbol(Color.namedColors, Decl(propertyNamesWithStringLiteral.ts, 10, 14)) ->"pale blue" : Symbol(NamedColors."pale blue", Decl(propertyNamesWithStringLiteral.ts, 6, 19)) +>"pale blue" : Symbol(NamedColors["pale blue"], Decl(propertyNamesWithStringLiteral.ts, 6, 19)) diff --git a/tests/baselines/reference/quotedPropertyName3.symbols b/tests/baselines/reference/quotedPropertyName3.symbols index 2b09da7f6cc..813cf23e336 100644 --- a/tests/baselines/reference/quotedPropertyName3.symbols +++ b/tests/baselines/reference/quotedPropertyName3.symbols @@ -9,7 +9,7 @@ class Test { var x = () => this["prop1"]; >x : Symbol(x, Decl(quotedPropertyName3.ts, 3, 11)) >this : Symbol(Test, Decl(quotedPropertyName3.ts, 0, 0)) ->"prop1" : Symbol(Test."prop1", Decl(quotedPropertyName3.ts, 0, 12)) +>"prop1" : Symbol(Test["prop1"], Decl(quotedPropertyName3.ts, 0, 12)) var y: number = x(); >y : Symbol(y, Decl(quotedPropertyName3.ts, 4, 11)) diff --git a/tests/baselines/reference/reExportGlobalDeclaration1.errors.txt b/tests/baselines/reference/reExportGlobalDeclaration1.errors.txt index 0ebeed05b28..0d83d8b94ee 100644 --- a/tests/baselines/reference/reExportGlobalDeclaration1.errors.txt +++ b/tests/baselines/reference/reExportGlobalDeclaration1.errors.txt @@ -1,15 +1,15 @@ -tests/cases/compiler/file2.ts(1,9): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(1,12): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(2,9): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(2,13): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(4,9): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(4,12): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(5,9): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(5,12): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(8,9): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(9,9): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(10,9): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(11,9): error TS2661: Cannot re-export name that is not defined in the module. +tests/cases/compiler/file2.ts(1,9): error TS2661: Cannot export 'x'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(1,12): error TS2661: Cannot export 'x'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(2,9): error TS2661: Cannot export 'x1'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(2,13): error TS2661: Cannot export 'x1'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(4,9): error TS2661: Cannot export 'a'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(4,12): error TS2661: Cannot export 'a'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(5,9): error TS2661: Cannot export 'b'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(5,12): error TS2661: Cannot export 'b'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(8,9): error TS2661: Cannot export 'x'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(9,9): error TS2661: Cannot export 'x1'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(10,9): error TS2661: Cannot export 'a'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(11,9): error TS2661: Cannot export 'b'. Only local declarations can be exported from a module. ==== tests/cases/compiler/file1.d.ts (0 errors) ==== @@ -21,37 +21,37 @@ tests/cases/compiler/file2.ts(11,9): error TS2661: Cannot re-export name that is ==== tests/cases/compiler/file2.ts (12 errors) ==== export {x, x as y}; ~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'x'. Only local declarations can be exported from a module. ~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'x'. Only local declarations can be exported from a module. export {x1, x1 as y1}; ~~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'x1'. Only local declarations can be exported from a module. ~~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'x1'. Only local declarations can be exported from a module. export {a, a as a1}; ~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'a'. Only local declarations can be exported from a module. ~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'a'. Only local declarations can be exported from a module. export {b, b as b1}; ~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'b'. Only local declarations can be exported from a module. ~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'b'. Only local declarations can be exported from a module. export {x as z}; ~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'x'. Only local declarations can be exported from a module. export {x1 as z1}; ~~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'x1'. Only local declarations can be exported from a module. export {a as a2}; ~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'a'. Only local declarations can be exported from a module. export {b as b2}; ~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'b'. Only local declarations can be exported from a module. \ No newline at end of file diff --git a/tests/baselines/reference/reExportGlobalDeclaration2.errors.txt b/tests/baselines/reference/reExportGlobalDeclaration2.errors.txt index 17a3e2ad565..b24a52aff49 100644 --- a/tests/baselines/reference/reExportGlobalDeclaration2.errors.txt +++ b/tests/baselines/reference/reExportGlobalDeclaration2.errors.txt @@ -1,9 +1,9 @@ -tests/cases/compiler/file2.ts(1,9): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(1,13): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(2,9): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(2,13): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(3,9): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(4,9): error TS2661: Cannot re-export name that is not defined in the module. +tests/cases/compiler/file2.ts(1,9): error TS2661: Cannot export 'I1'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(1,13): error TS2661: Cannot export 'I1'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(2,9): error TS2661: Cannot export 'I2'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(2,13): error TS2661: Cannot export 'I2'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(3,9): error TS2661: Cannot export 'I1'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(4,9): error TS2661: Cannot export 'I2'. Only local declarations can be exported from a module. ==== tests/cases/compiler/file1.d.ts (0 errors) ==== @@ -19,17 +19,17 @@ tests/cases/compiler/file2.ts(4,9): error TS2661: Cannot re-export name that is ==== tests/cases/compiler/file2.ts (6 errors) ==== export {I1, I1 as II1}; ~~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'I1'. Only local declarations can be exported from a module. ~~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'I1'. Only local declarations can be exported from a module. export {I2, I2 as II2}; ~~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'I2'. Only local declarations can be exported from a module. ~~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'I2'. Only local declarations can be exported from a module. export {I1 as III1}; ~~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'I1'. Only local declarations can be exported from a module. export {I2 as III2}; ~~ -!!! error TS2661: Cannot re-export name that is not defined in the module. \ No newline at end of file +!!! error TS2661: Cannot export 'I2'. Only local declarations can be exported from a module. \ No newline at end of file diff --git a/tests/baselines/reference/reExportGlobalDeclaration3.errors.txt b/tests/baselines/reference/reExportGlobalDeclaration3.errors.txt index d99c184518c..2f469e80491 100644 --- a/tests/baselines/reference/reExportGlobalDeclaration3.errors.txt +++ b/tests/baselines/reference/reExportGlobalDeclaration3.errors.txt @@ -1,9 +1,9 @@ -tests/cases/compiler/file2.ts(1,9): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(1,14): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(2,9): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(2,14): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(3,9): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(4,9): error TS2661: Cannot re-export name that is not defined in the module. +tests/cases/compiler/file2.ts(1,9): error TS2661: Cannot export 'NS1'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(1,14): error TS2661: Cannot export 'NS1'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(2,9): error TS2661: Cannot export 'NS2'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(2,14): error TS2661: Cannot export 'NS2'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(3,9): error TS2661: Cannot export 'NS1'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(4,9): error TS2661: Cannot export 'NS2'. Only local declarations can be exported from a module. ==== tests/cases/compiler/file1.d.ts (0 errors) ==== @@ -19,17 +19,17 @@ tests/cases/compiler/file2.ts(4,9): error TS2661: Cannot re-export name that is ==== tests/cases/compiler/file2.ts (6 errors) ==== export {NS1, NS1 as NNS1}; ~~~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'NS1'. Only local declarations can be exported from a module. ~~~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'NS1'. Only local declarations can be exported from a module. export {NS2, NS2 as NNS2}; ~~~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'NS2'. Only local declarations can be exported from a module. ~~~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'NS2'. Only local declarations can be exported from a module. export {NS1 as NNNS1}; ~~~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'NS1'. Only local declarations can be exported from a module. export {NS2 as NNNS2}; ~~~ -!!! error TS2661: Cannot re-export name that is not defined in the module. \ No newline at end of file +!!! error TS2661: Cannot export 'NS2'. Only local declarations can be exported from a module. \ No newline at end of file diff --git a/tests/baselines/reference/reExportGlobalDeclaration4.errors.txt b/tests/baselines/reference/reExportGlobalDeclaration4.errors.txt index 5e250a5fc57..a3b58a276ae 100644 --- a/tests/baselines/reference/reExportGlobalDeclaration4.errors.txt +++ b/tests/baselines/reference/reExportGlobalDeclaration4.errors.txt @@ -1,9 +1,9 @@ -tests/cases/compiler/file2.ts(1,9): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(1,15): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(2,9): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(2,15): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(3,9): error TS2661: Cannot re-export name that is not defined in the module. -tests/cases/compiler/file2.ts(4,9): error TS2661: Cannot re-export name that is not defined in the module. +tests/cases/compiler/file2.ts(1,9): error TS2661: Cannot export 'Cls1'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(1,15): error TS2661: Cannot export 'Cls1'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(2,9): error TS2661: Cannot export 'Cls2'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(2,15): error TS2661: Cannot export 'Cls2'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(3,9): error TS2661: Cannot export 'Cls1'. Only local declarations can be exported from a module. +tests/cases/compiler/file2.ts(4,9): error TS2661: Cannot export 'Cls2'. Only local declarations can be exported from a module. ==== tests/cases/compiler/file1.d.ts (0 errors) ==== @@ -19,17 +19,17 @@ tests/cases/compiler/file2.ts(4,9): error TS2661: Cannot re-export name that is ==== tests/cases/compiler/file2.ts (6 errors) ==== export {Cls1, Cls1 as CCls1}; ~~~~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'Cls1'. Only local declarations can be exported from a module. ~~~~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'Cls1'. Only local declarations can be exported from a module. export {Cls2, Cls2 as CCls2}; ~~~~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'Cls2'. Only local declarations can be exported from a module. ~~~~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'Cls2'. Only local declarations can be exported from a module. export {Cls1 as CCCls1}; ~~~~ -!!! error TS2661: Cannot re-export name that is not defined in the module. +!!! error TS2661: Cannot export 'Cls1'. Only local declarations can be exported from a module. export {Cls2 as CCCls2}; ~~~~ -!!! error TS2661: Cannot re-export name that is not defined in the module. \ No newline at end of file +!!! error TS2661: Cannot export 'Cls2'. Only local declarations can be exported from a module. \ No newline at end of file diff --git a/tests/baselines/reference/reExportUndefined1.errors.txt b/tests/baselines/reference/reExportUndefined1.errors.txt index ff3259ae37e..5042b4c4c0c 100644 --- a/tests/baselines/reference/reExportUndefined1.errors.txt +++ b/tests/baselines/reference/reExportUndefined1.errors.txt @@ -1,8 +1,8 @@ -tests/cases/compiler/a.ts(2,10): error TS2661: Cannot re-export name that is not defined in the module. +tests/cases/compiler/a.ts(2,10): error TS2661: Cannot export 'undefined'. Only local declarations can be exported from a module. ==== tests/cases/compiler/a.ts (1 errors) ==== export { undefined }; ~~~~~~~~~ -!!! error TS2661: Cannot re-export name that is not defined in the module. \ No newline at end of file +!!! error TS2661: Cannot export 'undefined'. Only local declarations can be exported from a module. \ No newline at end of file diff --git a/tests/baselines/reference/reachabilityChecks5.errors.txt b/tests/baselines/reference/reachabilityChecks5.errors.txt index 147dbe264a3..4a894261a3d 100644 --- a/tests/baselines/reference/reachabilityChecks5.errors.txt +++ b/tests/baselines/reference/reachabilityChecks5.errors.txt @@ -6,11 +6,12 @@ tests/cases/compiler/reachabilityChecks5.ts(52,17): error TS7030: Not all code p tests/cases/compiler/reachabilityChecks5.ts(80,17): error TS7030: Not all code paths return a value. tests/cases/compiler/reachabilityChecks5.ts(86,13): error TS7027: Unreachable code detected. tests/cases/compiler/reachabilityChecks5.ts(94,17): error TS7030: Not all code paths return a value. +tests/cases/compiler/reachabilityChecks5.ts(97,13): error TS7027: Unreachable code detected. tests/cases/compiler/reachabilityChecks5.ts(116,18): error TS7030: Not all code paths return a value. tests/cases/compiler/reachabilityChecks5.ts(123,13): error TS7027: Unreachable code detected. -==== tests/cases/compiler/reachabilityChecks5.ts (10 errors) ==== +==== tests/cases/compiler/reachabilityChecks5.ts (11 errors) ==== function f0(x): number { while (true); @@ -124,6 +125,8 @@ tests/cases/compiler/reachabilityChecks5.ts(123,13): error TS7027: Unreachable c try { while (false) { return 1; + ~~~~~~ +!!! error TS7027: Unreachable code detected. } } catch (e) { diff --git a/tests/baselines/reference/reachabilityChecks6.errors.txt b/tests/baselines/reference/reachabilityChecks6.errors.txt index 38e72def8c6..24832d9ab38 100644 --- a/tests/baselines/reference/reachabilityChecks6.errors.txt +++ b/tests/baselines/reference/reachabilityChecks6.errors.txt @@ -5,11 +5,12 @@ tests/cases/compiler/reachabilityChecks6.ts(52,10): error TS7030: Not all code p tests/cases/compiler/reachabilityChecks6.ts(80,10): error TS7030: Not all code paths return a value. tests/cases/compiler/reachabilityChecks6.ts(86,13): error TS7027: Unreachable code detected. tests/cases/compiler/reachabilityChecks6.ts(94,10): error TS7030: Not all code paths return a value. +tests/cases/compiler/reachabilityChecks6.ts(97,13): error TS7027: Unreachable code detected. tests/cases/compiler/reachabilityChecks6.ts(116,10): error TS7030: Not all code paths return a value. tests/cases/compiler/reachabilityChecks6.ts(123,13): error TS7027: Unreachable code detected. -==== tests/cases/compiler/reachabilityChecks6.ts (9 errors) ==== +==== tests/cases/compiler/reachabilityChecks6.ts (10 errors) ==== function f0(x) { while (true); @@ -121,6 +122,8 @@ tests/cases/compiler/reachabilityChecks6.ts(123,13): error TS7027: Unreachable c try { while (false) { return 1; + ~~~~~~ +!!! error TS7027: Unreachable code detected. } } catch (e) { diff --git a/tests/baselines/reference/restElementWithAssignmentPattern5.types b/tests/baselines/reference/restElementWithAssignmentPattern5.types index e3934c31197..c5cbc9ad206 100644 --- a/tests/baselines/reference/restElementWithAssignmentPattern5.types +++ b/tests/baselines/reference/restElementWithAssignmentPattern5.types @@ -7,7 +7,7 @@ var s: string, s2: string; >[...[s, s2]] = ["", ""] : string[] >[...[s, s2]] : string[] >...[s, s2] : string ->[s, s2] : string[] +>[s, s2] : [string, string] >s : string >s2 : string >["", ""] : string[] diff --git a/tests/baselines/reference/singleLineCommentInConciseArrowFunctionES3.js b/tests/baselines/reference/singleLineCommentInConciseArrowFunctionES3.js new file mode 100644 index 00000000000..db4ab7950eb --- /dev/null +++ b/tests/baselines/reference/singleLineCommentInConciseArrowFunctionES3.js @@ -0,0 +1,14 @@ +//// [singleLineCommentInConciseArrowFunctionES3.ts] +function test() { + return () => + // some comments here; + 123; +} + +//// [singleLineCommentInConciseArrowFunctionES3.js] +function test() { + return function () { + // some comments here; + return 123; + }; +} diff --git a/tests/baselines/reference/singleLineCommentInConciseArrowFunctionES3.symbols b/tests/baselines/reference/singleLineCommentInConciseArrowFunctionES3.symbols new file mode 100644 index 00000000000..cb53d292885 --- /dev/null +++ b/tests/baselines/reference/singleLineCommentInConciseArrowFunctionES3.symbols @@ -0,0 +1,8 @@ +=== tests/cases/compiler/singleLineCommentInConciseArrowFunctionES3.ts === +function test() { +>test : Symbol(test, Decl(singleLineCommentInConciseArrowFunctionES3.ts, 0, 0)) + + return () => + // some comments here; + 123; +} diff --git a/tests/baselines/reference/singleLineCommentInConciseArrowFunctionES3.types b/tests/baselines/reference/singleLineCommentInConciseArrowFunctionES3.types new file mode 100644 index 00000000000..e8c449e7bb8 --- /dev/null +++ b/tests/baselines/reference/singleLineCommentInConciseArrowFunctionES3.types @@ -0,0 +1,11 @@ +=== tests/cases/compiler/singleLineCommentInConciseArrowFunctionES3.ts === +function test() { +>test : () => () => number + + return () => +>() => // some comments here; 123 : () => number + + // some comments here; + 123; +>123 : number +} diff --git a/tests/baselines/reference/sourceMapValidationDestructuringForOfArrayBindingPattern2.types b/tests/baselines/reference/sourceMapValidationDestructuringForOfArrayBindingPattern2.types index 33b503d0d8f..78cb778b545 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringForOfArrayBindingPattern2.types +++ b/tests/baselines/reference/sourceMapValidationDestructuringForOfArrayBindingPattern2.types @@ -93,7 +93,7 @@ let numberA3: number, robotAInfo: (number | string)[], multiRobotAInfo: (string >multiRobotAInfo : (string | [string, string])[] for ([, nameA] of robots) { ->[, nameA] : string[] +>[, nameA] : [undefined, string] > : undefined >nameA : string >robots : [number, string, string][] @@ -106,7 +106,7 @@ for ([, nameA] of robots) { >nameA : string } for ([, nameA] of getRobots()) { ->[, nameA] : string[] +>[, nameA] : [undefined, string] > : undefined >nameA : string >getRobots() : [number, string, string][] @@ -120,7 +120,7 @@ for ([, nameA] of getRobots()) { >nameA : string } for ([, nameA] of [robotA, robotB]) { ->[, nameA] : string[] +>[, nameA] : [undefined, string] > : undefined >nameA : string >[robotA, robotB] : [number, string, string][] @@ -135,9 +135,9 @@ for ([, nameA] of [robotA, robotB]) { >nameA : string } for ([, [primarySkillA, secondarySkillA]] of multiRobots) { ->[, [primarySkillA, secondarySkillA]] : string[][] +>[, [primarySkillA, secondarySkillA]] : [undefined, [string, string]] > : undefined ->[primarySkillA, secondarySkillA] : string[] +>[primarySkillA, secondarySkillA] : [string, string] >primarySkillA : string >secondarySkillA : string >multiRobots : [string, [string, string]][] @@ -150,9 +150,9 @@ for ([, [primarySkillA, secondarySkillA]] of multiRobots) { >primarySkillA : string } for ([, [primarySkillA, secondarySkillA]] of getMultiRobots()) { ->[, [primarySkillA, secondarySkillA]] : string[][] +>[, [primarySkillA, secondarySkillA]] : [undefined, [string, string]] > : undefined ->[primarySkillA, secondarySkillA] : string[] +>[primarySkillA, secondarySkillA] : [string, string] >primarySkillA : string >secondarySkillA : string >getMultiRobots() : [string, [string, string]][] @@ -166,9 +166,9 @@ for ([, [primarySkillA, secondarySkillA]] of getMultiRobots()) { >primarySkillA : string } for ([, [primarySkillA, secondarySkillA]] of [multiRobotA, multiRobotB]) { ->[, [primarySkillA, secondarySkillA]] : string[][] +>[, [primarySkillA, secondarySkillA]] : [undefined, [string, string]] > : undefined ->[primarySkillA, secondarySkillA] : string[] +>[primarySkillA, secondarySkillA] : [string, string] >primarySkillA : string >secondarySkillA : string >[multiRobotA, multiRobotB] : [string, [string, string]][] @@ -184,7 +184,7 @@ for ([, [primarySkillA, secondarySkillA]] of [multiRobotA, multiRobotB]) { } for ([numberB] of robots) { ->[numberB] : number[] +>[numberB] : [number] >numberB : number >robots : [number, string, string][] @@ -196,7 +196,7 @@ for ([numberB] of robots) { >numberB : number } for ([numberB] of getRobots()) { ->[numberB] : number[] +>[numberB] : [number] >numberB : number >getRobots() : [number, string, string][] >getRobots : () => [number, string, string][] @@ -209,7 +209,7 @@ for ([numberB] of getRobots()) { >numberB : number } for ([numberB] of [robotA, robotB]) { ->[numberB] : number[] +>[numberB] : [number] >numberB : number >[robotA, robotB] : [number, string, string][] >robotA : [number, string, string] @@ -223,7 +223,7 @@ for ([numberB] of [robotA, robotB]) { >numberB : number } for ([nameB] of multiRobots) { ->[nameB] : string[] +>[nameB] : [string] >nameB : string >multiRobots : [string, [string, string]][] @@ -235,7 +235,7 @@ for ([nameB] of multiRobots) { >nameB : string } for ([nameB] of getMultiRobots()) { ->[nameB] : string[] +>[nameB] : [string] >nameB : string >getMultiRobots() : [string, [string, string]][] >getMultiRobots : () => [string, [string, string]][] @@ -248,7 +248,7 @@ for ([nameB] of getMultiRobots()) { >nameB : string } for ([nameB] of [multiRobotA, multiRobotB]) { ->[nameB] : string[] +>[nameB] : [string] >nameB : string >[multiRobotA, multiRobotB] : [string, [string, string]][] >multiRobotA : [string, [string, string]] @@ -263,7 +263,7 @@ for ([nameB] of [multiRobotA, multiRobotB]) { } for ([numberA2, nameA2, skillA2] of robots) { ->[numberA2, nameA2, skillA2] : (number | string)[] +>[numberA2, nameA2, skillA2] : [number, string, string] >numberA2 : number >nameA2 : string >skillA2 : string @@ -277,7 +277,7 @@ for ([numberA2, nameA2, skillA2] of robots) { >nameA2 : string } for ([numberA2, nameA2, skillA2] of getRobots()) { ->[numberA2, nameA2, skillA2] : (number | string)[] +>[numberA2, nameA2, skillA2] : [number, string, string] >numberA2 : number >nameA2 : string >skillA2 : string @@ -292,7 +292,7 @@ for ([numberA2, nameA2, skillA2] of getRobots()) { >nameA2 : string } for ([numberA2, nameA2, skillA2] of [robotA, robotB]) { ->[numberA2, nameA2, skillA2] : (number | string)[] +>[numberA2, nameA2, skillA2] : [number, string, string] >numberA2 : number >nameA2 : string >skillA2 : string @@ -308,9 +308,9 @@ for ([numberA2, nameA2, skillA2] of [robotA, robotB]) { >nameA2 : string } for ([nameMA, [primarySkillA, secondarySkillA]] of multiRobots) { ->[nameMA, [primarySkillA, secondarySkillA]] : (string | string[])[] +>[nameMA, [primarySkillA, secondarySkillA]] : [string, [string, string]] >nameMA : string ->[primarySkillA, secondarySkillA] : string[] +>[primarySkillA, secondarySkillA] : [string, string] >primarySkillA : string >secondarySkillA : string >multiRobots : [string, [string, string]][] @@ -323,9 +323,9 @@ for ([nameMA, [primarySkillA, secondarySkillA]] of multiRobots) { >nameMA : string } for ([nameMA, [primarySkillA, secondarySkillA]] of getMultiRobots()) { ->[nameMA, [primarySkillA, secondarySkillA]] : (string | string[])[] +>[nameMA, [primarySkillA, secondarySkillA]] : [string, [string, string]] >nameMA : string ->[primarySkillA, secondarySkillA] : string[] +>[primarySkillA, secondarySkillA] : [string, string] >primarySkillA : string >secondarySkillA : string >getMultiRobots() : [string, [string, string]][] @@ -339,9 +339,9 @@ for ([nameMA, [primarySkillA, secondarySkillA]] of getMultiRobots()) { >nameMA : string } for ([nameMA, [primarySkillA, secondarySkillA]] of [multiRobotA, multiRobotB]) { ->[nameMA, [primarySkillA, secondarySkillA]] : (string | string[])[] +>[nameMA, [primarySkillA, secondarySkillA]] : [string, [string, string]] >nameMA : string ->[primarySkillA, secondarySkillA] : string[] +>[primarySkillA, secondarySkillA] : [string, string] >primarySkillA : string >secondarySkillA : string >[multiRobotA, multiRobotB] : [string, [string, string]][] diff --git a/tests/baselines/reference/sourceMapValidationDestructuringForOfArrayBindingPatternDefaultValues2.types b/tests/baselines/reference/sourceMapValidationDestructuringForOfArrayBindingPatternDefaultValues2.types index 14189ad9d81..5f580ad38f4 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringForOfArrayBindingPatternDefaultValues2.types +++ b/tests/baselines/reference/sourceMapValidationDestructuringForOfArrayBindingPatternDefaultValues2.types @@ -93,7 +93,7 @@ let numberA3: number, robotAInfo: (number | string)[], multiRobotAInfo: (string >multiRobotAInfo : (string | [string, string])[] for ([, nameA = "noName"] of robots) { ->[, nameA = "noName"] : string[] +>[, nameA = "noName"] : [undefined, string] > : undefined >nameA = "noName" : string >nameA : string @@ -108,7 +108,7 @@ for ([, nameA = "noName"] of robots) { >nameA : string } for ([, nameA = "noName"] of getRobots()) { ->[, nameA = "noName"] : string[] +>[, nameA = "noName"] : [undefined, string] > : undefined >nameA = "noName" : string >nameA : string @@ -124,7 +124,7 @@ for ([, nameA = "noName"] of getRobots()) { >nameA : string } for ([, nameA = "noName"] of [robotA, robotB]) { ->[, nameA = "noName"] : string[] +>[, nameA = "noName"] : [undefined, string] > : undefined >nameA = "noName" : string >nameA : string @@ -141,7 +141,7 @@ for ([, nameA = "noName"] of [robotA, robotB]) { >nameA : string } for ([, [ ->[, [ primarySkillA = "primary", secondarySkillA = "secondary"] = ["skill1", "skill2"]] : [string, string][] +>[, [ primarySkillA = "primary", secondarySkillA = "secondary"] = ["skill1", "skill2"]] : [undefined, [string, string]] > : undefined >[ primarySkillA = "primary", secondarySkillA = "secondary"] = ["skill1", "skill2"] : [string, string] >[ primarySkillA = "primary", secondarySkillA = "secondary"] : [string, string] @@ -170,7 +170,7 @@ for ([, [ >primarySkillA : string } for ([, [ ->[, [ primarySkillA = "primary", secondarySkillA = "secondary"] = ["skill1", "skill2"]] : [string, string][] +>[, [ primarySkillA = "primary", secondarySkillA = "secondary"] = ["skill1", "skill2"]] : [undefined, [string, string]] > : undefined >[ primarySkillA = "primary", secondarySkillA = "secondary"] = ["skill1", "skill2"] : [string, string] >[ primarySkillA = "primary", secondarySkillA = "secondary"] : [string, string] @@ -200,7 +200,7 @@ for ([, [ >primarySkillA : string } for ([, [ ->[, [ primarySkillA = "primary", secondarySkillA = "secondary"] = ["skill1", "skill2"]] : [string, string][] +>[, [ primarySkillA = "primary", secondarySkillA = "secondary"] = ["skill1", "skill2"]] : [undefined, [string, string]] > : undefined >[ primarySkillA = "primary", secondarySkillA = "secondary"] = ["skill1", "skill2"] : [string, string] >[ primarySkillA = "primary", secondarySkillA = "secondary"] : [string, string] @@ -232,7 +232,7 @@ for ([, [ } for ([numberB = -1] of robots) { ->[numberB = -1] : number[] +>[numberB = -1] : [number] >numberB = -1 : number >numberB : number >-1 : number @@ -247,7 +247,7 @@ for ([numberB = -1] of robots) { >numberB : number } for ([numberB = -1] of getRobots()) { ->[numberB = -1] : number[] +>[numberB = -1] : [number] >numberB = -1 : number >numberB : number >-1 : number @@ -263,7 +263,7 @@ for ([numberB = -1] of getRobots()) { >numberB : number } for ([numberB = -1] of [robotA, robotB]) { ->[numberB = -1] : number[] +>[numberB = -1] : [number] >numberB = -1 : number >numberB : number >-1 : number @@ -280,7 +280,7 @@ for ([numberB = -1] of [robotA, robotB]) { >numberB : number } for ([nameB = "noName"] of multiRobots) { ->[nameB = "noName"] : string[] +>[nameB = "noName"] : [string] >nameB = "noName" : string >nameB : string >"noName" : string @@ -294,7 +294,7 @@ for ([nameB = "noName"] of multiRobots) { >nameB : string } for ([nameB = "noName"] of getMultiRobots()) { ->[nameB = "noName"] : string[] +>[nameB = "noName"] : [string] >nameB = "noName" : string >nameB : string >"noName" : string @@ -309,7 +309,7 @@ for ([nameB = "noName"] of getMultiRobots()) { >nameB : string } for ([nameB = "noName"] of [multiRobotA, multiRobotB]) { ->[nameB = "noName"] : string[] +>[nameB = "noName"] : [string] >nameB = "noName" : string >nameB : string >"noName" : string @@ -326,7 +326,7 @@ for ([nameB = "noName"] of [multiRobotA, multiRobotB]) { } for ([numberA2 = -1, nameA2 = "noName", skillA2 = "skill"] of robots) { ->[numberA2 = -1, nameA2 = "noName", skillA2 = "skill"] : (number | string)[] +>[numberA2 = -1, nameA2 = "noName", skillA2 = "skill"] : [number, string, string] >numberA2 = -1 : number >numberA2 : number >-1 : number @@ -347,7 +347,7 @@ for ([numberA2 = -1, nameA2 = "noName", skillA2 = "skill"] of robots) { >nameA2 : string } for ([numberA2 = -1, nameA2 = "noName", skillA2 = "skill"] of getRobots()) { ->[numberA2 = -1, nameA2 = "noName", skillA2 = "skill"] : (number | string)[] +>[numberA2 = -1, nameA2 = "noName", skillA2 = "skill"] : [number, string, string] >numberA2 = -1 : number >numberA2 : number >-1 : number @@ -369,7 +369,7 @@ for ([numberA2 = -1, nameA2 = "noName", skillA2 = "skill"] of getRobots()) { >nameA2 : string } for ([numberA2 = -1, nameA2 = "noName", skillA2 = "skill"] of [robotA, robotB]) { ->[numberA2 = -1, nameA2 = "noName", skillA2 = "skill"] : (number | string)[] +>[numberA2 = -1, nameA2 = "noName", skillA2 = "skill"] : [number, string, string] >numberA2 = -1 : number >numberA2 : number >-1 : number @@ -392,7 +392,7 @@ for ([numberA2 = -1, nameA2 = "noName", skillA2 = "skill"] of [robotA, robotB]) >nameA2 : string } for ([nameMA = "noName", [ ->[nameMA = "noName", [ primarySkillA = "primary", secondarySkillA = "secondary"] = ["skill1", "skill2"]] : (string | [string, string])[] +>[nameMA = "noName", [ primarySkillA = "primary", secondarySkillA = "secondary"] = ["skill1", "skill2"]] : [string, [string, string]] >nameMA = "noName" : string >nameMA : string >"noName" : string @@ -423,7 +423,7 @@ for ([nameMA = "noName", [ >nameMA : string } for ([nameMA = "noName", [ ->[nameMA = "noName", [ primarySkillA = "primary", secondarySkillA = "secondary"] = ["skill1", "skill2"]] : (string | [string, string])[] +>[nameMA = "noName", [ primarySkillA = "primary", secondarySkillA = "secondary"] = ["skill1", "skill2"]] : [string, [string, string]] >nameMA = "noName" : string >nameMA : string >"noName" : string @@ -455,7 +455,7 @@ for ([nameMA = "noName", [ >nameMA : string } for ([nameMA = "noName", [ ->[nameMA = "noName", [ primarySkillA = "primary", secondarySkillA = "secondary"] = ["skill1", "skill2"]] : (string | [string, string])[] +>[nameMA = "noName", [ primarySkillA = "primary", secondarySkillA = "secondary"] = ["skill1", "skill2"]] : [string, [string, string]] >nameMA = "noName" : string >nameMA : string >"noName" : string diff --git a/tests/baselines/reference/sourceMapValidationDestructuringForOfObjectBindingPatternDefaultValues2.types b/tests/baselines/reference/sourceMapValidationDestructuringForOfObjectBindingPatternDefaultValues2.types index fe630aafccc..adb5d515fe4 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringForOfObjectBindingPatternDefaultValues2.types +++ b/tests/baselines/reference/sourceMapValidationDestructuringForOfObjectBindingPatternDefaultValues2.types @@ -102,7 +102,7 @@ let name: string, primary: string, secondary: string, skill: string; >skill : string for ({name: nameA = "noName" } of robots) { ->{name: nameA = "noName" } : { name: string; } +>{name: nameA = "noName" } : { name?: string; } >name : Robot >nameA = "noName" : string >nameA : string @@ -117,7 +117,7 @@ for ({name: nameA = "noName" } of robots) { >nameA : string } for ({name: nameA = "noName" } of getRobots()) { ->{name: nameA = "noName" } : { name: string; } +>{name: nameA = "noName" } : { name?: string; } >name : Robot >nameA = "noName" : string >nameA : string @@ -133,7 +133,7 @@ for ({name: nameA = "noName" } of getRobots()) { >nameA : string } for ({name: nameA = "noName" } of [{ name: "mower", skill: "mowing" }, { name: "trimmer", skill: "trimming" }]) { ->{name: nameA = "noName" } : { name: string; } +>{name: nameA = "noName" } : { name?: string; } >name : { name: string; skill: string; } >nameA = "noName" : string >nameA : string @@ -158,7 +158,7 @@ for ({name: nameA = "noName" } of [{ name: "mower", skill: "mowing" }, { name: " >nameA : string } for ({ skills: { primary: primaryA = "primary", secondary: secondaryA = "secondary" } = ->{ skills: { primary: primaryA = "primary", secondary: secondaryA = "secondary" } = { primary: "nosKill", secondary: "noSkill" } } : { skills: { primary?: string; secondary?: string; }; } +>{ skills: { primary: primaryA = "primary", secondary: secondaryA = "secondary" } = { primary: "nosKill", secondary: "noSkill" } } : { skills?: { primary?: string; secondary?: string; }; } >skills : MultiRobot >{ primary: primaryA = "primary", secondary: secondaryA = "secondary" } = { primary: "nosKill", secondary: "noSkill" } : { primary?: string; secondary?: string; } >{ primary: primaryA = "primary", secondary: secondaryA = "secondary" } : { primary?: string; secondary?: string; } @@ -187,7 +187,7 @@ for ({ skills: { primary: primaryA = "primary", secondary: secondaryA = "seconda >primaryA : string } for ({ skills: { primary: primaryA = "primary", secondary: secondaryA = "secondary" } = ->{ skills: { primary: primaryA = "primary", secondary: secondaryA = "secondary" } = { primary: "nosKill", secondary: "noSkill" } } : { skills: { primary?: string; secondary?: string; }; } +>{ skills: { primary: primaryA = "primary", secondary: secondaryA = "secondary" } = { primary: "nosKill", secondary: "noSkill" } } : { skills?: { primary?: string; secondary?: string; }; } >skills : MultiRobot >{ primary: primaryA = "primary", secondary: secondaryA = "secondary" } = { primary: "nosKill", secondary: "noSkill" } : { primary?: string; secondary?: string; } >{ primary: primaryA = "primary", secondary: secondaryA = "secondary" } : { primary?: string; secondary?: string; } @@ -217,7 +217,7 @@ for ({ skills: { primary: primaryA = "primary", secondary: secondaryA = "seconda >primaryA : string } for ({ skills: { primary: primaryA = "primary", secondary: secondaryA = "secondary" } = ->{ skills: { primary: primaryA = "primary", secondary: secondaryA = "secondary" } = { primary: "nosKill", secondary: "noSkill" } } : { skills: { primary?: string; secondary?: string; }; } +>{ skills: { primary: primaryA = "primary", secondary: secondaryA = "secondary" } = { primary: "nosKill", secondary: "noSkill" } } : { skills?: { primary?: string; secondary?: string; }; } >skills : MultiRobot >{ primary: primaryA = "primary", secondary: secondaryA = "secondary" } = { primary: "nosKill", secondary: "noSkill" } : { primary?: string; secondary?: string; } >{ primary: primaryA = "primary", secondary: secondaryA = "secondary" } : { primary?: string; secondary?: string; } @@ -271,7 +271,7 @@ for ({ skills: { primary: primaryA = "primary", secondary: secondaryA = "seconda } for ({ name = "noName" } of robots) { ->{ name = "noName" } : { name: string; } +>{ name = "noName" } : { name?: string; } >name : Robot >robots : Robot[] @@ -283,7 +283,7 @@ for ({ name = "noName" } of robots) { >nameA : string } for ({ name = "noName" } of getRobots()) { ->{ name = "noName" } : { name: string; } +>{ name = "noName" } : { name?: string; } >name : Robot >getRobots() : Robot[] >getRobots : () => Robot[] @@ -296,7 +296,7 @@ for ({ name = "noName" } of getRobots()) { >nameA : string } for ({ name = "noName" } of [{ name: "mower", skill: "mowing" }, { name: "trimmer", skill: "trimming" }]) { ->{ name = "noName" } : { name: string; } +>{ name = "noName" } : { name?: string; } >name : { name: string; skill: string; } >[{ name: "mower", skill: "mowing" }, { name: "trimmer", skill: "trimming" }] : { name: string; skill: string; }[] >{ name: "mower", skill: "mowing" } : { name: string; skill: string; } @@ -318,7 +318,7 @@ for ({ name = "noName" } of [{ name: "mower", skill: "mowing" }, { name: "trimme >nameA : string } for ({ ->{ skills: { primary = "primary", secondary = "secondary" } = { primary: "noSkill", secondary: "noSkill" }} : { skills: { primary?: string; secondary?: string; }; } +>{ skills: { primary = "primary", secondary = "secondary" } = { primary: "noSkill", secondary: "noSkill" }} : { skills?: { primary?: string; secondary?: string; }; } skills: { >skills : MultiRobot @@ -349,7 +349,7 @@ for ({ >primaryA : string } for ({ ->{ skills: { primary = "primary", secondary = "secondary" } = { primary: "noSkill", secondary: "noSkill" }} : { skills: { primary?: string; secondary?: string; }; } +>{ skills: { primary = "primary", secondary = "secondary" } = { primary: "noSkill", secondary: "noSkill" }} : { skills?: { primary?: string; secondary?: string; }; } skills: { >skills : MultiRobot @@ -381,7 +381,7 @@ for ({ >primaryA : string } for ({ ->{ skills: { primary = "primary", secondary = "secondary" } = { primary: "noSkill", secondary: "noSkill" }} : { skills: { primary?: string; secondary?: string; }; } +>{ skills: { primary = "primary", secondary = "secondary" } = { primary: "noSkill", secondary: "noSkill" }} : { skills?: { primary?: string; secondary?: string; }; } skills: { >skills : { name: string; skills: { primary: string; secondary: string; }; } @@ -434,7 +434,7 @@ for ({ for ({name: nameA = "noName", skill: skillA = "noSkill" } of robots) { ->{name: nameA = "noName", skill: skillA = "noSkill" } : { name: string; skill: string; } +>{name: nameA = "noName", skill: skillA = "noSkill" } : { name?: string; skill?: string; } >name : Robot >nameA = "noName" : string >nameA : string @@ -453,7 +453,7 @@ for ({name: nameA = "noName", skill: skillA = "noSkill" } of robots) { >nameA : string } for ({name: nameA = "noName", skill: skillA = "noSkill" } of getRobots()) { ->{name: nameA = "noName", skill: skillA = "noSkill" } : { name: string; skill: string; } +>{name: nameA = "noName", skill: skillA = "noSkill" } : { name?: string; skill?: string; } >name : Robot >nameA = "noName" : string >nameA : string @@ -473,7 +473,7 @@ for ({name: nameA = "noName", skill: skillA = "noSkill" } of getRobots()) { >nameA : string } for ({name: nameA = "noName", skill: skillA = "noSkill" } of [{ name: "mower", skill: "mowing" }, { name: "trimmer", skill: "trimming" }]) { ->{name: nameA = "noName", skill: skillA = "noSkill" } : { name: string; skill: string; } +>{name: nameA = "noName", skill: skillA = "noSkill" } : { name?: string; skill?: string; } >name : { name: string; skill: string; } >nameA = "noName" : string >nameA : string @@ -502,7 +502,7 @@ for ({name: nameA = "noName", skill: skillA = "noSkill" } of [{ name: "mower", >nameA : string } for ({ ->{ name: nameA = "noName", skills: { primary: primaryA = "primary", secondary: secondaryA = "secondary" } = { primary: "noSkill", secondary: "noSkill" }} : { name: string; skills: { primary?: string; secondary?: string; }; } +>{ name: nameA = "noName", skills: { primary: primaryA = "primary", secondary: secondaryA = "secondary" } = { primary: "noSkill", secondary: "noSkill" }} : { name?: string; skills?: { primary?: string; secondary?: string; }; } name: nameA = "noName", >name : MultiRobot @@ -545,7 +545,7 @@ for ({ >nameA : string } for ({ ->{ name: nameA = "noName", skills: { primary: primaryA = "primary", secondary: secondaryA = "secondary" } = { primary: "noSkill", secondary: "noSkill" }} : { name: string; skills: { primary?: string; secondary?: string; }; } +>{ name: nameA = "noName", skills: { primary: primaryA = "primary", secondary: secondaryA = "secondary" } = { primary: "noSkill", secondary: "noSkill" }} : { name?: string; skills?: { primary?: string; secondary?: string; }; } name: nameA = "noName", >name : MultiRobot @@ -589,7 +589,7 @@ for ({ >nameA : string } for ({ ->{ name: nameA = "noName", skills: { primary: primaryA = "primary", secondary: secondaryA = "secondary" } = { primary: "noSkill", secondary: "noSkill" }} : { name: string; skills: { primary?: string; secondary?: string; }; } +>{ name: nameA = "noName", skills: { primary: primaryA = "primary", secondary: secondaryA = "secondary" } = { primary: "noSkill", secondary: "noSkill" }} : { name?: string; skills?: { primary?: string; secondary?: string; }; } name: nameA = "noName", >name : MultiRobot @@ -655,7 +655,7 @@ for ({ } for ({ name = "noName", skill = "noSkill" } of robots) { ->{ name = "noName", skill = "noSkill" } : { name: string; skill: string; } +>{ name = "noName", skill = "noSkill" } : { name?: string; skill?: string; } >name : Robot >skill : Robot >robots : Robot[] @@ -668,7 +668,7 @@ for ({ name = "noName", skill = "noSkill" } of robots) { >nameA : string } for ({ name = "noName", skill = "noSkill" } of getRobots()) { ->{ name = "noName", skill = "noSkill" } : { name: string; skill: string; } +>{ name = "noName", skill = "noSkill" } : { name?: string; skill?: string; } >name : Robot >skill : Robot >getRobots() : Robot[] @@ -682,7 +682,7 @@ for ({ name = "noName", skill = "noSkill" } of getRobots()) { >nameA : string } for ({ name = "noName", skill = "noSkill" } of [{ name: "mower", skill: "mowing" }, { name: "trimmer", skill: "trimming" }]) { ->{ name = "noName", skill = "noSkill" } : { name: string; skill: string; } +>{ name = "noName", skill = "noSkill" } : { name?: string; skill?: string; } >name : { name: string; skill: string; } >skill : { name: string; skill: string; } >[{ name: "mower", skill: "mowing" }, { name: "trimmer", skill: "trimming" }] : { name: string; skill: string; }[] @@ -705,7 +705,7 @@ for ({ name = "noName", skill = "noSkill" } of [{ name: "mower", skill: "mowing >nameA : string } for ({ ->{ name = "noName", skills: { primary = "primary", secondary = "secondary" } = { primary: "noSkill", secondary: "noSkill" }} : { name: string; skills: { primary?: string; secondary?: string; }; } +>{ name = "noName", skills: { primary = "primary", secondary = "secondary" } = { primary: "noSkill", secondary: "noSkill" }} : { name?: string; skills?: { primary?: string; secondary?: string; }; } name = "noName", >name : MultiRobot @@ -739,7 +739,7 @@ for ({ >nameA : string } for ({ ->{ name = "noName", skills: { primary = "primary", secondary = "secondary" } = { primary: "noSkill", secondary: "noSkill" }} : { name: string; skills: { primary?: string; secondary?: string; }; } +>{ name = "noName", skills: { primary = "primary", secondary = "secondary" } = { primary: "noSkill", secondary: "noSkill" }} : { name?: string; skills?: { primary?: string; secondary?: string; }; } name = "noName", >name : MultiRobot @@ -774,7 +774,7 @@ for ({ >nameA : string } for ({ ->{ name = "noName", skills: { primary = "primary", secondary = "secondary" } = { primary: "noSkill", secondary: "noSkill" }} : { name: string; skills: { primary?: string; secondary?: string; }; } +>{ name = "noName", skills: { primary = "primary", secondary = "secondary" } = { primary: "noSkill", secondary: "noSkill" }} : { name?: string; skills?: { primary?: string; secondary?: string; }; } name = "noName", >name : { name: string; skills: { primary: string; secondary: string; }; } diff --git a/tests/baselines/reference/specializedLambdaTypeArguments.types b/tests/baselines/reference/specializedLambdaTypeArguments.types index 3eb2fbc959e..b10da421044 100644 --- a/tests/baselines/reference/specializedLambdaTypeArguments.types +++ b/tests/baselines/reference/specializedLambdaTypeArguments.types @@ -4,7 +4,7 @@ class X { >A : A prop: X< () => Tany >; ->prop : X<() => Tany> +>prop : X<(() => Tany)> >X : X >Tany : Tany >Tany : Tany diff --git a/tests/baselines/reference/staticMemberWithStringAndNumberNames.symbols b/tests/baselines/reference/staticMemberWithStringAndNumberNames.symbols index 906bd824909..277a88ce38f 100644 --- a/tests/baselines/reference/staticMemberWithStringAndNumberNames.symbols +++ b/tests/baselines/reference/staticMemberWithStringAndNumberNames.symbols @@ -8,30 +8,30 @@ class C { x = C['foo']; >x : Symbol(C.x, Decl(staticMemberWithStringAndNumberNames.ts, 2, 17)) >C : Symbol(C, Decl(staticMemberWithStringAndNumberNames.ts, 0, 0)) ->'foo' : Symbol(C."foo", Decl(staticMemberWithStringAndNumberNames.ts, 0, 9)) +>'foo' : Symbol(C["foo"], Decl(staticMemberWithStringAndNumberNames.ts, 0, 9)) x2 = C['0']; >x2 : Symbol(C.x2, Decl(staticMemberWithStringAndNumberNames.ts, 4, 17)) >C : Symbol(C, Decl(staticMemberWithStringAndNumberNames.ts, 0, 0)) ->'0' : Symbol(C.0, Decl(staticMemberWithStringAndNumberNames.ts, 1, 21)) +>'0' : Symbol(C[0], Decl(staticMemberWithStringAndNumberNames.ts, 1, 21)) x3 = C[0]; >x3 : Symbol(C.x3, Decl(staticMemberWithStringAndNumberNames.ts, 5, 16)) >C : Symbol(C, Decl(staticMemberWithStringAndNumberNames.ts, 0, 0)) ->0 : Symbol(C.0, Decl(staticMemberWithStringAndNumberNames.ts, 1, 21)) +>0 : Symbol(C[0], Decl(staticMemberWithStringAndNumberNames.ts, 1, 21)) static s = C['foo']; >s : Symbol(C.s, Decl(staticMemberWithStringAndNumberNames.ts, 6, 14)) >C : Symbol(C, Decl(staticMemberWithStringAndNumberNames.ts, 0, 0)) ->'foo' : Symbol(C."foo", Decl(staticMemberWithStringAndNumberNames.ts, 0, 9)) +>'foo' : Symbol(C["foo"], Decl(staticMemberWithStringAndNumberNames.ts, 0, 9)) static s2 = C['0']; >s2 : Symbol(C.s2, Decl(staticMemberWithStringAndNumberNames.ts, 8, 24)) >C : Symbol(C, Decl(staticMemberWithStringAndNumberNames.ts, 0, 0)) ->'0' : Symbol(C.0, Decl(staticMemberWithStringAndNumberNames.ts, 1, 21)) +>'0' : Symbol(C[0], Decl(staticMemberWithStringAndNumberNames.ts, 1, 21)) static s3 = C[0]; >s3 : Symbol(C.s3, Decl(staticMemberWithStringAndNumberNames.ts, 9, 23)) >C : Symbol(C, Decl(staticMemberWithStringAndNumberNames.ts, 0, 0)) ->0 : Symbol(C.0, Decl(staticMemberWithStringAndNumberNames.ts, 1, 21)) +>0 : Symbol(C[0], Decl(staticMemberWithStringAndNumberNames.ts, 1, 21)) } diff --git a/tests/baselines/reference/stringLiteralTypesAndTuples01.types b/tests/baselines/reference/stringLiteralTypesAndTuples01.types index c874973e3e5..e8b5b37a2dd 100644 --- a/tests/baselines/reference/stringLiteralTypesAndTuples01.types +++ b/tests/baselines/reference/stringLiteralTypesAndTuples01.types @@ -28,7 +28,7 @@ let [im, a, dinosaur]: ["I'm", "a", RexOrRaptor] = ['I\'m', 'a', 't-rex']; rawr(dinosaur); >rawr(dinosaur) : string >rawr : (dino: "t-rex" | "raptor") => string ->dinosaur : "t-rex" | "raptor" +>dinosaur : "t-rex" function rawr(dino: RexOrRaptor) { >rawr : (dino: "t-rex" | "raptor") => string diff --git a/tests/baselines/reference/stringLiteralTypesAsTags01.types b/tests/baselines/reference/stringLiteralTypesAsTags01.types index a7f403e76ec..243b55c4419 100644 --- a/tests/baselines/reference/stringLiteralTypesAsTags01.types +++ b/tests/baselines/reference/stringLiteralTypesAsTags01.types @@ -116,6 +116,6 @@ if (!hasKind(x, "B")) { } else { let d = x; ->d : A ->x : A +>d : {} +>x : {} } diff --git a/tests/baselines/reference/stringLiteralTypesAsTags02.types b/tests/baselines/reference/stringLiteralTypesAsTags02.types index edad220b086..20834e1dfef 100644 --- a/tests/baselines/reference/stringLiteralTypesAsTags02.types +++ b/tests/baselines/reference/stringLiteralTypesAsTags02.types @@ -110,6 +110,6 @@ if (!hasKind(x, "B")) { } else { let d = x; ->d : A ->x : A +>d : {} +>x : {} } diff --git a/tests/baselines/reference/stringLiteralTypesAsTags03.types b/tests/baselines/reference/stringLiteralTypesAsTags03.types index 25816659388..78ad260b719 100644 --- a/tests/baselines/reference/stringLiteralTypesAsTags03.types +++ b/tests/baselines/reference/stringLiteralTypesAsTags03.types @@ -113,6 +113,6 @@ if (!hasKind(x, "B")) { } else { let d = x; ->d : A ->x : A +>d : {} +>x : {} } diff --git a/tests/baselines/reference/stringLiteralTypesInUnionTypes01.js b/tests/baselines/reference/stringLiteralTypesInUnionTypes01.js index d970310d68e..bdf06d393aa 100644 --- a/tests/baselines/reference/stringLiteralTypesInUnionTypes01.js +++ b/tests/baselines/reference/stringLiteralTypesInUnionTypes01.js @@ -2,8 +2,8 @@ type T = "foo" | "bar" | "baz"; -var x: "foo" | "bar" | "baz" = "foo"; -var y: T = "bar"; +var x: "foo" | "bar" | "baz" = undefined; +var y: T = undefined; if (x === "foo") { let a = x; @@ -21,8 +21,8 @@ x = y; y = x; //// [stringLiteralTypesInUnionTypes01.js] -var x = "foo"; -var y = "bar"; +var x = undefined; +var y = undefined; if (x === "foo") { var a = x; } diff --git a/tests/baselines/reference/stringLiteralTypesInUnionTypes01.symbols b/tests/baselines/reference/stringLiteralTypesInUnionTypes01.symbols index c608929383e..15a8db13cd0 100644 --- a/tests/baselines/reference/stringLiteralTypesInUnionTypes01.symbols +++ b/tests/baselines/reference/stringLiteralTypesInUnionTypes01.symbols @@ -3,12 +3,14 @@ type T = "foo" | "bar" | "baz"; >T : Symbol(T, Decl(stringLiteralTypesInUnionTypes01.ts, 0, 0)) -var x: "foo" | "bar" | "baz" = "foo"; +var x: "foo" | "bar" | "baz" = undefined; >x : Symbol(x, Decl(stringLiteralTypesInUnionTypes01.ts, 3, 3)) +>undefined : Symbol(undefined) -var y: T = "bar"; +var y: T = undefined; >y : Symbol(y, Decl(stringLiteralTypesInUnionTypes01.ts, 4, 3)) >T : Symbol(T, Decl(stringLiteralTypesInUnionTypes01.ts, 0, 0)) +>undefined : Symbol(undefined) if (x === "foo") { >x : Symbol(x, Decl(stringLiteralTypesInUnionTypes01.ts, 3, 3)) diff --git a/tests/baselines/reference/stringLiteralTypesInUnionTypes01.types b/tests/baselines/reference/stringLiteralTypesInUnionTypes01.types index e5ff509822b..7201aaa91ca 100644 --- a/tests/baselines/reference/stringLiteralTypesInUnionTypes01.types +++ b/tests/baselines/reference/stringLiteralTypesInUnionTypes01.types @@ -3,14 +3,14 @@ type T = "foo" | "bar" | "baz"; >T : "foo" | "bar" | "baz" -var x: "foo" | "bar" | "baz" = "foo"; +var x: "foo" | "bar" | "baz" = undefined; >x : "foo" | "bar" | "baz" ->"foo" : "foo" +>undefined : undefined -var y: T = "bar"; +var y: T = undefined; >y : "foo" | "bar" | "baz" >T : "foo" | "bar" | "baz" ->"bar" : "bar" +>undefined : undefined if (x === "foo") { >x === "foo" : boolean diff --git a/tests/baselines/reference/stringLiteralTypesInUnionTypes02.js b/tests/baselines/reference/stringLiteralTypesInUnionTypes02.js index 19b9c837c9d..bca25e744c9 100644 --- a/tests/baselines/reference/stringLiteralTypesInUnionTypes02.js +++ b/tests/baselines/reference/stringLiteralTypesInUnionTypes02.js @@ -2,8 +2,8 @@ type T = string | "foo" | "bar" | "baz"; -var x: "foo" | "bar" | "baz" | string = "foo"; -var y: T = "bar"; +var x: "foo" | "bar" | "baz" | string = undefined; +var y: T = undefined; if (x === "foo") { let a = x; @@ -21,8 +21,8 @@ x = y; y = x; //// [stringLiteralTypesInUnionTypes02.js] -var x = "foo"; -var y = "bar"; +var x = undefined; +var y = undefined; if (x === "foo") { var a = x; } diff --git a/tests/baselines/reference/stringLiteralTypesInUnionTypes02.symbols b/tests/baselines/reference/stringLiteralTypesInUnionTypes02.symbols index c9b31dc710a..c35b7a0691b 100644 --- a/tests/baselines/reference/stringLiteralTypesInUnionTypes02.symbols +++ b/tests/baselines/reference/stringLiteralTypesInUnionTypes02.symbols @@ -3,12 +3,14 @@ type T = string | "foo" | "bar" | "baz"; >T : Symbol(T, Decl(stringLiteralTypesInUnionTypes02.ts, 0, 0)) -var x: "foo" | "bar" | "baz" | string = "foo"; +var x: "foo" | "bar" | "baz" | string = undefined; >x : Symbol(x, Decl(stringLiteralTypesInUnionTypes02.ts, 3, 3)) +>undefined : Symbol(undefined) -var y: T = "bar"; +var y: T = undefined; >y : Symbol(y, Decl(stringLiteralTypesInUnionTypes02.ts, 4, 3)) >T : Symbol(T, Decl(stringLiteralTypesInUnionTypes02.ts, 0, 0)) +>undefined : Symbol(undefined) if (x === "foo") { >x : Symbol(x, Decl(stringLiteralTypesInUnionTypes02.ts, 3, 3)) diff --git a/tests/baselines/reference/stringLiteralTypesInUnionTypes02.types b/tests/baselines/reference/stringLiteralTypesInUnionTypes02.types index b468c620376..242248617e0 100644 --- a/tests/baselines/reference/stringLiteralTypesInUnionTypes02.types +++ b/tests/baselines/reference/stringLiteralTypesInUnionTypes02.types @@ -3,60 +3,60 @@ type T = string | "foo" | "bar" | "baz"; >T : string | "foo" | "bar" | "baz" -var x: "foo" | "bar" | "baz" | string = "foo"; +var x: "foo" | "bar" | "baz" | string = undefined; >x : "foo" | "bar" | "baz" | string ->"foo" : "foo" +>undefined : undefined -var y: T = "bar"; +var y: T = undefined; >y : string | "foo" | "bar" | "baz" >T : string | "foo" | "bar" | "baz" ->"bar" : "bar" +>undefined : undefined if (x === "foo") { >x === "foo" : boolean ->x : "foo" | "bar" | "baz" | string +>x : string >"foo" : string let a = x; ->a : "foo" | "bar" | "baz" | string ->x : "foo" | "bar" | "baz" | string +>a : string +>x : string } else if (x !== "bar") { >x !== "bar" : boolean ->x : "foo" | "bar" | "baz" | string +>x : string >"bar" : string let b = x || y; >b : string >x || y : string ->x : "foo" | "bar" | "baz" | string ->y : string | "foo" | "bar" | "baz" +>x : string +>y : string } else { let c = x; ->c : "foo" | "bar" | "baz" | string ->x : "foo" | "bar" | "baz" | string +>c : string +>x : string let d = y; ->d : string | "foo" | "bar" | "baz" ->y : string | "foo" | "bar" | "baz" +>d : string +>y : string let e: (typeof x) | (typeof y) = c || d; ->e : "foo" | "bar" | "baz" | string ->x : "foo" | "bar" | "baz" | string ->y : string | "foo" | "bar" | "baz" +>e : string +>x : string +>y : string >c || d : string ->c : "foo" | "bar" | "baz" | string ->d : string | "foo" | "bar" | "baz" +>c : string +>d : string } x = y; ->x = y : string | "foo" | "bar" | "baz" +>x = y : string >x : "foo" | "bar" | "baz" | string ->y : string | "foo" | "bar" | "baz" +>y : string y = x; ->y = x : "foo" | "bar" | "baz" | string +>y = x : string >y : string | "foo" | "bar" | "baz" ->x : "foo" | "bar" | "baz" | string +>x : string diff --git a/tests/baselines/reference/stringLiteralTypesInUnionTypes03.js b/tests/baselines/reference/stringLiteralTypesInUnionTypes03.js index f6728e0b2fb..6264c99c13d 100644 --- a/tests/baselines/reference/stringLiteralTypesInUnionTypes03.js +++ b/tests/baselines/reference/stringLiteralTypesInUnionTypes03.js @@ -3,7 +3,7 @@ type T = number | "foo" | "bar"; var x: "foo" | "bar" | number; -var y: T = "bar"; +var y: T = undefined; if (x === "foo") { let a = x; @@ -22,7 +22,7 @@ y = x; //// [stringLiteralTypesInUnionTypes03.js] var x; -var y = "bar"; +var y = undefined; if (x === "foo") { var a = x; } diff --git a/tests/baselines/reference/stringLiteralTypesInUnionTypes03.symbols b/tests/baselines/reference/stringLiteralTypesInUnionTypes03.symbols index df5498d9a59..6d519e24225 100644 --- a/tests/baselines/reference/stringLiteralTypesInUnionTypes03.symbols +++ b/tests/baselines/reference/stringLiteralTypesInUnionTypes03.symbols @@ -6,9 +6,10 @@ type T = number | "foo" | "bar"; var x: "foo" | "bar" | number; >x : Symbol(x, Decl(stringLiteralTypesInUnionTypes03.ts, 3, 3)) -var y: T = "bar"; +var y: T = undefined; >y : Symbol(y, Decl(stringLiteralTypesInUnionTypes03.ts, 4, 3)) >T : Symbol(T, Decl(stringLiteralTypesInUnionTypes03.ts, 0, 0)) +>undefined : Symbol(undefined) if (x === "foo") { >x : Symbol(x, Decl(stringLiteralTypesInUnionTypes03.ts, 3, 3)) diff --git a/tests/baselines/reference/stringLiteralTypesInUnionTypes03.types b/tests/baselines/reference/stringLiteralTypesInUnionTypes03.types index 5fca6e69be9..920f7e1a71c 100644 --- a/tests/baselines/reference/stringLiteralTypesInUnionTypes03.types +++ b/tests/baselines/reference/stringLiteralTypesInUnionTypes03.types @@ -6,10 +6,10 @@ type T = number | "foo" | "bar"; var x: "foo" | "bar" | number; >x : "foo" | "bar" | number -var y: T = "bar"; +var y: T = undefined; >y : number | "foo" | "bar" >T : number | "foo" | "bar" ->"bar" : "bar" +>undefined : undefined if (x === "foo") { >x === "foo" : boolean diff --git a/tests/baselines/reference/stringLiteralTypesInUnionTypes04.js b/tests/baselines/reference/stringLiteralTypesInUnionTypes04.js index dc6cf51ad1e..85c9a30c49d 100644 --- a/tests/baselines/reference/stringLiteralTypesInUnionTypes04.js +++ b/tests/baselines/reference/stringLiteralTypesInUnionTypes04.js @@ -2,8 +2,8 @@ type T = "" | "foo"; -let x: T = ""; -let y: T = "foo"; +let x: T = undefined; +let y: T = undefined; if (x === "") { let a = x; @@ -38,8 +38,8 @@ if (!!!x) { } //// [stringLiteralTypesInUnionTypes04.js] -var x = ""; -var y = "foo"; +var x = undefined; +var y = undefined; if (x === "") { var a = x; } diff --git a/tests/baselines/reference/stringLiteralTypesInUnionTypes04.symbols b/tests/baselines/reference/stringLiteralTypesInUnionTypes04.symbols index ced93fcefc9..9904fa8613f 100644 --- a/tests/baselines/reference/stringLiteralTypesInUnionTypes04.symbols +++ b/tests/baselines/reference/stringLiteralTypesInUnionTypes04.symbols @@ -3,13 +3,15 @@ type T = "" | "foo"; >T : Symbol(T, Decl(stringLiteralTypesInUnionTypes04.ts, 0, 0)) -let x: T = ""; +let x: T = undefined; >x : Symbol(x, Decl(stringLiteralTypesInUnionTypes04.ts, 3, 3)) >T : Symbol(T, Decl(stringLiteralTypesInUnionTypes04.ts, 0, 0)) +>undefined : Symbol(undefined) -let y: T = "foo"; +let y: T = undefined; >y : Symbol(y, Decl(stringLiteralTypesInUnionTypes04.ts, 4, 3)) >T : Symbol(T, Decl(stringLiteralTypesInUnionTypes04.ts, 0, 0)) +>undefined : Symbol(undefined) if (x === "") { >x : Symbol(x, Decl(stringLiteralTypesInUnionTypes04.ts, 3, 3)) diff --git a/tests/baselines/reference/stringLiteralTypesInUnionTypes04.types b/tests/baselines/reference/stringLiteralTypesInUnionTypes04.types index ad92dc360d0..fdaaa21b6cb 100644 --- a/tests/baselines/reference/stringLiteralTypesInUnionTypes04.types +++ b/tests/baselines/reference/stringLiteralTypesInUnionTypes04.types @@ -3,15 +3,15 @@ type T = "" | "foo"; >T : "" | "foo" -let x: T = ""; +let x: T = undefined; >x : "" | "foo" >T : "" | "foo" ->"" : "" +>undefined : undefined -let y: T = "foo"; +let y: T = undefined; >y : "" | "foo" >T : "" | "foo" ->"foo" : "foo" +>undefined : undefined if (x === "") { >x === "" : boolean diff --git a/tests/baselines/reference/stringLiteralTypesTypePredicates01.js b/tests/baselines/reference/stringLiteralTypesTypePredicates01.js index fd4129d272d..fdd03c83aa5 100644 --- a/tests/baselines/reference/stringLiteralTypesTypePredicates01.js +++ b/tests/baselines/reference/stringLiteralTypesTypePredicates01.js @@ -8,7 +8,7 @@ function kindIs(kind: Kind, is: Kind): boolean { return kind === is; } -var x: Kind = "A"; +var x: Kind = undefined; if (kindIs(x, "A")) { let a = x; @@ -28,7 +28,7 @@ else { function kindIs(kind, is) { return kind === is; } -var x = "A"; +var x = undefined; if (kindIs(x, "A")) { var a = x; } diff --git a/tests/baselines/reference/stringLiteralTypesTypePredicates01.symbols b/tests/baselines/reference/stringLiteralTypesTypePredicates01.symbols index 6b18cab7432..aea8c6ac262 100644 --- a/tests/baselines/reference/stringLiteralTypesTypePredicates01.symbols +++ b/tests/baselines/reference/stringLiteralTypesTypePredicates01.symbols @@ -29,9 +29,10 @@ function kindIs(kind: Kind, is: Kind): boolean { >is : Symbol(is, Decl(stringLiteralTypesTypePredicates01.ts, 5, 27)) } -var x: Kind = "A"; +var x: Kind = undefined; >x : Symbol(x, Decl(stringLiteralTypesTypePredicates01.ts, 9, 3)) >Kind : Symbol(Kind, Decl(stringLiteralTypesTypePredicates01.ts, 0, 0)) +>undefined : Symbol(undefined) if (kindIs(x, "A")) { >kindIs : Symbol(kindIs, Decl(stringLiteralTypesTypePredicates01.ts, 1, 21), Decl(stringLiteralTypesTypePredicates01.ts, 3, 50), Decl(stringLiteralTypesTypePredicates01.ts, 4, 50)) diff --git a/tests/baselines/reference/stringLiteralTypesTypePredicates01.types b/tests/baselines/reference/stringLiteralTypesTypePredicates01.types index 41da80afd30..4a765ea5312 100644 --- a/tests/baselines/reference/stringLiteralTypesTypePredicates01.types +++ b/tests/baselines/reference/stringLiteralTypesTypePredicates01.types @@ -30,10 +30,10 @@ function kindIs(kind: Kind, is: Kind): boolean { >is : "A" | "B" } -var x: Kind = "A"; +var x: Kind = undefined; >x : "A" | "B" >Kind : "A" | "B" ->"A" : "A" +>undefined : undefined if (kindIs(x, "A")) { >kindIs(x, "A") : boolean diff --git a/tests/baselines/reference/stringNamedPropertyAccess.symbols b/tests/baselines/reference/stringNamedPropertyAccess.symbols index 583e5da06ed..961b03f6e04 100644 --- a/tests/baselines/reference/stringNamedPropertyAccess.symbols +++ b/tests/baselines/reference/stringNamedPropertyAccess.symbols @@ -12,12 +12,12 @@ var c: C; var r1 = c["a b"]; >r1 : Symbol(r1, Decl(stringNamedPropertyAccess.ts, 5, 3)) >c : Symbol(c, Decl(stringNamedPropertyAccess.ts, 4, 3)) ->"a b" : Symbol(C."a b", Decl(stringNamedPropertyAccess.ts, 0, 9)) +>"a b" : Symbol(C["a b"], Decl(stringNamedPropertyAccess.ts, 0, 9)) var r1b = C['c d']; >r1b : Symbol(r1b, Decl(stringNamedPropertyAccess.ts, 6, 3)) >C : Symbol(C, Decl(stringNamedPropertyAccess.ts, 0, 0)) ->'c d' : Symbol(C."c d", Decl(stringNamedPropertyAccess.ts, 1, 18)) +>'c d' : Symbol(C["c d"], Decl(stringNamedPropertyAccess.ts, 1, 18)) interface I { >I : Symbol(I, Decl(stringNamedPropertyAccess.ts, 6, 19)) @@ -31,7 +31,7 @@ var i: I; var r2 = i["a b"]; >r2 : Symbol(r2, Decl(stringNamedPropertyAccess.ts, 12, 3)) >i : Symbol(i, Decl(stringNamedPropertyAccess.ts, 11, 3)) ->"a b" : Symbol(I."a b", Decl(stringNamedPropertyAccess.ts, 8, 13)) +>"a b" : Symbol(I["a b"], Decl(stringNamedPropertyAccess.ts, 8, 13)) var a: { >a : Symbol(a, Decl(stringNamedPropertyAccess.ts, 14, 3)) diff --git a/tests/baselines/reference/systemModule13.types b/tests/baselines/reference/systemModule13.types index 35f22be98b8..f31b0825416 100644 --- a/tests/baselines/reference/systemModule13.types +++ b/tests/baselines/reference/systemModule13.types @@ -24,7 +24,7 @@ export const {a: z0, b: {c: z1}} = {a: true, b: {c: "123"}}; >"123" : string for ([x] of [[1]]) {} ->[x] : number[] +>[x] : [number] >x : number >[[1]] : number[][] >[1] : number[] diff --git a/tests/baselines/reference/systemModule8.types b/tests/baselines/reference/systemModule8.types index 2c3dd1e48bb..940067c5653 100644 --- a/tests/baselines/reference/systemModule8.types +++ b/tests/baselines/reference/systemModule8.types @@ -135,7 +135,7 @@ export const {a: z0, b: {c: z1}} = {a: true, b: {c: "123"}}; >"123" : string for ([x] of [[1]]) {} ->[x] : any[] +>[x] : [any] >x : any >[[1]] : number[][] >[1] : number[] diff --git a/tests/baselines/reference/tsxElementResolution.symbols b/tests/baselines/reference/tsxElementResolution.symbols index cd7ac7807f1..729c3fc9f06 100644 --- a/tests/baselines/reference/tsxElementResolution.symbols +++ b/tests/baselines/reference/tsxElementResolution.symbols @@ -36,7 +36,7 @@ var a = ; var b = ; >b : Symbol(b, Decl(tsxElementResolution.tsx, 18, 3)) ->string_named : Symbol(JSX.IntrinsicElements.'string_named', Decl(tsxElementResolution.tsx, 3, 28)) +>string_named : Symbol(JSX.IntrinsicElements['string_named'], Decl(tsxElementResolution.tsx, 3, 28)) // TODO: This should not be a parse error (should // parse a property name here, not identifier) diff --git a/tests/baselines/reference/typeGuardEnums.types b/tests/baselines/reference/typeGuardEnums.types index 1d39a81d78a..2bef6915046 100644 --- a/tests/baselines/reference/typeGuardEnums.types +++ b/tests/baselines/reference/typeGuardEnums.types @@ -27,7 +27,7 @@ else { if (typeof x !== "number") { >typeof x !== "number" : boolean >typeof x : string ->x : number | string | E | V +>x : number | string >"number" : string x; // string @@ -35,6 +35,6 @@ if (typeof x !== "number") { } else { x; // number|E|V ->x : number | E | V +>x : number } diff --git a/tests/baselines/reference/typeGuardFunctionOfFormThis.js b/tests/baselines/reference/typeGuardFunctionOfFormThis.js index 0d1dceccede..ad85f679e0a 100644 --- a/tests/baselines/reference/typeGuardFunctionOfFormThis.js +++ b/tests/baselines/reference/typeGuardFunctionOfFormThis.js @@ -34,19 +34,19 @@ else if (b.isFollower()) { b.follow(); } -if (((a.isLeader)())) { - a.lead(); -} -else if (((a).isFollower())) { - a.follow(); -} +// if (((a.isLeader)())) { +// a.lead(); +// } +// else if (((a).isFollower())) { +// a.follow(); +// } -if (((a["isLeader"])())) { - a.lead(); -} -else if (((a)["isFollower"]())) { - a.follow(); -} +// if (((a["isLeader"])())) { +// a.lead(); +// } +// else if (((a)["isFollower"]())) { +// a.follow(); +// } var holder2 = {a}; @@ -190,18 +190,18 @@ if (b.isLeader()) { else if (b.isFollower()) { b.follow(); } -if (((a.isLeader)())) { - a.lead(); -} -else if (((a).isFollower())) { - a.follow(); -} -if (((a["isLeader"])())) { - a.lead(); -} -else if (((a)["isFollower"]())) { - a.follow(); -} +// if (((a.isLeader)())) { +// a.lead(); +// } +// else if (((a).isFollower())) { +// a.follow(); +// } +// if (((a["isLeader"])())) { +// a.lead(); +// } +// else if (((a)["isFollower"]())) { +// a.follow(); +// } var holder2 = { a: a }; if (holder2.a.isLeader()) { holder2.a; diff --git a/tests/baselines/reference/typeGuardFunctionOfFormThis.symbols b/tests/baselines/reference/typeGuardFunctionOfFormThis.symbols index 4f08201ba64..3ac972200e2 100644 --- a/tests/baselines/reference/typeGuardFunctionOfFormThis.symbols +++ b/tests/baselines/reference/typeGuardFunctionOfFormThis.symbols @@ -91,45 +91,19 @@ else if (b.isFollower()) { >follow : Symbol(FollowerGuard.follow, Decl(typeGuardFunctionOfFormThis.ts, 13, 40)) } -if (((a.isLeader)())) { ->a.isLeader : Symbol(RoyalGuard.isLeader, Decl(typeGuardFunctionOfFormThis.ts, 0, 18)) ->a : Symbol(a, Decl(typeGuardFunctionOfFormThis.ts, 17, 3)) ->isLeader : Symbol(RoyalGuard.isLeader, Decl(typeGuardFunctionOfFormThis.ts, 0, 18)) +// if (((a.isLeader)())) { +// a.lead(); +// } +// else if (((a).isFollower())) { +// a.follow(); +// } - a.lead(); ->a.lead : Symbol(LeadGuard.lead, Decl(typeGuardFunctionOfFormThis.ts, 9, 36)) ->a : Symbol(a, Decl(typeGuardFunctionOfFormThis.ts, 17, 3)) ->lead : Symbol(LeadGuard.lead, Decl(typeGuardFunctionOfFormThis.ts, 9, 36)) -} -else if (((a).isFollower())) { ->(a).isFollower : Symbol(RoyalGuard.isFollower, Decl(typeGuardFunctionOfFormThis.ts, 3, 5)) ->a : Symbol(a, Decl(typeGuardFunctionOfFormThis.ts, 17, 3)) ->isFollower : Symbol(RoyalGuard.isFollower, Decl(typeGuardFunctionOfFormThis.ts, 3, 5)) - - a.follow(); ->a.follow : Symbol(FollowerGuard.follow, Decl(typeGuardFunctionOfFormThis.ts, 13, 40)) ->a : Symbol(a, Decl(typeGuardFunctionOfFormThis.ts, 17, 3)) ->follow : Symbol(FollowerGuard.follow, Decl(typeGuardFunctionOfFormThis.ts, 13, 40)) -} - -if (((a["isLeader"])())) { ->a : Symbol(a, Decl(typeGuardFunctionOfFormThis.ts, 17, 3)) ->"isLeader" : Symbol(RoyalGuard.isLeader, Decl(typeGuardFunctionOfFormThis.ts, 0, 18)) - - a.lead(); ->a.lead : Symbol(LeadGuard.lead, Decl(typeGuardFunctionOfFormThis.ts, 9, 36)) ->a : Symbol(a, Decl(typeGuardFunctionOfFormThis.ts, 17, 3)) ->lead : Symbol(LeadGuard.lead, Decl(typeGuardFunctionOfFormThis.ts, 9, 36)) -} -else if (((a)["isFollower"]())) { ->a : Symbol(a, Decl(typeGuardFunctionOfFormThis.ts, 17, 3)) ->"isFollower" : Symbol(RoyalGuard.isFollower, Decl(typeGuardFunctionOfFormThis.ts, 3, 5)) - - a.follow(); ->a.follow : Symbol(FollowerGuard.follow, Decl(typeGuardFunctionOfFormThis.ts, 13, 40)) ->a : Symbol(a, Decl(typeGuardFunctionOfFormThis.ts, 17, 3)) ->follow : Symbol(FollowerGuard.follow, Decl(typeGuardFunctionOfFormThis.ts, 13, 40)) -} +// if (((a["isLeader"])())) { +// a.lead(); +// } +// else if (((a)["isFollower"]())) { +// a.follow(); +// } var holder2 = {a}; >holder2 : Symbol(holder2, Decl(typeGuardFunctionOfFormThis.ts, 49, 3)) diff --git a/tests/baselines/reference/typeGuardFunctionOfFormThis.types b/tests/baselines/reference/typeGuardFunctionOfFormThis.types index cd0381a94e9..66d1a4b5b11 100644 --- a/tests/baselines/reference/typeGuardFunctionOfFormThis.types +++ b/tests/baselines/reference/typeGuardFunctionOfFormThis.types @@ -102,63 +102,19 @@ else if (b.isFollower()) { >follow : () => void } -if (((a.isLeader)())) { ->((a.isLeader)()) : boolean ->(a.isLeader)() : boolean ->(a.isLeader) : () => this is LeadGuard ->a.isLeader : () => this is LeadGuard ->a : RoyalGuard ->isLeader : () => this is LeadGuard +// if (((a.isLeader)())) { +// a.lead(); +// } +// else if (((a).isFollower())) { +// a.follow(); +// } - a.lead(); ->a.lead() : void ->a.lead : () => void ->a : LeadGuard ->lead : () => void -} -else if (((a).isFollower())) { ->((a).isFollower()) : boolean ->(a).isFollower() : boolean ->(a).isFollower : () => this is FollowerGuard ->(a) : RoyalGuard ->a : RoyalGuard ->isFollower : () => this is FollowerGuard - - a.follow(); ->a.follow() : void ->a.follow : () => void ->a : FollowerGuard ->follow : () => void -} - -if (((a["isLeader"])())) { ->((a["isLeader"])()) : boolean ->(a["isLeader"])() : boolean ->(a["isLeader"]) : () => this is LeadGuard ->a["isLeader"] : () => this is LeadGuard ->a : RoyalGuard ->"isLeader" : string - - a.lead(); ->a.lead() : void ->a.lead : () => void ->a : LeadGuard ->lead : () => void -} -else if (((a)["isFollower"]())) { ->((a)["isFollower"]()) : boolean ->(a)["isFollower"]() : boolean ->(a)["isFollower"] : () => this is FollowerGuard ->(a) : RoyalGuard ->a : RoyalGuard ->"isFollower" : string - - a.follow(); ->a.follow() : void ->a.follow : () => void ->a : FollowerGuard ->follow : () => void -} +// if (((a["isLeader"])())) { +// a.lead(); +// } +// else if (((a)["isFollower"]())) { +// a.follow(); +// } var holder2 = {a}; >holder2 : { a: RoyalGuard; } diff --git a/tests/baselines/reference/typeGuardNesting.types b/tests/baselines/reference/typeGuardNesting.types index 255e96da89e..2b18e232412 100644 --- a/tests/baselines/reference/typeGuardNesting.types +++ b/tests/baselines/reference/typeGuardNesting.types @@ -34,7 +34,7 @@ if ((typeof strOrBool === 'boolean' && !strOrBool) || typeof strOrBool === 'stri >(typeof strOrBool === 'boolean') : boolean >typeof strOrBool === 'boolean' : boolean >typeof strOrBool : string ->strOrBool : boolean | string +>strOrBool : string | boolean >'boolean' : string >strOrBool : boolean >false : boolean @@ -56,7 +56,7 @@ if ((typeof strOrBool === 'boolean' && !strOrBool) || typeof strOrBool === 'stri >(typeof strOrBool !== 'string') : boolean >typeof strOrBool !== 'string' : boolean >typeof strOrBool : string ->strOrBool : boolean | string +>strOrBool : string | boolean >'string' : string >strOrBool : boolean >false : boolean @@ -68,7 +68,7 @@ if ((typeof strOrBool !== 'string' && !strOrBool) || typeof strOrBool !== 'boole >typeof strOrBool !== 'string' && !strOrBool : boolean >typeof strOrBool !== 'string' : boolean >typeof strOrBool : string ->strOrBool : string | boolean +>strOrBool : boolean | string >'string' : string >!strOrBool : boolean >strOrBool : boolean @@ -94,7 +94,7 @@ if ((typeof strOrBool !== 'string' && !strOrBool) || typeof strOrBool !== 'boole >(typeof strOrBool === 'boolean') : boolean >typeof strOrBool === 'boolean' : boolean >typeof strOrBool : string ->strOrBool : boolean | string +>strOrBool : string | boolean >'boolean' : string >strOrBool : boolean >false : boolean @@ -116,7 +116,7 @@ if ((typeof strOrBool !== 'string' && !strOrBool) || typeof strOrBool !== 'boole >(typeof strOrBool !== 'string') : boolean >typeof strOrBool !== 'string' : boolean >typeof strOrBool : string ->strOrBool : boolean | string +>strOrBool : string | boolean >'string' : string >strOrBool : boolean >false : boolean diff --git a/tests/baselines/reference/typeGuardOfFormExpr1AndExpr2.types b/tests/baselines/reference/typeGuardOfFormExpr1AndExpr2.types index 10f50bed52e..a10d398988f 100644 --- a/tests/baselines/reference/typeGuardOfFormExpr1AndExpr2.types +++ b/tests/baselines/reference/typeGuardOfFormExpr1AndExpr2.types @@ -95,11 +95,11 @@ if (typeof strOrNumOrBoolOrC !== "string" && typeof strOrNumOrBoolOrC !== "numbe >typeof strOrNumOrBoolOrC !== "string" && typeof strOrNumOrBoolOrC !== "number" : boolean >typeof strOrNumOrBoolOrC !== "string" : boolean >typeof strOrNumOrBoolOrC : string ->strOrNumOrBoolOrC : string | number | boolean | C +>strOrNumOrBoolOrC : C | string | number | boolean >"string" : string >typeof strOrNumOrBoolOrC !== "number" : boolean >typeof strOrNumOrBoolOrC : string ->strOrNumOrBoolOrC : number | boolean | C +>strOrNumOrBoolOrC : C | number | boolean >"number" : string >typeof strOrNumOrBool === "boolean" : boolean >typeof strOrNumOrBool : string @@ -107,9 +107,9 @@ if (typeof strOrNumOrBoolOrC !== "string" && typeof strOrNumOrBoolOrC !== "numbe >"boolean" : string cOrBool = strOrNumOrBoolOrC; // C | boolean ->cOrBool = strOrNumOrBoolOrC : boolean | C +>cOrBool = strOrNumOrBoolOrC : C | boolean >cOrBool : C | boolean ->strOrNumOrBoolOrC : boolean | C +>strOrNumOrBoolOrC : C | boolean bool = strOrNumOrBool; // boolean >bool = strOrNumOrBool : boolean @@ -120,7 +120,7 @@ else { var r1: string | number | boolean | C = strOrNumOrBoolOrC; // string | number | boolean | C >r1 : string | number | boolean | C >C : C ->strOrNumOrBoolOrC : string | number | boolean | C +>strOrNumOrBoolOrC : string | number | C | boolean var r2: string | number | boolean = strOrNumOrBool; >r2 : string | number | boolean diff --git a/tests/baselines/reference/typeGuardOfFormInstanceOf.types b/tests/baselines/reference/typeGuardOfFormInstanceOf.types index 6b83b57dcb5..608e827f479 100644 --- a/tests/baselines/reference/typeGuardOfFormInstanceOf.types +++ b/tests/baselines/reference/typeGuardOfFormInstanceOf.types @@ -60,7 +60,7 @@ num = ctor1 instanceof C2 && ctor1.p2; // C2 >num : number >ctor1 instanceof C2 && ctor1.p2 : number >ctor1 instanceof C2 : boolean ->ctor1 : C1 | C2 +>ctor1 : C2 | C1 >C2 : typeof C2 >ctor1.p2 : number >ctor1 : C2 @@ -109,7 +109,7 @@ num = ctor2 instanceof D1 && ctor2.p3; // D1 >num : number >ctor2 instanceof D1 && ctor2.p3 : number >ctor2 instanceof D1 : boolean ->ctor2 : C2 | D1 +>ctor2 : D1 | C2 >D1 : typeof D1 >ctor2.p3 : number >ctor2 : D1 diff --git a/tests/baselines/reference/typeGuardOfFormInstanceOfOnInterface.types b/tests/baselines/reference/typeGuardOfFormInstanceOfOnInterface.types index 20d1c1644fc..a5387e66d44 100644 --- a/tests/baselines/reference/typeGuardOfFormInstanceOfOnInterface.types +++ b/tests/baselines/reference/typeGuardOfFormInstanceOfOnInterface.types @@ -84,7 +84,7 @@ num = c1Orc2 instanceof c2 && c1Orc2.p2; // C2 >num : number >c1Orc2 instanceof c2 && c1Orc2.p2 : number >c1Orc2 instanceof c2 : boolean ->c1Orc2 : C1 | C2 +>c1Orc2 : C2 | C1 >c2 : C2 >c1Orc2.p2 : number >c1Orc2 : C2 @@ -133,7 +133,7 @@ num = c2Ord1 instanceof d1 && c2Ord1.p3; // D1 >num : number >c2Ord1 instanceof d1 && c2Ord1.p3 : number >c2Ord1 instanceof d1 : boolean ->c2Ord1 : C2 | D1 +>c2Ord1 : D1 | C2 >d1 : D1 >c2Ord1.p3 : number >c2Ord1 : D1 diff --git a/tests/baselines/reference/typeGuardOfFormIsType.types b/tests/baselines/reference/typeGuardOfFormIsType.types index e2059be7b63..23ce38732cd 100644 --- a/tests/baselines/reference/typeGuardOfFormIsType.types +++ b/tests/baselines/reference/typeGuardOfFormIsType.types @@ -80,7 +80,7 @@ num = isC2(c1Orc2) && c1Orc2.p2; // C2 >isC2(c1Orc2) && c1Orc2.p2 : number >isC2(c1Orc2) : boolean >isC2 : (x: any) => x is C2 ->c1Orc2 : C1 | C2 +>c1Orc2 : C2 | C1 >c1Orc2.p2 : number >c1Orc2 : C2 >p2 : number @@ -129,7 +129,7 @@ num = isD1(c2Ord1) && c2Ord1.p3; // D1 >isD1(c2Ord1) && c2Ord1.p3 : number >isD1(c2Ord1) : boolean >isD1 : (x: any) => x is D1 ->c2Ord1 : C2 | D1 +>c2Ord1 : D1 | C2 >c2Ord1.p3 : number >c2Ord1 : D1 >p3 : number diff --git a/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.types b/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.types index ea169e95413..728d3dc0e38 100644 --- a/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.types +++ b/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.types @@ -111,7 +111,7 @@ num = isC2(c1Orc2) && c1Orc2.p2; // C2 >isC2(c1Orc2) && c1Orc2.p2 : number >isC2(c1Orc2) : boolean >isC2 : (x: any) => x is C2 ->c1Orc2 : C1 | C2 +>c1Orc2 : C2 | C1 >c1Orc2.p2 : number >c1Orc2 : C2 >p2 : number @@ -160,7 +160,7 @@ num = isD1(c2Ord1) && c2Ord1.p3; // D1 >isD1(c2Ord1) && c2Ord1.p3 : number >isD1(c2Ord1) : boolean >isD1 : (x: any) => x is D1 ->c2Ord1 : C2 | D1 +>c2Ord1 : D1 | C2 >c2Ord1.p3 : number >c2Ord1 : D1 >p3 : number diff --git a/tests/baselines/reference/typeGuardOfFormNotExpr.types b/tests/baselines/reference/typeGuardOfFormNotExpr.types index a99db08efab..e7cfd6a0dce 100644 --- a/tests/baselines/reference/typeGuardOfFormNotExpr.types +++ b/tests/baselines/reference/typeGuardOfFormNotExpr.types @@ -73,13 +73,13 @@ if (!(typeof strOrNumOrBool !== "string") || !(typeof strOrNumOrBool !== "number >(typeof strOrNumOrBool !== "string") : boolean >typeof strOrNumOrBool !== "string" : boolean >typeof strOrNumOrBool : string ->strOrNumOrBool : string | number | boolean +>strOrNumOrBool : boolean | string | number >"string" : string >!(typeof strOrNumOrBool !== "number") : boolean >(typeof strOrNumOrBool !== "number") : boolean >typeof strOrNumOrBool !== "number" : boolean >typeof strOrNumOrBool : string ->strOrNumOrBool : number | boolean +>strOrNumOrBool : boolean | number >"number" : string strOrNum = strOrNumOrBool; // string | number @@ -152,19 +152,19 @@ if (!(typeof strOrNumOrBool === "string") && numOrBool !== strOrNumOrBool) { >(typeof strOrNumOrBool === "string") : boolean >typeof strOrNumOrBool === "string" : boolean >typeof strOrNumOrBool : string ->strOrNumOrBool : string | number | boolean +>strOrNumOrBool : boolean | string | number >"string" : string >numOrBool !== strOrNumOrBool : boolean >numOrBool : number | boolean ->strOrNumOrBool : number | boolean +>strOrNumOrBool : boolean | number numOrBool = strOrNumOrBool; // number | boolean ->numOrBool = strOrNumOrBool : number | boolean +>numOrBool = strOrNumOrBool : boolean | number >numOrBool : number | boolean ->strOrNumOrBool : number | boolean +>strOrNumOrBool : boolean | number } else { var r1: string | number | boolean = strOrNumOrBool; // string | number | boolean >r1 : string | number | boolean ->strOrNumOrBool : string | number | boolean +>strOrNumOrBool : string | boolean | number } diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfBoolean.js b/tests/baselines/reference/typeGuardOfFormTypeOfBoolean.js index e9e11275d0d..7d68b893373 100644 --- a/tests/baselines/reference/typeGuardOfFormTypeOfBoolean.js +++ b/tests/baselines/reference/typeGuardOfFormTypeOfBoolean.js @@ -42,12 +42,11 @@ else { c = boolOrC; // C } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrNum === "boolean") { - var z1: string | number = strOrNum; // string | number + let z1: {} = strOrNum; // {} } else { - var z2: string | number = strOrNum; // string | number + let z2: string | number = strOrNum; // string | number } @@ -79,12 +78,11 @@ else { bool = boolOrC; // boolean } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrNum !== "boolean") { - var z1: string | number = strOrNum; // string | number + let z1: string | number = strOrNum; // string | number } else { - var z2: string | number = strOrNum; // string | number + let z2: {} = strOrNum; // {} } @@ -134,9 +132,8 @@ if (typeof boolOrC === "boolean") { else { c = boolOrC; // C } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrNum === "boolean") { - var z1 = strOrNum; // string | number + var z1 = strOrNum; // {} } else { var z2 = strOrNum; // string | number @@ -168,10 +165,9 @@ if (typeof boolOrC !== "boolean") { else { bool = boolOrC; // boolean } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrNum !== "boolean") { var z1 = strOrNum; // string | number } else { - var z2 = strOrNum; // string | number + var z2 = strOrNum; // {} } diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfBoolean.symbols b/tests/baselines/reference/typeGuardOfFormTypeOfBoolean.symbols index d3879519228..dbef84c28c7 100644 --- a/tests/baselines/reference/typeGuardOfFormTypeOfBoolean.symbols +++ b/tests/baselines/reference/typeGuardOfFormTypeOfBoolean.symbols @@ -93,17 +93,16 @@ else { >boolOrC : Symbol(boolOrC, Decl(typeGuardOfFormTypeOfBoolean.ts, 11, 3)) } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrNum === "boolean") { >strOrNum : Symbol(strOrNum, Decl(typeGuardOfFormTypeOfBoolean.ts, 5, 3)) - var z1: string | number = strOrNum; // string | number ->z1 : Symbol(z1, Decl(typeGuardOfFormTypeOfBoolean.ts, 45, 7), Decl(typeGuardOfFormTypeOfBoolean.ts, 82, 7)) + let z1: {} = strOrNum; // {} +>z1 : Symbol(z1, Decl(typeGuardOfFormTypeOfBoolean.ts, 44, 7)) >strOrNum : Symbol(strOrNum, Decl(typeGuardOfFormTypeOfBoolean.ts, 5, 3)) } else { - var z2: string | number = strOrNum; // string | number ->z2 : Symbol(z2, Decl(typeGuardOfFormTypeOfBoolean.ts, 48, 7), Decl(typeGuardOfFormTypeOfBoolean.ts, 85, 7)) + let z2: string | number = strOrNum; // string | number +>z2 : Symbol(z2, Decl(typeGuardOfFormTypeOfBoolean.ts, 47, 7)) >strOrNum : Symbol(strOrNum, Decl(typeGuardOfFormTypeOfBoolean.ts, 5, 3)) } @@ -160,17 +159,16 @@ else { >boolOrC : Symbol(boolOrC, Decl(typeGuardOfFormTypeOfBoolean.ts, 11, 3)) } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrNum !== "boolean") { >strOrNum : Symbol(strOrNum, Decl(typeGuardOfFormTypeOfBoolean.ts, 5, 3)) - var z1: string | number = strOrNum; // string | number ->z1 : Symbol(z1, Decl(typeGuardOfFormTypeOfBoolean.ts, 45, 7), Decl(typeGuardOfFormTypeOfBoolean.ts, 82, 7)) + let z1: string | number = strOrNum; // string | number +>z1 : Symbol(z1, Decl(typeGuardOfFormTypeOfBoolean.ts, 80, 7)) >strOrNum : Symbol(strOrNum, Decl(typeGuardOfFormTypeOfBoolean.ts, 5, 3)) } else { - var z2: string | number = strOrNum; // string | number ->z2 : Symbol(z2, Decl(typeGuardOfFormTypeOfBoolean.ts, 48, 7), Decl(typeGuardOfFormTypeOfBoolean.ts, 85, 7)) + let z2: {} = strOrNum; // {} +>z2 : Symbol(z2, Decl(typeGuardOfFormTypeOfBoolean.ts, 83, 7)) >strOrNum : Symbol(strOrNum, Decl(typeGuardOfFormTypeOfBoolean.ts, 5, 3)) } diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfBoolean.types b/tests/baselines/reference/typeGuardOfFormTypeOfBoolean.types index 9d9f28548be..a5dcc9207cd 100644 --- a/tests/baselines/reference/typeGuardOfFormTypeOfBoolean.types +++ b/tests/baselines/reference/typeGuardOfFormTypeOfBoolean.types @@ -113,19 +113,18 @@ else { >boolOrC : C } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrNum === "boolean") { >typeof strOrNum === "boolean" : boolean >typeof strOrNum : string >strOrNum : string | number >"boolean" : string - var z1: string | number = strOrNum; // string | number ->z1 : string | number ->strOrNum : string | number + let z1: {} = strOrNum; // {} +>z1 : {} +>strOrNum : {} } else { - var z2: string | number = strOrNum; // string | number + let z2: string | number = strOrNum; // string | number >z2 : string | number >strOrNum : string | number } @@ -137,7 +136,7 @@ else { if (typeof strOrBool !== "boolean") { >typeof strOrBool !== "boolean" : boolean >typeof strOrBool : string ->strOrBool : string | boolean +>strOrBool : boolean | string >"boolean" : string str = strOrBool; // string @@ -154,7 +153,7 @@ else { if (typeof numOrBool !== "boolean") { >typeof numOrBool !== "boolean" : boolean >typeof numOrBool : string ->numOrBool : number | boolean +>numOrBool : boolean | number >"boolean" : string num = numOrBool; // number @@ -171,7 +170,7 @@ else { if (typeof strOrNumOrBool !== "boolean") { >typeof strOrNumOrBool !== "boolean" : boolean >typeof strOrNumOrBool : string ->strOrNumOrBool : string | number | boolean +>strOrNumOrBool : boolean | string | number >"boolean" : string strOrNum = strOrNumOrBool; // string | number @@ -203,20 +202,19 @@ else { >boolOrC : boolean } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrNum !== "boolean") { >typeof strOrNum !== "boolean" : boolean >typeof strOrNum : string >strOrNum : string | number >"boolean" : string - var z1: string | number = strOrNum; // string | number + let z1: string | number = strOrNum; // string | number >z1 : string | number >strOrNum : string | number } else { - var z2: string | number = strOrNum; // string | number ->z2 : string | number ->strOrNum : string | number + let z2: {} = strOrNum; // {} +>z2 : {} +>strOrNum : {} } diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfNumber.js b/tests/baselines/reference/typeGuardOfFormTypeOfNumber.js index 66fcff0c387..3bea6e87d2b 100644 --- a/tests/baselines/reference/typeGuardOfFormTypeOfNumber.js +++ b/tests/baselines/reference/typeGuardOfFormTypeOfNumber.js @@ -42,12 +42,11 @@ else { c = numOrC; // C } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrBool === "number") { - var y1: string | boolean = strOrBool; // string | boolean + let y1: {} = strOrBool; // {} } else { - var y2: string | boolean = strOrBool; // string | boolean + let y2: string | boolean = strOrBool; // string | boolean } // A type guard of the form typeof x !== s, where s is a string literal, @@ -78,12 +77,11 @@ else { num = numOrC; // number } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrBool !== "number") { - var y1: string | boolean = strOrBool; // string | boolean + let y1: string | boolean = strOrBool; // string | boolean } else { - var y2: string | boolean = strOrBool; // string | boolean + let y2: {} = strOrBool; // {} } @@ -133,9 +131,8 @@ if (typeof numOrC === "number") { else { c = numOrC; // C } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrBool === "number") { - var y1 = strOrBool; // string | boolean + var y1 = strOrBool; // {} } else { var y2 = strOrBool; // string | boolean @@ -167,10 +164,9 @@ if (typeof numOrC !== "number") { else { num = numOrC; // number } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrBool !== "number") { var y1 = strOrBool; // string | boolean } else { - var y2 = strOrBool; // string | boolean + var y2 = strOrBool; // {} } diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfNumber.symbols b/tests/baselines/reference/typeGuardOfFormTypeOfNumber.symbols index 2fd48389ae8..f38c348131e 100644 --- a/tests/baselines/reference/typeGuardOfFormTypeOfNumber.symbols +++ b/tests/baselines/reference/typeGuardOfFormTypeOfNumber.symbols @@ -65,7 +65,7 @@ if (typeof numOrBool === "number") { } else { var x: number | boolean = numOrBool; // number | boolean ->x : Symbol(x, Decl(typeGuardOfFormTypeOfNumber.ts, 28, 7), Decl(typeGuardOfFormTypeOfNumber.ts, 61, 7)) +>x : Symbol(x, Decl(typeGuardOfFormTypeOfNumber.ts, 28, 7), Decl(typeGuardOfFormTypeOfNumber.ts, 60, 7)) >numOrBool : Symbol(numOrBool, Decl(typeGuardOfFormTypeOfNumber.ts, 7, 3)) } if (typeof strOrNumOrBool === "number") { @@ -93,17 +93,16 @@ else { >numOrC : Symbol(numOrC, Decl(typeGuardOfFormTypeOfNumber.ts, 10, 3)) } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrBool === "number") { >strOrBool : Symbol(strOrBool, Decl(typeGuardOfFormTypeOfNumber.ts, 6, 3)) - var y1: string | boolean = strOrBool; // string | boolean ->y1 : Symbol(y1, Decl(typeGuardOfFormTypeOfNumber.ts, 45, 7), Decl(typeGuardOfFormTypeOfNumber.ts, 81, 7)) + let y1: {} = strOrBool; // {} +>y1 : Symbol(y1, Decl(typeGuardOfFormTypeOfNumber.ts, 44, 7)) >strOrBool : Symbol(strOrBool, Decl(typeGuardOfFormTypeOfNumber.ts, 6, 3)) } else { - var y2: string | boolean = strOrBool; // string | boolean ->y2 : Symbol(y2, Decl(typeGuardOfFormTypeOfNumber.ts, 48, 7), Decl(typeGuardOfFormTypeOfNumber.ts, 84, 7)) + let y2: string | boolean = strOrBool; // string | boolean +>y2 : Symbol(y2, Decl(typeGuardOfFormTypeOfNumber.ts, 47, 7)) >strOrBool : Symbol(strOrBool, Decl(typeGuardOfFormTypeOfNumber.ts, 6, 3)) } @@ -126,7 +125,7 @@ if (typeof numOrBool !== "number") { >numOrBool : Symbol(numOrBool, Decl(typeGuardOfFormTypeOfNumber.ts, 7, 3)) var x: number | boolean = numOrBool; // number | boolean ->x : Symbol(x, Decl(typeGuardOfFormTypeOfNumber.ts, 28, 7), Decl(typeGuardOfFormTypeOfNumber.ts, 61, 7)) +>x : Symbol(x, Decl(typeGuardOfFormTypeOfNumber.ts, 28, 7), Decl(typeGuardOfFormTypeOfNumber.ts, 60, 7)) >numOrBool : Symbol(numOrBool, Decl(typeGuardOfFormTypeOfNumber.ts, 7, 3)) } else { @@ -159,17 +158,16 @@ else { >numOrC : Symbol(numOrC, Decl(typeGuardOfFormTypeOfNumber.ts, 10, 3)) } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrBool !== "number") { >strOrBool : Symbol(strOrBool, Decl(typeGuardOfFormTypeOfNumber.ts, 6, 3)) - var y1: string | boolean = strOrBool; // string | boolean ->y1 : Symbol(y1, Decl(typeGuardOfFormTypeOfNumber.ts, 45, 7), Decl(typeGuardOfFormTypeOfNumber.ts, 81, 7)) + let y1: string | boolean = strOrBool; // string | boolean +>y1 : Symbol(y1, Decl(typeGuardOfFormTypeOfNumber.ts, 79, 7)) >strOrBool : Symbol(strOrBool, Decl(typeGuardOfFormTypeOfNumber.ts, 6, 3)) } else { - var y2: string | boolean = strOrBool; // string | boolean ->y2 : Symbol(y2, Decl(typeGuardOfFormTypeOfNumber.ts, 48, 7), Decl(typeGuardOfFormTypeOfNumber.ts, 84, 7)) + let y2: {} = strOrBool; // {} +>y2 : Symbol(y2, Decl(typeGuardOfFormTypeOfNumber.ts, 82, 7)) >strOrBool : Symbol(strOrBool, Decl(typeGuardOfFormTypeOfNumber.ts, 6, 3)) } diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfNumber.types b/tests/baselines/reference/typeGuardOfFormTypeOfNumber.types index d3caef24efd..99f927b7137 100644 --- a/tests/baselines/reference/typeGuardOfFormTypeOfNumber.types +++ b/tests/baselines/reference/typeGuardOfFormTypeOfNumber.types @@ -112,19 +112,18 @@ else { >numOrC : C } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrBool === "number") { >typeof strOrBool === "number" : boolean >typeof strOrBool : string >strOrBool : string | boolean >"number" : string - var y1: string | boolean = strOrBool; // string | boolean ->y1 : string | boolean ->strOrBool : string | boolean + let y1: {} = strOrBool; // {} +>y1 : {} +>strOrBool : {} } else { - var y2: string | boolean = strOrBool; // string | boolean + let y2: string | boolean = strOrBool; // string | boolean >y2 : string | boolean >strOrBool : string | boolean } @@ -135,7 +134,7 @@ else { if (typeof strOrNum !== "number") { >typeof strOrNum !== "number" : boolean >typeof strOrNum : string ->strOrNum : string | number +>strOrNum : number | string >"number" : string str === strOrNum; // string @@ -168,7 +167,7 @@ else { if (typeof strOrNumOrBool !== "number") { >typeof strOrNumOrBool !== "number" : boolean >typeof strOrNumOrBool : string ->strOrNumOrBool : string | number | boolean +>strOrNumOrBool : number | string | boolean >"number" : string strOrBool = strOrNumOrBool; // string | boolean @@ -200,20 +199,19 @@ else { >numOrC : number } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrBool !== "number") { >typeof strOrBool !== "number" : boolean >typeof strOrBool : string >strOrBool : string | boolean >"number" : string - var y1: string | boolean = strOrBool; // string | boolean + let y1: string | boolean = strOrBool; // string | boolean >y1 : string | boolean >strOrBool : string | boolean } else { - var y2: string | boolean = strOrBool; // string | boolean ->y2 : string | boolean ->strOrBool : string | boolean + let y2: {} = strOrBool; // {} +>y2 : {} +>strOrBool : {} } diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfOther.js b/tests/baselines/reference/typeGuardOfFormTypeOfOther.js index b1e6ca26566..ee0b6f66332 100644 --- a/tests/baselines/reference/typeGuardOfFormTypeOfOther.js +++ b/tests/baselines/reference/typeGuardOfFormTypeOfOther.js @@ -38,12 +38,11 @@ else { var r4: boolean = boolOrC; // boolean } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrNumOrBool === "Object") { - var q1: string | number | boolean = strOrNumOrBool; // string | number | boolean + let q1: {} = strOrNumOrBool; // {} } else { - var q2: string | number | boolean = strOrNumOrBool; // string | number | boolean + let q2: string | number | boolean = strOrNumOrBool; // string | number | boolean } // A type guard of the form typeof x !== s, where s is a string literal, @@ -68,12 +67,11 @@ else { c = boolOrC; // C } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrNumOrBool !== "Object") { - var q1: string | number | boolean = strOrNumOrBool; // string | number | boolean + let q1: string | number | boolean = strOrNumOrBool; // string | number | boolean } else { - var q2: string | number | boolean = strOrNumOrBool; // string | number | boolean + let q2: {} = strOrNumOrBool; // {} } @@ -118,9 +116,8 @@ if (typeof boolOrC === "Object") { else { var r4 = boolOrC; // boolean } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrNumOrBool === "Object") { - var q1 = strOrNumOrBool; // string | number | boolean + var q1 = strOrNumOrBool; // {} } else { var q2 = strOrNumOrBool; // string | number | boolean @@ -146,10 +143,9 @@ if (typeof boolOrC !== "Object") { else { c = boolOrC; // C } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrNumOrBool !== "Object") { var q1 = strOrNumOrBool; // string | number | boolean } else { - var q2 = strOrNumOrBool; // string | number | boolean + var q2 = strOrNumOrBool; // {} } diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfOther.symbols b/tests/baselines/reference/typeGuardOfFormTypeOfOther.symbols index ba759871a9b..a8760feda45 100644 --- a/tests/baselines/reference/typeGuardOfFormTypeOfOther.symbols +++ b/tests/baselines/reference/typeGuardOfFormTypeOfOther.symbols @@ -57,7 +57,7 @@ if (typeof strOrC === "Object") { } else { var r2: string = strOrC; // string ->r2 : Symbol(r2, Decl(typeGuardOfFormTypeOfOther.ts, 24, 7), Decl(typeGuardOfFormTypeOfOther.ts, 51, 7)) +>r2 : Symbol(r2, Decl(typeGuardOfFormTypeOfOther.ts, 24, 7), Decl(typeGuardOfFormTypeOfOther.ts, 50, 7)) >strOrC : Symbol(strOrC, Decl(typeGuardOfFormTypeOfOther.ts, 9, 3)) } if (typeof numOrC === "Object") { @@ -69,7 +69,7 @@ if (typeof numOrC === "Object") { } else { var r3: number = numOrC; // number ->r3 : Symbol(r3, Decl(typeGuardOfFormTypeOfOther.ts, 30, 7), Decl(typeGuardOfFormTypeOfOther.ts, 57, 7)) +>r3 : Symbol(r3, Decl(typeGuardOfFormTypeOfOther.ts, 30, 7), Decl(typeGuardOfFormTypeOfOther.ts, 56, 7)) >numOrC : Symbol(numOrC, Decl(typeGuardOfFormTypeOfOther.ts, 10, 3)) } if (typeof boolOrC === "Object") { @@ -81,21 +81,20 @@ if (typeof boolOrC === "Object") { } else { var r4: boolean = boolOrC; // boolean ->r4 : Symbol(r4, Decl(typeGuardOfFormTypeOfOther.ts, 36, 7), Decl(typeGuardOfFormTypeOfOther.ts, 63, 7)) +>r4 : Symbol(r4, Decl(typeGuardOfFormTypeOfOther.ts, 36, 7), Decl(typeGuardOfFormTypeOfOther.ts, 62, 7)) >boolOrC : Symbol(boolOrC, Decl(typeGuardOfFormTypeOfOther.ts, 11, 3)) } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrNumOrBool === "Object") { >strOrNumOrBool : Symbol(strOrNumOrBool, Decl(typeGuardOfFormTypeOfOther.ts, 8, 3)) - var q1: string | number | boolean = strOrNumOrBool; // string | number | boolean ->q1 : Symbol(q1, Decl(typeGuardOfFormTypeOfOther.ts, 41, 7), Decl(typeGuardOfFormTypeOfOther.ts, 71, 7)) + let q1: {} = strOrNumOrBool; // {} +>q1 : Symbol(q1, Decl(typeGuardOfFormTypeOfOther.ts, 40, 7)) >strOrNumOrBool : Symbol(strOrNumOrBool, Decl(typeGuardOfFormTypeOfOther.ts, 8, 3)) } else { - var q2: string | number | boolean = strOrNumOrBool; // string | number | boolean ->q2 : Symbol(q2, Decl(typeGuardOfFormTypeOfOther.ts, 44, 7), Decl(typeGuardOfFormTypeOfOther.ts, 74, 7)) + let q2: string | number | boolean = strOrNumOrBool; // string | number | boolean +>q2 : Symbol(q2, Decl(typeGuardOfFormTypeOfOther.ts, 43, 7)) >strOrNumOrBool : Symbol(strOrNumOrBool, Decl(typeGuardOfFormTypeOfOther.ts, 8, 3)) } @@ -106,7 +105,7 @@ if (typeof strOrC !== "Object") { >strOrC : Symbol(strOrC, Decl(typeGuardOfFormTypeOfOther.ts, 9, 3)) var r2: string = strOrC; // string ->r2 : Symbol(r2, Decl(typeGuardOfFormTypeOfOther.ts, 24, 7), Decl(typeGuardOfFormTypeOfOther.ts, 51, 7)) +>r2 : Symbol(r2, Decl(typeGuardOfFormTypeOfOther.ts, 24, 7), Decl(typeGuardOfFormTypeOfOther.ts, 50, 7)) >strOrC : Symbol(strOrC, Decl(typeGuardOfFormTypeOfOther.ts, 9, 3)) } else { @@ -118,7 +117,7 @@ if (typeof numOrC !== "Object") { >numOrC : Symbol(numOrC, Decl(typeGuardOfFormTypeOfOther.ts, 10, 3)) var r3: number = numOrC; // number ->r3 : Symbol(r3, Decl(typeGuardOfFormTypeOfOther.ts, 30, 7), Decl(typeGuardOfFormTypeOfOther.ts, 57, 7)) +>r3 : Symbol(r3, Decl(typeGuardOfFormTypeOfOther.ts, 30, 7), Decl(typeGuardOfFormTypeOfOther.ts, 56, 7)) >numOrC : Symbol(numOrC, Decl(typeGuardOfFormTypeOfOther.ts, 10, 3)) } else { @@ -130,7 +129,7 @@ if (typeof boolOrC !== "Object") { >boolOrC : Symbol(boolOrC, Decl(typeGuardOfFormTypeOfOther.ts, 11, 3)) var r4: boolean = boolOrC; // boolean ->r4 : Symbol(r4, Decl(typeGuardOfFormTypeOfOther.ts, 36, 7), Decl(typeGuardOfFormTypeOfOther.ts, 63, 7)) +>r4 : Symbol(r4, Decl(typeGuardOfFormTypeOfOther.ts, 36, 7), Decl(typeGuardOfFormTypeOfOther.ts, 62, 7)) >boolOrC : Symbol(boolOrC, Decl(typeGuardOfFormTypeOfOther.ts, 11, 3)) } else { @@ -139,17 +138,16 @@ else { >boolOrC : Symbol(boolOrC, Decl(typeGuardOfFormTypeOfOther.ts, 11, 3)) } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrNumOrBool !== "Object") { >strOrNumOrBool : Symbol(strOrNumOrBool, Decl(typeGuardOfFormTypeOfOther.ts, 8, 3)) - var q1: string | number | boolean = strOrNumOrBool; // string | number | boolean ->q1 : Symbol(q1, Decl(typeGuardOfFormTypeOfOther.ts, 41, 7), Decl(typeGuardOfFormTypeOfOther.ts, 71, 7)) + let q1: string | number | boolean = strOrNumOrBool; // string | number | boolean +>q1 : Symbol(q1, Decl(typeGuardOfFormTypeOfOther.ts, 69, 7)) >strOrNumOrBool : Symbol(strOrNumOrBool, Decl(typeGuardOfFormTypeOfOther.ts, 8, 3)) } else { - var q2: string | number | boolean = strOrNumOrBool; // string | number | boolean ->q2 : Symbol(q2, Decl(typeGuardOfFormTypeOfOther.ts, 44, 7), Decl(typeGuardOfFormTypeOfOther.ts, 74, 7)) + let q2: {} = strOrNumOrBool; // {} +>q2 : Symbol(q2, Decl(typeGuardOfFormTypeOfOther.ts, 72, 7)) >strOrNumOrBool : Symbol(strOrNumOrBool, Decl(typeGuardOfFormTypeOfOther.ts, 8, 3)) } diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfOther.types b/tests/baselines/reference/typeGuardOfFormTypeOfOther.types index 5cec3567194..aba8e429b8c 100644 --- a/tests/baselines/reference/typeGuardOfFormTypeOfOther.types +++ b/tests/baselines/reference/typeGuardOfFormTypeOfOther.types @@ -97,19 +97,18 @@ else { >boolOrC : boolean } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrNumOrBool === "Object") { >typeof strOrNumOrBool === "Object" : boolean >typeof strOrNumOrBool : string >strOrNumOrBool : string | number | boolean >"Object" : string - var q1: string | number | boolean = strOrNumOrBool; // string | number | boolean ->q1 : string | number | boolean ->strOrNumOrBool : string | number | boolean + let q1: {} = strOrNumOrBool; // {} +>q1 : {} +>strOrNumOrBool : {} } else { - var q2: string | number | boolean = strOrNumOrBool; // string | number | boolean + let q2: string | number | boolean = strOrNumOrBool; // string | number | boolean >q2 : string | number | boolean >strOrNumOrBool : string | number | boolean } @@ -120,7 +119,7 @@ else { if (typeof strOrC !== "Object") { >typeof strOrC !== "Object" : boolean >typeof strOrC : string ->strOrC : string | C +>strOrC : C | string >"Object" : string var r2: string = strOrC; // string @@ -136,7 +135,7 @@ else { if (typeof numOrC !== "Object") { >typeof numOrC !== "Object" : boolean >typeof numOrC : string ->numOrC : number | C +>numOrC : C | number >"Object" : string var r3: number = numOrC; // number @@ -152,7 +151,7 @@ else { if (typeof boolOrC !== "Object") { >typeof boolOrC !== "Object" : boolean >typeof boolOrC : string ->boolOrC : boolean | C +>boolOrC : C | boolean >"Object" : string var r4: boolean = boolOrC; // boolean @@ -166,20 +165,19 @@ else { >boolOrC : C } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrNumOrBool !== "Object") { >typeof strOrNumOrBool !== "Object" : boolean >typeof strOrNumOrBool : string >strOrNumOrBool : string | number | boolean >"Object" : string - var q1: string | number | boolean = strOrNumOrBool; // string | number | boolean + let q1: string | number | boolean = strOrNumOrBool; // string | number | boolean >q1 : string | number | boolean >strOrNumOrBool : string | number | boolean } else { - var q2: string | number | boolean = strOrNumOrBool; // string | number | boolean ->q2 : string | number | boolean ->strOrNumOrBool : string | number | boolean + let q2: {} = strOrNumOrBool; // {} +>q2 : {} +>strOrNumOrBool : {} } diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfString.js b/tests/baselines/reference/typeGuardOfFormTypeOfString.js index 5626396f73d..d79f73a87c5 100644 --- a/tests/baselines/reference/typeGuardOfFormTypeOfString.js +++ b/tests/baselines/reference/typeGuardOfFormTypeOfString.js @@ -42,12 +42,11 @@ else { c = strOrC; // C } -// Narrowing occurs only if target type is a subtype of variable type if (typeof numOrBool === "string") { - var x1: number | boolean = numOrBool; // number | boolean + let x1: {} = numOrBool; // {} } else { - var x2: number | boolean = numOrBool; // number | boolean + let x2: number | boolean = numOrBool; // number | boolean } // A type guard of the form typeof x !== s, where s is a string literal, @@ -78,12 +77,11 @@ else { str = strOrC; // string } -// Narrowing occurs only if target type is a subtype of variable type if (typeof numOrBool !== "string") { - var x1: number | boolean = numOrBool; // number | boolean + let x1: number | boolean = numOrBool; // number | boolean } else { - var x2: number | boolean = numOrBool; // number | boolean + let x2: {} = numOrBool; // {} } @@ -133,9 +131,8 @@ if (typeof strOrC === "string") { else { c = strOrC; // C } -// Narrowing occurs only if target type is a subtype of variable type if (typeof numOrBool === "string") { - var x1 = numOrBool; // number | boolean + var x1 = numOrBool; // {} } else { var x2 = numOrBool; // number | boolean @@ -167,10 +164,9 @@ if (typeof strOrC !== "string") { else { str = strOrC; // string } -// Narrowing occurs only if target type is a subtype of variable type if (typeof numOrBool !== "string") { var x1 = numOrBool; // number | boolean } else { - var x2 = numOrBool; // number | boolean + var x2 = numOrBool; // {} } diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfString.symbols b/tests/baselines/reference/typeGuardOfFormTypeOfString.symbols index d3209189f83..4a77ecb1ffb 100644 --- a/tests/baselines/reference/typeGuardOfFormTypeOfString.symbols +++ b/tests/baselines/reference/typeGuardOfFormTypeOfString.symbols @@ -93,17 +93,16 @@ else { >strOrC : Symbol(strOrC, Decl(typeGuardOfFormTypeOfString.ts, 9, 3)) } -// Narrowing occurs only if target type is a subtype of variable type if (typeof numOrBool === "string") { >numOrBool : Symbol(numOrBool, Decl(typeGuardOfFormTypeOfString.ts, 7, 3)) - var x1: number | boolean = numOrBool; // number | boolean ->x1 : Symbol(x1, Decl(typeGuardOfFormTypeOfString.ts, 45, 7), Decl(typeGuardOfFormTypeOfString.ts, 81, 7)) + let x1: {} = numOrBool; // {} +>x1 : Symbol(x1, Decl(typeGuardOfFormTypeOfString.ts, 44, 7)) >numOrBool : Symbol(numOrBool, Decl(typeGuardOfFormTypeOfString.ts, 7, 3)) } else { - var x2: number | boolean = numOrBool; // number | boolean ->x2 : Symbol(x2, Decl(typeGuardOfFormTypeOfString.ts, 48, 7), Decl(typeGuardOfFormTypeOfString.ts, 84, 7)) + let x2: number | boolean = numOrBool; // number | boolean +>x2 : Symbol(x2, Decl(typeGuardOfFormTypeOfString.ts, 47, 7)) >numOrBool : Symbol(numOrBool, Decl(typeGuardOfFormTypeOfString.ts, 7, 3)) } @@ -159,17 +158,16 @@ else { >strOrC : Symbol(strOrC, Decl(typeGuardOfFormTypeOfString.ts, 9, 3)) } -// Narrowing occurs only if target type is a subtype of variable type if (typeof numOrBool !== "string") { >numOrBool : Symbol(numOrBool, Decl(typeGuardOfFormTypeOfString.ts, 7, 3)) - var x1: number | boolean = numOrBool; // number | boolean ->x1 : Symbol(x1, Decl(typeGuardOfFormTypeOfString.ts, 45, 7), Decl(typeGuardOfFormTypeOfString.ts, 81, 7)) + let x1: number | boolean = numOrBool; // number | boolean +>x1 : Symbol(x1, Decl(typeGuardOfFormTypeOfString.ts, 79, 7)) >numOrBool : Symbol(numOrBool, Decl(typeGuardOfFormTypeOfString.ts, 7, 3)) } else { - var x2: number | boolean = numOrBool; // number | boolean ->x2 : Symbol(x2, Decl(typeGuardOfFormTypeOfString.ts, 48, 7), Decl(typeGuardOfFormTypeOfString.ts, 84, 7)) + let x2: {} = numOrBool; // {} +>x2 : Symbol(x2, Decl(typeGuardOfFormTypeOfString.ts, 82, 7)) >numOrBool : Symbol(numOrBool, Decl(typeGuardOfFormTypeOfString.ts, 7, 3)) } diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfString.types b/tests/baselines/reference/typeGuardOfFormTypeOfString.types index d6a382261ac..c77f9f3207a 100644 --- a/tests/baselines/reference/typeGuardOfFormTypeOfString.types +++ b/tests/baselines/reference/typeGuardOfFormTypeOfString.types @@ -113,19 +113,18 @@ else { >strOrC : C } -// Narrowing occurs only if target type is a subtype of variable type if (typeof numOrBool === "string") { >typeof numOrBool === "string" : boolean >typeof numOrBool : string >numOrBool : number | boolean >"string" : string - var x1: number | boolean = numOrBool; // number | boolean ->x1 : number | boolean ->numOrBool : number | boolean + let x1: {} = numOrBool; // {} +>x1 : {} +>numOrBool : {} } else { - var x2: number | boolean = numOrBool; // number | boolean + let x2: number | boolean = numOrBool; // number | boolean >x2 : number | boolean >numOrBool : number | boolean } @@ -202,20 +201,19 @@ else { >strOrC : string } -// Narrowing occurs only if target type is a subtype of variable type if (typeof numOrBool !== "string") { >typeof numOrBool !== "string" : boolean >typeof numOrBool : string >numOrBool : number | boolean >"string" : string - var x1: number | boolean = numOrBool; // number | boolean + let x1: number | boolean = numOrBool; // number | boolean >x1 : number | boolean >numOrBool : number | boolean } else { - var x2: number | boolean = numOrBool; // number | boolean ->x2 : number | boolean ->numOrBool : number | boolean + let x2: {} = numOrBool; // {} +>x2 : {} +>numOrBool : {} } diff --git a/tests/baselines/reference/typeGuardRedundancy.types b/tests/baselines/reference/typeGuardRedundancy.types index 1507ceb850e..754019de7ed 100644 --- a/tests/baselines/reference/typeGuardRedundancy.types +++ b/tests/baselines/reference/typeGuardRedundancy.types @@ -48,7 +48,7 @@ var r3 = typeof x === "string" || typeof x === "string" ? x.substr : x.toFixed; >typeof x === "string" || typeof x === "string" : boolean >typeof x === "string" : boolean >typeof x : string ->x : string | number +>x : number | string >"string" : string >typeof x === "string" : boolean >typeof x : string diff --git a/tests/baselines/reference/typeGuardTautologicalConsistiency.types b/tests/baselines/reference/typeGuardTautologicalConsistiency.types index d758dcde22b..100e528f616 100644 --- a/tests/baselines/reference/typeGuardTautologicalConsistiency.types +++ b/tests/baselines/reference/typeGuardTautologicalConsistiency.types @@ -15,7 +15,7 @@ if (typeof stringOrNumber === "number") { >"number" : string stringOrNumber; ->stringOrNumber : string | number +>stringOrNumber : {} } } @@ -23,7 +23,7 @@ if (typeof stringOrNumber === "number" && typeof stringOrNumber !== "number") { >typeof stringOrNumber === "number" && typeof stringOrNumber !== "number" : boolean >typeof stringOrNumber === "number" : boolean >typeof stringOrNumber : string ->stringOrNumber : string | number +>stringOrNumber : number | string >"number" : string >typeof stringOrNumber !== "number" : boolean >typeof stringOrNumber : string @@ -31,6 +31,6 @@ if (typeof stringOrNumber === "number" && typeof stringOrNumber !== "number") { >"number" : string stringOrNumber; ->stringOrNumber : string | number +>stringOrNumber : {} } diff --git a/tests/baselines/reference/typeGuardTypeOfUndefined.types b/tests/baselines/reference/typeGuardTypeOfUndefined.types index 6cf57e1a1dd..7073d9aeacb 100644 --- a/tests/baselines/reference/typeGuardTypeOfUndefined.types +++ b/tests/baselines/reference/typeGuardTypeOfUndefined.types @@ -26,7 +26,7 @@ function test1(a: any) { } else { a; ->a : any +>a : undefined } } @@ -43,15 +43,15 @@ function test2(a: any) { if (typeof a === "boolean") { >typeof a === "boolean" : boolean >typeof a : string ->a : any +>a : undefined >"boolean" : string a; ->a : boolean +>a : {} } else { a; ->a : any +>a : undefined } } else { @@ -76,7 +76,7 @@ function test3(a: any) { >"boolean" : string a; ->a : any +>a : boolean } else { a; @@ -121,7 +121,7 @@ function test5(a: boolean | void) { if (typeof a === "boolean") { >typeof a === "boolean" : boolean >typeof a : string ->a : boolean | void +>a : boolean >"boolean" : string a; @@ -129,7 +129,7 @@ function test5(a: boolean | void) { } else { a; ->a : void +>a : {} } } else { @@ -164,7 +164,7 @@ function test6(a: boolean | void) { } else { a; ->a : boolean | void +>a : boolean } } @@ -180,7 +180,7 @@ function test7(a: boolean | void) { >"undefined" : string >typeof a === "boolean" : boolean >typeof a : string ->a : boolean | void +>a : boolean >"boolean" : string a; @@ -188,7 +188,7 @@ function test7(a: boolean | void) { } else { a; ->a : void +>a : {} } } @@ -204,7 +204,7 @@ function test8(a: boolean | void) { >"undefined" : string >typeof a === "boolean" : boolean >typeof a : string ->a : boolean | void +>a : boolean >"boolean" : string a; @@ -337,7 +337,7 @@ function test13(a: boolean | number | void) { if (typeof a === "boolean") { >typeof a === "boolean" : boolean >typeof a : string ->a : boolean | number | void +>a : boolean | number >"boolean" : string a; @@ -345,7 +345,7 @@ function test13(a: boolean | number | void) { } else { a; ->a : number | void +>a : number } } else { @@ -380,7 +380,7 @@ function test14(a: boolean | number | void) { } else { a; ->a : boolean | number | void +>a : boolean | number } } @@ -396,7 +396,7 @@ function test15(a: boolean | number | void) { >"undefined" : string >typeof a === "boolean" : boolean >typeof a : string ->a : boolean | number | void +>a : boolean | number >"boolean" : string a; @@ -404,7 +404,7 @@ function test15(a: boolean | number | void) { } else { a; ->a : number | void +>a : number } } @@ -420,7 +420,7 @@ function test16(a: boolean | number | void) { >"undefined" : string >typeof a === "boolean" : boolean >typeof a : string ->a : boolean | number | void +>a : boolean | number >"boolean" : string a; diff --git a/tests/baselines/reference/typeGuardsInConditionalExpression.js b/tests/baselines/reference/typeGuardsInConditionalExpression.js index 118ebbc02c0..9aade91612a 100644 --- a/tests/baselines/reference/typeGuardsInConditionalExpression.js +++ b/tests/baselines/reference/typeGuardsInConditionalExpression.js @@ -12,43 +12,37 @@ function foo(x: number | string) { : x++; // number } function foo2(x: number | string) { - // x is assigned in the if true branch, the type is not narrowed return typeof x === "string" - ? (x = 10 && x)// string | number - : x; // string | number + ? ((x = "hello") && x) // string + : x; // number } function foo3(x: number | string) { - // x is assigned in the if false branch, the type is not narrowed - // even though assigned using same type as narrowed expression return typeof x === "string" - ? (x = "Hello" && x) // string | number - : x; // string | number + ? ((x = 10) && x) // number + : x; // number } function foo4(x: number | string) { - // false branch updates the variable - so here it is not number - // even though assigned using same type as narrowed expression return typeof x === "string" - ? x // string | number - : (x = 10 && x); // string | number + ? x // string + : ((x = 10) && x); // number } function foo5(x: number | string) { - // false branch updates the variable - so here it is not number return typeof x === "string" - ? x // string | number - : (x = "hello" && x); // string | number + ? x // string + : ((x = "hello") && x); // string } function foo6(x: number | string) { // Modify in both branches return typeof x === "string" - ? (x = 10 && x) // string | number - : (x = "hello" && x); // string | number + ? ((x = 10) && x) // number + : ((x = "hello") && x); // string } function foo7(x: number | string | boolean) { return typeof x === "string" - ? x === "hello" // string + ? x === "hello" // boolean : typeof x === "boolean" ? x // boolean - : x == 10; // number + : x == 10; // boolean } function foo8(x: number | string | boolean) { var b: number | boolean; @@ -57,14 +51,14 @@ function foo8(x: number | string | boolean) { : ((b = x) && // number | boolean (typeof x === "boolean" ? x // boolean - : x == 10)); // number + : x == 10)); // boolean } function foo9(x: number | string) { var y = 10; // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop return typeof x === "string" - ? ((y = x.length) && x === "hello") // string - : x === 10; // number + ? ((y = x.length) && x === "hello") // boolean + : x === 10; // boolean } function foo10(x: number | string | boolean) { // Mixing typeguards @@ -77,22 +71,20 @@ function foo10(x: number | string | boolean) { } function foo11(x: number | string | boolean) { // Mixing typeguards - // Assigning value to x deep inside another guard stops narrowing of type too var b: number | boolean | string; return typeof x === "string" - ? x // number | boolean | string - changed in the false branch - : ((b = x) // x is number | boolean | string - because the assignment changed it + ? x // string + : ((b = x) // x is number | boolean && typeof x === "number" && (x = 10) // assignment to x - && x); // x is number | boolean | string + && x); // x is number } function foo12(x: number | string | boolean) { // Mixing typeguards - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression var b: number | boolean | string; return typeof x === "string" - ? (x = 10 && x.toString().length) // number | boolean | string - changed here - : ((b = x) // x is number | boolean | string - changed in true branch + ? ((x = 10) && x.toString().length) // number + : ((b = x) // x is number | boolean && typeof x === "number" && x); // x is number } @@ -110,43 +102,37 @@ function foo(x) { : x++; // number } function foo2(x) { - // x is assigned in the if true branch, the type is not narrowed return typeof x === "string" - ? (x = 10 && x) // string | number - : x; // string | number + ? ((x = "hello") && x) // string + : x; // number } function foo3(x) { - // x is assigned in the if false branch, the type is not narrowed - // even though assigned using same type as narrowed expression return typeof x === "string" - ? (x = "Hello" && x) // string | number - : x; // string | number + ? ((x = 10) && x) // number + : x; // number } function foo4(x) { - // false branch updates the variable - so here it is not number - // even though assigned using same type as narrowed expression return typeof x === "string" - ? x // string | number - : (x = 10 && x); // string | number + ? x // string + : ((x = 10) && x); // number } function foo5(x) { - // false branch updates the variable - so here it is not number return typeof x === "string" - ? x // string | number - : (x = "hello" && x); // string | number + ? x // string + : ((x = "hello") && x); // string } function foo6(x) { // Modify in both branches return typeof x === "string" - ? (x = 10 && x) // string | number - : (x = "hello" && x); // string | number + ? ((x = 10) && x) // number + : ((x = "hello") && x); // string } function foo7(x) { return typeof x === "string" - ? x === "hello" // string + ? x === "hello" // boolean : typeof x === "boolean" ? x // boolean - : x == 10; // number + : x == 10; // boolean } function foo8(x) { var b; @@ -155,14 +141,14 @@ function foo8(x) { : ((b = x) && (typeof x === "boolean" ? x // boolean - : x == 10)); // number + : x == 10)); // boolean } function foo9(x) { var y = 10; // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop return typeof x === "string" - ? ((y = x.length) && x === "hello") // string - : x === 10; // number + ? ((y = x.length) && x === "hello") // boolean + : x === 10; // boolean } function foo10(x) { // Mixing typeguards @@ -175,22 +161,20 @@ function foo10(x) { } function foo11(x) { // Mixing typeguards - // Assigning value to x deep inside another guard stops narrowing of type too var b; return typeof x === "string" - ? x // number | boolean | string - changed in the false branch - : ((b = x) // x is number | boolean | string - because the assignment changed it + ? x // string + : ((b = x) // x is number | boolean && typeof x === "number" && (x = 10) // assignment to x - && x); // x is number | boolean | string + && x); // x is number } function foo12(x) { // Mixing typeguards - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression var b; return typeof x === "string" - ? (x = 10 && x.toString().length) // number | boolean | string - changed here - : ((b = x) // x is number | boolean | string - changed in true branch + ? ((x = 10) && x.toString().length) // number + : ((b = x) // x is number | boolean && typeof x === "number" && x); // x is number } diff --git a/tests/baselines/reference/typeGuardsInConditionalExpression.symbols b/tests/baselines/reference/typeGuardsInConditionalExpression.symbols index 7de63d90bf9..ada6a6d99fd 100644 --- a/tests/baselines/reference/typeGuardsInConditionalExpression.symbols +++ b/tests/baselines/reference/typeGuardsInConditionalExpression.symbols @@ -25,227 +25,219 @@ function foo2(x: number | string) { >foo2 : Symbol(foo2, Decl(typeGuardsInConditionalExpression.ts, 11, 1)) >x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 12, 14)) - // x is assigned in the if true branch, the type is not narrowed return typeof x === "string" >x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 12, 14)) - ? (x = 10 && x)// string | number + ? ((x = "hello") && x) // string >x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 12, 14)) >x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 12, 14)) - : x; // string | number + : x; // number >x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 12, 14)) } function foo3(x: number | string) { ->foo3 : Symbol(foo3, Decl(typeGuardsInConditionalExpression.ts, 17, 1)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 18, 14)) +>foo3 : Symbol(foo3, Decl(typeGuardsInConditionalExpression.ts, 16, 1)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 17, 14)) - // x is assigned in the if false branch, the type is not narrowed - // even though assigned using same type as narrowed expression return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 18, 14)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 17, 14)) - ? (x = "Hello" && x) // string | number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 18, 14)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 18, 14)) + ? ((x = 10) && x) // number +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 17, 14)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 17, 14)) - : x; // string | number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 18, 14)) + : x; // number +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 17, 14)) } function foo4(x: number | string) { ->foo4 : Symbol(foo4, Decl(typeGuardsInConditionalExpression.ts, 24, 1)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 25, 14)) +>foo4 : Symbol(foo4, Decl(typeGuardsInConditionalExpression.ts, 21, 1)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 22, 14)) - // false branch updates the variable - so here it is not number - // even though assigned using same type as narrowed expression return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 25, 14)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 22, 14)) - ? x // string | number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 25, 14)) + ? x // string +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 22, 14)) - : (x = 10 && x); // string | number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 25, 14)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 25, 14)) + : ((x = 10) && x); // number +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 22, 14)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 22, 14)) } function foo5(x: number | string) { ->foo5 : Symbol(foo5, Decl(typeGuardsInConditionalExpression.ts, 31, 1)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 32, 14)) +>foo5 : Symbol(foo5, Decl(typeGuardsInConditionalExpression.ts, 26, 1)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 27, 14)) - // false branch updates the variable - so here it is not number return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 32, 14)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 27, 14)) - ? x // string | number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 32, 14)) + ? x // string +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 27, 14)) - : (x = "hello" && x); // string | number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 32, 14)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 32, 14)) + : ((x = "hello") && x); // string +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 27, 14)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 27, 14)) } function foo6(x: number | string) { ->foo6 : Symbol(foo6, Decl(typeGuardsInConditionalExpression.ts, 37, 1)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 38, 14)) +>foo6 : Symbol(foo6, Decl(typeGuardsInConditionalExpression.ts, 31, 1)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 32, 14)) // Modify in both branches return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 38, 14)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 32, 14)) - ? (x = 10 && x) // string | number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 38, 14)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 38, 14)) + ? ((x = 10) && x) // number +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 32, 14)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 32, 14)) - : (x = "hello" && x); // string | number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 38, 14)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 38, 14)) + : ((x = "hello") && x); // string +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 32, 14)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 32, 14)) } function foo7(x: number | string | boolean) { ->foo7 : Symbol(foo7, Decl(typeGuardsInConditionalExpression.ts, 43, 1)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 44, 14)) +>foo7 : Symbol(foo7, Decl(typeGuardsInConditionalExpression.ts, 37, 1)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 38, 14)) return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 44, 14)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 38, 14)) - ? x === "hello" // string ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 44, 14)) + ? x === "hello" // boolean +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 38, 14)) : typeof x === "boolean" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 44, 14)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 38, 14)) ? x // boolean ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 44, 14)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 38, 14)) - : x == 10; // number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 44, 14)) + : x == 10; // boolean +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 38, 14)) } function foo8(x: number | string | boolean) { ->foo8 : Symbol(foo8, Decl(typeGuardsInConditionalExpression.ts, 50, 1)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 51, 14)) +>foo8 : Symbol(foo8, Decl(typeGuardsInConditionalExpression.ts, 44, 1)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 45, 14)) var b: number | boolean; ->b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 52, 7)) +>b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 46, 7)) return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 51, 14)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 45, 14)) ? x === "hello" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 51, 14)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 45, 14)) : ((b = x) && // number | boolean ->b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 52, 7)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 51, 14)) +>b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 46, 7)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 45, 14)) (typeof x === "boolean" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 51, 14)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 45, 14)) ? x // boolean ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 51, 14)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 45, 14)) - : x == 10)); // number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 51, 14)) + : x == 10)); // boolean +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 45, 14)) } function foo9(x: number | string) { ->foo9 : Symbol(foo9, Decl(typeGuardsInConditionalExpression.ts, 59, 1)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 60, 14)) +>foo9 : Symbol(foo9, Decl(typeGuardsInConditionalExpression.ts, 53, 1)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 54, 14)) var y = 10; ->y : Symbol(y, Decl(typeGuardsInConditionalExpression.ts, 61, 7)) +>y : Symbol(y, Decl(typeGuardsInConditionalExpression.ts, 55, 7)) // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 60, 14)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 54, 14)) - ? ((y = x.length) && x === "hello") // string ->y : Symbol(y, Decl(typeGuardsInConditionalExpression.ts, 61, 7)) + ? ((y = x.length) && x === "hello") // boolean +>y : Symbol(y, Decl(typeGuardsInConditionalExpression.ts, 55, 7)) >x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 60, 14)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 54, 14)) >length : Symbol(String.length, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 60, 14)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 54, 14)) - : x === 10; // number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 60, 14)) + : x === 10; // boolean +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 54, 14)) } function foo10(x: number | string | boolean) { ->foo10 : Symbol(foo10, Decl(typeGuardsInConditionalExpression.ts, 66, 1)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 67, 15)) +>foo10 : Symbol(foo10, Decl(typeGuardsInConditionalExpression.ts, 60, 1)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 61, 15)) // Mixing typeguards var b: boolean | number; ->b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 69, 7)) +>b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 63, 7)) return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 67, 15)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 61, 15)) ? x // string ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 67, 15)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 61, 15)) : ((b = x) // x is number | boolean ->b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 69, 7)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 67, 15)) +>b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 63, 7)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 61, 15)) && typeof x === "number" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 67, 15)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 61, 15)) && x.toString()); // x is number >x.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 67, 15)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 61, 15)) >toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) } function foo11(x: number | string | boolean) { ->foo11 : Symbol(foo11, Decl(typeGuardsInConditionalExpression.ts, 75, 1)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 76, 15)) +>foo11 : Symbol(foo11, Decl(typeGuardsInConditionalExpression.ts, 69, 1)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 70, 15)) // Mixing typeguards - // Assigning value to x deep inside another guard stops narrowing of type too var b: number | boolean | string; ->b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 79, 7)) +>b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 72, 7)) return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 76, 15)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 70, 15)) - ? x // number | boolean | string - changed in the false branch ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 76, 15)) + ? x // string +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 70, 15)) - : ((b = x) // x is number | boolean | string - because the assignment changed it ->b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 79, 7)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 76, 15)) + : ((b = x) // x is number | boolean +>b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 72, 7)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 70, 15)) && typeof x === "number" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 76, 15)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 70, 15)) && (x = 10) // assignment to x ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 76, 15)) - - && x); // x is number | boolean | string ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 76, 15)) -} -function foo12(x: number | string | boolean) { ->foo12 : Symbol(foo12, Decl(typeGuardsInConditionalExpression.ts, 86, 1)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 87, 15)) - - // Mixing typeguards - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - var b: number | boolean | string; ->b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 90, 7)) - - return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 87, 15)) - - ? (x = 10 && x.toString().length) // number | boolean | string - changed here ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 87, 15)) ->x.toString().length : Symbol(String.length, Decl(lib.d.ts, --, --)) ->x.toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 87, 15)) ->toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) ->length : Symbol(String.length, Decl(lib.d.ts, --, --)) - - : ((b = x) // x is number | boolean | string - changed in true branch ->b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 90, 7)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 87, 15)) - - && typeof x === "number" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 87, 15)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 70, 15)) && x); // x is number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 87, 15)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 70, 15)) +} +function foo12(x: number | string | boolean) { +>foo12 : Symbol(foo12, Decl(typeGuardsInConditionalExpression.ts, 79, 1)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 80, 15)) + + // Mixing typeguards + var b: number | boolean | string; +>b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 82, 7)) + + return typeof x === "string" +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 80, 15)) + + ? ((x = 10) && x.toString().length) // number +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 80, 15)) +>x.toString().length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>x.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 80, 15)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) + + : ((b = x) // x is number | boolean +>b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 82, 7)) +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 80, 15)) + + && typeof x === "number" +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 80, 15)) + + && x); // x is number +>x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 80, 15)) } diff --git a/tests/baselines/reference/typeGuardsInConditionalExpression.types b/tests/baselines/reference/typeGuardsInConditionalExpression.types index 493a8c0a31a..cc1459738e4 100644 --- a/tests/baselines/reference/typeGuardsInConditionalExpression.types +++ b/tests/baselines/reference/typeGuardsInConditionalExpression.types @@ -27,98 +27,96 @@ function foo(x: number | string) { >x : number } function foo2(x: number | string) { ->foo2 : (x: number | string) => number | string +>foo2 : (x: number | string) => string | number >x : number | string - // x is assigned in the if true branch, the type is not narrowed return typeof x === "string" ->typeof x === "string" ? (x = 10 && x)// string | number : x : number | string +>typeof x === "string" ? ((x = "hello") && x) // string : x : string | number >typeof x === "string" : boolean >typeof x : string >x : number | string >"string" : string - ? (x = 10 && x)// string | number ->(x = 10 && x) : number | string ->x = 10 && x : number | string ->x : number | string ->10 && x : number | string ->10 : number + ? ((x = "hello") && x) // string +>((x = "hello") && x) : string +>(x = "hello") && x : string +>(x = "hello") : string +>x = "hello" : string >x : number | string +>"hello" : string +>x : string - : x; // string | number ->x : number | string + : x; // number +>x : number } function foo3(x: number | string) { ->foo3 : (x: number | string) => number | string +>foo3 : (x: number | string) => number >x : number | string - // x is assigned in the if false branch, the type is not narrowed - // even though assigned using same type as narrowed expression return typeof x === "string" ->typeof x === "string" ? (x = "Hello" && x) // string | number : x : number | string +>typeof x === "string" ? ((x = 10) && x) // number : x : number >typeof x === "string" : boolean >typeof x : string >x : number | string >"string" : string - ? (x = "Hello" && x) // string | number ->(x = "Hello" && x) : number | string ->x = "Hello" && x : number | string ->x : number | string ->"Hello" && x : number | string ->"Hello" : string + ? ((x = 10) && x) // number +>((x = 10) && x) : number +>(x = 10) && x : number +>(x = 10) : number +>x = 10 : number >x : number | string +>10 : number +>x : number - : x; // string | number ->x : number | string + : x; // number +>x : number } function foo4(x: number | string) { ->foo4 : (x: number | string) => number | string +>foo4 : (x: number | string) => string | number >x : number | string - // false branch updates the variable - so here it is not number - // even though assigned using same type as narrowed expression return typeof x === "string" ->typeof x === "string" ? x // string | number : (x = 10 && x) : number | string +>typeof x === "string" ? x // string : ((x = 10) && x) : string | number >typeof x === "string" : boolean >typeof x : string >x : number | string >"string" : string - ? x // string | number ->x : number | string + ? x // string +>x : string - : (x = 10 && x); // string | number ->(x = 10 && x) : number | string ->x = 10 && x : number | string + : ((x = 10) && x); // number +>((x = 10) && x) : number +>(x = 10) && x : number +>(x = 10) : number +>x = 10 : number >x : number | string ->10 && x : number | string >10 : number ->x : number | string +>x : number } function foo5(x: number | string) { ->foo5 : (x: number | string) => number | string +>foo5 : (x: number | string) => string >x : number | string - // false branch updates the variable - so here it is not number return typeof x === "string" ->typeof x === "string" ? x // string | number : (x = "hello" && x) : number | string +>typeof x === "string" ? x // string : ((x = "hello") && x) : string >typeof x === "string" : boolean >typeof x : string >x : number | string >"string" : string - ? x // string | number ->x : number | string + ? x // string +>x : string - : (x = "hello" && x); // string | number ->(x = "hello" && x) : number | string ->x = "hello" && x : number | string + : ((x = "hello") && x); // string +>((x = "hello") && x) : string +>(x = "hello") && x : string +>(x = "hello") : string +>x = "hello" : string >x : number | string ->"hello" && x : number | string >"hello" : string ->x : number | string +>x : string } function foo6(x: number | string) { >foo6 : (x: number | string) => number | string @@ -126,40 +124,42 @@ function foo6(x: number | string) { // Modify in both branches return typeof x === "string" ->typeof x === "string" ? (x = 10 && x) // string | number : (x = "hello" && x) : number | string +>typeof x === "string" ? ((x = 10) && x) // number : ((x = "hello") && x) : number | string >typeof x === "string" : boolean >typeof x : string >x : number | string >"string" : string - ? (x = 10 && x) // string | number ->(x = 10 && x) : number | string ->x = 10 && x : number | string + ? ((x = 10) && x) // number +>((x = 10) && x) : number +>(x = 10) && x : number +>(x = 10) : number +>x = 10 : number >x : number | string ->10 && x : number | string >10 : number ->x : number | string +>x : number - : (x = "hello" && x); // string | number ->(x = "hello" && x) : number | string ->x = "hello" && x : number | string + : ((x = "hello") && x); // string +>((x = "hello") && x) : string +>(x = "hello") && x : string +>(x = "hello") : string +>x = "hello" : string >x : number | string ->"hello" && x : number | string >"hello" : string ->x : number | string +>x : string } function foo7(x: number | string | boolean) { >foo7 : (x: number | string | boolean) => boolean >x : number | string | boolean return typeof x === "string" ->typeof x === "string" ? x === "hello" // string : typeof x === "boolean" ? x // boolean : x == 10 : boolean +>typeof x === "string" ? x === "hello" // boolean : typeof x === "boolean" ? x // boolean : x == 10 : boolean >typeof x === "string" : boolean >typeof x : string >x : number | string | boolean >"string" : string - ? x === "hello" // string + ? x === "hello" // boolean >x === "hello" : boolean >x : string >"hello" : string @@ -174,7 +174,7 @@ function foo7(x: number | string | boolean) { ? x // boolean >x : boolean - : x == 10; // number + : x == 10; // boolean >x == 10 : boolean >x : number >10 : number @@ -217,7 +217,7 @@ function foo8(x: number | string | boolean) { ? x // boolean >x : boolean - : x == 10)); // number + : x == 10)); // boolean >x == 10 : boolean >x : number >10 : number @@ -232,13 +232,13 @@ function foo9(x: number | string) { // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop return typeof x === "string" ->typeof x === "string" ? ((y = x.length) && x === "hello") // string : x === 10 : boolean +>typeof x === "string" ? ((y = x.length) && x === "hello") // boolean : x === 10 : boolean >typeof x === "string" : boolean >typeof x : string >x : number | string >"string" : string - ? ((y = x.length) && x === "hello") // string + ? ((y = x.length) && x === "hello") // boolean >((y = x.length) && x === "hello") : boolean >(y = x.length) && x === "hello" : boolean >(y = x.length) : number @@ -251,7 +251,7 @@ function foo9(x: number | string) { >x : string >"hello" : string - : x === 10; // number + : x === 10; // boolean >x === 10 : boolean >x : number >10 : number @@ -296,38 +296,37 @@ function foo10(x: number | string | boolean) { >toString : (radix?: number) => string } function foo11(x: number | string | boolean) { ->foo11 : (x: number | string | boolean) => number | string | boolean +>foo11 : (x: number | string | boolean) => string | number >x : number | string | boolean // Mixing typeguards - // Assigning value to x deep inside another guard stops narrowing of type too var b: number | boolean | string; >b : number | boolean | string return typeof x === "string" ->typeof x === "string" ? x // number | boolean | string - changed in the false branch : ((b = x) // x is number | boolean | string - because the assignment changed it && typeof x === "number" && (x = 10) // assignment to x && x) : number | string | boolean +>typeof x === "string" ? x // string : ((b = x) // x is number | boolean && typeof x === "number" && (x = 10) // assignment to x && x) : string | number >typeof x === "string" : boolean >typeof x : string >x : number | string | boolean >"string" : string - ? x // number | boolean | string - changed in the false branch ->x : number | string | boolean + ? x // string +>x : string - : ((b = x) // x is number | boolean | string - because the assignment changed it ->((b = x) // x is number | boolean | string - because the assignment changed it && typeof x === "number" && (x = 10) // assignment to x && x) : number | string | boolean ->(b = x) // x is number | boolean | string - because the assignment changed it && typeof x === "number" && (x = 10) // assignment to x && x : number | string | boolean ->(b = x) // x is number | boolean | string - because the assignment changed it && typeof x === "number" && (x = 10) : number ->(b = x) // x is number | boolean | string - because the assignment changed it && typeof x === "number" : boolean ->(b = x) : number | string | boolean ->b = x : number | string | boolean + : ((b = x) // x is number | boolean +>((b = x) // x is number | boolean && typeof x === "number" && (x = 10) // assignment to x && x) : number +>(b = x) // x is number | boolean && typeof x === "number" && (x = 10) // assignment to x && x : number +>(b = x) // x is number | boolean && typeof x === "number" && (x = 10) : number +>(b = x) // x is number | boolean && typeof x === "number" : boolean +>(b = x) : number | boolean +>b = x : number | boolean >b : number | boolean | string ->x : number | string | boolean +>x : number | boolean && typeof x === "number" >typeof x === "number" : boolean >typeof x : string ->x : number | string | boolean +>x : number | boolean >"number" : string && (x = 10) // assignment to x @@ -336,51 +335,51 @@ function foo11(x: number | string | boolean) { >x : number | string | boolean >10 : number - && x); // x is number | boolean | string ->x : number | string | boolean + && x); // x is number +>x : number } function foo12(x: number | string | boolean) { >foo12 : (x: number | string | boolean) => number >x : number | string | boolean // Mixing typeguards - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression var b: number | boolean | string; >b : number | boolean | string return typeof x === "string" ->typeof x === "string" ? (x = 10 && x.toString().length) // number | boolean | string - changed here : ((b = x) // x is number | boolean | string - changed in true branch && typeof x === "number" && x) : number +>typeof x === "string" ? ((x = 10) && x.toString().length) // number : ((b = x) // x is number | boolean && typeof x === "number" && x) : number >typeof x === "string" : boolean >typeof x : string >x : number | string | boolean >"string" : string - ? (x = 10 && x.toString().length) // number | boolean | string - changed here ->(x = 10 && x.toString().length) : number ->x = 10 && x.toString().length : number + ? ((x = 10) && x.toString().length) // number +>((x = 10) && x.toString().length) : number +>(x = 10) && x.toString().length : number +>(x = 10) : number +>x = 10 : number >x : number | string | boolean ->10 && x.toString().length : number >10 : number >x.toString().length : number >x.toString() : string >x.toString : (radix?: number) => string ->x : number | string | boolean +>x : number >toString : (radix?: number) => string >length : number - : ((b = x) // x is number | boolean | string - changed in true branch ->((b = x) // x is number | boolean | string - changed in true branch && typeof x === "number" && x) : number ->(b = x) // x is number | boolean | string - changed in true branch && typeof x === "number" && x : number ->(b = x) // x is number | boolean | string - changed in true branch && typeof x === "number" : boolean ->(b = x) : number | string | boolean ->b = x : number | string | boolean + : ((b = x) // x is number | boolean +>((b = x) // x is number | boolean && typeof x === "number" && x) : number +>(b = x) // x is number | boolean && typeof x === "number" && x : number +>(b = x) // x is number | boolean && typeof x === "number" : boolean +>(b = x) : number | boolean +>b = x : number | boolean >b : number | boolean | string ->x : number | string | boolean +>x : number | boolean && typeof x === "number" >typeof x === "number" : boolean >typeof x : string ->x : number | string | boolean +>x : number | boolean >"number" : string && x); // x is number diff --git a/tests/baselines/reference/typeGuardsInDoStatement.js b/tests/baselines/reference/typeGuardsInDoStatement.js new file mode 100644 index 00000000000..7d299854f7d --- /dev/null +++ b/tests/baselines/reference/typeGuardsInDoStatement.js @@ -0,0 +1,60 @@ +//// [typeGuardsInDoStatement.ts] +let cond: boolean; +function a(x: string | number | boolean) { + x = true; + do { + x; // boolean | string + x = undefined; + } while (typeof x === "string") + x; // number | boolean +} +function b(x: string | number | boolean) { + x = true; + do { + x; // boolean | string + if (cond) continue; + x = undefined; + } while (typeof x === "string") + x; // number | boolean +} +function c(x: string | number) { + x = ""; + do { + x; // string + if (cond) break; + x = undefined; + } while (typeof x === "string") + x; // string | number +} + + +//// [typeGuardsInDoStatement.js] +var cond; +function a(x) { + x = true; + do { + x; // boolean | string + x = undefined; + } while (typeof x === "string"); + x; // number | boolean +} +function b(x) { + x = true; + do { + x; // boolean | string + if (cond) + continue; + x = undefined; + } while (typeof x === "string"); + x; // number | boolean +} +function c(x) { + x = ""; + do { + x; // string + if (cond) + break; + x = undefined; + } while (typeof x === "string"); + x; // string | number +} diff --git a/tests/baselines/reference/typeGuardsInDoStatement.symbols b/tests/baselines/reference/typeGuardsInDoStatement.symbols new file mode 100644 index 00000000000..7dff18d8d23 --- /dev/null +++ b/tests/baselines/reference/typeGuardsInDoStatement.symbols @@ -0,0 +1,74 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardsInDoStatement.ts === +let cond: boolean; +>cond : Symbol(cond, Decl(typeGuardsInDoStatement.ts, 0, 3)) + +function a(x: string | number | boolean) { +>a : Symbol(a, Decl(typeGuardsInDoStatement.ts, 0, 18)) +>x : Symbol(x, Decl(typeGuardsInDoStatement.ts, 1, 11)) + + x = true; +>x : Symbol(x, Decl(typeGuardsInDoStatement.ts, 1, 11)) + + do { + x; // boolean | string +>x : Symbol(x, Decl(typeGuardsInDoStatement.ts, 1, 11)) + + x = undefined; +>x : Symbol(x, Decl(typeGuardsInDoStatement.ts, 1, 11)) +>undefined : Symbol(undefined) + + } while (typeof x === "string") +>x : Symbol(x, Decl(typeGuardsInDoStatement.ts, 1, 11)) + + x; // number | boolean +>x : Symbol(x, Decl(typeGuardsInDoStatement.ts, 1, 11)) +} +function b(x: string | number | boolean) { +>b : Symbol(b, Decl(typeGuardsInDoStatement.ts, 8, 1)) +>x : Symbol(x, Decl(typeGuardsInDoStatement.ts, 9, 11)) + + x = true; +>x : Symbol(x, Decl(typeGuardsInDoStatement.ts, 9, 11)) + + do { + x; // boolean | string +>x : Symbol(x, Decl(typeGuardsInDoStatement.ts, 9, 11)) + + if (cond) continue; +>cond : Symbol(cond, Decl(typeGuardsInDoStatement.ts, 0, 3)) + + x = undefined; +>x : Symbol(x, Decl(typeGuardsInDoStatement.ts, 9, 11)) +>undefined : Symbol(undefined) + + } while (typeof x === "string") +>x : Symbol(x, Decl(typeGuardsInDoStatement.ts, 9, 11)) + + x; // number | boolean +>x : Symbol(x, Decl(typeGuardsInDoStatement.ts, 9, 11)) +} +function c(x: string | number) { +>c : Symbol(c, Decl(typeGuardsInDoStatement.ts, 17, 1)) +>x : Symbol(x, Decl(typeGuardsInDoStatement.ts, 18, 11)) + + x = ""; +>x : Symbol(x, Decl(typeGuardsInDoStatement.ts, 18, 11)) + + do { + x; // string +>x : Symbol(x, Decl(typeGuardsInDoStatement.ts, 18, 11)) + + if (cond) break; +>cond : Symbol(cond, Decl(typeGuardsInDoStatement.ts, 0, 3)) + + x = undefined; +>x : Symbol(x, Decl(typeGuardsInDoStatement.ts, 18, 11)) +>undefined : Symbol(undefined) + + } while (typeof x === "string") +>x : Symbol(x, Decl(typeGuardsInDoStatement.ts, 18, 11)) + + x; // string | number +>x : Symbol(x, Decl(typeGuardsInDoStatement.ts, 18, 11)) +} + diff --git a/tests/baselines/reference/typeGuardsInDoStatement.types b/tests/baselines/reference/typeGuardsInDoStatement.types new file mode 100644 index 00000000000..79183e7d6c8 --- /dev/null +++ b/tests/baselines/reference/typeGuardsInDoStatement.types @@ -0,0 +1,92 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardsInDoStatement.ts === +let cond: boolean; +>cond : boolean + +function a(x: string | number | boolean) { +>a : (x: string | number | boolean) => void +>x : string | number | boolean + + x = true; +>x = true : boolean +>x : string | number | boolean +>true : boolean + + do { + x; // boolean | string +>x : boolean | string + + x = undefined; +>x = undefined : undefined +>x : string | number | boolean +>undefined : undefined + + } while (typeof x === "string") +>typeof x === "string" : boolean +>typeof x : string +>x : string | number | boolean +>"string" : string + + x; // number | boolean +>x : number | boolean +} +function b(x: string | number | boolean) { +>b : (x: string | number | boolean) => void +>x : string | number | boolean + + x = true; +>x = true : boolean +>x : string | number | boolean +>true : boolean + + do { + x; // boolean | string +>x : boolean | string + + if (cond) continue; +>cond : boolean + + x = undefined; +>x = undefined : undefined +>x : string | number | boolean +>undefined : undefined + + } while (typeof x === "string") +>typeof x === "string" : boolean +>typeof x : string +>x : string | number | boolean +>"string" : string + + x; // number | boolean +>x : number | boolean +} +function c(x: string | number) { +>c : (x: string | number) => void +>x : string | number + + x = ""; +>x = "" : string +>x : string | number +>"" : string + + do { + x; // string +>x : string + + if (cond) break; +>cond : boolean + + x = undefined; +>x = undefined : undefined +>x : string | number +>undefined : undefined + + } while (typeof x === "string") +>typeof x === "string" : boolean +>typeof x : string +>x : string | number +>"string" : string + + x; // string | number +>x : string | number +} + diff --git a/tests/baselines/reference/typeGuardsInForStatement.js b/tests/baselines/reference/typeGuardsInForStatement.js new file mode 100644 index 00000000000..a2e104bc3f1 --- /dev/null +++ b/tests/baselines/reference/typeGuardsInForStatement.js @@ -0,0 +1,48 @@ +//// [typeGuardsInForStatement.ts] +let cond: boolean; +function a(x: string | number) { + for (x = undefined; typeof x !== "number"; x = undefined) { + x; // string + } + x; // number +} +function b(x: string | number) { + for (x = undefined; typeof x !== "number"; x = undefined) { + x; // string + if (cond) continue; + } + x; // number +} +function c(x: string | number) { + for (x = undefined; typeof x !== "number"; x = undefined) { + x; // string + if (cond) break; + } + x; // string | number +} + + +//// [typeGuardsInForStatement.js] +var cond; +function a(x) { + for (x = undefined; typeof x !== "number"; x = undefined) { + x; // string + } + x; // number +} +function b(x) { + for (x = undefined; typeof x !== "number"; x = undefined) { + x; // string + if (cond) + continue; + } + x; // number +} +function c(x) { + for (x = undefined; typeof x !== "number"; x = undefined) { + x; // string + if (cond) + break; + } + x; // string | number +} diff --git a/tests/baselines/reference/typeGuardsInForStatement.symbols b/tests/baselines/reference/typeGuardsInForStatement.symbols new file mode 100644 index 00000000000..fe1c10eb14e --- /dev/null +++ b/tests/baselines/reference/typeGuardsInForStatement.symbols @@ -0,0 +1,62 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardsInForStatement.ts === +let cond: boolean; +>cond : Symbol(cond, Decl(typeGuardsInForStatement.ts, 0, 3)) + +function a(x: string | number) { +>a : Symbol(a, Decl(typeGuardsInForStatement.ts, 0, 18)) +>x : Symbol(x, Decl(typeGuardsInForStatement.ts, 1, 11)) + + for (x = undefined; typeof x !== "number"; x = undefined) { +>x : Symbol(x, Decl(typeGuardsInForStatement.ts, 1, 11)) +>undefined : Symbol(undefined) +>x : Symbol(x, Decl(typeGuardsInForStatement.ts, 1, 11)) +>x : Symbol(x, Decl(typeGuardsInForStatement.ts, 1, 11)) +>undefined : Symbol(undefined) + + x; // string +>x : Symbol(x, Decl(typeGuardsInForStatement.ts, 1, 11)) + } + x; // number +>x : Symbol(x, Decl(typeGuardsInForStatement.ts, 1, 11)) +} +function b(x: string | number) { +>b : Symbol(b, Decl(typeGuardsInForStatement.ts, 6, 1)) +>x : Symbol(x, Decl(typeGuardsInForStatement.ts, 7, 11)) + + for (x = undefined; typeof x !== "number"; x = undefined) { +>x : Symbol(x, Decl(typeGuardsInForStatement.ts, 7, 11)) +>undefined : Symbol(undefined) +>x : Symbol(x, Decl(typeGuardsInForStatement.ts, 7, 11)) +>x : Symbol(x, Decl(typeGuardsInForStatement.ts, 7, 11)) +>undefined : Symbol(undefined) + + x; // string +>x : Symbol(x, Decl(typeGuardsInForStatement.ts, 7, 11)) + + if (cond) continue; +>cond : Symbol(cond, Decl(typeGuardsInForStatement.ts, 0, 3)) + } + x; // number +>x : Symbol(x, Decl(typeGuardsInForStatement.ts, 7, 11)) +} +function c(x: string | number) { +>c : Symbol(c, Decl(typeGuardsInForStatement.ts, 13, 1)) +>x : Symbol(x, Decl(typeGuardsInForStatement.ts, 14, 11)) + + for (x = undefined; typeof x !== "number"; x = undefined) { +>x : Symbol(x, Decl(typeGuardsInForStatement.ts, 14, 11)) +>undefined : Symbol(undefined) +>x : Symbol(x, Decl(typeGuardsInForStatement.ts, 14, 11)) +>x : Symbol(x, Decl(typeGuardsInForStatement.ts, 14, 11)) +>undefined : Symbol(undefined) + + x; // string +>x : Symbol(x, Decl(typeGuardsInForStatement.ts, 14, 11)) + + if (cond) break; +>cond : Symbol(cond, Decl(typeGuardsInForStatement.ts, 0, 3)) + } + x; // string | number +>x : Symbol(x, Decl(typeGuardsInForStatement.ts, 14, 11)) +} + diff --git a/tests/baselines/reference/typeGuardsInForStatement.types b/tests/baselines/reference/typeGuardsInForStatement.types new file mode 100644 index 00000000000..5ebdea53c31 --- /dev/null +++ b/tests/baselines/reference/typeGuardsInForStatement.types @@ -0,0 +1,77 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardsInForStatement.ts === +let cond: boolean; +>cond : boolean + +function a(x: string | number) { +>a : (x: string | number) => void +>x : string | number + + for (x = undefined; typeof x !== "number"; x = undefined) { +>x = undefined : undefined +>x : string | number +>undefined : undefined +>typeof x !== "number" : boolean +>typeof x : string +>x : string | number +>"number" : string +>x = undefined : undefined +>x : string | number +>undefined : undefined + + x; // string +>x : string + } + x; // number +>x : number +} +function b(x: string | number) { +>b : (x: string | number) => void +>x : string | number + + for (x = undefined; typeof x !== "number"; x = undefined) { +>x = undefined : undefined +>x : string | number +>undefined : undefined +>typeof x !== "number" : boolean +>typeof x : string +>x : string | number +>"number" : string +>x = undefined : undefined +>x : string | number +>undefined : undefined + + x; // string +>x : string + + if (cond) continue; +>cond : boolean + } + x; // number +>x : number +} +function c(x: string | number) { +>c : (x: string | number) => void +>x : string | number + + for (x = undefined; typeof x !== "number"; x = undefined) { +>x = undefined : undefined +>x : string | number +>undefined : undefined +>typeof x !== "number" : boolean +>typeof x : string +>x : string | number +>"number" : string +>x = undefined : undefined +>x : string | number +>undefined : undefined + + x; // string +>x : string + + if (cond) break; +>cond : boolean + } + x; // string | number +>x : number | string +} + diff --git a/tests/baselines/reference/typeGuardsInIfStatement.errors.txt b/tests/baselines/reference/typeGuardsInIfStatement.errors.txt new file mode 100644 index 00000000000..984ca454e76 --- /dev/null +++ b/tests/baselines/reference/typeGuardsInIfStatement.errors.txt @@ -0,0 +1,153 @@ +tests/cases/conformance/expressions/typeGuards/typeGuardsInIfStatement.ts(22,10): error TS2354: No best common type exists among return expressions. +tests/cases/conformance/expressions/typeGuards/typeGuardsInIfStatement.ts(31,10): error TS2354: No best common type exists among return expressions. +tests/cases/conformance/expressions/typeGuards/typeGuardsInIfStatement.ts(49,10): error TS2354: No best common type exists among return expressions. + + +==== tests/cases/conformance/expressions/typeGuards/typeGuardsInIfStatement.ts (3 errors) ==== + // In the true branch statement of an 'if' statement, + // the type of a variable or parameter is narrowed by any type guard in the 'if' condition when true. + // In the false branch statement of an 'if' statement, + // the type of a variable or parameter is narrowed by any type guard in the 'if' condition when false. + function foo(x: number | string) { + if (typeof x === "string") { + return x.length; // string + } + else { + return x++; // number + } + } + function foo2(x: number | string) { + if (typeof x === "string") { + x = 10; + return x; // number + } + else { + return x; // number + } + } + function foo3(x: number | string) { + ~~~~ +!!! error TS2354: No best common type exists among return expressions. + if (typeof x === "string") { + x = "Hello"; + return x; // string + } + else { + return x; // number + } + } + function foo4(x: number | string) { + ~~~~ +!!! error TS2354: No best common type exists among return expressions. + if (typeof x === "string") { + return x; // string + } + else { + x = 10; + return x; // number + } + } + function foo5(x: number | string) { + if (typeof x === "string") { + return x; // string + } + else { + x = "hello"; + return x; // string + } + } + function foo6(x: number | string) { + ~~~~ +!!! error TS2354: No best common type exists among return expressions. + if (typeof x === "string") { + x = 10; + return x; // number + } + else { + x = "hello"; + return x; // string + } + } + function foo7(x: number | string | boolean) { + if (typeof x === "string") { + return x === "hello"; // string + } + else if (typeof x === "boolean") { + return x; // boolean + } + else { + return x == 10; // number + } + } + function foo8(x: number | string | boolean) { + if (typeof x === "string") { + return x === "hello"; // string + } + else { + var b: number | boolean = x; // number | boolean + if (typeof x === "boolean") { + return x; // boolean + } + else { + return x == 10; // number + } + } + } + function foo9(x: number | string) { + var y = 10; + if (typeof x === "string") { + // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop + y = x.length; + return x === "hello"; // string + } + else { + return x == 10; // number + } + } + function foo10(x: number | string | boolean) { + // Mixing typeguard narrowing in if statement with conditional expression typeguard + if (typeof x === "string") { + return x === "hello"; // string + } + else { + var y: boolean | string; + var b = x; // number | boolean + return typeof x === "number" + ? x === 10 // number + : x; // x should be boolean + } + } + function foo11(x: number | string | boolean) { + // Mixing typeguard narrowing in if statement with conditional expression typeguard + // Assigning value to x deep inside another guard stops narrowing of type too + if (typeof x === "string") { + return x; // string | number | boolean - x changed in else branch + } + else { + var y: number| boolean | string; + var b = x; // number | boolean | string - because below we are changing value of x in if statement + return typeof x === "number" + ? ( + // change value of x + x = 10 && x.toString() // number | boolean | string + ) + : ( + // do not change value + y = x && x.toString() // number | boolean | string + ); + } + } + function foo12(x: number | string | boolean) { + // Mixing typeguard narrowing in if statement with conditional expression typeguard + // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression + if (typeof x === "string") { + return x.toString(); // string | number | boolean - x changed in else branch + } + else { + x = 10; + var b = x; // number | boolean | string + return typeof x === "number" + ? x.toString() // number + : x.toString(); // boolean | string + } + } \ No newline at end of file diff --git a/tests/baselines/reference/typeGuardsInIfStatement.js b/tests/baselines/reference/typeGuardsInIfStatement.js index de05a7bf82a..8e841d2eac3 100644 --- a/tests/baselines/reference/typeGuardsInIfStatement.js +++ b/tests/baselines/reference/typeGuardsInIfStatement.js @@ -1,10 +1,8 @@ //// [typeGuardsInIfStatement.ts] // In the true branch statement of an 'if' statement, -// the type of a variable or parameter is narrowed by any type guard in the 'if' condition when true, -// provided the true branch statement contains no assignments to the variable or parameter. +// the type of a variable or parameter is narrowed by any type guard in the 'if' condition when true. // In the false branch statement of an 'if' statement, -// the type of a variable or parameter is narrowed by any type guard in the 'if' condition when false, -// provided the false branch statement contains no assignments to the variable or parameter +// the type of a variable or parameter is narrowed by any type guard in the 'if' condition when false. function foo(x: number | string) { if (typeof x === "string") { return x.length; // string @@ -14,54 +12,49 @@ function foo(x: number | string) { } } function foo2(x: number | string) { - // x is assigned in the if true branch, the type is not narrowed if (typeof x === "string") { x = 10; - return x; // string | number + return x; // number } else { - return x; // string | number + return x; // number } } function foo3(x: number | string) { - // x is assigned in the if true branch, the type is not narrowed if (typeof x === "string") { - x = "Hello"; // even though assigned using same type as narrowed expression - return x; // string | number + x = "Hello"; + return x; // string } else { - return x; // string | number + return x; // number } } function foo4(x: number | string) { - // false branch updates the variable - so here it is not number if (typeof x === "string") { - return x; // string | number + return x; // string } else { - x = 10; // even though assigned number - this should result in x to be string | number - return x; // string | number + x = 10; + return x; // number } } function foo5(x: number | string) { - // false branch updates the variable - so here it is not number if (typeof x === "string") { - return x; // string | number + return x; // string } else { x = "hello"; - return x; // string | number + return x; // string } } function foo6(x: number | string) { - // Modify in both branches if (typeof x === "string") { x = 10; - return x; // string | number + return x; // number } else { x = "hello"; - return x; // string | number + return x; // string } } function foo7(x: number | string | boolean) { @@ -150,11 +143,9 @@ function foo12(x: number | string | boolean) { //// [typeGuardsInIfStatement.js] // In the true branch statement of an 'if' statement, -// the type of a variable or parameter is narrowed by any type guard in the 'if' condition when true, -// provided the true branch statement contains no assignments to the variable or parameter. +// the type of a variable or parameter is narrowed by any type guard in the 'if' condition when true. // In the false branch statement of an 'if' statement, -// the type of a variable or parameter is narrowed by any type guard in the 'if' condition when false, -// provided the false branch statement contains no assignments to the variable or parameter +// the type of a variable or parameter is narrowed by any type guard in the 'if' condition when false. function foo(x) { if (typeof x === "string") { return x.length; // string @@ -164,54 +155,49 @@ function foo(x) { } } function foo2(x) { - // x is assigned in the if true branch, the type is not narrowed if (typeof x === "string") { x = 10; - return x; // string | number + return x; // number } else { - return x; // string | number + return x; // number } } function foo3(x) { - // x is assigned in the if true branch, the type is not narrowed if (typeof x === "string") { - x = "Hello"; // even though assigned using same type as narrowed expression - return x; // string | number + x = "Hello"; + return x; // string } else { - return x; // string | number + return x; // number } } function foo4(x) { - // false branch updates the variable - so here it is not number if (typeof x === "string") { - return x; // string | number + return x; // string } else { - x = 10; // even though assigned number - this should result in x to be string | number - return x; // string | number + x = 10; + return x; // number } } function foo5(x) { - // false branch updates the variable - so here it is not number if (typeof x === "string") { - return x; // string | number + return x; // string } else { x = "hello"; - return x; // string | number + return x; // string } } function foo6(x) { - // Modify in both branches if (typeof x === "string") { x = 10; - return x; // string | number + return x; // number } else { x = "hello"; - return x; // string | number + return x; // string } } function foo7(x) { diff --git a/tests/baselines/reference/typeGuardsInIfStatement.symbols b/tests/baselines/reference/typeGuardsInIfStatement.symbols deleted file mode 100644 index 54a65f0693b..00000000000 --- a/tests/baselines/reference/typeGuardsInIfStatement.symbols +++ /dev/null @@ -1,304 +0,0 @@ -=== tests/cases/conformance/expressions/typeGuards/typeGuardsInIfStatement.ts === -// In the true branch statement of an 'if' statement, -// the type of a variable or parameter is narrowed by any type guard in the 'if' condition when true, -// provided the true branch statement contains no assignments to the variable or parameter. -// In the false branch statement of an 'if' statement, -// the type of a variable or parameter is narrowed by any type guard in the 'if' condition when false, -// provided the false branch statement contains no assignments to the variable or parameter -function foo(x: number | string) { ->foo : Symbol(foo, Decl(typeGuardsInIfStatement.ts, 0, 0)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 6, 13)) - - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 6, 13)) - - return x.length; // string ->x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 6, 13)) ->length : Symbol(String.length, Decl(lib.d.ts, --, --)) - } - else { - return x++; // number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 6, 13)) - } -} -function foo2(x: number | string) { ->foo2 : Symbol(foo2, Decl(typeGuardsInIfStatement.ts, 13, 1)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 14, 14)) - - // x is assigned in the if true branch, the type is not narrowed - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 14, 14)) - - x = 10; ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 14, 14)) - - return x; // string | number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 14, 14)) - } - else { - return x; // string | number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 14, 14)) - } -} -function foo3(x: number | string) { ->foo3 : Symbol(foo3, Decl(typeGuardsInIfStatement.ts, 23, 1)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 24, 14)) - - // x is assigned in the if true branch, the type is not narrowed - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 24, 14)) - - x = "Hello"; // even though assigned using same type as narrowed expression ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 24, 14)) - - return x; // string | number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 24, 14)) - } - else { - return x; // string | number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 24, 14)) - } -} -function foo4(x: number | string) { ->foo4 : Symbol(foo4, Decl(typeGuardsInIfStatement.ts, 33, 1)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 34, 14)) - - // false branch updates the variable - so here it is not number - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 34, 14)) - - return x; // string | number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 34, 14)) - } - else { - x = 10; // even though assigned number - this should result in x to be string | number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 34, 14)) - - return x; // string | number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 34, 14)) - } -} -function foo5(x: number | string) { ->foo5 : Symbol(foo5, Decl(typeGuardsInIfStatement.ts, 43, 1)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 44, 14)) - - // false branch updates the variable - so here it is not number - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 44, 14)) - - return x; // string | number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 44, 14)) - } - else { - x = "hello"; ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 44, 14)) - - return x; // string | number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 44, 14)) - } -} -function foo6(x: number | string) { ->foo6 : Symbol(foo6, Decl(typeGuardsInIfStatement.ts, 53, 1)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 54, 14)) - - // Modify in both branches - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 54, 14)) - - x = 10; ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 54, 14)) - - return x; // string | number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 54, 14)) - } - else { - x = "hello"; ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 54, 14)) - - return x; // string | number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 54, 14)) - } -} -function foo7(x: number | string | boolean) { ->foo7 : Symbol(foo7, Decl(typeGuardsInIfStatement.ts, 64, 1)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 65, 14)) - - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 65, 14)) - - return x === "hello"; // string ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 65, 14)) - } - else if (typeof x === "boolean") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 65, 14)) - - return x; // boolean ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 65, 14)) - } - else { - return x == 10; // number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 65, 14)) - } -} -function foo8(x: number | string | boolean) { ->foo8 : Symbol(foo8, Decl(typeGuardsInIfStatement.ts, 75, 1)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 76, 14)) - - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 76, 14)) - - return x === "hello"; // string ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 76, 14)) - } - else { - var b: number | boolean = x; // number | boolean ->b : Symbol(b, Decl(typeGuardsInIfStatement.ts, 81, 11)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 76, 14)) - - if (typeof x === "boolean") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 76, 14)) - - return x; // boolean ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 76, 14)) - } - else { - return x == 10; // number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 76, 14)) - } - } -} -function foo9(x: number | string) { ->foo9 : Symbol(foo9, Decl(typeGuardsInIfStatement.ts, 89, 1)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 90, 14)) - - var y = 10; ->y : Symbol(y, Decl(typeGuardsInIfStatement.ts, 91, 7)) - - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 90, 14)) - - // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop - y = x.length; ->y : Symbol(y, Decl(typeGuardsInIfStatement.ts, 91, 7)) ->x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 90, 14)) ->length : Symbol(String.length, Decl(lib.d.ts, --, --)) - - return x === "hello"; // string ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 90, 14)) - } - else { - return x == 10; // number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 90, 14)) - } -} -function foo10(x: number | string | boolean) { ->foo10 : Symbol(foo10, Decl(typeGuardsInIfStatement.ts, 100, 1)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 101, 15)) - - // Mixing typeguard narrowing in if statement with conditional expression typeguard - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 101, 15)) - - return x === "hello"; // string ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 101, 15)) - } - else { - var y: boolean | string; ->y : Symbol(y, Decl(typeGuardsInIfStatement.ts, 107, 11)) - - var b = x; // number | boolean ->b : Symbol(b, Decl(typeGuardsInIfStatement.ts, 108, 11)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 101, 15)) - - return typeof x === "number" ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 101, 15)) - - ? x === 10 // number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 101, 15)) - - : x; // x should be boolean ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 101, 15)) - } -} -function foo11(x: number | string | boolean) { ->foo11 : Symbol(foo11, Decl(typeGuardsInIfStatement.ts, 113, 1)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 114, 15)) - - // Mixing typeguard narrowing in if statement with conditional expression typeguard - // Assigning value to x deep inside another guard stops narrowing of type too - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 114, 15)) - - return x; // string | number | boolean - x changed in else branch ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 114, 15)) - } - else { - var y: number| boolean | string; ->y : Symbol(y, Decl(typeGuardsInIfStatement.ts, 121, 11)) - - var b = x; // number | boolean | string - because below we are changing value of x in if statement ->b : Symbol(b, Decl(typeGuardsInIfStatement.ts, 122, 11)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 114, 15)) - - return typeof x === "number" ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 114, 15)) - - ? ( - // change value of x - x = 10 && x.toString() // number | boolean | string ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 114, 15)) ->x.toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 114, 15)) ->toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) - - ) - : ( - // do not change value - y = x && x.toString() // number | boolean | string ->y : Symbol(y, Decl(typeGuardsInIfStatement.ts, 121, 11)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 114, 15)) ->x.toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 114, 15)) ->toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) - - ); - } -} -function foo12(x: number | string | boolean) { ->foo12 : Symbol(foo12, Decl(typeGuardsInIfStatement.ts, 133, 1)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 134, 15)) - - // Mixing typeguard narrowing in if statement with conditional expression typeguard - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 134, 15)) - - return x.toString(); // string | number | boolean - x changed in else branch ->x.toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 134, 15)) ->toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) - } - else { - x = 10; ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 134, 15)) - - var b = x; // number | boolean | string ->b : Symbol(b, Decl(typeGuardsInIfStatement.ts, 142, 11)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 134, 15)) - - return typeof x === "number" ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 134, 15)) - - ? x.toString() // number ->x.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 134, 15)) ->toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) - - : x.toString(); // boolean | string ->x.toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 134, 15)) ->toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) - } -} diff --git a/tests/baselines/reference/typeGuardsInIfStatement.types b/tests/baselines/reference/typeGuardsInIfStatement.types deleted file mode 100644 index 0095a7cc768..00000000000 --- a/tests/baselines/reference/typeGuardsInIfStatement.types +++ /dev/null @@ -1,405 +0,0 @@ -=== tests/cases/conformance/expressions/typeGuards/typeGuardsInIfStatement.ts === -// In the true branch statement of an 'if' statement, -// the type of a variable or parameter is narrowed by any type guard in the 'if' condition when true, -// provided the true branch statement contains no assignments to the variable or parameter. -// In the false branch statement of an 'if' statement, -// the type of a variable or parameter is narrowed by any type guard in the 'if' condition when false, -// provided the false branch statement contains no assignments to the variable or parameter -function foo(x: number | string) { ->foo : (x: number | string) => number ->x : number | string - - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : number | string ->"string" : string - - return x.length; // string ->x.length : number ->x : string ->length : number - } - else { - return x++; // number ->x++ : number ->x : number - } -} -function foo2(x: number | string) { ->foo2 : (x: number | string) => number | string ->x : number | string - - // x is assigned in the if true branch, the type is not narrowed - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : number | string ->"string" : string - - x = 10; ->x = 10 : number ->x : number | string ->10 : number - - return x; // string | number ->x : number | string - } - else { - return x; // string | number ->x : number | string - } -} -function foo3(x: number | string) { ->foo3 : (x: number | string) => number | string ->x : number | string - - // x is assigned in the if true branch, the type is not narrowed - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : number | string ->"string" : string - - x = "Hello"; // even though assigned using same type as narrowed expression ->x = "Hello" : string ->x : number | string ->"Hello" : string - - return x; // string | number ->x : number | string - } - else { - return x; // string | number ->x : number | string - } -} -function foo4(x: number | string) { ->foo4 : (x: number | string) => number | string ->x : number | string - - // false branch updates the variable - so here it is not number - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : number | string ->"string" : string - - return x; // string | number ->x : number | string - } - else { - x = 10; // even though assigned number - this should result in x to be string | number ->x = 10 : number ->x : number | string ->10 : number - - return x; // string | number ->x : number | string - } -} -function foo5(x: number | string) { ->foo5 : (x: number | string) => number | string ->x : number | string - - // false branch updates the variable - so here it is not number - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : number | string ->"string" : string - - return x; // string | number ->x : number | string - } - else { - x = "hello"; ->x = "hello" : string ->x : number | string ->"hello" : string - - return x; // string | number ->x : number | string - } -} -function foo6(x: number | string) { ->foo6 : (x: number | string) => number | string ->x : number | string - - // Modify in both branches - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : number | string ->"string" : string - - x = 10; ->x = 10 : number ->x : number | string ->10 : number - - return x; // string | number ->x : number | string - } - else { - x = "hello"; ->x = "hello" : string ->x : number | string ->"hello" : string - - return x; // string | number ->x : number | string - } -} -function foo7(x: number | string | boolean) { ->foo7 : (x: number | string | boolean) => boolean ->x : number | string | boolean - - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : number | string | boolean ->"string" : string - - return x === "hello"; // string ->x === "hello" : boolean ->x : string ->"hello" : string - } - else if (typeof x === "boolean") { ->typeof x === "boolean" : boolean ->typeof x : string ->x : number | boolean ->"boolean" : string - - return x; // boolean ->x : boolean - } - else { - return x == 10; // number ->x == 10 : boolean ->x : number ->10 : number - } -} -function foo8(x: number | string | boolean) { ->foo8 : (x: number | string | boolean) => boolean ->x : number | string | boolean - - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : number | string | boolean ->"string" : string - - return x === "hello"; // string ->x === "hello" : boolean ->x : string ->"hello" : string - } - else { - var b: number | boolean = x; // number | boolean ->b : number | boolean ->x : number | boolean - - if (typeof x === "boolean") { ->typeof x === "boolean" : boolean ->typeof x : string ->x : number | boolean ->"boolean" : string - - return x; // boolean ->x : boolean - } - else { - return x == 10; // number ->x == 10 : boolean ->x : number ->10 : number - } - } -} -function foo9(x: number | string) { ->foo9 : (x: number | string) => boolean ->x : number | string - - var y = 10; ->y : number ->10 : number - - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : number | string ->"string" : string - - // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop - y = x.length; ->y = x.length : number ->y : number ->x.length : number ->x : string ->length : number - - return x === "hello"; // string ->x === "hello" : boolean ->x : string ->"hello" : string - } - else { - return x == 10; // number ->x == 10 : boolean ->x : number ->10 : number - } -} -function foo10(x: number | string | boolean) { ->foo10 : (x: number | string | boolean) => boolean ->x : number | string | boolean - - // Mixing typeguard narrowing in if statement with conditional expression typeguard - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : number | string | boolean ->"string" : string - - return x === "hello"; // string ->x === "hello" : boolean ->x : string ->"hello" : string - } - else { - var y: boolean | string; ->y : boolean | string - - var b = x; // number | boolean ->b : number | boolean ->x : number | boolean - - return typeof x === "number" ->typeof x === "number" ? x === 10 // number : x : boolean ->typeof x === "number" : boolean ->typeof x : string ->x : number | boolean ->"number" : string - - ? x === 10 // number ->x === 10 : boolean ->x : number ->10 : number - - : x; // x should be boolean ->x : boolean - } -} -function foo11(x: number | string | boolean) { ->foo11 : (x: number | string | boolean) => number | string | boolean ->x : number | string | boolean - - // Mixing typeguard narrowing in if statement with conditional expression typeguard - // Assigning value to x deep inside another guard stops narrowing of type too - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : number | string | boolean ->"string" : string - - return x; // string | number | boolean - x changed in else branch ->x : number | string | boolean - } - else { - var y: number| boolean | string; ->y : number | boolean | string - - var b = x; // number | boolean | string - because below we are changing value of x in if statement ->b : number | string | boolean ->x : number | string | boolean - - return typeof x === "number" ->typeof x === "number" ? ( // change value of x x = 10 && x.toString() // number | boolean | string ) : ( // do not change value y = x && x.toString() // number | boolean | string ) : string ->typeof x === "number" : boolean ->typeof x : string ->x : number | string | boolean ->"number" : string - - ? ( ->( // change value of x x = 10 && x.toString() // number | boolean | string ) : string - - // change value of x - x = 10 && x.toString() // number | boolean | string ->x = 10 && x.toString() : string ->x : number | string | boolean ->10 && x.toString() : string ->10 : number ->x.toString() : string ->x.toString : (radix?: number) => string ->x : number | string | boolean ->toString : (radix?: number) => string - - ) - : ( ->( // do not change value y = x && x.toString() // number | boolean | string ) : string - - // do not change value - y = x && x.toString() // number | boolean | string ->y = x && x.toString() : string ->y : number | boolean | string ->x && x.toString() : string ->x : number | string | boolean ->x.toString() : string ->x.toString : (radix?: number) => string ->x : number | string | boolean ->toString : (radix?: number) => string - - ); - } -} -function foo12(x: number | string | boolean) { ->foo12 : (x: number | string | boolean) => string ->x : number | string | boolean - - // Mixing typeguard narrowing in if statement with conditional expression typeguard - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : number | string | boolean ->"string" : string - - return x.toString(); // string | number | boolean - x changed in else branch ->x.toString() : string ->x.toString : (radix?: number) => string ->x : number | string | boolean ->toString : (radix?: number) => string - } - else { - x = 10; ->x = 10 : number ->x : number | string | boolean ->10 : number - - var b = x; // number | boolean | string ->b : number | string | boolean ->x : number | string | boolean - - return typeof x === "number" ->typeof x === "number" ? x.toString() // number : x.toString() : string ->typeof x === "number" : boolean ->typeof x : string ->x : number | string | boolean ->"number" : string - - ? x.toString() // number ->x.toString() : string ->x.toString : (radix?: number) => string ->x : number ->toString : (radix?: number) => string - - : x.toString(); // boolean | string ->x.toString() : string ->x.toString : () => string ->x : string | boolean ->toString : () => string - } -} diff --git a/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.js b/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.js index e3f1a8c72c2..be1c497e3ea 100644 --- a/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.js +++ b/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.js @@ -1,7 +1,6 @@ //// [typeGuardsInRightOperandOfAndAndOperator.ts] // In the right operand of a && operation, -// the type of a variable or parameter is narrowed by any type guard in the left operand when true, -// provided the right operand contains no assignments to the variable or parameter. +// the type of a variable or parameter is narrowed by any type guard in the left operand when true. function foo(x: number | string) { return typeof x === "string" && x.length === 10; // string } @@ -36,29 +35,19 @@ function foo7(x: number | string | boolean) { var y: number| boolean | string; var z: number| boolean | string; // Mixing typeguard narrowing - // Assigning value to x deep inside another guard stops narrowing of type too return typeof x !== "string" - && ((z = x) // string | number | boolean - x changed deeper in conditional expression + && ((z = x) // number | boolean && (typeof x === "number" // change value of x - ? (x = 10 && x.toString()) // number | boolean | string + ? ((x = 10) && x.toString()) // x is number // do not change value - : (y = x && x.toString()))); // number | boolean | string + : ((y = x) && x.toString()))); // x is boolean } -function foo8(x: number | string) { - // Mixing typeguard - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - return typeof x !== "string" - && (x = 10) // change x - number| string - && (typeof x === "number" - ? x // number - : x.length); // string -} + //// [typeGuardsInRightOperandOfAndAndOperator.js] // In the right operand of a && operation, -// the type of a variable or parameter is narrowed by any type guard in the left operand when true, -// provided the right operand contains no assignments to the variable or parameter. +// the type of a variable or parameter is narrowed by any type guard in the left operand when true. function foo(x) { return typeof x === "string" && x.length === 10; // string } @@ -93,19 +82,9 @@ function foo7(x) { var y; var z; // Mixing typeguard narrowing - // Assigning value to x deep inside another guard stops narrowing of type too return typeof x !== "string" - && ((z = x) // string | number | boolean - x changed deeper in conditional expression + && ((z = x) // number | boolean && (typeof x === "number" - ? (x = 10 && x.toString()) // number | boolean | string - : (y = x && x.toString()))); // number | boolean | string -} -function foo8(x) { - // Mixing typeguard - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - return typeof x !== "string" - && (x = 10) // change x - number| string - && (typeof x === "number" - ? x // number - : x.length); // string + ? ((x = 10) && x.toString()) // x is number + : ((y = x) && x.toString()))); // x is boolean } diff --git a/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.symbols b/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.symbols index 21e3dd3701f..4028edb6b42 100644 --- a/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.symbols +++ b/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.symbols @@ -1,143 +1,119 @@ === tests/cases/conformance/expressions/typeGuards/typeGuardsInRightOperandOfAndAndOperator.ts === // In the right operand of a && operation, -// the type of a variable or parameter is narrowed by any type guard in the left operand when true, -// provided the right operand contains no assignments to the variable or parameter. +// the type of a variable or parameter is narrowed by any type guard in the left operand when true. function foo(x: number | string) { >foo : Symbol(foo, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 0, 0)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 3, 13)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 2, 13)) return typeof x === "string" && x.length === 10; // string ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 3, 13)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 2, 13)) >x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 3, 13)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 2, 13)) >length : Symbol(String.length, Decl(lib.d.ts, --, --)) } function foo2(x: number | string) { ->foo2 : Symbol(foo2, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 5, 1)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 6, 14)) +>foo2 : Symbol(foo2, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 4, 1)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 5, 14)) // modify x in right hand operand return typeof x === "string" && ((x = 10) && x); // string | number ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 6, 14)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 6, 14)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 6, 14)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 5, 14)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 5, 14)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 5, 14)) } function foo3(x: number | string) { ->foo3 : Symbol(foo3, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 9, 1)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 10, 14)) +>foo3 : Symbol(foo3, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 8, 1)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 9, 14)) // modify x in right hand operand with string type itself return typeof x === "string" && ((x = "hello") && x); // string | number ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 10, 14)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 10, 14)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 10, 14)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 9, 14)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 9, 14)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 9, 14)) } function foo4(x: number | string | boolean) { ->foo4 : Symbol(foo4, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 13, 1)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 14, 14)) +>foo4 : Symbol(foo4, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 12, 1)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 13, 14)) return typeof x !== "string" // string | number | boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 14, 14)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 13, 14)) && typeof x !== "number" // number | boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 14, 14)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 13, 14)) && x; // boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 14, 14)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 13, 14)) } function foo5(x: number | string | boolean) { ->foo5 : Symbol(foo5, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 18, 1)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 19, 14)) +>foo5 : Symbol(foo5, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 17, 1)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 18, 14)) // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop var b: number | boolean; ->b : Symbol(b, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 21, 7)) +>b : Symbol(b, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 20, 7)) return typeof x !== "string" // string | number | boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 19, 14)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 18, 14)) && ((b = x) && (typeof x !== "number" // number | boolean ->b : Symbol(b, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 21, 7)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 19, 14)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 19, 14)) +>b : Symbol(b, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 20, 7)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 18, 14)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 18, 14)) && x)); // boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 19, 14)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 18, 14)) } function foo6(x: number | string | boolean) { ->foo6 : Symbol(foo6, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 25, 1)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 26, 14)) +>foo6 : Symbol(foo6, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 24, 1)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 25, 14)) // Mixing typeguard narrowing in if statement with conditional expression typeguard return typeof x !== "string" // string | number | boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 26, 14)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 25, 14)) && (typeof x !== "number" // number | boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 26, 14)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 25, 14)) ? x // boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 26, 14)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 25, 14)) : x === 10) // number ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 26, 14)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 25, 14)) } function foo7(x: number | string | boolean) { ->foo7 : Symbol(foo7, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 32, 1)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 33, 14)) +>foo7 : Symbol(foo7, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 31, 1)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 32, 14)) var y: number| boolean | string; ->y : Symbol(y, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 34, 7)) +>y : Symbol(y, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 33, 7)) var z: number| boolean | string; ->z : Symbol(z, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 35, 7)) +>z : Symbol(z, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 34, 7)) // Mixing typeguard narrowing - // Assigning value to x deep inside another guard stops narrowing of type too return typeof x !== "string" ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 33, 14)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 32, 14)) - && ((z = x) // string | number | boolean - x changed deeper in conditional expression ->z : Symbol(z, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 35, 7)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 33, 14)) + && ((z = x) // number | boolean +>z : Symbol(z, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 34, 7)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 32, 14)) && (typeof x === "number" ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 33, 14)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 32, 14)) // change value of x - ? (x = 10 && x.toString()) // number | boolean | string ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 33, 14)) ->x.toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 33, 14)) ->toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + ? ((x = 10) && x.toString()) // x is number +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 32, 14)) +>x.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 32, 14)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) // do not change value - : (y = x && x.toString()))); // number | boolean | string ->y : Symbol(y, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 34, 7)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 33, 14)) ->x.toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 33, 14)) ->toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + : ((y = x) && x.toString()))); // x is boolean +>y : Symbol(y, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 33, 7)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 32, 14)) +>x.toString : Symbol(Object.toString, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 32, 14)) +>toString : Symbol(Object.toString, Decl(lib.d.ts, --, --)) } -function foo8(x: number | string) { ->foo8 : Symbol(foo8, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 45, 1)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 46, 14)) - // Mixing typeguard - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - return typeof x !== "string" ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 46, 14)) - - && (x = 10) // change x - number| string ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 46, 14)) - - && (typeof x === "number" ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 46, 14)) - - ? x // number ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 46, 14)) - - : x.length); // string ->x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 46, 14)) ->length : Symbol(String.length, Decl(lib.d.ts, --, --)) -} diff --git a/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.types b/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.types index 22d390618c1..2da52b8b1b8 100644 --- a/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.types +++ b/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.types @@ -1,7 +1,6 @@ === tests/cases/conformance/expressions/typeGuards/typeGuardsInRightOperandOfAndAndOperator.ts === // In the right operand of a && operation, -// the type of a variable or parameter is narrowed by any type guard in the left operand when true, -// provided the right operand contains no assignments to the variable or parameter. +// the type of a variable or parameter is narrowed by any type guard in the left operand when true. function foo(x: number | string) { >foo : (x: number | string) => boolean >x : number | string @@ -19,42 +18,42 @@ function foo(x: number | string) { >10 : number } function foo2(x: number | string) { ->foo2 : (x: number | string) => number | string +>foo2 : (x: number | string) => number >x : number | string // modify x in right hand operand return typeof x === "string" && ((x = 10) && x); // string | number ->typeof x === "string" && ((x = 10) && x) : number | string +>typeof x === "string" && ((x = 10) && x) : number >typeof x === "string" : boolean >typeof x : string >x : number | string >"string" : string ->((x = 10) && x) : number | string ->(x = 10) && x : number | string +>((x = 10) && x) : number +>(x = 10) && x : number >(x = 10) : number >x = 10 : number >x : number | string >10 : number ->x : number | string +>x : number } function foo3(x: number | string) { ->foo3 : (x: number | string) => number | string +>foo3 : (x: number | string) => string >x : number | string // modify x in right hand operand with string type itself return typeof x === "string" && ((x = "hello") && x); // string | number ->typeof x === "string" && ((x = "hello") && x) : number | string +>typeof x === "string" && ((x = "hello") && x) : string >typeof x === "string" : boolean >typeof x : string >x : number | string >"string" : string ->((x = "hello") && x) : number | string ->(x = "hello") && x : number | string +>((x = "hello") && x) : string +>(x = "hello") && x : string >(x = "hello") : string >x = "hello" : string >x : number | string >"hello" : string ->x : number | string +>x : string } function foo4(x: number | string | boolean) { >foo4 : (x: number | string | boolean) => boolean @@ -148,87 +147,53 @@ function foo7(x: number | string | boolean) { >z : number | boolean | string // Mixing typeguard narrowing - // Assigning value to x deep inside another guard stops narrowing of type too return typeof x !== "string" ->typeof x !== "string" && ((z = x) // string | number | boolean - x changed deeper in conditional expression && (typeof x === "number" // change value of x ? (x = 10 && x.toString()) // number | boolean | string // do not change value : (y = x && x.toString()))) : string +>typeof x !== "string" && ((z = x) // number | boolean && (typeof x === "number" // change value of x ? ((x = 10) && x.toString()) // x is number // do not change value : ((y = x) && x.toString()))) : string >typeof x !== "string" : boolean >typeof x : string >x : number | string | boolean >"string" : string - && ((z = x) // string | number | boolean - x changed deeper in conditional expression ->((z = x) // string | number | boolean - x changed deeper in conditional expression && (typeof x === "number" // change value of x ? (x = 10 && x.toString()) // number | boolean | string // do not change value : (y = x && x.toString()))) : string ->(z = x) // string | number | boolean - x changed deeper in conditional expression && (typeof x === "number" // change value of x ? (x = 10 && x.toString()) // number | boolean | string // do not change value : (y = x && x.toString())) : string ->(z = x) : number | string | boolean ->z = x : number | string | boolean + && ((z = x) // number | boolean +>((z = x) // number | boolean && (typeof x === "number" // change value of x ? ((x = 10) && x.toString()) // x is number // do not change value : ((y = x) && x.toString()))) : string +>(z = x) // number | boolean && (typeof x === "number" // change value of x ? ((x = 10) && x.toString()) // x is number // do not change value : ((y = x) && x.toString())) : string +>(z = x) : number | boolean +>z = x : number | boolean >z : number | boolean | string ->x : number | string | boolean +>x : number | boolean && (typeof x === "number" ->(typeof x === "number" // change value of x ? (x = 10 && x.toString()) // number | boolean | string // do not change value : (y = x && x.toString())) : string ->typeof x === "number" // change value of x ? (x = 10 && x.toString()) // number | boolean | string // do not change value : (y = x && x.toString()) : string +>(typeof x === "number" // change value of x ? ((x = 10) && x.toString()) // x is number // do not change value : ((y = x) && x.toString())) : string +>typeof x === "number" // change value of x ? ((x = 10) && x.toString()) // x is number // do not change value : ((y = x) && x.toString()) : string >typeof x === "number" : boolean >typeof x : string ->x : number | string | boolean +>x : number | boolean >"number" : string // change value of x - ? (x = 10 && x.toString()) // number | boolean | string ->(x = 10 && x.toString()) : string ->x = 10 && x.toString() : string + ? ((x = 10) && x.toString()) // x is number +>((x = 10) && x.toString()) : string +>(x = 10) && x.toString() : string +>(x = 10) : number +>x = 10 : number >x : number | string | boolean ->10 && x.toString() : string >10 : number >x.toString() : string >x.toString : (radix?: number) => string ->x : number | string | boolean +>x : number >toString : (radix?: number) => string // do not change value - : (y = x && x.toString()))); // number | boolean | string ->(y = x && x.toString()) : string ->y = x && x.toString() : string + : ((y = x) && x.toString()))); // x is boolean +>((y = x) && x.toString()) : string +>(y = x) && x.toString() : string +>(y = x) : boolean +>y = x : boolean >y : number | boolean | string ->x && x.toString() : string ->x : number | string | boolean +>x : boolean >x.toString() : string ->x.toString : (radix?: number) => string ->x : number | string | boolean ->toString : (radix?: number) => string +>x.toString : () => string +>x : boolean +>toString : () => string } -function foo8(x: number | string) { ->foo8 : (x: number | string) => number ->x : number | string - // Mixing typeguard - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - return typeof x !== "string" ->typeof x !== "string" && (x = 10) // change x - number| string && (typeof x === "number" ? x // number : x.length) : number ->typeof x !== "string" && (x = 10) : number ->typeof x !== "string" : boolean ->typeof x : string ->x : number | string ->"string" : string - - && (x = 10) // change x - number| string ->(x = 10) : number ->x = 10 : number ->x : number | string ->10 : number - - && (typeof x === "number" ->(typeof x === "number" ? x // number : x.length) : number ->typeof x === "number" ? x // number : x.length : number ->typeof x === "number" : boolean ->typeof x : string ->x : number | string ->"number" : string - - ? x // number ->x : number - - : x.length); // string ->x.length : number ->x : string ->length : number -} diff --git a/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.js b/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.js index 188d226da13..a8d66dc5fa2 100644 --- a/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.js +++ b/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.js @@ -36,24 +36,15 @@ function foo7(x: number | string | boolean) { var y: number| boolean | string; var z: number| boolean | string; // Mixing typeguard narrowing - // Assigning value to x deep inside another guard stops narrowing of type too return typeof x === "string" - || ((z = x) // string | number | boolean - x changed deeper in conditional expression + || ((z = x) // number | boolean || (typeof x === "number" // change value of x - ? (x = 10 && x.toString()) // number | boolean | string + ? ((x = 10) && x.toString()) // number | boolean | string // do not change value - : (y = x && x.toString()))); // number | boolean | string + : ((y = x) && x.toString()))); // number | boolean | string } -function foo8(x: number | string) { - // Mixing typeguard - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - return typeof x === "string" - || (x = 10) // change x - number| string - || (typeof x === "number" - ? x // number - : x.length); // string -} + //// [typeGuardsInRightOperandOfOrOrOperator.js] // In the right operand of a || operation, @@ -93,19 +84,9 @@ function foo7(x) { var y; var z; // Mixing typeguard narrowing - // Assigning value to x deep inside another guard stops narrowing of type too return typeof x === "string" - || ((z = x) // string | number | boolean - x changed deeper in conditional expression + || ((z = x) // number | boolean || (typeof x === "number" - ? (x = 10 && x.toString()) // number | boolean | string - : (y = x && x.toString()))); // number | boolean | string -} -function foo8(x) { - // Mixing typeguard - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - return typeof x === "string" - || (x = 10) // change x - number| string - || (typeof x === "number" - ? x // number - : x.length); // string + ? ((x = 10) && x.toString()) // number | boolean | string + : ((y = x) && x.toString()))); // number | boolean | string } diff --git a/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.symbols b/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.symbols index de9b4396d3d..b276671819a 100644 --- a/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.symbols +++ b/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.symbols @@ -92,11 +92,10 @@ function foo7(x: number | string | boolean) { >z : Symbol(z, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 35, 7)) // Mixing typeguard narrowing - // Assigning value to x deep inside another guard stops narrowing of type too return typeof x === "string" >x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 33, 14)) - || ((z = x) // string | number | boolean - x changed deeper in conditional expression + || ((z = x) // number | boolean >z : Symbol(z, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 35, 7)) >x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 33, 14)) @@ -104,40 +103,18 @@ function foo7(x: number | string | boolean) { >x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 33, 14)) // change value of x - ? (x = 10 && x.toString()) // number | boolean | string + ? ((x = 10) && x.toString()) // number | boolean | string >x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 33, 14)) ->x.toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>x.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) >x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 33, 14)) ->toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) // do not change value - : (y = x && x.toString()))); // number | boolean | string + : ((y = x) && x.toString()))); // number | boolean | string >y : Symbol(y, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 34, 7)) >x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 33, 14)) ->x.toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>x.toString : Symbol(Object.toString, Decl(lib.d.ts, --, --)) >x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 33, 14)) ->toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>toString : Symbol(Object.toString, Decl(lib.d.ts, --, --)) } -function foo8(x: number | string) { ->foo8 : Symbol(foo8, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 45, 1)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 46, 14)) - // Mixing typeguard - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 46, 14)) - - || (x = 10) // change x - number| string ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 46, 14)) - - || (typeof x === "number" ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 46, 14)) - - ? x // number ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 46, 14)) - - : x.length); // string ->x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 46, 14)) ->length : Symbol(String.length, Decl(lib.d.ts, --, --)) -} diff --git a/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.types b/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.types index 38d9a723d3a..659182ab888 100644 --- a/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.types +++ b/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.types @@ -19,42 +19,42 @@ function foo(x: number | string) { >10 : number } function foo2(x: number | string) { ->foo2 : (x: number | string) => boolean | number | string +>foo2 : (x: number | string) => boolean | number >x : number | string // modify x in right hand operand return typeof x !== "string" || ((x = 10) || x); // string | number ->typeof x !== "string" || ((x = 10) || x) : boolean | number | string +>typeof x !== "string" || ((x = 10) || x) : boolean | number >typeof x !== "string" : boolean >typeof x : string >x : number | string >"string" : string ->((x = 10) || x) : number | string ->(x = 10) || x : number | string +>((x = 10) || x) : number +>(x = 10) || x : number >(x = 10) : number >x = 10 : number >x : number | string >10 : number ->x : number | string +>x : number } function foo3(x: number | string) { ->foo3 : (x: number | string) => boolean | string | number +>foo3 : (x: number | string) => boolean | string >x : number | string // modify x in right hand operand with string type itself return typeof x !== "string" || ((x = "hello") || x); // string | number ->typeof x !== "string" || ((x = "hello") || x) : boolean | string | number +>typeof x !== "string" || ((x = "hello") || x) : boolean | string >typeof x !== "string" : boolean >typeof x : string >x : number | string >"string" : string ->((x = "hello") || x) : string | number ->(x = "hello") || x : string | number +>((x = "hello") || x) : string +>(x = "hello") || x : string >(x = "hello") : string >x = "hello" : string >x : number | string >"hello" : string ->x : number | string +>x : string } function foo4(x: number | string | boolean) { >foo4 : (x: number | string | boolean) => boolean @@ -148,87 +148,53 @@ function foo7(x: number | string | boolean) { >z : number | boolean | string // Mixing typeguard narrowing - // Assigning value to x deep inside another guard stops narrowing of type too return typeof x === "string" ->typeof x === "string" || ((z = x) // string | number | boolean - x changed deeper in conditional expression || (typeof x === "number" // change value of x ? (x = 10 && x.toString()) // number | boolean | string // do not change value : (y = x && x.toString()))) : boolean | number | string +>typeof x === "string" || ((z = x) // number | boolean || (typeof x === "number" // change value of x ? ((x = 10) && x.toString()) // number | boolean | string // do not change value : ((y = x) && x.toString()))) : boolean | number | string >typeof x === "string" : boolean >typeof x : string >x : number | string | boolean >"string" : string - || ((z = x) // string | number | boolean - x changed deeper in conditional expression ->((z = x) // string | number | boolean - x changed deeper in conditional expression || (typeof x === "number" // change value of x ? (x = 10 && x.toString()) // number | boolean | string // do not change value : (y = x && x.toString()))) : number | string | boolean ->(z = x) // string | number | boolean - x changed deeper in conditional expression || (typeof x === "number" // change value of x ? (x = 10 && x.toString()) // number | boolean | string // do not change value : (y = x && x.toString())) : number | string | boolean ->(z = x) : number | string | boolean ->z = x : number | string | boolean + || ((z = x) // number | boolean +>((z = x) // number | boolean || (typeof x === "number" // change value of x ? ((x = 10) && x.toString()) // number | boolean | string // do not change value : ((y = x) && x.toString()))) : number | boolean | string +>(z = x) // number | boolean || (typeof x === "number" // change value of x ? ((x = 10) && x.toString()) // number | boolean | string // do not change value : ((y = x) && x.toString())) : number | boolean | string +>(z = x) : number | boolean +>z = x : number | boolean >z : number | boolean | string ->x : number | string | boolean +>x : number | boolean || (typeof x === "number" ->(typeof x === "number" // change value of x ? (x = 10 && x.toString()) // number | boolean | string // do not change value : (y = x && x.toString())) : string ->typeof x === "number" // change value of x ? (x = 10 && x.toString()) // number | boolean | string // do not change value : (y = x && x.toString()) : string +>(typeof x === "number" // change value of x ? ((x = 10) && x.toString()) // number | boolean | string // do not change value : ((y = x) && x.toString())) : string +>typeof x === "number" // change value of x ? ((x = 10) && x.toString()) // number | boolean | string // do not change value : ((y = x) && x.toString()) : string >typeof x === "number" : boolean >typeof x : string ->x : number | string | boolean +>x : number | boolean >"number" : string // change value of x - ? (x = 10 && x.toString()) // number | boolean | string ->(x = 10 && x.toString()) : string ->x = 10 && x.toString() : string + ? ((x = 10) && x.toString()) // number | boolean | string +>((x = 10) && x.toString()) : string +>(x = 10) && x.toString() : string +>(x = 10) : number +>x = 10 : number >x : number | string | boolean ->10 && x.toString() : string >10 : number >x.toString() : string >x.toString : (radix?: number) => string ->x : number | string | boolean +>x : number >toString : (radix?: number) => string // do not change value - : (y = x && x.toString()))); // number | boolean | string ->(y = x && x.toString()) : string ->y = x && x.toString() : string + : ((y = x) && x.toString()))); // number | boolean | string +>((y = x) && x.toString()) : string +>(y = x) && x.toString() : string +>(y = x) : boolean +>y = x : boolean >y : number | boolean | string ->x && x.toString() : string ->x : number | string | boolean +>x : boolean >x.toString() : string ->x.toString : (radix?: number) => string ->x : number | string | boolean ->toString : (radix?: number) => string +>x.toString : () => string +>x : boolean +>toString : () => string } -function foo8(x: number | string) { ->foo8 : (x: number | string) => boolean | number ->x : number | string - // Mixing typeguard - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - return typeof x === "string" ->typeof x === "string" || (x = 10) // change x - number| string || (typeof x === "number" ? x // number : x.length) : boolean | number ->typeof x === "string" || (x = 10) : boolean | number ->typeof x === "string" : boolean ->typeof x : string ->x : number | string ->"string" : string - - || (x = 10) // change x - number| string ->(x = 10) : number ->x = 10 : number ->x : number | string ->10 : number - - || (typeof x === "number" ->(typeof x === "number" ? x // number : x.length) : number ->typeof x === "number" ? x // number : x.length : number ->typeof x === "number" : boolean ->typeof x : string ->x : number | string ->"number" : string - - ? x // number ->x : number - - : x.length); // string ->x.length : number ->x : string ->length : number -} diff --git a/tests/baselines/reference/typeGuardsInWhileStatement.js b/tests/baselines/reference/typeGuardsInWhileStatement.js new file mode 100644 index 00000000000..ac2ceaaf590 --- /dev/null +++ b/tests/baselines/reference/typeGuardsInWhileStatement.js @@ -0,0 +1,54 @@ +//// [typeGuardsInWhileStatement.ts] +let cond: boolean; +function a(x: string | number) { + while (typeof x === "string") { + x; // string + x = undefined; + } + x; // number +} +function b(x: string | number) { + while (typeof x === "string") { + if (cond) continue; + x; // string + x = undefined; + } + x; // number +} +function c(x: string | number) { + while (typeof x === "string") { + if (cond) break; + x; // string + x = undefined; + } + x; // string | number +} + + +//// [typeGuardsInWhileStatement.js] +var cond; +function a(x) { + while (typeof x === "string") { + x; // string + x = undefined; + } + x; // number +} +function b(x) { + while (typeof x === "string") { + if (cond) + continue; + x; // string + x = undefined; + } + x; // number +} +function c(x) { + while (typeof x === "string") { + if (cond) + break; + x; // string + x = undefined; + } + x; // string | number +} diff --git a/tests/baselines/reference/typeGuardsInWhileStatement.symbols b/tests/baselines/reference/typeGuardsInWhileStatement.symbols new file mode 100644 index 00000000000..b981943e216 --- /dev/null +++ b/tests/baselines/reference/typeGuardsInWhileStatement.symbols @@ -0,0 +1,62 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardsInWhileStatement.ts === +let cond: boolean; +>cond : Symbol(cond, Decl(typeGuardsInWhileStatement.ts, 0, 3)) + +function a(x: string | number) { +>a : Symbol(a, Decl(typeGuardsInWhileStatement.ts, 0, 18)) +>x : Symbol(x, Decl(typeGuardsInWhileStatement.ts, 1, 11)) + + while (typeof x === "string") { +>x : Symbol(x, Decl(typeGuardsInWhileStatement.ts, 1, 11)) + + x; // string +>x : Symbol(x, Decl(typeGuardsInWhileStatement.ts, 1, 11)) + + x = undefined; +>x : Symbol(x, Decl(typeGuardsInWhileStatement.ts, 1, 11)) +>undefined : Symbol(undefined) + } + x; // number +>x : Symbol(x, Decl(typeGuardsInWhileStatement.ts, 1, 11)) +} +function b(x: string | number) { +>b : Symbol(b, Decl(typeGuardsInWhileStatement.ts, 7, 1)) +>x : Symbol(x, Decl(typeGuardsInWhileStatement.ts, 8, 11)) + + while (typeof x === "string") { +>x : Symbol(x, Decl(typeGuardsInWhileStatement.ts, 8, 11)) + + if (cond) continue; +>cond : Symbol(cond, Decl(typeGuardsInWhileStatement.ts, 0, 3)) + + x; // string +>x : Symbol(x, Decl(typeGuardsInWhileStatement.ts, 8, 11)) + + x = undefined; +>x : Symbol(x, Decl(typeGuardsInWhileStatement.ts, 8, 11)) +>undefined : Symbol(undefined) + } + x; // number +>x : Symbol(x, Decl(typeGuardsInWhileStatement.ts, 8, 11)) +} +function c(x: string | number) { +>c : Symbol(c, Decl(typeGuardsInWhileStatement.ts, 15, 1)) +>x : Symbol(x, Decl(typeGuardsInWhileStatement.ts, 16, 11)) + + while (typeof x === "string") { +>x : Symbol(x, Decl(typeGuardsInWhileStatement.ts, 16, 11)) + + if (cond) break; +>cond : Symbol(cond, Decl(typeGuardsInWhileStatement.ts, 0, 3)) + + x; // string +>x : Symbol(x, Decl(typeGuardsInWhileStatement.ts, 16, 11)) + + x = undefined; +>x : Symbol(x, Decl(typeGuardsInWhileStatement.ts, 16, 11)) +>undefined : Symbol(undefined) + } + x; // string | number +>x : Symbol(x, Decl(typeGuardsInWhileStatement.ts, 16, 11)) +} + diff --git a/tests/baselines/reference/typeGuardsInWhileStatement.types b/tests/baselines/reference/typeGuardsInWhileStatement.types new file mode 100644 index 00000000000..cde045cc621 --- /dev/null +++ b/tests/baselines/reference/typeGuardsInWhileStatement.types @@ -0,0 +1,74 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardsInWhileStatement.ts === +let cond: boolean; +>cond : boolean + +function a(x: string | number) { +>a : (x: string | number) => void +>x : string | number + + while (typeof x === "string") { +>typeof x === "string" : boolean +>typeof x : string +>x : string | number +>"string" : string + + x; // string +>x : string + + x = undefined; +>x = undefined : undefined +>x : string | number +>undefined : undefined + } + x; // number +>x : number +} +function b(x: string | number) { +>b : (x: string | number) => void +>x : string | number + + while (typeof x === "string") { +>typeof x === "string" : boolean +>typeof x : string +>x : string | number +>"string" : string + + if (cond) continue; +>cond : boolean + + x; // string +>x : string + + x = undefined; +>x = undefined : undefined +>x : string | number +>undefined : undefined + } + x; // number +>x : number +} +function c(x: string | number) { +>c : (x: string | number) => void +>x : string | number + + while (typeof x === "string") { +>typeof x === "string" : boolean +>typeof x : string +>x : string | number +>"string" : string + + if (cond) break; +>cond : boolean + + x; // string +>x : string + + x = undefined; +>x = undefined : undefined +>x : string | number +>undefined : undefined + } + x; // string | number +>x : number | string +} + diff --git a/tests/baselines/reference/typeGuardsWithInstanceOf.errors.txt b/tests/baselines/reference/typeGuardsWithInstanceOf.errors.txt new file mode 100644 index 00000000000..28cc85695bc --- /dev/null +++ b/tests/baselines/reference/typeGuardsWithInstanceOf.errors.txt @@ -0,0 +1,14 @@ +tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOf.ts(7,20): error TS2339: Property 'global' does not exist on type '{}'. + + +==== tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOf.ts (1 errors) ==== + interface I { global: string; } + var result: I; + var result2: I; + + if (!(result instanceof RegExp)) { + result = result2; + } else if (!result.global) { + ~~~~~~ +!!! error TS2339: Property 'global' does not exist on type '{}'. + } \ No newline at end of file diff --git a/tests/baselines/reference/typeGuardsWithInstanceOf.symbols b/tests/baselines/reference/typeGuardsWithInstanceOf.symbols deleted file mode 100644 index cc2695e6aea..00000000000 --- a/tests/baselines/reference/typeGuardsWithInstanceOf.symbols +++ /dev/null @@ -1,26 +0,0 @@ -=== tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOf.ts === -interface I { global: string; } ->I : Symbol(I, Decl(typeGuardsWithInstanceOf.ts, 0, 0)) ->global : Symbol(I.global, Decl(typeGuardsWithInstanceOf.ts, 0, 13)) - -var result: I; ->result : Symbol(result, Decl(typeGuardsWithInstanceOf.ts, 1, 3)) ->I : Symbol(I, Decl(typeGuardsWithInstanceOf.ts, 0, 0)) - -var result2: I; ->result2 : Symbol(result2, Decl(typeGuardsWithInstanceOf.ts, 2, 3)) ->I : Symbol(I, Decl(typeGuardsWithInstanceOf.ts, 0, 0)) - -if (!(result instanceof RegExp)) { ->result : Symbol(result, Decl(typeGuardsWithInstanceOf.ts, 1, 3)) ->RegExp : Symbol(RegExp, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) - - result = result2; ->result : Symbol(result, Decl(typeGuardsWithInstanceOf.ts, 1, 3)) ->result2 : Symbol(result2, Decl(typeGuardsWithInstanceOf.ts, 2, 3)) - -} else if (!result.global) { ->result.global : Symbol(I.global, Decl(typeGuardsWithInstanceOf.ts, 0, 13)) ->result : Symbol(result, Decl(typeGuardsWithInstanceOf.ts, 1, 3)) ->global : Symbol(I.global, Decl(typeGuardsWithInstanceOf.ts, 0, 13)) -} diff --git a/tests/baselines/reference/typeGuardsWithInstanceOf.types b/tests/baselines/reference/typeGuardsWithInstanceOf.types deleted file mode 100644 index 0d7b477faed..00000000000 --- a/tests/baselines/reference/typeGuardsWithInstanceOf.types +++ /dev/null @@ -1,31 +0,0 @@ -=== tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOf.ts === -interface I { global: string; } ->I : I ->global : string - -var result: I; ->result : I ->I : I - -var result2: I; ->result2 : I ->I : I - -if (!(result instanceof RegExp)) { ->!(result instanceof RegExp) : boolean ->(result instanceof RegExp) : boolean ->result instanceof RegExp : boolean ->result : I ->RegExp : RegExpConstructor - - result = result2; ->result = result2 : I ->result : I ->result2 : I - -} else if (!result.global) { ->!result.global : boolean ->result.global : string ->result : I ->global : string -} diff --git a/tests/baselines/reference/typeofOperatorWithAnyOtherType.errors.txt b/tests/baselines/reference/typeofOperatorWithAnyOtherType.errors.txt index 0139c96b3f9..f9394c622c0 100644 --- a/tests/baselines/reference/typeofOperatorWithAnyOtherType.errors.txt +++ b/tests/baselines/reference/typeofOperatorWithAnyOtherType.errors.txt @@ -4,9 +4,13 @@ tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperator 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. tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(70,1): error TS7028: Unused label. +tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(71,1): error TS7028: Unused label. +tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(72,1): error TS7028: Unused label. +tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(73,1): error TS7028: Unused label. +tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(74,1): error TS7028: Unused label. -==== tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts (6 errors) ==== +==== tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts (10 errors) ==== // typeof operator on any type var ANY: any; @@ -90,6 +94,14 @@ tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperator ~ !!! error TS7028: Unused label. z: typeof objA.a; + ~ +!!! error TS7028: Unused label. z: typeof A.foo; + ~ +!!! error TS7028: Unused label. z: typeof M.n; - z: typeof obj1.x; \ No newline at end of file + ~ +!!! error TS7028: Unused label. + z: typeof obj1.x; + ~ +!!! error TS7028: Unused label. \ No newline at end of file diff --git a/tests/baselines/reference/typeofOperatorWithStringType.errors.txt b/tests/baselines/reference/typeofOperatorWithStringType.errors.txt index 37b2cafab37..bd891c949a3 100644 --- a/tests/baselines/reference/typeofOperatorWithStringType.errors.txt +++ b/tests/baselines/reference/typeofOperatorWithStringType.errors.txt @@ -1,9 +1,13 @@ tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithStringType.ts(50,1): error TS7028: Unused label. tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithStringType.ts(51,1): error TS7028: Unused label. tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithStringType.ts(52,1): error TS7028: Unused label. +tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithStringType.ts(54,1): error TS7028: Unused label. +tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithStringType.ts(55,1): error TS7028: Unused label. +tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithStringType.ts(56,1): error TS7028: Unused label. +tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithStringType.ts(57,1): error TS7028: Unused label. -==== tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithStringType.ts (3 errors) ==== +==== tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithStringType.ts (7 errors) ==== // typeof operator on string type var STRING: string; var STRING1: string[] = ["", "abc"]; @@ -64,6 +68,14 @@ tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperator !!! error TS7028: Unused label. var y = { a: "", b: "" }; z: typeof y.a; + ~ +!!! error TS7028: Unused label. z: typeof objA.a; + ~ +!!! error TS7028: Unused label. z: typeof A.foo; - z: typeof M.n; \ No newline at end of file + ~ +!!! error TS7028: Unused label. + z: typeof M.n; + ~ +!!! error TS7028: Unused label. \ No newline at end of file diff --git a/tests/baselines/reference/unionTypesAssignability.errors.txt b/tests/baselines/reference/unionTypesAssignability.errors.txt index cad61f41d1d..5be1ff3d246 100644 --- a/tests/baselines/reference/unionTypesAssignability.errors.txt +++ b/tests/baselines/reference/unionTypesAssignability.errors.txt @@ -24,9 +24,9 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTyp tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(43,1): error TS2322: Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(64,5): error TS2322: Type 'U' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(65,5): error TS2322: Type 'T' is not assignable to type 'U'. -tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(69,5): error TS2322: Type 'T | U' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(70,5): error TS2322: Type 'T | U' is not assignable to type 'T'. Type 'U' is not assignable to type 'T'. -tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(70,5): error TS2322: Type 'T | U' is not assignable to type 'U'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(71,5): error TS2322: Type 'T | U' is not assignable to type 'U'. Type 'T' is not assignable to type 'U'. @@ -142,6 +142,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTyp var x : T | U; x = t; // ok x = u; // ok + x = undefined; t = x; // error U not assignable to T ~ !!! error TS2322: Type 'T | U' is not assignable to type 'T'. diff --git a/tests/baselines/reference/unionTypesAssignability.js b/tests/baselines/reference/unionTypesAssignability.js index e07901347a5..c7105608004 100644 --- a/tests/baselines/reference/unionTypesAssignability.js +++ b/tests/baselines/reference/unionTypesAssignability.js @@ -67,6 +67,7 @@ function foo(t: T, u: U) { var x : T | U; x = t; // ok x = u; // ok + x = undefined; t = x; // error U not assignable to T u = x; // error T not assignable to U } @@ -157,6 +158,7 @@ function foo(t, u) { var x; x = t; // ok x = u; // ok + x = undefined; t = x; // error U not assignable to T u = x; // error T not assignable to U } diff --git a/tests/cases/compiler/arrayFilter.ts b/tests/cases/compiler/arrayFilter.ts new file mode 100644 index 00000000000..d13dc0dc9fa --- /dev/null +++ b/tests/cases/compiler/arrayFilter.ts @@ -0,0 +1,7 @@ +var foo = [ + { name: 'bar' }, + { name: null }, + { name: 'baz' } +] + +foo.filter(x => x.name); //should accepted all possible types not only boolean! \ No newline at end of file diff --git a/tests/cases/compiler/declarationEmitFirstTypeArgumentGenericFunctionType.ts b/tests/cases/compiler/declarationEmitFirstTypeArgumentGenericFunctionType.ts new file mode 100644 index 00000000000..3c5100d0772 --- /dev/null +++ b/tests/cases/compiler/declarationEmitFirstTypeArgumentGenericFunctionType.ts @@ -0,0 +1,26 @@ +// @declaration: true +// @module: commonjs +// @target: es6 + +class X { +} +var prop11: X< () => Tany >; // spaces before the first type argument +var prop12: X<(() => Tany)>; // spaces before the first type argument +function f1() { // Inferred return type + return prop11; +} +function f2() { // Inferred return type + return prop12; +} +function f3(): X< () => Tany> { // written with space before type argument + return prop11; +} +function f4(): X<(() => Tany)> { // written type with parenthesis + return prop12; +} +class Y { +} +var prop2: Y() => Tany>; // No space after second type argument +var prop2: Y() => Tany>; // space after second type argument +var prop3: Y< () => Tany, () => Tany>; // space before first type argument +var prop4: Y<(() => Tany), () => Tany>; // parenthesized first type argument diff --git a/tests/cases/compiler/declarationEmitPromise.ts b/tests/cases/compiler/declarationEmitPromise.ts new file mode 100644 index 00000000000..2eff0b6c50c --- /dev/null +++ b/tests/cases/compiler/declarationEmitPromise.ts @@ -0,0 +1,25 @@ +// @declaration: true +// @module: commonjs +// @target: es6 + +export class bluebird { + static all: Array>; +} + +export async function runSampleWorks( + a: bluebird, b?: bluebird, c?: bluebird, d?: bluebird, e?: bluebird) { + let result = await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el)); + let func = (f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T => + f.apply(this, result); + let rfunc: typeof func & {} = func as any; // <- This is the only difference + return rfunc +} + +export async function runSampleBreaks( + a: bluebird, b?: bluebird, c?: bluebird, d?: bluebird, e?: bluebird) { + let result = await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el)); + let func = (f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T => + f.apply(this, result); + let rfunc: typeof func = func as any; // <- This is the only difference + return rfunc +} \ No newline at end of file diff --git a/tests/cases/compiler/jsFileCompilationRestParamJsDocFunction.ts b/tests/cases/compiler/jsFileCompilationRestParamJsDocFunction.ts new file mode 100644 index 00000000000..03ad2d1b2ff --- /dev/null +++ b/tests/cases/compiler/jsFileCompilationRestParamJsDocFunction.ts @@ -0,0 +1,27 @@ +// @allowJs: true +// @out: apply.js +// @module: amd + +// @filename: _apply.js +/** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ +function apply(func, thisArg, args) { + var length = args.length; + switch (length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); +} + +export default apply; \ No newline at end of file diff --git a/tests/cases/compiler/moduleAugmentationInDependency.ts b/tests/cases/compiler/moduleAugmentationInDependency.ts new file mode 100644 index 00000000000..23d10edbd74 --- /dev/null +++ b/tests/cases/compiler/moduleAugmentationInDependency.ts @@ -0,0 +1,7 @@ +// @filename: /node_modules/A/index.d.ts +declare module "ext" { +} +export {}; + +// @filename: /src/app.ts +import "A" \ No newline at end of file diff --git a/tests/cases/compiler/moduleAugmentationInDependency2.ts b/tests/cases/compiler/moduleAugmentationInDependency2.ts new file mode 100644 index 00000000000..189e020fd2e --- /dev/null +++ b/tests/cases/compiler/moduleAugmentationInDependency2.ts @@ -0,0 +1,7 @@ +// @filename: /node_modules/A/index.ts +declare module "ext" { +} +export {}; + +// @filename: /src/app.ts +import "A" \ No newline at end of file diff --git a/tests/cases/compiler/newNamesInGlobalAugmentations1.ts b/tests/cases/compiler/newNamesInGlobalAugmentations1.ts new file mode 100644 index 00000000000..73ed4e5e2e8 --- /dev/null +++ b/tests/cases/compiler/newNamesInGlobalAugmentations1.ts @@ -0,0 +1,22 @@ +// @target: es6 + +// @filename: f1.d.ts +export {}; + +declare module M.M1 { + export let x: number; +} +declare global { + interface SymbolConstructor { + observable: symbol; + } + class Cls {x} + let [a, b]: number[]; + export import X = M.M1.x; +} + +// @filename: main.ts + +Symbol.observable; +new Cls().x +let c = a + b + X; \ No newline at end of file diff --git a/tests/cases/compiler/pathsValidation1.ts b/tests/cases/compiler/pathsValidation1.ts new file mode 100644 index 00000000000..45a4409cf03 --- /dev/null +++ b/tests/cases/compiler/pathsValidation1.ts @@ -0,0 +1,11 @@ +// @filename: tsconfig.json +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "*": "*" + } + } +} +// @filename: a.ts +let x = 1; \ No newline at end of file diff --git a/tests/cases/compiler/pathsValidation2.ts b/tests/cases/compiler/pathsValidation2.ts new file mode 100644 index 00000000000..b15ad4e236a --- /dev/null +++ b/tests/cases/compiler/pathsValidation2.ts @@ -0,0 +1,11 @@ +// @filename: tsconfig.json +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "*": [1] + } + } +} +// @filename: a.ts +let x = 1; \ No newline at end of file diff --git a/tests/cases/compiler/singleLineCommentInConciseArrowFunctionES3.ts b/tests/cases/compiler/singleLineCommentInConciseArrowFunctionES3.ts new file mode 100644 index 00000000000..0538df1c2d0 --- /dev/null +++ b/tests/cases/compiler/singleLineCommentInConciseArrowFunctionES3.ts @@ -0,0 +1,5 @@ +function test() { + return () => + // some comments here; + 123; +} \ No newline at end of file diff --git a/tests/cases/conformance/controlFlow/controlFlowAssignmentExpression.ts b/tests/cases/conformance/controlFlow/controlFlowAssignmentExpression.ts new file mode 100644 index 00000000000..83bf75ab94d --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowAssignmentExpression.ts @@ -0,0 +1,10 @@ +let x: string | boolean | number; +let obj: any; + +x = ""; +x = x.length; +x; // number + +x = true; +(x = "", obj).foo = (x = x.length); +x; // number diff --git a/tests/cases/conformance/controlFlow/controlFlowBinaryAndExpression.ts b/tests/cases/conformance/controlFlow/controlFlowBinaryAndExpression.ts new file mode 100644 index 00000000000..caaef9b890f --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowBinaryAndExpression.ts @@ -0,0 +1,9 @@ +let x: string | number | boolean; +let cond: boolean; + +(x = "") && (x = 0); +x; // string | number + +x = ""; +cond && (x = 0); +x; // string | number diff --git a/tests/cases/conformance/controlFlow/controlFlowBinaryOrExpression.ts b/tests/cases/conformance/controlFlow/controlFlowBinaryOrExpression.ts new file mode 100644 index 00000000000..9dab32e0cb8 --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowBinaryOrExpression.ts @@ -0,0 +1,35 @@ +let x: string | number | boolean; +let cond: boolean; + +(x = "") || (x = 0); +x; // string | number + +x = ""; +cond || (x = 0); +x; // string | number + +export interface NodeList { + length: number; +} + +export interface HTMLCollection { + length: number; +} + +declare function isNodeList(sourceObj: any): sourceObj is NodeList; +declare function isHTMLCollection(sourceObj: any): sourceObj is HTMLCollection; + +type EventTargetLike = {a: string} | HTMLCollection | NodeList; + +var sourceObj: EventTargetLike = undefined; +if (isNodeList(sourceObj)) { + sourceObj.length; +} + +if (isHTMLCollection(sourceObj)) { + sourceObj.length; +} + +if (isNodeList(sourceObj) || isHTMLCollection(sourceObj)) { + sourceObj.length; +} diff --git a/tests/cases/conformance/controlFlow/controlFlowCommaOperator.ts b/tests/cases/conformance/controlFlow/controlFlowCommaOperator.ts new file mode 100644 index 00000000000..d6d49e48f34 --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowCommaOperator.ts @@ -0,0 +1,22 @@ +function f(x: string | number | boolean) { + let y: string | number | boolean = false; + let z: string | number | boolean = false; + if (y = "", typeof x === "string") { + x; // string + y; // string + z; // boolean + } + else if (z = 1, typeof x === "number") { + x; // number + y; // string + z; // number + } + else { + x; // boolean + y; // string + z; // number + } + x; // string | number | boolean + y; // string + z; // number | boolean +} diff --git a/tests/cases/conformance/controlFlow/controlFlowConditionalExpression.ts b/tests/cases/conformance/controlFlow/controlFlowConditionalExpression.ts new file mode 100644 index 00000000000..c1c1d9956ea --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowConditionalExpression.ts @@ -0,0 +1,5 @@ +let x: string | number | boolean; +let cond: boolean; + +cond ? x = "" : x = 3; +x; // string | number diff --git a/tests/cases/conformance/controlFlow/controlFlowDestructuringDeclaration.ts b/tests/cases/conformance/controlFlow/controlFlowDestructuringDeclaration.ts new file mode 100644 index 00000000000..fc9c3ffb4d7 --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowDestructuringDeclaration.ts @@ -0,0 +1,59 @@ +// @strictNullChecks: true + +function f1() { + let x: string | number = 1; + x; + let y: string | undefined = ""; + y; +} + +function f2() { + let [x]: [string | number] = [1]; + x; + let [y]: [string | undefined] = [""]; + y; + let [z = ""]: [string | undefined] = [undefined]; + z; +} + +function f3() { + let [x]: (string | number)[] = [1]; + x; + let [y]: (string | undefined)[] = [""]; + y; + let [z = ""]: (string | undefined)[] = [undefined]; + z; +} + +function f4() { + let { x }: { x: string | number } = { x: 1 }; + x; + let { y }: { y: string | undefined } = { y: "" }; + y; + let { z = "" }: { z: string | undefined } = { z: undefined }; + z; +} + +function f5() { + let { x }: { x?: string | number } = { x: 1 }; + x; + let { y }: { y?: string | undefined } = { y: "" }; + y; + let { z = "" }: { z?: string | undefined } = { z: undefined }; + z; +} + +function f6() { + let { x }: { x?: string | number } = {}; + x; + let { y }: { y?: string | undefined } = {}; + y; + let { z = "" }: { z?: string | undefined } = {}; + z; +} + +function f7() { + let o: { [x: string]: number } = { x: 1 }; + let { x }: { [x: string]: string | number } = o; + x; +} diff --git a/tests/cases/conformance/controlFlow/controlFlowDoWhileStatement.ts b/tests/cases/conformance/controlFlow/controlFlowDoWhileStatement.ts new file mode 100644 index 00000000000..bd253bc064d --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowDoWhileStatement.ts @@ -0,0 +1,76 @@ +let cond: boolean; +function a() { + let x: string | number; + x = ""; + do { + x; // string + } while (cond) +} +function b() { + let x: string | number; + x = ""; + do { + x; // string + x = 42; + break; + } while (cond) +} +function c() { + let x: string | number; + x = ""; + do { + x; // string + x = undefined; + if (typeof x === "string") continue; + break; + } while (cond) +} +function d() { + let x: string | number; + x = 1000; + do { + x; // number + x = ""; + } while (x = x.length) + x; // number +} +function e() { + let x: string | number; + x = ""; + do { + x = 42; + } while (cond) + x; // number +} +function f() { + let x: string | number | boolean | RegExp | Function; + x = ""; + do { + if (cond) { + x = 42; + break; + } + if (cond) { + x = true; + continue; + } + x = /a/; + } while (cond) + x; // number | boolean | RegExp +} +function g() { + let x: string | number | boolean | RegExp | Function; + x = ""; + do { + if (cond) { + x = 42; + break; + } + if (cond) { + x = true; + continue; + } + x = /a/; + } while (true) + x; // number +} diff --git a/tests/cases/conformance/controlFlow/controlFlowForInStatement.ts b/tests/cases/conformance/controlFlow/controlFlowForInStatement.ts new file mode 100644 index 00000000000..a22e79506c2 --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowForInStatement.ts @@ -0,0 +1,17 @@ +let x: string | number | boolean | RegExp | Function; +let obj: any; +let cond: boolean; + +x = /a/; +for (let y in obj) { + x = y; + if (cond) { + x = 42; + continue; + } + if (cond) { + x = true; + break; + } +} +x; // RegExp | string | number | boolean diff --git a/tests/cases/conformance/controlFlow/controlFlowForOfStatement.ts b/tests/cases/conformance/controlFlow/controlFlowForOfStatement.ts new file mode 100644 index 00000000000..3abcf814f2a --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowForOfStatement.ts @@ -0,0 +1,10 @@ +let obj: number[]; +let x: string | number | boolean | RegExp; + +function a() { + x = true; + for (x of obj) { + x = x.toExponential(); + } + x; // string | boolean +} diff --git a/tests/cases/conformance/controlFlow/controlFlowForStatement.ts b/tests/cases/conformance/controlFlow/controlFlowForStatement.ts new file mode 100644 index 00000000000..d9e46781aa7 --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowForStatement.ts @@ -0,0 +1,41 @@ +let cond: boolean; +function a() { + let x: string | number | boolean; + for (x = ""; cond; x = 5) { + x; // string | number + } +} +function b() { + let x: string | number | boolean; + for (x = 5; cond; x = x.length) { + x; // number + x = ""; + } +} +function c() { + let x: string | number | boolean; + for (x = 5; x = x.toExponential(); x = 5) { + x; // string + } +} +function d() { + let x: string | number | boolean; + for (x = ""; typeof x === "string"; x = 5) { + x; // string + } +} +function e() { + let x: string | number | boolean | RegExp; + for (x = "" || 0; typeof x !== "string"; x = "" || true) { + x; // number | boolean + } +} +function f() { + let x: string | number | boolean; + for (; typeof x !== "string";) { + x; // number | boolean + if (typeof x === "number") break; + x = undefined; + } + x; // string | number +} diff --git a/tests/cases/conformance/controlFlow/controlFlowIfStatement.ts b/tests/cases/conformance/controlFlow/controlFlowIfStatement.ts new file mode 100644 index 00000000000..c9e9be92f8e --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowIfStatement.ts @@ -0,0 +1,36 @@ +let x: string | number | boolean | RegExp; +let cond: boolean; + +x = /a/; +if (x /* RegExp */, (x = true)) { + x; // boolean + x = ""; +} +else { + x; // boolean + x = 42; +} +x; // string | number + +function a() { + let x: string | number; + if (cond) { + x = 42; + } + else { + x = ""; + return; + } + x; // number +} +function b() { + let x: string | number; + if (cond) { + x = 42; + throw ""; + } + else { + x = ""; + } + x; // string +} diff --git a/tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts b/tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts new file mode 100644 index 00000000000..2e54b335537 --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts @@ -0,0 +1,93 @@ +// @noImplicitAny: true + +let cond: boolean; + +function len(s: string) { + return s.length; +} + +function f1() { + let x: string | number | boolean; + x = ""; + while (cond) { + x = len(x); + x; + } + x; +} + +function f2() { + let x: string | number | boolean; + x = ""; + while (cond) { + x; + x = len(x); + } + x; +} + +declare function foo(x: string): number; +declare function foo(x: number): string; + +function g1() { + let x: string | number | boolean; + x = ""; + while (cond) { + x = foo(x); + x; + } + x; +} + +function g2() { + let x: string | number | boolean; + x = ""; + while (cond) { + x; + x = foo(x); + } + x; +} + +function asNumber(x: string | number): number { + return +x; +} + +function h1() { + let x: string | number | boolean; + x = "0"; + while (cond) { + x = +x + 1; + x; + } +} + +function h2() { + let x: string | number | boolean; + x = "0"; + while (cond) { + x = asNumber(x) + 1; + x; + } +} + +function h3() { + let x: string | number | boolean; + x = "0"; + while (cond) { + let y = asNumber(x); + x = y + 1; + x; + } +} + +function h4() { + let x: string | number | boolean; + x = "0"; + while (cond) { + x; + let y = asNumber(x); + x = y + 1; + x; + } +} diff --git a/tests/cases/conformance/controlFlow/controlFlowTruthiness.ts b/tests/cases/conformance/controlFlow/controlFlowTruthiness.ts new file mode 100644 index 00000000000..ba1947da13b --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowTruthiness.ts @@ -0,0 +1,70 @@ +// @strictNullChecks: true + +declare function foo(): string | undefined; + +function f1() { + let x = foo(); + if (x) { + x; // string + } + else { + x; // string | undefined + } +} + +function f2() { + let x: string | undefined; + x = foo(); + if (x) { + x; // string + } + else { + x; // string | undefined + } +} + +function f3() { + let x: string | undefined; + if (x = foo()) { + x; // string + } + else { + x; // string | undefined + } +} + +function f4() { + let x: string | undefined; + if (!(x = foo())) { + x; // string | undefined + } + else { + x; // string + } +} + +function f5() { + let x: string | undefined; + let y: string | undefined; + if (x = y = foo()) { + x; // string + y; // string | undefined + } + else { + x; // string | undefined + y; // string | undefined + } +} + +function f6() { + let x: string | undefined; + let y: string | undefined; + if (x = foo(), y = foo()) { + x; // string | undefined + y; // string + } + else { + x; // string | undefined + y; // string | undefined + } +} diff --git a/tests/cases/conformance/controlFlow/controlFlowWhileStatement.ts b/tests/cases/conformance/controlFlow/controlFlowWhileStatement.ts new file mode 100644 index 00000000000..7bf49dd7224 --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowWhileStatement.ts @@ -0,0 +1,106 @@ +let cond: boolean; +function a() { + let x: string | number; + x = ""; + while (cond) { + x; // string + } +} +function b() { + let x: string | number; + x = ""; + while (cond) { + x; // string + x = 42; + break; + } +} +function c() { + let x: string | number; + x = ""; + while (cond) { + x; // string + x = undefined; + if (typeof x === "string") continue; + break; + } +} +function d() { + let x: string | number; + x = ""; + while (x = x.length) { + x; // number + x = ""; + } +} +function e() { + let x: string | number; + x = ""; + while (cond) { + x; // string | number + x = 42; + x; // number + } + x; // string | number +} +function f() { + let x: string | number | boolean | RegExp | Function; + x = ""; + while (cond) { + if (cond) { + x = 42; + break; + } + if (cond) { + x = true; + continue; + } + x = /a/; + } + x; // string | number | boolean | RegExp +} +function g() { + let x: string | number | boolean | RegExp | Function; + x = ""; + while (true) { + if (cond) { + x = 42; + break; + } + if (cond) { + x = true; + continue; + } + x = /a/; + } + x; // number +} +function h1() { + let x: string | number | boolean; + x = ""; + while (x > 1) { + x; // string | number + x = 1; + x; // number + } + x; // string | number +} +declare function len(s: string | number): number; +function h2() { + let x: string | number | boolean; + x = ""; + while (cond) { + x = len(x); + x; // number + } + x; // string | number +} +function h3() { + let x: string | number | boolean; + x = ""; + while (cond) { + x; // string | number + x = len(x); + } + x; // string | number +} diff --git a/tests/cases/conformance/expressions/assignmentOperator/assignmentTypeNarrowing.ts b/tests/cases/conformance/expressions/assignmentOperator/assignmentTypeNarrowing.ts new file mode 100644 index 00000000000..0e5e257635a --- /dev/null +++ b/tests/cases/conformance/expressions/assignmentOperator/assignmentTypeNarrowing.ts @@ -0,0 +1,28 @@ +let x: string | number | boolean | RegExp; + +x = ""; +x; // string + +[x] = [true]; +x; // boolean + +[x = ""] = [1]; +x; // string | number + +({x} = {x: true}); +x; // boolean + +({y: x} = {y: 1}); +x; // number + +({x = ""} = {x: true}); +x; // string | boolean + +({y: x = /a/} = {y: 1}); +x; // number | RegExp + +let a: string[]; + +for (x of a) { + x; // string +} diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardFunctionOfFormThis.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardFunctionOfFormThis.ts index aadbf3cd9c5..12f6687c401 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardFunctionOfFormThis.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardFunctionOfFormThis.ts @@ -34,19 +34,19 @@ else if (b.isFollower()) { b.follow(); } -if (((a.isLeader)())) { - a.lead(); -} -else if (((a).isFollower())) { - a.follow(); -} +// if (((a.isLeader)())) { +// a.lead(); +// } +// else if (((a).isFollower())) { +// a.follow(); +// } -if (((a["isLeader"])())) { - a.lead(); -} -else if (((a)["isFollower"]())) { - a.follow(); -} +// if (((a["isLeader"])())) { +// a.lead(); +// } +// else if (((a)["isFollower"]())) { +// a.follow(); +// } var holder2 = {a}; diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfBoolean.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfBoolean.ts index fb699ce8ce0..37651071b7f 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfBoolean.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfBoolean.ts @@ -41,12 +41,11 @@ else { c = boolOrC; // C } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrNum === "boolean") { - var z1: string | number = strOrNum; // string | number + let z1: {} = strOrNum; // {} } else { - var z2: string | number = strOrNum; // string | number + let z2: string | number = strOrNum; // string | number } @@ -78,10 +77,9 @@ else { bool = boolOrC; // boolean } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrNum !== "boolean") { - var z1: string | number = strOrNum; // string | number + let z1: string | number = strOrNum; // string | number } else { - var z2: string | number = strOrNum; // string | number + let z2: {} = strOrNum; // {} } diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfNumber.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfNumber.ts index 2868b114077..b4cdf81660e 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfNumber.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfNumber.ts @@ -41,12 +41,11 @@ else { c = numOrC; // C } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrBool === "number") { - var y1: string | boolean = strOrBool; // string | boolean + let y1: {} = strOrBool; // {} } else { - var y2: string | boolean = strOrBool; // string | boolean + let y2: string | boolean = strOrBool; // string | boolean } // A type guard of the form typeof x !== s, where s is a string literal, @@ -77,10 +76,9 @@ else { num = numOrC; // number } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrBool !== "number") { - var y1: string | boolean = strOrBool; // string | boolean + let y1: string | boolean = strOrBool; // string | boolean } else { - var y2: string | boolean = strOrBool; // string | boolean + let y2: {} = strOrBool; // {} } diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfOther.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfOther.ts index ac3403d8151..44b064c3219 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfOther.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfOther.ts @@ -37,12 +37,11 @@ else { var r4: boolean = boolOrC; // boolean } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrNumOrBool === "Object") { - var q1: string | number | boolean = strOrNumOrBool; // string | number | boolean + let q1: {} = strOrNumOrBool; // {} } else { - var q2: string | number | boolean = strOrNumOrBool; // string | number | boolean + let q2: string | number | boolean = strOrNumOrBool; // string | number | boolean } // A type guard of the form typeof x !== s, where s is a string literal, @@ -67,10 +66,9 @@ else { c = boolOrC; // C } -// Narrowing occurs only if target type is a subtype of variable type if (typeof strOrNumOrBool !== "Object") { - var q1: string | number | boolean = strOrNumOrBool; // string | number | boolean + let q1: string | number | boolean = strOrNumOrBool; // string | number | boolean } else { - var q2: string | number | boolean = strOrNumOrBool; // string | number | boolean + let q2: {} = strOrNumOrBool; // {} } diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfString.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfString.ts index a356858e6c8..f742124708f 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfString.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfString.ts @@ -41,12 +41,11 @@ else { c = strOrC; // C } -// Narrowing occurs only if target type is a subtype of variable type if (typeof numOrBool === "string") { - var x1: number | boolean = numOrBool; // number | boolean + let x1: {} = numOrBool; // {} } else { - var x2: number | boolean = numOrBool; // number | boolean + let x2: number | boolean = numOrBool; // number | boolean } // A type guard of the form typeof x !== s, where s is a string literal, @@ -77,10 +76,9 @@ else { str = strOrC; // string } -// Narrowing occurs only if target type is a subtype of variable type if (typeof numOrBool !== "string") { - var x1: number | boolean = numOrBool; // number | boolean + let x1: number | boolean = numOrBool; // number | boolean } else { - var x2: number | boolean = numOrBool; // number | boolean + let x2: {} = numOrBool; // {} } diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardsInConditionalExpression.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardsInConditionalExpression.ts index 1633c80ab67..01f9361ebc3 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardsInConditionalExpression.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardsInConditionalExpression.ts @@ -11,43 +11,37 @@ function foo(x: number | string) { : x++; // number } function foo2(x: number | string) { - // x is assigned in the if true branch, the type is not narrowed return typeof x === "string" - ? (x = 10 && x)// string | number - : x; // string | number + ? ((x = "hello") && x) // string + : x; // number } function foo3(x: number | string) { - // x is assigned in the if false branch, the type is not narrowed - // even though assigned using same type as narrowed expression return typeof x === "string" - ? (x = "Hello" && x) // string | number - : x; // string | number + ? ((x = 10) && x) // number + : x; // number } function foo4(x: number | string) { - // false branch updates the variable - so here it is not number - // even though assigned using same type as narrowed expression return typeof x === "string" - ? x // string | number - : (x = 10 && x); // string | number + ? x // string + : ((x = 10) && x); // number } function foo5(x: number | string) { - // false branch updates the variable - so here it is not number return typeof x === "string" - ? x // string | number - : (x = "hello" && x); // string | number + ? x // string + : ((x = "hello") && x); // string } function foo6(x: number | string) { // Modify in both branches return typeof x === "string" - ? (x = 10 && x) // string | number - : (x = "hello" && x); // string | number + ? ((x = 10) && x) // number + : ((x = "hello") && x); // string } function foo7(x: number | string | boolean) { return typeof x === "string" - ? x === "hello" // string + ? x === "hello" // boolean : typeof x === "boolean" ? x // boolean - : x == 10; // number + : x == 10; // boolean } function foo8(x: number | string | boolean) { var b: number | boolean; @@ -56,14 +50,14 @@ function foo8(x: number | string | boolean) { : ((b = x) && // number | boolean (typeof x === "boolean" ? x // boolean - : x == 10)); // number + : x == 10)); // boolean } function foo9(x: number | string) { var y = 10; // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop return typeof x === "string" - ? ((y = x.length) && x === "hello") // string - : x === 10; // number + ? ((y = x.length) && x === "hello") // boolean + : x === 10; // boolean } function foo10(x: number | string | boolean) { // Mixing typeguards @@ -76,22 +70,20 @@ function foo10(x: number | string | boolean) { } function foo11(x: number | string | boolean) { // Mixing typeguards - // Assigning value to x deep inside another guard stops narrowing of type too var b: number | boolean | string; return typeof x === "string" - ? x // number | boolean | string - changed in the false branch - : ((b = x) // x is number | boolean | string - because the assignment changed it + ? x // string + : ((b = x) // x is number | boolean && typeof x === "number" && (x = 10) // assignment to x - && x); // x is number | boolean | string + && x); // x is number } function foo12(x: number | string | boolean) { // Mixing typeguards - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression var b: number | boolean | string; return typeof x === "string" - ? (x = 10 && x.toString().length) // number | boolean | string - changed here - : ((b = x) // x is number | boolean | string - changed in true branch + ? ((x = 10) && x.toString().length) // number + : ((b = x) // x is number | boolean && typeof x === "number" && x); // x is number } \ No newline at end of file diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardsInDoStatement.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardsInDoStatement.ts new file mode 100644 index 00000000000..1afbe515df8 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardsInDoStatement.ts @@ -0,0 +1,27 @@ +let cond: boolean; +function a(x: string | number | boolean) { + x = true; + do { + x; // boolean | string + x = undefined; + } while (typeof x === "string") + x; // number | boolean +} +function b(x: string | number | boolean) { + x = true; + do { + x; // boolean | string + if (cond) continue; + x = undefined; + } while (typeof x === "string") + x; // number | boolean +} +function c(x: string | number) { + x = ""; + do { + x; // string + if (cond) break; + x = undefined; + } while (typeof x === "string") + x; // string | number +} diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardsInForStatement.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardsInForStatement.ts new file mode 100644 index 00000000000..cf5c008e800 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardsInForStatement.ts @@ -0,0 +1,21 @@ +let cond: boolean; +function a(x: string | number) { + for (x = undefined; typeof x !== "number"; x = undefined) { + x; // string + } + x; // number +} +function b(x: string | number) { + for (x = undefined; typeof x !== "number"; x = undefined) { + x; // string + if (cond) continue; + } + x; // number +} +function c(x: string | number) { + for (x = undefined; typeof x !== "number"; x = undefined) { + x; // string + if (cond) break; + } + x; // string | number +} diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardsInIfStatement.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardsInIfStatement.ts index f72845c18a4..1626cfdb82e 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardsInIfStatement.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardsInIfStatement.ts @@ -1,9 +1,7 @@ // In the true branch statement of an 'if' statement, -// the type of a variable or parameter is narrowed by any type guard in the 'if' condition when true, -// provided the true branch statement contains no assignments to the variable or parameter. +// the type of a variable or parameter is narrowed by any type guard in the 'if' condition when true. // In the false branch statement of an 'if' statement, -// the type of a variable or parameter is narrowed by any type guard in the 'if' condition when false, -// provided the false branch statement contains no assignments to the variable or parameter +// the type of a variable or parameter is narrowed by any type guard in the 'if' condition when false. function foo(x: number | string) { if (typeof x === "string") { return x.length; // string @@ -13,54 +11,49 @@ function foo(x: number | string) { } } function foo2(x: number | string) { - // x is assigned in the if true branch, the type is not narrowed if (typeof x === "string") { x = 10; - return x; // string | number + return x; // number } else { - return x; // string | number + return x; // number } } function foo3(x: number | string) { - // x is assigned in the if true branch, the type is not narrowed if (typeof x === "string") { - x = "Hello"; // even though assigned using same type as narrowed expression - return x; // string | number + x = "Hello"; + return x; // string } else { - return x; // string | number + return x; // number } } function foo4(x: number | string) { - // false branch updates the variable - so here it is not number if (typeof x === "string") { - return x; // string | number + return x; // string } else { - x = 10; // even though assigned number - this should result in x to be string | number - return x; // string | number + x = 10; + return x; // number } } function foo5(x: number | string) { - // false branch updates the variable - so here it is not number if (typeof x === "string") { - return x; // string | number + return x; // string } else { x = "hello"; - return x; // string | number + return x; // string } } function foo6(x: number | string) { - // Modify in both branches if (typeof x === "string") { x = 10; - return x; // string | number + return x; // number } else { x = "hello"; - return x; // string | number + return x; // string } } function foo7(x: number | string | boolean) { diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardsInRightOperandOfAndAndOperator.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardsInRightOperandOfAndAndOperator.ts index da0d8ce24b5..acd71f37d91 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardsInRightOperandOfAndAndOperator.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardsInRightOperandOfAndAndOperator.ts @@ -1,6 +1,5 @@ // In the right operand of a && operation, -// the type of a variable or parameter is narrowed by any type guard in the left operand when true, -// provided the right operand contains no assignments to the variable or parameter. +// the type of a variable or parameter is narrowed by any type guard in the left operand when true. function foo(x: number | string) { return typeof x === "string" && x.length === 10; // string } @@ -35,21 +34,11 @@ function foo7(x: number | string | boolean) { var y: number| boolean | string; var z: number| boolean | string; // Mixing typeguard narrowing - // Assigning value to x deep inside another guard stops narrowing of type too return typeof x !== "string" - && ((z = x) // string | number | boolean - x changed deeper in conditional expression + && ((z = x) // number | boolean && (typeof x === "number" // change value of x - ? (x = 10 && x.toString()) // number | boolean | string + ? ((x = 10) && x.toString()) // x is number // do not change value - : (y = x && x.toString()))); // number | boolean | string + : ((y = x) && x.toString()))); // x is boolean } -function foo8(x: number | string) { - // Mixing typeguard - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - return typeof x !== "string" - && (x = 10) // change x - number| string - && (typeof x === "number" - ? x // number - : x.length); // string -} \ No newline at end of file diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardsInRightOperandOfOrOrOperator.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardsInRightOperandOfOrOrOperator.ts index 867dc143a85..131e5dd10bc 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardsInRightOperandOfOrOrOperator.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardsInRightOperandOfOrOrOperator.ts @@ -35,21 +35,11 @@ function foo7(x: number | string | boolean) { var y: number| boolean | string; var z: number| boolean | string; // Mixing typeguard narrowing - // Assigning value to x deep inside another guard stops narrowing of type too return typeof x === "string" - || ((z = x) // string | number | boolean - x changed deeper in conditional expression + || ((z = x) // number | boolean || (typeof x === "number" // change value of x - ? (x = 10 && x.toString()) // number | boolean | string + ? ((x = 10) && x.toString()) // number | boolean | string // do not change value - : (y = x && x.toString()))); // number | boolean | string + : ((y = x) && x.toString()))); // number | boolean | string } -function foo8(x: number | string) { - // Mixing typeguard - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - return typeof x === "string" - || (x = 10) // change x - number| string - || (typeof x === "number" - ? x // number - : x.length); // string -} \ No newline at end of file diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardsInWhileStatement.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardsInWhileStatement.ts new file mode 100644 index 00000000000..642c8995795 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardsInWhileStatement.ts @@ -0,0 +1,24 @@ +let cond: boolean; +function a(x: string | number) { + while (typeof x === "string") { + x; // string + x = undefined; + } + x; // number +} +function b(x: string | number) { + while (typeof x === "string") { + if (cond) continue; + x; // string + x = undefined; + } + x; // number +} +function c(x: string | number) { + while (typeof x === "string") { + if (cond) break; + x; // string + x = undefined; + } + x; // string | number +} diff --git a/tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes01.ts b/tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes01.ts index b8ed1b47dd4..05f8c511118 100644 --- a/tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes01.ts +++ b/tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes01.ts @@ -2,8 +2,8 @@ type T = "foo" | "bar" | "baz"; -var x: "foo" | "bar" | "baz" = "foo"; -var y: T = "bar"; +var x: "foo" | "bar" | "baz" = undefined; +var y: T = undefined; if (x === "foo") { let a = x; diff --git a/tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes02.ts b/tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes02.ts index 2cc63ab4460..ee61efc37ca 100644 --- a/tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes02.ts +++ b/tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes02.ts @@ -2,8 +2,8 @@ type T = string | "foo" | "bar" | "baz"; -var x: "foo" | "bar" | "baz" | string = "foo"; -var y: T = "bar"; +var x: "foo" | "bar" | "baz" | string = undefined; +var y: T = undefined; if (x === "foo") { let a = x; diff --git a/tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes03.ts b/tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes03.ts index d5c6a38af79..96a4f035c4b 100644 --- a/tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes03.ts +++ b/tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes03.ts @@ -3,7 +3,7 @@ type T = number | "foo" | "bar"; var x: "foo" | "bar" | number; -var y: T = "bar"; +var y: T = undefined; if (x === "foo") { let a = x; diff --git a/tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes04.ts b/tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes04.ts index e9d062b0e5c..9f37e272b46 100644 --- a/tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes04.ts +++ b/tests/cases/conformance/types/stringLiteral/stringLiteralTypesInUnionTypes04.ts @@ -2,8 +2,8 @@ type T = "" | "foo"; -let x: T = ""; -let y: T = "foo"; +let x: T = undefined; +let y: T = undefined; if (x === "") { let a = x; diff --git a/tests/cases/conformance/types/stringLiteral/stringLiteralTypesTypePredicates01.ts b/tests/cases/conformance/types/stringLiteral/stringLiteralTypesTypePredicates01.ts index a78918c8122..2199ff3a7c7 100644 --- a/tests/cases/conformance/types/stringLiteral/stringLiteralTypesTypePredicates01.ts +++ b/tests/cases/conformance/types/stringLiteral/stringLiteralTypesTypePredicates01.ts @@ -8,7 +8,7 @@ function kindIs(kind: Kind, is: Kind): boolean { return kind === is; } -var x: Kind = "A"; +var x: Kind = undefined; if (kindIs(x, "A")) { let a = x; diff --git a/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts b/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts index 9ceee8845a5..90f16b6d15d 100644 --- a/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts +++ b/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts @@ -59,13 +59,14 @@ unionNumberString = null; unionDE = undefined; unionNumberString = undefined; -// type parameters -function foo(t: T, u: U) { - t = u; // error - u = t; // error - var x : T | U; - x = t; // ok - x = u; // ok - t = x; // error U not assignable to T - u = x; // error T not assignable to U +// type parameters +function foo(t: T, u: U) { + t = u; // error + u = t; // error + var x : T | U; + x = t; // ok + x = u; // ok + x = undefined; + t = x; // error U not assignable to T + u = x; // error T not assignable to U } diff --git a/tests/cases/fourslash/commentBraceCompletionPosition.ts b/tests/cases/fourslash/commentBraceCompletionPosition.ts new file mode 100644 index 00000000000..23b8240dcaf --- /dev/null +++ b/tests/cases/fourslash/commentBraceCompletionPosition.ts @@ -0,0 +1,23 @@ +/// + +//// /** +//// * inside jsdoc /*1*/ +//// */ +//// function f() { +//// // inside regular comment /*2*/ +//// var c = ""; +//// +//// /* inside multi- +//// line comment /*3*/ +//// */ +//// var y =12; +//// } + +goTo.marker('1'); +verify.not.isValidBraceCompletionAtPostion('('); + +goTo.marker('2'); +verify.not.isValidBraceCompletionAtPostion('('); + +goTo.marker('3'); +verify.not.isValidBraceCompletionAtPostion('('); \ No newline at end of file diff --git a/tests/cases/fourslash/completionEntryOnNarrowedType.ts b/tests/cases/fourslash/completionEntryOnNarrowedType.ts index 714d3390e76..f81572ccebf 100644 --- a/tests/cases/fourslash/completionEntryOnNarrowedType.ts +++ b/tests/cases/fourslash/completionEntryOnNarrowedType.ts @@ -3,10 +3,10 @@ ////function foo(strOrNum: string | number) { //// /*1*/ //// if (typeof strOrNum === "number") { -//// /*2*/ +//// strOrNum/*2*/; //// } //// else { -//// /*3*/ +//// strOrNum/*3*/; //// } ////} diff --git a/tests/cases/fourslash/findAllRefsInClassExpression.ts b/tests/cases/fourslash/findAllRefsInClassExpression.ts new file mode 100644 index 00000000000..951acdd336c --- /dev/null +++ b/tests/cases/fourslash/findAllRefsInClassExpression.ts @@ -0,0 +1,16 @@ +/// + +////interface I { [|boom|](): void; } +////new class C implements I { +//// [|boom|](){} +////} + +let ranges = test.ranges() +for (let range of ranges) { + goTo.position(range.start); + + verify.referencesCountIs(ranges.length); + for (let expectedReference of ranges) { + verify.referencesAtPositionContains(expectedReference); + } +} \ No newline at end of file diff --git a/tests/cases/fourslash/findReferencesAcrossMultipleProjects.ts b/tests/cases/fourslash/findReferencesAcrossMultipleProjects.ts new file mode 100644 index 00000000000..0ef7745f8f9 --- /dev/null +++ b/tests/cases/fourslash/findReferencesAcrossMultipleProjects.ts @@ -0,0 +1,17 @@ +/// + +//@Filename: a.ts +////var /*1*/x: number; + +//@Filename: b.ts +/////// +////x++; + +//@Filename: c.ts +/////// +////x++; + +goTo.file("a.ts"); +goTo.marker("1"); + +verify.referencesCountIs(3); \ No newline at end of file diff --git a/tests/cases/fourslash/formattingWithMultilineComments.ts b/tests/cases/fourslash/formattingWithMultilineComments.ts new file mode 100644 index 00000000000..04cdfbcf472 --- /dev/null +++ b/tests/cases/fourslash/formattingWithMultilineComments.ts @@ -0,0 +1,9 @@ +/// + +////f(/* +/////*2*/ */() => { /*1*/ }); + +goTo.marker("1"); +edit.insertLine(""); +goTo.marker("2"); +verify.currentLineContentIs(" */() => {"); \ No newline at end of file diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index b69a757f01e..48d69f0a85e 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -110,8 +110,8 @@ declare namespace FourSlashInterface { type(definitionIndex?: number): void; position(position: number, fileIndex?: number): any; position(position: number, fileName?: string): any; - file(index: number, content?: string): any; - file(name: string, content?: string): any; + file(index: number, content?: string, scriptKindName?: string): any; + file(name: string, content?: string, scriptKindName?: string): any; } class verifyNegatable { private negative; @@ -136,6 +136,7 @@ declare namespace FourSlashInterface { typeDefinitionCountIs(expectedCount: number): void; definitionLocationExists(): void; verifyDefinitionsName(name: string, containerName: string): void; + isValidBraceCompletionAtPostion(openingBrace?: string): void; } class verify extends verifyNegatable { assertHasRanges(ranges: FourSlash.Range[]): void; @@ -173,6 +174,7 @@ declare namespace FourSlashInterface { noMatchingBracePositionInCurrentFile(bracePosition: number): void; DocCommentTemplate(expectedText: string, expectedOffset: number, empty?: boolean): void; noDocCommentTemplate(): void; + getScriptLexicalStructureListCount(count: number): void; getScriptLexicalStructureListContains(name: string, kind: string, fileName?: string, parentName?: string, isAdditionalSpan?: boolean, markerPosition?: number): void; navigationItemsListCount(count: number, searchValue: string, matchKind?: string): void; diff --git a/tests/cases/fourslash/goToDefinitionAcrossMultipleProjects.ts b/tests/cases/fourslash/goToDefinitionAcrossMultipleProjects.ts new file mode 100644 index 00000000000..bac47638be6 --- /dev/null +++ b/tests/cases/fourslash/goToDefinitionAcrossMultipleProjects.ts @@ -0,0 +1,17 @@ +/// + +//@Filename: a.ts +////var x: number; + +//@Filename: b.ts +////var x: number; + +//@Filename: c.ts +/////// +/////// +/////**/x++; + +goTo.file("c.ts"); +goTo.marker(); + +verify.definitionCountIs(2); \ No newline at end of file diff --git a/tests/cases/fourslash/jsxBraceCompletionPosition.ts b/tests/cases/fourslash/jsxBraceCompletionPosition.ts new file mode 100644 index 00000000000..c1c331435ce --- /dev/null +++ b/tests/cases/fourslash/jsxBraceCompletionPosition.ts @@ -0,0 +1,47 @@ +/// + +//@Filename: file.tsx +//// declare var React: any; +//// +//// var x =
+//// /*1*/ +////
; +//// var y =
/*4*/
+//// var z =
+//// hello /*5*/ +////
+//// var z2 =
{ /*6*/ +////
+//// var z3 =
+//// { +//// /*7*/ +//// } +////
+ +goTo.marker('1'); +verify.not.isValidBraceCompletionAtPostion('('); +verify.isValidBraceCompletionAtPostion('{'); + +goTo.marker('2'); +verify.not.isValidBraceCompletionAtPostion('('); +verify.not.isValidBraceCompletionAtPostion('{'); + +goTo.marker('3'); +verify.not.isValidBraceCompletionAtPostion('('); +verify.isValidBraceCompletionAtPostion('{'); + +goTo.marker('4'); +verify.not.isValidBraceCompletionAtPostion('('); +verify.isValidBraceCompletionAtPostion('{'); + +goTo.marker('5'); +verify.not.isValidBraceCompletionAtPostion('('); +verify.isValidBraceCompletionAtPostion('{'); + +goTo.marker('6'); +verify.not.isValidBraceCompletionAtPostion('('); +verify.isValidBraceCompletionAtPostion('{'); + +goTo.marker('7'); +verify.not.isValidBraceCompletionAtPostion('('); +verify.isValidBraceCompletionAtPostion('{'); \ No newline at end of file diff --git a/tests/cases/fourslash/quickInfoDisplayPartsEnum.ts b/tests/cases/fourslash/quickInfoDisplayPartsEnum1.ts similarity index 100% rename from tests/cases/fourslash/quickInfoDisplayPartsEnum.ts rename to tests/cases/fourslash/quickInfoDisplayPartsEnum1.ts diff --git a/tests/cases/fourslash/quickInfoDisplayPartsEnum2.ts b/tests/cases/fourslash/quickInfoDisplayPartsEnum2.ts new file mode 100644 index 00000000000..ad08d84c1d5 --- /dev/null +++ b/tests/cases/fourslash/quickInfoDisplayPartsEnum2.ts @@ -0,0 +1,79 @@ +/// + +////enum /*1*/E { +//// /*2*/"e1", +//// /*3*/'e2' = 10, +//// /*4*/"e3" +////} +////var /*5*/eInstance: /*6*/E; +/////*7*/eInstance = /*8*/E./*9*/e1; +/////*10*/eInstance = /*11*/E./*12*/e2; +/////*13*/eInstance = /*14*/E./*15*/e3; +////const enum /*16*/constE { +//// /*17*/"e1", +//// /*18*/'e2' = 10, +//// /*19*/"e3" +////} +////var /*20*/eInstance1: /*21*/constE; +/////*22*/eInstance1 = /*23*/constE./*24*/e1; +/////*25*/eInstance1 = /*26*/constE./*27*/e2; +/////*28*/eInstance1 = /*29*/constE./*30*/e3; + +var marker = 0; +function verifyEnumDeclaration(enumName: string, instanceName: string, isConst?: boolean) { + verifyEnumDisplay(); + + verifyEnumMemberDisplay('"e1"', /*spanLength*/ 4, 0); + verifyEnumMemberDisplay("'e2'", /*spanLength*/ 4, 10); + verifyEnumMemberDisplay('"e3"', /*spanLength*/ 4, 11); + + verifyInstance(); + verifyEnumDisplay(); + + verifyInstance(); + verifyEnumDisplay(); + verifyEnumMemberDisplay('"e1"', /*spanLength*/ 2, 0); + + verifyInstance(); + verifyEnumDisplay(); + verifyEnumMemberDisplay("'e2'", /*spanLength*/ 2, 10); + + verifyInstance(); + verifyEnumDisplay(); + verifyEnumMemberDisplay('"e3"', /*spanLength*/ 2, 11); + + function verifyEnumDisplay() { + marker++; + goTo.marker(marker.toString()); + verify.verifyQuickInfoDisplayParts("enum", "", { start: test.markerByName(marker.toString()).position, length: enumName.length }, + (isConst ? [{ text: "const", kind: "keyword" }, { text: " ", kind: "space" }] : []).concat( + [{ text: "enum", kind: "keyword" }, { text: " ", kind: "space" }, { text: enumName, kind: "enumName" }]), + []);; + } + + function verifyEnumMemberDisplay(enumMemberName: string, spanLength: number, initializer: number) { + marker++; + goTo.marker(marker.toString()); + // Each of these names is a string literal, + // but since they're accessed by property accesses, + // we need to account for the quotes at the beginning and end. + verify.verifyQuickInfoDisplayParts("var", "", { start: test.markerByName(marker.toString()).position, length: spanLength }, + [{ text: "(", kind: "punctuation" }, { text: "enum member", kind: "text" }, { text: ")", kind: "punctuation" }, + { text: " ", kind: "space" }, { text: enumName, kind: "enumName" }, { text: "[", kind: "punctuation" }, { text: enumMemberName, kind: "stringLiteral" }, { text: "]", kind: "punctuation" }, + { text: " ", kind: "space" }, { text: "=", kind: "operator" }, { text: " ", kind: "space" }, { text: initializer.toString(), kind: "numericLiteral" }], + []); + } + + function verifyInstance() { + marker++; + goTo.marker(marker.toString()); + verify.verifyQuickInfoDisplayParts("var", "", { start: test.markerByName(marker.toString()).position, length: instanceName.length }, + [{ text: "var", kind: "keyword" }, + { text: " ", kind: "space" }, { text: instanceName, kind: "localName" }, { text: ":", kind: "punctuation" }, + { text: " ", kind: "space" }, { text: enumName, kind: "enumName" }], + []); + } +} + +verifyEnumDeclaration("E", "eInstance"); +verifyEnumDeclaration("constE", "eInstance1", /*isConst*/ true); diff --git a/tests/cases/fourslash/quickInfoDisplayPartsEnum3.ts b/tests/cases/fourslash/quickInfoDisplayPartsEnum3.ts new file mode 100644 index 00000000000..77fbda1e317 --- /dev/null +++ b/tests/cases/fourslash/quickInfoDisplayPartsEnum3.ts @@ -0,0 +1,80 @@ +/// + +////enum /*1*/E { +//// /*2*/"e1", +//// /*3*/'e2' = 10, +//// /*4*/"e3" +////} +////var /*5*/eInstance: /*6*/E; +/////*7*/eInstance = /*8*/E[/*9*/"e1"]; +/////*10*/eInstance = /*11*/E[/*12*/"e2"]; +/////*13*/eInstance = /*14*/E[/*15*/'e3']; +////const enum /*16*/constE { +//// /*17*/"e1", +//// /*18*/'e2' = 10, +//// /*19*/"e3" +////} +////var /*20*/eInstance1: /*21*/constE; +/////*22*/eInstance1 = /*23*/constE[/*24*/"e1"]; +/////*25*/eInstance1 = /*26*/constE[/*27*/"e2"]; +/////*28*/eInstance1 = /*29*/constE[/*30*/'e3']; + +var marker = 0; +function verifyEnumDeclaration(enumName: string, instanceName: string, isConst?: boolean) { + verifyEnumDisplay(); + + verifyEnumMemberDisplay('"e1"', /*spanLength*/ 4, 0); + verifyEnumMemberDisplay("'e2'", /*spanLength*/ 4, 10); + verifyEnumMemberDisplay('"e3"', /*spanLength*/ 4, 11); + + verifyInstance(); + verifyEnumDisplay(); + + verifyInstance(); + verifyEnumDisplay(); + verifyEnumMemberDisplay('"e1"', /*spanLength*/ 4, 0); + + verifyInstance(); + verifyEnumDisplay(); + verifyEnumMemberDisplay("'e2'", /*spanLength*/ 4, 10); + + verifyInstance(); + verifyEnumDisplay(); + verifyEnumMemberDisplay('"e3"', /*spanLength*/ 4, 11); + + function verifyEnumDisplay() { + marker++; + goTo.marker(marker.toString()); + verify.verifyQuickInfoDisplayParts("enum", "", { start: test.markerByName(marker.toString()).position, length: enumName.length }, + (isConst ? [{ text: "const", kind: "keyword" }, { text: " ", kind: "space" }] : []).concat( + [{ text: "enum", kind: "keyword" }, { text: " ", kind: "space" }, { text: enumName, kind: "enumName" }]), + []);; + } + + function verifyEnumMemberDisplay(enumMemberName: string, spanLength: number, initializer: number) { + marker++; + goTo.marker(marker.toString()); + // Each of these names is a string literal, + // but since they're accessed by property accesses, + // we need to account for the quotes at the beginning and end. + verify.verifyQuickInfoDisplayParts("var", "", { start: test.markerByName(marker.toString()).position, length: spanLength }, + [{ text: "(", kind: "punctuation" }, { text: "enum member", kind: "text" }, { text: ")", kind: "punctuation" }, + { text: " ", kind: "space" }, { text: enumName, kind: "enumName" }, { text: "[", kind: "punctuation" }, { text: enumMemberName, kind: "stringLiteral" }, { text: "]", kind: "punctuation" }, + { text: " ", kind: "space" }, { text: "=", kind: "operator" }, { text: " ", kind: "space" }, { text: initializer.toString(), kind: "numericLiteral" }], + []); + } + + function verifyInstance() { + marker++; + goTo.marker(marker.toString()); + verify.verifyQuickInfoDisplayParts("var", "", { start: test.markerByName(marker.toString()).position, length: instanceName.length }, + [{ text: "var", kind: "keyword" }, + { text: " ", kind: "space" }, { text: instanceName, kind: "localName" }, { text: ":", kind: "punctuation" }, + { text: " ", kind: "space" }, { text: enumName, kind: "enumName" }], + []); + } +} + +verifyEnumDeclaration("E", "eInstance"); +marker = 15; +//verifyEnumDeclaration("constE", "eInstance1", /*isConst*/ true); diff --git a/tests/cases/fourslash/quickInfoDisplayPartsLiteralLikeNames01.ts b/tests/cases/fourslash/quickInfoDisplayPartsLiteralLikeNames01.ts new file mode 100644 index 00000000000..939eb55610d --- /dev/null +++ b/tests/cases/fourslash/quickInfoDisplayPartsLiteralLikeNames01.ts @@ -0,0 +1,49 @@ +/// + +////class C { +//// public /*1*/1() { } +//// private /*2*/Infinity() { } +//// protected /*3*/NaN() { } +//// static /*4*/"stringLiteralName"() { } +//// method() { +//// this[/*5*/1](); +//// this[/*6*/"1"](); +//// this./*7*/Infinity(); +//// this[/*8*/"Infinity"](); +//// this./*9*/NaN(); +//// C./*10*/stringLiteralName(); +//// } + +verifyClassMethodWithElementAccessDisplay("1", "public", "1", "methodName", /*spanLength*/ "1".length); +verifyClassMethodWithPropertyAccessDisplay("2", "private", "Infinity", /*spanLength*/ "Infinity".length); +verifyClassMethodWithPropertyAccessDisplay("3", "protected", "NaN", /*spanLength*/ "NaN".length); +verifyClassMethodWithElementAccessDisplay("4", "static", '"stringLiteralName"', "stringLiteral", /*spanLength*/ '"stringLiteralName"'.length); +verifyClassMethodWithElementAccessDisplay("5", "public", "1", "methodName", /*spanLength*/ "1".length); +verifyClassMethodWithElementAccessDisplay("6", "public", "1", "methodName", /*spanLength*/ "1".length + 2); +verifyClassMethodWithPropertyAccessDisplay("7", "private", "Infinity", /*spanLength*/ "Infinity".length); +verifyClassMethodWithPropertyAccessDisplay("8", "private", "Infinity", /*spanLength*/ "Infinity".length + 2); +verifyClassMethodWithPropertyAccessDisplay("9", "protected", "NaN", /*spanLength*/ "NaN".length); +verifyClassMethodWithElementAccessDisplay("10", "static", '"stringLiteralName"', "stringLiteral", /*spanLength*/ "stringLiteralName".length); + + +function verifyClassMethodWithPropertyAccessDisplay(markerName: string, kindModifiers: string, methodName: string, spanLength: number) { + goTo.marker(markerName); + verify.verifyQuickInfoDisplayParts("method", kindModifiers, { start: test.markerByName(markerName).position, length: spanLength }, + [{ text: "(", kind: "punctuation" }, { text: "method", kind: "text" }, { text: ")", kind: "punctuation" }, + { text: " ", kind: "space" }, + { text: "C", kind: "className" }, { text: ".", kind: "punctuation" }, { text: methodName, kind: "methodName" }, + { text: "(", kind: "punctuation" }, { text: ")", kind: "punctuation" }, { text: ":", kind: "punctuation" }, + { text: " ", kind: "space" }, { text: "void", kind: "keyword" }], + []); +} + +function verifyClassMethodWithElementAccessDisplay(markerName: string, kindModifiers: string, methodName: string, methodDisplay: "methodName" | "stringLiteral", spanLength: number) { + goTo.marker(markerName); + verify.verifyQuickInfoDisplayParts("method", kindModifiers, { start: test.markerByName(markerName).position, length: spanLength }, + [{ text: "(", kind: "punctuation" }, { text: "method", kind: "text" }, { text: ")", kind: "punctuation" }, + { text: " ", kind: "space" }, + { text: "C", kind: "className" }, { text: "[", kind: "punctuation" }, { text: methodName, kind: methodDisplay }, { text: "]", kind: "punctuation" }, + { text: "(", kind: "punctuation" }, { text: ")", kind: "punctuation" }, { text: ":", kind: "punctuation" }, + { text: " ", kind: "space" }, { text: "void", kind: "keyword" }], + []); +} diff --git a/tests/cases/fourslash/quickInfoOnNarrowedTypeInModule.ts b/tests/cases/fourslash/quickInfoOnNarrowedTypeInModule.ts index b2826d01650..1f95de35403 100644 --- a/tests/cases/fourslash/quickInfoOnNarrowedTypeInModule.ts +++ b/tests/cases/fourslash/quickInfoOnNarrowedTypeInModule.ts @@ -38,7 +38,19 @@ goTo.marker('3'); verify.quickInfoIs('var nonExportedStrOrNum: string'); verify.completionListContains("nonExportedStrOrNum", "var nonExportedStrOrNum: string"); -['4', '5', '6', '7', '8', '9'].forEach((marker, index, arr) => { +goTo.marker('4'); +verify.quickInfoIs('var m.exportedStrOrNum: string | number'); +verify.completionListContains("exportedStrOrNum", "var m.exportedStrOrNum: string | number"); + +goTo.marker('5'); +verify.quickInfoIs('var m.exportedStrOrNum: number'); +verify.completionListContains("exportedStrOrNum", "var m.exportedStrOrNum: number"); + +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"); diff --git a/tests/cases/fourslash/referencesForClassMembers.ts b/tests/cases/fourslash/referencesForClassMembers.ts new file mode 100644 index 00000000000..851c1b39ab0 --- /dev/null +++ b/tests/cases/fourslash/referencesForClassMembers.ts @@ -0,0 +1,32 @@ +/// + +////class Base { +//// /*1*/a: number; +//// /*2*/method(): void { } +////} +////class MyClass extends Base { +//// /*3*/a; +//// /*4*/method() { } +////} +//// +////var c: MyClass; +////c./*5*/a; +////c./*6*/method(); + +goTo.marker("1"); +verify.referencesCountIs(3); + +goTo.marker("2"); +verify.referencesCountIs(3); + +goTo.marker("3"); +verify.referencesCountIs(3); + +goTo.marker("4"); +verify.referencesCountIs(3); + +goTo.marker("5"); +verify.referencesCountIs(3); + +goTo.marker("6"); +verify.referencesCountIs(3); diff --git a/tests/cases/fourslash/referencesForClassMembersExtendingAbstractClass.ts b/tests/cases/fourslash/referencesForClassMembersExtendingAbstractClass.ts new file mode 100644 index 00000000000..fcabff979fb --- /dev/null +++ b/tests/cases/fourslash/referencesForClassMembersExtendingAbstractClass.ts @@ -0,0 +1,32 @@ +/// + +////abstract class Base { +//// abstract /*1*/a: number; +//// abstract /*2*/method(): void; +////} +////class MyClass extends Base { +//// /*3*/a; +//// /*4*/method() { } +////} +//// +////var c: MyClass; +////c./*5*/a; +////c./*6*/method(); + +goTo.marker("1"); +verify.referencesCountIs(3); + +goTo.marker("2"); +verify.referencesCountIs(3); + +goTo.marker("3"); +verify.referencesCountIs(3); + +goTo.marker("4"); +verify.referencesCountIs(3); + +goTo.marker("5"); +verify.referencesCountIs(3); + +goTo.marker("6"); +verify.referencesCountIs(3); diff --git a/tests/cases/fourslash/referencesForClassMembersExtendingGenericClass.ts b/tests/cases/fourslash/referencesForClassMembersExtendingGenericClass.ts new file mode 100644 index 00000000000..f0185fb39aa --- /dev/null +++ b/tests/cases/fourslash/referencesForClassMembersExtendingGenericClass.ts @@ -0,0 +1,32 @@ +/// + +////class Base { +//// /*1*/a: this; +//// /*2*/method(a?:T, b?:U): this { } +////} +////class MyClass extends Base { +//// /*3*/a; +//// /*4*/method() { } +////} +//// +////var c: MyClass; +////c./*5*/a; +////c./*6*/method(); + +goTo.marker("1"); +verify.referencesCountIs(3); + +goTo.marker("2"); +verify.referencesCountIs(3); + +goTo.marker("3"); +verify.referencesCountIs(3); + +goTo.marker("4"); +verify.referencesCountIs(3); + +goTo.marker("5"); +verify.referencesCountIs(3); + +goTo.marker("6"); +verify.referencesCountIs(3); diff --git a/tests/cases/fourslash/referencesForInheritedProperties6.ts b/tests/cases/fourslash/referencesForInheritedProperties6.ts index de6a2f2eba1..ddd52447dc1 100644 --- a/tests/cases/fourslash/referencesForInheritedProperties6.ts +++ b/tests/cases/fourslash/referencesForInheritedProperties6.ts @@ -14,13 +14,13 @@ //// v./*6*/doStuff(); goTo.marker("1"); -verify.referencesCountIs(1); +verify.referencesCountIs(3); goTo.marker("2"); verify.referencesCountIs(3); goTo.marker("3"); -verify.referencesCountIs(2); +verify.referencesCountIs(3); goTo.marker("4"); verify.referencesCountIs(3); @@ -29,4 +29,4 @@ goTo.marker("5"); verify.referencesCountIs(3); goTo.marker("6"); -verify.referencesCountIs(2); \ No newline at end of file +verify.referencesCountIs(3); \ No newline at end of file diff --git a/tests/cases/fourslash/referencesForInheritedProperties7.ts b/tests/cases/fourslash/referencesForInheritedProperties7.ts index 000d4922222..5747e99615f 100644 --- a/tests/cases/fourslash/referencesForInheritedProperties7.ts +++ b/tests/cases/fourslash/referencesForInheritedProperties7.ts @@ -18,7 +18,7 @@ //// v./*8*/doStuff(); goTo.marker("1"); -verify.referencesCountIs(1); +verify.referencesCountIs(3); goTo.marker("2"); verify.referencesCountIs(3); @@ -30,7 +30,7 @@ goTo.marker("4"); verify.referencesCountIs(3); goTo.marker("5"); -verify.referencesCountIs(3); +verify.referencesCountIs(4); goTo.marker("6"); verify.referencesCountIs(4); @@ -39,4 +39,4 @@ goTo.marker("7"); verify.referencesCountIs(4); goTo.marker("8"); -verify.referencesCountIs(3); \ No newline at end of file +verify.referencesCountIs(4); \ No newline at end of file diff --git a/tests/cases/fourslash/renameAcrossMultipleProjects.ts b/tests/cases/fourslash/renameAcrossMultipleProjects.ts new file mode 100644 index 00000000000..44b5c0baef4 --- /dev/null +++ b/tests/cases/fourslash/renameAcrossMultipleProjects.ts @@ -0,0 +1,17 @@ +/// + +//@Filename: a.ts +////var /*1*/[|x|]: number; + +//@Filename: b.ts +/////// +////[|x|]++; + +//@Filename: c.ts +/////// +////[|x|]++; + +goTo.file("a.ts"); +goTo.marker("1"); + +verify.renameLocations( /*findInStrings*/ false, /*findInComments*/ false); \ No newline at end of file diff --git a/tests/cases/fourslash/server/jsdocParamTagSpecialKeywords.ts b/tests/cases/fourslash/server/jsdocParamTagSpecialKeywords.ts new file mode 100644 index 00000000000..be7ca5f0dff --- /dev/null +++ b/tests/cases/fourslash/server/jsdocParamTagSpecialKeywords.ts @@ -0,0 +1,14 @@ +/// + +// @allowNonTsExtensions: true +// @Filename: test.js +//// /** +//// * @param {string} type +//// */ +//// function test(type) { +//// type./**/ +//// } + + +goTo.marker(); +verify.completionListContains("charAt"); \ No newline at end of file diff --git a/tests/cases/fourslash/server/openFileWithSyntaxKind.ts b/tests/cases/fourslash/server/openFileWithSyntaxKind.ts new file mode 100644 index 00000000000..dcb1e54999e --- /dev/null +++ b/tests/cases/fourslash/server/openFileWithSyntaxKind.ts @@ -0,0 +1,19 @@ +/// + +// Because the fourslash runner automatically opens the first file with the default setting, +// to test the openFile function, the targeted file cannot be the first one. + +// @Filename: dumbFile.ts +//// var x; + +// @allowJs: true +// @Filename: test.ts +//// /** +//// * @type {number} +//// */ +//// var t; +//// t. + +goTo.file("test.ts", /*content*/ undefined, "JS"); +goTo.eof(); +verify.completionListContains("toExponential"); diff --git a/tests/cases/fourslash/shims-pp/getCompletionsAtPosition.ts b/tests/cases/fourslash/shims-pp/getCompletionsAtPosition.ts index 714d3390e76..f81572ccebf 100644 --- a/tests/cases/fourslash/shims-pp/getCompletionsAtPosition.ts +++ b/tests/cases/fourslash/shims-pp/getCompletionsAtPosition.ts @@ -3,10 +3,10 @@ ////function foo(strOrNum: string | number) { //// /*1*/ //// if (typeof strOrNum === "number") { -//// /*2*/ +//// strOrNum/*2*/; //// } //// else { -//// /*3*/ +//// strOrNum/*3*/; //// } ////} diff --git a/tests/cases/fourslash/shims/getCompletionsAtPosition.ts b/tests/cases/fourslash/shims/getCompletionsAtPosition.ts index 714d3390e76..f81572ccebf 100644 --- a/tests/cases/fourslash/shims/getCompletionsAtPosition.ts +++ b/tests/cases/fourslash/shims/getCompletionsAtPosition.ts @@ -3,10 +3,10 @@ ////function foo(strOrNum: string | number) { //// /*1*/ //// if (typeof strOrNum === "number") { -//// /*2*/ +//// strOrNum/*2*/; //// } //// else { -//// /*3*/ +//// strOrNum/*3*/; //// } ////} diff --git a/tests/cases/fourslash/stringBraceCompletionPosition.ts b/tests/cases/fourslash/stringBraceCompletionPosition.ts new file mode 100644 index 00000000000..09a9a86b0f1 --- /dev/null +++ b/tests/cases/fourslash/stringBraceCompletionPosition.ts @@ -0,0 +1,16 @@ +/// + +//// var x = "/*1*/"; +//// var x = '/*2*/'; +//// var x = "hello \ +//// /*3*/"; + +goTo.marker('1'); +verify.not.isValidBraceCompletionAtPostion('('); + +goTo.marker('2'); +verify.not.isValidBraceCompletionAtPostion('('); + +goTo.marker('3'); +verify.not.isValidBraceCompletionAtPostion('('); + diff --git a/tests/cases/fourslash/stringTemplateBraceCompletionPosition.ts b/tests/cases/fourslash/stringTemplateBraceCompletionPosition.ts new file mode 100644 index 00000000000..33bcd4d0625 --- /dev/null +++ b/tests/cases/fourslash/stringTemplateBraceCompletionPosition.ts @@ -0,0 +1,16 @@ +/// + +//// var x = `/*1*/`; +//// var y = `hello /*2*/world, ${100}how /*3*/are you{ 200 } to/*4*/day!?` + +goTo.marker('1'); +verify.not.isValidBraceCompletionAtPostion('('); + +goTo.marker('2'); +verify.not.isValidBraceCompletionAtPostion('('); + +goTo.marker('3'); +verify.not.isValidBraceCompletionAtPostion('('); + +goTo.marker('4'); +verify.not.isValidBraceCompletionAtPostion('('); diff --git a/tests/cases/fourslash/thisPredicateFunctionCompletions03.ts b/tests/cases/fourslash/thisPredicateFunctionCompletions03.ts index 3c93a859bf3..4985a1ca561 100644 --- a/tests/cases/fourslash/thisPredicateFunctionCompletions03.ts +++ b/tests/cases/fourslash/thisPredicateFunctionCompletions03.ts @@ -38,20 +38,6 @@ //// b./*8*/; //// } //// -//// if (((a.isLeader)())) { -//// a./*9*/; -//// } -//// else if (((a).isFollower())) { -//// a./*10*/; -//// } -//// -//// if (((a["isLeader"])())) { -//// a./*11*/; -//// } -//// else if (((a)["isFollower"]())) { -//// a./*12*/; -//// } -//// //// let leader/*13*/Status = a.isLeader(); //// function isLeaderGuard(g: RoyalGuard) { //// return g.isLeader(); @@ -68,13 +54,3 @@ goTo.marker("6"); verify.completionListContains("lead"); goTo.marker("8"); verify.completionListContains("follow"); - -goTo.marker("9"); -verify.completionListContains("lead"); -goTo.marker("10"); -verify.completionListContains("follow"); - -goTo.marker("11"); -verify.completionListContains("lead"); -goTo.marker("12"); -verify.completionListContains("follow"); \ No newline at end of file diff --git a/tests/cases/fourslash/validBraceCompletionPosition.ts b/tests/cases/fourslash/validBraceCompletionPosition.ts new file mode 100644 index 00000000000..57c30c27c21 --- /dev/null +++ b/tests/cases/fourslash/validBraceCompletionPosition.ts @@ -0,0 +1,23 @@ +/// + +//// function parseInt(/*1*/){} +//// class aa/*2*/{ +//// public b/*3*/(){} +//// } +//// interface I/*4*/{} +//// var x = /*5*/{ a:true } + +goTo.marker('1'); +verify.isValidBraceCompletionAtPostion('('); + +goTo.marker('2'); +verify.isValidBraceCompletionAtPostion('('); + +goTo.marker('3'); +verify.isValidBraceCompletionAtPostion('('); + +goTo.marker('4'); +verify.isValidBraceCompletionAtPostion('('); + +goTo.marker('5'); +verify.isValidBraceCompletionAtPostion('('); \ No newline at end of file