Add support for translation attributes.

This commit is contained in:
Matthias Mailänder
2022-10-25 21:31:36 +02:00
committed by Gustas
parent 760a1245c5
commit e251377f7c
3 changed files with 84 additions and 51 deletions

View File

@@ -7,7 +7,7 @@
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Linguini.Bundle" Version="0.3.1" />
<PackageReference Include="Linguini.Bundle" Version="0.3.2" />
<PackageReference Include="OpenRA-Eluant" Version="1.0.18" />
<PackageReference Include="Mono.NAT" Version="3.0.3" />
<PackageReference Include="SharpZipLib" Version="1.3.3" />

View File

@@ -101,7 +101,7 @@ namespace OpenRA
foreach (var (k, v) in arguments)
fluentArguments.Add(k, v.ToFluentType());
var result = bundle.TryGetAttrMsg(key, fluentArguments, out var errors, out value);
var result = bundle.TryGetAttrMessage(key, fluentArguments, out var errors, out value);
foreach (var error in errors)
Log.Write("debug", $"Translation of {key}: {error}");
@@ -118,7 +118,7 @@ namespace OpenRA
public bool HasMessage(string key)
{
return bundle.HasMessage(key);
return bundle.HasAttrMessage(key);
}
// Adapted from Fluent.Net.SimpleExample.TranslationService by Mark Weaver

View File

@@ -62,54 +62,31 @@ namespace OpenRA.Mods.Common.Lint
foreach (var entry in result.Entries)
{
// Don't flag definitions referenced (only) within the .ftl definitions as unused
var isReusableTerm = entry.GetType() == typeof(AstTerm);
var key = entry.GetId();
if (!referencedKeys.Contains(key) && !isReusableTerm)
emitWarning($"Unused key `{key}` in {file}.");
if (entry.GetType() == typeof(AstTerm))
continue;
variableReferences.Clear();
var key = entry.GetId();
if (entry is AstMessage message)
{
var node = message.Value;
foreach (var element in node.Elements)
{
if (element is Placeable placeable)
{
var expression = placeable.Expression;
if (expression is IInlineExpression inlineExpression)
{
if (inlineExpression is VariableReference variableReference)
CheckVariableReference(variableReference.Id.Name.ToString(), entry, emitWarning, file);
}
var hasAttributes = message.Attributes.Count > 0;
if (expression is SelectExpression selectExpression)
{
foreach (var variant in selectExpression.Variants)
{
foreach (var variantElement in variant.Value.Elements)
{
if (variantElement is Placeable variantPlaceable)
{
var variantExpression = variantPlaceable.Expression;
if (variantExpression is IInlineExpression variantInlineExpression)
{
if (variantInlineExpression is VariableReference variantVariableReference)
CheckVariableReference(variantVariableReference.Id.Name.ToString(), entry, emitWarning, file);
}
}
}
}
}
}
if (!hasAttributes)
{
CheckUnusedKey(key, null, emitWarning, file);
CheckMessageValue(message.Value, key, null, emitWarning, file);
CheckMissingVariable(key, null, emitError, file);
}
if (referencedVariablesPerKey.ContainsKey(entry.GetId()))
else
{
var referencedVariables = referencedVariablesPerKey[entry.GetId()];
foreach (var referencedVariable in referencedVariables)
foreach (var attribute in message.Attributes)
{
if (!variableReferences.Contains(referencedVariable))
emitError($"Missing variable `{referencedVariable}` for key `{entry.GetId()}` in {file}.");
var attrName = attribute.Id.Name.ToString();
CheckUnusedKey(key, attrName, emitWarning, file);
CheckMessageValue(attribute.Value, key, attrName, emitWarning, file);
CheckMissingVariable(key, attrName, emitError, file);
}
}
}
@@ -118,18 +95,74 @@ namespace OpenRA.Mods.Common.Lint
}
}
void CheckVariableReference(string element, IEntry entry, Action<string> emitWarning, string file)
void CheckUnusedKey(string key, string attribute, Action<string> emitWarning, string file)
{
variableReferences.Add(element);
var isAttribute = !string.IsNullOrEmpty(attribute);
var keyWithAtrr = isAttribute ? $"{key}.{attribute}" : key;
if (referencedVariablesPerKey.ContainsKey(entry.GetId()))
if (!referencedKeys.Contains(keyWithAtrr))
emitWarning(isAttribute ?
$"Unused attribute `{attribute}` of key `{key}` in {file}." :
$"Unused key `{key}` in {file}.");
}
void CheckMessageValue(Pattern node, string key, string attribute, Action<string> emitWarning, string file)
{
foreach (var element in node.Elements)
{
var referencedVariables = referencedVariablesPerKey[entry.GetId()];
if (!referencedVariables.Contains(element))
emitWarning($"Unused variable `{element}` for key `{entry.GetId()}` in {file}.");
if (element is Placeable placeable)
{
var expression = placeable.Expression;
if (expression is IInlineExpression inlineExpression)
if (inlineExpression is VariableReference variableReference)
CheckVariableReference(variableReference.Id.Name.ToString(), key, attribute, emitWarning, file);
if (expression is SelectExpression selectExpression)
{
foreach (var variant in selectExpression.Variants)
{
foreach (var variantElement in variant.Value.Elements)
{
if (variantElement is Placeable variantPlaceable)
{
var variantExpression = variantPlaceable.Expression;
if (variantExpression is IInlineExpression variantInlineExpression)
if (variantInlineExpression is VariableReference variantVariableReference)
CheckVariableReference(variantVariableReference.Id.Name.ToString(), key, attribute, emitWarning, file);
}
}
}
}
}
}
else
emitWarning($"Unused variable `{element}` for key `{entry.GetId()}` in {file}.");
}
void CheckMissingVariable(string key, string attribute, Action<string> emitError, string file)
{
var isAttribute = !string.IsNullOrEmpty(attribute);
var keyWithAtrr = isAttribute ? $"{key}.{attribute}" : key;
if (!referencedVariablesPerKey.ContainsKey(keyWithAtrr))
return;
foreach (var referencedVariable in referencedVariablesPerKey[keyWithAtrr])
if (!variableReferences.Contains(referencedVariable))
emitError(isAttribute ?
$"Missing variable `{referencedVariable}` for attribute `{attribute}` of key `{key}` in {file}." :
$"Missing variable `{referencedVariable}` for key `{key}` in {file}.");
}
void CheckVariableReference(string varName, string key, string attribute, Action<string> emitWarning, string file)
{
var isAttribute = !string.IsNullOrEmpty(attribute);
var keyWithAtrr = isAttribute ? $"{key}.{attribute}" : key;
variableReferences.Add(varName);
if (!referencedVariablesPerKey.ContainsKey(keyWithAtrr) || !referencedVariablesPerKey[keyWithAtrr].Contains(varName))
emitWarning(isAttribute ?
$"Unused variable `{varName}` for attribute `{attribute}` of key `{key}` in {file}." :
$"Unused variable `{varName}` for key `{key}` in {file}.");
}
}
}