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.