looksee 1.0.0-universal-java-1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. data/CHANGELOG +14 -0
  2. data/LICENSE +22 -0
  3. data/README.markdown +161 -0
  4. data/Rakefile +10 -0
  5. data/ext/extconf.rb +9 -0
  6. data/ext/mri/1.9.2/debug.h +36 -0
  7. data/ext/mri/1.9.2/id.h +170 -0
  8. data/ext/mri/1.9.2/method.h +103 -0
  9. data/ext/mri/1.9.2/node.h +483 -0
  10. data/ext/mri/1.9.2/thread_pthread.h +27 -0
  11. data/ext/mri/1.9.2/vm_core.h +707 -0
  12. data/ext/mri/1.9.2/vm_opts.h +51 -0
  13. data/ext/mri/env-1.8.h +27 -0
  14. data/ext/mri/eval_c-1.8.h +27 -0
  15. data/ext/mri/mri.c +269 -0
  16. data/ext/mri/node-1.9.h +35 -0
  17. data/ext/rbx/rbx.c +13 -0
  18. data/lib/looksee.rb +5 -0
  19. data/lib/looksee/adapter.rb +10 -0
  20. data/lib/looksee/adapter/base.rb +100 -0
  21. data/lib/looksee/adapter/rubinius.rb +73 -0
  22. data/lib/looksee/clean.rb +122 -0
  23. data/lib/looksee/columnizer.rb +73 -0
  24. data/lib/looksee/core_ext.rb +59 -0
  25. data/lib/looksee/editor.rb +58 -0
  26. data/lib/looksee/help.rb +54 -0
  27. data/lib/looksee/inspector.rb +55 -0
  28. data/lib/looksee/jruby.jar +0 -0
  29. data/lib/looksee/lookup_path.rb +95 -0
  30. data/lib/looksee/rbx.bundle +0 -0
  31. data/lib/looksee/shortcuts.rb +3 -0
  32. data/lib/looksee/version.rb +11 -0
  33. data/lib/looksee/wirble_compatibility.rb +86 -0
  34. data/spec/adapter_spec.rb +546 -0
  35. data/spec/columnizer_spec.rb +52 -0
  36. data/spec/core_ext_spec.rb +41 -0
  37. data/spec/editor_spec.rb +128 -0
  38. data/spec/inspector_spec.rb +178 -0
  39. data/spec/lookup_path_spec.rb +84 -0
  40. data/spec/spec_helper.rb +25 -0
  41. data/spec/support/core_ext.rb +25 -0
  42. data/spec/support/temporary_classes.rb +102 -0
  43. data/spec/support/test_adapter.rb +72 -0
  44. data/spec/wirble_compatibility_spec.rb +116 -0
  45. metadata +158 -0
@@ -0,0 +1,100 @@
1
+ module Looksee
2
+ module Adapter
3
+ class Base
4
+ #
5
+ # Return the chain of classes and modules which comprise the
6
+ # object's method lookup path.
7
+ #
8
+ def lookup_modules(object)
9
+ modules = []
10
+ klass = internal_class(object)
11
+ while klass
12
+ modules << internal_class_to_module(klass)
13
+ klass = internal_superclass(klass)
14
+ end
15
+ modules
16
+ end
17
+
18
+ #
19
+ # Return a description of the given module.
20
+ #
21
+ # This is used for the module labels in the Inspector output.
22
+ #
23
+ def describe_module(mod)
24
+ num_brackets = 0
25
+ object = mod
26
+ while singleton_class?(object)
27
+ num_brackets += 1
28
+ object = singleton_instance(object)
29
+ end
30
+
31
+ if object.is_a?(Module)
32
+ description = module_name(object)
33
+ if description.empty?
34
+ description = "unnamed #{object.is_a?(Class) ? 'Class' : 'Module'}"
35
+ end
36
+ else
37
+ description = "#{module_name(object.class)} instance"
38
+ end
39
+
40
+ if num_brackets == 0
41
+ description
42
+ else
43
+ "#{'['*num_brackets}#{description}#{']'*num_brackets}"
44
+ end
45
+ end
46
+
47
+ def internal_superclass(klass)
48
+ raise NotImplementedError, "abstract"
49
+ end
50
+
51
+ def internal_class(object)
52
+ raise NotImplementedError, "abstract"
53
+ end
54
+
55
+ def internal_class_to_module(internal_class)
56
+ raise NotImplementedError, "abstract"
57
+ end
58
+
59
+ def internal_public_instance_methods(mod)
60
+ raise NotImplementedError, "abstract"
61
+ end
62
+
63
+ def internal_protected_instance_methods(mod)
64
+ raise NotImplementedError, "abstract"
65
+ end
66
+
67
+ def internal_private_instance_methods(mod)
68
+ raise NotImplementedError, "abstract"
69
+ end
70
+
71
+ def internal_undefined_instance_methods(mod)
72
+ raise NotImplementedError, "abstract"
73
+ end
74
+
75
+ def singleton_class?(object)
76
+ raise NotImplementedError, "abstract"
77
+ end
78
+
79
+ def singleton_instance(singleton_class)
80
+ raise NotImplementedError, "abstract"
81
+ end
82
+
83
+ def module_name(mod)
84
+ raise NotImplementedError, "abstract"
85
+ end
86
+
87
+ if RUBY_VERSION >= '1.9.0' || Looksee.ruby_engine == 'rbx'
88
+ def source_location(method)
89
+ method.is_a?(UnboundMethod) or
90
+ raise TypeError, "expected UnboundMethod, got #{method.class}"
91
+ method.source_location
92
+ end
93
+ else
94
+ def source_location(method)
95
+ raise NotImplementedError, 'abstract'
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,73 @@
1
+ require 'looksee/adapter/base'
2
+ require 'looksee/rbx'
3
+
4
+ module Looksee
5
+ module Adapter
6
+ class Rubinius < Base
7
+ def internal_superclass(klass)
8
+ klass.direct_superclass
9
+ end
10
+
11
+ def internal_class_to_module(internal_class)
12
+ if internal_class.is_a?(::Rubinius::IncludedModule)
13
+ internal_class.module
14
+ else
15
+ internal_class
16
+ end
17
+ end
18
+
19
+ def internal_public_instance_methods(mod)
20
+ mod.method_table.public_names
21
+ end
22
+
23
+ def internal_protected_instance_methods(mod)
24
+ mod.method_table.protected_names
25
+ end
26
+
27
+ def internal_private_instance_methods(mod)
28
+ mod.method_table.private_names
29
+ end
30
+
31
+ def internal_undefined_instance_methods(mod)
32
+ names = []
33
+ mod.method_table.each_entry do |entry|
34
+ names << entry.name if entry.visibility.equal?(:undef)
35
+ end
36
+ names
37
+ end
38
+
39
+ def singleton_class?(object)
40
+ object.is_a?(Class) && object.__metaclass_object__
41
+ end
42
+
43
+ def singleton_instance(singleton_class)
44
+ singleton_class?(singleton_class) or
45
+ raise TypeError, "expected singleton class, got #{singleton_class.class}"
46
+ singleton_class.__metaclass_object__
47
+ end
48
+
49
+ def module_name(mod)
50
+ mod.is_a?(Module) or
51
+ raise TypeError, "expected module, got #{mod.class}"
52
+ mod.__name__
53
+ end
54
+
55
+ def source_location(method)
56
+ method.is_a?(UnboundMethod) or
57
+ raise TypeError, "expected UnboundMethod, got #{method.class}"
58
+ source_location = method.source_location and
59
+ return source_location
60
+
61
+ # #source_location doesn't always work. If it returns nil, try
62
+ # a little harder.
63
+ case (executable = method.executable)
64
+ when ::Rubinius::BlockEnvironment::AsMethod
65
+ method = executable.instance_variable_get(:@block_env).method
66
+ [method.file.to_s, method.lines[1]]
67
+ when ::Rubinius::DelegatedMethod
68
+ executable.instance_variable_get(:@receiver).source_location
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,122 @@
1
+ require "rbconfig"
2
+
3
+ require 'set'
4
+
5
+ module Looksee
6
+ autoload :VERSION, 'looksee/version'
7
+ autoload :Adapter, 'looksee/adapter'
8
+ autoload :Columnizer, 'looksee/columnizer'
9
+ autoload :Editor, 'looksee/editor'
10
+ autoload :Help, 'looksee/help'
11
+ autoload :Inspector, 'looksee/inspector'
12
+ autoload :LookupPath, 'looksee/lookup_path'
13
+ autoload :WirbleCompatibility, 'looksee/wirble_compatibility'
14
+
15
+ class << self
16
+ #
17
+ # The default options passed to #ls.
18
+ #
19
+ # Default: <tt>[:public, :protected, :private, :undefined,
20
+ # :overridden]</tt>
21
+ #
22
+ attr_accessor :default_specifiers
23
+
24
+ #
25
+ # The width to use for displaying output, when not available in
26
+ # the COLUMNS environment variable.
27
+ #
28
+ # Default: 80
29
+ #
30
+ attr_accessor :default_width
31
+
32
+ #
33
+ # The default styles to use for the +inspect+ strings.
34
+ #
35
+ # This is a hash with keys:
36
+ #
37
+ # * :module
38
+ # * :public
39
+ # * :protected
40
+ # * :private
41
+ # * :undefined
42
+ # * :overridden
43
+ #
44
+ # The values are format strings. They should all contain a single
45
+ # "%s", which is where the name is inserted.
46
+ #
47
+ # Default:
48
+ #
49
+ # {
50
+ # :module => "\e[1;37m%s\e[0m", # white
51
+ # :public => "\e[1;32m%s\e[0m", # green
52
+ # :protected => "\e[1;33m%s\e[0m", # yellow
53
+ # :private => "\e[1;31m%s\e[0m", # red
54
+ # :undefined => "\e[1;34m%s\e[0m", # blue
55
+ # :overridden => "\e[1;30m%s\e[0m", # black
56
+ # }
57
+ #
58
+ attr_accessor :styles
59
+
60
+ #
61
+ # The editor command, used for Object#edit.
62
+ #
63
+ # This string should contain a "%f", which is replaced with the
64
+ # file name, and/or "%l" which is replaced with the line number. A
65
+ # "%%" is replaced with "%".
66
+ #
67
+ # If the LOOKSEE_EDITOR environment variable is set, it is used as
68
+ # the default. Otherwise, we use the following heuristic:
69
+ #
70
+ # If EDITOR is set, we use that. If it looks like vi, emacs, or
71
+ # textmate, we also append options to position the cursor on the
72
+ # appropriate line. If EDITOR is not set, we use "vi +%l %f".
73
+ #
74
+ attr_accessor :editor
75
+
76
+ #
77
+ # The interpreter adapter.
78
+ #
79
+ # Encapsulates the interpreter-specific functionality.
80
+ #
81
+ attr_accessor :adapter
82
+
83
+ #
84
+ # Wrapper around RUBY_ENGINE that's always defined.
85
+ #
86
+ attr_accessor :ruby_engine
87
+
88
+ #
89
+ # Show a quick reference.
90
+ #
91
+ def help
92
+ Help.new
93
+ end
94
+ end
95
+
96
+ self.default_specifiers = [:public, :protected, :private, :undefined, :overridden]
97
+ self.default_width = 80
98
+ self.styles = {
99
+ :module => "\e[1;37m%s\e[0m", # white
100
+ :public => "\e[1;32m%s\e[0m", # green
101
+ :protected => "\e[1;33m%s\e[0m", # yellow
102
+ :private => "\e[1;31m%s\e[0m", # red
103
+ :undefined => "\e[1;34m%s\e[0m", # blue
104
+ :overridden => "\e[1;30m%s\e[0m", # black
105
+ }
106
+ self.editor = ENV['LOOKSEE_EDITOR'] || ENV['EDITOR'] || 'vi'
107
+
108
+ if Object.const_defined?(:RUBY_ENGINE)
109
+ self.ruby_engine = RUBY_ENGINE
110
+ else
111
+ self.ruby_engine = 'ruby'
112
+ end
113
+
114
+ case ruby_engine
115
+ when 'jruby'
116
+ self.adapter = Adapter::JRuby.new
117
+ when 'rbx'
118
+ self.adapter = Adapter::Rubinius.new
119
+ else
120
+ self.adapter = Adapter::MRI.new
121
+ end
122
+ end
@@ -0,0 +1,73 @@
1
+ module Looksee
2
+ module Columnizer
3
+ class << self
4
+ #
5
+ # Arrange the given strings in columns, restricted to the given
6
+ # width. Smart enough to ignore content in terminal control
7
+ # sequences.
8
+ #
9
+ def columnize(strings, width)
10
+ return '' if strings.empty?
11
+
12
+ num_columns = 1
13
+ layout = [strings]
14
+ loop do
15
+ break if layout.first.length <= 1
16
+ next_layout = layout_in_columns(strings, num_columns + 1)
17
+ break if layout_width(next_layout) > width
18
+ layout = next_layout
19
+ num_columns += 1
20
+ end
21
+
22
+ pad_strings(layout)
23
+ rectangularize_layout(layout)
24
+ layout.transpose.map do |row|
25
+ ' ' + row.compact.join(' ')
26
+ end.join("\n") << "\n"
27
+ end
28
+
29
+ private # -----------------------------------------------------
30
+
31
+ def layout_in_columns(strings, num_columns)
32
+ strings_per_column = (strings.length / num_columns.to_f).ceil
33
+ (0...num_columns).map{|i| strings[i*strings_per_column...(i+1)*strings_per_column] || []}
34
+ end
35
+
36
+ def layout_width(layout)
37
+ widths = layout_column_widths(layout)
38
+ widths.inject(0){|sum, w| sum + w} + 2*layout.length
39
+ end
40
+
41
+ def layout_column_widths(layout)
42
+ layout.map do |column|
43
+ column.map{|string| display_width(string)}.max || 0
44
+ end
45
+ end
46
+
47
+ def display_width(string)
48
+ # remove terminal control sequences
49
+ string.gsub(/\e\[.*?m/, '').length
50
+ end
51
+
52
+ def pad_strings(layout)
53
+ widths = layout_column_widths(layout)
54
+ layout.each_with_index do |column, i|
55
+ column_width = widths[i]
56
+ column.each do |string|
57
+ padding = column_width - display_width(string)
58
+ string << ' '*padding
59
+ end
60
+ end
61
+ end
62
+
63
+ def rectangularize_layout(layout)
64
+ return if layout.length == 1
65
+ height = layout[0].length
66
+ layout[1..-1].each do |column|
67
+ column.length == height or
68
+ column[height - 1] = nil
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,59 @@
1
+ module Looksee
2
+ module ObjectMixin
3
+ #
4
+ # Return a Looksee::Inspector for this object.
5
+ #
6
+ # +args+ is an optional list of specifiers.
7
+ #
8
+ # * +:public+ - include public methods
9
+ # * +:protected+ - include public methods
10
+ # * +:private+ - include public methods
11
+ # * +:undefined+ - include public methods (see Module#undef_method)
12
+ # * +:overridden+ - include public methods
13
+ # * +:nopublic+ - include public methods
14
+ # * +:noprotected+ - include public methods
15
+ # * +:noprivate+ - include public methods
16
+ # * +:noundefined+ - include public methods (see Module#undef_method)
17
+ # * +:nooverridden+ - include public methods
18
+ # * a string - only include methods containing this string (may
19
+ # be used multiple times)
20
+ # * a regexp - only include methods matching this regexp (may
21
+ # be used multiple times)
22
+ #
23
+ # The default (if options is nil or omitted) is given by
24
+ # #default_lookup_path_options.
25
+ #
26
+ def ls(*args)
27
+ options = {:visibilities => Set[], :filters => Set[]}
28
+ (Looksee.default_specifiers + args).each do |arg|
29
+ case arg
30
+ when String, Regexp
31
+ options[:filters] << arg
32
+ when :public, :protected, :private, :undefined, :overridden
33
+ options[:visibilities].add(arg)
34
+ when :nopublic, :noprotected, :noprivate, :noundefined, :nooverridden
35
+ visibility = arg.to_s.sub(/\Ano/, '').to_sym
36
+ options[:visibilities].delete(visibility)
37
+ else
38
+ raise ArgumentError, "invalid specifier: #{arg.inspect}"
39
+ end
40
+ end
41
+ lookup_path = LookupPath.new(self)
42
+ Inspector.new(lookup_path, options)
43
+ end
44
+
45
+ #
46
+ # Open an editor at the named method's definition.
47
+ #
48
+ # Uses Looksee.editor to determine the editor command to run.
49
+ #
50
+ # Only works for methods for which file and line numbers are
51
+ # accessible.
52
+ #
53
+ def edit(name)
54
+ Editor.new(Looksee.editor).edit(self, name)
55
+ end
56
+ end
57
+
58
+ Object.send :include, ObjectMixin
59
+ end
@@ -0,0 +1,58 @@
1
+ require 'shellwords'
2
+
3
+ module Looksee
4
+ class Editor
5
+ def initialize(command)
6
+ @command = command.dup
7
+ infer_arguments
8
+ end
9
+
10
+ attr_reader :command
11
+
12
+ #
13
+ # Run the editor command for the +method_name+ of +object+.
14
+ #
15
+ def edit(object, method_name)
16
+ method = LookupPath.new(object).find(method_name.to_s) or
17
+ return
18
+ file, line = Looksee.adapter.source_location(method)
19
+ run(file, line) unless line.nil?
20
+ end
21
+
22
+ #
23
+ # Run the editor command for the given file and line.
24
+ #
25
+ def run(file, line)
26
+ system *command_for(file, line)
27
+ end
28
+
29
+ #
30
+ # Return the editor command for the given file and line.
31
+ #
32
+ # This is an array of the command with its arguments.
33
+ #
34
+ def command_for(file, line)
35
+ line = line.to_s
36
+ words = Shellwords.shellwords(command)
37
+ words.map! do |word|
38
+ word.gsub!(/%f/, file)
39
+ word.gsub!(/%l/, line)
40
+ word.gsub!(/%%/, '%')
41
+ word
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def infer_arguments
48
+ return if command =~ /%[fl]/
49
+
50
+ case command[/\S+/]
51
+ when /\A(?:g?vim?|.*macs|pico|nano)\z/
52
+ command << " +%l %f"
53
+ when 'mate'
54
+ command << " -l%l %f"
55
+ end
56
+ end
57
+ end
58
+ end