Skip to content

Commit

Permalink
Merge pull request #288 from messageformat/reparse
Browse files Browse the repository at this point in the history
Refactor messageformat-parser, moving from PEG.js to moo
  • Loading branch information
eemeli committed Sep 13, 2020
2 parents 9d961ae + bcdf5b8 commit c432de7
Show file tree
Hide file tree
Showing 28 changed files with 1,244 additions and 1,282 deletions.
3 changes: 2 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ package-lock.json
/packages/webpack-loader-example/dist/bundle.js
/packages/messageformat/lib/*
/packages/messageformat/messageformat.*
/packages/parser/parser.js
/packages/parser/lib/*
/packages/rollup-plugin/lib/*
/packages/runtime/esm/*
/packages/runtime/lib/*
/packages/website/docs/
Expand Down
2 changes: 1 addition & 1 deletion .eslintrc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ parserOptions:
plugins:
- prettier
extends:
- "eslint:recommended"
- 'eslint:recommended'
- prettier

rules:
Expand Down
4 changes: 3 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ package-lock.json
/packages/webpack-loader-example/dist/bundle.js
/packages/messageformat/lib/
/packages/messageformat/messageformat.*
/packages/parser/parser.js
/packages/parser/lib/
/packages/rollup-plugin/lib/
/packages/runtime/esm/
/packages/runtime/lib/
/packages/website/docs/
/test/browser/dist/
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module.exports = {
'^messageformat$': '<rootDir>/packages/messageformat/src/messageformat.ts',
'^messageformat/compile-module$':
'<rootDir>/packages/messageformat/src/compile-module.ts',
'^messageformat-parser$': '<rootDir>/packages/parser/src/parser.ts',
'^messageformat-runtime$': '<rootDir>/packages/runtime/src/runtime.ts',
'^messageformat-runtime/lib/(.*)$': '<rootDir>/packages/runtime/src/$1.ts'
},
Expand Down
22 changes: 15 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
"test:chrome": "npm run pretest:browsers && mocha-selenium-bridge -b chrome test/browser/test.html",
"test:firefox": "npm run pretest:browsers && mocha-selenium-bridge -b firefox test/browser/test.html",
"test:serve": "npm run pretest:browsers && serve",
"pretest": "lerna run build --scope messageformat-parser",
"test": "jest"
},
"prettier": {
Expand Down Expand Up @@ -64,6 +63,7 @@
"@rollup/plugin-typescript": "^5.0.2",
"@types/chai": "^4.2.12",
"@types/jest": "^26.0.13",
"@types/moo": "^0.5.3",
"babel-eslint": "^10.0.2",
"babel-jest": "^26.3.0",
"babel-loader": "^8.0.6",
Expand All @@ -81,7 +81,6 @@
"memfs": "^3.2.0",
"mocha": "^8.1.3",
"mocha-selenium-bridge": "^0.2.0",
"pegjs": "^0.10.0",
"prettier": "^2.1.1",
"rimraf": "^3.0.2",
"rollup": "^2.26.10",
Expand Down
4 changes: 2 additions & 2 deletions packages/messageformat/compile-module.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from './lib/compile-module'
export { default } from './lib/compile-module'
export * from './lib/compile-module';
export { default } from './lib/compile-module';
9 changes: 6 additions & 3 deletions packages/messageformat/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,12 @@ const browserBundle = {
},
plugins: [
resolve(),
typescript({ target: 'ES5' }),
babel({ presets: [['@babel/preset-env', { targets: browserTargets }]] }),
commonjs()
commonjs(),
typescript({
downlevelIteration: true,
target: 'ES5'
}),
babel({ presets: [['@babel/preset-env', { targets: browserTargets }]] })
]
};

Expand Down
2 changes: 1 addition & 1 deletion packages/messageformat/src/compile-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Compiler, { RuntimeMap, StringStructure } from './compiler';
import MessageFormat, { MessageFunction } from './messageformat';
import { PluralObject } from './plurals';

export { MessageFunction }
export { MessageFunction };
export type MessageModule<T> = T extends string
? MessageFunction
: {
Expand Down
52 changes: 28 additions & 24 deletions packages/messageformat/src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ import {
} from 'messageformat-number-skeleton';
import {
parse,
FunctionArg,
Function,
Octothorpe,
Plural,
Select,
Token
} from 'messageformat-parser';
Expand Down Expand Up @@ -95,12 +94,15 @@ export default class Compiler {
return `function(d) { ${reqArgs}return ${this.concatenate(r, true)}; }`;
}

cases(token: Plural | Select, pluralToken: Plural | null) {
cases(token: Select, pluralToken: Select | null) {
let needOther = true;
const r = token.cases.map(({ key, tokens }) => {
if (key === 'other') needOther = false;
const s = tokens.map(tok => this.token(tok, pluralToken));
return `${property(null, key)}: ${this.concatenate(s, false)}`;
return `${property(null, key.replace(/^=/, ''))}: ${this.concatenate(
s,
false
)}`;
});
if (needOther) {
const { type } = token;
Expand All @@ -122,8 +124,8 @@ export default class Compiler {
: tokens.join(' + ') || '""';
}

token(token: Token | Octothorpe, pluralToken: Plural | null) {
if (typeof token == 'string') return JSON.stringify(token);
token(token: Token | Octothorpe, pluralToken: Select | null) {
if (token.type == 'content') return JSON.stringify(token.value);

const { id, lc } = this.plural;
let args: (number | string)[], fn: string;
Expand All @@ -146,14 +148,14 @@ export default class Compiler {

case 'selectordinal':
fn = 'plural';
args.push(token.offset || 0, id, this.cases(token, token), 1);
args.push(token.pluralOffset || 0, id, this.cases(token, token), 1);
this.setLocale(id, true);
this.setRuntimeFn('plural');
break;

case 'plural':
fn = 'plural';
args.push(token.offset || 0, id, this.cases(token, token));
args.push(token.pluralOffset || 0, id, this.cases(token, token));
this.setLocale(id, false);
this.setRuntimeFn('plural');
break;
Expand All @@ -171,9 +173,7 @@ export default class Compiler {
if (token.param) {
if (pluralToken && this.options.strictNumberSign)
pluralToken = null;
const s = token.param.tokens.map(tok =>
this.token(tok, pluralToken)
);
const s = token.param.map(tok => this.token(tok, pluralToken));
args.push('(' + (s.join(' + ') || '""') + ').trim()');
if (token.key === 'number')
args.push(JSON.stringify(this.options.currency));
Expand All @@ -188,7 +188,7 @@ export default class Compiler {
args = [
JSON.stringify(this.plural.locale),
property('d', pluralToken.arg),
pluralToken.offset || '0'
pluralToken.pluralOffset || 0
];
if (this.options.strictNumberSign) {
fn = 'strictNumber';
Expand Down Expand Up @@ -265,15 +265,19 @@ export default class Compiler {
}

setDateFormatter(
{ param }: FunctionArg,
{ param }: Function,
args: (number | string)[],
plural: Plural | null
plural: Select | null
) {
const { locale } = this.plural;

const argStyle = param && param.tokens.length === 1 && param.tokens[0];
if (typeof argStyle === 'string' && /^\s*::/.test(argStyle)) {
const argSkeletonText = argStyle.trim().substr(2);
const argStyle = param && param.length === 1 && param[0];
if (
argStyle &&
argStyle.type === 'content' &&
/^\s*::/.test(argStyle.value)
) {
const argSkeletonText = argStyle.value.trim().substr(2);
const key = identifier(`date_${locale}_${argSkeletonText}`, true);
if (!this.runtimeIncludes(key, 'formatter')) {
const fmt: RuntimeEntry = getDateFormatter(locale, argSkeletonText);
Expand All @@ -287,19 +291,19 @@ export default class Compiler {
}

args.push(JSON.stringify(locale));
if (param) {
if (param && param.length > 0) {
if (plural && this.options.strictNumberSign) plural = null;
const s = param.tokens.map(tok => this.token(tok, plural));
const s = param.map(tok => this.token(tok, plural));
args.push('(' + (s.join(' + ') || '""') + ').trim()');
}
this.setFormatter('date');
return 'date';
}

setNumberFormatter(
{ param }: FunctionArg,
{ param }: Function,
args: (number | string)[],
plural: Plural | null
plural: Select | null
) {
const { locale } = this.plural;

Expand All @@ -312,8 +316,8 @@ export default class Compiler {
}

args.push(JSON.stringify(locale));
if (param.tokens.length === 1 && typeof param.tokens[0] === 'string') {
const fmtArg = param.tokens[0].trim();
if (param.length === 1 && param[0].type === 'content') {
const fmtArg = param[0].value.trim();

switch (fmtArg) {
case 'currency':
Expand Down Expand Up @@ -350,7 +354,7 @@ export default class Compiler {
}

if (plural && this.options.strictNumberSign) plural = null;
const s = param.tokens.map(tok => this.token(tok, plural));
const s = param.map(tok => this.token(tok, plural));
args.push('(' + (s.join(' + ') || '""') + ').trim()');
args.push(JSON.stringify(this.options.currency));
this.setFormatter('numberFmt');
Expand Down
14 changes: 10 additions & 4 deletions packages/messageformat/src/messageformat.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,19 +96,25 @@ describe('compile() errors', () => {
test('Invalid plural key', () => {
const mf = new MessageFormat('en');
const src = '{X, plural, foo{a}}';
expect(() => mf.compile(src)).toThrow(/Invalid key `foo`/);
expect(() => mf.compile(src)).toThrow(
'The plural case foo is not valid in this locale'
);
});

test('Invalid selectordinal key', () => {
const mf = new MessageFormat('en');
const src = '{X, plural, foo{a}}';
expect(() => mf.compile(src)).toThrow(/Invalid key `foo`/);
const src = '{X, selectordinal, foo{a}}';
expect(() => mf.compile(src)).toThrow(
'The selectordinal case foo is not valid in this locale'
);
});

test('Invalid plural key for locale', () => {
const mf = new MessageFormat('en');
const src = '{X, plural, zero{none} one{one} other{some: #}}';
expect(() => mf.compile(src)).toThrow(/Invalid key `zero`/);
expect(() => mf.compile(src)).toThrow(
'The plural case zero is not valid in this locale'
);
});

test('Undefined formatting function', () => {
Expand Down
3 changes: 2 additions & 1 deletion packages/parser/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
parser.js
/lib/
/parser.js

0 comments on commit c432de7

Please sign in to comment.