Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add angular grammar #108

Merged
merged 17 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
},
"parser": {
"description": "Override parser detection.",
"enum": ["react", "vue", "svelte"]
"enum": ["react", "vue", "svelte", "ngx"]
},
"push": {
"type": "object",
Expand Down
8 changes: 7 additions & 1 deletion scripts/grammars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ export const Grammars: Record<string, UrlString> = {
Svelte:
'https://raw.githubusercontent.com/sveltejs/language-tools/master/packages/svelte-vscode/syntaxes/svelte.tmLanguage.src.yaml',
Vue: 'https://raw.githubusercontent.com/vuejs/language-tools/master/extensions/vscode/syntaxes/vue.tmLanguage.json',

AngularHtml:
'https://raw.githubusercontent.com/ghaschel/vscode-angular-html/master/syntaxes/html-template.ng.json',
HTML: 'https://raw.githubusercontent.com/textmate/html.tmbundle/master/Syntaxes/HTML.plist',
};

Expand All @@ -48,6 +49,11 @@ export const Licenses: LicenseInformation[] = [
license:
'https://raw.githubusercontent.com/vuejs/language-tools/master/extensions/vscode/LICENSE',
},
{
grammars: ['AngularHtml'],
license:
'https://raw.githubusercontent.com/ghaschel/vscode-angular-html/master/LICENSE',
},
];

// Transformers receive the grammar and a Record<keyof Grammars, string>, where the value is the downloaded TM grammar.
Expand Down
17 changes: 13 additions & 4 deletions src/extractor/extractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Token } from './parser/types.js';
import { tokensList } from './visualizers/printTokens.js';
import { visualizeRules } from './visualizers/visualizeRules.js';
import { ParserVue } from './parserVue/ParserVue.js';
import { ParserNgx } from './parserNgx/ParserNgx.js';
import { ParserSvelte } from './parserSvelte/ParserSvelte.js';
import { ExtractOptions, ExtractionResult, ParserType } from './index.js';
import { IteratorListener } from './parser/iterator.js';
Expand All @@ -16,6 +17,8 @@ function pickParser(format: ParserType) {
return ParserVue();
case 'svelte':
return ParserSvelte();
case 'ngx':
return ParserNgx();
}
}

Expand Down Expand Up @@ -48,10 +51,16 @@ export async function extractTreeAndReport(
});

if (debug) {
console.log(JSON.stringify(result.tree, null, 2));
console.log(tokensList(tokensMerged));
console.log(visualizeRules(tokensMerged, code));
console.log(visualizeRules(tokensWithRules, code));
console.log(
JSON.stringify(result.tree, null, 2) +
'\n' +
tokensList(tokensMerged) +
'\n' +
visualizeRules(tokensMerged, code) +
'\n' +
visualizeRules(tokensWithRules, code) +
'\n'
);
}

return result;
Expand Down
2 changes: 1 addition & 1 deletion src/extractor/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export type ExtractOptions = {
defaultNamespace: string | undefined;
};

export type ParserType = 'react' | 'vue' | 'svelte';
export type ParserType = 'react' | 'vue' | 'svelte' | 'ngx';

export type Extractor = (
fileContents: string,
Expand Down
18 changes: 7 additions & 11 deletions src/extractor/parser/extractComment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,6 @@ function isValidKeyOverride(data: any): data is KeyOverride {
return true;
}

function getEndLine(token: TokenType) {
return token.line + (token.token.match(/\n/gm)?.length ?? 0);
}

type TokenType = {
token: string;
line: number;
Expand All @@ -62,12 +58,12 @@ type TokenType = {
export function extractComment(
token: TokenType
): MagicCommentEvent | undefined {
const comment = token.token.trim();
const comment = token.token.replaceAll(/[^\n]([\w]*\*+)/g, '').trim();
if (comment.startsWith('@tolgee-ignore')) {
return {
type: 'MAGIC_COMMENT',
kind: 'ignore',
line: getEndLine(token),
line: token.line,
};
}

Expand All @@ -80,7 +76,7 @@ export function extractComment(
type: 'MAGIC_COMMENT',
kind: 'key',
keyName: data.slice(1),
line: getEndLine(token),
line: token.line,
};
}

Expand All @@ -93,7 +89,7 @@ export function extractComment(
return {
type: 'WARNING',
kind: 'W_INVALID_KEY_OVERRIDE',
line: getEndLine(token),
line: token.line,
};
} else {
return {
Expand All @@ -102,22 +98,22 @@ export function extractComment(
keyName: key.key,
namespace: key.ns,
defaultValue: key.defaultValue,
line: getEndLine(token),
line: token.line,
};
}
} catch {
return {
type: 'WARNING',
kind: 'W_MALFORMED_KEY_OVERRIDE',
line: getEndLine(token),
line: token.line,
};
}
}
return {
type: 'MAGIC_COMMENT',
kind: 'key',
keyName: data,
line: getEndLine(token),
line: token.line,
};
}
}
8 changes: 4 additions & 4 deletions src/extractor/parser/generalMapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ export const generalMapper = (token: Token) => {

// plain strings
case 'punctuation.definition.string.begin.ts':
return 'string.begin';
return 'string.quote';
case 'punctuation.definition.string.end.ts':
return 'string.end';
return 'string.quote';
case 'string.quoted.single.ts':
case 'string.quoted.double.ts':
return 'string.body';
Expand All @@ -28,9 +28,9 @@ export const generalMapper = (token: Token) => {

// template strings
case 'punctuation.definition.string.template.begin.ts':
return 'string.teplate.begin';
return 'string.teplate.quote';
case 'punctuation.definition.string.template.end.ts':
return 'string.template.end';
return 'string.template.quote';
case 'string.template.ts':
return 'string.template.body';

Expand Down
65 changes: 49 additions & 16 deletions src/extractor/parser/mergerMachine.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { Token } from './types.js';

export type MergeResult<T extends string | undefined> = {
before: Token<T>[];
toMerge: Token<T>[];
after: Token<T>[];
};

export type MachineType<
TokenType extends string | undefined,
State,
Expand All @@ -12,34 +18,37 @@ export type MachineType<
end: typeof endOptions
) => State | symbol | undefined;
customType: CustomTokenType;
resultToken?: (matched: Token<TokenType>[]) => string;
resultToken?: (matched: Token<TokenType>[]) => Partial<Token>;
customMerge?: (tokens: Token<TokenType>[]) => MergeResult<TokenType>;
};

function defaultResultToken<T extends string | undefined>(matched: Token<T>[]) {
return matched.map((t) => t.token).join('');
}

const MERGE_ALL = Symbol('MERGE_ALL');
const MERGE_WITHOUT_LAST = Symbol('MERGE_WITHOUT_LAST');
const REPLACE_FIRST = Symbol('REPLACE_FIRST');
const MERGE_CUSTOM = Symbol('MERGE_CUSTOM');

export const endOptions = {
MERGE_ALL,
MERGE_WITHOUT_LAST,
REPLACE_FIRST,
MERGE_CUSTOM,
};

function createNewToken(
tokens: Token[],
customType: string,
merger: (matched: Token[]) => string
merger: ((matched: Token[]) => Partial<Token>) | undefined
) {
const mergerData = merger?.(tokens);
return {
customType,
type: 'custom',
startIndex: tokens[0].startIndex,
endIndex: tokens[tokens.length - 1].endIndex,
scopes: [],
line: tokens[0].line,
token: merger(tokens),
token: tokens.map((t) => t.token).join(''),
...mergerData,
} satisfies Token;
}

Expand Down Expand Up @@ -72,21 +81,45 @@ export function createMachine<M extends MachineType<any, any, any>>(
continue;
} else if (
newState === endOptions.MERGE_ALL ||
newState === endOptions.MERGE_WITHOUT_LAST
newState === endOptions.MERGE_WITHOUT_LAST ||
newState === endOptions.REPLACE_FIRST ||
newState === endOptions.MERGE_CUSTOM
) {
const lastToken =
newState === endOptions.MERGE_WITHOUT_LAST ? stack.pop() : undefined;
let before: Token[] = [];
let toMerge: Token[];
let after: Token[];
if (newState === endOptions.MERGE_ALL) {
toMerge = stack;
after = [];
} else if (newState === endOptions.MERGE_WITHOUT_LAST) {
after = [stack.pop()!];
toMerge = stack;
} else if (newState === endOptions.REPLACE_FIRST) {
toMerge = [stack.shift()!];
after = stack;
} else {
if (!machine.customMerge) {
throw new Error('No custom merge cpecified');
}
const result = machine.customMerge(stack);
before = result.before;
toMerge = result.toMerge;
after = result.after;
}
const newToken = createNewToken(
stack,
toMerge,
machine.customType,
machine.resultToken ?? defaultResultToken
machine.resultToken
);
state = machine.initial;
stack = [];
for (const result of before) {
yield result;
}
yield newToken;
if (lastToken) {
yield lastToken;
for (const result of after) {
yield result;
}
stack = [];
state = machine.initial;
continue;
} else {
state = newState;
Expand Down
2 changes: 1 addition & 1 deletion src/extractor/parser/tokenMergers/closingTagMerger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ export const closingTagMerger = {
},
customType: 'tag.closing',
resultToken: (matched) => {
return matched[1].token;
return { token: matched[1].token };
},
} as const satisfies MachineType<ReactMappedTokenType, S>;
13 changes: 8 additions & 5 deletions src/extractor/parser/tokenMergers/commentsMerger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const commentsMerger = {
case S.CommentStart:
if (type === 'comment.line') {
return end.MERGE_ALL;
} else if (type === 'comment.block') {
} else if (type === 'comment.block' || token.token === '\n') {
return S.CommentBlock;
}
break;
Expand All @@ -36,10 +36,13 @@ export const commentsMerger = {
}
},
resultToken: (matched) => {
return matched
.filter((t) => t.customType && t.customType !== 'comment.definition')
.map((t) => t.token)
.join('');
return {
token: matched
.filter((t) => t.customType && t.customType !== 'comment.definition')
.map((t) => t.token)
.join(''),
line: matched[matched.length - 1].line,
};
},
customType: 'comment',
} as const satisfies MachineType<GeneralTokenType, S>;
10 changes: 5 additions & 5 deletions src/extractor/parser/tokenMergers/stringMerger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ export const stringMerger = {
const type = token.customType;
switch (state) {
case S.Idle:
if (type === 'string.begin') {
if (type === 'string.quote') {
return S.RegularString;
} else if (type === 'string.teplate.begin') {
} else if (type === 'string.teplate.quote') {
return S.TemplateString;
}
break;
Expand All @@ -25,7 +25,7 @@ export const stringMerger = {
return S.RegularString;
} else if (type === 'escaped.character') {
return S.RegularString;
} else if (type === 'string.end') {
} else if (type === 'string.quote') {
return end.MERGE_ALL;
}
break;
Expand All @@ -34,7 +34,7 @@ export const stringMerger = {
return S.TemplateString;
} else if (type === 'escaped.character') {
return S.TemplateString;
} else if (type === 'string.template.end') {
} else if (type === 'string.template.quote') {
return end.MERGE_ALL;
}
break;
Expand All @@ -55,6 +55,6 @@ export const stringMerger = {
}
})
.join('');
return unescape(escaped);
return { token: unescape(escaped) };
},
} as const satisfies MachineType<GeneralTokenType, S>;
2 changes: 1 addition & 1 deletion src/extractor/parser/tokenMergers/templateStringMerger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,6 @@ export const templateStringMerger = {
}
}

return result.join('').trim();
return { token: result.join('').trim() };
},
} as const satisfies MachineType<ReactMappedTokenType, S>;
2 changes: 1 addition & 1 deletion src/extractor/parser/tree/getTranslateProps.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ArrayNode, DictNode, GeneralNode } from '../types.js';

function getCombinedOptions(
export function getCombinedOptions(
{
ns,
noWrap,
Expand Down
Loading