Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Yard does not work in JRuby =>9.1.3.0 #4363

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

Yard does not work in JRuby =>9.1.3.0 #4363

petr666 opened this issue Dec 6, 2016 · 5 comments
Milestone

Comments

@petr666
Copy link

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
Copy link
Member

headius commented Dec 6, 2016

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

@olleolleolle
Copy link
Member

olleolleolle commented Dec 6, 2016

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
Copy link
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 as completed in 6a6383c Dec 9, 2016
@headius
Copy link
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
Copy link
Member

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants