rtext 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- end
34
-
35
- # Creates a completer for RText::Language +language+.
36
- #
37
- def initialize(language)
38
- @lang = language
39
- end
40
-
41
- # Provides completion options
42
- #
43
- def complete(context, version=0)
44
- clazz = context && context.element && context.element.class.ecore
45
- if clazz
46
- if context.position.in_block
47
- block_options(context, clazz)
48
- elsif !context.problem
49
- result = []
50
- add_value_options(context, result, version) if context.feature
51
- add_label_options(context, clazz, result, version) unless context.position.after_label
52
- result
53
- else
54
- # missing comma, after curly brace, etc.
55
- if version > 0 && !context.position.before_brace &&
56
- context.element.class.ecore.eAllReferences.any? { |r| r.containment }
57
- [CompletionOption.for_curly_braces(context)]
58
- else
59
- []
60
- end
61
- end
62
- elsif context
63
- root_options
64
- else
65
- []
66
- end
67
- end
68
-
69
- def block_options(context, clazz)
70
- types = []
71
- labled_refs = []
72
- if context.feature
73
- if context.feature.is_a?(RGen::ECore::EReference) && context.feature.containment
74
- types = @lang.concrete_types(context.feature.eType)
75
- else
76
- # invalid, ignore
77
- end
78
- else
79
- # all target types which don't need a label
80
- # and all lables which are needed by a potential target type
81
- @lang.containments(clazz).each do |r|
82
- ([r.eType] + r.eType.eAllSubTypes).select{|t| t.concrete}.each do |t|
83
- if @lang.labeled_containment?(clazz, r) || @lang.containments_by_target_type(clazz, t).size > 1
84
- labled_refs << r
85
- else
86
- types << t
87
- end
88
- end
89
- end
90
- end
91
- types.uniq.
92
- sort{|a,b| a.name <=> b.name}.collect do |c|
93
- class_completion_option(c)
94
- end +
95
- labled_refs.uniq.collect do |r|
96
- CompletionOption.from_text_extra("#{r.name}:", "<#{r.eType.name}>")
97
- end
98
- end
99
-
100
- def add_value_options(context, result, version)
101
- if context.feature.is_a?(RGen::ECore::EAttribute) || !context.feature.containment
102
- if context.feature.is_a?(RGen::ECore::EReference)
103
- result.concat(reference_options(context))
104
- if version > 0 && !context.position.before_bracket && context.feature.upperBound != 1
105
- result << CompletionOption.for_square_brackets
106
- end
107
- elsif context.feature.eType.is_a?(RGen::ECore::EEnum)
108
- result.concat(enum_options(context))
109
- elsif context.feature.eType.instanceClass == String
110
- result.concat(string_options(context))
111
- elsif context.feature.eType.instanceClass == Integer
112
- result.concat(integer_options(context))
113
- elsif context.feature.eType.instanceClass == Float
114
- result.concat(float_options(context))
115
- elsif context.feature.eType.instanceClass == RGen::MetamodelBuilder::DataTypes::Boolean
116
- result.concat(boolean_options(context))
117
- else
118
- # no options
119
- end
120
- else
121
- if version > 0 && !context.position.before_bracket && context.feature.upperBound != 1
122
- result << CompletionOption.for_square_brackets
123
- end
124
- end
125
- end
126
-
127
- def add_label_options(context, clazz, result, version)
128
- result.concat(@lang.labled_arguments(clazz).
129
- select{|f|
130
- !context.element.eIsSet(f.name)}.collect do |f|
131
- CompletionOption.from_text_extra("#{f.name}:", "<#{f.eType.name}>")
132
- end )
133
- if version > 0 && !context.position.after_comma &&
134
- context.element.class.ecore.eAllReferences.any? { |r| r.containment } && !context.position.before_brace
135
- result << CompletionOption.for_curly_braces(context)
136
- end
137
- end
138
-
139
- def root_options
140
- @lang.root_classes.
141
- sort{|a,b| a.name <=> b.name}.collect do |c|
142
- class_completion_option(c)
143
- end
144
- end
145
-
146
- def reference_options(context)
147
- []
148
- end
149
-
150
- def enum_options(context)
151
- context.feature.eType.eLiterals.collect do |l|
152
- lname = l.name
153
- if lname =~ /^\d|\W/ || lname == "true" || lname == "false"
154
- lname = "\"#{lname.gsub("\\","\\\\\\\\").gsub("\"","\\\"").gsub("\n","\\n").
155
- gsub("\r","\\r").gsub("\t","\\t").gsub("\f","\\f").gsub("\b","\\b")}\""
156
- end
157
- CompletionOption.from_text_extra("#{lname}", "<#{context.feature.eType.name}>")
158
- end
159
- end
160
-
161
- def string_options(context)
162
- if @lang.unquoted?(context.feature)
163
- [ CompletionOption.from_text_extra("#{context.feature.name.gsub(/\W/,"")}", value_description(context)) ]
164
- else
165
- [ CompletionOption.from_text_extra("\"\"", value_description(context)) ]
166
- end
167
- end
168
-
169
- def get_default_value_completion(context)
170
- return nil unless context.feature.defaultValue
171
- CompletionOption.from_text_extra("#{context.feature.defaultValue}", value_description(context))
172
- end
173
-
174
- def integer_options(context)
175
- default_comp = get_default_value_completion(context)
176
- return [default_comp] if default_comp
177
- (0..0).collect{|i| CompletionOption.from_text_extra("#{i}", value_description(context)) }
178
- end
179
-
180
- def float_options(context)
181
- default_comp = get_default_value_completion(context)
182
- return [default_comp] if default_comp
183
- (0..0).collect{|i| CompletionOption.from_text_extra("#{i}.0", value_description(context)) }
184
- end
185
-
186
- def boolean_options(context)
187
- [true, false].collect{|b| CompletionOption.from_text_extra("#{b}", value_description(context)) }
188
- end
189
-
190
- private
191
-
192
- def value_description(context)
193
- if context.position.after_label
194
- "<#{context.feature.eType.name}>"
195
- else
196
- "[#{context.feature.name}] <#{context.feature.eType.name}>"
197
- end
198
- end
199
-
200
- def class_completion_option(eclass)
201
- uargs = @lang.unlabled_arguments(eclass).collect{|a| "<#{a.name}>"}.join(", ")
202
- CompletionOption.from_text_extra(@lang.command_by_class(eclass.instanceClass), uargs)
203
- end
204
-
205
- end
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
+