Implement pretty-printer case for ClassAccessorProperty.

It's very similar to the one from Babel: f5b52208f0/packages/babel-generator/src/generators/classes.ts (L123-L166). However, `ast-types` doesn't seem to think a `definite` attribute exists on this node type so the type checking fails.
This commit is contained in:
Brian Donovan 2022-12-13 07:49:05 -08:00
parent 63cc9ba185
commit 780487577a
5 changed files with 140 additions and 13 deletions

View file

@ -1,14 +1,14 @@
import assert from "assert";
import * as types from "ast-types";
import { printComments } from "./comments";
import { Lines, fromString, concat } from "./lines";
import FastPath from "./fast-path";
import { concat, fromString, Lines } from "./lines";
import { normalize as normalizeOptions } from "./options";
import { getReprinter } from "./patcher";
import * as types from "ast-types";
import * as util from "./util";
const namedTypes = types.namedTypes;
const isString = types.builtInTypes.string;
const isObject = types.builtInTypes.object;
import FastPath from "./fast-path";
import * as util from "./util";
export interface PrintResultType {
code: string;
@ -1470,6 +1470,40 @@ function genericPrintNoParens(path: any, options: any, print: any) {
parts.push(";");
return concat(parts);
case "ClassAccessorProperty": {
if (n.static) {
parts.push("static ");
}
parts.push("accessor ");
if (n.computed) {
parts.push("[", path.call(print, "key"), "]");
} else {
parts.push(path.call(print, "key"));
}
if (n.optional) {
parts.push("?");
}
if (n.definite) {
parts.push("!");
}
if (n.typeAnnotation) {
parts.push(path.call(print, "typeAnnotation"));
}
if (n.value) {
parts.push(" = ", path.call(print, "value"));
}
parts.push(";");
return concat(parts);
}
case "ClassDeclaration":
case "ClassExpression":
case "DeclareClass":

View file

@ -28,6 +28,6 @@ export const parser = (function (): BabelParser {
//
export function parse(source: string, options?: Overrides) {
const babelOptions = getBabelOptions(options);
babelOptions.plugins.push("jsx", "flow");
babelOptions.plugins.push("jsx", "flow", "decoratorAutoAccessors");
return parser.parse(source, babelOptions);
}

View file

@ -1,8 +1,8 @@
import assert from "assert";
import { EOL as eol } from "os";
import * as recast from "../main";
const n = recast.types.namedTypes;
const b = recast.types.builders;
import { EOL as eol } from "os";
const nodeMajorVersion = parseInt(process.versions.node, 10);
describe("Babel", function () {
@ -478,4 +478,21 @@ describe("Babel", function () {
`'use strict';\nconst a = 1;`,
);
});
it("can handle ClassAccessorProperty elements", function () {
const code = [
"class A {",
" accessor x;",
" static accessor y;",
" accessor z = 1;",
" static accessor w = 2;",
"}",
];
const ast = recast.parse(code.join(eol), parseOptions);
assert.strictEqual(
recast.prettyPrint(ast).code,
code.join(eol),
);
});
});

View file

@ -1,12 +1,12 @@
import assert from "assert";
import * as recast from "../main";
import * as types from "ast-types";
import { EOL as eol } from "os";
import { fromString } from "../lib/lines";
import { parse } from "../lib/parser";
import { Printer } from "../lib/printer";
import * as types from "ast-types";
import * as recast from "../main";
const n = types.namedTypes;
const b = types.builders;
import { fromString } from "../lib/lines";
import { EOL as eol } from "os";
const linesModule = require("../lib/lines");
const nodeMajorVersion = parseInt(process.versions.node, 10);
@ -1272,6 +1272,82 @@ describe("printer", function () {
assert.strictEqual(pretty, code);
});
it("prints ClassAccessorProperty correctly", function () {
const code = ["class A {", " accessor foo: Type = Bar;", "}"].join(eol);
const ast = b.program([
b.classDeclaration(
b.identifier("A"),
b.classBody([
b.classAccessorProperty.from({
key: b.identifier("foo"),
value: b.identifier("Bar"),
typeAnnotation: b.tsTypeAnnotation(
b.tsTypeReference(b.identifier("Type")),
)
})
]),
),
]);
const printer = new Printer({
tabWidth: 2,
});
const pretty = printer.printGenerically(ast).code;
assert.strictEqual(pretty, code);
});
it("prints 'definite' ClassAccessorProperty correctly", function () {
const code = ["class A {", " foo!: string;", "}"].join(eol);
const ast = b.program([
b.classDeclaration(
b.identifier("A"),
b.classBody([
Object.assign(
b.classAccessorProperty.from({
key: b.identifier("foo"),
definite: true,
}),
{ definite: true },
),
]),
),
]);
const printer = new Printer({
tabWidth: 2,
});
const pretty = printer.printGenerically(ast).code;
assert.strictEqual(pretty, code);
});
it("prints static ClassAccessorProperty correctly", function () {
const code = ["class A {", " static accessor foo = Bar;", "}"].join(eol);
const ast = b.program([
b.classDeclaration(
b.identifier("A"),
b.classBody([
b.classAccessorProperty.from({
key: b.identifier("foo"),
value: b.identifier("Bar"),
static: true,
}),
]),
),
]);
const printer = new Printer({
tabWidth: 2,
});
const pretty = printer.printGenerically(ast).code;
assert.strictEqual(pretty, code);
});
it("prints template expressions correctly", function () {
let code = ["graphql`query`;"].join(eol);

View file

@ -1,9 +1,9 @@
import assert from "assert";
import path from "path";
import fs from "fs";
import * as recast from "../main";
import * as types from "ast-types";
import fs from "fs";
import { EOL as eol } from "os";
import path from "path";
import * as recast from "../main";
import * as parser from "../parsers/typescript";
// Babel 7 no longer supports Node 4 or 5.