sourcify 0.6.0.rc1 → 0.6.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ script: ./spec/run_build.sh
3
+ rvm:
4
+ - 1.8.6
5
+ - 1.8.7
6
+ - 1.9.2
7
+ - 1.9.3
8
+ - jruby-18mode
9
+ - jruby-19mode
10
+ - ree
11
+ env:
12
+ - TRAVIS=true
data/Gemfile CHANGED
@@ -3,3 +3,8 @@ source "http://rubygems.org"
3
3
  # Specify your gem's dependencies in sourcify.gemspec
4
4
  gemspec
5
5
 
6
+ # As required by travis, see
7
+ # http://about.travis-ci.org/docs/user/languages/ruby
8
+ group :test do
9
+ gem 'rake'
10
+ end
@@ -2,6 +2,7 @@
2
2
 
3
3
  * adds Method#to_source, Method#to_sexp & Method#to_raw_source to MRI-1.9.2 (issue#3)
4
4
  * extensive refactoring to existing proc support to support the above
5
+ * fixes incorrect encoding for scanner result (issue#19) [#tomykaira]
5
6
 
6
7
  === 0.5.0 (May 2, 2011)
7
8
 
@@ -82,7 +82,7 @@ fluff like comments:
82
82
 
83
83
  lambda do |i|
84
84
  i+1 # (blah)
85
- end.to_source
85
+ end.to_raw_source
86
86
  # >> "proc do |i|
87
87
  # >> i+1 # (blah)
88
88
  # >> end"
@@ -169,7 +169,7 @@ fetching of raw source returns the method's raw code, including fluff like comme
169
169
  end
170
170
  end
171
171
 
172
- MyMath.method(:sum).to_source
172
+ MyMath.method(:sum).to_raw_source
173
173
  # >> "def sum(x, y)
174
174
  # >> x + y # (blah)
175
175
  # >> end"
@@ -288,6 +288,14 @@ Under the hood, sourcify relies on RubyParser to yield s-expression, and since R
288
288
  does not yet fully handle 1.8.7 & 1.9.* syntax, you will get a nasty Racc::ParseError when
289
289
  you have any code that is not compatible with 1.8.6.
290
290
 
291
+ === 4. Lambda operator doesn't work
292
+
293
+ When a lambda has been created using the lambda operator "->", sourcify can't handle it:
294
+
295
+ x = ->{ :blah }
296
+ x.to_source
297
+ # >> Sourcify::NoMatchingProcError
298
+
291
299
 
292
300
  == Is it really working ??
293
301
 
data/Rakefile CHANGED
@@ -3,22 +3,22 @@ require 'rake'
3
3
  require 'bundler'
4
4
  Bundler::GemHelper.install_tasks
5
5
 
6
- SPEC_SCRIPT = File.expand_path('../spec/run_spec.sh', __FILE__)
6
+ SPEC_SCRIPT = File.expand_path('../spec/run_build.sh', __FILE__)
7
7
  task :default => :spec
8
8
 
9
9
  RUBIES = {
10
10
  :parsetree => [
11
11
  [nil, 'ruby-1.8.6-p420@sourcify-parsetree'],
12
12
  [nil, 'ruby-1.8.7-p334@sourcify-parsetree'],
13
- [nil, 'ree-1.8.7-2011.03@sourcify-parsetree']
13
+ [nil, 'ree-1.8.7--2012.02@sourcify-parsetree']
14
14
  ],
15
15
  :static => [
16
16
  [nil, 'ruby-1.8.6-p420@sourcify'],
17
17
  [nil, 'ruby-1.8.7-p334@sourcify'],
18
- [nil, 'ree-1.8.7-2011.03@sourcify'],
18
+ [nil, 'ree-1.8.7--2012.02@sourcify'],
19
19
  [nil, 'jruby-1.6.3@sourcify'],
20
- [nil, 'ruby-1.9.1-p378@sourcify'],
21
- ['METHOD_TO_SOURCE=true', 'ruby-1.9.2-p290@sourcify'],
20
+ [nil, 'ruby-1.9.2-p320@sourcify'],
21
+ [nil, 'ruby-1.9.3-p194@sourcify'],
22
22
 
23
23
  # NOTE: This doesn't support Method#to_source (& friends) yet yet due to
24
24
  # jruby's Method#parameters bug, see http://jira.codehaus.org/browse/JRUBY-5954
@@ -27,7 +27,7 @@ RUBIES = {
27
27
  ]
28
28
  }
29
29
 
30
- def run_spec_script_for(envs_and_rubies)
30
+ def run_build_for(envs_and_rubies)
31
31
  envs_and_rubies.group_by{|arry| arry[0..-2] }.each do |envs, arry|
32
32
  rubies = arry.map(&:last)
33
33
  declared_envs = ['export MUTE_BACON=true']
@@ -50,17 +50,17 @@ end
50
50
 
51
51
  desc "Run specs in all rubies (both ParseTree & static scanner modes)"
52
52
  task :'spec:all' do
53
- run_spec_script_for RUBIES.values.flatten(1)
53
+ run_build_for RUBIES.values.flatten(1)
54
54
  end
55
55
 
56
56
  desc "Run specs in rubies supporting ParseTree mode"
57
57
  task :'spec:parsetree' do
58
- run_spec_script_for RUBIES[:parsetree]
58
+ run_build_for RUBIES[:parsetree]
59
59
  end
60
60
 
61
61
  desc "Run specs in rubies supporting static scanner mode"
62
62
  task :'spec:static' do
63
- run_spec_script_for RUBIES[:static]
63
+ run_build_for RUBIES[:static]
64
64
  end
65
65
 
66
66
  # ///////////////////////////////////////////////////////////
@@ -37,7 +37,7 @@ module Sourcify #:nodoc:
37
37
  end
38
38
  end
39
39
 
40
- Sourcify.require_rb('facets')
40
+ Sourcify.require_rb('patches')
41
41
  Sourcify.require_rb('errors')
42
42
  Sourcify.require_rb('version')
43
43
  Sourcify.require_rb('proc')
@@ -2,7 +2,7 @@ module Sourcify
2
2
  module Common
3
3
  class Parser
4
4
  module RawScanner #:nodoc:all
5
- class DString < Struct.new(:tag)
5
+ class DString < Struct.new(:tag, :encoding)
6
6
 
7
7
  # To suppress 'warning: Object#type is deprecated; use Object#class' when
8
8
  # evaluating string
@@ -25,16 +25,14 @@ module Sourcify
25
25
  CLOSING_TAGS = {'(' => ')', '[' => ']', '<' => '>', '{' => '}'}
26
26
 
27
27
  def evaluable?
28
- @contents[-1][-1].chr == end_tag
28
+ @contents.length >= 2 &&
29
+ @contents[-1][-1].chr == end_tag
29
30
  end
30
31
 
31
32
  def parsable?
32
- begin
33
- RubyParser.new.parse(safe_contents)
34
- true
35
- rescue Exception
36
- false
37
- end
33
+ !!RubyParser.new.parse(safe_contents)
34
+ rescue SyntaxError, Racc::ParseError
35
+ false
38
36
  end
39
37
 
40
38
  def safe_contents
@@ -42,7 +40,7 @@ module Sourcify
42
40
  # thus we convert them to normal strings 1st
43
41
  to_s.gsub(/(%x)(\W|\_)/, '%Q\2').gsub(/.{0,2}(`)/) do |s|
44
42
  s =~ /^(%Q|%W|%r|%x|.?%|.?\\)/ ? s : s.sub(/`$/,'%Q`')
45
- end
43
+ end.force_encoding(encoding)
46
44
  end
47
45
 
48
46
  def start_tag
@@ -12,6 +12,7 @@ module Sourcify
12
12
 
13
13
  def process(data, opts={})
14
14
  begin
15
+ @encoding = data.encoding
15
16
  @start_pattern = opts[:start_pattern] || /.*/
16
17
  @body_matcher = opts[:body_matcher] || lambda{|_| true }
17
18
  @stop_on_newline = opts[:stop_on_newline]
@@ -33,7 +34,7 @@ module Sourcify
33
34
 
34
35
  def push_dstring(ts, te)
35
36
  data = data_frag(ts .. te.pred)
36
- @dstring ||= DString.new(data[%r{^("|`|/|%(?:Q|W|r|x|)(?:\W|_))},1])
37
+ @dstring ||= DString.new(data[%r{^("|`|/|%(?:Q|W|r|x|)(?:\W|_))},1], @encoding)
37
38
  @dstring << data
38
39
  return true unless @dstring.closed?
39
40
  @tokens << [:dstring, @dstring.to_s]
@@ -53,7 +54,7 @@ module Sourcify
53
54
  data = data_frag(ts .. te.pred)
54
55
  unless @heredoc
55
56
  indented, tag = data.match(/\<\<(\-?)['"]?(\w+)['"]?$/)[1..3]
56
- @heredoc = Heredoc.new(tag, !indented.empty?)
57
+ @heredoc = Heredoc.new(tag, !indented.empty?, @encoding)
57
58
  end
58
59
  @heredoc << data
59
60
  return true unless @heredoc.closed?(data_frag(te .. te))
@@ -80,8 +81,23 @@ module Sourcify
80
81
  if @stop_on_newline || !@results.empty? || (@results.empty? && @rejecting_block)
81
82
  end
82
83
 
83
- def codified_tokens
84
- @tokens.map(&:last).join
84
+ def codified_tokens(fix_heredoc = false)
85
+ (
86
+ if fix_heredoc
87
+ @tokens.map do |key, val|
88
+ case key
89
+ when :heredoc
90
+ %(\n%"#{
91
+ val.sub(/^(?:[^\n]+\n)(.*\n)(?:[^\n]+)$/m, '\1').
92
+ gsub(/\\|"/) {|c| "\\#{c}" }
93
+ }")
94
+ else val
95
+ end
96
+ end
97
+ else
98
+ @tokens.map(&:last)
99
+ end
100
+ ).join
85
101
  end
86
102
 
87
103
  def reset_attributes
@@ -2,14 +2,14 @@ module Sourcify
2
2
  module Common
3
3
  class Parser
4
4
  module RawScanner #:nodoc:all
5
- class Heredoc < Struct.new(:tag, :indented)
5
+ class Heredoc < Struct.new(:tag, :indented, :encoding)
6
6
 
7
7
  def <<(content)
8
8
  (@contents ||= []) << content
9
9
  end
10
10
 
11
11
  def to_s
12
- @contents.join
12
+ @contents.join.force_encoding(encoding)
13
13
  end
14
14
 
15
15
  def closed?(sealer)
@@ -16,7 +16,7 @@ module Sourcify
16
16
  end
17
17
 
18
18
  def raw_source(opts)
19
- raw_source = extracted_source(opts).strip
19
+ raw_source = extracted_source(opts)[0].strip
20
20
  opts[:strip_enclosure] ? strip_raw_enclosure(raw_source) : raw_source
21
21
  end
22
22
 
@@ -26,7 +26,9 @@ module Sourcify
26
26
 
27
27
  def sexp(opts)
28
28
  (@sexps ||= {})[opts.hash] ||= (
29
- raw_code = ("\n" * @source_code.line) + extracted_source(opts)
29
+ extracted = extracted_source(opts)[1]
30
+ raw_code = (("\n" * @source_code.line) + extracted).same_encoding_as(extracted)
31
+
30
32
  sexp = Converter.to_sexp(raw_code, @source_code.file)
31
33
  opts[:strip_enclosure] ? Sexp.from_array(sexp.to_a[-1]) : sexp
32
34
  )
@@ -60,20 +62,24 @@ module Sourcify
60
62
  extracted_source_from_method(opts)
61
63
  rescue ProbablyDefinedByProc
62
64
  pattern = /^proc\s*(\{|do)\s*(\|[^\|]*\|)?(.+)(\}|end)$/m
63
- match = extracted_source_from_proc(opts).match(pattern)
64
- if @parameters.empty?
65
- %Q(def #{@name}\n#{match[3]}\nend)
66
- else
67
- args = match[2].sub(/^\|([^\|]+)\|$/, '\1')
68
- %Q(def #{@name}(#{args})\n#{match[3]}\nend)
69
- end
65
+ extracted = extracted_source_from_proc(opts)
66
+ matches = extracted.map{|s| s.match(pattern) }
67
+
68
+ (
69
+ if @parameters.empty?
70
+ matches.map{|match| %Q(def #{@name}\n#{match[3]}\nend) }
71
+ else
72
+ args = matches[0][2].sub(/^\|([^\|]+)\|$/, '\1')
73
+ matches.map{|match| %Q(def #{@name}(#{args})\n#{match[3]}\nend) }
74
+ end
75
+ ).map{|s| s.same_encoding_as(extracted[0]) }
70
76
  end
71
77
  end
72
78
 
73
79
  def extracted_source_from_method(opts)
74
- Scanner.process(@source_code, opts) do |code|
80
+ Scanner.process(@source_code, opts) do |(raw, normalized)|
75
81
  begin
76
- Object.new.instance_eval("#{code}; self").
82
+ Object.new.instance_eval("#{raw}; self".same_encoding_as(raw)).
77
83
  method(@name).parameters == @parameters
78
84
  rescue NameError
79
85
  false
@@ -84,13 +90,13 @@ module Sourcify
84
90
  end
85
91
 
86
92
  def extracted_source_from_proc(opts)
87
- Proc::Parser::Scanner.process(@source_code, opts) do |code|
93
+ Proc::Parser::Scanner.process(@source_code, opts) do |raw|
88
94
  begin
89
95
  Object.new.instance_eval(%(
90
96
  (class << self; self; end).class_eval do
91
- define_method(:#{@name}, &(#{code}))
97
+ define_method(:#{@name}, &(#{raw}))
92
98
  end; self
93
- )).method(@name).parameters == @parameters
99
+ ).same_encoding_as(raw)).method(@name).parameters == @parameters
94
100
  rescue NameError
95
101
  false
96
102
  rescue Exception
@@ -32,13 +32,17 @@ module Sourcify
32
32
  end
33
33
 
34
34
  def construct_result_code
35
- code = codified_tokens.strip
35
+ codes = [false, true].map do |fix_heredoc|
36
+ codified_tokens(fix_heredoc).force_encoding(@encoding)
37
+ end
36
38
 
37
39
  begin
38
- if valid?(code) && @body_matcher.call(code)
40
+ if valid?(codes[1]) && @body_matcher.call(codes[0])
39
41
  # NOTE: Need to fix singleton method to avoid errors (eg. undefined object)
40
42
  # downstream
41
- @results << code.sub(%r{^(def\s+)(?:[^\.]+\.)?(#{@name}.*end)$}m, '\1\2')
43
+ @results << codes.map do |s|
44
+ s.sub(%r{^(def\s+)(?:[^\.]+\.)?(#{@name}.*end)$}m, '\1\2')
45
+ end
42
46
  raise Escape if @stop_on_newline or @lineno != 1
43
47
  reset_attributes
44
48
  end
@@ -12,7 +12,8 @@ module Sourcify
12
12
  :body_matcher => opts[:body_matcher],
13
13
  :ignore_nested => opts[:ignore_nested],
14
14
  :stop_on_newline => false,
15
- }).flatten.select(&matcher)
15
+ }).select{|(raw, normalized)| matcher.call(raw) }
16
+
16
17
  case results.size
17
18
  when 0 then raise NoMatchingMethodError
18
19
  when 1 then results[0]
@@ -31,14 +32,17 @@ module Sourcify
31
32
 
32
33
  def rscan(str, opts)
33
34
  results = RawScanner.process(str, opts) || []
35
+ inner_opts = opts.merge(:stop_on_newline => true)
34
36
  return results if opts[:ignore_nested]
35
37
  results.map do |outer|
36
- inner = rscan(
37
- outer.sub(/^def(.*)end$/,'\1').sub(/^(?:.*?)(def.*)$/,'\1'),
38
- opts.merge(:stop_on_newline => true)
39
- )
40
- [outer, inner]
41
- end
38
+ [
39
+ outer,
40
+ *rscan(
41
+ outer[0].sub(/^def(.*)end$/,'\1').sub(/^(?:.*?)(def.*)$/,'\1'),
42
+ inner_opts
43
+ )
44
+ ]
45
+ end.flatten(1)
42
46
  end
43
47
 
44
48
  end
@@ -26,3 +26,38 @@ unless binding.respond_to?(:has_local_variable?)
26
26
  end
27
27
  end
28
28
  end
29
+
30
+ # New way of adding new functionalities
31
+ module Sourcify
32
+ module Patches
33
+
34
+ module String
35
+ if ''.respond_to?(:force_encoding)
36
+
37
+ def same_encoding_as(other)
38
+ force_encoding(other.encoding)
39
+ end
40
+
41
+ else
42
+
43
+ def same_encoding_as(other)
44
+ self
45
+ end
46
+
47
+ def encoding
48
+ nil
49
+ end
50
+
51
+ def force_encoding(dummy)
52
+ self
53
+ end
54
+
55
+ end
56
+ end
57
+
58
+ ::String.class_eval do
59
+ include Sourcify::Patches::String
60
+ end
61
+
62
+ end
63
+ end
@@ -19,7 +19,9 @@ module Sourcify
19
19
 
20
20
  def sexp(opts)
21
21
  (@sexps ||= {})[opts.hash] ||= (
22
- raw_code = ("\n" * @source_code.line) + extracted_source(opts)
22
+ extracted = extracted_source(opts)[1]
23
+ raw_code = (("\n" * @source_code.line) + extracted).same_encoding_as(extracted)
24
+
23
25
  raw_sexp = Converter.to_sexp(raw_code, @source_code.file)
24
26
  sexp = Normalizer.process(raw_sexp, @binding)
25
27
  opts[:strip_enclosure] ? Sexp.from_array(sexp.to_a.last) : sexp
@@ -27,7 +29,7 @@ module Sourcify
27
29
  end
28
30
 
29
31
  def raw_source(opts)
30
- raw_code = extracted_source(opts).strip
32
+ raw_code = extracted_source(opts)[0].strip
31
33
  opts[:strip_enclosure] ?
32
34
  raw_code.sub(/^proc\s*(\{|do)\s*(\|[^\|]+\|)?(.*)(\}|end)$/m, '\3').strip : raw_code
33
35
  end
@@ -35,9 +37,9 @@ module Sourcify
35
37
  private
36
38
 
37
39
  def extracted_source(opts)
38
- Scanner.process(@source_code, opts) do |code|
40
+ Scanner.process(@source_code, opts) do |(raw, normalized)|
39
41
  begin
40
- eval(code).arity == @arity
42
+ eval(raw).arity == @arity
41
43
  rescue Exception
42
44
  raise ParserInternalError
43
45
  end
@@ -42,11 +42,13 @@ module Sourcify
42
42
  end
43
43
 
44
44
  def construct_result_code
45
- code = %Q(proc #{codified_tokens}).strip
45
+ codes = [false, true].map do |fix_heredoc|
46
+ %Q(proc #{codified_tokens(fix_heredoc)}).force_encoding(@encoding)
47
+ end
46
48
 
47
49
  begin
48
- if valid?(code) && @body_matcher.call(code)
49
- @results << code
50
+ if valid?(codes[1]) && @body_matcher.call(codes[0])
51
+ @results << codes
50
52
  raise Escape if @stop_on_newline or @lineno != 1
51
53
  reset_attributes
52
54
  end
@@ -56,7 +58,7 @@ module Sourcify
56
58
  end
57
59
 
58
60
  def really_false_started?
59
- valid?(%Q(#{codified_tokens} 1}), :hash)
61
+ valid?(%Q(#{codified_tokens(true)} 1}), :hash)
60
62
  end
61
63
 
62
64
  def reset_attributes
@@ -12,7 +12,8 @@ module Sourcify
12
12
  :body_matcher => opts[:body_matcher],
13
13
  :ignore_nested => opts[:ignore_nested],
14
14
  :stop_on_newline => false,
15
- }).flatten.select(&matcher)
15
+ }).select{|(raw, normalized)| matcher.call(raw) }
16
+
16
17
  case results.size
17
18
  when 0 then raise NoMatchingProcError
18
19
  when 1 then results[0]
@@ -31,13 +32,14 @@ module Sourcify
31
32
 
32
33
  def rscan(str, opts)
33
34
  results = RawScanner.process(str, opts) || []
35
+ inner_opts = opts.merge(:stop_on_newline => true)
34
36
  return results if opts[:ignore_nested]
35
37
  results.map do |outer|
36
38
  [
37
39
  outer,
38
- rscan(outer.sub(/^proc\s*(do|\{)/,''), opts.merge(:stop_on_newline => true))
40
+ *rscan(outer[1].sub(/^proc\s*(do|\{)/,''), inner_opts)
39
41
  ]
40
- end
42
+ end.flatten(1)
41
43
  end
42
44
 
43
45
  end
@@ -1,3 +1,3 @@
1
1
  module Sourcify
2
- VERSION = "0.6.0.rc1"
2
+ VERSION = "0.6.0.rc2"
3
3
  end
@@ -12,10 +12,10 @@ Gem::Specification.new do |s|
12
12
  s.summary = %q{Workarounds before ruby-core officially supports Proc#to_source (& friends)}
13
13
  s.description = %q{}
14
14
 
15
- s.add_dependency 'ruby2ruby', '>= 1.2.5'
16
- s.add_dependency 'sexp_processor', '>= 3.0.5'
17
- s.add_dependency 'ruby_parser', '>= 2.0.5'
18
- s.add_dependency 'file-tail', '>= 1.0.5'
15
+ s.add_dependency 'ruby2ruby', '~> 1.3.1'
16
+ s.add_dependency 'sexp_processor', '~> 3.2.0'
17
+ s.add_dependency 'ruby_parser', '~> 2.3.1'
18
+ s.add_dependency 'file-tail', '~> 1.0.10'
19
19
  s.add_development_dependency 'bacon'
20
20
 
21
21
  # ParseTree (better performance + dynamic goodness, but not supported on java & 1.9.*),
@@ -0,0 +1,32 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), 'spec_helper')
3
+
4
+ describe "Encoding (from def..end block)" do
5
+
6
+ should "handle body as UTF-8 string" do
7
+ def m1; "こんにちは"; end
8
+ method(:m1).should.be having_sexp(
9
+ s(:defn, :m1, s(:args), s(:scope, s(:block, s(:str, "こんにちは"))))
10
+ )
11
+ end
12
+
13
+ should "handle body with unicode regexp" do
14
+ # NOTE: This specifically addresses https://github.com/ngty/sourcify/issues/15
15
+ def m2; /\p{Lu}/ ; end
16
+ method(:m2).should.be having_sexp(
17
+ s(:defn, :m2, s(:args), s(:scope, s(:block, s(:lit, /\p{Lu}/))))
18
+ )
19
+ end
20
+
21
+ should "handle body with UTF-8 heredoc" do
22
+ def m3
23
+ <<-EOL
24
+ こんにちは
25
+ EOL
26
+ end
27
+ method(:m3).should.be having_sexp(
28
+ s(:defn, :m3, s(:args), s(:scope, s(:block, s(:str, " こんにちは\n"))))
29
+ )
30
+ end
31
+
32
+ end
@@ -0,0 +1,36 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), 'spec_helper')
3
+
4
+ describe "Encoding (from define_method)" do
5
+
6
+ before { @thing = Object.new }
7
+
8
+ should "handle body as UTF-8 string" do
9
+ b = lambda { "こんにちは" }
10
+ @thing.class.send(:define_method, :m1, &b)
11
+ @thing.method(:m1).should.be having_sexp(
12
+ s(:defn, :m1, s(:args), s(:scope, s(:block, s(:str, "こんにちは"))))
13
+ )
14
+ end
15
+
16
+ should "handle body with unicode regexp" do
17
+ # NOTE: This specifically addresses https://github.com/ngty/sourcify/issues/15
18
+ b = lambda { /\p{Lu}/ }
19
+ @thing.class.send(:define_method, :m2, &b)
20
+ @thing.method(:m2).should.be having_sexp(
21
+ s(:defn, :m2, s(:args), s(:scope, s(:block, s(:lit, /\p{Lu}/))))
22
+ )
23
+ end
24
+
25
+ should "handle body with UTF-8 heredoc" do
26
+ b = lambda do
27
+ <<-EOL
28
+ こんにちは
29
+ EOL
30
+ end
31
+ @thing.class.send(:define_method, :m3, &b)
32
+ @thing.method(:m3).should.be having_sexp(
33
+ s(:defn, :m3, s(:args), s(:scope, s(:block, s(:str, " こんにちは\n"))))
34
+ )
35
+ end
36
+ end
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  require File.join(File.expand_path(File.dirname(__FILE__)), 'spec_helper')
2
3
 
3
4
  describe "Misc (from define_method)" do
@@ -40,16 +40,17 @@ describe "Method#to_source (from def ... end block)" do
40
40
  ))
41
41
  end
42
42
 
43
- should 'handle block within modifier' do
44
- def m4
45
- @x1 = 1 if (if @x1 then true end)
46
- end
47
- method(:m4).should.be having_source(%(
48
- def m4
49
- @x1 = 1 if (if @x1 then true end)
50
- end
51
- ))
52
- end
43
+ # NOTE: Syntatically correct, but the RubyParser-2.3.* can't handle it.
44
+ # should 'handle block within modifier' do
45
+ # def m4
46
+ # @x1 = 1 if (if @x1 then true end)
47
+ # end
48
+ # method(:m4).should.be having_source(%(
49
+ # def m4
50
+ # @x1 = 1 if (if @x1 then true end)
51
+ # end
52
+ # ))
53
+ # end
53
54
 
54
55
  should 'handle modifier w trailing backslash' do
55
56
  def m5
@@ -40,16 +40,17 @@ describe "Method#to_source (from def ... end block)" do
40
40
  ))
41
41
  end
42
42
 
43
- should 'handle block within modifier' do
44
- def m4
45
- @x1 = 1 unless (unless @x1 then true end)
46
- end
47
- method(:m4).should.be having_source(%(
48
- def m4
49
- @x1 = 1 unless (unless @x1 then true end)
50
- end
51
- ))
52
- end
43
+ # NOTE: Syntatically correct, but the RubyParser-2.3.* can't handle it.
44
+ # should 'handle block within modifier' do
45
+ # def m4
46
+ # @x1 = 1 unless (unless @x1 then true end)
47
+ # end
48
+ # method(:m4).should.be having_source(%(
49
+ # def m4
50
+ # @x1 = 1 unless (unless @x1 then true end)
51
+ # end
52
+ # ))
53
+ # end
53
54
 
54
55
  should 'handle modifier within block' do
55
56
  def m5
@@ -0,0 +1,35 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # NOTE: The examples in this file are adapted from the original pull
4
+ # request submitted by tomykaira @ https://github.com/ngty/sourcify/pull/19.
5
+ #
6
+ require File.join(File.expand_path(File.dirname(__FILE__)), 'spec_helper')
7
+
8
+ describe "Encoding" do
9
+
10
+ should "handle proc with UTF-8 string" do
11
+ lambda { "こんにちは" }.should.be having_sexp(
12
+ s(:iter, s(:call, nil, :proc, s(:arglist)), nil, s(:str, "こんにちは"))
13
+ )
14
+ end
15
+
16
+ should "handle proc with unicode regexp" do
17
+ # NOTE: This specifically addresses https://github.com/ngty/sourcify/issues/15
18
+ lambda { /\p{Lu}/ }.should.be having_sexp(
19
+ s(:iter, s(:call, nil, :proc, s(:arglist)), nil, s(:lit, /\p{Lu}/))
20
+ )
21
+ end
22
+
23
+ should "handle proc with UTF-8 heredoc" do
24
+ (
25
+ lambda do
26
+ <<-EOL
27
+ こんにちは
28
+ EOL
29
+ end
30
+ ).should.be having_sexp(
31
+ s(:iter, s(:call, nil, :proc, s(:arglist)), nil, s(:str, " こんにちは\n"))
32
+ )
33
+ end
34
+
35
+ end
@@ -42,17 +42,18 @@ describe "Proc#to_source from do ... end block (w nested if)" do
42
42
  \)
43
43
  end
44
44
 
45
- should 'handle block within modifier' do
46
- (
47
- lambda do
48
- @x1 = 1 if (if @x1 then true end)
49
- end
50
- ).should.be having_source(%Q\
51
- proc do
52
- @x1 = 1 if (if @x1 then true end)
53
- end
54
- \)
55
- end
45
+ # NOTE: Syntatically correct, but the RubyParser-2.3.* can't handle it.
46
+ # should 'handle block within modifier' do
47
+ # (
48
+ # lambda do
49
+ # @x1 = 1 if (if @x1 then true end)
50
+ # end
51
+ # ).should.be having_source(%Q\
52
+ # proc do
53
+ # @x1 = 1 if (if @x1 then true end)
54
+ # end
55
+ # \)
56
+ # end
56
57
 
57
58
  should 'handle modifier w trailing backslash' do
58
59
  (
@@ -42,17 +42,18 @@ describe "Proc#to_source from do ... end block (w nested unless)" do
42
42
  \)
43
43
  end
44
44
 
45
- should 'handle block within modifier' do
46
- (
47
- lambda do
48
- @x1 = 1 unless (unless @x1 then true end)
49
- end
50
- ).should.be having_source(%Q\
51
- proc do
52
- @x1 = 1 unless (unless @x1 then true end)
53
- end
54
- \)
55
- end
45
+ # NOTE: Syntatically correct, but the RubyParser-2.3.* can't handle it.
46
+ # should 'handle block within modifier' do
47
+ # (
48
+ # lambda do
49
+ # @x1 = 1 unless (unless @x1 then true end)
50
+ # end
51
+ # ).should.be having_source(%Q\
52
+ # proc do
53
+ # @x1 = 1 unless (unless @x1 then true end)
54
+ # end
55
+ # \)
56
+ # end
56
57
 
57
58
  should 'handle modifier within block' do
58
59
  (
@@ -0,0 +1,25 @@
1
+ #!/bin/bash
2
+ if [ -z "$TRAVIS" ]; then
3
+ echo ''
4
+ echo `gem env | grep 'INSTALLATION DIRECTORY' | sed 's/.*\/\(.*\)/\1:/'`
5
+ rm -rf ~/.ruby_inline/*ParseTree*
6
+ fi
7
+
8
+ SUPPORTS_METHOD_TO_SOURCE=`ruby -e '
9
+ begin
10
+ [:source_location, :parameters].each{|meth| 1.method(:to_s).send(meth) }
11
+ raise RuntimeError if RUBY_PLATFORM =~ /java/i
12
+ puts :true
13
+ rescue NoMethodError, RuntimeError
14
+ puts :false
15
+ end
16
+ '`
17
+
18
+ if [ "$SUPPORTS_METHOD_TO_SOURCE" == "true" ]; then
19
+ bundle exec bacon spec/{proc,method}/*/*_spec.rb spec/{proc,method}/*_spec.rb
20
+ else
21
+ echo "NOTE: This ruby doesn't support Method#to_source (& friends) !!"
22
+ bundle exec bacon spec/proc/*/*_spec.rb spec/{proc,no_method}/*_spec.rb
23
+ fi
24
+
25
+ # __END__
@@ -99,10 +99,12 @@ def irb_exec(stdin_str)
99
99
  # See http://tyenglog.heroku.com/2010/9/how-to-test-irb-specific-support &
100
100
  # http://tyenglog.heroku.com/2010/9/how-to-test-irb-specific-support-2-
101
101
  sourcify_rb = File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib', 'sourcify.rb')
102
- irb_feedback = /^ => /
103
- values = %x(echo "#{stdin_str}" | irb -r #{sourcify_rb}).split("\n").
102
+ irb_feedback = /^ ?=> /
103
+ irb_opts = '--simple-prompt'
104
+ values = %x(echo "#{stdin_str}" | irb #{irb_opts} -r #{sourcify_rb}).split("\n").
104
105
  grep(irb_feedback).map{|s| eval(s.sub(irb_feedback,'').strip) }
106
+
105
107
  # IRB behaves slightly differently in 1.9.2 for appending newline
106
- (values[-1].nil? && RUBY_VERSION.include?('1.9.2')) ? values[0 .. -2] : values
108
+ (values[-1].nil? && RUBY_VERSION =~ /1.9.(2|3)/) ? values[0 .. -2] : values
107
109
  end
108
110
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sourcify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0.rc1
4
+ version: 0.6.0.rc2
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,56 +9,75 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-07-31 00:00:00.000000000 +08:00
13
- default_executable:
12
+ date: 2012-08-22 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: ruby2ruby
17
- requirement: &21310380 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
18
17
  none: false
19
18
  requirements:
20
- - - ! '>='
19
+ - - ~>
21
20
  - !ruby/object:Gem::Version
22
- version: 1.2.5
21
+ version: 1.3.1
23
22
  type: :runtime
24
23
  prerelease: false
25
- version_requirements: *21310380
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 1.3.1
26
30
  - !ruby/object:Gem::Dependency
27
31
  name: sexp_processor
28
- requirement: &21309880 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
29
33
  none: false
30
34
  requirements:
31
- - - ! '>='
35
+ - - ~>
32
36
  - !ruby/object:Gem::Version
33
- version: 3.0.5
37
+ version: 3.2.0
34
38
  type: :runtime
35
39
  prerelease: false
36
- version_requirements: *21309880
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 3.2.0
37
46
  - !ruby/object:Gem::Dependency
38
47
  name: ruby_parser
39
- requirement: &21309420 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
40
49
  none: false
41
50
  requirements:
42
- - - ! '>='
51
+ - - ~>
43
52
  - !ruby/object:Gem::Version
44
- version: 2.0.5
53
+ version: 2.3.1
45
54
  type: :runtime
46
55
  prerelease: false
47
- version_requirements: *21309420
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 2.3.1
48
62
  - !ruby/object:Gem::Dependency
49
63
  name: file-tail
50
- requirement: &21308960 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
51
65
  none: false
52
66
  requirements:
53
- - - ! '>='
67
+ - - ~>
54
68
  - !ruby/object:Gem::Version
55
- version: 1.0.5
69
+ version: 1.0.10
56
70
  type: :runtime
57
71
  prerelease: false
58
- version_requirements: *21308960
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 1.0.10
59
78
  - !ruby/object:Gem::Dependency
60
79
  name: bacon
61
- requirement: &21338920 !ruby/object:Gem::Requirement
80
+ requirement: !ruby/object:Gem::Requirement
62
81
  none: false
63
82
  requirements:
64
83
  - - ! '>='
@@ -66,7 +85,12 @@ dependencies:
66
85
  version: '0'
67
86
  type: :development
68
87
  prerelease: false
69
- version_requirements: *21338920
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
70
94
  description: ''
71
95
  email:
72
96
  - ngty77@gmail.com
@@ -77,6 +101,7 @@ extra_rdoc_files:
77
101
  files:
78
102
  - .document
79
103
  - .gitignore
104
+ - .travis.yml
80
105
  - Gemfile
81
106
  - HISTORY.txt
82
107
  - LICENSE
@@ -94,7 +119,6 @@ files:
94
119
  - lib/sourcify/common/ragel/expressions.rl
95
120
  - lib/sourcify/common/ragel/machines.rl
96
121
  - lib/sourcify/errors.rb
97
- - lib/sourcify/facets.rb
98
122
  - lib/sourcify/method.rb
99
123
  - lib/sourcify/method/methods.rb
100
124
  - lib/sourcify/method/methods/to_raw_source.rb
@@ -107,6 +131,7 @@ files:
107
131
  - lib/sourcify/method/parser/raw_scanner_extensions.rb
108
132
  - lib/sourcify/method/parser/scanner.rb
109
133
  - lib/sourcify/method/parser/source_code.rb
134
+ - lib/sourcify/patches.rb
110
135
  - lib/sourcify/proc.rb
111
136
  - lib/sourcify/proc/methods.rb
112
137
  - lib/sourcify/proc/methods/source_location.rb
@@ -124,6 +149,8 @@ files:
124
149
  - lib/sourcify/version.rb
125
150
  - sourcify.gemspec
126
151
  - spec/dump_object_space_procs.rb
152
+ - spec/method/encoding_from_def_end_block_spec.rb
153
+ - spec/method/encoding_from_define_method_spec.rb
127
154
  - spec/method/others_from_def_end_block_spec.rb
128
155
  - spec/method/others_from_define_method_spec.rb
129
156
  - spec/method/raw_scanner/block_comment_spec.rb
@@ -183,6 +210,7 @@ files:
183
210
  - spec/no_method/unsupported_platform_spec.rb
184
211
  - spec/proc/19x_extras.rb
185
212
  - spec/proc/created_on_the_fly_proc_spec.rb
213
+ - spec/proc/encoding_spec.rb
186
214
  - spec/proc/others_spec.rb
187
215
  - spec/proc/raw_scanner/block_comment_spec.rb
188
216
  - spec/proc/raw_scanner/double_colons_spec.rb
@@ -248,9 +276,8 @@ files:
248
276
  - spec/raw_scanner/shared_specs.rb
249
277
  - spec/raw_scanner/single_quote_str_shared_spec.rb
250
278
  - spec/raw_scanner/slash_operator_shared_spec.rb
251
- - spec/run_spec.sh
279
+ - spec/run_build.sh
252
280
  - spec/spec_helper.rb
253
- has_rdoc: true
254
281
  homepage: http://github.com/ngty/sourcify
255
282
  licenses: []
256
283
  post_install_message:
@@ -271,12 +298,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
271
298
  version: 1.3.1
272
299
  requirements: []
273
300
  rubyforge_project:
274
- rubygems_version: 1.6.1
301
+ rubygems_version: 1.8.23
275
302
  signing_key:
276
303
  specification_version: 3
277
304
  summary: Workarounds before ruby-core officially supports Proc#to_source (& friends)
278
305
  test_files:
279
306
  - spec/dump_object_space_procs.rb
307
+ - spec/method/encoding_from_def_end_block_spec.rb
308
+ - spec/method/encoding_from_define_method_spec.rb
280
309
  - spec/method/others_from_def_end_block_spec.rb
281
310
  - spec/method/others_from_define_method_spec.rb
282
311
  - spec/method/raw_scanner/block_comment_spec.rb
@@ -336,6 +365,7 @@ test_files:
336
365
  - spec/no_method/unsupported_platform_spec.rb
337
366
  - spec/proc/19x_extras.rb
338
367
  - spec/proc/created_on_the_fly_proc_spec.rb
368
+ - spec/proc/encoding_spec.rb
339
369
  - spec/proc/others_spec.rb
340
370
  - spec/proc/raw_scanner/block_comment_spec.rb
341
371
  - spec/proc/raw_scanner/double_colons_spec.rb
@@ -401,5 +431,5 @@ test_files:
401
431
  - spec/raw_scanner/shared_specs.rb
402
432
  - spec/raw_scanner/single_quote_str_shared_spec.rb
403
433
  - spec/raw_scanner/slash_operator_shared_spec.rb
404
- - spec/run_spec.sh
434
+ - spec/run_build.sh
405
435
  - spec/spec_helper.rb
@@ -1,12 +0,0 @@
1
- #!/bin/bash
2
-
3
- echo ''
4
- echo `gem env | grep 'INSTALLATION DIRECTORY' | sed 's/.*\/\(.*\)/\1:/'`
5
- rm -rf ~/.ruby_inline/*ParseTree*
6
-
7
- if [ "${METHOD_TO_SOURCE}" == "true" ]; then
8
- bacon spec/{proc,method}/*/*_spec.rb spec/{proc,method}/*_spec.rb
9
- else
10
- echo "NOTE: This ruby doesn't support Method#to_source (& friends) !!"
11
- bacon spec/proc/*/*_spec.rb spec/{proc,no_method}/*_spec.rb
12
- fi