class Xdrgen::Generators::Javascript

Constants

MAX_INT

Public Instance Methods

generate() click to toggle source
# File lib/xdrgen/generators/javascript.rb, line 6
def generate
  path = "#{@namespace}_generated.js"
  out = @output.open(path)

  render_top_matter out
  render_define_block(out) do
    render_definitions(out, @top)
  end
end

Private Instance Methods

const_name(named) click to toggle source
# File lib/xdrgen/generators/javascript.rb, line 188
def const_name(named)
  named.name.underscore.upcase
end
member_name(member) click to toggle source
# File lib/xdrgen/generators/javascript.rb, line 192
def member_name(member)
  name(member).camelize(:lower)
end
name(named) click to toggle source
# File lib/xdrgen/generators/javascript.rb, line 169
def name(named)
  parent = name named.parent_defn if named.is_a?(AST::Concerns::NestedDefinition)

  # NOTE: classify will strip plurality, so we restore it if necessary
  #
  # Downcase the value since pluralize adds a lower case `s`.
  #
  # Without downcasing, the following appears as singular, but it's plural:
  #
  #  "BEGIN_SPONSORING_FUTURE_RESERVEs" == "BEGIN_SPONSORING_FUTURE_RESERVES"
  #  => false
  #
  plural = named.name.underscore.downcase.pluralize == named.name.underscore.downcase
  base   = named.name.underscore.classify
  result = plural ? base.pluralize : base

  "#{parent}#{result}"
end
reference(type) click to toggle source
# File lib/xdrgen/generators/javascript.rb, line 196
def reference(type)
  baseReference = case type
  when AST::Typespecs::Bool
    "xdr.bool()"
  when AST::Typespecs::Double
    "xdr.double()"
  when AST::Typespecs::Float
    "xdr.float()"
  when AST::Typespecs::Hyper
    "xdr.hyper()"
  when AST::Typespecs::Int
    "xdr.int()"
  when AST::Typespecs::Opaque
    if type.fixed?
      "xdr.opaque(#{type.size})"
    else
      "xdr.varOpaque(#{type.size})"
    end
  when AST::Typespecs::Quadruple
    raise "no quadruple support for javascript"
  when AST::Typespecs::String
    "xdr.string(#{type.size})"
  when AST::Typespecs::UnsignedHyper
    "xdr.uhyper()"
  when AST::Typespecs::UnsignedInt
    "xdr.uint()"
  when AST::Typespecs::Simple
    "xdr.lookup(\"#{name type}\")"
  when AST::Definitions::Base
    "xdr.lookup(\"#{name type}\")"
  when AST::Concerns::NestedDefinition
    "xdr.lookup(\"#{name type}\")"
  else
    raise "Unknown reference type: #{type.class.name}, #{type.class.ancestors}"
  end

  case type.sub_type
  when :simple
    baseReference
  when :optional
    "xdr.option(#{baseReference})"
  when :array
    is_named, size = type.array_size
    size = is_named ? "xdr.lookup(\"#{size}\")" : size
    "xdr.array(#{baseReference}, #{size})"
  when :var_array
    is_named, size = type.array_size
    size = is_named ? "xdr.lookup(\"#{size}\")" : (size || MAX_INT)
    "xdr.varArray(#{baseReference}, #{size})"
  else
    raise "Unknown sub_type: #{type.sub_type}"
  end

end
render_const(out, const) click to toggle source
# File lib/xdrgen/generators/javascript.rb, line 92
def render_const(out, const)
  out.puts "xdr.const(\"#{const_name const}\", #{const.value});"
end
render_define_block(out) { || ... } click to toggle source
# File lib/xdrgen/generators/javascript.rb, line 78
def render_define_block(out)
  out.puts "var types = XDR.config(xdr => {"
  yield
ensure
  out.puts "});"
  out.puts "export default types;"
  out.break
end
render_definition(out, defn) click to toggle source
# File lib/xdrgen/generators/javascript.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/javascript.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/javascript.rb, line 106
def render_enum(out, enum)
  out.puts "xdr.enum(\"#{name enum}\", {"

  out.indent do
    enum.members.each do |m|
      out.puts "#{member_name m}: #{m.value},"
    end
  end

  out.puts "});"
end
render_nested_definitions(out, defn) click to toggle source
# File lib/xdrgen/generators/javascript.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/javascript.rb, line 47
      def render_source_comment(out, defn)
        return if defn.is_a?(AST::Definitions::Namespace)

        out.puts <<-EOS.strip_heredoc
          // === 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/javascript.rb, line 96
def render_struct(out, struct)
  out.puts "xdr.struct(\"#{name struct}\", ["
  out.indent do
    struct.members.each do |m|
      out.puts "[\"#{member_name m}\", #{reference m.type}],"
    end
  end
  out.puts "]);"
end
render_top_matter(out) click to toggle source
# File lib/xdrgen/generators/javascript.rb, line 64
      def render_top_matter(out)
        out.puts <<-EOS.strip_heredoc
          // Automatically generated on #{Time.now.iso8601}
          // DO NOT EDIT or your changes may be overwritten

          /* jshint maxstatements:2147483647  */
          /* jshint esnext:true  */

          import * as XDR from 'js-xdr';

        EOS
        out.break
      end
render_typedef(out, typedef) click to toggle source
# File lib/xdrgen/generators/javascript.rb, line 88
def render_typedef(out, typedef)
  out.puts "xdr.typedef(\"#{name typedef}\", #{reference typedef.declaration.type});"
end
render_union(out, union) click to toggle source
# File lib/xdrgen/generators/javascript.rb, line 118
def render_union(out, union)
  out.puts "xdr.union(\"#{name union}\", {"
  out.indent do
    out.puts "switchOn: #{reference union.discriminant.type},"
    out.puts "switchName: \"#{member_name union.discriminant}\","
    out.puts "switches: ["

    out.indent do
      union.normal_arms.each do |arm|
        arm_name = arm.void? ? "xdr.void()" : "\"#{member_name(arm)}\""

        arm.cases.each do |acase|
          switch = if acase.value.is_a?(AST::Identifier)
            if union.discriminant.type.is_a?(AST::Typespecs::Int)
              member = union.resolved_case(acase)
              "#{member.value}"
            else
              '"' + member_name(acase.value) + '"'
            end
          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}: #{reference arm.type},"
      end
    end

    out.puts "},"

    if union.default_arm.present?
      arm = union.default_arm
      arm_name = arm.void? ? "xdr.void()" : member_name(arm)
      out.puts "defaultArm: #{arm_name},"
    end

  end
  out.puts "});"
end