summaryrefslogtreecommitdiff
path: root/ruby_1_8_6/lib/xsd/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'ruby_1_8_6/lib/xsd/codegen')
-rw-r--r--ruby_1_8_6/lib/xsd/codegen/classdef.rb203
-rw-r--r--ruby_1_8_6/lib/xsd/codegen/commentdef.rb34
-rw-r--r--ruby_1_8_6/lib/xsd/codegen/gensupport.rb166
-rw-r--r--ruby_1_8_6/lib/xsd/codegen/methoddef.rb63
-rw-r--r--ruby_1_8_6/lib/xsd/codegen/moduledef.rb191
5 files changed, 657 insertions, 0 deletions
diff --git a/ruby_1_8_6/lib/xsd/codegen/classdef.rb b/ruby_1_8_6/lib/xsd/codegen/classdef.rb
new file mode 100644
index 0000000000..9eb1ce6607
--- /dev/null
+++ b/ruby_1_8_6/lib/xsd/codegen/classdef.rb
@@ -0,0 +1,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
diff --git a/ruby_1_8_6/lib/xsd/codegen/commentdef.rb b/ruby_1_8_6/lib/xsd/codegen/commentdef.rb
new file mode 100644
index 0000000000..c9493a1363
--- /dev/null
+++ b/ruby_1_8_6/lib/xsd/codegen/commentdef.rb
@@ -0,0 +1,34 @@
+# XSD4R - Generating comment 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'
+
+
+module XSD
+module CodeGen
+
+
+module CommentDef
+ include GenSupport
+
+ attr_accessor :comment
+
+private
+
+ def dump_comment
+ if /\A#/ =~ @comment
+ format(@comment)
+ else
+ format(@comment).gsub(/^/, '# ')
+ end
+ end
+end
+
+
+end
+end
diff --git a/ruby_1_8_6/lib/xsd/codegen/gensupport.rb b/ruby_1_8_6/lib/xsd/codegen/gensupport.rb
new file mode 100644
index 0000000000..1e85d3668f
--- /dev/null
+++ b/ruby_1_8_6/lib/xsd/codegen/gensupport.rb
@@ -0,0 +1,166 @@
+# XSD4R - Code generation support
+# Copyright (C) 2004, 2005 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.
+
+
+module XSD
+module CodeGen
+
+# from the file 'keywords' in 1.9.
+KEYWORD = {}
+%w(
+__LINE__
+__FILE__
+BEGIN
+END
+alias
+and
+begin
+break
+case
+class
+def
+defined?
+do
+else
+elsif
+end
+ensure
+false
+for
+if
+in
+module
+next
+nil
+not
+or
+redo
+rescue
+retry
+return
+self
+super
+then
+true
+undef
+unless
+until
+when
+while
+yield
+).each { |k| KEYWORD[k] = nil }
+
+module GenSupport
+ def capitalize(target)
+ target.sub(/^([a-z])/) { $1.tr!('[a-z]', '[A-Z]') }
+ end
+ module_function :capitalize
+
+ def uncapitalize(target)
+ target.sub(/^([A-Z])/) { $1.tr!('[A-Z]', '[a-z]') }
+ end
+ module_function :uncapitalize
+
+ def safeconstname(name)
+ safename = name.scan(/[a-zA-Z0-9_]+/).collect { |ele|
+ GenSupport.capitalize(ele)
+ }.join
+ if /^[A-Z]/ !~ safename or keyword?(safename)
+ safename = "C_#{safename}"
+ end
+ safename
+ end
+ module_function :safeconstname
+
+ def safeconstname?(name)
+ /\A[A-Z][a-zA-Z0-9_]*\z/ =~ name and !keyword?(name)
+ end
+ module_function :safeconstname?
+
+ def safemethodname(name)
+ safename = name.scan(/[a-zA-Z0-9_]+/).join('_')
+ safename = uncapitalize(safename)
+ if /^[a-z]/ !~ safename
+ safename = "m_#{safename}"
+ end
+ safename
+ end
+ module_function :safemethodname
+
+ def safemethodname?(name)
+ /\A[a-zA-Z_][a-zA-Z0-9_]*[=!?]?\z/ =~ name
+ end
+ module_function :safemethodname?
+
+ def safevarname(name)
+ safename = uncapitalize(name.scan(/[a-zA-Z0-9_]+/).join('_'))
+ if /^[a-z]/ !~ safename or keyword?(safename)
+ "v_#{safename}"
+ else
+ safename
+ end
+ end
+ module_function :safevarname
+
+ def safevarname?(name)
+ /\A[a-z_][a-zA-Z0-9_]*\z/ =~ name and !keyword?(name)
+ end
+ module_function :safevarname?
+
+ def keyword?(word)
+ KEYWORD.key?(word)
+ end
+ module_function :keyword?
+
+ def format(str, indent = nil)
+ str = trim_eol(str)
+ str = trim_indent(str)
+ if indent
+ str.gsub(/^/, " " * indent)
+ else
+ str
+ end
+ end
+
+private
+
+ def trim_eol(str)
+ str.collect { |line|
+ line.sub(/\r?\n\z/, "") + "\n"
+ }.join
+ end
+
+ def trim_indent(str)
+ indent = nil
+ str = str.collect { |line| untab(line) }.join
+ str.each do |line|
+ head = line.index(/\S/)
+ if !head.nil? and (indent.nil? or head < indent)
+ indent = head
+ end
+ end
+ return str unless indent
+ str.collect { |line|
+ line.sub(/^ {0,#{indent}}/, "")
+ }.join
+ end
+
+ def untab(line, ts = 8)
+ while pos = line.index(/\t/)
+ line = line.sub(/\t/, " " * (ts - (pos % ts)))
+ end
+ line
+ end
+
+ def dump_emptyline
+ "\n"
+ end
+end
+
+
+end
+end
diff --git a/ruby_1_8_6/lib/xsd/codegen/methoddef.rb b/ruby_1_8_6/lib/xsd/codegen/methoddef.rb
new file mode 100644
index 0000000000..15892fc5bf
--- /dev/null
+++ b/ruby_1_8_6/lib/xsd/codegen/methoddef.rb
@@ -0,0 +1,63 @@
+# XSD4R - Generating method 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/commentdef'
+
+
+module XSD
+module CodeGen
+
+
+class MethodDef
+ include GenSupport
+ include CommentDef
+
+ attr_accessor :definition
+
+ def initialize(name, *params)
+ unless safemethodname?(name)
+ raise ArgumentError.new("name '#{name}' seems to be unsafe")
+ end
+ @name = name
+ @params = params
+ @comment = nil
+ @definition = yield if block_given?
+ end
+
+ def dump
+ buf = ""
+ buf << dump_comment if @comment
+ buf << dump_method_def
+ buf << dump_definition if @definition and !@definition.empty?
+ buf << dump_method_def_end
+ buf
+ end
+
+private
+
+ def dump_method_def
+ if @params.empty?
+ format("def #{@name}")
+ else
+ format("def #{@name}(#{@params.join(", ")})")
+ end
+ end
+
+ def dump_method_def_end
+ format("end")
+ end
+
+ def dump_definition
+ format(@definition, 2)
+ end
+end
+
+
+end
+end
diff --git a/ruby_1_8_6/lib/xsd/codegen/moduledef.rb b/ruby_1_8_6/lib/xsd/codegen/moduledef.rb
new file mode 100644
index 0000000000..744af2ff97
--- /dev/null
+++ b/ruby_1_8_6/lib/xsd/codegen/moduledef.rb
@@ -0,0 +1,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