SexpProcessor
Parse protocol method definition to derive a Message specification.
Create a new MethodParser instance for method methodname of module modul. For eigenmethods set eigenclass to true, otherwise bad things will happen.
# File lib/protocol/method_parser/ruby_parser.rb, line 9 def initialize(modul, methodname, eigenclass = false) super() @method = Module === modul ? modul.instance_method(methodname) : modul.method(methodname) @complex = false @arity = @method.arity if @method.respond_to?(:parameters) parameters = @method.parameters @args, @arg_kinds = parameters.map do |kind, name| case kind when :req [ name, kind ] when :opt [ name, kind ] when :rest [ :"*#{name}", kind ] when :block [ :"&#{name}", kind ] end end.compact.transpose else raise NotImplementedError, "#{@method.class}#parameters as in ruby version >=1.9.2 is required" end @args ||= [] @arg_kinds ||= [] filename, lineno = @method.source_location if filename source = IO.readlines(filename) source = source[(lineno - 1)..-1].join current = 0 tree = nil while current = source.index('end', current) current += 3 begin tree = RubyParser.new.parse(source[0, current], filename) break rescue SyntaxError, Racc::ParseError end end ary = tree.to_a.flatten @complex = ary.flatten.any? { |node| [ :call, :fcall, :vcall ].include?(node) } if ary.index(:yield) and @arg_kinds.last != :block @args.push :'&block' @arg_kinds.push :block end end end
Create a new MethodParser instance for method methodname of module modul. For eigenmethods set eigenclass to true, otherwise bad things will happen.
# File lib/protocol/method_parser/parse_tree.rb, line 10 def initialize(modul, methodname, eigenclass = false) super() @method = Module === modul ? modul.instance_method(methodname) : modul.method(methodname) self.strict = false self.auto_shift_type = true @complex = false @first_defn = true @first_block = true @args = [] @arg_kinds = [] @arity = @method.arity parsed = ParseTree.new.parse_tree_for_method(modul, methodname, eigenclass) process parsed end
Returns the i-th argument (beginning with 0).
# File lib/protocol/method_parser/ruby_parser.rb, line 63 def arg(i) @args[i] end
(Not documented)
# File lib/protocol/method_parser/parse_tree.rb, line 36 def arg(i) @args[i] end
(Not documented)
# File lib/protocol/method_parser/parse_tree.rb, line 43 def arg_kind(i) @arg_kinds[i] end
Returns the i-th kind of an argument (beginning with 0).
# File lib/protocol/method_parser/ruby_parser.rb, line 71 def arg_kind(i) @arg_kinds[i] end
Return true if a block argument was detected.
# File lib/protocol/method_parser/ruby_parser.rb, line 85 def block_arg? @arg_kinds.last == :block end
Return true if a block argument was detected.
# File lib/protocol/method_parser/parse_tree.rb, line 57 def block_arg? @arg_kinds.last == :block end
Return true if this protocol method is a complex method, which ought to be called for checking conformance to the protocol.
# File lib/protocol/method_parser/parse_tree.rb, line 52 def complex? @complex end
Return true if this protocol method is a complex method, which ought to be called for checking conformance to the protocol.
# File lib/protocol/method_parser/ruby_parser.rb, line 80 def complex? @complex end
Process exp, but catch UnsupportedNodeError exceptions and ignore them.
# File lib/protocol/method_parser/parse_tree.rb, line 28 def process(exp) super rescue UnsupportedNodeError => ignore end
Remember the argument names in exp in the args attribute.
# File lib/protocol/method_parser/parse_tree.rb, line 73 def process_args(exp) @args.replace exp.select { |x| x.is_a? Symbol } @arg_kinds = @args.map { |a| a.to_s[0] == ?* ? :rest : :req } if block = exp.find { |x| x.is_a?(Array) and x.first == :block } lasgns = block[1..-1].transpose[1] i = args.size - 1 @args.reverse_each do |a| exp.first l = lasgns.last if a == l @arg_kinds[i] = :opt lasgns.pop end i -= 1 end end exp.clear s :dummy end
We only consider the first block in exp (can there be more than one?), and then try to figure out, if this is a complex method or not. Continue processing the exp tree after that.
# File lib/protocol/method_parser/parse_tree.rb, line 114 def process_block(exp) if @first_block @first_block = false @complex = exp.flatten.any? { |e| [ :call, :fcall, :vcall ].include?(e) } exp.each { |e| process e } end exp.clear s :dummy end
Remember if we encounter a block argument.
# File lib/protocol/method_parser/parse_tree.rb, line 94 def process_block_arg(exp) @args.push :"&#{exp.first}" @arg_kinds.push :block exp.clear s :dummy end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.