Skip to content

Commit

Permalink
feat(extractor): support TS experimental decorators
Browse files Browse the repository at this point in the history
  • Loading branch information
timofei-iatsenko committed Mar 14, 2023
1 parent ba41f35 commit 9fbd123
Show file tree
Hide file tree
Showing 14 changed files with 121 additions and 92 deletions.
11 changes: 5 additions & 6 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,11 @@
"build/"
],
"dependencies": {
"@babel/core": "^7.20.12",
"@babel/generator": "^7.20.14",
"@babel/parser": "^7.20.15",
"@babel/plugin-syntax-jsx": "^7.18.6",
"@babel/runtime": "^7.20.13",
"@babel/types": "^7.20.7",
"@babel/core": "^7.21.0",
"@babel/generator": "^7.21.1",
"@babel/parser": "^7.21.2",
"@babel/runtime": "^7.21.0",
"@babel/types": "^7.21.2",
"@lingui/babel-plugin-extract-messages": "4.0.0-next.1",
"@lingui/conf": "4.0.0-next.1",
"@lingui/core": "4.0.0-next.1",
Expand Down
49 changes: 35 additions & 14 deletions packages/cli/src/api/catalog.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
makeCatalog,
} from "../tests"
import { AllCatalogsType } from "./types"
import { extractFromFiles } from "./catalog/extractFromFiles"

export const fixture = (...dirs: string[]) =>
path.resolve(__dirname, path.join("fixtures", ...dirs)) +
Expand Down Expand Up @@ -165,26 +166,47 @@ describe("Catalog", () => {

describe("collect", () => {
it("should support JSX and Typescript", async () => {
const catalog = new Catalog(
{
name: "messages",
path: "locales/{locale}",
include: [fixture("collect-typescript-jsx/")],
exclude: [],
},
const messages = await extractFromFiles(
[
fixture("collect-typescript-jsx/jsx-syntax.jsx"),
fixture("collect-typescript-jsx/tsx-syntax.tsx"),
fixture("collect-typescript-jsx/macro.tsx"),
],
mockConfig()
)

const messages = await catalog.collect()
expect(messages).toBeTruthy()
expect(messages).toMatchSnapshot()
})

it("should support Flow syntax if enabled", async () => {
process.env.LINGUI_CONFIG = path.join(
__dirname,
"fixtures/collect-syntax-flow/lingui.config.js"
it("should support experimental typescript decorators under a flag", async () => {
const messages = await extractFromFiles(
[fixture("collect-typescript-jsx/tsx-experimental-decorators.tsx")],
mockConfig({
extractorParserOptions: {
tsExperimentalDecorators: true,
},
})
)

expect(messages).toBeTruthy()
expect(messages).toMatchInlineSnapshot(`
{
xDAtGP: {
context: undefined,
extractedComments: [],
message: Message,
origin: [
[
collect-typescript-jsx/tsx-experimental-decorators.tsx,
15,
],
],
},
}
`)
})

it("should support Flow syntax if enabled", async () => {
const catalog = new Catalog(
{
name: "messages",
Expand All @@ -200,7 +222,6 @@ describe("Catalog", () => {
)

const messages = await catalog.collect()
expect(messages).toBeTruthy()
expect(messages).toMatchSnapshot()
})
it("should extract messages from source files", async () => {
Expand Down
24 changes: 13 additions & 11 deletions packages/cli/src/api/extractors/babel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,24 @@ const extractor: ExtractorType = {
async extract(filename, code, onMessageExtracted, ctx) {
const parserOptions = ctx.linguiConfig.extractorParserOptions

const parserPlugins: ParserPlugin[] = [
// https://babeljs.io/docs/en/babel-parser#latest-ecmascript-features
[
"decorators",
{
decoratorsBeforeExport: parserOptions?.decoratorsBeforeExport || true,
},
],
]
// https://babeljs.io/docs/en/babel-parser#latest-ecmascript-features
const parserPlugins: ParserPlugin[] = []

if (
[/\.ts$/, /\.mts$/, /\.cts$/, /\.tsx$/].some((r) => filename.match(r))
) {
parserPlugins.push("typescript")
} else if (parserOptions?.flow) {
parserPlugins.push("flow")
if (parserOptions.tsExperimentalDecorators) {
parserPlugins.push("decorators-legacy")
} else {
parserPlugins.push("decorators")
}
} else {
parserPlugins.push("decorators")

if (parserOptions?.flow) {
parserPlugins.push("flow")
}
}

if ([/\.jsx$/, /\.tsx$/].some((r) => filename.match(r))) {
Expand Down
10 changes: 0 additions & 10 deletions packages/cli/src/api/fixtures/collect-syntax-flow/lingui.config.js

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,38 @@ const jsx = <div>Hello!</div>
@Decorator()
export class TestDecorator {
@Decorator()
prop;
prop

@Decorator()
method() {};
method() {}
}

export
@Decorator()
class TestDecoratorAfterExport {}

class A {
// classProperties
b = 1;
b = 1

// classPrivateProperties
#b = 1;
#b = 1
}

// dynamicImport
import('./guy').then(a)
import("./guy").then(a)

// exportNamespaceFrom
export * as ns from "mod"

// nullishCoalescingOperator
const a = a ?? b;
const a = a ?? b

// objectRestSpread
const b = { b, ...c };
const b = { b, ...c }

// optionalChaining
const c = a?.b;
const c = a?.b

// topLevelAwait
await promise;
await promise

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { t } from "@lingui/macro"

@Decorator()
export class TestDecorator {
// supports typescript legacy decorator on parameters
constructor(@Decorator() param) {}

@Decorator()
prop

@Decorator()
method() {}
}

t`Message`
24 changes: 12 additions & 12 deletions packages/cli/src/api/fixtures/collect-typescript-jsx/tsx-syntax.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,46 @@ const jsx = <div>Hello!</div>

// Typescript syntax
function foo(bar: string): string {
return bar;
return bar
}

const test1: string = "";
const test1: string = ""

// check parsing different syntax proposals
@Decorator()
export class TestDecorator {
@Decorator()
prop;
prop

@Decorator()
method() {};
method() {}
}

// optional chaining
const test = foo?.bar?.baz;
const test = foo?.bar?.baz

class A {
// classProperties
b = 1;
b = 1

// classPrivateProperties
#b = 1;
#b = 1
}

// dynamicImport
import('./guy').then(a)
import("./guy").then(a)

// exportNamespaceFrom
export * as ns from "mod"

// nullishCoalescingOperator
const a = a ?? b;
const a = a ?? b

// objectRestSpread
const b = { b, ...c };
const b = { b, ...c }

// optionalChaining
const c = a?.b;
const c = a?.b

// topLevelAwait
await promise;
await promise
2 changes: 1 addition & 1 deletion packages/conf/__typetests__/index.test-d.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ expectAssignable<LinguiConfig>({
},
extractorParserOptions: {
flow: false,
decoratorsBeforeExport: false,
tsExperimentalDecorators: false,
},
fallbackLocales: {} as FallbackLocales,
format: "po",
Expand Down
2 changes: 1 addition & 1 deletion packages/conf/src/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ exports[`@lingui/conf should return default config 1`] = `
minified: true,
},
extractorParserOptions: {
decoratorsBeforeExport: false,
flow: false,
tsExperimentalDecorators: false,
},
fallbackLocales: {
en-gb: en,
Expand Down
4 changes: 2 additions & 2 deletions packages/conf/src/makeConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export const defaultConfig: LinguiConfig = {
},
extractorParserOptions: {
flow: false,
decoratorsBeforeExport: false,
tsExperimentalDecorators: false,
},
fallbackLocales: {} as FallbackLocales,
format: "po",
Expand Down Expand Up @@ -82,7 +82,7 @@ export const exampleConfig = {
),
extractorParserOptions: {
flow: false,
decoratorsBeforeExport: false,
tsExperimentalDecorators: false,
},
}

Expand Down
7 changes: 5 additions & 2 deletions packages/conf/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,12 @@ export type LinguiConfig = {
compileNamespace?: "es" | "ts" | "cjs" | string
extractorParserOptions?: {
/**
* default true
* default false
*
* By default, standard decorators (Stage3) are applied for TS files
* Enable this if you want to use TypesScript's experimental decorators.
*/
decoratorsBeforeExport?: boolean
tsExperimentalDecorators?: boolean
/**
* Enable if you use flow. This will apply Flow syntax to js files
*/
Expand Down
7 changes: 4 additions & 3 deletions website/docs/ref/conf.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,11 @@ Specify extra options used to parse source files when messages are being extract
```ts
"extractorParserOptions": {
/**
* default true
* Use for Stage 3 decorators syntax.
* default false
* By default, standard decorators (Stage3) are applied for TS files
* Enable this if you want to use TypesScript's experimental decorators.
*/
decoratorsBeforeExport?: boolean
tsExperimentalDecorators?: boolean
/**
* default false
* Enable if you use flow. This will apply Flow syntax to files with .js, cjs, .mjs extension.
Expand Down
33 changes: 15 additions & 18 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,6 @@ __metadata:
languageName: node
linkType: hard

"@babel/generator@npm:^7.20.14":
version: 7.20.14
resolution: "@babel/generator@npm:7.20.14"
dependencies:
"@babel/types": ^7.20.7
"@jridgewell/gen-mapping": ^0.3.2
jsesc: ^2.5.1
checksum: 5f6aa2d86af26e76d276923a5c34191124a119b16ee9ccc34aef654a7dec84fbd7d2daed2e6458a6a06bf87f3661deb77c9fea59b8f67faff5c90793c96d76d6
languageName: node
linkType: hard

"@babel/generator@npm:^7.20.7":
version: 7.20.7
resolution: "@babel/generator@npm:7.20.7"
Expand Down Expand Up @@ -432,7 +421,7 @@ __metadata:
languageName: node
linkType: hard

"@babel/parser@npm:7.20.15, @babel/parser@npm:^7.20.15":
"@babel/parser@npm:7.20.15":
version: 7.20.15
resolution: "@babel/parser@npm:7.20.15"
bin:
Expand Down Expand Up @@ -1486,6 +1475,15 @@ __metadata:
languageName: node
linkType: hard

"@babel/runtime@npm:^7.21.0":
version: 7.21.0
resolution: "@babel/runtime@npm:7.21.0"
dependencies:
regenerator-runtime: ^0.13.11
checksum: 7b33e25bfa9e0e1b9e8828bb61b2d32bdd46b41b07ba7cb43319ad08efc6fda8eb89445193e67d6541814627df0ca59122c0ea795e412b99c5183a0540d338ab
languageName: node
linkType: hard

"@babel/template@npm:^7.18.10, @babel/template@npm:^7.20.7, @babel/template@npm:^7.3.3":
version: 7.20.7
resolution: "@babel/template@npm:7.20.7"
Expand Down Expand Up @@ -2181,12 +2179,11 @@ __metadata:
version: 0.0.0-use.local
resolution: "@lingui/cli@workspace:packages/cli"
dependencies:
"@babel/core": ^7.20.12
"@babel/generator": ^7.20.14
"@babel/parser": ^7.20.15
"@babel/plugin-syntax-jsx": ^7.18.6
"@babel/runtime": ^7.20.13
"@babel/types": ^7.20.7
"@babel/core": ^7.21.0
"@babel/generator": ^7.21.1
"@babel/parser": ^7.21.2
"@babel/runtime": ^7.21.0
"@babel/types": ^7.21.2
"@lingui/babel-plugin-extract-messages": 4.0.0-next.1
"@lingui/conf": 4.0.0-next.1
"@lingui/core": 4.0.0-next.1
Expand Down

0 comments on commit 9fbd123

Please sign in to comment.