codemodels-ruby 0.1.5-java
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/Gemfile +3 -0
- data/README.md +6 -0
- data/Rakefile +13 -0
- data/codemodels-ruby.gemspec +33 -0
- data/lib/codemodels/ruby.rb +12 -0
- data/lib/codemodels/ruby/code.rb +14 -0
- data/lib/codemodels/ruby/info_extraction.rb +100 -0
- data/lib/codemodels/ruby/language.rb +17 -0
- data/lib/codemodels/ruby/metamodel.rb +481 -0
- data/lib/codemodels/ruby/model_building.rb +36 -0
- data/lib/codemodels/ruby/parser.rb +809 -0
- data/lib/codemodels/ruby/query.rb +25 -0
- data/lib/jars/com.google.collect_1.0.0.v201105210816.jar +0 -0
- data/lib/jars/com.google.inject_2.0.0.v201105231817.jar +0 -0
- data/lib/jars/com.ibm.icu_4.4.2.v20110208.jar +0 -0
- data/lib/jars/org.apache.commons.lang_2.4.0.v201005080502.jar +0 -0
- data/lib/jars/org.apache.commons.logging_1.1.1.jar +0 -0
- data/lib/jars/org.apache.log4j_1.2.16.jar +0 -0
- data/lib/jars/org.eclipse.core.runtime.compatibility_3.2.100.v20100505.jar +0 -0
- data/lib/jars/org.eclipse.core.runtime_3.7.0.v20110110.jar +0 -0
- data/test/data/012_add_comments_permissions.rb +14 -0
- data/test/data/darcs_adapter.rb +242 -0
- data/test/data/example_of_complex_class.rb +157 -0
- data/test/data/issues_helper_test.rb +271 -0
- data/test/data/status_test.rb +14 -0
- data/test/data/user_custom_field.rb +23 -0
- data/test/helper.rb +87 -0
- data/test/test_assignments.rb +14 -0
- data/test/test_blocks.rb +102 -0
- data/test/test_constants.rb +14 -0
- data/test/test_exception_handling.rb +35 -0
- data/test/test_info.rb +52 -0
- data/test/test_logic.rb +61 -0
- data/test/test_metamodel.rb +70 -0
- data/test/test_modules_and_classes.rb +81 -0
- data/test/test_not_variable_assignements.rb +75 -0
- data/test/test_operations.rb +440 -0
- data/test/test_parsing_complex.rb +49 -0
- data/test/test_parsing_literals.rb +92 -0
- data/test/test_statements.rb +169 -0
- data/test/test_terms_extraction.rb +240 -0
- data/test/test_values_extraction.rb +102 -0
- data/test/test_variables.rb +81 -0
- metadata +272 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
module CodeModels
|
2
|
+
|
3
|
+
module Ruby
|
4
|
+
|
5
|
+
def self.is_call(node,name=nil,args=nil)
|
6
|
+
return false unless node.is_a? Ruby::Call
|
7
|
+
return false if name and node.name!=name
|
8
|
+
if args
|
9
|
+
return false if args.count != node.args.count
|
10
|
+
for i in 0..(args.count-1)
|
11
|
+
return false unless args[i].eql?(node.args[i])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.is_def(node,name=nil)
|
18
|
+
return false unless node.is_a? Ruby::Def
|
19
|
+
return false if name and node.name!=name
|
20
|
+
true
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class AddCommentsPermissions < ActiveRecord::Migration
|
2
|
+
# model removed
|
3
|
+
class Permission < ActiveRecord::Base; end
|
4
|
+
|
5
|
+
def self.up
|
6
|
+
Permission.create :controller => "news", :action => "add_comment", :description => "label_comment_add", :sort => 1130, :is_public => false, :mail_option => 0, :mail_enabled => 0
|
7
|
+
Permission.create :controller => "news", :action => "destroy_comment", :description => "label_comment_delete", :sort => 1133, :is_public => false, :mail_option => 0, :mail_enabled => 0
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.down
|
11
|
+
Permission.where("controller=? and action=?", 'news', 'add_comment').first.destroy
|
12
|
+
Permission.where("controller=? and action=?", 'news', 'destroy_comment').first.destroy
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,242 @@
|
|
1
|
+
# Redmine - project management software
|
2
|
+
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
3
|
+
#
|
4
|
+
# This program is free software; you can redistribute it and/or
|
5
|
+
# modify it under the terms of the GNU General Public License
|
6
|
+
# as published by the Free Software Foundation; either version 2
|
7
|
+
# of the License, or (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program; if not, write to the Free Software
|
16
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
17
|
+
|
18
|
+
require 'redmine/scm/adapters/abstract_adapter'
|
19
|
+
require 'rexml/document'
|
20
|
+
|
21
|
+
module Redmine
|
22
|
+
module Scm
|
23
|
+
module Adapters
|
24
|
+
class DarcsAdapter < AbstractAdapter
|
25
|
+
# Darcs executable name
|
26
|
+
DARCS_BIN = Redmine::Configuration['scm_darcs_command'] || "darcs"
|
27
|
+
|
28
|
+
class << self
|
29
|
+
def client_command
|
30
|
+
@@bin ||= DARCS_BIN
|
31
|
+
end
|
32
|
+
|
33
|
+
def sq_bin
|
34
|
+
@@sq_bin ||= shell_quote_command
|
35
|
+
end
|
36
|
+
|
37
|
+
def client_version
|
38
|
+
@@client_version ||= (darcs_binary_version || [])
|
39
|
+
end
|
40
|
+
|
41
|
+
def client_available
|
42
|
+
!client_version.empty?
|
43
|
+
end
|
44
|
+
|
45
|
+
def darcs_binary_version
|
46
|
+
darcsversion = darcs_binary_version_from_command_line.dup
|
47
|
+
if darcsversion.respond_to?(:force_encoding)
|
48
|
+
darcsversion.force_encoding('ASCII-8BIT')
|
49
|
+
end
|
50
|
+
if m = darcsversion.match(%r{\A(.*?)((\d+\.)+\d+)})
|
51
|
+
m[2].scan(%r{\d+}).collect(&:to_i)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def darcs_binary_version_from_command_line
|
56
|
+
shellout("#{sq_bin} --version") { |io| io.read }.to_s
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def initialize(url, root_url=nil, login=nil, password=nil,
|
61
|
+
path_encoding=nil)
|
62
|
+
@url = url
|
63
|
+
@root_url = url
|
64
|
+
end
|
65
|
+
|
66
|
+
def supports_cat?
|
67
|
+
# cat supported in darcs 2.0.0 and higher
|
68
|
+
self.class.client_version_above?([2, 0, 0])
|
69
|
+
end
|
70
|
+
|
71
|
+
# Get info about the darcs repository
|
72
|
+
def info
|
73
|
+
rev = revisions(nil,nil,nil,{:limit => 1})
|
74
|
+
rev ? Info.new({:root_url => @url, :lastrev => rev.last}) : nil
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns an Entries collection
|
78
|
+
# or nil if the given path doesn't exist in the repository
|
79
|
+
def entries(path=nil, identifier=nil, options={})
|
80
|
+
path_prefix = (path.blank? ? '' : "#{path}/")
|
81
|
+
if path.blank?
|
82
|
+
path = ( self.class.client_version_above?([2, 2, 0]) ? @url : '.' )
|
83
|
+
end
|
84
|
+
entries = Entries.new
|
85
|
+
cmd = "#{self.class.sq_bin} annotate --repodir #{shell_quote @url} --xml-output"
|
86
|
+
cmd << " --match #{shell_quote("hash #{identifier}")}" if identifier
|
87
|
+
cmd << " #{shell_quote path}"
|
88
|
+
shellout(cmd) do |io|
|
89
|
+
begin
|
90
|
+
doc = REXML::Document.new(io)
|
91
|
+
if doc.root.name == 'directory'
|
92
|
+
doc.elements.each('directory/*') do |element|
|
93
|
+
next unless ['file', 'directory'].include? element.name
|
94
|
+
entries << entry_from_xml(element, path_prefix)
|
95
|
+
end
|
96
|
+
elsif doc.root.name == 'file'
|
97
|
+
entries << entry_from_xml(doc.root, path_prefix)
|
98
|
+
end
|
99
|
+
rescue
|
100
|
+
end
|
101
|
+
end
|
102
|
+
return nil if $? && $?.exitstatus != 0
|
103
|
+
entries.compact!
|
104
|
+
entries.sort_by_name
|
105
|
+
end
|
106
|
+
|
107
|
+
def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
|
108
|
+
path = '.' if path.blank?
|
109
|
+
revisions = Revisions.new
|
110
|
+
cmd = "#{self.class.sq_bin} changes --repodir #{shell_quote @url} --xml-output"
|
111
|
+
cmd << " --from-match #{shell_quote("hash #{identifier_from}")}" if identifier_from
|
112
|
+
cmd << " --last #{options[:limit].to_i}" if options[:limit]
|
113
|
+
shellout(cmd) do |io|
|
114
|
+
begin
|
115
|
+
doc = REXML::Document.new(io)
|
116
|
+
doc.elements.each("changelog/patch") do |patch|
|
117
|
+
message = patch.elements['name'].text
|
118
|
+
message << "\n" + patch.elements['comment'].text.gsub(/\*\*\*END OF DESCRIPTION\*\*\*.*\z/m, '') if patch.elements['comment']
|
119
|
+
revisions << Revision.new({:identifier => nil,
|
120
|
+
:author => patch.attributes['author'],
|
121
|
+
:scmid => patch.attributes['hash'],
|
122
|
+
:time => Time.parse(patch.attributes['local_date']),
|
123
|
+
:message => message,
|
124
|
+
:paths => (options[:with_path] ? get_paths_for_patch(patch.attributes['hash']) : nil)
|
125
|
+
})
|
126
|
+
end
|
127
|
+
rescue
|
128
|
+
end
|
129
|
+
end
|
130
|
+
return nil if $? && $?.exitstatus != 0
|
131
|
+
revisions
|
132
|
+
end
|
133
|
+
|
134
|
+
def diff(path, identifier_from, identifier_to=nil)
|
135
|
+
path = '*' if path.blank?
|
136
|
+
cmd = "#{self.class.sq_bin} diff --repodir #{shell_quote @url}"
|
137
|
+
if identifier_to.nil?
|
138
|
+
cmd << " --match #{shell_quote("hash #{identifier_from}")}"
|
139
|
+
else
|
140
|
+
cmd << " --to-match #{shell_quote("hash #{identifier_from}")}"
|
141
|
+
cmd << " --from-match #{shell_quote("hash #{identifier_to}")}"
|
142
|
+
end
|
143
|
+
cmd << " -u #{shell_quote path}"
|
144
|
+
diff = []
|
145
|
+
shellout(cmd) do |io|
|
146
|
+
io.each_line do |line|
|
147
|
+
diff << line
|
148
|
+
end
|
149
|
+
end
|
150
|
+
return nil if $? && $?.exitstatus != 0
|
151
|
+
diff
|
152
|
+
end
|
153
|
+
|
154
|
+
def cat(path, identifier=nil)
|
155
|
+
cmd = "#{self.class.sq_bin} show content --repodir #{shell_quote @url}"
|
156
|
+
cmd << " --match #{shell_quote("hash #{identifier}")}" if identifier
|
157
|
+
cmd << " #{shell_quote path}"
|
158
|
+
cat = nil
|
159
|
+
shellout(cmd) do |io|
|
160
|
+
io.binmode
|
161
|
+
cat = io.read
|
162
|
+
end
|
163
|
+
return nil if $? && $?.exitstatus != 0
|
164
|
+
cat
|
165
|
+
end
|
166
|
+
|
167
|
+
private
|
168
|
+
|
169
|
+
# Returns an Entry from the given XML element
|
170
|
+
# or nil if the entry was deleted
|
171
|
+
def entry_from_xml(element, path_prefix)
|
172
|
+
modified_element = element.elements['modified']
|
173
|
+
if modified_element.elements['modified_how'].text.match(/removed/)
|
174
|
+
return nil
|
175
|
+
end
|
176
|
+
|
177
|
+
Entry.new({:name => element.attributes['name'],
|
178
|
+
:path => path_prefix + element.attributes['name'],
|
179
|
+
:kind => element.name == 'file' ? 'file' : 'dir',
|
180
|
+
:size => nil,
|
181
|
+
:lastrev => Revision.new({
|
182
|
+
:identifier => nil,
|
183
|
+
:scmid => modified_element.elements['patch'].attributes['hash']
|
184
|
+
})
|
185
|
+
})
|
186
|
+
end
|
187
|
+
|
188
|
+
def get_paths_for_patch(hash)
|
189
|
+
paths = get_paths_for_patch_raw(hash)
|
190
|
+
if self.class.client_version_above?([2, 4])
|
191
|
+
orig_paths = paths
|
192
|
+
paths = []
|
193
|
+
add_paths = []
|
194
|
+
add_paths_name = []
|
195
|
+
mod_paths = []
|
196
|
+
other_paths = []
|
197
|
+
orig_paths.each do |path|
|
198
|
+
if path[:action] == 'A'
|
199
|
+
add_paths << path
|
200
|
+
add_paths_name << path[:path]
|
201
|
+
elsif path[:action] == 'M'
|
202
|
+
mod_paths << path
|
203
|
+
else
|
204
|
+
other_paths << path
|
205
|
+
end
|
206
|
+
end
|
207
|
+
add_paths_name.each do |add_path|
|
208
|
+
mod_paths.delete_if { |m| m[:path] == add_path }
|
209
|
+
end
|
210
|
+
paths.concat add_paths
|
211
|
+
paths.concat mod_paths
|
212
|
+
paths.concat other_paths
|
213
|
+
end
|
214
|
+
paths
|
215
|
+
end
|
216
|
+
|
217
|
+
# Retrieve changed paths for a single patch
|
218
|
+
def get_paths_for_patch_raw(hash)
|
219
|
+
cmd = "#{self.class.sq_bin} annotate --repodir #{shell_quote @url} --summary --xml-output"
|
220
|
+
cmd << " --match #{shell_quote("hash #{hash}")} "
|
221
|
+
paths = []
|
222
|
+
shellout(cmd) do |io|
|
223
|
+
begin
|
224
|
+
# Darcs xml output has multiple root elements in this case (tested with darcs 1.0.7)
|
225
|
+
# A root element is added so that REXML doesn't raise an error
|
226
|
+
doc = REXML::Document.new("<fake_root>" + io.read + "</fake_root>")
|
227
|
+
doc.elements.each('fake_root/summary/*') do |modif|
|
228
|
+
paths << {:action => modif.name[0,1].upcase,
|
229
|
+
:path => "/" + modif.text.chomp.gsub(/^\s*/, '')
|
230
|
+
}
|
231
|
+
end
|
232
|
+
rescue
|
233
|
+
end
|
234
|
+
end
|
235
|
+
paths
|
236
|
+
rescue CommandFailed
|
237
|
+
paths
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'ruby-lightmodels'
|
5
|
+
|
6
|
+
class TestOperations < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def test_symbol
|
9
|
+
root = Ruby.parse(':a')
|
10
|
+
|
11
|
+
assert_right_class root, Ruby::Symbol
|
12
|
+
assert_equal 'a',root.name
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_sum
|
16
|
+
root = Ruby.parse('3+40')
|
17
|
+
|
18
|
+
assert_right_class root, Ruby::Call
|
19
|
+
assert_equal '+', root.name
|
20
|
+
assert_is_int root.receiver, 3
|
21
|
+
assert_equal false, root.implicit_receiver
|
22
|
+
assert_equal 1, root.args.count
|
23
|
+
assert_is_int root.args[0], 40
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_def_with_some_statements
|
27
|
+
root = Ruby.parse("def somefunc \n 1\n 2\n 3\n end")
|
28
|
+
|
29
|
+
assert_right_class root, Ruby::Def
|
30
|
+
assert_equal 'somefunc', root.name
|
31
|
+
assert root.body.is_a? Ruby::Block
|
32
|
+
assert_equal 3,root.body.contents.count
|
33
|
+
assert_is_int root.body.contents[0], 1
|
34
|
+
assert_is_int root.body.contents[1], 2
|
35
|
+
assert_is_int root.body.contents[2], 3
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_def_with_one_statements
|
39
|
+
root = Ruby.parse("def somefunc \n 10\n end")
|
40
|
+
|
41
|
+
assert_right_class root, Ruby::Def
|
42
|
+
assert_equal 'somefunc', root.name
|
43
|
+
assert_is_int root.body, 10
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_require
|
47
|
+
root = Ruby.parse("require 'something'")
|
48
|
+
|
49
|
+
assert_right_class root, Ruby::Call
|
50
|
+
assert_equal 'require', root.name
|
51
|
+
assert_equal true, root.implicit_receiver
|
52
|
+
assert_equal 1, root.args.count
|
53
|
+
assert_is_str root.args[0],'something'
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_class_decl_ext_class_in_module
|
57
|
+
root = Ruby.parse("class TestOperations < Test::Unit::TestCase\nend")
|
58
|
+
|
59
|
+
assert_right_class root, Ruby::ClassDecl
|
60
|
+
assert_right_class root.super_class,Ruby::Constant
|
61
|
+
assert_equal 'TestCase', root.super_class.name
|
62
|
+
assert_right_class root.super_class.container,Ruby::Constant
|
63
|
+
assert_equal 'Unit', root.super_class.container.name
|
64
|
+
assert_right_class root.super_class.container.container,Ruby::Constant
|
65
|
+
assert_equal 'Test', root.super_class.container.container.name
|
66
|
+
assert_equal nil, root.super_class.container.container.container
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_class_decl_ext_class_simple
|
70
|
+
root = Ruby.parse("class Literal < Value\nend")
|
71
|
+
|
72
|
+
assert_right_class root, Ruby::ClassDecl
|
73
|
+
assert_equal 'Value', root.super_class.name
|
74
|
+
assert_equal nil,root.super_class.container
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_class_decl_no_ext
|
78
|
+
root = Ruby.parse("class Literal\nend")
|
79
|
+
|
80
|
+
assert_right_class root, Ruby::ClassDecl
|
81
|
+
assert_equal nil,root.super_class
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_class_with_content
|
85
|
+
root = Ruby.parse("class AClass\nattr_accessor :name\nend")
|
86
|
+
|
87
|
+
assert_right_class root, Ruby::ClassDecl
|
88
|
+
assert_equal nil,root.super_class
|
89
|
+
assert_simple_const root.defname,'AClass'
|
90
|
+
assert_equal 1,root.body.count
|
91
|
+
assert_right_class root.body[0], Ruby::Call
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_false
|
95
|
+
root = Ruby.parse('false')
|
96
|
+
|
97
|
+
assert_right_class root, Ruby::BooleanLiteral
|
98
|
+
assert_equal false,root.value
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_dstring
|
102
|
+
root = Ruby.parse("\"some string\"")
|
103
|
+
|
104
|
+
assert_right_class root, Ruby::StringLiteral
|
105
|
+
assert_equal 'some string', root.value
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_dstring_with_value
|
109
|
+
root = Ruby.parse('"some #{val} string"')
|
110
|
+
|
111
|
+
assert_right_class root, Ruby::StringLiteral
|
112
|
+
assert_equal 3, root.pieces.count
|
113
|
+
assert_is_str root.pieces[0],'some '
|
114
|
+
assert_is_str root.pieces[2],' string'
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_true
|
118
|
+
root = Ruby.parse('true')
|
119
|
+
|
120
|
+
assert_right_class root, Ruby::BooleanLiteral
|
121
|
+
assert_equal true,root.value
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_nil
|
125
|
+
root = Ruby.parse('nil')
|
126
|
+
|
127
|
+
assert_right_class root, Ruby::NilLiteral
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_load_this_file
|
131
|
+
content = s = IO.read(__FILE__)
|
132
|
+
#root = Ruby.parse(content)
|
133
|
+
|
134
|
+
# check no exceptions are generated...
|
135
|
+
end
|
136
|
+
|
137
|
+
def assert_is_int(node,value)
|
138
|
+
assert node.is_a? Ruby::IntLiteral
|
139
|
+
assert_equal value, node.value
|
140
|
+
end
|
141
|
+
|
142
|
+
def assert_is_str(node,value)
|
143
|
+
assert node.is_a? Ruby::StringLiteral
|
144
|
+
assert_equal value, node.value
|
145
|
+
end
|
146
|
+
|
147
|
+
def assert_right_class(node,clazz)
|
148
|
+
assert node.is_a?(clazz), "Instead #{node.class}"
|
149
|
+
end
|
150
|
+
|
151
|
+
def assert_simple_const(node,name)
|
152
|
+
assert_right_class node,Ruby::Constant
|
153
|
+
assert_equal name, node.name
|
154
|
+
assert_equal nil, node.container
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|