rtext 0.8.0 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +113 -84
  3. data/Project.yaml +14 -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 +122 -55
  9. data/lib/rtext/frontend/context.rb +12 -12
  10. data/lib/rtext/instantiator.rb +11 -3
  11. data/lib/rtext/language.rb +5 -5
  12. data/lib/rtext/serializer.rb +1 -1
  13. data/lib/rtext/service.rb +264 -253
  14. data/lib/rtext/tokenizer.rb +1 -1
  15. metadata +18 -43
  16. data/Rakefile +0 -46
  17. data/test/completer_test.rb +0 -606
  18. data/test/context_builder_test.rb +0 -948
  19. data/test/frontend/context_test.rb +0 -205
  20. data/test/instantiator_test.rb +0 -1691
  21. data/test/integration/backend.out +0 -13
  22. data/test/integration/crash_on_request_editor.rb +0 -12
  23. data/test/integration/ecore_editor.rb +0 -50
  24. data/test/integration/frontend.log +0 -36049
  25. data/test/integration/model/invalid_encoding.invenc +0 -2
  26. data/test/integration/model/test.crash_on_request +0 -18
  27. data/test/integration/model/test.crashing_backend +0 -18
  28. data/test/integration/model/test.dont_open_socket +0 -0
  29. data/test/integration/model/test.invalid_cmd_line +0 -0
  30. data/test/integration/model/test.not_in_rtext +0 -0
  31. data/test/integration/model/test_large_with_errors.ect3 +0 -43523
  32. data/test/integration/model/test_metamodel.ect +0 -24
  33. data/test/integration/model/test_metamodel2.ect +0 -5
  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 -918
  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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 30018cf213c8569d30e5dc54462ee9e2924d216c
4
- data.tar.gz: dc83bc7704dfd9e36cf32b41ab163c3baea00fb7
3
+ metadata.gz: 5a5cc8d9398e6453bbc549caf640e38dabf76b56
4
+ data.tar.gz: bf45a3cb45e7dda6964b516ff71ad6f09ac02ca3
5
5
  SHA512:
6
- metadata.gz: adb5fcfbe05bd64b7917cd996c92a8b6034b107df31ffa745372ca7cf58c3fa2cba1be7f431b7040177dd170f34c8752f5779a5be9f9d83d30c4a8d821cbe2eb
7
- data.tar.gz: 758315e9d32a4e588f2952bc7f9ae8bfd1be461b3f9bbb62a84544ea9b2e38f21ca1be7623ed95ccbe49e3d4bd96acbaca0a2f599d05a5a6ea39e85f3e4af69b
6
+ metadata.gz: b6330b11b5cd1f8fa761db136ef272aa07d0994c1fef3739a8a689d0b28dfd5d363196fdf6ea04b8d7319d863f21c4ee3c875b59409a04b93e825d3abf782fe7
7
+ data.tar.gz: c61c3e48987ec0dc6ea4cebdfeb381764e5447ccda48cd6634158611ebb6a18f80a747c92fb748c582cd3344edb6eb87e8c30acf1dffaedb0c07650fa4b59485
data/CHANGELOG CHANGED
@@ -1,84 +1,113 @@
1
- =0.2.0
2
-
3
- * First public release
4
-
5
- =0.3.0
6
-
7
- * Added context sensitive commands
8
- * Show child role lables in auto completer
9
- * Show unlabled arguments in auto completer
10
- * Show only arguments in auto completer which don't have a value yet
11
- * Fixed auto completion within array values
12
- * Fixed generation of child role labels in serializer
13
- * Added :after_load hook to DefaultLoader
14
- * Added result limit option to DefaultServiceProvider
15
- * Removed short_class_names option from Language
16
-
17
- =0.4.0
18
-
19
- * Made instantiator a lot more robust against parse errors
20
- * Added DefaultLoader option to not reload fragments with errors
21
- * Added service load progress indication and custom problem severity
22
- * Fixed serialization of enum literals starting with a digit
23
- * Fixed used port detection in service
24
- * Fixed completion option order to match order defined in lanugage
25
-
26
- =0.5.0
27
-
28
- * Added annotations
29
- * Added generic value support
30
- * Added RText frontend support (for Ruby based RText plugins and testing)
31
- * Changed frontend/backend protocol to JSON over TCP
32
- * Generally improved completer and context builder, fixed bugs, added tests
33
- * Added automated frontend/backend tests
34
- * Added example language (ECore editor)
35
- * Added configurable backward reference attribute
36
- * Fixed backward reference resolution in case line ends with name attribute
37
- * Added more information to unlabled value completion options
38
- * Added backend service support for lanugage exchange at runtime
39
- * Extended support for relative reference calculation and resolution
40
- * Added on_progress hook to default_loader
41
- * Added explicit handling of encoding
42
- * Improved backend service progress reporting
43
- * Fixed backward reference list to not include opposites of forward references
44
- * Fixed problem with backend service socket connection on some machines
45
-
46
- =0.5.1
47
-
48
- * Fixed service connection problem when ports are in use by other processes
49
-
50
- =0.5.2
51
-
52
- * Fixed exception in default service provider when trying to follow a reference on an attribute value
53
- * Ignore BOM in instantiator
54
-
55
- =0.5.3
56
-
57
- * Fixed completion of enum values which need to be quoted
58
- * Added support for BigDecimal
59
-
60
- =0.6.0
61
-
62
- * Changed service provider interface to allow for more customization
63
- * Changed Completer into DefaultCompleter to allow for customization
64
- * Added labeled_containments language parameter
65
- * Made DefaultLoader robust against missing files
66
-
67
- =0.7.0
68
-
69
- * Added DefaultResolver and support for custom resolvers for DefaultLoader and DefaultServiceProvider
70
- * Changed instantiator on_progress proc to take a second argument with the number of progress steps
71
- * Changed tokenizer to start new tokens immediately after error tokens
72
- * Fixed line number in instantiator problem report for multiple childs in one-role
73
- * Fixed unit tests for Ruby 2.0
74
- * Fixed context builder prefixes for strings
75
- * Fixed DefaultLoader to let fragments calculate their elements list by themselves
76
- * Minor performance improvements, mainly for instantiator and when passing large RText messages
77
- * Improved performance of frontend connector especially for large amounts of data
78
-
79
- =0.8.0
80
-
81
- * Added line breaks support
82
- * Fixed problem when there is no whitespace before a curly bracket
83
- * Fixed problem when loading frontend context extractor in vim
84
-
1
+ =0.2.0
2
+
3
+ * First public release
4
+
5
+ =0.3.0
6
+
7
+ * Added context sensitive commands
8
+ * Show child role lables in auto completer
9
+ * Show unlabled arguments in auto completer
10
+ * Show only arguments in auto completer which don't have a value yet
11
+ * Fixed auto completion within array values
12
+ * Fixed generation of child role labels in serializer
13
+ * Added :after_load hook to DefaultLoader
14
+ * Added result limit option to DefaultServiceProvider
15
+ * Removed short_class_names option from Language
16
+
17
+ =0.4.0
18
+
19
+ * Made instantiator a lot more robust against parse errors
20
+ * Added DefaultLoader option to not reload fragments with errors
21
+ * Added service load progress indication and custom problem severity
22
+ * Fixed serialization of enum literals starting with a digit
23
+ * Fixed used port detection in service
24
+ * Fixed completion option order to match order defined in lanugage
25
+
26
+ =0.5.0
27
+
28
+ * Added annotations
29
+ * Added generic value support
30
+ * Added RText frontend support (for Ruby based RText plugins and testing)
31
+ * Changed frontend/backend protocol to JSON over TCP
32
+ * Generally improved completer and context builder, fixed bugs, added tests
33
+ * Added automated frontend/backend tests
34
+ * Added example language (ECore editor)
35
+ * Added configurable backward reference attribute
36
+ * Fixed backward reference resolution in case line ends with name attribute
37
+ * Added more information to unlabled value completion options
38
+ * Added backend service support for lanugage exchange at runtime
39
+ * Extended support for relative reference calculation and resolution
40
+ * Added on_progress hook to default_loader
41
+ * Added explicit handling of encoding
42
+ * Improved backend service progress reporting
43
+ * Fixed backward reference list to not include opposites of forward references
44
+ * Fixed problem with backend service socket connection on some machines
45
+
46
+ =0.5.1
47
+
48
+ * Fixed service connection problem when ports are in use by other processes
49
+
50
+ =0.5.2
51
+
52
+ * Fixed exception in default service provider when trying to follow a reference on an attribute value
53
+ * Ignore BOM in instantiator
54
+
55
+ =0.5.3
56
+
57
+ * Fixed completion of enum values which need to be quoted
58
+ * Added support for BigDecimal
59
+
60
+ =0.6.0
61
+
62
+ * Changed service provider interface to allow for more customization
63
+ * Changed Completer into DefaultCompleter to allow for customization
64
+ * Added labeled_containments language parameter
65
+ * Made DefaultLoader robust against missing files
66
+
67
+ =0.7.0
68
+
69
+ * Added DefaultResolver and support for custom resolvers for DefaultLoader and DefaultServiceProvider
70
+ * Changed instantiator on_progress proc to take a second argument with the number of progress steps
71
+ * Changed tokenizer to start new tokens immediately after error tokens
72
+ * Fixed line number in instantiator problem report for multiple childs in one-role
73
+ * Fixed unit tests for Ruby 2.0
74
+ * Fixed context builder prefixes for strings
75
+ * Fixed DefaultLoader to let fragments calculate their elements list by themselves
76
+ * Minor performance improvements, mainly for instantiator and when passing large RText messages
77
+ * Improved performance of frontend connector especially for large amounts of data
78
+
79
+ =0.8.0
80
+
81
+ * Added line breaks support
82
+ * Fixed problem when there is no whitespace before a curly bracket
83
+ * Fixed problem when loading frontend context extractor in vim
84
+
85
+ =0.8.1
86
+
87
+ * Fixed frontend content extraction to support line breaks with backslash
88
+ * Fixed frontend content extraction, joining of broken lines
89
+
90
+ =0.8.2
91
+
92
+ * Fixed serializer negative decimal quotation
93
+ * Added Object attribute test case
94
+
95
+ =0.9.0
96
+
97
+ * Added protocol versioning support
98
+ * Added completion options for square brackets and curly braces
99
+
100
+ =0.9.1
101
+
102
+ * Fixed backward compatibility issues
103
+
104
+ =0.9.2
105
+
106
+ * Fixed frontend connector
107
+ * Fixed frontend tests
108
+ * Automatic conversion of integer and float values to string
109
+
110
+ =0.9.3
111
+
112
+ * Fixed frontend log file path issue
113
+
data/Project.yaml ADDED
@@ -0,0 +1,14 @@
1
+ name: rtext
2
+ version: 0.9.3
3
+ git: https://github.com/mthiede/rtext.git
4
+ summary: Ruby Textual Modelling
5
+ email: martin dot thiede at gmx de
6
+ homepage: http://ruby-gen.org
7
+ description: RText can be used to derive textual languages from an RGen metamodel with very little effort.
8
+ authors: [Martin Thiede]
9
+ dependencies:
10
+ http://rubygems.org:
11
+ - {name: rgen, version: '~> 0.8.0'}
12
+ rdoc_options: [--main, README.rdoc, -x, test]
13
+ extra_rdoc_files: [README.rdoc, CHANGELOG, MIT-LICENSE, RText_Users_Guide, RText_Protocol]
14
+ encrypt_sources: false
data/RText_Protocol CHANGED
@@ -4,6 +4,10 @@ RText frontend and backend pass messages containing JSON objects.
4
4
  Normally the frontend invokes a backend command by means of a request message and the
5
5
  backend will eventually reply with a response message.
6
6
 
7
+ == Versioning
8
+
9
+ RText protocol supports versioning mechanism with a single version natural number.
10
+ The actual version of the protocol is 1.
7
11
 
8
12
  == Encoding
9
13
 
@@ -25,8 +29,8 @@ In addition, the character "%" is escaped in the same way, i.e. "%" will always
25
29
 
26
30
  Example:
27
31
 
28
- The word "�bung" (german: exercise), encoded in ISO-8859-1 would result in the string:
29
- "%dcbung" (the "" Umlaut has a byte value of 0xdc is ISO-8859-1).
32
+ The word "Übung" (german: exercise), encoded in ISO-8859-1 would result in the string:
33
+ "%dcbung" (the "Ü" Umlaut has a byte value of 0xdc is ISO-8859-1).
30
34
 
31
35
 
32
36
  == Request Messages
@@ -34,9 +38,12 @@ The word "
34
38
  Each request message contains a field ``command`` and a field ``invocation_id``.
35
39
  The command field holds the name of the command to be invoked as a string.
36
40
  The invocation id field holds an identifier which will be repeated by the backend's response.
41
+ The "version" field was introduced in version 1. It is optional for protocol version 0 requests,
42
+ but mandatory for newer versions.
37
43
 
38
44
  {
39
45
  "type": "request",
46
+ "version": <protocol_version [integer]>,
40
47
  "command": <command>,
41
48
  "invocation_id": <invocation_id>
42
49
  ...
@@ -65,6 +72,16 @@ There are a number of error message which may be sent in response to a request m
65
72
  "invocation_id": <invocation_id>,
66
73
  "command": <unknown command [string]>
67
74
  }
75
+
76
+ === Unsupported Protocol Version Error
77
+
78
+ Introduced in version 1.
79
+
80
+ {
81
+ "type": "unsupported_version",
82
+ "invocation_id": <invocation_id>,
83
+ "version": <supported version [integer]>
84
+ }
68
85
 
69
86
  == Progress Information
70
87
 
@@ -90,6 +107,25 @@ The message field may carry information about the currently ongoing subtask.
90
107
  For each command, the layout of the request and response messages will be given below.
91
108
  Note that the invocation id field is present in every request and response but is omitted for brevity.
92
109
 
110
+ === Backend version request
111
+
112
+ Introduced in version 1.
113
+
114
+ This command requests the backend to disclose its supported protocol version.
115
+
116
+ {
117
+ "type": "request",
118
+ "command": "version"
119
+ }
120
+
121
+ The backend responds with a version information.
122
+
123
+ {
124
+ "type": "response",
125
+ "version": <version [integer]>
126
+ }
127
+
128
+ The backend supporting protocool version 0 only responds with an 'Unknown Command Error'.
93
129
 
94
130
  === Load Model
95
131
 
@@ -141,7 +177,14 @@ build the set of context lines in the frontend. Column number start at 1.
141
177
  }
142
178
 
143
179
  The backend replies with a list of completion options.
144
- The field ``insert`` holds the text to be inserted if the completion option is chosen.
180
+ The field ``insert`` holds the text to be inserted if the completion option is chosen. This text
181
+ may contains placeholders for cursor position. An editor may use them to assist a user in
182
+ filling additional completion fields.
183
+ Each placeholder must start and end with a vertical bar character (``|``) and can contain up to
184
+ three optional parts separated by an additional vertical bar character: ordering number, name and
185
+ description of this cursor position. E.g.: ``||``, ``|1|name|Entity name|``, ``|||New value|``.
186
+ Placeholders with the same name must be considered as the same value repeated in different
187
+ positions.
145
188
  The field ``display`` contains the string which should be displayed to the user in some kind of
146
189
  completion option menu. An optional description field may provide more information about a
147
190
  particular option.
@@ -458,7 +501,7 @@ the parent commands wrapped around it. Any sibling commands can be omitted as we
458
501
  any lines containing closing braces and brackets. The order of lines is the same as in the
459
502
  RText file.
460
503
 
461
- Here is an example. Consider the following RText file with the cursor in the line of "Command3"
504
+ Here is an example. Consider the following RText file with the cursor in the line of "Command5"
462
505
  at the time when the auto completion command is issued.
463
506
 
464
507
  Command1 {
@@ -26,7 +26,8 @@ module RText
26
26
  #
27
27
  module ContextBuilder
28
28
 
29
- Context = Struct.new(:element, :feature, :prefix, :in_array, :in_block, :after_label, :problem)
29
+ PositionContext = Struct.new(:in_array, :in_block, :after_label, :after_comma, :before_brace, :before_bracket)
30
+ Context = Struct.new(:element, :feature, :prefix, :problem, :position, :line_indent, :indent)
30
31
 
31
32
  class << self
32
33
  include RText::Tokenizer
@@ -50,13 +51,37 @@ module ContextBuilder
50
51
  else
51
52
  feature = nil
52
53
  end
53
- Context.new(element, feature, context_info.prefix, context_info.in_array, context_info.in_block, after_label, context_info.problem)
54
+ context_info.position.after_label = after_label
55
+ Context.new(element, feature, context_info.prefix, context_info.problem, context_info.position,
56
+ get_line_indent(context_lines.last), get_indent(context_lines))
54
57
  else
55
- Context.new(nil, nil, context_info.prefix, context_info.in_array, context_info.in_block, false, context_info.problem)
58
+ context_info.position.after_label = false
59
+ Context.new(nil, nil, context_info.prefix, context_info.problem, context_info.position,
60
+ get_line_indent(context_lines.last), get_indent(context_lines))
56
61
  end
57
62
  end
58
63
 
59
64
  private
65
+
66
+ def get_line_indent(line)
67
+ return '' unless line
68
+ match = line.match(/^\s+/)
69
+ if match.nil?
70
+ ''
71
+ else
72
+ match[0]
73
+ end
74
+ end
75
+
76
+ # Compute indent from context lines
77
+ def get_indent(context_lines)
78
+ cl = context_lines.dup
79
+ while true
80
+ return ' ' if cl.size < 2 # default indentation is 2 spaces
81
+ indent = get_line_indent(cl.last)[get_line_indent(cl.delete_at(-2)).size..-1]
82
+ return indent unless indent.nil? || indent.empty?
83
+ end
84
+ end
60
85
 
61
86
  def instantiate_context_element(language, context_info)
62
87
  root_elements = []
@@ -72,7 +97,7 @@ module ContextBuilder
72
97
  end
73
98
 
74
99
  def find_leaf_child(element, num_required_children)
75
- childs = element.class.ecore.eAllReferences.select{|r| r.containment}.collect{|r|
100
+ childs = element.class.ecore.eAllReferences.select{|r| r.containment }.collect{|r|
76
101
  element.getGenericAsArray(r.name)}.flatten
77
102
  if num_required_children == 0
78
103
  element
@@ -83,7 +108,7 @@ module ContextBuilder
83
108
  end
84
109
  end
85
110
 
86
- ContextInternal = Struct.new(:lines, :num_elements, :role, :prefix, :in_array, :in_block, :problem)
111
+ ContextInternal = Struct.new(:lines, :num_elements, :role, :prefix, :problem, :position)
87
112
 
88
113
  # extend +context_lines+ into a set of lines which can be processed by the RText
89
114
  def fix_context(language, context_lines, position_in_line)
@@ -95,11 +120,14 @@ module ContextBuilder
95
120
  position_in_line ||= context_lines.last.size
96
121
  # cut off last line right of cursor
97
122
  if position_in_line < 1
98
- context_lines.pop
123
+ tail = context_lines.pop
99
124
  context_lines << ""
100
125
  else
126
+ tail = context_lines.last[position_in_line..-1]
101
127
  context_lines << context_lines.pop[0..position_in_line-1]
102
128
  end
129
+ before_brace = !tail.nil? && !tail.match(/^\s*\{/).nil?
130
+ before_bracket = !tail.nil? && !tail.match(/^\s*\[/).nil?
103
131
  problem = nil
104
132
  line = context_lines.last
105
133
  if line =~ /\{\s*$/
@@ -110,7 +138,7 @@ module ContextBuilder
110
138
  problem = :after_curly
111
139
  end
112
140
 
113
- num_elements = in_block = in_array = missing_comma = role = prefix = nil
141
+ num_elements = in_block = in_array = missing_comma = role = prefix = after_comma = nil
114
142
  tokens = tokenize(line, language.reference_regexp)
115
143
  tokens.pop if tokens.last && tokens.last.kind == :newline
116
144
  if tokens.size > 0 && tokens[0].kind == :identifier
@@ -124,6 +152,7 @@ module ContextBuilder
124
152
  unlabled_index = 0
125
153
  tokens[1..-1].each do |token|
126
154
  break if token.kind == :error
155
+ after_comma = false
127
156
  if token.kind == "["
128
157
  in_array = true
129
158
  elsif token.kind == "]"
@@ -136,6 +165,7 @@ module ContextBuilder
136
165
  missing_comma = false
137
166
  role = nil unless in_array
138
167
  unlabled_index += 1 unless in_array
168
+ after_comma = true
139
169
  end
140
170
  end
141
171
  if ((tokens.size == 1 && line =~ /\s+$/) ||
@@ -187,6 +217,16 @@ module ContextBuilder
187
217
  if context_lines[-2] =~ /^\s*\w+:\s*$/
188
218
  context_lines[-1] = context_lines.pop
189
219
  end
220
+ elsif tokens.size == 1 && tokens[0].kind == :label
221
+ token = tokens[0]
222
+ role = context_lines.last[token.scol - 1..token.ecol - 2]
223
+ context_lines << context_lines.pop[0..token.scol - 2]
224
+ context = fix_context(language, context_lines, context_lines.last.size)
225
+ context.role = role
226
+ context.position.in_block = false
227
+ context.position.before_brace = before_brace
228
+ context.position.before_bracket = before_bracket
229
+ return context
190
230
  else
191
231
  # comment, closing brackets, etc.
192
232
  num_elements = 0
@@ -210,7 +250,8 @@ module ContextBuilder
210
250
  end
211
251
  end
212
252
  problem = :missing_comma if !problem && missing_comma
213
- ContextInternal.new(context_lines, num_elements, role, prefix, in_array, in_block, problem)
253
+ ContextInternal.new(context_lines, num_elements, role, prefix, problem,
254
+ PositionContext.new(in_array, in_block, false, after_comma, before_brace, before_bracket))
214
255
  end
215
256
 
216
257
  def find_role(context_lines)