rtext 0.8.1 → 0.10.0

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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +120 -89
  3. data/Project.yaml +15 -0
  4. data/RText_Protocol +47 -4
  5. data/lib/rtext/context_builder.rb +49 -8
  6. data/lib/rtext/default_completer.rb +212 -163
  7. data/lib/rtext/default_service_provider.rb +3 -3
  8. data/lib/rtext/frontend/connector.rb +130 -56
  9. data/lib/rtext/instantiator.rb +11 -3
  10. data/lib/rtext/language.rb +5 -5
  11. data/lib/rtext/serializer.rb +3 -3
  12. data/lib/rtext/service.rb +281 -253
  13. data/lib/rtext/tokenizer.rb +2 -2
  14. metadata +33 -33
  15. data/Rakefile +0 -46
  16. data/test/completer_test.rb +0 -606
  17. data/test/context_builder_test.rb +0 -948
  18. data/test/frontend/context_test.rb +0 -301
  19. data/test/instantiator_test.rb +0 -1704
  20. data/test/integration/backend.out +0 -13
  21. data/test/integration/crash_on_request_editor.rb +0 -12
  22. data/test/integration/ecore_editor.rb +0 -50
  23. data/test/integration/frontend.log +0 -38203
  24. data/test/integration/model/invalid_encoding.invenc +0 -2
  25. data/test/integration/model/test.crash_on_request +0 -18
  26. data/test/integration/model/test.crashing_backend +0 -18
  27. data/test/integration/model/test.dont_open_socket +0 -0
  28. data/test/integration/model/test.invalid_cmd_line +0 -0
  29. data/test/integration/model/test.not_in_rtext +0 -0
  30. data/test/integration/model/test_large_with_errors.ect3 +0 -43523
  31. data/test/integration/model/test_metamodel.ect +0 -24
  32. data/test/integration/model/test_metamodel2.ect +0 -5
  33. data/test/integration/model/test_metamodel3.ect4 +0 -7
  34. data/test/integration/model/test_metamodel_error.ect2 +0 -3
  35. data/test/integration/model/test_metamodel_ok.ect2 +0 -18
  36. data/test/integration/test.rb +0 -966
  37. data/test/link_detector_test.rb +0 -287
  38. data/test/message_helper_test.rb +0 -118
  39. data/test/rtext_test.rb +0 -11
  40. data/test/serializer_test.rb +0 -1004
  41. data/test/tokenizer_test.rb +0 -173
@@ -1,163 +1,212 @@
1
- require 'rgen/ecore/ecore_ext'
2
-
3
- module RText
4
-
5
- class DefaultCompleter
6
-
7
- CompletionOption = Struct.new(:text, :extra)
8
-
9
- # Creates a completer for RText::Language +language+.
10
- #
11
- def initialize(language)
12
- @lang = language
13
- end
14
-
15
- # Provides completion options
16
- #
17
- def complete(context)
18
- clazz = context && context.element && context.element.class.ecore
19
- if clazz
20
- if context.in_block
21
- block_options(context, clazz)
22
- elsif !context.problem
23
- result = []
24
- if context.feature
25
- add_value_options(context, result)
26
- end
27
- if !context.after_label
28
- add_label_options(context, clazz, result)
29
- end
30
- result
31
- else
32
- # missing comma, after curly brace, etc.
33
- []
34
- end
35
- elsif context
36
- root_options
37
- else
38
- []
39
- end
40
- end
41
-
42
- def block_options(context, clazz)
43
- types = []
44
- labled_refs = []
45
- if context.feature
46
- if context.feature.is_a?(RGen::ECore::EReference) && context.feature.containment
47
- types = @lang.concrete_types(context.feature.eType)
48
- else
49
- # invalid, ignore
50
- end
51
- else
52
- # all target types which don't need a label
53
- # and all lables which are needed by a potential target type
54
- @lang.containments(clazz).each do |r|
55
- ([r.eType] + r.eType.eAllSubTypes).select{|t| !t.abstract}.each do |t|
56
- if @lang.labeled_containment?(clazz, r) || @lang.containments_by_target_type(clazz, t).size > 1
57
- labled_refs << r
58
- else
59
- types << t
60
- end
61
- end
62
- end
63
- end
64
- types.uniq.
65
- sort{|a,b| a.name <=> b.name}.collect do |c|
66
- class_completion_option(c)
67
- end +
68
- labled_refs.uniq.collect do |r|
69
- CompletionOption.new("#{r.name}:", "<#{r.eType.name}>")
70
- end
71
- end
72
-
73
- def add_value_options(context, result)
74
- if context.feature.is_a?(RGen::ECore::EAttribute) || !context.feature.containment
75
- if context.feature.is_a?(RGen::ECore::EReference)
76
- result.concat(reference_options(context))
77
- elsif context.feature.eType.is_a?(RGen::ECore::EEnum)
78
- result.concat(enum_options(context))
79
- elsif context.feature.eType.instanceClass == String
80
- result.concat(string_options(context))
81
- elsif context.feature.eType.instanceClass == Integer
82
- result.concat(integer_options(context))
83
- elsif context.feature.eType.instanceClass == Float
84
- result.concat(float_options(context))
85
- elsif context.feature.eType.instanceClass == RGen::MetamodelBuilder::DataTypes::Boolean
86
- result.concat(boolean_options(context))
87
- else
88
- # no options
89
- end
90
- else
91
- # containment reference, ignore
92
- end
93
- end
94
-
95
- def add_label_options(context, clazz, result)
96
- result.concat(@lang.labled_arguments(clazz).
97
- select{|f|
98
- !context.element.eIsSet(f.name)}.collect do |f|
99
- CompletionOption.new("#{f.name}:", "<#{f.eType.name}>")
100
- end )
101
- end
102
-
103
- def root_options
104
- @lang.root_classes.
105
- sort{|a,b| a.name <=> b.name}.collect do |c|
106
- class_completion_option(c)
107
- end
108
- end
109
-
110
- def reference_options(context)
111
- []
112
- end
113
-
114
- def enum_options(context)
115
- context.feature.eType.eLiterals.collect do |l|
116
- lname = l.name
117
- if lname =~ /^\d|\W/ || lname == "true" || lname == "false"
118
- lname = "\"#{lname.gsub("\\","\\\\\\\\").gsub("\"","\\\"").gsub("\n","\\n").
119
- gsub("\r","\\r").gsub("\t","\\t").gsub("\f","\\f").gsub("\b","\\b")}\""
120
- end
121
- CompletionOption.new("#{lname}", "<#{context.feature.eType.name}>")
122
- end
123
- end
124
-
125
- def string_options(context)
126
- if @lang.unquoted?(context.feature)
127
- [ CompletionOption.new("#{context.feature.name.gsub(/\W/,"")}", value_description(context)) ]
128
- else
129
- [ CompletionOption.new("\"\"", value_description(context)) ]
130
- end
131
- end
132
-
133
- def integer_options(context)
134
- (0..0).collect{|i| CompletionOption.new("#{i}", value_description(context)) }
135
- end
136
-
137
- def float_options(context)
138
- (0..0).collect{|i| CompletionOption.new("#{i}.0", value_description(context)) }
139
- end
140
-
141
- def boolean_options(context)
142
- [true, false].collect{|b| CompletionOption.new("#{b}", value_description(context)) }
143
- end
144
-
145
- private
146
-
147
- def value_description(context)
148
- if context.after_label
149
- "<#{context.feature.eType.name}>"
150
- else
151
- "[#{context.feature.name}] <#{context.feature.eType.name}>"
152
- end
153
- end
154
-
155
- def class_completion_option(eclass)
156
- uargs = @lang.unlabled_arguments(eclass).collect{|a| "<#{a.name}>"}.join(", ")
157
- CompletionOption.new(@lang.command_by_class(eclass.instanceClass), uargs)
158
- end
159
-
160
- end
161
-
162
- end
163
-
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
+
@@ -35,17 +35,17 @@ class DefaultServiceProvider
35
35
  end
36
36
  end
37
37
 
38
- def get_completion_options(context)
38
+ def get_completion_options(context, version=0)
39
39
  completer = RText::DefaultCompleter.new(@lang)
40
40
  class << completer
41
41
  attr_accessor :service_provider
42
42
  def reference_options(context)
43
43
  service_provider.get_reference_completion_options(context).collect {|o|
44
- DefaultCompleter::CompletionOption.new(o.identifier, "<#{o.type}>")}
44
+ DefaultCompleter::CompletionOption.from_text_extra(o.identifier, "<#{o.type}>")}
45
45
  end
46
46
  end
47
47
  completer.service_provider = self
48
- completer.complete(context)
48
+ completer.complete(context, version)
49
49
  end
50
50
 
51
51
  ReferenceCompletionOption = Struct.new(:identifier, :type)