Skip to content

Commit 8733973

Browse files
committed
Merge branch 'streamlineDestructuring' into isolateObjectSpread
2 parents 98e192f + 0dd96f5 commit 8733973

File tree

191 files changed

+2972
-2553
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

191 files changed

+2972
-2553
lines changed

src/compiler/binder.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,8 @@ namespace ts {
234234
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
235235
const nameExpression = (<ComputedPropertyName>node.name).expression;
236236
// treat computed property names where expression is string/numeric literal as just string/numeric literal
237-
if (isStringOrNumericLiteral(nameExpression.kind)) {
238-
return (<LiteralExpression>nameExpression).text;
237+
if (isStringOrNumericLiteral(nameExpression)) {
238+
return nameExpression.text;
239239
}
240240

241241
Debug.assert(isWellKnownSymbolSyntactically(nameExpression));
@@ -3209,7 +3209,7 @@ namespace ts {
32093209
break;
32103210

32113211
case SyntaxKind.SpreadAssignment:
3212-
transformFlags |= TransformFlags.AssertESNext | TransformFlags.ContainsSpread | TransformFlags.ContainsObjectSpread;
3212+
transformFlags |= TransformFlags.AssertESNext | TransformFlags.ContainsObjectSpread;
32133213
break;
32143214

32153215
case SyntaxKind.SuperKeyword:
@@ -3261,10 +3261,10 @@ namespace ts {
32613261
transformFlags |= TransformFlags.ContainsLexicalThis;
32623262
}
32633263

3264-
if (subtreeFlags & TransformFlags.ContainsSpread) {
3264+
if (subtreeFlags & TransformFlags.ContainsObjectSpread) {
32653265
// If an ObjectLiteralExpression contains a spread element, then it
32663266
// is an ES next node.
3267-
transformFlags |= TransformFlags.AssertESNext | TransformFlags.ContainsObjectSpread;
3267+
transformFlags |= TransformFlags.AssertESNext;
32683268
}
32693269

32703270
break;

src/compiler/checker.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3030,7 +3030,7 @@ namespace ts {
30303030
}
30313031

30323032
function isComputedNonLiteralName(name: PropertyName): boolean {
3033-
return name.kind === SyntaxKind.ComputedPropertyName && !isStringOrNumericLiteral((<ComputedPropertyName>name).expression.kind);
3033+
return name.kind === SyntaxKind.ComputedPropertyName && !isStringOrNumericLiteral((<ComputedPropertyName>name).expression);
30343034
}
30353035

30363036
function getRestType(source: Type, properties: PropertyName[], symbol: Symbol): Type {
@@ -8907,7 +8907,7 @@ namespace ts {
89078907
return type;
89088908
}
89098909

8910-
function getTypeOfDestructuredProperty(type: Type, name: Identifier | LiteralExpression | ComputedPropertyName) {
8910+
function getTypeOfDestructuredProperty(type: Type, name: PropertyName) {
89118911
const text = getTextOfPropertyName(name);
89128912
return getTypeOfPropertyOfType(type, text) ||
89138913
isNumericLiteralName(text) && getIndexTypeOfType(type, IndexKind.Number) ||
@@ -9936,8 +9936,7 @@ namespace ts {
99369936
// Due to the emit for class decorators, any reference to the class from inside of the class body
99379937
// must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
99389938
// behavior of class names in ES6.
9939-
if (languageVersion === ScriptTarget.ES2015
9940-
&& declaration.kind === SyntaxKind.ClassDeclaration
9939+
if (declaration.kind === SyntaxKind.ClassDeclaration
99419940
&& nodeIsDecorated(declaration)) {
99429941
let container = getContainingClass(node);
99439942
while (container !== undefined) {
@@ -11165,10 +11164,10 @@ namespace ts {
1116511164
return links.resolvedType;
1116611165
}
1116711166

11168-
function getObjectLiteralIndexInfo(node: ObjectLiteralExpression, properties: Symbol[], kind: IndexKind): IndexInfo {
11167+
function getObjectLiteralIndexInfo(propertyNodes: NodeArray<ObjectLiteralElementLike>, offset: number, properties: Symbol[], kind: IndexKind): IndexInfo {
1116911168
const propTypes: Type[] = [];
1117011169
for (let i = 0; i < properties.length; i++) {
11171-
if (kind === IndexKind.String || isNumericName(node.properties[i].name)) {
11170+
if (kind === IndexKind.String || isNumericName(propertyNodes[i + offset].name)) {
1117211171
propTypes.push(getTypeOfSymbol(properties[i]));
1117311172
}
1117411173
}
@@ -11194,7 +11193,9 @@ namespace ts {
1119411193
let hasComputedStringProperty = false;
1119511194
let hasComputedNumberProperty = false;
1119611195

11197-
for (const memberDecl of node.properties) {
11196+
let offset = 0;
11197+
for (let i = 0; i < node.properties.length; i++) {
11198+
const memberDecl = node.properties[i];
1119811199
let member = memberDecl.symbol;
1119911200
if (memberDecl.kind === SyntaxKind.PropertyAssignment ||
1120011201
memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ||
@@ -11263,6 +11264,7 @@ namespace ts {
1126311264
return unknownType;
1126411265
}
1126511266
spread = getSpreadType(spread, type, /*isFromObjectLiteral*/ false);
11267+
offset = i + 1;
1126611268
continue;
1126711269
}
1126811270
else {
@@ -11316,8 +11318,8 @@ namespace ts {
1131611318
return createObjectLiteralType();
1131711319

1131811320
function createObjectLiteralType() {
11319-
const stringIndexInfo = hasComputedStringProperty ? getObjectLiteralIndexInfo(node, propertiesArray, IndexKind.String) : undefined;
11320-
const numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node, propertiesArray, IndexKind.Number) : undefined;
11321+
const stringIndexInfo = hasComputedStringProperty ? getObjectLiteralIndexInfo(node.properties, offset, propertiesArray, IndexKind.String) : undefined;
11322+
const numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node.properties, offset, propertiesArray, IndexKind.Number) : undefined;
1132111323
const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
1132211324
const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : TypeFlags.FreshLiteral;
1132311325
result.flags |= TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag | (typeFlags & TypeFlags.PropagatingFlags);
@@ -14501,6 +14503,8 @@ namespace ts {
1450114503
case SyntaxKind.LessThanEqualsToken:
1450214504
case SyntaxKind.GreaterThanEqualsToken:
1450314505
if (checkForDisallowedESSymbolOperand(operator)) {
14506+
leftType = getBaseTypeOfLiteralType(leftType);
14507+
rightType = getBaseTypeOfLiteralType(rightType);
1450414508
if (!isTypeComparableTo(leftType, rightType) && !isTypeComparableTo(rightType, leftType)) {
1450514509
reportOperatorError();
1450614510
}

src/compiler/emitter.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,21 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
3838
s = arguments[i];
3939
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
4040
t[p] = s[p];
41+
if (typeof Object.getOwnPropertySymbols === "function")
42+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++)
43+
t[p[i]] = s[p[i]];
4144
}
4245
return t;
4346
};`;
4447

4548
const restHelper = `
4649
var __rest = (this && this.__rest) || function (s, e) {
4750
var t = {};
48-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && !e.indexOf(p))
51+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4952
t[p] = s[p];
53+
if (typeof Object.getOwnPropertySymbols === "function")
54+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
55+
t[p[i]] = s[p[i]];
5056
return t;
5157
};`;
5258

src/compiler/factory.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,12 @@ namespace ts {
102102

103103
// Literals
104104

105-
export function createLiteral(textSource: StringLiteral | Identifier, location?: TextRange): StringLiteral;
105+
export function createLiteral(textSource: StringLiteral | NumericLiteral | Identifier, location?: TextRange): StringLiteral;
106106
export function createLiteral(value: string, location?: TextRange): StringLiteral;
107107
export function createLiteral(value: number, location?: TextRange): NumericLiteral;
108108
export function createLiteral(value: boolean, location?: TextRange): BooleanLiteral;
109109
export function createLiteral(value: string | number | boolean, location?: TextRange): PrimaryExpression;
110-
export function createLiteral(value: string | number | boolean | StringLiteral | Identifier, location?: TextRange): PrimaryExpression {
110+
export function createLiteral(value: string | number | boolean | StringLiteral | NumericLiteral | Identifier, location?: TextRange): PrimaryExpression {
111111
if (typeof value === "number") {
112112
const node = <NumericLiteral>createNode(SyntaxKind.NumericLiteral, location, /*flags*/ undefined);
113113
node.text = value.toString();
@@ -3259,7 +3259,10 @@ namespace ts {
32593259
// `"a"` in `let { "a": b } = ...`
32603260
// `1` in `let { 1: b } = ...`
32613261
if ((<BindingElement>bindingElement).propertyName) {
3262-
return (<BindingElement>bindingElement).propertyName;
3262+
const propertyName = (<BindingElement>bindingElement).propertyName;
3263+
return isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression)
3264+
? propertyName.expression
3265+
: propertyName;
32633266
}
32643267

32653268
break;
@@ -3270,7 +3273,10 @@ namespace ts {
32703273
// `"a"` in `({ "a": b } = ...)`
32713274
// `1` in `({ 1: b } = ...)`
32723275
if ((<PropertyAssignment>bindingElement).name) {
3273-
return (<PropertyAssignment>bindingElement).name;
3276+
const propertyName = (<PropertyAssignment>bindingElement).name;
3277+
return isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression)
3278+
? propertyName.expression
3279+
: propertyName;
32743280
}
32753281

32763282
break;
@@ -3282,7 +3288,9 @@ namespace ts {
32823288

32833289
const target = getTargetOfBindingOrAssignmentElement(bindingElement);
32843290
if (target && isPropertyName(target)) {
3285-
return target;
3291+
return isComputedPropertyName(target) && isStringOrNumericLiteral(target.expression)
3292+
? target.expression
3293+
: target;
32863294
}
32873295

32883296
Debug.fail("Invalid property name for binding element.");

src/compiler/parser.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,7 +1168,7 @@ namespace ts {
11681168

11691169
function parsePropertyNameWorker(allowComputedPropertyNames: boolean): PropertyName {
11701170
if (token() === SyntaxKind.StringLiteral || token() === SyntaxKind.NumericLiteral) {
1171-
return parseLiteralNode(/*internName*/ true);
1171+
return <StringLiteral | NumericLiteral>parseLiteralNode(/*internName*/ true);
11721172
}
11731173
if (allowComputedPropertyNames && token() === SyntaxKind.OpenBracketToken) {
11741174
return parseComputedPropertyName();
@@ -5514,7 +5514,7 @@ namespace ts {
55145514
node.flags |= NodeFlags.GlobalAugmentation;
55155515
}
55165516
else {
5517-
node.name = parseLiteralNode(/*internName*/ true);
5517+
node.name = <StringLiteral>parseLiteralNode(/*internName*/ true);
55185518
}
55195519

55205520
if (token() === SyntaxKind.OpenBraceToken) {

src/compiler/transformers/destructuring.ts

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -244,21 +244,26 @@ namespace ts {
244244
boundValue = ensureIdentifier(host, boundValue, reuseIdentifierExpressions, location);
245245
}
246246
let bindingElements: BindingOrAssignmentElement[];
247+
let computedTempVariables: Expression[];
247248
for (let i = 0; i < numElements; i++) {
248249
const element = elements[i];
249250
if (!getRestIndicatorOfBindingOrAssignmentElement(element)) {
251+
const propertyName = getPropertyNameOfBindingOrAssignmentElement(element);
250252
if (host.level >= FlattenLevel.ObjectRest
251253
&& !(element.transformFlags & (TransformFlags.ContainsRest | TransformFlags.ContainsObjectRest))
252-
&& !(getTargetOfBindingOrAssignmentElement(element).transformFlags & (TransformFlags.ContainsRest | TransformFlags.ContainsObjectRest))) {
254+
&& !(getTargetOfBindingOrAssignmentElement(element).transformFlags & (TransformFlags.ContainsRest | TransformFlags.ContainsObjectRest))
255+
&& !isComputedPropertyName(propertyName)) {
253256
bindingElements = append(bindingElements, element);
254257
}
255258
else {
256259
if (bindingElements) {
257260
host.emitBindingOrAssignment(host.createObjectBindingOrAssignmentPattern(bindingElements), boundValue, location, bindingTarget);
258261
bindingElements = undefined;
259262
}
260-
const propertyName = getPropertyNameOfBindingOrAssignmentElement(element);
261263
const value = createDestructuringPropertyAccess(host, boundValue, propertyName);
264+
if (isComputedPropertyName(propertyName)) {
265+
computedTempVariables = append(computedTempVariables, (value as ElementAccessExpression).argumentExpression);
266+
}
262267
flattenBindingOrAssignmentElement(host, element, value, /*location*/ element);
263268
}
264269
}
@@ -267,7 +272,7 @@ namespace ts {
267272
host.emitBindingOrAssignment(host.createObjectBindingOrAssignmentPattern(bindingElements), boundValue, location, bindingTarget);
268273
bindingElements = undefined;
269274
}
270-
const value = createRestCall(boundValue, elements, bindingTarget);
275+
const value = createRestCall(boundValue, elements, computedTempVariables, bindingTarget);
271276
flattenBindingOrAssignmentElement(host, element, value, element);
272277
}
273278
}
@@ -433,17 +438,28 @@ namespace ts {
433438

434439
/** Given value: o, propName: p, pattern: { a, b, ...p } from the original statement
435440
* `{ a, b, ...p } = o`, create `p = __rest(o, ["a", "b"]);`*/
436-
function createRestCall(value: Expression, elements: BindingOrAssignmentElement[], location: TextRange): Expression {
437-
const propertyNames: LiteralExpression[] = [];
441+
function createRestCall(value: Expression, elements: BindingOrAssignmentElement[], computedTempVariables: Expression[], location: TextRange): Expression {
442+
const propertyNames: Expression[] = [];
438443
for (let i = 0; i < elements.length - 1; i++) {
439-
if (isOmittedExpression(elements[i])) {
440-
continue;
444+
const propertyName = getPropertyNameOfBindingOrAssignmentElement(elements[i]);
445+
if (propertyName) {
446+
if (isComputedPropertyName(propertyName)) {
447+
// get the temp name and put that in there instead, like `_tmp + ""`
448+
const temp = computedTempVariables.shift();
449+
propertyNames.push(
450+
createConditional(
451+
createStrictEquality(createTypeOf(temp), createLiteral("symbol")),
452+
createToken(SyntaxKind.QuestionToken),
453+
temp,
454+
createToken(SyntaxKind.ColonToken),
455+
createAdd(temp, createLiteral(""))
456+
)
457+
);
458+
}
459+
else {
460+
propertyNames.push(createLiteral(propertyName));
461+
}
441462
}
442-
const str = <StringLiteral>createSynthesizedNode(SyntaxKind.StringLiteral);
443-
str.pos = location.pos;
444-
str.end = location.end;
445-
str.text = getTextOfPropertyName(getPropertyNameOfBindingOrAssignmentElement(elements[i]));
446-
propertyNames.push(str);
447463
}
448464
const args = createSynthesizedNodeArray([value, createArrayLiteral(propertyNames, location)]);
449465
return createCall(createIdentifier("__rest"), undefined, args);

src/compiler/transformers/es2015.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1011,7 +1011,20 @@ namespace ts {
10111011

10121012
// Return the result if we have an immediate super() call on the last statement.
10131013
if (superCallExpression && statementOffset === ctorStatements.length - 1) {
1014-
statements.push(createReturn(superCallExpression));
1014+
const returnStatement = createReturn(superCallExpression);
1015+
1016+
if (superCallExpression.kind !== SyntaxKind.BinaryExpression
1017+
|| (superCallExpression as BinaryExpression).left.kind !== SyntaxKind.CallExpression) {
1018+
Debug.fail("Assumed generated super call would have form 'super.call(...) || this'.");
1019+
}
1020+
1021+
// Shift comments from the original super call to the return statement.
1022+
setCommentRange(returnStatement, getCommentRange(
1023+
setEmitFlags(
1024+
(superCallExpression as BinaryExpression).left,
1025+
EmitFlags.NoComments)));
1026+
1027+
statements.push(returnStatement);
10151028
return SuperCaptureResult.ReplaceWithReturn;
10161029
}
10171030

src/compiler/types.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -579,17 +579,17 @@ namespace ts {
579579

580580
export type EntityName = Identifier | QualifiedName;
581581

582-
export type PropertyName = Identifier | LiteralExpression | ComputedPropertyName;
582+
export type PropertyName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName;
583583

584-
export type DeclarationName = Identifier | LiteralExpression | ComputedPropertyName | BindingPattern;
584+
export type DeclarationName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | BindingPattern;
585585

586586
export interface Declaration extends Node {
587587
_declarationBrand: any;
588588
name?: DeclarationName;
589589
}
590590

591591
export interface DeclarationStatement extends Declaration, Statement {
592-
name?: Identifier | LiteralExpression;
592+
name?: Identifier | StringLiteral | NumericLiteral;
593593
}
594594

595595
export interface ComputedPropertyName extends Node {
@@ -919,7 +919,7 @@ namespace ts {
919919

920920
export interface StringLiteral extends LiteralExpression {
921921
kind: SyntaxKind.StringLiteral;
922-
/* @internal */ textSourceNode?: Identifier | StringLiteral; // Allows a StringLiteral to get its text from another node (used by transforms).
922+
/* @internal */ textSourceNode?: Identifier | StringLiteral | NumericLiteral; // Allows a StringLiteral to get its text from another node (used by transforms).
923923
}
924924

925925
// Note: 'brands' in our syntax nodes serve to give us a small amount of nominal typing.
@@ -1746,7 +1746,7 @@ namespace ts {
17461746

17471747
export interface ModuleDeclaration extends DeclarationStatement {
17481748
kind: SyntaxKind.ModuleDeclaration;
1749-
name: Identifier | LiteralExpression;
1749+
name: Identifier | StringLiteral;
17501750
body?: ModuleBlock | NamespaceDeclaration | JSDocNamespaceDeclaration | Identifier;
17511751
}
17521752

@@ -1952,7 +1952,7 @@ namespace ts {
19521952

19531953
export interface JSDocRecordMember extends PropertySignature {
19541954
kind: SyntaxKind.JSDocRecordMember;
1955-
name: Identifier | LiteralExpression;
1955+
name: Identifier | StringLiteral | NumericLiteral;
19561956
type?: JSDocType;
19571957
}
19581958

0 commit comments

Comments
 (0)