Closed
Bug 883664
Opened 13 years ago
Closed 13 years ago
Unify how compiler reacts to missing members of strings, hashes, globals and variables
Categories
(L20n :: JS Library, defect, P1)
Tracking
(Not tracked)
RESOLVED
FIXED
1.0
People
(Reporter: stas, Assigned: stas)
References
Details
Let's look at some code samples and the current compiler's behavior:
A.
<foo['a', 'b'] "Foo">
<bar['a', 'b'] {
*one: "One",
two: "Two"
}>
Output:
foo Foo
bar One
In foo, the compiler doesn't even look at 'a' or 'b' in the index, because the value is a string.
In bar, the compiler doesn't look at 'b', because the hash is only one-level-deep.
B.
<string1 "{{ foo.x }}">
<string2 "{{ foo.x.y }}">
<string3 "{{ foo.x.y.z }}">
Output:
string1 Foo
string2 {{ foo.x.y }} (ValueError in string2: y is not defined in the context data)
string3 {{ foo.x.y.z }} (ValueError in string3: y is not defined in the context data)
foo.x in string1 behaves a bit like an index in that it tries to get the 'x' member, fails, and returns the value Foo. But foo.x.y and foo.x.y.z are inconsistent with the index behavior and throw.
C.
<hash1 "{{ bar.one.x }}">
hash1 One
bar.one is a string, so bar.one.x works the same as foo.x above: it falls back on the value of bar.one (One)
<hash2 "{{ bar.one.x.y }}">
hash2 {{ bar.one.x.y }} (ValueError in hash2: y is not defined in the context data)
Same as foo.x.y
<hash3 "{{ bar.x }}">
hash3 One
This one is interesting. x is not found in bar's keys, so the default key is used: one. So bar.x is the same as bar.one, i.e. One.
<hash4 "{{ bar.x.y }}">
hash4 One
As seen above, bar.x is the same as bar.one, and is a string. Thus, bar.x.y works the same way as foo.x: <string>.<missing property> and it falls back on the value of the string.
<hash5 "{{ bar.x.y.z }}">
hash5 {{ bar.x.y.z }} (ValueError in hash5: z is not defined in the context data)
Only now does the compiler fail, similar to foo.x.y.
* * *
1. Should indexes be treated the same as property expressions?
I think it's OK for them to not behave the same way. Indexes are declarative, while property expressions are imperative. We don't even have to look at the index to return the value.
2. Should string.property fall back gracefully on the value of the string, or fail?
I'd like to suggest a change in that the compiler should fail in these scenarios.
<string1 "{{ foo.x }}">
<string2 "{{ foo.x.y }}">
<string3 "{{ foo.x.y.z }}">
string{1,2,3} should all fail with "x is not defined".
The same should happen for globals and variables if the requested property is not found.
<global "{{ @foo.x }}">
should fail with "x is not defined" if @foo is a string or an object without a member called x.
<variable "{{ $foo.x }}">
should fail with "x is not defined" if $foo is a string or an object without a member called x.
Updated•13 years ago
|
Assignee: nobody → stas
Priority: -- → P1
QA Contact: gandalf
Updated•13 years ago
|
Target Milestone: --- → 1.0
Comment 1•13 years ago
|
||
That sounds good
| Assignee | ||
Comment 2•13 years ago
|
||
Landed in https://github.com/l20n/l20n.js/commit/4df76aab0c49fe09eead9d54b77b94e36dd1f218
There are many changes in the patch, mostly tests and some clean-up regarding Runtime errors in compiler.js. The beef of the fix is in PropertyExpression:
https://github.com/l20n/l20n.js/commit/4df76aab0c49fe09eead9d54b77b94e36dd1f218#L0R822
The patch adds 72 tests (8 of which pending bug 816887 and bug 884734)
-
I think this fix will also greatly help with bug 815962. I tried to make sure I'm careful with built-in properties like 'length' on a string (which is an own property).
Status: NEW → RESOLVED
Closed: 13 years ago
Resolution: --- → FIXED
You need to log in
before you can comment on or make changes to this bug.
Description
•