diff options
Diffstat (limited to 'Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs')
| -rw-r--r-- | Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs | 330 |
1 files changed, 259 insertions, 71 deletions
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs index a4493d2c4..29af14ddc 100644 --- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs @@ -59,10 +59,14 @@ namespace Tango.Scripting.Editors private static Dictionary<Type, KnownType> _knownTypesCache; private static String KNOWN_TYPES_CACHE_FOLDER; private static List<CachedAssembly> _cachedAssemblies; + private static List<CachedUsing> _cachedUsings; private static bool _isLoadingCachedAssemblies; private static bool _isCacheAssembliesLoaded; + private static object _loadUsingsLock = new object(); - public static event EventHandler<TangoProgressChangedEventArgs<int>> AssemblyCacheProgress; + public static event EventHandler<TangoProgressChangedEventArgs<int>> LoadingSymbolsProgress; + public static event EventHandler LoadingSymbolsStarted; + public static event EventHandler LoadingSymbolsCompleted; #region Mini Classes @@ -96,6 +100,8 @@ namespace Tango.Scripting.Editors #region Properties + public static List<String> BlockedUsingsCache { get; set; } + /// <summary> /// Gets or sets a value indicating whether to enable folding. /// </summary> @@ -164,6 +170,8 @@ namespace Tango.Scripting.Editors { DefaultStyleKeyProperty.OverrideMetadata(typeof(ScriptEditor), new FrameworkPropertyMetadata(typeof(ScriptEditor))); + BlockedUsingsCache = new List<string>(); + if (KNOWN_TYPES_CACHE_FOLDER == null) { KNOWN_TYPES_CACHE_FOLDER = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Twine", "Tango", "Scripting", "Cache"); @@ -178,6 +186,7 @@ namespace Tango.Scripting.Editors _knownTypesCache = new Dictionary<Type, KnownType>(); _cachedAssemblies = new List<CachedAssembly>(); + _cachedUsings = new List<CachedUsing>(); } /// <summary> @@ -458,7 +467,17 @@ namespace Tango.Scripting.Editors }); } - foreach (var methodGroup in typeMembers.Where(x => x.GetType() != typeof(KnownTypeMethod)).GroupBy(x => x.Name)) + foreach (var ev in typeMembers.OfType<KnownTypeEvent>()) + { + data.Add(new EventCompletionItem() + { + Class = knownType.FriendlyName, + Name = ev.Name, + Description = ev.Summary, + }); + } + + foreach (var methodGroup in typeMembers.Where(x => x.GetType() != typeof(KnownTypeMethod) && x.GetType() != typeof(KnownTypeEvent)).GroupBy(x => x.Name)) { var member = methodGroup.First(); @@ -469,7 +488,6 @@ namespace Tango.Scripting.Editors Type = member.ReturnTypeFriendlyName, Description = member.Summary, }); - } } else @@ -558,7 +576,7 @@ namespace Tango.Scripting.Editors { //Maybe static ... var typeText = GetPreviousWord(); - knownType = _knownTypes.FirstOrDefault(x => x.FriendlyName == typeText); + knownType = _knownTypes.FirstOrDefault(x => x.FriendlyName == typeText || x.Alias == typeText); if (knownType != null) { @@ -902,7 +920,7 @@ namespace Tango.Scripting.Editors IList<ICompletionData> data = completionWindow.CompletionList.CompletionData; data.Clear(); - foreach (var item in suggestions) + foreach (var item in suggestions.DistinctBy(x => x.Text)) { data.Add(item); } @@ -984,6 +1002,13 @@ namespace Tango.Scripting.Editors { if (expression != null) { + var insideMethodExp = expression.Split('(').LastOrDefault(); + + if (insideMethodExp != null) + { + expression = insideMethodExp; + } + var tree = expression.Split('.').Select(x => x.Remove(@"\n|\t|\r|\(.*\)|\[.*\]|\s")).ToList(); var variableName = tree.FirstOrDefault(); @@ -1003,7 +1028,8 @@ namespace Tango.Scripting.Editors if (variable != null) { - var knownType = _knownTypes.FirstOrDefault(x => x.FriendlyName == Regex.Replace(variable.Type, "<.+>", "<T>")); + var name = Regex.Replace(variable.Type, "<.+>", "<T>"); + var knownType = _knownTypes.FirstOrDefault(x => name == x.FriendlyName || name == x.Alias); if (knownType != null) { @@ -1036,6 +1062,13 @@ namespace Tango.Scripting.Editors if (expression != null) { + var insideMethodExp = expression.Split('(').LastOrDefault(); + + if (insideMethodExp != null) + { + expression = insideMethodExp; + } + var tree = expression.Split('.').Select(x => x.Remove(@"\n|\t|\r|\(.*\)|\[.*\]|\s")).ToList(); var variableName = tree.FirstOrDefault(); @@ -1250,83 +1283,223 @@ namespace Tango.Scripting.Editors return popup; } - public static void LoadCachedAssemblies(List<Assembly> assemblies) + public static void LoadUsingsSymbols(List<Assembly> assemblies, List<String> usings) { - if (_isLoadingCachedAssemblies) return; + lock (_loadUsingsLock) + { + LoadingSymbolsStarted?.Invoke(null, new EventArgs()); - _isLoadingCachedAssemblies = true; + var allTypes = assemblies.SelectMany(x => x.GetTypes()); - if (!_isCacheAssembliesLoaded) - { - foreach (var file in System.IO.Directory.GetFiles(KNOWN_TYPES_CACHE_FOLDER)) + foreach (var use in usings) { - try + if (!_cachedUsings.Exists(x => x.Namespace == use)) { - AssemblyCacheProgress?.Invoke(null, new TangoProgressChangedEventArgs<int>() + var useFileName = System.IO.Path.Combine(KNOWN_TYPES_CACHE_FOLDER, use + ".json"); + + if (File.Exists(useFileName)) { - Progress = new TangoProgress<int>() + LoadingSymbolsProgress?.Invoke(null, new TangoProgressChangedEventArgs<int>() + { + Progress = new TangoProgress<int>() + { + IsIndeterminate = true, + Maximum = 100, + Message = $"Loading symbols for '{use}'..." + } + }); + + CachedUsing cached = JsonConvert.DeserializeObject<CachedUsing>(File.ReadAllText(useFileName), _jsonSettings); + _cachedUsings.Add(cached); + foreach (var knownType in cached.KnownTypes) { - IsIndeterminate = true, - Maximum = 100, - Message = $"Loading metadata cache for '{System.IO.Path.GetFileName(file)}'..." + _knownTypesCache.Add(knownType.Type, knownType); } - }); - var cachedAssembly = JsonConvert.DeserializeObject<CachedAssembly>(System.IO.File.ReadAllText(file), _jsonSettings); + continue; + } + + var useTypes = allTypes.Where(x => x.IsVisible && x.IsPublic && x.Namespace == use).ToList(); - foreach (var knownType in cachedAssembly.KnownTypes) + CachedUsing cachedUsing = new CachedUsing(); + cachedUsing.Namespace = use; + _cachedUsings.Add(cachedUsing); + + int i = 1; + + foreach (var type in useTypes) { - _knownTypesCache.Add(knownType.Type, knownType); + LoadingSymbolsProgress?.Invoke(null, new TangoProgressChangedEventArgs<int>() + { + Progress = new TangoProgress<int>() + { + IsIndeterminate = false, + Maximum = useTypes.Count, + Value = i++, + Message = $"Loading symbols for '{use}'..." + } + }); + + KnownType knownType = new KnownType(type); + + if (type.IsPrimitive) + { + if (type == typeof(Int32)) + { + knownType.Alias = "int"; + } + else if (type == typeof(float)) + { + knownType.Alias = "float"; + } + else if (type == typeof(Double)) + { + knownType.Alias = "double"; + } + else if (type == typeof(long)) + { + knownType.Alias = "long"; + } + else if (type == typeof(bool)) + { + knownType.Alias = "bool"; + } + else if (type == typeof(uint)) + { + knownType.Alias = "uint"; + } + } + + _knownTypesCache.Add(type, knownType); + cachedUsing.KnownTypes.Add(knownType); + knownType.LoadDocumentation(); } - _cachedAssemblies.Add(cachedAssembly); + if (!BlockedUsingsCache.Exists(x => x == use)) + { + Task.Factory.StartNew(() => + { + var json = JsonConvert.SerializeObject(cachedUsing, _jsonSettings); + File.WriteAllText(useFileName, json); + }); + } } - catch { } } - _isCacheAssembliesLoaded = true; + LoadingSymbolsCompleted?.Invoke(null, new EventArgs()); } + } - foreach (var asm in assemblies) - { - if (!_cachedAssemblies.Exists(x => x.Name == asm.FullName)) - { - String asmFileName = System.IO.Path.GetFileName(asm.Location); + //public static void LoadCachedAssemblies(List<Assembly> assemblies, List<String> usings = null) + //{ + // if (_isLoadingCachedAssemblies) return; - CachedAssembly cachedAssembly = new CachedAssembly(); - cachedAssembly.Name = asm.FullName; - _cachedAssemblies.Add(cachedAssembly); + // _isLoadingCachedAssemblies = true; - var types = asm.GetTypes().Where(x => x.IsVisible && x.IsPublic && !x.IsPrimitive).ToList(); + // LoadingSymbolsStarted?.Invoke(null, new EventArgs()); - int i = 0; + // if (!_isCacheAssembliesLoaded) + // { + // foreach (var file in System.IO.Directory.GetFiles(KNOWN_TYPES_CACHE_FOLDER)) + // { + // try + // { + // LoadingSymbolsProgress?.Invoke(null, new TangoProgressChangedEventArgs<int>() + // { + // Progress = new TangoProgress<int>() + // { + // IsIndeterminate = true, + // Maximum = 100, + // Message = $"Loading metadata cache for '{System.IO.Path.GetFileName(file)}'..." + // } + // }); - foreach (var type in types) - { - AssemblyCacheProgress?.Invoke(null, new TangoProgressChangedEventArgs<int>() - { - Progress = new TangoProgress<int>() - { - IsIndeterminate = false, - Maximum = types.Count, - Value = i++, - Message = $"Caching metadata for '{asmFileName}'..." - } - }); + // var cachedAssembly = JsonConvert.DeserializeObject<CachedAssembly>(System.IO.File.ReadAllText(file), _jsonSettings); - KnownType knownType = new KnownType(type); - _knownTypesCache.Add(type, knownType); - cachedAssembly.KnownTypes.Add(knownType); - knownType.LoadDocumentation(); - } + // foreach (var knownType in cachedAssembly.KnownTypes) + // { + // _knownTypesCache.Add(knownType.Type, knownType); + // } - String cachedAssemblyFile = System.IO.Path.Combine(KNOWN_TYPES_CACHE_FOLDER, asmFileName); - File.WriteAllText(cachedAssemblyFile, JsonConvert.SerializeObject(cachedAssembly, _jsonSettings)); - } - } + // _cachedAssemblies.Add(cachedAssembly); + // } + // catch { } + // } - _isLoadingCachedAssemblies = false; - } + // _isCacheAssembliesLoaded = true; + // } + + // foreach (var asm in assemblies) + // { + // if (!_cachedAssemblies.Exists(x => x.Name == asm.FullName)) + // { + // String asmFileName = System.IO.Path.GetFileName(asm.Location); + + // CachedAssembly cachedAssembly = new CachedAssembly(); + // cachedAssembly.Name = asm.FullName; + // _cachedAssemblies.Add(cachedAssembly); + + // var types = asm.GetTypes().Where(x => x.IsVisible && x.IsPublic).ToList(); + + // int i = 0; + + // foreach (var type in types) + // { + // LoadingSymbolsProgress?.Invoke(null, new TangoProgressChangedEventArgs<int>() + // { + // Progress = new TangoProgress<int>() + // { + // IsIndeterminate = false, + // Maximum = types.Count, + // Value = i++, + // Message = $"Caching metadata for '{asmFileName}'..." + // } + // }); + + // KnownType knownType = new KnownType(type); + + // if (type.IsPrimitive) + // { + // if (type == typeof(Int32)) + // { + // knownType.Alias = "int"; + // } + // else if (type == typeof(float)) + // { + // knownType.Alias = "float"; + // } + // else if (type == typeof(Double)) + // { + // knownType.Alias = "double"; + // } + // else if (type == typeof(long)) + // { + // knownType.Alias = "long"; + // } + // else if (type == typeof(bool)) + // { + // knownType.Alias = "bool"; + // } + // else if (type == typeof(uint)) + // { + // knownType.Alias = "uint"; + // } + // } + + // _knownTypesCache.Add(type, knownType); + // cachedAssembly.KnownTypes.Add(knownType); + // //knownType.LoadDocumentation(); + // } + + // String cachedAssemblyFile = System.IO.Path.Combine(KNOWN_TYPES_CACHE_FOLDER, asmFileName); + // File.WriteAllText(cachedAssemblyFile, JsonConvert.SerializeObject(cachedAssembly, _jsonSettings)); + // } + // } + + // LoadingSymbolsCompleted?.Invoke(null, new EventArgs()); + + // _isLoadingCachedAssemblies = false; + //} private void InvalidateHighlighting(bool loadKnownTypes = true) { @@ -1339,22 +1512,19 @@ namespace Tango.Scripting.Editors Thread t = new Thread(() => { - LoadCachedAssemblies(assemblies); + LoadUsingsSymbols(assemblies, usings); if (loadKnownTypes) { _knownTypes.Clear(); - foreach (var asm in assemblies) + foreach (var knownType in _knownTypesCache.ToList().Select(x => x.Value).ToList()) { - foreach (var knownType in _knownTypesCache.ToList().Select(x => x.Value).ToList()) + if (usings.Exists(x => knownType.Type.Namespace == x)) { - if (usings.Exists(x => knownType.Type.Namespace == x)) + lock (_knownTypes) { - lock (_knownTypes) - { - _knownTypes.Add(knownType); - } + _knownTypes.Add(knownType); } } } @@ -1589,7 +1759,11 @@ namespace Tango.Scripting.Editors private ConstructionSession GetConstructionSession() { - var expression = _parser.GetCurrentConstructionExpression(GetCurrentLineText()); + var currentLine = GetCurrentLineText(); + + //if (currentLine.Count(x => x == '(') > 1) return null; + + var expression = _parser.GetCurrentConstructionExpression(currentLine); if (expression != null) { @@ -1693,7 +1867,14 @@ namespace Tango.Scripting.Editors private MethodSession GetMethodSession() { - var words = GetCurrentLineText().Split(' '); + var currentLine = GetCurrentLineText(); + + if (currentLine.Count(x => x == '(') > 1) + { + currentLine = currentLine.Split('(')[currentLine.Split('(').Length - 2]; + } + + var words = currentLine.Split(' '); if (words.Count() > 0 && (words.First() == "private" || words.First() == "public" || words.First() == "void")) { @@ -1811,14 +1992,21 @@ namespace Tango.Scripting.Editors private DeclaredMethodSession GetDeclaredMethodSession() { - var words = GetCurrentLineText().Split(' '); + var currentLine = GetCurrentLineText(); + + if (currentLine.Count(x => x == '(') > 1) + { + currentLine = currentLine.Split('(')[currentLine.Split('(').Length - 2]; + } + + var words = currentLine.Split(' '); if (words.Count() > 0 && (words.First() == "private" || words.First() == "public" || words.First() == "void")) { return null; } - var expression = GetPreviousWords().LastOrDefault(); + var expression = currentLine; if (expression != null) { @@ -1833,7 +2021,7 @@ namespace Tango.Scripting.Editors if (variable != null) { - var declaredType = _declaredTypes.FirstOrDefault(x => x.Name == Regex.Replace(variable.Class, "<.+>", "<T>")); + var declaredType = _declaredTypes.FirstOrDefault(x => x.Name == Regex.Replace(variable.Type, "<.+>", "<T>")); if (declaredType != null) { |
