public void FindMembers() { try { var asts = SyntaxTreeMaintainer.GetSyntaxTrees(); dialog = CreateListFindControl(); dialog.DataSource = asts.SelectMany(a => a.GetAllMembers()).Cast <object>().ToList(); dialog.AlwaysShowList = false; dialog.MaxResults = 15; dialog.SearchHintText = "Search solution..."; dialog.OnGetIconForItem = FortranIconProvider.GetIconForMember; dialog.OnGetHintForItem = o => ((IMember)o).GetScopeDescription(); dialog.DataMember = "Name"; dialog.ItemChosen += (s, e) => { var chosenMember = (IMember)s; VisualStudio.Goto(chosenMember.Root.CodeFile, chosenMember.Location.Line, chosenMember.Location.Offset); }; dialog.Show(); } catch (Exception e) { Log.Error("FindMembers failed", e, GetContext()); } }
private void BrowseToVariable(string elementName) { //find variables var elementsInScope = FortranSyntaxTreeModel.GetElementsAvailableInScope( SyntaxTreeMaintainer.GetSyntaxTrees(), GetCurrentMember()); var firstMatch = elementsInScope.OfType <Variable>().FirstOrDefault(el => Equals(elementName, el.Name)); if (firstMatch == null) { // second chance: try items in types: var typesInScope = elementsInScope.OfType <Fortran.Elements.Type>().ToList(); foreach (var type in typesInScope) { new FortranDeclarationParser().ParseDeclarationsAndUses(type); } firstMatch = elementsInScope.OfType <Fortran.Elements.Type>() .SelectMany(t => t.LocalVariables) .FirstOrDefault(el => Equals(elementName, el.Name)); if (firstMatch == null) { return; } } VisualStudio.Goto(firstMatch.Member.Root.CodeFile, firstMatch.Location.Line, firstMatch.Location.Offset + 1); }
public void BrowseTo() { try { if (!VisualStudio.IsDocumentOpen()) { return; } var cursorPosition = VisualStudio.GetCursorPositionInLine(); var line = VisualStudio.GetCurrentLine(); int beginIndex; var elementName = FortranParseHelper.GetElementName(line, cursorPosition, out beginIndex); if (String.IsNullOrEmpty(elementName)) { return; } var memberMatches = SyntaxTreeMaintainer.GetSyntaxTrees() .SelectMany(st => st.GetAllMembers() .Where(m => Equals(elementName, m.Name)) .Select(m => new SearchResult { SyntaxTree = st, Member = m })) .ToList(); if (memberMatches.Any()) { BrowseToCore(memberMatches); } else { BrowseToVariable(elementName); } } catch (Exception e) { Log.Error("BrowseTo failed", e, GetContext()); } }
public void FindFiles() { try { var asts = SyntaxTreeMaintainer.GetSyntaxTrees(); dialog = CreateListFindControl(); dialog.DataSource = asts.Select(a => a.CodeFile).Cast <object>().ToList(); dialog.AlwaysShowList = false; dialog.MaxResults = 15; dialog.SearchHintText = "Find files..."; dialog.OnGetIconForItem = FortranIconProvider.GetIconForFile; dialog.OnGetHintForItem = o => ((CodeFile)o).ProjectName; dialog.DataMember = "FileName"; dialog.ItemChosen += (s, e) => VisualStudio.Goto(s as CodeFile, 1, 1); dialog.Show(); } catch (Exception e) { Log.Error("FindFiles failed", e, GetContext()); } }
/// <summary> /// This method parses the current line, and determines which suggestions to show for code completion (intellisense) /// </summary> /// <param name="session"></param> private void UpdateCodeComplete(CompletionSession session) { //parse current line //set results //set filter try { ParseQueueProcessor.ShowProgressDialog = false; //maybe not actually required anymore var currentLine = VisualStudio.GetCurrentLine(); var currentIndex = VisualStudio.GetCursorPositionInLine(); var lineParser = new FortranStatementParser(); var beginOfStatement = 0; var statement = lineParser.FindEffectiveStatementAtOffset(currentLine, currentIndex, out beginOfStatement); var fullStatement = currentLine.Substring(beginOfStatement, currentIndex - beginOfStatement); var currentMember = GetCurrent <IMember>(); ShowMethodSignatureAsToolTip(session, currentMember, currentLine, currentIndex); IList <INameable> codeCompleteOptions; var filter = ""; var addLanguageKeywords = false; var codeElementsInScope = FortranSyntaxTreeModel.GetElementsAvailableInScope(SyntaxTreeMaintainer.GetSyntaxTrees(), currentMember); // are we in a 'call something' statement? var callMatch = callRegex.Match(statement); if (callMatch.Success) { //only subroutines codeCompleteOptions = codeElementsInScope.OfType <Subroutine>().Cast <INameable>().ToList(); //subroutines only session.InsertionIndexInLine = beginOfStatement + callMatch.Groups[1].Index; filter = callMatch.Groups[1].Value; } else if (!statement.Contains('%')) //local scope { if (statement.Length > 0 && FortranParseHelper.IsWhiteSpace(statement[statement.Length - 1])) { //reset: wrong statement: beginOfStatement += statement.Length; statement = ""; } codeCompleteOptions = codeElementsInScope.Where(ce => !(ce is Subroutine)).ToList(); //subroutines only available after a 'call' session.InsertionIndexInLine = beginOfStatement; filter = statement; addLanguageKeywords = true; } else // nested in type, eg: channel % sourceNode % id { var elements = FortranParseHelper.SplitElementsInStatement(statement, fullStatement, ref beginOfStatement, out filter); if (elements.Count < 1) { throw new NotSupportedException("help!"); } var variableName = elements[0]; var matchingVariable = codeElementsInScope .OfType <Variable>() .FirstOrDefault(lv => String.Equals(lv.Name, variableName, StringComparison.InvariantCultureIgnoreCase)); var typeOfVariable = matchingVariable.TypeString; var currentType = codeElementsInScope .OfType <Type>() .FirstOrDefault(tp => String.Equals(tp.Name, typeOfVariable, StringComparison.InvariantCultureIgnoreCase)); for (int i = 1; i < elements.Count; i++) { if (currentType == null) { break; } var propertyName = elements[i]; var property = GetElementsOfType(currentType).FirstOrDefault(vf => String.Equals(vf.Name, propertyName, StringComparison.InvariantCultureIgnoreCase)); typeOfVariable = property.TypeString; currentType = codeElementsInScope .OfType <Type>() .FirstOrDefault(tp => String.Equals(tp.Name, typeOfVariable, StringComparison.InvariantCultureIgnoreCase)); } if (currentType == null) { codeCompleteOptions = new INameable[] { } } ; else { codeCompleteOptions = GetElementsOfType(currentType).Cast <INameable>().ToList(); } session.InsertionIndexInLine = beginOfStatement; } // gather all results var completionItems = codeCompleteOptions.Select(e => new CompletionItem(e.Name, FortranIconProvider.GetIconForMember(e)) { ToolTip = GetTooltipForMember(currentMember, e) }).ToList(); if (addLanguageKeywords) { foreach (var keyword in fortranKeywords) { completionItems.Add(new CompletionItem(keyword, null)); } foreach (var intrinsic in fortranIntrinsics) { completionItems.Add(new CompletionItem(intrinsic.Key, IntrinsicIcon) { ToolTip = intrinsic.Value }); } } session.SetCompletionSet(completionItems, filter); } catch (Exception e) { Log.Error("Error while updating code complete", e); } finally { ParseQueueProcessor.ShowProgressDialog = true; //messes with intellisense popup } }
private void ShowMethodSignatureAsToolTip(CompletionSession session, IMember currentMember, string currentLine, int currentIndex) { session.SignatureToolTip = ""; try { if (currentMember == null) { return; } var lineParser = new FortranStatementParser(); var methodName = lineParser.FindMethodAtOffset(currentLine, currentIndex); if (String.IsNullOrEmpty(methodName)) { return; } var allMethodsInScope = FortranSyntaxTreeModel.GetElementsAvailableInScope(SyntaxTreeMaintainer.GetSyntaxTrees(), currentMember). OfType <IMethod>(); var method = allMethodsInScope.FirstOrDefault(m => String.Equals(m.Name, methodName, StringComparison.InvariantCultureIgnoreCase)); if (method == null) { if (fortranIntrinsics.ContainsKey(methodName)) { var intrinsicDoc = fortranIntrinsics[methodName]; var fistLineOfDoc = intrinsicDoc.Split('\n').FirstOrDefault() ?? ""; // take first line of documentation session.SignatureToolTip = fistLineOfDoc; } return; } var declarationParser = new FortranDeclarationParser(); var signatureParser = new FortranSignatureParser(); declarationParser.ParseDeclarationsAndUses(method); signatureParser.ParseMethodSignature(method); session.SignatureToolTip = method.Name + "(" + String.Join(", ", method.Parameters.Select(p => p.TypeString + " " + p.Name).ToArray()) + ")"; } catch (Exception e) { Log.Error("Exception while generating signature tooltip", e); } }
public void FindUsage() { try { if (!VisualStudio.IsDocumentOpen()) { return; } var coords = VisualStudio.GetCaretPositionInScreenCoordinates(); var cursorPosition = VisualStudio.GetCursorPositionInLine(); var line = VisualStudio.GetCurrentLine(); int beginIndex; var memberName = FortranParseHelper.GetElementName(line, cursorPosition, out beginIndex); if (String.IsNullOrEmpty(memberName.Trim())) { return; } var asts = SyntaxTreeMaintainer.GetSyntaxTrees().ToList(); var matchingMember = asts.SelectMany(a => a.GetAllMembers()) .FirstOrDefault(m => String.Equals(m.Name, memberName, StringComparison.InvariantCultureIgnoreCase)); var searchObj = matchingMember != null ? new MemberOrSearchTerm(matchingMember) : new MemberOrSearchTerm(memberName); var usages = new FortranUsageSearcher().FindInFiles(searchObj, asts); if (usages.Count == 0) { return; } if (usages.Count == 1) { GotoUsage(usages.First()); return; } dialog = CreateListFindControl(); dialog.Location = coords; dialog.MaxResults = 500;//something big dialog.DataSource = usages.OfType <object>().ToList(); dialog.AlwaysShowList = true; dialog.HideSearchDialog = true; dialog.OnGetIconForItem = o => null; dialog.DataMember = "Name"; dialog.HintMember = "Hint"; dialog.OnGetHintEmphasisRangeForItem = o => { var usageRes = (UsageResult)o; var start = usageRes.Location.Offset; var end = start + memberName.Length; return(new Point(start, end)); }; dialog.ItemChosen += (chosenUsage, e) => GotoUsage((UsageResult)chosenUsage); dialog.Show(); } catch (Exception e) { Log.Error("FindUsage failed", e, GetContext()); } }
/// <summary> /// This method parses the current line, and determines which suggestions to show for code completion (intellisense) /// </summary> /// <param name="session"></param> private void UpdateCodeComplete(CompletionSession session) { //parse current line //set results //set filter try { ParseQueueProcessor.ShowProgressDialog = false; //maybe not actually required anymore var currentLine = VisualStudio.GetCurrentLine(); var currentIndex = VisualStudio.GetCursorPositionInLine(); var lineParser = new FortranStatementParser(); var beginOfStatement = 0; var statement = lineParser.FindEffectiveStatementAtOffset(currentLine, currentIndex, out beginOfStatement); var fullStatement = currentLine.Substring(beginOfStatement, currentIndex - beginOfStatement); var currentMember = GetCurrent <IMember>(); ShowMethodSignatureAsToolTip(session, currentMember, currentLine, currentIndex); IList <INameable> codeCompleteOptions; var filter = ""; var addLanguageKeywords = false; var codeElementsInScope = FortranSyntaxTreeModel.GetElementsAvailableInScope(SyntaxTreeMaintainer.GetSyntaxTrees(), currentMember); // are we in a 'call something' statement? var callMatch = callRegex.Match(statement); if (callMatch.Success) { //only subroutines codeCompleteOptions = codeElementsInScope.OfType <Subroutine>().Cast <INameable>().ToList(); //subroutines only session.InsertionIndexInLine = beginOfStatement + callMatch.Groups[1].Index; filter = callMatch.Groups[1].Value; } else if (!statement.Contains('%')) //local scope { if (statement.Length > 0 && FortranParseHelper.IsWhiteSpace(statement[statement.Length - 1])) { //reset: wrong statement: beginOfStatement += statement.Length; statement = ""; } codeCompleteOptions = codeElementsInScope.Where(ce => !(ce is Subroutine)).ToList(); //subroutines only available after a 'call' session.InsertionIndexInLine = beginOfStatement; filter = statement; addLanguageKeywords = true; } else // nested in type, eg: channel % sourceNode % id { var elements = FortranParseHelper.SplitElementsInStatement(statement, fullStatement, ref beginOfStatement, out filter); if (elements.Count < 1) { throw new NotSupportedException("help!"); } var variableName = elements[0]; var matchingVariable = codeElementsInScope .OfType <Variable>() .FirstOrDefault(lv => String.Equals(lv.Name, variableName, StringComparison.InvariantCultureIgnoreCase)); var typeOfVariable = matchingVariable.TypeString; var currentType = codeElementsInScope .OfType <Type>() .FirstOrDefault(tp => String.Equals(tp.Name, typeOfVariable, StringComparison.InvariantCultureIgnoreCase)); for (int i = 1; i < elements.Count; i++) { if (currentType == null) { break; } var propertyName = elements[i]; var property = GetElementsOfType(currentType).FirstOrDefault(vf => String.Equals(vf.Name, propertyName, StringComparison.InvariantCultureIgnoreCase)); typeOfVariable = property.TypeString; currentType = codeElementsInScope .OfType <Type>() .FirstOrDefault(tp => String.Equals(tp.Name, typeOfVariable, StringComparison.InvariantCultureIgnoreCase)); } if (currentType == null) { codeCompleteOptions = new INameable[] { } } ; else { codeCompleteOptions = GetElementsOfType(currentType).Cast <INameable>().ToList(); } session.InsertionIndexInLine = beginOfStatement; } // gather all results var completionItems = codeCompleteOptions.Select(e => new CompletionItem(e.Name, FortranIconProvider.GetIconForMember(e)) { ToolTip = GetTooltipForMember(currentMember, e) }).ToList(); if (addLanguageKeywords) { foreach (var keyword in fortranKeywords) { completionItems.Add(new CompletionItem(keyword, null)); } foreach (var intrinsic in fortranIntrinsics) { completionItems.Add(new CompletionItem(intrinsic.Key, IntrinsicIcon) { ToolTip = intrinsic.Value }); } } {//YK, 2020, also add all the words already in this current file //check file content. var myFileContents = VisualStudio.GetCurrentCodeFileContent(); { ////two methods to replace \t, \n, \r, tested and works //myFileContents = Regex.Replace(myFileContents, @"\t", " "); ////myFileContents = myFileContents.Replace("\t", " "); //myFileContents = myFileContents.Replace("\r", " "); //myFileContents = myFileContents.Replace("\n", " "); } {//example to remove separator... //char[] separators = new char[] { ' ', ';', ',', '\r', '\t', '\n', '(', ')', '!', ':', '=', '+', '*', '/' }; //string s = "replace;multiple,characters\tin;a,c\rsharp,string"; //string[] temp = s.Split(separators, StringSplitOptions.RemoveEmptyEntries); //s = String.Join("\n", temp); } {//example to remove duplicated string //String[] a = { "1", "1", "2", "1", "1", "3", "1", "1", }; //Console.WriteLine("原数组长度: {0}", a.Length); //Console.WriteLine("排除后数组长度:{0}", a.Distinct<string>().ToArray().Length); //Console.ReadKey(); } char[] separators = new char[] { ' ', ';', ',', '\r', '\t', '\n', '(', ')', '!', ':', '=', '+', '-', '*', '/', '&', '.', '\'', '<', '>', '{', '}', '[', ']', '$', '%', '?' }; string s = myFileContents; string[] myFileContentSplittedStr = myFileContents.Split(separators, StringSplitOptions.RemoveEmptyEntries); string[] myFileContentSplittedStrDistinct = myFileContentSplittedStr.Distinct <string>().ToArray(); foreach (var keyword in myFileContentSplittedStrDistinct) { //{//example to add non-duplicated string // //if (!listString.Contains(eachString)) // // listString.Add(eachString); //} completionItems.Add(new CompletionItem(keyword, null)); } } session.SetCompletionSet(completionItems, filter); } catch (Exception e) { Log.Error("Error while updating code complete", e); } finally { ParseQueueProcessor.ShowProgressDialog = true; //messes with intellisense popup } }