Skip to content

Commit d89e21a

Browse files
committed
General fixes and cleanup
1 parent 1cf183b commit d89e21a

10 files changed

Lines changed: 60 additions & 68 deletions

File tree

src/compiler/factory.ts

Lines changed: 21 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -110,21 +110,15 @@ namespace ts {
110110
}
111111

112112
/**
113-
* Creates a shallow, memberwise clone of a node. The "kind", "pos", "end", "flags", and "parent"
114-
* properties are excluded by default, and can be provided via the "location", "flags", and
115-
* "parent" parameters.
116-
*
117-
* @param node The node to clone.
118-
* @param location An optional TextRange to use to supply the new position.
119-
* @param flags The NodeFlags to use for the cloned node.
120-
* @param parent The parent for the new node.
121-
* @param original An optional pointer to the original source tree node.
113+
* Creates a shallow, memberwise clone of a node with no source map location.
122114
*/
123-
export function cloneNode<T extends Node>(node: T, location?: TextRange, flags?: NodeFlags, parent?: Node, original?: Node): T {
115+
export function getSynthesizedClone<T extends Node>(node: T): T {
124116
// We don't use "clone" from core.ts here, as we need to preserve the prototype chain of
125117
// the original node. We also need to exclude specific properties and only include own-
126118
// properties (to skip members already defined on the shared prototype).
127-
const clone = <T>createNode(node.kind, location);
119+
const clone = <T>createSynthesizedNode(node.kind);
120+
clone.flags = node.flags;
121+
clone.original = node;
128122

129123
for (const key in node) {
130124
if (clone.hasOwnProperty(key) || !node.hasOwnProperty(key)) {
@@ -134,40 +128,28 @@ namespace ts {
134128
(<any>clone)[key] = (<any>node)[key];
135129
}
136130

137-
if (flags !== undefined) {
138-
clone.flags = flags;
139-
}
140-
141-
if (parent !== undefined) {
142-
clone.parent = parent;
143-
}
144-
145-
if (original !== undefined) {
146-
clone.original = original;
147-
}
148-
149131
return clone;
150132
}
151133

152134
/**
153135
* Creates a shallow, memberwise clone of a node for mutation.
154136
*/
155137
export function getMutableClone<T extends Node>(node: T): T {
156-
return cloneNode(node, /*location*/ node, node.flags, /*parent*/ undefined, /*original*/ node);
157-
}
158-
159-
/**
160-
* Creates a shallow, memberwise clone of a node with no source map location.
161-
*/
162-
export function getSynthesizedClone<T extends Node>(node: T): T {
163-
return nodeIsSynthesized(node) ? node : cloneNode(node, /*location*/ undefined, node.flags, /*parent*/ undefined, /*original*/ node);
138+
const clone = getSynthesizedClone(node);
139+
clone.pos = node.pos;
140+
clone.end = node.end;
141+
clone.parent = node.parent;
142+
return clone;
164143
}
165144

166145
/**
167146
* Creates a shallow, memberwise clone of a node at the specified source map location.
168147
*/
169148
export function getRelocatedClone<T extends Node>(node: T, location: TextRange): T {
170-
return cloneNode(node, location, node.flags, /*parent*/ undefined, /*original*/ node);
149+
const clone = getSynthesizedClone(node);
150+
clone.pos = location.pos;
151+
clone.end = location.end;
152+
return clone;
171153
}
172154

173155
export function createNodeArrayNode<T extends Node>(elements: T[]): NodeArrayNode<T> {
@@ -718,8 +700,8 @@ namespace ts {
718700

719701
export function createMemberAccessForPropertyName(target: Expression, memberName: PropertyName, location?: TextRange): MemberExpression {
720702
return isIdentifier(memberName)
721-
? createPropertyAccess(target, cloneNode(memberName), location)
722-
: createElementAccess(target, cloneNode(isComputedPropertyName(memberName) ? memberName.expression : memberName), location);
703+
? createPropertyAccess(target, getSynthesizedClone(memberName), location)
704+
: createElementAccess(target, getSynthesizedClone(isComputedPropertyName(memberName) ? memberName.expression : memberName), location);
723705
}
724706

725707
export function createRestParameter(name: string | Identifier) {
@@ -1154,15 +1136,15 @@ namespace ts {
11541136
return isQualifiedName(node)
11551137
? createPropertyAccess(
11561138
createExpressionFromEntityName(node.left),
1157-
cloneNode(node.right)
1139+
getSynthesizedClone(node.right)
11581140
)
1159-
: cloneNode(node);
1141+
: getSynthesizedClone(node);
11601142
}
11611143

11621144
export function createExpressionForPropertyName(memberName: PropertyName, location?: TextRange): Expression {
11631145
return isIdentifier(memberName) ? createLiteral(memberName.text, location)
1164-
: isComputedPropertyName(memberName) ? cloneNode(memberName.expression, location)
1165-
: cloneNode(memberName, location);
1146+
: isComputedPropertyName(memberName) ? getRelocatedClone(memberName.expression, location)
1147+
: getRelocatedClone(memberName, location);
11661148
}
11671149

11681150
// Utilities
@@ -1370,7 +1352,7 @@ namespace ts {
13701352
const callee = expression.expression;
13711353
if (callee.kind === SyntaxKind.FunctionExpression
13721354
|| callee.kind === SyntaxKind.ArrowFunction) {
1373-
const clone = cloneNode(expression, expression, expression.flags, expression.parent, expression);
1355+
const clone = getMutableClone(expression);
13741356
clone.expression = createParen(callee, /*location*/ callee);
13751357
return clone;
13761358
}

src/compiler/printer.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ const _super = (function (geti, seti) {
675675
//
676676

677677
function emitIdentifier(node: Identifier) {
678-
if (getNodeEmitFlags(node) && NodeEmitFlags.UMDDefine) {
678+
if (getNodeEmitFlags(node) & NodeEmitFlags.UMDDefine) {
679679
writeLines(umdHelper);
680680
}
681681
else {
@@ -1411,6 +1411,10 @@ const _super = (function (geti, seti) {
14111411
}
14121412

14131413
function shouldEmitBlockFunctionBodyOnSingleLine(parentNode: Node, body: Block) {
1414+
if (body.multiLine) {
1415+
return false;
1416+
}
1417+
14141418
const originalNode = getOriginalNode(parentNode);
14151419
if (isFunctionLike(originalNode) && !nodeIsSynthesized(originalNode)) {
14161420
const body = originalNode.body;

src/compiler/transformers/destructuring.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ namespace ts {
236236
emitArrayLiteralAssignment(<ArrayLiteralExpression>target, value, location);
237237
}
238238
else {
239-
const name = cloneNode(<Identifier>target, /*location*/ target, /*flags*/ undefined, /*parent*/ undefined, /*original*/ target);
239+
const name = getRelocatedClone(<Identifier>target, /*location*/ target);
240240
emitAssignment(name, value, location, /*original*/ undefined);
241241
}
242242
}
@@ -326,7 +326,7 @@ namespace ts {
326326
}
327327
}
328328
else {
329-
const clonedName = cloneNode(name, /*location*/ undefined, /*flags*/ undefined, /*parent*/ undefined, /*original*/ name);
329+
const clonedName = getSynthesizedClone(name);
330330
emitAssignment(clonedName, value, target, target);
331331
}
332332
}
@@ -365,7 +365,7 @@ namespace ts {
365365
// otherwise occur when the identifier is emitted.
366366
return createElementAccess(
367367
expression,
368-
cloneNode(propertyName)
368+
getSynthesizedClone(propertyName)
369369
);
370370
}
371371
}

src/compiler/transformers/es6.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ namespace ts {
1616
startLexicalEnvironment,
1717
endLexicalEnvironment,
1818
hoistVariableDeclaration,
19+
getNodeEmitFlags,
1920
setNodeEmitFlags,
2021
} = context;
2122

@@ -50,6 +51,7 @@ namespace ts {
5051

5152
function transformSourceFile(node: SourceFile) {
5253
currentSourceFile = node;
54+
enclosingBlockScopeContainer = node;
5355
return visitEachChild(node, visitor, context);
5456
}
5557

@@ -772,7 +774,9 @@ namespace ts {
772774
enableSubstitutionsForCapturedThis();
773775
}
774776

775-
return transformFunctionLikeToExpression(node, /*location*/ node, /*name*/ undefined);
777+
const func = transformFunctionLikeToExpression(node, /*location*/ node, /*name*/ undefined);
778+
setNodeEmitFlags(func, NodeEmitFlags.CapturesThis);
779+
return func;
776780
}
777781

778782
/**
@@ -1514,7 +1518,7 @@ namespace ts {
15141518
* @param node A template literal.
15151519
*/
15161520
function visitTemplateLiteral(node: LiteralExpression): LeftHandSideExpression {
1517-
return createLiteral(node.text);
1521+
return createLiteral(node.text, /*location*/ node);
15181522
}
15191523

15201524
/**
@@ -1579,7 +1583,7 @@ namespace ts {
15791583
// <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for both TV and TRV.
15801584
text = text.replace(/\r\n?/g, "\n");
15811585
text = escapeString(text);
1582-
return createLiteral(text);
1586+
return createLiteral(text, /*location*/ node);
15831587
}
15841588

15851589
/**
@@ -1689,7 +1693,7 @@ namespace ts {
16891693
addCaptureThisForNodeIfNeeded(statements, node);
16901694
addRange(statements, visitNodes(createNodeArray(remaining), visitor, isStatement));
16911695
addRange(statements, endLexicalEnvironment());
1692-
const clone = cloneNode(node, node, node.flags, /*parent*/ undefined, node);
1696+
const clone = getMutableClone(node);
16931697
clone.statements = createNodeArray(statements, /*location*/ node.statements);
16941698
return clone;
16951699
}
@@ -1705,7 +1709,7 @@ namespace ts {
17051709
if (enabledSubstitutions & ES6SubstitutionFlags.CapturedThis && isFunctionLike(node)) {
17061710
// If we are tracking a captured `this`, push a bit that indicates whether the
17071711
// containing function is an arrow function.
1708-
useCapturedThis = node.kind === SyntaxKind.ArrowFunction;
1712+
useCapturedThis = (getNodeEmitFlags(node) & NodeEmitFlags.CapturesThis) !== 0;
17091713
}
17101714

17111715
previousOnEmitNode(node, emit);

src/compiler/transformers/module/module.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -750,7 +750,7 @@ namespace ts {
750750
}
751751

752752
function updateSourceFile(node: SourceFile, statements: Statement[]) {
753-
const updated = cloneNode(node, node, node.flags, /*parent*/ undefined, node);
753+
const updated = getMutableClone(node);
754754
updated.statements = createNodeArray(statements, node.statements);
755755
return updated;
756756
}

src/compiler/transformers/module/system.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1271,7 +1271,7 @@ namespace ts {
12711271
}
12721272

12731273
function updateSourceFile(node: SourceFile, statements: Statement[]) {
1274-
const updated = cloneNode(node, node, node.flags, /*parent*/ undefined, node);
1274+
const updated = getMutableClone(node);
12751275
updated.statements = createNodeArray(statements, node.statements);
12761276
return updated;
12771277
}

src/compiler/transformers/ts.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,11 @@ namespace ts {
198198
// Fallback to the default visit behavior.
199199
return visitorWorker(node);
200200

201+
case SyntaxKind.SemicolonClassElement:
202+
return node;
203+
201204
default:
202-
Debug.fail("Unexpected node.");
205+
Debug.fail(`Unexpected node kind: ${formatSyntaxKind(node.kind)}.`);
203206
break;
204207
}
205208
}
@@ -867,7 +870,7 @@ namespace ts {
867870
function transformParameterWithPropertyAssignment(node: ParameterDeclaration) {
868871
Debug.assert(isIdentifier(node.name));
869872

870-
const name = cloneNode(<Identifier>node.name);
873+
const name = getSynthesizedClone(<Identifier>node.name);
871874
return startOnNewLine(
872875
createStatement(
873876
createAssignment(
@@ -1730,10 +1733,7 @@ namespace ts {
17301733
);
17311734
}
17321735
else {
1733-
return setOriginalNode(
1734-
cloneNode(name),
1735-
name
1736-
);
1736+
return getSynthesizedClone(name);
17371737
}
17381738
}
17391739

@@ -2347,7 +2347,7 @@ namespace ts {
23472347

23482348
function trackChildOfNotEmittedNode<T extends Node>(parent: Node, child: T, original: T) {
23492349
if (!child.parent && !child.original) {
2350-
child = cloneNode(child, child, child.flags, child.parent, original);
2350+
child = getMutableClone(child);
23512351
}
23522352

23532353
setNodeEmitFlags(parent, NodeEmitFlags.IsNotEmittedNode);
@@ -2403,7 +2403,7 @@ namespace ts {
24032403
);
24042404

24052405
if (isNamespaceExport(node)) {
2406-
moduleParam = createAssignment(cloneNode(node.name), moduleParam);
2406+
moduleParam = createAssignment(getSynthesizedClone(node.name), moduleParam);
24072407
}
24082408

24092409
currentNamespaceLocalName = getGeneratedNameForNode(node);
@@ -2710,7 +2710,7 @@ namespace ts {
27102710
if (declaration) {
27112711
const classAlias = currentDecoratedClassAliases[getNodeId(declaration)];
27122712
if (classAlias) {
2713-
return cloneNode(classAlias);
2713+
return getRelocatedClone(classAlias, /*location*/ node);
27142714
}
27152715
}
27162716
}

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2810,6 +2810,7 @@ namespace ts {
28102810
IsNotEmittedNode = 1 << 8, // Is a node that is not emitted but whose comments should be preserved if possible.
28112811
EmitCommentsOfNotEmittedParent = 1 << 9, // Emits comments of missing parent nodes.
28122812
NoSubstitution = 1 << 10, // Disables further substitution of an expression.
2813+
CapturesThis = 1 << 11, // The function captures a lexical `this`
28132814
}
28142815

28152816
/** Additional context provided to `visitEachChild` */

src/compiler/utilities.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1666,11 +1666,11 @@ namespace ts {
16661666
* @param parent The parent for the cloned node.
16671667
*/
16681668
export function cloneEntityName(node: EntityName, parent?: Node): EntityName {
1669-
const clone = cloneNode(node, node, node.flags, parent);
1669+
const clone = getMutableClone(node);
16701670
if (isQualifiedName(clone)) {
16711671
const { left, right } = clone;
16721672
clone.left = cloneEntityName(left, clone);
1673-
clone.right = cloneNode(right, right, right.flags, parent);
1673+
clone.right = getMutableClone(right);
16741674
}
16751675

16761676
return clone;
@@ -3066,7 +3066,8 @@ namespace ts {
30663066
|| kind === SyntaxKind.MethodDeclaration
30673067
|| kind === SyntaxKind.GetAccessor
30683068
|| kind === SyntaxKind.SetAccessor
3069-
|| kind === SyntaxKind.IndexSignature;
3069+
|| kind === SyntaxKind.IndexSignature
3070+
|| kind === SyntaxKind.SemicolonClassElement;
30703071
}
30713072

30723073
export function isObjectLiteralElement(node: Node): node is ObjectLiteralElement {

src/compiler/visitor.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ namespace ts {
516516
return undefined;
517517
}
518518

519-
Debug.assert(test === undefined || test(visited), "Wrong node type after visit.");
519+
Debug.assert(test === undefined || test(visited), "Wrong node type after visit.", () => `Node ${formatSyntaxKind(visited.kind)} did not pass test ${(<any>test).name}.`);
520520
aggregateTransformFlags(visited);
521521
return visited;
522522
}
@@ -717,7 +717,7 @@ namespace ts {
717717
from = parenthesize(from, parentNode);
718718
}
719719

720-
Debug.assert(test === undefined || test(from), "Wrong node type after visit.");
720+
Debug.assert(test === undefined || test(from), "Wrong node type after visit.", () => `Node ${formatSyntaxKind(from.kind)} did not pass test ${(<any>test).name}.`);
721721

722722
if (startOnNewLine) {
723723
from.startsOnNewLine = true;
@@ -774,7 +774,7 @@ namespace ts {
774774
*/
775775
export function mergeSourceFileLexicalEnvironment(node: SourceFile, declarations: Statement[]) {
776776
if (declarations !== undefined && declarations.length) {
777-
const mutableNode = cloneNode(node, /*location*/ node, node.flags, /*parent*/ undefined, /*original*/ node);
777+
const mutableNode = getMutableClone(node);
778778
mutableNode.statements = mergeStatements(mutableNode.statements, declarations);
779779
return mutableNode;
780780
}
@@ -791,7 +791,7 @@ namespace ts {
791791
export function mergeModuleDeclarationLexicalEnvironment(node: ModuleDeclaration, declarations: Statement[]) {
792792
Debug.assert(node.body.kind === SyntaxKind.ModuleBlock);
793793
if (declarations !== undefined && declarations.length) {
794-
const mutableNode = cloneNode(node, /*location*/ node, node.flags, /*parent*/ undefined, /*original*/ node);
794+
const mutableNode = getMutableClone(node);
795795
mutableNode.body = mergeBlockLexicalEnvironment(<ModuleBlock>node.body, declarations);
796796
return mutableNode;
797797
}
@@ -808,7 +808,7 @@ namespace ts {
808808
function mergeFunctionLikeLexicalEnvironment(node: FunctionLikeDeclaration, declarations: Statement[]) {
809809
Debug.assert(node.body !== undefined);
810810
if (declarations !== undefined && declarations.length) {
811-
const mutableNode = cloneNode(node, /*location*/ node, node.flags, /*parent*/ undefined, /*original*/ node);
811+
const mutableNode = getMutableClone(node);
812812
mutableNode.body = mergeConciseBodyLexicalEnvironment(mutableNode.body, declarations);
813813
return mutableNode;
814814
}
@@ -859,7 +859,7 @@ namespace ts {
859859
* @param declarations The lexical declarations to merge.
860860
*/
861861
function mergeBlockLexicalEnvironment<T extends Block>(node: T, declarations: Statement[]) {
862-
const mutableNode = cloneNode(node, /*location*/ node, node.flags, /*parent*/ undefined, /*original*/ node);
862+
const mutableNode = getMutableClone(node);
863863
mutableNode.statements = mergeStatements(node.statements, declarations);
864864
return mutableNode;
865865
}

0 commit comments

Comments
 (0)