1
1
using System ;
2
- using System . Collections ;
3
2
using System . Collections . Generic ;
4
3
using System . IO ;
5
4
using System . Text . RegularExpressions ;
16
15
17
16
namespace HaXeContext
18
17
{
19
- internal delegate void HaXeCompletionResultHandler ( HaxeComplete sender , HaxeCompleteStatus status ) ;
18
+ internal delegate void HaxeCompleteResultHandler < T > ( HaxeComplete hc , T result , HaxeCompleteStatus status ) ;
20
19
21
20
internal class HaxeComplete
22
21
{
23
- static readonly Regex reArg = new Regex ( "^(-cp)\\ s*([^\" '].*)$" , RegexOptions . Compiled | RegexOptions . IgnoreCase ) ;
22
+ static readonly Regex reArg =
23
+ new Regex ( "^(-cp)\\ s*([^\" '].*)$" , RegexOptions . Compiled | RegexOptions . IgnoreCase ) ;
24
+
25
+ static readonly Regex rePosition =
26
+ new Regex ( "(?<path>.*?):(?<line>[0-9]*): (?<range>characters|lines) (?<start>[0-9]*)-(?<end>[0-9]*)" ,
27
+ RegexOptions . Compiled | RegexOptions . IgnoreCase ) ;
24
28
25
29
// completion context
26
30
public readonly ScintillaControl Sci ;
27
31
public readonly ASExpr Expr ;
32
+ public readonly string CurrentWord ;
28
33
public readonly bool AutoHide ;
34
+ public readonly HaxeCompilerService CompilerService ;
29
35
30
36
// result
31
37
public HaxeCompleteStatus Status ;
32
38
public string Errors ;
33
- public MemberModel Type ;
34
- public MemberList Members ;
39
+ private HaxeCompleteResult result ;
40
+ private HaxePositionCompleteResult positionResult ;
35
41
36
42
readonly IHaxeCompletionHandler handler ;
37
43
readonly string FileName ;
38
44
39
- public HaxeComplete ( ScintillaControl sci , ASExpr expr , bool autoHide , IHaxeCompletionHandler completionHandler )
45
+ public HaxeComplete ( ScintillaControl sci , ASExpr expr , bool autoHide , IHaxeCompletionHandler completionHandler , HaxeCompilerService compilerService )
40
46
{
41
47
Sci = sci ;
42
48
Expr = expr ;
49
+ CurrentWord = Sci . GetWordFromPosition ( Sci . CurrentPos ) ;
43
50
AutoHide = autoHide ;
44
51
handler = completionHandler ;
52
+ CompilerService = compilerService ;
45
53
Status = HaxeCompleteStatus . NONE ;
46
54
FileName = PluginBase . MainForm . CurrentDocument . FileName ;
47
55
}
48
56
49
57
/* EXECUTION */
50
58
51
- public void GetList ( HaXeCompletionResultHandler callback )
59
+ public void GetList ( HaxeCompleteResultHandler < HaxeCompleteResult > callback )
60
+ {
61
+ PluginBase . MainForm . CallCommand ( "Save" , null ) ;
62
+
63
+ ThreadPool . QueueUserWorkItem ( _ =>
64
+ {
65
+ Status = ParseLines ( handler . GetCompletion ( BuildHxmlArgs ( ) ) ) ;
66
+ Notify ( callback , result ) ;
67
+ } ) ;
68
+ }
69
+
70
+ public void GetPosition ( HaxeCompleteResultHandler < HaxePositionCompleteResult > callback )
52
71
{
53
72
PluginBase . MainForm . CallCommand ( "Save" , null ) ;
54
73
55
74
ThreadPool . QueueUserWorkItem ( _ =>
56
75
{
57
76
Status = ParseLines ( handler . GetCompletion ( BuildHxmlArgs ( ) ) ) ;
58
- Notify ( callback ) ;
77
+ Notify ( callback , positionResult ) ;
59
78
} ) ;
60
79
}
61
80
62
- void Notify ( HaXeCompletionResultHandler callback )
81
+ void Notify < T > ( HaxeCompleteResultHandler < T > callback , T result )
63
82
{
64
83
if ( Sci . InvokeRequired )
65
84
{
66
85
Sci . BeginInvoke ( ( MethodInvoker ) delegate {
67
- Notify ( callback ) ;
86
+ Notify ( callback , result ) ;
68
87
} ) ;
69
88
return ;
70
89
}
71
- callback ( this , Status ) ;
90
+ callback ( this , result , Status ) ;
72
91
}
73
92
74
93
/* HAXE COMPILER ARGS */
@@ -83,7 +102,7 @@ string[] BuildHxmlArgs()
83
102
var hxproj = ( PluginBase . CurrentProject as HaxeProject ) ;
84
103
var pos = GetDisplayPosition ( ) ;
85
104
86
- // Build haXe command
105
+ // Build Haxe command
87
106
var paths = ProjectManager . PluginMain . Settings . GlobalClasspaths . ToArray ( ) ;
88
107
var hxmlArgs = new List < String > ( hxproj . BuildHXML ( paths , "Nothing__" , true ) ) ;
89
108
QuotePath ( hxmlArgs ) ;
@@ -102,9 +121,11 @@ string[] BuildHxmlArgs()
102
121
else
103
122
hxmlArgs . Add ( GetMainClassName ( ) ) ;
104
123
105
- hxmlArgs . Insert ( 0 , String . Format ( "--display \" {0}\" @{1}" , FileName , pos ) ) ;
124
+ String mode = ( CompilerService == HaxeCompilerService . COMPLETION ) ? "" : "@position" ;
125
+ hxmlArgs . Insert ( 0 , String . Format ( "--display \" {0}\" @{1}{2}" , FileName , pos , mode ) ) ;
106
126
hxmlArgs . Insert ( 1 , "-D use_rtti_doc" ) ;
107
127
hxmlArgs . Insert ( 2 , "-D display-details" ) ;
128
+
108
129
if ( hxproj . TraceEnabled ) hxmlArgs . Insert ( 2 , "-debug" ) ;
109
130
110
131
return hxmlArgs . ToArray ( ) ;
@@ -136,10 +157,20 @@ string GetMainClassName()
136
157
int GetDisplayPosition ( )
137
158
{
138
159
var pos = Expr . Position ;
139
- // locate a . or (
140
- while ( pos > 1 && Sci . CharAt ( pos - 1 ) != '.' && Sci . CharAt ( pos - 1 ) != '(' )
141
- pos -- ;
142
160
161
+ switch ( CompilerService )
162
+ {
163
+ case HaxeCompilerService . COMPLETION :
164
+ // locate a . or (
165
+ while ( pos > 1 && Sci . CharAt ( pos - 1 ) != '.' && Sci . CharAt ( pos - 1 ) != '(' )
166
+ pos -- ;
167
+ break ;
168
+
169
+ case HaxeCompilerService . POSITION :
170
+ pos = Sci . WordEndPosition ( Sci . CurrentPos , true ) + 1 ;
171
+ break ;
172
+ }
173
+
143
174
// account for BOM characters
144
175
pos += FileHelper . GetEncodingFileInfo ( FileName ) . BomLength ;
145
176
return pos ;
@@ -175,15 +206,16 @@ HaxeCompleteStatus ParseLines(string lines)
175
206
HaxeCompleteStatus ProcessResponse ( XmlTextReader reader )
176
207
{
177
208
reader . MoveToContent ( ) ;
209
+
178
210
switch ( reader . Name )
179
211
{
180
212
case "type" :
181
213
ProcessType ( reader ) ;
182
214
return HaxeCompleteStatus . TYPE ;
183
215
184
216
case "list" :
185
- ProcessMembers ( reader ) ;
186
- return HaxeCompleteStatus . MEMBERS ;
217
+ return ProcessList ( reader ) ;
218
+
187
219
}
188
220
return HaxeCompleteStatus . FAILED ;
189
221
}
@@ -196,22 +228,26 @@ void ProcessType(XmlTextReader reader)
196
228
var type = new MemberModel ( ) ;
197
229
type . Name = name ;
198
230
ExtractType ( reader , type ) ;
199
- this . Type = type ;
231
+ result . Type = type ;
200
232
}
201
233
202
- void ProcessMembers ( XmlTextReader reader )
234
+ HaxeCompleteStatus ProcessList ( XmlTextReader reader )
203
235
{
204
- Members = new MemberList ( ) ;
205
- MemberModel member = null ;
236
+ result = new HaxeCompleteResult ( ) ;
237
+ result . Members = new MemberList ( ) ;
238
+ MemberModel member = null ;
206
239
207
240
while ( reader . Read ( ) )
208
241
{
209
242
if ( reader . NodeType == XmlNodeType . EndElement )
210
243
{
211
244
switch ( reader . Name )
212
245
{
213
- case "list" : return ;
214
- case "i" : member = null ; break ;
246
+ case "list" :
247
+ return HaxeCompleteStatus . MEMBERS ;
248
+ case "i" :
249
+ member = null ;
250
+ break ;
215
251
}
216
252
continue ;
217
253
}
@@ -232,18 +268,56 @@ void ProcessMembers(XmlTextReader reader)
232
268
case "t" :
233
269
if ( member == null ) continue ;
234
270
ExtractType ( reader , member ) ;
235
- if ( ! IsOverload ( member ) )
236
- Members . Add ( member ) ;
271
+ if ( ! IsOverload ( result . Members , member ) )
272
+ result . Members . Add ( member ) ;
237
273
break ;
274
+
275
+ case "pos" :
276
+ positionResult = ExtractPos ( reader ) ;
277
+ return HaxeCompleteStatus . POSITION ;
238
278
}
239
279
}
280
+ return HaxeCompleteStatus . MEMBERS ;
240
281
}
241
282
242
- bool IsOverload ( MemberModel member )
283
+ HaxePositionCompleteResult ExtractPos ( XmlTextReader reader )
243
284
{
244
- return Members . Count > 0 && Members [ Members . Count - 1 ] . FullName == member . FullName ;
285
+ var result = new HaxePositionCompleteResult ( ) ;
286
+
287
+ string value = ReadValue ( reader ) ;
288
+ Match match = rePosition . Match ( value ) ;
289
+ result . Path = match . Groups [ "path" ] . Value ;
290
+ int . TryParse ( match . Groups [ "line" ] . Value , out result . LineStart ) ;
291
+ string rangeType = match . Groups [ "range" ] . Value ;
292
+ if ( rangeType == "lines" )
293
+ result . RangeType = HaxePositionCompleteRangeType . LINES ;
294
+ else
295
+ result . RangeType = HaxePositionCompleteRangeType . CHARACTERS ;
296
+
297
+ int start = 0 ;
298
+ int end = 0 ;
299
+ int . TryParse ( match . Groups [ "start" ] . Value , out start ) ;
300
+ int . TryParse ( match . Groups [ "end" ] . Value , out end ) ;
301
+
302
+ if ( result . RangeType == HaxePositionCompleteRangeType . LINES )
303
+ {
304
+ result . LineStart = start ;
305
+ result . LineEnd = end ;
306
+ }
307
+ else
308
+ {
309
+ result . CharacterStart = start ;
310
+ result . CharacterEnd = end ;
311
+ }
312
+
313
+ return result ;
245
314
}
246
315
316
+ bool IsOverload ( MemberList members , MemberModel member )
317
+ {
318
+ return members . Count > 0 && members [ members . Count - 1 ] . FullName == member . FullName ;
319
+ }
320
+
247
321
MemberModel ExtractMember ( XmlTextReader reader )
248
322
{
249
323
var name = reader . GetAttribute ( "n" ) ;
@@ -296,7 +370,6 @@ void ExtractType(XmlTextReader reader, MemberModel member)
296
370
if ( member . Flags == 0 ) member . Flags = FlagType . Variable ;
297
371
member . Type = type ;
298
372
}
299
-
300
373
}
301
374
}
302
375
@@ -314,6 +387,35 @@ enum HaxeCompleteStatus: int
314
387
FAILED = 1 ,
315
388
ERROR = 2 ,
316
389
TYPE = 3 ,
317
- MEMBERS = 4
390
+ MEMBERS = 4 ,
391
+ POSITION = 5
392
+ }
393
+
394
+ enum HaxeCompilerService
395
+ {
396
+ COMPLETION ,
397
+ POSITION
398
+ }
399
+
400
+ class HaxeCompleteResult
401
+ {
402
+ public MemberModel Type ;
403
+ public MemberList Members ;
404
+ }
405
+
406
+ class HaxePositionCompleteResult
407
+ {
408
+ public string Path ;
409
+ public HaxePositionCompleteRangeType RangeType ;
410
+ public int LineStart ;
411
+ public int LineEnd ;
412
+ public int CharacterStart ;
413
+ public int CharacterEnd ;
414
+ }
415
+
416
+ enum HaxePositionCompleteRangeType
417
+ {
418
+ CHARACTERS ,
419
+ LINES
318
420
}
319
421
}
0 commit comments