Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/microsoft/TypeScript into…
Browse files Browse the repository at this point in the history
… small_ts
  • Loading branch information
orta committed Sep 26, 2019
2 parents 92b3266 + 3dd7b84 commit 392af2b
Show file tree
Hide file tree
Showing 408 changed files with 18,354 additions and 5,196 deletions.
10 changes: 6 additions & 4 deletions scripts/processDiagnosticMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ interface DiagnosticDetails {
code: number;
reportsUnnecessary?: {};
isEarly?: boolean;
elidedInCompatabilityPyramid?: boolean;
}

type InputDiagnosticMessageTable = Map<string, DiagnosticDetails>;
Expand Down Expand Up @@ -63,14 +64,15 @@ function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable, inputFil
"// generated from '" + inputFilePathRel + "' by '" + thisFilePathRel.replace(/\\/g, "/") + "'\r\n" +
"/* @internal */\r\n" +
"namespace ts {\r\n" +
" function diag(code: number, category: DiagnosticCategory, key: string, message: string, reportsUnnecessary?: {}): DiagnosticMessage {\r\n" +
" return { code, category, key, message, reportsUnnecessary };\r\n" +
" function diag(code: number, category: DiagnosticCategory, key: string, message: string, reportsUnnecessary?: {}, elidedInCompatabilityPyramid?: boolean): DiagnosticMessage {\r\n" +
" return { code, category, key, message, reportsUnnecessary, elidedInCompatabilityPyramid };\r\n" +
" }\r\n" +
" export const Diagnostics = {\r\n";
messageTable.forEach(({ code, category, reportsUnnecessary }, name) => {
messageTable.forEach(({ code, category, reportsUnnecessary, elidedInCompatabilityPyramid }, name) => {
const propName = convertPropertyName(name);
const argReportsUnnecessary = reportsUnnecessary ? `, /*reportsUnnecessary*/ ${reportsUnnecessary}` : "";
result += ` ${propName}: diag(${code}, DiagnosticCategory.${category}, "${createKey(propName, code)}", ${JSON.stringify(name)}${argReportsUnnecessary}),\r\n`;
const argElidedInCompatabilityPyramid = elidedInCompatabilityPyramid ? `${!reportsUnnecessary ? ", /*reportsUnnecessary*/ undefined" : ""}, /*elidedInCompatabilityPyramid*/ ${elidedInCompatabilityPyramid}` : "";
result += ` ${propName}: diag(${code}, DiagnosticCategory.${category}, "${createKey(propName, code)}", ${JSON.stringify(name)}${argReportsUnnecessary}${argElidedInCompatabilityPyramid}),\r\n`;
});

result += " };\r\n}";
Expand Down
54 changes: 39 additions & 15 deletions src/compiler/binder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ namespace ts {
if (!isIIFE) {
currentFlow = { flags: FlowFlags.Start };
if (containerFlags & (ContainerFlags.IsFunctionExpression | ContainerFlags.IsObjectLiteralOrClassExpressionMethod)) {
currentFlow.container = <FunctionExpression | ArrowFunction | MethodDeclaration>node;
currentFlow.node = <FunctionExpression | ArrowFunction | MethodDeclaration>node;
}
}
// We create a return control flow graph for IIFEs and constructors. For constructors
Expand All @@ -581,6 +581,7 @@ namespace ts {
if (!(currentFlow.flags & FlowFlags.Unreachable) && containerFlags & ContainerFlags.IsFunctionLike && nodeIsPresent((<FunctionLikeDeclaration>node).body)) {
node.flags |= NodeFlags.HasImplicitReturn;
if (hasExplicitReturn) node.flags |= NodeFlags.HasExplicitReturn;
(<FunctionLikeDeclaration>node).endFlowNode = currentFlow;
}
if (node.kind === SyntaxKind.SourceFile) {
node.flags |= emitFlags;
Expand Down Expand Up @@ -671,6 +672,9 @@ namespace ts {
bindJSDoc(node);
return;
}
if (node.kind >= SyntaxKind.FirstStatement && node.kind <= SyntaxKind.LastStatement && !options.allowUnreachableCode) {
node.flowNode = currentFlow;
}
switch (node.kind) {
case SyntaxKind.WhileStatement:
bindWhileStatement(<WhileStatement>node);
Expand Down Expand Up @@ -708,6 +712,9 @@ namespace ts {
case SyntaxKind.CaseClause:
bindCaseClause(<CaseClause>node);
break;
case SyntaxKind.ExpressionStatement:
bindExpressionStatement(<ExpressionStatement>node);
break;
case SyntaxKind.LabeledStatement:
bindLabeledStatement(<LabeledStatement>node);
break;
Expand Down Expand Up @@ -845,17 +852,11 @@ namespace ts {
}

function createBranchLabel(): FlowLabel {
return {
flags: FlowFlags.BranchLabel,
antecedents: undefined
};
return { flags: FlowFlags.BranchLabel, antecedents: undefined };
}

function createLoopLabel(): FlowLabel {
return {
flags: FlowFlags.LoopLabel,
antecedents: undefined
};
return { flags: FlowFlags.LoopLabel, antecedents: undefined };
}

function setFlowNodeReferenced(flow: FlowNode) {
Expand Down Expand Up @@ -885,26 +886,30 @@ namespace ts {
return antecedent;
}
setFlowNodeReferenced(antecedent);
return flowNodeCreated({ flags, expression, antecedent });
return flowNodeCreated({ flags, antecedent, node: expression });
}

function createFlowSwitchClause(antecedent: FlowNode, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number): FlowNode {
if (!isNarrowingExpression(switchStatement.expression)) {
return antecedent;
}
setFlowNodeReferenced(antecedent);
return flowNodeCreated({ flags: FlowFlags.SwitchClause, switchStatement, clauseStart, clauseEnd, antecedent });
return flowNodeCreated({ flags: FlowFlags.SwitchClause, antecedent, switchStatement, clauseStart, clauseEnd });
}

function createFlowAssignment(antecedent: FlowNode, node: Expression | VariableDeclaration | BindingElement): FlowNode {
setFlowNodeReferenced(antecedent);
return flowNodeCreated({ flags: FlowFlags.Assignment, antecedent, node });
}

function createFlowCall(antecedent: FlowNode, node: CallExpression): FlowNode {
setFlowNodeReferenced(antecedent);
return flowNodeCreated({ flags: FlowFlags.Call, antecedent, node });
}

function createFlowArrayMutation(antecedent: FlowNode, node: CallExpression | BinaryExpression): FlowNode {
setFlowNodeReferenced(antecedent);
const res: FlowArrayMutation = flowNodeCreated({ flags: FlowFlags.ArrayMutation, antecedent, node });
return res;
return flowNodeCreated({ flags: FlowFlags.ArrayMutation, antecedent, node });
}

function finishFlowLabel(flow: FlowLabel): FlowNode {
Expand Down Expand Up @@ -1030,12 +1035,12 @@ namespace ts {
function bindForInOrForOfStatement(node: ForInOrOfStatement): void {
const preLoopLabel = createLoopLabel();
const postLoopLabel = createBranchLabel();
bind(node.expression);
addAntecedent(preLoopLabel, currentFlow);
currentFlow = preLoopLabel;
if (node.kind === SyntaxKind.ForOfStatement) {
bind(node.awaitModifier);
}
bind(node.expression);
addAntecedent(postLoopLabel, currentFlow);
bind(node.initializer);
if (node.initializer.kind !== SyntaxKind.VariableDeclarationList) {
Expand Down Expand Up @@ -1222,7 +1227,8 @@ namespace ts {
addAntecedent(postSwitchLabel, currentFlow);
const hasDefault = forEach(node.caseBlock.clauses, c => c.kind === SyntaxKind.DefaultClause);
// We mark a switch statement as possibly exhaustive if it has no default clause and if all
// case clauses have unreachable end points (e.g. they all return).
// case clauses have unreachable end points (e.g. they all return). Note, we no longer need
// this property in control flow analysis, it's there only for backwards compatibility.
node.possiblyExhaustive = !hasDefault && !postSwitchLabel.antecedents;
if (!hasDefault) {
addAntecedent(postSwitchLabel, createFlowSwitchClause(preSwitchCaseFlow, node, 0, 0));
Expand Down Expand Up @@ -1281,6 +1287,24 @@ namespace ts {
activeLabels!.pop();
}

function isDottedName(node: Expression): boolean {
return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.ThisKeyword ||
node.kind === SyntaxKind.PropertyAccessExpression && isDottedName((<PropertyAccessExpression>node).expression) ||
node.kind === SyntaxKind.ParenthesizedExpression && isDottedName((<ParenthesizedExpression>node).expression);
}

function bindExpressionStatement(node: ExpressionStatement): void {
bind(node.expression);
// A top level call expression with a dotted function name and at least one argument
// is potentially an assertion and is therefore included in the control flow.
if (node.expression.kind === SyntaxKind.CallExpression) {
const call = <CallExpression>node.expression;
if (isDottedName(call.expression)) {
currentFlow = createFlowCall(currentFlow, call);
}
}
}

function bindLabeledStatement(node: LabeledStatement): void {
const preStatementLabel = createLoopLabel();
const postStatementLabel = createBranchLabel();
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ namespace ts {
const options = program.getCompilerOptions();
forEach(program.getSourceFiles(), f =>
program.isSourceFileDefaultLibrary(f) &&
!skipTypeChecking(f, options) &&
!skipTypeChecking(f, options, program) &&
removeSemanticDiagnosticsOf(state, f.path)
);
}
Expand Down
Loading

0 comments on commit 392af2b

Please sign in to comment.