mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' of https://github.com/Microsoft/TypeScript into typedefForJsdoc
This commit is contained in:
@@ -6,6 +6,8 @@ tests/cases/perf/*
|
||||
!tests/cases/webharness/compilerToString.js
|
||||
test-args.txt
|
||||
~*.docx
|
||||
\#*\#
|
||||
.\#*
|
||||
tests/baselines/local/*
|
||||
tests/services/baselines/local/*
|
||||
tests/baselines/prototyping/local/*
|
||||
|
||||
+1
-1
@@ -203,7 +203,7 @@ var librarySourceMap = [
|
||||
|
||||
// JavaScript + all host library
|
||||
{ target: "lib.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(hostsLibrarySources), },
|
||||
{ target: "lib.es6.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(es2015LibrarySources, hostsLibrarySources), },
|
||||
{ target: "lib.es6.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts"), },
|
||||
].concat(es2015LibrarySourceMap, es2016LibrarySourceMap);
|
||||
|
||||
var libraryTargets = librarySourceMap.map(function (f) {
|
||||
|
||||
+556
-295
@@ -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;
|
||||
@@ -450,11 +451,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;
|
||||
@@ -471,20 +472,22 @@ namespace ts {
|
||||
|
||||
const saveState = kind === SyntaxKind.SourceFile || kind === SyntaxKind.ModuleBlock || isFunctionLikeKind(kind);
|
||||
if (saveState) {
|
||||
savedReachabilityState = currentReachabilityState;
|
||||
savedLabelStack = labelStack;
|
||||
savedLabels = labelIndexMap;
|
||||
savedImplicitLabels = implicitLabels;
|
||||
savedHasExplicitReturn = hasExplicitReturn;
|
||||
savedCurrentFlow = currentFlow;
|
||||
savedBreakTarget = currentBreakTarget;
|
||||
savedContinueTarget = currentContinueTarget;
|
||||
savedActiveLabels = activeLabels;
|
||||
|
||||
currentReachabilityState = Reachability.Reachable;
|
||||
hasExplicitReturn = false;
|
||||
labelStack = labelIndexMap = implicitLabels = undefined;
|
||||
currentFlow = { kind: FlowKind.Start };
|
||||
currentBreakTarget = undefined;
|
||||
currentContinueTarget = undefined;
|
||||
activeLabels = undefined;
|
||||
}
|
||||
|
||||
bindReachableStatement(node);
|
||||
|
||||
if (currentReachabilityState === Reachability.Reachable && isFunctionLikeKind(kind) && nodeIsPresent((<FunctionLikeDeclaration>node).body)) {
|
||||
if (currentFlow.kind !== FlowKind.Unreachable && isFunctionLikeKind(kind) && nodeIsPresent((<FunctionLikeDeclaration>node).body)) {
|
||||
flags |= NodeFlags.HasImplicitReturn;
|
||||
if (hasExplicitReturn) {
|
||||
flags |= NodeFlags.HasExplicitReturn;
|
||||
@@ -517,10 +520,10 @@ namespace ts {
|
||||
|
||||
if (saveState) {
|
||||
hasExplicitReturn = savedHasExplicitReturn;
|
||||
currentReachabilityState = savedReachabilityState;
|
||||
labelStack = savedLabelStack;
|
||||
labelIndexMap = savedLabels;
|
||||
implicitLabels = savedImplicitLabels;
|
||||
currentFlow = savedCurrentFlow;
|
||||
currentBreakTarget = savedBreakTarget;
|
||||
currentContinueTarget = savedContinueTarget;
|
||||
activeLabels = savedActiveLabels;
|
||||
}
|
||||
|
||||
container = saveContainer;
|
||||
@@ -575,174 +578,502 @@ namespace ts {
|
||||
case SyntaxKind.LabeledStatement:
|
||||
bindLabeledStatement(<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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1283,7 +1614,16 @@ namespace ts {
|
||||
switch (node.kind) {
|
||||
/* Strict mode checks */
|
||||
case SyntaxKind.Identifier:
|
||||
case SyntaxKind.ThisKeyword:
|
||||
if (currentFlow && (isExpression(node) || parent.kind === SyntaxKind.ShorthandPropertyAssignment)) {
|
||||
node.flowNode = currentFlow;
|
||||
}
|
||||
return checkStrictModeIdentifier(<Identifier>node);
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
if (currentFlow && isNarrowableReference(<Expression>node)) {
|
||||
node.flowNode = currentFlow;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.BinaryExpression:
|
||||
if (isInJavaScriptFile(node)) {
|
||||
const specialKind = getSpecialPropertyAssignmentKind(node);
|
||||
@@ -1720,132 +2060,53 @@ namespace ts {
|
||||
|
||||
// reachability checks
|
||||
|
||||
function pushNamedLabel(name: Identifier): boolean {
|
||||
initializeReachabilityStateIfNecessary();
|
||||
|
||||
if (hasProperty(labelIndexMap, name.text)) {
|
||||
return false;
|
||||
}
|
||||
labelIndexMap[name.text] = labelStack.push(Reachability.Uninitialized) - 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
function pushImplicitLabel(): number {
|
||||
initializeReachabilityStateIfNecessary();
|
||||
|
||||
const index = labelStack.push(Reachability.Uninitialized) - 1;
|
||||
implicitLabels.push(index);
|
||||
return index;
|
||||
}
|
||||
|
||||
function popNamedLabel(label: Identifier, outerState: Reachability): void {
|
||||
const index = labelIndexMap[label.text];
|
||||
Debug.assert(index !== undefined);
|
||||
Debug.assert(labelStack.length == index + 1);
|
||||
|
||||
labelIndexMap[label.text] = undefined;
|
||||
|
||||
setCurrentStateAtLabel(labelStack.pop(), outerState, label);
|
||||
}
|
||||
|
||||
function popImplicitLabel(implicitLabelIndex: number, outerState: Reachability): void {
|
||||
if (labelStack.length !== implicitLabelIndex + 1) {
|
||||
Debug.assert(false, `Label stack: ${labelStack.length}, index:${implicitLabelIndex}`);
|
||||
}
|
||||
|
||||
const i = implicitLabels.pop();
|
||||
|
||||
if (implicitLabelIndex !== i) {
|
||||
Debug.assert(false, `i: ${i}, index: ${implicitLabelIndex}`);
|
||||
}
|
||||
|
||||
setCurrentStateAtLabel(labelStack.pop(), outerState, /*name*/ undefined);
|
||||
}
|
||||
|
||||
function setCurrentStateAtLabel(innerMergedState: Reachability, outerState: Reachability, label: Identifier): void {
|
||||
if (innerMergedState === Reachability.Uninitialized) {
|
||||
if (label && !options.allowUnusedLabels) {
|
||||
file.bindDiagnostics.push(createDiagnosticForNode(label, Diagnostics.Unused_label));
|
||||
}
|
||||
currentReachabilityState = outerState;
|
||||
}
|
||||
else {
|
||||
currentReachabilityState = or(innerMergedState, outerState);
|
||||
}
|
||||
}
|
||||
|
||||
function jumpToLabel(label: Identifier, outerState: Reachability): boolean {
|
||||
initializeReachabilityStateIfNecessary();
|
||||
|
||||
const index = label ? labelIndexMap[label.text] : lastOrUndefined(implicitLabels);
|
||||
if (index === undefined) {
|
||||
// reference to unknown label or
|
||||
// break/continue used outside of loops
|
||||
return false;
|
||||
}
|
||||
const stateAtLabel = labelStack[index];
|
||||
labelStack[index] = stateAtLabel === Reachability.Uninitialized ? outerState : or(stateAtLabel, outerState);
|
||||
return true;
|
||||
function shouldReportErrorOnModuleDeclaration(node: ModuleDeclaration): boolean {
|
||||
const instanceState = getModuleInstanceState(node);
|
||||
return instanceState === ModuleInstanceState.Instantiated || (instanceState === ModuleInstanceState.ConstEnumOnly && options.preserveConstEnums);
|
||||
}
|
||||
|
||||
function checkUnreachable(node: Node): boolean {
|
||||
switch (currentReachabilityState) {
|
||||
case Reachability.Unreachable:
|
||||
const reportError =
|
||||
// report error on all statements except empty ones
|
||||
(isStatement(node) && node.kind !== SyntaxKind.EmptyStatement) ||
|
||||
// report error on class declarations
|
||||
node.kind === SyntaxKind.ClassDeclaration ||
|
||||
// report error on instantiated modules or const-enums only modules if preserveConstEnums is set
|
||||
(node.kind === SyntaxKind.ModuleDeclaration && shouldReportErrorOnModuleDeclaration(<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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+610
-523
File diff suppressed because it is too large
Load Diff
@@ -91,10 +91,10 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function contains<T>(array: T[], value: T): boolean {
|
||||
export function contains<T>(array: T[], value: T, areEqual?: (a: T, b: T) => boolean): boolean {
|
||||
if (array) {
|
||||
for (const v of array) {
|
||||
if (v === value) {
|
||||
if (areEqual ? areEqual(v, value) : v === value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -156,12 +156,12 @@ namespace ts {
|
||||
return array1.concat(array2);
|
||||
}
|
||||
|
||||
export function deduplicate<T>(array: T[]): T[] {
|
||||
export function deduplicate<T>(array: T[], areEqual?: (a: T, b: T) => boolean): T[] {
|
||||
let result: T[];
|
||||
if (array) {
|
||||
result = [];
|
||||
for (const item of array) {
|
||||
if (!contains(result, item)) {
|
||||
if (!contains(result, item, areEqual)) {
|
||||
result.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1377,6 +1377,7 @@ namespace ts {
|
||||
function emitSignatureDeclaration(node: SignatureDeclaration) {
|
||||
const prevEnclosingDeclaration = enclosingDeclaration;
|
||||
enclosingDeclaration = node;
|
||||
let closeParenthesizedFunctionType = false;
|
||||
|
||||
if (node.kind === SyntaxKind.IndexSignature) {
|
||||
// Index signature can have readonly modifier
|
||||
@@ -1388,6 +1389,16 @@ namespace ts {
|
||||
if (node.kind === SyntaxKind.ConstructSignature || node.kind === SyntaxKind.ConstructorType) {
|
||||
write("new ");
|
||||
}
|
||||
else if (node.kind === SyntaxKind.FunctionType) {
|
||||
const currentOutput = writer.getText();
|
||||
// Do not generate incorrect type when function type with type parameters is type argument
|
||||
// This could happen if user used space between two '<' making it error free
|
||||
// e.g var x: A< <Tany>(a: Tany)=>Tany>;
|
||||
if (node.typeParameters && currentOutput.charAt(currentOutput.length - 1) === "<") {
|
||||
closeParenthesizedFunctionType = true;
|
||||
write("(");
|
||||
}
|
||||
}
|
||||
emitTypeParameters(node.typeParameters);
|
||||
write("(");
|
||||
}
|
||||
@@ -1421,6 +1432,9 @@ namespace ts {
|
||||
write(";");
|
||||
writeLine();
|
||||
}
|
||||
else if (closeParenthesizedFunctionType) {
|
||||
write(")");
|
||||
}
|
||||
|
||||
function getReturnTypeVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
|
||||
let diagnosticMessage: DiagnosticMessage;
|
||||
|
||||
@@ -1743,10 +1743,18 @@
|
||||
"category": "Error",
|
||||
"code": 2530
|
||||
},
|
||||
"Object is possibly 'null' or 'undefined'.": {
|
||||
"Object is possibly 'null'.": {
|
||||
"category": "Error",
|
||||
"code": 2531
|
||||
},
|
||||
"Object is possibly 'undefined'.": {
|
||||
"category": "Error",
|
||||
"code": 2532
|
||||
},
|
||||
"Object is possibly 'null' or 'undefined'.": {
|
||||
"category": "Error",
|
||||
"code": 2533
|
||||
},
|
||||
"JSX element attributes type '{0}' may not be a union type.": {
|
||||
"category": "Error",
|
||||
"code": 2600
|
||||
@@ -1823,7 +1831,7 @@
|
||||
"category": "Error",
|
||||
"code": 2660
|
||||
},
|
||||
"Cannot re-export name that is not defined in the module.": {
|
||||
"Cannot export '{0}'. Only local declarations can be exported from a module.": {
|
||||
"category": "Error",
|
||||
"code": 2661
|
||||
},
|
||||
@@ -2296,7 +2304,14 @@
|
||||
"category": "Error",
|
||||
"code": 5062
|
||||
},
|
||||
|
||||
"Substututions for pattern '{0}' should be an array.": {
|
||||
"category": "Error",
|
||||
"code": 5063
|
||||
},
|
||||
"Substitution '{0}' for pattern '{1}' has incorrect type, expected 'string', got '{2}'.": {
|
||||
"category": "Error",
|
||||
"code": 5064
|
||||
},
|
||||
"Concatenate and emit output to single file.": {
|
||||
"category": "Message",
|
||||
"code": 6001
|
||||
|
||||
@@ -4487,7 +4487,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
}
|
||||
|
||||
function emitRestParameter(node: FunctionLikeDeclaration) {
|
||||
if (languageVersion < ScriptTarget.ES6 && hasRestParameter(node)) {
|
||||
if (languageVersion < ScriptTarget.ES6 && hasDeclaredRestParameter(node)) {
|
||||
const restIndex = node.parameters.length - 1;
|
||||
const restParam = node.parameters[restIndex];
|
||||
|
||||
@@ -4644,7 +4644,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
if (node) {
|
||||
const parameters = node.parameters;
|
||||
const skipCount = node.parameters.length && (<Identifier>node.parameters[0].name).text === "this" ? 1 : 0;
|
||||
const omitCount = languageVersion < ScriptTarget.ES6 && hasRestParameter(node) ? 1 : 0;
|
||||
const omitCount = languageVersion < ScriptTarget.ES6 && hasDeclaredRestParameter(node) ? 1 : 0;
|
||||
emitList(parameters, skipCount, parameters.length - omitCount - skipCount, /*multiLine*/ false, /*trailingComma*/ false);
|
||||
}
|
||||
write(")");
|
||||
@@ -7879,7 +7879,7 @@ const _super = (function (geti, seti) {
|
||||
node.parent &&
|
||||
node.parent.kind === SyntaxKind.ArrowFunction &&
|
||||
(<ArrowFunction>node.parent).body === node &&
|
||||
compilerOptions.target <= ScriptTarget.ES5) {
|
||||
languageVersion <= ScriptTarget.ES5) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
+13
-9
@@ -1825,7 +1825,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);
|
||||
@@ -3657,7 +3657,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);
|
||||
@@ -6141,7 +6141,7 @@ namespace ts {
|
||||
atToken.end = scanner.getTextPos();
|
||||
nextJSDocToken();
|
||||
|
||||
const tagName = parseJSDocIdentifier();
|
||||
const tagName = parseJSDocIdentifierName();
|
||||
if (!tagName) {
|
||||
return;
|
||||
}
|
||||
@@ -6236,7 +6236,7 @@ namespace ts {
|
||||
let isBracketed: boolean;
|
||||
// Looking for something like '[foo]' or 'foo'
|
||||
if (parseOptionalToken(SyntaxKind.OpenBracketToken)) {
|
||||
name = parseJSDocIdentifier();
|
||||
name = parseJSDocIdentifierName();
|
||||
isBracketed = true;
|
||||
|
||||
// May have an optional default, e.g. '[foo = 42]'
|
||||
@@ -6246,8 +6246,8 @@ namespace ts {
|
||||
|
||||
parseExpected(SyntaxKind.CloseBracketToken);
|
||||
}
|
||||
else if (token === SyntaxKind.Identifier) {
|
||||
name = parseJSDocIdentifier();
|
||||
else if (tokenIsIdentifierOrKeyword(token)) {
|
||||
name = parseJSDocIdentifierName();
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
@@ -6400,7 +6400,7 @@ namespace ts {
|
||||
typeParameters.pos = scanner.getStartPos();
|
||||
|
||||
while (true) {
|
||||
const name = parseJSDocIdentifier();
|
||||
const name = parseJSDocIdentifierName();
|
||||
if (!name) {
|
||||
parseErrorAtPosition(scanner.getStartPos(), 0, Diagnostics.Identifier_expected);
|
||||
return undefined;
|
||||
@@ -6433,8 +6433,12 @@ namespace ts {
|
||||
return token = scanner.scanJSDocToken();
|
||||
}
|
||||
|
||||
function parseJSDocIdentifier(): Identifier {
|
||||
if (token !== SyntaxKind.Identifier) {
|
||||
function parseJSDocIdentifierName(): Identifier {
|
||||
return createJSDocIdentifier(tokenIsIdentifierOrKeyword(token));
|
||||
}
|
||||
|
||||
function createJSDocIdentifier(isIdentifier: boolean): Identifier {
|
||||
if (!isIdentifier) {
|
||||
parseErrorAtCurrentToken(Diagnostics.Identifier_expected);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
+14
-3
@@ -1985,11 +1985,22 @@ namespace ts {
|
||||
if (!hasZeroOrOneAsteriskCharacter(key)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, key));
|
||||
}
|
||||
for (const subst of options.paths[key]) {
|
||||
if (!hasZeroOrOneAsteriskCharacter(subst)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character, subst, key));
|
||||
if (isArray(options.paths[key])) {
|
||||
for (const subst of options.paths[key]) {
|
||||
const typeOfSubst = typeof subst;
|
||||
if (typeOfSubst === "string") {
|
||||
if (!hasZeroOrOneAsteriskCharacter(subst)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character, subst, key));
|
||||
}
|
||||
}
|
||||
else {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2, subst, key, typeOfSubst));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Substututions_for_pattern_0_should_be_an_array, key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-5
@@ -44,11 +44,9 @@ namespace ts {
|
||||
const territory = matchResult[3];
|
||||
|
||||
// First try the entire locale, then fall back to just language if that's all we have.
|
||||
if (!trySetLanguageAndTerritory(language, territory, errors) &&
|
||||
!trySetLanguageAndTerritory(language, undefined, errors)) {
|
||||
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Unsupported_locale_0, locale));
|
||||
return false;
|
||||
// Either ways do not fail, and fallback to the English diagnostic strings.
|
||||
if (!trySetLanguageAndTerritory(language, territory, errors)) {
|
||||
trySetLanguageAndTerritory(language, undefined, errors);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
+36
-12
@@ -455,6 +455,7 @@ namespace ts {
|
||||
/* @internal */ locals?: SymbolTable; // Locals associated with node (initialized by binding)
|
||||
/* @internal */ nextContainer?: Node; // Next container in declaration order (initialized by binding)
|
||||
/* @internal */ localSymbol?: Symbol; // Local symbol declared by node (initialized by binding only for exported nodes)
|
||||
/* @internal */ flowNode?: FlowNode; // Associated FlowNode (initialized by binding)
|
||||
}
|
||||
|
||||
export interface NodeArray<T> extends Array<T>, TextRange {
|
||||
@@ -483,11 +484,6 @@ namespace ts {
|
||||
originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later
|
||||
}
|
||||
|
||||
// Transient identifier node (marked by id === -1)
|
||||
export interface TransientIdentifier extends Identifier {
|
||||
resolvedSymbol: Symbol;
|
||||
}
|
||||
|
||||
// @kind(SyntaxKind.QualifiedName)
|
||||
export interface QualifiedName extends Node {
|
||||
// Must have same layout as PropertyAccess
|
||||
@@ -1551,6 +1547,39 @@ namespace ts {
|
||||
isBracketed: boolean;
|
||||
}
|
||||
|
||||
export const enum FlowKind {
|
||||
Unreachable,
|
||||
Start,
|
||||
Label,
|
||||
Assignment,
|
||||
Condition
|
||||
}
|
||||
|
||||
export interface FlowNode {
|
||||
kind: FlowKind; // Node kind
|
||||
id?: number; // Node id used by flow type cache in checker
|
||||
}
|
||||
|
||||
// FlowLabel represents a junction with multiple possible preceding control flows.
|
||||
export interface FlowLabel extends FlowNode {
|
||||
antecedents: FlowNode[];
|
||||
}
|
||||
|
||||
// FlowAssignment represents a node that assigns a value to a narrowable reference,
|
||||
// i.e. an identifier or a dotted name that starts with an identifier or 'this'.
|
||||
export interface FlowAssignment extends FlowNode {
|
||||
node: Expression | VariableDeclaration | BindingElement;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
|
||||
// FlowCondition represents a condition that is known to be true or false at the
|
||||
// node's location in the control flow.
|
||||
export interface FlowCondition extends FlowNode {
|
||||
expression: Expression;
|
||||
assumeTrue: boolean;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
|
||||
export interface AmdDependency {
|
||||
path: string;
|
||||
name: string;
|
||||
@@ -1852,6 +1881,7 @@ namespace ts {
|
||||
WriteTypeArgumentsOfSignature = 0x00000020, // Write the type arguments instead of type parameters of the signature
|
||||
InElementType = 0x00000040, // Writing an array or union element type
|
||||
UseFullyQualifiedType = 0x00000080, // Write out the fully qualified type name (eg. Module.Type, instead of Type)
|
||||
InFirstTypeArgument = 0x00000100, // Writing first type argument of the instantiated type
|
||||
}
|
||||
|
||||
export const enum SymbolFormatFlags {
|
||||
@@ -2085,8 +2115,6 @@ namespace ts {
|
||||
isDeclarationWithCollidingName?: boolean; // True if symbol is block scoped redeclaration
|
||||
bindingElement?: BindingElement; // Binding element associated with property symbol
|
||||
exportsSomeValue?: boolean; // True if module exports some value (not just types)
|
||||
firstAssignmentChecked?: boolean; // True if first assignment node has been computed
|
||||
firstAssignment?: Node; // First assignment node (undefined if no assignments)
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -2120,18 +2148,13 @@ namespace ts {
|
||||
/* @internal */
|
||||
export interface NodeLinks {
|
||||
resolvedType?: Type; // Cached type of type node
|
||||
resolvedAwaitedType?: Type; // Cached awaited type of type node
|
||||
resolvedSignature?: Signature; // Cached signature of signature node or call expression
|
||||
resolvedSymbol?: Symbol; // Cached name resolution result
|
||||
resolvedIndexInfo?: IndexInfo; // Cached indexing info resolution result
|
||||
flags?: NodeCheckFlags; // Set of flags specific to Node
|
||||
enumMemberValue?: number; // Constant value of enum member
|
||||
isVisible?: boolean; // Is this node visible
|
||||
generatedName?: string; // Generated name for module, enum, or import declaration
|
||||
generatedNames?: Map<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.
|
||||
@@ -2183,6 +2206,7 @@ namespace ts {
|
||||
ObjectType = Class | Interface | Reference | Tuple | Anonymous,
|
||||
UnionOrIntersection = Union | Intersection,
|
||||
StructuredType = ObjectType | Union | Intersection,
|
||||
Narrowable = Any | ObjectType | Union | TypeParameter,
|
||||
/* @internal */
|
||||
RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral,
|
||||
/* @internal */
|
||||
|
||||
+55
-14
@@ -455,7 +455,7 @@ namespace ts {
|
||||
const { line: startLine } = getLineAndCharacterOfPosition(sourceFile, node.body.pos);
|
||||
const { line: endLine } = getLineAndCharacterOfPosition(sourceFile, node.body.end);
|
||||
if (startLine < endLine) {
|
||||
// The arrow function spans multiple lines,
|
||||
// The arrow function spans multiple lines,
|
||||
// make the error span be the first line, inclusive.
|
||||
return createTextSpan(pos, getEndLinePosition(startLine, sourceFile) - pos + 1);
|
||||
}
|
||||
@@ -860,6 +860,15 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function getContainingFunctionOrModule(node: Node): Node {
|
||||
while (true) {
|
||||
node = node.parent;
|
||||
if (isFunctionLike(node) || node.kind === SyntaxKind.ModuleDeclaration || node.kind === SyntaxKind.SourceFile) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getContainingClass(node: Node): ClassLikeDeclaration {
|
||||
while (true) {
|
||||
node = node.parent;
|
||||
@@ -1216,6 +1225,10 @@ namespace ts {
|
||||
return isRequire && (!checkArgumentIsStringLiteral || (<CallExpression>expression).arguments[0].kind === SyntaxKind.StringLiteral);
|
||||
}
|
||||
|
||||
export function isSingleOrDoubleQuote(charCode: number) {
|
||||
return charCode === CharacterCodes.singleQuote || charCode === CharacterCodes.doubleQuote;
|
||||
}
|
||||
|
||||
/// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property
|
||||
/// assignments we treat as special in the binder
|
||||
export function getSpecialPropertyAssignmentKind(expression: Node): SpecialPropertyAssignmentKind {
|
||||
@@ -1397,23 +1410,26 @@ namespace ts {
|
||||
return isRestParameter(lastOrUndefined(s.parameters));
|
||||
}
|
||||
|
||||
export function isRestParameter(node: ParameterDeclaration) {
|
||||
if (node) {
|
||||
if (node.flags & NodeFlags.JavaScriptFile) {
|
||||
if (node.type && node.type.kind === SyntaxKind.JSDocVariadicType) {
|
||||
return true;
|
||||
}
|
||||
export function hasDeclaredRestParameter(s: SignatureDeclaration): boolean {
|
||||
return isDeclaredRestParam(lastOrUndefined(s.parameters));
|
||||
}
|
||||
|
||||
const paramTag = getCorrespondingJSDocParameterTag(node);
|
||||
if (paramTag && paramTag.typeExpression) {
|
||||
return paramTag.typeExpression.type.kind === SyntaxKind.JSDocVariadicType;
|
||||
}
|
||||
export function isRestParameter(node: ParameterDeclaration) {
|
||||
if (node && (node.flags & NodeFlags.JavaScriptFile)) {
|
||||
if (node.type && node.type.kind === SyntaxKind.JSDocVariadicType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return node.dotDotDotToken !== undefined;
|
||||
const paramTag = getCorrespondingJSDocParameterTag(node);
|
||||
if (paramTag && paramTag.typeExpression) {
|
||||
return paramTag.typeExpression.type.kind === SyntaxKind.JSDocVariadicType;
|
||||
}
|
||||
}
|
||||
return isDeclaredRestParam(node);
|
||||
}
|
||||
|
||||
return false;
|
||||
export function isDeclaredRestParam(node: ParameterDeclaration) {
|
||||
return node && node.dotDotDotToken !== undefined;
|
||||
}
|
||||
|
||||
export function isLiteralKind(kind: SyntaxKind): boolean {
|
||||
@@ -1432,6 +1448,31 @@ namespace ts {
|
||||
return !!node && (node.kind === SyntaxKind.ArrayBindingPattern || node.kind === SyntaxKind.ObjectBindingPattern);
|
||||
}
|
||||
|
||||
// A node is an assignment target if it is on the left hand side of an '=' token, if it is parented by a property
|
||||
// assignment in an object literal that is an assignment target, or if it is parented by an array literal that is
|
||||
// an assignment target. Examples include 'a = xxx', '{ p: a } = xxx', '[{ p: a}] = xxx'.
|
||||
export function isAssignmentTarget(node: Node): boolean {
|
||||
while (node.parent.kind === SyntaxKind.ParenthesizedExpression) {
|
||||
node = node.parent;
|
||||
}
|
||||
while (true) {
|
||||
const parent = node.parent;
|
||||
if (parent.kind === SyntaxKind.ArrayLiteralExpression || parent.kind === SyntaxKind.SpreadElementExpression) {
|
||||
node = parent;
|
||||
continue;
|
||||
}
|
||||
if (parent.kind === SyntaxKind.PropertyAssignment || parent.kind === SyntaxKind.ShorthandPropertyAssignment) {
|
||||
node = parent.parent;
|
||||
continue;
|
||||
}
|
||||
return parent.kind === SyntaxKind.BinaryExpression &&
|
||||
(<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;
|
||||
@@ -1529,7 +1570,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// True if the given identifier, string literal, or number literal is the name of a declaration node
|
||||
export function isDeclarationName(name: Node): name is Identifier | StringLiteral | LiteralExpression {
|
||||
export function isDeclarationName(name: Node): boolean {
|
||||
if (name.kind !== SyntaxKind.Identifier && name.kind !== SyntaxKind.StringLiteral && name.kind !== SyntaxKind.NumericLiteral) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+52
-17
@@ -362,14 +362,14 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
// Opens a file given its 0-based index or fileName
|
||||
public openFile(index: number, content?: string): void;
|
||||
public openFile(name: string, content?: string): void;
|
||||
public openFile(indexOrName: any, content?: string) {
|
||||
public openFile(index: number, content?: string, scriptKindName?: string): void;
|
||||
public openFile(name: string, content?: string, scriptKindName?: string): void;
|
||||
public openFile(indexOrName: any, content?: string, scriptKindName?: string) {
|
||||
const fileToOpen: FourSlashFile = this.findFile(indexOrName);
|
||||
fileToOpen.fileName = ts.normalizeSlashes(fileToOpen.fileName);
|
||||
this.activeFile = fileToOpen;
|
||||
// Let the host know that this file is now open
|
||||
this.languageServiceAdapterHost.openFile(fileToOpen.fileName, content);
|
||||
this.languageServiceAdapterHost.openFile(fileToOpen.fileName, content, scriptKindName);
|
||||
}
|
||||
|
||||
public verifyErrorExistsBetweenMarkers(startMarkerName: string, endMarkerName: string, negative: boolean) {
|
||||
@@ -655,7 +655,7 @@ namespace FourSlash {
|
||||
this.assertItemInCompletionList(completions.entries, symbol, text, documentation, kind);
|
||||
}
|
||||
else {
|
||||
this.raiseError(`No completions at position '${ this.currentCaretPosition }' when looking for '${ symbol }'.`);
|
||||
this.raiseError(`No completions at position '${this.currentCaretPosition}' when looking for '${symbol}'.`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1758,13 +1758,13 @@ namespace FourSlash {
|
||||
const actual = (<ts.server.SessionClient>this.languageService).getProjectInfo(
|
||||
this.activeFile.fileName,
|
||||
/* needFileNameList */ true
|
||||
);
|
||||
);
|
||||
assert.equal(
|
||||
expected.join(","),
|
||||
actual.fileNames.map( file => {
|
||||
actual.fileNames.map(file => {
|
||||
return file.replace(this.basePath + "/", "");
|
||||
}).join(",")
|
||||
);
|
||||
}).join(",")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1850,6 +1850,37 @@ namespace FourSlash {
|
||||
});
|
||||
}
|
||||
|
||||
public verifyBraceCompletionAtPostion(negative: boolean, openingBrace: string) {
|
||||
|
||||
const openBraceMap: ts.Map<ts.CharacterCodes> = {
|
||||
"(": ts.CharacterCodes.openParen,
|
||||
"{": ts.CharacterCodes.openBrace,
|
||||
"[": ts.CharacterCodes.openBracket,
|
||||
"'": ts.CharacterCodes.singleQuote,
|
||||
'"': ts.CharacterCodes.doubleQuote,
|
||||
"`": ts.CharacterCodes.backtick,
|
||||
"<": ts.CharacterCodes.lessThan
|
||||
};
|
||||
|
||||
const charCode = openBraceMap[openingBrace];
|
||||
|
||||
if (!charCode) {
|
||||
this.raiseError(`Invalid openingBrace '${openingBrace}' specified.`);
|
||||
}
|
||||
|
||||
const position = this.currentCaretPosition;
|
||||
|
||||
const validBraceCompletion = this.languageService.isValidBraceCompletionAtPostion(this.activeFile.fileName, position, charCode);
|
||||
|
||||
if (!negative && !validBraceCompletion) {
|
||||
this.raiseError(`${position} is not a valid brace completion position for ${openingBrace}`);
|
||||
}
|
||||
|
||||
if (negative && validBraceCompletion) {
|
||||
this.raiseError(`${position} is a valid brace completion position for ${openingBrace}`);
|
||||
}
|
||||
}
|
||||
|
||||
public verifyMatchingBracePosition(bracePosition: number, expectedMatchPosition: number) {
|
||||
const actual = this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, bracePosition);
|
||||
|
||||
@@ -2239,7 +2270,7 @@ namespace FourSlash {
|
||||
};
|
||||
|
||||
const host = Harness.Compiler.createCompilerHost(
|
||||
[ fourslashFile, testFile ],
|
||||
[fourslashFile, testFile],
|
||||
(fn, contents) => result = contents,
|
||||
ts.ScriptTarget.Latest,
|
||||
Harness.IO.useCaseSensitiveFileNames(),
|
||||
@@ -2264,7 +2295,7 @@ namespace FourSlash {
|
||||
function runCode(code: string, state: TestState): void {
|
||||
// Compile and execute the test
|
||||
const wrappedCode =
|
||||
`(function(test, goTo, verify, edit, debug, format, cancellation, classification, verifyOperationIsCancelled) {
|
||||
`(function(test, goTo, verify, edit, debug, format, cancellation, classification, verifyOperationIsCancelled) {
|
||||
${code}
|
||||
})`;
|
||||
try {
|
||||
@@ -2378,7 +2409,7 @@ ${code}
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: should be '==='?
|
||||
// TODO: should be '==='?
|
||||
}
|
||||
else if (line == "" || lineLength === 0) {
|
||||
// Previously blank lines between fourslash content caused it to be considered as 2 files,
|
||||
@@ -2759,10 +2790,10 @@ namespace FourSlashInterface {
|
||||
// Opens a file, given either its index as it
|
||||
// appears in the test source, or its filename
|
||||
// as specified in the test metadata
|
||||
public file(index: number, content?: string): void;
|
||||
public file(name: string, content?: string): void;
|
||||
public file(indexOrName: any, content?: string): void {
|
||||
this.state.openFile(indexOrName, content);
|
||||
public file(index: number, content?: string, scriptKindName?: string): void;
|
||||
public file(name: string, content?: string, scriptKindName?: string): void;
|
||||
public file(indexOrName: any, content?: string, scriptKindName?: string): void {
|
||||
this.state.openFile(indexOrName, content, scriptKindName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2870,6 +2901,10 @@ namespace FourSlashInterface {
|
||||
public verifyDefinitionsName(name: string, containerName: string) {
|
||||
this.state.verifyDefinitionsName(this.negative, name, containerName);
|
||||
}
|
||||
|
||||
public isValidBraceCompletionAtPostion(openingBrace: string) {
|
||||
this.state.verifyBraceCompletionAtPostion(this.negative, openingBrace);
|
||||
}
|
||||
}
|
||||
|
||||
export class Verify extends VerifyNegatable {
|
||||
@@ -3088,7 +3123,7 @@ namespace FourSlashInterface {
|
||||
this.state.getSemanticDiagnostics(expected);
|
||||
}
|
||||
|
||||
public ProjectInfo(expected: string []) {
|
||||
public ProjectInfo(expected: string[]) {
|
||||
this.state.verifyProjectInfo(expected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ namespace Harness.LanguageService {
|
||||
throw new Error("No script with name '" + fileName + "'");
|
||||
}
|
||||
|
||||
public openFile(fileName: string, content?: string): void {
|
||||
public openFile(fileName: string, content?: string, scriptKindName?: string): void {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -437,6 +437,9 @@ namespace Harness.LanguageService {
|
||||
getDocCommentTemplateAtPosition(fileName: string, position: number): ts.TextInsertion {
|
||||
return unwrapJSONCallResult(this.shim.getDocCommentTemplateAtPosition(fileName, position));
|
||||
}
|
||||
isValidBraceCompletionAtPostion(fileName: string, position: number, openingBrace: number): boolean {
|
||||
return unwrapJSONCallResult(this.shim.isValidBraceCompletionAtPostion(fileName, position, openingBrace));
|
||||
}
|
||||
getEmitOutput(fileName: string): ts.EmitOutput {
|
||||
return unwrapJSONCallResult(this.shim.getEmitOutput(fileName));
|
||||
}
|
||||
@@ -525,9 +528,9 @@ namespace Harness.LanguageService {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
openFile(fileName: string, content?: string): void {
|
||||
super.openFile(fileName, content);
|
||||
this.client.openFile(fileName, content);
|
||||
openFile(fileName: string, content?: string, scriptKindName?: "TS" | "JS" | "TSX" | "JSX"): void {
|
||||
super.openFile(fileName, content, scriptKindName);
|
||||
this.client.openFile(fileName, content, scriptKindName);
|
||||
}
|
||||
|
||||
editScript(fileName: string, start: number, end: number, newText: string) {
|
||||
|
||||
@@ -149,7 +149,7 @@ namespace Playback {
|
||||
recordLog = createEmptyLog();
|
||||
|
||||
if (typeof underlying.args !== "function") {
|
||||
recordLog.arguments = <string[]>underlying.args;
|
||||
recordLog.arguments = underlying.args;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -190,8 +190,9 @@ namespace RWC {
|
||||
if (compilerResult.errors.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Harness.Compiler.getErrorBaseline(inputFiles.concat(otherFiles), compilerResult.errors);
|
||||
// Do not include the library in the baselines to avoid noise
|
||||
const baselineFiles = inputFiles.concat(otherFiles).filter(f => !Harness.isDefaultLibraryFile(f.unitName));
|
||||
return Harness.Compiler.getErrorBaseline(baselineFiles, compilerResult.errors);
|
||||
}, false, baselineOpts);
|
||||
});
|
||||
|
||||
|
||||
Vendored
+11
-11
@@ -1064,7 +1064,7 @@ interface ReadonlyArray<T> {
|
||||
* @param callbackfn A function that accepts up to three arguments. The filter method calls the callbackfn function one time for each element in the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
filter(callbackfn: (value: T, index: number, array: ReadonlyArray<T>) => boolean, thisArg?: any): T[];
|
||||
filter(callbackfn: (value: T, index: number, array: ReadonlyArray<T>) => any, thisArg?: any): T[];
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.
|
||||
@@ -1199,7 +1199,7 @@ interface Array<T> {
|
||||
* @param callbackfn A function that accepts up to three arguments. The filter method calls the callbackfn function one time for each element in the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
filter(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): T[];
|
||||
filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[];
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.
|
||||
@@ -1511,7 +1511,7 @@ interface Int8Array {
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
filter(callbackfn: (value: number, index: number, array: Int8Array) => boolean, thisArg?: any): Int8Array;
|
||||
filter(callbackfn: (value: number, index: number, array: Int8Array) => any, thisArg?: any): Int8Array;
|
||||
|
||||
/**
|
||||
* Returns the value of the first element in the array where predicate is true, and undefined
|
||||
@@ -1784,7 +1784,7 @@ interface Uint8Array {
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
filter(callbackfn: (value: number, index: number, array: Uint8Array) => boolean, thisArg?: any): Uint8Array;
|
||||
filter(callbackfn: (value: number, index: number, array: Uint8Array) => any, thisArg?: any): Uint8Array;
|
||||
|
||||
/**
|
||||
* Returns the value of the first element in the array where predicate is true, and undefined
|
||||
@@ -2058,7 +2058,7 @@ interface Uint8ClampedArray {
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
filter(callbackfn: (value: number, index: number, array: Uint8ClampedArray) => boolean, thisArg?: any): Uint8ClampedArray;
|
||||
filter(callbackfn: (value: number, index: number, array: Uint8ClampedArray) => any, thisArg?: any): Uint8ClampedArray;
|
||||
|
||||
/**
|
||||
* Returns the value of the first element in the array where predicate is true, and undefined
|
||||
@@ -2331,7 +2331,7 @@ interface Int16Array {
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
filter(callbackfn: (value: number, index: number, array: Int16Array) => boolean, thisArg?: any): Int16Array;
|
||||
filter(callbackfn: (value: number, index: number, array: Int16Array) => any, thisArg?: any): Int16Array;
|
||||
|
||||
/**
|
||||
* Returns the value of the first element in the array where predicate is true, and undefined
|
||||
@@ -2605,7 +2605,7 @@ interface Uint16Array {
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
filter(callbackfn: (value: number, index: number, array: Uint16Array) => boolean, thisArg?: any): Uint16Array;
|
||||
filter(callbackfn: (value: number, index: number, array: Uint16Array) => any, thisArg?: any): Uint16Array;
|
||||
|
||||
/**
|
||||
* Returns the value of the first element in the array where predicate is true, and undefined
|
||||
@@ -2878,7 +2878,7 @@ interface Int32Array {
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
filter(callbackfn: (value: number, index: number, array: Int32Array) => boolean, thisArg?: any): Int32Array;
|
||||
filter(callbackfn: (value: number, index: number, array: Int32Array) => any, thisArg?: any): Int32Array;
|
||||
|
||||
/**
|
||||
* Returns the value of the first element in the array where predicate is true, and undefined
|
||||
@@ -3151,7 +3151,7 @@ interface Uint32Array {
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
filter(callbackfn: (value: number, index: number, array: Uint32Array) => boolean, thisArg?: any): Uint32Array;
|
||||
filter(callbackfn: (value: number, index: number, array: Uint32Array) => any, thisArg?: any): Uint32Array;
|
||||
|
||||
/**
|
||||
* Returns the value of the first element in the array where predicate is true, and undefined
|
||||
@@ -3424,7 +3424,7 @@ interface Float32Array {
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
filter(callbackfn: (value: number, index: number, array: Float32Array) => boolean, thisArg?: any): Float32Array;
|
||||
filter(callbackfn: (value: number, index: number, array: Float32Array) => any, thisArg?: any): Float32Array;
|
||||
|
||||
/**
|
||||
* Returns the value of the first element in the array where predicate is true, and undefined
|
||||
@@ -3698,7 +3698,7 @@ interface Float64Array {
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
filter(callbackfn: (value: number, index: number, array: Float64Array) => boolean, thisArg?: any): Float64Array;
|
||||
filter(callbackfn: (value: number, index: number, array: Float64Array) => any, thisArg?: any): Float64Array;
|
||||
|
||||
/**
|
||||
* Returns the value of the first element in the array where predicate is true, and undefined
|
||||
|
||||
@@ -120,8 +120,8 @@ namespace ts.server {
|
||||
return response;
|
||||
}
|
||||
|
||||
openFile(fileName: string, content?: string): void {
|
||||
var args: protocol.OpenRequestArgs = { file: fileName, fileContent: content };
|
||||
openFile(fileName: string, content?: string, scriptKindName?: "TS" | "JS" | "TSX" | "JSX"): void {
|
||||
var args: protocol.OpenRequestArgs = { file: fileName, fileContent: content, scriptKindName };
|
||||
this.processRequest(CommandNames.Open, args);
|
||||
}
|
||||
|
||||
@@ -568,6 +568,10 @@ namespace ts.server {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
}
|
||||
|
||||
isValidBraceCompletionAtPostion(fileName: string, position: number, openingBrace: number): boolean {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
}
|
||||
|
||||
getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[] {
|
||||
var lineOffset = this.positionToOneBasedLineOffset(fileName, position);
|
||||
var args: protocol.FileLocationRequestArgs = {
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace ts.server {
|
||||
fileWatcher: FileWatcher;
|
||||
formatCodeOptions = ts.clone(CompilerService.defaultFormatCodeOptions);
|
||||
path: Path;
|
||||
scriptKind: ScriptKind;
|
||||
|
||||
constructor(private host: ServerHost, public fileName: string, public content: string, public isOpen = false) {
|
||||
this.path = toPath(fileName, host.getCurrentDirectory(), createGetCanonicalFileName(host.useCaseSensitiveFileNames));
|
||||
@@ -215,8 +216,16 @@ namespace ts.server {
|
||||
return this.roots.map(root => root.fileName);
|
||||
}
|
||||
|
||||
getScriptKind() {
|
||||
return ScriptKind.Unknown;
|
||||
getScriptKind(fileName: string) {
|
||||
const info = this.getScriptInfo(fileName);
|
||||
if (!info) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (!info.scriptKind) {
|
||||
info.scriptKind = getScriptKindFromFileName(fileName);
|
||||
}
|
||||
return info.scriptKind;
|
||||
}
|
||||
|
||||
getScriptVersion(filename: string) {
|
||||
@@ -489,6 +498,14 @@ namespace ts.server {
|
||||
return copiedList;
|
||||
}
|
||||
|
||||
/**
|
||||
* This helper funciton processes a list of projects and return the concatenated, sortd and deduplicated output of processing each project.
|
||||
*/
|
||||
export function combineProjectOutput<T>(projects: Project[], action: (project: Project) => T[], comparer?: (a: T, b: T) => number, areEqual?: (a: T, b: T) => boolean) {
|
||||
const result = projects.reduce<T[]>((previous, current) => concatenate(previous, action(current)), []).sort(comparer);
|
||||
return projects.length > 1 ? deduplicate(result, areEqual) : result;
|
||||
}
|
||||
|
||||
export interface ProjectServiceEventHandler {
|
||||
(eventName: string, project: Project, fileName: string): void;
|
||||
}
|
||||
@@ -1013,7 +1030,7 @@ namespace ts.server {
|
||||
* @param filename is absolute pathname
|
||||
* @param fileContent is a known version of the file content that is more up to date than the one on disk
|
||||
*/
|
||||
openFile(fileName: string, openedByClient: boolean, fileContent?: string) {
|
||||
openFile(fileName: string, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind) {
|
||||
fileName = ts.normalizePath(fileName);
|
||||
let info = ts.lookUp(this.filenameToScriptInfo, fileName);
|
||||
if (!info) {
|
||||
@@ -1028,6 +1045,7 @@ namespace ts.server {
|
||||
}
|
||||
if (content !== undefined) {
|
||||
info = new ScriptInfo(this.host, fileName, content, openedByClient);
|
||||
info.scriptKind = scriptKind;
|
||||
info.setFormatOptions(this.getFormatCodeOptions());
|
||||
this.filenameToScriptInfo[fileName] = info;
|
||||
if (!info.isOpen) {
|
||||
@@ -1077,9 +1095,9 @@ namespace ts.server {
|
||||
* @param filename is absolute pathname
|
||||
* @param fileContent is a known version of the file content that is more up to date than the one on disk
|
||||
*/
|
||||
openClientFile(fileName: string, fileContent?: string) {
|
||||
openClientFile(fileName: string, fileContent?: string, scriptKind?: ScriptKind) {
|
||||
this.openOrUpdateConfiguredProjectForFile(fileName);
|
||||
const info = this.openFile(fileName, /*openedByClient*/ true, fileContent);
|
||||
const info = this.openFile(fileName, /*openedByClient*/ true, fileContent, scriptKind);
|
||||
this.addOpenFile(info);
|
||||
this.printProjects();
|
||||
return info;
|
||||
|
||||
Vendored
+5
@@ -518,6 +518,11 @@ declare namespace ts.server.protocol {
|
||||
* Then the known content will be used upon opening instead of the disk copy
|
||||
*/
|
||||
fileContent?: string;
|
||||
/**
|
||||
* Used to specify the script kind of the file explicitly. It could be one of the following:
|
||||
* "TS", "JS", "TSX", "JSX"
|
||||
*/
|
||||
scriptKindName?: "TS" | "JS" | "TSX" | "JSX";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+193
-127
@@ -141,8 +141,8 @@ namespace ts.server {
|
||||
) {
|
||||
this.projectService =
|
||||
new ProjectService(host, logger, (eventName, project, fileName) => {
|
||||
this.handleEvent(eventName, project, fileName);
|
||||
});
|
||||
this.handleEvent(eventName, project, fileName);
|
||||
});
|
||||
}
|
||||
|
||||
private handleEvent(eventName: string, project: Project, fileName: string) {
|
||||
@@ -412,14 +412,17 @@ namespace ts.server {
|
||||
|
||||
private getRenameLocations(line: number, offset: number, fileName: string, findInComments: boolean, findInStrings: boolean): protocol.RenameResponseBody {
|
||||
const file = ts.normalizePath(fileName);
|
||||
const project = this.projectService.getProjectForFile(file);
|
||||
if (!project) {
|
||||
const info = this.projectService.getScriptInfo(file);
|
||||
const projects = this.projectService.findReferencingProjects(info);
|
||||
if (!projects.length) {
|
||||
throw Errors.NoProject;
|
||||
}
|
||||
|
||||
const compilerService = project.compilerService;
|
||||
const position = compilerService.host.lineOffsetToPosition(file, line, offset);
|
||||
const renameInfo = compilerService.languageService.getRenameInfo(file, position);
|
||||
const defaultProject = projects[0];
|
||||
// The rename info should be the same for every project
|
||||
const defaultProjectCompilerService = defaultProject.compilerService;
|
||||
const position = defaultProjectCompilerService.host.lineOffsetToPosition(file, line, offset);
|
||||
const renameInfo = defaultProjectCompilerService.languageService.getRenameInfo(file, position);
|
||||
if (!renameInfo) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -431,16 +434,43 @@ namespace ts.server {
|
||||
};
|
||||
}
|
||||
|
||||
const renameLocations = compilerService.languageService.findRenameLocations(file, position, findInStrings, findInComments);
|
||||
if (!renameLocations) {
|
||||
return undefined;
|
||||
}
|
||||
const fileSpans = combineProjectOutput(
|
||||
projects,
|
||||
(project: Project) => {
|
||||
const compilerService = project.compilerService;
|
||||
const renameLocations = compilerService.languageService.findRenameLocations(file, position, findInStrings, findInComments);
|
||||
if (!renameLocations) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const bakedRenameLocs = renameLocations.map(location => (<protocol.FileSpan>{
|
||||
file: location.fileName,
|
||||
start: compilerService.host.positionToLineOffset(location.fileName, location.textSpan.start),
|
||||
end: compilerService.host.positionToLineOffset(location.fileName, ts.textSpanEnd(location.textSpan)),
|
||||
})).sort((a, b) => {
|
||||
return renameLocations.map(location => (<protocol.FileSpan>{
|
||||
file: location.fileName,
|
||||
start: compilerService.host.positionToLineOffset(location.fileName, location.textSpan.start),
|
||||
end: compilerService.host.positionToLineOffset(location.fileName, ts.textSpanEnd(location.textSpan)),
|
||||
}));
|
||||
},
|
||||
compareRenameLocation,
|
||||
(a, b) => a.file === b.file && a.start.line === b.start.line && a.start.offset === b.start.offset
|
||||
);
|
||||
const locs = fileSpans.reduce<protocol.SpanGroup[]>((accum, cur) => {
|
||||
let curFileAccum: protocol.SpanGroup;
|
||||
if (accum.length > 0) {
|
||||
curFileAccum = accum[accum.length - 1];
|
||||
if (curFileAccum.file !== cur.file) {
|
||||
curFileAccum = undefined;
|
||||
}
|
||||
}
|
||||
if (!curFileAccum) {
|
||||
curFileAccum = { file: cur.file, locs: [] };
|
||||
accum.push(curFileAccum);
|
||||
}
|
||||
curFileAccum.locs.push({ start: cur.start, end: cur.end });
|
||||
return accum;
|
||||
}, []);
|
||||
|
||||
return { info: renameInfo, locs };
|
||||
|
||||
function compareRenameLocation(a: protocol.FileSpan, b: protocol.FileSpan) {
|
||||
if (a.file < b.file) {
|
||||
return -1;
|
||||
}
|
||||
@@ -459,79 +489,79 @@ namespace ts.server {
|
||||
return b.start.offset - a.start.offset;
|
||||
}
|
||||
}
|
||||
}).reduce<protocol.SpanGroup[]>((accum: protocol.SpanGroup[], cur: protocol.FileSpan) => {
|
||||
let curFileAccum: protocol.SpanGroup;
|
||||
if (accum.length > 0) {
|
||||
curFileAccum = accum[accum.length - 1];
|
||||
if (curFileAccum.file != cur.file) {
|
||||
curFileAccum = undefined;
|
||||
}
|
||||
}
|
||||
if (!curFileAccum) {
|
||||
curFileAccum = { file: cur.file, locs: [] };
|
||||
accum.push(curFileAccum);
|
||||
}
|
||||
curFileAccum.locs.push({ start: cur.start, end: cur.end });
|
||||
return accum;
|
||||
}, []);
|
||||
|
||||
return { info: renameInfo, locs: bakedRenameLocs };
|
||||
}
|
||||
}
|
||||
|
||||
private getReferences(line: number, offset: number, fileName: string): protocol.ReferencesResponseBody {
|
||||
// TODO: get all projects for this file; report refs for all projects deleting duplicates
|
||||
// can avoid duplicates by eliminating same ref file from subsequent projects
|
||||
const file = ts.normalizePath(fileName);
|
||||
const project = this.projectService.getProjectForFile(file);
|
||||
if (!project) {
|
||||
const info = this.projectService.getScriptInfo(file);
|
||||
const projects = this.projectService.findReferencingProjects(info);
|
||||
if (!projects.length) {
|
||||
throw Errors.NoProject;
|
||||
}
|
||||
|
||||
const compilerService = project.compilerService;
|
||||
const position = compilerService.host.lineOffsetToPosition(file, line, offset);
|
||||
|
||||
const references = compilerService.languageService.getReferencesAtPosition(file, position);
|
||||
if (!references) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const nameInfo = compilerService.languageService.getQuickInfoAtPosition(file, position);
|
||||
const defaultProject = projects[0];
|
||||
const position = defaultProject.compilerService.host.lineOffsetToPosition(file, line, offset);
|
||||
const nameInfo = defaultProject.compilerService.languageService.getQuickInfoAtPosition(file, position);
|
||||
if (!nameInfo) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const displayString = ts.displayPartsToString(nameInfo.displayParts);
|
||||
const nameSpan = nameInfo.textSpan;
|
||||
const nameColStart = compilerService.host.positionToLineOffset(file, nameSpan.start).offset;
|
||||
const nameText = compilerService.host.getScriptSnapshot(file).getText(nameSpan.start, ts.textSpanEnd(nameSpan));
|
||||
const bakedRefs: protocol.ReferencesResponseItem[] = references.map(ref => {
|
||||
const start = compilerService.host.positionToLineOffset(ref.fileName, ref.textSpan.start);
|
||||
const refLineSpan = compilerService.host.lineToTextSpan(ref.fileName, start.line - 1);
|
||||
const snap = compilerService.host.getScriptSnapshot(ref.fileName);
|
||||
const lineText = snap.getText(refLineSpan.start, ts.textSpanEnd(refLineSpan)).replace(/\r|\n/g, "");
|
||||
return {
|
||||
file: ref.fileName,
|
||||
start: start,
|
||||
lineText: lineText,
|
||||
end: compilerService.host.positionToLineOffset(ref.fileName, ts.textSpanEnd(ref.textSpan)),
|
||||
isWriteAccess: ref.isWriteAccess
|
||||
};
|
||||
}).sort(compareFileStart);
|
||||
const nameColStart = defaultProject.compilerService.host.positionToLineOffset(file, nameSpan.start).offset;
|
||||
const nameText = defaultProject.compilerService.host.getScriptSnapshot(file).getText(nameSpan.start, ts.textSpanEnd(nameSpan));
|
||||
const refs = combineProjectOutput<protocol.ReferencesResponseItem>(
|
||||
projects,
|
||||
(project: Project) => {
|
||||
const compilerService = project.compilerService;
|
||||
const references = compilerService.languageService.getReferencesAtPosition(file, position);
|
||||
if (!references) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return references.map(ref => {
|
||||
const start = compilerService.host.positionToLineOffset(ref.fileName, ref.textSpan.start);
|
||||
const refLineSpan = compilerService.host.lineToTextSpan(ref.fileName, start.line - 1);
|
||||
const snap = compilerService.host.getScriptSnapshot(ref.fileName);
|
||||
const lineText = snap.getText(refLineSpan.start, ts.textSpanEnd(refLineSpan)).replace(/\r|\n/g, "");
|
||||
return {
|
||||
file: ref.fileName,
|
||||
start: start,
|
||||
lineText: lineText,
|
||||
end: compilerService.host.positionToLineOffset(ref.fileName, ts.textSpanEnd(ref.textSpan)),
|
||||
isWriteAccess: ref.isWriteAccess
|
||||
};
|
||||
});
|
||||
},
|
||||
compareFileStart,
|
||||
areReferencesResponseItemsForTheSameLocation
|
||||
);
|
||||
|
||||
return {
|
||||
refs: bakedRefs,
|
||||
refs,
|
||||
symbolName: nameText,
|
||||
symbolStartOffset: nameColStart,
|
||||
symbolDisplayString: displayString
|
||||
};
|
||||
|
||||
function areReferencesResponseItemsForTheSameLocation(a: protocol.ReferencesResponseItem, b: protocol.ReferencesResponseItem) {
|
||||
if (a && b) {
|
||||
return a.file === b.file &&
|
||||
a.start === b.start &&
|
||||
a.end === b.end;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fileName is the name of the file to be opened
|
||||
* @param fileContent is a version of the file content that is known to be more up to date than the one on disk
|
||||
*/
|
||||
private openClientFile(fileName: string, fileContent?: string) {
|
||||
private openClientFile(fileName: string, fileContent?: string, scriptKind?: ScriptKind) {
|
||||
const file = ts.normalizePath(fileName);
|
||||
this.projectService.openClientFile(file, fileContent);
|
||||
this.projectService.openClientFile(file, fileContent, scriptKind);
|
||||
}
|
||||
|
||||
private getQuickInfo(line: number, offset: number, fileName: string): protocol.QuickInfoResponseBody {
|
||||
@@ -836,41 +866,60 @@ namespace ts.server {
|
||||
|
||||
private getNavigateToItems(searchValue: string, fileName: string, maxResultCount?: number): protocol.NavtoItem[] {
|
||||
const file = ts.normalizePath(fileName);
|
||||
const project = this.projectService.getProjectForFile(file);
|
||||
if (!project) {
|
||||
const info = this.projectService.getScriptInfo(file);
|
||||
const projects = this.projectService.findReferencingProjects(info);
|
||||
const defaultProject = projects[0];
|
||||
if (!defaultProject) {
|
||||
throw Errors.NoProject;
|
||||
}
|
||||
|
||||
const compilerService = project.compilerService;
|
||||
const navItems = compilerService.languageService.getNavigateToItems(searchValue, maxResultCount);
|
||||
if (!navItems) {
|
||||
return undefined;
|
||||
}
|
||||
const allNavToItems = combineProjectOutput(
|
||||
projects,
|
||||
(project: Project) => {
|
||||
const compilerService = project.compilerService;
|
||||
const navItems = compilerService.languageService.getNavigateToItems(searchValue, maxResultCount);
|
||||
if (!navItems) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return navItems.map((navItem) => {
|
||||
const start = compilerService.host.positionToLineOffset(navItem.fileName, navItem.textSpan.start);
|
||||
const end = compilerService.host.positionToLineOffset(navItem.fileName, ts.textSpanEnd(navItem.textSpan));
|
||||
const bakedItem: protocol.NavtoItem = {
|
||||
name: navItem.name,
|
||||
kind: navItem.kind,
|
||||
file: navItem.fileName,
|
||||
start: start,
|
||||
end: end,
|
||||
};
|
||||
if (navItem.kindModifiers && (navItem.kindModifiers != "")) {
|
||||
bakedItem.kindModifiers = navItem.kindModifiers;
|
||||
return navItems.map((navItem) => {
|
||||
const start = compilerService.host.positionToLineOffset(navItem.fileName, navItem.textSpan.start);
|
||||
const end = compilerService.host.positionToLineOffset(navItem.fileName, ts.textSpanEnd(navItem.textSpan));
|
||||
const bakedItem: protocol.NavtoItem = {
|
||||
name: navItem.name,
|
||||
kind: navItem.kind,
|
||||
file: navItem.fileName,
|
||||
start: start,
|
||||
end: end,
|
||||
};
|
||||
if (navItem.kindModifiers && (navItem.kindModifiers !== "")) {
|
||||
bakedItem.kindModifiers = navItem.kindModifiers;
|
||||
}
|
||||
if (navItem.matchKind !== "none") {
|
||||
bakedItem.matchKind = navItem.matchKind;
|
||||
}
|
||||
if (navItem.containerName && (navItem.containerName.length > 0)) {
|
||||
bakedItem.containerName = navItem.containerName;
|
||||
}
|
||||
if (navItem.containerKind && (navItem.containerKind.length > 0)) {
|
||||
bakedItem.containerKind = navItem.containerKind;
|
||||
}
|
||||
return bakedItem;
|
||||
});
|
||||
},
|
||||
/*comparer*/ undefined,
|
||||
areNavToItemsForTheSameLocation
|
||||
);
|
||||
return allNavToItems;
|
||||
|
||||
function areNavToItemsForTheSameLocation(a: protocol.NavtoItem, b: protocol.NavtoItem) {
|
||||
if (a && b) {
|
||||
return a.file === b.file &&
|
||||
a.start === b.start &&
|
||||
a.end === b.end;
|
||||
}
|
||||
if (navItem.matchKind !== "none") {
|
||||
bakedItem.matchKind = navItem.matchKind;
|
||||
}
|
||||
if (navItem.containerName && (navItem.containerName.length > 0)) {
|
||||
bakedItem.containerName = navItem.containerName;
|
||||
}
|
||||
if (navItem.containerKind && (navItem.containerKind.length > 0)) {
|
||||
bakedItem.containerKind = navItem.containerKind;
|
||||
}
|
||||
return bakedItem;
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private getBraceMatching(line: number, offset: number, fileName: string): protocol.TextSpan[] {
|
||||
@@ -944,129 +993,146 @@ namespace ts.server {
|
||||
exit() {
|
||||
}
|
||||
|
||||
private handlers: Map<(request: protocol.Request) => {response?: any, responseRequired?: boolean}> = {
|
||||
private handlers: Map<(request: protocol.Request) => { response?: any, responseRequired?: boolean }> = {
|
||||
[CommandNames.Exit]: () => {
|
||||
this.exit();
|
||||
return { responseRequired: false};
|
||||
return { responseRequired: false };
|
||||
},
|
||||
[CommandNames.Definition]: (request: protocol.Request) => {
|
||||
const defArgs = <protocol.FileLocationRequestArgs>request.arguments;
|
||||
return {response: this.getDefinition(defArgs.line, defArgs.offset, defArgs.file), responseRequired: true};
|
||||
return { response: this.getDefinition(defArgs.line, defArgs.offset, defArgs.file), responseRequired: true };
|
||||
},
|
||||
[CommandNames.TypeDefinition]: (request: protocol.Request) => {
|
||||
const defArgs = <protocol.FileLocationRequestArgs>request.arguments;
|
||||
return {response: this.getTypeDefinition(defArgs.line, defArgs.offset, defArgs.file), responseRequired: true};
|
||||
return { response: this.getTypeDefinition(defArgs.line, defArgs.offset, defArgs.file), responseRequired: true };
|
||||
},
|
||||
[CommandNames.References]: (request: protocol.Request) => {
|
||||
const defArgs = <protocol.FileLocationRequestArgs>request.arguments;
|
||||
return {response: this.getReferences(defArgs.line, defArgs.offset, defArgs.file), responseRequired: true};
|
||||
return { response: this.getReferences(defArgs.line, defArgs.offset, defArgs.file), responseRequired: true };
|
||||
},
|
||||
[CommandNames.Rename]: (request: protocol.Request) => {
|
||||
const renameArgs = <protocol.RenameRequestArgs>request.arguments;
|
||||
return {response: this.getRenameLocations(renameArgs.line, renameArgs.offset, renameArgs.file, renameArgs.findInComments, renameArgs.findInStrings), responseRequired: true};
|
||||
return { response: this.getRenameLocations(renameArgs.line, renameArgs.offset, renameArgs.file, renameArgs.findInComments, renameArgs.findInStrings), responseRequired: true };
|
||||
},
|
||||
[CommandNames.Open]: (request: protocol.Request) => {
|
||||
const openArgs = <protocol.OpenRequestArgs>request.arguments;
|
||||
this.openClientFile(openArgs.file, openArgs.fileContent);
|
||||
return {responseRequired: false};
|
||||
let scriptKind: ScriptKind;
|
||||
switch (openArgs.scriptKindName) {
|
||||
case "TS":
|
||||
scriptKind = ScriptKind.TS;
|
||||
break;
|
||||
case "JS":
|
||||
scriptKind = ScriptKind.JS;
|
||||
break;
|
||||
case "TSX":
|
||||
scriptKind = ScriptKind.TSX;
|
||||
break;
|
||||
case "JSX":
|
||||
scriptKind = ScriptKind.JSX;
|
||||
break;
|
||||
}
|
||||
this.openClientFile(openArgs.file, openArgs.fileContent, scriptKind);
|
||||
return { responseRequired: false };
|
||||
},
|
||||
[CommandNames.Quickinfo]: (request: protocol.Request) => {
|
||||
const quickinfoArgs = <protocol.FileLocationRequestArgs>request.arguments;
|
||||
return {response: this.getQuickInfo(quickinfoArgs.line, quickinfoArgs.offset, quickinfoArgs.file), responseRequired: true};
|
||||
return { response: this.getQuickInfo(quickinfoArgs.line, quickinfoArgs.offset, quickinfoArgs.file), responseRequired: true };
|
||||
},
|
||||
[CommandNames.Format]: (request: protocol.Request) => {
|
||||
const formatArgs = <protocol.FormatRequestArgs>request.arguments;
|
||||
return {response: this.getFormattingEditsForRange(formatArgs.line, formatArgs.offset, formatArgs.endLine, formatArgs.endOffset, formatArgs.file), responseRequired: true};
|
||||
return { response: this.getFormattingEditsForRange(formatArgs.line, formatArgs.offset, formatArgs.endLine, formatArgs.endOffset, formatArgs.file), responseRequired: true };
|
||||
},
|
||||
[CommandNames.Formatonkey]: (request: protocol.Request) => {
|
||||
const formatOnKeyArgs = <protocol.FormatOnKeyRequestArgs>request.arguments;
|
||||
return {response: this.getFormattingEditsAfterKeystroke(formatOnKeyArgs.line, formatOnKeyArgs.offset, formatOnKeyArgs.key, formatOnKeyArgs.file), responseRequired: true};
|
||||
return { response: this.getFormattingEditsAfterKeystroke(formatOnKeyArgs.line, formatOnKeyArgs.offset, formatOnKeyArgs.key, formatOnKeyArgs.file), responseRequired: true };
|
||||
},
|
||||
[CommandNames.Completions]: (request: protocol.Request) => {
|
||||
const completionsArgs = <protocol.CompletionsRequestArgs>request.arguments;
|
||||
return {response: this.getCompletions(completionsArgs.line, completionsArgs.offset, completionsArgs.prefix, completionsArgs.file), responseRequired: true};
|
||||
return { response: this.getCompletions(completionsArgs.line, completionsArgs.offset, completionsArgs.prefix, completionsArgs.file), responseRequired: true };
|
||||
},
|
||||
[CommandNames.CompletionDetails]: (request: protocol.Request) => {
|
||||
const completionDetailsArgs = <protocol.CompletionDetailsRequestArgs>request.arguments;
|
||||
return {response: this.getCompletionEntryDetails(completionDetailsArgs.line, completionDetailsArgs.offset,
|
||||
completionDetailsArgs.entryNames, completionDetailsArgs.file), responseRequired: true};
|
||||
return {
|
||||
response: this.getCompletionEntryDetails(completionDetailsArgs.line, completionDetailsArgs.offset,
|
||||
completionDetailsArgs.entryNames, completionDetailsArgs.file), responseRequired: true
|
||||
};
|
||||
},
|
||||
[CommandNames.SignatureHelp]: (request: protocol.Request) => {
|
||||
const signatureHelpArgs = <protocol.SignatureHelpRequestArgs>request.arguments;
|
||||
return {response: this.getSignatureHelpItems(signatureHelpArgs.line, signatureHelpArgs.offset, signatureHelpArgs.file), responseRequired: true};
|
||||
return { response: this.getSignatureHelpItems(signatureHelpArgs.line, signatureHelpArgs.offset, signatureHelpArgs.file), responseRequired: true };
|
||||
},
|
||||
[CommandNames.Geterr]: (request: protocol.Request) => {
|
||||
const geterrArgs = <protocol.GeterrRequestArgs>request.arguments;
|
||||
return {response: this.getDiagnostics(geterrArgs.delay, geterrArgs.files), responseRequired: false};
|
||||
return { response: this.getDiagnostics(geterrArgs.delay, geterrArgs.files), responseRequired: false };
|
||||
},
|
||||
[CommandNames.GeterrForProject]: (request: protocol.Request) => {
|
||||
const { file, delay } = <protocol.GeterrForProjectRequestArgs>request.arguments;
|
||||
return {response: this.getDiagnosticsForProject(delay, file), responseRequired: false};
|
||||
return { response: this.getDiagnosticsForProject(delay, file), responseRequired: false };
|
||||
},
|
||||
[CommandNames.Change]: (request: protocol.Request) => {
|
||||
const changeArgs = <protocol.ChangeRequestArgs>request.arguments;
|
||||
this.change(changeArgs.line, changeArgs.offset, changeArgs.endLine, changeArgs.endOffset,
|
||||
changeArgs.insertString, changeArgs.file);
|
||||
return {responseRequired: false};
|
||||
changeArgs.insertString, changeArgs.file);
|
||||
return { responseRequired: false };
|
||||
},
|
||||
[CommandNames.Configure]: (request: protocol.Request) => {
|
||||
const configureArgs = <protocol.ConfigureRequestArguments>request.arguments;
|
||||
this.projectService.setHostConfiguration(configureArgs);
|
||||
this.output(undefined, CommandNames.Configure, request.seq);
|
||||
return {responseRequired: false};
|
||||
return { responseRequired: false };
|
||||
},
|
||||
[CommandNames.Reload]: (request: protocol.Request) => {
|
||||
const reloadArgs = <protocol.ReloadRequestArgs>request.arguments;
|
||||
this.reload(reloadArgs.file, reloadArgs.tmpfile, request.seq);
|
||||
return {responseRequired: false};
|
||||
return {response: { reloadFinished: true }, responseRequired: true};
|
||||
},
|
||||
[CommandNames.Saveto]: (request: protocol.Request) => {
|
||||
const savetoArgs = <protocol.SavetoRequestArgs>request.arguments;
|
||||
this.saveToTmp(savetoArgs.file, savetoArgs.tmpfile);
|
||||
return {responseRequired: false};
|
||||
return { responseRequired: false };
|
||||
},
|
||||
[CommandNames.Close]: (request: protocol.Request) => {
|
||||
const closeArgs = <protocol.FileRequestArgs>request.arguments;
|
||||
this.closeClientFile(closeArgs.file);
|
||||
return {responseRequired: false};
|
||||
return { responseRequired: false };
|
||||
},
|
||||
[CommandNames.Navto]: (request: protocol.Request) => {
|
||||
const navtoArgs = <protocol.NavtoRequestArgs>request.arguments;
|
||||
return {response: this.getNavigateToItems(navtoArgs.searchValue, navtoArgs.file, navtoArgs.maxResultCount), responseRequired: true};
|
||||
return { response: this.getNavigateToItems(navtoArgs.searchValue, navtoArgs.file, navtoArgs.maxResultCount), responseRequired: true };
|
||||
},
|
||||
[CommandNames.Brace]: (request: protocol.Request) => {
|
||||
const braceArguments = <protocol.FileLocationRequestArgs>request.arguments;
|
||||
return {response: this.getBraceMatching(braceArguments.line, braceArguments.offset, braceArguments.file), responseRequired: true};
|
||||
return { response: this.getBraceMatching(braceArguments.line, braceArguments.offset, braceArguments.file), responseRequired: true };
|
||||
},
|
||||
[CommandNames.NavBar]: (request: protocol.Request) => {
|
||||
const navBarArgs = <protocol.FileRequestArgs>request.arguments;
|
||||
return {response: this.getNavigationBarItems(navBarArgs.file), responseRequired: true};
|
||||
return { response: this.getNavigationBarItems(navBarArgs.file), responseRequired: true };
|
||||
},
|
||||
[CommandNames.Occurrences]: (request: protocol.Request) => {
|
||||
const { line, offset, file: fileName } = <protocol.FileLocationRequestArgs>request.arguments;
|
||||
return {response: this.getOccurrences(line, offset, fileName), responseRequired: true};
|
||||
return { response: this.getOccurrences(line, offset, fileName), responseRequired: true };
|
||||
},
|
||||
[CommandNames.DocumentHighlights]: (request: protocol.Request) => {
|
||||
const { line, offset, file: fileName, filesToSearch } = <protocol.DocumentHighlightsRequestArgs>request.arguments;
|
||||
return {response: this.getDocumentHighlights(line, offset, fileName, filesToSearch), responseRequired: true};
|
||||
return { response: this.getDocumentHighlights(line, offset, fileName, filesToSearch), responseRequired: true };
|
||||
},
|
||||
[CommandNames.ProjectInfo]: (request: protocol.Request) => {
|
||||
const { file, needFileNameList } = <protocol.ProjectInfoRequestArgs>request.arguments;
|
||||
return {response: this.getProjectInfo(file, needFileNameList), responseRequired: true};
|
||||
return { response: this.getProjectInfo(file, needFileNameList), responseRequired: true };
|
||||
},
|
||||
[CommandNames.ReloadProjects]: (request: protocol.ReloadProjectsRequest) => {
|
||||
this.reloadProjects();
|
||||
return {responseRequired: false};
|
||||
return { responseRequired: false };
|
||||
}
|
||||
};
|
||||
public addProtocolHandler(command: string, handler: (request: protocol.Request) => {response?: any, responseRequired: boolean}) {
|
||||
public addProtocolHandler(command: string, handler: (request: protocol.Request) => { response?: any, responseRequired: boolean }) {
|
||||
if (this.handlers[command]) {
|
||||
throw new Error(`Protocol handler already exists for command "${command}"`);
|
||||
}
|
||||
this.handlers[command] = handler;
|
||||
}
|
||||
|
||||
public executeCommand(request: protocol.Request): {response?: any, responseRequired?: boolean} {
|
||||
public executeCommand(request: protocol.Request): { response?: any, responseRequired?: boolean } {
|
||||
const handler = this.handlers[request.command];
|
||||
if (handler) {
|
||||
return handler(request);
|
||||
@@ -1074,7 +1140,7 @@ namespace ts.server {
|
||||
else {
|
||||
this.projectService.log("Unrecognized JSON command: " + JSON.stringify(request));
|
||||
this.output(undefined, CommandNames.Unknown, request.seq, "Unrecognized JSON command: " + request.command);
|
||||
return {responseRequired: false};
|
||||
return { responseRequired: false };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -728,25 +728,24 @@ namespace ts.formatting {
|
||||
dynamicIndentation.getIndentationForToken(tokenStart.line, currentTokenInfo.token.kind, container) :
|
||||
Constants.Unknown;
|
||||
|
||||
let indentNextTokenOrTrivia = true;
|
||||
if (currentTokenInfo.leadingTrivia) {
|
||||
let commentIndentation = dynamicIndentation.getIndentationForComment(currentTokenInfo.token.kind, tokenIndentation, container);
|
||||
let indentNextTokenOrTrivia = true;
|
||||
|
||||
for (let triviaItem of currentTokenInfo.leadingTrivia) {
|
||||
if (!rangeContainsRange(originalRange, triviaItem)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const triviaInRange = rangeContainsRange(originalRange, triviaItem);
|
||||
switch (triviaItem.kind) {
|
||||
case SyntaxKind.MultiLineCommentTrivia:
|
||||
indentMultilineComment(triviaItem, commentIndentation, /*firstLineIsIndented*/ !indentNextTokenOrTrivia);
|
||||
if (triviaInRange) {
|
||||
indentMultilineComment(triviaItem, commentIndentation, /*firstLineIsIndented*/ !indentNextTokenOrTrivia);
|
||||
}
|
||||
indentNextTokenOrTrivia = false;
|
||||
break;
|
||||
case SyntaxKind.SingleLineCommentTrivia:
|
||||
if (indentNextTokenOrTrivia) {
|
||||
if (indentNextTokenOrTrivia && triviaInRange) {
|
||||
insertIndentation(triviaItem.pos, commentIndentation, /*lineAdded*/ false);
|
||||
indentNextTokenOrTrivia = false;
|
||||
}
|
||||
indentNextTokenOrTrivia = false;
|
||||
break;
|
||||
case SyntaxKind.NewLineTrivia:
|
||||
indentNextTokenOrTrivia = true;
|
||||
@@ -756,7 +755,7 @@ namespace ts.formatting {
|
||||
}
|
||||
|
||||
// indent token only if is it is in target range and does not overlap with any error ranges
|
||||
if (tokenIndentation !== Constants.Unknown) {
|
||||
if (tokenIndentation !== Constants.Unknown && indentNextTokenOrTrivia) {
|
||||
insertIndentation(currentTokenInfo.token.pos, tokenIndentation, lineAdded);
|
||||
|
||||
lastIndentedLine = tokenStart.line;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
namespace ts {
|
||||
/** The version of the language service API */
|
||||
export const servicesVersion = "0.4";
|
||||
export const servicesVersion = "0.5";
|
||||
|
||||
export interface Node {
|
||||
getSourceFile(): SourceFile;
|
||||
@@ -1135,6 +1135,8 @@ namespace ts {
|
||||
|
||||
getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion;
|
||||
|
||||
isValidBraceCompletionAtPostion(fileName: string, position: number, openingBrace: number): boolean;
|
||||
|
||||
getEmitOutput(fileName: string): EmitOutput;
|
||||
|
||||
getProgram(): Program;
|
||||
@@ -5694,7 +5696,7 @@ namespace ts {
|
||||
declaration => (declaration.kind === SyntaxKind.ImportSpecifier ||
|
||||
declaration.kind === SyntaxKind.ExportSpecifier) ? declaration : undefined);
|
||||
if (importOrExportSpecifier &&
|
||||
// export { a }
|
||||
// export { a }
|
||||
(!importOrExportSpecifier.propertyName ||
|
||||
// export {a as class } where a is location
|
||||
importOrExportSpecifier.propertyName === location)) {
|
||||
@@ -5774,7 +5776,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// If symbol is of object binding pattern element without property name we would want to
|
||||
// If symbol is of object binding pattern element without property name we would want to
|
||||
// look for property too and that could be anywhere
|
||||
if (isObjectBindingPatternElementWithoutPropertyName(symbol)) {
|
||||
return undefined;
|
||||
@@ -6236,7 +6238,7 @@ namespace ts {
|
||||
result = result.concat(typeChecker.getSymbolsOfParameterPropertyDeclaration(<ParameterDeclaration>symbol.valueDeclaration, symbol.name));
|
||||
}
|
||||
|
||||
// If this is symbol of binding element without propertyName declaration in Object binding pattern
|
||||
// If this is symbol of binding element without propertyName declaration in Object binding pattern
|
||||
// Include the property in the search
|
||||
const bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol);
|
||||
if (bindingElementPropertySymbol) {
|
||||
@@ -6290,7 +6292,7 @@ namespace ts {
|
||||
|
||||
if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
|
||||
forEach(symbol.getDeclarations(), declaration => {
|
||||
if (declaration.kind === SyntaxKind.ClassDeclaration) {
|
||||
if (isClassLike(declaration)) {
|
||||
getPropertySymbolFromTypeReference(getClassExtendsHeritageClauseElement(<ClassDeclaration>declaration));
|
||||
forEach(getClassImplementsHeritageClauseElements(<ClassDeclaration>declaration), getPropertySymbolFromTypeReference);
|
||||
}
|
||||
@@ -6307,7 +6309,7 @@ namespace ts {
|
||||
if (type) {
|
||||
const propertySymbol = typeChecker.getPropertyOfType(type, propertyName);
|
||||
if (propertySymbol) {
|
||||
result.push(propertySymbol);
|
||||
result.push(...typeChecker.getRootSymbols(propertySymbol));
|
||||
}
|
||||
|
||||
// Visit the typeReference as well to see if it directly or indirectly use that property
|
||||
@@ -6352,7 +6354,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
// If the reference location is the binding element and doesn't have property name
|
||||
// If the reference location is the binding element and doesn't have property name
|
||||
// then include the binding element in the related symbols
|
||||
// let { a } : { a };
|
||||
const bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(referenceSymbol);
|
||||
@@ -7469,6 +7471,36 @@ namespace ts {
|
||||
return { newText: result, caretOffset: preamble.length };
|
||||
}
|
||||
|
||||
function isValidBraceCompletionAtPostion(fileName: string, position: number, openingBrace: number): boolean {
|
||||
|
||||
// '<' is currently not supported, figuring out if we're in a Generic Type vs. a comparison is too
|
||||
// expensive to do during typing scenarios
|
||||
// i.e. whether we're dealing with:
|
||||
// var x = new foo<| ( with class foo<T>{} )
|
||||
// or
|
||||
// var y = 3 <|
|
||||
if (openingBrace === CharacterCodes.lessThan) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
|
||||
|
||||
// Check if in a context where we don't want to perform any insertion
|
||||
if (isInString(sourceFile, position) || isInComment(sourceFile, position)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isInsideJsxElementOrAttribute(sourceFile, position)) {
|
||||
return openingBrace === CharacterCodes.openBrace;
|
||||
}
|
||||
|
||||
if (isInTemplateString(sourceFile, position)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function getParametersForJsDocOwningNode(commentOwner: Node): ParameterDeclaration[] {
|
||||
if (isFunctionLike(commentOwner)) {
|
||||
return commentOwner.parameters;
|
||||
@@ -7763,6 +7795,7 @@ namespace ts {
|
||||
getFormattingEditsForDocument,
|
||||
getFormattingEditsAfterKeystroke,
|
||||
getDocCommentTemplateAtPosition,
|
||||
isValidBraceCompletionAtPostion,
|
||||
getEmitOutput,
|
||||
getNonBoundSourceFile,
|
||||
getProgram
|
||||
|
||||
@@ -221,6 +221,13 @@ namespace ts {
|
||||
*/
|
||||
getDocCommentTemplateAtPosition(fileName: string, position: number): string;
|
||||
|
||||
/**
|
||||
* Returns JSON-encoded boolean to indicate whether we should support brace location
|
||||
* at the current position.
|
||||
* E.g. we don't want brace completion inside string-literals, comments, etc.
|
||||
*/
|
||||
isValidBraceCompletionAtPostion(fileName: string, position: number, openingBrace: number): string;
|
||||
|
||||
getEmitOutput(fileName: string): string;
|
||||
}
|
||||
|
||||
@@ -733,6 +740,13 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
public isValidBraceCompletionAtPostion(fileName: string, position: number, openingBrace: number): string {
|
||||
return this.forwardJSONCall(
|
||||
`isValidBraceCompletionAtPostion('${fileName}', ${position}, ${openingBrace})`,
|
||||
() => this.languageService.isValidBraceCompletionAtPostion(fileName, position, openingBrace)
|
||||
);
|
||||
}
|
||||
|
||||
/// GET SMART INDENT
|
||||
public getIndentationAtPosition(fileName: string, position: number, options: string /*Services.EditorOptions*/): string {
|
||||
return this.forwardJSONCall(
|
||||
|
||||
@@ -428,13 +428,53 @@ namespace ts {
|
||||
|
||||
export function isInString(sourceFile: SourceFile, position: number) {
|
||||
let token = getTokenAtPosition(sourceFile, position);
|
||||
return token && (token.kind === SyntaxKind.StringLiteral || token.kind === SyntaxKind.StringLiteralType) && position > token.getStart();
|
||||
return token && (token.kind === SyntaxKind.StringLiteral || token.kind === SyntaxKind.StringLiteralType) && position > token.getStart(sourceFile);
|
||||
}
|
||||
|
||||
export function isInComment(sourceFile: SourceFile, position: number) {
|
||||
return isInCommentHelper(sourceFile, position, /*predicate*/ undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if the position is in between the open and close elements of an JSX expression.
|
||||
*/
|
||||
export function isInsideJsxElementOrAttribute(sourceFile: SourceFile, position: number) {
|
||||
let token = getTokenAtPosition(sourceFile, position);
|
||||
|
||||
if (!token) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// <div>Hello |</div>
|
||||
if (token.kind === SyntaxKind.LessThanToken && token.parent.kind === SyntaxKind.JsxText) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// <div> { | </div> or <div a={| </div>
|
||||
if (token.kind === SyntaxKind.LessThanToken && token.parent.kind === SyntaxKind.JsxExpression) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// <div> {
|
||||
// |
|
||||
// } < /div>
|
||||
if (token && token.kind === SyntaxKind.CloseBraceToken && token.parent.kind === SyntaxKind.JsxExpression) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// <div>|</div>
|
||||
if (token.kind === SyntaxKind.LessThanToken && token.parent.kind === SyntaxKind.JsxClosingElement) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isInTemplateString(sourceFile: SourceFile, position: number) {
|
||||
let token = getTokenAtPosition(sourceFile, position);
|
||||
return isTemplateLiteralKind(token.kind) && position > token.getStart(sourceFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the cursor at position in sourceFile is within a comment that additionally
|
||||
* satisfies predicate, and false otherwise.
|
||||
@@ -442,7 +482,7 @@ namespace ts {
|
||||
export function isInCommentHelper(sourceFile: SourceFile, position: number, predicate?: (c: CommentRange) => boolean): boolean {
|
||||
let token = getTokenAtPosition(sourceFile, position);
|
||||
|
||||
if (token && position <= token.getStart()) {
|
||||
if (token && position <= token.getStart(sourceFile)) {
|
||||
let commentRanges = getLeadingCommentRanges(sourceFile.text, token.pos);
|
||||
|
||||
// The end marker of a single-line comment does not include the newline character.
|
||||
@@ -844,12 +884,15 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getScriptKind(fileName: string, host?: LanguageServiceHost): ScriptKind {
|
||||
// First check to see if the script kind can be determined from the file name
|
||||
var scriptKind = getScriptKindFromFileName(fileName);
|
||||
if (scriptKind === ScriptKind.Unknown && host && host.getScriptKind) {
|
||||
// Next check to see if the host can resolve the script kind
|
||||
// First check to see if the script kind was specified by the host. Chances are the host
|
||||
// may override the default script kind for the file extension.
|
||||
let scriptKind: ScriptKind;
|
||||
if (host && host.getScriptKind) {
|
||||
scriptKind = host.getScriptKind(fileName);
|
||||
}
|
||||
if (!scriptKind || scriptKind === ScriptKind.Unknown) {
|
||||
scriptKind = getScriptKindFromFileName(fileName);
|
||||
}
|
||||
return ensureScriptKind(fileName, scriptKind);
|
||||
}
|
||||
}
|
||||
@@ -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,16 @@
|
||||
//// [arrayFilter.ts]
|
||||
var foo = [
|
||||
{ name: 'bar' },
|
||||
{ name: null },
|
||||
{ name: 'baz' }
|
||||
]
|
||||
|
||||
foo.filter(x => x.name); //should accepted all possible types not only boolean!
|
||||
|
||||
//// [arrayFilter.js]
|
||||
var foo = [
|
||||
{ name: 'bar' },
|
||||
{ name: null },
|
||||
{ name: 'baz' }
|
||||
];
|
||||
foo.filter(function (x) { return x.name; }); //should accepted all possible types not only boolean!
|
||||
@@ -0,0 +1,24 @@
|
||||
=== tests/cases/compiler/arrayFilter.ts ===
|
||||
var foo = [
|
||||
>foo : Symbol(foo, Decl(arrayFilter.ts, 0, 3))
|
||||
|
||||
{ name: 'bar' },
|
||||
>name : Symbol(name, Decl(arrayFilter.ts, 1, 5))
|
||||
|
||||
{ name: null },
|
||||
>name : Symbol(name, Decl(arrayFilter.ts, 2, 5))
|
||||
|
||||
{ name: 'baz' }
|
||||
>name : Symbol(name, Decl(arrayFilter.ts, 3, 5))
|
||||
|
||||
]
|
||||
|
||||
foo.filter(x => x.name); //should accepted all possible types not only boolean!
|
||||
>foo.filter : Symbol(Array.filter, Decl(lib.d.ts, --, --))
|
||||
>foo : Symbol(foo, Decl(arrayFilter.ts, 0, 3))
|
||||
>filter : Symbol(Array.filter, Decl(lib.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(arrayFilter.ts, 6, 11))
|
||||
>x.name : Symbol(name, Decl(arrayFilter.ts, 1, 5))
|
||||
>x : Symbol(x, Decl(arrayFilter.ts, 6, 11))
|
||||
>name : Symbol(name, Decl(arrayFilter.ts, 1, 5))
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
=== tests/cases/compiler/arrayFilter.ts ===
|
||||
var foo = [
|
||||
>foo : { name: string; }[]
|
||||
>[ { name: 'bar' }, { name: null }, { name: 'baz' }] : { name: string; }[]
|
||||
|
||||
{ name: 'bar' },
|
||||
>{ name: 'bar' } : { name: string; }
|
||||
>name : string
|
||||
>'bar' : string
|
||||
|
||||
{ name: null },
|
||||
>{ name: null } : { name: null; }
|
||||
>name : null
|
||||
>null : null
|
||||
|
||||
{ name: 'baz' }
|
||||
>{ name: 'baz' } : { name: string; }
|
||||
>name : string
|
||||
>'baz' : string
|
||||
|
||||
]
|
||||
|
||||
foo.filter(x => x.name); //should accepted all possible types not only boolean!
|
||||
>foo.filter(x => x.name) : { name: string; }[]
|
||||
>foo.filter : (callbackfn: (value: { name: string; }, index: number, array: { name: string; }[]) => any, thisArg?: any) => { name: string; }[]
|
||||
>foo : { name: string; }[]
|
||||
>filter : (callbackfn: (value: { name: string; }, index: number, array: { name: string; }[]) => any, thisArg?: any) => { name: string; }[]
|
||||
>x => x.name : (x: { name: string; }) => string
|
||||
>x : { name: string; }
|
||||
>x.name : string
|
||||
>x : { name: string; }
|
||||
>name : string
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -24,12 +24,12 @@ let test: indexAccess;
|
||||
let s = test[0];
|
||||
>s : Symbol(s, Decl(constIndexedAccess.ts, 13, 3))
|
||||
>test : Symbol(test, Decl(constIndexedAccess.ts, 11, 3))
|
||||
>0 : Symbol(indexAccess.0, Decl(constIndexedAccess.ts, 6, 23))
|
||||
>0 : Symbol(indexAccess[0], Decl(constIndexedAccess.ts, 6, 23))
|
||||
|
||||
let n = test[1];
|
||||
>n : Symbol(n, Decl(constIndexedAccess.ts, 14, 3))
|
||||
>test : Symbol(test, Decl(constIndexedAccess.ts, 11, 3))
|
||||
>1 : Symbol(indexAccess.1, Decl(constIndexedAccess.ts, 7, 14))
|
||||
>1 : Symbol(indexAccess[1], Decl(constIndexedAccess.ts, 7, 14))
|
||||
|
||||
let s1 = test[numbers.zero];
|
||||
>s1 : Symbol(s1, Decl(constIndexedAccess.ts, 16, 3))
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
//// [declarationEmitFirstTypeArgumentGenericFunctionType.ts]
|
||||
|
||||
class X<A> {
|
||||
}
|
||||
var prop11: X< <Tany>() => Tany >; // spaces before the first type argument
|
||||
var prop12: X<(<Tany>() => Tany)>; // spaces before the first type argument
|
||||
function f1() { // Inferred return type
|
||||
return prop11;
|
||||
}
|
||||
function f2() { // Inferred return type
|
||||
return prop12;
|
||||
}
|
||||
function f3(): X< <Tany>() => Tany> { // written with space before type argument
|
||||
return prop11;
|
||||
}
|
||||
function f4(): X<(<Tany>() => Tany)> { // written type with parenthesis
|
||||
return prop12;
|
||||
}
|
||||
class Y<A, B> {
|
||||
}
|
||||
var prop2: Y<string[], <Tany>() => Tany>; // No space after second type argument
|
||||
var prop2: Y<string[], <Tany>() => Tany>; // space after second type argument
|
||||
var prop3: Y< <Tany>() => Tany, <Tany>() => Tany>; // space before first type argument
|
||||
var prop4: Y<(<Tany>() => Tany), <Tany>() => Tany>; // parenthesized first type argument
|
||||
|
||||
|
||||
//// [declarationEmitFirstTypeArgumentGenericFunctionType.js]
|
||||
class X {
|
||||
}
|
||||
var prop11; // spaces before the first type argument
|
||||
var prop12; // spaces before the first type argument
|
||||
function f1() {
|
||||
return prop11;
|
||||
}
|
||||
function f2() {
|
||||
return prop12;
|
||||
}
|
||||
function f3() {
|
||||
return prop11;
|
||||
}
|
||||
function f4() {
|
||||
return prop12;
|
||||
}
|
||||
class Y {
|
||||
}
|
||||
var prop2; // No space after second type argument
|
||||
var prop2; // space after second type argument
|
||||
var prop3; // space before first type argument
|
||||
var prop4; // parenthesized first type argument
|
||||
|
||||
|
||||
//// [declarationEmitFirstTypeArgumentGenericFunctionType.d.ts]
|
||||
declare class X<A> {
|
||||
}
|
||||
declare var prop11: X<(<Tany>() => Tany)>;
|
||||
declare var prop12: X<(<Tany>() => Tany)>;
|
||||
declare function f1(): X<(<Tany>() => Tany)>;
|
||||
declare function f2(): X<(<Tany>() => Tany)>;
|
||||
declare function f3(): X<(<Tany>() => Tany)>;
|
||||
declare function f4(): X<(<Tany>() => Tany)>;
|
||||
declare class Y<A, B> {
|
||||
}
|
||||
declare var prop2: Y<string[], <Tany>() => Tany>;
|
||||
declare var prop2: Y<string[], <Tany>() => Tany>;
|
||||
declare var prop3: Y<(<Tany>() => Tany), <Tany>() => Tany>;
|
||||
declare var prop4: Y<(<Tany>() => Tany), <Tany>() => Tany>;
|
||||
@@ -0,0 +1,81 @@
|
||||
=== tests/cases/compiler/declarationEmitFirstTypeArgumentGenericFunctionType.ts ===
|
||||
|
||||
class X<A> {
|
||||
>X : Symbol(X, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 0, 0))
|
||||
>A : Symbol(A, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 1, 8))
|
||||
}
|
||||
var prop11: X< <Tany>() => Tany >; // spaces before the first type argument
|
||||
>prop11 : Symbol(prop11, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 3, 3))
|
||||
>X : Symbol(X, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 0, 0))
|
||||
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 3, 16))
|
||||
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 3, 16))
|
||||
|
||||
var prop12: X<(<Tany>() => Tany)>; // spaces before the first type argument
|
||||
>prop12 : Symbol(prop12, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 4, 3))
|
||||
>X : Symbol(X, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 0, 0))
|
||||
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 4, 16))
|
||||
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 4, 16))
|
||||
|
||||
function f1() { // Inferred return type
|
||||
>f1 : Symbol(f1, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 4, 34))
|
||||
|
||||
return prop11;
|
||||
>prop11 : Symbol(prop11, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 3, 3))
|
||||
}
|
||||
function f2() { // Inferred return type
|
||||
>f2 : Symbol(f2, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 7, 1))
|
||||
|
||||
return prop12;
|
||||
>prop12 : Symbol(prop12, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 4, 3))
|
||||
}
|
||||
function f3(): X< <Tany>() => Tany> { // written with space before type argument
|
||||
>f3 : Symbol(f3, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 10, 1))
|
||||
>X : Symbol(X, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 0, 0))
|
||||
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 11, 19))
|
||||
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 11, 19))
|
||||
|
||||
return prop11;
|
||||
>prop11 : Symbol(prop11, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 3, 3))
|
||||
}
|
||||
function f4(): X<(<Tany>() => Tany)> { // written type with parenthesis
|
||||
>f4 : Symbol(f4, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 13, 1))
|
||||
>X : Symbol(X, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 0, 0))
|
||||
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 14, 19))
|
||||
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 14, 19))
|
||||
|
||||
return prop12;
|
||||
>prop12 : Symbol(prop12, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 4, 3))
|
||||
}
|
||||
class Y<A, B> {
|
||||
>Y : Symbol(Y, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 16, 1))
|
||||
>A : Symbol(A, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 17, 8))
|
||||
>B : Symbol(B, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 17, 10))
|
||||
}
|
||||
var prop2: Y<string[], <Tany>() => Tany>; // No space after second type argument
|
||||
>prop2 : Symbol(prop2, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 19, 3), Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 20, 3))
|
||||
>Y : Symbol(Y, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 16, 1))
|
||||
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 19, 24))
|
||||
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 19, 24))
|
||||
|
||||
var prop2: Y<string[], <Tany>() => Tany>; // space after second type argument
|
||||
>prop2 : Symbol(prop2, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 19, 3), Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 20, 3))
|
||||
>Y : Symbol(Y, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 16, 1))
|
||||
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 20, 24))
|
||||
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 20, 24))
|
||||
|
||||
var prop3: Y< <Tany>() => Tany, <Tany>() => Tany>; // space before first type argument
|
||||
>prop3 : Symbol(prop3, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 21, 3))
|
||||
>Y : Symbol(Y, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 16, 1))
|
||||
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 21, 15))
|
||||
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 21, 15))
|
||||
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 21, 33))
|
||||
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 21, 33))
|
||||
|
||||
var prop4: Y<(<Tany>() => Tany), <Tany>() => Tany>; // parenthesized first type argument
|
||||
>prop4 : Symbol(prop4, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 22, 3))
|
||||
>Y : Symbol(Y, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 16, 1))
|
||||
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 22, 15))
|
||||
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 22, 15))
|
||||
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 22, 34))
|
||||
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 22, 34))
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
=== tests/cases/compiler/declarationEmitFirstTypeArgumentGenericFunctionType.ts ===
|
||||
|
||||
class X<A> {
|
||||
>X : X<A>
|
||||
>A : A
|
||||
}
|
||||
var prop11: X< <Tany>() => Tany >; // spaces before the first type argument
|
||||
>prop11 : X<(<Tany>() => Tany)>
|
||||
>X : X<A>
|
||||
>Tany : Tany
|
||||
>Tany : Tany
|
||||
|
||||
var prop12: X<(<Tany>() => Tany)>; // spaces before the first type argument
|
||||
>prop12 : X<(<Tany>() => Tany)>
|
||||
>X : X<A>
|
||||
>Tany : Tany
|
||||
>Tany : Tany
|
||||
|
||||
function f1() { // Inferred return type
|
||||
>f1 : () => X<(<Tany>() => Tany)>
|
||||
|
||||
return prop11;
|
||||
>prop11 : X<(<Tany>() => Tany)>
|
||||
}
|
||||
function f2() { // Inferred return type
|
||||
>f2 : () => X<(<Tany>() => Tany)>
|
||||
|
||||
return prop12;
|
||||
>prop12 : X<(<Tany>() => Tany)>
|
||||
}
|
||||
function f3(): X< <Tany>() => Tany> { // written with space before type argument
|
||||
>f3 : () => X<(<Tany>() => Tany)>
|
||||
>X : X<A>
|
||||
>Tany : Tany
|
||||
>Tany : Tany
|
||||
|
||||
return prop11;
|
||||
>prop11 : X<(<Tany>() => Tany)>
|
||||
}
|
||||
function f4(): X<(<Tany>() => Tany)> { // written type with parenthesis
|
||||
>f4 : () => X<(<Tany>() => Tany)>
|
||||
>X : X<A>
|
||||
>Tany : Tany
|
||||
>Tany : Tany
|
||||
|
||||
return prop12;
|
||||
>prop12 : X<(<Tany>() => Tany)>
|
||||
}
|
||||
class Y<A, B> {
|
||||
>Y : Y<A, B>
|
||||
>A : A
|
||||
>B : B
|
||||
}
|
||||
var prop2: Y<string[], <Tany>() => Tany>; // No space after second type argument
|
||||
>prop2 : Y<string[], <Tany>() => Tany>
|
||||
>Y : Y<A, B>
|
||||
>Tany : Tany
|
||||
>Tany : Tany
|
||||
|
||||
var prop2: Y<string[], <Tany>() => Tany>; // space after second type argument
|
||||
>prop2 : Y<string[], <Tany>() => Tany>
|
||||
>Y : Y<A, B>
|
||||
>Tany : Tany
|
||||
>Tany : Tany
|
||||
|
||||
var prop3: Y< <Tany>() => Tany, <Tany>() => Tany>; // space before first type argument
|
||||
>prop3 : Y<(<Tany>() => Tany), <Tany>() => Tany>
|
||||
>Y : Y<A, B>
|
||||
>Tany : Tany
|
||||
>Tany : Tany
|
||||
>Tany : Tany
|
||||
>Tany : Tany
|
||||
|
||||
var prop4: Y<(<Tany>() => Tany), <Tany>() => Tany>; // parenthesized first type argument
|
||||
>prop4 : Y<(<Tany>() => Tany), <Tany>() => Tany>
|
||||
>Y : Y<A, B>
|
||||
>Tany : Tany
|
||||
>Tany : Tany
|
||||
>Tany : Tany
|
||||
>Tany : Tany
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
//// [declarationEmitPromise.ts]
|
||||
|
||||
export class bluebird<T> {
|
||||
static all: Array<bluebird<any>>;
|
||||
}
|
||||
|
||||
export async function runSampleWorks<A, B, C, D, E>(
|
||||
a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>) {
|
||||
let result = await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el));
|
||||
let func = <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T =>
|
||||
f.apply(this, result);
|
||||
let rfunc: typeof func & {} = func as any; // <- This is the only difference
|
||||
return rfunc
|
||||
}
|
||||
|
||||
export async function runSampleBreaks<A, B, C, D, E>(
|
||||
a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>) {
|
||||
let result = await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el));
|
||||
let func = <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T =>
|
||||
f.apply(this, result);
|
||||
let rfunc: typeof func = func as any; // <- This is the only difference
|
||||
return rfunc
|
||||
}
|
||||
|
||||
//// [declarationEmitPromise.js]
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments)).next());
|
||||
});
|
||||
};
|
||||
class bluebird {
|
||||
}
|
||||
exports.bluebird = bluebird;
|
||||
function runSampleWorks(a, b, c, d, e) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let result = yield bluebird.all([a, b, c, d, e].filter(el => !!el));
|
||||
let func = (f) => f.apply(this, result);
|
||||
let rfunc = func; // <- This is the only difference
|
||||
return rfunc;
|
||||
});
|
||||
}
|
||||
exports.runSampleWorks = runSampleWorks;
|
||||
function runSampleBreaks(a, b, c, d, e) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let result = yield bluebird.all([a, b, c, d, e].filter(el => !!el));
|
||||
let func = (f) => f.apply(this, result);
|
||||
let rfunc = func; // <- This is the only difference
|
||||
return rfunc;
|
||||
});
|
||||
}
|
||||
exports.runSampleBreaks = runSampleBreaks;
|
||||
|
||||
|
||||
//// [declarationEmitPromise.d.ts]
|
||||
export declare class bluebird<T> {
|
||||
static all: Array<bluebird<any>>;
|
||||
}
|
||||
export declare function runSampleWorks<A, B, C, D, E>(a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>): Promise<(<T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T) & {}>;
|
||||
export declare function runSampleBreaks<A, B, C, D, E>(a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>): Promise<(<T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T)>;
|
||||
@@ -0,0 +1,155 @@
|
||||
=== tests/cases/compiler/declarationEmitPromise.ts ===
|
||||
|
||||
export class bluebird<T> {
|
||||
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(declarationEmitPromise.ts, 1, 22))
|
||||
|
||||
static all: Array<bluebird<any>>;
|
||||
>all : Symbol(bluebird.all, Decl(declarationEmitPromise.ts, 1, 26))
|
||||
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
|
||||
}
|
||||
|
||||
export async function runSampleWorks<A, B, C, D, E>(
|
||||
>runSampleWorks : Symbol(runSampleWorks, Decl(declarationEmitPromise.ts, 3, 1))
|
||||
>A : Symbol(A, Decl(declarationEmitPromise.ts, 5, 37))
|
||||
>B : Symbol(B, Decl(declarationEmitPromise.ts, 5, 39))
|
||||
>C : Symbol(C, Decl(declarationEmitPromise.ts, 5, 42))
|
||||
>D : Symbol(D, Decl(declarationEmitPromise.ts, 5, 45))
|
||||
>E : Symbol(E, Decl(declarationEmitPromise.ts, 5, 48))
|
||||
|
||||
a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>) {
|
||||
>a : Symbol(a, Decl(declarationEmitPromise.ts, 5, 52))
|
||||
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
|
||||
>A : Symbol(A, Decl(declarationEmitPromise.ts, 5, 37))
|
||||
>b : Symbol(b, Decl(declarationEmitPromise.ts, 6, 19))
|
||||
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
|
||||
>B : Symbol(B, Decl(declarationEmitPromise.ts, 5, 39))
|
||||
>c : Symbol(c, Decl(declarationEmitPromise.ts, 6, 36))
|
||||
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
|
||||
>C : Symbol(C, Decl(declarationEmitPromise.ts, 5, 42))
|
||||
>d : Symbol(d, Decl(declarationEmitPromise.ts, 6, 53))
|
||||
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
|
||||
>D : Symbol(D, Decl(declarationEmitPromise.ts, 5, 45))
|
||||
>e : Symbol(e, Decl(declarationEmitPromise.ts, 6, 70))
|
||||
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
|
||||
>E : Symbol(E, Decl(declarationEmitPromise.ts, 5, 48))
|
||||
|
||||
let result = await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el));
|
||||
>result : Symbol(result, Decl(declarationEmitPromise.ts, 7, 7))
|
||||
>bluebird.all : Symbol(bluebird.all, Decl(declarationEmitPromise.ts, 1, 26))
|
||||
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
|
||||
>all : Symbol(bluebird.all, Decl(declarationEmitPromise.ts, 1, 26))
|
||||
>[a, b, c, d, e].filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --))
|
||||
>a : Symbol(a, Decl(declarationEmitPromise.ts, 5, 52))
|
||||
>b : Symbol(b, Decl(declarationEmitPromise.ts, 6, 19))
|
||||
>c : Symbol(c, Decl(declarationEmitPromise.ts, 6, 36))
|
||||
>d : Symbol(d, Decl(declarationEmitPromise.ts, 6, 53))
|
||||
>e : Symbol(e, Decl(declarationEmitPromise.ts, 6, 70))
|
||||
>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --))
|
||||
>el : Symbol(el, Decl(declarationEmitPromise.ts, 7, 68))
|
||||
>el : Symbol(el, Decl(declarationEmitPromise.ts, 7, 68))
|
||||
|
||||
let func = <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T =>
|
||||
>func : Symbol(func, Decl(declarationEmitPromise.ts, 8, 7))
|
||||
>T : Symbol(T, Decl(declarationEmitPromise.ts, 8, 16))
|
||||
>f : Symbol(f, Decl(declarationEmitPromise.ts, 8, 19))
|
||||
>a : Symbol(a, Decl(declarationEmitPromise.ts, 8, 23))
|
||||
>A : Symbol(A, Decl(declarationEmitPromise.ts, 5, 37))
|
||||
>b : Symbol(b, Decl(declarationEmitPromise.ts, 8, 28))
|
||||
>B : Symbol(B, Decl(declarationEmitPromise.ts, 5, 39))
|
||||
>c : Symbol(c, Decl(declarationEmitPromise.ts, 8, 35))
|
||||
>C : Symbol(C, Decl(declarationEmitPromise.ts, 5, 42))
|
||||
>d : Symbol(d, Decl(declarationEmitPromise.ts, 8, 42))
|
||||
>D : Symbol(D, Decl(declarationEmitPromise.ts, 5, 45))
|
||||
>e : Symbol(e, Decl(declarationEmitPromise.ts, 8, 49))
|
||||
>E : Symbol(E, Decl(declarationEmitPromise.ts, 5, 48))
|
||||
>T : Symbol(T, Decl(declarationEmitPromise.ts, 8, 16))
|
||||
>T : Symbol(T, Decl(declarationEmitPromise.ts, 8, 16))
|
||||
|
||||
f.apply(this, result);
|
||||
>f.apply : Symbol(Function.apply, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>f : Symbol(f, Decl(declarationEmitPromise.ts, 8, 19))
|
||||
>apply : Symbol(Function.apply, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>result : Symbol(result, Decl(declarationEmitPromise.ts, 7, 7))
|
||||
|
||||
let rfunc: typeof func & {} = func as any; // <- This is the only difference
|
||||
>rfunc : Symbol(rfunc, Decl(declarationEmitPromise.ts, 10, 7))
|
||||
>func : Symbol(func, Decl(declarationEmitPromise.ts, 8, 7))
|
||||
>func : Symbol(func, Decl(declarationEmitPromise.ts, 8, 7))
|
||||
|
||||
return rfunc
|
||||
>rfunc : Symbol(rfunc, Decl(declarationEmitPromise.ts, 10, 7))
|
||||
}
|
||||
|
||||
export async function runSampleBreaks<A, B, C, D, E>(
|
||||
>runSampleBreaks : Symbol(runSampleBreaks, Decl(declarationEmitPromise.ts, 12, 1))
|
||||
>A : Symbol(A, Decl(declarationEmitPromise.ts, 14, 38))
|
||||
>B : Symbol(B, Decl(declarationEmitPromise.ts, 14, 40))
|
||||
>C : Symbol(C, Decl(declarationEmitPromise.ts, 14, 43))
|
||||
>D : Symbol(D, Decl(declarationEmitPromise.ts, 14, 46))
|
||||
>E : Symbol(E, Decl(declarationEmitPromise.ts, 14, 49))
|
||||
|
||||
a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>) {
|
||||
>a : Symbol(a, Decl(declarationEmitPromise.ts, 14, 53))
|
||||
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
|
||||
>A : Symbol(A, Decl(declarationEmitPromise.ts, 14, 38))
|
||||
>b : Symbol(b, Decl(declarationEmitPromise.ts, 15, 19))
|
||||
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
|
||||
>B : Symbol(B, Decl(declarationEmitPromise.ts, 14, 40))
|
||||
>c : Symbol(c, Decl(declarationEmitPromise.ts, 15, 36))
|
||||
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
|
||||
>C : Symbol(C, Decl(declarationEmitPromise.ts, 14, 43))
|
||||
>d : Symbol(d, Decl(declarationEmitPromise.ts, 15, 53))
|
||||
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
|
||||
>D : Symbol(D, Decl(declarationEmitPromise.ts, 14, 46))
|
||||
>e : Symbol(e, Decl(declarationEmitPromise.ts, 15, 70))
|
||||
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
|
||||
>E : Symbol(E, Decl(declarationEmitPromise.ts, 14, 49))
|
||||
|
||||
let result = await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el));
|
||||
>result : Symbol(result, Decl(declarationEmitPromise.ts, 16, 7))
|
||||
>bluebird.all : Symbol(bluebird.all, Decl(declarationEmitPromise.ts, 1, 26))
|
||||
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
|
||||
>all : Symbol(bluebird.all, Decl(declarationEmitPromise.ts, 1, 26))
|
||||
>[a, b, c, d, e].filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --))
|
||||
>a : Symbol(a, Decl(declarationEmitPromise.ts, 14, 53))
|
||||
>b : Symbol(b, Decl(declarationEmitPromise.ts, 15, 19))
|
||||
>c : Symbol(c, Decl(declarationEmitPromise.ts, 15, 36))
|
||||
>d : Symbol(d, Decl(declarationEmitPromise.ts, 15, 53))
|
||||
>e : Symbol(e, Decl(declarationEmitPromise.ts, 15, 70))
|
||||
>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --))
|
||||
>el : Symbol(el, Decl(declarationEmitPromise.ts, 16, 68))
|
||||
>el : Symbol(el, Decl(declarationEmitPromise.ts, 16, 68))
|
||||
|
||||
let func = <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T =>
|
||||
>func : Symbol(func, Decl(declarationEmitPromise.ts, 17, 7))
|
||||
>T : Symbol(T, Decl(declarationEmitPromise.ts, 17, 16))
|
||||
>f : Symbol(f, Decl(declarationEmitPromise.ts, 17, 19))
|
||||
>a : Symbol(a, Decl(declarationEmitPromise.ts, 17, 23))
|
||||
>A : Symbol(A, Decl(declarationEmitPromise.ts, 14, 38))
|
||||
>b : Symbol(b, Decl(declarationEmitPromise.ts, 17, 28))
|
||||
>B : Symbol(B, Decl(declarationEmitPromise.ts, 14, 40))
|
||||
>c : Symbol(c, Decl(declarationEmitPromise.ts, 17, 35))
|
||||
>C : Symbol(C, Decl(declarationEmitPromise.ts, 14, 43))
|
||||
>d : Symbol(d, Decl(declarationEmitPromise.ts, 17, 42))
|
||||
>D : Symbol(D, Decl(declarationEmitPromise.ts, 14, 46))
|
||||
>e : Symbol(e, Decl(declarationEmitPromise.ts, 17, 49))
|
||||
>E : Symbol(E, Decl(declarationEmitPromise.ts, 14, 49))
|
||||
>T : Symbol(T, Decl(declarationEmitPromise.ts, 17, 16))
|
||||
>T : Symbol(T, Decl(declarationEmitPromise.ts, 17, 16))
|
||||
|
||||
f.apply(this, result);
|
||||
>f.apply : Symbol(Function.apply, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>f : Symbol(f, Decl(declarationEmitPromise.ts, 17, 19))
|
||||
>apply : Symbol(Function.apply, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>result : Symbol(result, Decl(declarationEmitPromise.ts, 16, 7))
|
||||
|
||||
let rfunc: typeof func = func as any; // <- This is the only difference
|
||||
>rfunc : Symbol(rfunc, Decl(declarationEmitPromise.ts, 19, 7))
|
||||
>func : Symbol(func, Decl(declarationEmitPromise.ts, 17, 7))
|
||||
>func : Symbol(func, Decl(declarationEmitPromise.ts, 17, 7))
|
||||
|
||||
return rfunc
|
||||
>rfunc : Symbol(rfunc, Decl(declarationEmitPromise.ts, 19, 7))
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
=== tests/cases/compiler/declarationEmitPromise.ts ===
|
||||
|
||||
export class bluebird<T> {
|
||||
>bluebird : bluebird<T>
|
||||
>T : T
|
||||
|
||||
static all: Array<bluebird<any>>;
|
||||
>all : bluebird<any>[]
|
||||
>Array : T[]
|
||||
>bluebird : bluebird<T>
|
||||
}
|
||||
|
||||
export async function runSampleWorks<A, B, C, D, E>(
|
||||
>runSampleWorks : <A, B, C, D, E>(a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>) => Promise<(<T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T) & {}>
|
||||
>A : A
|
||||
>B : B
|
||||
>C : C
|
||||
>D : D
|
||||
>E : E
|
||||
|
||||
a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>) {
|
||||
>a : bluebird<A>
|
||||
>bluebird : bluebird<T>
|
||||
>A : A
|
||||
>b : bluebird<B>
|
||||
>bluebird : bluebird<T>
|
||||
>B : B
|
||||
>c : bluebird<C>
|
||||
>bluebird : bluebird<T>
|
||||
>C : C
|
||||
>d : bluebird<D>
|
||||
>bluebird : bluebird<T>
|
||||
>D : D
|
||||
>e : bluebird<E>
|
||||
>bluebird : bluebird<T>
|
||||
>E : E
|
||||
|
||||
let result = await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el));
|
||||
>result : any
|
||||
>await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el)) : any
|
||||
>(bluebird.all as any)([a, b, c, d, e].filter(el => !!el)) : any
|
||||
>(bluebird.all as any) : any
|
||||
>bluebird.all as any : any
|
||||
>bluebird.all : bluebird<any>[]
|
||||
>bluebird : typeof bluebird
|
||||
>all : bluebird<any>[]
|
||||
>[a, b, c, d, e].filter(el => !!el) : bluebird<A>[]
|
||||
>[a, b, c, d, e].filter : (callbackfn: (value: bluebird<A>, index: number, array: bluebird<A>[]) => any, thisArg?: any) => bluebird<A>[]
|
||||
>[a, b, c, d, e] : bluebird<A>[]
|
||||
>a : bluebird<A>
|
||||
>b : bluebird<B>
|
||||
>c : bluebird<C>
|
||||
>d : bluebird<D>
|
||||
>e : bluebird<E>
|
||||
>filter : (callbackfn: (value: bluebird<A>, index: number, array: bluebird<A>[]) => any, thisArg?: any) => bluebird<A>[]
|
||||
>el => !!el : (el: bluebird<A>) => boolean
|
||||
>el : bluebird<A>
|
||||
>!!el : boolean
|
||||
>!el : boolean
|
||||
>el : bluebird<A>
|
||||
|
||||
let func = <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T =>
|
||||
>func : <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T
|
||||
><T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T => f.apply(this, result) : <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T
|
||||
>T : T
|
||||
>f : (a: A, b?: B, c?: C, d?: D, e?: E) => T
|
||||
>a : A
|
||||
>A : A
|
||||
>b : B
|
||||
>B : B
|
||||
>c : C
|
||||
>C : C
|
||||
>d : D
|
||||
>D : D
|
||||
>e : E
|
||||
>E : E
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
f.apply(this, result);
|
||||
>f.apply(this, result) : T
|
||||
>f.apply : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, argArray?: any): U; (this: Function, thisArg: any, argArray?: any): any; }
|
||||
>f : (a: A, b?: B, c?: C, d?: D, e?: E) => T
|
||||
>apply : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, argArray?: any): U; (this: Function, thisArg: any, argArray?: any): any; }
|
||||
>this : any
|
||||
>result : any
|
||||
|
||||
let rfunc: typeof func & {} = func as any; // <- This is the only difference
|
||||
>rfunc : (<T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T) & {}
|
||||
>func : <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T
|
||||
>func as any : any
|
||||
>func : <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T
|
||||
|
||||
return rfunc
|
||||
>rfunc : (<T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T) & {}
|
||||
}
|
||||
|
||||
export async function runSampleBreaks<A, B, C, D, E>(
|
||||
>runSampleBreaks : <A, B, C, D, E>(a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>) => Promise<(<T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T)>
|
||||
>A : A
|
||||
>B : B
|
||||
>C : C
|
||||
>D : D
|
||||
>E : E
|
||||
|
||||
a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>) {
|
||||
>a : bluebird<A>
|
||||
>bluebird : bluebird<T>
|
||||
>A : A
|
||||
>b : bluebird<B>
|
||||
>bluebird : bluebird<T>
|
||||
>B : B
|
||||
>c : bluebird<C>
|
||||
>bluebird : bluebird<T>
|
||||
>C : C
|
||||
>d : bluebird<D>
|
||||
>bluebird : bluebird<T>
|
||||
>D : D
|
||||
>e : bluebird<E>
|
||||
>bluebird : bluebird<T>
|
||||
>E : E
|
||||
|
||||
let result = await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el));
|
||||
>result : any
|
||||
>await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el)) : any
|
||||
>(bluebird.all as any)([a, b, c, d, e].filter(el => !!el)) : any
|
||||
>(bluebird.all as any) : any
|
||||
>bluebird.all as any : any
|
||||
>bluebird.all : bluebird<any>[]
|
||||
>bluebird : typeof bluebird
|
||||
>all : bluebird<any>[]
|
||||
>[a, b, c, d, e].filter(el => !!el) : bluebird<A>[]
|
||||
>[a, b, c, d, e].filter : (callbackfn: (value: bluebird<A>, index: number, array: bluebird<A>[]) => any, thisArg?: any) => bluebird<A>[]
|
||||
>[a, b, c, d, e] : bluebird<A>[]
|
||||
>a : bluebird<A>
|
||||
>b : bluebird<B>
|
||||
>c : bluebird<C>
|
||||
>d : bluebird<D>
|
||||
>e : bluebird<E>
|
||||
>filter : (callbackfn: (value: bluebird<A>, index: number, array: bluebird<A>[]) => any, thisArg?: any) => bluebird<A>[]
|
||||
>el => !!el : (el: bluebird<A>) => boolean
|
||||
>el : bluebird<A>
|
||||
>!!el : boolean
|
||||
>!el : boolean
|
||||
>el : bluebird<A>
|
||||
|
||||
let func = <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T =>
|
||||
>func : <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T
|
||||
><T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T => f.apply(this, result) : <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T
|
||||
>T : T
|
||||
>f : (a: A, b?: B, c?: C, d?: D, e?: E) => T
|
||||
>a : A
|
||||
>A : A
|
||||
>b : B
|
||||
>B : B
|
||||
>c : C
|
||||
>C : C
|
||||
>d : D
|
||||
>D : D
|
||||
>e : E
|
||||
>E : E
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
f.apply(this, result);
|
||||
>f.apply(this, result) : T
|
||||
>f.apply : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, argArray?: any): U; (this: Function, thisArg: any, argArray?: any): any; }
|
||||
>f : (a: A, b?: B, c?: C, d?: D, e?: E) => T
|
||||
>apply : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, argArray?: any): U; (this: Function, thisArg: any, argArray?: any): any; }
|
||||
>this : any
|
||||
>result : any
|
||||
|
||||
let rfunc: typeof func = func as any; // <- This is the only difference
|
||||
>rfunc : <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T
|
||||
>func : <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T
|
||||
>func as any : any
|
||||
>func : <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T
|
||||
|
||||
return rfunc
|
||||
>rfunc : <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T
|
||||
}
|
||||
@@ -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,4 +1,4 @@
|
||||
tests/cases/compiler/b.ts(1,9): error TS2661: Cannot re-export name that is not defined in the module.
|
||||
tests/cases/compiler/b.ts(1,9): error TS2661: Cannot export 'X'. Only local declarations can be exported from a module.
|
||||
|
||||
|
||||
==== tests/cases/compiler/a.d.ts (0 errors) ====
|
||||
@@ -8,7 +8,7 @@ tests/cases/compiler/b.ts(1,9): error TS2661: Cannot re-export name that is not
|
||||
==== tests/cases/compiler/b.ts (1 errors) ====
|
||||
export {X};
|
||||
~
|
||||
!!! error TS2661: Cannot re-export name that is not defined in the module.
|
||||
!!! error TS2661: Cannot export 'X'. Only local declarations can be exported from a module.
|
||||
export function f() {
|
||||
var x: X;
|
||||
return x;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
tests/cases/compiler/exportSpecifierReferencingOuterDeclaration1.ts(3,14): error TS2661: Cannot re-export name that is not defined in the module.
|
||||
tests/cases/compiler/exportSpecifierReferencingOuterDeclaration1.ts(3,14): error TS2661: Cannot export 'X'. Only local declarations can be exported from a module.
|
||||
|
||||
|
||||
==== tests/cases/compiler/exportSpecifierReferencingOuterDeclaration1.ts (1 errors) ====
|
||||
@@ -6,6 +6,6 @@ tests/cases/compiler/exportSpecifierReferencingOuterDeclaration1.ts(3,14): error
|
||||
declare module "m" {
|
||||
export { X };
|
||||
~
|
||||
!!! error TS2661: Cannot re-export name that is not defined in the module.
|
||||
!!! error TS2661: Cannot export 'X'. Only local declarations can be exported from a module.
|
||||
export function foo(): X.bar;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
tests/cases/compiler/exportSpecifierReferencingOuterDeclaration2_B.ts(1,10): error TS2661: Cannot re-export name that is not defined in the module.
|
||||
tests/cases/compiler/exportSpecifierReferencingOuterDeclaration2_B.ts(1,10): error TS2661: Cannot export 'X'. Only local declarations can be exported from a module.
|
||||
|
||||
|
||||
==== tests/cases/compiler/exportSpecifierReferencingOuterDeclaration2_A.ts (0 errors) ====
|
||||
@@ -7,5 +7,5 @@ tests/cases/compiler/exportSpecifierReferencingOuterDeclaration2_B.ts(1,10): err
|
||||
==== tests/cases/compiler/exportSpecifierReferencingOuterDeclaration2_B.ts (1 errors) ====
|
||||
export { X };
|
||||
~
|
||||
!!! error TS2661: Cannot re-export name that is not defined in the module.
|
||||
!!! error TS2661: Cannot export 'X'. Only local declarations can be exported from a module.
|
||||
export declare function foo(): X.bar;
|
||||
@@ -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
|
||||
|
||||
@@ -53,9 +53,9 @@ var elements = names.map(function (name) {
|
||||
var xxx = elements.filter(function (e) {
|
||||
>xxx : HTMLElement[]
|
||||
>elements.filter(function (e) { return !e.isDisabled;}) : HTMLElement[]
|
||||
>elements.filter : (callbackfn: (value: HTMLElement, index: number, array: HTMLElement[]) => boolean, thisArg?: any) => HTMLElement[]
|
||||
>elements.filter : (callbackfn: (value: HTMLElement, index: number, array: HTMLElement[]) => any, thisArg?: any) => HTMLElement[]
|
||||
>elements : HTMLElement[]
|
||||
>filter : (callbackfn: (value: HTMLElement, index: number, array: HTMLElement[]) => boolean, thisArg?: any) => HTMLElement[]
|
||||
>filter : (callbackfn: (value: HTMLElement, index: number, array: HTMLElement[]) => any, thisArg?: any) => HTMLElement[]
|
||||
>function (e) { return !e.isDisabled;} : (e: HTMLElement) => boolean
|
||||
>e : HTMLElement
|
||||
|
||||
|
||||
@@ -36,12 +36,12 @@ var r = c.fn();
|
||||
var r2 = r[1];
|
||||
>r2 : Symbol(r2, Decl(indexersInClassType.ts, 13, 3))
|
||||
>r : Symbol(r, Decl(indexersInClassType.ts, 12, 3))
|
||||
>1 : Symbol(C.1, Decl(indexersInClassType.ts, 2, 24))
|
||||
>1 : Symbol(C[1], Decl(indexersInClassType.ts, 2, 24))
|
||||
|
||||
var r3 = r.a
|
||||
>r3 : Symbol(r3, Decl(indexersInClassType.ts, 14, 3))
|
||||
>r.a : Symbol(C.'a', Decl(indexersInClassType.ts, 3, 12))
|
||||
>r.a : Symbol(C['a'], Decl(indexersInClassType.ts, 3, 12))
|
||||
>r : Symbol(r, Decl(indexersInClassType.ts, 12, 3))
|
||||
>a : Symbol(C.'a', Decl(indexersInClassType.ts, 3, 12))
|
||||
>a : Symbol(C['a'], Decl(indexersInClassType.ts, 3, 12))
|
||||
|
||||
|
||||
|
||||
@@ -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,51 @@
|
||||
//// [_apply.js]
|
||||
|
||||
/**
|
||||
* A faster alternative to `Function#apply`, this function invokes `func`
|
||||
* with the `this` binding of `thisArg` and the arguments of `args`.
|
||||
*
|
||||
* @private
|
||||
* @param {Function} func The function to invoke.
|
||||
* @param {*} thisArg The `this` binding of `func`.
|
||||
* @param {...*} args The arguments to invoke `func` with.
|
||||
* @returns {*} Returns the result of `func`.
|
||||
*/
|
||||
function apply(func, thisArg, args) {
|
||||
var length = args.length;
|
||||
switch (length) {
|
||||
case 0: return func.call(thisArg);
|
||||
case 1: return func.call(thisArg, args[0]);
|
||||
case 2: return func.call(thisArg, args[0], args[1]);
|
||||
case 3: return func.call(thisArg, args[0], args[1], args[2]);
|
||||
}
|
||||
return func.apply(thisArg, args);
|
||||
}
|
||||
|
||||
export default apply;
|
||||
|
||||
//// [apply.js]
|
||||
define("_apply", ["require", "exports"], function (require, exports) {
|
||||
"use strict";
|
||||
/**
|
||||
* A faster alternative to `Function#apply`, this function invokes `func`
|
||||
* with the `this` binding of `thisArg` and the arguments of `args`.
|
||||
*
|
||||
* @private
|
||||
* @param {Function} func The function to invoke.
|
||||
* @param {*} thisArg The `this` binding of `func`.
|
||||
* @param {...*} args The arguments to invoke `func` with.
|
||||
* @returns {*} Returns the result of `func`.
|
||||
*/
|
||||
function apply(func, thisArg, args) {
|
||||
var length = args.length;
|
||||
switch (length) {
|
||||
case 0: return func.call(thisArg);
|
||||
case 1: return func.call(thisArg, args[0]);
|
||||
case 2: return func.call(thisArg, args[0], args[1]);
|
||||
case 3: return func.call(thisArg, args[0], args[1], args[2]);
|
||||
}
|
||||
return func.apply(thisArg, args);
|
||||
}
|
||||
exports.__esModule = true;
|
||||
exports["default"] = apply;
|
||||
});
|
||||
@@ -0,0 +1,68 @@
|
||||
=== tests/cases/compiler/_apply.js ===
|
||||
|
||||
/**
|
||||
* A faster alternative to `Function#apply`, this function invokes `func`
|
||||
* with the `this` binding of `thisArg` and the arguments of `args`.
|
||||
*
|
||||
* @private
|
||||
* @param {Function} func The function to invoke.
|
||||
* @param {*} thisArg The `this` binding of `func`.
|
||||
* @param {...*} args The arguments to invoke `func` with.
|
||||
* @returns {*} Returns the result of `func`.
|
||||
*/
|
||||
function apply(func, thisArg, args) {
|
||||
>apply : Symbol(apply, Decl(_apply.js, 0, 0))
|
||||
>func : Symbol(func, Decl(_apply.js, 11, 15))
|
||||
>thisArg : Symbol(thisArg, Decl(_apply.js, 11, 20))
|
||||
>args : Symbol(args, Decl(_apply.js, 11, 29))
|
||||
|
||||
var length = args.length;
|
||||
>length : Symbol(length, Decl(_apply.js, 12, 7))
|
||||
>args.length : Symbol(Array.length, Decl(lib.d.ts, --, --))
|
||||
>args : Symbol(args, Decl(_apply.js, 11, 29))
|
||||
>length : Symbol(Array.length, Decl(lib.d.ts, --, --))
|
||||
|
||||
switch (length) {
|
||||
>length : Symbol(length, Decl(_apply.js, 12, 7))
|
||||
|
||||
case 0: return func.call(thisArg);
|
||||
>func.call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>func : Symbol(func, Decl(_apply.js, 11, 15))
|
||||
>call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>thisArg : Symbol(thisArg, Decl(_apply.js, 11, 20))
|
||||
|
||||
case 1: return func.call(thisArg, args[0]);
|
||||
>func.call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>func : Symbol(func, Decl(_apply.js, 11, 15))
|
||||
>call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>thisArg : Symbol(thisArg, Decl(_apply.js, 11, 20))
|
||||
>args : Symbol(args, Decl(_apply.js, 11, 29))
|
||||
|
||||
case 2: return func.call(thisArg, args[0], args[1]);
|
||||
>func.call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>func : Symbol(func, Decl(_apply.js, 11, 15))
|
||||
>call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>thisArg : Symbol(thisArg, Decl(_apply.js, 11, 20))
|
||||
>args : Symbol(args, Decl(_apply.js, 11, 29))
|
||||
>args : Symbol(args, Decl(_apply.js, 11, 29))
|
||||
|
||||
case 3: return func.call(thisArg, args[0], args[1], args[2]);
|
||||
>func.call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>func : Symbol(func, Decl(_apply.js, 11, 15))
|
||||
>call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>thisArg : Symbol(thisArg, Decl(_apply.js, 11, 20))
|
||||
>args : Symbol(args, Decl(_apply.js, 11, 29))
|
||||
>args : Symbol(args, Decl(_apply.js, 11, 29))
|
||||
>args : Symbol(args, Decl(_apply.js, 11, 29))
|
||||
}
|
||||
return func.apply(thisArg, args);
|
||||
>func.apply : Symbol(Function.apply, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>func : Symbol(func, Decl(_apply.js, 11, 15))
|
||||
>apply : Symbol(Function.apply, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>thisArg : Symbol(thisArg, Decl(_apply.js, 11, 20))
|
||||
>args : Symbol(args, Decl(_apply.js, 11, 29))
|
||||
}
|
||||
|
||||
export default apply;
|
||||
>apply : Symbol(apply, Decl(_apply.js, 0, 0))
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
=== tests/cases/compiler/_apply.js ===
|
||||
|
||||
/**
|
||||
* A faster alternative to `Function#apply`, this function invokes `func`
|
||||
* with the `this` binding of `thisArg` and the arguments of `args`.
|
||||
*
|
||||
* @private
|
||||
* @param {Function} func The function to invoke.
|
||||
* @param {*} thisArg The `this` binding of `func`.
|
||||
* @param {...*} args The arguments to invoke `func` with.
|
||||
* @returns {*} Returns the result of `func`.
|
||||
*/
|
||||
function apply(func, thisArg, args) {
|
||||
>apply : (func: Function, thisArg: any, ...args: any[]) => any
|
||||
>func : Function
|
||||
>thisArg : any
|
||||
>args : any[]
|
||||
|
||||
var length = args.length;
|
||||
>length : number
|
||||
>args.length : number
|
||||
>args : any[]
|
||||
>length : number
|
||||
|
||||
switch (length) {
|
||||
>length : number
|
||||
|
||||
case 0: return func.call(thisArg);
|
||||
>0 : number
|
||||
>func.call(thisArg) : any
|
||||
>func.call : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; }
|
||||
>func : Function
|
||||
>call : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; }
|
||||
>thisArg : any
|
||||
|
||||
case 1: return func.call(thisArg, args[0]);
|
||||
>1 : number
|
||||
>func.call(thisArg, args[0]) : any
|
||||
>func.call : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; }
|
||||
>func : Function
|
||||
>call : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; }
|
||||
>thisArg : any
|
||||
>args[0] : any
|
||||
>args : any[]
|
||||
>0 : number
|
||||
|
||||
case 2: return func.call(thisArg, args[0], args[1]);
|
||||
>2 : number
|
||||
>func.call(thisArg, args[0], args[1]) : any
|
||||
>func.call : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; }
|
||||
>func : Function
|
||||
>call : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; }
|
||||
>thisArg : any
|
||||
>args[0] : any
|
||||
>args : any[]
|
||||
>0 : number
|
||||
>args[1] : any
|
||||
>args : any[]
|
||||
>1 : number
|
||||
|
||||
case 3: return func.call(thisArg, args[0], args[1], args[2]);
|
||||
>3 : number
|
||||
>func.call(thisArg, args[0], args[1], args[2]) : any
|
||||
>func.call : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; }
|
||||
>func : Function
|
||||
>call : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; }
|
||||
>thisArg : any
|
||||
>args[0] : any
|
||||
>args : any[]
|
||||
>0 : number
|
||||
>args[1] : any
|
||||
>args : any[]
|
||||
>1 : number
|
||||
>args[2] : any
|
||||
>args : any[]
|
||||
>2 : number
|
||||
}
|
||||
return func.apply(thisArg, args);
|
||||
>func.apply(thisArg, args) : any
|
||||
>func.apply : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, argArray?: any): U; (this: Function, thisArg: any, argArray?: any): any; }
|
||||
>func : Function
|
||||
>apply : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, argArray?: any): U; (this: Function, thisArg: any, argArray?: any): any; }
|
||||
>thisArg : any
|
||||
>args : any[]
|
||||
}
|
||||
|
||||
export default apply;
|
||||
>apply : (func: Function, thisArg: any, ...args: any[]) => any
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
tests/cases/compiler/f1.ts(3,15): error TS2665: Module augmentation cannot introduce new names in the top level scope.
|
||||
tests/cases/compiler/f2.ts(3,15): error TS2665: Module augmentation cannot introduce new names in the top level scope.
|
||||
|
||||
|
||||
==== tests/cases/compiler/f1.ts (1 errors) ====
|
||||
|
||||
declare global {
|
||||
interface Something {x}
|
||||
~~~~~~~~~
|
||||
!!! error TS2665: Module augmentation cannot introduce new names in the top level scope.
|
||||
}
|
||||
export {};
|
||||
==== tests/cases/compiler/f2.ts (1 errors) ====
|
||||
|
||||
declare global {
|
||||
interface Something {y}
|
||||
~~~~~~~~~
|
||||
!!! error TS2665: Module augmentation cannot introduce new names in the top level scope.
|
||||
}
|
||||
export {};
|
||||
==== tests/cases/compiler/f3.ts (0 errors) ====
|
||||
import "./f1";
|
||||
import "./f2";
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
=== tests/cases/compiler/f1.ts ===
|
||||
|
||||
declare global {
|
||||
>global : Symbol(, Decl(f1.ts, 0, 0))
|
||||
|
||||
interface Something {x}
|
||||
>Something : Symbol(Something, Decl(f1.ts, 1, 16), Decl(f2.ts, 1, 16))
|
||||
>x : Symbol(Something.x, Decl(f1.ts, 2, 25))
|
||||
}
|
||||
export {};
|
||||
=== tests/cases/compiler/f2.ts ===
|
||||
|
||||
declare global {
|
||||
>global : Symbol(, Decl(f2.ts, 0, 0))
|
||||
|
||||
interface Something {y}
|
||||
>Something : Symbol(Something, Decl(f1.ts, 1, 16), Decl(f2.ts, 1, 16))
|
||||
>y : Symbol(Something.y, Decl(f2.ts, 2, 25))
|
||||
}
|
||||
export {};
|
||||
=== tests/cases/compiler/f3.ts ===
|
||||
import "./f1";
|
||||
No type information for this code.import "./f2";
|
||||
No type information for this code.
|
||||
No type information for this code.
|
||||
No type information for this code.
|
||||
@@ -0,0 +1,26 @@
|
||||
=== tests/cases/compiler/f1.ts ===
|
||||
|
||||
declare global {
|
||||
>global : any
|
||||
|
||||
interface Something {x}
|
||||
>Something : Something
|
||||
>x : any
|
||||
}
|
||||
export {};
|
||||
=== tests/cases/compiler/f2.ts ===
|
||||
|
||||
declare global {
|
||||
>global : any
|
||||
|
||||
interface Something {y}
|
||||
>Something : Something
|
||||
>y : any
|
||||
}
|
||||
export {};
|
||||
=== tests/cases/compiler/f3.ts ===
|
||||
import "./f1";
|
||||
No type information for this code.import "./f2";
|
||||
No type information for this code.
|
||||
No type information for this code.
|
||||
No type information for this code.
|
||||
@@ -1,28 +0,0 @@
|
||||
tests/cases/compiler/f1.d.ts(4,19): error TS2665: Module augmentation cannot introduce new names in the top level scope.
|
||||
tests/cases/compiler/f2.d.ts(3,19): error TS2665: Module augmentation cannot introduce new names in the top level scope.
|
||||
|
||||
|
||||
==== tests/cases/compiler/f3.ts (0 errors) ====
|
||||
/// <reference path="f1.d.ts"/>
|
||||
/// <reference path="f2.d.ts"/>
|
||||
import "A";
|
||||
import "B";
|
||||
|
||||
|
||||
==== tests/cases/compiler/f1.d.ts (1 errors) ====
|
||||
|
||||
declare module "A" {
|
||||
global {
|
||||
interface Something {x}
|
||||
~~~~~~~~~
|
||||
!!! error TS2665: Module augmentation cannot introduce new names in the top level scope.
|
||||
}
|
||||
}
|
||||
==== tests/cases/compiler/f2.d.ts (1 errors) ====
|
||||
declare module "B" {
|
||||
global {
|
||||
interface Something {y}
|
||||
~~~~~~~~~
|
||||
!!! error TS2665: Module augmentation cannot introduce new names in the top level scope.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
=== tests/cases/compiler/f3.ts ===
|
||||
/// <reference path="f1.d.ts"/>
|
||||
No type information for this code./// <reference path="f2.d.ts"/>
|
||||
No type information for this code.import "A";
|
||||
No type information for this code.import "B";
|
||||
No type information for this code.
|
||||
No type information for this code.
|
||||
No type information for this code.=== tests/cases/compiler/f1.d.ts ===
|
||||
|
||||
declare module "A" {
|
||||
global {
|
||||
>global : Symbol(, Decl(f1.d.ts, 1, 20))
|
||||
|
||||
interface Something {x}
|
||||
>Something : Symbol(Something, Decl(f1.d.ts, 2, 12), Decl(f2.d.ts, 1, 12))
|
||||
>x : Symbol(Something.x, Decl(f1.d.ts, 3, 29))
|
||||
}
|
||||
}
|
||||
=== tests/cases/compiler/f2.d.ts ===
|
||||
declare module "B" {
|
||||
global {
|
||||
>global : Symbol(, Decl(f2.d.ts, 0, 20))
|
||||
|
||||
interface Something {y}
|
||||
>Something : Symbol(Something, Decl(f1.d.ts, 2, 12), Decl(f2.d.ts, 1, 12))
|
||||
>y : Symbol(Something.y, Decl(f2.d.ts, 2, 29))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
=== tests/cases/compiler/f3.ts ===
|
||||
/// <reference path="f1.d.ts"/>
|
||||
No type information for this code./// <reference path="f2.d.ts"/>
|
||||
No type information for this code.import "A";
|
||||
No type information for this code.import "B";
|
||||
No type information for this code.
|
||||
No type information for this code.
|
||||
No type information for this code.=== tests/cases/compiler/f1.d.ts ===
|
||||
|
||||
declare module "A" {
|
||||
global {
|
||||
>global : any
|
||||
|
||||
interface Something {x}
|
||||
>Something : Something
|
||||
>x : any
|
||||
}
|
||||
}
|
||||
=== tests/cases/compiler/f2.d.ts ===
|
||||
declare module "B" {
|
||||
global {
|
||||
>global : any
|
||||
|
||||
interface Something {y}
|
||||
>Something : Something
|
||||
>y : any
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
//// [tests/cases/compiler/moduleAugmentationInDependency.ts] ////
|
||||
|
||||
//// [index.d.ts]
|
||||
declare module "ext" {
|
||||
}
|
||||
export {};
|
||||
|
||||
//// [app.ts]
|
||||
import "A"
|
||||
|
||||
//// [app.js]
|
||||
"use strict";
|
||||
require("A");
|
||||
@@ -0,0 +1,8 @@
|
||||
=== /node_modules/A/index.d.ts ===
|
||||
declare module "ext" {
|
||||
No type information for this code.}
|
||||
No type information for this code.export {};
|
||||
No type information for this code.
|
||||
No type information for this code.=== /src/app.ts ===
|
||||
import "A"
|
||||
No type information for this code.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user