Просмотр исходного кода

Support indexing tuple and list variable values.

Fixes #87.
Andreas Stenius 11 лет назад
Родитель
Сommit
c2aaf7db51
4 измененных файлов с 29 добавлено и 9 удалено
  1. 7 2
      src/erlydtl_compiler.erl
  2. 1 0
      src/erlydtl_parser.yrl
  3. 14 6
      src/erlydtl_runtime.erl
  4. 7 1
      tests/src/erlydtl_unittests.erl

+ 7 - 2
src/erlydtl_compiler.erl

@@ -1211,17 +1211,22 @@ resolve_variable_ast(VarTuple, Context, TreeWalker, EmptyIfUndefined)
 resolve_variable_ast(VarTuple, Context, TreeWalker, FinderFunction) ->
     resolve_variable_ast1(VarTuple, Context, TreeWalker, FinderFunction).
 
-resolve_variable_ast1({attribute, {{identifier, {Row, Col}, AttrName}, Variable}}, Context, TreeWalker, FinderFunction) ->
+resolve_variable_ast1({attribute, {{AttrKind, {Row, Col}, Attr}, Variable}}, Context, TreeWalker, FinderFunction) ->
     {{VarAst, VarInfo}, TreeWalker1} = resolve_variable_ast(Variable, Context, TreeWalker, FinderFunction),
     FileNameAst = case Context#dtl_context.parse_trail of
                       [] -> erl_syntax:atom(undefined);
                       [H|_] -> erl_syntax:string(H)
                   end,
+    AttrAst = erl_syntax:abstract(
+                case AttrKind of
+                    number_literal -> erlang:list_to_integer(Attr);
+                    _ -> Attr
+                end),
     {Runtime, Finder} = FinderFunction,
     {{erl_syntax:application(
         erl_syntax:atom(Runtime),
         erl_syntax:atom(Finder),
-        [erl_syntax:atom(AttrName), VarAst, FileNameAst,
+        [AttrAst, VarAst, FileNameAst,
          erl_syntax:tuple([erl_syntax:integer(Row), erl_syntax:integer(Col)])
         ]),
       VarInfo},

+ 1 - 0
src/erlydtl_parser.yrl

@@ -250,6 +250,7 @@ Values -> Values Value : '$1' ++ ['$2'].
 
 Variable -> identifier : {variable, '$1'}.
 Variable -> Variable '.' identifier : {attribute, {'$3', '$1'}}.
+Variable -> Variable '.' Literal : {attribute, {'$3', '$1'}}.
 
 AutoEscapeBlock -> AutoEscapeBraced Elements EndAutoEscapeBraced : {autoescape, '$1', '$2'}.
 AutoEscapeBraced -> open_tag autoescape_keyword identifier close_tag : '$3'.

+ 14 - 6
src/erlydtl_runtime.erl

@@ -26,6 +26,10 @@ find_value(Key, L) when is_binary(Key), is_list(L) ->
         false           -> undefined;
         {Key, Value}    -> Value
     end;
+find_value(Key, L) when is_integer(Key), is_list(L) ->
+    if Key < length(L) -> lists:nth(Key, L);
+       true -> undefined
+    end;
 find_value(Key, {GBSize, GBData}) when is_integer(GBSize) ->
     case gb_trees:lookup(Key, {GBSize, GBData}) of
         {value, Val} ->
@@ -42,6 +46,10 @@ find_value(Key, Tuple) when is_tuple(Tuple) ->
                 _ ->
                     undefined
             end;
+        _ when is_integer(Key) ->
+            if Key < size(Tuple) -> element(Key, Tuple);
+               true -> undefined
+            end;
         Module ->
             case lists:member({Key, 1}, Module:module_info(exports)) of
                 true ->
@@ -59,6 +67,12 @@ find_value(Key, Tuple) when is_tuple(Tuple) ->
             end
     end.
 
+fetch_value(Key, Data, _FileName, _Pos) ->
+    case find_value(Key, Data) of
+        undefined -> [];
+        Val -> Val
+    end.
+
 find_deep_value([Key|Rest],Item) ->
     case find_value(Key,Item) of
         undefined -> undefined;
@@ -66,12 +80,6 @@ find_deep_value([Key|Rest],Item) ->
     end;
 find_deep_value([],Item) -> Item.
 
-fetch_value(Key, Data, _FileName, _Pos) ->
-    case find_value(Key, Data) of
-        undefined -> [];
-        Val -> Val
-    end.
-
 regroup(List, Attribute) ->
     regroup(List, Attribute, []).
 

+ 7 - 1
tests/src/erlydtl_unittests.erl

@@ -83,7 +83,13 @@ tests() ->
                     <<"{{ var1.some_var }}">>, [{var1, erlydtl_example_variable_storage:new("foo")}], <<"foo">>},
                    {"Nested attributes",
                     <<"{{ person.city.state.country }}">>, [{person, [{city, [{state, [{country, "Italy"}]}]}]}],
-                    <<"Italy">>}
+                    <<"Italy">>},
+                   {"Index list variable",
+                    <<"{{ var1.2 }}">>, [{var1, [a, b, c]}],
+                    <<"b">>},
+                   {"Index tuple variable",
+                    <<"{{ var1.2 }}">>, [{var1, {a, b, c}}],
+                    <<"b">>}
                   ]},
      {"now", [
               {"now functional",