diff --git a/lib/absinthe/language/input_value_definition.ex b/lib/absinthe/language/input_value_definition.ex index 8762bf5c80..9686449815 100644 --- a/lib/absinthe/language/input_value_definition.ex +++ b/lib/absinthe/language/input_value_definition.ex @@ -31,10 +31,7 @@ defmodule Absinthe.Language.InputValueDefinition do identifier: Macro.underscore(node.name) |> String.to_atom(), default_value: Blueprint.Draft.convert(node.default_value, doc), directives: Blueprint.Draft.convert(node.directives, doc), - source_location: source_location(node), - __reference__: %{ - location: source_location(node) |> Map.put(:file, "TODO") - } + source_location: source_location(node) } end diff --git a/lib/absinthe/schema/notation.ex b/lib/absinthe/schema/notation.ex index c28d4cc33f..6f0d77a7d3 100644 --- a/lib/absinthe/schema/notation.ex +++ b/lib/absinthe/schema/notation.ex @@ -1150,12 +1150,14 @@ defmodule Absinthe.Schema.Notation do """ @spec import_sdl([import_sdl_option(), ...]) :: Macro.t() defmacro import_sdl(opts) when is_list(opts) do - do_import_sdl(nil, opts) + __CALLER__ + |> do_import_sdl(nil, opts) end @spec import_sdl(String.t() | Macro.t(), [import_sdl_option()]) :: Macro.t() defmacro import_sdl(sdl, opts \\ []) do - do_import_sdl(sdl, opts) + __CALLER__ + |> do_import_sdl(sdl, opts) end defmacro values(values) do @@ -1471,8 +1473,8 @@ defmodule Absinthe.Schema.Notation do [] end - @spec do_import_sdl(nil, [import_sdl_option()]) :: Macro.t() - defp do_import_sdl(nil, opts) do + @spec do_import_sdl(Macro.Env.t(), nil, [import_sdl_option()]) :: Macro.t() + defp do_import_sdl(env, nil, opts) do case Keyword.fetch(opts, :path) do {:ok, path} -> [ @@ -1480,10 +1482,11 @@ defmodule Absinthe.Schema.Notation do @__absinthe_import_sdl_path__ unquote(path) end, do_import_sdl( + env, quote do File.read!(@__absinthe_import_sdl_path__) end, - Keyword.delete(opts, :path) + opts ), quote do @external_resource @__absinthe_import_sdl_path__ @@ -1495,10 +1498,11 @@ defmodule Absinthe.Schema.Notation do end end - @spec do_import_sdl(String.t() | Macro.t(), Keyword.t()) :: Macro.t() - defp do_import_sdl(sdl, _opts) do + @spec do_import_sdl(Macro.Env.t(), String.t() | Macro.t(), Keyword.t()) :: Macro.t() + defp do_import_sdl(env, sdl, opts) do + ref = build_reference(env) quote do - with {:ok, definitions} <- unquote(__MODULE__).SDL.parse(unquote(sdl), __MODULE__) do + with {:ok, definitions} <- unquote(__MODULE__).SDL.parse(unquote(sdl), __MODULE__, unquote(Macro.escape(ref)), unquote(Macro.escape(opts))) do @__absinthe_sdl_definitions__ definitions ++ (Module.get_attribute( __MODULE__, diff --git a/lib/absinthe/schema/notation/sdl.ex b/lib/absinthe/schema/notation/sdl.ex index 75e7428286..ce41c659e1 100644 --- a/lib/absinthe/schema/notation/sdl.ex +++ b/lib/absinthe/schema/notation/sdl.ex @@ -4,13 +4,14 @@ defmodule Absinthe.Schema.Notation.SDL do @doc """ Parse definitions from SDL source """ - @spec parse(sdl :: String.t(), Module.t()) :: + @spec parse(sdl :: String.t(), Module.t(), map(), Keyword.t()) :: {:ok, [Absinthe.Blueprint.Schema.type_t()]} | {:error, String.t()} - def parse(sdl, module) do + def parse(sdl, module, ref, opts) do with {:ok, doc} <- Absinthe.Phase.Parse.run(sdl) do definitions = doc.input.definitions |> Enum.map(&Absinthe.Blueprint.Draft.convert(&1, doc)) + |> Enum.map(&put_ref(&1, ref, opts)) |> Enum.map(fn type -> %{type | module: module} end) {:ok, definitions} @@ -27,4 +28,31 @@ defmodule Absinthe.Schema.Notation.SDL do other end end + + defp put_ref(%{fields: fields} = node, ref, opts) do + %{node | fields: Enum.map(fields, &put_ref(&1, ref, opts))} + |> do_put_ref(ref, opts) + end + defp put_ref(%{arguments: args} = node, ref, opts) do + %{node | arguments: Enum.map(args, &put_ref(&1, ref, opts))} + |> do_put_ref(ref, opts) + end + defp put_ref(%{directives: dirs} = node, ref, opts) do + %{node | directives: Enum.map(dirs, &put_ref(&1, ref, opts))} + |> do_put_ref(ref, opts) + end + defp put_ref(node, ref, opts), do: do_put_ref(node, ref, opts) + + defp do_put_ref(%{__reference__: nil} = node, ref, opts) do + ref = + case opts[:path] do + nil -> + ref + path -> + put_in(ref.location, %{file: path, line: node.source_location.line}) + end + %{node | __reference__: ref} + end + defp do_put_ref(node, _ref, _opts), do: node + end diff --git a/test/absinthe/language/field_definition_test.exs b/test/absinthe/language/field_definition_test.exs index 7465940d15..8736e8a78d 100644 --- a/test/absinthe/language/field_definition_test.exs +++ b/test/absinthe/language/field_definition_test.exs @@ -46,14 +46,6 @@ defmodule Absinthe.Language.FieldDefinitionTest do }, arguments: [ %Blueprint.Schema.InputValueDefinition{ - __reference__: %{ - location: %{ - __struct__: Absinthe.Blueprint.SourceLocation, - column: 10, - file: "TODO", - line: 4 - } - }, name: "limit", identifier: :limit, type: %Blueprint.TypeReference.Name{name: "Int"},