Add parameter initialisers to control flow

Also a little code to emit them in declarations, but this doesn't work
yet.
This commit is contained in:
Nathan Shively-Sanders 2016-12-14 08:48:39 -08:00
parent caad486a46
commit bb6f3ad29a
3 changed files with 19 additions and 14 deletions

View File

@ -810,7 +810,7 @@ namespace ts {
};
}
function createFlowAssignment(antecedent: FlowNode, node: Expression | VariableDeclaration | BindingElement): FlowNode {
function createFlowAssignment(antecedent: FlowNode, node: Expression | VariableDeclaration | BindingElement | ParameterDeclaration): FlowNode {
setFlowNodeReferenced(antecedent);
return <FlowAssignment>{
flags: FlowFlags.Assignment,
@ -2311,6 +2311,9 @@ namespace ts {
}
else {
declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes);
if (node.initializer) {
currentFlow = createFlowAssignment(currentFlow, node);
}
}
// If this is a property-parameter, then also declare the property symbol into the

View File

@ -3245,7 +3245,9 @@ namespace ts {
// Use type from type annotation if one is present
if (declaration.type) {
return addOptionality(getTypeFromTypeNode(declaration.type), /*optional*/ declaration.questionToken && includeOptionality);
const isOptional = declaration.questionToken ||
(declaration.initializer && declaration.kind === SyntaxKind.Parameter && !(getModifierFlags(declaration) & ModifierFlags.ParameterPropertyModifier));
return addOptionality(getTypeFromTypeNode(declaration.type), /*optional*/ isOptional && includeOptionality);
}
if ((compilerOptions.noImplicitAny || declaration.flags & NodeFlags.JavaScriptFile) &&
@ -9042,8 +9044,8 @@ namespace ts {
switch (source.kind) {
case SyntaxKind.Identifier:
return target.kind === SyntaxKind.Identifier && getResolvedSymbol(<Identifier>source) === getResolvedSymbol(<Identifier>target) ||
(target.kind === SyntaxKind.VariableDeclaration || target.kind === SyntaxKind.BindingElement) &&
getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(<Identifier>source)) === getSymbolOfNode(target);
(target.kind === SyntaxKind.VariableDeclaration || target.kind === SyntaxKind.BindingElement) && getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(<Identifier>source)) === getSymbolOfNode(target) ||
target.kind === SyntaxKind.Parameter && getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(source as Identifier)) === getSymbolOfNode(target);
case SyntaxKind.ThisKeyword:
return target.kind === SyntaxKind.ThisKeyword;
case SyntaxKind.PropertyAccessExpression:
@ -9314,7 +9316,7 @@ namespace ts {
return links.resolvedType || getTypeOfExpression(node);
}
function getInitialTypeOfVariableDeclaration(node: VariableDeclaration) {
function getInitialTypeOfVariableDeclaration(node: VariableDeclaration | ParameterDeclaration) {
if (node.initializer) {
return getTypeOfInitializer(node.initializer);
}
@ -9327,15 +9329,15 @@ namespace ts {
return unknownType;
}
function getInitialType(node: VariableDeclaration | BindingElement) {
return node.kind === SyntaxKind.VariableDeclaration ?
getInitialTypeOfVariableDeclaration(<VariableDeclaration>node) :
function getInitialType(node: VariableDeclaration | BindingElement | ParameterDeclaration) {
return node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.Parameter ?
getInitialTypeOfVariableDeclaration(<VariableDeclaration | ParameterDeclaration>node) :
getInitialTypeOfBindingElement(<BindingElement>node);
}
function getInitialOrAssignedType(node: VariableDeclaration | BindingElement | Expression) {
return node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement ?
getInitialType(<VariableDeclaration | BindingElement>node) :
return node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement || node.kind === SyntaxKind.Parameter ?
getInitialType(<VariableDeclaration | BindingElement | ParameterDeclaration>node) :
getAssignedType(<Expression>node);
}

View File

@ -319,12 +319,12 @@ namespace ts {
}
}
function writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, type: TypeNode, getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic) {
function writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, type: TypeNode, getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic, addUndefined?: boolean) {
writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic;
write(": ");
if (type) {
// Write the type
emitType(type);
emitType(type, addUndefined);
}
else {
errorNameNode = declaration.name;
@ -384,7 +384,7 @@ namespace ts {
emitType(type);
}
function emitType(type: TypeNode | Identifier | QualifiedName) {
function emitType(type: TypeNode | Identifier | QualifiedName, addUndefined?: boolean) {
switch (type.kind) {
case SyntaxKind.AnyKeyword:
case SyntaxKind.StringKeyword:
@ -1593,7 +1593,7 @@ namespace ts {
emitTypeOfVariableDeclarationFromTypeLiteral(node);
}
else if (!hasModifier(node.parent, ModifierFlags.Private)) {
writeTypeOfDeclaration(node, node.type, getParameterDeclarationTypeVisibilityError);
writeTypeOfDeclaration(node, node.type, getParameterDeclarationTypeVisibilityError, !!node.initializer && !(getModifierFlags(node) & ModifierFlags.ParameterPropertyModifier));
}
function getParameterDeclarationTypeVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {