summaryrefslogtreecommitdiff
path: root/ruby_1_8_6/lib/xsd/codegen/moduledef.rb
blob: 744af2ff97f615d0b6e774446249591800f34d4e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# XSD4R - Generating module definition code
# Copyright (C) 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.

# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.


require 'xsd/codegen/gensupport'
require 'xsd/codegen/methoddef'
require 'xsd/codegen/commentdef'


module XSD
module CodeGen


class ModuleDef
  include GenSupport
  include CommentDef

  def initialize(name)
    @name = name
    @comment = nil
    @const = []
    @code = []
    @requirepath = []
    @methoddef = []
  end

  def def_require(path)
    @requirepath << path
  end

  def def_const(const, value)
    unless safeconstname?(const)
      raise ArgumentError.new("#{const} seems to be unsafe")
    end
    @const << [const, value]
  end

  def def_code(code)
    @code << code
  end

  def def_method(name, *params)
    add_method(MethodDef.new(name, *params) { yield if block_given? }, :public)
  end
  alias def_publicmethod def_method

  def def_protectedmethod(name, *params)
    add_method(MethodDef.new(name, *params) { yield if block_given? },
      :protected)
  end

  def def_privatemethod(name, *params)
    add_method(MethodDef.new(name, *params) { yield if block_given? }, :private)
  end

  def add_method(m, visibility = :public)
    @methoddef << [visibility, m]
  end

  def dump
    buf = ""
    unless @requirepath.empty?
      buf << dump_requirepath 
    end
    buf << dump_emptyline unless buf.empty?
    package = @name.split(/::/)[0..-2]
    buf << dump_package_def(package) unless package.empty?
    buf << dump_comment if @comment
    buf << dump_module_def
    spacer = false
    unless @const.empty?
      buf << dump_emptyline if spacer
      spacer = true
      buf << dump_const
    end
    unless @code.empty?
      buf << dump_emptyline if spacer
      spacer = true
      buf << dump_code
    end
    unless @methoddef.empty?
      buf << dump_emptyline if spacer
      spacer = true
      buf << dump_methods
    end
    buf << dump_module_def_end
    buf << dump_package_def_end(package) unless package.empty?
    buf.gsub(/^\s+$/, '')
  end

private

  def dump_requirepath
    format(
      @requirepath.collect { |path|
        %Q(require '#{path}')
      }.join("\n")
    )
  end

  def dump_const
    dump_static(
      @const.sort.collect { |var, value|
        %Q(#{var} = #{dump_value(value)})
      }.join("\n")
    )
  end

  def dump_code
    dump_static(@code.join("\n"))
  end

  def dump_static(str)
    format(str, 2)
  end

  def dump_methods
    methods = {}
    @methoddef.each do |visibility, method|
      (methods[visibility] ||= []) << method
    end
    str = ""
    [:public, :protected, :private].each do |visibility|
      if methods[visibility]
        str << "\n" unless str.empty?
        str << visibility.to_s << "\n\n" unless visibility == :public
        str << methods[visibility].collect { |m| format(m.dump, 2) }.join("\n")
      end
    end
    str
  end

  def dump_value(value)
    if value.respond_to?(:to_src)
      value.to_src
    else
      value
    end
  end

  def dump_package_def(package)
    format(package.collect { |ele| "module #{ele}" }.join("; ")) + "\n\n"
  end

  def dump_package_def_end(package)
    "\n\n" + format(package.collect { |ele| "end" }.join("; "))
  end

  def dump_module_def
    name = @name.to_s.split(/::/)
    format("module #{name.last}")
  end

  def dump_module_def_end
    format("end")
  end
end


end
end


if __FILE__ == $0
  require 'xsd/codegen/moduledef'
  include XSD::CodeGen
  m = ModuleDef.new("Foo::Bar::HobbitName")
  m.def_require("foo/bar")
  m.def_require("baz")
  m.comment = <<-EOD
    foo
    bar
    baz
  EOD
  m.def_method("foo") do
    <<-EOD
      foo.bar = 1
      baz.each do |ele|
        ele + 1
      end
    EOD
  end
  m.def_method("baz", "qux")
  #m.def_protectedmethod("aaa")
  m.def_privatemethod("bbb")
  puts m.dump
end