8000 Merge branch 'transforms-transformer-es6' into transforms-transformer… · icssjs/TypeScript@c4a75ba · GitHub
[go: up one dir, main page]

Skip to content

Commit c4a75ba

Browse files
committed
Merge branch 'transforms-transformer-es6' into transforms-transformer-module
2 parents 70cbb9b + 1c73818 commit c4a75ba

File tree

5 files changed

+126
-209
lines changed

5 files changed

+126
-209
lines changed

src/compiler/printer.ts

Lines changed: 51 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,7 @@ const _super = (function (geti, seti) {
152152
let isEmitNotificationEnabled: (node: Node) => boolean;
153153
let expressionSubstitution: (node: Expression) => Expression;
154154
let identifierSubstitution: (node: Identifier) => Identifier;
155-
let onBeforeEmitNode: (node: Node) => void;
156-
let onAfterEmitNode: (node: Node) => void;
155+
let onEmitNode: (node: Node, emit: (node: Node) => void) => void;
157156
let nodeToGeneratedName: string[];
158157
let generatedNameSet: Map<string>;
159158
let tempFlags: TempFlags;
@@ -215,8 +214,7 @@ const _super = (function (geti, seti) {
215214
isEmitNotificationEnabled = undefined;
216215
expressionSubstitution = undefined;
217216
identifierSubstitution = undefined;
218-
onBeforeEmitNode = undefined;
219-
onAfterEmitNode = undefined;
217+
onEmitNode = undefined;
220218
tempFlags = TempFlags.Auto;
221219
currentSourceFile = undefined;
222220
currentText = undefined;
@@ -237,8 +235,7 @@ const _super = (function (geti, seti) {
237235
isEmitNotificationEnabled = context.isEmitNotificationEnabled;
238236
expressionSubstitution = context.expressionSubstitution;
239237
identifierSubstitution = context.identifierSubstitution;
240-
onBeforeEmitNode = context.onBeforeEmitNode;
241-
onAfterEmitNode = context.onAfterEmitNode;
238+
onEmitNode = context.onEmitNode;
242239
return printSourceFile;
243240
}
244241

@@ -252,46 +249,62 @@ const _super = (function (geti, seti) {
252249
return node;
253250
}
254251

252+
/**
253+
* Emits a node.
254+
*/
255255
function emit(node: Node) {
256-
emitWithWorker(node, emitWorker);
256+
emitNodeWithNotificationOption(node, emitWithoutNotificationOption);
257+
}
258+
259+
/**
260+
* Emits a node without calling onEmitNode.
261+
* NOTE: Do not call this method directly.
262+
*/
263+
function emitWithoutNotificationOption(node: Node) {
264+
emitNodeWithWorker(node, emitWorker);
257265
}
258266

267+
/**
268+
* Emits an expression node.
269+
*/
259270
function emitExpression(node: Expression) {
260-
emitWithWorker(node, emitExpressionWorker);
271+
emitNodeWithNotificationOption(node, emitExpressionWithoutNotificationOption);
272+
}
273+
274+
/**
275+
* Emits an expression without calling onEmitNode.
276+
* NOTE: Do not call this method directly.
277+
*/
278+
function emitExpressionWithoutNotificationOption(node: Expression) {
279+
emitNodeWithWorker(node, emitExpressionWorker);
261280
}
262281

263-
function emitWithWorker(node: Node, emitWorker: (node: Node) => void) {
282+
/**
283+
* Emits a node with emit notification if available.
284+
*/
285+
function emitNodeWithNotificationOption(node: Node, emit: (node: Node) => void) {
264286
if (node) {
265-
const adviseOnEmit = isEmitNotificationEnabled(node);
266-
if (adviseOnEmit && onBeforeEmitNode) {
267-
onBeforeEmitNode(node);
287+
if (isEmitNotificationEnabled(node)) {
288+
onEmitNode(node, emit);
289+
}
290+
else {
291+
emit(node);
268292
}
293+
}
294+
}
269295

296+
function emitNodeWithWorker(node: Node, emitWorker: (node: Node) => void) {
297+
if (node) {
270298
const leadingComments = getLeadingComments(node, getNotEmittedParent);
271299
const trailingComments = getTrailingComments(node, getNotEmittedParent);
272300
emitLeadingComments(node, leadingComments);
273301
emitStart(node);
274302
emitWorker(node);
275303
emitEnd(node);
276304
emitTrailingComments(node, trailingComments);
277-
278-
if (adviseOnEmit && onAfterEmitNode) {
279-
onAfterEmitNode(node);
280-
}
281305
}
282306
}
283307

284-
function getNotEmittedParent(node: Node): Node {
285-
if (getNodeEmitFlags(node) & NodeEmitFlags.EmitCommentsOfNotEmittedParent) {
286-
const parent = getOriginalNode(node).parent;
287-
if (getNodeEmitFlags(parent) & NodeEmitFlags.IsNotEmittedNode) {
288-
return parent;
289-
}
290-
}
291-
292-
return undefined;
293-
}
294-
295308
function emitWorker(node: Node): void {
296309
const kind = node.kind;
297310
switch (kind) {
@@ -2367,6 +2380,17 @@ const _super = (function (geti, seti) {
23672380
&& rangeEndIsOnSameLineAsRangeStart(block, block);
23682381
}
23692382

2383+
function getNotEmittedParent(node: Node): Node {
2384+
if (getNodeEmitFlags(node) & NodeEmitFlags.EmitCommentsOfNotEmittedParent) {
2385+
const parent = getOriginalNode(node).parent;
2386+
if (getNodeEmitFlags(parent) & NodeEmitFlags.IsNotEmittedNode) {
2387+
return parent;
2388+
}
2389+
}
2390+
2391+
return undefined;
2392+
}
2393+
23702394
function isUniqueName(name: string): boolean {
23712395
return !resolver.hasGlobalName(name) &&
23722396
!hasProperty(currentFileIdentifiers, name) &&

src/compiler/transformer.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ namespace ts {
7878
expressionSubstitution: node => node,
7979
enableExpressionSubstitution,
8080
isExpressionSubstitutionEnabled,
81-
onBeforeEmitNode: node => { },
82-
onAfterEmitNode: node => { },
81+
onEmitNode: (node, emit) => emit(node),
8382
enableEmitNotification,
8483
isEmitNotificationEnabled,
8584
};

src/compiler/transformers/es6.ts

Lines changed: 10 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,8 @@ namespace ts {
2222
const resolver = context.getEmitResolver();
2323
const previousIdentifierSubstitution = context.identifierSubstitution;
2424
const previousExpressionSubstitution = context.expressionSubstitution;
25-
const previousOnBeforeEmitNode = context.onBeforeEmitNode;
26-
const previousOnAfterEmitNode = context.onAfterEmitNode;
27-
context.onBeforeEmitNode = onBeforeEmitNode;
28-
context.onAfterEmitNode = onAfterEmitNode;
25+
const previousOnEmitNode = context.onEmitNode;
26+
context.onEmitNode = onEmitNode;
2927
context.identifierSubstitution = substituteIdentifier;
3028
context.expressionSubstitution = substituteExpression;
3129

@@ -44,23 +42,9 @@ namespace ts {
4442
let enabledSubstitutions: ES6SubstitutionFlags;
4543

4644
/**
47-
* Keeps track of how deeply nested we are within function-likes when printing
48-
* nodes. This is used to determine whether we need to emit `_this` instead of
49-
* `this`.
45+
* This is used to determine whether we need to emit `_this` instead of `this`.
5046
*/
51-
let containingFunctionDepth: number;
52-
53-
/**
54-
* The first 31 bits are used to determine whether a containing function is an
55-
* arrow function.
56-
*/
57-
let containingFunctionState: number;
58-
59-
/**
60-
* If the containingFunctionDepth grows beyond 31 nested function-likes, this
61-
* array is used as a stack to track deeper levels of nesting.
62-
*/
63-
let containingFunctionStack: number[];
47+
let useCapturedThis: boolean;
6448

6549
return transformSourceFile;
6650

@@ -1715,28 +1699,18 @@ namespace ts {
17151699
*
17161700
* @param node The node to be printed.
17171701
*/
1718-
function onBeforeEmitNode(node: Node) {
1719-
previousOnBeforeEmitNode(node);
1702+
function onEmitNode(node: Node, emit: (node: Node) => void) {
1703+
const savedUseCapturedThis = useCapturedThis;
17201704

17211705
if (enabledSubstitutions & ES6SubstitutionFlags.CapturedThis && isFunctionLike(node)) {
17221706
// If we are tracking a captured `this`, push a bit that indicates whether the
17231707
// containing function is an arrow function.
1724-
pushContainingFunction(node.kind === SyntaxKind.ArrowFunction);
1708+
useCapturedThis = node.kind === SyntaxKind.ArrowFunction;
17251709
}
1726-
}
17271710

1728-
/**
1729-
* Called by the printer just after a node is printed.
1730-
*
1731-
* @param node The node that was printed.
1732-
*/
1733-
function onAfterEmitNode(node: Node) {
1734-
previousOnAfterEmitNode(node);
1711+
previousOnEmitNode(node, emit);
17351712

1736-
if (enabledSubstitutions & ES6SubstitutionFlags.CapturedThis && isFunctionLike(node)) {
1737-
// If we are tracking a captured `this`, pop the last containing function bit.
1738-
popContainingFunction();
1739-
}
1713+
useCapturedThis = savedUseCapturedThis;
17401714
}
17411715

17421716
/**
@@ -1757,7 +1731,6 @@ namespace ts {
17571731
function enableSubstitutionsForCapturedThis() {
17581732
if ((enabledSubstitutions & ES6SubstitutionFlags.CapturedThis) === 0) {
17591733
enabledSubstitutions |= ES6SubstitutionFlags.CapturedThis;
1760-
containingFunctionDepth = 0;
17611734
context.enableExpressionSubstitution(SyntaxKind.ThisKeyword);
17621735
context.enableEmitNotification(SyntaxKind.Constructor);
17631736
context.enableEmitNotification(SyntaxKind.MethodDeclaration);
@@ -1850,68 +1823,13 @@ namespace ts {
18501823
* @param node The ThisKeyword node.
18511824
*/
18521825
function substituteThisKeyword(node: PrimaryExpression): PrimaryExpression {
1853-
if (enabledSubstitutions & ES6SubstitutionFlags.CapturedThis && isContainedInArrowFunction()) {
1826+
if (enabledSubstitutions & ES6SubstitutionFlags.CapturedThis && useCapturedThis) {
18541827
return createIdentifier("_this", /*location*/ node);
18551828
}
18561829

18571830
return node;
18581831
}
18591832

1860-
/**
1861-
* Pushes a value onto a stack that indicates whether we are currently printing a node
1862-
* within an arrow function. This is used to determine whether we need to capture `this`.
1863-
*
1864-
* @param isArrowFunction A value indicating whether the current function container is
1865-
* an arrow function.
1866-
*/
1867-
function pushContainingFunction(isArrowFunction: boolean) {
1868-
// Encode whether the containing function is an arrow function in the first 31 bits of
1869-
// an integer. If the stack grows beyond a depth of 31 functions, use an array.
1870-
if (containingFunctionDepth > 0 && containingFunctionDepth % 31 === 0) {
1871-
if (!containingFunctionStack) {
1872-
containingFunctionStack = [containingFunctionState];
1873-
}
1874-
else {
1875-
containingFunctionStack.push(containingFunctionState);
1876-
}
1877-
1878-
containingFunctionState = 0;
1879-
}
1880-
1881-
if (isArrowFunction) {
1882-
containingFunctionState |= 1 << (containingFunctionDepth % 31);
1883-
}
1884-
1885-
containingFunctionDepth++;
1886-
}
1887-
1888-
/**
1889-
* Pops a value off of the containing function stack.
1890-
*/
1891-
function popContainingFunction() {
1892-
if (containingFunctionDepth > 0) {
1893-
containingFunctionDepth--;
1894-
if (containingFunctionDepth === 0) {
1895-
containingFunctionState = 0;
1896-
}
1897-
else if (containingFunctionDepth % 31 === 0) {
1898-
containingFunctionState = containingFunctionStack.pop();
1899-
}
1900-
else {
1901-
containingFunctionState &= ~(1 << containingFunctionDepth % 31);
1902-
}
1903-
}
1904-
}
1905-
1906-
/**
1907-
* Gets a value indicating whether we are currently printing a node inside of an arrow
1908-
* function.
1909-
*/
1910-
function isContainedInArrowFunction() {
1911-
return containingFunctionDepth > 0
1912-
&& containingFunctionState & (1 << (containingFunctionDepth - 1) % 31);
1913-
}
1914-
19151833
function getDeclarationName(node: ClassExpression | ClassDeclaration | FunctionDeclaration) {
19161834
return node.name ? getSynthesizedClone(node.name) : getGeneratedNameForNode(node);
19171835
}

0 commit comments

Comments
 (0)
0