Skip to content

Commit bcf5420

Browse files
author
slavara
committed
Fixes NPE
1 parent 60b5e10 commit bcf5420

File tree

2 files changed

+85
-61
lines changed

2 files changed

+85
-61
lines changed

PostfixCodeCompletion/Completion/HaxeComplete.cs

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.IO;
4+
using System.Text.RegularExpressions;
45
using System.Threading;
56
using System.Windows.Forms;
67
using System.Xml;
@@ -15,7 +16,7 @@
1516

1617
namespace PostfixCodeCompletion.Completion
1718
{
18-
internal delegate void HaxeCompleteResultHandler<T>(HaxeComplete hc, T result, HaxeCompleteStatus status);
19+
internal delegate void HaxeCompleteResultHandler<in T>(HaxeComplete hc, T result, HaxeCompleteStatus status);
1920

2021
interface IHaxeCompletionHandler
2122
{
@@ -25,6 +26,9 @@ interface IHaxeCompletionHandler
2526

2627
internal class HaxeComplete
2728
{
29+
static readonly Regex reArg = new Regex("^(-cp|-resource)\\s*([^\"'].*)$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
30+
static readonly Regex reMacro = new Regex("^(--macro)\\s*([^\"'].*)$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
31+
2832
public readonly ScintillaControl Sci;
2933
public readonly ASResult Expr;
3034
public readonly string CurrentWord;
@@ -95,20 +99,56 @@ string[] BuildHxmlArgs()
9599
if (PluginBase.CurrentProject == null || !(PluginBase.CurrentProject is HaxeProject)
96100
|| !(ASContext.Context is Context))
97101
return null;
98-
var hxproj = ((HaxeProject) PluginBase.CurrentProject);
102+
var project = (HaxeProject) PluginBase.CurrentProject;
99103
var pos = GetDisplayPosition();
100104
var paths = ProjectManager.PluginMain.Settings.GlobalClasspaths.ToArray();
101-
var hxmlArgs = new List<string>(hxproj.BuildHXML(paths, "Nothing__", true))
105+
var args = new List<string>(project.BuildHXML(paths, "Nothing__", true))
102106
{
103-
"-cp " + Path.GetDirectoryName(tempFileName)
107+
$"-cp {Path.GetDirectoryName(tempFileName)}"
104108
};
109+
RemoveComments(args);
110+
QuotePath(args);
111+
EscapeMacros(args);
105112
var mode = "";
106113
if (CompilerService == HaxeCompilerService.Type) mode = "@type";
107-
hxmlArgs.Insert(0, string.Format("--display {0}@{1}{2}", tempFileName, pos, mode));
108-
hxmlArgs.Insert(1, "-D use_rtti_doc");
109-
hxmlArgs.Insert(2, "-D display-details");
110-
if (hxproj.TraceEnabled) hxmlArgs.Insert(2, "-debug");
111-
return hxmlArgs.ToArray();
114+
args.Insert(0, $"--display {tempFileName}@{pos}{mode}");
115+
args.Insert(1, "-D use_rtti_doc");
116+
args.Insert(2, "-D display-details");
117+
if (project.TraceEnabled) args.Insert(2, "-debug");
118+
return args.ToArray();
119+
}
120+
121+
static void RemoveComments(IList<string> args)
122+
{
123+
for (var i = 0; i < args.Count; i++)
124+
{
125+
var arg = args[i];
126+
if (string.IsNullOrEmpty(arg)) continue;
127+
if (arg.StartsWith('#')) // commented line
128+
args[i] = "";
129+
}
130+
}
131+
132+
static void QuotePath(IList<string> args)
133+
{
134+
for (var i = 0; i < args.Count; i++)
135+
{
136+
var arg = args[i];
137+
if (string.IsNullOrEmpty(arg)) continue;
138+
var m = reArg.Match(arg);
139+
if (m.Success) args[i] = $"{m.Groups[1].Value} \"{m.Groups[2].Value.Trim()}\"";
140+
}
141+
}
142+
143+
static void EscapeMacros(IList<string> args)
144+
{
145+
for (var i = 0; i < args.Count; i++)
146+
{
147+
var arg = args[i];
148+
if (string.IsNullOrEmpty(arg)) continue;
149+
var m = reMacro.Match(arg);
150+
if (m.Success) args[i] = $"{m.Groups[1].Value} \"{m.Groups[2].Value.Trim()}\"";
151+
}
112152
}
113153

114154
int GetDisplayPosition()

PostfixCodeCompletion/PluginMain.cs

Lines changed: 36 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public void Initialize()
6565
/// </summary>
6666
public void Dispose()
6767
{
68-
if (completionModeHandler != null) completionModeHandler.Stop();
68+
completionModeHandler?.Stop();
6969
SaveSettings();
7070
}
7171

@@ -74,11 +74,12 @@ public void Dispose()
7474
/// </summary>
7575
public void HandleEvent(object sender, NotifyEvent e, HandlingPriority priority)
7676
{
77+
var completionList = Reflector.CompletionList.completionList;
7778
switch (e.Type)
7879
{
7980
case EventType.UIStarted:
80-
Reflector.CompletionList.completionList.VisibleChanged -= OnCompletionListVisibleChanged;
81-
Reflector.CompletionList.completionList.VisibleChanged += OnCompletionListVisibleChanged;
81+
completionList.VisibleChanged -= OnCompletionListVisibleChanged;
82+
completionList.VisibleChanged += OnCompletionListVisibleChanged;
8283
break;
8384
case EventType.Command:
8485
if (((DataEvent) e).Action == ProjectManagerEvents.Project)
@@ -96,15 +97,13 @@ public void HandleEvent(object sender, NotifyEvent e, HandlingPriority priority)
9697
var keys = ((KeyEvent) e).Value;
9798
if (keys == (Keys.Control | Keys.Space))
9899
{
100+
if (CompletionList.Active) return;
99101
var expr = GetPostfixCompletionExpr();
100102
if (expr == null || expr.IsNull()) return;
101103
e.Handled = ASComplete.OnShortcut(keys, PluginBase.MainForm.CurrentDocument.SciControl);
102-
if (!CompletionList.Active)
103-
{
104-
Reflector.CompletionList.completionList.VisibleChanged -= OnCompletionListVisibleChanged;
105-
UpdateCompletionList(expr);
106-
Reflector.CompletionList.completionList.VisibleChanged += OnCompletionListVisibleChanged;
107-
}
104+
completionList.VisibleChanged -= OnCompletionListVisibleChanged;
105+
UpdateCompletionList(expr);
106+
completionList.VisibleChanged += OnCompletionListVisibleChanged;
108107
}
109108
break;
110109
}
@@ -148,14 +147,12 @@ void AddEventHandlers()
148147
/// <summary>
149148
/// Saves the plugin settings
150149
/// </summary>
151-
void SaveSettings()
152-
{
153-
ObjectSerializer.Serialize(settingFilename, Settings);
154-
}
150+
void SaveSettings() => ObjectSerializer.Serialize(settingFilename, Settings);
155151

156152
static void UpdateCompletionList()
157153
{
158-
UpdateCompletionList(GetPostfixCompletionExpr());
154+
var expr = GetPostfixCompletionExpr();
155+
UpdateCompletionList(expr);
159156
}
160157

161158
static void UpdateCompletionList(ASResult expr)
@@ -167,10 +164,9 @@ static void UpdateCompletionList(ASResult expr)
167164
UpdateCompletionList(target, expr);
168165
return;
169166
}
170-
if (completionModeHandler == null) return;
167+
if (expr.Context == null || completionModeHandler == null) return;
171168
var sci = PluginBase.MainForm.CurrentDocument.SciControl;
172-
if (sci.ConfigurationLanguage.ToLower() != "haxe" || expr.Context == null || sci.CharAt(expr.Context.Position) != '.')
173-
return;
169+
if (sci.ConfigurationLanguage.ToLower() != "haxe" || sci.CharAt(expr.Context.Position) != '.') return;
174170
var hc = new HaxeComplete(sci, expr, false, completionModeHandler, HaxeCompilerService.Type);
175171
hc.GetPositionType(OnFunctionTypeResult);
176172
}
@@ -183,10 +179,15 @@ static void UpdateCompletionList(MemberModel target, ASResult expr)
183179
var allItems = Reflector.CompletionList.allItems;
184180
if (allItems != null)
185181
{
186-
allItems = new List<ICompletionListItem>(allItems);
182+
var labels = new HashSet<string>();
183+
foreach (var item in allItems)
184+
{
185+
labels.Add(item.Label);
186+
}
187187
foreach (var item in items)
188188
{
189-
if (!allItems.Exists(it => it.Label == item.Label)) allItems.Add(item);
189+
var label = item.Label;
190+
if (!labels.Contains(label)) allItems.Add(item);
190191
}
191192
items = allItems;
192193
}
@@ -195,6 +196,7 @@ static void UpdateCompletionList(MemberModel target, ASResult expr)
195196
CompletionList.Show(items, false, word);
196197
var list = Reflector.CompletionList.completionList;
197198
completionListItemCount = list.Items.Count;
199+
list.SelectedValueChanged -= OnCompletionListSelectedValueChanged;
198200
list.SelectedValueChanged += OnCompletionListSelectedValueChanged;
199201
}
200202

@@ -247,12 +249,9 @@ static List<ICompletionListItem> GetPostfixCompletionItems(MemberModel target, A
247249
if (expr.Member != null) result.AddRange(GetCompletionItems(expr.Member.Type, target, expr));
248250
else if (expr.Type != null) result.AddRange(GetCompletionItems(expr.Type.Type, target, expr));
249251
result.AddRange(GetCompletionItems(TemplateUtils.PATTERN_MEMBER, expr));
250-
if (GetTargetIsNullable(target))
251-
result.AddRange(GetCompletionItems(TemplateUtils.PATTERN_NULLABLE, expr));
252-
if (GetTargetIsCollection(target))
253-
result.AddRange(GetCompletionItems(TemplateUtils.PATTERN_COLLECTION, expr));
254-
if (GetTargetIsHash(target))
255-
result.AddRange(GetCompletionItems(TemplateUtils.PATTERN_HASH, expr));
252+
if (IsNullable(target)) result.AddRange(GetCompletionItems(TemplateUtils.PATTERN_NULLABLE, expr));
253+
if (IsCollection(target)) result.AddRange(GetCompletionItems(TemplateUtils.PATTERN_COLLECTION, expr));
254+
if (IsHash(target)) result.AddRange(GetCompletionItems(TemplateUtils.PATTERN_HASH, expr));
256255
if (PluginBase.MainForm.CurrentDocument.SciControl.ConfigurationLanguage.ToLower() == "haxe")
257256
{
258257
var type = expr.Type != null && !string.IsNullOrEmpty(expr.Type.Type) &&
@@ -261,27 +260,19 @@ static List<ICompletionListItem> GetPostfixCompletionItems(MemberModel target, A
261260
: null;
262261
if (type != null)
263262
{
264-
if (GetTargetIsCollection(type))
265-
result.AddRange(GetCompletionItems(TemplateUtils.PATTERN_COLLECTION, expr));
266-
if (GetTargetIsHash(type))
267-
result.AddRange(GetCompletionItems(TemplateUtils.PATTERN_HASH, expr));
263+
if (IsCollection(type)) result.AddRange(GetCompletionItems(TemplateUtils.PATTERN_COLLECTION, expr));
264+
if (IsHash(type)) result.AddRange(GetCompletionItems(TemplateUtils.PATTERN_HASH, expr));
268265
}
269266
}
270-
if (GetTargetIsBoolean(target))
271-
result.AddRange(GetCompletionItems(TemplateUtils.PATTERN_BOOL, expr));
272-
if (GetTargetIsNumber(target))
273-
result.AddRange(GetCompletionItems(TemplateUtils.PATTERN_NUMBER, expr));
274-
if (GetTargetIsString(target))
275-
result.AddRange(GetCompletionItems(TemplateUtils.PATTERN_STRING, expr));
267+
if (IsBoolean(target)) result.AddRange(GetCompletionItems(TemplateUtils.PATTERN_BOOL, expr));
268+
if (IsNumber(target)) result.AddRange(GetCompletionItems(TemplateUtils.PATTERN_NUMBER, expr));
269+
if (IsString(target)) result.AddRange(GetCompletionItems(TemplateUtils.PATTERN_STRING, expr));
276270
return result.Distinct().ToList();
277271
}
278272

279-
static bool GetTargetIsNullable(MemberModel target)
280-
{
281-
return !GetTargetIsNumber(target) && target.Type != ASContext.Context.Features.booleanKey;
282-
}
273+
static bool IsNullable(MemberModel target) => !IsNumber(target) && target.Type != ASContext.Context.Features.booleanKey;
283274

284-
static bool GetTargetIsCollection(MemberModel target)
275+
static bool IsCollection(MemberModel target)
285276
{
286277
var type = target.Type;
287278
var arrayKey = ASContext.Context.Features.arrayKey;
@@ -290,7 +281,7 @@ static bool GetTargetIsCollection(MemberModel target)
290281
{
291282
case "as2":
292283
case "as3":
293-
return type.Contains("Vector.<") || type.Contains("@" + arrayKey);
284+
return type.Contains("Vector.<") || type.Contains($"@{arrayKey}");
294285
case "haxe":
295286
return Reflector.ASGenerator.CleanType(type) == Reflector.ASGenerator.CleanType(arrayKey)
296287
|| (type.Contains("Vector<") && Reflector.ASGenerator.CleanType(type) == Reflector.ASGenerator.CleanType("Vector<T>"));
@@ -299,7 +290,7 @@ static bool GetTargetIsCollection(MemberModel target)
299290
}
300291
}
301292

302-
static bool GetTargetIsHash(MemberModel target)
293+
static bool IsHash(MemberModel target)
303294
{
304295
switch (PluginBase.MainForm.CurrentDocument.SciControl.ConfigurationLanguage.ToLower())
305296
{
@@ -331,12 +322,9 @@ static bool IsIteratorOrIterable(MemberModel member)
331322
return cleanType == "Iterator" || cleanType == "Iterable";
332323
}
333324

334-
static bool GetTargetIsBoolean(MemberModel target)
335-
{
336-
return target.Type == ASContext.Context.Features.booleanKey;
337-
}
325+
static bool IsBoolean(MemberModel target) => target.Type == ASContext.Context.Features.booleanKey;
338326

339-
static bool GetTargetIsNumber(MemberModel target)
327+
static bool IsNumber(MemberModel target)
340328
{
341329
var type = target.Type;
342330
if (type == ASContext.Context.Features.numberKey) return true;
@@ -352,10 +340,7 @@ static bool GetTargetIsNumber(MemberModel target)
352340
}
353341
}
354342

355-
static bool GetTargetIsString(MemberModel target)
356-
{
357-
return target.Type == ASContext.Context.Features.stringKey;
358-
}
343+
static bool IsString(MemberModel target) => target.Type == ASContext.Context.Features.stringKey;
359344

360345
static IEnumerable<ICompletionListItem> GetCompletionItems(string pattern, MemberModel target, ASResult expr)
361346
{
@@ -464,7 +449,6 @@ static void OnCharAdded(ScintillaControl sender, int value)
464449
}
465450
catch (Exception e)
466451
{
467-
Console.WriteLine(e);
468452
ErrorManager.ShowError(e);
469453
}
470454
}

0 commit comments

Comments
 (0)