Skip to content

Commit 80537f6

Browse files
committed
compiler: Add doctests to compile
1 parent 862cbc0 commit 80537f6

2 files changed

Lines changed: 83 additions & 16 deletions

File tree

lib/compiler/src/compile.erl

Lines changed: 70 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -980,23 +980,76 @@ file(File, Opts) when is_list(Opts) ->
980980
file(File, Opt) ->
981981
file(File, [Opt|?DEFAULT_OPTIONS]).
982982

983-
-doc """
984-
Is the same as
985-
[`forms(Forms, [verbose,report_errors,report_warnings])`](`forms/2`).
986-
""".
983+
-doc #{ equiv => forms(Forms, ?DEFAULT_OPTIONS) }.
987984
-spec forms(forms()) -> CompRet :: comp_ret().
988985

989986
forms(Forms) -> forms(Forms, ?DEFAULT_OPTIONS).
990987

991-
-doc """
988+
-doc """"
992989
Analogous to [`file/1`](`file/1`), but takes a list of forms (in either Erlang
993990
abstract or Core Erlang format representation) as first argument.
994991

995992
Option `binary` is implicit, that is, no object code file is
996993
produced. For options that normally produce a listing file, such as
997994
'E', the internal format for that compiler pass (an Erlang term,
998995
usually not a binary) is returned instead of a binary.
999-
""".
996+
997+
## Examples
998+
999+
Parsing using `m:erl_scan` and `m:erl_parse`:
1000+
1001+
```erlang
1002+
1> Program = """
1003+
-module(test).
1004+
-export([foo/0]).
1005+
foo() -> bar.
1006+
1007+
""".
1008+
2> ParseForms =
1009+
fun
1010+
Parse("", Loc) ->
1011+
[];
1012+
Parse(String, Loc) ->
1013+
case erl_scan:tokens("", String, Loc) of
1014+
{done, {ok, Tokens, NewLoc}, Cont} ->
1015+
{ok, Form} = erl_parse:parse_form(Tokens),
1016+
[FormParse(Cont, NewLoc)]
1017+
end
1018+
end.
1019+
3> Forms = ParseForms(Program, {1,1}).
1020+
[{attribute,{1,2},module,test},
1021+
{attribute,{2,2},export,[{foo,0}]},
1022+
{function,{3,1},
1023+
foo,0,
1024+
[{clause,{3,1},[],[],[{atom,{3,10},bar}]}]}]
1025+
4> compile:forms(Forms).
1026+
{ok,test,
1027+
<<70,79,82,49,0,0,1,196,66,69,65,77,65,116,85,56,0,0,0,
1028+
52,255,255,255,250,64,116,...>>}
1029+
```
1030+
1031+
Parsing using `epp`:
1032+
1033+
```erlang
1034+
1> Program = ~"""
1035+
-module(test).
1036+
-export([foo/0]).
1037+
foo() -> bar.
1038+
1039+
""".
1040+
2> {ok, IoServer} = file:open(Program, [read, binary, ram, cooked]).
1041+
3> {ok, Forms} = epp:parse_file("test.erl", [{fd, IoServer}]).
1042+
{ok,[{attribute,1,file,{"test.erl",1}},
1043+
{attribute,1,module,test},
1044+
{attribute,2,export,[{foo,0}]},
1045+
{function,3,foo,0,[{clause,3,[],[],[{atom,3,bar}]}]},
1046+
{eof,4}]}
1047+
4> compile:forms(Forms).
1048+
{ok,test,
1049+
<<70,79,82,49,0,0,1,196,66,69,65,77,65,116,85,56,0,0,0,
1050+
52,255,255,255,250,64,116,...>>}
1051+
```
1052+
"""".
10001053
-spec forms(Forms :: forms(), Options :: [option()] | option()) -> CompRet :: comp_ret().
10011054
10021055
forms(Forms, Opts) when is_list(Opts) ->
@@ -1051,7 +1104,6 @@ noenv_forms(Forms, Opt) when is_atom(Opt) ->
10511104
-doc #{ equiv => string(String, []) }.
10521105
-doc #{ since => <<"OTP @OTP-1234567@">> }.
10531106
-spec string(String :: unicode:chardata()) -> CompRet :: comp_ret().
1054-
10551107
string(String) -> string(String, ?DEFAULT_OPTIONS).
10561108
10571109
-doc """
@@ -1062,25 +1114,29 @@ Erlang source code as first argument. The source code is run through the
10621114
Erlang preprocessor (`epp`) just as when compiling a file, so directives
10631115
such as `-include`, `-define`, and `-ifdef` are supported.
10641116
1065-
Option `binary` is implicit, that is, no object code file is produced.
1066-
1067-
The `source` option can be used to set the source file name that will
1068-
appear in error messages and the `module_info/1` function. If not given,
1069-
it defaults to the module name with a `.erl` extension.
1117+
Option `binary` is implicit, that is, no object code file is
1118+
produced. For options that normally produce a listing file, such as
1119+
'E', the internal format for that compiler pass (an Erlang term,
1120+
usually not a binary) is returned instead of a binary.
10701121
10711122
The `{include_path_open, Fun}` option can be used to provide a custom function
10721123
for opening include files (see `epp:open/1`), allowing compilation
10731124
entirely in memory without touching the file system.
10741125
1126+
## Examples
1127+
10751128
```erlang
1076-
1> compile:string("-module(foo). -export([bar/0]). bar() -> ok.").
1129+
1> {ok, foo, Bin} = compile:string("-module(foo). -export([bar/0]). bar() -> ok.").
10771130
{ok,foo,<<...>>}
1131+
2> code:load_binary(foo, "foo.erl", Bin).
1132+
{module, foo}
1133+
3> foo:bar().
1134+
ok
10781135
```
10791136
""".
10801137
-doc #{ since => <<"OTP @OTP-1234567@">> }.
10811138
-spec string(String :: unicode:chardata(), Options :: [option()] | option()) ->
10821139
CompRet :: comp_ret().
1083-
10841140
string(String, Opts) when is_list(Opts) ->
10851141
do_compile({string,String}, [binary|Opts++env_default_opts()]);
10861142
string(String, Opt) when is_atom(Opt) ->

lib/compiler/test/compile_SUITE.erl

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
compile_attribute/1, message_printing/1, other_options/1,
4646
transforms/1, erl_compile_api/1, types_pp/1, bs_init_writable/1,
4747
annotations_pp/1, option_order/1,
48-
sys_coverage/1
48+
sys_coverage/1, doctests/1
4949
]).
5050

5151
-import_record(v3_core, [c_case, c_clause, c_fun, c_literal,
@@ -72,7 +72,7 @@ all() ->
7272
deterministic_docs,
7373
compile_attribute, message_printing, other_options, transforms,
7474
erl_compile_api, types_pp, bs_init_writable, annotations_pp,
75-
option_order, sys_coverage].
75+
option_order, sys_coverage, doctests].
7676

7777
groups() ->
7878
[].
@@ -2554,6 +2554,17 @@ sys_coverage_2(DataDir) ->
25542554

25552555
ok.
25562556

2557+
doctests(_Config) ->
2558+
PathOpen = fun(Path, Filename, Modes) ->
2559+
case file:path_open(Path, Filename, Modes) of
2560+
{error, enoent} ->
2561+
{ok, FD} = file:open(~"", [ram, cooked | Modes]),
2562+
{ok, FD, filename:basename(Filename)};
2563+
Else -> Else
2564+
end
2565+
end,
2566+
ct_doctest:module(compile, [], [{compile_options, [{include_path_open, PathOpen}]}]).
2567+
25572568
%%%
25582569
%%% Utilities.
25592570
%%%

0 commit comments

Comments
 (0)