Merge pull request #8010 from Microsoft/controlFlowTypes

Control flow based type analysis
This commit is contained in:
Anders Hejlsberg
2016-04-22 14:18:56 -07:00
198 changed files with 8081 additions and 3626 deletions
+556 -295
View File
@@ -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<number>;
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<string>;
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;
@@ -441,11 +442,11 @@ namespace ts {
blockScopeContainer.locals = undefined;
}
let savedReachabilityState: Reachability;
let savedLabelStack: Reachability[];
let savedLabels: Map<number>;
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;
@@ -462,15 +463,17 @@ 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;
}
if (isInJavaScriptFile(node) && node.jsDocComment) {
@@ -479,7 +482,7 @@ namespace ts {
bindReachableStatement(node);
if (currentReachabilityState === Reachability.Reachable && isFunctionLikeKind(kind) && nodeIsPresent((<FunctionLikeDeclaration>node).body)) {
if (currentFlow.kind !== FlowKind.Unreachable && isFunctionLikeKind(kind) && nodeIsPresent((<FunctionLikeDeclaration>node).body)) {
flags |= NodeFlags.HasImplicitReturn;
if (hasExplicitReturn) {
flags |= NodeFlags.HasExplicitReturn;
@@ -512,10 +515,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;
@@ -570,174 +573,502 @@ namespace ts {
case SyntaxKind.LabeledStatement:
bindLabeledStatement(<LabeledStatement>node);
break;
case SyntaxKind.PrefixUnaryExpression:
bindPrefixUnaryExpressionFlow(<PrefixUnaryExpression>node);
break;
case SyntaxKind.BinaryExpression:
bindBinaryExpressionFlow(<BinaryExpression>node);
break;
case SyntaxKind.ConditionalExpression:
bindConditionalExpressionFlow(<ConditionalExpression>node);
break;
case SyntaxKind.VariableDeclaration:
bindVariableDeclarationFlow(<VariableDeclaration>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((<PropertyAccessExpression>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((<ParenthesizedExpression>expr).expression);
case SyntaxKind.BinaryExpression:
return isNarrowingBinaryExpression(<BinaryExpression>expr);
case SyntaxKind.PrefixUnaryExpression:
return (<PrefixUnaryExpression>expr).operator === SyntaxKind.ExclamationToken && isNarrowingExpression((<PrefixUnaryExpression>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((<TypeOfExpression>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 <FlowCondition>{
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 <FlowAssignment>{
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 (<IfStatement | WhileStatement | DoStatement>parent).expression === node;
case SyntaxKind.ForStatement:
case SyntaxKind.ConditionalExpression:
return (<ForStatement | ConditionalExpression>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 = (<ParenthesizedExpression>node).expression;
}
else if (node.kind === SyntaxKind.PrefixUnaryExpression && (<PrefixUnaryExpression>node).operator === SyntaxKind.ExclamationToken) {
node = (<PrefixUnaryExpression>node).operand;
}
else {
return node.kind === SyntaxKind.BinaryExpression && (
(<BinaryExpression>node).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken ||
(<BinaryExpression>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 &&
(<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(<Expression>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 && (<BinaryExpression>node).operatorToken.kind === SyntaxKind.EqualsToken) {
bindAssignmentTargetFlow((<BinaryExpression>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 (<ArrayLiteralExpression>node).elements) {
if (e.kind === SyntaxKind.SpreadElementExpression) {
bindAssignmentTargetFlow((<SpreadElementExpression>e).expression);
}
else {
bindDestructuringTargetFlow(e);
}
}
}
else if (node.kind === SyntaxKind.ObjectLiteralExpression) {
for (const p of (<ObjectLiteralExpression>node).properties) {
if (p.kind === SyntaxKind.PropertyAssignment) {
bindDestructuringTargetFlow((<PropertyAssignment>p).initializer);
}
else if (p.kind === SyntaxKind.ShorthandPropertyAssignment) {
bindAssignmentTargetFlow((<ShorthandPropertyAssignment>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);
}
}
@@ -1276,7 +1607,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(<Identifier>node);
case SyntaxKind.PropertyAccessExpression:
if (currentFlow && isNarrowableReference(<Expression>node)) {
node.flowNode = currentFlow;
}
break;
case SyntaxKind.BinaryExpression:
if (isInJavaScriptFile(node)) {
const specialKind = getSpecialPropertyAssignmentKind(node);
@@ -1710,132 +2050,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(<ModuleDeclaration>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(<ModuleDeclaration>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((<VariableStatement>node).declarationList) & NodeFlags.BlockScoped ||
forEach((<VariableStatement>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((<VariableStatement>node).declarationList) & NodeFlags.BlockScoped ||
forEach((<VariableStatement>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;
}
}
}
+541 -501
View File
File diff suppressed because it is too large Load Diff
+9 -1
View File
@@ -1739,10 +1739,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
+2 -2
View File
@@ -1811,7 +1811,7 @@ namespace ts {
function parseEntityName(allowReservedWords: boolean, diagnosticMessage?: DiagnosticMessage): EntityName {
let entity: EntityName = parseIdentifier(diagnosticMessage);
while (parseOptional(SyntaxKind.DotToken)) {
const node = <QualifiedName>createNode(SyntaxKind.QualifiedName, entity.pos);
const node: QualifiedName = <QualifiedName>createNode(SyntaxKind.QualifiedName, entity.pos); // !!!
node.left = entity;
node.right = parseRightSideOfDot(allowReservedWords);
entity = finishNode(node);
@@ -3643,7 +3643,7 @@ namespace ts {
let elementName: EntityName = parseIdentifierName();
while (parseOptional(SyntaxKind.DotToken)) {
scanJsxIdentifier();
const node = <QualifiedName>createNode(SyntaxKind.QualifiedName, elementName.pos);
const node: QualifiedName = <QualifiedName>createNode(SyntaxKind.QualifiedName, elementName.pos); // !!!
node.left = elementName;
node.right = parseIdentifierName();
elementName = finishNode(node);
+35 -12
View File
@@ -450,6 +450,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<T> extends Array<T>, TextRange {
@@ -478,11 +479,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
@@ -1519,6 +1515,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;
@@ -2054,8 +2083,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 */
@@ -2089,18 +2116,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<string>; // Generated names table for source file
assignmentMap?: Map<boolean>; // 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.
@@ -2152,6 +2174,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 */
+35 -1
View File
@@ -840,6 +840,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;
@@ -1415,6 +1424,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 &&
(<BinaryExpression>parent).operatorToken.kind === SyntaxKind.EqualsToken &&
(<BinaryExpression>parent).left === node ||
(parent.kind === SyntaxKind.ForInStatement || parent.kind === SyntaxKind.ForOfStatement) &&
(<ForInStatement | ForOfStatement>parent).initializer === node;
}
}
export function isNodeDescendentOf(node: Node, ancestor: Node): boolean {
while (node) {
if (node === ancestor) return true;
@@ -1511,7 +1545,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;
}
+1 -1
View File
@@ -149,7 +149,7 @@ namespace Playback {
recordLog = createEmptyLog();
if (typeof underlying.args !== "function") {
recordLog.arguments = <string[]>underlying.args;
recordLog.arguments = underlying.args;
}
};
@@ -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;
@@ -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;
@@ -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))
}
@@ -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
}
@@ -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
@@ -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))
@@ -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
@@ -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
@@ -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))
@@ -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
@@ -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 = <any>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;
}
@@ -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 = <any>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))
}
@@ -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 = <any>undefined;
>sourceObj : { a: string; } | HTMLCollection | NodeList
>EventTargetLike : { a: string; } | HTMLCollection | NodeList
><any>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
}
@@ -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
}
@@ -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))
}
@@ -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
}
@@ -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
@@ -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))
@@ -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
@@ -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;
}
@@ -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))
}
@@ -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
}
@@ -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
}
@@ -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))
}
@@ -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
}
@@ -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
@@ -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))
@@ -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
@@ -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
}
@@ -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))
}
@@ -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
}
@@ -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
}
@@ -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))
}
@@ -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
}
@@ -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
}
@@ -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))
}
@@ -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
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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
}
}
@@ -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))
}
}
@@ -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
}
}
@@ -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
}
@@ -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))
}
@@ -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
}
@@ -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
}
+1 -1
View File
@@ -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
@@ -133,8 +133,8 @@ function fn5(x: Derived1) {
// 1.5: y: Derived1
// Want: ???
let y = x;
>y : Derived1
>x : Derived1
>y : {}
>x : {}
}
}
@@ -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;
}
@@ -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))
}
@@ -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
}
@@ -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;
}
@@ -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))
}
@@ -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
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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.
}
@@ -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))
}
@@ -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
}
@@ -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.
}
@@ -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))
}
@@ -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
}
@@ -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) {
}
@@ -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) {
}
}
@@ -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) {
@@ -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) {
@@ -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[]
@@ -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]][]
@@ -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
@@ -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; }; }
@@ -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
@@ -116,6 +116,6 @@ if (!hasKind(x, "B")) {
}
else {
let d = x;
>d : A
>x : A
>d : {}
>x : {}
}
@@ -110,6 +110,6 @@ if (!hasKind(x, "B")) {
}
else {
let d = x;
>d : A
>x : A
>d : {}
>x : {}
}
@@ -113,6 +113,6 @@ if (!hasKind(x, "B")) {
}
else {
let d = x;
>d : A
>x : A
>d : {}
>x : {}
}
@@ -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;
}
@@ -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))
@@ -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
@@ -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;
}
@@ -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))
@@ -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
@@ -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;
}
@@ -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))
@@ -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
@@ -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;
}
@@ -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))
@@ -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

Some files were not shown because too many files have changed in this diff Show More