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

IndexOutOfBoundsException while rewriting #27

Open
ftomassetti opened this issue Sep 17, 2013 · 1 comment
Open

IndexOutOfBoundsException while rewriting #27

ftomassetti opened this issue Sep 17, 2013 · 1 comment

Comments

@ftomassetti
Copy link

I parsed this method and I was trying to regenerate the code with this code:

            sw = java.io.StringWriter.new
            rwv = org.jrubyparser.rewriter.ReWriteVisitor.new(sw,'')
            cbw = org.jrubyparser.rewriter.ClassBodyWriter.new(rwv,corr_node)
            cbw.write
            sw.to_string

This code works for thousand of methods but fail on a few.

The methods parsed and failed 1/2:

     def index
          @question = params[:q] || ""
          @question.strip!
          @all_words = params[:all_words] ? params[:all_words].present? : true
          @titles_only = params[:titles_only] ? params[:titles_only].present? : false

          projects_to_search =
            case params[:scope]
            when 'all'
              nil
            when 'my_projects'
              User.current.memberships.collect(&:project)
            when 'subprojects'
              @project ? (@project.self_and_descendants.active.all) : nil
            else
              @project
            end

          offset = nil
          begin; offset = params[:offset].to_time if params[:offset]; rescue; end

          # quick jump to an issue
          if (m = @question.match(/^#?(\d+)$/)) && (issue = Issue.visible.find_by_id(m[1].to_i))
            redirect_to issue_path(issue)
            return
          end

          @object_types = Redmine::Search.available_search_types.dup
          if projects_to_search.is_a? Project
            # don't search projects
            @object_types.delete('projects')
            # only show what the user is allowed to view
            @object_types = @object_types.select {|o| User.current.allowed_to?("view_#{o}".to_sym, projects_to_search)}
          end

          @scope = @object_types.select {|t| params[t]}
          @scope = @object_types if @scope.empty?

          # extract tokens from the question
          # eg. hello "bye bye" => ["hello", "bye bye"]
          @tokens = @question.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}).collect {|m| m.first.gsub(%r{(^\s*"\s*|\s*"\s*$)}, '')}
          # tokens must be at least 2 characters long
          @tokens = @tokens.uniq.select {|w| w.length > 1 }

          if [email protected]?
            # no more than 5 tokens to search for
            @tokens.slice! 5..-1 if @tokens.size > 5

            @results = []
            @results_by_type = Hash.new {|h,k| h[k] = 0}

            limit = 10
            @scope.each do |s|
              r, c = s.singularize.camelcase.constantize.search(@tokens, projects_to_search,
                :all_words => @all_words,
                :titles_only => @titles_only,
                :limit => (limit+1),
                :offset => offset,
                :before => params[:previous].nil?)
              @results += r
              @results_by_type[s] += c
            end
            @results = @results.sort {|a,b| b.event_datetime <=> a.event_datetime}
            if params[:previous].nil?
              @pagination_previous_date = @results[0].event_datetime if offset && @results[0]
              if @results.size > limit
                @pagination_next_date = @results[limit-1].event_datetime
                @results = @results[0, limit]
              end
            else
              @pagination_next_date = @results[-1].event_datetime if offset && @results[-1]
              if @results.size > limit
                @pagination_previous_date = @results[-(limit)].event_datetime
                @results = @results[-(limit), limit]
              end
            end
          else
            @question = ""
          end
          render :layout => false if request.xhr?
        end

methods 2/2:

  def pretty_title
        WikiPage.pretty_title(title)
  end

This is the exception I get:

String.java:695:in charAt': java.lang.StringIndexOutOfBoundsException: String index out of range: 1344 from ShortIfNodeReWriteVisitor.java:47:invisitNewlineNode'
from NewlineNode.java:65:in accept' from ReWriteVisitor.java:247:invisitNode'
from ReWriteVisitor.java:942:in printShortIfStatement' from ReWriteVisitor.java:968:invisitIfNode'
from IfNode.java:61:in accept' from ReWriteVisitor.java:247:invisitNode'
from ReWriteVisitor.java:1146:in visitNewlineNode' from NewlineNode.java:65:inaccept'
from ReWriteVisitor.java:247:in visitNode' from ReWriteVisitor.java:1569:invisitNodeInIndentation'
from ReWriteVisitor.java:1579:in visitWhenNode' from WhenNode.java:59:inaccept'
from ReWriteVisitor.java:247:in visitNode' from ReWriteVisitor.java:1581:invisitWhenNode'
from WhenNode.java:59:in accept' from ReWriteVisitor.java:247:invisitNode'
from ReWriteVisitor.java:1581:in visitWhenNode' from WhenNode.java:59:inaccept'
from ReWriteVisitor.java:247:in visitNode' from ReWriteVisitor.java:334:invisitAndPrintWithSeparator'
from ReWriteVisitor.java:420:in visitArrayNode' from ArrayNode.java:59:inaccept'
from ReWriteVisitor.java:247:in visitNode' from ReWriteVisitor.java:596:invisitCaseNode'
from CaseNode.java:74:in accept' from ReWriteVisitor.java:247:invisitNode'
from ReWriteVisitor.java:1602:in visitNewlineInParentheses' from ReWriteVisitor.java:900:inprintAsgnNode'
from ReWriteVisitor.java:1075:in visitLocalAsgnNode' from LocalAsgnNode.java:62:inaccept'
from ReWriteVisitor.java:247:in visitNode' from ReWriteVisitor.java:1146:invisitNewlineNode'
from NewlineNode.java:65:in accept' from ReWriteVisitor.java:247:invisitNode'
from ReWriteVisitor.java:255:in visitIter' from ReWriteVisitor.java:457:invisitBlockNode'
from BlockNode.java:54:in accept' from ReWriteVisitor.java:247:invisitNode'
from ReWriteVisitor.java:758:in printDefNode' from ReWriteVisitor.java:767:invisitDefnNode'
from DefnNode.java:52:in accept' from ReWriteVisitor.java:247:invisitNode'
from ReWriteVisitor.java:1146:in visitNewlineNode' from NewlineNode.java:65:inaccept'
from ReWriteVisitor.java:247:in visitNode' from ReWriteVisitor.java:1569:invisitNodeInIndentation'
from ClassBodyWriter.java:28:in write' from null:-1:ininvoke'
from DelegatingMethodAccessorImpl.java:43:in invoke' from Method.java:601:ininvoke'
from JavaMethod.java:440:in invokeDirectWithExceptionHandling' from JavaMethod.java:304:ininvokeDirect'
from InstanceMethodInvoker.java:52:in call' from CachingCallSite.java:134:incall'
from models_redundancy_calc.rb:43:in block_5$RUBY$model_handler' from models_redundancy_calc$block_5$RUBY$model_handler:-1:incall'
from CompiledBlock19.java:163:in yield' from CompiledBlock19.java:91:incall'
from Block.java:89:in call' from RubyProc.java:261:incall'
from RubyProc.java:249:in call19' from RubyProc$INVOKER$i$0$0$call19.gen:-1:incall'
from DynamicMethod.java:209:in call' from DynamicMethod.java:205:incall'
from CachingCallSite.java:168:in call' from models_redundancy_calc.rb:55:inblock_6$RUBY$model_handler'
from models_redundancy_calc$block_6$RUBY$model_handler:-1:in call' from CompiledBlock19.java:139:inyield'
from Block.java:130:in yield' from RubyArray.java:1606:ineachCommon'
from RubyArray.java:1613:in each' from RubyArray$INVOKER$i$0$0$each.gen:-1:incall'
from CachingCallSite.java:143:in callBlock' from CachingCallSite.java:154:incallIter'
from models_redundancy_calc.rb:49:in block_1$RUBY$model_handler' from models_redundancy_calc$block_1$RUBY$model_handler:-1:incall'
from CompiledBlock19.java:163:in yield' from CompiledBlock19.java:91:incall'
from Block.java:89:in call' from RubyProc.java:261:incall'
from RubyProc.java:249:in call19' from RubyProc$INVOKER$i$0$0$call19.gen:-1:incall'
from DynamicMethod.java:217:in call' from DynamicMethod.java:213:incall'
from CachingCallSite.java:202:in call' from CallTwoArgNode.java:59:ininterpret'
from NewlineNode.java:105:in interpret' from BlockNode.java:71:ininterpret'
from IfNode.java:118:in interpret' from NewlineNode.java:105:ininterpret'
from BlockNode.java:71:in interpret' from ASTInterpreter.java:75:inINTERPRET_METHOD'
from InterpretedMethod.java:290:in call' from DefaultMethod.java:228:incall'
from CachingCallSite.java:245:in `callBlock'

@enebo
Copy link
Member

enebo commented Oct 4, 2013

So I just looked at this and the wild thing is that in order to rewrite short if's (?:) you need to pass string source or original source. That seems rather sad. You currently are passing in '' which explains why when you hit a few constructs it blows up.

I have the beginnings of an AST annotator which adds all syntactical elements to the AST. Once that is done then rewriting will become 100% lexically equivalent to the original source. Unfortunately, I have not had time to complete this. I have added commands into the tree but not all syntactical elements (like ')').

So I will leave this open to remember to ping you when I am able to make more progress on the real fix.

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

2 participants