codemodels-js 0.1.0-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 05f1f1e4418831b8d5b8b7c19b50ad5d238bc526
4
+ data.tar.gz: 16bf23856ac1cba00a85fca4141c6725c927ef3c
5
+ SHA512:
6
+ metadata.gz: fd23eb8f5f4f3a49784ecc3acac275d2d4047323a62abc904418f0895e97b6312d1659f04a2de6ae08456fe3f274db0697df602163a857d9a961d7e24cff7a9f
7
+ data.tar.gz: 63edfdee587862a836bc278ca36889d34c116ee86a6be5aaa13d4660b232b1e51dcb799d32901994630d23a650e7c1d2f95c72d7912d17ee5cf054960f959149
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+ Gemfile.lock
15
+
16
+ # YARD artifacts
17
+ .yardoc
18
+ _yardoc
19
+ doc/
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in js-lightmodels.gemspec
4
+ gemspec
5
+
data/LICENSE ADDED
@@ -0,0 +1,191 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction, and
10
+ distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright
13
+ owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all other entities
16
+ that control, are controlled by, or are under common control with that entity.
17
+ For the purposes of this definition, "control" means (i) the power, direct or
18
+ indirect, to cause the direction or management of such entity, whether by
19
+ contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
20
+ outstanding shares, or (iii) beneficial ownership of such entity.
21
+
22
+ "You" (or "Your") shall mean an individual or Legal Entity exercising
23
+ permissions granted by this License.
24
+
25
+ "Source" form shall mean the preferred form for making modifications, including
26
+ but not limited to software source code, documentation source, and configuration
27
+ files.
28
+
29
+ "Object" form shall mean any form resulting from mechanical transformation or
30
+ translation of a Source form, including but not limited to compiled object code,
31
+ generated documentation, and conversions to other media types.
32
+
33
+ "Work" shall mean the work of authorship, whether in Source or Object form, made
34
+ available under the License, as indicated by a copyright notice that is included
35
+ in or attached to the work (an example is provided in the Appendix below).
36
+
37
+ "Derivative Works" shall mean any work, whether in Source or Object form, that
38
+ is based on (or derived from) the Work and for which the editorial revisions,
39
+ annotations, elaborations, or other modifications represent, as a whole, an
40
+ original work of authorship. For the purposes of this License, Derivative Works
41
+ shall not include works that remain separable from, or merely link (or bind by
42
+ name) to the interfaces of, the Work and Derivative Works thereof.
43
+
44
+ "Contribution" shall mean any work of authorship, including the original version
45
+ of the Work and any modifications or additions to that Work or Derivative Works
46
+ thereof, that is intentionally submitted to Licensor for inclusion in the Work
47
+ by the copyright owner or by an individual or Legal Entity authorized to submit
48
+ on behalf of the copyright owner. For the purposes of this definition,
49
+ "submitted" means any form of electronic, verbal, or written communication sent
50
+ to the Licensor or its representatives, including but not limited to
51
+ communication on electronic mailing lists, source code control systems, and
52
+ issue tracking systems that are managed by, or on behalf of, the Licensor for
53
+ the purpose of discussing and improving the Work, but excluding communication
54
+ that is conspicuously marked or otherwise designated in writing by the copyright
55
+ owner as "Not a Contribution."
56
+
57
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf
58
+ of whom a Contribution has been received by Licensor and subsequently
59
+ incorporated within the Work.
60
+
61
+ 2. Grant of Copyright License.
62
+
63
+ Subject to the terms and conditions of this License, each Contributor hereby
64
+ grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
65
+ irrevocable copyright license to reproduce, prepare Derivative Works of,
66
+ publicly display, publicly perform, sublicense, and distribute the Work and such
67
+ Derivative Works in Source or Object form.
68
+
69
+ 3. Grant of Patent License.
70
+
71
+ Subject to the terms and conditions of this License, each Contributor hereby
72
+ grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
73
+ irrevocable (except as stated in this section) patent license to make, have
74
+ made, use, offer to sell, sell, import, and otherwise transfer the Work, where
75
+ such license applies only to those patent claims licensable by such Contributor
76
+ that are necessarily infringed by their Contribution(s) alone or by combination
77
+ of their Contribution(s) with the Work to which such Contribution(s) was
78
+ submitted. If You institute patent litigation against any entity (including a
79
+ cross-claim or counterclaim in a lawsuit) alleging that the Work or a
80
+ Contribution incorporated within the Work constitutes direct or contributory
81
+ patent infringement, then any patent licenses granted to You under this License
82
+ for that Work shall terminate as of the date such litigation is filed.
83
+
84
+ 4. Redistribution.
85
+
86
+ You may reproduce and distribute copies of the Work or Derivative Works thereof
87
+ in any medium, with or without modifications, and in Source or Object form,
88
+ provided that You meet the following conditions:
89
+
90
+ You must give any other recipients of the Work or Derivative Works a copy of
91
+ this License; and
92
+ You must cause any modified files to carry prominent notices stating that You
93
+ changed the files; and
94
+ You must retain, in the Source form of any Derivative Works that You distribute,
95
+ all copyright, patent, trademark, and attribution notices from the Source form
96
+ of the Work, excluding those notices that do not pertain to any part of the
97
+ Derivative Works; and
98
+ If the Work includes a "NOTICE" text file as part of its distribution, then any
99
+ Derivative Works that You distribute must include a readable copy of the
100
+ attribution notices contained within such NOTICE file, excluding those notices
101
+ that do not pertain to any part of the Derivative Works, in at least one of the
102
+ following places: within a NOTICE text file distributed as part of the
103
+ Derivative Works; within the Source form or documentation, if provided along
104
+ with the Derivative Works; or, within a display generated by the Derivative
105
+ Works, if and wherever such third-party notices normally appear. The contents of
106
+ the NOTICE file are for informational purposes only and do not modify the
107
+ License. You may add Your own attribution notices within Derivative Works that
108
+ You distribute, alongside or as an addendum to the NOTICE text from the Work,
109
+ provided that such additional attribution notices cannot be construed as
110
+ modifying the License.
111
+ You may add Your own copyright statement to Your modifications and may provide
112
+ additional or different license terms and conditions for use, reproduction, or
113
+ distribution of Your modifications, or for any such Derivative Works as a whole,
114
+ provided Your use, reproduction, and distribution of the Work otherwise complies
115
+ with the conditions stated in this License.
116
+
117
+ 5. Submission of Contributions.
118
+
119
+ Unless You explicitly state otherwise, any Contribution intentionally submitted
120
+ for inclusion in the Work by You to the Licensor shall be under the terms and
121
+ conditions of this License, without any additional terms or conditions.
122
+ Notwithstanding the above, nothing herein shall supersede or modify the terms of
123
+ any separate license agreement you may have executed with Licensor regarding
124
+ such Contributions.
125
+
126
+ 6. Trademarks.
127
+
128
+ This License does not grant permission to use the trade names, trademarks,
129
+ service marks, or product names of the Licensor, except as required for
130
+ reasonable and customary use in describing the origin of the Work and
131
+ reproducing the content of the NOTICE file.
132
+
133
+ 7. Disclaimer of Warranty.
134
+
135
+ Unless required by applicable law or agreed to in writing, Licensor provides the
136
+ Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
137
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
138
+ including, without limitation, any warranties or conditions of TITLE,
139
+ NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
140
+ solely responsible for determining the appropriateness of using or
141
+ redistributing the Work and assume any risks associated with Your exercise of
142
+ permissions under this License.
143
+
144
+ 8. Limitation of Liability.
145
+
146
+ In no event and under no legal theory, whether in tort (including negligence),
147
+ contract, or otherwise, unless required by applicable law (such as deliberate
148
+ and grossly negligent acts) or agreed to in writing, shall any Contributor be
149
+ liable to You for damages, including any direct, indirect, special, incidental,
150
+ or consequential damages of any character arising as a result of this License or
151
+ out of the use or inability to use the Work (including but not limited to
152
+ damages for loss of goodwill, work stoppage, computer failure or malfunction, or
153
+ any and all other commercial damages or losses), even if such Contributor has
154
+ been advised of the possibility of such damages.
155
+
156
+ 9. Accepting Warranty or Additional Liability.
157
+
158
+ While redistributing the Work or Derivative Works thereof, You may choose to
159
+ offer, and charge a fee for, acceptance of support, warranty, indemnity, or
160
+ other liability obligations and/or rights consistent with this License. However,
161
+ in accepting such obligations, You may act only on Your own behalf and on Your
162
+ sole responsibility, not on behalf of any other Contributor, and only if You
163
+ agree to indemnify, defend, and hold each Contributor harmless for any liability
164
+ incurred by, or claims asserted against, such Contributor by reason of your
165
+ accepting any such warranty or additional liability.
166
+
167
+ END OF TERMS AND CONDITIONS
168
+
169
+ APPENDIX: How to apply the Apache License to your work
170
+
171
+ To apply the Apache License to your work, attach the following boilerplate
172
+ notice, with the fields enclosed by brackets "[]" replaced with your own
173
+ identifying information. (Don't include the brackets!) The text should be
174
+ enclosed in the appropriate comment syntax for the file format. We also
175
+ recommend that a file or class name and description of purpose be included on
176
+ the same "printed page" as the copyright notice for easier identification within
177
+ third-party archives.
178
+
179
+ Copyright [yyyy] [name of copyright owner]
180
+
181
+ Licensed under the Apache License, Version 2.0 (the "License");
182
+ you may not use this file except in compliance with the License.
183
+ You may obtain a copy of the License at
184
+
185
+ http://www.apache.org/licenses/LICENSE-2.0
186
+
187
+ Unless required by applicable law or agreed to in writing, software
188
+ distributed under the License is distributed on an "AS IS" BASIS,
189
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
190
+ See the License for the specific language governing permissions and
191
+ limitations under the License.
data/README.md ADDED
@@ -0,0 +1,4 @@
1
+ codemodels-js
2
+ =============
3
+
4
+ Building codemodels of Javascript files. See https://github.com/ftomassetti/codemodels
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'test'
6
+ end
7
+
8
+ desc "Run tests"
9
+ task :default => :test
10
+
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'codemodels/js/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.platform = 'java'
8
+ spec.name = "codemodels-js"
9
+ spec.version = CodeModels::Js::VERSION
10
+ spec.authors = ["Federico Tomassetti"]
11
+ spec.email = ["f.tomassetti@gmail.com"]
12
+ spec.description = %q{Building codemodels of Javascript files}
13
+ spec.summary = %q{Building codemodels of Javascript files. See https://github.com/ftomassetti/codemodels}
14
+ spec.homepage = "https://github.com/ftomassetti/codemodels-js"
15
+ spec.license = "APACHE2"
16
+
17
+ spec.files = `git ls-files`.split($/)
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency "codemodels"
23
+ spec.add_dependency "rgen"
24
+
25
+ spec.add_development_dependency "bundler"
26
+ spec.add_development_dependency "rake"
27
+ spec.add_development_dependency "simplecov"
28
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: UTF-8
2
+ require 'codemodels'
3
+
4
+ module CodeModels
5
+ module Js
6
+
7
+ class JsLanguage < Language
8
+ def initialize
9
+ super('Javascript')
10
+ @extensions << 'js'
11
+ @parser = CodeModels::Js::Parser.new
12
+ end
13
+ end
14
+
15
+ LANGUAGE = JsLanguage.new
16
+ CodeModels.register_language LANGUAGE
17
+
18
+ end
19
+ end
@@ -0,0 +1,586 @@
1
+ # encoding: UTF-8
2
+ require 'rgen/metamodel_builder'
3
+ require 'codemodels'
4
+
5
+ # TODO move some stuff to the lightmodels module
6
+
7
+ module CodeModels
8
+
9
+ module Js
10
+
11
+ @@additional_props = Hash.new {|h,k| h[k]={} }
12
+
13
+ class << self
14
+ attr_accessor :verbose
15
+ end
16
+
17
+ verbose = false
18
+
19
+ java_import 'org.mozilla.javascript.ast.AstNode'
20
+
21
+ JavaString = ::Java::JavaClass.for_name("java.lang.String")
22
+ JavaBoolean = ::Java::boolean.java_class
23
+ JavaInt = ::Java::int.java_class
24
+ JavaDouble = ::Java::double.java_class
25
+ JavaList = ::Java::JavaClass.for_name("java.util.List")
26
+ JavaSortedSet = ::Java::JavaClass.for_name("java.util.SortedSet")
27
+ JavaCollectionTypes = [JavaList,JavaSortedSet]
28
+
29
+ MappedAstClasses = {}
30
+
31
+ def self.get_metaclass_by_name(name)
32
+ return JsNode if name=='JsNode'
33
+ return JsNode if is_base_class?(name)
34
+ k = MappedAstClasses.keys.find{|k| k.name==name}
35
+ MappedAstClasses[k]
36
+ end
37
+
38
+ def self.is_base_class?(name)
39
+ # Object is here because of Symbol, which does not extenf Node
40
+ ['org.mozilla.javascript.Node','org.mozilla.javascript.ast.AstNode','java.lang.Object'].include? name
41
+ end
42
+
43
+ # Works with both Java and Ruby type
44
+ def self.get_att_type(type)
45
+ return type if [String,RGen::MetamodelBuilder::DataTypes::Boolean,Integer,Float].include?(type)
46
+ return String if type.respond_to?(:enum?) and type.enum?
47
+ case type
48
+ when JavaString
49
+ String
50
+ when JavaBoolean
51
+ RGen::MetamodelBuilder::DataTypes::Boolean
52
+ when JavaInt
53
+ Integer
54
+ when JavaDouble
55
+ Float
56
+ else
57
+ nil
58
+ end
59
+ end
60
+
61
+ def self.add_ref_or_att(c,type_name,prop_name,ast_name,multiplicity=:single)
62
+ #puts "Adding #{type_name} to #{c}"
63
+ case multiplicity
64
+ when :single
65
+ add_single_ref_or_att(c,type_name,prop_name,ast_name)
66
+ when :many
67
+ add_many_ref_or_att(c,type_name,prop_name,ast_name)
68
+ else
69
+ raise "wrong"
70
+ end
71
+ end
72
+
73
+ def self.add_single_ref_or_att(c,type_name,prop_name,ast_name)
74
+ rgen_class = get_metaclass_by_name(type_name)
75
+ if rgen_class
76
+ c.class_eval do
77
+ contains_one_uni prop_name, rgen_class
78
+ end
79
+ else
80
+ att_type = get_att_type(type_name)
81
+ if type_name
82
+ c.class_eval { has_attr prop_name, att_type }
83
+ else
84
+ raise "#{ast_name}) Property (many) #{prop_name} is else: #{type_name}"
85
+ end
86
+ end
87
+ end
88
+
89
+ def self.add_many_ref_or_att(c,type_name,prop_name,ast_name)
90
+ rgen_class = get_metaclass_by_name(type_name)
91
+ #puts "\trgen_class: #{rgen_class} from #{type_name} #{type_name.class}"
92
+ if rgen_class
93
+ c.class_eval do
94
+ contains_many_uni prop_name, rgen_class
95
+ end
96
+ else
97
+ att_type = get_att_type(type_name)
98
+ if type_name
99
+ c.class_eval { has_many_attr prop_name, att_type }
100
+ else
101
+ raise "#{ast_name}) Property (many) #{prop_name} is else: #{type_name}"
102
+ end
103
+ end
104
+ end
105
+
106
+ def self.rhino_node_class(name)
107
+ java_class = ::Java::JavaClass.for_name("org.mozilla.javascript.ast.#{name}")
108
+ end
109
+
110
+ def self.metasuperclass(java_super_class)
111
+ if is_base_class?(java_super_class.name)
112
+ JsNode
113
+ else
114
+ raise "Super class #{java_super_class.name} not found, it should be wrapped before the classes extending it!" unless MappedAstClasses[java_super_class]
115
+ MappedAstClasses[java_super_class]
116
+ end
117
+ end
118
+
119
+ def self.add_feature(c,name,type,multiplicity)
120
+ return unless type # type nil means to ignore the feature
121
+ method = if Js.get_att_type(type)
122
+ multiplicity==:many ? :has_many_attr : :has_attr
123
+ else
124
+ multiplicity==:many ? :contains_many_uni : :contains_one_uni
125
+ end
126
+ c.send(method,name,type)
127
+ end
128
+
129
+ def self.wrap(ast_names)
130
+ # first create all the classes
131
+ ast_names.each do |ast_name|
132
+ ast_java_class = rhino_node_class(ast_name)
133
+ meta_super_class = metasuperclass(ast_java_class.superclass)
134
+ meta_class = Class.new(meta_super_class)
135
+
136
+ raise "Already mapped! #{ast_name}" if MappedAstClasses[ast_java_class]
137
+ MappedAstClasses[ast_java_class] = meta_class
138
+
139
+ Js.const_set ast_java_class.simple_name, meta_class
140
+ end
141
+
142
+ # then add all the properties and attributes
143
+ ast_names.each do |ast_name|
144
+ java_class = rhino_node_class(ast_name)
145
+ ast_class = java_class.ruby_class
146
+ c = MappedAstClasses[java_class]
147
+
148
+ to_ignore = %w( symbolTable compilerData comments liveLocals regexpString
149
+ regexpFlags indexForNameNode paramAndVarCount paramAndVarNames
150
+ paramAndVarConst jumpStatement finally loop default continue
151
+ containingTable definingScope parentScope top quoteCharacter
152
+ sourceName inStrictMode encodedSourceStart encodedSourceEnd
153
+ baseLineno endLineno functionCount regexpCount paramCount nextTempName
154
+ functions symbols childScopes encodedSource statement var const let
155
+ destructuring localName scope operatorPosition
156
+ )
157
+
158
+ c.class_eval do
159
+ ast_class.java_class.declared_instance_methods.select { |m| Js.getter?(m) }.each do |m|
160
+ prop_name = CodeModels::Js.property_name(m)
161
+ unless to_ignore.include?(prop_name)
162
+ if PROP_ADAPTERS[ast_class.simple_name.to_sym][prop_name.to_sym]
163
+ #puts "Adapting #{ast_class.simple_name} #{prop_name}"
164
+ adapter = PROP_ADAPTERS[ast_class.simple_name.to_sym][prop_name.to_sym]
165
+ #puts "Type of adapter = #{adapter[:type]==nil}"
166
+ Js.add_feature(c,prop_name,adapter[:type],adapter[:multiplicity])
167
+ elsif Js.get_att_type(m.return_type)
168
+ # the type is simple (-> attribute)
169
+ has_attr prop_name, Js.get_att_type(m.return_type)
170
+ elsif MappedAstClasses.has_key?(m.return_type)
171
+ # the type is complex (-> reference)
172
+ contains_one_uni prop_name, MappedAstClasses[m.return_type]
173
+ elsif JavaCollectionTypes.include?(m.return_type)
174
+ type_name = CodeModels::Js.get_generic_param_name(m.to_generic_string)
175
+ CodeModels::Js.add_many_ref_or_att(c,type_name,prop_name,ast_name)
176
+ elsif m.return_type.array?
177
+ CodeModels::Js.add_many_ref_or_att(c,m.return_type.component_type.name,prop_name,ast_name)
178
+ elsif Js.is_base_class?(m.return_type.name)
179
+ #puts "#{ast_class.simple_name} #{prop_name} is base type"
180
+ contains_one_uni prop_name, JsNode
181
+ else
182
+ raise "#{ast_name}) Property (single) '#{prop_name}' is else: #{m.return_type}"
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end
188
+ end
189
+
190
+ def self.getter?(java_method)
191
+ (java_method.name.start_with?('get')||java_method.name.start_with?('is')) and java_method.argument_types.count==0
192
+ end
193
+
194
+ def self.get_corresponding_metaclass(node)
195
+ node_class = node.class
196
+ name = simple_java_class_name(node_class)
197
+ if name=='InfixExpression'
198
+ operator = AstNode::operatorToString(node.operator)
199
+ name = INFIX_OPERATORS[operator]
200
+ raise "Unknown operator for infix expression: #{operator}" unless name
201
+ end
202
+ if name=='UnaryExpression'
203
+ operator = AstNode::operatorToString(node.operator)
204
+ name = case operator
205
+ when '++'
206
+ node.prefix ? 'PrefixIncrement' : 'PostfixIncrement'
207
+ when '--'
208
+ node.prefix ? 'PrefixDecrement' : 'PostfixDecrement'
209
+ when '~'
210
+ 'BitwiseNotOperator'
211
+ when '!'
212
+ 'NotOperator'
213
+ when '-'
214
+ 'UnaryMinusOperator'
215
+ when '+'
216
+ 'UnaryPlusOperator'
217
+ when 'typeof'
218
+ 'TypeOfOperator'
219
+ when 'delete'
220
+ 'DeleteOperator'
221
+ else
222
+ raise "Unknown unary operator: #{operator}"
223
+ end
224
+ end
225
+ if name=='ObjectProperty'
226
+ if node.getter?
227
+ name='GetObjectProperty'
228
+ elsif node.setter?
229
+ name='SetObjectProperty'
230
+ else
231
+ name='SimpleObjectProperty'
232
+ end
233
+ end
234
+ if name=='SwitchCase'
235
+ if node.expression
236
+ name='ExpressionSwitchCase'
237
+ else
238
+ name='DefaultSwitchCase'
239
+ end
240
+ end
241
+ Js.const_get(name)
242
+ end
243
+
244
+ class JsNode < ::CodeModels::CodeModelsAstNode
245
+ end
246
+
247
+ private
248
+
249
+ def self.property_name(java_method)
250
+ return java_method.name.remove_prefix('get').proper_uncapitalize if java_method.name.start_with?('get')
251
+ return java_method.name.remove_prefix('is').proper_uncapitalize if java_method.name.start_with?('is')
252
+ raise "Error"
253
+ end
254
+
255
+ def self.simple_java_class_name(java_class)
256
+ name = java_class.name
257
+ if (i = (r = name).rindex(':')) then r[0..i] = '' end
258
+ r
259
+ end
260
+
261
+ def self.get_generic_param_name(generic_str)
262
+ type_name = nil
263
+ collections = JavaCollectionTypes.select{|ct|ct.name}
264
+ collections.each do |c|
265
+ prefixes = ["public #{c}<","public final #{c}<"]
266
+ prefixes.each do |p|
267
+ type_name = generic_str.remove_prefix(p) if generic_str.start_with?(p)
268
+ last = type_name.index '>'
269
+ type_name = type_name[0..last-1] if last
270
+ end
271
+ end
272
+ raise "I don't know how to get the generic param from '#{generic_str}'" unless type_name
273
+ type_name
274
+ end
275
+
276
+ PROP_ADAPTERS = Hash.new {|h,k| h[k] = {} }
277
+
278
+ def self.get_feature_value_through_getter(node,feat_name)
279
+ capitalized_name = feat_name.proper_capitalize
280
+ methods = [:"get#{capitalized_name}",:"is#{capitalized_name}"]
281
+
282
+ methods.each do |m|
283
+ if node.respond_to?(m)
284
+ begin
285
+ return node.send(m)
286
+ rescue Object => e
287
+ raise "Problem invoking #{m} on #{node.class}: #{e}"
288
+ end
289
+ end
290
+ end
291
+ raise "how should I get this... #{feat_name} on #{node.class}. It does not respond to #{methods}"
292
+ end
293
+
294
+ # If the feature is inherited I need to look among my super classes for
295
+ # adapters
296
+ def self.get_adapter(node_class,feat_name)
297
+ raise "Error" unless node_class
298
+ raise "Error: nil feat_name" unless feat_name
299
+ class_name = simple_java_class_name(node_class)
300
+ raise "Error" unless class_name
301
+ adapter = PROP_ADAPTERS[class_name.to_sym][feat_name.to_sym]
302
+ return adapter if adapter
303
+ # TODO stop at RGen::MetamodelBuilder::MMBase
304
+ return get_adapter(node_class.superclass,feat_name) if node_class.superclass
305
+ nil
306
+ end
307
+
308
+ def self.get_feature_value(node,feat_name,model)
309
+ raise "Error: nil feat_name" unless feat_name
310
+ #puts "Asking feature value for #{model.class} #{feat_name}"
311
+ adapter = get_adapter(model.class,feat_name)
312
+ if adapter
313
+ unless adapter[:adapter]
314
+ # ok, it was ignored, and later added...
315
+ # so call the getter specified when adding the property
316
+ node_type = simple_java_class_name(model.class).to_sym
317
+ prop_name = feat_name.to_sym
318
+ raise "Additional prop not found #{model.class}.#{prop_name}" unless @@additional_props[node_type][prop_name]
319
+ getter = @@additional_props[node_type][prop_name][:getter]
320
+ raise "Getter not found" unless getter
321
+ getter.call(node)
322
+ else
323
+ adapter[:adapter].call(node)
324
+ end
325
+ else
326
+ get_feature_value_through_getter(node,feat_name)
327
+ end
328
+ end
329
+
330
+ def self.record_prop_adapter(node_type,prop_name,prop_type,&adapter)
331
+ PROP_ADAPTERS[node_type][prop_name] = {type: prop_type, multiplicity: :single, adapter: adapter}
332
+ end
333
+
334
+ def self.ignore_prop(node_type,prop_name)
335
+ record_prop_adapter(node_type,prop_name,nil)
336
+ end
337
+
338
+ java_import 'org.mozilla.javascript.Token'
339
+
340
+ record_prop_adapter(:Symbol,:declType,String) do |node|
341
+ declTypeCode = node.send(:getDeclType)
342
+ %w(FUNCTION LP VAR LET CONST).each do |name|
343
+ return name if (declTypeCode == Token.get_const(name))
344
+ end
345
+ raise "Unexpected value: #{declTypeCode}"
346
+ end
347
+
348
+ record_prop_adapter(:InfixExpression,:operator,String) do |node|
349
+ operator_code = node.send(:getType)
350
+ begin
351
+ AstNode::operatorToString(operator_code)
352
+ rescue
353
+ puts "I can not get the operator for node #{node.class} (value: #{operator_code})" if verbose
354
+ nil
355
+ end
356
+ end
357
+
358
+ record_prop_adapter(:FunctionNode,:name,String) do |node|
359
+ name = node.name
360
+ name = nil if name==''
361
+ name
362
+ end
363
+
364
+ def self.add_prop(node_type,prop_name,prop_type,multiplicity=:single,&getter)
365
+ raise "Getter not specified" unless getter
366
+ @@additional_props[node_type][prop_name] = {prop_type:prop_type,multiplicity:multiplicity,getter:getter}
367
+ c = Js.const_get(node_type.to_s)
368
+ raise "Error" unless c
369
+ raise "No name" unless prop_name
370
+ add_ref_or_att(c,prop_type.to_s,prop_name.to_s,node_type.to_s,multiplicity)
371
+ end
372
+
373
+ def self.additional_properties(node_class)
374
+ node_type_name = simple_java_class_name(node_class).to_sym
375
+ ap = {}
376
+ ap = additional_properties(node_class.superclass) if node_class.superclass
377
+ @@additional_props[node_type_name].each do |k,v|
378
+ ap[k] = v
379
+ end
380
+ ap
381
+ end
382
+
383
+ def self.additional_property?(node_class,prop_name)
384
+ node_type_name = simple_java_class_name(node_class).to_sym
385
+ additional_properties(node_class)[prop_name.to_sym]
386
+ end
387
+
388
+ ignore_prop(:ArrayLiteral, :skipCount)
389
+ ignore_prop(:ArrayLiteral, :destructuringLength)
390
+ ignore_prop(:ArrayLiteral, :size)
391
+
392
+ ignore_prop(:PropertyGet,:target) # alias for left
393
+ ignore_prop(:PropertyGet,:property) # alias for right
394
+ ignore_prop(:InfixExpression, :operator) # we use a different subclass to discriminate
395
+ ignore_prop(:UnaryExpression, :operator)
396
+ ignore_prop(:UnaryExpression, :postfix)
397
+ ignore_prop(:UnaryExpression, :prefix)
398
+ ignore_prop(:Loop, :rp) # position of right paren...
399
+ ignore_prop(:Loop, :lp) # position of left paren...
400
+ ignore_prop(:FunctionNode, :lp)
401
+ ignore_prop(:FunctionNode, :rp)
402
+ ignore_prop(:FunctionNode, :expressionClosure)
403
+ ignore_prop(:FunctionNode, :generator)
404
+ ignore_prop(:FunctionNode, :functionType)
405
+ ignore_prop(:FunctionNode, :getterOrSetter)
406
+ ignore_prop(:FunctionNode, :getter)
407
+ ignore_prop(:FunctionNode, :setter)
408
+
409
+ ignore_prop(:FunctionCall, :lp)
410
+ ignore_prop(:FunctionCall, :rp)
411
+
412
+ ignore_prop(:ConditionalExpression, :questionMarkPosition)
413
+ ignore_prop(:ConditionalExpression, :colonPosition)
414
+
415
+ ignore_prop(:BreakStatement, :breakTarget)
416
+
417
+ ignore_prop(:CatchClause, :lp)
418
+ ignore_prop(:CatchClause, :rp)
419
+ ignore_prop(:CatchClause, :ifPosition)
420
+
421
+ ignore_prop(:ContinueStatement, :target)
422
+
423
+ ignore_prop(:DoLoop, :whilePosition)
424
+
425
+ ignore_prop(:NumberLiteral, :value)
426
+
427
+ ignore_prop(:SwitchStatement, :lp)
428
+ ignore_prop(:SwitchStatement, :rp)
429
+
430
+ ignore_prop(:SwitchCase, :expression) # we use it for ExpressionSwitchCase but not for DefaultSwitchCase
431
+
432
+ ignore_prop(:ElementGet, :lb)
433
+ ignore_prop(:ElementGet, :rb)
434
+
435
+ record_prop_adapter(:ObjectProperty,:name,JsNode) do |node|
436
+ node.left
437
+ end
438
+
439
+ record_prop_adapter(:ObjectProperty,:value,JsNode) do |node|
440
+ node.right
441
+ end
442
+
443
+ #ignore_prop(:Loop, :body)
444
+ #ignore_prop(:Scope, :statements)
445
+
446
+ # We don't want it to extend Scope
447
+ class Loop < JsNode
448
+ contains_one_uni 'body',JsNode
449
+ end
450
+ MappedAstClasses[::Java::JavaClass.for_name("org.mozilla.javascript.ast.Loop")] = Loop
451
+
452
+ class ObjectProperty < JsNode # maybe it should be directly a MMBase
453
+ contains_one_uni 'name',JsNode
454
+ contains_one_uni 'value',JsNode
455
+ end
456
+ MappedAstClasses[::Java::JavaClass.for_name("org.mozilla.javascript.ast.ObjectProperty")] = ObjectProperty
457
+
458
+ class ObjectLiteral < JsNode
459
+ contains_many_uni 'elements',ObjectProperty
460
+ end
461
+ MappedAstClasses[::Java::JavaClass.for_name("org.mozilla.javascript.ast.ObjectLiteral")] = ObjectLiteral
462
+
463
+ wrap %w(
464
+ Symbol
465
+ Jump
466
+ Scope
467
+ ScriptNode
468
+ AstRoot
469
+ Name
470
+ Block
471
+ FunctionNode
472
+ ExpressionStatement
473
+ FunctionCall
474
+ ParenthesizedExpression
475
+ InfixExpression
476
+ PropertyGet
477
+ Assignment
478
+ KeywordLiteral
479
+ ReturnStatement
480
+ UnaryExpression
481
+ ElementGet
482
+ IfStatement
483
+ StringLiteral
484
+ ArrayLiteral
485
+ ForLoop
486
+ ForInLoop
487
+ NumberLiteral
488
+ VariableInitializer
489
+ VariableDeclaration
490
+ ConditionalExpression
491
+ RegExpLiteral
492
+ BreakStatement
493
+ CatchClause
494
+ ContinueStatement
495
+ DoLoop
496
+ WhileLoop
497
+ NewExpression
498
+ EmptyStatement
499
+ EmptyExpression
500
+ ThrowStatement
501
+ TryStatement
502
+ SwitchStatement
503
+ SwitchCase
504
+ )
505
+
506
+ INFIX_OPERATORS = {
507
+ '+' => 'AddInfixExpression',
508
+ '-' => 'SubInfixExpression',
509
+ '/' => 'DivInfixExpression',
510
+ '*' => 'MulInfixExpression',
511
+ '<' => 'LessInfixExpression',
512
+ '>' => 'MoreInfixExpression',
513
+ '<=' => 'LessEqualInfixExpression',
514
+ '>=' => 'MoreEqualInfixExpression',
515
+ '|' => 'BitOrInfixExpression',
516
+ '&' => 'BitAndInfixExpression',
517
+ '===' => 'IdentityInfixExpression',
518
+ '!==' => 'NotIdentityInfixExpression',
519
+ '!=' => 'NotEqualsInfixExpression',
520
+ '==' => 'EqualsInfixExpression',
521
+ '&&' => 'LogicAndInfixExpression',
522
+ '||' => 'LogicOrInfixExpression',
523
+ ',' => 'CommaInfixExpression',
524
+ 'instanceof' => 'InstanceOfInfixExpression',
525
+ 'in' => 'InInfixExpression',
526
+ '%' => 'ModuleInfixExpression',
527
+ '^' => 'PowerInfixExpression'
528
+ }
529
+ INFIX_OPERATORS.values.each do |io|
530
+ c = Class.new(InfixExpression)
531
+ Js.const_set(io,c)
532
+ end
533
+
534
+ class SimpleObjectProperty < ObjectProperty
535
+ end
536
+ class GetObjectProperty < ObjectProperty
537
+ end
538
+ class SetObjectProperty < ObjectProperty
539
+ end
540
+
541
+ class PostfixIncrement < UnaryExpression
542
+ end
543
+ class PrefixIncrement < UnaryExpression
544
+ end
545
+ class PostfixDecrement < UnaryExpression
546
+ end
547
+ class PrefixDecrement < UnaryExpression
548
+ end
549
+ class BitwiseNotOperator < UnaryExpression
550
+ end
551
+ class NotOperator < UnaryExpression
552
+ end
553
+ class UnaryMinusOperator < UnaryExpression
554
+ end
555
+ class UnaryPlusOperator < UnaryExpression
556
+ end
557
+ class TypeOfOperator < UnaryExpression
558
+ end
559
+ class DeleteOperator < UnaryExpression
560
+ end
561
+
562
+ class ExpressionSwitchCase < SwitchCase
563
+ end
564
+ class DefaultSwitchCase < SwitchCase
565
+ end
566
+
567
+ add_prop(:Block,:contents,:JsNode,:many) do |node|
568
+ l = java.util.LinkedList.new
569
+ node.each do |el|
570
+ l.add(el)
571
+ end
572
+ l
573
+ end
574
+
575
+ add_prop(:ExpressionSwitchCase,:expression,:JsNode,:single) do |node|
576
+ node.expression
577
+ end
578
+
579
+ # add_prop(:ScriptNode,:statements,:JsNode,:many) do |node|
580
+ # # we disabled in general for scope but we re-enabled for ScriptNode
581
+ # node.statements
582
+ # end
583
+
584
+ end
585
+
586
+ end