Compare commits

...
12 Commits
Author SHA1 Message Date
Eksperimental 5131c6be9d Missing deprecation notices in CHANGELOG v1.4 (#7614) 2018-04-28 12:07:33 +08:00
Wojtek Mach e3f3dce208 Fix links in documentation guideline on v1.4 (#6282) 2017-07-01 21:45:53 +02:00
José Valim 5ebd0d2b0b Fix misplaced backtick on CHANGELOG 2017-06-22 10:44:40 +02:00
José Valim e25c37108a Release v1.4.5 2017-06-22 10:30:39 +02:00
James Fish 0b30f6495b Handle changes to crash reports in OTP 20 (#6185)
* :message_queue_len and :current_stacktrace added
* :messages and :dictionary not always present

Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2017-06-11 17:35:32 +02:00
Andrea Leopardi f126e9f6f6 Fix indentation in Logger.Translator
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2017-06-11 17:33:32 +02:00
Steven Blowers ca06fbf6e0 Fix whitespace inconsistencies all around (#5562)
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2017-06-11 17:33:28 +02:00
José Valim 20621d41c6 Do not leak EXIT messages on Registry dispatch
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2017-06-11 17:30:13 +02:00
Lukas Dolezal 600ca02749 Fix DateTime.from_iso8601/2 when offset has no colon
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2017-06-02 20:00:11 +02:00
Josh Austin 241e13da98 Add note to CHANGELOG.md about Version parser updates (#6157) 2017-05-27 10:31:55 +02:00
Eksperimental 9c8250a092 Replace no-break space in CHANGELOG (#6140)
This was introduced in
https://github.com/elixir-lang/elixir/pull/5804
due to creating a patch via web interface
2017-05-23 15:22:20 +02:00
José Valim 867da6f876 Release v1.4.4 2017-05-15 16:53:22 +02:00
18 changed files with 220 additions and 96 deletions
+35 -4
View File
@@ -109,9 +109,36 @@ You can now also install archives from Hex in this way. Since they are fetched a
It is also possible to install escripts and archives by providing a Git/GitHub repo. See `mix help escript.install` and `mix help archive.install` for more details.
## v1.4.5 (2017-06-22)
This version includes changes that make Elixir fully compatible with Erlang/OTP 20.
### 1. Enhancements
#### Logger
* [Logger] Handle changes to crash reports in OTP 20
### 2. Bug fixes
#### Elixir
* [DateTime] Fix `DateTime.from_iso8601/2` when offset has no colon
* [Registry] Do not leak EXIT messages on `Registry.dispatch/3`
## v1.4.4 (2017-05-15)
This version includes changes that make Elixir fully compatible with Erlang/OTP 20-rc.1.
### 1. Bug fixes
#### Elixir
* [Map] Fix regression on struct update syntax
## v1.4.3 (2017-05-15)
This version includes changes that make Elixir fully compatible with Erlang OTP 20-rc.1.
This version includes changes that make Elixir fully compatible with Erlang/OTP 20-rc.1.
### 1. Enhancements
@@ -135,6 +162,7 @@ This version includes changes that make Elixir fully compatible with Erlang OTP
* [Kernel] Fix code generation when non-binary bitstrings are in AST
* [Record] Properly escape fields passed to `defrecord`
* [Version] Reject leading zeros according to the SemVer spec
#### ExUnit
@@ -310,14 +338,17 @@ This version includes changes that make Elixir fully compatible with Erlang OTP
#### Elixir
 * [Access] `Access.key/1` is deprecated due to erratic behaviour for missing keys, please use `Access.key/2` instead with proper default values
* [Access] `Access.key/1` is deprecated due to erratic behaviour for missing keys, please use `Access.key/2` instead with proper default values
* [Behaviour] The `Behaviour` module is deprecated. Callbacks may now be defined directly via the `@callback` attribute
* [Enum] Deprecate `Enum.uniq/2` in favor of `Enum.uniq_by/2`
* [Float] `Float.to_char_list/2` and `Float.to_string/2` are deprecated (use the `:erlang.float_to_list/2` and `:erlang.float_to_binary/2` functions if such conversions are desired)
* [Kernel] Deprecate support for making private functions overridable. Overridable functions must always be public as they must be contracts
 * [HashDict] The `HashDict` module is deprecated, in favour of the `Map`
 * [HashSet] The `HashDict` module is deprecated, in favour of the `MapSet`
 * [Kernel] Deprecate support for making private functions overridable. Overridable functions must always be public as they must be contracts
* [Kernel] Anonymous functions with no expression after `->`, in favor of using an expression or returning `nil`
* [Kernel] Warn if variable is used as a function call
* [OptionParser] Deprecate aliases with multiple letters, such as `-abc`
* [Set] Deprecate the `Set` module
* [Set] Deprecation of the `Set` module in favor of `MapSet`
* [Stream] Deprecate `Stream.uniq/2` in favor of `Stream.uniq_by/2`
#### IEx
+1 -1
View File
@@ -1 +1 @@
1.4.3
1.4.5
+8
View File
@@ -240,6 +240,14 @@ defmodule Calendar.ISO do
do: parse_offset(1, hour, min, rest)
def parse_offset(<<?-, hour::2-bytes, ?:, min::2-bytes, rest::binary>>),
do: parse_offset(-1, hour, min, rest)
def parse_offset(<<?+, hour::2-bytes, min::2-bytes, rest::binary>>),
do: parse_offset(1, hour, min, rest)
def parse_offset(<<?-, hour::2-bytes, min::2-bytes, rest::binary>>),
do: parse_offset(-1, hour, min, rest)
def parse_offset(<<?+, hour::2-bytes, rest::binary>>),
do: parse_offset(1, hour, "00", rest)
def parse_offset(<<?-, hour::2-bytes, rest::binary>>),
do: parse_offset(-1, hour, "00", rest)
def parse_offset(_),
do: :error
+2
View File
@@ -359,11 +359,13 @@ defmodule Registry do
end
defp dispatch_task(registry, key, mfa_or_fun, partition) do
partition = partition - 1
parent = self()
task = Task.async(fn ->
registry
|> key_ets!(partition)
|> safe_lookup_second(key)
|> apply_non_empty_to_mfa_or_fun(mfa_or_fun)
Process.unlink(parent)
:ok
end)
[task | dispatch_task(registry, key, mfa_or_fun, partition)]
+2 -2
View File
@@ -6,8 +6,8 @@ Elixir treats documentation as a first-class citizen. This means documentation s
Elixir documentation is written using Markdown. There are plenty of guides on Markdown online, we recommend the ones available on GitHub as a getting started point:
* [https://help.github.com/articles/markdown-basics/](https://help.github.com/articles/markdown-basics/)
* [https://help.github.com/articles/markdown-basics/](https://help.github.com/articles/github-flavored-markdown/)
* [Basic writing and formatting syntax](https://help.github.com/articles/basic-writing-and-formatting-syntax/)
* [Mastering Markdown](https://guides.github.com/features/mastering-markdown/)
## Module Attributes
+16 -12
View File
@@ -13,18 +13,8 @@ expand_map(Meta, Args, E) ->
{{'%{}', Meta, EArgs}, EA}.
expand_struct(Meta, Left, {'%{}', MapMeta, MapArgs}, #{context := Context} = E) ->
CleanArgs =
case lists:keytake('__struct__', 1, MapArgs) of
{value, _, ValueArgs} ->
elixir_errors:warn(?line(Meta), ?m(E, file),
"key :__struct__ is ignored when building structs"),
ValueArgs;
false ->
MapArgs
end,
{[ELeft | EArgs], EE} = elixir_exp:expand_args([Left | CleanArgs], E),
ERight = {'%{}', MapMeta, EArgs},
CleanArgs = clean_struct_key_from_map_args(Meta, MapArgs, E),
{[ELeft, ERight], EE} = elixir_exp:expand_args([Left, {'%{}', MapMeta, CleanArgs}], E),
case validate_struct(ELeft, Context) of
true when is_atom(ELeft) ->
@@ -54,6 +44,20 @@ expand_struct(Meta, _Left, Right, E) ->
compile_error(Meta, ?m(E, file), "expected struct to be followed by a map, got: ~ts",
['Elixir.Macro':to_string(Right)]).
clean_struct_key_from_map_args(Meta, [{'|', PipeMeta, [Left, MapAssocs]}], E) ->
[{'|', PipeMeta, [Left, clean_struct_key_from_map_assocs(Meta, MapAssocs, E)]}];
clean_struct_key_from_map_args(Meta, MapAssocs, E) ->
clean_struct_key_from_map_assocs(Meta, MapAssocs, E).
clean_struct_key_from_map_assocs(Meta, Assocs, E) ->
case lists:keytake('__struct__', 1, Assocs) of
{value, _, CleanAssocs} ->
elixir_errors:warn(?line(Meta), ?m(E, file), "key :__struct__ is ignored when using structs"),
CleanAssocs;
false ->
Assocs
end.
validate_struct({'^', _, [{Var, _, Ctx}]}, match) when is_atom(Var), is_atom(Ctx) -> true;
validate_struct({Var, _Meta, Ctx}, match) when is_atom(Var), is_atom(Ctx) -> true;
validate_struct(Atom, _) when is_atom(Atom) -> true;
+32
View File
@@ -163,4 +163,36 @@ defmodule DateTimeTest do
assert DateTime.compare(datetime1, datetime2) == :lt
assert DateTime.compare(datetime2, datetime1) == :gt
end
test "from_iso8601/1 with tz offsets" do
assert DateTime.from_iso8601("2017-06-02T14:00:00+01:00") |> elem(1) ==
%DateTime{year: 2017, month: 6, day: 2, zone_abbr: "UTC",
hour: 13, minute: 0, second: 0, microsecond: {0, 0},
utc_offset: 0, std_offset: 0, time_zone: "Etc/UTC"}
assert DateTime.from_iso8601("2017-06-02T14:00:00-04:00") |> elem(1) ==
%DateTime{year: 2017, month: 6, day: 2, zone_abbr: "UTC",
hour: 18, minute: 0, second: 0, microsecond: {0, 0},
utc_offset: 0, std_offset: 0, time_zone: "Etc/UTC"}
assert DateTime.from_iso8601("2017-06-02T14:00:00+0100") |> elem(1) ==
%DateTime{year: 2017, month: 6, day: 2, zone_abbr: "UTC",
hour: 13, minute: 0, second: 0, microsecond: {0, 0},
utc_offset: 0, std_offset: 0, time_zone: "Etc/UTC"}
assert DateTime.from_iso8601("2017-06-02T14:00:00-0400") |> elem(1) ==
%DateTime{year: 2017, month: 6, day: 2, zone_abbr: "UTC",
hour: 18, minute: 0, second: 0, microsecond: {0, 0},
utc_offset: 0, std_offset: 0, time_zone: "Etc/UTC"}
assert DateTime.from_iso8601("2017-06-02T14:00:00+01") |> elem(1) ==
%DateTime{year: 2017, month: 6, day: 2, zone_abbr: "UTC",
hour: 13, minute: 0, second: 0, microsecond: {0, 0},
utc_offset: 0, std_offset: 0, time_zone: "Etc/UTC"}
assert DateTime.from_iso8601("2017-06-02T14:00:00-04") |> elem(1) ==
%DateTime{year: 2017, month: 6, day: 2, zone_abbr: "UTC",
hour: 18, minute: 0, second: 0, microsecond: {0, 0},
utc_offset: 0, std_offset: 0, time_zone: "Etc/UTC"}
end
end
@@ -781,6 +781,27 @@ defmodule Kernel.WarningTest do
purge Sample
end
defmodule User do
defstruct [:name]
end
test ":__struct__ is ignored when using structs" do
assert capture_err(fn ->
Code.eval_string """
assert %Kernel.WarningTest.User{__struct__: Ignored, name: "joe"} ==
%Kernel.WarningTest.User{name: "joe"}
""", [], __ENV__
end) =~ "key :__struct__ is ignored when using structs"
assert capture_err(fn ->
Code.eval_string """
user = %Kernel.WarningTest.User{name: "meg"}
assert %Kernel.WarningTest.User{user | __struct__: Ignored, name: "joe"} ==
%Kernel.WarningTest.User{__struct__: Kernel.WarningTest.User, name: "joe"}
""", [], __ENV__
end) =~ "key :__struct__ is ignored when using structs"
end
defp purge(list) when is_list(list) do
Enum.each list, &purge/1
end
+4
View File
@@ -207,6 +207,8 @@ defmodule RegistryTest do
end
test "dispatches to multiple keys", %{registry: registry} do
Process.flag(:trap_exit, true)
assert Registry.dispatch(registry, "hello", fn _ ->
raise "will never be invoked"
end) == :ok
@@ -230,6 +232,8 @@ defmodule RegistryTest do
refute_received {:dispatch, :value1}
refute_received {:dispatch, :value2}
assert_received {:dispatch, :value3}
refute_received {:EXIT, _, _}
end
test "allows process unregistering", %{registry: registry} do
+1 -1
View File
@@ -11,7 +11,7 @@ defmodule ExUnit.OnExitHandler do
Agent.update(@name, &Map.put(&1, pid, []))
end
@spec add(pid, term, (()-> term)) :: :ok | :error
@spec add(pid, term, (() -> term)) :: :ok | :error
def add(pid, name_or_ref, callback) when is_pid(pid) and is_function(callback, 0) do
Agent.get_and_update(@name, fn map ->
if entries = Map.get(map, pid) do
+2 -2
View File
@@ -102,7 +102,7 @@ defmodule IEx.Autocomplete do
if prefix in [0, length] do
yes("", Enum.flat_map(entries, &to_entries/1))
else
yes(:binary.part(first.name, prefix, length-prefix), [])
yes(:binary.part(first.name, prefix, length - prefix), [])
end
end
@@ -212,7 +212,7 @@ defmodule IEx.Autocomplete do
for mod <- match_modules(base, module === Elixir),
parts = String.split(mod, "."),
depth <= length(parts) do
%{kind: :module, type: :elixir, name: Enum.at(parts, depth-1)}
%{kind: :module, type: :elixir, name: Enum.at(parts, depth - 1)}
end
|> Enum.uniq
end
+77 -59
View File
@@ -97,7 +97,7 @@ defmodule Logger.Translator do
[supervisor: sup, errorContext: context,
reason: reason,
offender: [{:pid, pid}, {name_or_id, name} | offender]])
when is_pid(pid) and context !== :shutdown and name_or_id in [:name, :id] do
when is_pid(pid) and context !== :shutdown and name_or_id in [:name, :id] do
{:ok, ["Child ", inspect(name), " of Supervisor ",
sup_name(sup), ?\s, sup_context(context),
"\n** (exit) ", offender_reason(reason, context),
@@ -106,37 +106,37 @@ defmodule Logger.Translator do
end
defp translate_supervisor(min_level,
[supervisor: sup, errorContext: context,
[supervisor: sup, errorContext: context,
reason: reason,
offender: [{:pid, _pid},
{name_or_id, name} | offender]]) when name_or_id in [:name, :id] do
{:ok, ["Child ", inspect(name), " of Supervisor ",
sup_name(sup), ?\s, sup_context(context),
"\n** (exit) ", offender_reason(reason, context) |
child_info(min_level, offender)]}
sup_name(sup), ?\s, sup_context(context),
"\n** (exit) ", offender_reason(reason, context) |
child_info(min_level, offender)]}
end
defp translate_supervisor(min_level,
[supervisor: sup, errorContext: context,
[supervisor: sup, errorContext: context,
reason: reason,
offender: [{:pid, pid} | offender]]) do
{:ok, ["Child of Supervisor ",
sup_name(sup), ?\s, sup_context(context),
"\n** (exit) ", offender_reason(reason, context),
"\nPid: ", inspect(pid) |
child_info(min_level, offender)]}
sup_name(sup), ?\s, sup_context(context),
"\n** (exit) ", offender_reason(reason, context),
"\nPid: ", inspect(pid) |
child_info(min_level, offender)]}
end
defp translate_supervisor(min_level,
[supervisor: sup, errorContext: context,
[supervisor: sup, errorContext: context,
reason: reason,
offender: [{:nb_children, n},
{name_or_id, name} | offender]]) when name_or_id in [:name, :id] do
{:ok, ["Children ", inspect(name), " of Supervisor ",
sup_name(sup), ?\s, sup_context(context),
"\n** (exit) ", offender_reason(reason, context),
"\nNumber: ", inspect(n) |
child_info(min_level, offender)]}
sup_name(sup), ?\s, sup_context(context),
"\n** (exit) ", offender_reason(reason, context),
"\nNumber: ", inspect(n) |
child_info(min_level, offender)]}
end
defp translate_supervisor(_min_level, _other), do: :none
@@ -148,19 +148,19 @@ defmodule Logger.Translator do
defp translate_progress(min_level,
[supervisor: sup,
started: [{:pid, pid}, {name_or_id, name} | started]]) when name_or_id in [:name, :id] do
started: [{:pid, pid}, {name_or_id, name} | started]]) when name_or_id in [:name, :id] do
{:ok, ["Child ", inspect(name), " of Supervisor ",
sup_name(sup), " started",
"\nPid: ", inspect(pid) |
child_info(min_level, started)]}
sup_name(sup), " started",
"\nPid: ", inspect(pid) |
child_info(min_level, started)]}
end
defp translate_progress(min_level,
[supervisor: sup,
started: [{:pid, pid} | started]]) do
started: [{:pid, pid} | started]]) do
{:ok, ["Child of Supervisor ", sup_name(sup), " started",
"\nPid: ", inspect(pid) |
child_info(min_level, started)]}
"\nPid: ", inspect(pid) |
child_info(min_level, started)]}
end
defp translate_progress(_min_level, _other), do: :none
@@ -177,17 +177,17 @@ defmodule Logger.Translator do
defp child_info(min_level, [{:mfargs, {mod, fun, args}} | debug]) do
["\nStart Call: ", format_mfa(mod, fun, args) |
child_debug(min_level, debug)]
child_debug(min_level, debug)]
end
defp child_info(min_level, [{:mfa, {mod, fun, args}} | debug]) do
["\nStart Call: ", format_mfa(mod, fun, args) |
child_debug(min_level, debug)]
child_debug(min_level, debug)]
end
defp child_info(min_level, [{:mod, mod} | debug]) do
["\nStart Module: ", inspect(mod) |
child_debug(min_level, debug)]
child_debug(min_level, debug)]
end
defp child_debug(:debug,
@@ -217,9 +217,9 @@ defmodule Logger.Translator do
{:error_info, {kind, exception, stack}} | crashed],
linked]) do
{:ok, ["Process ", crash_name(pid, name), " terminating",
format(kind, exception, stack),
crash_info(min_level, [initial_call | crashed]) |
crash_linked(min_level, linked)]}
format(kind, exception, stack),
crash_info(min_level, [initial_call | crashed]) |
crash_linked(min_level, linked)]}
end
defp translate_crash(min_level,
@@ -228,9 +228,9 @@ defmodule Logger.Translator do
{:error_info, {kind, exception, stack}} | crashed],
linked]) do
{:ok, ["Process ", crash_name(pid, name), " terminating",
format(kind, exception, stack),
crash_info(min_level, crashed),
crash_linked(min_level, linked)]}
format(kind, exception, stack),
crash_info(min_level, crashed),
crash_linked(min_level, linked)]}
end
defp crash_name(pid, []), do: inspect(pid)
@@ -241,13 +241,13 @@ defmodule Logger.Translator do
defp crash_info(min_level,
[{:initial_call, {mod, fun, args}} | info], prefix) do
[prefix, "Initial Call: ", crash_call(mod, fun, args) |
crash_info(min_level, info, prefix)]
crash_info(min_level, info, prefix)]
end
defp crash_info(min_level,
[{:current_function, {mod, fun, args}} | info], prefix) do
[prefix, "Current Call: ", crash_call(mod, fun, args) |
crash_info(min_level, info, prefix)]
crash_info(min_level, info, prefix)]
end
defp crash_info(min_level, [{:current_function, []} | info], prefix) do
@@ -257,7 +257,17 @@ defmodule Logger.Translator do
defp crash_info(min_level,
[{:ancestors, ancestors} | debug], prefix) do
[prefix, "Ancestors: ", inspect(ancestors) |
crash_debug(min_level, debug, prefix)]
crash_info(min_level, debug, prefix)]
end
defp crash_info(:debug, debug, prefix) do
for {key, value} <- debug do
crash_debug(key, value, prefix)
end
end
defp crash_info(_, _, _) do
[]
end
defp crash_call(mod, fun, arity) when is_integer(arity) do
@@ -268,22 +278,28 @@ defmodule Logger.Translator do
format_mfa(mod, fun, length(args))
end
defp crash_debug(:debug,
[messages: msgs, links: links, dictionary: dict,
trap_exit: trap, status: status, heap_size: heap_size,
stack_size: stack_size, reductions: reductions], prefix) do
[prefix, "Messages: ", inspect(msgs),
prefix, "Links: ", inspect(links),
prefix, "Dictionary: ", inspect(dict),
prefix, "Trapping Exits: ", inspect(trap),
prefix, "Status: ", inspect(status),
prefix, "Heap Size: ", inspect(heap_size),
prefix, "Stack Size: ", inspect(stack_size),
prefix, "Reductions: ", inspect(reductions)]
defp crash_debug(:current_stacktrace, stack, prefix) do
stack_prefix = [prefix | " "]
[prefix, "Current Stacktrace:" |
Enum.map(stack, &[stack_prefix | Exception.format_stacktrace_entry(&1)])]
end
defp crash_debug(_min_level, _info, _prefix) do
[]
defp crash_debug(key, value, prefix) do
[prefix, crash_debug_key(key), ?:, ?\s, inspect(value)]
end
defp crash_debug_key(key) do
case key do
:message_queue_len -> "Message Queue Length"
:messages -> "Messages"
:links -> "Links"
:dictionary -> "Dictionary"
:trap_exit -> "Trapping Exits"
:status -> "Status"
:heap_size -> "Heap Size"
:stack_size -> "Stack Size"
:reductions -> "Reductions"
end
end
defp crash_linked(_min_level, []), do: []
@@ -298,17 +314,17 @@ defmodule Logger.Translator do
[{:pid, pid}, {:registered_name, []} | info]) do
indent = " "
[?\n, indent, inspect(pid) |
crash_info(min_level, info, [?\n, indent | indent])]
crash_info(min_level, info, [?\n, indent | indent])]
end
defp crash_neighbour(min_level,
[{:pid, pid}, {:registered_name, name} | info]) do
indent = " "
[?\n, indent, inspect(name), " (", inspect(pid), ")" |
crash_info(min_level, info, [?\n, indent | indent])]
crash_info(min_level, info, [?\n, indent | indent])]
end
defp format_stop({maybe_exception, [_ | _ ] = maybe_stacktrace} = reason) do
defp format_stop({maybe_exception, [_ | _] = maybe_stacktrace} = reason) do
try do
format_stacktrace(maybe_stacktrace)
catch
@@ -316,8 +332,7 @@ defmodule Logger.Translator do
format_stop_banner(reason)
else
formatted_stacktrace ->
[format_stop_banner(maybe_exception, maybe_stacktrace) |
formatted_stacktrace]
[format_stop_banner(maybe_exception, maybe_stacktrace) | formatted_stacktrace]
end
end
@@ -332,8 +347,8 @@ defmodule Logger.Translator do
# OTP processes rewrite the :undef error to these reasons when logging
@gen_undef [:"module could not be loaded", :"function not exported"]
defp format_stop_banner(undef, [{mod, fun, args, _info} | _ ] = stacktrace)
when undef in @gen_undef and is_atom(mod) and is_atom(fun) do
defp format_stop_banner(undef, [{mod, fun, args, _info} | _] = stacktrace)
when undef in @gen_undef and is_atom(mod) and is_atom(fun) do
cond do
is_list(args) ->
format_undef(mod, fun, length(args), undef, stacktrace)
@@ -345,8 +360,11 @@ defmodule Logger.Translator do
end
defp format_stop_banner(reason, stacktrace) do
# If this is already an exception (even an ErlangError), we format it as an
# exception. Otherwise, we try to normalize it, and if it's normalized as an
# ErlangError we instead format it as an exit.
if Exception.exception?(reason) do
[?\n | Exception.format_banner(:error, reason, stacktrace)]
[?\n | Exception.format_banner(:error, reason, stacktrace)]
else
case Exception.normalize(:error, reason, stacktrace) do
%ErlangError{} ->
@@ -369,9 +387,9 @@ defmodule Logger.Translator do
end
defp format_stacktrace(stacktrace) do
for entry <- stacktrace do
[<<"\n ">> | Exception.format_stacktrace_entry(entry)]
end
for entry <- stacktrace do
[<<"\n ">> | Exception.format_stacktrace_entry(entry)]
end
end
defp format_mfa(mod, fun, :undefined), do: [inspect(mod), ?., to_string(fun) | "/?"]
+4 -4
View File
@@ -32,10 +32,10 @@ defmodule Logger.Utils do
end
end
defp truncate_n(int, n) when int in 0..127, do: {int, n-1}
defp truncate_n(int, n) when int in 127..0x07FF, do: {int, n-2}
defp truncate_n(int, n) when int in 0x800..0xFFFF, do: {int, n-3}
defp truncate_n(int, n) when int >= 0x10000 and is_integer(int), do: {int, n-4}
defp truncate_n(int, n) when int in 0..127, do: {int, n - 1}
defp truncate_n(int, n) when int in 127..0x07FF, do: {int, n - 2}
defp truncate_n(int, n) when int in 0x800..0xFFFF, do: {int, n - 3}
defp truncate_n(int, n) when int >= 0x10000 and is_integer(int), do: {int, n - 4}
defp truncate_n(list, n) when is_list(list) do
truncate_n_list(list, n, [])
+10 -6
View File
@@ -472,7 +472,8 @@ defmodule Logger.TranslatorTest do
send(pid, :go)
receive do: ({:DOWN, ^ref, _, _, _} -> :ok)
end) =~ ~r"""
Ancestors: \[#PID<\d+\.\d+\.\d+>\]
Ancestors: \[#PID<\d+\.\d+\.\d+>\](?:
Message Queue Length: 1(?#TODO: Require once depend on 20)|)
Messages: \[:message\]
Links: \[\]
Dictionary: \[\]
@@ -493,15 +494,18 @@ defmodule Logger.TranslatorTest do
send(pid, :go)
receive do: ({:DOWN, ^ref, _, _, _} -> :ok)
end) =~ ~r"""
Ancestors: \[#PID<\d+\.\d+\.\d+>, #PID<\d+\.\d+\.\d+>\]
Messages: \[\]
Links: \[#PID<\d+\.\d+\.\d+>\]
Dictionary: \[\]
Ancestors: \[#PID<\d+\.\d+\.\d+>, #PID<\d+\.\d+\.\d+>\](?:
Message Queue Length: 0|
Messages: \[\](?# TODO: Remove once depend on 20))
Links: \[#PID<\d+\.\d+\.\d+>\](?:|
Dictionary: \[\](?# TODO: Remove once depend on 20))
Trapping Exits: false
Status: :waiting
Heap Size: \d+
Stack Size: \d+
Reductions: \d+
Reductions: \d+(?:
Current Stacktrace:
test/logger/translator_test.exs:\d+: Logger.TranslatorTest.sleep/1(?#TODO: Require once depend on 20)|)
"""
end
+1 -1
View File
@@ -78,7 +78,7 @@ defmodule Mix.Generator do
@file file
File.read!(file)
c when is_binary(c) ->
@file {__ENV__.file, __ENV__.line+1}
@file {__ENV__.file, __ENV__.line + 1}
c
_ ->
raise ArgumentError, "expected string or from_file: file"
+1 -1
View File
@@ -255,7 +255,7 @@ defmodule Mix.Local.Installer do
path = Path.join(root, name)
cond do
not File.exists?(path) ->
Mix.shell.error "Could not find a local #{item_name} named #{inspect name}. "<>
Mix.shell.error "Could not find a local #{item_name} named #{inspect name}. " <>
"Existing #{item_plural} are:"
Mix.Task.run item_name
nil
+2 -2
View File
@@ -119,11 +119,11 @@ defmodule Mix.Tasks.New do
defp otp_app(mod, true) do
" [extra_applications: [:logger],\n mod: {#{mod}.Application, []}]"
end
defp cd_path(".") do
""
end
defp cd_path(path) do
"cd #{path}\n "
end
+1 -1
View File
@@ -1,6 +1,6 @@
{application, elixir,
[{description, "elixir"},
{vsn, "1.4.3"},
{vsn, "1.4.5"},
{modules, [
elixir
]},