codemodels-js 0.1.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,33 @@
1
+ # encoding: UTF-8
2
+ require 'codemodels'
3
+
4
+ module CodeModels
5
+
6
+ module Js
7
+
8
+ EXTENSION = 'js'
9
+
10
+ def self.handle_models_in_dir(src,error_handler=nil,model_handler)
11
+ CodeModels::ModelBuilding.handle_models_in_dir(src,EXTENSION,error_handler,model_handler) do |src|
12
+ root = parse_file(src)
13
+ CodeModels::Serialization.rgenobject_to_model(root)
14
+ end
15
+ end
16
+
17
+ def self.generate_models_in_dir(src,dest,model_ext="#{EXTENSION}.lm",max_nesting=500,error_handler=nil)
18
+ CodeModels::ModelBuilding.generate_models_in_dir(src,dest,EXTENSION,model_ext,max_nesting,error_handler) do |src|
19
+ root = parse_file(src)
20
+ CodeModels::Serialization.rgenobject_to_model(root)
21
+ end
22
+ end
23
+
24
+ def self.generate_model_per_file(src,dest,model_ext="#{EXTENSION}.lm",max_nesting=500,error_handler=nil)
25
+ CodeModels::ModelBuilding.generate_model_per_file(src,dest,max_nesting,error_handler) do |src|
26
+ root = parse_file(src)
27
+ CodeModels::Serialization.rgenobject_to_model(root)
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,227 @@
1
+ # encoding: UTF-8
2
+ require 'codemodels'
3
+ require 'codemodels/js/metamodel'
4
+
5
+ module CodeModels
6
+ module Js
7
+
8
+ class Parser < CodeModels::Parser
9
+
10
+ attr_accessor :skip_unknown_node
11
+
12
+ def internal_parse_artifact(artifact)
13
+ code = artifact.code
14
+ name = artifact.name
15
+ java_import 'java.io.StringReader'
16
+ java_import 'org.mozilla.javascript.CompilerEnvirons'
17
+ rhino_parser = (java_import 'org.mozilla.javascript.Parser')[0]
18
+ env = CompilerEnvirons.new
19
+ parser = rhino_parser.new(env)
20
+ reader = StringReader.new(code)
21
+ tree = parser.parse(reader, name, 1)
22
+ tree_to_model(tree,code,artifact)
23
+ end
24
+
25
+ def tree_to_model(tree,code,artifact,offset=0)
26
+ node_to_model(tree,code,artifact,offset)
27
+ end
28
+
29
+ private
30
+
31
+ def adapter_specific_class(model_class,ref)
32
+ return nil unless CodeModels::Js::ParsingAdapters[model_class]
33
+ CodeModels::Js::ParsingAdapters[model_class][ref.name]
34
+ end
35
+
36
+ # TODO remove code below, moved to CodeModels
37
+
38
+ def adapter(model_class,ref)
39
+ if CodeModels::Js::ParsingAdapters[model_class] && CodeModels::Js::ParsingAdapters[model_class][ref.name]
40
+ CodeModels::Js::ParsingAdapters[model_class][ref.name]
41
+ else
42
+ if model_class.superclass!=Object
43
+ adapter(model_class.superclass,ref)
44
+ else
45
+ nil
46
+ end
47
+ end
48
+ end
49
+
50
+ def reference_to_method(model_class,ref)
51
+ s = ref.name
52
+ adapted = adapter(model_class,ref)
53
+ s = adapted if adapted
54
+ s.to_sym
55
+ end
56
+
57
+ def attribute_to_method(model_class,att)
58
+ s = att.name
59
+ adapted = adapter(model_class,att)
60
+ s = adapted if adapted
61
+ s.to_sym
62
+ end
63
+
64
+ def assign_ref_to_model(model,ref,value,code,artifact,offset)
65
+ return unless value!=nil # we do not need to assign a nil...
66
+ if ref.many
67
+ adder_method = :"add#{ref.name.capitalize}"
68
+ value.each {|el| model.send(adder_method,node_to_model(el,code,artifact,offset))}
69
+ else
70
+ setter_method = :"#{ref.name}="
71
+ raise "Trying to assign an array to a single property. Class #{model.class}, property #{ref.name}" if value.is_a?(::Array)
72
+ model.send(setter_method,node_to_model(value,code,artifact,offset))
73
+ end
74
+ rescue Object => e
75
+ puts "Problem while assigning ref #{ref.name} (many? #{ref.many}) to #{model.class}. Value: #{value.class}"
76
+ puts "\t<<#{e}>>"
77
+ raise e
78
+ end
79
+
80
+ def assign_att_to_model(model,att,value)
81
+ if att.many
82
+ adder_method = :"add#{att.name.capitalize}"
83
+ value.each {|el| model.send(adder_method,el)}
84
+ else
85
+ setter_method = :"#{att.name}="
86
+ raise "Trying to assign an array to a single property. Class #{model.class}, property #{att.name}" if value.is_a?(::Array)
87
+ model.send(setter_method,value)
88
+ end
89
+ end
90
+
91
+ def populate_attr(node,att,model)
92
+ raise "Error: the attribute has no name" unless att.name
93
+ value = Js.get_feature_value(node,att.name,model)
94
+ model.send(:"#{att.name}=",value) if value!=nil
95
+ end
96
+
97
+ def populate_ref(node,ref,model,code,artifact,offset)
98
+ value = Js.get_feature_value(node,ref.name,model)
99
+ if value
100
+ if value==node
101
+ puts "avoiding loop... #{ref.name}, class #{node.class}"
102
+ return
103
+ end
104
+ if value.is_a?(Java::JavaUtil::Collection)
105
+ capitalized_name = ref.name.proper_capitalize
106
+ value.each do |el|
107
+ model.send(:"add#{capitalized_name}",node_to_model(el,code,artifact,offset))
108
+ end
109
+ else
110
+ model.send(:"#{ref.name}=",node_to_model(value,code,artifact,offset))
111
+ end
112
+ end
113
+ end
114
+
115
+ def assign_attr_value(model,prop_name,value)
116
+ if value.is_a?(Java::JavaUtil::Collection)
117
+ capitalized_name = prop_name.proper_capitalize
118
+ value.each do |el|
119
+ model.send(:"add#{capitalized_name}",el)
120
+ end
121
+ else
122
+ model.send(:"#{ref.name}=",value)
123
+ end
124
+ end
125
+
126
+ def assign_ref_value(model,prop_name,value,code,artifact,offset)
127
+ if value.is_a?(Java::JavaUtil::Collection)
128
+ capitalized_name = prop_name.proper_capitalize
129
+ value.each do |el|
130
+ #begin
131
+ model.send(:"add#{capitalized_name}",node_to_model(el,code,artifact,offset))
132
+ #rescue Object=>e
133
+ # raise "Assigning prop #{prop_name} to #{model}: #{e}"
134
+ #end
135
+ end
136
+ else
137
+ model.send(:"#{ref.name}=",node_to_model(value,code,artifact,offset))
138
+ end
139
+ end
140
+
141
+ def newlines(code,start_pos,end_pos)
142
+ piece = code[start_pos..end_pos]
143
+ piece.lines.count
144
+ end
145
+
146
+ def column_last_char(code,start_pos,end_pos)
147
+ piece = code[start_pos..end_pos]
148
+ last_line = nil
149
+ piece.lines.each{|l| last_line=l}
150
+ last_line.length
151
+ end
152
+
153
+ def node_to_model(node,code,artifact,offset)
154
+ metaclass = Js.get_corresponding_metaclass(node)
155
+ instance = metaclass.new
156
+
157
+ instance.language = LANGUAGE
158
+ instance.source = CodeModels::SourceInfo.new
159
+
160
+ bp = node.getAbsolutePosition
161
+ ep = node.getAbsolutePosition+node.length-1
162
+
163
+ instance.source.artifact = artifact
164
+ instance.source.position = SourcePosition.from_code_indexes(code,bp,ep)
165
+ instance.source.position.begin_point.column+=offset if instance.source.position.begin_point.line==1
166
+ instance.source.position.end_point.column+=offset if instance.source.position.end_point.line==1
167
+
168
+ metaclass.ecore.eAllAttributes.each do |attr|
169
+ unless Js.additional_property?(node.class,attr.name)
170
+ populate_attr(node,attr,instance)
171
+ end
172
+ end
173
+ metaclass.ecore.eAllReferences.each do |ref|
174
+ unless Js.additional_property?(node.class,ref.name)
175
+ populate_ref(node,ref,instance,code,artifact,offset)
176
+ end
177
+ end
178
+ # check for added properties
179
+ Js.additional_properties(node.class).each do |prop_name,prop_data|
180
+ value = prop_data[:getter].call(node)
181
+ if Js.get_att_type(prop_data[:prop_type])
182
+ assign_attr_value(instance,prop_name.to_s,value)
183
+ else
184
+ assign_ref_value(instance,prop_name.to_s,value,code,artifact,offset)
185
+ end
186
+ end
187
+ instance
188
+ end
189
+
190
+ end # class Parser
191
+
192
+ DefaultParser = Parser.new
193
+
194
+ ExpressionParser = Parser.new
195
+
196
+ class << ExpressionParser
197
+
198
+ def parse_code(code,filename='<code>')
199
+ parse_artifact(FileArtifact.new(filename,code))
200
+ end
201
+
202
+ def parse_artifact(artifact)
203
+ code = "a=#{artifact.code};".encode(internal_encoding)
204
+ java_import 'java.io.StringReader'
205
+ java_import 'org.mozilla.javascript.CompilerEnvirons'
206
+ rhino_parser = (java_import 'org.mozilla.javascript.Parser')[0]
207
+ env = CompilerEnvirons.new
208
+ parser = rhino_parser.new(env)
209
+ reader = StringReader.new(code)
210
+ filename = '<code>'
211
+ filename = artifact.filename if artifact.respond_to?(:filename)
212
+ tree = parser.parse(reader, filename, 1)
213
+ tree_to_model(tree.statements[0].expression.right,code,artifact,-2)
214
+ end
215
+
216
+ end
217
+
218
+ def self.parse_code(code)
219
+ DefaultParser.parse_code(code)
220
+ end
221
+
222
+ def self.parse_file(path,encoding=nil)
223
+ DefaultParser.parse_file(path,encoding)
224
+ end
225
+
226
+ end
227
+ end
@@ -0,0 +1,6 @@
1
+ # encoding: UTF-8
2
+ module CodeModels
3
+ module Js
4
+ VERSION = "0.1.0"
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'jars/js.jar'
2
+
3
+ require 'codemodels/js/metamodel'
4
+ require 'codemodels/js/parser'
5
+ require 'codemodels/js/model_building'
6
+ require 'codemodels/js/language'
data/lib/jars/js.jar ADDED
Binary file
data/test/data/app.js ADDED
@@ -0,0 +1,66 @@
1
+ (function(angular) {
2
+ 'use strict';
3
+
4
+ var app = angular.module('puzzleApp', ['slidingPuzzle', 'wordSearchPuzzle']);
5
+
6
+ // puzzle types
7
+ var types = [
8
+ { id: 'sliding-puzzle', title: 'Sliding puzzle' },
9
+ { id: 'word-search-puzzle', title: 'Word search puzzle' }
10
+ ];
11
+
12
+ /**
13
+ * Config
14
+ */
15
+ app.config(function($routeProvider) {
16
+ $routeProvider.when('/:type');
17
+ });
18
+
19
+ /**
20
+ * Startup
21
+ */
22
+ app.run(function($rootScope, $route, $filter) {
23
+ $rootScope.types = types;
24
+ $rootScope.type = types[0].id;
25
+
26
+ // set type on route change
27
+ $rootScope.$on('$routeChangeSuccess', function(event, route) {
28
+ $rootScope.type = ($filter('filter')(types, { id: route.params.type }).length ? route.params.type : types[0].id);
29
+ });
30
+ });
31
+
32
+ /**
33
+ * Advanced sliding puzzle controller
34
+ */
35
+ app.controller('slidingAdvancedCtrl', function($scope) {
36
+ $scope.puzzles = [
37
+ { src: './img/misko.jpg', title: 'Miško Hevery', rows: 4, cols: 4 },
38
+ { src: './img/igor.jpg', title: 'Igor Minár', rows: 3, cols: 3 },
39
+ { src: './img/vojta.jpg', title: 'Vojta Jína', rows: 4, cols: 3 }
40
+ ];
41
+ });
42
+
43
+ /**
44
+ * Word search puzzle controller
45
+ */
46
+ app.controller('wordSearchCtrl', function($scope) {
47
+ $scope.matrix = [
48
+ ['N', 'I', 'G', 'O', 'R', 'Y', 'G', 'S', 'T', 'T', 'A', 'N'],
49
+ ['O', 'G', 'G', 'U', 'L', 'C', 'O', 'E', 'P', 'E', 'A', 'S'],
50
+ ['I', 'N', 'N', 'R', 'M', 'N', 'O', 'R', 'I', 'M', 'E', 'C'],
51
+ ['T', 'I', 'A', 'I', 'O', 'E', 'G', 'V', 'R', 'P', 'V', 'E'],
52
+ ['C', 'T', 'T', 'E', 'D', 'D', 'L', 'I', 'C', 'L', 'I', 'N'],
53
+ ['E', 'S', 'J', 'P', 'U', 'N', 'E', 'C', 'S', 'A', 'T', 'A'],
54
+ ['J', 'E', 'O', 'O', 'L', 'E', 'I', 'E', 'A', 'T', 'C', 'R'],
55
+ ['N', 'T', 'V', 'C', 'E', 'P', 'J', 'B', 'V', 'E', 'E', 'I'],
56
+ ['I', 'S', 'I', 'S', 'S', 'E', 'S', 'A', 'A', 'W', 'R', 'O'],
57
+ ['O', 'K', 'S', 'I', 'M', 'D', 'E', 'S', 'J', 'O', 'I', 'M'],
58
+ ['R', 'E', 'L', 'L', 'O', 'R', 'T', 'N', 'O', 'C', 'D', 'E']
59
+ ];
60
+ $scope.words = [
61
+ 'BINDING', 'CONTROLLER', 'DEPENDENCY', 'DIRECTIVE', 'GOOGLE', 'IGOR', 'INJECTION', 'JAVASCRIPT',
62
+ 'MISKO', 'MODULES', 'SCENARIO', 'SCOPE', 'SERVICE', 'TEMPLATE', 'TESTING', 'VOJTA'
63
+ ];
64
+ });
65
+
66
+ })(window.angular);
@@ -0,0 +1,66 @@
1
+ (function(angular) {
2
+ 'use strict';
3
+
4
+ var app = angular.module('puzzleApp', ['slidingPuzzle', 'wordSearchPuzzle']);
5
+
6
+ // puzzle types
7
+ var types = [
8
+ { id: 'sliding-puzzle', title: 'Sliding puzzle' },
9
+ { id: 'word-search-puzzle', title: 'Word search puzzle' }
10
+ ];
11
+
12
+ /**
13
+ * Config
14
+ */
15
+ app.config(function($routeProvider) {
16
+ $routeProvider.when('/:type');
17
+ });
18
+
19
+ /**
20
+ * Startup
21
+ */
22
+ app.run(function($rootScope, $route, $filter) {
23
+ $rootScope.types = types;
24
+ $rootScope.type = types[0].id;
25
+
26
+ // set type on route change
27
+ $rootScope.$on('$routeChangeSuccess', function(event, route) {
28
+ $rootScope.type = ($filter('filter')(types, { id: route.params.type }).length ? route.params.type : types[0].id);
29
+ });
30
+ });
31
+
32
+ /**
33
+ * Advanced sliding puzzle controller
34
+ */
35
+ app.controller('slidingAdvancedCtrl', function($scope) {
36
+ $scope.puzzles = [
37
+ { src: './img/misko.jpg', title: 'Misko Hevery', rows: 4, cols: 4 },
38
+ { src: './img/igor.jpg', title: 'Igor Minar', rows: 3, cols: 3 },
39
+ { src: './img/vojta.jpg', title: 'Vojta Jina', rows: 4, cols: 3 }
40
+ ];
41
+ });
42
+
43
+ /**
44
+ * Word search puzzle controller
45
+ */
46
+ app.controller('wordSearchCtrl', function($scope) {
47
+ $scope.matrix = [
48
+ ['N', 'I', 'G', 'O', 'R', 'Y', 'G', 'S', 'T', 'T', 'A', 'N'],
49
+ ['O', 'G', 'G', 'U', 'L', 'C', 'O', 'E', 'P', 'E', 'A', 'S'],
50
+ ['I', 'N', 'N', 'R', 'M', 'N', 'O', 'R', 'I', 'M', 'E', 'C'],
51
+ ['T', 'I', 'A', 'I', 'O', 'E', 'G', 'V', 'R', 'P', 'V', 'E'],
52
+ ['C', 'T', 'T', 'E', 'D', 'D', 'L', 'I', 'C', 'L', 'I', 'N'],
53
+ ['E', 'S', 'J', 'P', 'U', 'N', 'E', 'C', 'S', 'A', 'T', 'A'],
54
+ ['J', 'E', 'O', 'O', 'L', 'E', 'I', 'E', 'A', 'T', 'C', 'R'],
55
+ ['N', 'T', 'V', 'C', 'E', 'P', 'J', 'B', 'V', 'E', 'E', 'I'],
56
+ ['I', 'S', 'I', 'S', 'S', 'E', 'S', 'A', 'A', 'W', 'R', 'O'],
57
+ ['O', 'K', 'S', 'I', 'M', 'D', 'E', 'S', 'J', 'O', 'I', 'M'],
58
+ ['R', 'E', 'L', 'L', 'O', 'R', 'T', 'N', 'O', 'C', 'D', 'E']
59
+ ];
60
+ $scope.words = [
61
+ 'BINDING', 'CONTROLLER', 'DEPENDENCY', 'DIRECTIVE', 'GOOGLE', 'IGOR', 'INJECTION', 'JAVASCRIPT',
62
+ 'MISKO', 'MODULES', 'SCENARIO', 'SCOPE', 'SERVICE', 'TEMPLATE', 'TESTING', 'VOJTA'
63
+ ];
64
+ });
65
+
66
+ })(window.angular);
@@ -0,0 +1,52 @@
1
+ require 'test_helper'
2
+
3
+ class TestBasicNodeProperties < Test::Unit::TestCase
4
+
5
+ include TestHelper
6
+ include CodeModels
7
+ include CodeModels::Js
8
+
9
+ def test_node_has_expected_basic_properties
10
+ r = parse_code("i < 10;")
11
+ assert r.respond_to?(:source)
12
+ assert r.respond_to?(:language)
13
+ assert_equal CodeModels::Js::LANGUAGE,r.language
14
+ end
15
+
16
+ def test_node_has_expected_basic_position
17
+ r = parse_code("i < 10;")
18
+ assert_not_nil r.source
19
+ assert_not_nil r.source.position,"Source of #{r.class} has not the position"
20
+ assert_not_nil r.source.position.begin_point
21
+ assert_not_nil r.source.position.end_point
22
+ assert_equal 1,r.source.position.begin_point.line
23
+ assert_equal 1,r.source.position.begin_point.column
24
+ assert_equal 1,r.source.position.end_point.line
25
+ assert_equal 7,r.source.position.end_point.column
26
+ end
27
+
28
+ def test_node_has_expected_multiline_position
29
+ r = parse_code("{\ni < 10;\n}")
30
+ assert_not_nil r.source
31
+ assert_not_nil r.source.position
32
+ assert_not_nil r.source.position.begin_point
33
+ assert_not_nil r.source.position.end_point
34
+ assert_equal 1,r.source.position.begin_point.line
35
+ assert_equal 1,r.source.position.begin_point.column
36
+ assert_equal 3,r.source.position.end_point.line
37
+ assert_equal 1,r.source.position.end_point.column
38
+ end
39
+
40
+ def test_node_code
41
+ r = parse_code("{\ni < 10;\n}")
42
+ assert_equal "{\ni < 10;\n}",r.source.code
43
+ end
44
+
45
+ def test_artifact_final_host_is_set_correctly_for_all
46
+ r = Js.parse_file('test/data/app.js')
47
+ r.traverse(:also_foreign) do |n|
48
+ assert_equal 'test/data/app.js',n.source.artifact.final_host.filename, "Node with wrong final_host: #{n}"
49
+ end
50
+ end
51
+
52
+ end