/tools/Ruby/lib/ruby/1.8/rdoc/parsers/parserfactory.rb

http://github.com/agross/netopenspace · Ruby · 99 lines · 35 code · 16 blank · 48 comment · 3 complexity · fbdbf7ba9154ffcea0925a05a115af0b MD5 · raw file

  1. require "rdoc/parsers/parse_simple"
  2. module RDoc
  3. # A parser is simple a class that implements
  4. #
  5. # #initialize(file_name, body, options)
  6. #
  7. # and
  8. #
  9. # #scan
  10. #
  11. # The initialize method takes a file name to be used, the body of the
  12. # file, and an RDoc::Options object. The scan method is then called
  13. # to return an appropriately parsed TopLevel code object.
  14. #
  15. # The ParseFactory is used to redirect to the correct parser given a filename
  16. # extension. This magic works because individual parsers have to register
  17. # themselves with us as they are loaded in. The do this using the following
  18. # incantation
  19. #
  20. #
  21. # require "rdoc/parsers/parsefactory"
  22. #
  23. # module RDoc
  24. #
  25. # class XyzParser
  26. # extend ParseFactory <<<<
  27. # parse_files_matching /\.xyz$/ <<<<
  28. #
  29. # def initialize(file_name, body, options)
  30. # ...
  31. # end
  32. #
  33. # def scan
  34. # ...
  35. # end
  36. # end
  37. # end
  38. #
  39. # Just to make life interesting, if we suspect a plain text file, we
  40. # also look for a shebang line just in case it's a potential
  41. # shell script
  42. module ParserFactory
  43. @@parsers = []
  44. Parsers = Struct.new(:regexp, :parser)
  45. # Record the fact that a particular class parses files that
  46. # match a given extension
  47. def parse_files_matching(regexp)
  48. @@parsers.unshift Parsers.new(regexp, self)
  49. end
  50. # Return a parser that can handle a particular extension
  51. def ParserFactory.can_parse(file_name)
  52. @@parsers.find {|p| p.regexp.match(file_name) }
  53. end
  54. # Alias an extension to another extension. After this call,
  55. # files ending "new_ext" will be parsed using the same parser
  56. # as "old_ext"
  57. def ParserFactory.alias_extension(old_ext, new_ext)
  58. parser = ParserFactory.can_parse("xxx.#{old_ext}")
  59. return false unless parser
  60. @@parsers.unshift Parsers.new(Regexp.new("\\.#{new_ext}$"), parser.parser)
  61. true
  62. end
  63. # Find the correct parser for a particular file name. Return a
  64. # SimpleParser for ones that we don't know
  65. def ParserFactory.parser_for(top_level, file_name, body, options, stats)
  66. # If no extension, look for shebang
  67. if file_name !~ /\.\w+$/ && body =~ %r{\A#!(.+)}
  68. shebang = $1
  69. case shebang
  70. when %r{env\s+ruby}, %r{/ruby}
  71. file_name = "dummy.rb"
  72. end
  73. end
  74. parser_description = can_parse(file_name)
  75. if parser_description
  76. parser = parser_description.parser
  77. else
  78. parser = SimpleParser
  79. end
  80. parser.new(top_level, file_name, body, options, stats)
  81. end
  82. end
  83. end