Skip to content

Bug 1412808 - Remove the LITERAL helper. #25

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

Merged
merged 1 commit into from
Oct 30, 2017
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 fluent/migrate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
Source, COPY, REPLACE_IN_TEXT, REPLACE, PLURALS, CONCAT
)
from .helpers import ( # noqa: F401
LITERAL, EXTERNAL_ARGUMENT, MESSAGE_REFERENCE
EXTERNAL_ARGUMENT, MESSAGE_REFERENCE
)
from .changesets import convert_blame_to_changesets # noqa: F401
2 changes: 1 addition & 1 deletion fluent/migrate/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class MergeContext(object):
- A list of `FTL.Message` objects some of whose nodes are special
helper or transform nodes:

helpers: LITERAL, EXTERNAL_ARGUMENT, MESSAGE_REFERENCE
helpers: EXTERNAL_ARGUMENT, MESSAGE_REFERENCE
transforms: COPY, REPLACE_IN_TEXT, REPLACE, PLURALS, CONCAT
"""

Expand Down
6 changes: 0 additions & 6 deletions fluent/migrate/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,6 @@
import fluent.syntax.ast as FTL


def LITERAL(value):
"""Create a Pattern with a single TextElement."""
elements = [FTL.TextElement(value)]
return FTL.Pattern(elements)


def EXTERNAL_ARGUMENT(name):
"""Create an ExternalArgument expression."""

Expand Down
45 changes: 26 additions & 19 deletions fluent/migrate/transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,44 +8,44 @@
All Transforms evaluate to Fluent Patterns. This makes them suitable for
defining migrations of values of message, attributes and variants. The special
CONCAT Transform is capable of joining multiple Patterns returned by evaluating
other Transforms into a single Pattern. It can also concatenate Fluent
Expressions, like MessageReferences and ExternalArguments.
other Transforms into a single Pattern. It can also concatenate Pattern
elements: TextElements and Placeables.

The COPY, REPLACE and PLURALS Transforms inherit from Source which is a special
AST Node defining the location (the file path and the id) of the legacy
translation. During the migration, the current MergeContext scans the
migration spec for Source nodes and extracts the information about all legacy
translations being migrated. Thus,
translations being migrated. For instance,

COPY('file.dtd', 'hello')

is equivalent to:

LITERAL(Source('file.dtd', 'hello'))
FTL.Pattern([
FTL.TextElement(Source('file.dtd', 'hello'))
])

where LITERAL is a helper defined in the helpers.py module for creating Fluent
Patterns from the text passed as the argument.

The LITERAL helper and the special REPLACE_IN_TEXT Transforms are useful for
working with text rather than (path, key) source definitions. This is the case
when the migrated translation requires some hardcoded text, e.g. <a> and </a>
when multiple translations become a single one with a DOM overlay.
Sometimes it's useful to work with text rather than (path, key) source
definitions. This is the case when the migrated translation requires some
hardcoded text, e.g. <a> and </a> when multiple translations become a single
one with a DOM overlay. In such cases it's best to use the AST nodes:

FTL.Message(
id=FTL.Identifier('update-failed'),
value=CONCAT(
COPY('aboutDialog.dtd', 'update.failed.start'),
LITERAL('<a>'),
FTL.TextElement('<a>'),
COPY('aboutDialog.dtd', 'update.failed.linkText'),
LITERAL('</a>'),
FTL.TextElement('</a>'),
COPY('aboutDialog.dtd', 'update.failed.end'),
)
)

The REPLACE_IN_TEXT Transform also takes text as input, making in possible to
pass it as the foreach function of the PLURALS Transform. In this case, each
slice of the plural string will be run through a REPLACE_IN_TEXT operation.
Those slices are strings, so a REPLACE(path, key, …) isn't suitable for them.
Those slices are strings, so a REPLACE(path, key, …) wouldn't be suitable for
them.

FTL.Message(
FTL.Identifier('delete-all'),
Expand All @@ -66,7 +66,12 @@
from __future__ import unicode_literals

import fluent.syntax.ast as FTL
from .helpers import LITERAL


def pattern_from_text(value):
return FTL.Pattern([
FTL.TextElement(value)
])


def evaluate(ctx, node):
Expand Down Expand Up @@ -120,7 +125,7 @@ class COPY(Source):

def __call__(self, ctx):
source = super(self.__class__, self).__call__(ctx)
return LITERAL(source)
return pattern_from_text(source)


class REPLACE_IN_TEXT(Transform):
Expand Down Expand Up @@ -210,10 +215,12 @@ class PLURALS(Source):
Build an `FTL.SelectExpression` with the supplied `selector` and variants
extracted from the source. The source needs to be a semicolon-separated
list of variants. Each variant will be run through the `foreach` function,
which should return an `FTL.Node` or a `Transform`.
which should return an `FTL.Node` or a `Transform`. By default, the
`foreach` function transforms the source text into a Pattern with a single
TextElement.
"""

def __init__(self, path, key, selector, foreach=LITERAL):
def __init__(self, path, key, selector, foreach=pattern_from_text):
super(self.__class__, self).__init__(path, key)
self.selector = selector
self.foreach = foreach
Expand Down Expand Up @@ -264,7 +271,7 @@ def concat_elements(acc, cur):
return acc

raise RuntimeError(
'CONCAT accepts FTL Patterns and Expressions.'
'CONCAT accepts FTL Patterns, TextElements and Placeables.'
)

# Merge adjecent `FTL.TextElement` nodes.
Expand Down
25 changes: 10 additions & 15 deletions tests/migrate/test_concat.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,8 @@
DTDParser = PropertiesParser = None

from fluent.migrate.util import parse, ftl_message_to_json
from fluent.migrate.helpers import (
LITERAL, EXTERNAL_ARGUMENT, MESSAGE_REFERENCE
)
from fluent.migrate.transforms import (
evaluate, CONCAT, COPY, REPLACE
)
from fluent.migrate.helpers import EXTERNAL_ARGUMENT, MESSAGE_REFERENCE
from fluent.migrate.transforms import evaluate, CONCAT, COPY, REPLACE


class MockContext(unittest.TestCase):
Expand Down Expand Up @@ -134,9 +130,9 @@ def test_concat_literal(self):
FTL.Identifier('update-failed'),
value=CONCAT(
COPY(self.strings, 'update.failed.start'),
LITERAL('<a>'),
FTL.TextElement('<a>'),
COPY(self.strings, 'update.failed.linkText'),
LITERAL('</a>'),
FTL.TextElement('</a>'),
COPY(self.strings, 'update.failed.end'),
)
)
Expand All @@ -154,16 +150,15 @@ class TestConcatInterpolate(MockContext):
def setUp(self):
self.strings = parse(DTDParser, '''
<!ENTITY channel.description.start "You are on the ">
<!ENTITY channel.description.end " channel. ">
<!ENTITY channel.description.end " channel.">
''')

@unittest.skip('Parser/Serializer trim whitespace')
def test_concat_replace(self):
msg = FTL.Message(
FTL.Identifier('channel-desc'),
value=CONCAT(
COPY(self.strings, 'channel.description.start'),
EXTERNAL_ARGUMENT('channelname'),
FTL.Placeable(EXTERNAL_ARGUMENT('channelname')),
COPY(self.strings, 'channel.description.end'),
)
)
Expand Down Expand Up @@ -200,7 +195,7 @@ def test_concat_replace(self):
)
}
),
LITERAL('<a>'),
FTL.TextElement('<a>'),
REPLACE(
self.strings,
'community.mozillaLink',
Expand All @@ -210,11 +205,11 @@ def test_concat_replace(self):
)
}
),
LITERAL('</a>'),
FTL.TextElement('</a>'),
COPY(self.strings, 'community.middle'),
LITERAL('<a>'),
FTL.TextElement('<a>'),
COPY(self.strings, 'community.creditsLink'),
LITERAL('</a>'),
FTL.TextElement('</a>'),
COPY(self.strings, 'community.end')
)
)
Expand Down
5 changes: 3 additions & 2 deletions tests/migrate/test_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

from fluent.migrate.util import ftl, ftl_resource_to_json, to_json
from fluent.migrate.context import MergeContext
from fluent.migrate.helpers import LITERAL
from fluent.migrate.transforms import COPY


Expand Down Expand Up @@ -37,7 +36,9 @@ def test_hardcoded_node(self):
self.ctx.add_transforms('aboutDownloads.ftl', [
FTL.Message(
id=FTL.Identifier('about'),
value=LITERAL('Hardcoded Value')
value=FTL.Pattern([
FTL.TextElement('Hardcoded Value')
])
),
])

Expand Down
16 changes: 7 additions & 9 deletions tests/migrate/test_context_real_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@

from fluent.migrate.util import ftl_resource_to_json, to_json
from fluent.migrate.context import MergeContext
from fluent.migrate.helpers import (
LITERAL, EXTERNAL_ARGUMENT, MESSAGE_REFERENCE
)
from fluent.migrate.helpers import EXTERNAL_ARGUMENT, MESSAGE_REFERENCE
from fluent.migrate.transforms import (
CONCAT, COPY, PLURALS, REPLACE_IN_TEXT, REPLACE
)
Expand Down Expand Up @@ -301,9 +299,9 @@ def setUp(self):
id=FTL.Identifier('update-failed'),
value=CONCAT(
COPY('aboutDialog.dtd', 'update.failed.start'),
LITERAL('<a>'),
FTL.TextElement('<a>'),
COPY('aboutDialog.dtd', 'update.failed.linkText'),
LITERAL('</a>'),
FTL.TextElement('</a>'),
COPY('aboutDialog.dtd', 'update.failed.end'),
)
),
Expand All @@ -329,7 +327,7 @@ def setUp(self):
)
}
),
LITERAL('<a>'),
FTL.TextElement('<a>'),
REPLACE(
'aboutDialog.dtd',
'community.mozillaLink',
Expand All @@ -339,11 +337,11 @@ def setUp(self):
)
}
),
LITERAL('</a>'),
FTL.TextElement('</a>'),
COPY('aboutDialog.dtd', 'community.middle'),
LITERAL('<a>'),
FTL.TextElement('<a>'),
COPY('aboutDialog.dtd', 'community.creditsLink'),
LITERAL('</a>'),
FTL.TextElement('</a>'),
COPY('aboutDialog.dtd', 'community.end')
)
),
Expand Down
File renamed without changes.
5 changes: 3 additions & 2 deletions tests/migrate/test_merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

from fluent.migrate.util import parse, ftl, ftl_resource_to_json
from fluent.migrate.merge import merge_resource
from fluent.migrate.helpers import LITERAL
from fluent.migrate.transforms import COPY


Expand Down Expand Up @@ -64,7 +63,9 @@ def setUp(self):
),
FTL.Message(
FTL.Identifier('about'),
value=LITERAL('Hardcoded Value')
value=FTL.Pattern([
FTL.TextElement('Hardcoded Value')
])
),
FTL.Message(
FTL.Identifier('open-menuitem'),
Expand Down
5 changes: 2 additions & 3 deletions tests/migrate/test_plural.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
PropertiesParser = None

from fluent.migrate.util import parse, ftl_message_to_json
from fluent.migrate.helpers import LITERAL, EXTERNAL_ARGUMENT
from fluent.migrate.helpers import EXTERNAL_ARGUMENT
from fluent.migrate.transforms import evaluate, PLURALS, REPLACE_IN_TEXT


Expand Down Expand Up @@ -88,8 +88,7 @@ def setUp(self):
value=PLURALS(
self.strings,
'deleteAll',
EXTERNAL_ARGUMENT('num'),
LITERAL
EXTERNAL_ARGUMENT('num')
)
)

Expand Down
17 changes: 8 additions & 9 deletions tools/migrate/examples/about_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

import fluent.syntax.ast as FTL
from fluent.migrate import (
CONCAT, LITERAL, EXTERNAL_ARGUMENT, MESSAGE_REFERENCE, COPY,
REPLACE
CONCAT, EXTERNAL_ARGUMENT, MESSAGE_REFERENCE, COPY, REPLACE
)


Expand All @@ -21,12 +20,12 @@ def migrate(ctx):
'browser/chrome/browser/aboutDialog.dtd',
'update.failed.start'
),
LITERAL('<a>'),
FTL.TextElement('<a>'),
COPY(
'browser/chrome/browser/aboutDialog.dtd',
'update.failed.linkText'
),
LITERAL('</a>'),
FTL.TextElement('</a>'),
COPY(
'browser/chrome/browser/aboutDialog.dtd',
'update.failed.end'
Expand All @@ -40,7 +39,7 @@ def migrate(ctx):
'browser/chrome/browser/aboutDialog.dtd',
'channel.description.start'
),
EXTERNAL_ARGUMENT('channelname'),
FTL.Placeable(EXTERNAL_ARGUMENT('channelname')),
COPY(
'browser/chrome/browser/aboutDialog.dtd',
'channel.description.end'
Expand All @@ -59,7 +58,7 @@ def migrate(ctx):
)
}
),
LITERAL('<a>'),
FTL.TextElement('<a>'),
REPLACE(
'browser/chrome/browser/aboutDialog.dtd',
'community.mozillaLink',
Expand All @@ -69,17 +68,17 @@ def migrate(ctx):
)
}
),
LITERAL('</a>'),
FTL.TextElement('</a>'),
COPY(
'browser/chrome/browser/aboutDialog.dtd',
'community.middle2'
),
LITERAL('<a>'),
FTL.TextElement('<a>'),
COPY(
'browser/chrome/browser/aboutDialog.dtd',
'community.creditsLink'
),
LITERAL('</a>'),
FTL.TextElement('</a>'),
COPY(
'browser/chrome/browser/aboutDialog.dtd',
'community.end3'
Expand Down