Last active
December 1, 2015 03:09
-
-
Save guilleiguaran/e757425ea8777d9c6384 to your computer and use it in GitHub Desktop.
Revisions
-
guilleiguaran revised this gist
Dec 1, 2015 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -31,7 +31,7 @@ defmodule Contracts do var!(result) = unquote(content) var!(result) end end # |> Macro.to_string |> IO.puts end def __on_definition__(env, function) do -
guilleiguaran created this gist
Dec 1, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,53 @@ defmodule Contracts do defmacro __using__(_opts) do quote do Module.register_attribute(__MODULE__, :requires, accumulate: true) Module.register_attribute(__MODULE__, :ensures, accumulate: true) @contracts %{} import Kernel, except: [def: 2] import Contracts, only: [def: 2] end end defmacro def(definition, do: content) do function_name = case definition do {:when, _, [{name, _, _params} | _guards] } -> name {name, _, _} -> name end contracts = Module.get_attribute(__CALLER__.module, :contracts) precondition = contracts[function_name][:requires] IO.inspect precondition quote do Contracts.__on_definition__(__ENV__, unquote(function_name)) #contracts = Module.get_attribute(__ENV__.module, :contracts) #precondition = contracts[unquote(function_name)][:requires] #IO.inspect unquote(quote do: precondition) Kernel.def(unquote(definition)) do unless unquote(precondition), do: raise "Contract not met: blame the client" var!(result) = unquote(content) var!(result) end end |> Macro.to_string |> IO.puts end def __on_definition__(env, function) do mod = env.module requires = Module.get_attribute(mod, :requires) |> List.first |> Code.string_to_quoted! ensures = Module.get_attribute(mod, :ensures) |> List.first |> Code.string_to_quoted! contract = %{requires: requires, ensures: ensures} contracts = Module.get_attribute(mod, :contracts) unless Map.has_key?(contracts, function) do Module.put_attribute(mod, :contracts, Map.put(contracts, function, contract)) end Module.delete_attribute(mod, :requires) Module.delete_attribute(mod, :ensures) end end This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,16 @@ defmodule ContractsTest do use ExUnit.Case defmodule TestMod do use Contracts @requires "x > 0" def inv(x) do -x end end test "with bad args" do TestMod.inv(1) end end