Welcome to the "trac"-ing site of soap4r!
[soap4r] [httpclient] [openpgp4u] [pkcs1] [logger] [csv] [vtr]

root/trunk/lib/xsd/codegen/classdef.rb

Revision 1915, 4.4 kB (checked in by nahi, 1 year ago)
  • added support for anonymous type. anonymous type is mapped to inner class. closes #355.
  • Property svn:eol-style set to native
  • Property svn:keywords set to author date id revision
Line 
1 # XSD4R - Generating class definition code
2 # Copyright (C) 2000-2007  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
3
4 # This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
5 # redistribute it and/or modify it under the same terms of Ruby's license;
6 # either the dual license version in 2003, or any later version.
7
8
9 require 'xsd/codegen/gensupport'
10 require 'xsd/codegen/moduledef'
11 require 'xsd/codegen/methoddef'
12
13
14 module XSD
15 module CodeGen
16
17
18 class ClassDef < ModuleDef
19   include GenSupport
20
21   def initialize(name, baseclass = nil)
22     super(name)
23     @baseclass = baseclass
24     @classvar = []
25     @attrdef = []
26   end
27
28   def def_classvar(var, value)
29     var = var.sub(/\A@@/, "")
30     unless safevarname?(var)
31       raise ArgumentError.new("#{var} seems to be unsafe")
32     end
33     @classvar << [var, value]
34   end
35
36   def def_attr(attrname, writable = true, varname = nil)
37     unless safevarname?(varname || attrname)
38       raise ArgumentError.new("#{varname || attrname} seems to be unsafe")
39     end
40     @attrdef << [attrname, writable, varname]
41   end
42
43   def dump
44     buf = ""
45     unless @requirepath.empty?
46       buf << dump_requirepath
47     end
48     buf << dump_emptyline unless buf.empty?
49     package = @name.split(/::/)[0..-2]
50     buf << dump_package_def(package) unless package.empty?
51     buf << dump_comment if @comment
52     buf << dump_class_def
53     spacer = false
54     unless @classvar.empty?
55       spacer = true
56       buf << dump_classvar
57     end
58     unless @const.empty?
59       buf << dump_emptyline if spacer
60       spacer = true
61       buf << dump_const
62     end
63     unless @innermodule.empty?
64       buf << dump_emptyline # always add 1 empty line
65       spacer = true
66       buf << dump_innermodule
67     end
68     unless @code.empty?
69       buf << dump_emptyline if spacer
70       spacer = true
71       buf << dump_code
72     end
73     unless @attrdef.empty?
74       buf << dump_emptyline if spacer
75       spacer = true
76       buf << dump_attributes
77     end
78     unless @methoddef.empty?
79       buf << dump_emptyline if spacer
80       spacer = true
81       buf << dump_methods
82     end
83     buf << dump_class_def_end
84     buf << dump_package_def_end(package) unless package.empty?
85     buf.gsub(/^\s+$/, '')
86   end
87
88 private
89
90   def dump_class_def
91     name = @name.to_s.split(/::/)
92     if @baseclass
93       format("class #{name.last} < #{@baseclass}")
94     else
95       format("class #{name.last}")
96     end
97   end
98
99   def dump_class_def_end
100     str = format("end")
101   end
102
103   def dump_classvar
104     dump_static(
105       @classvar.collect { |var, value|
106         %Q(@@#{var.sub(/^@@/, "")} = #{dump_value(value)})
107       }.join("\n")
108     )
109   end
110
111   def dump_attributes
112     str = ""
113     @attrdef.each do |attrname, writable, varname|
114       varname ||= attrname
115       if attrname == varname
116         str << format(dump_accessor(attrname, writable), 2)
117       end
118     end
119     @attrdef.each do |attrname, writable, varname|
120       varname ||= attrname
121       if attrname != varname
122         str << "\n" unless str.empty?
123         str << format(dump_attribute(attrname, writable, varname), 2)
124       end
125     end
126     str
127   end
128
129   def dump_accessor(attrname, writable)
130     if writable
131       "attr_accessor :#{attrname}"
132     else
133       "attr_reader :#{attrname}"
134     end
135   end
136
137   def dump_attribute(attrname, writable, varname)
138     str = nil
139     mr = MethodDef.new(attrname)
140     mr.definition = "@#{varname}"
141     str = mr.dump
142     if writable
143       mw = MethodDef.new(attrname + "=", 'value')
144       mw.definition = "@#{varname} = value"
145       str << "\n" + mw.dump
146     end
147     str
148   end
149 end
150
151
152 end
153 end
154
155
156 if __FILE__ == $0
157   require 'xsd/codegen/classdef'
158   include XSD::CodeGen
159   c = ClassDef.new("Foo::Bar::HobbitName", String)
160   c.def_require("foo/bar")
161   c.comment = <<-EOD
162       foo
163     bar
164       baz
165   EOD
166   c.def_const("FOO", 1)
167   c.def_classvar("@@foo", "var".dump)
168   c.def_classvar("baz", "1".dump)
169   c.def_attr("Foo", true, "foo")
170   c.def_attr("bar")
171   c.def_attr("baz", true)
172   c.def_attr("Foo2", true, "foo2")
173   c.def_attr("foo3", false, "foo3")
174   c.def_method("foo") do
175     <<-EOD
176         foo.bar = 1
177 \tbaz.each do |ele|
178 \t  ele
179         end
180     EOD
181   end
182   c.def_method("baz", "qux") do
183     <<-EOD
184       [1, 2, 3].each do |i|
185         p i
186       end
187     EOD
188   end
189
190   m = MethodDef.new("qux", "quxx", "quxxx") do
191     <<-EOD
192     p quxx + quxxx
193     EOD
194   end
195   m.comment = "hello world\n123"
196   c.add_method(m)
197   c.def_code <<-EOD
198     Foo.new
199     Bar.z
200   EOD
201   c.def_code <<-EOD
202     Foo.new
203     Bar.z
204   EOD
205   c.def_privatemethod("foo", "baz", "*arg", "&block")
206
207   puts c.dump
208 end
Note: See TracBrowser for help on using the browser.