private async Task UpdateDescription() { HideDescription(); if (SelectedItemIndex == -1) { return; } var completionItem = SelectedItem; var token = descriptionCts.Token; TooltipInformation description = null; try { var document = _subjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChangesSafe(); description = await RoslynCompletionData.CreateTooltipInformation(document, completionItem, false, token); Runtime.CheckMainThread(); } catch { } if (token.IsCancellationRequested || completionItem != SelectedItem) { return; } ShowDescription(description); }
protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var model = ctx.SemanticModel; var tree = ctx.SyntaxTree; if (tree.IsInNonUserCode(completionContext.Position, cancellationToken)) { return(Enumerable.Empty <CompletionData> ()); } var token = tree.FindTokenOnLeftOfPosition(completionContext.Position, cancellationToken); if (token.IsMandatoryNamedParameterPosition()) { return(Enumerable.Empty <CompletionData> ()); } var result = new List <CompletionData> (); foreach (var _type in ctx.InferredTypes) { var type = _type; if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) { type = type.GetTypeArguments().FirstOrDefault(); if (type == null) { continue; } } if (type.TypeKind != TypeKind.Enum) { continue; } if (!type.IsEditorBrowsable()) { continue; } // Does type have any aliases? ISymbol alias = await type.FindApplicableAlias(completionContext.Position, model, cancellationToken).ConfigureAwait(false); if (string.IsNullOrEmpty(completionResult.DefaultCompletionString)) { completionResult.DefaultCompletionString = type.Name; } result.Add(engine.Factory.CreateSymbolCompletionData(this, type, RoslynCompletionData.SafeMinimalDisplayString(type, model, completionContext.Position, SymbolDisplayFormat.CSharpErrorMessageFormat))); foreach (IFieldSymbol field in type.GetMembers().OfType <IFieldSymbol>()) { if (field.DeclaredAccessibility == Accessibility.Public && (field.IsConst || field.IsStatic)) { result.Add(engine.Factory.CreateEnumMemberCompletionData(this, alias, field)); } } } return(result); }
private async Task UpdateDescription() { if (descriptionWindow != null) { descriptionWindow.Destroy(); descriptionWindow = null; } descriptionCts.Cancel(); if (SelectedItemIndex == -1) { return; } var completionItem = SelectedItem; descriptionCts = new CancellationTokenSource(); var token = descriptionCts.Token; TooltipInformation description = null; try { var document = _subjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChangesSafe(); description = await RoslynCompletionData.CreateTooltipInformation(document, completionItem, false, token); } catch { } if (token.IsCancellationRequested) { return; } if (descriptionWindow != null) { descriptionWindow.Destroy(); descriptionWindow = null; } if (description == null) { return; } var window = new TooltipInformationWindow(); window.AddOverload(description); descriptionWindow = window; ShowDescription(); }
public void TestCache() { var types = new HashSet <string> (RoslynCompletionData.roslynCompletionTypeTable.Values); var mods = new HashSet <string> (RoslynCompletionData.modifierTypeTable.Values); var hashes = new Dictionary <int, string> (); foreach (var type in types) { foreach (var mod in mods) { var hash = RoslynCompletionData.CalculateHashCode(mod, type); var id = mod + type; if (hashes.ContainsKey(hash)) { Assert.Fail("Hash is already there: " + id + " equals " + hashes[hash]); } hashes.Add(hash, id); } } System.Console.WriteLine(hashes.Count); }
// // void AppendBraceStart (StringBuilder result, BraceStyle braceStyle) // { // switch (braceStyle) { // case BraceStyle.BannerStyle: // case BraceStyle.EndOfLine: // result.Append (" {"); // AppendLine (result); // break; // case BraceStyle.EndOfLineWithoutSpace: // result.Append ("{"); // AppendLine (result); // break; // case BraceStyle.NextLine: // AppendLine (result); // AppendIndent (result); // result.Append ("{"); // AppendLine (result); // break; // case BraceStyle.NextLineShifted: // AppendLine (result); // result.Append (GetIndent (IndentLevel + 1)); // result.Append ("{"); // AppendLine (result); // break; // case BraceStyle.NextLineShifted2: // AppendLine (result); // result.Append (GetIndent (IndentLevel + 1)); // result.Append ("{"); // AppendLine (result); // IndentLevel++; // break; // default: // goto case BraceStyle.NextLine; // } // IndentLevel++; // } // // void AppendBraceEnd (StringBuilder result, BraceStyle braceStyle) // { // switch (braceStyle) { // case BraceStyle.EndOfLineWithoutSpace: // case BraceStyle.NextLine: // case BraceStyle.EndOfLine: // IndentLevel --; // AppendIndent (result); // result.Append ("}"); // break; // case BraceStyle.BannerStyle: // case BraceStyle.NextLineShifted: // AppendIndent (result); // result.Append ("}"); // IndentLevel--; // break; // case BraceStyle.NextLineShifted2: // IndentLevel--; // AppendIndent (result); // result.Append ("}"); // IndentLevel--; // break; // default: // goto case BraceStyle.NextLine; // } // } // // void AppendIndent (StringBuilder result) // { // result.Append (GetIndent (IndentLevel)); // } // static void AppendReturnType(StringBuilder result, CodeGenerationOptions options, ITypeSymbol type) { if (type == null) { throw new ArgumentNullException("type"); } result.Append(RoslynCompletionData.SafeMinimalDisplayString(type, options.SemanticModel, options.Part.SourceSpan.Start, Ambience.LabelFormat)); // var implementingType = options.Part; // var loc = implementingType.Region.End; // // var pf = implementingType.UnresolvedFile; // var file = pf as CSharpUnresolvedFile; // var resolved = type; // if (resolved.Kind == TypeKind.Unknown) { // result.Append (type.FullName); // return; // } // var def = type.GetDefinition (); // if (def != null) { // using (var stringWriter = new System.IO.StringWriter ()) { // var formatter = new TextWriterTokenWriter (stringWriter); // stringWriter.NewLine = EolMarker; // var visitor = new CSharpOutputVisitor (formatter, FormattingOptionsFactory.CreateMono ()); // var shortType = CreateShortType (def.Compilation, file, loc, resolved); // shortType.AcceptVisitor (visitor); // // var typeString = stringWriter.ToString (); // if (typeString.StartsWith ("global::")) // typeString = typeString.Substring ("global::".Length); // result.Append (typeString); // } // } else { // result.Append (new ICSharpCode.NRefactory.CSharp.CSharpAmbience ().ConvertType (type)); // } }
public string GetShortType(string ns, string name, int typeArguments = 0) { if (DocumentContext == null || Editor == null || SemanticModel == null || DocumentContext.ParsedDocument == null) { return(ns + "." + name); } var model = DocumentContext.ParsedDocument.GetAst <SemanticModel>(); if (model == null) { return(ns + "." + name); } var type = model.Compilation.GetTypeByMetadataName(ns + "." + name); if (type == null) { return(ns + "." + name); } return(RoslynCompletionData.SafeMinimalDisplayString(type, model, Editor.CaretOffset, Ambience.LabelFormat)); }
protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var model = ctx.SemanticModel; var tree = ctx.SyntaxTree; if (tree.IsInNonUserCode(completionContext.Position, cancellationToken)) { return(Enumerable.Empty <CompletionData> ()); } var token = tree.FindTokenOnLeftOfPosition(completionContext.Position, cancellationToken); if (token.IsKind(SyntaxKind.DotToken) || token.IsMandatoryNamedParameterPosition()) { return(Enumerable.Empty <CompletionData> ()); } var result = new List <CompletionData> (); // check if it's the first parameter and set autoselect == false if a parameterless version exists. if (token.IsKind(SyntaxKind.OpenParenToken)) { var parent = token.Parent?.Parent; if (parent == null) { return(Enumerable.Empty <CompletionData> ()); } var symbolInfo = model.GetSymbolInfo(parent); foreach (var symbol in new [] { symbolInfo.Symbol }.Concat(symbolInfo.CandidateSymbols)) { if (symbol != null && symbol.IsKind(SymbolKind.Method)) { if (symbol.GetParameters().Length == 0) { completionResult.AutoSelect = false; break; } } } } foreach (var _type in ctx.InferredTypes) { var type = _type; if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) { type = type.GetTypeArguments().FirstOrDefault(); if (type == null) { continue; } } if (type.TypeKind != TypeKind.Enum) { continue; } if (!type.IsEditorBrowsable()) { continue; } // Does type have any aliases? ISymbol alias = await type.FindApplicableAlias(completionContext.Position, model, cancellationToken).ConfigureAwait(false); var displayString = RoslynCompletionData.SafeMinimalDisplayString(type, model, completionContext.Position, SymbolDisplayFormat.CSharpErrorMessageFormat); if (string.IsNullOrEmpty(completionResult.DefaultCompletionString)) { completionResult.DefaultCompletionString = displayString; completionResult.AutoCompleteEmptyMatch = true; } if (!IsReachable(model, type, token.Parent)) { result.Add(engine.Factory.CreateSymbolCompletionData(this, type, displayString)); } foreach (IFieldSymbol field in type.GetMembers().OfType <IFieldSymbol> ()) { if (field.DeclaredAccessibility == Accessibility.Public && (field.IsConst || field.IsStatic)) { result.Add(engine.Factory.CreateEnumMemberCompletionData(this, alias, field)); } } } return(result); }
void AddDelegateHandlers(List <CompletionData> completionList, SyntaxNode parent, SemanticModel semanticModel, CompletionEngine engine, CompletionResult result, ITypeSymbol delegateType, int position, string optDelegateName, CancellationToken cancellationToken) { var delegateMethod = delegateType.GetDelegateInvokeMethod(); result.PossibleDelegates.Add(delegateMethod); var thisLineIndent = ""; string EolMarker = "\n"; bool addSemicolon = true; bool addDefault = true; string delegateEndString = EolMarker + thisLineIndent + "}" + (addSemicolon ? ";" : ""); //bool containsDelegateData = completionList.Result.Any(d => d.DisplayText.StartsWith("delegate(")); CompletionData item; if (addDefault) { item = engine.Factory.CreateAnonymousMethod( this, "delegate", "Creates anonymous delegate.", "delegate {" + EolMarker + thisLineIndent, delegateEndString ); if (!completionList.Any(i => i.DisplayText == item.DisplayText)) { completionList.Add(item); } //if (LanguageVersion.Major >= 5) item = engine.Factory.CreateAnonymousMethod( this, "async delegate", "Creates anonymous async delegate.", "async delegate {" + EolMarker + thisLineIndent, delegateEndString ); if (!completionList.Any(i => i.DisplayText == item.DisplayText)) { completionList.Add(item); } } var sb = new StringBuilder("("); var sbWithoutTypes = new StringBuilder("("); for (int k = 0; k < delegateMethod.Parameters.Length; k++) { if (k > 0) { sb.Append(", "); sbWithoutTypes.Append(", "); } sb.Append(RoslynCompletionData.SafeMinimalDisplayString(delegateMethod.Parameters [k], semanticModel, position, overrideNameFormat)); sbWithoutTypes.Append(delegateMethod.Parameters [k].Name); } sb.Append(")"); sbWithoutTypes.Append(")"); var signature = sb.ToString() .Replace(", params ", ", ") .Replace("(params ", "("); if (completionList.All(data => data.DisplayText != signature)) { item = engine.Factory.CreateAnonymousMethod( this, signature + " =>", "Creates typed lambda expression.", signature + " => ", (addSemicolon ? ";" : "") ); if (!completionList.Any(i => i.DisplayText == item.DisplayText)) { completionList.Add(item); } // if (LanguageVersion.Major >= 5) { item = engine.Factory.CreateAnonymousMethod( this, "async " + signature + " =>", "Creates typed async lambda expression.", "async " + signature + " => ", (addSemicolon ? ";" : "") ); if (!completionList.Any(i => i.DisplayText == item.DisplayText)) { completionList.Add(item); } var signatureWithoutTypes = sbWithoutTypes.ToString(); if (!delegateMethod.Parameters.Any(p => p.RefKind != RefKind.None) && completionList.All(data => data.DisplayText != signatureWithoutTypes)) { item = engine.Factory.CreateAnonymousMethod( this, signatureWithoutTypes + " =>", "Creates typed lambda expression.", signatureWithoutTypes + " => ", (addSemicolon ? ";" : "") ); if (!completionList.Any(i => i.DisplayText == item.DisplayText)) { completionList.Add(item); } //if (LanguageVersion.Major >= 5) { item = engine.Factory.CreateAnonymousMethod( this, "async " + signatureWithoutTypes + " =>", "Creates typed async lambda expression.", "async " + signatureWithoutTypes + " => ", (addSemicolon ? ";" : "") ); if (!completionList.Any(i => i.DisplayText == item.DisplayText)) { completionList.Add(item); } //} } } string varName = optDelegateName ?? "Handle" + delegateType.Name; var curType = semanticModel.GetEnclosingSymbol <INamedTypeSymbol> (position, cancellationToken); var uniqueName = new UniqueNameGenerator(semanticModel).CreateUniqueMethodName(parent, varName); item = engine.Factory.CreateNewMethodDelegate(this, delegateType, uniqueName, curType); if (!completionList.Any(i => i.DisplayText == item.DisplayText)) { completionList.Add(item); } }
public string CreateShortType(ITypeSymbol fullType) { return(RoslynCompletionData.SafeMinimalDisplayString(fullType, CurrentState, offset)); }
public static TypeSyntax ConvertType(SemanticModel model, int position, ITypeSymbol type) { return(SyntaxFactory.ParseTypeName(RoslynCompletionData.SafeMinimalDisplayString(type, model, position))); }
protected override bool OnExposeEvent(Gdk.EventExpose args) { bool needsRefresh = false; using (var context = Gdk.CairoHelper.Create(args.Window)) { var scalef = GtkWorkarounds.GetScaleFactor(this); context.LineWidth = 1; var alloc = Allocation; int width = alloc.Width; int height = alloc.Height; context.Rectangle(args.Area.X, args.Area.Y, args.Area.Width, args.Area.Height); var backgroundColor = Styles.CodeCompletion.BackgroundColor.ToCairoColor(); var textColor = Styles.CodeCompletion.TextColor.ToCairoColor(); var categoryColor = Styles.CodeCompletion.CategoryColor.ToCairoColor(); context.SetSourceColor(backgroundColor); context.Fill(); int xpos = iconTextSpacing; int yPos = (int)-vadj.Value; //when there are no matches, display a message to indicate that the completion list is still handling input if (filteredItems.Count == 0) { context.Rectangle(0, yPos, width, height - yPos); context.SetSourceColor(backgroundColor); context.Stroke(); //TODO: David, line below is simplified noMatchLayout.SetText (DataProvider.ItemCount == 0 ? NoSuggestionsMsg : NoMatchesMsg); noMatchLayout.SetText(NoSuggestionsMsg); int lWidth, lHeight; noMatchLayout.GetPixelSize(out lWidth, out lHeight); context.SetSourceColor(textColor); context.MoveTo((width - lWidth) / 2, yPos + (height - lHeight - yPos) / 2 - lHeight / 2); Pango.CairoHelper.ShowLayout(context, noMatchLayout); return(false); } Iterate(true, ref yPos, delegate(int index, int itemidx, int ypos) { if (ypos >= height) { return(false); } if (ypos < -rowHeight) { return(true); } xpos = iconTextSpacing; var selected = index == SelectedItemIndex; bool drawIconAsSelected = SelectionEnabled && selected; var item = filteredItems [index]; string markup = GLib.Markup.EscapeText(item.DisplayText); string description = ""; //TODO: David DataProvider.GetDescription (item, drawIconAsSelected); if (string.IsNullOrEmpty(description)) { layout.SetMarkup(markup); } else { layout.SetMarkup(markup + " " + description); } string text = item.DisplayText; //TODO: David, where do we get HighlightedSpans? //if (!string.IsNullOrEmpty (text) && item.HighlightedSpans.Any ()) { // Pango.AttrList attrList = layout.Attributes ?? new Pango.AttrList (); // foreach (var span in item.HighlightedSpans) { // var bold = new AttrWeight (Weight.Bold); // bold.StartIndex = (uint)span.Start; // bold.EndIndex = (uint)span.End; // attrList.Insert (bold); // if (!selected) { // var highlightColor = (selected) ? Styles.CodeCompletion.SelectionHighlightColor : Styles.CodeCompletion.HighlightColor; // var fg = new AttrForeground ((ushort)(highlightColor.Red * ushort.MaxValue), (ushort)(highlightColor.Green * ushort.MaxValue), (ushort)(highlightColor.Blue * ushort.MaxValue)); // fg.StartIndex = (uint)span.Start; // fg.EndIndex = (uint)span.End; // attrList.Insert (fg); // } // } // layout.Attributes = attrList; //} //TODO: Todd, can you sprinkle some magic on this to do //textView.GetTextBufferFromSpan(triggerSpan).GetMimeType() instead fixed text/csharp? Xwt.Drawing.Image icon = ImageService.GetIcon(RoslynCompletionData.GetIcon(item, "text/csharp")); int iconHeight, iconWidth; if (icon != null) { if (drawIconAsSelected) { icon = icon.WithStyles("sel"); } iconWidth = (int)icon.Width; iconHeight = (int)icon.Height; } else if (!Gtk.Icon.SizeLookup(IconSize.Menu, out iconWidth, out iconHeight)) { iconHeight = iconWidth = 24; } int wi, he, typos, iypos; layout.GetPixelSize(out wi, out he); typos = he < rowHeight ? ypos + (int)Math.Ceiling((rowHeight - he) / 2.0) : ypos; if (scalef <= 1.0) { typos -= 1; // 1px up on non HiDPI } iypos = iconHeight < rowHeight ? ypos + (rowHeight - iconHeight) / 2 : ypos; if (selected) { var barStyle = SelectionEnabled ? Styles.CodeCompletion.SelectionBackgroundColor : Styles.CodeCompletion.SelectionBackgroundInactiveColor; context.SetSourceColor(barStyle.ToCairoColor()); if (SelectionEnabled) { context.Rectangle(0, ypos, Allocation.Width, rowHeight); context.Fill(); } else { context.LineWidth++; context.Rectangle(0.5, ypos + 0.5, Allocation.Width - 1, rowHeight - 1); context.Stroke(); context.LineWidth--; } } if (icon != null) { context.DrawImage(this, icon, xpos, iypos); xpos += iconTextSpacing; } context.SetSourceColor((drawIconAsSelected ? Styles.CodeCompletion.SelectionTextColor : Styles.CodeCompletion.TextColor).ToCairoColor()); var textXPos = xpos + iconWidth + 2; context.MoveTo(textXPos, typos); layout.Width = (int)((Allocation.Width - textXPos) * Pango.Scale.PangoScale); layout.Ellipsize = EllipsizeMode.End; Pango.CairoHelper.ShowLayout(context, layout); int textW, textH; layout.GetPixelSize(out textW, out textH); layout.Width = -1; layout.Ellipsize = EllipsizeMode.None; layout.SetMarkup(""); if (layout.Attributes != null) { layout.Attributes.Dispose(); layout.Attributes = null; } string rightText = ""; //TODO: David DataProvider.GetRightSideDescription (index, drawIconAsSelected); if (!string.IsNullOrEmpty(rightText)) { layout.SetMarkup(rightText); int w, h; layout.GetPixelSize(out w, out h); const int leftpadding = 8; const int rightpadding = 3; w += rightpadding; w = Math.Min(w, Allocation.Width - textXPos - textW - leftpadding); wi += w; typos = h < rowHeight ? ypos + (rowHeight - h) / 2 : ypos; if (scalef <= 1.0) { typos -= 1; // 1px up on non HiDPI } context.MoveTo(Allocation.Width - w, typos); layout.Width = (int)(w * Pango.Scale.PangoScale); layout.Ellipsize = EllipsizeMode.End; Pango.CairoHelper.ShowLayout(context, layout); layout.Width = -1; layout.Ellipsize = EllipsizeMode.None; } if (Math.Min(maxListWidth, wi + xpos + iconWidth + 2) > listWidth) { box.WidthRequest = listWidth = Math.Min(maxListWidth, wi + xpos + iconWidth + 2 + iconTextSpacing); needsRefresh = true; } else { //workaround for the vscrollbar display - the calculated width needs to be the width ofthe render region. if (Allocation.Width < listWidth) { if (listWidth - Allocation.Width < 30) { box.WidthRequest = listWidth + listWidth - Allocation.Width; needsRefresh = true; } } } return(true); }); if (needsRefresh) { QueueSpaceReservationStackRefresh(); } return(false); } }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var document = context.Document; var span = context.Span; var diagnostics = context.Diagnostics; var cancellationToken = context.CancellationToken; var project = document.Project; var diagnostic = diagnostics.First(); var model = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false); if (model.IsFromGeneratedCode(context.CancellationToken)) { return; } var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var node = root.FindToken(span.Start).GetAncestors <SyntaxNode>().First(n => n.Span.Contains(span)); // Has to be a simple identifier or generic name. if (node != null && CanFullyQualify(diagnostic, ref node)) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var matchingTypes = await this.GetMatchingTypesAsync(project, semanticModel, node, cancellationToken).ConfigureAwait(false); var matchingNamespaces = await this.GetMatchingNamespacesAsync(project, semanticModel, node, cancellationToken).ConfigureAwait(false); if (matchingTypes != null || matchingNamespaces != null) { matchingTypes = matchingTypes ?? SpecializedCollections.EmptyEnumerable <ISymbol>(); matchingNamespaces = matchingNamespaces ?? SpecializedCollections.EmptyEnumerable <ISymbol>(); var matchingTypeContainers = FilterAndSort(GetContainers(matchingTypes, semanticModel.Compilation)); var matchingNamespaceContainers = FilterAndSort(GetContainers(matchingNamespaces, semanticModel.Compilation)); var proposedContainers = matchingTypeContainers.Concat(matchingNamespaceContainers) .Distinct() .Take(8); foreach (var container in proposedContainers) { var containerName = RoslynCompletionData.SafeMinimalDisplayString(container, semanticModel, node.SpanStart); string name; int arity; node.GetNameAndArityOfSimpleName(out name, out arity); // Actual member name might differ by case. string memberName; if (this.IgnoreCase) { var member = container.GetMembers(name).FirstOrDefault(); memberName = member != null ? member.Name : name; } else { memberName = name; } var codeAction = new DocumentChangeAction( node.Span, DiagnosticSeverity.Info, string.Format(GettextCatalog.GetString("Change '{0}' to '{1}.{2}'"), name, containerName, memberName), (c) => { var newRoot = this.ReplaceNode(node, containerName, c); return(Task.FromResult(document.WithSyntaxRoot(newRoot))); }); context.RegisterCodeFix(codeAction, diagnostic); } } } }