Skip to content

Commit

Permalink
Generate types and type specs for all generated functions in aws-elix…
Browse files Browse the repository at this point in the history
…ir and aws-erlang

- Generate common errors in order to unify types and reduce noise
- Ensure that for Elixir, typedoc examples are considered code blocks
- Erlang Type docs are not hoverable for now due to issues with 'rebar3 ex_doc'
  - Will follow up on this task
- Increase Task.await/2 timeout
  • Loading branch information
onno-vos-dev committed Mar 28, 2024
1 parent 6ba75a2 commit 643d443
Show file tree
Hide file tree
Showing 12 changed files with 981 additions and 125 deletions.
3 changes: 2 additions & 1 deletion lib/aws_codegen.ex
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ defmodule AWS.CodeGen do
protocol: nil,
signature_version: nil,
service_id: nil,
shapes: %{},
signing_name: nil,
target_prefix: nil
end
Expand Down Expand Up @@ -96,7 +97,7 @@ defmodule AWS.CodeGen do
end
)

Enum.each(tasks, fn task -> Task.await(task, 60_000) end)
Enum.each(tasks, fn task -> Task.await(task, 120_000) end)
end

defp generate_code(spec, language, endpoints_spec, template_base_path, output_path) do
Expand Down
12 changes: 11 additions & 1 deletion lib/aws_codegen/post_service.ex
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
defmodule AWS.CodeGen.PostService do
alias AWS.CodeGen.Docstring
alias AWS.CodeGen.Service
alias AWS.CodeGen.Shapes

defmodule Action do
defstruct arity: nil,
docstring: nil,
function_name: nil,
input: nil,
output: nil,
errors: %{},
host_prefix: nil,
name: nil
end
Expand Down Expand Up @@ -57,6 +61,7 @@ defmodule AWS.CodeGen.PostService do
service = spec.api["shapes"][spec.shape_name]
traits = service["traits"]
actions = collect_actions(language, spec.api)
shapes = Shapes.collect_shapes(language, spec.api)
endpoint_prefix = traits["aws.api#service"]["endpointPrefix"] || traits["aws.api#service"]["arnNamespace"]
endpoint_info = endpoints_spec["services"][endpoint_prefix]
is_global = not is_nil(endpoint_info) and not Map.get(endpoint_info, "isRegionalized", true)
Expand Down Expand Up @@ -89,6 +94,7 @@ defmodule AWS.CodeGen.PostService do
language: language,
module_name: spec.module_name,
protocol: protocol |> to_string() |> String.replace("_", "-"),
shapes: shapes,
signing_name: signing_name,
signature_version: AWS.CodeGen.Util.get_signature_version(service),
service_id: AWS.CodeGen.Util.get_service_id(service),
Expand Down Expand Up @@ -137,10 +143,14 @@ defmodule AWS.CodeGen.PostService do
),
function_name: AWS.CodeGen.Name.to_snake_case(operation),
host_prefix: operation_spec["traits"]["smithy.api#endpoint"]["hostPrefix"],
name: String.replace(operation, ~r/com\.amazonaws\.[^#]+#/, "")
name: String.replace(operation, ~r/com\.amazonaws\.[^#]+#/, ""),
input: operation_spec["input"],
output: operation_spec["output"],
errors: operation_spec["errors"]
}
end)
|> Enum.sort(fn a, b -> a.function_name < b.function_name end)
|> Enum.uniq()
end

end
13 changes: 10 additions & 3 deletions lib/aws_codegen/rest_service.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ defmodule AWS.CodeGen.RestService do
send_body_as_binary?: false,
receive_body_as_binary?: false,
host_prefix: nil,
language: nil
language: nil,
input: nil,
output: nil,
errors: []

def method(action) do
result = action.method |> String.downcase() |> String.to_atom()
Expand Down Expand Up @@ -145,7 +148,8 @@ defmodule AWS.CodeGen.RestService do
signing_name: signing_name,
signature_version: AWS.CodeGen.Util.get_signature_version(service),
service_id: AWS.CodeGen.Util.get_service_id(service),
target_prefix: nil, ##TODO: metadata["targetPrefix"]
target_prefix: nil, ##TODO: metadata["targetPrefix"],
shapes: Shapes.collect_shapes(language, spec.api)
}
end

Expand Down Expand Up @@ -275,7 +279,10 @@ defmodule AWS.CodeGen.RestService do
send_body_as_binary?: Shapes.body_as_binary?(shapes, input_shape),
receive_body_as_binary?: Shapes.body_as_binary?(shapes, output_shape),
host_prefix: operation_spec["traits"]["smithy.api#endpoint"]["hostPrefix"],
language: language
language: language,
input: operation_spec["input"],
output: operation_spec["output"],
errors: operation_spec["errors"]
}
end)
|> Enum.sort(fn a, b -> a.function_name < b.function_name end)
Expand Down
32 changes: 31 additions & 1 deletion lib/aws_codegen/shapes.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
defmodule AWS.CodeGen.Shapes do
@moduledoc false

defmodule Shape do
defstruct name: nil,
type: nil,
members: [],
member: [],
enum: [],
min: nil,
required: [],
is_input: nil
end

def get_input_shape(operation_spec) do
get_in(operation_spec, ["input", "target"])
Expand All @@ -9,6 +19,22 @@ defmodule AWS.CodeGen.Shapes do
get_in(operation_spec, ["output", "target"])
end

def collect_shapes(_language, api_spec) do
api_spec["shapes"]
|> Map.new(fn {name, shape} ->
{name,
%Shape{
name: name,
type: shape["type"],
member: shape["member"],
members: shape["members"],
min: shape["min"],
enum: shape["enum"],
is_input: is_input?(shape)
}}
end)
end

def body_as_binary?(shapes, shape) do
## TODO: Should we validate or search for trait `smithy.api#httpPayload` rather than
## trust that the member is always named `Body`?
Expand All @@ -23,4 +49,8 @@ defmodule AWS.CodeGen.Shapes do
end
end

def is_input?(shape) do
!Map.has_key?(shape, "traits") or Map.has_key?(shape["traits"], "smithy.api#input")
end

end
Loading

0 comments on commit 643d443

Please sign in to comment.