Repository: shepherdwind/velocity.js (ts)

Issue:
#set 中通过动态的$key给 对象/数组 赋值失败
最近接手的项目中存在类似下面的二次整理数据的代码，在java端解析时可以正常赋值，但是在nodejs端就不行。请问有什么办法可以实现下面的需求，就是用动态的key或index给对象和数组赋值。谢谢:)


<h1>简单赋值</h1>
#set($o = {})

#set($key = "k")
#set($o[$key] = "c")
#set($o.f = "d")
<p>输出 {undefined=c, f=d}</p>

<h1>循环给对象赋值(key)</h1>
#set($obj = {})

#set($objlist = [
  {"k": "a"},
  {"k": "b"},
  {"k": "c"}
])
<p>初始值 obj = $!{obj}</p>

#foreach( $item in $!{objlist} )
  #set($obj[$item.k] = $item)
#end
<p>结果值 obj = $!{obj}</p>
<p>输出 {undefined={k=c}}，在java端解析返回的是包含 a,b,c 3个key的对象</p>
<h1>循环给数组赋值(index)</h1>
#set($ary = [])
<p>初始值 ary = $!{ary}</p>

#foreach( $item in $!{objlist} )
  #set($index = $velocityCount - 1)
  #set($obj[$index] = $item)
#end
<p>结果值 ary = $!{ary}</p>
<p>输出 []</p>


Pull request:
fix: fix error when set variable key
close #91

Patch:
diff --git a/src/compile/set.js b/src/compile/set.js
index 3f4def2..da96fdd 100644
--- a/src/compile/set.js
+++ b/src/compile/set.js
@@ -52,12 +52,19 @@ module.exports = function(Velocity, utils){
         context[ref.id] = baseRef;
         var len = ref.path ? ref.path.length: 0;
 
+        const self = this;
         //console.log(val);
         utils.some(ref.path, function(exp, i){
 
           var isEnd = len === i + 1;
           var key = exp.id;
-          if (exp.type === 'index')  key = key.value;
+          if (exp.type === 'index')  {
+            if (exp.id) {
+              key = self.getLiteral(exp.id);
+            } else {
+              key = key.value;
+            }
+          }
 
           if (isEnd) {
             return baseRef[key] = val;


Test patch:
diff --git a/tests/set.test.js b/tests/set.test.js
index fbb38d0..79d69f4 100644
--- a/tests/set.test.js
+++ b/tests/set.test.js
@@ -140,6 +140,27 @@ describe('Set && Expression', function() {
     assert.equal(true, getContext('#set($foo = $a or $b)', {a: 1, b: 0}).foo)
   })
 
+  it('var in key', function() {
+    var vm = '#set($o = {}) #set($key = "k") #set($o[$key] = "c") #set($o.f = "d") $o $o[$key]'
+    var ret = render(vm).replace(/\s+/g, '')
+    assert.equal('{k=c,f=d}c', ret)
+
+    var vm2 = `
+      #set($obj = {})
+      #set($objlist = [
+        {"k": "a"},
+        {"k": "b"},
+        {"k": "c"}
+      ])
+      #foreach( $item in $!{objlist} )
+        #set($obj[$item.k] = $item)
+      #end
+      $obj
+    `
+    var ret2 = render(vm2).replace(/\s+/g, '')
+    assert.equal('{a={k=a},b={k=b},c={k=c}}', ret2);
+  })
+
   it('#set context should be global, #25', function() {
     var vm = '#macro(local) #set($val =1) $val #end #local() $val'
     var ret = render(vm).replace(/\s+/g, '')