diff --git a/External/Plugins/ASCompletion/ASCompletion.csproj b/External/Plugins/ASCompletion/ASCompletion.csproj
index cd662c73b4..65870bec44 100644
--- a/External/Plugins/ASCompletion/ASCompletion.csproj
+++ b/External/Plugins/ASCompletion/ASCompletion.csproj
@@ -150,6 +150,10 @@
PluginCore
False
+
+ {78101c01-e186-4954-b1dd-debb7905fad8}
+ ProjectManager
+
diff --git a/External/Plugins/ASCompletion/Helpers/ASTCache.cs b/External/Plugins/ASCompletion/Helpers/ASTCache.cs
index de9679faa4..790ef2a4af 100644
--- a/External/Plugins/ASCompletion/Helpers/ASTCache.cs
+++ b/External/Plugins/ASCompletion/Helpers/ASTCache.cs
@@ -1,6 +1,8 @@
using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
+using System.Threading;
using System.Windows.Forms;
using ASCompletion.Context;
using ASCompletion.Model;
@@ -16,12 +18,14 @@ internal class ASTCache
{
public event Action FinishedUpdate;
- Dictionary cache = new Dictionary(new ClassModelComparer());
- readonly List outdatedModels = new List();
+ Dictionary cache = new Dictionary(CacheHelper.classModelComparer);
+ readonly HashSet outdatedModels = new HashSet(CacheHelper.classModelComparer);
///
/// A list of ClassModels that extend / implement something that does not exist yet
///
- readonly HashSet unfinishedModels = new HashSet();
+ readonly HashSet unfinishedModels = new HashSet(CacheHelper.classModelComparer);
+
+ private int outdateUpdateCount;
public CachedClassModel GetCachedModel(ClassModel cls)
{
@@ -34,15 +38,18 @@ public void Clear()
{
lock (outdatedModels)
outdatedModels.Clear();
- lock (cache)
- cache.Clear();
+ lock (unfinishedModels)
+ unfinishedModels.Clear();
+ cache.Clear();
}
public void Remove(ClassModel cls)
{
lock (cache)
{
- var cachedClassModel = GetOrCreate(cache, cls);
+ var cachedClassModel = GetCachedModel(cls);
+
+ if (cachedClassModel == null) return;
var implementing = cachedClassModel.Implementing;
var overriding = cachedClassModel.Overriding;
@@ -71,72 +78,68 @@ public void Remove(ClassModel cls)
public void MarkAsOutdated(ClassModel cls)
{
lock (outdatedModels)
- if (!outdatedModels.Contains(cls))
- outdatedModels.Add(cls);
+ outdatedModels.Add(cls);
}
public void UpdateOutdatedModels()
{
- var action = new Action(() =>
+ var context = ASContext.GetLanguageContext(PluginBase.CurrentProject.Language);
+ if (context?.Classpath == null)
+ return;
+
+ HashSet outdated;
+ lock (outdatedModels)
{
- var context = ASContext.GetLanguageContext(PluginBase.CurrentProject.Language);
- if (context == null || context.Classpath == null)
- return;
+ outdated = new HashSet(outdatedModels, outdatedModels.Comparer);
+ outdatedModels.Clear();
+ }
- List outdated;
- lock (outdatedModels)
- {
- outdated = new List(outdatedModels);
- outdatedModels.Clear();
- }
-
- foreach (var cls in outdated)
- {
- cls.ResolveExtends();
+ var newModels = outdated.Any(m => GetCachedModel(m) == null);
- lock (cache)
- {
- //get the old CachedClassModel
- var cachedClassModel = GetCachedModel(cls);
- var connectedClasses = cachedClassModel?.ConnectedClassModels;
+ Interlocked.Increment(ref outdateUpdateCount);
+
+ foreach (var cls in outdated)
+ {
+ cls.ResolveExtends();
- //remove old cls
- Remove(cls);
+ lock (cache)
+ {
+ //get the old CachedClassModel
+ var cachedClassModel = GetCachedModel(cls);
+ var connectedClasses = cachedClassModel?.ConnectedClassModels;
- UpdateClass(cls, cache);
+ //remove old cls
+ Remove(cls);
- //also update all classes / interfaces that are connected to cls
- if (connectedClasses != null)
- foreach (var connection in connectedClasses)
- if (GetCachedModel(connection) != null) //only update existing connections, so a removed class is not reintroduced
- UpdateClass(connection, cache);
- }
+ UpdateClass(cls, cache);
+
+ //also update all classes / interfaces that are connected to cls
+ if (connectedClasses != null)
+ foreach (var connection in connectedClasses)
+ if (GetCachedModel(connection) != null) //only update existing connections, so a removed class is not reintroduced
+ UpdateClass(connection, cache);
}
+ }
+
+ //for new ClassModels, we need to update everything in the list of classes that extend / implement something that does not exist
+ if (newModels)
+ {
+ HashSet toUpdate;
+ lock (unfinishedModels)
+ toUpdate = new HashSet(unfinishedModels, unfinishedModels.Comparer);
- var newModels = outdated.Any(m => GetCachedModel(m) == null);
- //for new ClassModels, we need to update everything in the list of classes that extend / implement something that does not exist
- if (newModels)
+ foreach (var model in toUpdate)
{
- HashSet toUpdate;
lock (unfinishedModels)
- toUpdate = new HashSet(unfinishedModels);
-
- foreach (var model in toUpdate)
- {
- lock (unfinishedModels)
- unfinishedModels.Remove(model); //will be added back by UpdateClass if needed
+ unfinishedModels.Remove(model); //will be added back by UpdateClass if needed
- lock (cache)
- UpdateClass(model, cache);
- }
+ lock (cache)
+ UpdateClass(model, cache);
}
-
- if (FinishedUpdate != null)
- PluginBase.RunAsync(new MethodInvoker(FinishedUpdate));
-
- });
+ }
- action.BeginInvoke(null, null);
+ if (Interlocked.Decrement(ref outdateUpdateCount) == 0 && FinishedUpdate != null)
+ PluginBase.RunAsync(new MethodInvoker(FinishedUpdate));
}
///
@@ -144,38 +147,34 @@ public void UpdateOutdatedModels()
///
public void UpdateCompleteCache()
{
- var action = new Action(() =>
+ var context = ASContext.GetLanguageContext(PluginBase.CurrentProject.Language);
+ if (context?.Classpath == null || PathExplorer.IsWorking)
{
- var context = ASContext.GetLanguageContext(PluginBase.CurrentProject.Language);
- if (context == null || context.Classpath == null || PathExplorer.IsWorking)
- {
- if (FinishedUpdate != null)
- PluginBase.RunAsync(new MethodInvoker(FinishedUpdate));
- return;
- }
+ if (FinishedUpdate != null)
+ PluginBase.RunAsync(new MethodInvoker(FinishedUpdate));
+ return;
+ }
- var c = new Dictionary(cache.Comparer);
+ var c = new Dictionary(CacheHelper.classModelComparer);
- foreach (MemberModel memberModel in context.GetAllProjectClasses())
- {
- if (PluginBase.MainForm.ClosingEntirely)
- return; //make sure we leave if the form is closing, so we do not block it
+ foreach (MemberModel memberModel in context.GetAllProjectClasses())
+ {
+ if (PluginBase.MainForm.ClosingEntirely)
+ return; //make sure we leave if the form is closing, so we do not block it
- var cls = GetClassModel(memberModel);
- UpdateClass(cls, c);
- }
+ var cls = GetClassModel(memberModel);
+ UpdateClass(cls, c);
+ }
- lock(cache)
- cache = c;
- if (FinishedUpdate != null)
- PluginBase.RunAsync(new MethodInvoker(FinishedUpdate));
- });
- action.BeginInvoke(null, null);
+ lock (cache)
+ cache = c;
+ if (FinishedUpdate != null)
+ PluginBase.RunAsync(new MethodInvoker(FinishedUpdate));
}
internal HashSet ResolveInterfaces(ClassModel cls)
{
- if (cls == null || cls.IsVoid()) return new HashSet();
+ if (cls == null || cls.IsVoid()) return new HashSet(CacheHelper.classModelComparer);
if (cls.Implements == null) return ResolveInterfaces(cls.Extends);
var context = ASContext.GetLanguageContext(PluginBase.CurrentProject.Language);
@@ -189,7 +188,7 @@ internal HashSet ResolveInterfaces(ClassModel cls)
set.Add(interf);
return set;
})
- .Union(ResolveInterfaces(cls.Extends)).ToHashSet();
+ .Union(ResolveInterfaces(cls.Extends)).ToHashSet(CacheHelper.classModelComparer);
}
///
@@ -244,7 +243,7 @@ void RemoveConnections(ClassModel cls, CacheDictionary goThrough, Func
- void UpdateClass(ClassModel cls, Dictionary cache)
+ void UpdateClass(ClassModel cls, Dictionary classModelCache)
{
var context = ASContext.GetLanguageContext(PluginBase.CurrentProject.Language);
@@ -254,14 +253,14 @@ void UpdateClass(ClassModel cls, Dictionary cache)
return;
}
cls.ResolveExtends();
- var cachedClassModel = GetOrCreate(cache, cls);
+ var cachedClassModel = GetOrCreate(classModelCache, cls);
//look for functions / variables in cls that originate from interfaces of cls
var interfaces = ResolveInterfaces(cls);
foreach (var interf in interfaces)
{
- var cachedInterf = GetOrCreate(cache, interf);
+ var cachedInterf = GetOrCreate(classModelCache, interf);
cachedClassModel.ConnectedClassModels.Add(interf); //cachedClassModel is connected to interf.Key
cachedInterf.ConnectedClassModels.Add(cls); //the inverse is also true
@@ -277,12 +276,12 @@ void UpdateClass(ClassModel cls, Dictionary cache)
if (implementing.Count == 0) continue;
- cachedClassModel.Implementing.AddUnion(member, implementing.Keys);
+ cachedClassModel.Implementing.AddUnion(member, implementing.Keys, CacheHelper.classModelComparer);
//now that we know member is implementing the interfaces in implementing, we can add cls as implementor for them
foreach (var interf in implementing)
{
- var cachedModel = GetOrCreate(cache, interf.Key);
- var set = CacheHelper.GetOrCreateSet(cachedModel.Implementors, interf.Value);
+ var cachedModel = GetOrCreate(classModelCache, interf.Key);
+ var set = CacheHelper.GetOrCreateSet(cachedModel.Implementors, interf.Value, CacheHelper.classModelComparer);
set.Add(cls);
}
}
@@ -294,7 +293,7 @@ void UpdateClass(ClassModel cls, Dictionary cache)
var currentParent = cls.Extends;
while (currentParent != null && !currentParent.IsVoid())
{
- var cachedParent = GetOrCreate(cache, currentParent);
+ var cachedParent = GetOrCreate(classModelCache, currentParent);
cachedClassModel.ConnectedClassModels.Add(currentParent); //cachedClassModel is connected to currentParent
cachedParent.ConnectedClassModels.Add(cls); //the inverse is also true
@@ -310,12 +309,12 @@ void UpdateClass(ClassModel cls, Dictionary cache)
if (overridden == null || overridden.Count <= 0) continue;
- cachedClassModel.Overriding.AddUnion(member, overridden.Keys);
+ cachedClassModel.Overriding.AddUnion(member, overridden.Keys, CacheHelper.classModelComparer);
//now that we know member is overriding the classes in overridden, we can add cls as overrider for them
foreach (var over in overridden)
{
- var cachedModel = GetOrCreate(cache, over.Key);
- var set = CacheHelper.GetOrCreateSet(cachedModel.Overriders, over.Value);
+ var cachedModel = GetOrCreate(classModelCache, over.Key);
+ var set = CacheHelper.GetOrCreateSet(cachedModel.Overriders, over.Value, CacheHelper.classModelComparer);
set.Add(cls);
}
}
@@ -326,7 +325,7 @@ void UpdateClass(ClassModel cls, Dictionary cache)
lock (unfinishedModels)
unfinishedModels.Add(cls);
}
-
+
///
/// Gets all ClassModels from and the interfaces they extend that contain a definition of
///
@@ -335,7 +334,7 @@ internal Dictionary GetDefiningInterfaces(MemberModel m
{
//look for all ClassModels with variables / functions of the same name as member
//this could give faulty results if there are variables / functions of the same name with different signature in the interface
- var implementors = new Dictionary();
+ var implementors = new Dictionary(CacheHelper.classModelComparer);
foreach (var interf in interfaces)
{
@@ -357,7 +356,7 @@ internal Dictionary GetOverriddenClasses(ClassModel cls
if (cls.Extends == null || cls.Extends.IsVoid()) return null;
if ((function.Flags & FlagType.Function) == 0 || (function.Flags & FlagType.Override) == 0) return null;
- var parentFunctions = new Dictionary();
+ var parentFunctions = new Dictionary(CacheHelper.classModelComparer);
var currentParent = cls.Extends;
while (currentParent != null && !currentParent.IsVoid())
@@ -379,7 +378,7 @@ internal Dictionary GetOverriddenClasses(ClassModel cls
///
static HashSet ResolveExtends(ClassModel cls)
{
- var set = new HashSet();
+ var set = new HashSet(CacheHelper.classModelComparer);
var current = cls.Extends;
while (current != null && !current.IsVoid())
@@ -399,7 +398,7 @@ static CachedClassModel GetOrCreate(Dictionary cac
cached = new CachedClassModel();
cache.Add(cls, cached);
}
-
+
return cached;
}
@@ -416,29 +415,29 @@ static ClassModel GetClassModel(MemberModel cls)
class CachedClassModel
{
- public HashSet ConnectedClassModels = new HashSet();
+ public HashSet ConnectedClassModels = new HashSet(CacheHelper.classModelComparer);
///
/// A set of ClassModels that extend this ClassModel
///
- public HashSet ChildClassModels = new HashSet();
+ public HashSet ChildClassModels = new HashSet(CacheHelper.classModelComparer);
///
/// If this ClassModel is an interface, this contains a set of classes that implement this interface
///
- public HashSet ImplementorClassModels = new HashSet();
+ public HashSet ImplementorClassModels = new HashSet(CacheHelper.classModelComparer);
///
/// If this ClassModel is an interface, this contains a set of classes - for each member - that implement the given members
///
public CacheDictionary Implementors = new CacheDictionary();
-
+
///
/// Contains a set of interfaces - for each member - that contain the member.
///
public CacheDictionary Implementing = new CacheDictionary();
-
+
///
/// Contains a set of classes - for each member - that override the member.
///
@@ -452,26 +451,28 @@ class CachedClassModel
static class CacheHelper
{
- internal static HashSet ToHashSet(this IEnumerable e)
+ internal static ClassModelComparer classModelComparer = new ClassModelComparer();
+
+ internal static HashSet ToHashSet(this IEnumerable e, IEqualityComparer comparer)
{
- if (e == null) return new HashSet();
+ if (e == null) return new HashSet(comparer);
- return new HashSet(e);
+ return new HashSet(e, comparer);
}
- internal static void AddUnion(this Dictionary> dict, S key, IEnumerable value)
+ internal static void AddUnion(this Dictionary> dict, S key, IEnumerable value, IEqualityComparer comparer)
{
- var set = GetOrCreateSet(dict, key);
+ var set = GetOrCreateSet(dict, key, comparer);
set.UnionWith(value);
}
- internal static ISet GetOrCreateSet(Dictionary> dict, S key)
+ internal static ISet GetOrCreateSet(Dictionary> dict, S key, IEqualityComparer comparer)
{
HashSet set;
if (!dict.TryGetValue(key, out set))
{
- set = new HashSet(); //TODO: maybe supply new ClassModelComparer()
+ set = new HashSet(comparer);
dict.Add(key, set);
}
return set;
@@ -484,9 +485,12 @@ public bool Equals(ClassModel x, ClassModel y)
{
if (x == null || y == null) return x == y;
- return x.Type == y.Type;
+ return x.Type == y.Type && x.InFile?.FileName == y.InFile?.FileName;
}
- public int GetHashCode(ClassModel obj) => obj.BaseType.GetHashCode();
+ public int GetHashCode(ClassModel obj) =>
+ !string.IsNullOrEmpty(obj.InFile?.FileName)
+ ? obj.InFile.FileName.GetHashCode() ^ obj.BaseType.GetHashCode()
+ : obj.BaseType.GetHashCode();
}
}
diff --git a/External/Plugins/ASCompletion/PluginMain.cs b/External/Plugins/ASCompletion/PluginMain.cs
index cb580cbce4..8247cf72b0 100644
--- a/External/Plugins/ASCompletion/PluginMain.cs
+++ b/External/Plugins/ASCompletion/PluginMain.cs
@@ -8,6 +8,7 @@
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
+using System.Threading;
using System.Timers;
using System.Windows.Forms;
using ASCompletion.Commands;
@@ -23,13 +24,14 @@
using PluginCore.Localization;
using PluginCore.Managers;
using PluginCore.Utilities;
+using ProjectManager.Projects;
using ScintillaNet;
using WeifenLuo.WinFormsUI.Docking;
using Timer = System.Timers.Timer;
namespace ASCompletion
{
- public class PluginMain: IPlugin
+ public class PluginMain : IPlugin
{
private string pluginName = "ASCompletion";
private string pluginGuid = "078c7c1a-c667-4f54-9e47-d45c0e835c4e";
@@ -81,7 +83,8 @@ public class PluginMain: IPlugin
Bitmap upDownArrow;
readonly ASTCache astCache = new ASTCache();
- bool initializedCache = true;
+ bool initializedCache;
+ bool cacheNeedsRecheck;
IProject lastProject;
Timer astCacheTimer;
@@ -157,7 +160,7 @@ public virtual void Initialize()
ASContext.GlobalInit(this);
ModelsExplorer.CreatePanel();
}
- catch(Exception ex)
+ catch (Exception ex)
{
ErrorManager.ShowError(/*"Failed to initialize the completion engine.\n"+ex.Message,*/ ex);
}
@@ -276,6 +279,8 @@ public void HandleEvent(Object sender, NotifyEvent e, HandlingPriority priority)
astCache.Clear();
foreach (var document in PluginBase.MainForm.Documents)
{
+ if (!document.IsEditable) continue;
+
//remove the markers
UpdateMarkersFromCache(document.SplitSci1);
UpdateMarkersFromCache(document.SplitSci2);
@@ -338,7 +343,7 @@ public void HandleEvent(Object sender, NotifyEvent e, HandlingPriority priority)
if (info != null && info.ContainsKey("language"))
{
IASContext context = ASContext.GetLanguageContext(info["language"] as string);
- if (context != null && context.Settings != null
+ if (context != null && context.Settings != null
&& context.Settings.UserClasspath != null)
info["cp"] = new List(context.Settings.UserClasspath);
}
@@ -385,7 +390,7 @@ public void HandleEvent(Object sender, NotifyEvent e, HandlingPriority priority)
{
case "AS2": name = "AS2Context"; break;
case "AS3": name = "AS3Context"; break;
- default:
+ default:
name = cmdData.Substring(0, 1).ToUpper() + cmdData.Substring(1) + "Context";
break;
}
@@ -482,16 +487,31 @@ public void HandleEvent(Object sender, NotifyEvent e, HandlingPriority priority)
{
if (lastProject != PluginBase.CurrentProject)
{
+ if (lastProject is Project)
+ ((Project) lastProject).ClasspathChanged -= Project_ClassPathChanged;
lastProject = PluginBase.CurrentProject;
+ if (lastProject is Project)
+ ((Project) lastProject).ClasspathChanged += Project_ClassPathChanged;
initializedCache = false;
+ astCacheTimer.Stop();
+ astCache.Clear();
+ foreach (var document in PluginBase.MainForm.Documents)
+ {
+ if (!document.IsEditable) continue;
+
+ //remove the markers
+ ClearMarkersFromCache(document.SplitSci1);
+ ClearMarkersFromCache(document.SplitSci2);
+ }
+ }
+ else if (command == "ProjectManager.Menu")
+ {
+ var image = PluginBase.MainForm.FindImage("202");
+ var item = new ToolStripMenuItem(TextHelper.GetString("Label.TypesExplorer"), image,
+ TypesExplorer, Keys.Control | Keys.J);
+ PluginBase.MainForm.RegisterShortcutItem("FlashToolsMenu.TypeExplorer", item);
+ ((ToolStripMenuItem) de.Data).DropDownItems.Insert(6, item);
}
- }
- else if (command == "ProjectManager.Menu")
- {
- var image = PluginBase.MainForm.FindImage("202");
- var item = new ToolStripMenuItem(TextHelper.GetString("Label.TypesExplorer"), image, TypesExplorer, Keys.Control | Keys.J);
- PluginBase.MainForm.RegisterShortcutItem("FlashToolsMenu.TypeExplorer", item);
- ((ToolStripMenuItem)de.Data).DropDownItems.Insert(6, item);
}
break;
}
@@ -504,7 +524,7 @@ public void HandleEvent(Object sender, NotifyEvent e, HandlingPriority priority)
switch (e.Type)
{
case EventType.ProcessArgs:
- TextEvent te = (TextEvent) e;
+ TextEvent te = (TextEvent)e;
if (reArgs.IsMatch(te.Value))
{
// resolve current element
@@ -607,7 +627,7 @@ public void HandleEvent(Object sender, NotifyEvent e, HandlingPriority priority)
}
}
}
- catch(Exception ex)
+ catch (Exception ex)
{
ErrorManager.ShowError(ex);
}
@@ -835,18 +855,17 @@ private void AddEventHandlers()
// application events
EventManager.AddEventHandler(this, eventMask);
EventManager.AddEventHandler(this, EventType.UIStarted, HandlingPriority.Low);
-
+
// cursor position changes tracking
timerPosition = new Timer();
timerPosition.SynchronizingObject = PluginBase.MainForm as Form;
timerPosition.Interval = 200;
- timerPosition.Elapsed += new ElapsedEventHandler(timerPosition_Elapsed);
+ timerPosition.Elapsed += TimerPosition_Elapsed;
//Cache update
astCache.FinishedUpdate += UpdateOpenDocumentMarkers;
astCacheTimer = new Timer
{
- SynchronizingObject = PluginBase.MainForm as Form,
AutoReset = false,
Enabled = false
};
@@ -861,7 +880,7 @@ void UpdateCompleteCache()
{
if (PluginBase.CurrentProject == null) return;
- astCache.UpdateCompleteCache();
+ ThreadPool.QueueUserWorkItem(s => astCache.UpdateCompleteCache());
}
void UpdateOpenDocumentMarkers()
@@ -878,7 +897,7 @@ void UpdateOpenDocumentMarkers()
void ApplyMarkers(ScintillaControl sci)
{
if (settingObject.DisableInheritanceNavigation || sci == null) return;
-
+
//Register marker
sci.MarkerDefineRGBAImage(MarkerDown, downArrow);
sci.MarkerDefineRGBAImage(MarkerUp, upArrow);
@@ -894,18 +913,24 @@ void ApplyMarkers(ScintillaControl sci)
UpdateMarkersFromCache(sci);
}
- void UpdateMarkersFromCache(ScintillaControl sci)
+ void ClearMarkersFromCache(ScintillaControl sci)
{
- var marginWidth = 16;
sci.SetMarginWidthN(Margin, 0); //margin is only made visible if something is found
sci.MarkerDeleteAll(MarkerUp);
sci.MarkerDeleteAll(MarkerDown);
sci.MarkerDeleteAll(MarkerUpDown);
+ }
+
+ void UpdateMarkersFromCache(ScintillaControl sci)
+ {
+ ClearMarkersFromCache(sci);
if (settingObject.DisableInheritanceNavigation) return;
if (PluginBase.CurrentProject == null) return;
+
+ const int marginWidth = 16;
var context = ASContext.GetLanguageContext(PluginBase.CurrentProject.Language) as ASContext;
if (context == null) return;
@@ -1081,37 +1106,51 @@ private void SetItemsEnabled(bool enabled, bool canBuild)
void OnFileRemove(FileModel obj)
{
- PluginBase.RunAsync(() =>
+ ThreadPool.QueueUserWorkItem(s =>
{
-
- foreach (var cls in obj.Classes)
+ try
{
- var cached = astCache.GetCachedModel(cls);
- astCache.Remove(cls);
- if (cached != null)
- foreach (var c in cached.ConnectedClassModels) //need to update all connected stuff
- astCache.MarkAsOutdated(c);
- }
+ astCacheTimer.Stop();
- astCacheTimer.Stop();
- astCacheTimer.Start();
-
- var sci1 = DocumentManager.FindDocument(obj.FileName)?.SplitSci1;
- var sci2 = DocumentManager.FindDocument(obj.FileName)?.SplitSci2;
+ foreach (var cls in obj.Classes)
+ {
+ var cached = astCache.GetCachedModel(cls);
+ astCache.Remove(cls);
+ if (cached != null)
+ foreach (var c in cached.ConnectedClassModels) //need to update all connected stuff
+ astCache.MarkAsOutdated(c);
+ }
- if (sci1 != null)
- {
- sci1.MarkerDeleteAll(MarkerUp);
- sci1.MarkerDeleteAll(MarkerDown);
- sci1.MarkerDeleteAll(MarkerUpDown);
+ if (initializedCache) astCacheTimer.Start();
}
- if (sci2 != null)
+ catch
{
- sci2.MarkerDeleteAll(MarkerUp);
- sci2.MarkerDeleteAll(MarkerDown);
- sci2.MarkerDeleteAll(MarkerUpDown);
+ //TODO: Look into Timer problem
}
+ PluginBase.RunAsync(() =>
+ {
+ var doc = DocumentManager.FindDocument(obj.FileName);
+ if (doc != null)
+ {
+ var sci1 = doc.SplitSci1;
+ var sci2 = doc.SplitSci2;
+
+ if (sci1 != null)
+ {
+ sci1.MarkerDeleteAll(MarkerUp);
+ sci1.MarkerDeleteAll(MarkerDown);
+ sci1.MarkerDeleteAll(MarkerUpDown);
+ }
+ if (sci2 != null)
+ {
+ sci2.MarkerDeleteAll(MarkerUp);
+ sci2.MarkerDeleteAll(MarkerDown);
+ sci2.MarkerDeleteAll(MarkerUpDown);
+ }
+ }
+ });
+
EventManager.DispatchEvent(this, new DataEvent(EventType.Command, "ASCompletion.FileModelUpdated", obj));
});
}
@@ -1122,17 +1161,25 @@ void OnFileRemove(FileModel obj)
///
void OnFileUpdate(FileModel obj)
{
- PluginBase.RunAsync(() =>
+ ThreadPool.QueueUserWorkItem(s =>
{
if (PluginBase.CurrentProject == null) return;
- foreach (var cls in obj.Classes)
+ try
{
- astCache.MarkAsOutdated(cls);
- }
+ astCacheTimer.Stop();
- astCacheTimer.Stop();
- astCacheTimer.Start();
+ foreach (var cls in obj.Classes)
+ {
+ astCache.MarkAsOutdated(cls);
+ }
+
+ if (initializedCache) astCacheTimer.Start();
+ }
+ catch
+ {
+ //TODO: Possible multi-threaded problem with timer
+ }
EventManager.DispatchEvent(this, new DataEvent(EventType.Command, "ASCompletion.FileModelUpdated", obj));
});
@@ -1140,7 +1187,27 @@ void OnFileUpdate(FileModel obj)
void AstCacheTimer_Elapsed(object sender, ElapsedEventArgs e)
{
- astCache.UpdateOutdatedModels();
+ try
+ {
+ astCache.UpdateOutdatedModels();
+ }
+ catch
+ {
+ //TODO: Handle some inner cases more properly
+ }
+ }
+
+ void Project_ClassPathChanged(Project project)
+ {
+ try
+ {
+ astCacheTimer.Stop();
+ if (initializedCache) astCacheTimer.Start();
+ }
+ catch
+ {
+ //TODO: Potential timer problem
+ }
}
void Sci_MarginClick(ScintillaControl sender, int modifiers, int position, int margin)
@@ -1156,12 +1223,11 @@ void Sci_MarginClick(ScintillaControl sender, int modifiers, int position, int m
if (cached == null) return;
-
if (declaration.InClass.LineFrom == line)
{
ReferenceList.Show(
ReferenceList.ConvertClassCache(cached.ImplementorClassModels).ToList(),
- new List(0),
+ new List(0),
ReferenceList.ConvertClassCache(cached.ChildClassModels).ToList(),
new List(0)
);
@@ -1257,7 +1323,7 @@ private void OnTextChanged(ScintillaControl sender, int position, int length, in
sender.MarkerDelete(i, MarkerUpDown);
}
}
-
+
}
private void OnUpdateCallTip(ScintillaControl sci, int position)
@@ -1278,7 +1344,7 @@ private void OnUpdateSimpleTip(ScintillaControl sci, Point mousePosition)
OnMouseHover(sci, lastHoverPosition);
}
- void timerPosition_Elapsed(object sender, ElapsedEventArgs e)
+ void TimerPosition_Elapsed(object sender, ElapsedEventArgs e)
{
ScintillaControl sci = ASContext.CurSciControl;
if (sci == null) return;
@@ -1309,7 +1375,7 @@ private void ContextChanged()
if (isValid) ASComplete.ResolveContext(sci);
}
else ASComplete.ResolveContext(null);
-
+
bool enableItems = isValid && !doc.IsUntitled;
pluginUI.OutlineTree.Enabled = ASContext.Context.CurrentModel != null;
SetItemsEnabled(enableItems, ASContext.Context.CanBuild);
diff --git a/External/Plugins/HaXeContext/ExternalToolchain.cs b/External/Plugins/HaXeContext/ExternalToolchain.cs
index 284ae53a2f..fba906a799 100644
--- a/External/Plugins/HaXeContext/ExternalToolchain.cs
+++ b/External/Plugins/HaXeContext/ExternalToolchain.cs
@@ -246,9 +246,7 @@ private static void UpdateProject()
var form = PluginBase.MainForm as System.Windows.Forms.Form;
if (form.InvokeRequired)
{
- form.BeginInvoke((System.Windows.Forms.MethodInvoker)delegate {
- UpdateProject();
- });
+ form.BeginInvoke((Action)UpdateProject);
return;
}
@@ -259,14 +257,11 @@ private static void UpdateProject()
string args = GetCommand(hxproj, "display");
if (args == null)
{
- var msg = String.Format("No external 'display' command found for platform '{0}'", hxproj.MovieOptions.Platform);
+ var msg = $"No external 'display' command found for platform '{hxproj.MovieOptions.Platform}'";
TraceManager.Add(msg, -3);
return;
}
- string config = hxproj.TargetBuild;
- if (String.IsNullOrEmpty(config)) config = "flash";
-
ProcessStartInfo pi = new ProcessStartInfo();
pi.FileName = Environment.ExpandEnvironmentVariables(exe);
pi.Arguments = args;
@@ -303,7 +298,7 @@ private static void UpdateProject()
args = GetCommand(hxproj, "build", false);
if (args == null)
{
- var msg = String.Format("No external 'build' command found for platform '{0}'", hxproj.MovieOptions.Platform);
+ var msg = $"No external 'build' command found for platform '{hxproj.MovieOptions.Platform}'";
TraceManager.Add(msg, -3);
}
else if (string.IsNullOrEmpty(hxproj.PreBuildEvent))
@@ -381,8 +376,8 @@ static string GetCommand(HaxeProject project, string name, bool processArguments
var version = platform.GetVersion(project.MovieOptions.Version);
if (version.Commands == null)
{
- throw new Exception(String.Format("No external commands found for target {0} and version {1}",
- project.MovieOptions.Platform, project.MovieOptions.Version));
+ throw new Exception(
+ $"No external commands found for target {project.MovieOptions.Platform} and version {project.MovieOptions.Version}");
}
if (version.Commands.ContainsKey(name))
{
diff --git a/External/Plugins/HaXeContext/Linters/DiagnosticsLinter.cs b/External/Plugins/HaXeContext/Linters/DiagnosticsLinter.cs
index 512e7179b2..6eb063e90f 100644
--- a/External/Plugins/HaXeContext/Linters/DiagnosticsLinter.cs
+++ b/External/Plugins/HaXeContext/Linters/DiagnosticsLinter.cs
@@ -108,6 +108,8 @@ void AddDiagnosticsResults(List list, HaxeCompleteStatus status,
{
var range = res.Range ?? res.Args.Range;
+ if (range == null) continue;
+
var result = new LintingResult
{
File = range.Path,