summaryrefslogtreecommitdiff
path: root/ruby_1_8_6/lib/xsd/codegen/classdef.rb
blob: 9eb1ce660788c1f3da0f7dd42d9c2055bde10ff8 (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
192
193
194
195
196
197
198
199
200
201
202
203
# XSD4R - Generating class 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/moduledef'
require 'xsd/codegen/methoddef'


module XSD
module CodeGen


class ClassDef < ModuleDef
  include GenSupport

  def initialize(name, baseclass = nil)
    super(name)
    @baseclass = baseclass
    @classvar = []
    @attrdef = []
  end

  def def_classvar(var, value)
    var = var.sub(/\A@@/, "")
    unless safevarname?(var)
      raise ArgumentError.new("#{var} seems to be unsafe")
    end
    @classvar << [var, value]
  end

  def def_attr(attrname, writable = true, varname = nil)
    unless safevarname?(varname || attrname)
      raise ArgumentError.new("#{varname || attrname} seems to be unsafe")
    end
    @attrdef << [attrname, writable, varname]
  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_class_def
    spacer = false
    unless @classvar.empty?
      spacer = true
      buf << dump_classvar
    end
    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 @attrdef.empty?
      buf << dump_emptyline if spacer
      spacer = true
      buf << dump_attributes
    end
    unless @methoddef.empty?
      buf << dump_emptyline if spacer
      spacer = true
      buf << dump_methods
    end
    buf << dump_class_def_end
    buf << dump_package_def_end(package) unless package.empty?
    buf.gsub(/^\s+$/, '')
  end

private

  def dump_class_def
    name = @name.to_s.split(/::/)
    if @baseclass
      format("class #{name.last} < #{@baseclass}")
    else
      format("class #{name.last}")
    end
  end

  def dump_class_def_end
    str = format("end")
  end

  def dump_classvar
    dump_static(
      @classvar.collect { |var, value|
        %Q(@@#{var.sub(/^@@/, "")} = #{dump_value(value)})
      }.join("\n")
    )
  end

  def dump_attributes
    str = ""
    @attrdef.each do |attrname, writable, varname|
      varname ||= attrname
      if attrname == varname
        str << format(dump_accessor(attrname, writable), 2)
      end
    end
    @attrdef.each do |attrname, writable, varname|
      varname ||= attrname
      if attrname != varname
        str << "\n" unless str.empty?
        str << format(dump_attribute(attrname, writable, varname), 2)
      end
    end
    str
  end

  def dump_accessor(attrname, writable)
    if writable
      "attr_accessor :#{attrname}"
    else
      "attr_reader :#{attrname}"
    end
  end

  def dump_attribute(attrname, writable, varname)
    str = nil
    mr = MethodDef.new(attrname)
    mr.definition = "@#{varname}"
    str = mr.dump
    if writable
      mw = MethodDef.new(attrname + "=", 'value')
      mw.definition = "@#{varname} = value"
      str << "\n" + mw.dump
    end
    str
  end
end


end
end


if __FILE__ == $0
  require 'xsd/codegen/classdef'
  include XSD::CodeGen
  c = ClassDef.new("Foo::Bar::HobbitName", String)
  c.def_require("foo/bar")
  c.comment = <<-EOD
      foo
    bar
      baz
  EOD
  c.def_const("FOO", 1)
  c.def_classvar("@@foo", "var".dump)
  c.def_classvar("baz", "1".dump)
  c.def_attr("Foo", true, "foo")
  c.def_attr("bar")
  c.def_attr("baz", true)
  c.def_attr("Foo2", true, "foo2")
  c.def_attr("foo3", false, "foo3")
  c.def_method("foo") do
    <<-EOD
        foo.bar = 1
\tbaz.each do |ele|
\t  ele
        end
    EOD
  end
  c.def_method("baz", "qux") do
    <<-EOD
      [1, 2, 3].each do |i|
        p i
      end
    EOD
  end

  m = MethodDef.new("qux", "quxx", "quxxx") do
    <<-EOD
    p quxx + quxxx
    EOD
  end
  m.comment = "hello world\n123"
  c.add_method(m)
  c.def_code <<-EOD
    Foo.new
    Bar.z
  EOD
  c.def_code <<-EOD
    Foo.new
    Bar.z
  EOD
  c.def_privatemethod("foo", "baz", "*arg", "&block")

  puts c.dump
end