exercism-analysis 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/exercism-analysis.gemspec +30 -0
- data/lib/exercism-analysis.rb +38 -0
- data/lib/exercism-analysis/adapters/adapter.rb +23 -0
- data/lib/exercism-analysis/adapters/clojure.rb +13 -0
- data/lib/exercism-analysis/adapters/go.rb +19 -0
- data/lib/exercism-analysis/adapters/javascript.rb +13 -0
- data/lib/exercism-analysis/adapters/python.rb +13 -0
- data/lib/exercism-analysis/adapters/ruby.rb +19 -0
- data/lib/exercism-analysis/analysis.rb +18 -0
- data/lib/exercism-analysis/analyzers/analyzer.rb +54 -0
- data/lib/exercism-analysis/analyzers/clojure/kibit.rb +25 -0
- data/lib/exercism-analysis/analyzers/go/golint.rb +23 -0
- data/lib/exercism-analysis/analyzers/javascript/jslint.rb +24 -0
- data/lib/exercism-analysis/analyzers/python/pylint.rb +24 -0
- data/lib/exercism-analysis/analyzers/ruby/control_flow.rb +21 -0
- data/lib/exercism-analysis/analyzers/ruby/enumerable_condition.rb +21 -0
- data/lib/exercism-analysis/analyzers/ruby/for_loop.rb +29 -0
- data/lib/exercism-analysis/analyzers/ruby/indentation.rb +21 -0
- data/lib/exercism-analysis/analyzers/ruby/iter_mutation.rb +37 -0
- data/lib/exercism-analysis/analyzers/ruby/output.rb +20 -0
- data/lib/exercism-analysis/analyzers/ruby/range.rb +28 -0
- data/lib/exercism-analysis/analyzers/ruby/roodi.rb +19 -0
- data/lib/exercism-analysis/analyzers/ruby/send.rb +25 -0
- data/lib/exercism-analysis/analyzers/ruby/shebang.rb +23 -0
- data/lib/exercism-analysis/analyzers/ruby/tab.rb +38 -0
- data/lib/exercism-analysis/processors/call_processor.rb +39 -0
- data/lib/exercism-analysis/processors/control_flow_processor.rb +27 -0
- data/lib/exercism-analysis/processors/enumerable_condition_processor.rb +31 -0
- data/lib/exercism-analysis/processors/for_loop_processor.rb +21 -0
- data/lib/exercism-analysis/processors/indentation_processor.rb +69 -0
- data/lib/exercism-analysis/processors/iter_mutation_processor.rb +50 -0
- data/lib/exercism-analysis/processors/processor.rb +34 -0
- data/lib/exercism-analysis/processors/range_processor.rb +23 -0
- data/lib/exercism-analysis/processors/send_processor.rb +23 -0
- data/lib/exercism-analysis/templates/each_to_map.rb +29 -0
- data/lib/exercism-analysis/templates/each_to_select.rb +31 -0
- data/lib/exercism-analysis/templates/range_exclusive.rb +19 -0
- data/lib/exercism-analysis/templates/template.rb +29 -0
- data/vendor/clojure/kibit-runner/LICENSE +214 -0
- data/vendor/clojure/kibit-runner/project.clj +10 -0
- data/vendor/clojure/kibit-runner/src/kibit_runner/core.clj +17 -0
- data/vendor/clojure/kibit-runner/target/kibit-runner-0.1.0-SNAPSHOT-standalone.jar +0 -0
- data/vendor/clojure/kibit-runner/target/kibit-runner-0.1.0-SNAPSHOT.jar +0 -0
- data/vendor/clojure/kibit-runner/target/stale/extract-native.dependencies +1 -0
- data/vendor/go/src/github.com/golang/lint/LICENSE +27 -0
- data/vendor/go/src/github.com/golang/lint/README +59 -0
- data/vendor/go/src/github.com/golang/lint/golint/golint.go +67 -0
- data/vendor/go/src/github.com/golang/lint/lint.go +1061 -0
- data/vendor/go/src/runner/golint_runner.go +23 -0
- data/vendor/javascript/jshint_runner.js +6 -0
- data/vendor/javascript/node_modules/jshint/README.md +47 -0
- data/vendor/javascript/node_modules/jshint/bin/apply +6 -0
- data/vendor/javascript/node_modules/jshint/bin/build +36 -0
- data/vendor/javascript/node_modules/jshint/bin/changelog +36 -0
- data/vendor/javascript/node_modules/jshint/bin/jshint +3 -0
- data/vendor/javascript/node_modules/jshint/bin/land +34 -0
- data/vendor/javascript/node_modules/jshint/data/ascii-identifier-data.js +22 -0
- data/vendor/javascript/node_modules/jshint/data/non-ascii-identifier-part-only.js +1570 -0
- data/vendor/javascript/node_modules/jshint/data/non-ascii-identifier-start.js +48477 -0
- data/vendor/javascript/node_modules/jshint/dist/jshint-rhino.js +60642 -0
- data/vendor/javascript/node_modules/jshint/dist/jshint.js +60525 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/README.md +196 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/cli.js +1139 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/examples/cat.js +17 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/examples/command.js +16 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/examples/echo.js +54 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/examples/glob.js +6 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/examples/long_desc.js +20 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/examples/progress.js +11 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/examples/sort.js +18 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/examples/spinner.js +9 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/examples/static.coffee +27 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/examples/static.js +25 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/index.js +1 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/LICENSE +27 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/README.md +250 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/examples/g.js +9 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/examples/usr-local.js +9 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/glob.js +728 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/inherits/LICENSE +16 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/inherits/README.md +42 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/inherits/inherits.js +1 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/inherits/inherits_browser.js +23 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/inherits/package.json +51 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/inherits/test.js +25 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/package.json +58 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/00-setup.js +176 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/bash-comparison.js +63 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/bash-results.json +351 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/cwd-test.js +55 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/globstar-match.js +19 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/mark.js +118 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/new-glob-optional-options.js +10 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/nocase-nomagic.js +113 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/pause-resume.js +73 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/readme-issue.js +36 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/root-nomount.js +39 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/root.js +46 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/stat.js +32 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/zz-cleanup.js +11 -0
- data/vendor/javascript/node_modules/jshint/node_modules/cli/package.json +70 -0
- data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/LICENCE +19 -0
- data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/README.md +33 -0
- data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/index.js +86 -0
- data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/node_modules/date-now/LICENCE +19 -0
- data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/node_modules/date-now/README.md +45 -0
- data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/node_modules/date-now/index.js +5 -0
- data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/node_modules/date-now/package.json +89 -0
- data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/node_modules/date-now/seed.js +16 -0
- data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/node_modules/date-now/test/index.js +28 -0
- data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/node_modules/date-now/test/static/index.html +10 -0
- data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/package.json +88 -0
- data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/test/index.js +67 -0
- data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/test/static/index.html +12 -0
- data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/test/static/test-adapter.js +53 -0
- data/vendor/javascript/node_modules/jshint/node_modules/exit/Gruntfile.js +48 -0
- data/vendor/javascript/node_modules/jshint/node_modules/exit/LICENSE-MIT +22 -0
- data/vendor/javascript/node_modules/jshint/node_modules/exit/README.md +75 -0
- data/vendor/javascript/node_modules/jshint/node_modules/exit/lib/exit.js +41 -0
- data/vendor/javascript/node_modules/jshint/node_modules/exit/package.json +69 -0
- data/vendor/javascript/node_modules/jshint/node_modules/exit/test/exit_test.js +121 -0
- data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/10-stderr.txt +10 -0
- data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/10-stdout-stderr.txt +20 -0
- data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/10-stdout.txt +10 -0
- data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/100-stderr.txt +100 -0
- data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/100-stdout-stderr.txt +200 -0
- data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/100-stdout.txt +100 -0
- data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/1000-stderr.txt +1000 -0
- data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/1000-stdout-stderr.txt +2000 -0
- data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/1000-stdout.txt +1000 -0
- data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/create-files.sh +8 -0
- data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/log-broken.js +23 -0
- data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/log.js +25 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/LICENSE +18 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/README.md +83 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/lib/CollectingHandler.js +55 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/lib/FeedHandler.js +95 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/lib/Parser.js +337 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/lib/ProxyHandler.js +27 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/lib/Stream.js +35 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/lib/Tokenizer.js +891 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/lib/WritableStream.js +21 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/lib/index.js +68 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domelementtype/LICENSE +11 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domelementtype/index.js +14 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domelementtype/package.json +40 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domelementtype/readme.md +1 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/LICENSE +11 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/index.js +211 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/package.json +68 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/readme.md +102 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/01-basic.json +57 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/02-single_tag_1.json +21 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/03-single_tag_2.json +21 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/04-unescaped_in_script.json +27 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/05-tags_in_comment.json +18 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/06-comment_in_script.json +18 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/07-unescaped_in_style.json +20 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/08-extra_spaces_in_tag.json +20 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/09-unquoted_attrib.json +20 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/10-singular_attribute.json +15 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/11-text_outside_tags.json +40 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/12-text_only.json +11 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/13-comment_in_text.json +19 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/14-comment_in_text_in_script.json +18 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/15-non-verbose.json +22 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/16-normalize_whitespace.json +47 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/17-xml_namespace.json +18 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/18-enforce_empty_tags.json +16 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/19-ignore_empty_tags.json +20 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/20-template_script_tags.json +20 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/21-conditional_comments.json +15 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/22-lowercase_tags.json +41 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/23-dom-lvl1.json +121 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/tests.js +58 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/LICENSE +11 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/index.js +14 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/lib/helpers.js +141 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/lib/legacy.js +87 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/lib/manipulation.js +77 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/lib/querying.js +94 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/lib/stringify.js +93 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/lib/traversal.js +24 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/package.json +71 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/readme.md +1 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/test/fixture.js +6 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/test/tests/helpers.js +89 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/test/tests/legacy.js +119 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/test/utils.js +9 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/LICENSE +11 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/index.js +31 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/lib/decode.js +72 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/lib/decode_codepoint.js +26 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/lib/encode.js +48 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/maps/decode.json +1 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/maps/entities.json +1 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/maps/legacy.json +1 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/maps/xml.json +1 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/package.json +79 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/readme.md +31 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/test/mocha.opts +2 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/test/test.js +150 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/LICENSE +18 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/README.md +15 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/duplex.js +1 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/float.patch +923 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/lib/_stream_duplex.js +89 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/lib/_stream_passthrough.js +46 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/lib/_stream_readable.js +944 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/lib/_stream_transform.js +209 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/lib/_stream_writable.js +472 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/core-util-is/README.md +3 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/core-util-is/float.patch +604 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/core-util-is/lib/util.js +107 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/core-util-is/package.json +53 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/core-util-is/util.js +106 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/inherits/LICENSE +16 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/inherits/README.md +42 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/inherits/inherits.js +1 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/inherits/inherits_browser.js +23 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/inherits/package.json +51 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/inherits/test.js +25 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/isarray/README.md +54 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/isarray/build/build.js +209 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/isarray/component.json +19 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/isarray/index.js +3 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/isarray/package.json +54 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/string_decoder/LICENSE +20 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/string_decoder/README.md +7 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/string_decoder/index.js +200 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/string_decoder/package.json +53 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/package.json +68 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/passthrough.js +1 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/readable.js +7 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/transform.js +1 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/writable.js +1 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/package.json +90 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/01-events.js +9 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/02-stream.js +23 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/03-feed.js +19 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Documents/Atom_Example.xml +25 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Documents/Attributes.html +16 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Documents/Basic.html +1 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Documents/RDF_Example.xml +63 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Documents/RSS_Example.xml +48 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/01-simple.json +44 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/02-template.json +63 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/03-lowercase_tags.json +46 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/04-cdata.json +50 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/05-cdata-special.json +35 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/06-leading-lt.json +16 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/07-self-closing.json +67 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/08-implicit-close-tags.json +59 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/09-attributes.json +68 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/10-crazy-attrib.json +52 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/11-script_in_script.json +54 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/12-long-comment-end.json +20 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/13-long-cdata-end.json +22 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/14-implicit-open-tags.json +27 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/15-lt-whitespace.json +16 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/16-double_attribs.json +45 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/17-numeric_entities.json +16 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/18-legacy_entities.json +16 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/19-named_entities.json +16 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/20-xml_entities.json +16 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/21-entity_in_attribute.json +38 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/22-double_brackets.json +41 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/23-legacy_entity_fail.json +16 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/24-special_special.json +133 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/25-empty_tag_name.json +13 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/26-not-quite-closed.json +35 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/27-entities_in_attributes.json +62 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/28-cdata_in_html.json +9 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/29-comment_edge-cases.json +18 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/30-cdata_edge-cases.json +22 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Feeds/01-rss.js +34 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Feeds/02-atom.js +18 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Feeds/03-rdf.js +20 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Stream/01-basic.json +83 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Stream/02-RSS.json +1093 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Stream/03-Atom.json +644 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Stream/04-RDF.json +1399 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Stream/05-Attributes.json +354 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/api.js +63 -0
- data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/test-helper.js +83 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/LICENSE +23 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/README.md +218 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/minimatch.js +1061 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS +14 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/lru-cache/LICENSE +23 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/lru-cache/README.md +97 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js +252 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/lru-cache/package.json +50 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/lru-cache/test/basic.js +369 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/lru-cache/test/foreach.js +52 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js +50 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/sigmund/LICENSE +27 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/sigmund/README.md +53 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/sigmund/bench.js +283 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/sigmund/package.json +58 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/sigmund/sigmund.js +39 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/sigmund/test/basic.js +24 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/package.json +57 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/test/basic.js +399 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/test/brace-expand.js +33 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/test/caching.js +14 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/test/defaults.js +274 -0
- data/vendor/javascript/node_modules/jshint/node_modules/minimatch/test/extglob-ending-with-state-char.js +8 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/LICENSE +26 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/README.md +569 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/bin/shjs +51 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/global.js +3 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/make.js +47 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/package.json +61 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/scripts/generate-docs.js +21 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/scripts/run-tests.js +50 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/shell.js +157 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/cat.js +43 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/cd.js +19 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/chmod.js +208 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/common.js +203 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/cp.js +201 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/dirs.js +191 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/echo.js +20 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/error.js +10 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/exec.js +181 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/find.js +51 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/grep.js +52 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/ln.js +53 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/ls.js +126 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/mkdir.js +68 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/mv.js +80 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/popd.js +1 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/pushd.js +1 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/pwd.js +11 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/rm.js +145 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/sed.js +43 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/tempdir.js +56 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/test.js +85 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/to.js +29 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/toEnd.js +29 -0
- data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/which.js +83 -0
- data/vendor/javascript/node_modules/jshint/node_modules/strip-json-comments/cli.js +41 -0
- data/vendor/javascript/node_modules/jshint/node_modules/strip-json-comments/package.json +76 -0
- data/vendor/javascript/node_modules/jshint/node_modules/strip-json-comments/readme.md +74 -0
- data/vendor/javascript/node_modules/jshint/node_modules/strip-json-comments/strip-json-comments.js +64 -0
- data/vendor/javascript/node_modules/jshint/node_modules/underscore/LICENSE +23 -0
- data/vendor/javascript/node_modules/jshint/node_modules/underscore/README.md +22 -0
- data/vendor/javascript/node_modules/jshint/node_modules/underscore/package.json +66 -0
- data/vendor/javascript/node_modules/jshint/node_modules/underscore/underscore-min.js +6 -0
- data/vendor/javascript/node_modules/jshint/node_modules/underscore/underscore.js +1343 -0
- data/vendor/javascript/node_modules/jshint/package.json +80 -0
- data/vendor/javascript/node_modules/jshint/src/cli.js +731 -0
- data/vendor/javascript/node_modules/jshint/src/jshint.js +5023 -0
- data/vendor/javascript/node_modules/jshint/src/lex.js +1650 -0
- data/vendor/javascript/node_modules/jshint/src/messages.js +223 -0
- data/vendor/javascript/node_modules/jshint/src/platforms/rhino.js +115 -0
- data/vendor/javascript/node_modules/jshint/src/reg.js +38 -0
- data/vendor/javascript/node_modules/jshint/src/reporters/checkstyle.js +81 -0
- data/vendor/javascript/node_modules/jshint/src/reporters/default.js +34 -0
- data/vendor/javascript/node_modules/jshint/src/reporters/jslint_xml.js +57 -0
- data/vendor/javascript/node_modules/jshint/src/reporters/non_error.js +52 -0
- data/vendor/javascript/node_modules/jshint/src/state.js +28 -0
- data/vendor/javascript/node_modules/jshint/src/style.js +143 -0
- data/vendor/javascript/node_modules/jshint/src/vars.js +658 -0
- data/vendor/python/astroid/COPYING +339 -0
- data/vendor/python/astroid/COPYING.LESSER +510 -0
- data/vendor/python/astroid/ChangeLog +574 -0
- data/vendor/python/astroid/MANIFEST.in +9 -0
- data/vendor/python/astroid/README +56 -0
- data/vendor/python/astroid/README.Python3 +26 -0
- data/vendor/python/astroid/__init__.py +118 -0
- data/vendor/python/astroid/__init__.pyc +0 -0
- data/vendor/python/astroid/__pkginfo__.py +48 -0
- data/vendor/python/astroid/__pkginfo__.pyc +0 -0
- data/vendor/python/astroid/announce.txt +23 -0
- data/vendor/python/astroid/as_string.py +496 -0
- data/vendor/python/astroid/as_string.pyc +0 -0
- data/vendor/python/astroid/bases.py +618 -0
- data/vendor/python/astroid/bases.pyc +0 -0
- data/vendor/python/astroid/brain/py2gi.py +159 -0
- data/vendor/python/astroid/brain/py2gi.pyc +0 -0
- data/vendor/python/astroid/brain/py2mechanize.py +20 -0
- data/vendor/python/astroid/brain/py2mechanize.pyc +0 -0
- data/vendor/python/astroid/brain/py2qt4.py +25 -0
- data/vendor/python/astroid/brain/py2qt4.pyc +0 -0
- data/vendor/python/astroid/brain/py2stdlib.py +252 -0
- data/vendor/python/astroid/brain/py2stdlib.pyc +0 -0
- data/vendor/python/astroid/builder.py +238 -0
- data/vendor/python/astroid/builder.pyc +0 -0
- data/vendor/python/astroid/exceptions.py +51 -0
- data/vendor/python/astroid/exceptions.pyc +0 -0
- data/vendor/python/astroid/inference.py +393 -0
- data/vendor/python/astroid/inference.pyc +0 -0
- data/vendor/python/astroid/inspector.py +275 -0
- data/vendor/python/astroid/manager.py +336 -0
- data/vendor/python/astroid/manager.pyc +0 -0
- data/vendor/python/astroid/mixins.py +122 -0
- data/vendor/python/astroid/mixins.pyc +0 -0
- data/vendor/python/astroid/node_classes.py +928 -0
- data/vendor/python/astroid/node_classes.pyc +0 -0
- data/vendor/python/astroid/nodes.py +73 -0
- data/vendor/python/astroid/nodes.pyc +0 -0
- data/vendor/python/astroid/protocols.py +322 -0
- data/vendor/python/astroid/protocols.pyc +0 -0
- data/vendor/python/astroid/raw_building.py +361 -0
- data/vendor/python/astroid/raw_building.pyc +0 -0
- data/vendor/python/astroid/rebuilder.py +954 -0
- data/vendor/python/astroid/rebuilder.pyc +0 -0
- data/vendor/python/astroid/scoped_nodes.py +1118 -0
- data/vendor/python/astroid/scoped_nodes.pyc +0 -0
- data/vendor/python/astroid/setup.py +184 -0
- data/vendor/python/astroid/tox.ini +10 -0
- data/vendor/python/astroid/utils.py +236 -0
- data/vendor/python/astroid/utils.pyc +0 -0
- data/vendor/python/logilab/__init__.py +0 -0
- data/vendor/python/logilab/__init__.pyc +0 -0
- data/vendor/python/logilab/common/COPYING +339 -0
- data/vendor/python/logilab/common/COPYING.LESSER +510 -0
- data/vendor/python/logilab/common/ChangeLog +1517 -0
- data/vendor/python/logilab/common/MANIFEST.in +13 -0
- data/vendor/python/logilab/common/README +185 -0
- data/vendor/python/logilab/common/README.Python3 +29 -0
- data/vendor/python/logilab/common/__init__.py +171 -0
- data/vendor/python/logilab/common/__init__.pyc +0 -0
- data/vendor/python/logilab/common/__pkginfo__.py +53 -0
- data/vendor/python/logilab/common/__pkginfo__.pyc +0 -0
- data/vendor/python/logilab/common/announce.txt +25 -0
- data/vendor/python/logilab/common/bin/pytest +7 -0
- data/vendor/python/logilab/common/bin/pytest.bat +17 -0
- data/vendor/python/logilab/common/cache.py +114 -0
- data/vendor/python/logilab/common/changelog.py +236 -0
- data/vendor/python/logilab/common/changelog.pyc +0 -0
- data/vendor/python/logilab/common/clcommands.py +332 -0
- data/vendor/python/logilab/common/cli.py +208 -0
- data/vendor/python/logilab/common/compat.py +243 -0
- data/vendor/python/logilab/common/compat.pyc +0 -0
- data/vendor/python/logilab/common/configuration.py +1094 -0
- data/vendor/python/logilab/common/configuration.pyc +0 -0
- data/vendor/python/logilab/common/contexts.py +5 -0
- data/vendor/python/logilab/common/corbautils.py +117 -0
- data/vendor/python/logilab/common/daemon.py +100 -0
- data/vendor/python/logilab/common/date.py +333 -0
- data/vendor/python/logilab/common/dbf.py +229 -0
- data/vendor/python/logilab/common/debugger.py +210 -0
- data/vendor/python/logilab/common/decorators.py +281 -0
- data/vendor/python/logilab/common/decorators.pyc +0 -0
- data/vendor/python/logilab/common/deprecation.py +188 -0
- data/vendor/python/logilab/common/deprecation.pyc +0 -0
- data/vendor/python/logilab/common/fileutils.py +402 -0
- data/vendor/python/logilab/common/graph.py +276 -0
- data/vendor/python/logilab/common/graph.pyc +0 -0
- data/vendor/python/logilab/common/hg.py +130 -0
- data/vendor/python/logilab/common/interface.py +71 -0
- data/vendor/python/logilab/common/interface.pyc +0 -0
- data/vendor/python/logilab/common/logging_ext.py +193 -0
- data/vendor/python/logilab/common/modutils.py +695 -0
- data/vendor/python/logilab/common/modutils.pyc +0 -0
- data/vendor/python/logilab/common/optik_ext.py +391 -0
- data/vendor/python/logilab/common/optik_ext.pyc +0 -0
- data/vendor/python/logilab/common/optparser.py +90 -0
- data/vendor/python/logilab/common/proc.py +277 -0
- data/vendor/python/logilab/common/pyro_ext.py +180 -0
- data/vendor/python/logilab/common/pytest.py +1177 -0
- data/vendor/python/logilab/common/python-logilab-common.spec +184 -0
- data/vendor/python/logilab/common/registry.py +1113 -0
- data/vendor/python/logilab/common/setup.cfg +3 -0
- data/vendor/python/logilab/common/setup.py +189 -0
- data/vendor/python/logilab/common/shellutils.py +455 -0
- data/vendor/python/logilab/common/sphinx_ext.py +87 -0
- data/vendor/python/logilab/common/sphinxutils.py +122 -0
- data/vendor/python/logilab/common/table.py +925 -0
- data/vendor/python/logilab/common/tasksqueue.py +100 -0
- data/vendor/python/logilab/common/textutils.py +534 -0
- data/vendor/python/logilab/common/textutils.pyc +0 -0
- data/vendor/python/logilab/common/tree.py +369 -0
- data/vendor/python/logilab/common/tree.pyc +0 -0
- data/vendor/python/logilab/common/umessage.py +190 -0
- data/vendor/python/logilab/common/ureports/__init__.py +174 -0
- data/vendor/python/logilab/common/ureports/__init__.pyc +0 -0
- data/vendor/python/logilab/common/ureports/docbook_writer.py +139 -0
- data/vendor/python/logilab/common/ureports/html_writer.py +131 -0
- data/vendor/python/logilab/common/ureports/html_writer.pyc +0 -0
- data/vendor/python/logilab/common/ureports/nodes.py +201 -0
- data/vendor/python/logilab/common/ureports/nodes.pyc +0 -0
- data/vendor/python/logilab/common/ureports/text_writer.py +140 -0
- data/vendor/python/logilab/common/ureports/text_writer.pyc +0 -0
- data/vendor/python/logilab/common/urllib2ext.py +87 -0
- data/vendor/python/logilab/common/vcgutils.py +216 -0
- data/vendor/python/logilab/common/visitor.py +107 -0
- data/vendor/python/logilab/common/visitor.pyc +0 -0
- data/vendor/python/logilab/common/xmlrpcutils.py +131 -0
- data/vendor/python/logilab/common/xmlutils.py +61 -0
- data/vendor/python/pylint/CONTRIBUTORS.txt +38 -0
- data/vendor/python/pylint/COPYING +340 -0
- data/vendor/python/pylint/ChangeLog +1437 -0
- data/vendor/python/pylint/DEPENDS +3 -0
- data/vendor/python/pylint/MANIFEST.in +14 -0
- data/vendor/python/pylint/README +50 -0
- data/vendor/python/pylint/README.Python3 +37 -0
- data/vendor/python/pylint/__init__.py +44 -0
- data/vendor/python/pylint/__init__.pyc +0 -0
- data/vendor/python/pylint/__main__.py +3 -0
- data/vendor/python/pylint/__pkginfo__.py +74 -0
- data/vendor/python/pylint/__pkginfo__.pyc +0 -0
- data/vendor/python/pylint/bin/epylint +3 -0
- data/vendor/python/pylint/bin/epylint.bat +5 -0
- data/vendor/python/pylint/bin/pylint +3 -0
- data/vendor/python/pylint/bin/pylint-gui +3 -0
- data/vendor/python/pylint/bin/pylint-gui.bat +5 -0
- data/vendor/python/pylint/bin/pylint.bat +5 -0
- data/vendor/python/pylint/bin/pyreverse +3 -0
- data/vendor/python/pylint/bin/pyreverse.bat +5 -0
- data/vendor/python/pylint/bin/symilar +3 -0
- data/vendor/python/pylint/bin/symilar.bat +5 -0
- data/vendor/python/pylint/checkers/__init__.py +145 -0
- data/vendor/python/pylint/checkers/__init__.pyc +0 -0
- data/vendor/python/pylint/checkers/base.py +1141 -0
- data/vendor/python/pylint/checkers/base.pyc +0 -0
- data/vendor/python/pylint/checkers/classes.py +792 -0
- data/vendor/python/pylint/checkers/classes.pyc +0 -0
- data/vendor/python/pylint/checkers/design_analysis.py +367 -0
- data/vendor/python/pylint/checkers/design_analysis.pyc +0 -0
- data/vendor/python/pylint/checkers/exceptions.py +306 -0
- data/vendor/python/pylint/checkers/exceptions.pyc +0 -0
- data/vendor/python/pylint/checkers/format.py +943 -0
- data/vendor/python/pylint/checkers/format.pyc +0 -0
- data/vendor/python/pylint/checkers/imports.py +394 -0
- data/vendor/python/pylint/checkers/imports.pyc +0 -0
- data/vendor/python/pylint/checkers/logging.py +213 -0
- data/vendor/python/pylint/checkers/logging.pyc +0 -0
- data/vendor/python/pylint/checkers/misc.py +90 -0
- data/vendor/python/pylint/checkers/misc.pyc +0 -0
- data/vendor/python/pylint/checkers/newstyle.py +151 -0
- data/vendor/python/pylint/checkers/newstyle.pyc +0 -0
- data/vendor/python/pylint/checkers/raw_metrics.py +129 -0
- data/vendor/python/pylint/checkers/raw_metrics.pyc +0 -0
- data/vendor/python/pylint/checkers/similar.py +365 -0
- data/vendor/python/pylint/checkers/similar.pyc +0 -0
- data/vendor/python/pylint/checkers/stdlib.py +69 -0
- data/vendor/python/pylint/checkers/stdlib.pyc +0 -0
- data/vendor/python/pylint/checkers/strings.py +304 -0
- data/vendor/python/pylint/checkers/strings.pyc +0 -0
- data/vendor/python/pylint/checkers/typecheck.py +451 -0
- data/vendor/python/pylint/checkers/typecheck.pyc +0 -0
- data/vendor/python/pylint/checkers/utils.py +416 -0
- data/vendor/python/pylint/checkers/utils.pyc +0 -0
- data/vendor/python/pylint/checkers/variables.py +741 -0
- data/vendor/python/pylint/checkers/variables.pyc +0 -0
- data/vendor/python/pylint/config.py +156 -0
- data/vendor/python/pylint/config.pyc +0 -0
- data/vendor/python/pylint/epylint.py +175 -0
- data/vendor/python/pylint/gui.py +508 -0
- data/vendor/python/pylint/interfaces.py +72 -0
- data/vendor/python/pylint/interfaces.pyc +0 -0
- data/vendor/python/pylint/lint.py +1106 -0
- data/vendor/python/pylint/lint.pyc +0 -0
- data/vendor/python/pylint/pyreverse/__init__.py +5 -0
- data/vendor/python/pylint/pyreverse/diadefslib.py +233 -0
- data/vendor/python/pylint/pyreverse/diagrams.py +247 -0
- data/vendor/python/pylint/pyreverse/main.py +124 -0
- data/vendor/python/pylint/pyreverse/utils.py +131 -0
- data/vendor/python/pylint/pyreverse/writer.py +199 -0
- data/vendor/python/pylint/reporters/__init__.py +138 -0
- data/vendor/python/pylint/reporters/__init__.pyc +0 -0
- data/vendor/python/pylint/reporters/guireporter.py +28 -0
- data/vendor/python/pylint/reporters/guireporter.pyc +0 -0
- data/vendor/python/pylint/reporters/html.py +70 -0
- data/vendor/python/pylint/reporters/html.pyc +0 -0
- data/vendor/python/pylint/reporters/text.py +143 -0
- data/vendor/python/pylint/reporters/text.pyc +0 -0
- data/vendor/python/pylint/setup.cfg +3 -0
- data/vendor/python/pylint/setup.py +203 -0
- data/vendor/python/pylint/tox.ini +10 -0
- data/vendor/python/pylint/utils.py +744 -0
- data/vendor/python/pylint/utils.pyc +0 -0
- data/vendor/python/pylint_runner.py +22 -0
- metadata +675 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Copyright (c) 2013 The Go Authors. All rights reserved.
|
|
2
|
+
//
|
|
3
|
+
// Use of this source code is governed by a BSD-style
|
|
4
|
+
// license that can be found in the LICENSE file or at
|
|
5
|
+
// https://developers.google.com/open-source/licenses/bsd.
|
|
6
|
+
|
|
7
|
+
// golint lints the Go source files named on its command line.
|
|
8
|
+
package main
|
|
9
|
+
|
|
10
|
+
import (
|
|
11
|
+
"flag"
|
|
12
|
+
"fmt"
|
|
13
|
+
"io/ioutil"
|
|
14
|
+
"os"
|
|
15
|
+
"path/filepath"
|
|
16
|
+
"strings"
|
|
17
|
+
|
|
18
|
+
"github.com/golang/lint"
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
var minConfidence = flag.Float64("min_confidence", 0.8, "minimum confidence of a problem to print it")
|
|
22
|
+
|
|
23
|
+
func main() {
|
|
24
|
+
flag.Parse()
|
|
25
|
+
|
|
26
|
+
for _, filename := range flag.Args() {
|
|
27
|
+
if isDir(filename) {
|
|
28
|
+
lintDir(filename)
|
|
29
|
+
} else {
|
|
30
|
+
lintFile(filename)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
func isDir(filename string) bool {
|
|
36
|
+
fi, err := os.Stat(filename)
|
|
37
|
+
return err == nil && fi.IsDir()
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
func lintFile(filename string) {
|
|
41
|
+
src, err := ioutil.ReadFile(filename)
|
|
42
|
+
if err != nil {
|
|
43
|
+
fmt.Fprintln(os.Stderr, err)
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
l := new(lint.Linter)
|
|
48
|
+
ps, err := l.Lint(filename, src)
|
|
49
|
+
if err != nil {
|
|
50
|
+
fmt.Fprintf(os.Stderr, "%v:%v\n", filename, err)
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
for _, p := range ps {
|
|
54
|
+
if p.Confidence >= *minConfidence {
|
|
55
|
+
fmt.Printf("%s:%v: %s\n", filename, p.Position, p.Text)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
func lintDir(dirname string) {
|
|
61
|
+
filepath.Walk(dirname, func(path string, info os.FileInfo, err error) error {
|
|
62
|
+
if err == nil && !info.IsDir() && strings.HasSuffix(path, ".go") {
|
|
63
|
+
lintFile(path)
|
|
64
|
+
}
|
|
65
|
+
return err
|
|
66
|
+
})
|
|
67
|
+
}
|
|
@@ -0,0 +1,1061 @@
|
|
|
1
|
+
// Copyright (c) 2013 The Go Authors. All rights reserved.
|
|
2
|
+
//
|
|
3
|
+
// Use of this source code is governed by a BSD-style
|
|
4
|
+
// license that can be found in the LICENSE file or at
|
|
5
|
+
// https://developers.google.com/open-source/licenses/bsd.
|
|
6
|
+
|
|
7
|
+
// Package lint contains a linter for Go source code.
|
|
8
|
+
package lint
|
|
9
|
+
|
|
10
|
+
import (
|
|
11
|
+
"bytes"
|
|
12
|
+
"fmt"
|
|
13
|
+
"go/ast"
|
|
14
|
+
"go/parser"
|
|
15
|
+
"go/printer"
|
|
16
|
+
"go/token"
|
|
17
|
+
"regexp"
|
|
18
|
+
"strconv"
|
|
19
|
+
"strings"
|
|
20
|
+
"unicode"
|
|
21
|
+
"unicode/utf8"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
const styleGuideBase = "http://golang.org/s/comments"
|
|
25
|
+
|
|
26
|
+
// A Linter lints Go source code.
|
|
27
|
+
type Linter struct {
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Problem represents a problem in some source code.
|
|
31
|
+
type Problem struct {
|
|
32
|
+
Position token.Position // position in source file
|
|
33
|
+
Text string // the prose that describes the problem
|
|
34
|
+
Link string // (optional) the link to the style guide for the problem
|
|
35
|
+
Confidence float64 // a value in (0,1] estimating the confidence in this problem's correctness
|
|
36
|
+
LineText string // the source line
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
func (p *Problem) String() string {
|
|
40
|
+
if p.Link != "" {
|
|
41
|
+
return p.Text + "\n\n" + p.Link
|
|
42
|
+
}
|
|
43
|
+
return p.Text
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Lint lints src.
|
|
47
|
+
func (l *Linter) Lint(filename string, src []byte) ([]Problem, error) {
|
|
48
|
+
fset := token.NewFileSet()
|
|
49
|
+
f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
|
|
50
|
+
if err != nil {
|
|
51
|
+
return nil, err
|
|
52
|
+
}
|
|
53
|
+
return (&file{fset: fset, f: f, src: src, filename: filename}).lint(), nil
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// file represents a file being linted.
|
|
57
|
+
type file struct {
|
|
58
|
+
fset *token.FileSet
|
|
59
|
+
f *ast.File
|
|
60
|
+
src []byte
|
|
61
|
+
filename string
|
|
62
|
+
|
|
63
|
+
// sortable is the set of types in the file that implement sort.Interface.
|
|
64
|
+
sortable map[string]bool
|
|
65
|
+
// main is whether this file is in a "main" package.
|
|
66
|
+
main bool
|
|
67
|
+
|
|
68
|
+
problems []Problem
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
func (f *file) isTest() bool { return strings.HasSuffix(f.filename, "_test.go") }
|
|
72
|
+
|
|
73
|
+
func (f *file) lint() []Problem {
|
|
74
|
+
f.scanSortable()
|
|
75
|
+
f.main = f.isMain()
|
|
76
|
+
|
|
77
|
+
f.lintPackageComment()
|
|
78
|
+
f.lintImports()
|
|
79
|
+
f.lintBlankImports()
|
|
80
|
+
f.lintExported()
|
|
81
|
+
f.lintNames()
|
|
82
|
+
f.lintVarDecls()
|
|
83
|
+
f.lintElses()
|
|
84
|
+
f.lintRanges()
|
|
85
|
+
f.lintErrorf()
|
|
86
|
+
f.lintErrors()
|
|
87
|
+
f.lintErrorStrings()
|
|
88
|
+
f.lintReceiverNames()
|
|
89
|
+
f.lintIncDec()
|
|
90
|
+
f.lintMake()
|
|
91
|
+
|
|
92
|
+
return f.problems
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
func (f *file) errorf(n ast.Node, confidence float64, link, format string, a ...interface{}) {
|
|
96
|
+
p := f.fset.Position(n.Pos())
|
|
97
|
+
f.problems = append(f.problems, Problem{
|
|
98
|
+
Position: p,
|
|
99
|
+
Text: fmt.Sprintf(format, a...),
|
|
100
|
+
Link: link,
|
|
101
|
+
Confidence: confidence,
|
|
102
|
+
LineText: srcLine(f.src, p),
|
|
103
|
+
})
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
func (f *file) scanSortable() {
|
|
107
|
+
f.sortable = make(map[string]bool)
|
|
108
|
+
|
|
109
|
+
// bitfield for which methods exist on each type.
|
|
110
|
+
const (
|
|
111
|
+
Len = 1 << iota
|
|
112
|
+
Less
|
|
113
|
+
Swap
|
|
114
|
+
)
|
|
115
|
+
nmap := map[string]int{"Len": Len, "Less": Less, "Swap": Swap}
|
|
116
|
+
has := make(map[string]int)
|
|
117
|
+
f.walk(func(n ast.Node) bool {
|
|
118
|
+
fn, ok := n.(*ast.FuncDecl)
|
|
119
|
+
if !ok || fn.Recv == nil {
|
|
120
|
+
return true
|
|
121
|
+
}
|
|
122
|
+
// TODO(dsymonds): We could check the signature to be more precise.
|
|
123
|
+
recv := receiverType(fn)
|
|
124
|
+
if i, ok := nmap[fn.Name.Name]; ok {
|
|
125
|
+
has[recv] |= i
|
|
126
|
+
}
|
|
127
|
+
return false
|
|
128
|
+
})
|
|
129
|
+
for typ, ms := range has {
|
|
130
|
+
if ms == Len|Less|Swap {
|
|
131
|
+
f.sortable[typ] = true
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
func (f *file) isMain() bool {
|
|
137
|
+
if f.f.Name.Name == "main" {
|
|
138
|
+
return true
|
|
139
|
+
}
|
|
140
|
+
return false
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// lintPackageComment checks package comments. It complains if
|
|
144
|
+
// there is no package comment, or if it is not of the right form.
|
|
145
|
+
// This has a notable false positive in that a package comment
|
|
146
|
+
// could rightfully appear in a different file of the same package,
|
|
147
|
+
// but that's not easy to fix since this linter is file-oriented.
|
|
148
|
+
func (f *file) lintPackageComment() {
|
|
149
|
+
if f.isTest() {
|
|
150
|
+
return
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const link = styleGuideBase + "#Package_Comments"
|
|
154
|
+
if f.f.Doc == nil {
|
|
155
|
+
f.errorf(f.f, 0.2, link, "should have a package comment, unless it's in another file for this package")
|
|
156
|
+
return
|
|
157
|
+
}
|
|
158
|
+
s := f.f.Doc.Text()
|
|
159
|
+
prefix := "Package " + f.f.Name.Name + " "
|
|
160
|
+
if ts := strings.TrimLeft(s, " \t"); ts != s {
|
|
161
|
+
f.errorf(f.f.Doc, 1, link, "package comment should not have leading space")
|
|
162
|
+
s = ts
|
|
163
|
+
}
|
|
164
|
+
// Only non-main packages need to keep to this form.
|
|
165
|
+
if f.f.Name.Name != "main" && !strings.HasPrefix(s, prefix) {
|
|
166
|
+
f.errorf(f.f.Doc, 1, link, `package comment should be of the form "%s..."`, prefix)
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// lintBlankImports complains if a non-main package has blank imports that are
|
|
171
|
+
// not documented.
|
|
172
|
+
func (f *file) lintBlankImports() {
|
|
173
|
+
// In package main and in tests, we don't complain about blank imports.
|
|
174
|
+
if f.main || f.isTest() {
|
|
175
|
+
return
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// The first element of each contiguous group of blank imports should have
|
|
179
|
+
// an explanatory comment of some kind.
|
|
180
|
+
for i, imp := range f.f.Imports {
|
|
181
|
+
pos := f.fset.Position(imp.Pos())
|
|
182
|
+
|
|
183
|
+
if !isBlank(imp.Name) {
|
|
184
|
+
continue // Ignore non-blank imports.
|
|
185
|
+
}
|
|
186
|
+
if i > 0 {
|
|
187
|
+
prev := f.f.Imports[i-1]
|
|
188
|
+
prevPos := f.fset.Position(prev.Pos())
|
|
189
|
+
if isBlank(prev.Name) && prevPos.Line+1 == pos.Line {
|
|
190
|
+
continue // A subsequent blank in a group.
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// This is the first blank import of a group.
|
|
195
|
+
if imp.Doc == nil && imp.Comment == nil {
|
|
196
|
+
link := ""
|
|
197
|
+
f.errorf(imp, 1, link, "a blank import should be only in a main or test package, or have a comment justifying it")
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// lintImports examines import blocks.
|
|
203
|
+
func (f *file) lintImports() {
|
|
204
|
+
|
|
205
|
+
for i, is := range f.f.Imports {
|
|
206
|
+
_ = i
|
|
207
|
+
if is.Name != nil && is.Name.Name == "." && !f.isTest() {
|
|
208
|
+
f.errorf(is, 1, styleGuideBase+"#Import_Dot", "should not use dot imports")
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const docCommentsLink = styleGuideBase + "#Doc_Comments"
|
|
216
|
+
|
|
217
|
+
// lintExported examines the doc comments of exported names.
|
|
218
|
+
// It complains if any required doc comments are missing,
|
|
219
|
+
// or if they are not of the right form. The exact rules are in
|
|
220
|
+
// lintFuncDoc, lintTypeDoc and lintValueSpecDoc; this function
|
|
221
|
+
// also tracks the GenDecl structure being traversed to permit
|
|
222
|
+
// doc comments for constants to be on top of the const block.
|
|
223
|
+
func (f *file) lintExported() {
|
|
224
|
+
if f.isTest() {
|
|
225
|
+
return
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
var lastGen *ast.GenDecl // last GenDecl entered.
|
|
229
|
+
|
|
230
|
+
// Set of GenDecls that have already had missing comments flagged.
|
|
231
|
+
genDeclMissingComments := make(map[*ast.GenDecl]bool)
|
|
232
|
+
|
|
233
|
+
f.walk(func(node ast.Node) bool {
|
|
234
|
+
switch v := node.(type) {
|
|
235
|
+
case *ast.GenDecl:
|
|
236
|
+
if v.Tok == token.IMPORT {
|
|
237
|
+
return false
|
|
238
|
+
}
|
|
239
|
+
// token.CONST, token.TYPE or token.VAR
|
|
240
|
+
lastGen = v
|
|
241
|
+
return true
|
|
242
|
+
case *ast.FuncDecl:
|
|
243
|
+
f.lintFuncDoc(v)
|
|
244
|
+
// Don't proceed inside funcs.
|
|
245
|
+
return false
|
|
246
|
+
case *ast.TypeSpec:
|
|
247
|
+
// inside a GenDecl, which usually has the doc
|
|
248
|
+
doc := v.Doc
|
|
249
|
+
if doc == nil {
|
|
250
|
+
doc = lastGen.Doc
|
|
251
|
+
}
|
|
252
|
+
f.lintTypeDoc(v, doc)
|
|
253
|
+
// Don't proceed inside types.
|
|
254
|
+
return false
|
|
255
|
+
case *ast.ValueSpec:
|
|
256
|
+
f.lintValueSpecDoc(v, lastGen, genDeclMissingComments)
|
|
257
|
+
return false
|
|
258
|
+
}
|
|
259
|
+
return true
|
|
260
|
+
})
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
var allCapsRE = regexp.MustCompile(`^[A-Z0-9_]+$`)
|
|
264
|
+
|
|
265
|
+
// lintNames examines all names in the file.
|
|
266
|
+
// It complains if any use underscores or incorrect known initialisms.
|
|
267
|
+
func (f *file) lintNames() {
|
|
268
|
+
// Package names need slightly different handling than other names.
|
|
269
|
+
if strings.Contains(f.f.Name.Name, "_") && !strings.HasSuffix(f.f.Name.Name, "_test") {
|
|
270
|
+
f.errorf(f.f, 1, "http://golang.org/doc/effective_go.html#package-names", "don't use an underscore in package name")
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
check := func(id *ast.Ident, thing string) {
|
|
274
|
+
if id.Name == "_" {
|
|
275
|
+
return
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Handle two common styles from other languages that don't belong in Go.
|
|
279
|
+
if len(id.Name) >= 5 && allCapsRE.MatchString(id.Name) && strings.Contains(id.Name, "_") {
|
|
280
|
+
f.errorf(id, 0.8, styleGuideBase+"#Mixed_Caps", "don't use ALL_CAPS in Go names; use CamelCase")
|
|
281
|
+
return
|
|
282
|
+
}
|
|
283
|
+
if len(id.Name) > 2 && id.Name[0] == 'k' && id.Name[1] >= 'A' && id.Name[1] <= 'Z' {
|
|
284
|
+
should := string(id.Name[1]+'a'-'A') + id.Name[2:]
|
|
285
|
+
f.errorf(id, 0.8, "", "don't use leading k in Go names; %s %s should be %s", thing, id.Name, should)
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
should := lintName(id.Name)
|
|
289
|
+
if id.Name == should {
|
|
290
|
+
return
|
|
291
|
+
}
|
|
292
|
+
if len(id.Name) > 2 && strings.Contains(id.Name[1:], "_") {
|
|
293
|
+
f.errorf(id, 0.9, "http://golang.org/doc/effective_go.html#mixed-caps", "don't use underscores in Go names; %s %s should be %s", thing, id.Name, should)
|
|
294
|
+
return
|
|
295
|
+
}
|
|
296
|
+
f.errorf(id, 0.8, styleGuideBase+"#Initialisms", "%s %s should be %s", thing, id.Name, should)
|
|
297
|
+
}
|
|
298
|
+
checkList := func(fl *ast.FieldList, thing string) {
|
|
299
|
+
if fl == nil {
|
|
300
|
+
return
|
|
301
|
+
}
|
|
302
|
+
for _, f := range fl.List {
|
|
303
|
+
for _, id := range f.Names {
|
|
304
|
+
check(id, thing)
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
f.walk(func(node ast.Node) bool {
|
|
309
|
+
switch v := node.(type) {
|
|
310
|
+
case *ast.AssignStmt:
|
|
311
|
+
if v.Tok == token.ASSIGN {
|
|
312
|
+
return true
|
|
313
|
+
}
|
|
314
|
+
for _, exp := range v.Lhs {
|
|
315
|
+
if id, ok := exp.(*ast.Ident); ok {
|
|
316
|
+
check(id, "var")
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
case *ast.FuncDecl:
|
|
320
|
+
if f.isTest() && (strings.HasPrefix(v.Name.Name, "Example") || strings.HasPrefix(v.Name.Name, "Test") || strings.HasPrefix(v.Name.Name, "Benchmark")) {
|
|
321
|
+
return true
|
|
322
|
+
}
|
|
323
|
+
check(v.Name, "func")
|
|
324
|
+
|
|
325
|
+
thing := "func"
|
|
326
|
+
if v.Recv != nil {
|
|
327
|
+
thing = "method"
|
|
328
|
+
}
|
|
329
|
+
checkList(v.Type.Params, thing+" parameter")
|
|
330
|
+
checkList(v.Type.Results, thing+" result")
|
|
331
|
+
case *ast.GenDecl:
|
|
332
|
+
if v.Tok == token.IMPORT {
|
|
333
|
+
return true
|
|
334
|
+
}
|
|
335
|
+
var thing string
|
|
336
|
+
switch v.Tok {
|
|
337
|
+
case token.CONST:
|
|
338
|
+
thing = "const"
|
|
339
|
+
case token.TYPE:
|
|
340
|
+
thing = "type"
|
|
341
|
+
case token.VAR:
|
|
342
|
+
thing = "var"
|
|
343
|
+
}
|
|
344
|
+
for _, spec := range v.Specs {
|
|
345
|
+
switch s := spec.(type) {
|
|
346
|
+
case *ast.TypeSpec:
|
|
347
|
+
check(s.Name, thing)
|
|
348
|
+
case *ast.ValueSpec:
|
|
349
|
+
for _, id := range s.Names {
|
|
350
|
+
check(id, thing)
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
case *ast.InterfaceType:
|
|
355
|
+
// Do not check interface method names.
|
|
356
|
+
// They are often constrainted by the method names of concrete types.
|
|
357
|
+
for _, x := range v.Methods.List {
|
|
358
|
+
ft, ok := x.Type.(*ast.FuncType)
|
|
359
|
+
if !ok { // might be an embedded interface name
|
|
360
|
+
continue
|
|
361
|
+
}
|
|
362
|
+
checkList(ft.Params, "interface method parameter")
|
|
363
|
+
checkList(ft.Results, "interface method result")
|
|
364
|
+
}
|
|
365
|
+
case *ast.RangeStmt:
|
|
366
|
+
if v.Tok == token.ASSIGN {
|
|
367
|
+
return true
|
|
368
|
+
}
|
|
369
|
+
if id, ok := v.Key.(*ast.Ident); ok {
|
|
370
|
+
check(id, "range var")
|
|
371
|
+
}
|
|
372
|
+
if id, ok := v.Value.(*ast.Ident); ok {
|
|
373
|
+
check(id, "range var")
|
|
374
|
+
}
|
|
375
|
+
case *ast.StructType:
|
|
376
|
+
for _, f := range v.Fields.List {
|
|
377
|
+
for _, id := range f.Names {
|
|
378
|
+
check(id, "struct field")
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return true
|
|
383
|
+
})
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// lintName returns a different name if it should be different.
|
|
387
|
+
func lintName(name string) (should string) {
|
|
388
|
+
// Fast path for simple cases: "_" and all lowercase.
|
|
389
|
+
if name == "_" {
|
|
390
|
+
return name
|
|
391
|
+
}
|
|
392
|
+
allLower := true
|
|
393
|
+
for _, r := range name {
|
|
394
|
+
if !unicode.IsLower(r) {
|
|
395
|
+
allLower = false
|
|
396
|
+
break
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
if allLower {
|
|
400
|
+
return name
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Split camelCase at any lower->upper transition, and split on underscores.
|
|
404
|
+
// Check each word for common initialisms.
|
|
405
|
+
runes := []rune(name)
|
|
406
|
+
w, i := 0, 0 // index of start of word, scan
|
|
407
|
+
for i+1 <= len(runes) {
|
|
408
|
+
eow := false // whether we hit the end of a word
|
|
409
|
+
if i+1 == len(runes) {
|
|
410
|
+
eow = true
|
|
411
|
+
} else if runes[i+1] == '_' {
|
|
412
|
+
// underscore; shift the remainder forward over any run of underscores
|
|
413
|
+
eow = true
|
|
414
|
+
n := 1
|
|
415
|
+
for i+n+1 < len(runes) && runes[i+n+1] == '_' {
|
|
416
|
+
n++
|
|
417
|
+
}
|
|
418
|
+
copy(runes[i+1:], runes[i+n+1:])
|
|
419
|
+
runes = runes[:len(runes)-n]
|
|
420
|
+
} else if unicode.IsLower(runes[i]) && !unicode.IsLower(runes[i+1]) {
|
|
421
|
+
// lower->non-lower
|
|
422
|
+
eow = true
|
|
423
|
+
}
|
|
424
|
+
i++
|
|
425
|
+
if !eow {
|
|
426
|
+
continue
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// [w,i) is a word.
|
|
430
|
+
word := string(runes[w:i])
|
|
431
|
+
if u := strings.ToUpper(word); commonInitialisms[u] {
|
|
432
|
+
// Keep consistent case, which is lowercase only at the start.
|
|
433
|
+
if w == 0 && unicode.IsLower(runes[w]) {
|
|
434
|
+
u = strings.ToLower(u)
|
|
435
|
+
}
|
|
436
|
+
// All the common initialisms are ASCII,
|
|
437
|
+
// so we can replace the bytes exactly.
|
|
438
|
+
copy(runes[w:], []rune(u))
|
|
439
|
+
} else if w > 0 && strings.ToLower(word) == word {
|
|
440
|
+
// already all lowercase, and not the first word, so uppercase the first character.
|
|
441
|
+
runes[w] = unicode.ToUpper(runes[w])
|
|
442
|
+
}
|
|
443
|
+
w = i
|
|
444
|
+
}
|
|
445
|
+
return string(runes)
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// commonInitialisms is a set of common initialisms.
|
|
449
|
+
// Only add entries that are highly unlikely to be non-initialisms.
|
|
450
|
+
// For instance, "ID" is fine (Freudian code is rare), but "AND" is not.
|
|
451
|
+
var commonInitialisms = map[string]bool{
|
|
452
|
+
"API": true,
|
|
453
|
+
"ASCII": true,
|
|
454
|
+
"CPU": true,
|
|
455
|
+
"CSS": true,
|
|
456
|
+
"DNS": true,
|
|
457
|
+
"EOF": true,
|
|
458
|
+
"HTML": true,
|
|
459
|
+
"HTTP": true,
|
|
460
|
+
"HTTPS": true,
|
|
461
|
+
"ID": true,
|
|
462
|
+
"IP": true,
|
|
463
|
+
"JSON": true,
|
|
464
|
+
"LHS": true,
|
|
465
|
+
"QPS": true,
|
|
466
|
+
"RAM": true,
|
|
467
|
+
"RHS": true,
|
|
468
|
+
"RPC": true,
|
|
469
|
+
"SLA": true,
|
|
470
|
+
"SSH": true,
|
|
471
|
+
"TLS": true,
|
|
472
|
+
"TTL": true,
|
|
473
|
+
"UI": true,
|
|
474
|
+
"UID": true,
|
|
475
|
+
"URL": true,
|
|
476
|
+
"UTF8": true,
|
|
477
|
+
"VM": true,
|
|
478
|
+
"XML": true,
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// lintTypeDoc examines the doc comment on a type.
|
|
482
|
+
// It complains if they are missing from an exported type,
|
|
483
|
+
// or if they are not of the standard form.
|
|
484
|
+
func (f *file) lintTypeDoc(t *ast.TypeSpec, doc *ast.CommentGroup) {
|
|
485
|
+
if !ast.IsExported(t.Name.Name) {
|
|
486
|
+
return
|
|
487
|
+
}
|
|
488
|
+
if doc == nil {
|
|
489
|
+
f.errorf(t, 1, docCommentsLink, "exported type %v should have comment or be unexported", t.Name)
|
|
490
|
+
return
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
s := doc.Text()
|
|
494
|
+
articles := [...]string{"A", "An", "The"}
|
|
495
|
+
for _, a := range articles {
|
|
496
|
+
if strings.HasPrefix(s, a+" ") {
|
|
497
|
+
s = s[len(a)+1:]
|
|
498
|
+
break
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
if !strings.HasPrefix(s, t.Name.Name+" ") {
|
|
502
|
+
f.errorf(doc, 1, docCommentsLink, `comment on exported type %v should be of the form "%v ..." (with optional leading article)`, t.Name, t.Name)
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
var commonMethods = map[string]bool{
|
|
507
|
+
"Error": true,
|
|
508
|
+
"Read": true,
|
|
509
|
+
"ServeHTTP": true,
|
|
510
|
+
"String": true,
|
|
511
|
+
"Write": true,
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// lintFuncDoc examines doc comments on functions and methods.
|
|
515
|
+
// It complains if they are missing, or not of the right form.
|
|
516
|
+
// It has specific exclusions for well-known methods (see commonMethods above).
|
|
517
|
+
func (f *file) lintFuncDoc(fn *ast.FuncDecl) {
|
|
518
|
+
if !ast.IsExported(fn.Name.Name) {
|
|
519
|
+
// func is unexported
|
|
520
|
+
return
|
|
521
|
+
}
|
|
522
|
+
kind := "function"
|
|
523
|
+
name := fn.Name.Name
|
|
524
|
+
if fn.Recv != nil {
|
|
525
|
+
// method
|
|
526
|
+
kind = "method"
|
|
527
|
+
recv := receiverType(fn)
|
|
528
|
+
if !ast.IsExported(recv) {
|
|
529
|
+
// receiver is unexported
|
|
530
|
+
return
|
|
531
|
+
}
|
|
532
|
+
if commonMethods[name] {
|
|
533
|
+
return
|
|
534
|
+
}
|
|
535
|
+
switch name {
|
|
536
|
+
case "Len", "Less", "Swap":
|
|
537
|
+
if f.sortable[recv] {
|
|
538
|
+
return
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
name = recv + "." + name
|
|
542
|
+
}
|
|
543
|
+
if fn.Doc == nil {
|
|
544
|
+
f.errorf(fn, 1, docCommentsLink, "exported %s %s should have comment or be unexported", kind, name)
|
|
545
|
+
return
|
|
546
|
+
}
|
|
547
|
+
s := fn.Doc.Text()
|
|
548
|
+
prefix := fn.Name.Name + " "
|
|
549
|
+
if !strings.HasPrefix(s, prefix) {
|
|
550
|
+
f.errorf(fn.Doc, 1, docCommentsLink, `comment on exported %s %s should be of the form "%s..."`, kind, name, prefix)
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
// lintValueSpecDoc examines package-global variables and constants.
|
|
555
|
+
// It complains if they are not individually declared,
|
|
556
|
+
// or if they are not suitably documented in the right form (unless they are in a block that is commented).
|
|
557
|
+
func (f *file) lintValueSpecDoc(vs *ast.ValueSpec, gd *ast.GenDecl, genDeclMissingComments map[*ast.GenDecl]bool) {
|
|
558
|
+
kind := "var"
|
|
559
|
+
if gd.Tok == token.CONST {
|
|
560
|
+
kind = "const"
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
if len(vs.Names) > 1 {
|
|
564
|
+
// Check that none are exported except for the first.
|
|
565
|
+
for _, n := range vs.Names[1:] {
|
|
566
|
+
if ast.IsExported(n.Name) {
|
|
567
|
+
f.errorf(vs, 1, "", "exported %s %s should have its own declaration", kind, n.Name)
|
|
568
|
+
return
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// Only one name.
|
|
574
|
+
name := vs.Names[0].Name
|
|
575
|
+
if !ast.IsExported(name) {
|
|
576
|
+
return
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
if vs.Doc == nil {
|
|
580
|
+
if gd.Doc == nil && !genDeclMissingComments[gd] {
|
|
581
|
+
block := ""
|
|
582
|
+
if kind == "const" && gd.Lparen.IsValid() {
|
|
583
|
+
block = " (or a comment on this block)"
|
|
584
|
+
}
|
|
585
|
+
f.errorf(vs, 1, docCommentsLink, "exported %s %s should have comment%s or be unexported", kind, name, block)
|
|
586
|
+
genDeclMissingComments[gd] = true
|
|
587
|
+
}
|
|
588
|
+
return
|
|
589
|
+
}
|
|
590
|
+
prefix := name + " "
|
|
591
|
+
if !strings.HasPrefix(vs.Doc.Text(), prefix) {
|
|
592
|
+
f.errorf(vs.Doc, 1, docCommentsLink, `comment on exported %s %s should be of the form "%s..."`, kind, name, prefix)
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
// zeroLiteral is a set of ast.BasicLit values that are zero values.
|
|
597
|
+
// It is not exhaustive.
|
|
598
|
+
var zeroLiteral = map[string]bool{
|
|
599
|
+
"false": true, // bool
|
|
600
|
+
// runes
|
|
601
|
+
`'\x00'`: true,
|
|
602
|
+
`'\000'`: true,
|
|
603
|
+
// strings
|
|
604
|
+
`""`: true,
|
|
605
|
+
"``": true,
|
|
606
|
+
// numerics
|
|
607
|
+
"0": true,
|
|
608
|
+
"0.": true,
|
|
609
|
+
"0.0": true,
|
|
610
|
+
"0i": true,
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
// lintVarDecls examines variable declarations. It complains about declarations with
|
|
614
|
+
// redundant LHS types that can be inferred from the RHS.
|
|
615
|
+
func (f *file) lintVarDecls() {
|
|
616
|
+
var lastGen *ast.GenDecl // last GenDecl entered.
|
|
617
|
+
|
|
618
|
+
f.walk(func(node ast.Node) bool {
|
|
619
|
+
switch v := node.(type) {
|
|
620
|
+
case *ast.GenDecl:
|
|
621
|
+
if v.Tok != token.CONST && v.Tok != token.VAR {
|
|
622
|
+
return false
|
|
623
|
+
}
|
|
624
|
+
lastGen = v
|
|
625
|
+
return true
|
|
626
|
+
case *ast.ValueSpec:
|
|
627
|
+
if lastGen.Tok == token.CONST {
|
|
628
|
+
return false
|
|
629
|
+
}
|
|
630
|
+
if len(v.Names) > 1 || v.Type == nil || len(v.Values) == 0 {
|
|
631
|
+
return false
|
|
632
|
+
}
|
|
633
|
+
rhs := v.Values[0]
|
|
634
|
+
// An underscore var appears in a common idiom for compile-time interface satisfaction,
|
|
635
|
+
// as in "var _ Interface = (*Concrete)(nil)".
|
|
636
|
+
if isIdent(v.Names[0], "_") {
|
|
637
|
+
return false
|
|
638
|
+
}
|
|
639
|
+
// If the RHS is a zero value, suggest dropping it.
|
|
640
|
+
zero := false
|
|
641
|
+
if lit, ok := rhs.(*ast.BasicLit); ok {
|
|
642
|
+
zero = zeroLiteral[lit.Value]
|
|
643
|
+
} else if isIdent(rhs, "nil") {
|
|
644
|
+
zero = true
|
|
645
|
+
}
|
|
646
|
+
if zero {
|
|
647
|
+
f.errorf(rhs, 0.9, "", "should drop = %s from declaration of var %s; it is the zero value", f.render(rhs), v.Names[0])
|
|
648
|
+
return false
|
|
649
|
+
}
|
|
650
|
+
// If the LHS type is an interface, don't warn, since it is probably a
|
|
651
|
+
// concrete type on the RHS. Note that our feeble lexical check here
|
|
652
|
+
// will only pick up interface{} and other literal interface types;
|
|
653
|
+
// that covers most of the cases we care to exclude right now.
|
|
654
|
+
// TODO(dsymonds): Use typechecker to make this heuristic more accurate.
|
|
655
|
+
if _, ok := v.Type.(*ast.InterfaceType); ok {
|
|
656
|
+
return false
|
|
657
|
+
}
|
|
658
|
+
// If the RHS is an untyped const, only warn if the LHS type is its default type.
|
|
659
|
+
if defType, ok := isUntypedConst(rhs); ok && !isIdent(v.Type, defType) {
|
|
660
|
+
return false
|
|
661
|
+
}
|
|
662
|
+
f.errorf(v.Type, 0.8, "", "should omit type %s from declaration of var %s; it will be inferred from the right-hand side", f.render(v.Type), v.Names[0])
|
|
663
|
+
return false
|
|
664
|
+
}
|
|
665
|
+
return true
|
|
666
|
+
})
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
// lintElses examines else blocks. It complains about any else block whose if block ends in a return.
|
|
670
|
+
func (f *file) lintElses() {
|
|
671
|
+
// We don't want to flag if { } else if { } else { } constructions.
|
|
672
|
+
// They will appear as an IfStmt whose Else field is also an IfStmt.
|
|
673
|
+
// Record such a node so we ignore it when we visit it.
|
|
674
|
+
ignore := make(map[*ast.IfStmt]bool)
|
|
675
|
+
|
|
676
|
+
f.walk(func(node ast.Node) bool {
|
|
677
|
+
ifStmt, ok := node.(*ast.IfStmt)
|
|
678
|
+
if !ok || ifStmt.Else == nil {
|
|
679
|
+
return true
|
|
680
|
+
}
|
|
681
|
+
if ignore[ifStmt] {
|
|
682
|
+
return true
|
|
683
|
+
}
|
|
684
|
+
if elseif, ok := ifStmt.Else.(*ast.IfStmt); ok {
|
|
685
|
+
ignore[elseif] = true
|
|
686
|
+
return true
|
|
687
|
+
}
|
|
688
|
+
if _, ok := ifStmt.Else.(*ast.BlockStmt); !ok {
|
|
689
|
+
// only care about elses without conditions
|
|
690
|
+
return true
|
|
691
|
+
}
|
|
692
|
+
if len(ifStmt.Body.List) == 0 {
|
|
693
|
+
return true
|
|
694
|
+
}
|
|
695
|
+
shortDecl := false // does the if statement have a ":=" initialization statement?
|
|
696
|
+
if ifStmt.Init != nil {
|
|
697
|
+
if as, ok := ifStmt.Init.(*ast.AssignStmt); ok && as.Tok == token.DEFINE {
|
|
698
|
+
shortDecl = true
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
lastStmt := ifStmt.Body.List[len(ifStmt.Body.List)-1]
|
|
702
|
+
if _, ok := lastStmt.(*ast.ReturnStmt); ok {
|
|
703
|
+
extra := ""
|
|
704
|
+
if shortDecl {
|
|
705
|
+
extra = " (move short variable declaration to its own line if necessary)"
|
|
706
|
+
}
|
|
707
|
+
f.errorf(ifStmt.Else, 1, styleGuideBase+"#Indent_Error_Flow", "if block ends with a return statement, so drop this else and outdent its block"+extra)
|
|
708
|
+
}
|
|
709
|
+
return true
|
|
710
|
+
})
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
// lintRanges examines range clauses. It complains about redundant constructions.
|
|
714
|
+
func (f *file) lintRanges() {
|
|
715
|
+
f.walk(func(node ast.Node) bool {
|
|
716
|
+
rs, ok := node.(*ast.RangeStmt)
|
|
717
|
+
if !ok {
|
|
718
|
+
return true
|
|
719
|
+
}
|
|
720
|
+
if rs.Value == nil {
|
|
721
|
+
// for x = range m { ... }
|
|
722
|
+
return true // single var form
|
|
723
|
+
}
|
|
724
|
+
if !isIdent(rs.Value, "_") {
|
|
725
|
+
// for ?, y = range m { ... }
|
|
726
|
+
return true
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
f.errorf(rs.Value, 1, "", "should omit 2nd value from range; this loop is equivalent to `for %s %s range ...`", f.render(rs.Key), rs.Tok)
|
|
730
|
+
return true
|
|
731
|
+
})
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
// lintErrorf examines errors.New calls. It complains if its only argument is an fmt.Sprintf invocation.
|
|
735
|
+
func (f *file) lintErrorf() {
|
|
736
|
+
f.walk(func(node ast.Node) bool {
|
|
737
|
+
ce, ok := node.(*ast.CallExpr)
|
|
738
|
+
if !ok {
|
|
739
|
+
return true
|
|
740
|
+
}
|
|
741
|
+
if !isPkgDot(ce.Fun, "errors", "New") || len(ce.Args) != 1 {
|
|
742
|
+
return true
|
|
743
|
+
}
|
|
744
|
+
arg := ce.Args[0]
|
|
745
|
+
ce, ok = arg.(*ast.CallExpr)
|
|
746
|
+
if !ok || !isPkgDot(ce.Fun, "fmt", "Sprintf") {
|
|
747
|
+
return true
|
|
748
|
+
}
|
|
749
|
+
f.errorf(node, 1, "", "should replace errors.New(fmt.Sprintf(...)) with fmt.Errorf(...)")
|
|
750
|
+
return true
|
|
751
|
+
})
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
// lintErrors examines global error vars. It complains if they aren't named in the standard way.
|
|
755
|
+
func (f *file) lintErrors() {
|
|
756
|
+
for _, decl := range f.f.Decls {
|
|
757
|
+
gd, ok := decl.(*ast.GenDecl)
|
|
758
|
+
if !ok || gd.Tok != token.VAR {
|
|
759
|
+
continue
|
|
760
|
+
}
|
|
761
|
+
for _, spec := range gd.Specs {
|
|
762
|
+
spec := spec.(*ast.ValueSpec)
|
|
763
|
+
if len(spec.Names) != 1 || len(spec.Values) != 1 {
|
|
764
|
+
continue
|
|
765
|
+
}
|
|
766
|
+
ce, ok := spec.Values[0].(*ast.CallExpr)
|
|
767
|
+
if !ok {
|
|
768
|
+
continue
|
|
769
|
+
}
|
|
770
|
+
if !isPkgDot(ce.Fun, "errors", "New") && !isPkgDot(ce.Fun, "fmt", "Errorf") {
|
|
771
|
+
continue
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
id := spec.Names[0]
|
|
775
|
+
prefix := "err"
|
|
776
|
+
if id.IsExported() {
|
|
777
|
+
prefix = "Err"
|
|
778
|
+
}
|
|
779
|
+
if !strings.HasPrefix(id.Name, prefix) {
|
|
780
|
+
f.errorf(id, 0.9, "", "error var %s should have name of the form %sFoo", id.Name, prefix)
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
func lintCapAndPunct(s string) (isCap, isPunct bool) {
|
|
787
|
+
first, firstN := utf8.DecodeRuneInString(s)
|
|
788
|
+
last, _ := utf8.DecodeLastRuneInString(s)
|
|
789
|
+
isPunct = last == '.' || last == ':' || last == '!'
|
|
790
|
+
isCap = unicode.IsUpper(first)
|
|
791
|
+
if isCap && len(s) > firstN {
|
|
792
|
+
// Don't flag strings starting with something that looks like an initialism.
|
|
793
|
+
if second, _ := utf8.DecodeRuneInString(s[firstN:]); unicode.IsUpper(second) {
|
|
794
|
+
isCap = false
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
return
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
// lintErrorStrings examines error strings. It complains if they are capitalized or end in punctuation.
|
|
801
|
+
func (f *file) lintErrorStrings() {
|
|
802
|
+
f.walk(func(node ast.Node) bool {
|
|
803
|
+
ce, ok := node.(*ast.CallExpr)
|
|
804
|
+
if !ok {
|
|
805
|
+
return true
|
|
806
|
+
}
|
|
807
|
+
if !isPkgDot(ce.Fun, "errors", "New") && !isPkgDot(ce.Fun, "fmt", "Errorf") {
|
|
808
|
+
return true
|
|
809
|
+
}
|
|
810
|
+
if len(ce.Args) < 1 {
|
|
811
|
+
return true
|
|
812
|
+
}
|
|
813
|
+
str, ok := ce.Args[0].(*ast.BasicLit)
|
|
814
|
+
if !ok || str.Kind != token.STRING {
|
|
815
|
+
return true
|
|
816
|
+
}
|
|
817
|
+
s, _ := strconv.Unquote(str.Value) // can assume well-formed Go
|
|
818
|
+
if s == "" {
|
|
819
|
+
return true
|
|
820
|
+
}
|
|
821
|
+
isCap, isPunct := lintCapAndPunct(s)
|
|
822
|
+
var msg string
|
|
823
|
+
switch {
|
|
824
|
+
case isCap && isPunct:
|
|
825
|
+
msg = "error strings should not be capitalized and should not end with punctuation"
|
|
826
|
+
case isCap:
|
|
827
|
+
msg = "error strings should not be capitalized"
|
|
828
|
+
case isPunct:
|
|
829
|
+
msg = "error strings should not end with punctuation"
|
|
830
|
+
default:
|
|
831
|
+
return true
|
|
832
|
+
}
|
|
833
|
+
// People use proper nouns and exported Go identifiers in error strings,
|
|
834
|
+
// so decrease the confidence of warnings for capitalization.
|
|
835
|
+
conf := 0.8
|
|
836
|
+
if isCap {
|
|
837
|
+
conf = 0.6
|
|
838
|
+
}
|
|
839
|
+
f.errorf(str, conf, styleGuideBase+"#Error_Strings", msg)
|
|
840
|
+
return true
|
|
841
|
+
})
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
var badReceiverNames = map[string]bool{
|
|
845
|
+
"me": true,
|
|
846
|
+
"this": true,
|
|
847
|
+
"self": true,
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
// lintReceiverNames examines receiver names. It complains about inconsistent
|
|
851
|
+
// names used for the same type and names such as "this".
|
|
852
|
+
func (f *file) lintReceiverNames() {
|
|
853
|
+
typeReceiver := map[string]string{}
|
|
854
|
+
f.walk(func(n ast.Node) bool {
|
|
855
|
+
fn, ok := n.(*ast.FuncDecl)
|
|
856
|
+
if !ok || fn.Recv == nil {
|
|
857
|
+
return true
|
|
858
|
+
}
|
|
859
|
+
names := fn.Recv.List[0].Names
|
|
860
|
+
if len(names) < 1 {
|
|
861
|
+
return true
|
|
862
|
+
}
|
|
863
|
+
name := names[0].Name
|
|
864
|
+
const link = styleGuideBase + "#Receiver_Names"
|
|
865
|
+
if name == "_" {
|
|
866
|
+
f.errorf(n, 1, link, `receiver name should not be an underscore`)
|
|
867
|
+
return true
|
|
868
|
+
}
|
|
869
|
+
if badReceiverNames[name] {
|
|
870
|
+
f.errorf(n, 1, link, `receiver name should be a reflection of its identity; don't use generic names such as "me", "this", or "self"`)
|
|
871
|
+
return true
|
|
872
|
+
}
|
|
873
|
+
recv := receiverType(fn)
|
|
874
|
+
if prev, ok := typeReceiver[recv]; ok && prev != name {
|
|
875
|
+
f.errorf(n, 1, link, "receiver name %s should be consistent with previous receiver name %s for %s", name, prev, recv)
|
|
876
|
+
return true
|
|
877
|
+
}
|
|
878
|
+
typeReceiver[recv] = name
|
|
879
|
+
return true
|
|
880
|
+
})
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
// lintIncDec examines statements that increment or decrement a variable.
|
|
884
|
+
// It complains if they don't use x++ or x--.
|
|
885
|
+
func (f *file) lintIncDec() {
|
|
886
|
+
f.walk(func(n ast.Node) bool {
|
|
887
|
+
as, ok := n.(*ast.AssignStmt)
|
|
888
|
+
if !ok {
|
|
889
|
+
return true
|
|
890
|
+
}
|
|
891
|
+
if len(as.Lhs) != 1 {
|
|
892
|
+
return true
|
|
893
|
+
}
|
|
894
|
+
if !isOne(as.Rhs[0]) {
|
|
895
|
+
return true
|
|
896
|
+
}
|
|
897
|
+
var suffix string
|
|
898
|
+
switch as.Tok {
|
|
899
|
+
case token.ADD_ASSIGN:
|
|
900
|
+
suffix = "++"
|
|
901
|
+
case token.SUB_ASSIGN:
|
|
902
|
+
suffix = "--"
|
|
903
|
+
default:
|
|
904
|
+
return true
|
|
905
|
+
}
|
|
906
|
+
f.errorf(as, 0.8, "", "should replace %s with %s%s", f.render(as), f.render(as.Lhs[0]), suffix)
|
|
907
|
+
return true
|
|
908
|
+
})
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
// lineMake examines statements that declare and initialize a variable with make.
|
|
912
|
+
// It complains if they are constructing a zero element slice.
|
|
913
|
+
func (f *file) lintMake() {
|
|
914
|
+
f.walk(func(n ast.Node) bool {
|
|
915
|
+
as, ok := n.(*ast.AssignStmt)
|
|
916
|
+
if !ok {
|
|
917
|
+
return true
|
|
918
|
+
}
|
|
919
|
+
// Only want single var := assignment statements.
|
|
920
|
+
if len(as.Lhs) != 1 || as.Tok != token.DEFINE {
|
|
921
|
+
return true
|
|
922
|
+
}
|
|
923
|
+
ce, ok := as.Rhs[0].(*ast.CallExpr)
|
|
924
|
+
if !ok {
|
|
925
|
+
return true
|
|
926
|
+
}
|
|
927
|
+
// Check if ce is make([]T, 0).
|
|
928
|
+
if !isIdent(ce.Fun, "make") || len(ce.Args) != 2 || !isZero(ce.Args[1]) {
|
|
929
|
+
return true
|
|
930
|
+
}
|
|
931
|
+
at, ok := ce.Args[0].(*ast.ArrayType)
|
|
932
|
+
if !ok || at.Len != nil {
|
|
933
|
+
return true
|
|
934
|
+
}
|
|
935
|
+
f.errorf(as, 0.8, "", `can probably use "var %s %s" instead`, f.render(as.Lhs[0]), f.render(at))
|
|
936
|
+
return true
|
|
937
|
+
})
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
func receiverType(fn *ast.FuncDecl) string {
|
|
941
|
+
switch e := fn.Recv.List[0].Type.(type) {
|
|
942
|
+
case *ast.Ident:
|
|
943
|
+
return e.Name
|
|
944
|
+
case *ast.StarExpr:
|
|
945
|
+
return e.X.(*ast.Ident).Name
|
|
946
|
+
}
|
|
947
|
+
panic(fmt.Sprintf("unknown method receiver AST node type %T", fn.Recv.List[0].Type))
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
func (f *file) walk(fn func(ast.Node) bool) {
|
|
951
|
+
ast.Walk(walker(fn), f.f)
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
func (f *file) render(x interface{}) string {
|
|
955
|
+
var buf bytes.Buffer
|
|
956
|
+
if err := printer.Fprint(&buf, f.fset, x); err != nil {
|
|
957
|
+
panic(err)
|
|
958
|
+
}
|
|
959
|
+
return buf.String()
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
func (f *file) debugRender(x interface{}) string {
|
|
963
|
+
var buf bytes.Buffer
|
|
964
|
+
if err := ast.Fprint(&buf, f.fset, x, nil); err != nil {
|
|
965
|
+
panic(err)
|
|
966
|
+
}
|
|
967
|
+
return buf.String()
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
// walker adapts a function to satisfy the ast.Visitor interface.
|
|
971
|
+
// The function return whether the walk should proceed into the node's children.
|
|
972
|
+
type walker func(ast.Node) bool
|
|
973
|
+
|
|
974
|
+
func (w walker) Visit(node ast.Node) ast.Visitor {
|
|
975
|
+
if w(node) {
|
|
976
|
+
return w
|
|
977
|
+
}
|
|
978
|
+
return nil
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
func isIdent(expr ast.Expr, ident string) bool {
|
|
982
|
+
id, ok := expr.(*ast.Ident)
|
|
983
|
+
return ok && id.Name == ident
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
// isBlank returns whether id is the blank identifier "_".
|
|
987
|
+
// If id == nil, the answer is false.
|
|
988
|
+
func isBlank(id *ast.Ident) bool { return id != nil && id.Name == "_" }
|
|
989
|
+
|
|
990
|
+
func isPkgDot(expr ast.Expr, pkg, name string) bool {
|
|
991
|
+
sel, ok := expr.(*ast.SelectorExpr)
|
|
992
|
+
return ok && isIdent(sel.X, pkg) && isIdent(sel.Sel, name)
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
func isZero(expr ast.Expr) bool {
|
|
996
|
+
lit, ok := expr.(*ast.BasicLit)
|
|
997
|
+
return ok && lit.Kind == token.INT && lit.Value == "0"
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
func isOne(expr ast.Expr) bool {
|
|
1001
|
+
lit, ok := expr.(*ast.BasicLit)
|
|
1002
|
+
return ok && lit.Kind == token.INT && lit.Value == "1"
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
var basicLitKindTypes = map[token.Token]string{
|
|
1006
|
+
token.FLOAT: "float64",
|
|
1007
|
+
token.IMAG: "complex128",
|
|
1008
|
+
token.CHAR: "rune",
|
|
1009
|
+
token.STRING: "string",
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
// isUntypedConst reports whether expr is an untyped constant,
|
|
1013
|
+
// and indicates what its default type is.
|
|
1014
|
+
func isUntypedConst(expr ast.Expr) (defType string, ok bool) {
|
|
1015
|
+
if isIntLiteral(expr) {
|
|
1016
|
+
return "int", true
|
|
1017
|
+
}
|
|
1018
|
+
if bl, ok := expr.(*ast.BasicLit); ok {
|
|
1019
|
+
if dt, ok := basicLitKindTypes[bl.Kind]; ok {
|
|
1020
|
+
return dt, true
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
return "", false
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
func isIntLiteral(expr ast.Expr) bool {
|
|
1027
|
+
// Either a BasicLit with Kind token.INT,
|
|
1028
|
+
// or some combination of a UnaryExpr with Op token.SUB (for "-<lit>")
|
|
1029
|
+
// or a ParenExpr (for "(<lit>)").
|
|
1030
|
+
Loop:
|
|
1031
|
+
for {
|
|
1032
|
+
switch v := expr.(type) {
|
|
1033
|
+
case *ast.UnaryExpr:
|
|
1034
|
+
if v.Op == token.SUB {
|
|
1035
|
+
expr = v.X
|
|
1036
|
+
continue Loop
|
|
1037
|
+
}
|
|
1038
|
+
case *ast.ParenExpr:
|
|
1039
|
+
expr = v.X
|
|
1040
|
+
continue Loop
|
|
1041
|
+
case *ast.BasicLit:
|
|
1042
|
+
if v.Kind == token.INT {
|
|
1043
|
+
return true
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
return false
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
// srcLine returns the complete line at p, including the terminating newline.
|
|
1051
|
+
func srcLine(src []byte, p token.Position) string {
|
|
1052
|
+
// Run to end of line in both directions if not at line start/end.
|
|
1053
|
+
lo, hi := p.Offset, p.Offset+1
|
|
1054
|
+
for lo > 0 && src[lo-1] != '\n' {
|
|
1055
|
+
lo--
|
|
1056
|
+
}
|
|
1057
|
+
for hi < len(src) && src[hi-1] != '\n' {
|
|
1058
|
+
hi++
|
|
1059
|
+
}
|
|
1060
|
+
return string(src[lo:hi])
|
|
1061
|
+
}
|