Skip to content

Commit

Permalink
Use arb-dir (#58)
Browse files Browse the repository at this point in the history
* Use arb-dir

* Refactor parser and add tests

* Update test

---------

Co-authored-by: Moritz <mosum@google.com>
  • Loading branch information
kzrnm and mosuem authored Sep 30, 2024
1 parent 962ca41 commit a12845a
Show file tree
Hide file tree
Showing 25 changed files with 250 additions and 73 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@ To set a template file, either set the `@@x-template` element in your `arb` file
```
or set a file to be the template in the `l10n.yaml` using:
```yaml
template-arb-file: path/to/template.arb
arb-dir: path/to
template-arb-file: template.arb
```

You can suppress specific diagnostics warnings by adding into `settings.json`:
```json
"arb-editor.suppressedWarnings": string | string[]
Expand Down
55 changes: 8 additions & 47 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ import { CodeActions } from './codeactions';
import { Decorator } from './decorate';
import { Diagnostics } from './diagnose';
import { Literal, MessageList, Parser } from './messageParser';
import { locateL10nYaml } from './project';
import YAML = require('yaml');
import fs = require('fs');
const snippetsJson = require("../snippets/snippets.json");
const snippetsInlineJson = require("../snippets/snippets_inline.json");

Expand Down Expand Up @@ -87,10 +84,14 @@ export async function activate(context: vscode.ExtensionContext) {
if (!editor || isNotArbFile(editor.document)) {
return;
}
var l10nYamlPath = locateL10nYaml(editor.document.uri.fsPath);
var l10nOptions: L10nYaml | undefined;
if (l10nYamlPath) {
l10nOptions = parseYaml(l10nYamlPath);

function parseAndDecorate(): MessageList {
return parser.parseAndDecorate({
editor: editor!,
decorator: decorator,
diagnostics: diagnostics,
quickfixes: quickfixes,
}).messageList;
}

if (executeDelayed && pendingDecorations) {
Expand All @@ -103,38 +104,6 @@ export async function activate(context: vscode.ExtensionContext) {
commonMessageList = parseAndDecorate();
}
}

function parseAndDecorate(): MessageList {
let templatePathFromOptions = l10nOptions?.['template-arb-file'];
let templateMessageList: MessageList | undefined;
let templateErrors: Literal[] | undefined;
let [templatePathFromFile, messageList, errors] = parser.parse(editor!.document.getText(), l10nOptions)!;
if (templatePathFromOptions || templatePathFromFile) {
let templatePath: string;
if (templatePathFromFile) {
if (path.isAbsolute(templatePathFromFile)) {
templatePath = templatePathFromFile;
} else {
templatePath = path.join(path.dirname(editor?.document.uri.path!), templatePathFromFile);
}
} else {
if (path.isAbsolute(templatePathFromOptions!)) {
templatePath = templatePathFromOptions!;
} else {
templatePath = path.join(path.dirname(l10nYamlPath!), templatePathFromOptions!);
}
}
if (templatePath !== editor!.document.uri.fsPath) {
const template = fs.readFileSync(templatePath, "utf8");
// TODO(mosuem): Allow chaining of template files.
[, templateMessageList, templateErrors] = parser.parse(template, l10nOptions)!;
}
}
decorator.decorate(editor!, messageList);
diagnostics.diagnose(editor!, messageList, errors, templateMessageList);
quickfixes.update(messageList);
return messageList;
}
}
}

Expand Down Expand Up @@ -164,14 +133,6 @@ function getSnippets(snippetsJson: any): vscode.CompletionList {
// This method is called when your extension is deactivated
export function deactivate() { }

function parseYaml(uri: string): L10nYaml | undefined {
if (!fs.existsSync(uri)) {
return;
}
const yaml = fs.readFileSync(uri, "utf8");
return YAML.parse(yaml) as L10nYaml;
}

export interface L10nYaml {
'arb-dir'?: string | undefined;
'output-dir'?: string | undefined;
Expand Down
98 changes: 95 additions & 3 deletions src/messageParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,21 @@
// limitations under the License.
'use strict';

import * as vscode from 'vscode';
import { JSONPath, visit } from 'jsonc-parser';
import XRegExp = require('xregexp');
import { locateL10nYaml } from './project';
import { L10nYaml } from './extension';
import { Diagnostics } from './diagnose';
import { Decorator } from './decorate';
import { CodeActions } from './codeactions';
import path = require('path');
import YAML = require('yaml');
import fs = require('fs');

export class Parser {

parse(document: string, l10nOptions?: L10nYaml): [string|undefined, MessageList, Literal[]] {
parse(document: string, l10nOptions?: L10nYaml): [MessageList, Literal[]] {
let templatePath: string | undefined;
const messages: MessageEntry[] = [];
const metadata: MessageEntry[] = [];
Expand All @@ -25,7 +33,7 @@ export class Parser {
let inTemplateTag = false;
let placeholderLevel: number | null = null;
let metadataLevel: number | null = null;
let metadataKey: Key | null = null;
let metadataKey: Key | null = null;
let messageKey: Key | null = null;
let definedPlaceholders: PlaceholderMetadata[] = [];
let errors: Literal[] = [];
Expand Down Expand Up @@ -172,8 +180,84 @@ export class Parser {
}
}

return [templatePath, new MessageList(templatePath, indentation ?? 0, indentationCharacter ?? ' ', messages, metadata), errors];
return [new MessageList(templatePath, indentation ?? 0, indentationCharacter ?? ' ', messages, metadata), errors];
}


private resolveTemplatePath({
document,
messageList,
l10nYamlPath,
l10nOptions,
}: {
document: vscode.TextDocument;
messageList: MessageList;
} & L10nYamlPathAndOptions): string | undefined {
if (messageList.templatePath) {
return path.isAbsolute(messageList.templatePath)
? messageList.templatePath
: path.join(path.dirname(document.uri.fsPath), messageList.templatePath);
} else if (l10nOptions !== undefined) {
const templateRootFromOptions = l10nOptions?.['arb-dir'] ?? 'lib/l10n';
const templatePathFromOptions = l10nOptions?.['template-arb-file'] ?? 'app_en.arb';

return path.isAbsolute(templatePathFromOptions)
? templatePathFromOptions
: path.join(path.dirname(l10nYamlPath), templateRootFromOptions, templatePathFromOptions);
}
}

parseAndDecorate({
editor,
decorator,
diagnostics,
quickfixes,
}: ParseAndDecorateOptions): ParseAndDecorateResult {
let templateMessageList: MessageList | undefined;

const l10nYamlPath = locateL10nYaml(editor.document.uri.fsPath);
const l10nOptions = l10nYamlPath
? parseYaml(l10nYamlPath)
: undefined;
const [messageList, errors] = this.parse(editor.document.getText(), l10nOptions)!;

const templatePath = this.resolveTemplatePath({
document: editor.document,
messageList,
l10nYamlPath: l10nYamlPath!,
l10nOptions: l10nOptions,
});

if (templatePath && templatePath !== editor.document.uri.fsPath) {
const template = fs.readFileSync(templatePath, "utf8");
// TODO(mosuem): Allow chaining of template files.
[templateMessageList,] = this.parse(template, l10nOptions)!;
}

const decorations = decorator.decorate(editor, messageList);
const diags = diagnostics.diagnose(editor, messageList, errors, templateMessageList);
quickfixes.update(messageList);
return { messageList, decorations, diagnostics: diags };
}
}

type L10nYamlPathAndOptions = {
l10nYamlPath: string;
l10nOptions: L10nYaml;
} | {
l10nYamlPath: string | undefined;
l10nOptions: undefined;
};
interface ParseAndDecorateResult {
messageList: MessageList;
decorations: Map<vscode.TextEditorDecorationType, vscode.Range[]>;
diagnostics: vscode.Diagnostic[];
}
interface ParseAndDecorateOptions {
editor: vscode.TextEditor;
decorator: Decorator;
diagnostics: Diagnostics;
quickfixes: CodeActions;
}

function matchCurlyBrackets(v: string, l10nOptions?: L10nYaml): XRegExp.MatchRecursiveValueNameMatch[] {
Expand All @@ -189,6 +273,14 @@ function matchCurlyBrackets(v: string, l10nOptions?: L10nYaml): XRegExp.MatchRec
return values;
}

function parseYaml(uri: string): L10nYaml | undefined {
if (!fs.existsSync(uri)) {
return;
}
const yaml = fs.readFileSync(uri, "utf8");
return YAML.parse(yaml) as L10nYaml;
}

export function getUnescapedRegions(expression: string, l10nOptions?: L10nYaml): [number, number][] {
const unEscapedRegions: [number, number][] = [];

Expand Down
5 changes: 5 additions & 0 deletions src/test/l10nYaml/arb-dir/_l10n/app_en.arb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"@@locale": "en",
"appName": "Demo app",
"dir": "dir"
}
4 changes: 4 additions & 0 deletions src/test/l10nYaml/arb-dir/_l10n/testarb_2.annotated
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"@@locale": "en"
}
[Warning]:"Missing messages from template: appName, dir"
3 changes: 3 additions & 0 deletions src/test/l10nYaml/arb-dir/_l10n/testarb_2.arb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"@@locale": "en"
}
4 changes: 4 additions & 0 deletions src/test/l10nYaml/arb-dir/l10n.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
arb-dir: _l10n
output-class: Words
output-localization-file: app_localizations.dart
untranslated-messages-file: lib/_l10n/desiredFileName.txt
5 changes: 5 additions & 0 deletions src/test/l10nYaml/arb-dir_template-arb-file/_l10n/testarb.arb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"@@locale": "en",
"appName": "Demo app",
"dirAndTemplate": "dirAndTemplate"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"@@locale": "en"
}
[Warning]:"Missing messages from template: appName, dirAndTemplate"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"@@locale": "en"
}
5 changes: 5 additions & 0 deletions src/test/l10nYaml/arb-dir_template-arb-file/l10n.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
arb-dir: _l10n
template-arb-file: testarb.arb
output-class: Words
output-localization-file: app_localizations.dart
untranslated-messages-file: lib/_l10n/desiredFileName.txt
Empty file.
5 changes: 5 additions & 0 deletions src/test/l10nYaml/empty/lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"@@locale": "en",
"appName": "Demo app",
"empty": "empty"
}
4 changes: 4 additions & 0 deletions src/test/l10nYaml/empty/lib/l10n/testarb_2.annotated
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"@@locale": "en"
}
[Warning]:"Missing messages from template: appName, empty"
3 changes: 3 additions & 0 deletions src/test/l10nYaml/empty/lib/l10n/testarb_2.arb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"@@locale": "en"
}
4 changes: 4 additions & 0 deletions src/test/l10nYaml/template-arb-file/l10n.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
template-arb-file: testarb.arb
output-class: Words
output-localization-file: app_localizations.dart
untranslated-messages-file: lib/_l10n/desiredFileName.txt
5 changes: 5 additions & 0 deletions src/test/l10nYaml/template-arb-file/lib/l10n/testarb.arb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"@@locale": "en",
"appName": "Demo app",
"template": "template"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"@@locale": "en"
}
[Warning]:"Missing messages from template: appName, template"
3 changes: 3 additions & 0 deletions src/test/l10nYaml/template-arb-file/lib/l10n/testarb_2.arb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"@@locale": "en"
}
5 changes: 5 additions & 0 deletions src/test/l10nYaml/with_x-template/l10n.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
arb-dir: lib/_l10n
template-arb-file: app_ja.arb
output-class: Words
output-localization-file: app_localizations.dart
untranslated-messages-file: lib/_l10n/desiredFileName.txt
5 changes: 5 additions & 0 deletions src/test/l10nYaml/with_x-template/l10n/testarb.arb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"@@locale": "en",
"appName": "Demo app",
"withTemplate": "withTemplate"
}
5 changes: 5 additions & 0 deletions src/test/l10nYaml/with_x-template/l10n/testarb_2.annotated
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"@@locale": "en",
"@@x-template": "testarb.arb"
}
[Warning]:"Missing messages from template: appName, withTemplate"
4 changes: 4 additions & 0 deletions src/test/l10nYaml/with_x-template/l10n/testarb_2.arb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"@@locale": "en",
"@@x-template": "testarb.arb"
}
1 change: 1 addition & 0 deletions src/test/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
name: Dummy
Loading

0 comments on commit a12845a

Please sign in to comment.