Skip to content

Commit c50c6b5

Browse files
committed
Merge pull request #788 from fdorg/fd5
Haxe compiler "position" resolution
2 parents 4b92fb1 + d6faba0 commit c50c6b5

File tree

9 files changed

+290
-50
lines changed

9 files changed

+290
-50
lines changed

External/Plugins/ASCompletion/Completion/ASComplete.cs

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,20 @@ static public bool DeclarationLookup(ScintillaControl Sci)
461461
{
462462
if (!ASContext.Context.IsFileValid || (Sci == null)) return false;
463463

464+
// let the context handle goto declaration if we couldn't find anything
465+
if (!InternalDeclarationLookup(Sci))
466+
{
467+
ASExpr expression = GetExpression(Sci, Sci.CurrentPos);
468+
if (expression != null)
469+
{
470+
return ASContext.Context.HandleGotoDeclaration(Sci, expression);
471+
}
472+
}
473+
return true;
474+
}
475+
476+
static private bool InternalDeclarationLookup(ScintillaControl Sci)
477+
{
464478
// get type at cursor position
465479
int position = Sci.WordEndPosition(Sci.CurrentPos, true);
466480
ASResult result = GetExpressionType(Sci, position, false);
@@ -513,6 +527,16 @@ static public bool DeclarationLookup(ScintillaControl Sci)
513527
return false;
514528
}
515529

530+
static public void SaveLastLookupPosition(ScintillaControl Sci)
531+
{
532+
if (Sci != null)
533+
{
534+
int lookupLine = Sci.CurrentLine;
535+
int lookupCol = Sci.CurrentPos - Sci.PositionFromLine(lookupLine);
536+
ASContext.Panel.SetLastLookupPosition(ASContext.Context.CurrentFile, lookupLine, lookupCol);
537+
}
538+
}
539+
516540
/// <summary>
517541
/// Show resolved element declaration
518542
/// </summary>
@@ -524,13 +548,7 @@ static public bool OpenDocumentToDeclaration(ScintillaControl Sci, ASResult resu
524548
if (model == null || model.FileName == "") return false;
525549
ClassModel inClass = result.InClass ?? result.Type;
526550

527-
// for Back command
528-
if (Sci != null)
529-
{
530-
int lookupLine = Sci.CurrentLine;
531-
int lookupCol = Sci.CurrentPos - Sci.PositionFromLine(lookupLine);
532-
ASContext.Panel.SetLastLookupPosition(ASContext.Context.CurrentFile, lookupLine, lookupCol);
533-
}
551+
SaveLastLookupPosition(Sci);
534552

535553
if (model != ASContext.Context.CurrentModel)
536554
{

External/Plugins/ASCompletion/Context/ASContext.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,6 +1334,11 @@ public virtual MemberModel ResolveFunctionContext(ScintillaNet.ScintillaControl
13341334
{
13351335
return null;
13361336
}
1337+
1338+
public virtual bool HandleGotoDeclaration(ScintillaNet.ScintillaControl sci, ASExpr expression)
1339+
{
1340+
return false;
1341+
}
13371342
#endregion
13381343

13391344
#region plugin commands

External/Plugins/ASCompletion/Context/IASContext.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,8 @@ public interface IASContext
298298
/// <param name="expression">Completion context</param>
299299
/// <returns>Null (not handled) or function signature</returns>
300300
MemberModel ResolveFunctionContext(ScintillaNet.ScintillaControl sci, ASExpr expression, bool autoHide);
301+
302+
bool HandleGotoDeclaration(ScintillaNet.ScintillaControl sci, ASExpr expression);
301303
#endregion
302304

303305
#region Properties

External/Plugins/HaXeContext/Completion/HaxeComplete.cs

Lines changed: 132 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Collections;
32
using System.Collections.Generic;
43
using System.IO;
54
using System.Text.RegularExpressions;
@@ -16,59 +15,79 @@
1615

1716
namespace HaXeContext
1817
{
19-
internal delegate void HaXeCompletionResultHandler(HaxeComplete sender, HaxeCompleteStatus status);
18+
internal delegate void HaxeCompleteResultHandler<T>(HaxeComplete hc, T result, HaxeCompleteStatus status);
2019

2120
internal class HaxeComplete
2221
{
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);
2428

2529
// completion context
2630
public readonly ScintillaControl Sci;
2731
public readonly ASExpr Expr;
32+
public readonly string CurrentWord;
2833
public readonly bool AutoHide;
34+
public readonly HaxeCompilerService CompilerService;
2935

3036
// result
3137
public HaxeCompleteStatus Status;
3238
public string Errors;
33-
public MemberModel Type;
34-
public MemberList Members;
39+
private HaxeCompleteResult result;
40+
private HaxePositionCompleteResult positionResult;
3541

3642
readonly IHaxeCompletionHandler handler;
3743
readonly string FileName;
3844

39-
public HaxeComplete(ScintillaControl sci, ASExpr expr, bool autoHide, IHaxeCompletionHandler completionHandler)
45+
public HaxeComplete(ScintillaControl sci, ASExpr expr, bool autoHide, IHaxeCompletionHandler completionHandler, HaxeCompilerService compilerService)
4046
{
4147
Sci = sci;
4248
Expr = expr;
49+
CurrentWord = Sci.GetWordFromPosition(Sci.CurrentPos);
4350
AutoHide = autoHide;
4451
handler = completionHandler;
52+
CompilerService = compilerService;
4553
Status = HaxeCompleteStatus.NONE;
4654
FileName = PluginBase.MainForm.CurrentDocument.FileName;
4755
}
4856

4957
/* EXECUTION */
5058

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)
5271
{
5372
PluginBase.MainForm.CallCommand("Save", null);
5473

5574
ThreadPool.QueueUserWorkItem(_ =>
5675
{
5776
Status = ParseLines(handler.GetCompletion(BuildHxmlArgs()));
58-
Notify(callback);
77+
Notify(callback, positionResult);
5978
});
6079
}
6180

62-
void Notify(HaXeCompletionResultHandler callback)
81+
void Notify<T>(HaxeCompleteResultHandler<T> callback, T result)
6382
{
6483
if (Sci.InvokeRequired)
6584
{
6685
Sci.BeginInvoke((MethodInvoker)delegate {
67-
Notify(callback);
86+
Notify(callback, result);
6887
});
6988
return;
7089
}
71-
callback(this, Status);
90+
callback(this, result, Status);
7291
}
7392

7493
/* HAXE COMPILER ARGS */
@@ -83,7 +102,7 @@ string[] BuildHxmlArgs()
83102
var hxproj = (PluginBase.CurrentProject as HaxeProject);
84103
var pos = GetDisplayPosition();
85104

86-
// Build haXe command
105+
// Build Haxe command
87106
var paths = ProjectManager.PluginMain.Settings.GlobalClasspaths.ToArray();
88107
var hxmlArgs = new List<String>(hxproj.BuildHXML(paths, "Nothing__", true));
89108
QuotePath(hxmlArgs);
@@ -102,9 +121,11 @@ string[] BuildHxmlArgs()
102121
else
103122
hxmlArgs.Add(GetMainClassName());
104123

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));
106126
hxmlArgs.Insert(1, "-D use_rtti_doc");
107127
hxmlArgs.Insert(2, "-D display-details");
128+
108129
if (hxproj.TraceEnabled) hxmlArgs.Insert(2, "-debug");
109130

110131
return hxmlArgs.ToArray();
@@ -136,10 +157,20 @@ string GetMainClassName()
136157
int GetDisplayPosition()
137158
{
138159
var pos = Expr.Position;
139-
// locate a . or (
140-
while (pos > 1 && Sci.CharAt(pos - 1) != '.' && Sci.CharAt(pos - 1) != '(')
141-
pos--;
142160

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+
143174
// account for BOM characters
144175
pos += FileHelper.GetEncodingFileInfo(FileName).BomLength;
145176
return pos;
@@ -175,15 +206,16 @@ HaxeCompleteStatus ParseLines(string lines)
175206
HaxeCompleteStatus ProcessResponse(XmlTextReader reader)
176207
{
177208
reader.MoveToContent();
209+
178210
switch (reader.Name)
179211
{
180212
case "type":
181213
ProcessType(reader);
182214
return HaxeCompleteStatus.TYPE;
183215

184216
case "list":
185-
ProcessMembers(reader);
186-
return HaxeCompleteStatus.MEMBERS;
217+
return ProcessList(reader);
218+
187219
}
188220
return HaxeCompleteStatus.FAILED;
189221
}
@@ -196,22 +228,26 @@ void ProcessType(XmlTextReader reader)
196228
var type = new MemberModel();
197229
type.Name = name;
198230
ExtractType(reader, type);
199-
this.Type = type;
231+
result.Type = type;
200232
}
201233

202-
void ProcessMembers(XmlTextReader reader)
234+
HaxeCompleteStatus ProcessList(XmlTextReader reader)
203235
{
204-
Members = new MemberList();
205-
MemberModel member = null;
236+
result = new HaxeCompleteResult();
237+
result.Members = new MemberList();
238+
MemberModel member = null;
206239

207240
while (reader.Read())
208241
{
209242
if (reader.NodeType == XmlNodeType.EndElement)
210243
{
211244
switch (reader.Name)
212245
{
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;
215251
}
216252
continue;
217253
}
@@ -232,18 +268,56 @@ void ProcessMembers(XmlTextReader reader)
232268
case "t":
233269
if (member == null) continue;
234270
ExtractType(reader, member);
235-
if (!IsOverload(member))
236-
Members.Add(member);
271+
if (!IsOverload(result.Members, member))
272+
result.Members.Add(member);
237273
break;
274+
275+
case "pos":
276+
positionResult = ExtractPos(reader);
277+
return HaxeCompleteStatus.POSITION;
238278
}
239279
}
280+
return HaxeCompleteStatus.MEMBERS;
240281
}
241282

242-
bool IsOverload(MemberModel member)
283+
HaxePositionCompleteResult ExtractPos(XmlTextReader reader)
243284
{
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;
245314
}
246315

316+
bool IsOverload(MemberList members, MemberModel member)
317+
{
318+
return members.Count > 0 && members[members.Count - 1].FullName == member.FullName;
319+
}
320+
247321
MemberModel ExtractMember(XmlTextReader reader)
248322
{
249323
var name = reader.GetAttribute("n");
@@ -296,7 +370,6 @@ void ExtractType(XmlTextReader reader, MemberModel member)
296370
if (member.Flags == 0) member.Flags = FlagType.Variable;
297371
member.Type = type;
298372
}
299-
300373
}
301374
}
302375

@@ -314,6 +387,35 @@ enum HaxeCompleteStatus: int
314387
FAILED = 1,
315388
ERROR = 2,
316389
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
318420
}
319421
}

0 commit comments

Comments
 (0)