aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs
diff options
context:
space:
mode:
authorVictoria Plitt <Victoria.Plitt@twine-s.com>2020-04-26 08:34:14 +0200
committerVictoria Plitt <Victoria.Plitt@twine-s.com>2020-04-26 08:34:14 +0200
commit9038c50a3a350312c9895240be28b4fb90fbe3b1 (patch)
treecbc8824844340d8eff76f57455fcea8e7a9d6cd6 /Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs
parentccaf9afcde7a630a7d765fa9874322b5f44e2df7 (diff)
parent8438e5447b6bed6ed97f2e3fda6977ce4bf74d0c (diff)
downloadTango-9038c50a3a350312c9895240be28b4fb90fbe3b1.tar.gz
Tango-9038c50a3a350312c9895240be28b4fb90fbe3b1.zip
Merge branch 'master' of https://twinetfs.visualstudio.com/Tango/_git/Tango
Diffstat (limited to 'Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs')
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs576
1 files changed, 539 insertions, 37 deletions
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs
index d06862cef..d1ea9de43 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs
@@ -1,5 +1,6 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@@ -23,7 +24,9 @@ using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Xml;
+using Tango.Core;
using Tango.Core.Commands;
+using Tango.Scripting.Core;
using Tango.Scripting.Editors.CodeCompletion;
using Tango.Scripting.Editors.Document;
using Tango.Scripting.Editors.Editing;
@@ -52,6 +55,18 @@ namespace Tango.Scripting.Editors
private List<KnownType> _knownTypes;
private List<ScriptType> _declaredTypes;
private bool _isLoadingTypes;
+ private static JsonSerializerSettings _jsonSettings;
+ 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>> LoadingSymbolsProgress;
+ public static event EventHandler LoadingSymbolsStarted;
+ public static event EventHandler LoadingSymbolsCompleted;
#region Mini Classes
@@ -85,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>
@@ -110,13 +127,13 @@ namespace Tango.Scripting.Editors
/// <summary>
/// Gets or sets the reference assemblies.
/// </summary>
- public ObservableCollection<ReferenceAssembly> ReferenceAssemblies
+ public ObservableCollection<Assembly> ReferenceAssemblies
{
- get { return (ObservableCollection<ReferenceAssembly>)GetValue(ReferenceAssembliesProperty); }
+ get { return (ObservableCollection<Assembly>)GetValue(ReferenceAssembliesProperty); }
set { SetValue(ReferenceAssembliesProperty, value); }
}
public static readonly DependencyProperty ReferenceAssembliesProperty =
- DependencyProperty.Register("ReferenceAssemblies", typeof(ObservableCollection<ReferenceAssembly>), typeof(ScriptEditor), new PropertyMetadata(null));
+ DependencyProperty.Register("ReferenceAssemblies", typeof(ObservableCollection<Assembly>), typeof(ScriptEditor), new PropertyMetadata(null, (d, e) => (d as ScriptEditor).OnReferenceAssembliesChanged()));
public Object CurrentPopupContent
{
@@ -126,6 +143,21 @@ namespace Tango.Scripting.Editors
public static readonly DependencyProperty CurrentPopupContentProperty =
DependencyProperty.Register("CurrentPopupContent", typeof(Object), typeof(ScriptEditor), new PropertyMetadata(null));
+ public String Code
+ {
+ get { return (String)GetValue(CodeProperty); }
+ set { SetValue(CodeProperty, value); }
+ }
+ public static readonly DependencyProperty CodeProperty =
+ DependencyProperty.Register("Code", typeof(String), typeof(ScriptEditor), new PropertyMetadata(null, (d, e) => (d as ScriptEditor).OnCodeChanged()));
+
+ public ObservableCollection<IScriptSource> AdditionalScripts
+ {
+ get { return (ObservableCollection<IScriptSource>)GetValue(AdditionalScriptsProperty); }
+ set { SetValue(AdditionalScriptsProperty, value); }
+ }
+ public static readonly DependencyProperty AdditionalScriptsProperty =
+ DependencyProperty.Register("AdditionalScripts", typeof(ObservableCollection<IScriptSource>), typeof(ScriptEditor), new PropertyMetadata(null));
#endregion
@@ -137,6 +169,24 @@ namespace Tango.Scripting.Editors
static ScriptEditor()
{
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");
+ Directory.CreateDirectory(KNOWN_TYPES_CACHE_FOLDER);
+ }
+
+ _jsonSettings = new JsonSerializerSettings()
+ {
+ TypeNameHandling = TypeNameHandling.Auto,
+ PreserveReferencesHandling = PreserveReferencesHandling.All
+ };
+
+ _knownTypesCache = new Dictionary<Type, KnownType>();
+ _cachedAssemblies = new List<CachedAssembly>();
+ _cachedUsings = new List<CachedUsing>();
}
/// <summary>
@@ -148,12 +198,11 @@ namespace Tango.Scripting.Editors
_current_usings = new List<string>();
- ReferenceAssemblies = new ObservableCollection<ReferenceAssembly>();
+ //ReferenceAssemblies = new ObservableCollection<ReferenceAssembly>();
- //Add basic assemblies...
- ReferenceAssemblies.Add(new ReferenceAssembly(typeof(String))); //mscorelib
- ReferenceAssemblies.Add(new ReferenceAssembly(typeof(Enumerable))); //System.Core
- ReferenceAssemblies.Add(new ReferenceAssembly(typeof(Tango.Core.CoreSettings))); //System.Core
+ ////Add basic assemblies...
+ //ReferenceAssemblies.Add(new ReferenceAssembly(typeof(String))); //mscorelib
+ //ReferenceAssemblies.Add(new ReferenceAssembly(typeof(Enumerable))); //System.Core
_knownTypes = new List<KnownType>();
_parser = new ScriptParser();
@@ -175,6 +224,29 @@ namespace Tango.Scripting.Editors
completionWindow.AllowsTransparency = true;
completionWindow.ResizeMode = ResizeMode.NoResize;
completionWindow.InsertionRequest += CompletionWindow_InsertionRequest;
+
+ TextChanged += ScriptEditor_TextChanged;
+ }
+
+ private bool preventCodeUpdate;
+ private void ScriptEditor_TextChanged(object sender, EventArgs e)
+ {
+ if (!preventCodeUpdate)
+ {
+ preventCodeUpdate = true;
+ Code = Text;
+ preventCodeUpdate = false;
+ }
+ }
+
+ private void OnCodeChanged()
+ {
+ if (!preventCodeUpdate)
+ {
+ preventCodeUpdate = true;
+ Text = Code;
+ preventCodeUpdate = false;
+ }
}
#endregion
@@ -370,16 +442,17 @@ namespace Tango.Scripting.Editors
{
var knownType = GetCurrentKnownType();
+ IList<ICompletionData> data = new List<ICompletionData>();
+
if (knownType != null)
{
completionWindow.HideCompletion();
- IList<ICompletionData> data = new List<ICompletionData>();
if (!knownType.Type.IsEnum)
{
var typeMembers = knownType.Members.ToList();
- foreach (var methodGroup in typeMembers.OfType<KnownTypeMethod>().GroupBy(x => x.NameWithTypeArguments))
+ foreach (var methodGroup in typeMembers.OfType<KnownTypeMethod>().Where(x => !x.IsStatic).GroupBy(x => x.NameWithTypeArguments))
{
var method = methodGroup.First();
@@ -394,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();
@@ -405,7 +488,6 @@ namespace Tango.Scripting.Editors
Type = member.ReturnTypeFriendlyName,
Description = member.Summary,
});
-
}
}
else
@@ -432,7 +514,6 @@ namespace Tango.Scripting.Editors
if (declaredType != null)
{
completionWindow.HideCompletion();
- IList<ICompletionData> data = new List<ICompletionData>();
var typeMembers = declaredType.Symbols.ToList();
@@ -491,6 +572,34 @@ namespace Tango.Scripting.Editors
ShowCompletionWindow(data, GetCurrentWord());
}
+ else
+ {
+ //Maybe static ...
+ var typeText = GetPreviousWord();
+ knownType = _knownTypes.FirstOrDefault(x => x.FriendlyName == typeText || x.Alias == typeText);
+
+ if (knownType != null)
+ {
+ var typeMembers = knownType.Members.ToList();
+
+ foreach (var methodGroup in typeMembers.OfType<KnownTypeMethod>().Where(x => x.IsStatic).GroupBy(x => x.NameWithTypeArguments))
+ {
+ var method = methodGroup.First();
+
+ data.Add(new MethodCompletionItem()
+ {
+ Class = knownType.FriendlyName,
+ Name = method.NameWithTypeArguments,
+ ReturnType = method.ReturnTypeFriendlyName,
+ Description = method.Summary,
+ Parameters = method.Parameters,
+ Overloads = methodGroup.Count() - 1,
+ });
+ }
+
+ ShowCompletionWindow(data.OrderBy(x => x.Text).ToList(), GetCurrentWord());
+ }
+ }
}
}
else if (e.Text == "(" || e.Text == ",")
@@ -534,6 +643,18 @@ namespace Tango.Scripting.Editors
return;
}
}
+
+ var staticMethodSession = GetStaticMethodSession();
+
+ if (staticMethodSession != null)
+ {
+ var content = CreateMethodSessionPopupContent(staticMethodSession);
+ if (content.Methods.Count > 0)
+ {
+ ShowPopup(content);
+ return;
+ }
+ }
}
catch (Exception ex)
{
@@ -552,12 +673,12 @@ namespace Tango.Scripting.Editors
foreach (var asm in ReferenceAssemblies)
{
- foreach (var ns in asm.Assembly.GetTypes().Select(x => x.Namespace).Distinct().Where(x => x != null))
+ foreach (var ns in asm.GetTypes().Select(x => x.Namespace).Distinct().Where(x => x != null))
{
data.Add(new NamespaceCompletionItem()
{
Name = ns,
- Assembly = asm.Assembly.GetName().Name,
+ Assembly = asm.GetName().Name,
});
}
}
@@ -799,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);
}
@@ -881,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();
@@ -900,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)
{
@@ -933,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();
@@ -1147,33 +1283,251 @@ namespace Tango.Scripting.Editors
return popup;
}
- private void InvalidateHighlighting()
+ public static void LoadUsingsSymbols(List<Assembly> assemblies, List<String> usings)
+ {
+ lock (_loadUsingsLock)
+ {
+ LoadingSymbolsStarted?.Invoke(null, new EventArgs());
+
+ var allTypes = assemblies.SelectMany(x => x.GetTypes());
+
+ foreach (var use in usings)
+ {
+ if (!_cachedUsings.Exists(x => x.Namespace == use))
+ {
+ var useFileName = System.IO.Path.Combine(KNOWN_TYPES_CACHE_FOLDER, use + ".json");
+
+ if (File.Exists(useFileName))
+ {
+ 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)
+ {
+ _knownTypesCache.Add(knownType.Type, knownType);
+ }
+
+ continue;
+ }
+
+ var useTypes = allTypes.Where(x => x.IsVisible && x.IsPublic && x.Namespace == use).ToList();
+
+ CachedUsing cachedUsing = new CachedUsing();
+ cachedUsing.Namespace = use;
+ _cachedUsings.Add(cachedUsing);
+
+ int i = 1;
+
+ foreach (var type in useTypes)
+ {
+ 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();
+ }
+
+ if (!BlockedUsingsCache.Exists(x => x == use))
+ {
+ Task.Factory.StartNew(() =>
+ {
+ var json = JsonConvert.SerializeObject(cachedUsing, _jsonSettings);
+ File.WriteAllText(useFileName, json);
+ });
+ }
+ }
+ }
+
+ LoadingSymbolsCompleted?.Invoke(null, new EventArgs());
+ }
+ }
+
+ //public static void LoadCachedAssemblies(List<Assembly> assemblies, List<String> usings = null)
+ //{
+ // if (_isLoadingCachedAssemblies) return;
+
+ // _isLoadingCachedAssemblies = true;
+
+ // LoadingSymbolsStarted?.Invoke(null, new EventArgs());
+
+ // 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)}'..."
+ // }
+ // });
+
+ // var cachedAssembly = JsonConvert.DeserializeObject<CachedAssembly>(System.IO.File.ReadAllText(file), _jsonSettings);
+
+ // foreach (var knownType in cachedAssembly.KnownTypes)
+ // {
+ // _knownTypesCache.Add(knownType.Type, knownType);
+ // }
+
+ // _cachedAssemblies.Add(cachedAssembly);
+ // }
+ // catch { }
+ // }
+
+ // _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)
{
if (!_isLoadingTypes)
{
_isLoadingTypes = true;
- _knownTypes.Clear();
var assemblies = ReferenceAssemblies.ToList();
var usings = _current_usings.ToList();
Thread t = new Thread(() =>
{
- foreach (var asm in assemblies.Select(x => x.Assembly))
+ LoadUsingsSymbols(assemblies, usings);
+
+ if (loadKnownTypes)
{
- Parallel.ForEach(asm.GetTypes().Where(x => x.IsVisible && x.IsPublic && !x.IsPrimitive), (type) =>
+ _knownTypes.Clear();
+
+ foreach (var knownType in _knownTypesCache.ToList().Select(x => x.Value).ToList())
{
- if (usings.Exists(x => type.Namespace == x))
+ if (usings.Exists(x => knownType.Type.Namespace == x) && assemblies.Exists(x => x == knownType.Type.Assembly))
{
lock (_knownTypes)
{
- if (!_knownTypes.Exists(x => x.Type.FullName == type.FullName))
- {
- _knownTypes.Add(new KnownType(type));
- }
+ _knownTypes.Add(knownType);
}
}
- });
+ }
}
if (_knownTypes.Count > 0 || _declaredTypes.Count > 0)
@@ -1246,10 +1600,10 @@ namespace Tango.Scripting.Editors
}));
- foreach (var knownType in _knownTypes)
- {
- knownType.LoadDocumentation();
- }
+ //foreach (var knownType in _knownTypes)
+ //{
+ // knownType.LoadDocumentation();
+ //}
}
_isLoadingTypes = false;
@@ -1263,10 +1617,19 @@ namespace Tango.Scripting.Editors
{
var declaredTypes = _parser.GetDeclaredTypes(Text);
+ if (AdditionalScripts != null)
+ {
+ foreach (var script in AdditionalScripts)
+ {
+ declaredTypes.AddRange(_parser.GetDeclaredTypes(script.Code));
+ }
+ }
+
+
if (declaredTypes.Exists(x => !_declaredTypes.Exists(y => y.Name == x.Name)) || _declaredTypes.Exists(x => !declaredTypes.Exists(y => y.Name == x.Name)))
{
_declaredTypes = declaredTypes;
- InvalidateHighlighting();
+ InvalidateHighlighting(false);
}
_declaredTypes = declaredTypes;
@@ -1396,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)
{
@@ -1452,13 +1819,62 @@ namespace Tango.Scripting.Editors
}
}
+ else
+ {
+ var expression2 = _parser.GetCurrentConstructionExpressionAlt(GetCurrentLineText());
+
+ if (expression2 != null && expression2.Identifier != null)
+ {
+ ConstructionSession session = new ConstructionSession();
+
+ var line = GetCurrentLine();
+ int parameterIndex = 0;
+ for (int i = CaretOffset; i > line.Offset; i--)
+ {
+ String c = Document.GetText(i, 1);
+
+ if (c == "(")
+ {
+ KnownType type = null;
+
+ if (expression2.Identifier != null)
+ {
+ var typeName = expression2.Identifier.ToString();
+ type = _knownTypes.FirstOrDefault(x => x.Type.Name == typeName);
+
+ if (type != null)
+ {
+ session.Type = type;
+ session.ParameterIndex = parameterIndex;
+ return session;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+ else if (c == ",")
+ {
+ parameterIndex++;
+ }
+ }
+ }
+ }
return null;
}
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"))
{
@@ -1515,7 +1931,7 @@ namespace Tango.Scripting.Editors
return null;
}
- private DeclaredMethodSession GetDeclaredMethodSession()
+ private MethodSession GetStaticMethodSession()
{
var words = GetCurrentLineText().Split(' ');
@@ -1524,7 +1940,73 @@ namespace Tango.Scripting.Editors
return null;
}
- var expression = GetPreviousWords().LastOrDefault();
+ var expression = words.LastOrDefault();
+
+ if (expression != null)
+ {
+ int parameterIndex = expression.Count(x => x == ',');
+ expression = new string(expression.TakeWhile(x => x != '(').ToArray());
+
+ var tree = expression.Split('.').Select(x => x.Remove(@"\n|\r|\s|\t|\(|\)|\[|\]|<.*>")).ToList();
+ var variableName = tree.FirstOrDefault();
+
+ if (variableName != null && tree.Count > 1)
+ {
+ tree.RemoveAt(0);
+ var variables = _parser.GetContextSymbols(Document.Text, CaretOffset);
+ var variable = variableName;
+
+ if (variable != null)
+ {
+ var knownType = _knownTypes.FirstOrDefault(x => x.FriendlyName == Regex.Replace(variable, "<.+>", "<T>"));
+
+ if (knownType != null)
+ {
+ while (tree.Count > 1)
+ {
+ var memberName = tree.First();
+ tree.RemoveAt(0);
+ var member = knownType.Members.FirstOrDefault(x => x.Name == memberName);
+
+ if (member == null)
+ {
+ return null;
+ }
+
+ knownType = _knownTypes.FirstOrDefault(x => x.Type.Namespace + "." + x.Type.Name == member.ReturnType.Namespace + "." + member.ReturnType.Name);
+ }
+
+ return new MethodSession()
+ {
+ Type = knownType,
+ MethodName = tree.Last(),
+ ParameterIndex = parameterIndex,
+ };
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private DeclaredMethodSession GetDeclaredMethodSession()
+ {
+ 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 = currentLine;
if (expression != null)
{
@@ -1539,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)
{
@@ -1598,5 +2080,25 @@ namespace Tango.Scripting.Editors
}
#endregion
+
+ #region Reference Assemblies Changed
+
+ private void OnReferenceAssembliesChanged()
+ {
+ if (ReferenceAssemblies != null)
+ {
+ ReferenceAssemblies.CollectionChanged -= ReferenceAssemblies_CollectionChanged;
+ ReferenceAssemblies.CollectionChanged += ReferenceAssemblies_CollectionChanged;
+
+ InvalidateHighlighting();
+ }
+ }
+
+ private void ReferenceAssemblies_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
+ {
+ InvalidateHighlighting();
+ }
+
+ #endregion
}
}