{"action":"created","comment":{"url":"https://api.github.com/repos/dotnet/roslyn/pulls/comments/232510338","pull_request_review_id":173721254,"id":232510338,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIzMjUxMDMzOA==","diff_hunk":"@@ -0,0 +1,477 @@\n+﻿// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.\n+\n+using System;\n+using System.Collections.Generic;\n+using System.Collections.Immutable;\n+using System.Globalization;\n+using System.Linq;\n+using System.Threading;\n+using System.Threading.Tasks;\n+using Microsoft.CodeAnalysis;\n+using Microsoft.CodeAnalysis.Completion;\n+using Microsoft.CodeAnalysis.Editor.Shared.Utilities;\n+using Microsoft.CodeAnalysis.Shared.Extensions;\n+using Microsoft.CodeAnalysis.Text;\n+using Microsoft.CodeAnalysis.Text.Shared.Extensions;\n+using Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion;\n+using Microsoft.VisualStudio.Text;\n+using Roslyn.Utilities;\n+using AsyncCompletionData = Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion.Data;\n+using FilterResult = Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.Completion.Controller.Session.FilterResult;\n+using RoslynCompletionItem = Microsoft.CodeAnalysis.Completion.CompletionItem;\n+using Session = Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.Completion.Controller.Session;\n+using VSCompletionItem = Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion.Data.CompletionItem;\n+\n+namespace Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.Completion.AsyncCompletion\n+{\n+    internal class ItemManager : ForegroundThreadAffinitizedObject, IAsyncCompletionItemManager\n+    {\n+        private readonly CompletionHelper _completionHelper;\n+\n+        private const int MaxMRUSize = 10;\n+        private ImmutableArray<string> _recentItems = ImmutableArray<string>.Empty;\n+\n+        internal ItemManager(IThreadingContext threadingContext) : base(threadingContext)\n+        {\n+            _completionHelper = new CompletionHelper(isCaseSensitive: true);\n+        }\n+\n+        public Task<ImmutableArray<VSCompletionItem>> SortCompletionListAsync(\n+            IAsyncCompletionSession session,\n+            AsyncCompletionData.AsyncCompletionSessionInitialDataSnapshot data,\n+            CancellationToken cancellationToken)\n+        {\n+            AssertIsBackground();\n+\n+            SubscribeEvents(session);\n+            return Task.FromResult(data.InitialList.OrderBy(i => i.SortText).ToImmutableArray());\n+        }\n+\n+        public Task<AsyncCompletionData.FilteredCompletionModel> UpdateCompletionListAsync(\n+            IAsyncCompletionSession session,\n+            AsyncCompletionData.AsyncCompletionSessionDataSnapshot data,\n+            CancellationToken cancellationToken)\n+            => Task.FromResult(UpdateCompletionList(session, data, cancellationToken));\n+\n+        private AsyncCompletionData.FilteredCompletionModel UpdateCompletionList(\n+            IAsyncCompletionSession session,\n+            AsyncCompletionData.AsyncCompletionSessionDataSnapshot data,\n+            CancellationToken cancellationToken)\n+        {\n+            AssertIsBackground();\n+\n+            SubscribeEvents(session);\n+            if (!session.Properties.TryGetProperty(CompletionSource.HasSuggestionItemOptions, out bool hasSuggestedItemOptions))\n+            {\n+                // This is the scenario when the session is created out of Roslyn, in some other provider, e.g. in Debugger.\n+                // For now, the default hasSuggestedItemOptions is false. We can discuss if the opposite is required.\n+                hasSuggestedItemOptions = false;\n+            }\n+\n+            var filterText = session.ApplicableToSpan.GetText(data.Snapshot);\n+            var reason = data.Trigger.Reason;\n+\n+            // We do not care about the character in the case. We care about the reason only.\n+            var roslynTrigger = Helpers.GetRoslynTrigger(data.Trigger, data.Trigger.Character);\n+\n+            if (!session.Properties.TryGetProperty(CompletionSource.InitialTriggerKind, out CompletionTriggerKind initialRoslynTriggerKind))\n+            {\n+                initialRoslynTriggerKind = CompletionTriggerKind.Invoke;\n+            }\n+\n+            // Check if the user is typing a number. If so, only proceed if it's a number\n+            // directly after a <dot>. That's because it is actually reasonable for completion\n+            // to be brought up after a <dot> and for the user to want to filter completion\n+            // items based on a number that exists in the name of the item. However, when\n+            // we are not after a dot (i.e. we're being brought up after <space> is typed)\n+            // then we don't want to filter things. Consider the user writing:\n+            //\n+            //      dim i =<space>\n+            //\n+            // We'll bring up the completion list here (as VB has completion on <space>).\n+            // If the user then types '3', we don't want to match against Int32.\n+            if (filterText.Length > 0 && char.IsNumber(filterText[0]))\n+            {\n+                if (!IsAfterDot(data.Snapshot, session.ApplicableToSpan))\n+                {\n+                    session.Dismiss();\n+                    return null;\n+                }\n+            }\n+\n+            // We need to filter if a non-empty strict subset of filters are selected\n+            var selectedFilters = data.SelectedFilters.Where(f => f.IsSelected).Select(f => f.Filter).ToImmutableArray();\n+            var needToFilter = selectedFilters.Length > 0 && selectedFilters.Length < data.SelectedFilters.Length;\n+            var filterReason = Helpers.GetFilterReason(roslynTrigger);\n+\n+            var initialListOfItemsToBeIncluded = new List<ExtendedFilterResult>();\n+            foreach (var item in data.InitialSortedList)\n+            {\n+                cancellationToken.ThrowIfCancellationRequested();\n+\n+                if (needToFilter && ShouldBeFilteredOutOfCompletionList(item, selectedFilters))\n+                {\n+                    continue;\n+                }\n+\n+                if (!item.Properties.TryGetProperty(CompletionSource.RoslynItem, out RoslynCompletionItem roslynItem))\n+                {\n+                    roslynItem = RoslynCompletionItem.Create(\n+                        displayText: item.DisplayText, \n+                        filterText: item.FilterText, \n+                        sortText: item.SortText,\n+                        displayTextSuffix: item.Suffix);\n+                }\n+\n+                if (Session.MatchesFilterText(_completionHelper, roslynItem, filterText, initialRoslynTriggerKind, filterReason, _recentItems))\n+                {\n+                    initialListOfItemsToBeIncluded.Add(new ExtendedFilterResult(item, new FilterResult(roslynItem, filterText, matchedFilterText: true)));\n+                }\n+                else\n+                {\n+                    // The item didn't match the filter text.  We'll still keep it in the list\n+                    // if one of two things is true:\n+                    //\n+                    //  1. The user has only typed a single character.  In this case they might\n+                    //     have just typed the character to get completion.  Filtering out items\n+                    //     here is not desirable.\n+                    //\n+                    //  2. They brough up completion with ctrl-j or through deletion.  In these\n+                    //     cases we just always keep all the items in the list.\n+                    if (roslynTrigger.Kind == CompletionTriggerKind.Deletion ||\n+                        roslynTrigger.Kind == CompletionTriggerKind.Invoke ||\n+                        filterText.Length <= 1)\n+                    {\n+                        initialListOfItemsToBeIncluded.Add(new ExtendedFilterResult(item, new FilterResult(roslynItem, filterText, matchedFilterText: false)));\n+                    }\n+                }\n+            }\n+\n+            // If the session was created/maintained out of Roslyn, e.g. in debugger; no properties are set and we should use data.Snapshot.\n+            // However, we prefer using the original snapshot in some projection scenarios.\n+            var snapshotForDocument = data.InitialSortedList\n+                                          .FirstOrDefault(i => i.Properties.ContainsProperty(CompletionSource.TriggerSnapshot))?\n+                                          .Properties.GetProperty<ITextSnapshot>(CompletionSource.TriggerSnapshot)\n+                                          ?? data.Snapshot;\n+\n+            var document = snapshotForDocument.GetOpenDocumentInCurrentContextWithChanges();\n+            var completionService = document?.GetLanguageService<CompletionService>();\n+            var completionRules = completionService?.GetRules() ?? CompletionRules.Default;\n+\n+            if (data.Trigger.Reason == AsyncCompletionData.CompletionTriggerReason.Backspace &&\n+                completionRules.DismissIfLastCharacterDeleted &&\n+                session.ApplicableToSpan.GetText(data.Snapshot).Length == 0)\n+            {\n+                // Dismiss the session\n+                return null;\n+            }\n+\n+            if (initialListOfItemsToBeIncluded.Count == 0)\n+            {\n+                return HandleAllItemsFilteredOut(reason, data.SelectedFilters, selectedFilters.Any(), completionRules);\n+            }\n+\n+            var options = document?.Project?.Solution?.Options;\n+            var highlightMatchingPortions = options?.GetOption(CompletionOptions.HighlightMatchingPortionsOfCompletionListItems, document.Project.Language) ?? true;\n+            var showCompletionItemFilters = options?.GetOption(CompletionOptions.ShowCompletionItemFilters, document.Project.Language) ?? true;\n+\n+            var updatedFilters = showCompletionItemFilters\n+                ? GetUpdatedFilters(initialListOfItemsToBeIncluded, data.SelectedFilters)\n+                : ImmutableArray<AsyncCompletionData.CompletionFilterWithState>.Empty;\n+\n+            var highlightedList = GetHighlightedList(initialListOfItemsToBeIncluded, filterText, highlightMatchingPortions).ToImmutableArray();\n+\n+            // If this was deletion, then we control the entire behavior of deletion ourselves.\n+            if (initialRoslynTriggerKind == CompletionTriggerKind.Deletion)\n+            {\n+                return HandleDeletionTrigger(initialListOfItemsToBeIncluded, filterText, updatedFilters, highlightedList);\n+            }\n+\n+            Func<ImmutableArray<RoslynCompletionItem>, string, ImmutableArray<RoslynCompletionItem>> filterMethod;\n+            if (completionService == null)\n+            {\n+                filterMethod = (items, text) => CompletionService.FilterItems(_completionHelper, items, text);\n+            }\n+            else\n+            {\n+                filterMethod = (items, text) => completionService.FilterItems(document, items, text);\n+            }\n+\n+            return HandleNormalFiltering(\n+                filterMethod,\n+                filterText,\n+                updatedFilters,\n+                initialRoslynTriggerKind,\n+                filterReason,\n+                data.Trigger.Character,\n+                initialListOfItemsToBeIncluded,\n+                highlightedList,\n+                hasSuggestedItemOptions);\n+        }\n+\n+        private static bool IsAfterDot(ITextSnapshot snapshot, ITrackingSpan applicableToSpan)\n+        {\n+            var position = applicableToSpan.GetStartPoint(snapshot).Position;\n+            return position > 0 && snapshot[position - 1] == '.';\n+        }\n+\n+        private AsyncCompletionData.FilteredCompletionModel HandleNormalFiltering(\n+            Func<ImmutableArray<RoslynCompletionItem>, string, ImmutableArray<RoslynCompletionItem>> filterMethod,\n+            string filterText,\n+            ImmutableArray<AsyncCompletionData.CompletionFilterWithState> filters,\n+            CompletionTriggerKind initialRoslynTriggerKind,\n+            CompletionFilterReason filterReason,\n+            char typeChar,\n+            List<ExtendedFilterResult> itemsInList,\n+            ImmutableArray<AsyncCompletionData.CompletionItemWithHighlight> highlightedList,\n+            bool hasSuggestedItemOptions)\n+        {\n+            // Not deletion.  Defer to the language to decide which item it thinks best\n+            // matches the text typed so far.\n+\n+            // Ask the language to determine which of the *matched* items it wants to select.\n+            var matchingItems = itemsInList.Where(r => r.FilterResult.MatchedFilterText)\n+                                           .Select(t => t.FilterResult.CompletionItem)\n+                                           .AsImmutable();\n+\n+            var chosenItems = filterMethod(matchingItems, filterText);\n+\n+            var recentItems = _recentItems;\n+\n+            // Of the items the service returned, pick the one most recently committed\n+            var bestItem = Session.GetBestCompletionItemBasedOnMRU(chosenItems, recentItems);\n+            VSCompletionItem uniqueItem = null;\n+            int selectedItemIndex = 0;\n+\n+            // Determine if we should consider this item 'unique' or not.  A unique item\n+            // will be automatically committed if the user hits the 'invoke completion' \n+            // without bringing up the completion list.  An item is unique if it was the\n+            // only item to match the text typed so far, and there was at least some text\n+            // typed.  i.e.  if we have \"Console.$$\" we don't want to commit something\n+            // like \"WriteLine\" since no filter text has actually been provided.  HOwever,\n+            // if \"Console.WriteL$$\" is typed, then we do want \"WriteLine\" to be committed.\n+            if (bestItem != null)\n+            {\n+                selectedItemIndex = itemsInList.IndexOf(i => Equals(i.FilterResult.CompletionItem, bestItem));\n+                if (selectedItemIndex > -1 && bestItem != null && matchingItems.Length == 1 && filterText.Length > 0)\n+                {\n+                    uniqueItem = highlightedList[selectedItemIndex].CompletionItem;\n+                }\n+            }\n+\n+            // If we don't have a best completion item yet, then pick the first item from the list.\n+            var bestOrFirstCompletionItem = bestItem ?? itemsInList.First().FilterResult.CompletionItem;\n+\n+            // Check that it is a filter symbol. We can be called for a non-filter symbol.\n+            if (filterReason == CompletionFilterReason.Insertion &&\n+                !Controller.IsPotentialFilterCharacter(typeChar) &&\n+                !string.IsNullOrEmpty(filterText) &&\n+                !Controller.IsFilterCharacter(bestOrFirstCompletionItem, typeChar, filterText))\n+            {\n+                return null;\n+            }\n+\n+            var updateSelectionHint = Session.IsHardSelection(\n+                        filterText, initialRoslynTriggerKind, bestOrFirstCompletionItem,\n+                        _completionHelper, filterReason, recentItems, hasSuggestedItemOptions)\n+                        ? AsyncCompletionData.UpdateSelectionHint.Selected\n+                        : AsyncCompletionData.UpdateSelectionHint.SoftSelected;","path":"src/EditorFeatures/Core/Implementation/IntelliSense/AsyncCompletion/ItemManager.cs","position":278,"original_position":278,"commit_id":"6d35a6f0077e477206312062cda4d982c1ab0739","original_commit_id":"6d35a6f0077e477206312062cda4d982c1ab0739","user":{"login":"CyrusNajmabadi","id":4564579,"node_id":"MDQ6VXNlcjQ1NjQ1Nzk=","avatar_url":"https://avatars3.githubusercontent.com/u/4564579?v=4","gravatar_id":"","url":"https://api.github.com/users/CyrusNajmabadi","html_url":"https://github.com/CyrusNajmabadi","followers_url":"https://api.github.com/users/CyrusNajmabadi/followers","following_url":"https://api.github.com/users/CyrusNajmabadi/following{/other_user}","gists_url":"https://api.github.com/users/CyrusNajmabadi/gists{/gist_id}","starred_url":"https://api.github.com/users/CyrusNajmabadi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CyrusNajmabadi/subscriptions","organizations_url":"https://api.github.com/users/CyrusNajmabadi/orgs","repos_url":"https://api.github.com/users/CyrusNajmabadi/repos","events_url":"https://api.github.com/users/CyrusNajmabadi/events{/privacy}","received_events_url":"https://api.github.com/users/CyrusNajmabadi/received_events","type":"User","site_admin":false},"body":"indentation is just super weird and hard to read here.  ","created_at":"2018-11-11T23:34:16Z","updated_at":"2018-11-11T23:34:16Z","html_url":"https://github.com/dotnet/roslyn/pull/29016#discussion_r232510338","pull_request_url":"https://api.github.com/repos/dotnet/roslyn/pulls/29016","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/comments/232510338"},"html":{"href":"https://github.com/dotnet/roslyn/pull/29016#discussion_r232510338"},"pull_request":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/29016"}}},"pull_request":{"url":"https://api.github.com/repos/dotnet/roslyn/pulls/29016","id":205575269,"node_id":"MDExOlB1bGxSZXF1ZXN0MjA1NTc1MjY5","html_url":"https://github.com/dotnet/roslyn/pull/29016","diff_url":"https://github.com/dotnet/roslyn/pull/29016.diff","patch_url":"https://github.com/dotnet/roslyn/pull/29016.patch","issue_url":"https://api.github.com/repos/dotnet/roslyn/issues/29016","number":29016,"state":"open","locked":false,"title":"Implementation of new editor completion API","user":{"login":"ivanbasov","id":5455484,"node_id":"MDQ6VXNlcjU0NTU0ODQ=","avatar_url":"https://avatars2.githubusercontent.com/u/5455484?v=4","gravatar_id":"","url":"https://api.github.com/users/ivanbasov","html_url":"https://github.com/ivanbasov","followers_url":"https://api.github.com/users/ivanbasov/followers","following_url":"https://api.github.com/users/ivanbasov/following{/other_user}","gists_url":"https://api.github.com/users/ivanbasov/gists{/gist_id}","starred_url":"https://api.github.com/users/ivanbasov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ivanbasov/subscriptions","organizations_url":"https://api.github.com/users/ivanbasov/orgs","repos_url":"https://api.github.com/users/ivanbasov/repos","events_url":"https://api.github.com/users/ivanbasov/events{/privacy}","received_events_url":"https://api.github.com/users/ivanbasov/received_events","type":"User","site_admin":false},"body":"","created_at":"2018-08-01T22:51:57Z","updated_at":"2018-11-11T23:34:16Z","closed_at":null,"merged_at":null,"merge_commit_sha":"91bc7e8a203ea5b7e099bf27319649861dd587f8","assignee":null,"assignees":[],"requested_reviewers":[{"login":"jinujoseph","id":12449387,"node_id":"MDQ6VXNlcjEyNDQ5Mzg3","avatar_url":"https://avatars3.githubusercontent.com/u/12449387?v=4","gravatar_id":"","url":"https://api.github.com/users/jinujoseph","html_url":"https://github.com/jinujoseph","followers_url":"https://api.github.com/users/jinujoseph/followers","following_url":"https://api.github.com/users/jinujoseph/following{/other_user}","gists_url":"https://api.github.com/users/jinujoseph/gists{/gist_id}","starred_url":"https://api.github.com/users/jinujoseph/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jinujoseph/subscriptions","organizations_url":"https://api.github.com/users/jinujoseph/orgs","repos_url":"https://api.github.com/users/jinujoseph/repos","events_url":"https://api.github.com/users/jinujoseph/events{/privacy}","received_events_url":"https://api.github.com/users/jinujoseph/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[{"id":166377917,"node_id":"MDU6TGFiZWwxNjYzNzc5MTc=","url":"https://api.github.com/repos/dotnet/roslyn/labels/Area-IDE","name":"Area-IDE","color":"5319e7","default":false}],"milestone":{"url":"https://api.github.com/repos/dotnet/roslyn/milestones/18","html_url":"https://github.com/dotnet/roslyn/milestone/18","labels_url":"https://api.github.com/repos/dotnet/roslyn/milestones/18/labels","id":1675130,"node_id":"MDk6TWlsZXN0b25lMTY3NTEzMA==","number":18,"title":"16.0","description":"The version *after* the next major version.","creator":{"login":"gafter","id":3804346,"node_id":"MDQ6VXNlcjM4MDQzNDY=","avatar_url":"https://avatars3.githubusercontent.com/u/3804346?v=4","gravatar_id":"","url":"https://api.github.com/users/gafter","html_url":"https://github.com/gafter","followers_url":"https://api.github.com/users/gafter/followers","following_url":"https://api.github.com/users/gafter/following{/other_user}","gists_url":"https://api.github.com/users/gafter/gists{/gist_id}","starred_url":"https://api.github.com/users/gafter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gafter/subscriptions","organizations_url":"https://api.github.com/users/gafter/orgs","repos_url":"https://api.github.com/users/gafter/repos","events_url":"https://api.github.com/users/gafter/events{/privacy}","received_events_url":"https://api.github.com/users/gafter/received_events","type":"User","site_admin":false},"open_issues":1342,"closed_issues":856,"state":"open","created_at":"2016-03-31T00:06:25Z","updated_at":"2018-11-11T18:33:42Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/dotnet/roslyn/pulls/29016/commits","review_comments_url":"https://api.github.com/repos/dotnet/roslyn/pulls/29016/comments","review_comment_url":"https://api.github.com/repos/dotnet/roslyn/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dotnet/roslyn/issues/29016/comments","statuses_url":"https://api.github.com/repos/dotnet/roslyn/statuses/6d35a6f0077e477206312062cda4d982c1ab0739","head":{"label":"ivanbasov:asynccompletion","ref":"asynccompletion","sha":"6d35a6f0077e477206312062cda4d982c1ab0739","user":{"login":"ivanbasov","id":5455484,"node_id":"MDQ6VXNlcjU0NTU0ODQ=","avatar_url":"https://avatars2.githubusercontent.com/u/5455484?v=4","gravatar_id":"","url":"https://api.github.com/users/ivanbasov","html_url":"https://github.com/ivanbasov","followers_url":"https://api.github.com/users/ivanbasov/followers","following_url":"https://api.github.com/users/ivanbasov/following{/other_user}","gists_url":"https://api.github.com/users/ivanbasov/gists{/gist_id}","starred_url":"https://api.github.com/users/ivanbasov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ivanbasov/subscriptions","organizations_url":"https://api.github.com/users/ivanbasov/orgs","repos_url":"https://api.github.com/users/ivanbasov/repos","events_url":"https://api.github.com/users/ivanbasov/events{/privacy}","received_events_url":"https://api.github.com/users/ivanbasov/received_events","type":"User","site_admin":false},"repo":{"id":85608790,"node_id":"MDEwOlJlcG9zaXRvcnk4NTYwODc5MA==","name":"roslyn","full_name":"ivanbasov/roslyn","private":false,"owner":{"login":"ivanbasov","id":5455484,"node_id":"MDQ6VXNlcjU0NTU0ODQ=","avatar_url":"https://avatars2.githubusercontent.com/u/5455484?v=4","gravatar_id":"","url":"https://api.github.com/users/ivanbasov","html_url":"https://github.com/ivanbasov","followers_url":"https://api.github.com/users/ivanbasov/followers","following_url":"https://api.github.com/users/ivanbasov/following{/other_user}","gists_url":"https://api.github.com/users/ivanbasov/gists{/gist_id}","starred_url":"https://api.github.com/users/ivanbasov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ivanbasov/subscriptions","organizations_url":"https://api.github.com/users/ivanbasov/orgs","repos_url":"https://api.github.com/users/ivanbasov/repos","events_url":"https://api.github.com/users/ivanbasov/events{/privacy}","received_events_url":"https://api.github.com/users/ivanbasov/received_events","type":"User","site_admin":false},"html_url":"https://github.com/ivanbasov/roslyn","description":"The .NET Compiler Platform (\"Roslyn\") provides open-source C# and Visual Basic compilers with rich code analysis APIs.","fork":true,"url":"https://api.github.com/repos/ivanbasov/roslyn","forks_url":"https://api.github.com/repos/ivanbasov/roslyn/forks","keys_url":"https://api.github.com/repos/ivanbasov/roslyn/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ivanbasov/roslyn/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ivanbasov/roslyn/teams","hooks_url":"https://api.github.com/repos/ivanbasov/roslyn/hooks","issue_events_url":"https://api.github.com/repos/ivanbasov/roslyn/issues/events{/number}","events_url":"https://api.github.com/repos/ivanbasov/roslyn/events","assignees_url":"https://api.github.com/repos/ivanbasov/roslyn/assignees{/user}","branches_url":"https://api.github.com/repos/ivanbasov/roslyn/branches{/branch}","tags_url":"https://api.github.com/repos/ivanbasov/roslyn/tags","blobs_url":"https://api.github.com/repos/ivanbasov/roslyn/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ivanbasov/roslyn/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ivanbasov/roslyn/git/refs{/sha}","trees_url":"https://api.github.com/repos/ivanbasov/roslyn/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ivanbasov/roslyn/statuses/{sha}","languages_url":"https://api.github.com/repos/ivanbasov/roslyn/languages","stargazers_url":"https://api.github.com/repos/ivanbasov/roslyn/stargazers","contributors_url":"https://api.github.com/repos/ivanbasov/roslyn/contributors","subscribers_url":"https://api.github.com/repos/ivanbasov/roslyn/subscribers","subscription_url":"https://api.github.com/repos/ivanbasov/roslyn/subscription","commits_url":"https://api.github.com/repos/ivanbasov/roslyn/commits{/sha}","git_commits_url":"https://api.github.com/repos/ivanbasov/roslyn/git/commits{/sha}","comments_url":"https://api.github.com/repos/ivanbasov/roslyn/comments{/number}","issue_comment_url":"https://api.github.com/repos/ivanbasov/roslyn/issues/comments{/number}","contents_url":"https://api.github.com/repos/ivanbasov/roslyn/contents/{+path}","compare_url":"https://api.github.com/repos/ivanbasov/roslyn/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ivanbasov/roslyn/merges","archive_url":"https://api.github.com/repos/ivanbasov/roslyn/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ivanbasov/roslyn/downloads","issues_url":"https://api.github.com/repos/ivanbasov/roslyn/issues{/number}","pulls_url":"https://api.github.com/repos/ivanbasov/roslyn/pulls{/number}","milestones_url":"https://api.github.com/repos/ivanbasov/roslyn/milestones{/number}","notifications_url":"https://api.github.com/repos/ivanbasov/roslyn/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ivanbasov/roslyn/labels{/name}","releases_url":"https://api.github.com/repos/ivanbasov/roslyn/releases{/id}","deployments_url":"https://api.github.com/repos/ivanbasov/roslyn/deployments","created_at":"2017-03-20T17:55:57Z","updated_at":"2017-03-20T17:56:36Z","pushed_at":"2018-11-10T00:24:04Z","git_url":"git://github.com/ivanbasov/roslyn.git","ssh_url":"git@github.com:ivanbasov/roslyn.git","clone_url":"https://github.com/ivanbasov/roslyn.git","svn_url":"https://github.com/ivanbasov/roslyn","homepage":"","size":437786,"stargazers_count":0,"watchers_count":0,"language":"C#","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"dotnet:dev16.0-preview2-vs-deps","ref":"dev16.0-preview2-vs-deps","sha":"905cb87bc57ea57930a80613fec9c5851c247946","user":{"login":"dotnet","id":9141961,"node_id":"MDEyOk9yZ2FuaXphdGlvbjkxNDE5NjE=","avatar_url":"https://avatars0.githubusercontent.com/u/9141961?v=4","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"repo":{"id":29078997,"node_id":"MDEwOlJlcG9zaXRvcnkyOTA3ODk5Nw==","name":"roslyn","full_name":"dotnet/roslyn","private":false,"owner":{"login":"dotnet","id":9141961,"node_id":"MDEyOk9yZ2FuaXphdGlvbjkxNDE5NjE=","avatar_url":"https://avatars0.githubusercontent.com/u/9141961?v=4","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/dotnet/roslyn","description":"The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.","fork":false,"url":"https://api.github.com/repos/dotnet/roslyn","forks_url":"https://api.github.com/repos/dotnet/roslyn/forks","keys_url":"https://api.github.com/repos/dotnet/roslyn/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dotnet/roslyn/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dotnet/roslyn/teams","hooks_url":"https://api.github.com/repos/dotnet/roslyn/hooks","issue_events_url":"https://api.github.com/repos/dotnet/roslyn/issues/events{/number}","events_url":"https://api.github.com/repos/dotnet/roslyn/events","assignees_url":"https://api.github.com/repos/dotnet/roslyn/assignees{/user}","branches_url":"https://api.github.com/repos/dotnet/roslyn/branches{/branch}","tags_url":"https://api.github.com/repos/dotnet/roslyn/tags","blobs_url":"https://api.github.com/repos/dotnet/roslyn/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dotnet/roslyn/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dotnet/roslyn/git/refs{/sha}","trees_url":"https://api.github.com/repos/dotnet/roslyn/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dotnet/roslyn/statuses/{sha}","languages_url":"https://api.github.com/repos/dotnet/roslyn/languages","stargazers_url":"https://api.github.com/repos/dotnet/roslyn/stargazers","contributors_url":"https://api.github.com/repos/dotnet/roslyn/contributors","subscribers_url":"https://api.github.com/repos/dotnet/roslyn/subscribers","subscription_url":"https://api.github.com/repos/dotnet/roslyn/subscription","commits_url":"https://api.github.com/repos/dotnet/roslyn/commits{/sha}","git_commits_url":"https://api.github.com/repos/dotnet/roslyn/git/commits{/sha}","comments_url":"https://api.github.com/repos/dotnet/roslyn/comments{/number}","issue_comment_url":"https://api.github.com/repos/dotnet/roslyn/issues/comments{/number}","contents_url":"https://api.github.com/repos/dotnet/roslyn/contents/{+path}","compare_url":"https://api.github.com/repos/dotnet/roslyn/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dotnet/roslyn/merges","archive_url":"https://api.github.com/repos/dotnet/roslyn/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dotnet/roslyn/downloads","issues_url":"https://api.github.com/repos/dotnet/roslyn/issues{/number}","pulls_url":"https://api.github.com/repos/dotnet/roslyn/pulls{/number}","milestones_url":"https://api.github.com/repos/dotnet/roslyn/milestones{/number}","notifications_url":"https://api.github.com/repos/dotnet/roslyn/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dotnet/roslyn/labels{/name}","releases_url":"https://api.github.com/repos/dotnet/roslyn/releases{/id}","deployments_url":"https://api.github.com/repos/dotnet/roslyn/deployments","created_at":"2015-01-11T02:39:03Z","updated_at":"2018-11-11T06:09:53Z","pushed_at":"2018-11-11T22:30:59Z","git_url":"git://github.com/dotnet/roslyn.git","ssh_url":"git@github.com:dotnet/roslyn.git","clone_url":"https://github.com/dotnet/roslyn.git","svn_url":"https://github.com/dotnet/roslyn","homepage":"https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/","size":483837,"stargazers_count":10335,"watchers_count":10335,"language":"C#","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2448,"mirror_url":null,"archived":false,"open_issues_count":5378,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":2448,"open_issues":5378,"watchers":10335,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/29016"},"html":{"href":"https://github.com/dotnet/roslyn/pull/29016"},"issue":{"href":"https://api.github.com/repos/dotnet/roslyn/issues/29016"},"comments":{"href":"https://api.github.com/repos/dotnet/roslyn/issues/29016/comments"},"review_comments":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/29016/comments"},"review_comment":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/29016/commits"},"statuses":{"href":"https://api.github.com/repos/dotnet/roslyn/statuses/6d35a6f0077e477206312062cda4d982c1ab0739"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"CyrusNajmabadi"}}