@tolgee/cli 2.0.3 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +15 -23
- package/dist/commands/extract/check.js +2 -6
- package/dist/commands/extract/print.js +2 -6
- package/dist/commands/pull.js +2 -4
- package/dist/commands/sync/compare.js +2 -6
- package/dist/commands/sync/sync.js +1 -5
- package/dist/commands/tag.js +1 -5
- package/dist/config/tolgeerc.js +4 -6
- package/dist/extractor/extractor.js +40 -66
- package/dist/extractor/parser/extractComment.js +78 -0
- package/dist/extractor/parser/generalMapper.js +82 -0
- package/dist/extractor/parser/generateReport.js +161 -0
- package/dist/extractor/parser/iterator.js +37 -0
- package/dist/extractor/parser/mergerMachine.js +66 -0
- package/dist/extractor/parser/nodeUtils.js +21 -0
- package/dist/extractor/parser/parser.js +129 -0
- package/dist/extractor/parser/rules/tComponentGeneral.js +45 -0
- package/dist/extractor/parser/rules/tFunctionGeneral.js +41 -0
- package/dist/extractor/parser/rules/tNsSourceGeneral.js +36 -0
- package/dist/extractor/parser/tokenMergers/closingTagMerger.js +27 -0
- package/dist/extractor/parser/tokenMergers/commentsMerger.js +36 -0
- package/dist/extractor/parser/tokenMergers/stringMerger.js +50 -0
- package/dist/extractor/parser/tokenMergers/templateStringMerger.js +55 -0
- package/dist/extractor/parser/tokenMergers/typesAsMergerer.js +40 -0
- package/dist/extractor/parser/tokenMergers/typesCastMerger.js +28 -0
- package/dist/extractor/parser/tree/getTranslateProps.js +54 -0
- package/dist/extractor/parser/tree/getValue.js +17 -0
- package/dist/extractor/parser/tree/parseGeneral.js +51 -0
- package/dist/extractor/parser/tree/parseList.js +33 -0
- package/dist/extractor/parser/tree/parseObject.js +130 -0
- package/dist/extractor/parser/tree/parseProps.js +56 -0
- package/dist/extractor/parser/tree/parseTag.js +26 -0
- package/dist/extractor/parser/types.js +1 -0
- package/dist/extractor/parserReact/ParserReact.js +30 -0
- package/dist/extractor/parserReact/jsxMapper.js +24 -0
- package/dist/extractor/parserReact/rules/createElement.js +62 -0
- package/dist/extractor/parserReact/rules/tComponent.js +9 -0
- package/dist/extractor/parserReact/rules/tFunction.js +7 -0
- package/dist/extractor/parserReact/rules/useTranslate.js +7 -0
- package/dist/extractor/parserReact/tokenMergers/createElementMerger.js +35 -0
- package/dist/extractor/parserReact/tokenMergers/tComponentMerger.js +20 -0
- package/dist/extractor/parserReact/tokenMergers/tFunctionMerger.js +23 -0
- package/dist/extractor/parserReact/tokenMergers/useTranslateMerger.js +20 -0
- package/dist/extractor/parserSvelte/ParserSvelte.js +32 -0
- package/dist/extractor/parserSvelte/contextConstants.js +1 -0
- package/dist/extractor/parserSvelte/rules/scriptTag.js +26 -0
- package/dist/extractor/parserSvelte/rules/tComponent.js +9 -0
- package/dist/extractor/parserSvelte/rules/tFunction.js +7 -0
- package/dist/extractor/parserSvelte/rules/useTranslate.js +7 -0
- package/dist/extractor/parserSvelte/svelteMapper.js +39 -0
- package/dist/extractor/parserSvelte/svelteTreeTransform.js +38 -0
- package/dist/extractor/parserSvelte/tokenMergers/getTranslateMerger.js +20 -0
- package/dist/extractor/parserSvelte/tokenMergers/scriptTagMerger.js +20 -0
- package/dist/extractor/parserSvelte/tokenMergers/tComponentMerger.js +20 -0
- package/dist/extractor/parserSvelte/tokenMergers/tFunctionMerger.js +29 -0
- package/dist/extractor/parserVue/ParserVue.js +45 -0
- package/dist/extractor/parserVue/contextConstants.js +3 -0
- package/dist/extractor/parserVue/rules/exportDefaultObject.js +14 -0
- package/dist/extractor/parserVue/rules/globalTFunction.js +7 -0
- package/dist/extractor/parserVue/rules/scriptTag.js +31 -0
- package/dist/extractor/parserVue/rules/tComponent.js +9 -0
- package/dist/extractor/parserVue/rules/tFunction.js +7 -0
- package/dist/extractor/parserVue/rules/useTranslate.js +7 -0
- package/dist/extractor/parserVue/tokenMergers/exportDefaultObjectMerger.js +25 -0
- package/dist/extractor/parserVue/tokenMergers/globalTFunctionMerger.js +36 -0
- package/dist/extractor/parserVue/tokenMergers/scriptTagMerger.js +20 -0
- package/dist/extractor/parserVue/tokenMergers/tComponentMerger.js +20 -0
- package/dist/extractor/parserVue/tokenMergers/tFunctionMerger.js +37 -0
- package/dist/extractor/parserVue/tokenMergers/useTranslateMerger.js +20 -0
- package/dist/extractor/parserVue/vueMapper.js +51 -0
- package/dist/extractor/parserVue/vueTreeTransform.js +109 -0
- package/dist/extractor/runner.js +52 -4
- package/dist/extractor/visualizers/printTokens.js +7 -0
- package/dist/extractor/visualizers/tokensToString.js +28 -0
- package/dist/extractor/visualizers/visualizeRules.js +40 -0
- package/dist/extractor/warnings.js +4 -0
- package/dist/extractor/worker.js +10 -7
- package/dist/options.js +5 -0
- package/extractor.d.ts +8 -1
- package/package.json +2 -4
- package/schema.json +18 -6
- package/dist/client/internal/requester.js +0 -130
- package/dist/extractor/machines/comments.js +0 -78
- package/dist/extractor/machines/react.js +0 -705
- package/dist/extractor/machines/shared/comments.js +0 -79
- package/dist/extractor/machines/shared/properties.js +0 -380
- package/dist/extractor/machines/shared/translateCall.js +0 -141
- package/dist/extractor/machines/svelte.js +0 -429
- package/dist/extractor/machines/vue/decoder.js +0 -194
- package/dist/extractor/machines/vue/extract.js +0 -491
- package/dist/extractor/processors/vueSfc.js +0 -55
@@ -0,0 +1,37 @@
|
|
1
|
+
export const createIterator = (items) => {
|
2
|
+
const iterator = items[Symbol.iterator]();
|
3
|
+
let currentItem;
|
4
|
+
let nextItem = iterator.next();
|
5
|
+
const listeners = [];
|
6
|
+
let currentContext = undefined;
|
7
|
+
const self = {
|
8
|
+
getLineNumber() {
|
9
|
+
return currentItem?.line ?? 0;
|
10
|
+
},
|
11
|
+
current() {
|
12
|
+
return currentItem;
|
13
|
+
},
|
14
|
+
peek() {
|
15
|
+
return nextItem.done ? undefined : nextItem.value;
|
16
|
+
},
|
17
|
+
onAccept(listener) {
|
18
|
+
listeners.push(listener);
|
19
|
+
},
|
20
|
+
setLabel(context) {
|
21
|
+
currentContext = context;
|
22
|
+
},
|
23
|
+
getLabel() {
|
24
|
+
return currentContext;
|
25
|
+
},
|
26
|
+
next() {
|
27
|
+
const value = self.peek();
|
28
|
+
if (currentItem) {
|
29
|
+
listeners.forEach((cb) => cb(currentItem, currentContext));
|
30
|
+
}
|
31
|
+
currentItem = nextItem.done ? undefined : nextItem.value;
|
32
|
+
nextItem = iterator.next();
|
33
|
+
return value;
|
34
|
+
},
|
35
|
+
};
|
36
|
+
return self;
|
37
|
+
};
|
@@ -0,0 +1,66 @@
|
|
1
|
+
function defaultResultToken(matched) {
|
2
|
+
return matched.map((t) => t.token).join('');
|
3
|
+
}
|
4
|
+
const MERGE_ALL = Symbol('MERGE_ALL');
|
5
|
+
const MERGE_WITHOUT_LAST = Symbol('MERGE_WITHOUT_LAST');
|
6
|
+
export const endOptions = {
|
7
|
+
MERGE_ALL,
|
8
|
+
MERGE_WITHOUT_LAST,
|
9
|
+
};
|
10
|
+
function createNewToken(tokens, customType, merger) {
|
11
|
+
return {
|
12
|
+
customType,
|
13
|
+
type: 'custom',
|
14
|
+
startIndex: tokens[0].startIndex,
|
15
|
+
endIndex: tokens[tokens.length - 1].endIndex,
|
16
|
+
scopes: [],
|
17
|
+
line: tokens[0].line,
|
18
|
+
token: merger(tokens),
|
19
|
+
};
|
20
|
+
}
|
21
|
+
export function createMachine(machine) {
|
22
|
+
function* generator(tokens) {
|
23
|
+
let state = machine.initial;
|
24
|
+
let stack = [];
|
25
|
+
for (const token of tokens) {
|
26
|
+
const newState = machine.step(state, token, endOptions);
|
27
|
+
stack.push(token);
|
28
|
+
if (newState === undefined) {
|
29
|
+
state = machine.initial;
|
30
|
+
for (const result of stack) {
|
31
|
+
yield result;
|
32
|
+
}
|
33
|
+
stack = [];
|
34
|
+
continue;
|
35
|
+
}
|
36
|
+
else if (newState === endOptions.MERGE_ALL ||
|
37
|
+
newState === endOptions.MERGE_WITHOUT_LAST) {
|
38
|
+
const lastToken = newState === endOptions.MERGE_WITHOUT_LAST ? stack.pop() : undefined;
|
39
|
+
const newToken = createNewToken(stack, machine.customType, machine.resultToken ?? defaultResultToken);
|
40
|
+
state = machine.initial;
|
41
|
+
stack = [];
|
42
|
+
yield newToken;
|
43
|
+
if (lastToken) {
|
44
|
+
yield lastToken;
|
45
|
+
}
|
46
|
+
continue;
|
47
|
+
}
|
48
|
+
else {
|
49
|
+
state = newState;
|
50
|
+
continue;
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
54
|
+
return generator;
|
55
|
+
}
|
56
|
+
export function pipeMachines(definitions) {
|
57
|
+
const machines = definitions.map((def) => createMachine(def));
|
58
|
+
function generator(tokens) {
|
59
|
+
let items = tokens;
|
60
|
+
for (const machine of machines) {
|
61
|
+
items = machine(items);
|
62
|
+
}
|
63
|
+
return items;
|
64
|
+
}
|
65
|
+
return generator;
|
66
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
export function isPrimitive(node) {
|
2
|
+
return node.type === 'primitive';
|
3
|
+
}
|
4
|
+
export function isString(node) {
|
5
|
+
return node.type === 'primitive' && typeof node.value === 'string';
|
6
|
+
}
|
7
|
+
export function isEmptyExpr(node) {
|
8
|
+
return node.type === 'expr' && node.values.length === 0;
|
9
|
+
}
|
10
|
+
export function extractString(node) {
|
11
|
+
return node && isString(node) ? node.value : undefined;
|
12
|
+
}
|
13
|
+
export function extractValue(node) {
|
14
|
+
return node && node.type === 'primitive' ? node.value : undefined;
|
15
|
+
}
|
16
|
+
export function simplifyNode(node) {
|
17
|
+
if (node?.type === 'expr' && node.values.length === 1) {
|
18
|
+
return node.values[0];
|
19
|
+
}
|
20
|
+
return node;
|
21
|
+
}
|
@@ -0,0 +1,129 @@
|
|
1
|
+
import { extractComment } from './extractComment.js';
|
2
|
+
import { createIterator, } from './iterator.js';
|
3
|
+
import { generateReport } from './generateReport.js';
|
4
|
+
import { parseGeneral } from './tree/parseGeneral.js';
|
5
|
+
import { commentsMerger } from './tokenMergers/commentsMerger.js';
|
6
|
+
import { createMachine } from './mergerMachine.js';
|
7
|
+
import { stringMerger } from './tokenMergers/stringMerger.js';
|
8
|
+
import { templateStringMerger } from './tokenMergers/templateStringMerger.js';
|
9
|
+
import { closingTagMerger } from './tokenMergers/closingTagMerger.js';
|
10
|
+
import { typesAsMergerer } from './tokenMergers/typesAsMergerer.js';
|
11
|
+
import { typesCastMergerer } from './tokenMergers/typesCastMerger.js';
|
12
|
+
export const DEFAULT_BLOCKS = {
|
13
|
+
'block.begin': ['block.end'],
|
14
|
+
'expression.begin': ['expression.end'],
|
15
|
+
'expression.template.begin': ['expression.template.end'],
|
16
|
+
'tag.regular.begin': [
|
17
|
+
'tag.closing',
|
18
|
+
'tag.self-closing.end',
|
19
|
+
'tag.closing.begin',
|
20
|
+
],
|
21
|
+
};
|
22
|
+
export const DEFAULT_MERGERERS = [
|
23
|
+
stringMerger,
|
24
|
+
templateStringMerger,
|
25
|
+
closingTagMerger,
|
26
|
+
typesAsMergerer,
|
27
|
+
typesCastMergerer,
|
28
|
+
];
|
29
|
+
export const Parser = ({ mappers, blocks, rules, merger, treeTransform, }) => {
|
30
|
+
const ruleMap = new Map();
|
31
|
+
rules.forEach(({ trigger, call }) => {
|
32
|
+
ruleMap.set(trigger, call);
|
33
|
+
});
|
34
|
+
let iterator;
|
35
|
+
function getCurrentLine() {
|
36
|
+
return iterator.getLineNumber();
|
37
|
+
}
|
38
|
+
return {
|
39
|
+
parse({ tokens, onAccept, options }) {
|
40
|
+
for (const t of tokens) {
|
41
|
+
// use first mapper, which gives some result
|
42
|
+
const type = mappers.find((mapper) => mapper(t))?.(t);
|
43
|
+
t.customType = type;
|
44
|
+
}
|
45
|
+
const mergedComments = [...createMachine(commentsMerger)(tokens)];
|
46
|
+
const comments = mergedComments
|
47
|
+
.filter((c) => c.customType === 'comment')
|
48
|
+
.map((token) => extractComment(token))
|
49
|
+
.filter(Boolean);
|
50
|
+
// remove whitespaces and comments
|
51
|
+
const filteredWhitespaces = mergedComments.filter((t) => {
|
52
|
+
if (t.customType === 'comment') {
|
53
|
+
return false;
|
54
|
+
}
|
55
|
+
if (t.customType === 'ignore') {
|
56
|
+
return false;
|
57
|
+
}
|
58
|
+
if (!t.customType && t.token.match(/^[\s]+$/gmu)) {
|
59
|
+
return false;
|
60
|
+
}
|
61
|
+
return true;
|
62
|
+
});
|
63
|
+
const mergedTokens = [...merger(filteredWhitespaces)];
|
64
|
+
// remove ignored after merge
|
65
|
+
const filteredIgnored = mergedTokens.filter((t) => {
|
66
|
+
if (t.customType === 'ignore') {
|
67
|
+
return false;
|
68
|
+
}
|
69
|
+
return true;
|
70
|
+
});
|
71
|
+
iterator = createIterator(filteredIgnored);
|
72
|
+
const context = {
|
73
|
+
tokens: iterator,
|
74
|
+
getCurrentLine,
|
75
|
+
withLabel,
|
76
|
+
ruleMap,
|
77
|
+
blocks,
|
78
|
+
};
|
79
|
+
let depth = 0;
|
80
|
+
function withLabel(fn) {
|
81
|
+
return (...args) => {
|
82
|
+
let label;
|
83
|
+
const currentTokenName = context.tokens.current()?.customType || '';
|
84
|
+
const isTrigger = currentTokenName.startsWith('trigger.');
|
85
|
+
if (!isTrigger) {
|
86
|
+
depth += 1;
|
87
|
+
label = `depth.${depth}`;
|
88
|
+
}
|
89
|
+
else {
|
90
|
+
label = currentTokenName;
|
91
|
+
}
|
92
|
+
const previous = iterator.getLabel();
|
93
|
+
iterator.setLabel(label);
|
94
|
+
const result = fn(...args);
|
95
|
+
iterator.setLabel(previous);
|
96
|
+
if (!isTrigger) {
|
97
|
+
depth -= 1;
|
98
|
+
}
|
99
|
+
return result;
|
100
|
+
};
|
101
|
+
}
|
102
|
+
iterator.next();
|
103
|
+
if (onAccept) {
|
104
|
+
iterator.onAccept(onAccept);
|
105
|
+
}
|
106
|
+
let rootNode = parseGeneral(context, {
|
107
|
+
end: [],
|
108
|
+
keepNested: true,
|
109
|
+
});
|
110
|
+
const keys = [];
|
111
|
+
const warnings = [];
|
112
|
+
if (treeTransform) {
|
113
|
+
const { tree, report } = treeTransform(rootNode);
|
114
|
+
rootNode = tree;
|
115
|
+
if (report) {
|
116
|
+
keys.push(...report.keys);
|
117
|
+
warnings.push(...report.warnings);
|
118
|
+
}
|
119
|
+
}
|
120
|
+
const report = generateReport({ node: rootNode, comments, options });
|
121
|
+
keys.push(...report.keys);
|
122
|
+
warnings.push(...report.warnings);
|
123
|
+
return {
|
124
|
+
tree: rootNode,
|
125
|
+
report: { keys, warnings },
|
126
|
+
};
|
127
|
+
},
|
128
|
+
};
|
129
|
+
};
|
@@ -0,0 +1,45 @@
|
|
1
|
+
import { parseTag } from '../tree/parseTag.js';
|
2
|
+
// <T keyName="test">Default</T>
|
3
|
+
// ^^-----------------------^^^^
|
4
|
+
export const tComponentGeneral = (context) => {
|
5
|
+
const { getCurrentLine } = context;
|
6
|
+
const line = getCurrentLine();
|
7
|
+
const { props, child } = parseTag(context);
|
8
|
+
const result = {
|
9
|
+
type: 'keyInfo',
|
10
|
+
line,
|
11
|
+
dependsOnContext: false,
|
12
|
+
values: [],
|
13
|
+
};
|
14
|
+
// read props
|
15
|
+
if (props.type === 'dict') {
|
16
|
+
for (const [key, value] of Object.entries(props.value)) {
|
17
|
+
switch (key) {
|
18
|
+
case 'keyName':
|
19
|
+
result.keyName = value;
|
20
|
+
break;
|
21
|
+
case 'defaultValue':
|
22
|
+
result.defaultValue = value;
|
23
|
+
break;
|
24
|
+
case 'ns':
|
25
|
+
result.namespace = value;
|
26
|
+
break;
|
27
|
+
default:
|
28
|
+
result.values.push(value);
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
32
|
+
// read children
|
33
|
+
if (child) {
|
34
|
+
if (!result.keyName) {
|
35
|
+
result.keyName = child;
|
36
|
+
}
|
37
|
+
else if (!result.defaultValue) {
|
38
|
+
result.defaultValue = child;
|
39
|
+
}
|
40
|
+
else {
|
41
|
+
result.values.push(child);
|
42
|
+
}
|
43
|
+
}
|
44
|
+
return result;
|
45
|
+
};
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import { getTranslateProps } from '../tree/getTranslateProps.js';
|
2
|
+
import { parseList } from '../tree/parseList.js';
|
3
|
+
// t('key_name', 'default_value', { ns: 'namespace' })
|
4
|
+
// ^^------------------------------------------------^
|
5
|
+
export const tFunctionGeneral = (context, dependsOnContext) => {
|
6
|
+
const line = context.getCurrentLine();
|
7
|
+
const args = parseList(context, 'expression.end');
|
8
|
+
if (args.type !== 'array') {
|
9
|
+
// invalid arguments
|
10
|
+
return args;
|
11
|
+
}
|
12
|
+
const { result: props, optionsDynamic } = getTranslateProps(args);
|
13
|
+
if (props.type !== 'dict') {
|
14
|
+
return props;
|
15
|
+
}
|
16
|
+
const result = {
|
17
|
+
type: 'keyInfo',
|
18
|
+
line,
|
19
|
+
dependsOnContext,
|
20
|
+
values: [],
|
21
|
+
optionsDynamic,
|
22
|
+
};
|
23
|
+
// read props
|
24
|
+
for (const [key, value] of Object.entries(props.value)) {
|
25
|
+
switch (key) {
|
26
|
+
case 'key':
|
27
|
+
result.keyName = value;
|
28
|
+
break;
|
29
|
+
case 'defaultValue':
|
30
|
+
result.defaultValue = value;
|
31
|
+
break;
|
32
|
+
case 'ns':
|
33
|
+
result.namespace = value;
|
34
|
+
break;
|
35
|
+
default:
|
36
|
+
// unknown parameter
|
37
|
+
result.values.push(value);
|
38
|
+
}
|
39
|
+
}
|
40
|
+
return result;
|
41
|
+
};
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import { parseList } from '../tree/parseList.js';
|
2
|
+
/**
|
3
|
+
* useTranslate('namespace')
|
4
|
+
* ^^^^^^^^^^^^^-----------^
|
5
|
+
*
|
6
|
+
* or
|
7
|
+
*
|
8
|
+
* useTranslate(['namespace', ...])
|
9
|
+
* ^^^^^^^^^^^^^------------------^
|
10
|
+
*/
|
11
|
+
export const tNsSourceGeneral = (context) => {
|
12
|
+
const line = context.getCurrentLine();
|
13
|
+
const args = parseList(context, 'expression.end');
|
14
|
+
if (args.type !== 'array') {
|
15
|
+
// invalid arguments
|
16
|
+
return args;
|
17
|
+
}
|
18
|
+
const result = {
|
19
|
+
type: 'nsInfo',
|
20
|
+
line,
|
21
|
+
values: [],
|
22
|
+
};
|
23
|
+
const [firstArg, ...otherArgs] = args.values;
|
24
|
+
if (firstArg?.type === 'array') {
|
25
|
+
// useTranslate(['namespace', ...])
|
26
|
+
const [firstItem, ...otherItems] = firstArg.values;
|
27
|
+
result.name = firstItem;
|
28
|
+
otherItems.forEach((item) => result.values.push(item));
|
29
|
+
}
|
30
|
+
else {
|
31
|
+
// useTranslate('namespace')
|
32
|
+
result.name = firstArg;
|
33
|
+
}
|
34
|
+
otherArgs.forEach((arg) => result.values.push(arg));
|
35
|
+
return result;
|
36
|
+
};
|
@@ -0,0 +1,27 @@
|
|
1
|
+
export const closingTagMerger = {
|
2
|
+
initial: 0 /* S.Idle */,
|
3
|
+
step: (state, token, end) => {
|
4
|
+
const type = token.customType;
|
5
|
+
switch (state) {
|
6
|
+
case 0 /* S.Idle */:
|
7
|
+
if (type === 'tag.closing.begin') {
|
8
|
+
return 1 /* S.ExpectName */;
|
9
|
+
}
|
10
|
+
break;
|
11
|
+
case 1 /* S.ExpectName */:
|
12
|
+
if (type === 'tag.name') {
|
13
|
+
return 2 /* S.ExpectEnd */;
|
14
|
+
}
|
15
|
+
break;
|
16
|
+
case 2 /* S.ExpectEnd */:
|
17
|
+
if (type === 'tag.regular.end') {
|
18
|
+
return end.MERGE_ALL;
|
19
|
+
}
|
20
|
+
break;
|
21
|
+
}
|
22
|
+
},
|
23
|
+
customType: 'tag.closing',
|
24
|
+
resultToken: (matched) => {
|
25
|
+
return matched[1].token;
|
26
|
+
},
|
27
|
+
};
|
@@ -0,0 +1,36 @@
|
|
1
|
+
export const commentsMerger = {
|
2
|
+
initial: 0 /* S.Idle */,
|
3
|
+
step: (state, token, end) => {
|
4
|
+
const type = token.customType;
|
5
|
+
switch (state) {
|
6
|
+
case 0 /* S.Idle */:
|
7
|
+
if (type === 'comment.definition') {
|
8
|
+
return 1 /* S.CommentStart */;
|
9
|
+
}
|
10
|
+
break;
|
11
|
+
case 1 /* S.CommentStart */:
|
12
|
+
if (type === 'comment.line') {
|
13
|
+
return end.MERGE_ALL;
|
14
|
+
}
|
15
|
+
else if (type === 'comment.block') {
|
16
|
+
return 2 /* S.CommentBlock */;
|
17
|
+
}
|
18
|
+
break;
|
19
|
+
case 2 /* S.CommentBlock */:
|
20
|
+
if (type === 'comment.block' || token.token === '\n') {
|
21
|
+
return 2 /* S.CommentBlock */;
|
22
|
+
}
|
23
|
+
else if (type === 'comment.definition') {
|
24
|
+
return end.MERGE_ALL;
|
25
|
+
}
|
26
|
+
break;
|
27
|
+
}
|
28
|
+
},
|
29
|
+
resultToken: (matched) => {
|
30
|
+
return matched
|
31
|
+
.filter((t) => t.customType && t.customType !== 'comment.definition')
|
32
|
+
.map((t) => t.token)
|
33
|
+
.join('');
|
34
|
+
},
|
35
|
+
customType: 'comment',
|
36
|
+
};
|
@@ -0,0 +1,50 @@
|
|
1
|
+
export const stringMerger = {
|
2
|
+
initial: 0 /* S.Idle */,
|
3
|
+
step: (state, token, end) => {
|
4
|
+
const type = token.customType;
|
5
|
+
switch (state) {
|
6
|
+
case 0 /* S.Idle */:
|
7
|
+
if (type === 'string.begin') {
|
8
|
+
return 1 /* S.RegularString */;
|
9
|
+
}
|
10
|
+
else if (type === 'string.teplate.begin') {
|
11
|
+
return 3 /* S.TemplateString */;
|
12
|
+
}
|
13
|
+
break;
|
14
|
+
case 1 /* S.RegularString */:
|
15
|
+
if (type === 'string.body') {
|
16
|
+
return 2 /* S.RegularStringEnd */;
|
17
|
+
}
|
18
|
+
else if (type === 'string.end') {
|
19
|
+
return end.MERGE_ALL;
|
20
|
+
}
|
21
|
+
break;
|
22
|
+
case 2 /* S.RegularStringEnd */:
|
23
|
+
if (type === 'string.end') {
|
24
|
+
return end.MERGE_ALL;
|
25
|
+
}
|
26
|
+
break;
|
27
|
+
case 3 /* S.TemplateString */:
|
28
|
+
if (type === 'string.template.body') {
|
29
|
+
return 4 /* S.TemplateStringEnd */;
|
30
|
+
}
|
31
|
+
else if (type === 'string.template.end') {
|
32
|
+
return end.MERGE_ALL;
|
33
|
+
}
|
34
|
+
break;
|
35
|
+
case 4 /* S.TemplateStringEnd */:
|
36
|
+
if (type === 'string.template.end') {
|
37
|
+
return end.MERGE_ALL;
|
38
|
+
}
|
39
|
+
}
|
40
|
+
},
|
41
|
+
customType: 'string',
|
42
|
+
resultToken: (matched) => {
|
43
|
+
if (matched.length === 3) {
|
44
|
+
return matched[1].token;
|
45
|
+
}
|
46
|
+
else {
|
47
|
+
return '';
|
48
|
+
}
|
49
|
+
},
|
50
|
+
};
|
@@ -0,0 +1,55 @@
|
|
1
|
+
export const templateStringMerger = {
|
2
|
+
initial: 0 /* S.Idle */,
|
3
|
+
step: (state, token, end) => {
|
4
|
+
const type = token.customType;
|
5
|
+
switch (state) {
|
6
|
+
case 0 /* S.Idle */:
|
7
|
+
if (type === 'string.template') {
|
8
|
+
return 1 /* S.Merging */;
|
9
|
+
}
|
10
|
+
else if (type === 'expression.template.begin') {
|
11
|
+
return 2 /* S.ExpectingExpression */;
|
12
|
+
}
|
13
|
+
break;
|
14
|
+
case 1 /* S.Merging */:
|
15
|
+
if (type === 'string.template') {
|
16
|
+
return 1 /* S.Merging */;
|
17
|
+
}
|
18
|
+
else if (type === 'expression.template.begin') {
|
19
|
+
return 2 /* S.ExpectingExpression */;
|
20
|
+
}
|
21
|
+
else {
|
22
|
+
return end.MERGE_WITHOUT_LAST;
|
23
|
+
}
|
24
|
+
case 2 /* S.ExpectingExpression */:
|
25
|
+
if (type === 'string') {
|
26
|
+
return 3 /* S.ExpectingEndBrace */;
|
27
|
+
}
|
28
|
+
break;
|
29
|
+
case 3 /* S.ExpectingEndBrace */:
|
30
|
+
if (type === 'expression.template.end') {
|
31
|
+
return 1 /* S.Merging */;
|
32
|
+
}
|
33
|
+
break;
|
34
|
+
}
|
35
|
+
},
|
36
|
+
customType: 'string',
|
37
|
+
resultToken: (matched) => {
|
38
|
+
const result = [];
|
39
|
+
for (const token of matched) {
|
40
|
+
if (token.customType === 'string.template') {
|
41
|
+
// Match and remove leading whitespace except for newlines
|
42
|
+
let value = token.token.replace(/^[^\S\n]+/gm, '');
|
43
|
+
// Match and remove trailing whitespace except for newlines
|
44
|
+
value = value.replace(/[^\S\n]+$/gm, '');
|
45
|
+
// replace multiple newlines with one space
|
46
|
+
value = value.replace(/[\n]+/gm, ' ');
|
47
|
+
result.push(value);
|
48
|
+
}
|
49
|
+
else if (token.customType === 'string') {
|
50
|
+
result.push(token.token);
|
51
|
+
}
|
52
|
+
}
|
53
|
+
return result.join('').trim();
|
54
|
+
},
|
55
|
+
};
|
@@ -0,0 +1,40 @@
|
|
1
|
+
const INITIAL_DEPTH = -1;
|
2
|
+
// in ts files we want to ignore stuff after 'as' `[count as number]`
|
3
|
+
export const typesAsMergerer = {
|
4
|
+
initial: INITIAL_DEPTH,
|
5
|
+
step: (depth, token, end) => {
|
6
|
+
const type = token.customType;
|
7
|
+
if (depth === INITIAL_DEPTH) {
|
8
|
+
if (type === 'typescript.as') {
|
9
|
+
return 0;
|
10
|
+
}
|
11
|
+
}
|
12
|
+
else if (depth === 0) {
|
13
|
+
// anything unexpected will end the ignoring
|
14
|
+
switch (type) {
|
15
|
+
case 'typescript.expr.begin':
|
16
|
+
case 'expression.begin':
|
17
|
+
return depth + 1;
|
18
|
+
case 'typescript.type.primitive':
|
19
|
+
case 'typescript.operator':
|
20
|
+
return depth;
|
21
|
+
default:
|
22
|
+
return end.MERGE_WITHOUT_LAST;
|
23
|
+
}
|
24
|
+
}
|
25
|
+
else if (depth > 0) {
|
26
|
+
// we are deeply nested, ignore everything
|
27
|
+
switch (type) {
|
28
|
+
case 'typescript.expr.begin':
|
29
|
+
case 'expression.begin':
|
30
|
+
return depth + 1;
|
31
|
+
case 'typescript.expr.end':
|
32
|
+
case 'expression.end':
|
33
|
+
return depth - 1;
|
34
|
+
default:
|
35
|
+
return depth;
|
36
|
+
}
|
37
|
+
}
|
38
|
+
},
|
39
|
+
customType: 'ignore',
|
40
|
+
};
|
@@ -0,0 +1,28 @@
|
|
1
|
+
const INITIAL_DEPTH = 0;
|
2
|
+
// in ts files we want to ignore type casting (<number> count)
|
3
|
+
export const typesCastMergerer = {
|
4
|
+
initial: INITIAL_DEPTH,
|
5
|
+
step: (depth, token, end) => {
|
6
|
+
const type = token.customType;
|
7
|
+
if (depth === INITIAL_DEPTH) {
|
8
|
+
if (type === 'typescript.expr.begin') {
|
9
|
+
return 1;
|
10
|
+
}
|
11
|
+
}
|
12
|
+
else if (depth > 0) {
|
13
|
+
if (type === 'typescript.expr.end' && depth === 1) {
|
14
|
+
return end.MERGE_ALL;
|
15
|
+
}
|
16
|
+
else if (type === 'typescript.expr.end') {
|
17
|
+
return depth - 1;
|
18
|
+
}
|
19
|
+
else if (type === 'typescript.expr.begin') {
|
20
|
+
return depth + 1;
|
21
|
+
}
|
22
|
+
else {
|
23
|
+
return depth;
|
24
|
+
}
|
25
|
+
}
|
26
|
+
},
|
27
|
+
customType: 'ignore',
|
28
|
+
};
|
@@ -0,0 +1,54 @@
|
|
1
|
+
function getCombinedOptions({ ns, noWrap, orEmpty, params, language, ...rest }, line) {
|
2
|
+
const options = {
|
3
|
+
ns: ns,
|
4
|
+
noWrap: noWrap,
|
5
|
+
orEmpty: orEmpty,
|
6
|
+
language: language,
|
7
|
+
};
|
8
|
+
return {
|
9
|
+
...options,
|
10
|
+
params: {
|
11
|
+
type: 'dict',
|
12
|
+
line,
|
13
|
+
value: {
|
14
|
+
...rest,
|
15
|
+
},
|
16
|
+
unknown: [],
|
17
|
+
},
|
18
|
+
};
|
19
|
+
}
|
20
|
+
export const getTranslateProps = (node) => {
|
21
|
+
const [keyOrProps, ...params] = node.values;
|
22
|
+
let result = {
|
23
|
+
type: 'dict',
|
24
|
+
line: node.line,
|
25
|
+
value: {},
|
26
|
+
unknown: [],
|
27
|
+
};
|
28
|
+
let options = undefined;
|
29
|
+
if (keyOrProps?.type === 'dict') {
|
30
|
+
result = keyOrProps;
|
31
|
+
}
|
32
|
+
else {
|
33
|
+
result.value.key = keyOrProps;
|
34
|
+
if (params[0]?.type === 'primitive' || params.length >= 2) {
|
35
|
+
result.value.defaultValue = params[0];
|
36
|
+
options = params[1];
|
37
|
+
}
|
38
|
+
else {
|
39
|
+
options = params[0];
|
40
|
+
}
|
41
|
+
}
|
42
|
+
let optionsDynamic = false;
|
43
|
+
if (options?.type === 'dict') {
|
44
|
+
result.value = {
|
45
|
+
...getCombinedOptions(options.value, options.line),
|
46
|
+
...result.value,
|
47
|
+
};
|
48
|
+
result.unknown.push(...options.unknown);
|
49
|
+
}
|
50
|
+
else if (options) {
|
51
|
+
optionsDynamic = true;
|
52
|
+
}
|
53
|
+
return { result, optionsDynamic };
|
54
|
+
};
|