codercmp 0.9.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/codercmp +101 -0
- data/lib/codercompanion/api.rb +47 -0
- data/lib/codercompanion/cachehandler.rb +94 -0
- data/lib/codercompanion/codercompanion_exception.rb +4 -0
- data/lib/codercompanion/common/common.rb +44 -0
- data/lib/codercompanion/common/literals.rb +58 -0
- data/lib/codercompanion/common_namespace.rb +2 -0
- data/lib/codercompanion/cpp/cpp_parser.rb +31 -0
- data/lib/codercompanion/cpp/cpp_tree_walker.rb +20 -0
- data/lib/codercompanion/java/java.rb +365 -0
- data/lib/codercompanion/java/java_grammar.treetop +283 -0
- data/lib/codercompanion/java/java_parser.rb +62 -0
- data/lib/codercompanion/java/java_tree_walker.rb +114 -0
- data/lib/codercompanion/language_parser.rb +54 -0
- data/lib/codercompanion/languages.rb +23 -0
- data/lib/codercompanion/parser_factory.rb +27 -0
- data/lib/codercompanion/ruby/ruby_annotations.rb +8 -0
- data/lib/codercompanion/ruby/ruby_parser.rb +45 -0
- data/lib/codercompanion/ruby/ruby_tree_walker.rb +229 -0
- data/lib/codercompanion/s3_client.rb +32 -0
- data/lib/codercompanion/tree_walker.rb +8 -0
- data/lib/codercompanion.rb +410 -0
- data/lib/codercompanion_version.rb +3 -0
- metadata +155 -0
@@ -0,0 +1,365 @@
|
|
1
|
+
require 'codercompanion/common_namespace'
|
2
|
+
|
3
|
+
module CoderCompanion
|
4
|
+
|
5
|
+
module Java
|
6
|
+
# include Literals
|
7
|
+
include CoderCompanion::Common
|
8
|
+
|
9
|
+
def self.extract_privacy(member_qualifiers)
|
10
|
+
privacy = 'private'
|
11
|
+
qualifiers = member_qualifiers.split(/\s+/)
|
12
|
+
if !qualifiers.empty? and qualifiers.first.match(/(public|protected)/)
|
13
|
+
privacy = qualifiers.first
|
14
|
+
end
|
15
|
+
return privacy
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.has_final_qualifier(member_qualifiers)
|
19
|
+
return true if member_qualifiers.match(/final/)
|
20
|
+
false
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.has_static_qualifier(member_qualifiers)
|
24
|
+
return true if member_qualifiers.match(/static/)
|
25
|
+
false
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.remove_nested_pattern(value, pattern_to_search, pattern_to_remove)
|
29
|
+
loop do
|
30
|
+
has_pattern = value.match(pattern_to_search)
|
31
|
+
if has_pattern
|
32
|
+
value = value.gsub(pattern_to_remove, '')
|
33
|
+
else
|
34
|
+
break
|
35
|
+
end
|
36
|
+
end
|
37
|
+
return value
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.remove_nested_brackets(value)
|
41
|
+
return self.remove_nested_pattern(value, /[\(\)]/, /(\([^\(\)]*\))/)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.remove_generics(value)
|
45
|
+
return self.remove_nested_pattern(value, /[<>]/, /(<[^<>]*>)/)
|
46
|
+
end
|
47
|
+
|
48
|
+
class SourceFile2 < Treetop::Runtime::SyntaxNode
|
49
|
+
def build
|
50
|
+
els = []
|
51
|
+
elements.each do |e|
|
52
|
+
next unless e and e.elements
|
53
|
+
e.elements.each do |inner_e|
|
54
|
+
els.push(inner_e.elements.first.build) if inner_e.respond_to?(:class_definition)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
return els
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class Interface2 < Treetop::Runtime::SyntaxNode
|
62
|
+
def build
|
63
|
+
comma_separated_list = CoderCompanion::Java.remove_generics(text_value)
|
64
|
+
comma_separated_list.gsub!(/implements\s/,'')
|
65
|
+
return comma_separated_list.split(/\s*,\s*/)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
class ClassDefinitions < Treetop::Runtime::SyntaxNode
|
71
|
+
def build
|
72
|
+
els = []
|
73
|
+
privacy = ''
|
74
|
+
class_name = ''
|
75
|
+
inherits_from = ''
|
76
|
+
element_type = ''
|
77
|
+
implements = []
|
78
|
+
elements.each do |e|
|
79
|
+
if e.respond_to?(:class_qualifiers)
|
80
|
+
privacy = ::CoderCompanion::Java.extract_privacy(e.text_value)
|
81
|
+
end
|
82
|
+
if e.respond_to?(:class_or_enum)
|
83
|
+
element_type = e.text_value
|
84
|
+
next
|
85
|
+
end
|
86
|
+
if e.respond_to?(:class_name)
|
87
|
+
class_name = e.text_value
|
88
|
+
next
|
89
|
+
end
|
90
|
+
if e.respond_to?(:inheritance)
|
91
|
+
inherits_from = e.text_value.gsub(/extends\s+/, '')
|
92
|
+
inherits_from = inherits_from.gsub(/<.*>/, '')
|
93
|
+
next
|
94
|
+
end
|
95
|
+
if e.respond_to?(:implements)
|
96
|
+
implements = e.elements.first.build # reach into child's elements
|
97
|
+
next
|
98
|
+
end
|
99
|
+
if e.respond_to?(:class_body)
|
100
|
+
els.concat(e.elements.first.build)
|
101
|
+
next
|
102
|
+
end
|
103
|
+
end
|
104
|
+
ret = {:type => "#{element_type}_definition", :value => class_name, :privacy => privacy, :inherits_from => inherits_from, :implements => implements, :class_elements => els}
|
105
|
+
return ret
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
class ClassBody2 < Treetop::Runtime::SyntaxNode
|
111
|
+
def build
|
112
|
+
els = []
|
113
|
+
elements.each do |e|
|
114
|
+
next if e.elements.nil?
|
115
|
+
e.elements.each do |inner_e|
|
116
|
+
els.concat(inner_e.build) if inner_e.respond_to?(:build)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
return els
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
class ClassBodyDeclaration < Treetop::Runtime::SyntaxNode
|
124
|
+
def build
|
125
|
+
els = []
|
126
|
+
elements.each do |e|
|
127
|
+
if e.respond_to? :class_element
|
128
|
+
e.elements.each do |inner_e|
|
129
|
+
els.push(inner_e.build) if inner_e.respond_to? :build
|
130
|
+
end
|
131
|
+
end
|
132
|
+
els.concat(e.build) if e.respond_to?(:build)
|
133
|
+
end
|
134
|
+
return els
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
class ClassQualifiers < Treetop::Runtime::SyntaxNode
|
139
|
+
def build
|
140
|
+
elements.each do |e|
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
class CommaSeparatedConstants < Treetop::Runtime::SyntaxNode
|
146
|
+
def build
|
147
|
+
els = []
|
148
|
+
no_comments = text_value.gsub(/"(\\"|[^"])*"/, '')
|
149
|
+
no_comments = no_comments.gsub(/(\/\/[^\n]*\n+|\/\*(?:.|[\r\n])*?\*\/)/, '') #Remove comments
|
150
|
+
no_comments = CoderCompanion::Java.remove_nested_brackets(no_comments)
|
151
|
+
values = no_comments.split(/\s*,\s*/)
|
152
|
+
enum_constants = []
|
153
|
+
values.each do |e|
|
154
|
+
e.strip! #Trim white spaces
|
155
|
+
enum_constants.push( {:type => 'enum_constant', :value => e.gsub(/[\\n]/, '')} ) unless e.match(/;/)
|
156
|
+
end
|
157
|
+
return enum_constants
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
class VariableDeclarationList < Treetop::Runtime::SyntaxNode
|
162
|
+
def build
|
163
|
+
variables = []
|
164
|
+
elements.each do |e|
|
165
|
+
variables.push(e.text_value) if e.respond_to? :variable_defined
|
166
|
+
variables.concat(e.build) if e.respond_to? :build
|
167
|
+
end
|
168
|
+
return variables
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
class NextVariable < Treetop::Runtime::SyntaxNode
|
173
|
+
def build
|
174
|
+
variables = []
|
175
|
+
elements.each do |e|
|
176
|
+
variables.push(e.text_value) if e.respond_to? :variable_defined
|
177
|
+
variables.concat(e.build) if e.respond_to? :build
|
178
|
+
end
|
179
|
+
return variables
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
class MemberVariable < Treetop::Runtime::SyntaxNode
|
184
|
+
def build
|
185
|
+
variable_type = ''
|
186
|
+
privacy = ''
|
187
|
+
variable_name = ''
|
188
|
+
type = ''
|
189
|
+
qualifiers = []
|
190
|
+
variables = []
|
191
|
+
elements.each do |e|
|
192
|
+
if e.respond_to? :qualifiers
|
193
|
+
qualifiers = e.elements[0].text_value
|
194
|
+
privacy = CoderCompanion::Java.extract_privacy(qualifiers)
|
195
|
+
if CoderCompanion::Java.has_final_qualifier(qualifiers) && CoderCompanion::Java.has_static_qualifier(qualifiers)
|
196
|
+
variable_type = 'constant'
|
197
|
+
elsif !CoderCompanion::Java.has_final_qualifier(qualifiers) && CoderCompanion::Java.has_static_qualifier(qualifiers)
|
198
|
+
variable_type = 'class_variable'
|
199
|
+
else
|
200
|
+
variable_type = 'instance_variable'
|
201
|
+
end
|
202
|
+
end
|
203
|
+
variables = e.build if e.respond_to? :build
|
204
|
+
type = e.text_value if e.respond_to? :type
|
205
|
+
variable_name = e.text_value if e.respond_to? :variable_defined
|
206
|
+
end
|
207
|
+
|
208
|
+
to_return = []
|
209
|
+
variables.each do |v|
|
210
|
+
to_return.push( {:type => 'variable_definition', :value => v.gsub(/[\s]+/, ' '), :return_type => type, :privacy => privacy, :variable_type => variable_type})
|
211
|
+
end
|
212
|
+
return to_return
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
class ConstructorDefinition < Treetop::Runtime::SyntaxNode
|
217
|
+
def build
|
218
|
+
privacy = ''
|
219
|
+
method_text = ''
|
220
|
+
elements.each do |e|
|
221
|
+
privacy = e.text_value if e.respond_to? :privacy
|
222
|
+
method_text = e.text_value if e.respond_to? :method_defined
|
223
|
+
end
|
224
|
+
return [{:type => 'constructor_definition', :value => method_text.gsub(/[\s]+/, ' '), :privacy => privacy}]
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
class MethodDefinition < Treetop::Runtime::SyntaxNode
|
229
|
+
def build
|
230
|
+
class_method = false
|
231
|
+
params = []
|
232
|
+
privacy = ''
|
233
|
+
method_text = ''
|
234
|
+
return_type = ''
|
235
|
+
qualifiers = []
|
236
|
+
elements.each do |e|
|
237
|
+
if e.respond_to? :qualifiers
|
238
|
+
qualifiers = e.elements[0].text_value
|
239
|
+
privacy = CoderCompanion::Java.extract_privacy(qualifiers)
|
240
|
+
if (CoderCompanion::Java.has_static_qualifier(qualifiers) )
|
241
|
+
class_method = true
|
242
|
+
end
|
243
|
+
end
|
244
|
+
return_type = e.text_value if e.respond_to? :return_type
|
245
|
+
method_text = e.text_value if e.respond_to? :method_defined
|
246
|
+
if e.respond_to? :method_defined
|
247
|
+
e.elements[0].elements.each do |f|
|
248
|
+
s_params = CoderCompanion::Java.remove_generics(f.text_value) if f.respond_to? :params
|
249
|
+
if s_params
|
250
|
+
s_params = s_params.gsub(/@[^\s]+\s+/, '') #Remove annotation for parameters
|
251
|
+
s_params = s_params.gsub(/\sfinal\s/, '') #Remove final keyword
|
252
|
+
s_params = s_params.gsub(/\.\.\./, '') #Remove the ellipsis at the end '...'
|
253
|
+
pre_params = s_params.split(/\s*\,\s*/)
|
254
|
+
pre_params.each do |p|
|
255
|
+
val_arr = p.split(/\s+/)
|
256
|
+
params.push({:type => val_arr[0], :value => val_arr[1]})
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
return [{:type => 'method_definition', :value => method_text.gsub(/[\s]+/, ' '), :params => params, :return_type => return_type, :privacy => privacy, :class_method => class_method}]
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
class Qualifiers < Treetop::Runtime::SyntaxNode
|
267
|
+
def build
|
268
|
+
els = []
|
269
|
+
elements.each do |e|
|
270
|
+
els.push(e.elements[0].text_value) if e.respond_to? :qualifier
|
271
|
+
end
|
272
|
+
return els
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
class InterfaceDefinition < Treetop::Runtime::SyntaxNode
|
277
|
+
def build
|
278
|
+
els = []
|
279
|
+
class_name = ''
|
280
|
+
privacy = ''
|
281
|
+
inherits_from = ''
|
282
|
+
elements.each do |e|
|
283
|
+
inherits_from = e.elements[0].build if e.respond_to? :inheritance
|
284
|
+
class_name = e.text_value if e.respond_to? :class_name
|
285
|
+
privacy = e.text_value if e.respond_to? :privacy
|
286
|
+
if e.respond_to? :class_element
|
287
|
+
e.elements[0].elements.each {|f| els.push(f.build) if f.respond_to? :build }
|
288
|
+
end
|
289
|
+
end
|
290
|
+
return {:type => "interface_definition", :value => class_name, :privacy => privacy, :inherits_from => inherits_from, :class_elements => els}
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
class ClassDefinition < Treetop::Runtime::SyntaxNode
|
295
|
+
def build
|
296
|
+
els = []
|
297
|
+
class_name = ''
|
298
|
+
privacy = ''
|
299
|
+
inherits_from = ''
|
300
|
+
implements = []
|
301
|
+
element_type = ''
|
302
|
+
elements.each do |e|
|
303
|
+
element_type = e.text_value if e.respond_to? :class_or_enum
|
304
|
+
inherits_from = e.elements[0].build if e.respond_to? :inheritance
|
305
|
+
implements = e.elements[0].build if e.respond_to? :implements
|
306
|
+
class_name = e.text_value if e.respond_to? :class_name
|
307
|
+
privacy = e.text_value if e.respond_to? :privacy
|
308
|
+
if e.respond_to? :class_element
|
309
|
+
resp = nil
|
310
|
+
e.elements[0].elements.each do |f|
|
311
|
+
resp = f.build if f.respond_to? :build
|
312
|
+
if resp && resp.class.to_s == "Array"
|
313
|
+
els.concat(resp)
|
314
|
+
elsif resp
|
315
|
+
els.push(resp)
|
316
|
+
end
|
317
|
+
resp = nil
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
321
|
+
return {:type => "#{element_type}_definition", :value => class_name, :privacy => privacy, :inherits_from => inherits_from, :implements => implements, :class_elements => els}
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
class Inheritance < Treetop::Runtime::SyntaxNode
|
326
|
+
def build
|
327
|
+
result = ''
|
328
|
+
elements.each {|e| result = e.build if e.respond_to? :build}
|
329
|
+
return result
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
class Implementation < Treetop::Runtime::SyntaxNode
|
334
|
+
def build
|
335
|
+
implements = []
|
336
|
+
elements.each do |e|
|
337
|
+
val = e.build if e.respond_to? :build
|
338
|
+
if val && val.class.to_s == "Array"
|
339
|
+
implements.concat(val)
|
340
|
+
elsif val
|
341
|
+
implements.push(val)
|
342
|
+
end
|
343
|
+
end
|
344
|
+
return implements
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
class NextInterface < Treetop::Runtime::SyntaxNode
|
349
|
+
def build
|
350
|
+
els = []
|
351
|
+
elements.each do |e|
|
352
|
+
val = e.build if e.respond_to? :build
|
353
|
+
if val && val.class.to_s == "Array"
|
354
|
+
els.concat(val)
|
355
|
+
elsif val
|
356
|
+
els.push(val)
|
357
|
+
end
|
358
|
+
# els.push(e.text_value) if e.respond_to? :variable_defined
|
359
|
+
# els.concat(e.build) if e.respond_to? :build
|
360
|
+
end
|
361
|
+
return els
|
362
|
+
end
|
363
|
+
end
|
364
|
+
end
|
365
|
+
end
|
@@ -0,0 +1,283 @@
|
|
1
|
+
module CoderCompanion
|
2
|
+
grammar Java
|
3
|
+
|
4
|
+
rule fake_start
|
5
|
+
source_file_2
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
rule source_file_2
|
10
|
+
s? package? s? (import s)* s? multiple_annotations? s? (class_definition:class_definition_2 s?)* <SourceFile2>
|
11
|
+
end
|
12
|
+
|
13
|
+
rule package
|
14
|
+
'package' s? !'.' identifier s? ('.' s? identifier )* s? ';'
|
15
|
+
end
|
16
|
+
|
17
|
+
rule import
|
18
|
+
'import' s? 'static'? s? !'.' identifier s? ('.' s? ( identifier / '*') )* s? ';'
|
19
|
+
end
|
20
|
+
|
21
|
+
rule comment_2
|
22
|
+
('/*' (!'*/' .)* '*/' ) / '//' (![\n] .)* [\n]
|
23
|
+
end
|
24
|
+
|
25
|
+
rule class_definition_2
|
26
|
+
(class_qualifiers:class_qualifiers_2*) s? (class_or_enum:('class'/'enum'/'interface'/'@' identifier)) s
|
27
|
+
(class_name:class_identifier) ( s? generics )? s? (inheritance:inheritance)? s?
|
28
|
+
(implements:interfaces_2)? s? (class_body:class_body_2) s? <ClassDefinitions>
|
29
|
+
end
|
30
|
+
|
31
|
+
rule interfaces_2
|
32
|
+
'implements' s? qualified_name (s? generics)? (s? ',' s? qualified_name (s? generics)? )* <Interface2>
|
33
|
+
end
|
34
|
+
|
35
|
+
rule class_body_2
|
36
|
+
'{' s? class_body_declaration_2* s? '}' <ClassBody2>
|
37
|
+
end
|
38
|
+
|
39
|
+
rule class_body_declaration_2
|
40
|
+
s? ';' / ('static' s) block_2 / s? member_declaration_2 <ClassBodyDeclaration>
|
41
|
+
end
|
42
|
+
|
43
|
+
rule variable_declaration_2
|
44
|
+
(qualifiers:general_qualifiers_2*) s? (type:type) s variable_declaration_list s? <MemberVariable>
|
45
|
+
end
|
46
|
+
|
47
|
+
rule variable_declaration_list
|
48
|
+
(variable_defined:identifier) s? (array_indicator)? s? ( method_assignment / block_assignment / assignment )? s? next_variable? s? ';' s? <VariableDeclarationList>
|
49
|
+
end
|
50
|
+
|
51
|
+
rule next_variable
|
52
|
+
s? ',' s? ( variable_defined:identifier ) s? (array_indicator?) s? ( method_assignment / block_assignment / assignment )? next_variable? <NextVariable>
|
53
|
+
end
|
54
|
+
|
55
|
+
rule method_definition_2
|
56
|
+
(qualifiers:general_qualifiers_2*) s? (return_type:type) s ( method_defined:method ) s? ('throws' s qualified_name_list)? s? ( '{' s? method_body? s? '}' / 'default' s? (string / (!";" .)*) s? ';' / ';' ) <MethodDefinition>
|
57
|
+
end
|
58
|
+
|
59
|
+
rule general_qualifiers_2
|
60
|
+
class_qualifier_2 / annotation s / generics s / ( 'native' s / 'synchronized' s / 'transient' s / 'volatile' s )
|
61
|
+
end
|
62
|
+
|
63
|
+
rule generics
|
64
|
+
'<' ( !angle_bracket . )* ( s? generics array_indicator?)? additional_generics s? '>'
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
rule additional_generics
|
69
|
+
( s? ',' s? (!angle_bracket .)* (s? generics array_indicator?)? )*
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
rule angle_bracket
|
74
|
+
'<' / '>'
|
75
|
+
end
|
76
|
+
|
77
|
+
rule class_qualifiers_2
|
78
|
+
class_qualifier_2 (s class_qualifier_2)* <ClassQualifiers>
|
79
|
+
end
|
80
|
+
|
81
|
+
rule class_qualifier_2
|
82
|
+
'public' s / 'protected' s / 'private' s / 'static' s / 'abstract' s / 'final' s / 'strictfp' s
|
83
|
+
end
|
84
|
+
|
85
|
+
rule member_declaration_2
|
86
|
+
s
|
87
|
+
/ ('static' s) block_2
|
88
|
+
/ annotation
|
89
|
+
/ (class_element:class_definition_2)
|
90
|
+
/ method_definition_2
|
91
|
+
/ variable_declaration_2
|
92
|
+
/ constructor
|
93
|
+
/ comma_separated_constants_2
|
94
|
+
end
|
95
|
+
|
96
|
+
rule qualified_name_list
|
97
|
+
qualified_name s? (',' s? qualified_name)*
|
98
|
+
end
|
99
|
+
|
100
|
+
rule qualified_name
|
101
|
+
identifier ('.' identifier )*
|
102
|
+
end
|
103
|
+
|
104
|
+
rule comma_separated_constants_2
|
105
|
+
identifier s? ( '(' s? method_call_params? s? ')' )? (s? ',' s? ( identifier s? ( '(' s? method_call_params? s? ')' )? / ';' / s? ) )* <CommaSeparatedConstants>
|
106
|
+
end
|
107
|
+
|
108
|
+
rule block_2
|
109
|
+
#'{' s? block_2? s? (!curly_brackets .)* s? block_2? s? (!curly_brackets .)* s? block_2? s? '}'
|
110
|
+
'{' s? (block_2 s?)* s? (anything_but_curly_brackets? s? block_2 s?)* s? anything_but_curly_brackets? s? (block_2 s?)* s? '}'
|
111
|
+
end
|
112
|
+
|
113
|
+
rule multiple_annotations
|
114
|
+
annotation (s annotation)*
|
115
|
+
end
|
116
|
+
|
117
|
+
rule annotation
|
118
|
+
'@' qualified_name ( s? '(' (!')' .)* ')' )?
|
119
|
+
end
|
120
|
+
|
121
|
+
rule interface_definition
|
122
|
+
(privacy:privacy?) s? (qualifiers:qualifiers?) s? 'interface' s (class_name:class_identifier) s? (inheritance:inheritance)? s? (interfaces)? s? '{' s? ( class_element:class_element* ) s? '}' <InterfaceDefinition>
|
123
|
+
end
|
124
|
+
|
125
|
+
rule inheritance
|
126
|
+
'extends' s qualified_name (s? generics)? next_interface? <Inheritance>
|
127
|
+
end
|
128
|
+
|
129
|
+
rule interfaces
|
130
|
+
'implements' s qualified_name s? (array_indicator)? next_interface? <Implementation>
|
131
|
+
end
|
132
|
+
|
133
|
+
rule next_interface
|
134
|
+
s? ',' s? qualified_name s? (array_indicator)? next_interface? <NextInterface>
|
135
|
+
end
|
136
|
+
|
137
|
+
rule constructor
|
138
|
+
(privacy:privacy?) s? (qualifiers:qualifiers?) s? ( method_defined:method ) s? ('throws' s qualified_name_list)? s? '{' s? method_body? s? '}' <ConstructorDefinition>
|
139
|
+
end
|
140
|
+
|
141
|
+
rule interface_method_definition
|
142
|
+
(privacy:privacy?) s? (qualifiers:qualifiers?) s? (return_type:type) s ( method_defined:method ) s? ';' <MethodDefinition>
|
143
|
+
end
|
144
|
+
|
145
|
+
rule method_body
|
146
|
+
method_statement (s method_statement)*
|
147
|
+
end
|
148
|
+
|
149
|
+
rule method_statement
|
150
|
+
'(' ')'
|
151
|
+
/
|
152
|
+
comment_2
|
153
|
+
/
|
154
|
+
return_statement
|
155
|
+
/
|
156
|
+
statement
|
157
|
+
/
|
158
|
+
scope
|
159
|
+
end
|
160
|
+
|
161
|
+
rule return_statement
|
162
|
+
'return' s? ( (!'new' qualified_name) s? '(' s? method_call_params? s? ')' s? ';' s? / return_new_object s? ';' / qualified_name method_call? s? ';' )
|
163
|
+
end
|
164
|
+
|
165
|
+
rule method_call_params
|
166
|
+
( string / number / return_new_object / cast_statement / qualified_name method_call? / identifier ) next_method_call_params?
|
167
|
+
end
|
168
|
+
|
169
|
+
rule next_method_call_params
|
170
|
+
(s? ',' s? ( string / number / return_new_object / cast_statement / qualified_name method_call? / identifier ) ) next_method_call_params?
|
171
|
+
end
|
172
|
+
|
173
|
+
rule return_new_object
|
174
|
+
'new' s class_identifier s? generics? s? '(' (!')' .)* ')' s '{' s? method_body s? '}'
|
175
|
+
end
|
176
|
+
|
177
|
+
rule method_call
|
178
|
+
'(' s? ( string / return_new_object / qualified_name method_call / cast_statement / (!'(' !')' .)* / '' ) s? ')' ('.' qualified_name method_call)?
|
179
|
+
end
|
180
|
+
|
181
|
+
rule cast_statement
|
182
|
+
'(' (!')' .)* ')' s? qualified_name method_call?
|
183
|
+
end
|
184
|
+
|
185
|
+
rule statement
|
186
|
+
(anything_but_curly_brackets &';') ';'
|
187
|
+
end
|
188
|
+
|
189
|
+
rule anything_but_semi_colon
|
190
|
+
[^;]+
|
191
|
+
end
|
192
|
+
|
193
|
+
rule scope
|
194
|
+
( anything_but_curly_brackets '{' s? anything_but_curly_brackets s? scope? s? anything_but_curly_brackets s? '}' anything_but_curly_brackets scope? / anything_but_curly_brackets )
|
195
|
+
end
|
196
|
+
|
197
|
+
rule anything_but_curly_brackets
|
198
|
+
( s / comment &{|seq| seq[0].is_valid_comment} / string / [^{}] / '.' / other_values )*
|
199
|
+
end
|
200
|
+
|
201
|
+
rule other_values
|
202
|
+
( [\@@$] / "'@'" / "'@'" / "'.'" / "':'" / "'#'" / "'#'" )
|
203
|
+
end
|
204
|
+
|
205
|
+
rule assignment
|
206
|
+
'=' s? ( string / (!';' .) )*
|
207
|
+
end
|
208
|
+
|
209
|
+
rule method_assignment
|
210
|
+
'=' s? (!'new' qualified_name) s? '(' s? method_call_params s? ')' ('.' qualified_name method_call)? s?
|
211
|
+
end
|
212
|
+
|
213
|
+
rule block_assignment
|
214
|
+
'=' s? 'new' s (!curly_brackets !';' .)* s? block_2?
|
215
|
+
end
|
216
|
+
|
217
|
+
rule curly_brackets
|
218
|
+
'{' / '}'
|
219
|
+
end
|
220
|
+
|
221
|
+
rule privacy
|
222
|
+
( 'public' <Identifier> / 'protected' <Identifier> / 'private' <Identifier> )
|
223
|
+
end
|
224
|
+
|
225
|
+
rule qualifiers
|
226
|
+
qualifier (s qualifier)* <Qualifiers>
|
227
|
+
end
|
228
|
+
|
229
|
+
rule qualifier
|
230
|
+
'synchronized' / 'abstract' / 'static' / 'final' / 'const' / 'transient' / 'volatile' / 'strictfp'
|
231
|
+
end
|
232
|
+
|
233
|
+
rule method
|
234
|
+
( qualified_name s? '(' s? ( multiple_annotations? s? !',' ('final' s)? (first_type:type) s? params:(identifier s? array_indicator*) rest_of_params:(s? ',' s? annotation? s? ('final' s)? (next_type:type) s? identifier s? array_indicator* )* )? s? ')' ) <Method>
|
235
|
+
end
|
236
|
+
|
237
|
+
rule type
|
238
|
+
( !class_qualifiers_2 !'class' !'enum' !'interface' qualified_name array_indicator?)
|
239
|
+
end
|
240
|
+
|
241
|
+
rule array_indicator
|
242
|
+
( s? '[]' array_indicator? / s? generics array_indicator? / s? '...' )
|
243
|
+
end
|
244
|
+
|
245
|
+
rule string
|
246
|
+
(
|
247
|
+
"'" ( (!'\\\'' '\\\\') / '\\\'' / !"'" . )* "'" <StringLiteral>
|
248
|
+
/
|
249
|
+
'"' ( (!'\"' '\\\\') / '\"' / !'"' . )* '"' <StringLiteral>
|
250
|
+
)
|
251
|
+
end
|
252
|
+
|
253
|
+
rule comment
|
254
|
+
( '/*' s? (!'*/' .)* s? '*/' / '//' s? [^\n]* )
|
255
|
+
{
|
256
|
+
def is_valid_comment
|
257
|
+
return true if text_value.match(/(\/\/[^"'\n\r]*(?:("|')[^"'\n\r]*("|')[^"'\n\r]*)*$|\/\*([^*]|\*(?!\/))*?\*\/)(?=[^"]*(?:"[^"]*"[^"]*)*$)/)
|
258
|
+
return false
|
259
|
+
end
|
260
|
+
}
|
261
|
+
end
|
262
|
+
|
263
|
+
rule s
|
264
|
+
( comment_2 / [ \s] )+
|
265
|
+
end
|
266
|
+
|
267
|
+
rule class_identifier
|
268
|
+
[A-Za-z_] [a-zA-Z0-9_]*
|
269
|
+
end
|
270
|
+
|
271
|
+
rule identifier
|
272
|
+
[a-zA-Z_] [a-zA-Z0-9_]* <Identifier>
|
273
|
+
end
|
274
|
+
|
275
|
+
rule number
|
276
|
+
[0-9]+ 'L'?
|
277
|
+
end
|
278
|
+
|
279
|
+
rule anything
|
280
|
+
.*
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|