public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (XSharpProjectPackage.Instance.DebuggerIsRunning) { return; } try { XSharpModel.ModelWalker.Suspend(); var package = XSharp.Project.XSharpProjectPackage.Instance; var optionsPage = package.GetIntellisenseOptionsPage(); if (optionsPage.DisableQuickInfo) { return; } // Map the trigger point down to our buffer. SnapshotPoint?subjectTriggerPoint = session.GetTriggerPoint(_subjectBuffer.CurrentSnapshot); if (!subjectTriggerPoint.HasValue) { return; } ITextSnapshot currentSnapshot = subjectTriggerPoint.Value.Snapshot; WriteOutputMessage($"Triggerpoint: {subjectTriggerPoint.Value.Position}"); if ((subjectTriggerPoint.Value.Position == lastTriggerPoint) && (lastVersion == currentSnapshot.Version.VersionNumber)) { if (lastHelp != null) { var description = new TextBlock(); description.Inlines.AddRange(lastHelp); qiContent.Add(description); if (lastxmldoc != null) { qiContent.Add(lastxmldoc); } WriteOutputMessage($"Return last help content: {lastHelp}"); } if (lastSpan != null) { applicableToSpan = lastSpan; } return; } // We don't want to lex the buffer. So get the tokens from the last lex run // and when these are too old, then simply bail out var tokens = _subjectBuffer.GetTokens(); if (tokens != null) { if (tokens.SnapShot.Version != currentSnapshot.Version) { return; } } lastTriggerPoint = subjectTriggerPoint.Value.Position; //look for occurrences of our QuickInfo words in the span ITextStructureNavigator navigator = _provider.NavigatorService.GetTextStructureNavigator(_subjectBuffer); TextExtent extent = navigator.GetExtentOfWord(subjectTriggerPoint.Value); string searchText = extent.Span.GetText(); // First, where are we ? int caretPos = subjectTriggerPoint.Value.Position; int lineNumber = subjectTriggerPoint.Value.GetContainingLine().LineNumber; var snapshot = session.TextView.TextBuffer.CurrentSnapshot; if (_file == null) { return; } // Then, the corresponding Type/Element if possible IToken stopToken; //ITokenStream tokenStream; XSharpModel.XTypeMember member = XSharpLanguage.XSharpTokenTools.FindMember(lineNumber, _file); XSharpModel.XType currentNamespace = XSharpLanguage.XSharpTokenTools.FindNamespace(caretPos, _file); // adjust caretpos, for other completions we need to stop before the caret. Now we include the caret List <String> tokenList = XSharpLanguage.XSharpTokenTools.GetTokenList(caretPos + 1, lineNumber, tokens.TokenStream, out stopToken, true, _file, false, member); // Check if we can get the member where we are //if (tokenList.Count > 1) //{ // tokenList.RemoveRange(0, tokenList.Count - 1); //} // LookUp for the BaseType, reading the TokenList (From left to right) XSharpLanguage.CompletionElement gotoElement; String currentNS = ""; if (currentNamespace != null) { currentNS = currentNamespace.Name; } XSharpModel.CompletionType cType = XSharpLanguage.XSharpTokenTools.RetrieveType(_file, tokenList, member, currentNS, stopToken, out gotoElement, snapshot, lineNumber, _file.Project.Dialect); // // if ((gotoElement != null) && (gotoElement.IsInitialized)) { IClassificationType kwType = _registry.GetClassificationType("keyword"); IClassificationFormatMap fmap = _formatMap.GetClassificationFormatMap(category: "text"); Microsoft.VisualStudio.Text.Formatting.TextFormattingRunProperties kwFormat = fmap.GetTextProperties(kwType); kwType = _registry.GetClassificationType("text"); fmap = _formatMap.GetClassificationFormatMap(category: "text"); Microsoft.VisualStudio.Text.Formatting.TextFormattingRunProperties txtFormat = fmap.GetTextProperties(kwType); // // Ok, find it ! Let's go ;) applicableToSpan = currentSnapshot.CreateTrackingSpan ( extent.Span.Start, searchText.Length, SpanTrackingMode.EdgeInclusive ); if (gotoElement.XSharpElement != null) { if (gotoElement.XSharpElement.Kind == XSharpModel.Kind.Constructor) { if (gotoElement.XSharpElement.Parent != null) { var xtype = gotoElement.XSharpElement.Parent as XType; var qitm = new QuickInfoTypeAnalysis(xtype, kwFormat.ForegroundBrush, txtFormat.ForegroundBrush); var description = new TextBlock(); description.Inlines.AddRange(qitm.WPFDescription); qiContent.Add(description); } } else if (gotoElement.XSharpElement is XSharpModel.XTypeMember) { QuickInfoTypeMember qitm = new QuickInfoTypeMember((XSharpModel.XTypeMember)gotoElement.XSharpElement, kwFormat.ForegroundBrush, txtFormat.ForegroundBrush); var description = new TextBlock(); description.Inlines.AddRange(qitm.WPFDescription); qiContent.Add(description); } else if (gotoElement.XSharpElement is XSharpModel.XVariable) { QuickInfoVariable qitm = new QuickInfoVariable((XSharpModel.XVariable)gotoElement.XSharpElement, kwFormat.ForegroundBrush, txtFormat.ForegroundBrush); var description = new TextBlock(); description.Inlines.AddRange(qitm.WPFDescription); qiContent.Add(description); } else if (gotoElement.XSharpElement is XSharpModel.XType) { var xtype = gotoElement.XSharpElement as XType; var qitm = new QuickInfoTypeAnalysis(xtype, kwFormat.ForegroundBrush, txtFormat.ForegroundBrush); var description = new TextBlock(); description.Inlines.AddRange(qitm.WPFDescription); qiContent.Add(description); } else { var description = new TextBlock(); Run temp; temp = new Run(gotoElement.XSharpElement.Description); temp.Foreground = txtFormat.ForegroundBrush; // description.Inlines.Add(temp); qiContent.Add(description); } } else if (gotoElement.SystemElement is TypeInfo) { var ti = gotoElement.SystemElement as TypeInfo; string xmldoc = XSharpXMLDocMember.GetTypeSummary(ti, member.File.Project); QuickInfoTypeAnalysis analysis = new QuickInfoTypeAnalysis(ti, kwFormat.ForegroundBrush, txtFormat.ForegroundBrush); var description = new TextBlock(); description.Inlines.AddRange(analysis.WPFDescription); qiContent.Add(description); if (xmldoc != null) { qiContent.Add(xmldoc); } } else { // This works with System.MemberInfo AND QuickInfoMemberAnalysis analysis = null; if (gotoElement.SystemElement is MemberInfo) { string xmldoc = XSharpXMLDocMember.GetMemberSummary(gotoElement.SystemElement, member.File.Project); analysis = new QuickInfoMemberAnalysis(gotoElement.SystemElement, kwFormat.ForegroundBrush, txtFormat.ForegroundBrush); if (analysis.IsInitialized) { if ((analysis.Kind == XSharpModel.Kind.Constructor) && (cType != null) && (cType.SType != null)) { QuickInfoTypeAnalysis typeAnalysis; typeAnalysis = new QuickInfoTypeAnalysis(cType.SType.GetTypeInfo(), kwFormat.ForegroundBrush, txtFormat.ForegroundBrush); if (typeAnalysis.IsInitialized) { var description = new TextBlock(); description.Inlines.AddRange(typeAnalysis.WPFDescription); qiContent.Add(description); } } else { var description = new TextBlock(); description.Inlines.AddRange(analysis.WPFDescription); qiContent.Add(description); } if (xmldoc != null) { qiContent.Add(xmldoc); } } } } if (qiContent.Count > 0) { TextBlock description; description = qiContent[0] as TextBlock; if (qiContent.Count > 1) { lastxmldoc = qiContent[1] as String; } else { lastxmldoc = null; } if (description != null) { lastHelp = new Inline[description.Inlines.Count]; description.Inlines.CopyTo(lastHelp, 0); lastSpan = applicableToSpan; lastVersion = currentSnapshot.Version.VersionNumber; WriteOutputMessage($"Found new help content: {lastHelp}"); } } return; } } catch (Exception ex) { XSharpProjectPackage.Instance.DisplayOutPutMessage("XSharpQuickInfo.AugmentQuickInfoSession failed : "); XSharpProjectPackage.Instance.DisplayException(ex); } finally { XSharpModel.ModelWalker.Resume(); } }
private XSharpVsSignature CreateSignature(ITextBuffer textBuffer, IXMember member, string methodSig, string methodDoc, ITrackingSpan span, bool comma, bool isCtor, XFile file) { var doc = methodDoc; string returns; string remarks; if (member != null) { doc = XSharpXMLDocMember.GetMemberSummary(member, file.Project, out returns, out remarks); } Debug("XSharpSignatureHelpSource.CreateSignature()"); var sig = new XSharpVsSignature(textBuffer, methodSig, doc, null); var names = new List <String>(); var descriptions = new List <String>(); if (member != null) { XSharpXMLDocMember.GetMemberParameters(member, file.Project, names, descriptions); } // Moved : Done in the XSharpSignature constructor // textBuffer.Changed += new EventHandler<TextContentChangedEventArgs>(sig.OnSubjectBufferChanged); // find the parameters in the method signature : // MyMethod( param1 AS TYPE1, param2 AS TYPE2 ) AS TYPE3 will turn to // 0 : MyMethod // 1 : param1 AS TYPE1 // 2 : param2 AS TYPE2 // 3 : AS TYPE3 string[] pars; if (isCtor) { pars = methodSig.Split(new char[] { '{', ',', '}' }); } else { pars = methodSig.Split(new char[] { '(', ',', ')' }); } List <IParameter> paramList = new List <IParameter>(); int locusSearchStart = 0; // i = 1 to skip the MethodName; Length-1 to Skip the ReturnType while (names.Count < pars.Length) { names.Add(""); descriptions.Add(""); } for (int i = 1; i < pars.Length - 1; i++) { string param = pars[i].Trim(); if (string.IsNullOrEmpty(param)) { continue; } //find where this parameter is located in the method signature int locusStart = methodSig.IndexOf(param, locusSearchStart); if (locusStart >= 0) { Span locus = new Span(locusStart, param.Length); locusSearchStart = locusStart + param.Length; // paramList.Add(new XSharpParameter("Documentation for the parameter.", locus, param, sig)); if (!string.IsNullOrEmpty(names[i - 1])) { param = names[i - 1]; } paramList.Add(new XSharpVsParameter(descriptions[i - 1], locus, param, sig)); } } sig.Parameters = new ReadOnlyCollection <IParameter>(paramList); sig.ApplicableToSpan = span; sig.ComputeCurrentParameter(); return(sig); }
private void initDescription(XEntityDefinition member) //, _VSOBJDESCOPTIONS flags, IVsObjectBrowserDescription3 description) { description = new List <Tuple <string, VSOBDESCRIPTIONSECTION> >(); // string descText = this.Name; // string namesp = ""; string className = ""; if (member != null) { if (member.Parent != null) { if (member.Parent is IXType) { namesp = ((IXType)member.Parent).Namespace; className = ((IXType)member.Parent).Name; } } // string modifier = ""; string access = ""; if ((member is XTypeDefinition) && (member.Kind != Kind.Namespace)) { modifier = member.Modifiers.ToDisplayString(); access = member.Visibility.ToDisplayString(); } else if ((member is XMemberDefinition) && ((member.Kind != Kind.Function) && (member.Kind != Kind.Procedure))) { modifier = member.Modifiers.ToDisplayString(); access = member.Visibility.ToDisplayString(); } // if (!String.IsNullOrEmpty(modifier)) { description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(modifier + " ", VSOBDESCRIPTIONSECTION.OBDS_ATTRIBUTE)); } // if (!String.IsNullOrEmpty(access)) { description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(access + " ", VSOBDESCRIPTIONSECTION.OBDS_ATTRIBUTE)); //description.AddDescriptionText3(access, VSOBDESCRIPTIONSECTION.OBDS_MISC, null); } // if (member.Kind != Kind.Field) { VSOBDESCRIPTIONSECTION descName = VSOBDESCRIPTIONSECTION.OBDS_MISC; descText = XSettings.FormatKeyword(member.Kind.DisplayName()) + " "; if (member.Kind == Kind.Constructor) { descName = VSOBDESCRIPTIONSECTION.OBDS_NAME; } description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(descText, descName)); //description.AddDescriptionText3(descText, VSOBDESCRIPTIONSECTION.OBDS_MISC, null); } if (member.Kind != Kind.Constructor) { descText = member.Name; description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(descText, VSOBDESCRIPTIONSECTION.OBDS_NAME)); } //description.AddDescriptionText3(descText, VSOBDESCRIPTIONSECTION.OBDS_NAME, null); // Parameters ? if (member.Kind.HasParameters()) { descText = "("; description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(descText, VSOBDESCRIPTIONSECTION.OBDS_MISC)); //description.AddDescriptionText3(descText, VSOBDESCRIPTIONSECTION.OBDS_MISC, null); XMemberDefinition realmember; XTypeDefinition type = member as XTypeDefinition; if (member.Kind == Kind.Delegate && type?.XMembers.Count > 0) { realmember = type.XMembers[0]; } else { realmember = member as XMemberDefinition; } if (realmember != null && realmember.HasParameters) { // int paramNum = 1; foreach (XVariable param in realmember.Parameters) { descText = param.Name; description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(descText, VSOBDESCRIPTIONSECTION.OBDS_PARAM)); descText = param.ParamTypeDesc; description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(descText, VSOBDESCRIPTIONSECTION.OBDS_MISC)); //description.AddDescriptionText3(descText, VSOBDESCRIPTIONSECTION.OBDS_PARAM, null); descText = param.TypeName; // IVsNavInfo navInfo = buildNavInfo(member.File, param.TypeName); // description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(descText, VSOBDESCRIPTIONSECTION.OBDS_TYPE)); //description.AddDescriptionText3(descText, VSOBDESCRIPTIONSECTION.OBDS_TYPE, navInfo); // Need a comma ? if (paramNum < realmember.ParameterCount) { paramNum++; descText = ","; description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(descText, VSOBDESCRIPTIONSECTION.OBDS_COMMA)); //description.AddDescriptionText3(descText, VSOBDESCRIPTIONSECTION.OBDS_COMMA, null); } } } descText = ")"; description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(descText, VSOBDESCRIPTIONSECTION.OBDS_MISC)); //description.AddDescriptionText3(descText, VSOBDESCRIPTIONSECTION.OBDS_MISC, null); } if (member.Kind.HasReturnType()) { descText = XLiterals.AsKeyWord; description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(descText, VSOBDESCRIPTIONSECTION.OBDS_MISC)); //description.AddDescriptionText3(descText, VSOBDESCRIPTIONSECTION.OBDS_MISC, null); descText = member.TypeName; description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(descText, VSOBDESCRIPTIONSECTION.OBDS_TYPE)); //description.AddDescriptionText3(descText, VSOBDESCRIPTIONSECTION.OBDS_TYPE, null); } // //if (!((member.Kind == Kind.Function) || (member.Kind == Kind.Procedure) || (member.Kind == Kind.VODLL)) && // ((member.Parent is XTypeDefinition) && (member.Parent.Kind == Kind.Class))) //{ // descText = " CLASS "; // description.Add(new Tuple<string, VSOBDESCRIPTIONSECTION>(descText, VSOBDESCRIPTIONSECTION.OBDS_MISC)); // //description.AddDescriptionText3(descText, VSOBDESCRIPTIONSECTION.OBDS_MISC, null); // descText = className; // description.Add(new Tuple<string, VSOBDESCRIPTIONSECTION>(descText, VSOBDESCRIPTIONSECTION.OBDS_TYPE)); // //description.AddDescriptionText3(descText, VSOBDESCRIPTIONSECTION.OBDS_TYPE, null); //} // description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(null, VSOBDESCRIPTIONSECTION.OBDS_ENDDECL)); //description.AddDescriptionText3(null, VSOBDESCRIPTIONSECTION.OBDS_ENDDECL, null); } // if (member.File?.Project != null) { string summary = null, returns = null, remarks = null; List <string> pNames = new List <string>(); List <string> pDescriptions = new List <string>(); if (member is XMemberDefinition) { summary = XSharpXMLDocMember.GetMemberSummary((XMemberDefinition)member, member.File?.Project, out returns, out remarks); XSharpXMLDocMember.GetMemberParameters((XMemberDefinition)member, member.File?.Project, pNames, pDescriptions); } else if (member is XTypeDefinition) { summary = XSharpXMLDocMember.GetTypeSummary((XTypeDefinition)member, member.File?.Project, out returns, out remarks); } if (!String.IsNullOrEmpty(summary)) { description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>("\n", VSOBDESCRIPTIONSECTION.OBDS_MISC)); description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>("\nSummary:\n", VSOBDESCRIPTIONSECTION.OBDS_NAME)); description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(summary, VSOBDESCRIPTIONSECTION.OBDS_MISC)); } if (pNames.Count > 0) { description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>("\n", VSOBDESCRIPTIONSECTION.OBDS_MISC)); description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>("\nParameters:", VSOBDESCRIPTIONSECTION.OBDS_NAME)); for (int i = 0; i < pNames.Count; i++) { description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>("\n" + pNames[i], VSOBDESCRIPTIONSECTION.OBDS_PARAM)); description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(" : ", VSOBDESCRIPTIONSECTION.OBDS_MISC)); description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(pDescriptions[i], VSOBDESCRIPTIONSECTION.OBDS_MISC)); } } if (!String.IsNullOrEmpty(returns)) { description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>("\n", VSOBDESCRIPTIONSECTION.OBDS_MISC)); description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>("\nReturn:\n", VSOBDESCRIPTIONSECTION.OBDS_NAME)); description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(returns, VSOBDESCRIPTIONSECTION.OBDS_MISC)); } if (!String.IsNullOrEmpty(remarks)) { description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>("\n", VSOBDESCRIPTIONSECTION.OBDS_MISC)); description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>("\nRemarks:\n", VSOBDESCRIPTIONSECTION.OBDS_NAME)); description.Add(new Tuple <string, VSOBDESCRIPTIONSECTION>(remarks, VSOBDESCRIPTIONSECTION.OBDS_MISC)); } } }