did_you_mean 0.9.6-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +27 -0
- data/.travis.yml +35 -0
- data/Appraisals +23 -0
- data/Gemfile +18 -0
- data/LICENSE.txt +22 -0
- data/README.md +110 -0
- data/Rakefile +61 -0
- data/did_you_mean.gemspec +35 -0
- data/ext/did_you_mean/extconf.rb +3 -0
- data/ext/did_you_mean/method_missing.c +20 -0
- data/ext/did_you_mean/org/yukinishijima/ReceiverCapturer.java +57 -0
- data/gemfiles/activerecord_32.gemfile +21 -0
- data/gemfiles/activerecord_40.gemfile +21 -0
- data/gemfiles/activerecord_41.gemfile +21 -0
- data/gemfiles/activerecord_42.gemfile +21 -0
- data/gemfiles/activerecord_edge.gemfile +25 -0
- data/lib/did_you_mean.rb +16 -0
- data/lib/did_you_mean/core_ext/name_error.rb +28 -0
- data/lib/did_you_mean/finders.rb +31 -0
- data/lib/did_you_mean/finders/name_error_finders.rb +24 -0
- data/lib/did_you_mean/finders/name_error_finders/similar_class_finder.rb +50 -0
- data/lib/did_you_mean/finders/name_error_finders/similar_name_finder.rb +61 -0
- data/lib/did_you_mean/finders/similar_attribute_finder.rb +26 -0
- data/lib/did_you_mean/finders/similar_method_finder.rb +45 -0
- data/lib/did_you_mean/levenshtein.rb +49 -0
- data/lib/did_you_mean/receiver_capturer.jar +0 -0
- data/lib/did_you_mean/test_helper.rb +7 -0
- data/lib/did_you_mean/version.rb +3 -0
- data/lib/did_you_mean/word_collection.rb +27 -0
- data/test/all_test.rb +17 -0
- data/test/name_error_extension_test.rb +65 -0
- data/test/no_method_error_extension_test.rb +14 -0
- data/test/null_finder_test.rb +19 -0
- data/test/similar_attribute_finder_test.rb +17 -0
- data/test/similar_class_finder_test.rb +85 -0
- data/test/similar_method_finder_test.rb +60 -0
- data/test/similar_name_finder_test.rb +62 -0
- data/test/test_helper.rb +32 -0
- metadata +165 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 13329e71de97d9e4cda167360459805c0db8c76c
|
4
|
+
data.tar.gz: 9d7a6935356b77b99b37b8b05bcb41484a75884f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: acf487a2a5b82bd13dff01e93ed33167684ffbcf1695aaefb46a19ff37ab3608a26c306641262ccb15dc25c1d9c0da58f3f852d9da7c9cad92cc94988cf3da45
|
7
|
+
data.tar.gz: 4ca91bcb998eb4b39abc3e49b0c1f13962977cb374d92dbf8f39fae4febe08bde1aeb2a3d377d1d72eb37a3f5b2e8d021b877df74f19e5e8a99b04ccd4ef03fc
|
data/.gitignore
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
.DS_Store
|
7
|
+
Gemfile.lock
|
8
|
+
gemfiles/*.lock
|
9
|
+
InstalledFiles
|
10
|
+
_yardoc
|
11
|
+
coverage
|
12
|
+
doc/
|
13
|
+
lib/bundler/man
|
14
|
+
pkg
|
15
|
+
rdoc
|
16
|
+
spec/reports
|
17
|
+
test/tmp
|
18
|
+
test/version_tmp
|
19
|
+
tmp
|
20
|
+
|
21
|
+
ext/**/*.o
|
22
|
+
ext/**/*.so
|
23
|
+
ext/**/Makefile
|
24
|
+
|
25
|
+
lib/**/*.so
|
26
|
+
|
27
|
+
.travis.yml.osx
|
data/.travis.yml
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
language: ruby
|
2
|
+
script: bundle exec rake test
|
3
|
+
cache: bundler
|
4
|
+
sudo: false
|
5
|
+
|
6
|
+
rvm:
|
7
|
+
- 1.9.3
|
8
|
+
- 2.0.0
|
9
|
+
- 2.1.5
|
10
|
+
- 2.2.0
|
11
|
+
- ruby-head
|
12
|
+
- jruby-1.7.17
|
13
|
+
- jruby-head
|
14
|
+
- rbx-2.4.1
|
15
|
+
|
16
|
+
gemfile:
|
17
|
+
- gemfiles/activerecord_32.gemfile
|
18
|
+
- gemfiles/activerecord_40.gemfile
|
19
|
+
- gemfiles/activerecord_41.gemfile
|
20
|
+
- gemfiles/activerecord_42.gemfile
|
21
|
+
- gemfiles/activerecord_edge.gemfile
|
22
|
+
|
23
|
+
matrix:
|
24
|
+
exclude:
|
25
|
+
- rvm: 1.9.3
|
26
|
+
gemfile: gemfiles/activerecord_edge.gemfile
|
27
|
+
- rvm: 2.0.0
|
28
|
+
gemfile: gemfiles/activerecord_edge.gemfile
|
29
|
+
- rvm: 2.1.5
|
30
|
+
gemfile: gemfiles/activerecord_edge.gemfile
|
31
|
+
allow_failures:
|
32
|
+
- rvm: jruby-head
|
33
|
+
- rvm: rbx-2.4.1
|
34
|
+
- gemfile: gemfiles/activerecord_edge.gemfile
|
35
|
+
fast_finish: true
|
data/Appraisals
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
appraise "activerecord_32" do
|
2
|
+
gem "activerecord", "~> 3.2.0"
|
3
|
+
end
|
4
|
+
|
5
|
+
appraise "activerecord_40" do
|
6
|
+
gem "activerecord", "~> 4.0.0"
|
7
|
+
end
|
8
|
+
|
9
|
+
appraise "activerecord_41" do
|
10
|
+
gem "activerecord", "~> 4.1.0"
|
11
|
+
end
|
12
|
+
|
13
|
+
appraise "activerecord_42" do
|
14
|
+
gem "activerecord", "~> 4.2.0"
|
15
|
+
end
|
16
|
+
|
17
|
+
appraise "activerecord_edge" do
|
18
|
+
git 'git://github.com/rails/rails.git' do
|
19
|
+
gem 'activerecord', require: 'activerecord'
|
20
|
+
end
|
21
|
+
|
22
|
+
gem 'arel', :github => 'rails/arel'
|
23
|
+
end
|
data/Gemfile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in did_you_mean.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
platforms :ruby do
|
7
|
+
gem 'sqlite3'
|
8
|
+
end
|
9
|
+
|
10
|
+
platforms :jruby do
|
11
|
+
gem 'activerecord-jdbcsqlite3-adapter'
|
12
|
+
end
|
13
|
+
|
14
|
+
platforms :rbx do
|
15
|
+
gem 'rubysl', '~> 2.0'
|
16
|
+
gem 'racc'
|
17
|
+
gem 'rubinius-developer_tools'
|
18
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Yuki Nishijima
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
# did_you_mean [![Gem Version](https://badge.fury.io/rb/did_you_mean.svg)](https://rubygems.org/gems/did_you_mean) [![Build Status](https://travis-ci.org/yuki24/did_you_mean.svg?branch=master)](https://travis-ci.org/yuki24/did_you_mean)
|
2
|
+
|
3
|
+
'Did you mean?' experience in Ruby. No, Really.
|
4
|
+
|
5
|
+
**For those who are still using 0.6.0, 0.7.0 and 0.8.0, please upgrade to 0.9.0 as they have a serious bug with Ruby 2.1.3 and 2.1.4 installed on Max OS X.**
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'did_you_mean', group: [:development, :test]
|
13
|
+
```
|
14
|
+
|
15
|
+
## Examples
|
16
|
+
|
17
|
+
### NameError
|
18
|
+
|
19
|
+
#### Correcting a Misspelled Method Name
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
class User
|
23
|
+
attr_accessor :first_name, :last_name
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
"#{f1rst_name} #{last_name}" # f1rst_name ???
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
user.to_s
|
31
|
+
# => NameError: undefined local variable or method `f1rst_name' for #<User:0x0000000928fad8>
|
32
|
+
#
|
33
|
+
# Did you mean? #first_name
|
34
|
+
#
|
35
|
+
```
|
36
|
+
|
37
|
+
#### Correcting a Misspelled Class Name
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
class Book
|
41
|
+
class TableOfContents
|
42
|
+
# ...
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
Book::TableofContents # TableofContents ???
|
47
|
+
# => NameError: uninitialized constant Book::TableofContents
|
48
|
+
#
|
49
|
+
# Did you mean? Book::TableOfContents
|
50
|
+
#
|
51
|
+
```
|
52
|
+
|
53
|
+
#### Suggesting an instance variable name
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
@full_name = "Yuki Nishijima"
|
57
|
+
first_name, last_name = full_name.split(" ")
|
58
|
+
# => NameError: undefined local variable or method `full_name' for main:Object
|
59
|
+
#
|
60
|
+
# Did you mean? @full_name
|
61
|
+
#
|
62
|
+
```
|
63
|
+
|
64
|
+
### NoMethodError
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
# In a Rails controller:
|
68
|
+
params.with_inddiferent_access
|
69
|
+
# => NoMethodError: undefined method `with_inddiferent_access' for {}:Hash
|
70
|
+
#
|
71
|
+
# Did you mean? #with_indifferent_access
|
72
|
+
#
|
73
|
+
```
|
74
|
+
|
75
|
+
### ActiveRecord::UnknownAttributeError
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
User.new(nmee: "wrong flrst name")
|
79
|
+
# => ActiveRecord::UnknownAttributeError: unknown attribute: nmee
|
80
|
+
#
|
81
|
+
# Did you mean? name: string
|
82
|
+
#
|
83
|
+
```
|
84
|
+
|
85
|
+
## 'Did You Mean' Experience is Everywhere
|
86
|
+
|
87
|
+
_did\_you\_mean_ gem automagically puts method suggestions into the error message. This means you'll have the "Did you mean?" experience almost everywhere:
|
88
|
+
|
89
|
+
![Did you mean? on BetterErrors](https://raw.githubusercontent.com/yuki24/did_you_mean/master/doc/did_you_mean_example.png)
|
90
|
+
|
91
|
+
## Support
|
92
|
+
|
93
|
+
_did\_you\_mean_ gem supports the following implementations:
|
94
|
+
|
95
|
+
* MRI 1.9.3, 2.0.0, 2.1.x, 2.2.0-preview1 and ruby-head
|
96
|
+
* JRuby (tested against 1.7.16)
|
97
|
+
|
98
|
+
Any other implementations are **NOT** supported (Rubinius support is work in progress).
|
99
|
+
|
100
|
+
## Contributing
|
101
|
+
|
102
|
+
1. Fork it (http://github.com/yuki24/did_you_mean/fork)
|
103
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
104
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
105
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
106
|
+
5. Create new Pull Request
|
107
|
+
|
108
|
+
## License
|
109
|
+
|
110
|
+
Copyright (c) 2014 Yuki Nishijima. See MIT-LICENSE for further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
|
3
|
+
def mri?
|
4
|
+
defined?(RUBY_ENGINE) && RUBY_ENGINE == "ruby"
|
5
|
+
end
|
6
|
+
|
7
|
+
def jruby?
|
8
|
+
defined?(JRuby)
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "run tests"
|
12
|
+
task default: [:test]
|
13
|
+
|
14
|
+
if mri? || jruby?
|
15
|
+
if mri?
|
16
|
+
require 'rake/extensiontask'
|
17
|
+
|
18
|
+
Rake::ExtensionTask.new('did_you_mean') do |ext|
|
19
|
+
ext.name = "method_missing"
|
20
|
+
ext.lib_dir = "lib/did_you_mean"
|
21
|
+
end
|
22
|
+
elsif jruby?
|
23
|
+
require 'rake/javaextensiontask'
|
24
|
+
|
25
|
+
Rake::JavaExtensionTask.new('did_you_mean') do |ext|
|
26
|
+
ext.name = "receiver_capturer"
|
27
|
+
ext.lib_dir = "lib/did_you_mean"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "Run tests"
|
32
|
+
task :test do
|
33
|
+
Rake::Task['compile'].reenable
|
34
|
+
Rake::Task['compile'].invoke
|
35
|
+
|
36
|
+
begin
|
37
|
+
$stdout.puts("\033[33m")
|
38
|
+
sh "bundle exec ruby test/all_test.rb"
|
39
|
+
ensure
|
40
|
+
$stdout.puts("\033[0m")
|
41
|
+
end
|
42
|
+
|
43
|
+
Rake::Task['clobber'].execute
|
44
|
+
end
|
45
|
+
|
46
|
+
namespace :test do
|
47
|
+
desc "Run tests without re-compiling extensions"
|
48
|
+
task :without_compile do
|
49
|
+
$stdout.puts("\033[33m")
|
50
|
+
sh "bundle exec ruby test/all_test.rb"
|
51
|
+
$stdout.puts("\033[0m")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
else # for Rubinius
|
55
|
+
desc "Run tests"
|
56
|
+
task :test do
|
57
|
+
$stdout.puts("\033[33m")
|
58
|
+
sh "bundle exec ruby test/all_test.rb"
|
59
|
+
$stdout.puts("\033[0m")
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'did_you_mean/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "did_you_mean"
|
8
|
+
spec.version = DidYouMean::VERSION
|
9
|
+
spec.authors = ["Yuki Nishijima"]
|
10
|
+
spec.email = ["mail@yukinishijima.net"]
|
11
|
+
spec.summary = '"Did you mean?" experience in Ruby'
|
12
|
+
spec.description = '"did you mean?" experience in Ruby: the error message will tell you the right one when you misspelled something.'
|
13
|
+
spec.homepage = "https://github.com/yuki24/did_you_mean"
|
14
|
+
spec.license = "MIT"
|
15
|
+
spec.files = `git ls-files`.split($/)
|
16
|
+
|
17
|
+
case RUBY_ENGINE
|
18
|
+
when 'ruby'
|
19
|
+
spec.extensions = ["ext/did_you_mean/extconf.rb"]
|
20
|
+
when 'jruby'
|
21
|
+
spec.platform = "java"
|
22
|
+
spec.files << "lib/did_you_mean/receiver_capturer.jar"
|
23
|
+
end
|
24
|
+
|
25
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
26
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
27
|
+
spec.require_paths = ["lib"]
|
28
|
+
|
29
|
+
spec.add_dependency "interception"
|
30
|
+
|
31
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
32
|
+
spec.add_development_dependency "rake"
|
33
|
+
spec.add_development_dependency "rake-compiler"
|
34
|
+
spec.add_development_dependency "minitest"
|
35
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
|
3
|
+
static const rb_data_type_t *type;
|
4
|
+
|
5
|
+
static VALUE
|
6
|
+
name_err_receiver(VALUE self)
|
7
|
+
{
|
8
|
+
VALUE *ptr, mesg = rb_attr_get(self, rb_intern("mesg"));
|
9
|
+
TypedData_Get_Struct(mesg, VALUE, type, ptr);
|
10
|
+
return ptr[1];
|
11
|
+
}
|
12
|
+
|
13
|
+
void
|
14
|
+
Init_method_missing()
|
15
|
+
{
|
16
|
+
VALUE err_mesg = rb_funcall(rb_cNameErrorMesg, '!', 3, Qnil, Qnil, Qnil);
|
17
|
+
type = RTYPEDDATA(err_mesg)->type;
|
18
|
+
|
19
|
+
rb_define_method(rb_eNameError, "receiver", name_err_receiver, 0);
|
20
|
+
}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
package org.yukinishijima;
|
2
|
+
|
3
|
+
import org.jruby.anno.JRubyMethod;
|
4
|
+
import org.jruby.exceptions.RaiseException;
|
5
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
6
|
+
import org.jruby.runtime.Block;
|
7
|
+
import org.jruby.runtime.ThreadContext;
|
8
|
+
import org.jruby.runtime.Visibility;
|
9
|
+
import org.jruby.Ruby;
|
10
|
+
import org.jruby.RubyArray;
|
11
|
+
import org.jruby.RubyException;
|
12
|
+
import org.jruby.RubyModule;
|
13
|
+
import org.jruby.RubyNoMethodError;
|
14
|
+
import org.jruby.internal.runtime.methods.CallConfiguration;
|
15
|
+
import org.jruby.internal.runtime.methods.DynamicMethod;
|
16
|
+
import org.jruby.internal.runtime.methods.JavaMethod.JavaMethodNBlock;
|
17
|
+
|
18
|
+
public class ReceiverCapturer extends JavaMethodNBlock {
|
19
|
+
private DynamicMethod methodMissingMethod;
|
20
|
+
|
21
|
+
public ReceiverCapturer(RubyModule implementationClass, DynamicMethod methodMissingMethod) {
|
22
|
+
super(implementationClass, Visibility.PRIVATE, CallConfiguration.FrameFullScopeNone);
|
23
|
+
this.methodMissingMethod = methodMissingMethod;
|
24
|
+
}
|
25
|
+
|
26
|
+
@Override
|
27
|
+
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args, Block block) {
|
28
|
+
try {
|
29
|
+
return this.methodMissingMethod.call(context, self, clazz, name, args, block);
|
30
|
+
} catch (RaiseException exception) {
|
31
|
+
appendReceiverToException(exception, self);
|
32
|
+
throw exception;
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
@JRubyMethod
|
37
|
+
public static void setup(Ruby runtime) {
|
38
|
+
RubyModule module = runtime.defineModule("Kernel");
|
39
|
+
|
40
|
+
DynamicMethod privateMethodMissing = runtime.getPrivateMethodMissing();
|
41
|
+
DynamicMethod protectedMethodMissing = runtime.getProtectedMethodMissing();
|
42
|
+
DynamicMethod superMethodMissing = runtime.getSuperMethodMissing();
|
43
|
+
DynamicMethod normalMethodMissing = runtime.getNormalMethodMissing();
|
44
|
+
|
45
|
+
runtime.setPrivateMethodMissing(new ReceiverCapturer(module, privateMethodMissing));
|
46
|
+
runtime.setProtectedMethodMissing(new ReceiverCapturer(module, protectedMethodMissing));
|
47
|
+
runtime.setSuperMethodMissing(new ReceiverCapturer(module, superMethodMissing));
|
48
|
+
runtime.setNormalMethodMissing(new ReceiverCapturer(module, normalMethodMissing));
|
49
|
+
}
|
50
|
+
|
51
|
+
private void appendReceiverToException(RaiseException exception, IRubyObject self) {
|
52
|
+
if (exception.getException() instanceof RubyNoMethodError) {
|
53
|
+
RubyNoMethodError noMethodError = (RubyNoMethodError) exception.getException();
|
54
|
+
noMethodError.setInstanceVariable("@receiver", self);
|
55
|
+
}
|
56
|
+
}
|
57
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "activerecord", "~> 3.2.0"
|
6
|
+
|
7
|
+
platforms :ruby do
|
8
|
+
gem "sqlite3"
|
9
|
+
end
|
10
|
+
|
11
|
+
platforms :jruby do
|
12
|
+
gem "activerecord-jdbcsqlite3-adapter"
|
13
|
+
end
|
14
|
+
|
15
|
+
platforms :rbx do
|
16
|
+
gem "rubysl", "~> 2.0"
|
17
|
+
gem "racc"
|
18
|
+
gem "rubinius-developer_tools"
|
19
|
+
end
|
20
|
+
|
21
|
+
gemspec :path => "../"
|