mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-26 09:48:06 -05:00
Fix deferred export of array binding pattern
This commit is contained in:
@@ -1150,8 +1150,8 @@ namespace ts {
|
||||
currentFlow = finishFlowLabel(postExpressionLabel);
|
||||
}
|
||||
|
||||
function bindInitializedVariableFlow(node: VariableDeclaration | BindingElement) {
|
||||
const name = node.name;
|
||||
function bindInitializedVariableFlow(node: VariableDeclaration | ArrayBindingElement) {
|
||||
const name = !isOmittedExpression(node) ? node.name : undefined;
|
||||
if (isBindingPattern(name)) {
|
||||
for (const child of name.elements) {
|
||||
bindInitializedVariableFlow(child);
|
||||
|
||||
@@ -2505,8 +2505,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function buildBindingElementDisplay(bindingElement: BindingElement, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) {
|
||||
if (bindingElement.kind === SyntaxKind.OmittedExpression) {
|
||||
function buildBindingElementDisplay(bindingElement: ArrayBindingElement, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) {
|
||||
if (isOmittedExpression(bindingElement)) {
|
||||
return;
|
||||
}
|
||||
Debug.assert(bindingElement.kind === SyntaxKind.BindingElement);
|
||||
@@ -3125,7 +3125,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Return the type implied by an object binding pattern
|
||||
function getTypeFromObjectBindingPattern(pattern: BindingPattern, includePatternInType: boolean, reportErrors: boolean): Type {
|
||||
function getTypeFromObjectBindingPattern(pattern: ObjectBindingPattern, includePatternInType: boolean, reportErrors: boolean): Type {
|
||||
const members = createMap<Symbol>();
|
||||
let hasComputedProperties = false;
|
||||
forEach(pattern.elements, e => {
|
||||
@@ -3156,11 +3156,12 @@ namespace ts {
|
||||
// Return the type implied by an array binding pattern
|
||||
function getTypeFromArrayBindingPattern(pattern: BindingPattern, includePatternInType: boolean, reportErrors: boolean): Type {
|
||||
const elements = pattern.elements;
|
||||
if (elements.length === 0 || elements[elements.length - 1].dotDotDotToken) {
|
||||
const lastElement = lastOrUndefined(elements);
|
||||
if (elements.length === 0 || (!isOmittedExpression(lastElement) && lastElement.dotDotDotToken)) {
|
||||
return languageVersion >= ScriptTarget.ES6 ? createIterableType(anyType) : anyArrayType;
|
||||
}
|
||||
// If the pattern has at least one element, and no rest element, then it should imply a tuple type.
|
||||
const elementTypes = map(elements, e => e.kind === SyntaxKind.OmittedExpression ? anyType : getTypeFromBindingElement(e, includePatternInType, reportErrors));
|
||||
const elementTypes = map(elements, e => isOmittedExpression(e) ? anyType : getTypeFromBindingElement(e, includePatternInType, reportErrors));
|
||||
let result = createTupleType(elementTypes);
|
||||
if (includePatternInType) {
|
||||
result = cloneTypeReference(result);
|
||||
@@ -3178,8 +3179,8 @@ namespace ts {
|
||||
// the parameter.
|
||||
function getTypeFromBindingPattern(pattern: BindingPattern, includePatternInType?: boolean, reportErrors?: boolean): Type {
|
||||
return pattern.kind === SyntaxKind.ObjectBindingPattern
|
||||
? getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors)
|
||||
: getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors);
|
||||
? getTypeFromObjectBindingPattern(<ObjectBindingPattern>pattern, includePatternInType, reportErrors)
|
||||
: getTypeFromArrayBindingPattern(<ArrayBindingPattern>pattern, includePatternInType, reportErrors);
|
||||
}
|
||||
|
||||
// Return the type associated with a variable, parameter, or property declaration. In the simple case this is the type
|
||||
@@ -12413,7 +12414,7 @@ namespace ts {
|
||||
function assignBindingElementTypes(node: VariableLikeDeclaration) {
|
||||
if (isBindingPattern(node.name)) {
|
||||
for (const element of (<BindingPattern>node.name).elements) {
|
||||
if (element.kind !== SyntaxKind.OmittedExpression) {
|
||||
if (!isOmittedExpression(element)) {
|
||||
if (element.name.kind === SyntaxKind.Identifier) {
|
||||
getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element);
|
||||
}
|
||||
@@ -13889,7 +13890,12 @@ namespace ts {
|
||||
pattern: BindingPattern,
|
||||
predicateVariableNode: Node,
|
||||
predicateVariableName: string) {
|
||||
for (const { name } of pattern.elements) {
|
||||
for (const element of pattern.elements) {
|
||||
if (isOmittedExpression(element)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const name = element.name;
|
||||
if (name.kind === SyntaxKind.Identifier &&
|
||||
(<Identifier>name).text === predicateVariableName) {
|
||||
error(predicateVariableNode,
|
||||
@@ -19999,7 +20005,7 @@ namespace ts {
|
||||
else {
|
||||
const elements = (<BindingPattern>name).elements;
|
||||
for (const element of elements) {
|
||||
if (element.kind !== SyntaxKind.OmittedExpression) {
|
||||
if (!isOmittedExpression(element)) {
|
||||
checkGrammarNameInLetOrConstDeclarations(element.name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -554,9 +554,9 @@ const _super = (function (geti, seti) {
|
||||
|
||||
// Binding patterns
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
return emitObjectBindingPattern(<BindingPattern>node);
|
||||
return emitObjectBindingPattern(<ObjectBindingPattern>node);
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
return emitArrayBindingPattern(<BindingPattern>node);
|
||||
return emitArrayBindingPattern(<ArrayBindingPattern>node);
|
||||
case SyntaxKind.BindingElement:
|
||||
return emitBindingElement(<BindingElement>node);
|
||||
|
||||
|
||||
@@ -368,13 +368,13 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createArrayBindingPattern(elements: BindingElement[], location?: TextRange) {
|
||||
export function createArrayBindingPattern(elements: ArrayBindingElement[], location?: TextRange) {
|
||||
const node = <ArrayBindingPattern>createNode(SyntaxKind.ArrayBindingPattern, location);
|
||||
node.elements = createNodeArray(elements);
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateArrayBindingPattern(node: ArrayBindingPattern, elements: BindingElement[]) {
|
||||
export function updateArrayBindingPattern(node: ArrayBindingPattern, elements: ArrayBindingElement[]) {
|
||||
if (node.elements !== elements) {
|
||||
return updateNode(createArrayBindingPattern(elements, node), node);
|
||||
}
|
||||
|
||||
@@ -4815,9 +4815,9 @@ namespace ts {
|
||||
|
||||
// DECLARATIONS
|
||||
|
||||
function parseArrayBindingElement(): BindingElement {
|
||||
function parseArrayBindingElement(): ArrayBindingElement {
|
||||
if (token() === SyntaxKind.CommaToken) {
|
||||
return <BindingElement>createNode(SyntaxKind.OmittedExpression);
|
||||
return <OmittedExpression>createNode(SyntaxKind.OmittedExpression);
|
||||
}
|
||||
const node = <BindingElement>createNode(SyntaxKind.BindingElement);
|
||||
node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken);
|
||||
@@ -4842,16 +4842,16 @@ namespace ts {
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseObjectBindingPattern(): BindingPattern {
|
||||
const node = <BindingPattern>createNode(SyntaxKind.ObjectBindingPattern);
|
||||
function parseObjectBindingPattern(): ObjectBindingPattern {
|
||||
const node = <ObjectBindingPattern>createNode(SyntaxKind.ObjectBindingPattern);
|
||||
parseExpected(SyntaxKind.OpenBraceToken);
|
||||
node.elements = parseDelimitedList(ParsingContext.ObjectBindingElements, parseObjectBindingElement);
|
||||
parseExpected(SyntaxKind.CloseBraceToken);
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseArrayBindingPattern(): BindingPattern {
|
||||
const node = <BindingPattern>createNode(SyntaxKind.ArrayBindingPattern);
|
||||
function parseArrayBindingPattern(): ArrayBindingPattern {
|
||||
const node = <ArrayBindingPattern>createNode(SyntaxKind.ArrayBindingPattern);
|
||||
parseExpected(SyntaxKind.OpenBracketToken);
|
||||
node.elements = parseDelimitedList(ParsingContext.ArrayBindingElements, parseArrayBindingElement);
|
||||
parseExpected(SyntaxKind.CloseBracketToken);
|
||||
|
||||
@@ -326,12 +326,15 @@ namespace ts {
|
||||
}
|
||||
for (let i = 0; i < numElements; i++) {
|
||||
const element = elements[i];
|
||||
if (name.kind === SyntaxKind.ObjectBindingPattern) {
|
||||
if (isOmittedExpression(element)) {
|
||||
continue;
|
||||
}
|
||||
else if (name.kind === SyntaxKind.ObjectBindingPattern) {
|
||||
// Rewrite element to a declaration with an initializer that fetches property
|
||||
const propName = element.propertyName || <Identifier>element.name;
|
||||
emitBindingElement(element, createDestructuringPropertyAccess(value, propName));
|
||||
}
|
||||
else if (element.kind !== SyntaxKind.OmittedExpression) {
|
||||
else {
|
||||
if (!element.dotDotDotToken) {
|
||||
// Rewrite element to a declaration that accesses array element at index i
|
||||
emitBindingElement(element, createElementAccess(value, i));
|
||||
|
||||
@@ -1945,7 +1945,9 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
for (const element of (<BindingPattern>node).elements) {
|
||||
visit(element.name);
|
||||
if (!isOmittedExpression(element)) {
|
||||
visit(element.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2289,7 +2291,9 @@ namespace ts {
|
||||
const name = decl.name;
|
||||
if (isBindingPattern(name)) {
|
||||
for (const element of name.elements) {
|
||||
processLoopVariableDeclaration(element, loopParameters, loopOutParameters);
|
||||
if (!isOmittedExpression(element)) {
|
||||
processLoopVariableDeclaration(element, loopParameters, loopOutParameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -660,7 +660,9 @@ namespace ts {
|
||||
function addExportMemberAssignmentsForBindingName(resultStatements: Statement[], name: BindingName): void {
|
||||
if (isBindingPattern(name)) {
|
||||
for (const element of name.elements) {
|
||||
addExportMemberAssignmentsForBindingName(resultStatements, element.name);
|
||||
if (!isOmittedExpression(element)) {
|
||||
addExportMemberAssignmentsForBindingName(resultStatements, element.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -1368,7 +1368,11 @@ namespace ts {
|
||||
exportedFunctionDeclarations.push(createDeclarationExport(node));
|
||||
}
|
||||
|
||||
function hoistBindingElement(node: VariableDeclaration | BindingElement, isExported: boolean): void {
|
||||
function hoistBindingElement(node: VariableDeclaration | ArrayBindingElement, isExported: boolean): void {
|
||||
if (isOmittedExpression(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const name = node.name;
|
||||
if (isIdentifier(name)) {
|
||||
hoistVariableDeclaration(getSynthesizedClone(name));
|
||||
@@ -1381,11 +1385,11 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function hoistExportedBindingElement(node: VariableDeclaration | BindingElement) {
|
||||
function hoistExportedBindingElement(node: VariableDeclaration | ArrayBindingElement) {
|
||||
hoistBindingElement(node, /*isExported*/ true);
|
||||
}
|
||||
|
||||
function hoistNonExportedBindingElement(node: VariableDeclaration | BindingElement) {
|
||||
function hoistNonExportedBindingElement(node: VariableDeclaration | ArrayBindingElement) {
|
||||
hoistBindingElement(node, /*isExported*/ false);
|
||||
}
|
||||
|
||||
|
||||
@@ -2187,7 +2187,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The function expression node.
|
||||
*/
|
||||
function visitFunctionExpression(node: FunctionExpression) {
|
||||
function visitFunctionExpression(node: FunctionExpression): Expression {
|
||||
if (nodeIsMissing(node.body)) {
|
||||
return createOmittedExpression();
|
||||
}
|
||||
|
||||
@@ -688,14 +688,20 @@ namespace ts {
|
||||
}
|
||||
|
||||
export interface BindingPattern extends Node {
|
||||
elements: NodeArray<BindingElement>;
|
||||
elements: NodeArray<BindingElement | ArrayBindingElement>;
|
||||
}
|
||||
|
||||
// @kind(SyntaxKind.ObjectBindingPattern)
|
||||
export interface ObjectBindingPattern extends BindingPattern { }
|
||||
export interface ObjectBindingPattern extends BindingPattern {
|
||||
elements: NodeArray<BindingElement>;
|
||||
}
|
||||
|
||||
export type ArrayBindingElement = BindingElement | OmittedExpression;
|
||||
|
||||
// @kind(SyntaxKind.ArrayBindingPattern)
|
||||
export interface ArrayBindingPattern extends BindingPattern { }
|
||||
export interface ArrayBindingPattern extends BindingPattern {
|
||||
elements: NodeArray<ArrayBindingElement>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Several node kinds share function-like features such as a signature,
|
||||
@@ -868,7 +874,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
// @kind(SyntaxKind.OmittedExpression)
|
||||
export interface OmittedExpression extends Expression { }
|
||||
export interface OmittedExpression extends Expression {
|
||||
_omittedExpressionBrand: any;
|
||||
}
|
||||
|
||||
// Represents an expression that is elided as part of a transformation to emit comments on a
|
||||
// not-emitted node. The 'expression' property of a NotEmittedExpression should be emitted.
|
||||
|
||||
@@ -3701,6 +3701,12 @@ namespace ts {
|
||||
return node.kind === SyntaxKind.BindingElement;
|
||||
}
|
||||
|
||||
export function isArrayBindingElement(node: Node): node is ArrayBindingElement {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.BindingElement
|
||||
|| kind === SyntaxKind.OmittedExpression;
|
||||
}
|
||||
|
||||
// Expression
|
||||
|
||||
export function isPropertyAccessExpression(node: Node): node is PropertyAccessExpression {
|
||||
@@ -3817,6 +3823,10 @@ namespace ts {
|
||||
|| isPartiallyEmittedExpression(node);
|
||||
}
|
||||
|
||||
export function isOmittedExpression(node: Node): node is OmittedExpression {
|
||||
return node.kind === SyntaxKind.OmittedExpression;
|
||||
}
|
||||
|
||||
// Misc
|
||||
|
||||
export function isTemplateSpan(node: Node): node is TemplateSpan {
|
||||
|
||||
@@ -757,7 +757,7 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
return updateArrayBindingPattern(<ArrayBindingPattern>node,
|
||||
visitNodes((<ArrayBindingPattern>node).elements, visitor, isBindingElement));
|
||||
visitNodes((<ArrayBindingPattern>node).elements, visitor, isArrayBindingElement));
|
||||
|
||||
case SyntaxKind.BindingElement:
|
||||
return updateBindingElement(<BindingElement>node,
|
||||
|
||||
@@ -1192,7 +1192,7 @@ namespace ts.Completions {
|
||||
}
|
||||
if (canGetType) {
|
||||
typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer);
|
||||
existingMembers = (<BindingPattern>objectLikeContainer).elements;
|
||||
existingMembers = (<ObjectBindingPattern>objectLikeContainer).elements;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
Reference in New Issue
Block a user