Module: CodeModels::Js
- Defined in:
- lib/codemodels/js/parser.rb,
lib/codemodels/js/version.rb,
lib/codemodels/js/language.rb,
lib/codemodels/js/metamodel.rb,
lib/codemodels/js/model_building.rb
Defined Under Namespace
Classes: BitwiseNotOperator, DefaultSwitchCase, DeleteOperator, ExpressionSwitchCase, GetObjectProperty, JsLanguage, JsNode, Loop, NotOperator, ObjectLiteral, ObjectProperty, Parser, PostfixDecrement, PostfixIncrement, PrefixDecrement, PrefixIncrement, SetObjectProperty, SimpleObjectProperty, TypeOfOperator, UnaryMinusOperator, UnaryPlusOperator
Constant Summary
collapse
- DefaultParser =
Parser.new
- ExpressionParser =
Parser.new
- VERSION =
"0.1.1"
- LANGUAGE =
JsLanguage.new
- JavaString =
::Java::JavaClass.for_name("java.lang.String")
- JavaBoolean =
::Java::boolean.java_class
- JavaInt =
::Java::int.java_class
- JavaDouble =
::Java::double.java_class
- JavaList =
::Java::JavaClass.for_name("java.util.List")
- JavaSortedSet =
::Java::JavaClass.for_name("java.util.SortedSet")
- JavaCollectionTypes =
[JavaList,JavaSortedSet]
- MappedAstClasses =
{}
- EXTENSION =
'js'
- @@additional_props =
Hash.new {|h,k| h[k]={} }
Class Attribute Summary collapse
Class Method Summary
collapse
-
.add_feature(c, name, type, multiplicity) ⇒ Object
-
.add_many_ref_or_att(c, type_name, prop_name, ast_name) ⇒ Object
-
.add_ref_or_att(c, type_name, prop_name, ast_name, multiplicity = :single) ⇒ Object
-
.add_single_ref_or_att(c, type_name, prop_name, ast_name) ⇒ Object
-
.generate_model_per_file(src, dest, model_ext = "#{EXTENSION}.lm", max_nesting = 500, error_handler = nil) ⇒ Object
-
.generate_models_in_dir(src, dest, model_ext = "#{EXTENSION}.lm", max_nesting = 500, error_handler = nil) ⇒ Object
-
.get_att_type(type) ⇒ Object
Works with both Java and Ruby type.
-
.get_corresponding_metaclass(node) ⇒ Object
-
.get_metaclass_by_name(name) ⇒ Object
-
.getter?(java_method) ⇒ Boolean
-
.handle_models_in_dir(src, error_handler = nil, model_handler) ⇒ Object
-
.is_base_class?(name) ⇒ Boolean
-
.metasuperclass(java_super_class) ⇒ Object
-
.parse_code(code) ⇒ Object
-
.parse_file(path, encoding = nil) ⇒ Object
-
.rhino_node_class(name) ⇒ Object
-
.wrap(ast_names) ⇒ Object
Class Attribute Details
.verbose ⇒ Object
Returns the value of attribute verbose.
14
15
16
|
# File 'lib/codemodels/js/metamodel.rb', line 14
def verbose
@verbose
end
|
Class Method Details
.add_feature(c, name, type, multiplicity) ⇒ Object
119
120
121
122
123
124
125
126
127
|
# File 'lib/codemodels/js/metamodel.rb', line 119
def self.add_feature(c,name,type,multiplicity)
return unless type method = if Js.get_att_type(type)
multiplicity==:many ? :has_many_attr : :has_attr
else
multiplicity==:many ? :contains_many_uni : :contains_one_uni
end
c.send(method,name,type)
end
|
.add_many_ref_or_att(c, type_name, prop_name, ast_name) ⇒ Object
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
# File 'lib/codemodels/js/metamodel.rb', line 89
def self.add_many_ref_or_att(c,type_name,prop_name,ast_name)
rgen_class = get_metaclass_by_name(type_name)
if rgen_class
c.class_eval do
contains_many_uni prop_name, rgen_class
end
else
att_type = get_att_type(type_name)
if type_name
c.class_eval { has_many_attr prop_name, att_type }
else
raise "#{ast_name}) Property (many) #{prop_name} is else: #{type_name}"
end
end
end
|
.add_ref_or_att(c, type_name, prop_name, ast_name, multiplicity = :single) ⇒ Object
61
62
63
64
65
66
67
68
69
70
71
|
# File 'lib/codemodels/js/metamodel.rb', line 61
def self.add_ref_or_att(c,type_name,prop_name,ast_name,multiplicity=:single)
case multiplicity
when :single
add_single_ref_or_att(c,type_name,prop_name,ast_name)
when :many
add_many_ref_or_att(c,type_name,prop_name,ast_name)
else
raise "wrong"
end
end
|
.add_single_ref_or_att(c, type_name, prop_name, ast_name) ⇒ Object
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
# File 'lib/codemodels/js/metamodel.rb', line 73
def self.add_single_ref_or_att(c,type_name,prop_name,ast_name)
rgen_class = get_metaclass_by_name(type_name)
if rgen_class
c.class_eval do
contains_one_uni prop_name, rgen_class
end
else
att_type = get_att_type(type_name)
if type_name
c.class_eval { has_attr prop_name, att_type }
else
raise "#{ast_name}) Property (many) #{prop_name} is else: #{type_name}"
end
end
end
|
.generate_model_per_file(src, dest, model_ext = "#{EXTENSION}.lm", max_nesting = 500, error_handler = nil) ⇒ Object
24
25
26
27
28
29
|
# File 'lib/codemodels/js/model_building.rb', line 24
def self.generate_model_per_file(src,dest,model_ext="#{EXTENSION}.lm",max_nesting=500,error_handler=nil)
CodeModels::ModelBuilding.generate_model_per_file(src,dest,max_nesting,error_handler) do |src|
root = parse_file(src)
CodeModels::Serialization.rgenobject_to_model(root)
end
end
|
.generate_models_in_dir(src, dest, model_ext = "#{EXTENSION}.lm", max_nesting = 500, error_handler = nil) ⇒ Object
17
18
19
20
21
22
|
# File 'lib/codemodels/js/model_building.rb', line 17
def self.generate_models_in_dir(src,dest,model_ext="#{EXTENSION}.lm",max_nesting=500,error_handler=nil)
CodeModels::ModelBuilding.generate_models_in_dir(src,dest,EXTENSION,model_ext,max_nesting,error_handler) do |src|
root = parse_file(src)
CodeModels::Serialization.rgenobject_to_model(root)
end
end
|
.get_att_type(type) ⇒ Object
Works with both Java and Ruby type
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
# File 'lib/codemodels/js/metamodel.rb', line 44
def self.get_att_type(type)
return type if [String,RGen::MetamodelBuilder::DataTypes::Boolean,Integer,Float].include?(type)
return String if type.respond_to?(:enum?) and type.enum?
case type
when JavaString
String
when JavaBoolean
RGen::MetamodelBuilder::DataTypes::Boolean
when JavaInt
Integer
when JavaDouble
Float
else
nil
end
end
|
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
|
# File 'lib/codemodels/js/metamodel.rb', line 194
def self.get_corresponding_metaclass(node)
node_class = node.class
name = simple_java_class_name(node_class)
if name=='InfixExpression'
operator = AstNode::operatorToString(node.operator)
name = INFIX_OPERATORS[operator]
raise "Unknown operator for infix expression: #{operator}" unless name
end
if name=='UnaryExpression'
operator = AstNode::operatorToString(node.operator)
name = case operator
when '++'
node.prefix ? 'PrefixIncrement' : 'PostfixIncrement'
when '--'
node.prefix ? 'PrefixDecrement' : 'PostfixDecrement'
when '~'
'BitwiseNotOperator'
when '!'
'NotOperator'
when '-'
'UnaryMinusOperator'
when '+'
'UnaryPlusOperator'
when 'typeof'
'TypeOfOperator'
when 'delete'
'DeleteOperator'
else
raise "Unknown unary operator: #{operator}"
end
end
if name=='ObjectProperty'
if node.getter?
name='GetObjectProperty'
elsif node.setter?
name='SetObjectProperty'
else
name='SimpleObjectProperty'
end
end
if name=='SwitchCase'
if node.expression
name='ExpressionSwitchCase'
else
name='DefaultSwitchCase'
end
end
Js.const_get(name)
end
|
31
32
33
34
35
36
|
# File 'lib/codemodels/js/metamodel.rb', line 31
def self.get_metaclass_by_name(name)
return JsNode if name=='JsNode'
return JsNode if is_base_class?(name)
k = MappedAstClasses.keys.find{|k| k.name==name}
MappedAstClasses[k]
end
|
.getter?(java_method) ⇒ Boolean
190
191
192
|
# File 'lib/codemodels/js/metamodel.rb', line 190
def self.getter?(java_method)
(java_method.name.start_with?('get')||java_method.name.start_with?('is')) and java_method.argument_types.count==0
end
|
.handle_models_in_dir(src, error_handler = nil, model_handler) ⇒ Object
10
11
12
13
14
15
|
# File 'lib/codemodels/js/model_building.rb', line 10
def self.handle_models_in_dir(src,error_handler=nil,model_handler)
CodeModels::ModelBuilding.handle_models_in_dir(src,EXTENSION,error_handler,model_handler) do |src|
root = parse_file(src)
CodeModels::Serialization.rgenobject_to_model(root)
end
end
|
.is_base_class?(name) ⇒ Boolean
38
39
40
41
|
# File 'lib/codemodels/js/metamodel.rb', line 38
def self.is_base_class?(name)
['org.mozilla.javascript.Node','org.mozilla.javascript.ast.AstNode','java.lang.Object'].include? name
end
|
110
111
112
113
114
115
116
117
|
# File 'lib/codemodels/js/metamodel.rb', line 110
def self.metasuperclass(java_super_class)
if is_base_class?(java_super_class.name)
JsNode
else
raise "Super class #{java_super_class.name} not found, it should be wrapped before the classes extending it!" unless MappedAstClasses[java_super_class]
MappedAstClasses[java_super_class]
end
end
|
.parse_code(code) ⇒ Object
219
220
221
|
# File 'lib/codemodels/js/parser.rb', line 219
def self.parse_code(code)
DefaultParser.parse_code(code)
end
|
.parse_file(path, encoding = nil) ⇒ Object
223
224
225
|
# File 'lib/codemodels/js/parser.rb', line 223
def self.parse_file(path,encoding=nil)
DefaultParser.parse_file(path,encoding)
end
|
.rhino_node_class(name) ⇒ Object
106
107
108
|
# File 'lib/codemodels/js/metamodel.rb', line 106
def self.rhino_node_class(name)
java_class = ::Java::JavaClass.for_name("org.mozilla.javascript.ast.#{name}")
end
|
.wrap(ast_names) ⇒ Object
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
# File 'lib/codemodels/js/metamodel.rb', line 129
def self.wrap(ast_names)
ast_names.each do |ast_name|
ast_java_class = rhino_node_class(ast_name)
meta_super_class = metasuperclass(ast_java_class.superclass)
meta_class = Class.new(meta_super_class)
raise "Already mapped! #{ast_name}" if MappedAstClasses[ast_java_class]
MappedAstClasses[ast_java_class] = meta_class
Js.const_set ast_java_class.simple_name, meta_class
end
ast_names.each do |ast_name|
java_class = rhino_node_class(ast_name)
ast_class = java_class.ruby_class
c = MappedAstClasses[java_class]
to_ignore = %w( symbolTable compilerData comments liveLocals regexpString
regexpFlags indexForNameNode paramAndVarCount paramAndVarNames
paramAndVarConst jumpStatement finally loop default continue
containingTable definingScope parentScope top quoteCharacter
sourceName inStrictMode encodedSourceStart encodedSourceEnd
baseLineno endLineno functionCount regexpCount paramCount nextTempName
functions symbols childScopes encodedSource statement var const let
destructuring localName scope operatorPosition
)
c.class_eval do
ast_class.java_class.declared_instance_methods.select { |m| Js.getter?(m) }.each do |m|
prop_name = CodeModels::Js.property_name(m)
unless to_ignore.include?(prop_name)
if PROP_ADAPTERS[ast_class.simple_name.to_sym][prop_name.to_sym]
adapter = PROP_ADAPTERS[ast_class.simple_name.to_sym][prop_name.to_sym]
Js.add_feature(c,prop_name,adapter[:type],adapter[:multiplicity])
elsif Js.get_att_type(m.return_type)
has_attr prop_name, Js.get_att_type(m.return_type)
elsif MappedAstClasses.has_key?(m.return_type)
contains_one_uni prop_name, MappedAstClasses[m.return_type]
elsif JavaCollectionTypes.include?(m.return_type)
type_name = CodeModels::Js.get_generic_param_name(m.to_generic_string)
CodeModels::Js.add_many_ref_or_att(c,type_name,prop_name,ast_name)
elsif m.return_type.array?
CodeModels::Js.add_many_ref_or_att(c,m.return_type.component_type.name,prop_name,ast_name)
elsif Js.is_base_class?(m.return_type.name)
contains_one_uni prop_name, JsNode
else
raise "#{ast_name}) Property (single) '#{prop_name}' is else: #{m.return_type}"
end
end
end
end
end
end
|