laplus 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9a5e4f5f7c618538833a7e28579077a1c3f27c88de1b1de0114cbf7cb9a00911
4
- data.tar.gz: bc30b116c3a1ec82a78dda212c1e213348f534219c536a6b9fa351e3a9c69c60
3
+ metadata.gz: 8d9a7313969eddd93b1d3cd04dcfe984903118ca5a59f569ceae4d192631df2b
4
+ data.tar.gz: 836c649f816ce8c5420cfd0780e2739c53348e77a845c252e3a9a6619bffbe09
5
5
  SHA512:
6
- metadata.gz: a154ffee6ca3d223e1af27ef3d85ae8004aa75690274a77ed8f027db5de0d8ab5c8c39194fabe03bf7ae5c2f90308c33f77372cc914ffd3a256f2a621e38b29f
7
- data.tar.gz: af8b184fa7a4a45136f011852e44f0d8d99f443eb88c730b2638c9ec5da5ea6ab42c336c4b29cf2765823d0c57094c45096ad3e517601b739b2d4dd73e0e695f
6
+ metadata.gz: 83e991aa35c6a7cd394ea56128b726b91555ecda9f9acdd27e60ef2539a3c2890552660f0ba318476b545d51436acb8b2185759bf4995f85a3f696885200b85e
7
+ data.tar.gz: 5855b09beef4e874107dff83f46aea02c0ea2ca866ab5cae5146cbced41d46ef0289eb6068f892e694963bf23864d76de980884ea916f0bff76fb3fad88e59da
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.7.0-preview1
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in laplus.gemspec
4
4
  gemspec
5
+
6
+ gem 'pry'
data/Gemfile.lock CHANGED
@@ -1,13 +1,18 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- laplus (0.1.0)
4
+ laplus (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ coderay (1.1.2)
10
+ method_source (0.9.2)
9
11
  minitest (5.11.3)
10
- rake (10.5.0)
12
+ pry (0.12.2)
13
+ coderay (~> 1.1.0)
14
+ method_source (~> 0.9.0)
15
+ rake (12.3.2)
11
16
 
12
17
  PLATFORMS
13
18
  ruby
@@ -16,7 +21,8 @@ DEPENDENCIES
16
21
  bundler (~> 2.0)
17
22
  laplus!
18
23
  minitest (~> 5.0)
19
- rake (~> 10.0)
24
+ pry
25
+ rake (~> 12.0)
20
26
 
21
27
  BUNDLED WITH
22
- 2.0.2
28
+ 2.1.0.pre.1
data/bin/pry ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "laplus"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ require "pry"
11
+ Pry.start
data/laplus.gemspec CHANGED
@@ -28,6 +28,6 @@ Gem::Specification.new do |spec|
28
28
  spec.require_paths = ["lib"]
29
29
 
30
30
  spec.add_development_dependency "bundler", "~> 2.0"
31
- spec.add_development_dependency "rake", "~> 10.0"
31
+ spec.add_development_dependency "rake", "~> 12.0"
32
32
  spec.add_development_dependency "minitest", "~> 5.0"
33
33
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Laplus
4
+ module Helper
5
+ class MethodHelper
6
+ def initialize(_method)
7
+ @_method = _method
8
+ end
9
+
10
+ def owner_singleton?
11
+ _method.owner.singleton_class?
12
+ end
13
+
14
+ def alias?
15
+ _method.original_name != _method.name
16
+ end
17
+
18
+ def singleton_method_of_module?
19
+ owner_singleton? && _method.receiver.kind_of?(Module)
20
+ end
21
+
22
+ def super_methods
23
+ _super_methods = [_method]
24
+ while super_method = _super_methods.last.super_method
25
+ _super_methods << super_method
26
+ end
27
+ _super_methods.reverse
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :_method
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Laplus
4
+ module Helper
5
+ autoload :MethodHelper, 'laplus/helper/method_helper'
6
+ end
7
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Laplus
4
+ module InspectStrategy
5
+ class Base
6
+ def initialize(inspector)
7
+ @inspector = inspector
8
+ end
9
+
10
+ def inspect
11
+ raise NotImplementedError
12
+ end
13
+
14
+ private
15
+
16
+ attr_reader :inspector
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Laplus
4
+ module InspectStrategy
5
+ class MethodStrategy < Base
6
+ # if with_super && method.respond_to?(:super_method) && method.super_method
7
+ # method.super_method.definition(with_super) + [MethodDefinition.definition(method)]
8
+ # else
9
+ # [MethodDefinition.definition(method)]
10
+ # end
11
+ def inspect
12
+ method = inspector.object
13
+ path, line = method.source_location
14
+
15
+ method_helper = Helper::MethodHelper.new(method)
16
+ super_methods = method_helper.super_methods
17
+
18
+ snippet = if method.source_location.nil?
19
+ '(defined in clang)'
20
+ elsif !File.exist?(path)
21
+ "defined at #{path}. but no such file."
22
+ else
23
+ Source.new(path).snip_code_at(line)
24
+ end
25
+
26
+ defined_class_text = if method_helper.singleton_method_of_module?
27
+ "#{method.receiver.class.name.downcase} #{method.receiver.name}" # ex. module Hoge
28
+ else
29
+ "#{method.owner.class.name.downcase} #{method.owner.name}" # ex. module Hoge
30
+ end
31
+
32
+ singleton_class_text = if method_helper.singleton_method_of_module?
33
+ ' class << self'
34
+ end
35
+
36
+ if method_helper.singleton_method_of_module?
37
+ def_snippet = snippet.split("\n").first
38
+ if def_snippet.match?(/def self./)
39
+ singleton_class_text = nil
40
+ end
41
+ end
42
+
43
+ desc_lines = []
44
+ desc_lines << ''
45
+ desc_lines << "#{path}:#{line}"
46
+ desc_lines << ''
47
+ desc_lines << 'super_methods:'
48
+ desc_lines += super_methods.map { |m| ' ' + m.inspect.match(/Method: (.+)>\z/).to_a[1] }
49
+ desc_lines << ''
50
+ desc_lines << defined_class_text
51
+ desc_lines << singleton_class_text unless singleton_class_text.nil?
52
+ desc_lines << UI::Indention.split(snippet).offset.indent(singleton_class_text.nil? ? 1 : 2).chomp
53
+ desc_lines << ' end' unless singleton_class_text.nil?
54
+ desc_lines << 'end'
55
+
56
+ desc_lines.join("\n")
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Laplus
4
+ module InspectStrategy
5
+ autoload :Base, 'laplus/inspect_strategy/base'
6
+ autoload :MethodStrategy, 'laplus/inspect_strategy/method_strategy'
7
+ end
8
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'laplus/inspect_strategy'
4
+
5
+ module Laplus
6
+ class Inspector
7
+ attr_reader :object
8
+
9
+ def initialize(object)
10
+ @object = object.freeze
11
+ end
12
+
13
+ def inspect
14
+ inspect_strategy.inspect
15
+ end
16
+
17
+ private
18
+
19
+ def inspect_strategy
20
+ case object
21
+ when Method, UnboundMethod
22
+ InspectStrategy::MethodStrategy.new(self)
23
+ when Proc
24
+ raise NotImplementedError
25
+ else
26
+ raise NotImplementedError
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ripper'
4
+
5
+ module Laplus
6
+ class Parser
7
+ def parse(code)
8
+ parser = Ripper.new(code)
9
+ parser.parse
10
+ !parser.error?
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Laplus
4
+ module IRBCommandExtension
5
+ def lp_def(method)
6
+ method.definition
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require 'pry'
5
+
6
+ Pry::Commands.block_command :lp_def, 'show arg method definition' do |method_str|
7
+ m = target.eval(method_str)
8
+ definition = m.definition
9
+ output.p definition
10
+ end
11
+ rescue LoadError
12
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'laplus/parser'
4
+
5
+ module Laplus
6
+ class Source
7
+ SnipTooManyLines = Class.new(Laplus::Error)
8
+
9
+ def initialize(path, reader = File, parser = Parser.new)
10
+ @path = path
11
+ @reader = reader
12
+ @parser = parser
13
+ end
14
+
15
+ def snip_code_at(line)
16
+ beginning_index = line - 1
17
+ ending_index = (beginning_index..).find do |index|
18
+ raise SnipTooManyLines if index - beginning_index > 100
19
+ code = lines[beginning_index..index].join
20
+ parser.parse(code)
21
+ end
22
+ snip_line_in(beginning_index..ending_index)
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :path, :reader, :parser
28
+
29
+ def lines
30
+ @lines ||= reader.readlines(path)
31
+ end
32
+
33
+ def snip_line_in(range)
34
+ lines[range].join
35
+ end
36
+ end
37
+ end
data/lib/laplus/ui.rb ADDED
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Laplus
4
+ module UI
5
+ class Indention
6
+ class << self
7
+ def split(text)
8
+ new(text.split("\n"))
9
+ end
10
+ end
11
+
12
+ INDENTION_REGEX = /\A(\s+)/
13
+
14
+ def initialize(lines, padding = ' ')
15
+ @lines = lines.clone(freeze: false)
16
+ @padding = padding.freeze
17
+ end
18
+
19
+ def offset
20
+ if (match = lines.first&.match(INDENTION_REGEX))
21
+ indention = match.captures.first
22
+ lines.map! { |line| line.delete_prefix(indention) }
23
+ end
24
+
25
+ self
26
+ end
27
+
28
+ def indent(depth)
29
+ indention = padding * depth
30
+ lines.map { |line| "#{indention}#{line}" }.join("\n")
31
+ end
32
+
33
+ private
34
+
35
+ attr_reader :lines, :padding
36
+ end
37
+ end
38
+ end
@@ -1,3 +1,3 @@
1
1
  module Laplus
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/laplus.rb CHANGED
@@ -1,6 +1,29 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "laplus/version"
2
4
 
3
5
  module Laplus
4
6
  class Error < StandardError; end
5
- # Your code goes here...
7
+
8
+ module Extension
9
+ def lp
10
+ Laplus::Inspector.new(self)
11
+ end
12
+ end
13
+
14
+ autoload :Inspector, 'laplus/inspector'
15
+ autoload :Source, 'laplus/source'
16
+
17
+ autoload :UI, 'laplus/ui'
18
+ autoload :Helper, 'laplus/helper'
19
+
20
+ autoload :IRBCommandExtension, 'laplus/repl_extensions/irb_command_extension'
6
21
  end
22
+
23
+ [Method, UnboundMethod].each do |klass|
24
+ klass.include Laplus::Extension
25
+ end
26
+
27
+ # require for side effects
28
+ require 'laplus/repl_extensions/pry_command_extension'
29
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: laplus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - nishisuke
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-07-11 00:00:00.000000000 Z
11
+ date: 2019-07-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '12.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '12.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -60,6 +60,7 @@ extensions: []
60
60
  extra_rdoc_files: []
61
61
  files:
62
62
  - ".gitignore"
63
+ - ".ruby-version"
63
64
  - ".travis.yml"
64
65
  - CHANGELOG.md
65
66
  - CODE_OF_CONDUCT.md
@@ -69,9 +70,21 @@ files:
69
70
  - README.md
70
71
  - Rakefile
71
72
  - bin/console
73
+ - bin/pry
72
74
  - bin/setup
73
75
  - laplus.gemspec
74
76
  - lib/laplus.rb
77
+ - lib/laplus/helper.rb
78
+ - lib/laplus/helper/method_helper.rb
79
+ - lib/laplus/inspect_strategy.rb
80
+ - lib/laplus/inspect_strategy/base.rb
81
+ - lib/laplus/inspect_strategy/method_strategy.rb
82
+ - lib/laplus/inspector.rb
83
+ - lib/laplus/parser.rb
84
+ - lib/laplus/repl_extensions/irb_command_extension.rb
85
+ - lib/laplus/repl_extensions/pry_command_extension.rb
86
+ - lib/laplus/source.rb
87
+ - lib/laplus/ui.rb
75
88
  - lib/laplus/version.rb
76
89
  homepage: https://github.com/nishisuke/laplus
77
90
  licenses:
@@ -95,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
108
  - !ruby/object:Gem::Version
96
109
  version: '0'
97
110
  requirements: []
98
- rubygems_version: 3.0.3
111
+ rubygems_version: 3.0.4
99
112
  signing_key:
100
113
  specification_version: 4
101
114
  summary: laplus