codemodels 0.2.6-java → 0.2.7-java
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|