Skip to content

Commit

Permalink
Revert "Revert "Move class property transformation into new transform…
Browse files Browse the repository at this point in the history
…er. (#30467)""

This reverts commit 53467ae.
  • Loading branch information
rbuckton committed Jun 10, 2019
1 parent 8705844 commit 6178abe
Show file tree
Hide file tree
Showing 11 changed files with 807 additions and 434 deletions.
21 changes: 10 additions & 11 deletions src/compiler/binder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3229,8 +3229,7 @@ namespace ts {
// A ClassDeclaration is ES6 syntax.
transformFlags = subtreeFlags | TransformFlags.AssertES2015;

// A class with a parameter property assignment, property initializer, computed property name, or decorator is
// TypeScript syntax.
// A class with a parameter property assignment or decorator is TypeScript syntax.
// An exported declaration may be TypeScript syntax, but is handled by the visitor
// for a namespace declaration.
if ((subtreeFlags & TransformFlags.ContainsTypeScriptClassSyntax)
Expand All @@ -3247,8 +3246,7 @@ namespace ts {
// A ClassExpression is ES6 syntax.
let transformFlags = subtreeFlags | TransformFlags.AssertES2015;

// A class with a parameter property assignment, property initializer, or decorator is
// TypeScript syntax.
// A class with a parameter property assignment or decorator is TypeScript syntax.
if (subtreeFlags & TransformFlags.ContainsTypeScriptClassSyntax
|| node.typeParameters) {
transformFlags |= TransformFlags.AssertTypeScript;
Expand Down Expand Up @@ -3338,7 +3336,6 @@ namespace ts {
|| hasModifier(node, ModifierFlags.TypeScriptModifier)
|| node.typeParameters
|| node.type
|| (node.name && isComputedPropertyName(node.name)) // While computed method names aren't typescript, the TS transform must visit them to emit property declarations correctly
|| !node.body) {
transformFlags |= TransformFlags.AssertTypeScript;
}
Expand Down Expand Up @@ -3369,7 +3366,6 @@ namespace ts {
if (node.decorators
|| hasModifier(node, ModifierFlags.TypeScriptModifier)
|| node.type
|| (node.name && isComputedPropertyName(node.name)) // While computed accessor names aren't typescript, the TS transform must visit them to emit property declarations correctly
|| !node.body) {
transformFlags |= TransformFlags.AssertTypeScript;
}
Expand All @@ -3384,12 +3380,15 @@ namespace ts {
}

function computePropertyDeclaration(node: PropertyDeclaration, subtreeFlags: TransformFlags) {
// A PropertyDeclaration is TypeScript syntax.
let transformFlags = subtreeFlags | TransformFlags.AssertTypeScript;
let transformFlags = subtreeFlags | TransformFlags.ContainsClassFields;

// Decorators, TypeScript-specific modifiers, and type annotations are TypeScript syntax.
if (some(node.decorators) || hasModifier(node, ModifierFlags.TypeScriptModifier) || node.type) {
transformFlags |= TransformFlags.AssertTypeScript;
}

// If the PropertyDeclaration has an initializer or a computed name, we need to inform its ancestor
// so that it handle the transformation.
if (node.initializer || isComputedPropertyName(node.name)) {
// Hoisted variables related to class properties should live within the TypeScript class wrapper.
if (isComputedPropertyName(node.name) || (hasStaticModifier(node) && node.initializer)) {
transformFlags |= TransformFlags.ContainsTypeScriptClassSyntax;
}

Expand Down
1 change: 1 addition & 0 deletions src/compiler/transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ namespace ts {
addRange(transformers, customTransformers && map(customTransformers.before, wrapScriptTransformerFactory));

transformers.push(transformTypeScript);
transformers.push(transformClassFields);

if (jsx === JsxEmit.React) {
transformers.push(transformJsx);
Expand Down
491 changes: 491 additions & 0 deletions src/compiler/transformers/classFields.ts

Large diffs are not rendered by default.

493 changes: 146 additions & 347 deletions src/compiler/transformers/ts.ts

Large diffs are not rendered by default.

80 changes: 80 additions & 0 deletions src/compiler/transformers/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,47 @@ namespace ts {
isIdentifier(expression);
}

/**
* A simple inlinable expression is an expression which can be copied into multiple locations
* without risk of repeating any sideeffects and whose value could not possibly change between
* any such locations
*/
export function isSimpleInlineableExpression(expression: Expression) {
return !isIdentifier(expression) && isSimpleCopiableExpression(expression) ||
isWellKnownSymbolSyntactically(expression);
}

/**
* Adds super call and preceding prologue directives into the list of statements.
*
* @param ctor The constructor node.
* @param result The list of statements.
* @param visitor The visitor to apply to each node added to the result array.
* @returns index of the statement that follows super call
*/
export function addPrologueDirectivesAndInitialSuperCall(ctor: ConstructorDeclaration, result: Statement[], visitor: Visitor): number {
if (ctor.body) {
const statements = ctor.body.statements;
// add prologue directives to the list (if any)
const index = addPrologue(result, statements, /*ensureUseStrict*/ false, visitor);
if (index === statements.length) {
// list contains nothing but prologue directives (or empty) - exit
return index;
}

const statement = statements[index];
if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCall((<ExpressionStatement>statement).expression)) {
result.push(visitNode(statement, visitor, isStatement));
return index + 1;
}

return index;
}

return 0;
}


/**
* @param input Template string input strings
* @param args Names which need to be made file-level unique
Expand All @@ -255,4 +296,43 @@ namespace ts {
return result;
};
}

/**
* Gets all property declarations with initializers on either the static or instance side of a class.
*
* @param node The class node.
* @param isStatic A value indicating whether to get properties from the static or instance side of the class.
*/
export function getInitializedProperties(node: ClassExpression | ClassDeclaration, isStatic: boolean): ReadonlyArray<PropertyDeclaration> {
return filter(node.members, isStatic ? isStaticInitializedProperty : isInstanceInitializedProperty);
}

/**
* Gets a value indicating whether a class element is a static property declaration with an initializer.
*
* @param member The class element node.
*/
export function isStaticInitializedProperty(member: ClassElement): member is PropertyDeclaration & { initializer: Expression; } {
return isInitializedProperty(member) && hasStaticModifier(member);
}

/**
* Gets a value indicating whether a class element is an instance property declaration with an initializer.
*
* @param member The class element node.
*/
export function isInstanceInitializedProperty(member: ClassElement): member is PropertyDeclaration & { initializer: Expression; } {
return isInitializedProperty(member) && !hasStaticModifier(member);
}

/**
* Gets a value indicating whether a class element is either a static or an instance property declaration with an initializer.
*
* @param member The class element node.
* @param isStatic A value indicating whether the member should be a static or instance member.
*/
export function isInitializedProperty(member: ClassElement): member is PropertyDeclaration & { initializer: Expression; } {
return member.kind === SyntaxKind.PropertyDeclaration
&& (<PropertyDeclaration>member).initializer !== undefined;
}
}
1 change: 1 addition & 0 deletions src/compiler/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"transformers/utilities.ts",
"transformers/destructuring.ts",
"transformers/ts.ts",
"transformers/classFields.ts",
"transformers/es2017.ts",
"transformers/es2018.ts",
"transformers/es2019.ts",
Expand Down
1 change: 1 addition & 0 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5197,6 +5197,7 @@ namespace ts {
ContainsYield = 1 << 17,
ContainsHoistedDeclarationOrCompletion = 1 << 18,
ContainsDynamicImport = 1 << 19,
ContainsClassFields = 1 << 20,

// Please leave this as 1 << 29.
// It is the maximum bit we can set before we outgrow the size of a v8 small integer (SMI) on an x86 system.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ var C = /** @class */ (function () {
}
return C;
}());
_a = a_1.x;
exports.C = C;
_a = a_1.x;
//// [c.js]
"use strict";
var __extends = (this && this.__extends) || (function () {
Expand Down Expand Up @@ -64,8 +64,8 @@ var D = /** @class */ (function (_super) {
}
return D;
}(b_1.C));
_a = a_1.x;
exports.D = D;
_a = a_1.x;


//// [a.d.ts]
Expand Down
Loading

0 comments on commit 6178abe

Please sign in to comment.