View Source Rewrite.Source (rewrite v0.3.0)
A representation of some source in a project.
The %Source{}
contains the code
of the file given by path
. The module
contains Source.update/3
to update the path
and/or the code
. The changes
are recorded in the updates
list.
The struct also holds issues
for the source.
Link to this section Summary
Types
The version
of a %Source{}
. The version 1
indicates that the source has
no changes.
Functions
Adds the given issue
to the source
.
Adds the given issues
to the source
.
Returns the AST for the given %Source
.
Returns the current code for the given source
.
Returns the code of a source
for the given version
.
Compares the path
values of the given sources.
Returns true
if the %Source{}
was created.
Marks the given source
as deleted.
Returns iodata showing all diffs of the given source
.
Creates a new %Source{}
from the given ast
.
Creates a new %Source{}
from the given string
.
Returns true
if the source
has issues for the given version
.
Returns the current modules for the given source
.
Returns the modules of a source
for the given version
.
Returns the owner of the given source
.
Returns the current path for the given source
.
Returns the path of a source
for the given version
.
Creates a new %Source{}
from the given path
.
Saves the source to disk.
Updates the code
or the path
of a source
.
Returns true
if the source was updated.
Returns the version
of the given source
. The value 1
indicates that the
source has no changes.
Link to this section Types
@type by() :: module()
@type from() :: :file | :ast | :string
@type id() :: String.t()
@type issue() :: term()
@type kind() :: :code | :path
@type version() :: pos_integer()
The version
of a %Source{}
. The version 1
indicates that the source has
no changes.
Link to this section Functions
Adds the given issue
to the source
.
Adds the given issues
to the source
.
Returns the AST for the given %Source
.
The returned extended AST is generated with Sourceror.parse_string/1
.
Uses the current code
of the source
.
examples
Examples
iex> "def foo, do: :foo" |> Source.from_string() |> Source.ast()
{:def, [trailing_comments: [], leading_comments: [], line: 1, column: 1],
[
{:foo, [trailing_comments: [], leading_comments: [], line: 1, column: 5], nil},
[
{{:__block__,
[trailing_comments: [], leading_comments: [], format: :keyword, line: 1, column: 10],
[:do]},
{:__block__, [trailing_comments: [], leading_comments: [], line: 1, column: 14], [:foo]}}
]
]
}
Returns the current code for the given source
.
Returns the code of a source
for the given version
.
examples
Examples
iex> bar =
...> """
...> defmodule Bar do
...> def bar, do: :bar
...> end
...> """
iex> foo =
...> """
...> defmodule Foo do
...> def foo, do: :foo
...> end
...> """
iex> source = Source.from_string(bar)
iex> source = Source.update(source, :example, code: foo)
iex> Source.code(source) == foo
true
iex> Source.code(source, 2) == foo
true
iex> Source.code(source, 1) == bar
true
Compares the path
values of the given sources.
examples
Examples
iex> a = Source.from_string(":foo", "a.exs")
iex> Source.compare(a, a)
:eq
iex> b = Source.from_string(":foo", "b.exs")
iex> Source.compare(a, b)
:lt
iex> Source.compare(b, a)
:gt
Returns true
if the %Source{}
was created.
Created means here that a new file is written when saving.
examples
Examples
iex> source = Source.read!("test/fixtures/source/simple.ex")
...> Source.created?(source)
false
iex> source = Source.from_string(":foo")
...> Source.created?(source)
true
iex> source = Source.from_string(":foo", "test/fixtures/new.ex", Test)
...> Source.created?(source)
true
Marks the given source
as deleted.
This function set the path
of the given
source to nil
.
Returns iodata showing all diffs of the given source
.
examples
Examples
iex> code = """
...> def foo( x ) do
...> {:x,
...> x}
...> end
...> """
iex> formatted = code |> Code.format_string!() |> IO.iodata_to_binary()
iex> source = Source.from_string(code)
iex> source |> Source.diff() |> IO.iodata_to_binary()
""
iex> source
...> |> Source.update(Test, code: formatted)
...> |> Source.diff(color: false)
...> |> IO.iodata_to_binary()
"""
1 - |def foo( x ) do
2 - | {:x,
3 - | x}
1 + |def foo(x) do
2 + | {:x, x}
4 3 |end
5 4 |
"""
Creates a new %Source{}
from the given ast
.
examples
Examples
iex> ast = Sourceror.parse_string!("a + b")
iex> source = Source.from_ast(ast)
iex> source.modules
[]
iex> source.code
"a + b"
Creates a new %Source{}
from the given string
.
examples
Examples
iex> source = Source.from_string("a + b")
iex> source.modules
[]
iex> source.code
"a + b"
Returns true
if the source
has issues for the given version
.
The version
argument also accepts :actual
and :all
to check whether the
source
has problems for the actual version or if there are problems at all.
examples
Examples
iex> source =
...> "a + b"
...> |> Source.from_string("some/where/plus.exs")
...> |> Source.add_issue(%{issue: :foo})
...> |> Source.update(:example, path: "some/where/else/plus.exs")
...> |> Source.add_issue(%{issue: :bar})
iex> Source.has_issues?(source)
true
iex> Source.has_issues?(source, 1)
true
iex> Source.has_issues?(source, :all)
true
iex> source = Source.update(source, :example, code: "a - b")
iex> Source.has_issues?(source)
false
iex> Source.has_issues?(source, 2)
true
iex> Source.has_issues?(source, :all)
true
Returns the current modules for the given source
.
Returns the modules of a source
for the given version
.
examples
Examples
iex> bar =
...> """
...> defmodule Bar do
...> def bar, do: :bar
...> end
...> """
iex> foo =
...> """
...> defmodule Foo do
...> def foo, do: :foo
...> end
...> """
iex> source = Source.from_string(bar)
iex> source = Source.update(source, :example, code: bar <> foo)
iex> Source.modules(source)
[Foo, Bar]
iex> Source.modules(source, 2)
[Foo, Bar]
iex> Source.modules(source, 1)
[Bar]
Returns the owner of the given source
.
Returns the current path for the given source
.
Returns the path of a source
for the given version
.
examples
Examples
iex> source =
...> "a + b"
...> |> Source.from_string("some/where/plus.exs")
...> |> Source.update(:example, path: "some/where/else/plus.exs")
...> Source.path(source, 1)
"some/where/plus.exs"
iex> Source.path(source, 2)
"some/where/else/plus.exs"
Creates a new %Source{}
from the given path
.
examples
Examples
iex> source = Source.read!("test/fixtures/source/simple.ex")
iex> source.modules
[MyApp.Simple]
iex> source.code
"""
defmodule MyApp.Simple do
def foo(x) do
x * 2
end
end
"""
@spec save(t()) :: :ok | {:error, :nofile | File.posix()}
Saves the source to disk.
If the source :path
was updated then the old file will be deleted. The
original file will also deleted when the source
was marked as deleted with
del/1
.
Missing directories are created.
examples
Examples
iex> ":test" |> Source.from_string() |> Source.save()
{:error, :nofile}
iex> path = "tmp/foo.ex"
iex> File.write(path, ":foo")
iex> source = path |> Source.read!() |> Source.update(:test, code: ":bar")
iex> Source.save(source)
:ok
iex> File.read(path)
{:ok, ":bar\n"}
iex> source |> Source.del() |> Source.save()
iex> File.exists?(path)
false
iex> source = Source.from_string(":bar")
iex> Source.save(source)
{:error, :nofile}
iex> source |> Source.update(:test, path: "tmp/bar.ex") |> Source.save()
:ok
iex> path = "tmp/ping.ex"
iex> File.write(path, ":ping")
iex> source = path |> Source.read!()
iex> new_path = "tmp/pong.ex"
iex> source |> Source.update(:test, path: new_path) |> Source.save()
:ok
iex> File.exists?(path)
false
iex> File.read(new_path)
{:ok, ":ping"}
Updates the code
or the path
of a source
.
examples
Examples
iex> source =
...> "a + b"
...> |> Source.from_string()
...> |> Source.update(:example, path: "test/fixtures/new.exs")
...> |> Source.update(:example, code: "a - b")
iex> source.updates
[{:code, :example, "a + b"}, {:path, :example, nil}]
iex> source.code
"a - b\n"
If the new value equal to the current value, no updates will be added.
iex> source =
...> "a = 42"
...> |> Source.from_string()
...> |> Source.update(:example, code: "b = 21")
...> |> Source.update(:example, code: "b = 21")
...> |> Source.update(:example, code: "b = 21")
iex> source.updates
[{:code, :example, "a = 42"}]
Returns true
if the source was updated.
The optional argument kind
specifies whether only :code
changes or :path
changes are considered. Defaults to :any
.
examples
Examples
iex> source = Source.from_string("a = 42")
iex> Source.updated?(source)
false
iex> source = Source.update(source, :example, code: "b = 21")
iex> Source.updated?(source)
true
iex> Source.updated?(source, :path)
false
iex> Source.updated?(source, :code)
true
Returns the version
of the given source
. The value 1
indicates that the
source has no changes.