Use injectInitialization to generate ts parameter properties (#9610)

This commit is contained in:
Nicolò Ribaudo 2019-05-21 22:28:55 +02:00 committed by GitHub
parent 58cf1a7d48
commit 87fb6c4a8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 35 additions and 27 deletions

View File

@ -21,7 +21,7 @@ import {
import pkg from "../package.json"; import pkg from "../package.json";
export { FEATURES }; export { FEATURES, injectInitialization };
// Note: Versions are represented as an integer. e.g. 7.1.5 is represented // Note: Versions are represented as an integer. e.g. 7.1.5 is represented
// as 70000100005. This method is easier than using a semver-parsing // as 70000100005. This method is easier than using a semver-parsing

View File

@ -13,6 +13,7 @@
"typescript" "typescript"
], ],
"dependencies": { "dependencies": {
"@babel/helper-create-class-features-plugin": "^7.3.4",
"@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0",
"@babel/plugin-syntax-typescript": "^7.2.0" "@babel/plugin-syntax-typescript": "^7.2.0"
}, },

View File

@ -1,6 +1,7 @@
import { declare } from "@babel/helper-plugin-utils"; import { declare } from "@babel/helper-plugin-utils";
import syntaxTypeScript from "@babel/plugin-syntax-typescript"; import syntaxTypeScript from "@babel/plugin-syntax-typescript";
import { types as t } from "@babel/core"; import { types as t, template } from "@babel/core";
import { injectInitialization } from "@babel/helper-create-class-features-plugin";
import transpileEnum from "./enum"; import transpileEnum from "./enum";
@ -240,41 +241,21 @@ export default declare((api, { jsxPragma = "React" }) => {
if (parameterProperties.length) { if (parameterProperties.length) {
const assigns = parameterProperties.map(p => { const assigns = parameterProperties.map(p => {
let name; let id;
if (t.isIdentifier(p)) { if (t.isIdentifier(p)) {
name = p.name; id = p;
} else if (t.isAssignmentPattern(p) && t.isIdentifier(p.left)) { } else if (t.isAssignmentPattern(p) && t.isIdentifier(p.left)) {
name = p.left.name; id = p.left;
} else { } else {
throw path.buildCodeFrameError( throw path.buildCodeFrameError(
"Parameter properties can not be destructuring patterns.", "Parameter properties can not be destructuring patterns.",
); );
} }
const assign = t.assignmentExpression( return template.statement.ast`this.${id} = ${id}`;
"=",
t.memberExpression(t.thisExpression(), t.identifier(name)),
t.identifier(name),
);
return t.expressionStatement(assign);
}); });
const statements = childNode.body.body; injectInitialization(path, child, assigns);
const first = statements[0];
const startsWithSuperCall =
first !== undefined &&
t.isExpressionStatement(first) &&
t.isCallExpression(first.expression) &&
t.isSuper(first.expression.callee);
// Make sure to put parameter properties *after* the `super`
// call. TypeScript will enforce that a 'super()' call is the
// first statement when there are parameter properties.
childNode.body.body = startsWithSuperCall
? [first, ...assigns, ...statements.slice(1)]
: [...assigns, ...statements];
} }
} else if (child.isClassProperty()) { } else if (child.isClassProperty()) {
childNode.typeAnnotation = null; childNode.typeAnnotation = null;

View File

@ -0,0 +1,9 @@
class B extends A {
constructor(public p: string) {
console.log('anything before super');
if (p) super();
else {
super();
}
}
}

View File

@ -0,0 +1,3 @@
{
"plugins": ["transform-typescript"]
}

View File

@ -0,0 +1,14 @@
class B extends A {
constructor(p) {
console.log('anything before super');
if (p) {
super();
this.p = p;
} else {
super();
this.p = p;
}
}
}