Roberto Saccon 17 лет назад
Родитель
Сommit
7bad48f6a3
2 измененных файлов с 93 добавлено и 75 удалено
  1. 48 42
      src/erlydtl/erlydtl_base.erl
  2. 45 33
      src/erlydtl/erlydtl_server.erl

+ 48 - 42
src/erlydtl/erlydtl_base.erl

@@ -38,7 +38,6 @@
     args = [], 
     args = [], 
     doc_root = [], 
     doc_root = [], 
     ext = [], 
     ext = [], 
-    ns = [],
     var = [], 
     var = [], 
     props = []}).
     props = []}).
 	
 	
@@ -46,8 +45,7 @@
 -export([parse/1, 
 -export([parse/1, 
     build_tree/3, 
     build_tree/3, 
     build_tree/4, 
     build_tree/4, 
-    build_tree/5, 
-    parse_transform/6, 
+    build_tree/5,  
     parse_transform/3, 
     parse_transform/3, 
     parse_transform/2, 
     parse_transform/2, 
     parse_transform/1, 
     parse_transform/1, 
@@ -59,7 +57,7 @@ build_tree(H, T, Ext) ->
     build_tree2(H, T, #dtl{ext = Ext}).
     build_tree2(H, T, #dtl{ext = Ext}).
     
     
 build_tree(H, T, DocRoot, Ext) ->
 build_tree(H, T, DocRoot, Ext) ->
-    build_tree2(H, T, #dtl{doc_root = DocRot, ext = Ext}).
+    build_tree2(H, T, #dtl{doc_root = DocRoot, ext = Ext}).
     
     
 build_tree(H, T, Args, Ext, Var) ->
 build_tree(H, T, Args, Ext, Var) ->
     build_tree2(H, T, #dtl{args = Args, ext = Ext, var = Var}).
     build_tree2(H, T, #dtl{args = Args, ext = Ext, var = Var}).
@@ -95,7 +93,7 @@ parse_transform({block, _, Name, [nil, Block]}, #dtl{buffer = Buffer} = Dtl) ->
 		false -> 
 		false -> 
             parse_transform(Block, Dtl);
             parse_transform(Block, Dtl);
 		{value, {_, _, _, [H | T]}} -> 
 		{value, {_, _, _, [H | T]}} -> 
-		    {_, Buffer1, Args1, Props1} = build_tree(H, T, Dtl),
+		    {_, Buffer1, Args1, Props1} = build_tree2(H, T, Dtl),
             parse_transform(lists:reverse(Buffer1), Dtl#dtl{args = Args1, props = Props1})
             parse_transform(lists:reverse(Buffer1), Dtl#dtl{args = Args1, props = Props1})
  	end;
  	end;
 parse_transform(Other, #dtl{args = Args}) ->    
 parse_transform(Other, #dtl{args = Args}) ->    
@@ -110,7 +108,7 @@ parse_transform(Other, _) ->
 
 
 parse_transform({block, _Line , _Name, [nil, T]}) ->
 parse_transform({block, _Line , _Name, [nil, T]}) ->
 	parse_transform(T); 
 	parse_transform(T); 
-parse_transform({var, L, Val}) ->
+parse_transform({var, _Line, Val}) ->
     io:format("TRACE ~p:~p var_parse_transform: ~p~n",[?MODULE, ?LINE, Val]),    
     io:format("TRACE ~p:~p var_parse_transform: ~p~n",[?MODULE, ?LINE, Val]),    
     erl_syntax:variable(Val);
     erl_syntax:variable(Val);
 parse_transform(Other) -> 
 parse_transform(Other) -> 
@@ -138,13 +136,13 @@ new_var(List, Acc) ->
 %%====================================================================
 %%====================================================================
 %% Internal functions
 %% Internal functions
 %%====================================================================
 %%====================================================================
-build_tree(nil, [{extends, Line, Name}], #dtl{buffer = Buffer, doc_root = DocRoot, ext = Ext} = Dtl) ->
-    case parse(filename:join([RelDir, Name])) of
+build_tree2(nil, [{extends, Line, Name}], #dtl{doc_root = DocRoot, ext = Ext} = Dtl) ->
+    case parse(filename:join([DocRoot, Name])) of
         {ok, ParentAst} ->
         {ok, ParentAst} ->
 		    [H|T] = ParentAst,
 		    [H|T] = ParentAst,
 			{_, Buffer1, Args1, _} = build_tree(H, T, DocRoot, Ext),			 
 			{_, Buffer1, Args1, _} = build_tree(H, T, DocRoot, Ext),			 
 			{Buffer2, Args3} = lists:foldl(fun(X, {AccBuffer, AccArgs}) ->  
 			{Buffer2, Args3} = lists:foldl(fun(X, {AccBuffer, AccArgs}) ->  
-                    {Buffer3, Args4} = parse_transform(X, Dtl#dtl{args = AccArgs, ns = [], var = []}),           
+                    {Buffer3, Args4} = parse_transform(X, Dtl#dtl{args = AccArgs, var = []}),           
                     {[Buffer3 | AccBuffer], Args4}
                     {[Buffer3 | AccBuffer], Args4}
                 end, 
                 end, 
                 {[], Args1}, 
                 {[], Args1}, 
@@ -154,25 +152,29 @@ build_tree(nil, [{extends, Line, Name}], #dtl{buffer = Buffer, doc_root = DocRoo
 		     {error, {extends, Line, "file not found"}}		
 		     {error, {extends, Line, "file not found"}}		
     end;
     end;
     
     
-build_tree(nil, [{var, Line, Var}], #dtl{buffer = Buffer, args = Args, props = Props}) ->      
-    {regular, [erl_syntax:variable(Var) | Buffer], Args, Prop};
+build_tree2(nil, [{var, _, Var}], #dtl{buffer = Buffer, args = Args, var = Var, props = Props}) ->      
+    {regular, [erl_syntax:variable(Var) | Buffer], Args, Props};
 
 
-build_tree(nil, [{var, Line, Ns, Var}], #dtl{buffer = Buffer, args = Args, var = Ns, props = Props}) ->     
+build_tree2(nil, [{var, _, Ns, Var}], #dtl{buffer = Buffer, args = Args, var = Ns, props = Props}) ->     
     Var1 = lists:concat([Ns, ".", Var]),
     Var1 = lists:concat([Ns, ".", Var]),
     Props1 = [list_to_atom(Var1) | Props],
     Props1 = [list_to_atom(Var1) | Props],
     {regular, [erl_syntax:variable(Var1) | Buffer], Args, Props1};
     {regular, [erl_syntax:variable(Var1) | Buffer], Args, Props1};
  
  
-build_tree(nil, [{var, _, Var}], #dtl{buffer = Buffer, args = Args, props = Props}) ->       	
+build_tree2(nil, [{var, _, Var}], #dtl{buffer = Buffer, args = Args, props = Props}) ->       	
     case lists:member(Var, Args) of
     case lists:member(Var, Args) of
         true ->
         true ->
-            {regular, [erl_syntax:variable(Var) | Buffer], Args, Rec};
+            {regular, [erl_syntax:variable(Var) | Buffer], Args, Props};
         _ ->
         _ ->
-            {regular, [erl_syntax:variable(Var) | Buffer], [Var | Args], Rec} 
+            {regular, [erl_syntax:variable(Var) | Buffer], [Var | Args], Props} 
     end;    
     end;    
  
  
-build_tree(nil, [{tag, _, TagName, TagArgs}], #dtl{buffer = Buffer, args = Args, ext = Ext, props = Props}) ->
-    Buffer1 = handle_tag(TagName, TagArgs, Buffer, default, Ext),    
-    {regular, lists:flatten([Buffer1, Buffer]), Args, Props};
+build_tree2(nil, [{tag, Line, TagName, TagArgs}], #dtl{buffer = Buffer, args = Args, ext = Ext, props = Props}) ->
+    case handle_tag(TagName, Line, TagArgs, Buffer, default, Ext) of
+        {ok, Buffer1} ->
+            {regular, lists:flatten([Buffer1, Buffer]), Args, Props};
+        Err ->
+            Err
+    end;
     
     
 build_tree2(nil, [{for, _, It, Var, [HFor | TFor]}], #dtl{buffer = Buffer, props = Props} = Dtl) ->
 build_tree2(nil, [{for, _, It, Var, [HFor | TFor]}], #dtl{buffer = Buffer, props = Props} = Dtl) ->
     {Buffer1, Args1} = handle_for(It, Var, HFor, TFor, Dtl), 
     {Buffer1, Args1} = handle_for(It, Var, HFor, TFor, Dtl), 
@@ -181,21 +183,21 @@ build_tree2(nil, [{for, _, It, Var, [HFor | TFor]}], #dtl{buffer = Buffer, props
 build_tree2(nil, [Token], #dtl{buffer = Buffer, args = Args, props = Props}) ->
 build_tree2(nil, [Token], #dtl{buffer = Buffer, args = Args, props = Props}) ->
     io:format("TRACE ~p:~p other1-Token: ~p~n",[?MODULE, ?LINE, Token]),
     io:format("TRACE ~p:~p other1-Token: ~p~n",[?MODULE, ?LINE, Token]),
     {regular, [Token | Buffer], Args, Props}; 
     {regular, [Token | Buffer], Args, Props}; 
-
-build_tree2([H | T], [{var, _, Var}], #dtl{buffer = Buffer} = Dtl) ->
-    build_tree2(H, T, Dtl#dtl{buffer = [erl_syntax:variable(Var) | Buffer]);
+  
+build_tree2([H | T], [{var, _, Var}], #dtl{buffer = Buffer, var = Var} = Dtl) ->
+    build_tree2(H, T, Dtl#dtl{buffer = [erl_syntax:variable(Var) | Buffer]});
  
  
-build_tree2([H | T], [{var, _, Ns, Var}], #dtl{buffer = Buffer, ns = Ns, props = Props} = Dtl) ->
+build_tree2([H | T], [{var, _, Ns, Var}], #dtl{buffer = Buffer, var = Ns, props = Props} = Dtl) ->
     Var1 = lists:concat([Ns, ".", Var]),
     Var1 = lists:concat([Ns, ".", Var]),
     Dtl1 = Dtl#dtl{
     Dtl1 = Dtl#dtl{
         buffer = [erl_syntax:variable(Var1) | Buffer], 
         buffer = [erl_syntax:variable(Var1) | Buffer], 
         props = [list_to_atom(Var1) | Props]},
         props = [list_to_atom(Var1) | Props]},
-    build_tree2(H, T, Dtl);
+    build_tree2(H, T, Dtl1);
   
   
 build_tree2([H | T], [{var, _, Var}], #dtl{buffer = Buffer, args = Args} = Dtl) ->           		
 build_tree2([H | T], [{var, _, Var}], #dtl{buffer = Buffer, args = Args} = Dtl) ->           		
     Dtl1 = case lists:member(Var, Args) of
     Dtl1 = case lists:member(Var, Args) of
         true ->
         true ->
-            Dtl#dtl{buffer = [erl_syntax:variable(Var) | Buffer];
+            Dtl#dtl{buffer = [erl_syntax:variable(Var) | Buffer]};
         _ ->
         _ ->
             Dtl#dtl{
             Dtl#dtl{
                 buffer = [erl_syntax:variable(Var) | Buffer],
                 buffer = [erl_syntax:variable(Var) | Buffer],
@@ -203,11 +205,15 @@ build_tree2([H | T], [{var, _, Var}], #dtl{buffer = Buffer, args = Args} = Dtl)
     end,
     end,
     build_tree2(H, T, Dtl1);
     build_tree2(H, T, Dtl1);
     
     
-build_tree2([H | T], [{tag, _Line, TagName, TagArgs}], #dtl{buffer = Buffer, ext = Ext} = Dtl) ->	
-    Buffer2 = handle_tag(TagName, TagArgs, Buffer, default, Ext),
-    build_tree2(H, T, Dtl#dtl{buffer = Buffer2});
+build_tree2([H | T], [{tag, Line, TagName, TagArgs}], #dtl{buffer = Buffer, ext = Ext} = Dtl) ->	
+    case handle_tag(TagName, Line, TagArgs, Buffer, default, Ext) of
+        {ok, Buffer1} ->
+            build_tree2(H, T, Dtl#dtl{buffer = Buffer1});
+        Err ->
+            Err
+    end;
  
  
-build_tree2([H | T], [{for, _, It, Var, [HFor | TFor]}], Dtl) ->
+build_tree2([H | T], [{for, _, It, Var, [HFor | TFor]}], #dtl{buffer = Buffer} = Dtl) ->
     {Buffer1, Args1} = handle_for(It, Var, HFor, TFor, Dtl),
     {Buffer1, Args1} = handle_for(It, Var, HFor, TFor, Dtl),
     build_tree2(H, T, Dtl#dtl{buffer = lists:flatten([Buffer1, Buffer]), args = Args1});
     build_tree2(H, T, Dtl#dtl{buffer = lists:flatten([Buffer1, Buffer]), args = Args1});
         	
         	
@@ -216,14 +222,8 @@ build_tree2([H | T], [Token], #dtl{buffer = Buffer} = Dtl) ->
     build_tree2(H, T, Dtl#dtl{buffer = [Token | Buffer]}).
     build_tree2(H, T, Dtl#dtl{buffer = [Token | Buffer]}).
     
     
 
 
-handle_for(It, Var, HFor, TFor, #dtl{buffer = Buffer, args = Args, ext = Ext, props = Props}) ->
-    {_, List1, Args1, Props1} = build_tree(HFor, TFor, Args, Ext, It),  
-    Args2 = case lists:member(Var, Args1) of
-        true ->
-            Args1;
-        _ ->
-            [Var | Args1]
-	end,  
+handle_for(It, Var, HFor, TFor, #dtl{args = Args, ext = Ext}) ->
+    {_, List1, Args1, Props1} = build_tree(HFor, TFor, Args, Ext, It),    
 	ItAST = erl_syntax:variable(It),
 	ItAST = erl_syntax:variable(It),
     Buffer1 = case Props1 of
     Buffer1 = case Props1 of
         [] ->
         [] ->
@@ -244,21 +244,27 @@ handle_for(It, Var, HFor, TFor, #dtl{buffer = Buffer, args = Args, ext = Ext, pr
                 erl_syntax:atom(map),
                 erl_syntax:atom(map),
                 [erl_syntax:fun_expr([FunClauseAST]), erl_syntax:variable(Var)])
                 [erl_syntax:fun_expr([FunClauseAST]), erl_syntax:variable(Var)])
     end,   
     end,   
-    {Buffer1, Args1}.
+    case lists:member(Var, Args1) of
+        true ->
+            {Buffer1, Args1};
+        _ ->
+            {Buffer1, [Var | Args1]}
+	end.
     
     
            	        	
            	        	
-handle_tag(TagName, TagArgs, Acc0, default, Ext) ->
+handle_tag(TagName, Line, TagArgs, Acc0, default, Ext) ->
     case parse(filename:join([erlydtl_deps:get_base_dir(), "priv", "tags", atom_to_list(TagName) ++ Ext])) of
     case parse(filename:join([erlydtl_deps:get_base_dir(), "priv", "tags", atom_to_list(TagName) ++ Ext])) of
         {ok, ParentAst} ->
         {ok, ParentAst} ->
 		    [H|T]=ParentAst,
 		    [H|T]=ParentAst,
 			{_, List, _, _} = build_tree(H, T, Ext),
 			{_, List, _, _} = build_tree(H, T, Ext),
-			lists:foldl(fun(X, Acc) -> 
+			List = lists:foldl(fun(X, Acc) -> 
 			        [parse_transform(X, TagArgs) | Acc]			        
 			        [parse_transform(X, TagArgs) | Acc]			        
 			    end, 
 			    end, 
 			    Acc0,
 			    Acc0,
-			    lists:reverse(List));
-		{error, Msg} ->
-    	    Acc0
+			    lists:reverse(List)),
+			{ok, List};
+		_ ->
+    	    {error, {TagName, Line, "loading tag source template failed"}}
     end.
     end.
   
   
     
     

+ 45 - 33
src/erlydtl/erlydtl_server.erl

@@ -115,12 +115,10 @@ init([]) ->
 handle_call({compile, File, ModuleName, DocRoot, FunctionName}, _From, State) ->
 handle_call({compile, File, ModuleName, DocRoot, FunctionName}, _From, State) ->
     Reply = case erlydtl_base:parse(File) of
     Reply = case erlydtl_base:parse(File) of
         {ok, Ast} ->
         {ok, Ast} ->
-		    RelDir = erlydtl_base:rel_dir(filename:dirname(File), DocRoot),
+		    RelDocRoot = erlydtl_base:rel_dir(filename:dirname(File), DocRoot),
 		    Ext = filename:extension(File),
 		    Ext = filename:extension(File),
-            compile(Ast, ModuleName, FunctionName, RelDir, Ext);
-        {error, Msg} = Err ->
-            io:format("TRACE ~p:~p ~p~n",[?MODULE, ?LINE, File ++ " Parser failure:"]),
-            io:format("TRACE ~p:~p ~p~n",[?MODULE, ?LINE, Msg]),
+            compile(Ast, ModuleName, FunctionName, RelDocRoot, Ext);
+       Err ->
             Err
             Err
     end,
     end,
     {reply, Reply, State};
     {reply, Reply, State};
@@ -173,39 +171,53 @@ code_change(_OldVsn, State, _Extra) ->
 %% Internal functions
 %% Internal functions
 %%====================================================================
 %%====================================================================
 compile([H | T], ModuleName, FunctionName, DocRoot, Ext) ->
 compile([H | T], ModuleName, FunctionName, DocRoot, Ext) ->
-    {List, Args} = case erlydtl_base:build_tree(H, T, DocRoot, Ext) of
-        {regular, List0, Args0, _} ->
-            {[erlydtl_scanner:parse_transform(X) ||  X <- List0], Args0};
-        {inherited, List0, Arg0, _} ->
-            {List0, Arg0};
+    case erlydtl_base:build_tree(H, T, DocRoot, Ext) of
+        {regular, Out, Args, _} ->
+            Out1 = [erlydtl_scanner:parse_transform(X) ||  X <- Out],
+            create_module(Out1, Args, ModuleName, FunctionName);
+        {inherited, Out, Args, _} ->
+            create_module(Out, Args, ModuleName, FunctionName);
         {error, Reason} ->
         {error, Reason} ->
-            todo
-    end,   
-    {Args1, BodyAST} = case Args of 
+            % check whether Reason contains Linenumber
+            {error, Reason}
+    end.   
+    
+
+create_module(List, Args, ModuleName, FunctionName) ->
+    {BodyAST, Args1} = case Args of 
         []  ->
         []  ->
-            {[], [erl_syntax:list(List)]};
+            {[erl_syntax:list(List)], []};
         _ ->
         _ ->
-         Var = erl_syntax:variable(erlydtl_base:new_var(Args, 0)),
-         BodyAST0 = lists:foldl(fun(X, Acc) -> 
-                 X2 = list_to_atom(tl(atom_to_list(X))),
-                 A = erl_syntax:variable(X),
-                 B = erl_syntax:application(erl_syntax:atom(proplists), 
-                     erl_syntax:atom(get_value), [erl_syntax:atom(X2), Var]),
-                 [erl_syntax:match_expr(A, B) | Acc]
-             end,
-             [erl_syntax:list(List)],
-             Args),
-         {[Var], BodyAST0}
- end,
- ClauseAST = erl_syntax:clause(Args1, none, BodyAST),
- FuncAST = erl_syntax:function(erl_syntax:atom(FunctionName), [ClauseAST]),
- [ModAST, CmpAST] = [erl_syntax:attribute(erl_syntax:atom(X), [erl_syntax:atom(Y)]) ||
-     {X, Y} <- [{"module", ModuleName}, {"compile", "export_all"}]],
+            Var = erl_syntax:variable(erlydtl_base:new_var(Args, 0)),
+            BodyAST0 = lists:foldl(fun(X, Acc) -> 
+                    X2 = list_to_atom(tl(atom_to_list(X))),
+                    A = erl_syntax:variable(X),
+                    B = erl_syntax:application(erl_syntax:atom(proplists), 
+                        erl_syntax:atom(get_value), [erl_syntax:atom(X2), Var]),
+                    [erl_syntax:match_expr(A, B) | Acc]
+                end,
+                [erl_syntax:list(List)],
+                Args),
+            {BodyAST0, [Var]}
+    end,
+    ClauseAST = erl_syntax:clause(Args1, none, BodyAST),
+    FuncAST = erl_syntax:function(erl_syntax:atom(FunctionName), [ClauseAST]),
+    [ModAST, CmpAST] = [erl_syntax:attribute(erl_syntax:atom(X), [erl_syntax:atom(Y)]) ||
+        {X, Y} <- [{"module", ModuleName}, {"compile", "export_all"}]],
     Forms = [erl_syntax:revert(X) || X <- [ModAST, CmpAST, FuncAST]],
     Forms = [erl_syntax:revert(X) || X <- [ModAST, CmpAST, FuncAST]],
     case compile:forms(Forms) of
     case compile:forms(Forms) of
         {ok, Module, Bin} ->
         {ok, Module, Bin} ->
-            erlydtl_tools:write_beam(Module, Bin, "ebin"),
-            erlydtl_tools:reload(Module, Bin);
+            case erlydtl:write_beam(Module, Bin, "ebin") of
+                ok ->
+                    case erlydtl:reload(Module, Bin) of
+                        ok ->
+                            ok;
+                        _ ->
+                            {error, "code reload failed"}
+                    end;
+                _ ->
+                    {error, "beam generation failed"}
+            end;
         _ ->
         _ ->
             {error, "compilation failed"}
             {error, "compilation failed"}
     end.    
     end.    
@@ -214,7 +226,7 @@ compile([H | T], ModuleName, FunctionName, DocRoot, Ext) ->
      
      
      
      
      
      
-     
+    
      
      
  
  
 %% build_tree(nil, [{extends, _Line, Name}], Out, Args, RelDir, Ext, _, _) -> 
 %% build_tree(nil, [{extends, _Line, Name}], Out, Args, RelDir, Ext, _, _) ->