Yard does not work in JRuby =>9.1.3.0 #4363

Closed
petr666 opened this Issue Dec 6, 2016 · 5 comments

Projects

None yet

4 participants

@petr666
petr666 commented Dec 6, 2016

Since JRuby 9.1.3.0 yard stopped working. More precisely it is probably not able to align comments with actual elements. Same project, same version of yard, "documented" dropped from 100% to 28.57%. Also it started to print warning "Unknown tag @host", however there is no such tag in comments and this warning is generated based on commented instance variable within method implementation (therefore I guess there is some problem with comment alignment).
Everything is working as expected in JRuby 9.1.2.0 and older (including 1.7.x)

@headius
Member
headius commented Dec 6, 2016

Can you show us an example of the problem? I'm not a yard user.

@olleolleolle
Contributor
olleolleolle commented Dec 6, 2016 edited

Running the test suite of YARD makes JRuby 9.1.6.0 confused.

This works on JRuby 9.1.2.0 and fails on higher versions:

bundle exec rspec spec/code_objects/base_spec.rb:405

There's a bit of re-setting back to CLI defaults using some metaprogramming. Here's one test-case which fails on JRuby 9.1.6.0:

bundle exec rspec spec/templates/helpers/text_helper_spec.rb

https://github.com/lsegal/yard/blob/master/spec/templates/helpers/shared_signature_examples.rb

https://github.com/lsegal/yard/blob/master/lib/yard/options.rb#L188-L199

...FFFFFFFFFFFF.....

Failures:

  1. YARD::Templates::Helpers::TextHelper#signature it should behave like signature shows signature for private class method
    Failure/Error: expect(trim(signature(Registry.at('A.foo')))).to eq @results[:private_class]

    expected: "A.foo -> Object (private)"
    got: "A.foo -> Object"

    (compared using ==)
    Shared Example Group: "signature" called from ./spec/templates/helpers/text_helper_spec.rb:32

    ./spec/templates/helpers/shared_signature_examples.rb:31:in `block in (root)'

    ./spec/spec_helper.rb:127:in `block in (root)'

  2. YARD::Templates::Helpers::TextHelper#signature it should behave like signature shows return type for single type
    Failure/Error: expect(trim(signature(Registry.at('#foo')))).to eq @results[:single]

    expected: "root.foo -> String"
    got: "root.foo -> Object"

    (compared using ==)
    Shared Example Group: "signature" called from ./spec/templates/helpers/text_helper_spec.rb:32

    ./spec/templates/helpers/shared_signature_examples.rb:39:in `block in (root)'

    ./spec/spec_helper.rb:127:in `block in (root)'

  3. YARD::Templates::Helpers::TextHelper#signature it should behave like signature shows return type for 2 types
    Failure/Error: expect(trim(signature(Registry.at('#foo')))).to eq @results[:two_types]

    expected: "root.foo -> (String, Symbol)"
    got: "root.foo -> Object"

    (compared using ==)
    Shared Example Group: "signature" called from ./spec/templates/helpers/text_helper_spec.rb:32

    ./spec/templates/helpers/shared_signature_examples.rb:47:in `block in (root)'

    ./spec/spec_helper.rb:127:in `block in (root)'

  4. YARD::Templates::Helpers::TextHelper#signature it should behave like signature shows return type for 2 types over multiple tags
    Failure/Error: expect(trim(signature(Registry.at('#foo')))).to eq @results[:two_types_multitag]

    expected: "root.foo -> (String, Symbol)"
    got: "root.foo -> Object"

    (compared using ==)
    Shared Example Group: "signature" called from ./spec/templates/helpers/text_helper_spec.rb:32

    ./spec/templates/helpers/shared_signature_examples.rb:56:in `block in (root)'

    ./spec/spec_helper.rb:127:in `block in (root)'

  5. YARD::Templates::Helpers::TextHelper#signature it should behave like signature shows 'Type?' if return types are [Type, nil]
    Failure/Error: expect(trim(signature(Registry.at('#foo')))).to eq @results[:type_nil]

    expected: "root.foo -> Type?"
    got: "root.foo -> Object"

    (compared using ==)
    Shared Example Group: "signature" called from ./spec/templates/helpers/text_helper_spec.rb:32

    ./spec/templates/helpers/shared_signature_examples.rb:64:in `block in (root)'

    ./spec/spec_helper.rb:127:in `block in (root)'

  6. YARD::Templates::Helpers::TextHelper#signature it should behave like signature shows 'Type?' if return types are [Type, nil, nil] (extra nil)
    Failure/Error: expect(trim(signature(Registry.at('#foo')))).to eq @results[:type_nil]

    expected: "root.foo -> Type?"
    got: "root.foo -> Object"

    (compared using ==)
    Shared Example Group: "signature" called from ./spec/templates/helpers/text_helper_spec.rb:32

    ./spec/templates/helpers/shared_signature_examples.rb:73:in `block in (root)'

    ./spec/spec_helper.rb:127:in `block in (root)'

  7. YARD::Templates::Helpers::TextHelper#signature it should behave like signature shows 'Type+' if return types are [Type, Array]
    Failure/Error: expect(trim(signature(Registry.at('#foo')))).to eq @results[:type_array]

    expected: "root.foo -> Type+"
    got: "root.foo -> Object"

    (compared using ==)
    Shared Example Group: "signature" called from ./spec/templates/helpers/text_helper_spec.rb:32

    ./spec/templates/helpers/shared_signature_examples.rb:81:in `block in (root)'

    ./spec/spec_helper.rb:127:in `block in (root)'

  8. YARD::Templates::Helpers::TextHelper#signature it should behave like signature shows (Type, ...) for more than 2 return types
    Failure/Error: expect(trim(signature(Registry.at('#foo')))).to eq @results[:multitype]

    expected: "root.foo -> (Type, ...)"
    got: "root.foo -> Object"

    (compared using ==)
    Shared Example Group: "signature" called from ./spec/templates/helpers/text_helper_spec.rb:32

    ./spec/templates/helpers/shared_signature_examples.rb:90:in `block in (root)'

    ./spec/spec_helper.rb:127:in `block in (root)'

  9. YARD::Templates::Helpers::TextHelper#signature it should behave like signature shows (void) for @return [void] by default
    Failure/Error: expect(trim(signature(Registry.at('#foo')))).to eq @results[:void]

    expected: "root.foo -> void"
    got: "root.foo -> Object"

    (compared using ==)
    Shared Example Group: "signature" called from ./spec/templates/helpers/text_helper_spec.rb:32

    ./spec/templates/helpers/shared_signature_examples.rb:98:in `block in (root)'

    ./spec/spec_helper.rb:127:in `block in (root)'

  10. YARD::Templates::Helpers::TextHelper#signature it should behave like signature does not show return for @return [void] if :hide_void_return is true
    Failure/Error: expect(trim(signature(Registry.at('#foo')))).to eq @results[:hide_void]

    expected: "root.foo"
    got: "root.foo -> Object"

    (compared using ==)
    Shared Example Group: "signature" called from ./spec/templates/helpers/text_helper_spec.rb:32

    ./spec/templates/helpers/shared_signature_examples.rb:107:in `block in (root)'

    ./spec/spec_helper.rb:127:in `block in (root)'

  11. YARD::Templates::Helpers::TextHelper#signature it should behave like signature shows block for method with yield
    Failure/Error: expect(trim(signature(Registry.at('#foo')))).to eq @results[:block]

    expected: "root.foo {|a, b, c| ... } -> Object"
    got: "root.foo {|(a, b, c)| ... } -> Object"

    (compared using ==)
    Shared Example Group: "signature" called from ./spec/templates/helpers/text_helper_spec.rb:32

    ./spec/templates/helpers/shared_signature_examples.rb:114:in `block in (root)'

    ./spec/spec_helper.rb:127:in `block in (root)'

  12. YARD::Templates::Helpers::TextHelper#signature it should behave like signature uses regular return tag if the @overload is empty
    Failure/Error: if !meth.tag(:return) && meth.tag(:overload) && meth.tag(:overload).tag(:return)

    NoMethodError:
    undefined method `tag' for nil:NilClass
    Did you mean? tap
    Shared Example Group: "signature" called from ./spec/templates/helpers/text_helper_spec.rb:32

    ./lib/yard/templates/helpers/text_helper.rb:52:in `signature'

    ./spec/templates/helpers/text_helper_spec.rb:30:in `signature'

    ./spec/templates/helpers/shared_signature_examples.rb:124:in `block in (root)'

    ./spec/spec_helper.rb:127:in `block in (root)'

Finished in 2.44 seconds (files took 1.79 seconds to load)
20 examples, 12 failures

Failed examples:

rspec './spec/templates/helpers/text_helper_spec.rb[1:1:1:4]' # YARD::Templates::Helpers::TextHelper#signature it should behave like signature shows signature for private class method
rspec './spec/templates/helpers/text_helper_spec.rb[1:1:1:5]' # YARD::Templates::Helpers::TextHelper#signature it should behave like signature shows return type for single type
rspec './spec/templates/helpers/text_helper_spec.rb[1:1:1:6]' # YARD::Templates::Helpers::TextHelper#signature it should behave like signature shows return type for 2 types
rspec './spec/templates/helpers/text_helper_spec.rb[1:1:1:7]' # YARD::Templates::Helpers::TextHelper#signature it should behave like signature shows return type for 2 types over multiple tags
rspec './spec/templates/helpers/text_helper_spec.rb[1:1:1:8]' # YARD::Templates::Helpers::TextHelper#signature it should behave like signature shows 'Type?' if return types are [Type, nil]
rspec './spec/templates/helpers/text_helper_spec.rb[1:1:1:9]' # YARD::Templates::Helpers::TextHelper#signature it should behave like signature shows 'Type?' if return types are [Type, nil, nil] (extra nil)
rspec './spec/templates/helpers/text_helper_spec.rb[1:1:1:10]' # YARD::Templates::Helpers::TextHelper#signature it should behave like signature shows 'Type+' if return types are [Type, Array]
rspec './spec/templates/helpers/text_helper_spec.rb[1:1:1:11]' # YARD::Templates::Helpers::TextHelper#signature it should behave like signature shows (Type, ...) for more than 2 return types
rspec './spec/templates/helpers/text_helper_spec.rb[1:1:1:12]' # YARD::Templates::Helpers::TextHelper#signature it should behave like signature shows (void) for @return [void] by default
rspec './spec/templates/helpers/text_helper_spec.rb[1:1:1:13]' # YARD::Templates::Helpers::TextHelper#signature it should behave like signature does not show return for @return [void] if :hide_void_return is true
rspec './spec/templates/helpers/text_helper_spec.rb[1:1:1:14]' # YARD::Templates::Helpers::TextHelper#signature it should behave like signature shows block for method with yield
rspec './spec/templates/helpers/text_helper_spec.rb[1:1:1:15]' # YARD::Templates::Helpers::TextHelper#signature it should behave like signature uses regular return tag if the @overload is empty

Hm. It seems it uses something called "thread-local store": Thread.current[:__yard_registry__] ||= clear. The clear method creates a new RegistryStore

@enebo
Member
enebo commented Dec 9, 2016

Woo even after narrowing this down with a bisect it took a while to get it:

nodes = [1]
nodes.each.with_index do |node, index|
  puts node
  nodes.insert index + 1, *[2, 3, 4] if node == 1
end

The if is just so this does not run forever. JRuby will only print 1 and MRI will print 1,2,3,4.

@headius headius closed this in 6a6383c Dec 9, 2016
@headius
Member
headius commented Dec 10, 2016

Closing the loop...

The problem was that the newish packed arrays had a couple block-receiving methods that did not handle modification during iteration. So if it was a one or two element array and you did ary = [1]; ary.each {|x| ary << 1} it would only run the block once, rather than as many times as there were elements inserted.

NOTE: Matz himself has said that modification during iteration is an undefined behavior, so technically we were not doing anything wrong here. However, the fix was simple so we went ahead with it. I do not recommend relying on this behavior.

@olleolleolle
Contributor

@petr666 This change is a fix for the test that I noted, but it will not make all of YARD's behavior work in JRuby.

I have set up a Travis build with YARD's test suite on my own Github fork. It shows lots of test failures on jruby-head. https://travis-ci.org/olleolleolle/yard/jobs/182802272

I recommend running yard using MRI until it can run its own test suite with JRuby.

@headius headius added this to the JRuby 9.1.7.0 milestone Dec 15, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment