codemodels 0.2.6-java → 0.2.7-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.
- checksums.yaml +4 -4
- data/codemodels.gemspec +8 -7
- data/lib/codemodels/artifact.rb +15 -4
- data/lib/codemodels/language.rb +10 -3
- data/lib/codemodels/model_building.rb +2 -1
- data/lib/codemodels/monkey_patching.rb +2 -0
- data/lib/codemodels/navigation.rb +19 -4
- data/lib/codemodels/parser.rb +27 -10
- data/lib/codemodels/position.rb +27 -16
- data/lib/codemodels/serialization.rb +18 -12
- data/lib/codemodels/source_info.rb +34 -19
- data/lib/codemodels/version.rb +1 -1
- data/test/test_language.rb +19 -4
- data/test/test_parser.rb +18 -0
- metadata +28 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a2687b4c80653a5757086fcd1c7eafa187d3321
|
4
|
+
data.tar.gz: e33b1d14fb8a3463b0bb9c2e6fee8e3501cfb926
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 77c41350b27ae2be3e258154227e951325ee120ebfad6db08624b34106702e1232996f78e66aedcf31637b20fe5d2243628f489448990125ed88b4be8cf1e379
|
7
|
+
data.tar.gz: e006252eabfea9c26d342795faa62b14da3be41dab18eb397d5a10a399ac5b47fb71469b9d9235ace6120ddfb71337748308735ee19378d43fc89e940d256c71
|
data/codemodels.gemspec
CHANGED
@@ -19,12 +19,13 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
|
-
s.add_dependency
|
23
|
-
s.add_dependency
|
24
|
-
s.add_dependency
|
22
|
+
s.add_dependency 'json', '~> 1.8'
|
23
|
+
s.add_dependency 'rgen', '~> 0.6.6'
|
24
|
+
s.add_dependency 'rgen_ext','0.0.2'
|
25
25
|
|
26
|
-
s.add_development_dependency
|
27
|
-
s.add_development_dependency
|
28
|
-
s.add_development_dependency
|
29
|
-
s.add_development_dependency
|
26
|
+
s.add_development_dependency 'bundler'
|
27
|
+
s.add_development_dependency 'rake'
|
28
|
+
s.add_development_dependency 'simplecov'
|
29
|
+
s.add_development_dependency 'rubygems-tasks', '~> 0.2.4'
|
30
|
+
s.add_development_dependency 'yard', '~> 0.8.7'
|
30
31
|
end
|
data/lib/codemodels/artifact.rb
CHANGED
@@ -3,8 +3,16 @@ require 'codemodels/position'
|
|
3
3
|
|
4
4
|
module CodeModels
|
5
5
|
|
6
|
-
|
6
|
+
# An artifact is everything that
|
7
|
+
# can contain code
|
8
|
+
class Artifact
|
7
9
|
|
10
|
+
def initialize
|
11
|
+
raise "You should not use Artifact directly" if self.class==Artifact
|
12
|
+
end
|
13
|
+
|
14
|
+
# @param point a point relative to this artifact
|
15
|
+
# @return the same point specified in respect to the absolute artifact
|
8
16
|
def point_to_absolute(point)
|
9
17
|
offset = absolute_start
|
10
18
|
p = SourcePoint.new
|
@@ -14,6 +22,8 @@ class AbstractArtifact
|
|
14
22
|
p
|
15
23
|
end
|
16
24
|
|
25
|
+
# @param position a position relative to this artifact
|
26
|
+
# @return the same position specified in respect to the absolute artifact
|
17
27
|
def position_to_absolute(position)
|
18
28
|
pos = SourcePosition.new
|
19
29
|
pos.begin_point = point_to_absolute(position.begin_point)
|
@@ -23,7 +33,8 @@ class AbstractArtifact
|
|
23
33
|
|
24
34
|
end
|
25
35
|
|
26
|
-
|
36
|
+
# Represent a snippet embedded in something else
|
37
|
+
class EmbeddedArtifact < Artifact
|
27
38
|
attr_accessor :host_artifact
|
28
39
|
attr_accessor :position_in_host
|
29
40
|
|
@@ -67,7 +78,7 @@ class EmbeddedArtifact < AbstractArtifact
|
|
67
78
|
|
68
79
|
end
|
69
80
|
|
70
|
-
class FileArtifact <
|
81
|
+
class FileArtifact < Artifact
|
71
82
|
attr_reader :filename
|
72
83
|
attr_reader :code
|
73
84
|
|
@@ -114,7 +125,7 @@ class FileArtifact < AbstractArtifact
|
|
114
125
|
|
115
126
|
end
|
116
127
|
|
117
|
-
class StringArtifact <
|
128
|
+
class StringArtifact < Artifact
|
118
129
|
attr_reader :code
|
119
130
|
|
120
131
|
def initialize(code)
|
data/lib/codemodels/language.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
1
3
|
# encoding: utf-8
|
2
4
|
module CodeModels
|
3
5
|
|
@@ -5,18 +7,21 @@ module CodeModels
|
|
5
7
|
|
6
8
|
class Language
|
7
9
|
attr_reader :name
|
10
|
+
attr_reader :filenames
|
8
11
|
attr_reader :extensions
|
9
12
|
attr_reader :parser
|
10
13
|
|
11
14
|
def initialize(name)
|
12
15
|
@name = name
|
13
16
|
@extensions = []
|
17
|
+
@filenames = []
|
14
18
|
end
|
15
19
|
|
16
20
|
def can_parse?(path)
|
21
|
+
simple_name = Pathname.new(path).basename.to_s
|
17
22
|
extension = File.extname(path)
|
18
23
|
extension=extension[1..-1] if extension.length>0
|
19
|
-
@extensions.include?(extension)
|
24
|
+
@extensions.include?(extension) || @filenames.include?(simple_name)
|
20
25
|
end
|
21
26
|
|
22
27
|
end
|
@@ -31,17 +36,19 @@ def self.registered_languages
|
|
31
36
|
@@languages
|
32
37
|
end
|
33
38
|
|
34
|
-
class
|
39
|
+
class NoLanguageRegisteredError < StandardError
|
35
40
|
attr_reader :path
|
36
41
|
|
37
42
|
def initialize(path)
|
43
|
+
super("No language registered to parse #{path}")
|
38
44
|
@path = path
|
39
45
|
end
|
46
|
+
|
40
47
|
end
|
41
48
|
|
42
49
|
def self.parse_file(path)
|
43
50
|
l = @@languages.find {|l| l.can_parse?(path) }
|
44
|
-
raise
|
51
|
+
raise NoLanguageRegisteredError.new(path) unless l
|
45
52
|
l.parser.parse_file(path)
|
46
53
|
end
|
47
54
|
|
@@ -1,8 +1,11 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
module CodeModels
|
3
3
|
|
4
|
+
# The flag :also_foreign deciced if to consider the
|
5
|
+
# AST of embedded code
|
4
6
|
module NavigationExtensions
|
5
7
|
|
8
|
+
# All direct children
|
6
9
|
def all_children(flag=nil)
|
7
10
|
also_foreign = (flag==:also_foreign)
|
8
11
|
arr = []
|
@@ -11,7 +14,6 @@ module NavigationExtensions
|
|
11
14
|
# two references with the same name are found
|
12
15
|
already_used_references = []
|
13
16
|
ecore.eAllReferences.sort_by{|r| r.name}.select {|r| r.containment}.each do |ref|
|
14
|
-
#raise "Too many features with name #{ref.name}. Count: #{features_by_name(ref.name).count}" if features_by_name(ref.name).count!=1
|
15
17
|
unless already_used_references.include?(ref.name)
|
16
18
|
res = self.send(ref.name.to_sym)
|
17
19
|
if ref.many
|
@@ -32,6 +34,7 @@ module NavigationExtensions
|
|
32
34
|
arr
|
33
35
|
end
|
34
36
|
|
37
|
+
# All direct and indirect children
|
35
38
|
def all_children_deep(flag=nil)
|
36
39
|
arr = []
|
37
40
|
all_children(flag).each do |c|
|
@@ -43,6 +46,8 @@ module NavigationExtensions
|
|
43
46
|
arr
|
44
47
|
end
|
45
48
|
|
49
|
+
# Execute an operation on the node itself and all children,
|
50
|
+
# direct and indirect.
|
46
51
|
def traverse(flag=nil,&op)
|
47
52
|
op.call(self)
|
48
53
|
all_children_deep(flag).each do |c|
|
@@ -50,14 +55,20 @@ module NavigationExtensions
|
|
50
55
|
end
|
51
56
|
end
|
52
57
|
|
58
|
+
# All the values considering the node,
|
59
|
+
# and the direct and indirect children (if :deep is contained in flags).
|
60
|
+
# In that case the presence of :also_foreign determine if also embedded
|
61
|
+
# ASTs are considrered
|
53
62
|
def values_map(flags=nil)
|
63
|
+
raise ":also_foreign makes sense only when :deep is used" if flags.include?(:also_foreign) && !flags.include?(:deep)
|
54
64
|
if flags.include?(:deep)
|
55
|
-
collect_values_with_count_subtree(flags
|
65
|
+
collect_values_with_count_subtree(flags.include?(:also_foreign)?(:also_foreign):nil)
|
56
66
|
else
|
57
67
|
collect_values_with_count
|
58
68
|
end
|
59
69
|
end
|
60
70
|
|
71
|
+
# Deprecated, use values_map instead
|
61
72
|
def collect_values_with_count
|
62
73
|
values = Hash.new {|h,k| h[k]=0}
|
63
74
|
self.class.ecore.eAllAttributes.each do |a|
|
@@ -73,6 +84,7 @@ module NavigationExtensions
|
|
73
84
|
values
|
74
85
|
end
|
75
86
|
|
87
|
+
# Deprecated, use values_map instead
|
76
88
|
def collect_values_with_count_subtree(flag=nil)
|
77
89
|
values = collect_values_with_count
|
78
90
|
all_children_deep(flag).each do |c|
|
@@ -103,9 +115,10 @@ module NavigationExtensions
|
|
103
115
|
selected[0]
|
104
116
|
end
|
105
117
|
|
118
|
+
# Parent of the node.
|
119
|
+
# A foreign child could have its own parent in the foreign ast, which is not part of the complexive AST
|
120
|
+
# the foreign parent has therefore the precedence.
|
106
121
|
def container(flag=nil)
|
107
|
-
# a foreign child could have its own parent in the foreign ast, which is not part of the complexive AST
|
108
|
-
# the foreign parent has therefore the precedence.
|
109
122
|
also_foreign = (flag==:also_foreign)
|
110
123
|
if also_foreign && self.foreign_container
|
111
124
|
return self.foreign_container
|
@@ -127,10 +140,12 @@ module NavigationExtensions
|
|
127
140
|
all_children_deep(:also_foreign)
|
128
141
|
end
|
129
142
|
|
143
|
+
# Deprecated
|
130
144
|
def traverse_also_foreign(&block)
|
131
145
|
traverse(:also_foreign,&block)
|
132
146
|
end
|
133
147
|
|
148
|
+
# Deprecated
|
134
149
|
def container_also_foreign
|
135
150
|
container(:also_foreign)
|
136
151
|
end
|
data/lib/codemodels/parser.rb
CHANGED
@@ -4,54 +4,67 @@ require 'codemodels/monkey_patching'
|
|
4
4
|
|
5
5
|
module CodeModels
|
6
6
|
|
7
|
+
# A parser get code and produce an AST
|
8
|
+
#
|
9
|
+
# Sub-classes should provide internal_parse_artifact
|
7
10
|
class Parser
|
8
11
|
|
9
12
|
DEFAULT_INTERNAL_ENCODING = 'UTF-8'
|
10
13
|
|
14
|
+
# Internal encoding.
|
15
|
+
# Code is internally converted to this encoding.
|
11
16
|
attr_reader :internal_encoding
|
12
17
|
|
13
18
|
def initialize(internal_encoding=DEFAULT_INTERNAL_ENCODING)
|
14
19
|
@internal_encoding = internal_encoding
|
15
20
|
puts "WARN using an internal encoding different from the local encoding..." if "".encoding.name!=internal_encoding
|
21
|
+
raise "The method internal_parse_artifact should be implemented" unless self.respond_to?(:internal_parse_artifact)
|
16
22
|
end
|
17
23
|
|
18
24
|
def parse_artifact(artifact)
|
19
25
|
internal_parse_artifact(artifact)
|
20
26
|
end
|
21
27
|
|
28
|
+
# Parse the file by producing an artifact corresponding to the file
|
22
29
|
def parse_file(path,file_encoding=nil)
|
23
30
|
file_encoding = internal_encoding unless file_encoding
|
24
31
|
code = IO.read(path,{ :encoding => file_encoding, :mode => 'rb'})
|
25
32
|
code = code.encode(internal_encoding)
|
26
33
|
artifact = FileArtifact.new(path,code)
|
27
|
-
|
28
|
-
end
|
29
|
-
|
30
|
-
# Deprecated: use parse_string
|
31
|
-
def parse_code(code)
|
32
|
-
parse_string(code)
|
34
|
+
parse_artifact(artifact)
|
33
35
|
end
|
34
36
|
|
37
|
+
# Parse the file by producing an artifact corresponding to the string
|
35
38
|
def parse_string(code)
|
36
39
|
raise "Wrong encoding: it is #{code.encoding.name}, internally expected #{internal_encoding}" unless code.encoding.name==internal_encoding
|
37
40
|
artifact = StringArtifact.new(code)
|
38
|
-
|
41
|
+
parse_artifact(artifact)
|
39
42
|
end
|
40
43
|
|
41
44
|
end
|
42
45
|
|
43
|
-
class ParsingError <
|
46
|
+
class ParsingError < StandardError
|
44
47
|
attr_reader :node
|
45
48
|
attr_reader :line
|
49
|
+
attr_reader :column
|
46
50
|
|
47
|
-
def initialize(node,msg,line=nil)
|
51
|
+
def initialize(node,msg,line=nil,column=nil)
|
52
|
+
super("Parsing error: #{msg}")
|
48
53
|
@node = node
|
49
54
|
@msg = msg
|
50
55
|
@line = line
|
56
|
+
@column = column
|
57
|
+
raise "If column is specified also line should be" if line==nil and column!=nil
|
51
58
|
end
|
52
59
|
|
53
60
|
def to_s
|
54
|
-
|
61
|
+
if @line and @column
|
62
|
+
"Parsing error: #{@msg}, node: #{node}, line: #{@line}, column: #{column}"
|
63
|
+
elsif @line
|
64
|
+
"Parsing error: #{@msg}, node: #{node}, line: #{@line}"
|
65
|
+
else
|
66
|
+
"Parsing error: #{@msg}, node: #{node}"
|
67
|
+
end
|
55
68
|
end
|
56
69
|
|
57
70
|
end
|
@@ -60,10 +73,14 @@ end
|
|
60
73
|
# wrapping another parser and adapting it
|
61
74
|
# to CodeModels. When they encounter a node type
|
62
75
|
# they do not know how to wrap this error is thrown.
|
76
|
+
#
|
63
77
|
# This is not just for java based parsers, so it should
|
64
78
|
# be not moved to codemodels-javaparserwrapper
|
65
79
|
class UnknownNodeType < ParsingError
|
66
80
|
|
81
|
+
# @param node the node that can not be translated
|
82
|
+
# @param node_type node that is not understood
|
83
|
+
# @param where describe where the node was contained (artifact, line, column)
|
67
84
|
def initialize(node,line=nil,node_type=nil,where=nil)
|
68
85
|
super(node,"UnknownNodeType: type=#{node_type} , where: #{where}")
|
69
86
|
end
|
data/lib/codemodels/position.rb
CHANGED
@@ -2,11 +2,17 @@
|
|
2
2
|
|
3
3
|
module CodeModels
|
4
4
|
|
5
|
+
# Point in an artifact, indicated by line and column
|
6
|
+
# The newlines are considered as column 0 of the next line.
|
7
|
+
# Lines should be always positive and all but newlines should have
|
8
|
+
# columns positive (>0)
|
5
9
|
class SourcePoint
|
6
10
|
include Comparable
|
7
11
|
|
8
12
|
attr_accessor :line, :column
|
9
13
|
|
14
|
+
# @param [String code]
|
15
|
+
# @param [int index] index of the starting character in the code
|
10
16
|
def self.from_code_index(code,index)
|
11
17
|
l = line(code,index)
|
12
18
|
c = column(code,index)
|
@@ -50,18 +56,6 @@ class SourcePoint
|
|
50
56
|
index+=@column
|
51
57
|
index-=1
|
52
58
|
index
|
53
|
-
|
54
|
-
# current_line = lines.next
|
55
|
-
# i=0
|
56
|
-
# c=0
|
57
|
-
# while c<@column
|
58
|
-
# c += current_line[i]=='\t' ? COLUMNS_FOR_TAB : 1
|
59
|
-
# i += 1
|
60
|
-
# end
|
61
|
-
|
62
|
-
# index+=c
|
63
|
-
# index-=1
|
64
|
-
# index
|
65
59
|
end
|
66
60
|
|
67
61
|
def <=>(other)
|
@@ -90,6 +84,7 @@ class SourcePoint
|
|
90
84
|
end
|
91
85
|
end
|
92
86
|
|
87
|
+
# A position is a pair of a begin and an end point
|
93
88
|
class SourcePosition
|
94
89
|
attr_accessor :begin_point, :end_point
|
95
90
|
|
@@ -112,6 +107,17 @@ class SourcePosition
|
|
112
107
|
@begin_point.column = column
|
113
108
|
end
|
114
109
|
|
110
|
+
def end_line=(line)
|
111
|
+
@end_point=SourcePoint.new unless @end_point
|
112
|
+
@end_point.line = line
|
113
|
+
end
|
114
|
+
|
115
|
+
def end_column=(column)
|
116
|
+
@end_point=SourcePoint.new unless @end_point
|
117
|
+
@end_point.column = column
|
118
|
+
end
|
119
|
+
|
120
|
+
|
115
121
|
def eql?(other)
|
116
122
|
return false unless other.respond_to?(:begin_point)
|
117
123
|
return false unless other.respond_to?(:end_point)
|
@@ -126,10 +132,15 @@ class SourcePosition
|
|
126
132
|
"from #{@begin_point} to #{@end_point}"
|
127
133
|
end
|
128
134
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
135
|
+
# Deprecated, use get_code instead
|
136
|
+
def get_string(artifact_code)
|
137
|
+
get_code(artifact_code)
|
138
|
+
end
|
139
|
+
|
140
|
+
def get_code(artifact_code)
|
141
|
+
as = @begin_point.to_absolute_index(artifact_code)
|
142
|
+
ae = @end_point.to_absolute_index(artifact_code)
|
143
|
+
artifact_code[as..ae]
|
133
144
|
end
|
134
145
|
|
135
146
|
def begin_line
|
@@ -1,18 +1,24 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
# This code permit to transform AstNode in Hash objects
|
4
|
-
# containing lists and single values
|
5
|
-
|
6
3
|
require 'json'
|
7
4
|
require 'fileutils'
|
8
5
|
require 'rgen/metamodel_builder'
|
9
6
|
|
10
7
|
module CodeModels
|
8
|
+
|
9
|
+
# Everything related to serialization to Hash, lists and basic values
|
10
|
+
# is contained in this module
|
11
11
|
module Serialization
|
12
12
|
|
13
|
+
# Intended to be included
|
13
14
|
module SerializationFunctionalities
|
14
15
|
|
16
|
+
# Deprecated, use to_hash instead
|
15
17
|
def to_json(params={})
|
18
|
+
to_hash(params)
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_hash(params={})
|
16
22
|
serialization_memory = params.fetch(:memory,SerializationMemory.new)
|
17
23
|
adapters = params.fetch(:adapters,{})
|
18
24
|
with_source_info = params.fetch(:source_info,true)
|
@@ -21,15 +27,15 @@ module SerializationFunctionalities
|
|
21
27
|
map = { 'type' => type, 'id' => serialization_memory.id(e_object) }
|
22
28
|
if with_source_info
|
23
29
|
if self.respond_to?(:source) && self.source
|
24
|
-
map['source'] =
|
30
|
+
map['source'] = source_info_to_hash(self.source)
|
25
31
|
end
|
26
32
|
end
|
27
33
|
e_class = e_object.class.ecore
|
28
34
|
e_class.eAllAttributes.sort_by { |a| a.name }.each do |a|
|
29
|
-
|
35
|
+
insert_attr_value_in_hash(map,a)
|
30
36
|
end
|
31
37
|
e_class.eAllReferences.sort_by { |r| r.name }.each do |r|
|
32
|
-
id =
|
38
|
+
id = insert_ref_value_in_hash(map,r,adapters,serialization_memory)
|
33
39
|
end
|
34
40
|
if adapters.has_key? type
|
35
41
|
adapters[type].adapt(self,map)
|
@@ -39,7 +45,7 @@ module SerializationFunctionalities
|
|
39
45
|
|
40
46
|
private
|
41
47
|
|
42
|
-
def
|
48
|
+
def source_info_to_hash(source_info)
|
43
49
|
source_map = {}
|
44
50
|
if self.source.begin_point
|
45
51
|
source_map['begin_point'] = {'line'=> self.source.begin_point.line, 'column'=>self.source.begin_point.column}
|
@@ -54,7 +60,7 @@ module SerializationFunctionalities
|
|
54
60
|
self.class.to_s
|
55
61
|
end
|
56
62
|
|
57
|
-
def
|
63
|
+
def insert_attr_value_in_hash(map,e_attr)
|
58
64
|
value = self.send(e_attr.name.to_sym)
|
59
65
|
unless e_attr.many
|
60
66
|
map["attr_#{e_attr.name}"] = value
|
@@ -67,24 +73,24 @@ module SerializationFunctionalities
|
|
67
73
|
end
|
68
74
|
end
|
69
75
|
|
70
|
-
def
|
76
|
+
def insert_ref_value_in_hash(map,e_ref,adapters,serialization_memory)
|
71
77
|
value = self.send e_ref.name.to_sym
|
72
78
|
|
73
79
|
propname = "relcont_#{e_ref.name}" if e_ref.containment
|
74
80
|
propname = "relnoncont_#{e_ref.name}" if not e_ref.containment
|
75
81
|
|
76
82
|
unless e_ref.many
|
77
|
-
map[propname] =
|
83
|
+
map[propname] = insert_ref_single_value_in_hash(value,e_ref.containment,adapters,serialization_memory)
|
78
84
|
else
|
79
85
|
l = []
|
80
86
|
(0...(value.size)).each do |i|
|
81
|
-
l <<
|
87
|
+
l << insert_ref_single_value_in_hash(value.at(i),e_ref.containment,adapters,serialization_memory)
|
82
88
|
end
|
83
89
|
map[propname] = l
|
84
90
|
end
|
85
91
|
end
|
86
92
|
|
87
|
-
def
|
93
|
+
def insert_ref_single_value_in_hash(single_value,containment,adapters,serialization_memory)
|
88
94
|
if containment
|
89
95
|
single_value.to_json(memory:serialization_memory,adapters:adapters)
|
90
96
|
else
|
@@ -7,6 +7,13 @@ require 'codemodels/artifact'
|
|
7
7
|
|
8
8
|
module CodeModels
|
9
9
|
|
10
|
+
# Info which specify from which part of the code a node was
|
11
|
+
# obtained.
|
12
|
+
#
|
13
|
+
# Some methods can accept a scope to be :relative or :absolute.
|
14
|
+
# When a piece of code derives from some embedded snipped (e.g., a piece of JS in html file)
|
15
|
+
# the relative position is specified in respect to the snippet, while the absolute
|
16
|
+
# in respect to the containing file.
|
10
17
|
class SourceInfo
|
11
18
|
attr_accessor :artifact
|
12
19
|
attr_accessor :position
|
@@ -31,46 +38,48 @@ class SourceInfo
|
|
31
38
|
@position = value
|
32
39
|
end
|
33
40
|
|
41
|
+
# @param data is expected to be an hash with :line and :column
|
34
42
|
def begin_point=(data)
|
35
43
|
point = data_to_point(data)
|
36
44
|
@position = SourcePosition.new unless @position
|
37
45
|
@position.begin_point = point
|
38
46
|
end
|
39
47
|
|
48
|
+
# @param data is expected to be an hash with :line and :column
|
40
49
|
def end_point=(data)
|
41
50
|
point = data_to_point(data)
|
42
51
|
@position = SourcePosition.new unless @position
|
43
52
|
@position.end_point = point
|
44
53
|
end
|
45
54
|
|
46
|
-
def begin_line(
|
47
|
-
position.begin_point.line
|
55
|
+
def begin_line(scope=:relative)
|
56
|
+
position(scope).begin_point.line
|
48
57
|
end
|
49
58
|
|
50
|
-
def end_line(
|
51
|
-
position(
|
59
|
+
def end_line(scope=:relative)
|
60
|
+
position(scope).end_point.line
|
52
61
|
end
|
53
62
|
|
54
|
-
def begin_column(
|
55
|
-
position(
|
63
|
+
def begin_column(scope=:relative)
|
64
|
+
position(scope).begin_point.column
|
56
65
|
end
|
57
66
|
|
58
67
|
def end_column(flag=:relative)
|
59
|
-
position(
|
68
|
+
position(scope).end_point.column
|
60
69
|
end
|
61
70
|
|
62
|
-
def begin_point(
|
63
|
-
position(
|
71
|
+
def begin_point(scope=:relative)
|
72
|
+
position(scope).begin_point
|
64
73
|
end
|
65
74
|
|
66
|
-
def end_point(
|
67
|
-
position(
|
75
|
+
def end_point(scope=:relative)
|
76
|
+
position(scope).end_point
|
68
77
|
end
|
69
78
|
|
70
|
-
def position(
|
71
|
-
value = if
|
79
|
+
def position(scope=:relative)
|
80
|
+
value = if scope==:relative
|
72
81
|
@position
|
73
|
-
elsif
|
82
|
+
elsif scope==:absolute
|
74
83
|
absolute_position
|
75
84
|
else
|
76
85
|
raise "unvalid value #{flag}"
|
@@ -79,6 +88,7 @@ class SourceInfo
|
|
79
88
|
value
|
80
89
|
end
|
81
90
|
|
91
|
+
# Deprecated, use position(:absolute) instead
|
82
92
|
def absolute_position
|
83
93
|
raise "#{self} is not placed in any artifact" unless @artifact
|
84
94
|
@artifact.position_to_absolute(@position)
|
@@ -115,14 +125,16 @@ module SourceInfoExtensions
|
|
115
125
|
attr_accessor :language
|
116
126
|
attr_accessor :source
|
117
127
|
|
118
|
-
|
128
|
+
# @param data is expected to be an hash with :line and :column
|
129
|
+
def start_point=(data)
|
119
130
|
@source = SourceInfo.new unless @source
|
120
|
-
@source.
|
131
|
+
@source.start_point = data
|
121
132
|
end
|
122
133
|
|
123
|
-
|
134
|
+
# @param data is expected to be an hash with :line and :column
|
135
|
+
def end_point=(data)
|
124
136
|
@source = SourceInfo.new unless @source
|
125
|
-
@source.
|
137
|
+
@source.end_point = data
|
126
138
|
end
|
127
139
|
end
|
128
140
|
|
@@ -134,6 +146,7 @@ module ForeignAstExtensions
|
|
134
146
|
|
135
147
|
attr_accessor :foreign_container
|
136
148
|
|
149
|
+
# The name is to maintain similarity with RGen (so we used camelcase instead of underscore)
|
137
150
|
def addForeign_asts(foreign_ast)
|
138
151
|
foreign_asts << foreign_ast
|
139
152
|
foreign_ast.foreign_container = self
|
@@ -145,14 +158,16 @@ module ForeignAstExtensions
|
|
145
158
|
end
|
146
159
|
end
|
147
160
|
|
161
|
+
# Deprecated
|
148
162
|
module HostPositionExtensions
|
149
163
|
|
164
|
+
# Deprecated
|
150
165
|
def absolute_position
|
166
|
+
puts "HostPositionExtensions is DEPRECATED"
|
151
167
|
artifact = source.artifact
|
152
168
|
artifact.absolute_position(source.position)
|
153
169
|
end
|
154
170
|
|
155
171
|
end
|
156
172
|
|
157
|
-
|
158
173
|
end
|
data/lib/codemodels/version.rb
CHANGED
data/test/test_language.rb
CHANGED
@@ -13,6 +13,15 @@ class MyLanguage < Language
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
+
class MyOtherLanguage < Language
|
17
|
+
def initialize(my_parser)
|
18
|
+
super('MyLanguage')
|
19
|
+
@filenames << 'pippo'
|
20
|
+
@parser = my_parser
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
16
25
|
class MyParser
|
17
26
|
attr_reader :invokations
|
18
27
|
|
@@ -39,9 +48,15 @@ def test_my_language
|
|
39
48
|
assert l.parser.is_a?(MyParser)
|
40
49
|
end
|
41
50
|
|
42
|
-
def
|
43
|
-
assert_equal true, @my_language.can_parse?('pippo.my1')
|
44
|
-
assert_equal false, @my_language.can_parse?('pippo.else')
|
51
|
+
def test_can_parse_extension?
|
52
|
+
assert_equal true, @my_language.can_parse?('a/dir/pippo.my1')
|
53
|
+
assert_equal false, @my_language.can_parse?('a/dir/pippo.else')
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_can_parse_extension?
|
57
|
+
@l = MyOtherLanguage.new('MyOtherLanguage')
|
58
|
+
assert_equal true, @l.can_parse?('a/dir/pippo')
|
59
|
+
assert_equal false, @l.can_parse?('a/dir/pluto')
|
45
60
|
end
|
46
61
|
|
47
62
|
def test_parse_file_registered_language
|
@@ -50,7 +65,7 @@ def test_parse_file_registered_language
|
|
50
65
|
end
|
51
66
|
|
52
67
|
def test_parse_file_unregistered_language
|
53
|
-
assert_raise
|
68
|
+
assert_raise NoLanguageRegisteredError do
|
54
69
|
CodeModels.parse_file('pippo.else')
|
55
70
|
end
|
56
71
|
end
|
data/test/test_parser.rb
CHANGED
@@ -18,6 +18,24 @@ class TestParser < Test::Unit::TestCase
|
|
18
18
|
|
19
19
|
end
|
20
20
|
|
21
|
+
class ArtifactReturningParser < CodeModels::Parser
|
22
|
+
|
23
|
+
attr_reader :last_parser_artifact
|
24
|
+
|
25
|
+
def internal_parse_artifact(artifact)
|
26
|
+
@last_parser_artifact = artifact
|
27
|
+
Metamodel::SimpleText.build(artifact.code)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_parse_string
|
33
|
+
p = ArtifactReturningParser.new
|
34
|
+
p.parse_string("PIPPO")
|
35
|
+
assert p.last_parser_artifact.is_a?(StringArtifact)
|
36
|
+
assert_equal "PIPPO", p.last_parser_artifact.code
|
37
|
+
end
|
38
|
+
|
21
39
|
def test_encoding
|
22
40
|
text1 = "Füße laissé fenêtre Miško Minár ă î Timișoara"
|
23
41
|
# ISO 8859-1 does not support all characters, so it is shorter
|
metadata
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: codemodels
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.7
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Federico Tomassetti
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-01-
|
11
|
+
date: 2014-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
15
15
|
version_requirements: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '1.8'
|
20
20
|
requirement: !ruby/object:Gem::Requirement
|
21
21
|
requirements:
|
22
|
-
- -
|
22
|
+
- - ~>
|
23
23
|
- !ruby/object:Gem::Version
|
24
|
-
version: '
|
24
|
+
version: '1.8'
|
25
25
|
prerelease: false
|
26
26
|
type: :runtime
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rgen
|
29
29
|
version_requirements: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 0.6.6
|
34
34
|
requirement: !ruby/object:Gem::Requirement
|
35
35
|
requirements:
|
36
|
-
- -
|
36
|
+
- - ~>
|
37
37
|
- !ruby/object:Gem::Version
|
38
|
-
version:
|
38
|
+
version: 0.6.6
|
39
39
|
prerelease: false
|
40
40
|
type: :runtime
|
41
41
|
- !ruby/object:Gem::Dependency
|
@@ -98,14 +98,28 @@ dependencies:
|
|
98
98
|
name: rubygems-tasks
|
99
99
|
version_requirements: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - ~>
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
103
|
+
version: 0.2.4
|
104
104
|
requirement: !ruby/object:Gem::Requirement
|
105
105
|
requirements:
|
106
|
-
- -
|
106
|
+
- - ~>
|
107
107
|
- !ruby/object:Gem::Version
|
108
|
-
version:
|
108
|
+
version: 0.2.4
|
109
|
+
prerelease: false
|
110
|
+
type: :development
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: yard
|
113
|
+
version_requirements: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.8.7
|
118
|
+
requirement: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ~>
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: 0.8.7
|
109
123
|
prerelease: false
|
110
124
|
type: :development
|
111
125
|
description: Library to build models of code of different languages in a uniform way.
|