Skip to content

Commit

Permalink
white paper update (#581)
Browse files Browse the repository at this point in the history
  • Loading branch information
acheshkov authored Jul 30, 2020
1 parent 2132291 commit 1192345
Show file tree
Hide file tree
Showing 21 changed files with 1,508 additions and 663 deletions.
Binary file added wp/how_it_works_diagram_5.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
421 changes: 399 additions & 22 deletions wp/references.bib

Large diffs are not rendered by default.

425 changes: 425 additions & 0 deletions wp/sections/appendix.tex

Large diffs are not rendered by default.

36 changes: 0 additions & 36 deletions wp/sections/available_data.tex

This file was deleted.

28 changes: 28 additions & 0 deletions wp/sections/conclusion.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
Aibolit is a recommender system that helps improve the quality of Java classes.
The recommendations are learned from OSS Java projects using ML methods.
Aibolit provides ranked recommendations for each specific Java class,
which differs Aibolit from others style checkers and makes it unique.

Aibolit is an extendable system, allowing anyone to add new patterns and to
increase the training dataset and thus improve the precision and usefulness
of recommendations. Aibolit can also be used as a framework for analysis of
patterns and to decide whether any pattern, however subjective it is, is an anti- or a pro-pattern
with respect to a particular quality metric. As a complementary result,
we contribute a 100K+ dataset of patterns and metrics calculated for Java classes.

The first version of Aibolit is relatively simple and there is room
for improvement. If the anti-pattern has found, we recommend to fix all instances
of the pattern in the code. Instead, we may consider each specific occurrence of the pattern.
We may exploit its relative position in the structure of the code, rather than just count
the frequency. Moreover, Aibolit inspects each Java class independently. But
we might consider the relations between classes in the future. Furthermore,
Aibolit's prediction model relies on patterns only. In order to improve the model,
we have to think about additional features, for example, information about
project domain or used frameworks.

Aibolit is a firm step toward the next generation of tools to control
and improve software quality. It is a complementary tool for
product owners who already use tools to manage software quality.



126 changes: 0 additions & 126 deletions wp/sections/considered.tex

This file was deleted.

13 changes: 0 additions & 13 deletions wp/sections/empirical_results.tex

This file was deleted.

Loading

1 comment on commit 1192345

@0pdd
Copy link
Collaborator

@0pdd 0pdd commented on 1192345 Jul 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't able to retrieve PDD puzzles from the code base and submit them to GitHub. If you think that it's a bug on our side, please submit it to yegor256/0pdd:

set -x && set -e && set -o pipefail && cd /tmp/0pdd20200730-13-157q04g/cqfn/aibolit && pdd -v -f /tmp/20200730-32477-1bg98me [1]: + set -e + set -o pipefail + cd /tmp/0pdd20200730-13-157q04g/cqfn/aibolit + pdd -v -f /tmp/20200730-32477-1bg98me Found 10 lines in...

Please, copy and paste this stack trace to GitHub:

UserError
set -x && set -e && set -o pipefail && cd /tmp/0pdd20200730-13-157q04g/cqfn/aibolit && pdd -v -f /tmp/20200730-32477-1bg98me [1]:
+ set -e
+ set -o pipefail
+ cd /tmp/0pdd20200730-13-157q04g/cqfn/aibolit
+ pdd -v -f /tmp/20200730-32477-1bg98me

Found 10 lines in /tmp/0pdd20200730-13-157q04g/cqfn/aibolit/.pdd
My version is 0.20.5
Ruby version is 2.6.0 at x86_64-linux
Reading .
Excluding test/**/*
Excluding test/**/*
Excluding stubs/**/*
Excluding aibolit/metrics/halsteadvolume/target/**/*
Excluding scripts/target/**/*
224 file(s) found, 3338 excluded
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/binary_files/halstead.jar is a binary file (10595980 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/binary_files/model.pkl is a binary file (16409229 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/binary_files/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/utils/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/ast_framework/computed_fields_catalog/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/non_final_class/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/array_as_argument/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/private_static_method/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/nested_blocks/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/supermethod/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/many_primary_ctors/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/send_null/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/method_siblings/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/er_class/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/assert_in_code/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/public_static_method/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/nested_loop/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/protected_method/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/non_final_argument/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/bidirect_index/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/mutable_index/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/classic_setter/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/non_final_attribute/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/redundant_catch/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/string_concat/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/implements_multi/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/empty_rethrow/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/multiple_while/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/multiple_try/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/var_siblings/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/loop_outsider/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/var_decl_diff/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/return_null/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/force_type_casting_finder/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/var_middle/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/if_return_if_detection/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/assign_null_finder/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/instanceof/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/null_check/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/hybrid_constructor/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/method_chaining/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/joined_validation/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/patterns/partial_synchronized/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/local_methods_calls/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/cognitiveC/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/number_variables/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/entropy/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/maxDiameter/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/external_methods_called/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/spaces/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/lcom4/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/RFC/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/loc/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/fanout/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/mda/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/countLeaves/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/metrics/cc/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/aibolit/ml_pipeline/__init__.py is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/wp/sections/motivation.tex is a binary file (1 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/wp/sections/.gitkeep is a binary file (0 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/wp/how_it_works_diagram_5.jpg is a binary file (71972 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/wp/logo.png is a binary file (208813 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/logo.png is a binary file (208813 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/uml/recommendation_pipeline.png is a binary file (223568 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/uml/train_pipeline.png is a binary file (167130 bytes)
/tmp/0pdd20200730-13-157q04g/cqfn/aibolit/uml/classes_diagram.png is a binary file (190488 bytes)
Reading appveyor.yml...
Reading .gitignore...
Reading README.md...
Reading .gitattributes...
Reading MANIFEST.in...
Reading .rultor.yml...
Reading aibolit/types_decl.py...
Reading aibolit/__main__.py...
Reading aibolit/utils/lines.py...
Reading aibolit/utils/utils.py...
Reading aibolit/utils/ast_builder.py...
Reading aibolit/utils/encoding_detector.py...
Reading aibolit/utils/java_parser.py...
Reading aibolit/utils/scope_status.py...
Reading aibolit/utils/cfg_builder.py...
Reading aibolit/utils/filter.py...
Reading aibolit/utils/cohesiongraph.py...
Reading aibolit/config.py...
Reading aibolit/model/model.py...
Reading aibolit/model/stats.py...
Reading aibolit/ast_framework/ast.py...
Reading aibolit/ast_framework/computed_fields_catalog/nodes_filter.py...
Reading aibolit/ast_framework/computed_fields_catalog/standard_fields.py...
Reading aibolit/ast_framework/computed_fields_catalog/chained_fields.py...
Reading aibolit/ast_framework/ast_node.py...
Reading aibolit/ast_framework/_auxiliary_data.py...
Reading aibolit/ast_framework/java_class.py...
Reading aibolit/ast_framework/java_package.py...
Reading aibolit/ast_framework/java_class_method.py...
Reading aibolit/ast_framework/java_class_decomposition.py...
Reading aibolit/ast_framework/computed_fields_registry.py...
Reading aibolit/ast_framework/ast_node_type.py...
Reading aibolit/ast_framework/__init__.py...
Reading aibolit/ast_framework/java_class_field.py...
Reading aibolit/patterns/non_final_class/non_final_class.py...
Reading aibolit/patterns/array_as_argument/array_as_argument.py...
Reading aibolit/patterns/private_static_method/private_static_method.py...
Reading aibolit/patterns/nested_blocks/nested_blocks.py...
Reading aibolit/patterns/nested_blocks/README.md...
Reading aibolit/patterns/supermethod/supermethod.py...
Reading aibolit/patterns/many_primary_ctors/many_primary_ctors.py...
Reading aibolit/patterns/send_null/send_null.py...
Reading aibolit/patterns/send_null/readme.md...
Reading aibolit/patterns/method_siblings/method_siblings.py...
Reading aibolit/patterns/er_class/er_class.py...
Reading aibolit/patterns/assert_in_code/assert_in_code.py...
Reading aibolit/patterns/public_static_method/public_static_method.py...
Reading aibolit/patterns/nested_loop/nested_loop.py...
Reading aibolit/patterns/protected_method/protected_method.py...
Reading aibolit/patterns/non_final_argument/NonFinalArgumentCtor.java...
Reading aibolit/patterns/non_final_argument/non_final_argument.py...
Puzzle 146-4f2084fc 30/DEV at aibolit/patterns/non_final_argument/non_final_argument.py
Reading aibolit/patterns/non_final_argument/NonFinalArgumentMethod.java...
Reading aibolit/patterns/bidirect_index/bidirect_index.py...
Puzzle 139-732b1bcc 30/DEV at aibolit/patterns/bidirect_index/bidirect_index.py
Reading aibolit/patterns/mutable_index/mutable_index.py...
Puzzle 147-d9d6862a 30/DEV at aibolit/patterns/mutable_index/mutable_index.py
Reading aibolit/patterns/classic_setter/classic_setter.py...
Reading aibolit/patterns/non_final_attribute/non_final_attribute.py...
Reading aibolit/patterns/redundant_catch/redundant_catch.py...
Reading aibolit/patterns/string_concat/string_concat.py...
Reading aibolit/patterns/implements_multi/implements_multi.py...
Reading aibolit/patterns/empty_rethrow/empty_rethrow.py...
Reading aibolit/patterns/multiple_while/multiple_while.py...
Reading aibolit/patterns/multiple_try/multiple_try.py...
Reading aibolit/patterns/var_siblings/var_siblings.py...
Reading aibolit/patterns/loop_outsider/loop_outsider.py...
Reading aibolit/patterns/var_decl_diff/README.md...
Reading aibolit/patterns/var_decl_diff/var_decl_diff.py...
Reading aibolit/patterns/return_null/return_null.py...
Reading aibolit/patterns/force_type_casting_finder/force_type_casting_finder.py...
Reading aibolit/patterns/var_middle/README.md...
Reading aibolit/patterns/var_middle/var_middle.py...
Reading aibolit/patterns/if_return_if_detection/if_detection.py...
Reading aibolit/patterns/assign_null_finder/assign_null_finder.py...
Reading aibolit/patterns/instanceof/instance_of.py...
Reading aibolit/patterns/null_check/null_check.py...
Reading aibolit/patterns/hybrid_constructor/hybrid_constructor.py...
Reading aibolit/patterns/__init__.py...
Reading aibolit/patterns/method_chaining/method_chaining.py...
Reading aibolit/patterns/joined_validation/joined_validation.py...
Reading aibolit/patterns/partial_synchronized/partial_synchronized.py...
Reading aibolit/metrics/local_methods_calls/local_methods_calls.py...
Puzzle 183-069e5295 30/DEV at aibolit/metrics/local_methods_calls/local_methods_calls.py
Reading aibolit/metrics/halsteadvolume/README.md...
Reading aibolit/metrics/halsteadvolume/pom.xml...
Reading aibolit/metrics/halsteadvolume/src/main/java/com/metrics/halstead/ASTVisitorMod.java...
Reading aibolit/metrics/halsteadvolume/src/main/java/com/metrics/halstead/App.java...
Reading aibolit/metrics/halsteadvolume/src/main/java/com/metrics/halstead/HalsteadMetrics.java...
Reading aibolit/metrics/cognitiveC/README.md...
Reading aibolit/metrics/cognitiveC/cognitive_c.py...
Reading aibolit/metrics/number_variables/numVariables.py...
Reading aibolit/metrics/number_variables/README.md...
Reading aibolit/metrics/npath/README.md...
Reading aibolit/metrics/npath/pom.xml...
Reading aibolit/metrics/npath/npath.xml...
Reading aibolit/metrics/npath/main.py...
Reading aibolit/metrics/npath/__init__.py...
Reading aibolit/metrics/hv/README.md...
Reading aibolit/metrics/hv/main.py...
Reading aibolit/metrics/hv/__init__.py...
Reading aibolit/metrics/entropy/README.md...
Reading aibolit/metrics/entropy/entropy.py...
Reading aibolit/metrics/maxDiameter/README.md...
Reading aibolit/metrics/maxDiameter/max_diam_of_tree.py...
Reading aibolit/metrics/external_methods_called/external_methods_called.py...
Puzzle 183-9b03d7d9 30/DEV at aibolit/metrics/external_methods_called/external_methods_called.py
Reading aibolit/metrics/spaces/SpaceCounter.py...
Reading aibolit/metrics/lcom4/lcom4.py...
Reading aibolit/metrics/RFC/rfc.py...
Reading aibolit/metrics/ncss/README.md...
Reading aibolit/metrics/ncss/ncss.py...
Reading aibolit/metrics/ncss/__init__.py...
Reading aibolit/metrics/loc/README.md...
Reading aibolit/metrics/loc/loc.py...
Reading aibolit/metrics/fanout/FanOut.py...
Reading aibolit/metrics/mda/mda.py...
Reading aibolit/metrics/__init__.py...
Reading aibolit/metrics/countLeaves/README.md...
Reading aibolit/metrics/countLeaves/numberofleaves.py...
Reading aibolit/metrics/cc/README.md...
Reading aibolit/metrics/cc/cyclical.xml...
Reading aibolit/metrics/cc/pom.xml...
Reading aibolit/metrics/cc/requirements.txt...
Reading aibolit/metrics/cc/main.py...
Reading aibolit/ml_pipeline/ml_pipeline.py...
Reading aibolit/__init__.py...
Reading wp/references.bib...
Reading wp/sections/usage_scenarios.tex...
Reading wp/sections/related_work.tex...
Reading wp/sections/how_aibolit_works.tex...
Reading wp/sections/conclusion.tex...
Reading wp/sections/pattern_emp_analysis.tex...
Reading wp/sections/appendix.tex...
Reading wp/sections/introduction.tex...
Reading wp/sections/threats_to_validity.tex...
Reading wp/wp.tex...
ERROR: wp/wp.tex; puzzle at line #62; TODO must have a leading space to become a puzzle, as this page explains: https://github.com/yegor256/pdd#how-to-format
If you can't understand the cause of this issue or you don't know how to fix it, please submit a GitHub issue, we will try to help you: https://github.com/yegor256/pdd/issues. This tool is still in its beta version and we will appreciate your feedback. Here is where you can find more documentation: https://github.com/yegor256/pdd/blob/master/README.md.
Exit code is 1

/app/objects/git_repo.rb:66:in `rescue in block in xml'
/app/objects/git_repo.rb:63:in `block in xml'
/app/vendor/ruby-2.6.0/lib/ruby/2.6.0/tempfile.rb:295:in `open'
/app/objects/git_repo.rb:62:in `xml'
/app/objects/puzzles.rb:36:in `deploy'
/app/objects/job.rb:38:in `proceed'
/app/objects/job_starred.rb:33:in `proceed'
/app/objects/job_recorded.rb:32:in `proceed'
/app/objects/job_emailed.rb:35:in `proceed'
/app/objects/job_commiterrors.rb:36:in `proceed'
/app/objects/job_detached.rb:48:in `exclusive'
/app/objects/job_detached.rb:36:in `block in proceed'
/app/objects/job_detached.rb:36:in `fork'
/app/objects/job_detached.rb:36:in `proceed'
/app/0pdd.rb:358:in `block in <top (required)>'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1635:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1635:in `block in compile!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:992:in `block (3 levels) in route!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1011:in `route_eval'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:992:in `block (2 levels) in route!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1040:in `block in process_route'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1038:in `catch'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1038:in `process_route'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:990:in `block in route!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:989:in `each'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:989:in `route!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1097:in `block in dispatch!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1076:in `block in invoke'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1076:in `catch'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1076:in `invoke'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1094:in `dispatch!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:924:in `block in call!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1076:in `block in invoke'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1076:in `catch'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1076:in `invoke'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:924:in `call!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:913:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-protection-2.0.4/lib/rack/protection/xss_header.rb:18:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-protection-2.0.4/lib/rack/protection/path_traversal.rb:16:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-protection-2.0.4/lib/rack/protection/json_csrf.rb:26:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-protection-2.0.4/lib/rack/protection/base.rb:50:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-protection-2.0.4/lib/rack/protection/base.rb:50:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-protection-2.0.4/lib/rack/protection/frame_options.rb:31:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-2.0.6/lib/rack/logger.rb:15:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-2.0.6/lib/rack/common_logger.rb:33:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:231:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:224:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-2.0.6/lib/rack/head.rb:12:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-2.0.6/lib/rack/method_override.rb:22:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:194:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1957:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1502:in `block in call'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1729:in `synchronize'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1502:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-2.0.6/lib/rack/handler/webrick.rb:86:in `service'
/app/vendor/ruby-2.6.0/lib/ruby/2.6.0/webrick/httpserver.rb:140:in `service'
/app/vendor/ruby-2.6.0/lib/ruby/2.6.0/webrick/httpserver.rb:96:in `run'
/app/vendor/ruby-2.6.0/lib/ruby/2.6.0/webrick/server.rb:307:in `block in start_thread'

Please sign in to comment.