class Xdrgen::Generators::Elixir
Constants
- MAX_INT
Public Instance Methods
generate()
click to toggle source
# File lib/xdrgen/generators/elixir.rb, line 5 def generate path = "#{@namespace}_generated.ex" out = @output.open(path) render_define_block(out) do out.indent() do render_definitions(out, @top) end end end
Private Instance Methods
build_type_args(type)
click to toggle source
the args to supply build_type (or define_type(name, …args))
# File lib/xdrgen/generators/elixir.rb, line 200 def build_type_args(type) base_ref = case type when AST::Typespecs::Bool "Bool" when AST::Typespecs::Double "Double" when AST::Typespecs::Float "Float" when AST::Typespecs::Hyper "HyperInt" when AST::Typespecs::Int "Int" when AST::Typespecs::Opaque if type.fixed? "Opaque, #{type.size}" else type.size ? "VariableOpaque, #{type.size}" : "VariableOpaque" end when AST::Typespecs::Quadruple raise "no quadruple support in elixir" when AST::Typespecs::String "XDR.Type.String, #{type.size}" when AST::Typespecs::UnsignedHyper "UnsignedHyperInt" when AST::Typespecs::UnsignedInt "UnsignedInt" when AST::Typespecs::Simple "\"#{name type}\"" when AST::Definitions::Base "\"#{name type}\"" when AST::Concerns::NestedDefinition "\"#{name type}\"" else raise "Unknown reference type: #{type.class.name}, #{type.class.ancestors}" end base_type = base_ref === "\"#{name type}\"" ? base_ref : "buid_type(base_ref)" case type.sub_type when :simple base_ref when :optional "Optional, #{base_type}" when :array is_named, size = type.array_size size = is_named ? "\"#{size}\"" : size "Array, length: #{size}, type: #{base_type}" when :var_array is_named, size = type.array_size size = is_named ? "\"#{size}\"" : (size || MAX_INT) "VariableArray, max_length: #{size}, type: #{base_type}" else raise "Unknown sub_type: #{type.sub_type}" end end
comma_unless_last(index, collection)
click to toggle source
# File lib/xdrgen/generators/elixir.rb, line 191 def comma_unless_last(index, collection) if index + 1 >= collection.length "" else "," end end
const_name(named)
click to toggle source
# File lib/xdrgen/generators/elixir.rb, line 174 def const_name(named) named.name.underscore.upcase end
member_name(member)
click to toggle source
# File lib/xdrgen/generators/elixir.rb, line 178 def member_name(member) name(member).underscore end
name(named)
click to toggle source
# File lib/xdrgen/generators/elixir.rb, line 161 def name(named) return nil unless named.respond_to?(:name) parent = name named.parent_defn if named.is_a?(AST::Concerns::NestedDefinition) # NOTE: classify will strip plurality, so we restore it if necessary plural = named.name.underscore.downcase.pluralize == named.name.underscore.downcase base = named.name.underscore.classify result = plural ? base.pluralize : base "#{parent}#{result}" end
render_const(out, const)
click to toggle source
# File lib/xdrgen/generators/elixir.rb, line 94 def render_const(out, const) out.puts "define_type(\"#{const_name const}\", Const, #{const.value});" end
render_define_block(out) { || ... }
click to toggle source
# File lib/xdrgen/generators/elixir.rb, line 77 def render_define_block(out) out.puts "defmodule #{@namespace} do" out.indent do render_moduledoc(out) out.puts "use XDR.Base\n\n" end yield ensure out.puts "end" out.break end
render_definition(out, defn)
click to toggle source
# File lib/xdrgen/generators/elixir.rb, line 27 def render_definition(out, defn) render_nested_definitions(out, defn) render_source_comment(out, defn) case defn when AST::Definitions::Struct ; render_struct out, defn when AST::Definitions::Enum ; render_enum out, defn when AST::Definitions::Union ; render_union out, defn when AST::Definitions::Typedef ; render_typedef out, defn when AST::Definitions::Const ; render_const out, defn end out.break end
render_definitions(out, node)
click to toggle source
# File lib/xdrgen/generators/elixir.rb, line 17 def render_definitions(out, node) node.definitions.each{|n| render_definition out, n } node.namespaces.each{|n| render_definitions out, n } end
render_enum(out, enum)
click to toggle source
# File lib/xdrgen/generators/elixir.rb, line 108 def render_enum(out, enum) out.puts "define_type(\"#{name enum}\", Enum," out.indent do enum.members.each_with_index do |m, i| out.puts "#{member_name m}: #{m.value}#{comma_unless_last(i, enum.members)}" end end out.puts ")" end
render_moduledoc(out)
click to toggle source
# File lib/xdrgen/generators/elixir.rb, line 65 def render_moduledoc(out) out.puts <<-EOS.strip_heredoc @moduledoc """ Automatically generated on #{Time.now.iso8601} DO NOT EDIT or your changes may be overwritten Target implementation: exdr at https://hex.pm/packages/exdr """ EOS out.break end
render_nested_definitions(out, defn)
click to toggle source
# File lib/xdrgen/generators/elixir.rb, line 22 def render_nested_definitions(out, defn) return unless defn.respond_to? :nested_definitions defn.nested_definitions.each{|ndefn| render_definition out, ndefn} end
render_source_comment(out, defn)
click to toggle source
# File lib/xdrgen/generators/elixir.rb, line 47 def render_source_comment(out, defn) return if defn.is_a?(AST::Definitions::Namespace) out.puts <<-EOS.strip_heredoc comment ~S""" === xdr source ============================================================ EOS out.puts " " + defn.text_value.split("\n").join("\n ") out.puts <<-EOS.strip_heredoc =========================================================================== """ EOS end
render_struct(out, struct)
click to toggle source
# File lib/xdrgen/generators/elixir.rb, line 98 def render_struct(out, struct) out.puts "define_type(\"#{name struct}\", Struct," out.indent do struct.members.each_with_index do |m, i| out.puts "#{member_name m}: #{type_reference m.type}#{comma_unless_last(i, struct.members)}" end end out.puts ")" end
render_typedef(out, typedef)
click to toggle source
# File lib/xdrgen/generators/elixir.rb, line 90 def render_typedef(out, typedef) out.puts "define_type(\"#{name typedef}\", #{build_type_args typedef.declaration.type})" end
render_union(out, union)
click to toggle source
# File lib/xdrgen/generators/elixir.rb, line 118 def render_union(out, union) out.puts "define_type(\"#{name union}\", Union," out.indent do out.puts "switch_type: #{type_reference union.discriminant.type}," out.puts "switch_name: :#{member_name union.discriminant}," out.puts "switches: [" out.indent do union.normal_arms.each do |arm| arm_name = arm.void? ? "XDR.Type.Void" : ":#{member_name(arm)}" arm.cases.each do |acase| switch = if acase.value.is_a?(AST::Identifier) ":#{member_name(acase.value)}" else acase.value.text_value end out.puts "{#{switch}, #{arm_name}}," end end end out.puts "]," out.puts "arms: [" out.indent do union.arms.each do |arm| next if arm.void? out.puts "#{member_name arm}: #{type_reference arm.type}," end end out.puts union.default_arm.present? ? "]," : "]" if union.default_arm.present? arm = union.default_arm arm_name = arm.void? ? "XDR.Type.Void" : member_name(arm) out.puts "default_arm: #{arm_name}," end end out.puts ")" end
type_reference(type)
click to toggle source
this can be a string to reference a custom type or a build_type call like build_type(VariableOpaque, 100) args for build_type can be created with build_type_args
# File lib/xdrgen/generators/elixir.rb, line 185 def type_reference(type) build_args = build_type_args(type) build_args === "\"#{name type}\"" ? build_args : "build_type(#{build_args})" end