Browse Source

Merge pull request #44 from saleyn/erlydtl_compiler

Erlydtl compiler
Evan Miller 12 years ago
parent
commit
2ef2f7d3b4
2 changed files with 40 additions and 15 deletions
  1. 1 0
      README.markdown
  2. 39 15
      src/erlydtl_compiler.erl

+ 1 - 0
README.markdown

@@ -102,6 +102,7 @@ Defaults to [].
 * `binary_strings` - Whether to compile strings as binary terms (rather than
 lists). Defaults to `true`.
 
+* `verbose` - Enable verbose printing of compilation results.
 
 Helper compilation
 ------------------

+ 39 - 15
src/erlydtl_compiler.erl

@@ -86,7 +86,7 @@ compile(Binary, Module, Options) when is_binary(Binary) ->
         {ok, DjangoParseTree} ->
             case compile_to_binary(File, DjangoParseTree, 
                     init_dtl_context(File, Module, Options), CheckSum) of
-                {ok, Module1, _} ->
+                {ok, Module1, _, _} ->
                     {ok, Module1};
                 Err ->
                     Err
@@ -102,8 +102,8 @@ compile(File, Module, Options) ->
             ok;
         {ok, DjangoParseTree, CheckSum} ->
             case compile_to_binary(File, DjangoParseTree, Context, CheckSum) of
-                {ok, Module1, Bin} ->
-                    write_binary(Module1, Bin, Options);
+                {ok, Module1, Bin, Warnings} ->
+                    write_binary(Module1, Bin, Options, Warnings);
                 Err ->
                     Err
             end;
@@ -143,8 +143,8 @@ compile_dir(Dir, Module, Options) ->
     case ParserErrors of
         [] ->
             case compile_multiple_to_binary(Dir, ParserResults, Context) of
-                {ok, Module1, Bin} ->
-                    write_binary(Module1, Bin, Options);
+                {ok, Module1, Bin, Warnings} ->
+                    write_binary(Module1, Bin, Options, Warnings);
                 Err ->
                     Err
             end;
@@ -156,17 +156,31 @@ compile_dir(Dir, Module, Options) ->
 %% Internal functions
 %%====================================================================
 
-write_binary(Module1, Bin, Options) ->
+write_binary(Module1, Bin, Options, Warnings) ->
+    Verbose = proplists:get_value(verbose, Options, false),
     case proplists:get_value(out_dir, Options) of
         undefined ->
+            Verbose =:= true andalso
+                io:format("Template module: ~w not saved (no out_dir option)\n", [Module1]),
             ok;
         OutDir ->
             BeamFile = filename:join([OutDir, atom_to_list(Module1) ++ ".beam"]),
+
+            Verbose =:= true andalso
+                io:format("Template module: ~w -> ~s~s\n",
+                    [Module1, BeamFile,
+                        case Warnings of
+                        [] -> "";
+                        _  -> io_lib:format("\n  Warnings: ~p", [Warnings])
+                        end]),
+
             case file:write_file(BeamFile, Bin) of
                 ok ->
                     ok;
                 {error, Reason} ->
-                    {error, lists:concat(["beam generation failed (", Reason, "): ", BeamFile])}
+                    {error, lists:flatten(
+                        io_lib:format("Beam generation of '~s' failed: ~p",
+                            [BeamFile, file:format_error(Reason)]))}
             end
     end.
 
@@ -205,17 +219,22 @@ compile_to_binary(File, DjangoParseTree, Context, CheckSum) ->
 compile_forms_and_reload(File, Forms, CompilerOptions) ->
     case compile:forms(Forms, CompilerOptions) of
         {ok, Module1, Bin} -> 
-            code:purge(Module1),
-            case code:load_binary(Module1, atom_to_list(Module1) ++ ".erl", Bin) of
-                {module, _} -> {ok, Module1, Bin};
-                _ -> {error, lists:concat(["code reload failed: ", Module1])}
-            end;
+            load_code(Module1, Bin, []);
+        {ok, Module1, Bin, Warnings} ->
+            load_code(Module1, Bin, Warnings);
         error ->
             {error, lists:concat(["compilation failed: ", File])};
         OtherError ->
             OtherError
     end.
                 
+load_code(Module, Bin, Warnings) ->
+    code:purge(Module),
+    case code:load_binary(Module, atom_to_list(Module) ++ ".erl", Bin) of
+        {module, _} -> {ok, Module, Bin, Warnings};
+        _ -> {error, lists:concat(["code reload failed: ", Module])}
+    end.
+
 init_dtl_context(File, Module, Options) when is_list(Module) ->
     init_dtl_context(File, list_to_atom(Module), Options);
 init_dtl_context(File, Module, Options) ->
@@ -1218,17 +1237,22 @@ full_path(File, DocRoot) ->
 %% Custom tags
 %%-------------------------------------------------------------------
 
+key_to_string(Key) when is_atom(Key) ->
+    erl_syntax:string(atom_to_list(Key));
+key_to_string(Key) when is_list(Key) ->
+    erl_syntax:string(Key).
+
 tag_ast(Name, Args, Context, TreeWalker) ->
     {InterpretedArgs, AstInfo} = lists:mapfoldl(fun
             ({{identifier, _, Key}, {string_literal, _, Value}}, AstInfoAcc) ->
                 {{StringAst, StringAstInfo}, _} = string_ast(unescape_string_literal(Value), Context, TreeWalker),
-                {erl_syntax:tuple([erl_syntax:string(Key), StringAst]), merge_info(StringAstInfo, AstInfoAcc)};
+                {erl_syntax:tuple([key_to_string(Key), StringAst]), merge_info(StringAstInfo, AstInfoAcc)};
             ({{identifier, _, Key}, {trans, StringLiteral}}, AstInfoAcc) ->
                 {{TransAst, TransAstInfo}, _} = translated_ast(StringLiteral, Context, TreeWalker),
-                {erl_syntax:tuple([erl_syntax:string(Key), TransAst]), merge_info(TransAstInfo, AstInfoAcc)};
+                {erl_syntax:tuple([key_to_string(Key), TransAst]), merge_info(TransAstInfo, AstInfoAcc)};
             ({{identifier, _, Key}, Value}, AstInfoAcc) ->
                 {AST, VarName} = resolve_variable_ast(Value, Context),
-                {erl_syntax:tuple([erl_syntax:string(Key), format(AST,Context, TreeWalker)]), merge_info(#ast_info{var_names=[VarName]}, AstInfoAcc)}
+                {erl_syntax:tuple([key_to_string(Key), format(AST,Context, TreeWalker)]), merge_info(#ast_info{var_names=[VarName]}, AstInfoAcc)}
         end, #ast_info{}, Args),
 
     {RenderAst, RenderInfo} = custom_tags_modules_ast(Name, InterpretedArgs, Context),