rtext 0.9.0 → 0.9.1
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 +5 -5
- data/CHANGELOG +102 -98
- data/Rakefile +46 -46
- data/lib/rtext/default_completer.rb +212 -208
- data/lib/rtext/service.rb +264 -260
- data/test/completer_test.rb +606 -607
- data/test/context_builder_test.rb +948 -949
- data/test/frontend/context_test.rb +301 -302
- data/test/instantiator_test.rb +1732 -1733
- data/test/integration/frontend.log +401 -40039
- data/test/integration/test.rb +967 -968
- data/test/link_detector_test.rb +287 -288
- data/test/message_helper_test.rb +116 -117
- data/test/serializer_test.rb +1023 -1024
- data/test/tokenizer_test.rb +173 -174
- metadata +15 -17
- data/test/integration/backend.out +0 -16
@@ -1,208 +1,212 @@
|
|
1
|
-
require 'rgen/ecore/ecore_ext'
|
2
|
-
|
3
|
-
module RText
|
4
|
-
|
5
|
-
class DefaultCompleter
|
6
|
-
|
7
|
-
class CompletionOption
|
8
|
-
|
9
|
-
attr_accessor :insert
|
10
|
-
attr_accessor :display
|
11
|
-
attr_accessor :extra
|
12
|
-
attr_accessor :description
|
13
|
-
|
14
|
-
def self.from_text_extra(text, extra)
|
15
|
-
self.new(text, text + ' ' + extra, nil, extra)
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.for_curly_braces(context)
|
19
|
-
self.new("{\n#{context.line_indent}#{context.indent}||\n#{context.line_indent}}", '{}')
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.for_square_brackets
|
23
|
-
self.new('[ || ]', '[]', '')
|
24
|
-
end
|
25
|
-
|
26
|
-
def initialize(insert, display, description=nil, extra=nil)
|
27
|
-
@insert = insert
|
28
|
-
@display = display
|
29
|
-
@description = description
|
30
|
-
@extra = extra
|
31
|
-
end
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
elsif context.feature.eType.
|
112
|
-
result.concat(
|
113
|
-
elsif context.feature.eType.instanceClass ==
|
114
|
-
result.concat(
|
115
|
-
elsif context.feature.eType.instanceClass ==
|
116
|
-
result.concat(
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
end
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
context.element.
|
135
|
-
|
136
|
-
end
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
end
|
149
|
-
|
150
|
-
def
|
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
|
-
end
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
end
|
208
|
-
|
1
|
+
require 'rgen/ecore/ecore_ext'
|
2
|
+
|
3
|
+
module RText
|
4
|
+
|
5
|
+
class DefaultCompleter
|
6
|
+
|
7
|
+
class CompletionOption
|
8
|
+
|
9
|
+
attr_accessor :insert
|
10
|
+
attr_accessor :display
|
11
|
+
attr_accessor :extra
|
12
|
+
attr_accessor :description
|
13
|
+
|
14
|
+
def self.from_text_extra(text, extra)
|
15
|
+
self.new(text, text + ' ' + extra, nil, extra)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.for_curly_braces(context)
|
19
|
+
self.new("{\n#{context.line_indent}#{context.indent}||\n#{context.line_indent}}", '{}')
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.for_square_brackets
|
23
|
+
self.new('[ || ]', '[]', '')
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize(insert, display, description=nil, extra=nil)
|
27
|
+
@insert = insert
|
28
|
+
@display = display
|
29
|
+
@description = description
|
30
|
+
@extra = extra
|
31
|
+
end
|
32
|
+
|
33
|
+
def text
|
34
|
+
@insert
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
# Creates a completer for RText::Language +language+.
|
40
|
+
#
|
41
|
+
def initialize(language)
|
42
|
+
@lang = language
|
43
|
+
end
|
44
|
+
|
45
|
+
# Provides completion options
|
46
|
+
#
|
47
|
+
def complete(context, version=0)
|
48
|
+
clazz = context && context.element && context.element.class.ecore
|
49
|
+
if clazz
|
50
|
+
if context.position.in_block
|
51
|
+
block_options(context, clazz)
|
52
|
+
elsif !context.problem
|
53
|
+
result = []
|
54
|
+
add_value_options(context, result, version) if context.feature
|
55
|
+
add_label_options(context, clazz, result, version) unless context.position.after_label
|
56
|
+
result
|
57
|
+
else
|
58
|
+
# missing comma, after curly brace, etc.
|
59
|
+
if version > 0 && !context.position.before_brace &&
|
60
|
+
context.element.class.ecore.eAllReferences.any? { |r| r.containment }
|
61
|
+
[CompletionOption.for_curly_braces(context)]
|
62
|
+
else
|
63
|
+
[]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
elsif context
|
67
|
+
root_options
|
68
|
+
else
|
69
|
+
[]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def block_options(context, clazz)
|
74
|
+
types = []
|
75
|
+
labled_refs = []
|
76
|
+
if context.feature
|
77
|
+
if context.feature.is_a?(RGen::ECore::EReference) && context.feature.containment
|
78
|
+
types = @lang.concrete_types(context.feature.eType)
|
79
|
+
else
|
80
|
+
# invalid, ignore
|
81
|
+
end
|
82
|
+
else
|
83
|
+
# all target types which don't need a label
|
84
|
+
# and all lables which are needed by a potential target type
|
85
|
+
@lang.containments(clazz).each do |r|
|
86
|
+
([r.eType] + r.eType.eAllSubTypes).select{|t| t.concrete}.each do |t|
|
87
|
+
if @lang.labeled_containment?(clazz, r) || @lang.containments_by_target_type(clazz, t).size > 1
|
88
|
+
labled_refs << r
|
89
|
+
else
|
90
|
+
types << t
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
types.uniq.
|
96
|
+
sort{|a,b| a.name <=> b.name}.collect do |c|
|
97
|
+
class_completion_option(c)
|
98
|
+
end +
|
99
|
+
labled_refs.uniq.collect do |r|
|
100
|
+
CompletionOption.from_text_extra("#{r.name}:", "<#{r.eType.name}>")
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def add_value_options(context, result, version)
|
105
|
+
if context.feature.is_a?(RGen::ECore::EAttribute) || !context.feature.containment
|
106
|
+
if context.feature.is_a?(RGen::ECore::EReference)
|
107
|
+
result.concat(reference_options(context))
|
108
|
+
if version > 0 && !context.position.before_bracket && context.feature.upperBound != 1
|
109
|
+
result << CompletionOption.for_square_brackets
|
110
|
+
end
|
111
|
+
elsif context.feature.eType.is_a?(RGen::ECore::EEnum)
|
112
|
+
result.concat(enum_options(context))
|
113
|
+
elsif context.feature.eType.instanceClass == String
|
114
|
+
result.concat(string_options(context))
|
115
|
+
elsif context.feature.eType.instanceClass == Integer
|
116
|
+
result.concat(integer_options(context))
|
117
|
+
elsif context.feature.eType.instanceClass == Float
|
118
|
+
result.concat(float_options(context))
|
119
|
+
elsif context.feature.eType.instanceClass == RGen::MetamodelBuilder::DataTypes::Boolean
|
120
|
+
result.concat(boolean_options(context))
|
121
|
+
else
|
122
|
+
# no options
|
123
|
+
end
|
124
|
+
else
|
125
|
+
if version > 0 && !context.position.before_bracket && context.feature.upperBound != 1
|
126
|
+
result << CompletionOption.for_square_brackets
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def add_label_options(context, clazz, result, version)
|
132
|
+
result.concat(@lang.labled_arguments(clazz).
|
133
|
+
select{|f|
|
134
|
+
!context.element.eIsSet(f.name)}.collect do |f|
|
135
|
+
CompletionOption.from_text_extra("#{f.name}:", "<#{f.eType.name}>")
|
136
|
+
end )
|
137
|
+
if version > 0 && !context.position.after_comma &&
|
138
|
+
context.element.class.ecore.eAllReferences.any? { |r| r.containment } && !context.position.before_brace
|
139
|
+
result << CompletionOption.for_curly_braces(context)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def root_options
|
144
|
+
@lang.root_classes.
|
145
|
+
sort{|a,b| a.name <=> b.name}.collect do |c|
|
146
|
+
class_completion_option(c)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def reference_options(context)
|
151
|
+
[]
|
152
|
+
end
|
153
|
+
|
154
|
+
def enum_options(context)
|
155
|
+
context.feature.eType.eLiterals.collect do |l|
|
156
|
+
lname = l.name
|
157
|
+
if lname =~ /^\d|\W/ || lname == "true" || lname == "false"
|
158
|
+
lname = "\"#{lname.gsub("\\","\\\\\\\\").gsub("\"","\\\"").gsub("\n","\\n").
|
159
|
+
gsub("\r","\\r").gsub("\t","\\t").gsub("\f","\\f").gsub("\b","\\b")}\""
|
160
|
+
end
|
161
|
+
CompletionOption.from_text_extra("#{lname}", "<#{context.feature.eType.name}>")
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def string_options(context)
|
166
|
+
if @lang.unquoted?(context.feature)
|
167
|
+
[ CompletionOption.from_text_extra("#{context.feature.name.gsub(/\W/,"")}", value_description(context)) ]
|
168
|
+
else
|
169
|
+
[ CompletionOption.from_text_extra("\"\"", value_description(context)) ]
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def get_default_value_completion(context)
|
174
|
+
return nil unless context.feature.defaultValue
|
175
|
+
CompletionOption.from_text_extra("#{context.feature.defaultValue}", value_description(context))
|
176
|
+
end
|
177
|
+
|
178
|
+
def integer_options(context)
|
179
|
+
default_comp = get_default_value_completion(context)
|
180
|
+
return [default_comp] if default_comp
|
181
|
+
(0..0).collect{|i| CompletionOption.from_text_extra("#{i}", value_description(context)) }
|
182
|
+
end
|
183
|
+
|
184
|
+
def float_options(context)
|
185
|
+
default_comp = get_default_value_completion(context)
|
186
|
+
return [default_comp] if default_comp
|
187
|
+
(0..0).collect{|i| CompletionOption.from_text_extra("#{i}.0", value_description(context)) }
|
188
|
+
end
|
189
|
+
|
190
|
+
def boolean_options(context)
|
191
|
+
[true, false].collect{|b| CompletionOption.from_text_extra("#{b}", value_description(context)) }
|
192
|
+
end
|
193
|
+
|
194
|
+
private
|
195
|
+
|
196
|
+
def value_description(context)
|
197
|
+
if context.position.after_label
|
198
|
+
"<#{context.feature.eType.name}>"
|
199
|
+
else
|
200
|
+
"[#{context.feature.name}] <#{context.feature.eType.name}>"
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def class_completion_option(eclass)
|
205
|
+
uargs = @lang.unlabled_arguments(eclass).collect{|a| "<#{a.name}>"}.join(", ")
|
206
|
+
CompletionOption.from_text_extra(@lang.command_by_class(eclass.instanceClass), uargs)
|
207
|
+
end
|
208
|
+
|
209
|
+
end
|
210
|
+
|
211
|
+
end
|
212
|
+
|