public override BaseTypeInfo ResolvePropertyPath(Globals globals, params string[] path) { string str = path[0]; if (str.Contains('(')) { string content = str.Substring(0, str.IndexOf('(')); FunctionInfo fi = Functions.FirstOrDefault(f => f.Name.Equals(content)); if (fi != null) { if (str.Contains('[') && fi.ReturnType is TemplateInst) { return(((TemplateInst)fi.ReturnType).WrappedType); } else if (fi.ReturnType is TemplateInst) { return(globals.Classes[fi.ReturnType.Name.Substring(0, fi.ReturnType.Name.IndexOf('<'))]); } return(fi.ReturnType); } } else if (str.Contains('[')) { string content = str.Extract('[', ']'); str = str.Replace(string.Format("[{0}]", content), ""); TemplateInst ti = Properties[str] as TemplateInst; if (ti != null && path.Length > 1) { TypeInfo t = ti.WrappedType; return(t.ResolvePropertyPath(globals, path.SubArray(1, path.Length - 1))); } if (ti == null) { return(null); } else if (ti.WrappedType == null) { return(ti); } return(globals.Classes[ti.WrappedType.Name]); } else if (Properties.ContainsKey(path[0])) { BaseTypeInfo ti = Properties[path[0]]; if (ti is TemplateInst) { ti = globals.Classes[((TemplateInst)ti).Name]; } if (path.Length > 1) { ti = ti.ResolvePropertyPath(globals, path.SubArray(1, path.Length - 1)); } return(ti); } return(null); }
void editor_KeyUp(object sender, KeyEventArgs e) { // These keys halt and terminate intellisense switch (e.Key) { case Key.Home: case Key.End: case Key.Left: case Key.Right: case Key.Escape: case Key.LWin: case Key.RWin: case Key.Space: if (currentComp != null) { currentComp.Close(); } return; } // These keys halt further checks switch (e.Key) { case Key.Up: case Key.Down: case Key.PageDown: case Key.PageUp: case Key.LeftShift: case Key.RightShift: case Key.LeftAlt: case Key.RightAlt: case Key.LeftCtrl: case Key.RightCtrl: case Key.Scroll: case Key.Capital: case Key.CrSel: case Key.Clear: case Key.Insert: case Key.PrintScreen: case Key.Print: return; } char KEY = KeyHelpers.GetCharFromKey(e.Key); if (KEY == ')' || KEY == ';') { if (currentComp != null) { currentComp.Close(); } return; } int curOfs = editor.TextArea.Caret.Offset; int line = editor.TextArea.Caret.Line; // Do not attempt intellisense inside of comments string txt = editor.Document.GetText(editor.Document.Lines[editor.TextArea.Caret.Line - 1]); if (txt.Trim().StartsWith("//")) { return; } if (e.Key == Key.OemPeriod || KEY == ':') { //IntellisenseHelper.ResemblesDotPath(editor.Document, curOfs-1, line-1)) { int ofs = TextUtilities.GetNextCaretPosition(editor.Document, curOfs, LogicalDirection.Backward, CaretPositioningMode.WordStart); ofs = TextUtilities.GetNextCaretPosition(editor.Document, ofs, LogicalDirection.Backward, CaretPositioningMode.WordStart); string word = ""; for (; ofs < curOfs; ++ofs) { if (editor.Document.Text[ofs] != '.') { word += editor.Document.Text[ofs]; } } NameResolver reso = new NameResolver(IDEProject.inst().GlobalTypes, scanner); BaseTypeInfo info = null; string[] words = IntellisenseHelper.DotPath(editor.Document, curOfs - 1, line - 1); if (words.Length > 1) { for (int i = 0; i < words.Length - 1; ++i) { if (info == null) { info = reso.GetClassType(editor.Document, editor.TextArea.Caret.Line, words[i]); } else if (info != null) { info = info.ResolvePropertyPath(IDEProject.inst().GlobalTypes, words[i]); //if (info.Properties.ContainsKey(words[i])) // info = info.Properties[words[i]]; } } } bool functionsOnly = false; //attempt to resolve it locally if (info == null) { info = reso.GetClassType(editor.Document, editor.TextArea.Caret.Line, word); } //attempt to resolve it from globals if (info == null && IDEProject.inst().GlobalTypes != null && IDEProject.inst().GlobalTypes.Properties.ContainsKey(word)) { info = IDEProject.inst().GlobalTypes.Properties[word]; } if (info == null && word.Contains("::")) { if (IDEProject.inst().GlobalTypes == null) { return; } if (word.Length > 2) { if (IDEProject.inst().GlobalTypes.Classes.ContainsKey(word.Replace("::", ""))) { EnumInfo ti = IDEProject.inst().GlobalTypes.Classes[word.Replace("::", "")] as EnumInfo; if (ti != null) { currentComp = new CompletionWindow(editor.TextArea); IList <ICompletionData> data = currentComp.CompletionList.CompletionData; foreach (string str in ti.Values) { data.Add(new BaseCompletionData(null, str)); } currentComp.Show(); currentComp.Closed += comp_Closed; return; } else { TypeInfo ty = IDEProject.inst().GlobalTypes.Classes.FirstOrDefault(p => p.Key.Equals(word.Replace("::", ""))).Value; if (ty != null) { info = ty; functionsOnly = true; } } } else //list global functions { Globals globs = IDEProject.inst().GlobalTypes; currentComp = new CompletionWindow(editor.TextArea); IList <ICompletionData> data = currentComp.CompletionList.CompletionData; foreach (string str in globs.Properties.Keys) { data.Add(new PropertyCompletionData(globs.Properties[str], str)); } foreach (FunctionInfo fi in globs.Functions) { data.Add(new FunctionCompletionData(fi)); } currentComp.Show(); currentComp.Closed += comp_Closed; return; } } } //build the list if (info != null && info is TypeInfo) { TypeInfo ti = info as TypeInfo; currentComp = new CompletionWindow(editor.TextArea); IList <ICompletionData> data = currentComp.CompletionList.CompletionData; if (!functionsOnly) { foreach (string str in ti.Properties.Keys) { data.Add(new PropertyCompletionData(ti.Properties[str], str, ti.ReadonlyProperties.Contains(str))); } } foreach (FunctionInfo fi in ti.Functions) { data.Add(new FunctionCompletionData(fi)); } currentComp.Show(); currentComp.Closed += comp_Closed; } } else if (KEY == '(' && IntellisenseHelper.ResemblesDotPath(editor.Document, curOfs - 2, line - 1)) { NameResolver reso = new NameResolver(IDEProject.inst().GlobalTypes, scanner); TypeInfo info = null; FunctionInfo func = null; string[] words = IntellisenseHelper.DotPath(editor.Document, curOfs - 2, line - 1); if (words.Length > 1) { for (int i = 0; i < words.Length; ++i) { if (i == words.Length - 1 && info != null) { func = info.Functions.FirstOrDefault(f => f.Name.Equals(words[i])); } else { if (info == null) { info = reso.GetClassType(editor.Document, editor.TextArea.Caret.Line, words[i]); } else if (info != null) { if (info.Properties.ContainsKey(words[i])) { info = info.Properties[words[i]]; } } } } } if (func != null) { List <FunctionInfo> data = new List <FunctionInfo>(); foreach (FunctionInfo fi in info.Functions.Where(f => { return(f.Name.Equals(func.Name)); })) { data.Add(fi); } if (data.Count > 0) { OverloadInsightWindow window = new OverloadInsightWindow(editor.TextArea); window.Provider = new OverloadProvider(info, data.ToArray()); window.Show(); //compWindow.Closed += comp_Closed; } } else if (func == null && info == null) // Found nothing { List <FunctionInfo> data = new List <FunctionInfo>(); foreach (FunctionInfo fi in IDEProject.inst().GlobalTypes.Functions.Where(f => { return(f.Name.Equals(words[1])); })) { data.Add(fi); } if (data.Count > 0) { OverloadInsightWindow window = new OverloadInsightWindow(editor.TextArea); window.Provider = new OverloadProvider(info, data.ToArray()); window.Show(); //compWindow.Closed += comp_Closed; } } } else if (Char.IsLetter(KEY)) { if (currentComp != null || editor.TextArea.Caret.Line == 1) { return; } int ofs = TextUtilities.GetNextCaretPosition(editor.Document, curOfs, LogicalDirection.Backward, CaretPositioningMode.WordStart); int nextOfs = TextUtilities.GetNextCaretPosition(editor.Document, ofs, LogicalDirection.Backward, CaretPositioningMode.WordStart); if (nextOfs > 0) { if (editor.Document.Text[nextOfs] == '.') { return; } } string word = ""; if (ofs < 0) { return; } for (; ofs < curOfs; ++ofs) { if (editor.Document.Text[ofs] != '.') { word += editor.Document.Text[ofs]; } } if (word.Contains(".")) { if (currentComp != null) { currentComp.Close(); } //editor_KeyUp(sender, e); return; } NameResolver reso = new NameResolver(IDEProject.inst().GlobalTypes, scanner); List <string> suggestions = new List <string>(); reso.GetNameMatch(editor.Document, editor.TextArea.Caret.Line - 1, word, ref suggestions); CompletionWindow compWindow = new CompletionWindow(editor.TextArea); compWindow.StartOffset = TextUtilities.GetNextCaretPosition(editor.Document, curOfs, LogicalDirection.Backward, CaretPositioningMode.WordStart); IList <ICompletionData> data = compWindow.CompletionList.CompletionData; //attempt local name resolution first if (suggestions.Count > 0) { foreach (string str in suggestions) //text suggestions are of lower priority { data.Add(new BaseCompletionData(null, str) { Priority = 0.5 }); } } //Scal globals if (IDEProject.inst().GlobalTypes != null) { foreach (string str in IDEProject.inst().GlobalTypes.Classes.Keys) { if (str.StartsWith(word)) { data.Add(new ClassCompletionData(IDEProject.inst().GlobalTypes.Classes[str])); } } foreach (FunctionInfo fun in IDEProject.inst().GlobalTypes.Functions) { if (fun.Name.StartsWith(word)) { data.Add(new FunctionCompletionData(fun)); } } } if (data.Count > 0) { currentComp = compWindow; currentComp.Show(); currentComp.Closed += comp_Closed; } } }