| 1 |
# XSD4R - Generating module 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/methoddef' |
|---|
| 11 |
require 'xsd/codegen/commentdef' |
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
module XSD |
|---|
| 15 |
module CodeGen |
|---|
| 16 |
|
|---|
| 17 |
|
|---|
| 18 |
class ModuleDef |
|---|
| 19 |
include GenSupport |
|---|
| 20 |
include CommentDef |
|---|
| 21 |
|
|---|
| 22 |
attr_reader :name |
|---|
| 23 |
attr_reader :innermodule |
|---|
| 24 |
|
|---|
| 25 |
def initialize(name) |
|---|
| 26 |
@name = name |
|---|
| 27 |
@comment = nil |
|---|
| 28 |
@const = [] |
|---|
| 29 |
@code = [] |
|---|
| 30 |
@requirepath = [] |
|---|
| 31 |
@methoddef = [] |
|---|
| 32 |
@innermodule = [] |
|---|
| 33 |
end |
|---|
| 34 |
|
|---|
| 35 |
def def_require(path) |
|---|
| 36 |
@requirepath << path |
|---|
| 37 |
end |
|---|
| 38 |
|
|---|
| 39 |
def def_const(const, value) |
|---|
| 40 |
unless safeconstname?(const) |
|---|
| 41 |
raise ArgumentError.new("#{const} seems to be unsafe") |
|---|
| 42 |
end |
|---|
| 43 |
@const << [const, value] |
|---|
| 44 |
end |
|---|
| 45 |
|
|---|
| 46 |
def def_code(code) |
|---|
| 47 |
@code << code |
|---|
| 48 |
end |
|---|
| 49 |
|
|---|
| 50 |
def def_method(name, *params) |
|---|
| 51 |
add_method(MethodDef.new(name, *params) { yield if block_given? }, :public) |
|---|
| 52 |
end |
|---|
| 53 |
alias def_publicmethod def_method |
|---|
| 54 |
|
|---|
| 55 |
def def_protectedmethod(name, *params) |
|---|
| 56 |
add_method(MethodDef.new(name, *params) { yield if block_given? }, |
|---|
| 57 |
:protected) |
|---|
| 58 |
end |
|---|
| 59 |
|
|---|
| 60 |
def def_privatemethod(name, *params) |
|---|
| 61 |
add_method(MethodDef.new(name, *params) { yield if block_given? }, :private) |
|---|
| 62 |
end |
|---|
| 63 |
|
|---|
| 64 |
def add_method(m, visibility = :public) |
|---|
| 65 |
@methoddef << [visibility, m] |
|---|
| 66 |
end |
|---|
| 67 |
|
|---|
| 68 |
def dump |
|---|
| 69 |
buf = "" |
|---|
| 70 |
unless @requirepath.empty? |
|---|
| 71 |
buf << dump_requirepath |
|---|
| 72 |
end |
|---|
| 73 |
buf << dump_emptyline unless buf.empty? |
|---|
| 74 |
package = @name.split(/::/)[0..-2] |
|---|
| 75 |
buf << dump_package_def(package) unless package.empty? |
|---|
| 76 |
buf << dump_comment if @comment |
|---|
| 77 |
buf << dump_module_def |
|---|
| 78 |
spacer = false |
|---|
| 79 |
unless @const.empty? |
|---|
| 80 |
buf << dump_emptyline if spacer |
|---|
| 81 |
spacer = true |
|---|
| 82 |
buf << dump_const |
|---|
| 83 |
end |
|---|
| 84 |
unless @innermodule.empty? |
|---|
| 85 |
buf << dump_emptyline # always add 1 empty line |
|---|
| 86 |
spacer = true |
|---|
| 87 |
buf << dump_innermodule |
|---|
| 88 |
end |
|---|
| 89 |
unless @code.empty? |
|---|
| 90 |
buf << dump_emptyline if spacer |
|---|
| 91 |
spacer = true |
|---|
| 92 |
buf << dump_code |
|---|
| 93 |
end |
|---|
| 94 |
unless @methoddef.empty? |
|---|
| 95 |
buf << dump_emptyline if spacer |
|---|
| 96 |
spacer = true |
|---|
| 97 |
buf << dump_methods |
|---|
| 98 |
end |
|---|
| 99 |
buf << dump_module_def_end |
|---|
| 100 |
buf << dump_package_def_end(package) unless package.empty? |
|---|
| 101 |
buf.gsub(/^\s+$/, '') |
|---|
| 102 |
end |
|---|
| 103 |
|
|---|
| 104 |
private |
|---|
| 105 |
|
|---|
| 106 |
def dump_requirepath |
|---|
| 107 |
format( |
|---|
| 108 |
@requirepath.collect { |path| |
|---|
| 109 |
%Q(require '#{path}') |
|---|
| 110 |
}.join("\n") |
|---|
| 111 |
) |
|---|
| 112 |
end |
|---|
| 113 |
|
|---|
| 114 |
def dump_const |
|---|
| 115 |
dump_static( |
|---|
| 116 |
@const.sort.collect { |var, value| |
|---|
| 117 |
%Q(#{var} = #{dump_value(value)}) |
|---|
| 118 |
}.join("\n") |
|---|
| 119 |
) |
|---|
| 120 |
end |
|---|
| 121 |
|
|---|
| 122 |
def dump_innermodule |
|---|
| 123 |
dump_static( |
|---|
| 124 |
@innermodule.collect { |moduledef| |
|---|
| 125 |
moduledef.dump |
|---|
| 126 |
}.join("\n") |
|---|
| 127 |
) |
|---|
| 128 |
end |
|---|
| 129 |
|
|---|
| 130 |
def dump_code |
|---|
| 131 |
dump_static(@code.join("\n")) |
|---|
| 132 |
end |
|---|
| 133 |
|
|---|
| 134 |
def dump_static(str) |
|---|
| 135 |
format(str, 2) |
|---|
| 136 |
end |
|---|
| 137 |
|
|---|
| 138 |
def dump_methods |
|---|
| 139 |
methods = {} |
|---|
| 140 |
@methoddef.each do |visibility, method| |
|---|
| 141 |
(methods[visibility] ||= []) << method |
|---|
| 142 |
end |
|---|
| 143 |
str = "" |
|---|
| 144 |
[:public, :protected, :private].each do |visibility| |
|---|
| 145 |
if methods[visibility] |
|---|
| 146 |
str << "\n" unless str.empty? |
|---|
| 147 |
str << visibility.to_s << "\n\n" unless visibility == :public |
|---|
| 148 |
str << methods[visibility].collect { |m| format(m.dump, 2) }.join("\n") |
|---|
| 149 |
end |
|---|
| 150 |
end |
|---|
| 151 |
str |
|---|
| 152 |
end |
|---|
| 153 |
|
|---|
| 154 |
def dump_value(value) |
|---|
| 155 |
if value.respond_to?(:to_src) |
|---|
| 156 |
value.to_src |
|---|
| 157 |
else |
|---|
| 158 |
value |
|---|
| 159 |
end |
|---|
| 160 |
end |
|---|
| 161 |
|
|---|
| 162 |
def dump_package_def(package) |
|---|
| 163 |
format(package.collect { |ele| "module #{ele}" }.join("; ")) + "\n\n" |
|---|
| 164 |
end |
|---|
| 165 |
|
|---|
| 166 |
def dump_package_def_end(package) |
|---|
| 167 |
"\n\n" + format(package.collect { |ele| "end" }.join("; ")) |
|---|
| 168 |
end |
|---|
| 169 |
|
|---|
| 170 |
def dump_module_def |
|---|
| 171 |
name = @name.to_s.split(/::/) |
|---|
| 172 |
format("module #{name.last}") |
|---|
| 173 |
end |
|---|
| 174 |
|
|---|
| 175 |
def dump_module_def_end |
|---|
| 176 |
format("end") |
|---|
| 177 |
end |
|---|
| 178 |
end |
|---|
| 179 |
|
|---|
| 180 |
|
|---|
| 181 |
end |
|---|
| 182 |
end |
|---|
| 183 |
|
|---|
| 184 |
|
|---|
| 185 |
if __FILE__ == $0 |
|---|
| 186 |
require 'xsd/codegen/moduledef' |
|---|
| 187 |
include XSD::CodeGen |
|---|
| 188 |
m = ModuleDef.new("Foo::Bar::HobbitName") |
|---|
| 189 |
m.def_require("foo/bar") |
|---|
| 190 |
m.def_require("baz") |
|---|
| 191 |
m.comment = <<-EOD |
|---|
| 192 |
foo |
|---|
| 193 |
bar |
|---|
| 194 |
baz |
|---|
| 195 |
EOD |
|---|
| 196 |
m.def_method("foo") do |
|---|
| 197 |
<<-EOD |
|---|
| 198 |
foo.bar = 1 |
|---|
| 199 |
baz.each do |ele| |
|---|
| 200 |
ele + 1 |
|---|
| 201 |
end |
|---|
| 202 |
EOD |
|---|
| 203 |
end |
|---|
| 204 |
m.def_method("baz", "qux") |
|---|
| 205 |
#m.def_protectedmethod("aaa") |
|---|
| 206 |
m.def_privatemethod("bbb") |
|---|
| 207 |
puts m.dump |
|---|
| 208 |
end |
|---|