Allow this references in literal statements

Fixes #967
This commit is contained in:
kpdecker
2015-04-14 01:12:39 -05:00
parent a7160a8d27
commit 54e743a09a
4 changed files with 33 additions and 11 deletions
+13 -2
View File
@@ -12,6 +12,14 @@ export function SourceLocation(source, locInfo) {
}; };
} }
export function id(token) {
if (/^\[.*\]$/.test(token)) {
return token.substr(1, token.length - 2);
} else {
return token;
}
}
export function stripFlags(open, close) { export function stripFlags(open, close) {
return { return {
open: open.charAt(2) === '~', open: open.charAt(2) === '~',
@@ -34,10 +42,13 @@ export function preparePath(data, parts, locInfo) {
depthString = ''; depthString = '';
for(var i=0,l=parts.length; i<l; i++) { for(var i=0,l=parts.length; i<l; i++) {
var part = parts[i].part; var part = parts[i].part,
// If we have [] syntax then we do not treat path references as operators,
// i.e. foo.[this] resolves to approximately context.foo['this']
isLiteral = parts[i].original !== part;
original += (parts[i].separator || '') + part; original += (parts[i].separator || '') + part;
if (part === '..' || part === '.' || part === 'this') { if (!isLiteral && (part === '..' || part === '.' || part === 'this')) {
if (dig.length > 0) { if (dig.length > 0) {
throw new Exception('Invalid path: ' + original, {loc: locInfo}); throw new Exception('Invalid path: ' + original, {loc: locInfo});
} else if (part === '..') { } else if (part === '..') {
+15 -4
View File
@@ -227,10 +227,12 @@ describe("basic context", function() {
}); });
it("this keyword nested inside path", function() { it("this keyword nested inside path", function() {
var string = "{{#hellos}}{{text/this/foo}}{{/hellos}}";
shouldThrow(function() { shouldThrow(function() {
CompilerContext.compile(string); CompilerContext.compile('{{#hellos}}{{text/this/foo}}{{/hellos}}');
}, Error); }, Error, 'Invalid path: text/this - 1:13');
shouldCompileTo('{{[this]}}', {'this': 'bar'}, 'bar');
shouldCompileTo('{{text/[this]}}', {text: {'this': 'bar'}}, 'bar');
}); });
it("this keyword in helpers", function() { it("this keyword in helpers", function() {
@@ -251,7 +253,16 @@ describe("basic context", function() {
var string = "{{#hellos}}{{foo text/this/foo}}{{/hellos}}"; var string = "{{#hellos}}{{foo text/this/foo}}{{/hellos}}";
shouldThrow(function() { shouldThrow(function() {
CompilerContext.compile(string); CompilerContext.compile(string);
}, Error); }, Error, 'Invalid path: text/this - 1:17');
shouldCompileTo(
'{{foo [this]}}',
{foo: function(value) { return value; }, 'this': 'bar'},
'bar');
shouldCompileTo(
'{{foo text/[this]}}',
{foo: function(value) { return value; }, text: {'this': 'bar'}},
'bar');
}); });
it('pass string literals', function() { it('pass string literals', function() {
+1 -1
View File
@@ -110,7 +110,7 @@ ID [^\s!"#%-,\.\/;->@\[-\^`\{-~]+/{LOOKAHEAD}
<mu>{ID} return 'ID'; <mu>{ID} return 'ID';
<mu>'['[^\]]*']' yytext = strip(1,2); return 'ID'; <mu>'['[^\]]*']' return 'ID';
<mu>. return 'INVALID'; <mu>. return 'INVALID';
<INITIAL,mu><<EOF>> return 'EOF'; <INITIAL,mu><<EOF>> return 'EOF';
+4 -4
View File
@@ -94,11 +94,11 @@ hash
; ;
hashSegment hashSegment
: ID EQUALS param -> new yy.HashPair($1, $3, yy.locInfo(@$)) : ID EQUALS param -> new yy.HashPair(yy.id($1), $3, yy.locInfo(@$))
; ;
blockParams blockParams
: OPEN_BLOCK_PARAMS ID+ CLOSE_BLOCK_PARAMS -> $2 : OPEN_BLOCK_PARAMS ID+ CLOSE_BLOCK_PARAMS -> yy.id($2)
; ;
helperName helperName
@@ -125,6 +125,6 @@ path
; ;
pathSegments pathSegments
: pathSegments SEP ID { $1.push({part: $3, separator: $2}); $$ = $1; } : pathSegments SEP ID { $1.push({part: yy.id($3), original: $3, separator: $2}); $$ = $1; }
| ID -> [{part: $1}] | ID -> [{part: yy.id($1), original: $1}]
; ;